tidal-link 1.2.1 → 1.2.2
raw patch · 909 files changed
+52419/−40898 lines, 909 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- link/examples/linkaudio/AudioEngine.hpp +19/−34
- link/examples/linkaudio/AudioEngine.ipp +0/−255
- link/examples/linkaudio/AudioPlatform_Asio.hpp +9/−10
- link/examples/linkaudio/AudioPlatform_Asio.ipp +0/−319
- link/examples/linkaudio/AudioPlatform_CoreAudio.hpp +6/−15
- link/examples/linkaudio/AudioPlatform_CoreAudio.ipp +0/−294
- link/examples/linkaudio/AudioPlatform_Dummy.hpp +25/−8
- link/examples/linkaudio/AudioPlatform_Jack.hpp +3/−5
- link/examples/linkaudio/AudioPlatform_Jack.ipp +0/−221
- link/examples/linkaudio/AudioPlatform_Portaudio.hpp +8/−10
- link/examples/linkaudio/AudioPlatform_Portaudio.ipp +0/−168
- link/examples/linkaudio/AudioPlatform_Wasapi.hpp +2/−6
- link/examples/linkaudio/AudioPlatform_Wasapi.ipp +0/−344
- link/examples/linkaudio/LinkAudioRenderer.hpp +0/−418
- link/extensions/abl_link/include/abl_link.h +31/−276
- link/extensions/abl_link/src/abl_link.cpp +39/−391
- link/include/ableton/Link.hpp +12/−16
- link/include/ableton/Link.ipp +16/−38
- link/include/ableton/LinkAudio.hpp +0/−358
- link/include/ableton/LinkAudio.ipp +0/−267
- link/include/ableton/discovery/AsioTypes.hpp +2/−8
- link/include/ableton/discovery/InterfaceScanner.hpp +7/−9
- link/include/ableton/discovery/IpInterface.hpp +12/−8
- link/include/ableton/discovery/NetworkByteStreamSerializable.hpp +10/−62
- link/include/ableton/discovery/Payload.hpp +19/−10
- link/include/ableton/discovery/PeerGateway.hpp +26/−28
- link/include/ableton/discovery/PeerGateways.hpp +19/−35
- link/include/ableton/discovery/Service.hpp +9/−5
- link/include/ableton/discovery/UdpMessenger.hpp +80/−75
- link/include/ableton/discovery/UnicastIpInterface.hpp +0/−99
- link/include/ableton/discovery/test/Interface.hpp +9/−17
- link/include/ableton/discovery/test/PayloadEntries.hpp +4/−1
- link/include/ableton/discovery/test/Socket.hpp +15/−8
- link/include/ableton/discovery/v1/Messages.hpp +9/−13
- link/include/ableton/link/ApiConfig.hpp +0/−46
- link/include/ableton/link/Beats.hpp +16/−4
- link/include/ableton/link/ClientSessionTimelines.hpp +8/−9
- link/include/ableton/link/Controller.hpp +185/−250
- link/include/ableton/link/EndpointV4.hpp +0/−75
- link/include/ableton/link/EndpointV6.hpp +0/−75
- link/include/ableton/link/Gateway.hpp +12/−26
- link/include/ableton/link/Measurement.hpp +51/−75
- link/include/ableton/link/MeasurementEndpointV4.hpp +75/−0
- link/include/ableton/link/MeasurementEndpointV6.hpp +75/−0
- link/include/ableton/link/MeasurementService.hpp +31/−78
- link/include/ableton/link/NodeId.hpp +1/−13
- link/include/ableton/link/NodeState.hpp +11/−9
- link/include/ableton/link/Optional.hpp +97/−0
- link/include/ableton/link/PeerState.hpp +31/−68
- link/include/ableton/link/Peers.hpp +55/−75
- link/include/ableton/link/Phase.hpp +4/−6
- link/include/ableton/link/PingResponder.hpp +40/−30
- link/include/ableton/link/SessionController.hpp +0/−106
- link/include/ableton/link/SessionState.hpp +10/−34
- link/include/ableton/link/Sessions.hpp +28/−33
- link/include/ableton/link/StartStopState.hpp +4/−5
- link/include/ableton/link/Tempo.hpp +6/−3
- link/include/ableton/link/TripleBuffer.hpp +121/−0
- link/include/ableton/link/v1/Messages.hpp +3/−4
- link/include/ableton/link_audio/ApiConfig.hpp +0/−56
- link/include/ableton/link_audio/AudioBuffer.hpp +0/−245
- link/include/ableton/link_audio/BeatTimeMapping.hpp +0/−50
- link/include/ableton/link_audio/Buffer.hpp +0/−67
- link/include/ableton/link_audio/ChannelAnnouncements.hpp +0/−180
- link/include/ableton/link_audio/ChannelId.hpp +0/−63
- link/include/ableton/link_audio/ChannelRequests.hpp +0/−92
- link/include/ableton/link_audio/Channels.hpp +0/−594
- link/include/ableton/link_audio/Controller.hpp +0/−388
- link/include/ableton/link_audio/Encoder.hpp +0/−69
- link/include/ableton/link_audio/Id.hpp +0/−32
- link/include/ableton/link_audio/MainProcessor.hpp +0/−242
- link/include/ableton/link_audio/NetworkMetrics.hpp +0/−82
- link/include/ableton/link_audio/PCMCodec.hpp +0/−116
- link/include/ableton/link_audio/PeerAnnouncement.hpp +0/−78
- link/include/ableton/link_audio/PeerGateways.hpp +0/−154
- link/include/ableton/link_audio/PeerInfo.hpp +0/−75
- link/include/ableton/link_audio/Queue.hpp +0/−217
- link/include/ableton/link_audio/Receivers.hpp +0/−172
- link/include/ableton/link_audio/Resizer.hpp +0/−147
- link/include/ableton/link_audio/SessionController.hpp +0/−125
- link/include/ableton/link_audio/Sink.hpp +0/−144
- link/include/ableton/link_audio/SinkProcessor.hpp +0/−146
- link/include/ableton/link_audio/Source.hpp +0/−67
- link/include/ableton/link_audio/SourceProcessor.hpp +0/−159
- link/include/ableton/link_audio/UdpMessenger.hpp +0/−617
- link/include/ableton/link_audio/v1/Messages.hpp +0/−170
- link/include/ableton/platforms/Config.hpp +11/−16
- link/include/ableton/platforms/asio/AsioTimer.hpp +11/−11
- link/include/ableton/platforms/asio/AsioWrapper.hpp +2/−2
- link/include/ableton/platforms/asio/Context.hpp +28/−40
- link/include/ableton/platforms/asio/LockFreeCallbackDispatcher.hpp +6/−23
- link/include/ableton/platforms/asio/Socket.hpp +12/−11
- link/include/ableton/platforms/darwin/Clock.hpp +8/−2
- link/include/ableton/platforms/darwin/ThreadFactory.hpp +2/−87
- link/include/ableton/platforms/esp32/Context.hpp +54/−19
- link/include/ableton/platforms/esp32/LockFreeCallbackDispatcher.hpp +3/−17
- link/include/ableton/platforms/esp32/Log.hpp +0/−138
- link/include/ableton/platforms/esp32/ScanIpIfAddrs.hpp +14/−31
- link/include/ableton/platforms/linux/ThreadFactory.hpp +0/−40
- link/include/ableton/platforms/posix/ScanIpIfAddrs.hpp +28/−34
- link/include/ableton/platforms/stl/Random.hpp +4/−1
- link/include/ableton/platforms/windows/Clock.hpp +4/−1
- link/include/ableton/platforms/windows/ScanIpIfAddrs.hpp +43/−55
- link/include/ableton/platforms/windows/ThreadFactory.hpp +2/−39
- link/include/ableton/platforms/windows/Windows.hpp +2/−2
- link/include/ableton/test/serial_io/Context.hpp +17/−6
- link/include/ableton/test/serial_io/Fixture.hpp +12/−3
- link/include/ableton/test/serial_io/Timer.hpp +6/−3
- link/include/ableton/util/FloatIntConversion.hpp +0/−54
- link/include/ableton/util/Injected.hpp +64/−16
- link/include/ableton/util/Locked.hpp +0/−58
- link/include/ableton/util/Log.hpp +36/−9
- link/include/ableton/util/TripleBuffer.hpp +0/−117
- link/include/ableton/util/test/IoService.hpp +12/−3
- link/include/ableton/util/test/Timer.hpp +4/−1
- link/modules/asio-standalone/asio/include/asio.hpp +23/−9
- link/modules/asio-standalone/asio/include/asio/any_completion_executor.hpp +32/−26
- link/modules/asio-standalone/asio/include/asio/any_completion_handler.hpp +61/−121
- link/modules/asio-standalone/asio/include/asio/any_io_executor.hpp +42/−34
- link/modules/asio-standalone/asio/include/asio/append.hpp +23/−10
- link/modules/asio-standalone/asio/include/asio/as_tuple.hpp +39/−52
- link/modules/asio-standalone/asio/include/asio/associated_allocator.hpp +45/−26
- link/modules/asio-standalone/asio/include/asio/associated_cancellation_slot.hpp +43/−26
- link/modules/asio-standalone/asio/include/asio/associated_executor.hpp +46/−28
- link/modules/asio-standalone/asio/include/asio/associated_immediate_executor.hpp +59/−43
- link/modules/asio-standalone/asio/include/asio/associator.hpp +2/−2
- link/modules/asio-standalone/asio/include/asio/async_result.hpp +1665/−962
- link/modules/asio-standalone/asio/include/asio/awaitable.hpp +1/−4
- link/modules/asio-standalone/asio/include/asio/basic_datagram_socket.hpp +111/−77
- link/modules/asio-standalone/asio/include/asio/basic_deadline_timer.hpp +25/−25
- link/modules/asio-standalone/asio/include/asio/basic_file.hpp +25/−132
- link/modules/asio-standalone/asio/include/asio/basic_io_object.hpp +17/−14
- link/modules/asio-standalone/asio/include/asio/basic_random_access_file.hpp +44/−32
- link/modules/asio-standalone/asio/include/asio/basic_raw_socket.hpp +108/−77
- link/modules/asio-standalone/asio/include/asio/basic_readable_pipe.hpp +30/−21
- link/modules/asio-standalone/asio/include/asio/basic_seq_packet_socket.hpp +51/−39
- link/modules/asio-standalone/asio/include/asio/basic_serial_port.hpp +46/−33
- link/modules/asio-standalone/asio/include/asio/basic_signal_set.hpp +23/−25
- link/modules/asio-standalone/asio/include/asio/basic_socket.hpp +47/−36
- link/modules/asio-standalone/asio/include/asio/basic_socket_acceptor.hpp +162/−115
- link/modules/asio-standalone/asio/include/asio/basic_socket_iostream.hpp +146/−5
- link/modules/asio-standalone/asio/include/asio/basic_socket_streambuf.hpp +148/−6
- link/modules/asio-standalone/asio/include/asio/basic_stream_file.hpp +42/−32
- link/modules/asio-standalone/asio/include/asio/basic_stream_socket.hpp +82/−56
- link/modules/asio-standalone/asio/include/asio/basic_streambuf.hpp +17/−15
- link/modules/asio-standalone/asio/include/asio/basic_streambuf_fwd.hpp +3/−3
- link/modules/asio-standalone/asio/include/asio/basic_waitable_timer.hpp +213/−25
- link/modules/asio-standalone/asio/include/asio/basic_writable_pipe.hpp +30/−21
- link/modules/asio-standalone/asio/include/asio/bind_allocator.hpp +302/−172
- link/modules/asio-standalone/asio/include/asio/bind_cancellation_slot.hpp +293/−177
- link/modules/asio-standalone/asio/include/asio/bind_executor.hpp +290/−180
- link/modules/asio-standalone/asio/include/asio/bind_immediate_executor.hpp +286/−173
- link/modules/asio-standalone/asio/include/asio/buffer.hpp +2900/−2872
- link/modules/asio-standalone/asio/include/asio/buffer_registration.hpp +40/−30
- link/modules/asio-standalone/asio/include/asio/buffered_read_stream.hpp +39/−26
- link/modules/asio-standalone/asio/include/asio/buffered_read_stream_fwd.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/buffered_stream.hpp +48/−32
- link/modules/asio-standalone/asio/include/asio/buffered_stream_fwd.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/buffered_write_stream.hpp +39/−26
- link/modules/asio-standalone/asio/include/asio/buffered_write_stream_fwd.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/buffers_iterator.hpp +24/−4
- link/modules/asio-standalone/asio/include/asio/cancel_after.hpp +0/−301
- link/modules/asio-standalone/asio/include/asio/cancel_at.hpp +0/−294
- link/modules/asio-standalone/asio/include/asio/cancellation_signal.hpp +85/−25
- link/modules/asio-standalone/asio/include/asio/cancellation_state.hpp +16/−16
- link/modules/asio-standalone/asio/include/asio/cancellation_type.hpp +25/−8
- link/modules/asio-standalone/asio/include/asio/co_composed.hpp +0/−1319
- link/modules/asio-standalone/asio/include/asio/co_spawn.hpp +17/−17
- link/modules/asio-standalone/asio/include/asio/completion_condition.hpp +1/−50
- link/modules/asio-standalone/asio/include/asio/compose.hpp +424/−21
- link/modules/asio-standalone/asio/include/asio/composed.hpp +0/−413
- link/modules/asio-standalone/asio/include/asio/config.hpp +0/−193
- link/modules/asio-standalone/asio/include/asio/connect.hpp +367/−180
- link/modules/asio-standalone/asio/include/asio/connect_pipe.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/consign.hpp +24/−11
- link/modules/asio-standalone/asio/include/asio/coroutine.hpp +6/−6
- link/modules/asio-standalone/asio/include/asio/deadline_timer.hpp +2/−7
- link/modules/asio-standalone/asio/include/asio/default_completion_token.hpp +0/−89
- link/modules/asio-standalone/asio/include/asio/defer.hpp +26/−22
- link/modules/asio-standalone/asio/include/asio/deferred.hpp +279/−196
- link/modules/asio-standalone/asio/include/asio/detached.hpp +22/−14
- link/modules/asio-standalone/asio/include/asio/detail/array.hpp +10/−2
- link/modules/asio-standalone/asio/include/asio/detail/array_fwd.hpp +4/−2
- link/modules/asio-standalone/asio/include/asio/detail/assert.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/atomic_count.hpp +13/−5
- link/modules/asio-standalone/asio/include/asio/detail/base_from_cancellation_state.hpp +20/−21
- link/modules/asio-standalone/asio/include/asio/detail/base_from_completion_cond.hpp +2/−2
- link/modules/asio-standalone/asio/include/asio/detail/bind_handler.hpp +563/−129
- link/modules/asio-standalone/asio/include/asio/detail/blocking_executor_op.hpp +3/−2
- link/modules/asio-standalone/asio/include/asio/detail/buffer_resize_guard.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/buffer_sequence_adapter.hpp +147/−3
- link/modules/asio-standalone/asio/include/asio/detail/buffered_stream_storage.hpp +2/−2
- link/modules/asio-standalone/asio/include/asio/detail/bulk_executor_op.hpp +89/−0
- link/modules/asio-standalone/asio/include/asio/detail/call_stack.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/chrono.hpp +23/−2
- link/modules/asio-standalone/asio/include/asio/detail/chrono_time_traits.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/completion_handler.hpp +4/−4
- link/modules/asio-standalone/asio/include/asio/detail/completion_message.hpp +0/−127
- link/modules/asio-standalone/asio/include/asio/detail/completion_payload.hpp +0/−220
- link/modules/asio-standalone/asio/include/asio/detail/completion_payload_handler.hpp +0/−79
- link/modules/asio-standalone/asio/include/asio/detail/composed_work.hpp +97/−21
- link/modules/asio-standalone/asio/include/asio/detail/concurrency_hint.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/conditionally_enabled_event.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/conditionally_enabled_mutex.hpp +3/−24
- link/modules/asio-standalone/asio/include/asio/detail/config.hpp +2301/−1423
- link/modules/asio-standalone/asio/include/asio/detail/consuming_buffers.hpp +55/−9
- link/modules/asio-standalone/asio/include/asio/detail/cstddef.hpp +5/−1
- link/modules/asio-standalone/asio/include/asio/detail/cstdint.hpp +24/−2
- link/modules/asio-standalone/asio/include/asio/detail/date_time_fwd.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/deadline_timer_service.hpp +21/−31
- link/modules/asio-standalone/asio/include/asio/detail/dependent_type.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/descriptor_ops.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/descriptor_read_op.hpp +4/−4
- link/modules/asio-standalone/asio/include/asio/detail/descriptor_write_op.hpp +4/−4
- link/modules/asio-standalone/asio/include/asio/detail/dev_poll_reactor.hpp +21/−21
- link/modules/asio-standalone/asio/include/asio/detail/epoll_reactor.hpp +25/−30
- link/modules/asio-standalone/asio/include/asio/detail/event.hpp +5/−3
- link/modules/asio-standalone/asio/include/asio/detail/eventfd_select_interrupter.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/exception.hpp +13/−2
- link/modules/asio-standalone/asio/include/asio/detail/executor_function.hpp +60/−8
- link/modules/asio-standalone/asio/include/asio/detail/executor_op.hpp +6/−5
- link/modules/asio-standalone/asio/include/asio/detail/fd_set_adapter.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/fenced_block.hpp +43/−3
- link/modules/asio-standalone/asio/include/asio/detail/functional.hpp +12/−1
- link/modules/asio-standalone/asio/include/asio/detail/future.hpp +10/−9
- link/modules/asio-standalone/asio/include/asio/detail/gcc_arm_fenced_block.hpp +91/−0
- link/modules/asio-standalone/asio/include/asio/detail/gcc_hppa_fenced_block.hpp +68/−0
- link/modules/asio-standalone/asio/include/asio/detail/gcc_sync_fenced_block.hpp +65/−0
- link/modules/asio-standalone/asio/include/asio/detail/gcc_x86_fenced_block.hpp +99/−0
- link/modules/asio-standalone/asio/include/asio/detail/global.hpp +5/−3
- link/modules/asio-standalone/asio/include/asio/detail/handler_alloc_helpers.hpp +184/−19
- link/modules/asio-standalone/asio/include/asio/detail/handler_cont_helpers.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/handler_invoke_helpers.hpp +80/−0
- link/modules/asio-standalone/asio/include/asio/detail/handler_tracking.hpp +3/−3
- link/modules/asio-standalone/asio/include/asio/detail/handler_type_requirements.hpp +37/−9
- link/modules/asio-standalone/asio/include/asio/detail/handler_work.hpp +127/−73
- link/modules/asio-standalone/asio/include/asio/detail/hash_map.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/impl/buffer_sequence_adapter.ipp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/impl/descriptor_ops.ipp +19/−43
- link/modules/asio-standalone/asio/include/asio/detail/impl/dev_poll_reactor.hpp +19/−25
- link/modules/asio-standalone/asio/include/asio/detail/impl/dev_poll_reactor.ipp +2/−2
- link/modules/asio-standalone/asio/include/asio/detail/impl/epoll_reactor.hpp +19/−24
- link/modules/asio-standalone/asio/include/asio/detail/impl/epoll_reactor.ipp +15/−29
- link/modules/asio-standalone/asio/include/asio/detail/impl/eventfd_select_interrupter.ipp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/impl/handler_tracking.ipp +16/−5
- link/modules/asio-standalone/asio/include/asio/detail/impl/io_uring_descriptor_service.ipp +2/−2
- link/modules/asio-standalone/asio/include/asio/detail/impl/io_uring_file_service.ipp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/impl/io_uring_service.hpp +19/−25
- link/modules/asio-standalone/asio/include/asio/detail/impl/io_uring_service.ipp +36/−45
- link/modules/asio-standalone/asio/include/asio/detail/impl/io_uring_socket_service_base.ipp +2/−2
- link/modules/asio-standalone/asio/include/asio/detail/impl/kqueue_reactor.hpp +19/−23
- link/modules/asio-standalone/asio/include/asio/detail/impl/kqueue_reactor.ipp +6/−12
- link/modules/asio-standalone/asio/include/asio/detail/impl/null_event.ipp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/impl/pipe_select_interrupter.ipp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/impl/posix_event.ipp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/impl/posix_mutex.ipp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/impl/posix_serial_port_service.ipp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/impl/posix_thread.ipp +12/−12
- link/modules/asio-standalone/asio/include/asio/detail/impl/posix_tss_ptr.ipp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/impl/reactive_descriptor_service.ipp +7/−9
- link/modules/asio-standalone/asio/include/asio/detail/impl/reactive_socket_service_base.ipp +6/−8
- link/modules/asio-standalone/asio/include/asio/detail/impl/resolver_service_base.ipp +87/−8
- link/modules/asio-standalone/asio/include/asio/detail/impl/resolver_thread_pool.ipp +0/−124
- link/modules/asio-standalone/asio/include/asio/detail/impl/scheduler.ipp +33/−54
- link/modules/asio-standalone/asio/include/asio/detail/impl/select_reactor.hpp +19/−25
- link/modules/asio-standalone/asio/include/asio/detail/impl/select_reactor.ipp +18/−7
- link/modules/asio-standalone/asio/include/asio/detail/impl/service_registry.hpp +6/−29
- link/modules/asio-standalone/asio/include/asio/detail/impl/service_registry.ipp +4/−12
- link/modules/asio-standalone/asio/include/asio/detail/impl/signal_set_service.ipp +5/−6
- link/modules/asio-standalone/asio/include/asio/detail/impl/socket_ops.ipp +14/−81
- link/modules/asio-standalone/asio/include/asio/detail/impl/socket_select_interrupter.ipp +2/−2
- link/modules/asio-standalone/asio/include/asio/detail/impl/strand_executor_service.hpp +68/−47
- link/modules/asio-standalone/asio/include/asio/detail/impl/strand_executor_service.ipp +4/−5
- link/modules/asio-standalone/asio/include/asio/detail/impl/strand_service.hpp +3/−2
- link/modules/asio-standalone/asio/include/asio/detail/impl/strand_service.ipp +3/−6
- link/modules/asio-standalone/asio/include/asio/detail/impl/thread_context.ipp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/impl/throw_error.ipp +22/−1
- link/modules/asio-standalone/asio/include/asio/detail/impl/timer_queue_ptime.ipp +97/−0
- link/modules/asio-standalone/asio/include/asio/detail/impl/timer_queue_set.ipp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/impl/win_event.ipp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/impl/win_iocp_file_service.ipp +9/−32
- link/modules/asio-standalone/asio/include/asio/detail/impl/win_iocp_handle_service.ipp +6/−6
- link/modules/asio-standalone/asio/include/asio/detail/impl/win_iocp_io_context.hpp +20/−23
- link/modules/asio-standalone/asio/include/asio/detail/impl/win_iocp_io_context.ipp +22/−43
- link/modules/asio-standalone/asio/include/asio/detail/impl/win_iocp_serial_port_service.ipp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/impl/win_iocp_socket_service_base.ipp +2/−2
- link/modules/asio-standalone/asio/include/asio/detail/impl/win_mutex.ipp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/impl/win_object_handle_service.ipp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/impl/win_static_mutex.ipp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/impl/win_thread.ipp +42/−43
- link/modules/asio-standalone/asio/include/asio/detail/impl/win_tss_ptr.ipp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/impl/winrt_ssocket_service_base.ipp +2/−2
- link/modules/asio-standalone/asio/include/asio/detail/impl/winrt_timer_scheduler.hpp +16/−22
- link/modules/asio-standalone/asio/include/asio/detail/impl/winrt_timer_scheduler.ipp +11/−4
- link/modules/asio-standalone/asio/include/asio/detail/impl/winsock_init.ipp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/initiate_defer.hpp +101/−56
- link/modules/asio-standalone/asio/include/asio/detail/initiate_dispatch.hpp +92/−56
- link/modules/asio-standalone/asio/include/asio/detail/initiate_post.hpp +101/−56
- link/modules/asio-standalone/asio/include/asio/detail/initiation_base.hpp +0/−62
- link/modules/asio-standalone/asio/include/asio/detail/io_control.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/io_object_impl.hpp +10/−6
- link/modules/asio-standalone/asio/include/asio/detail/io_uring_descriptor_read_at_op.hpp +3/−3
- link/modules/asio-standalone/asio/include/asio/detail/io_uring_descriptor_read_op.hpp +4/−4
- link/modules/asio-standalone/asio/include/asio/detail/io_uring_descriptor_service.hpp +9/−9
- link/modules/asio-standalone/asio/include/asio/detail/io_uring_descriptor_write_at_op.hpp +3/−3
- link/modules/asio-standalone/asio/include/asio/detail/io_uring_descriptor_write_op.hpp +4/−4
- link/modules/asio-standalone/asio/include/asio/detail/io_uring_file_service.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/io_uring_null_buffers_op.hpp +4/−3
- link/modules/asio-standalone/asio/include/asio/detail/io_uring_operation.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/io_uring_service.hpp +25/−30
- link/modules/asio-standalone/asio/include/asio/detail/io_uring_socket_accept_op.hpp +12/−7
- link/modules/asio-standalone/asio/include/asio/detail/io_uring_socket_connect_op.hpp +4/−3
- link/modules/asio-standalone/asio/include/asio/detail/io_uring_socket_recv_op.hpp +4/−4
- link/modules/asio-standalone/asio/include/asio/detail/io_uring_socket_recvfrom_op.hpp +4/−4
- link/modules/asio-standalone/asio/include/asio/detail/io_uring_socket_recvmsg_op.hpp +3/−3
- link/modules/asio-standalone/asio/include/asio/detail/io_uring_socket_send_op.hpp +4/−4
- link/modules/asio-standalone/asio/include/asio/detail/io_uring_socket_sendto_op.hpp +3/−3
- link/modules/asio-standalone/asio/include/asio/detail/io_uring_socket_service.hpp +13/−11
- link/modules/asio-standalone/asio/include/asio/detail/io_uring_socket_service_base.hpp +9/−9
- link/modules/asio-standalone/asio/include/asio/detail/io_uring_wait_op.hpp +4/−3
- link/modules/asio-standalone/asio/include/asio/detail/is_buffer_sequence.hpp +49/−7
- link/modules/asio-standalone/asio/include/asio/detail/is_executor.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/keyword_tss_ptr.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/kqueue_reactor.hpp +24/−30
- link/modules/asio-standalone/asio/include/asio/detail/limits.hpp +6/−1
- link/modules/asio-standalone/asio/include/asio/detail/local_free_on_block_exit.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/macos_fenced_block.hpp +62/−0
- link/modules/asio-standalone/asio/include/asio/detail/memory.hpp +54/−41
- link/modules/asio-standalone/asio/include/asio/detail/mutex.hpp +5/−3
- link/modules/asio-standalone/asio/include/asio/detail/non_const_lvalue.hpp +15/−4
- link/modules/asio-standalone/asio/include/asio/detail/noncopyable.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/null_event.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/null_fenced_block.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/null_global.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/null_mutex.hpp +1/−7
- link/modules/asio-standalone/asio/include/asio/detail/null_reactor.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/null_signal_blocker.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/null_socket_service.hpp +3/−3
- link/modules/asio-standalone/asio/include/asio/detail/null_static_mutex.hpp +1/−7
- link/modules/asio-standalone/asio/include/asio/detail/null_thread.hpp +3/−31
- link/modules/asio-standalone/asio/include/asio/detail/null_tss_ptr.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/object_pool.hpp +83/−39
- link/modules/asio-standalone/asio/include/asio/detail/old_win_sdk_compat.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/op_queue.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/operation.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/pipe_select_interrupter.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/pop_options.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/posix_event.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/posix_fd_set_adapter.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/posix_global.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/posix_mutex.hpp +1/−7
- link/modules/asio-standalone/asio/include/asio/detail/posix_serial_port_service.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/posix_signal_blocker.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/posix_static_mutex.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/posix_thread.hpp +17/−52
- link/modules/asio-standalone/asio/include/asio/detail/posix_tss_ptr.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/push_options.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/reactive_descriptor_service.hpp +25/−29
- link/modules/asio-standalone/asio/include/asio/detail/reactive_null_buffers_op.hpp +5/−4
- link/modules/asio-standalone/asio/include/asio/detail/reactive_socket_accept_op.hpp +16/−11
- link/modules/asio-standalone/asio/include/asio/detail/reactive_socket_connect_op.hpp +5/−4
- link/modules/asio-standalone/asio/include/asio/detail/reactive_socket_recv_op.hpp +5/−4
- link/modules/asio-standalone/asio/include/asio/detail/reactive_socket_recvfrom_op.hpp +5/−4
- link/modules/asio-standalone/asio/include/asio/detail/reactive_socket_recvmsg_op.hpp +5/−4
- link/modules/asio-standalone/asio/include/asio/detail/reactive_socket_send_op.hpp +6/−4
- link/modules/asio-standalone/asio/include/asio/detail/reactive_socket_sendto_op.hpp +5/−4
- link/modules/asio-standalone/asio/include/asio/detail/reactive_socket_service.hpp +17/−15
- link/modules/asio-standalone/asio/include/asio/detail/reactive_socket_service_base.hpp +35/−40
- link/modules/asio-standalone/asio/include/asio/detail/reactive_wait_op.hpp +5/−4
- link/modules/asio-standalone/asio/include/asio/detail/reactor.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/reactor_op.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/reactor_op_queue.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/recycling_allocator.hpp +2/−11
- link/modules/asio-standalone/asio/include/asio/detail/regex_fwd.hpp +13/−4
- link/modules/asio-standalone/asio/include/asio/detail/resolve_endpoint_op.hpp +5/−4
- link/modules/asio-standalone/asio/include/asio/detail/resolve_op.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/resolve_query_op.hpp +5/−4
- link/modules/asio-standalone/asio/include/asio/detail/resolver_service.hpp +17/−10
- link/modules/asio-standalone/asio/include/asio/detail/resolver_service_base.hpp +37/−4
- link/modules/asio-standalone/asio/include/asio/detail/resolver_thread_pool.hpp +0/−105
- link/modules/asio-standalone/asio/include/asio/detail/scheduler.hpp +18/−20
- link/modules/asio-standalone/asio/include/asio/detail/scheduler_operation.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/scheduler_task.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/scheduler_thread_info.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/scoped_lock.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/scoped_ptr.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/select_interrupter.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/select_reactor.hpp +20/−21
- link/modules/asio-standalone/asio/include/asio/detail/service_registry.hpp +11/−20
- link/modules/asio-standalone/asio/include/asio/detail/signal_blocker.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/signal_handler.hpp +3/−3
- link/modules/asio-standalone/asio/include/asio/detail/signal_init.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/signal_op.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/signal_set_service.hpp +2/−2
- link/modules/asio-standalone/asio/include/asio/detail/socket_holder.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/socket_ops.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/socket_option.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/socket_select_interrupter.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/socket_types.hpp +2/−6
- link/modules/asio-standalone/asio/include/asio/detail/solaris_fenced_block.hpp +62/−0
- link/modules/asio-standalone/asio/include/asio/detail/source_location.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/static_mutex.hpp +5/−3
- link/modules/asio-standalone/asio/include/asio/detail/std_event.hpp +6/−1
- link/modules/asio-standalone/asio/include/asio/detail/std_fenced_block.hpp +6/−1
- link/modules/asio-standalone/asio/include/asio/detail/std_global.hpp +6/−1
- link/modules/asio-standalone/asio/include/asio/detail/std_mutex.hpp +6/−7
- link/modules/asio-standalone/asio/include/asio/detail/std_static_mutex.hpp +6/−1
- link/modules/asio-standalone/asio/include/asio/detail/std_thread.hpp +9/−34
- link/modules/asio-standalone/asio/include/asio/detail/strand_executor_service.hpp +15/−14
- link/modules/asio-standalone/asio/include/asio/detail/strand_service.hpp +3/−2
- link/modules/asio-standalone/asio/include/asio/detail/string_view.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/thread.hpp +5/−3
- link/modules/asio-standalone/asio/include/asio/detail/thread_context.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/thread_group.hpp +8/−13
- link/modules/asio-standalone/asio/include/asio/detail/thread_info_base.hpp +23/−23
- link/modules/asio-standalone/asio/include/asio/detail/throw_error.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/throw_exception.hpp +2/−2
- link/modules/asio-standalone/asio/include/asio/detail/timed_cancel_op.hpp +0/−361
- link/modules/asio-standalone/asio/include/asio/detail/timer_queue.hpp +17/−21
- link/modules/asio-standalone/asio/include/asio/detail/timer_queue_base.hpp +2/−2
- link/modules/asio-standalone/asio/include/asio/detail/timer_queue_ptime.hpp +103/−0
- link/modules/asio-standalone/asio/include/asio/detail/timer_queue_set.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/timer_scheduler.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/timer_scheduler_fwd.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/tss_ptr.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/type_traits.hpp +90/−116
- link/modules/asio-standalone/asio/include/asio/detail/utility.hpp +4/−4
- link/modules/asio-standalone/asio/include/asio/detail/variadic_templates.hpp +294/−0
- link/modules/asio-standalone/asio/include/asio/detail/wait_handler.hpp +3/−3
- link/modules/asio-standalone/asio/include/asio/detail/wait_op.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/win_event.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/win_fd_set_adapter.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/win_fenced_block.hpp +90/−0
- link/modules/asio-standalone/asio/include/asio/detail/win_global.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/win_iocp_file_service.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/win_iocp_handle_read_op.hpp +4/−3
- link/modules/asio-standalone/asio/include/asio/detail/win_iocp_handle_service.hpp +5/−5
- link/modules/asio-standalone/asio/include/asio/detail/win_iocp_handle_write_op.hpp +4/−3
- link/modules/asio-standalone/asio/include/asio/detail/win_iocp_io_context.hpp +33/−33
- link/modules/asio-standalone/asio/include/asio/detail/win_iocp_null_buffers_op.hpp +4/−3
- link/modules/asio-standalone/asio/include/asio/detail/win_iocp_operation.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/win_iocp_overlapped_op.hpp +4/−3
- link/modules/asio-standalone/asio/include/asio/detail/win_iocp_overlapped_ptr.hpp +7/−7
- link/modules/asio-standalone/asio/include/asio/detail/win_iocp_serial_port_service.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/win_iocp_socket_accept_op.hpp +12/−7
- link/modules/asio-standalone/asio/include/asio/detail/win_iocp_socket_connect_op.hpp +4/−3
- link/modules/asio-standalone/asio/include/asio/detail/win_iocp_socket_recv_op.hpp +4/−3
- link/modules/asio-standalone/asio/include/asio/detail/win_iocp_socket_recvfrom_op.hpp +4/−3
- link/modules/asio-standalone/asio/include/asio/detail/win_iocp_socket_recvmsg_op.hpp +5/−4
- link/modules/asio-standalone/asio/include/asio/detail/win_iocp_socket_send_op.hpp +4/−3
- link/modules/asio-standalone/asio/include/asio/detail/win_iocp_socket_service.hpp +13/−10
- link/modules/asio-standalone/asio/include/asio/detail/win_iocp_socket_service_base.hpp +10/−9
- link/modules/asio-standalone/asio/include/asio/detail/win_iocp_thread_info.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/win_iocp_wait_op.hpp +4/−3
- link/modules/asio-standalone/asio/include/asio/detail/win_mutex.hpp +1/−7
- link/modules/asio-standalone/asio/include/asio/detail/win_object_handle_service.hpp +2/−1
- link/modules/asio-standalone/asio/include/asio/detail/win_static_mutex.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/win_thread.hpp +19/−55
- link/modules/asio-standalone/asio/include/asio/detail/win_tss_ptr.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/winapp_thread.hpp +26/−73
- link/modules/asio-standalone/asio/include/asio/detail/wince_thread.hpp +25/−72
- link/modules/asio-standalone/asio/include/asio/detail/winrt_async_manager.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/winrt_async_op.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/winrt_resolve_op.hpp +4/−3
- link/modules/asio-standalone/asio/include/asio/detail/winrt_resolver_service.hpp +3/−3
- link/modules/asio-standalone/asio/include/asio/detail/winrt_socket_connect_op.hpp +4/−3
- link/modules/asio-standalone/asio/include/asio/detail/winrt_socket_recv_op.hpp +4/−3
- link/modules/asio-standalone/asio/include/asio/detail/winrt_socket_send_op.hpp +4/−3
- link/modules/asio-standalone/asio/include/asio/detail/winrt_ssocket_service.hpp +4/−4
- link/modules/asio-standalone/asio/include/asio/detail/winrt_ssocket_service_base.hpp +3/−3
- link/modules/asio-standalone/asio/include/asio/detail/winrt_timer_scheduler.hpp +17/−18
- link/modules/asio-standalone/asio/include/asio/detail/winrt_utils.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/winsock_init.hpp +2/−2
- link/modules/asio-standalone/asio/include/asio/detail/work_dispatcher.hpp +34/−20
- link/modules/asio-standalone/asio/include/asio/detail/wrapped_handler.hpp +180/−61
- link/modules/asio-standalone/asio/include/asio/dispatch.hpp +26/−21
- link/modules/asio-standalone/asio/include/asio/disposition.hpp +0/−282
- link/modules/asio-standalone/asio/include/asio/error.hpp +3/−1
- link/modules/asio-standalone/asio/include/asio/error_code.hpp +166/−3
- link/modules/asio-standalone/asio/include/asio/execution.hpp +16/−1
- link/modules/asio-standalone/asio/include/asio/execution/allocator.hpp +113/−35
- link/modules/asio-standalone/asio/include/asio/execution/any_executor.hpp +2648/−1918
- link/modules/asio-standalone/asio/include/asio/execution/bad_executor.hpp +4/−3
- link/modules/asio-standalone/asio/include/asio/execution/blocking.hpp +537/−297
- link/modules/asio-standalone/asio/include/asio/execution/blocking_adaptation.hpp +413/−275
- link/modules/asio-standalone/asio/include/asio/execution/bulk_execute.hpp +402/−0
- link/modules/asio-standalone/asio/include/asio/execution/bulk_guarantee.hpp +1252/−0
- link/modules/asio-standalone/asio/include/asio/execution/connect.hpp +494/−0
- link/modules/asio-standalone/asio/include/asio/execution/context.hpp +74/−21
- link/modules/asio-standalone/asio/include/asio/execution/context_as.hpp +72/−30
- link/modules/asio-standalone/asio/include/asio/execution/detail/as_invocable.hpp +152/−0
- link/modules/asio-standalone/asio/include/asio/execution/detail/as_operation.hpp +109/−0
- link/modules/asio-standalone/asio/include/asio/execution/detail/as_receiver.hpp +128/−0
- link/modules/asio-standalone/asio/include/asio/execution/detail/bulk_sender.hpp +261/−0
- link/modules/asio-standalone/asio/include/asio/execution/detail/submit_receiver.hpp +233/−0
- link/modules/asio-standalone/asio/include/asio/execution/detail/void_receiver.hpp +90/−0
- link/modules/asio-standalone/asio/include/asio/execution/execute.hpp +290/−0
- link/modules/asio-standalone/asio/include/asio/execution/executor.hpp +170/−24
- link/modules/asio-standalone/asio/include/asio/execution/impl/bad_executor.ipp +5/−5
- link/modules/asio-standalone/asio/include/asio/execution/impl/receiver_invocation_error.ipp +36/−0
- link/modules/asio-standalone/asio/include/asio/execution/invocable_archetype.hpp +30/−2
- link/modules/asio-standalone/asio/include/asio/execution/mapping.hpp +399/−241
- link/modules/asio-standalone/asio/include/asio/execution/occupancy.hpp +74/−21
- link/modules/asio-standalone/asio/include/asio/execution/operation_state.hpp +99/−0
- link/modules/asio-standalone/asio/include/asio/execution/outstanding_work.hpp +297/−150
- link/modules/asio-standalone/asio/include/asio/execution/prefer_only.hpp +59/−56
- link/modules/asio-standalone/asio/include/asio/execution/receiver.hpp +285/−0
- link/modules/asio-standalone/asio/include/asio/execution/receiver_invocation_error.hpp +48/−0
- link/modules/asio-standalone/asio/include/asio/execution/relationship.hpp +297/−150
- link/modules/asio-standalone/asio/include/asio/execution/schedule.hpp +292/−0
- link/modules/asio-standalone/asio/include/asio/execution/scheduler.hpp +91/−0
- link/modules/asio-standalone/asio/include/asio/execution/sender.hpp +316/−0
- link/modules/asio-standalone/asio/include/asio/execution/set_done.hpp +255/−0
- link/modules/asio-standalone/asio/include/asio/execution/set_error.hpp +255/−0
- link/modules/asio-standalone/asio/include/asio/execution/set_value.hpp +488/−0
- link/modules/asio-standalone/asio/include/asio/execution/start.hpp +252/−0
- link/modules/asio-standalone/asio/include/asio/execution/submit.hpp +455/−0
- link/modules/asio-standalone/asio/include/asio/execution_context.hpp +28/−203
- link/modules/asio-standalone/asio/include/asio/executor.hpp +43/−59
- link/modules/asio-standalone/asio/include/asio/executor_work_guard.hpp +61/−56
- link/modules/asio-standalone/asio/include/asio/experimental/append.hpp +36/−0
- link/modules/asio-standalone/asio/include/asio/experimental/as_single.hpp +24/−20
- link/modules/asio-standalone/asio/include/asio/experimental/as_tuple.hpp +36/−0
- link/modules/asio-standalone/asio/include/asio/experimental/awaitable_operators.hpp +8/−8
- link/modules/asio-standalone/asio/include/asio/experimental/basic_channel.hpp +35/−58
- link/modules/asio-standalone/asio/include/asio/experimental/basic_concurrent_channel.hpp +35/−58
- link/modules/asio-standalone/asio/include/asio/experimental/cancellation_condition.hpp +36/−20
- link/modules/asio-standalone/asio/include/asio/experimental/channel.hpp +3/−9
- link/modules/asio-standalone/asio/include/asio/experimental/channel_error.hpp +3/−1
- link/modules/asio-standalone/asio/include/asio/experimental/channel_traits.hpp +15/−15
- link/modules/asio-standalone/asio/include/asio/experimental/co_composed.hpp +114/−3
- link/modules/asio-standalone/asio/include/asio/experimental/co_spawn.hpp +2/−2
- link/modules/asio-standalone/asio/include/asio/experimental/concurrent_channel.hpp +3/−9
- link/modules/asio-standalone/asio/include/asio/experimental/deferred.hpp +36/−0
- link/modules/asio-standalone/asio/include/asio/experimental/detail/channel_handler.hpp +80/−0
- link/modules/asio-standalone/asio/include/asio/experimental/detail/channel_message.hpp +129/−0
- link/modules/asio-standalone/asio/include/asio/experimental/detail/channel_operation.hpp +53/−130
- link/modules/asio-standalone/asio/include/asio/experimental/detail/channel_payload.hpp +139/−0
- link/modules/asio-standalone/asio/include/asio/experimental/detail/channel_receive_op.hpp +11/−17
- link/modules/asio-standalone/asio/include/asio/experimental/detail/channel_send_functions.hpp +36/−92
- link/modules/asio-standalone/asio/include/asio/experimental/detail/channel_send_op.hpp +13/−12
- link/modules/asio-standalone/asio/include/asio/experimental/detail/channel_service.hpp +66/−68
- link/modules/asio-standalone/asio/include/asio/experimental/detail/coro_promise_allocator.hpp +3/−3
- link/modules/asio-standalone/asio/include/asio/experimental/detail/has_signature.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/experimental/detail/impl/channel_service.hpp +30/−41
- link/modules/asio-standalone/asio/include/asio/experimental/detail/partial_promise.hpp +5/−3
- link/modules/asio-standalone/asio/include/asio/experimental/impl/as_single.hpp +100/−42
- link/modules/asio-standalone/asio/include/asio/experimental/impl/channel_error.ipp +2/−2
- link/modules/asio-standalone/asio/include/asio/experimental/impl/co_composed.hpp +1175/−0
- link/modules/asio-standalone/asio/include/asio/experimental/impl/coro.hpp +40/−40
- link/modules/asio-standalone/asio/include/asio/experimental/impl/parallel_group.hpp +63/−60
- link/modules/asio-standalone/asio/include/asio/experimental/impl/promise.hpp +3/−4
- link/modules/asio-standalone/asio/include/asio/experimental/impl/use_promise.hpp +2/−2
- link/modules/asio-standalone/asio/include/asio/experimental/parallel_group.hpp +71/−65
- link/modules/asio-standalone/asio/include/asio/experimental/prepend.hpp +36/−0
- link/modules/asio-standalone/asio/include/asio/experimental/promise.hpp +3/−3
- link/modules/asio-standalone/asio/include/asio/experimental/use_coro.hpp +25/−19
- link/modules/asio-standalone/asio/include/asio/experimental/use_promise.hpp +12/−12
- link/modules/asio-standalone/asio/include/asio/file_base.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/generic/basic_endpoint.hpp +6/−2
- link/modules/asio-standalone/asio/include/asio/generic/datagram_protocol.hpp +4/−4
- link/modules/asio-standalone/asio/include/asio/generic/detail/endpoint.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/generic/detail/impl/endpoint.ipp +1/−1
- link/modules/asio-standalone/asio/include/asio/generic/raw_protocol.hpp +4/−4
- link/modules/asio-standalone/asio/include/asio/generic/seq_packet_protocol.hpp +4/−4
- link/modules/asio-standalone/asio/include/asio/generic/stream_protocol.hpp +4/−4
- link/modules/asio-standalone/asio/include/asio/handler_alloc_hook.hpp +104/−0
- link/modules/asio-standalone/asio/include/asio/handler_continuation_hook.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/handler_invoke_hook.hpp +111/−0
- link/modules/asio-standalone/asio/include/asio/high_resolution_timer.hpp +6/−1
- link/modules/asio-standalone/asio/include/asio/immediate.hpp +0/−142
- link/modules/asio-standalone/asio/include/asio/impl/any_completion_executor.ipp +14/−10
- link/modules/asio-standalone/asio/include/asio/impl/any_io_executor.ipp +17/−10
- link/modules/asio-standalone/asio/include/asio/impl/append.hpp +104/−48
- link/modules/asio-standalone/asio/include/asio/impl/as_tuple.hpp +145/−101
- link/modules/asio-standalone/asio/include/asio/impl/awaitable.hpp +189/−97
- link/modules/asio-standalone/asio/include/asio/impl/awaitable.ipp +0/−48
- link/modules/asio-standalone/asio/include/asio/impl/buffered_read_stream.hpp +179/−56
- link/modules/asio-standalone/asio/include/asio/impl/buffered_write_stream.hpp +179/−56
- link/modules/asio-standalone/asio/include/asio/impl/cancel_after.hpp +0/−268
- link/modules/asio-standalone/asio/include/asio/impl/cancel_at.hpp +0/−268
- link/modules/asio-standalone/asio/include/asio/impl/cancellation_signal.ipp +1/−1
- link/modules/asio-standalone/asio/include/asio/impl/co_spawn.hpp +81/−137
- link/modules/asio-standalone/asio/include/asio/impl/config.hpp +0/−102
- link/modules/asio-standalone/asio/include/asio/impl/config.ipp +0/−345
- link/modules/asio-standalone/asio/include/asio/impl/connect.hpp +391/−77
- link/modules/asio-standalone/asio/include/asio/impl/connect_pipe.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/impl/connect_pipe.ipp +3/−4
- link/modules/asio-standalone/asio/include/asio/impl/consign.hpp +101/−43
- link/modules/asio-standalone/asio/include/asio/impl/deferred.hpp +41/−32
- link/modules/asio-standalone/asio/include/asio/impl/detached.hpp +60/−7
- link/modules/asio-standalone/asio/include/asio/impl/error.ipp +4/−4
- link/modules/asio-standalone/asio/include/asio/impl/error_code.ipp +3/−4
- link/modules/asio-standalone/asio/include/asio/impl/execution_context.hpp +40/−76
- link/modules/asio-standalone/asio/include/asio/impl/execution_context.ipp +4/−42
- link/modules/asio-standalone/asio/include/asio/impl/executor.hpp +43/−60
- link/modules/asio-standalone/asio/include/asio/impl/executor.ipp +3/−3
- link/modules/asio-standalone/asio/include/asio/impl/handler_alloc_hook.ipp +62/−0
- link/modules/asio-standalone/asio/include/asio/impl/io_context.hpp +160/−53
- link/modules/asio-standalone/asio/include/asio/impl/io_context.ipp +59/−10
- link/modules/asio-standalone/asio/include/asio/impl/multiple_exceptions.ipp +8/−4
- link/modules/asio-standalone/asio/include/asio/impl/prepend.hpp +102/−47
- link/modules/asio-standalone/asio/include/asio/impl/read.hpp +522/−148
- link/modules/asio-standalone/asio/include/asio/impl/read_at.hpp +266/−54
- link/modules/asio-standalone/asio/include/asio/impl/read_until.hpp +3443/−2656
- link/modules/asio-standalone/asio/include/asio/impl/redirect_error.hpp +428/−81
- link/modules/asio-standalone/asio/include/asio/impl/serial_port_base.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/impl/serial_port_base.ipp +1/−1
- link/modules/asio-standalone/asio/include/asio/impl/spawn.hpp +710/−209
- link/modules/asio-standalone/asio/include/asio/impl/src.hpp +4/−4
- link/modules/asio-standalone/asio/include/asio/impl/system_context.hpp +2/−2
- link/modules/asio-standalone/asio/include/asio/impl/system_context.ipp +3/−4
- link/modules/asio-standalone/asio/include/asio/impl/system_executor.hpp +25/−19
- link/modules/asio-standalone/asio/include/asio/impl/thread_pool.hpp +108/−73
- link/modules/asio-standalone/asio/include/asio/impl/thread_pool.ipp +35/−38
- link/modules/asio-standalone/asio/include/asio/impl/use_awaitable.hpp +124/−57
- link/modules/asio-standalone/asio/include/asio/impl/use_future.hpp +518/−107
- link/modules/asio-standalone/asio/include/asio/impl/write.hpp +527/−154
- link/modules/asio-standalone/asio/include/asio/impl/write_at.hpp +259/−52
- link/modules/asio-standalone/asio/include/asio/io_context.hpp +350/−137
- link/modules/asio-standalone/asio/include/asio/io_context_strand.hpp +125/−31
- link/modules/asio-standalone/asio/include/asio/io_service.hpp +33/−0
- link/modules/asio-standalone/asio/include/asio/io_service_strand.hpp +20/−0
- link/modules/asio-standalone/asio/include/asio/ip/address.hpp +61/−26
- link/modules/asio-standalone/asio/include/asio/ip/address_v4.hpp +90/−25
- link/modules/asio-standalone/asio/include/asio/ip/address_v4_iterator.hpp +19/−13
- link/modules/asio-standalone/asio/include/asio/ip/address_v4_range.hpp +22/−16
- link/modules/asio-standalone/asio/include/asio/ip/address_v6.hpp +83/−33
- link/modules/asio-standalone/asio/include/asio/ip/address_v6_iterator.hpp +18/−13
- link/modules/asio-standalone/asio/include/asio/ip/address_v6_range.hpp +20/−15
- link/modules/asio-standalone/asio/include/asio/ip/bad_address_cast.hpp +3/−13
- link/modules/asio-standalone/asio/include/asio/ip/basic_endpoint.hpp +35/−26
- link/modules/asio-standalone/asio/include/asio/ip/basic_resolver.hpp +172/−46
- link/modules/asio-standalone/asio/include/asio/ip/basic_resolver_entry.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/ip/basic_resolver_iterator.hpp +8/−4
- link/modules/asio-standalone/asio/include/asio/ip/basic_resolver_query.hpp +1/−17
- link/modules/asio-standalone/asio/include/asio/ip/basic_resolver_results.hpp +17/−9
- link/modules/asio-standalone/asio/include/asio/ip/detail/endpoint.hpp +22/−26
- link/modules/asio-standalone/asio/include/asio/ip/detail/impl/endpoint.ipp +14/−10
- link/modules/asio-standalone/asio/include/asio/ip/detail/socket_option.hpp +2/−2
- link/modules/asio-standalone/asio/include/asio/ip/host_name.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/ip/icmp.hpp +7/−7
- link/modules/asio-standalone/asio/include/asio/ip/impl/address.hpp +29/−1
- link/modules/asio-standalone/asio/include/asio/ip/impl/address.ipp +31/−18
- link/modules/asio-standalone/asio/include/asio/ip/impl/address_v4.hpp +29/−1
- link/modules/asio-standalone/asio/include/asio/ip/impl/address_v4.ipp +69/−9
- link/modules/asio-standalone/asio/include/asio/ip/impl/address_v6.hpp +29/−1
- link/modules/asio-standalone/asio/include/asio/ip/impl/address_v6.ipp +94/−25
- link/modules/asio-standalone/asio/include/asio/ip/impl/basic_endpoint.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/ip/impl/host_name.ipp +1/−1
- link/modules/asio-standalone/asio/include/asio/ip/impl/network_v4.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/ip/impl/network_v4.ipp +3/−3
- link/modules/asio-standalone/asio/include/asio/ip/impl/network_v6.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/ip/impl/network_v6.ipp +3/−3
- link/modules/asio-standalone/asio/include/asio/ip/multicast.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/ip/network_v4.hpp +20/−16
- link/modules/asio-standalone/asio/include/asio/ip/network_v6.hpp +18/−14
- link/modules/asio-standalone/asio/include/asio/ip/resolver_base.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/ip/resolver_query_base.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/ip/tcp.hpp +7/−7
- link/modules/asio-standalone/asio/include/asio/ip/udp.hpp +7/−7
- link/modules/asio-standalone/asio/include/asio/ip/unicast.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/ip/v6_only.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/is_applicable_property.hpp +6/−6
- link/modules/asio-standalone/asio/include/asio/is_contiguous_iterator.hpp +2/−2
- link/modules/asio-standalone/asio/include/asio/is_executor.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/is_read_buffered.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/is_write_buffered.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/local/basic_endpoint.hpp +21/−17
- link/modules/asio-standalone/asio/include/asio/local/connect_pair.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/local/datagram_protocol.hpp +4/−4
- link/modules/asio-standalone/asio/include/asio/local/detail/endpoint.hpp +10/−10
- link/modules/asio-standalone/asio/include/asio/local/detail/impl/endpoint.ipp +4/−4
- link/modules/asio-standalone/asio/include/asio/local/seq_packet_protocol.hpp +4/−4
- link/modules/asio-standalone/asio/include/asio/local/stream_protocol.hpp +4/−4
- link/modules/asio-standalone/asio/include/asio/multiple_exceptions.hpp +9/−3
- link/modules/asio-standalone/asio/include/asio/packaged_task.hpp +61/−1
- link/modules/asio-standalone/asio/include/asio/placeholders.hpp +103/−33
- link/modules/asio-standalone/asio/include/asio/posix/basic_descriptor.hpp +30/−22
- link/modules/asio-standalone/asio/include/asio/posix/basic_stream_descriptor.hpp +36/−26
- link/modules/asio-standalone/asio/include/asio/posix/descriptor.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/posix/descriptor_base.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/posix/stream_descriptor.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/post.hpp +26/−21
- link/modules/asio-standalone/asio/include/asio/prefer.hpp +331/−174
- link/modules/asio-standalone/asio/include/asio/prepend.hpp +23/−11
- link/modules/asio-standalone/asio/include/asio/query.hpp +70/−57
- link/modules/asio-standalone/asio/include/asio/random_access_file.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/read.hpp +178/−245
- link/modules/asio-standalone/asio/include/asio/read_at.hpp +60/−93
- link/modules/asio-standalone/asio/include/asio/read_until.hpp +314/−350
- link/modules/asio-standalone/asio/include/asio/readable_pipe.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/recycling_allocator.hpp +15/−15
- link/modules/asio-standalone/asio/include/asio/redirect_error.hpp +9/−47
- link/modules/asio-standalone/asio/include/asio/registered_buffer.hpp +49/−37
- link/modules/asio-standalone/asio/include/asio/require.hpp +245/−107
- link/modules/asio-standalone/asio/include/asio/require_concept.hpp +79/−70
- link/modules/asio-standalone/asio/include/asio/serial_port.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/serial_port_base.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/signal_set.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/signal_set_base.hpp +21/−10
- link/modules/asio-standalone/asio/include/asio/socket_base.hpp +12/−1
- link/modules/asio-standalone/asio/include/asio/spawn.hpp +317/−101
- link/modules/asio-standalone/asio/include/asio/ssl.hpp +2/−1
- link/modules/asio-standalone/asio/include/asio/ssl/context.hpp +3/−1
- link/modules/asio-standalone/asio/include/asio/ssl/context_base.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/ssl/detail/buffered_handshake_op.hpp +3/−3
- link/modules/asio-standalone/asio/include/asio/ssl/detail/engine.hpp +7/−3
- link/modules/asio-standalone/asio/include/asio/ssl/detail/handshake_op.hpp +3/−3
- link/modules/asio-standalone/asio/include/asio/ssl/detail/impl/engine.ipp +7/−9
- link/modules/asio-standalone/asio/include/asio/ssl/detail/impl/openssl_init.ipp +4/−4
- link/modules/asio-standalone/asio/include/asio/ssl/detail/io.hpp +75/−16
- link/modules/asio-standalone/asio/include/asio/ssl/detail/openssl_init.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/ssl/detail/openssl_types.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/ssl/detail/password_callback.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/ssl/detail/read_op.hpp +3/−3
- link/modules/asio-standalone/asio/include/asio/ssl/detail/shutdown_op.hpp +4/−4
- link/modules/asio-standalone/asio/include/asio/ssl/detail/stream_core.hpp +65/−12
- link/modules/asio-standalone/asio/include/asio/ssl/detail/verify_callback.hpp +2/−2
- link/modules/asio-standalone/asio/include/asio/ssl/detail/write_op.hpp +3/−3
- link/modules/asio-standalone/asio/include/asio/ssl/error.hpp +3/−1
- link/modules/asio-standalone/asio/include/asio/ssl/host_name_verification.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/ssl/impl/context.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/ssl/impl/context.ipp +11/−12
- link/modules/asio-standalone/asio/include/asio/ssl/impl/error.ipp +3/−3
- link/modules/asio-standalone/asio/include/asio/ssl/impl/host_name_verification.ipp +1/−1
- link/modules/asio-standalone/asio/include/asio/ssl/impl/rfc2818_verification.ipp +164/−0
- link/modules/asio-standalone/asio/include/asio/ssl/impl/src.hpp +2/−1
- link/modules/asio-standalone/asio/include/asio/ssl/rfc2818_verification.hpp +98/−0
- link/modules/asio-standalone/asio/include/asio/ssl/stream.hpp +87/−56
- link/modules/asio-standalone/asio/include/asio/ssl/stream_base.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/ssl/verify_context.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/ssl/verify_mode.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/static_thread_pool.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/steady_timer.hpp +6/−1
- link/modules/asio-standalone/asio/include/asio/strand.hpp +118/−91
- link/modules/asio-standalone/asio/include/asio/stream_file.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/streambuf.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/system_context.hpp +4/−4
- link/modules/asio-standalone/asio/include/asio/system_error.hpp +102/−2
- link/modules/asio-standalone/asio/include/asio/system_executor.hpp +62/−62
- link/modules/asio-standalone/asio/include/asio/system_timer.hpp +6/−1
- link/modules/asio-standalone/asio/include/asio/this_coro.hpp +50/−37
- link/modules/asio-standalone/asio/include/asio/thread.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/thread_pool.hpp +277/−173
- link/modules/asio-standalone/asio/include/asio/time_traits.hpp +3/−7
- link/modules/asio-standalone/asio/include/asio/traits/bulk_execute_free.hpp +114/−0
- link/modules/asio-standalone/asio/include/asio/traits/bulk_execute_member.hpp +114/−0
- link/modules/asio-standalone/asio/include/asio/traits/connect_free.hpp +112/−0
- link/modules/asio-standalone/asio/include/asio/traits/connect_member.hpp +112/−0
- link/modules/asio-standalone/asio/include/asio/traits/equality_comparable.hpp +18/−14
- link/modules/asio-standalone/asio/include/asio/traits/execute_free.hpp +108/−0
- link/modules/asio-standalone/asio/include/asio/traits/execute_member.hpp +20/−16
- link/modules/asio-standalone/asio/include/asio/traits/prefer_free.hpp +20/−16
- link/modules/asio-standalone/asio/include/asio/traits/prefer_member.hpp +20/−16
- link/modules/asio-standalone/asio/include/asio/traits/query_free.hpp +20/−16
- link/modules/asio-standalone/asio/include/asio/traits/query_member.hpp +20/−16
- link/modules/asio-standalone/asio/include/asio/traits/query_static_constexpr_member.hpp +22/−15
- link/modules/asio-standalone/asio/include/asio/traits/require_concept_free.hpp +20/−16
- link/modules/asio-standalone/asio/include/asio/traits/require_concept_member.hpp +20/−16
- link/modules/asio-standalone/asio/include/asio/traits/require_free.hpp +20/−16
- link/modules/asio-standalone/asio/include/asio/traits/require_member.hpp +20/−16
- link/modules/asio-standalone/asio/include/asio/traits/schedule_free.hpp +108/−0
- link/modules/asio-standalone/asio/include/asio/traits/schedule_member.hpp +108/−0
- link/modules/asio-standalone/asio/include/asio/traits/set_done_free.hpp +108/−0
- link/modules/asio-standalone/asio/include/asio/traits/set_done_member.hpp +108/−0
- link/modules/asio-standalone/asio/include/asio/traits/set_error_free.hpp +112/−0
- link/modules/asio-standalone/asio/include/asio/traits/set_error_member.hpp +112/−0
- link/modules/asio-standalone/asio/include/asio/traits/set_value_free.hpp +234/−0
- link/modules/asio-standalone/asio/include/asio/traits/set_value_member.hpp +234/−0
- link/modules/asio-standalone/asio/include/asio/traits/start_free.hpp +108/−0
- link/modules/asio-standalone/asio/include/asio/traits/start_member.hpp +108/−0
- link/modules/asio-standalone/asio/include/asio/traits/static_query.hpp +26/−20
- link/modules/asio-standalone/asio/include/asio/traits/static_require.hpp +30/−22
- link/modules/asio-standalone/asio/include/asio/traits/static_require_concept.hpp +30/−22
- link/modules/asio-standalone/asio/include/asio/traits/submit_free.hpp +112/−0
- link/modules/asio-standalone/asio/include/asio/traits/submit_member.hpp +112/−0
- link/modules/asio-standalone/asio/include/asio/ts/buffer.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/ts/executor.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/ts/internet.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/ts/io_context.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/ts/net.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/ts/netfwd.hpp +45/−4
- link/modules/asio-standalone/asio/include/asio/ts/socket.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/ts/timer.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/unyield.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/use_awaitable.hpp +23/−17
- link/modules/asio-standalone/asio/include/asio/use_future.hpp +23/−10
- link/modules/asio-standalone/asio/include/asio/uses_executor.hpp +7/−3
- link/modules/asio-standalone/asio/include/asio/version.hpp +2/−2
- link/modules/asio-standalone/asio/include/asio/wait_traits.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/windows/basic_object_handle.hpp +29/−21
- link/modules/asio-standalone/asio/include/asio/windows/basic_overlapped_handle.hpp +18/−13
- link/modules/asio-standalone/asio/include/asio/windows/basic_random_access_handle.hpp +37/−25
- link/modules/asio-standalone/asio/include/asio/windows/basic_stream_handle.hpp +35/−25
- link/modules/asio-standalone/asio/include/asio/windows/object_handle.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/windows/overlapped_handle.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/windows/overlapped_ptr.hpp +17/−17
- link/modules/asio-standalone/asio/include/asio/windows/random_access_handle.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/windows/stream_handle.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/writable_pipe.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/write.hpp +158/−246
- link/modules/asio-standalone/asio/include/asio/write_at.hpp +60/−96
- link/modules/asio-standalone/asio/include/asio/yield.hpp +1/−1
- link/modules/asio-standalone/asio/src/examples/cpp03/chat/chat_message.hpp +96/−0
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server/connection.hpp +83/−0
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server/connection_manager.hpp +44/−0
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server/header.hpp +28/−0
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server/mime_types.hpp +27/−0
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server/reply.hpp +64/−0
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server/request.hpp +34/−0
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server/request_handler.hpp +46/−0
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server/request_parser.hpp +95/−0
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server/server.hpp +69/−0
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server2/connection.hpp +75/−0
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server2/header.hpp +28/−0
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server2/io_context_pool.hpp +58/−0
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server2/mime_types.hpp +27/−0
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server2/reply.hpp +64/−0
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server2/request.hpp +34/−0
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server2/request_handler.hpp +46/−0
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server2/request_parser.hpp +95/−0
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server2/server.hpp +68/−0
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server3/connection.hpp +78/−0
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server3/header.hpp +28/−0
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server3/mime_types.hpp +27/−0
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server3/reply.hpp +64/−0
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server3/request.hpp +34/−0
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server3/request_handler.hpp +46/−0
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server3/request_parser.hpp +95/−0
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server3/server.hpp +70/−0
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server4/file_handler.hpp +44/−0
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server4/header.hpp +28/−0
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server4/mime_types.hpp +27/−0
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server4/reply.hpp +64/−0
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server4/request.hpp +46/−0
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server4/request_parser.hpp +78/−0
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server4/server.hpp +73/−0
- link/modules/asio-standalone/asio/src/examples/cpp03/icmp/icmp_header.hpp +94/−0
- link/modules/asio-standalone/asio/src/examples/cpp03/icmp/ipv4_header.hpp +102/−0
- link/modules/asio-standalone/asio/src/examples/cpp03/porthopper/protocol.hpp +156/−0
- link/modules/asio-standalone/asio/src/examples/cpp03/serialization/connection.hpp +188/−0
- link/modules/asio-standalone/asio/src/examples/cpp03/serialization/stock.hpp +50/−0
- link/modules/asio-standalone/asio/src/examples/cpp03/services/basic_logger.hpp +77/−0
- link/modules/asio-standalone/asio/src/examples/cpp03/services/logger.hpp +24/−0
- link/modules/asio-standalone/asio/src/examples/cpp03/services/logger_service.hpp +145/−0
- link/modules/asio-standalone/asio/src/examples/cpp03/socks4/socks4.hpp +144/−0
- link/modules/asio-standalone/asio/src/examples/cpp11/chat/chat_message.hpp +2/−3
- link/modules/asio-standalone/asio/src/examples/cpp11/handler_tracking/custom_tracking.hpp +3/−3
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server/connection.hpp +2/−2
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server/connection_manager.hpp +1/−1
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server/header.hpp +1/−1
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server/mime_types.hpp +1/−1
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server/reply.hpp +1/−1
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server/request.hpp +1/−1
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server/request_handler.hpp +1/−1
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server/request_parser.hpp +1/−1
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server/server.hpp +1/−1
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server2/connection.hpp +0/−71
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server2/header.hpp +0/−28
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server2/io_context_pool.hpp +0/−59
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server2/mime_types.hpp +0/−27
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server2/reply.hpp +0/−64
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server2/request.hpp +0/−34
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server2/request_handler.hpp +0/−47
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server2/request_parser.hpp +0/−96
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server2/server.hpp +0/−60
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server3/connection.hpp +0/−71
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server3/header.hpp +0/−28
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server3/mime_types.hpp +0/−27
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server3/reply.hpp +0/−64
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server3/request.hpp +0/−34
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server3/request_handler.hpp +0/−47
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server3/request_parser.hpp +0/−96
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server3/server.hpp +0/−62
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server4/file_handler.hpp +0/−44
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server4/header.hpp +0/−28
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server4/mime_types.hpp +0/−27
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server4/reply.hpp +0/−64
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server4/request.hpp +0/−34
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server4/request_handler.hpp +0/−47
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server4/request_parser.hpp +0/−96
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server4/server.hpp +0/−73
- link/modules/asio-standalone/asio/src/examples/cpp11/icmp/icmp_header.hpp +0/−94
- link/modules/asio-standalone/asio/src/examples/cpp11/icmp/ipv4_header.hpp +0/−102
- link/modules/asio-standalone/asio/src/examples/cpp11/porthopper/protocol.hpp +0/−156
- link/modules/asio-standalone/asio/src/examples/cpp11/serialization/connection.hpp +0/−184
- link/modules/asio-standalone/asio/src/examples/cpp11/serialization/stock.hpp +0/−50
- link/modules/asio-standalone/asio/src/examples/cpp11/services/basic_logger.hpp +0/−78
- link/modules/asio-standalone/asio/src/examples/cpp11/services/logger.hpp +0/−24
- link/modules/asio-standalone/asio/src/examples/cpp11/services/logger_service.hpp +0/−145
- link/modules/asio-standalone/asio/src/examples/cpp11/socks4/socks4.hpp +2/−2
- link/modules/asio-standalone/asio/src/examples/cpp11/type_erasure/line_reader.hpp +4/−4
- link/modules/asio-standalone/asio/src/examples/cpp11/type_erasure/sleep.hpp +1/−1
- link/modules/asio-standalone/asio/src/examples/cpp11/type_erasure/stdin_line_reader.hpp +2/−2
- link/modules/asio-standalone/asio/src/examples/cpp20/type_erasure/line_reader.hpp +1/−1
- link/modules/asio-standalone/asio/src/examples/cpp20/type_erasure/sleep.hpp +1/−1
- link/modules/asio-standalone/asio/src/examples/cpp20/type_erasure/stdin_line_reader.hpp +1/−1
- link/modules/asio-standalone/asio/src/tests/latency/allocator.hpp +1/−1
- link/modules/asio-standalone/asio/src/tests/latency/high_res_clock.hpp +1/−1
- link/modules/asio-standalone/asio/src/tests/performance/handler_allocator.hpp +8/−8
- link/modules/asio-standalone/asio/src/tests/unit/archetypes/async_ops.hpp +317/−362
- link/modules/asio-standalone/asio/src/tests/unit/archetypes/async_result.hpp +12/−6
- link/modules/asio-standalone/asio/src/tests/unit/archetypes/gettable_socket_option.hpp +1/−1
- link/modules/asio-standalone/asio/src/tests/unit/archetypes/io_control_command.hpp +1/−1
- link/modules/asio-standalone/asio/src/tests/unit/archetypes/settable_socket_option.hpp +1/−1
- link/modules/asio-standalone/asio/src/tests/unit/unit_test.hpp +2/−2
- src/hs/Sound/Tidal/Link.hsc +12/−12
- tidal-link.cabal +3/−3
link/examples/linkaudio/AudioEngine.hpp view
@@ -21,22 +21,15 @@ // Make sure to define this before <cmath> is included for Windows #define _USE_MATH_DEFINES-#include <array>+#include <ableton/Link.hpp> #include <atomic>-#include <iostream>-#include <math.h> #include <mutex>-#include <vector> -#include "AudioPlatform.hpp"-#include "LinkAudioRenderer.hpp"- namespace ableton { namespace linkaudio { -template <typename Link> class AudioEngine { public:@@ -51,46 +44,38 @@ bool isStartStopSyncEnabled() const; void setStartStopSyncEnabled(bool enabled); +private: struct EngineData {- double requestedTempo = 0;- bool requestStart = false;- bool requestStop = false;- double quantum = 4;- bool startStopSyncOn = false;- };-- struct EngineDataSignals- {- std::atomic<double> requestedTempo{0};- std::atomic<bool> requestStart{false};- std::atomic<bool> requestStop{false};- std::atomic<double> quantum{4};- std::atomic<bool> startStopSyncOn{false};+ double requestedTempo;+ bool requestStart;+ bool requestStop;+ double quantum;+ bool startStopSyncOn; }; -- void setNumFrames(std::size_t size);+ void setBufferSize(std::size_t size); void setSampleRate(double sampleRate); EngineData pullEngineData();- void renderMetronomeIntoBuffer(typename Link::SessionState sessionState,- double quantum,- std::chrono::microseconds beginHostTime,- std::size_t numSamples);- void audioCallback(std::chrono::microseconds hostTime, std::size_t numSamples);+ void renderMetronomeIntoBuffer(Link::SessionState sessionState,+ double quantum,+ std::chrono::microseconds beginHostTime,+ std::size_t numSamples);+ void audioCallback(const std::chrono::microseconds hostTime, std::size_t numSamples); Link& mLink; double mSampleRate; std::atomic<std::chrono::microseconds> mOutputLatency;- std::array<std::vector<double>, 2> mBuffers;- EngineDataSignals mEngineDataSignals;+ std::vector<double> mBuffer;+ EngineData mSharedEngineData;+ EngineData mLockfreeEngineData; std::chrono::microseconds mTimeAtLastClick; bool mIsPlaying;+ std::mutex mEngineDataGuard; - LinkAudioRenderer<Link> mLinkAudioRenderer;+ friend class AudioPlatform; }; + } // namespace linkaudio } // namespace ableton--#include "AudioEngine.ipp"
− link/examples/linkaudio/AudioEngine.ipp
@@ -1,255 +0,0 @@-/* Copyright 2016, Ableton AG, Berlin. All rights reserved.- *- * This program is free software: you can redistribute it and/or modify- * it under the terms of the GNU General Public License as published by- * the Free Software Foundation, either version 2 of the License, or- * (at your option) any later version.- *- * This program is distributed in the hope that it will be useful,- * but WITHOUT ANY WARRANTY; without even the implied warranty of- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- * GNU General Public License for more details.- *- * You should have received a copy of the GNU General Public License- * along with this program. If not, see <http://www.gnu.org/licenses/>.- *- * If you would like to incorporate Link into a proprietary software application,- * please contact <link-devs@ableton.com>.- */--#pragma once--// Make sure to define this before <cmath> is included for-// Wihttps://github.com/AbletonAppDev/link/pull/664ndows-#ifdef LINK_PLATFORM_WINDOWS-#define _USE_MATH_DEFINES-#endif-#include <cmath>-#include <iostream>--namespace ableton-{-namespace linkaudio-{--template <typename Link>-AudioEngine<Link>::AudioEngine(Link& link)- : mLink(link)- , mSampleRate(44100.)- , mOutputLatency(std::chrono::microseconds{0})- , mTimeAtLastClick{}- , mIsPlaying(false)- , mLinkAudioRenderer(mLink, mSampleRate)-{- if (!mOutputLatency.is_lock_free())- {- std::cout << "WARNING: AudioEngine::mOutputLatency is not lock free!" << std::endl;- }-}--template <typename Link>-void AudioEngine<Link>::startPlaying()-{- mEngineDataSignals.requestStart = true;-}--template <typename Link>-void AudioEngine<Link>::stopPlaying()-{- mEngineDataSignals.requestStop = true;-}--template <typename Link>-bool AudioEngine<Link>::isPlaying() const-{- return mLink.captureAppSessionState().isPlaying();-}--template <typename Link>-double AudioEngine<Link>::beatTime() const-{- const auto sessionState = mLink.captureAppSessionState();- return sessionState.beatAtTime(mLink.clock().micros(), mEngineDataSignals.quantum);-}--template <typename Link>-void AudioEngine<Link>::setTempo(double tempo)-{- mEngineDataSignals.requestedTempo = tempo;-}--template <typename Link>-double AudioEngine<Link>::quantum() const-{- return mEngineDataSignals.quantum;-}--template <typename Link>-void AudioEngine<Link>::setQuantum(double quantum)-{- mEngineDataSignals.quantum = quantum;-}--template <typename Link>-bool AudioEngine<Link>::isStartStopSyncEnabled() const-{- return mLink.isStartStopSyncEnabled();-}--template <typename Link>-void AudioEngine<Link>::setStartStopSyncEnabled(const bool enabled)-{- mLink.enableStartStopSync(enabled);-}--template <typename Link>-void AudioEngine<Link>::setNumFrames(std::size_t size)-{- mBuffers[0] = std::vector<double>(size, 0.);- mBuffers[1] = std::vector<double>(size, 0.);-}--template <typename Link>-void AudioEngine<Link>::setSampleRate(double sampleRate)-{- mSampleRate = sampleRate;-}--template <typename Link>-typename AudioEngine<Link>::EngineData AudioEngine<Link>::pullEngineData()-{- auto engineData = EngineData{};-- engineData.requestedTempo = mEngineDataSignals.requestedTempo.exchange(0.);- engineData.requestStart = mEngineDataSignals.requestStart.exchange(false);- engineData.requestStop = mEngineDataSignals.requestStop.exchange(false);- engineData.startStopSyncOn = mEngineDataSignals.startStopSyncOn.load();- engineData.quantum = mEngineDataSignals.quantum.load();-- return engineData;-}--template <typename Link>-void AudioEngine<Link>::renderMetronomeIntoBuffer(- const typename Link::SessionState sessionState,- const double quantum,- const std::chrono::microseconds beginHostTime,- const std::size_t numSamples)-{- using namespace std::chrono;-- // Metronome frequencies- static const double highTone = 1567.98;- static const double lowTone = 1108.73;- // 100ms click duration- static const auto clickDuration = duration<double>{0.1};-- // The number of microseconds that elapse between samples- const auto microsPerSample = 1e6 / mSampleRate;-- for (std::size_t i = 0; i < numSamples; ++i)- {- double amplitude = 0.;- // Compute the host time for this sample and the last.- const auto hostTime =- beginHostTime + microseconds(llround(static_cast<double>(i) * microsPerSample));- const auto lastSampleHostTime = hostTime - microseconds(llround(microsPerSample));-- // Only make sound for positive beat magnitudes. Negative beat- // magnitudes are count-in beats.- if (sessionState.beatAtTime(hostTime, quantum) >= 0.)- {- // If the phase wraps around between the last sample and the- // current one with respect to a 1 beat quantum, then a click- // should occur.- if (sessionState.phaseAtTime(hostTime, 1)- < sessionState.phaseAtTime(lastSampleHostTime, 1))- {- mTimeAtLastClick = hostTime;- }-- const auto secondsAfterClick =- duration_cast<duration<double>>(hostTime - mTimeAtLastClick);-- // If we're within the click duration of the last beat, render- // the click tone into this sample- if (secondsAfterClick < clickDuration)- {- // If the phase of the last beat with respect to the current- // quantum was zero, then it was at a quantum boundary and we- // want to use the high tone. For other beats within the- // quantum, use the low tone.- const auto freq =- floor(sessionState.phaseAtTime(hostTime, quantum)) == 0 ? highTone : lowTone;-- // Simple cosine synth- amplitude = cos(2 * M_PI * secondsAfterClick.count() * freq)- * (1 - sin(5 * M_PI * secondsAfterClick.count()));- }- }- mBuffers[0][i] = amplitude;- }-}--template <typename Link>-void AudioEngine<Link>::audioCallback(const std::chrono::microseconds hostTime,- const std::size_t numSamples)-{- const auto engineData = pullEngineData();-- auto sessionState = mLink.captureAudioSessionState();-- // Clear the buffer- for (auto& buffer : mBuffers)- {- std::fill(buffer.begin(), buffer.end(), 0);- }-- if (engineData.requestStart)- {- sessionState.setIsPlaying(true, hostTime);- }-- if (engineData.requestStop)- {- sessionState.setIsPlaying(false, hostTime);- }-- if (!mIsPlaying && sessionState.isPlaying())- {- // Reset the timeline so that beat 0 corresponds to the time when transport starts- sessionState.requestBeatAtStartPlayingTime(0, engineData.quantum);- mIsPlaying = true;- }- else if (mIsPlaying && !sessionState.isPlaying())- {- mIsPlaying = false;- }-- if (engineData.requestedTempo > 0)- {- // Set the newly requested tempo from the beginning of this buffer- sessionState.setTempo(engineData.requestedTempo, hostTime);- }-- // Timeline modifications are complete, commit the results- mLink.commitAudioSessionState(sessionState);-- if (mIsPlaying)- {- // As long as the engine is playing, generate metronome clicks in- // the buffer at the appropriate beats.- renderMetronomeIntoBuffer(sessionState, engineData.quantum, hostTime, numSamples);- }-- mLinkAudioRenderer(mBuffers[0].data(),- mBuffers[1].data(),- mBuffers[0].size(),- sessionState,- mSampleRate,- hostTime,- engineData.quantum);-}--} // namespace linkaudio-} // namespace ableton
link/examples/linkaudio/AudioPlatform_Asio.hpp view
@@ -21,6 +21,7 @@ #include "AudioEngine.hpp" +#include <ableton/Link.hpp> #include <ableton/link/HostTimeFilter.hpp> #include "asiosys.h" // Should be included before asio.h@@ -66,13 +67,9 @@ void fatalError(const ASIOError result, const std::string& function); double asioSamplesToDouble(const ASIOSamples& samples); -template <typename Link> ASIOTime* bufferSwitchTimeInfo(ASIOTime* timeInfo, long index, ASIOBool);--template <typename Link> void bufferSwitch(long index, ASIOBool processNow); -template <typename Link> class AudioPlatform { public:@@ -81,8 +78,13 @@ void audioCallback(ASIOTime* timeInfo, long index); - AudioEngine<Link> mEngine;+ AudioEngine mEngine; + // Unfortunately, the ASIO SDK does not allow passing void* user data to callback+ // functions, so we need to keep a singleton instance of the audio engine+ static AudioPlatform* singleton();+ static void setSingleton(AudioPlatform* platform);+ private: void createAsioBuffers(); void initializeDriverInfo();@@ -92,13 +94,10 @@ DriverInfo mDriverInfo; ASIOCallbacks mAsioCallbacks;- link::HostTimeFilter<typename Link::Clock> mHostTimeFilter;+ link::HostTimeFilter<platforms::windows::Clock> mHostTimeFilter; -public:- static AudioPlatform<Link>* _singleton;+ static AudioPlatform* _singleton; }; } // namespace linkaudio } // namespace ableton--#include "AudioPlatform_Asio.ipp"
− link/examples/linkaudio/AudioPlatform_Asio.ipp
@@ -1,319 +0,0 @@-/* Copyright 2016, Ableton AG, Berlin. All rights reserved.- *- * This program is free software: you can redistribute it and/or modify- * it under the terms of the GNU General Public License as published by- * the Free Software Foundation, either version 2 of the License, or- * (at your option) any later version.- *- * This program is distributed in the hope that it will be useful,- * but WITHOUT ANY WARRANTY; without even the implied warranty of- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- * GNU General Public License for more details.- *- * You should have received a copy of the GNU General Public License- * along with this program. If not, see <http://www.gnu.org/licenses/>.- *- * If you would like to incorporate Link into a proprietary software application,- * please contact <link-devs@ableton.com>.- */--#pragma once--namespace ableton-{-namespace linkaudio-{--static void* SINGLETON = nullptr;--void fatalError(const ASIOError result, const std::string& function)-{- std::cerr << "Call to ASIO function " << function << " failed";- if (result != ASE_OK)- {- std::cerr << " (ASIO error code " << result << ")";- }- std::cerr << std::endl;- std::terminate();-}--double asioSamplesToDouble(const ASIOSamples& samples)-{- return samples.lo + samples.hi * std::pow(2, 32);-}--// ASIO processing callbacks-template <typename Link>-ASIOTime* bufferSwitchTimeInfo(ASIOTime* timeInfo, long index, ASIOBool)-{- AudioPlatform<Link>* platform =- static_cast<AudioPlatform<Link>*>(SINGLETON); // AudioPlatform<Link>::_singleton;- if (platform)- {- platform->audioCallback(timeInfo, index);- }- return nullptr;-}--template <typename Link>-void bufferSwitch(long index, ASIOBool processNow)-{- ASIOTime timeInfo{};- ASIOError result = ASIOGetSamplePosition(- &timeInfo.timeInfo.samplePosition, &timeInfo.timeInfo.systemTime);- if (result != ASE_OK)- {- std::cerr << "ASIOGetSamplePosition failed with ASIO error: " << result << std::endl;- }- else- {- timeInfo.timeInfo.flags = kSystemTimeValid | kSamplePositionValid;- }-- bufferSwitchTimeInfo<Link>(&timeInfo, index, processNow);-}--template <typename Link>-AudioPlatform<Link>::AudioPlatform(Link& link)- : mEngine(link)-{- initialize();- mEngine.setNumFrames(mDriverInfo.preferredSize);- mEngine.setSampleRate(mDriverInfo.sampleRate);- SINGLETON = this;- start();-}--template <typename Link>-AudioPlatform<Link>::~AudioPlatform()-{- stop();- ASIODisposeBuffers();- ASIOExit();- if (asioDrivers != nullptr)- {- asioDrivers->removeCurrentDriver();- }-- SINGLETON = nullptr;-}--template <typename Link>-void AudioPlatform<Link>::audioCallback(ASIOTime* timeInfo, long index)-{- auto hostTime = std::chrono::microseconds(0);- if (timeInfo->timeInfo.flags & kSystemTimeValid)- {- hostTime = mHostTimeFilter.sampleTimeToHostTime(- asioSamplesToDouble(timeInfo->timeInfo.samplePosition));- }-- const auto bufferBeginAtOutput = hostTime + mEngine.mOutputLatency.load();--- ASIOBufferInfo* bufferInfos = mDriverInfo.bufferInfos;- const long numSamples = mDriverInfo.preferredSize;- const long numChannels = mDriverInfo.numBuffers;- const double maxAmp = std::numeric_limits<int>::max();-- mEngine.audioCallback(bufferBeginAtOutput, numSamples);-- for (long i = 0; i < numSamples; ++i)- {- for (long j = 0; j < numChannels; ++j)- {- int* buffer = static_cast<int*>(bufferInfos[j].buffers[index]);- buffer[i] = static_cast<int>(mEngine.mBuffers[j][i] * maxAmp);- }- }-- if (mDriverInfo.outputReady)- {- ASIOOutputReady();- }-}--template <typename Link>-void AudioPlatform<Link>::createAsioBuffers()-{- DriverInfo& driverInfo = mDriverInfo;- ASIOBufferInfo* bufferInfo = driverInfo.bufferInfos;- driverInfo.numBuffers = 0;-- // Prepare input channels. Though this is not necessarily required, the opened input- // channels will not work.- int numInputBuffers;- if (driverInfo.inputChannels > LINK_ASIO_INPUT_CHANNELS)- {- numInputBuffers = LINK_ASIO_INPUT_CHANNELS;- }- else- {- numInputBuffers = driverInfo.inputChannels;- }-- for (long i = 0; i < numInputBuffers; ++i, ++bufferInfo)- {- bufferInfo->isInput = ASIOTrue;- bufferInfo->channelNum = i;- bufferInfo->buffers[0] = bufferInfo->buffers[1] = nullptr;- }-- // Prepare output channels- int numOutputBuffers;- if (driverInfo.outputChannels > LINK_ASIO_OUTPUT_CHANNELS)- {- numOutputBuffers = LINK_ASIO_OUTPUT_CHANNELS;- }- else- {- numOutputBuffers = driverInfo.outputChannels;- }-- for (long i = 0; i < numOutputBuffers; i++, bufferInfo++)- {- bufferInfo->isInput = ASIOFalse;- bufferInfo->channelNum = i;- bufferInfo->buffers[0] = bufferInfo->buffers[1] = nullptr;- }-- driverInfo.numBuffers = numInputBuffers + numOutputBuffers;- ASIOError result = ASIOCreateBuffers(driverInfo.bufferInfos,- driverInfo.numBuffers,- driverInfo.preferredSize,- &(mAsioCallbacks));- if (result != ASE_OK)- {- fatalError(result, "ASIOCreateBuffers");- }-- // Now get all buffer details, sample word length, name, word clock group and latency- for (long i = 0; i < driverInfo.numBuffers; ++i)- {- driverInfo.channelInfos[i].channel = driverInfo.bufferInfos[i].channelNum;- driverInfo.channelInfos[i].isInput = driverInfo.bufferInfos[i].isInput;-- result = ASIOGetChannelInfo(&driverInfo.channelInfos[i]);- if (result != ASE_OK)- {- fatalError(result, "ASIOGetChannelInfo");- }-- std::clog << "ASIOGetChannelInfo successful, type: "- << (driverInfo.bufferInfos[i].isInput ? "input" : "output")- << ", channel: " << i- << ", sample type: " << driverInfo.channelInfos[i].type << std::endl;-- if (driverInfo.channelInfos[i].type != ASIOSTInt32LSB)- {- fatalError(ASE_OK, "Unsupported sample type!");- }- }-- long inputLatency, outputLatency;- result = ASIOGetLatencies(&inputLatency, &outputLatency);- if (result != ASE_OK)- {- fatalError(result, "ASIOGetLatencies");- }- std::clog << "Driver input latency: " << inputLatency << "usec"- << ", output latency: " << outputLatency << "usec" << std::endl;-- const double bufferSize = driverInfo.preferredSize / driverInfo.sampleRate;- auto outputLatencyMicros =- std::chrono::microseconds(llround(outputLatency / driverInfo.sampleRate));- outputLatencyMicros += std::chrono::microseconds(llround(1.0e6 * bufferSize));-- mEngine.mOutputLatency.store(outputLatencyMicros);-- std::clog << "Total latency: " << outputLatencyMicros.count() << "usec" << std::endl;-}--template <typename Link>-void AudioPlatform<Link>::initializeDriverInfo()-{- ASIOError result =- ASIOGetChannels(&mDriverInfo.inputChannels, &mDriverInfo.outputChannels);- if (result != ASE_OK)- {- fatalError(result, "ASIOGetChannels");- }- std::clog << "ASIOGetChannels succeeded, inputs:" << mDriverInfo.inputChannels- << ", outputs: " << mDriverInfo.outputChannels << std::endl;-- long minSize, maxSize, granularity;- result =- ASIOGetBufferSize(&minSize, &maxSize, &mDriverInfo.preferredSize, &granularity);- if (result != ASE_OK)- {- fatalError(result, "ASIOGetBufferSize");- }- std::clog << "ASIOGetBufferSize succeeded, min: " << minSize << ", max: " << maxSize- << ", preferred: " << mDriverInfo.preferredSize- << ", granularity: " << granularity << std::endl;-- result = ASIOGetSampleRate(&mDriverInfo.sampleRate);- if (result != ASE_OK)- {- fatalError(result, "ASIOGetSampleRate");- }- std::clog << "ASIOGetSampleRate succeeded, sampleRate: " << mDriverInfo.sampleRate- << "Hz" << std::endl;-- // Check wether the driver requires the ASIOOutputReady() optimization, which can be- // used by the driver to reduce output latency by one block- mDriverInfo.outputReady = (ASIOOutputReady() == ASE_OK);- std::clog << "ASIOOutputReady optimization is "- << (mDriverInfo.outputReady ? "enabled" : "disabled") << std::endl;-}--template <typename Link>-void AudioPlatform<Link>::initialize()-{- if (!loadAsioDriver(LINK_ASIO_DRIVER_NAME))- {- std::cerr << "Failed opening ASIO driver for device named '" << LINK_ASIO_DRIVER_NAME- << "', is the driver installed?" << std::endl;- std::terminate();- }-- ASIOError result = ASIOInit(&mDriverInfo.driverInfo);- if (result != ASE_OK)- {- fatalError(result, "ASIOInit");- }-- std::clog << "ASIOInit succeeded, asioVersion: " << mDriverInfo.driverInfo.asioVersion- << ", driverVersion: " << mDriverInfo.driverInfo.driverVersion- << ", name: " << mDriverInfo.driverInfo.name << std::endl;-- initializeDriverInfo();-- ASIOCallbacks* callbacks = &(mAsioCallbacks);- callbacks->bufferSwitch = &bufferSwitch<Link>;- callbacks->bufferSwitchTimeInfo = &bufferSwitchTimeInfo<Link>;- createAsioBuffers();-}--template <typename Link>-void AudioPlatform<Link>::start()-{- ASIOError result = ASIOStart();- if (result != ASE_OK)- {- fatalError(result, "ASIOStart");- }-}--template <typename Link>-void AudioPlatform<Link>::stop()-{- ASIOError result = ASIOStop();- if (result != ASE_OK)- {- fatalError(result, "ASIOStop");- }-}--} // namespace linkaudio-} // namespace ableton
link/examples/linkaudio/AudioPlatform_CoreAudio.hpp view
@@ -27,27 +27,20 @@ namespace linkaudio { -template <typename Link> class AudioPlatform { public: AudioPlatform(Link& link); ~AudioPlatform();- AudioEngine<Link> mEngine;+ AudioEngine mEngine; private: static OSStatus audioCallback(void* inRefCon,- AudioUnitRenderActionFlags*,- const AudioTimeStamp* inTimeStamp,- UInt32,- UInt32 inNumberFrames,- AudioBufferList* ioData);-- static void streamFormatCallback(void* inRefCon,- AudioUnit inUnit,- AudioUnitPropertyID inID,- AudioUnitScope inScope,- AudioUnitElement inElement);+ AudioUnitRenderActionFlags*,+ const AudioTimeStamp* inTimeStamp,+ UInt32,+ UInt32 inNumberFrames,+ AudioBufferList* ioData); void initialize(); void uninitialize();@@ -59,5 +52,3 @@ } // namespace linkaudio } // namespace ableton--#include "AudioPlatform_CoreAudio.ipp"
− link/examples/linkaudio/AudioPlatform_CoreAudio.ipp
@@ -1,294 +0,0 @@-/* Copyright 2016, Ableton AG, Berlin. All rights reserved.- *- * This program is free software: you can redistribute it and/or modify- * it under the terms of the GNU General Public License as published by- * the Free Software Foundation, either version 2 of the License, or- * (at your option) any later version.- *- * This program is distributed in the hope that it will be useful,- * but WITHOUT ANY WARRANTY; without even the implied warranty of- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- * GNU General Public License for more details.- *- * You should have received a copy of the GNU General Public License- * along with this program. If not, see <http://www.gnu.org/licenses/>.- *- * If you would like to incorporate Link into a proprietary software application,- * please contact <link-devs@ableton.com>.- */--#include "AudioPlatform_CoreAudio.hpp"-#include <chrono>-#include <iostream>-#include <mach/mach_time.h>--namespace ableton-{-namespace linkaudio-{--template <typename Link>-AudioPlatform<Link>::AudioPlatform(Link& link)- : mEngine(link)-{- initialize();- start();-}--template <typename Link>-AudioPlatform<Link>::~AudioPlatform()-{- stop();- uninitialize();-}--template <typename Link>-OSStatus AudioPlatform<Link>::audioCallback(void* inRefCon,- AudioUnitRenderActionFlags*,- const AudioTimeStamp* inTimeStamp,- UInt32,- UInt32 inNumberFrames,- AudioBufferList* ioData)-{- auto engine = static_cast<AudioEngine<Link>*>(inRefCon);-- const auto bufferBeginAtOutput =- engine->mLink.clock().ticksToMicros(inTimeStamp->mHostTime)- + engine->mOutputLatency.load();-- engine->audioCallback(bufferBeginAtOutput, inNumberFrames);-- for (std::size_t i = 0; i < inNumberFrames; ++i)- {- for (UInt32 j = 0; j < ioData->mNumberBuffers; ++j)- {- auto bufData = static_cast<SInt16*>(ioData->mBuffers[j].mData);- bufData[i] = static_cast<SInt16>(32761. * engine->mBuffers[j][i]);- }- }-- return noErr;-}--template <typename Link>-void AudioPlatform<Link>::streamFormatCallback(void* inRefCon,- AudioUnit inUnit,- AudioUnitPropertyID inID,- AudioUnitScope inScope,- AudioUnitElement inElement)-{-#pragma unused(inID)- if (inScope == kAudioUnitScope_Output && inElement == 0)- {- AudioStreamBasicDescription asbd;- UInt32 dataSize = sizeof(asbd);- OSStatus result = AudioUnitGetProperty(inUnit,- kAudioUnitProperty_StreamFormat,- kAudioUnitScope_Output,- 0,- &asbd,- &dataSize);- if (result)- {- std::cerr << "Could not get Audio Unit stream format. " << result << std::endl;- }-- auto pPlatform = static_cast<AudioPlatform<Link>*>(inRefCon);- const Float64 oldSampleRate = pPlatform->mEngine.mSampleRate;- if (fabs(oldSampleRate - asbd.mSampleRate) > 1.)- {- std::cout << "CORE AUDIO STREAM FORMAT CHANGED: " << asbd.mSampleRate << std::endl;- pPlatform->stop();- pPlatform->uninitialize();- pPlatform->mEngine.setSampleRate(asbd.mSampleRate);- pPlatform->initialize();- pPlatform->start();- }- }-}--template <typename Link>-void AudioPlatform<Link>::initialize()-{- AudioComponentDescription cd = {};- cd.componentManufacturer = kAudioUnitManufacturer_Apple;- cd.componentFlags = 0;- cd.componentFlagsMask = 0;- cd.componentType = kAudioUnitType_Output;- cd.componentSubType = kAudioUnitSubType_DefaultOutput;-- AudioComponent component = AudioComponentFindNext(nullptr, &cd);- OSStatus result = AudioComponentInstanceNew(component, &mIoUnit);- if (result)- {- std::cerr << "Could not get Audio Unit. " << result << std::endl;- std::terminate();- }-- UInt32 size = sizeof(mEngine.mSampleRate);- result = AudioUnitGetProperty(mIoUnit,- kAudioUnitProperty_SampleRate,- kAudioUnitScope_Output,- 0,- &mEngine.mSampleRate,- &size);- if (result)- {- std::cerr << "Could not get sample rate. " << result << std::endl;- std::terminate();- }- std::clog << "SAMPLE RATE: " << mEngine.mSampleRate << std::endl;-- AudioStreamBasicDescription asbd = {};- asbd.mFormatID = kAudioFormatLinearPCM;- asbd.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked- | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsNonInterleaved;- asbd.mChannelsPerFrame = 2;- asbd.mBytesPerPacket = sizeof(SInt16);- asbd.mFramesPerPacket = 1;- asbd.mBytesPerFrame = sizeof(SInt16);- asbd.mBitsPerChannel = 8 * sizeof(SInt16);- asbd.mSampleRate = mEngine.mSampleRate;-- result = AudioUnitSetProperty(mIoUnit,- kAudioUnitProperty_StreamFormat,- kAudioUnitScope_Input,- 0,- &asbd,- sizeof(asbd));- if (result)- {- std::cerr << "Could not set stream format. " << result << std::endl;- }-- result = AudioUnitAddPropertyListener(- mIoUnit, kAudioUnitProperty_StreamFormat, streamFormatCallback, this);- if (result)- {- std::cerr << "Could not add listener to stream format changes. " << result- << std::endl;- }-- char deviceName[512];- size = sizeof(deviceName);- result = AudioUnitGetProperty(mIoUnit,- kAudioDevicePropertyDeviceName,- kAudioUnitScope_Global,- 0,- &deviceName,- &size);- if (result)- {- std::cerr << "Could not get device name. " << result << std::endl;- std::terminate();- }- std::clog << "DEVICE NAME: " << deviceName << std::endl;-- UInt32 numFrames = 512;- size = sizeof(numFrames);- result = AudioUnitSetProperty(mIoUnit,- kAudioDevicePropertyBufferFrameSize,- kAudioUnitScope_Global,- 0,- &numFrames,- size);- if (result)- {- std::cerr << "Could not set num frames. " << result << std::endl;- std::terminate();- }- mEngine.setNumFrames(numFrames);-- UInt32 propertyResult = 0;- size = sizeof(propertyResult);- result = AudioUnitGetProperty(mIoUnit,- kAudioDevicePropertyBufferFrameSize,- kAudioUnitScope_Global,- 0,- &propertyResult,- &size);- if (result)- {- std::cerr << "Could not get buffer size. " << result << std::endl;- std::terminate();- }- std::clog << "BUFFER SIZE: " << propertyResult << " samples, "- << propertyResult / mEngine.mSampleRate * 1e3 << " ms." << std::endl;-- // the buffer, stream and safety-offset latencies are part of inTimeStamp->mHostTime- // within the audio callback.- UInt32 deviceLatency = 0;- size = sizeof(deviceLatency);- result = AudioUnitGetProperty(mIoUnit,- kAudioDevicePropertyLatency,- kAudioUnitScope_Output,- 0,- &deviceLatency,- &size);- if (result)- {- std::cerr << "Could not get output device latency. " << result << std::endl;- std::terminate();- }- std::clog << "OUTPUT DEVICE LATENCY: " << deviceLatency << " samples, "- << deviceLatency / mEngine.mSampleRate * 1e3 << " ms." << std::endl;-- using namespace std::chrono;- const auto latency = static_cast<double>(deviceLatency) / mEngine.mSampleRate;- mEngine.mOutputLatency.store(duration_cast<microseconds>(duration<double>{latency}));-- AURenderCallbackStruct ioRemoteInput;- ioRemoteInput.inputProc = audioCallback;- ioRemoteInput.inputProcRefCon = &mEngine;-- result = AudioUnitSetProperty(mIoUnit,- kAudioUnitProperty_SetRenderCallback,- kAudioUnitScope_Input,- 0,- &ioRemoteInput,- sizeof(ioRemoteInput));- if (result)- {- std::cerr << "Could not set render callback. " << result << std::endl;- }-- result = AudioUnitInitialize(mIoUnit);- if (result)- {- std::cerr << "Could not initialize audio unit. " << result << std::endl;- }-}--template <typename Link>-void AudioPlatform<Link>::uninitialize()-{- OSStatus result = AudioUnitUninitialize(mIoUnit);- if (result)- {- std::cerr << "Could not uninitialize Audio Unit. " << result << std::endl;- }-}--template <typename Link>-void AudioPlatform<Link>::start()-{- OSStatus result = AudioOutputUnitStart(mIoUnit);- if (result)- {- std::cerr << "Could not start Audio Unit. " << result << std::endl;- std::terminate();- }-}--template <typename Link>-void AudioPlatform<Link>::stop()-{- OSStatus result = AudioOutputUnitStop(mIoUnit);- if (result)- {- std::cerr << "Could not stop Audio Unit. " << result << std::endl;- }-}--} // namespace linkaudio-} // namespace ableton
link/examples/linkaudio/AudioPlatform_Dummy.hpp view
@@ -19,14 +19,13 @@ #pragma once -#include <chrono>+#include <ableton/Link.hpp> namespace ableton { namespace linkaudio { -template <typename Link> class AudioPlatform { class AudioEngine@@ -52,7 +51,10 @@ mLink.commitAppSessionState(sessionState); } - bool isPlaying() const { return mLink.captureAppSessionState().isPlaying(); }+ bool isPlaying() const+ {+ return mLink.captureAppSessionState().isPlaying();+ } double beatTime() const {@@ -67,16 +69,31 @@ mLink.commitAppSessionState(sessionState); } - double quantum() const { return mQuantum; }+ double quantum() const+ {+ return mQuantum;+ } - void setQuantum(double quantum) { mQuantum = quantum; }+ void setQuantum(double quantum)+ {+ mQuantum = quantum;+ } - bool isStartStopSyncEnabled() const { return mLink.isStartStopSyncEnabled(); }+ bool isStartStopSyncEnabled() const+ {+ return mLink.isStartStopSyncEnabled();+ } - void setStartStopSyncEnabled(bool enabled) { mLink.enableStartStopSync(enabled); }+ void setStartStopSyncEnabled(bool enabled)+ {+ mLink.enableStartStopSync(enabled);+ } private:- std::chrono::microseconds now() const { return mLink.clock().micros(); }+ std::chrono::microseconds now() const+ {+ return mLink.clock().micros();+ } Link& mLink; double mQuantum;
link/examples/linkaudio/AudioPlatform_Jack.hpp view
@@ -21,6 +21,7 @@ #include "AudioEngine.hpp" #include <ableton/link/HostTimeFilter.hpp>+#include <ableton/platforms/Config.hpp> #include <jack/jack.h> namespace ableton@@ -28,14 +29,13 @@ namespace linkaudio { -template <typename Link> class AudioPlatform { public: AudioPlatform(Link& link); ~AudioPlatform(); - AudioEngine<Link> mEngine;+ AudioEngine mEngine; private: static int audioCallback(jack_nframes_t nframes, void* pvUserData);@@ -48,7 +48,7 @@ void start(); void stop(); - link::HostTimeFilter<typename Link::Clock> mHostTimeFilter;+ link::HostTimeFilter<link::platform::Clock> mHostTimeFilter; double mSampleTime; jack_client_t* mpJackClient; jack_port_t** mpJackPorts;@@ -56,5 +56,3 @@ } // namespace linkaudio } // namespace ableton--#include "AudioPlatform_Jack.ipp"
− link/examples/linkaudio/AudioPlatform_Jack.ipp
@@ -1,221 +0,0 @@-/* Copyright 2016, Ableton AG, Berlin. All rights reserved.- *- * This program is free software: you can redistribute it and/or modify- * it under the terms of the GNU General Public License as published by- * the Free Software Foundation, either version 2 of the License, or- * (at your option) any later version.- *- * This program is distributed in the hope that it will be useful,- * but WITHOUT ANY WARRANTY; without even the implied warranty of- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- * GNU General Public License for more details.- *- * You should have received a copy of the GNU General Public License- * along with this program. If not, see <http://www.gnu.org/licenses/>.- *- * If you would like to incorporate Link into a proprietary software application,- * please contact <link-devs@ableton.com>.- */--#include <chrono>-#include <iostream>-#include <string>--namespace ableton-{-namespace linkaudio-{--template <typename Link>-AudioPlatform<Link>::AudioPlatform(Link& link)- : mEngine(link)- , mSampleTime(0.)- , mpJackClient(nullptr)- , mpJackPorts(nullptr)-{- initialize();- start();-}--template <typename Link>-AudioPlatform<Link>::~AudioPlatform<Link>()-{- stop();- uninitialize();-}--template <typename Link>-int AudioPlatform<Link>::audioCallback(jack_nframes_t nframes, void* pvUserData)-{- auto pAudioPlatform = static_cast<AudioPlatform*>(pvUserData);- return pAudioPlatform->audioCallback(nframes);-}--template <typename Link>-void AudioPlatform<Link>::latencyCallback(jack_latency_callback_mode_t, void* pvUserData)-{- auto pAudioPlatform = static_cast<AudioPlatform*>(pvUserData);- pAudioPlatform->updateLatency();-}--template <typename Link>-void AudioPlatform<Link>::updateLatency()-{- jack_latency_range_t latencyRange;- jack_port_get_latency_range(mpJackPorts[0], JackPlaybackLatency, &latencyRange);- mEngine.mOutputLatency.store(- std::chrono::microseconds(llround(1.0e6 * latencyRange.max / mEngine.mSampleRate)));-}--template <typename Link>-int AudioPlatform<Link>::audioCallback(jack_nframes_t nframes)-{- using namespace std::chrono;- AudioEngine<Link>& engine = mEngine;-- const auto hostTime = mHostTimeFilter.sampleTimeToHostTime(mSampleTime);-- mSampleTime += nframes;-- const auto bufferBeginAtOutput = hostTime + engine.mOutputLatency.load();-- engine.audioCallback(bufferBeginAtOutput, nframes);-- for (std::size_t k = 0; k < 2; ++k)- {- auto buffer = static_cast<float*>(jack_port_get_buffer(mpJackPorts[k], nframes));- for (std::size_t i = 0; i < nframes; ++i)- {- buffer[i] = static_cast<float>(engine.mBuffers[k][i]);- }- }-- return 0;-}--template <typename Link>-void AudioPlatform<Link>::initialize()-{- jack_status_t status = JackFailure;- mpJackClient = jack_client_open("LinkHut", JackNullOption, &status);- if (mpJackClient == nullptr)- {- std::cerr << "Could not initialize Audio Engine. ";- std::cerr << "JACK: " << std::endl;- if (status & JackFailure)- {- std::cerr << "Overall operation failed." << std::endl;- }- if (status & JackInvalidOption)- {- std::cerr << "Invalid or unsupported option." << std::endl;- }- if (status & JackNameNotUnique)- {- std::cerr << "Client name not unique." << std::endl;- }- if (status & JackServerStarted)- {- std::cerr << "Server is started." << std::endl;- }- if (status & JackServerFailed)- {- std::cerr << "Unable to connect to server." << std::endl;- }- if (status & JackServerError)- {- std::cerr << "Server communication error." << std::endl;- }- if (status & JackNoSuchClient)- {- std::cerr << "Client does not exist." << std::endl;- }- if (status & JackLoadFailure)- {- std::cerr << "Unable to load internal client." << std::endl;- }- if (status & JackInitFailure)- {- std::cerr << "Unable to initialize client." << std::endl;- }- if (status & JackShmFailure)- {- std::cerr << "Unable to access shared memory." << std::endl;- }- if (status & JackVersionError)- {- std::cerr << "Client protocol version mismatch." << std::endl;- }- std::cerr << std::endl;- std::terminate();- }-- const double bufferSize = jack_get_buffer_size(mpJackClient);- const double sampleRate = jack_get_sample_rate(mpJackClient);- mEngine.setNumFrames(static_cast<std::size_t>(bufferSize));- mEngine.setSampleRate(sampleRate);-- jack_set_latency_callback(mpJackClient, AudioPlatform::latencyCallback, this);-- mpJackPorts = new jack_port_t*[2];-- for (int k = 0; k < 2; ++k)- {- const std::string port_name = "out_" + std::to_string(k + 1);- mpJackPorts[k] = jack_port_register(- mpJackClient, port_name.c_str(), JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);- if (mpJackPorts[k] == nullptr)- {- std::cerr << "Could not get Audio Device. " << std::endl;- jack_client_close(mpJackClient);- std::terminate();- }- }-- jack_set_process_callback(mpJackClient, AudioPlatform::audioCallback, this);-}--template <typename Link>-void AudioPlatform<Link>::uninitialize()-{- for (int k = 0; k < 2; ++k)- {- jack_port_unregister(mpJackClient, mpJackPorts[k]);- mpJackPorts[k] = nullptr;- }- delete[] mpJackPorts;- mpJackPorts = nullptr;-- jack_client_close(mpJackClient);- mpJackClient = nullptr;-}--template <typename Link>-void AudioPlatform<Link>::start()-{- jack_activate(mpJackClient);-- const char** playback_ports = jack_get_ports(- mpJackClient, nullptr, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput | JackPortIsPhysical);-- if (playback_ports)- {- const std::string client_name = jack_get_client_name(mpJackClient);- for (int k = 0; k < 2; ++k)- {- const std::string port_name = "out_" + std::to_string(k + 1);- const std::string client_port = client_name + ':' + port_name;- jack_connect(mpJackClient, client_port.c_str(), playback_ports[k]);- }- jack_free(playback_ports);- }-}--template <typename Link>-void AudioPlatform<Link>::stop()-{- jack_deactivate(mpJackClient);-}--} // namespace linkaudio-} // namespace ableton
link/examples/linkaudio/AudioPlatform_Portaudio.hpp view
@@ -21,6 +21,7 @@ #include "AudioEngine.hpp" #include <ableton/link/HostTimeFilter.hpp>+#include <ableton/platforms/Config.hpp> #include <portaudio.h> namespace ableton@@ -28,34 +29,31 @@ namespace linkaudio { -template <typename Link> class AudioPlatform { public: AudioPlatform(Link& link); ~AudioPlatform(); - AudioEngine<Link> mEngine;+ AudioEngine mEngine; private: static int audioCallback(const void* inputBuffer,- void* outputBuffer,- unsigned long inNumFrames,- const PaStreamCallbackTimeInfo* timeInfo,- PaStreamCallbackFlags statusFlags,- void* userData);+ void* outputBuffer,+ unsigned long inNumFrames,+ const PaStreamCallbackTimeInfo* timeInfo,+ PaStreamCallbackFlags statusFlags,+ void* userData); void initialize(); void uninitialize(); void start(); void stop(); - link::HostTimeFilter<typename Link::Clock> mHostTimeFilter;+ link::HostTimeFilter<link::platform::Clock> mHostTimeFilter; double mSampleTime; PaStream* pStream; }; } // namespace linkaudio } // namespace ableton--#include "AudioPlatform_Portaudio.ipp"
− link/examples/linkaudio/AudioPlatform_Portaudio.ipp
@@ -1,168 +0,0 @@-/* Copyright 2016, Ableton AG, Berlin. All rights reserved.- *- * This program is free software: you can redistribute it and/or modify- * it under the terms of the GNU General Public License as published by- * the Free Software Foundation, either version 2 of the License, or- * (at your option) any later version.- *- * This program is distributed in the hope that it will be useful,- * but WITHOUT ANY WARRANTY; without even the implied warranty of- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- * GNU General Public License for more details.- *- * You should have received a copy of the GNU General Public License- * along with this program. If not, see <http://www.gnu.org/licenses/>.- *- * If you would like to incorporate Link into a proprietary software application,- * please contact <link-devs@ableton.com>.- */--#include <chrono>-#include <iostream>--namespace ableton-{-namespace linkaudio-{--template <typename Link>-AudioPlatform<Link>::AudioPlatform(Link& link)- : mEngine(link)- , mSampleTime(0.)-{- mEngine.setSampleRate(44100.);- mEngine.setNumFrames(512);- initialize();- start();-}--template <typename Link>-AudioPlatform<Link>::~AudioPlatform()-{- stop();- uninitialize();-}--template <typename Link>-int AudioPlatform<Link>::audioCallback(const void* /*inputBuffer*/,- void* outputBuffer,- unsigned long inNumFrames,- const PaStreamCallbackTimeInfo* /*timeInfo*/,- PaStreamCallbackFlags /*statusFlags*/,- void* userData)-{- using namespace std::chrono;- float* buffer = static_cast<float*>(outputBuffer);- AudioPlatform& platform = *static_cast<AudioPlatform*>(userData);- AudioEngine<Link>& engine = platform.mEngine;-- const auto hostTime =- platform.mHostTimeFilter.sampleTimeToHostTime(platform.mSampleTime);-- platform.mSampleTime += static_cast<double>(inNumFrames);-- const auto bufferBeginAtOutput = hostTime + engine.mOutputLatency.load();-- engine.audioCallback(bufferBeginAtOutput, inNumFrames);-- for (unsigned long i = 0; i < inNumFrames; ++i)- {- buffer[i * 2] = static_cast<float>(engine.mBuffers[0][i]);- buffer[i * 2 + 1] = static_cast<float>(engine.mBuffers[1][i]);- }-- return paContinue;-}--template <typename Link>-void AudioPlatform<Link>::initialize()-{- PaError result = Pa_Initialize();- if (result)- {- std::cerr << "Could not initialize Audio Engine. " << result << std::endl;- std::terminate();- }-- PaStreamParameters outputParameters;- outputParameters.device = Pa_GetDefaultOutputDevice();- if (outputParameters.device == paNoDevice)- {- std::cerr << "Could not get Audio Device. " << std::endl;- std::terminate();- }-- outputParameters.channelCount = 2;- outputParameters.sampleFormat = paFloat32;- outputParameters.suggestedLatency =- Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency;- outputParameters.hostApiSpecificStreamInfo = nullptr;- mEngine.mOutputLatency.store(- std::chrono::microseconds(llround(outputParameters.suggestedLatency * 1.0e6)));- result = Pa_OpenStream(&pStream,- nullptr,- &outputParameters,- mEngine.mSampleRate,- mEngine.mBuffers[0].size(),- paClipOff,- &audioCallback,- this);-- if (result)- {- std::cerr << "Could not open stream. " << result << std::endl;- std::terminate();- }-- if (!pStream)- {- std::cerr << "No valid audio stream." << std::endl;- std::terminate();- }-}--template <typename Link>-void AudioPlatform<Link>::uninitialize()-{- PaError result = Pa_CloseStream(pStream);- if (result)- {- std::cerr << "Could not close Audio Stream. " << result << std::endl;- }- Pa_Terminate();-- if (!pStream)- {- std::cerr << "No valid audio stream." << std::endl;- std::terminate();- }-}--template <typename Link>-void AudioPlatform<Link>::start()-{- PaError result = Pa_StartStream(pStream);- if (result)- {- std::cerr << "Could not start Audio Stream. " << result << std::endl;- }-}--template <typename Link>-void AudioPlatform<Link>::stop()-{- if (pStream == nullptr)- {- return;- }-- PaError result = Pa_StopStream(pStream);- if (result)- {- std::cerr << "Could not stop Audio Stream. " << result << std::endl;- std::terminate();- }-}--} // namespace linkaudio-} // namespace ableton
link/examples/linkaudio/AudioPlatform_Wasapi.hpp view
@@ -38,10 +38,8 @@ // and then terminate the application. void fatalError(HRESULT result, LPCTSTR context); -template <typename Link> DWORD renderAudioRunloop(LPVOID); -template <typename Link> class AudioPlatform { public:@@ -50,7 +48,7 @@ DWORD audioRunloop(); - AudioEngine<Link> mEngine;+ AudioEngine mEngine; private: UINT32 bufferSize();@@ -58,7 +56,7 @@ void initialize(); void start(); - link::HostTimeFilter<typename Link::Clock> mHostTimeFilter;+ link::HostTimeFilter<platforms::windows::Clock> mHostTimeFilter; double mSampleTime; IMMDevice* mDevice;@@ -72,5 +70,3 @@ } // namespace linkaudio } // namespace ableton--#include "AudioPlatform_Wasapi.ipp"
− link/examples/linkaudio/AudioPlatform_Wasapi.ipp
@@ -1,344 +0,0 @@-/* Copyright 2016, Ableton AG, Berlin. All rights reserved.- *- * This program is free software: you can redistribute it and/or modify- * it under the terms of the GNU General Public License as published by- * the Free Software Foundation, either version 2 of the License, or- * (at your option) any later version.- *- * This program is distributed in the hope that it will be useful,- * but WITHOUT ANY WARRANTY; without even the implied warranty of- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- * GNU General Public License for more details.- *- * You should have received a copy of the GNU General Public License- * along with this program. If not, see <http://www.gnu.org/licenses/>.- *- * If you would like to incorporate Link into a proprietary software application,- * please contact <link-devs@ableton.com>.- */--#include <Comdef.h>-#include <chrono>--// WARNING: This file provides an audio driver for Windows using WASAPI. This driver is-// considered experimental and has problems with low-latency playback. Please consider-// using the ASIO driver instead.--namespace ableton-{-namespace linkaudio-{--// GUID identifiers used to when looking up COM enumerators and devices-static const IID kMMDeviceEnumeratorId = __uuidof(MMDeviceEnumerator);-static const IID kIMMDeviceEnumeratorId = __uuidof(IMMDeviceEnumerator);-static const IID kAudioClientId = __uuidof(IAudioClient);-static const IID kAudioRenderClientId = __uuidof(IAudioRenderClient);--// Controls how large the driver's ring buffer will be, expressed in terms of-// 100-nanosecond units. This value also influences the overall driver latency.-static const REFERENCE_TIME kBufferDuration = 1000000;--// How long to block the runloop while waiting for an event callback.-static const DWORD kWaitTimeoutInMs = 2000;--void fatalError(HRESULT result, LPCTSTR context)-{- if (result > 0)- {- _com_error error(result);- LPCTSTR errorMessage = error.ErrorMessage();- std::cerr << context << ": " << errorMessage << std::endl;- }- else- {- std::cerr << context << std::endl;- }-- std::terminate();-}--template <typename Link>-DWORD renderAudioRunloop(LPVOID lpParam)-{- AudioPlatform<Link>* platform = static_cast<AudioPlatform<Link>*>(lpParam);- return platform->audioRunloop();-}--template <typename Link>-AudioPlatform<Link>::AudioPlatform(Link& link)- : mEngine(link)- , mSampleTime(0)- , mDevice(nullptr)- , mAudioClient(nullptr)- , mRenderClient(nullptr)- , mStreamFormat(nullptr)- , mEventHandle(nullptr)- , mAudioThreadHandle(nullptr)- , mIsRunning(false)-{- initialize();- mEngine.setNumFrames(bufferSize());- mEngine.setSampleRate(mStreamFormat->nSamplesPerSec);- start();-}--template <typename Link>-AudioPlatform<Link>::~AudioPlatform()-{- // WARNING: Here be dragons!- // The WASAPI driver is not thread-safe, and crashes may occur when shutting down due- // to these fields being concurrently accessed in the audio thread. Introducing a mutex- // in the audio thread is not an appropriate solution to fix this race condition; a more- // robust solution needs to be considered instead.-- if (mDevice != nullptr)- {- mDevice->Release();- }- if (mAudioClient != nullptr)- {- mAudioClient->Release();- }- if (mRenderClient != nullptr)- {- mRenderClient->Release();- }- CoTaskMemFree(mStreamFormat);-}--template <typename Link>-UINT32 AudioPlatform<Link>::bufferSize()-{- UINT32 bufferSize;- HRESULT result = mAudioClient->GetBufferSize(&bufferSize);- if (FAILED(result))- {- fatalError(result, "Could not get buffer size");- return 0; // not reached- }-- return bufferSize;-}--template <typename Link>-void AudioPlatform<Link>::initialize()-{- HRESULT result = CoInitialize(nullptr);- if (FAILED(result))- {- fatalError(result, "Could not initialize COM library");- }-- IMMDeviceEnumerator* enumerator = nullptr;- result = CoCreateInstance(kMMDeviceEnumeratorId,- nullptr,- CLSCTX_ALL,- kIMMDeviceEnumeratorId,- (void**)&enumerator);- if (FAILED(result))- {- fatalError(result, "Could not create device instance");- }-- result = enumerator->GetDefaultAudioEndpoint(eRender, eConsole, &(mDevice));- if (FAILED(result))- {- fatalError(result, "Could not get default audio endpoint");- }- else- {- enumerator->Release();- enumerator = nullptr;- }-- result =- mDevice->Activate(kAudioClientId, CLSCTX_ALL, nullptr, (void**)&(mAudioClient));- if (FAILED(result))- {- fatalError(result, "Could not activate audio device");- }-- result = mAudioClient->GetMixFormat(&(mStreamFormat));- if (FAILED(result))- {- fatalError(result, "Could not get mix format");- }-- if (mStreamFormat->wFormatTag == WAVE_FORMAT_EXTENSIBLE)- {- WAVEFORMATEXTENSIBLE* streamFormatEx =- reinterpret_cast<WAVEFORMATEXTENSIBLE*>(mStreamFormat);- if (streamFormatEx->SubFormat != KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)- {- fatalError(0, "Sorry, only IEEE floating point streams are supported");- }- }- else- {- fatalError(0, "Sorry, only extensible wave streams are supported");- }-- result = mAudioClient->Initialize(AUDCLNT_SHAREMODE_SHARED,- AUDCLNT_STREAMFLAGS_EVENTCALLBACK,- kBufferDuration,- 0,- mStreamFormat,- nullptr);- if (FAILED(result))- {- fatalError(result, "Could not initialize audio device");- }-- mEventHandle = CreateEvent(nullptr, false, false, nullptr);- if (mEventHandle == nullptr)- {- fatalError(result, "Could not create event handle");- }-- result = mAudioClient->GetService(kAudioRenderClientId, (void**)&(mRenderClient));- if (FAILED(result))- {- fatalError(result, "Could not get audio render service");- }-- mIsRunning = true;- LPTHREAD_START_ROUTINE threadEntryPoint =- reinterpret_cast<LPTHREAD_START_ROUTINE>(renderAudioRunloop<Link>);- mAudioThreadHandle = CreateThread(nullptr, 0, threadEntryPoint, this, 0, nullptr);- if (mAudioThreadHandle == nullptr)- {- fatalError(GetLastError(), "Could not create audio thread");- }-}--template <typename Link>-void AudioPlatform<Link>::start()-{- UINT32 bufSize = bufferSize();- BYTE* buffer;- HRESULT result = mRenderClient->GetBuffer(bufSize, &buffer);- if (FAILED(result))- {- fatalError(result, "Could not get render client buffer (in start audio engine)");- }-- result = mRenderClient->ReleaseBuffer(bufSize, 0);- if (FAILED(result))- {- fatalError(result, "Could not release buffer");- }-- result = mAudioClient->SetEventHandle(mEventHandle);- if (FAILED(result))- {- fatalError(result, "Could not set event handle to audio client");- }-- REFERENCE_TIME latency;- result = mAudioClient->GetStreamLatency(&latency);- if (FAILED(result))- {- fatalError(result, "Could not get stream latency");- }-- result = mAudioClient->Start();- if (FAILED(result))- {- fatalError(result, "Could not start audio client");- }-}--template <typename Link>-DWORD AudioPlatform<Link>::audioRunloop()-{- while (mIsRunning)- {- DWORD wait = WaitForSingleObject(mEventHandle, kWaitTimeoutInMs);- if (wait != WAIT_OBJECT_0)- {- mIsRunning = false;- mAudioClient->Stop();- return wait;- }-- // Get the amount of padding, which basically is the amount of data in the driver's- // ring buffer that is filled with unread data. Thus, subtracting this amount from- // the buffer size gives the effective buffer size, which is the amount of frames- // that can be safely written to the driver.- UINT32 paddingFrames;- HRESULT result = mAudioClient->GetCurrentPadding(&paddingFrames);- if (FAILED(result))- {- fatalError(result, "Could not get number of padding frames");- }-- const UINT32 numSamples = bufferSize() - paddingFrames;-- BYTE* buffer;- result = mRenderClient->GetBuffer(numSamples, &buffer);- if (FAILED(result))- {- fatalError(result, "Could not get render client buffer (in callback)");- }-- const double sampleRate = static_cast<double>(mStreamFormat->nSamplesPerSec);- using namespace std::chrono;- const auto bufferDuration =- duration_cast<microseconds>(duration<double>{numSamples / sampleRate});-- const auto hostTime = mHostTimeFilter.sampleTimeToHostTime(mSampleTime);-- mSampleTime += numSamples;-- const auto bufferBeginAtOutput = hostTime + mEngine.mOutputLatency.load();-- mEngine.audioCallback(bufferBeginAtOutput, numSamples);-- float* floatBuffer = reinterpret_cast<float*>(buffer);- for (WORD i = 0; i < numSamples; ++i)- {- if (i >= mEngine.mBuffers[0].size())- {- break;- }- for (WORD j = 0; j < mStreamFormat->nChannels; ++j)- {- floatBuffer[j + (i * mStreamFormat->nChannels)] =- static_cast<float>(mEngine.mBuffers[j][i]);- }- }-- // Write the buffer to the audio driver and subsequently free the buffer memory- result = mRenderClient->ReleaseBuffer(numSamples, 0);- if (FAILED(result))- {- fatalError(result, "Error rendering data");- }- } // end of runloop-- mIsRunning = false;- return 0;-}---// void fillBuffer(MetronomeSynth& metronome,-// const UINT32 startFrame,-// const UINT32 numSamples,-// const UINT32 numChannels,-// BYTE* buffer)-//{-// float* floatBuffer = reinterpret_cast<float*>(buffer);-// UINT32 frame = startFrame;-// while (frame < numSamples * numChannels)-// {-// const float sample = static_cast<float>(metronome.getSample());-// for (UINT32 channel = 0; channel < numChannels; ++channel)-// {-// floatBuffer[frame++] = sample;-// }-// }-//}--} // namespace linkaudio-} // namespace ableton
− link/examples/linkaudio/LinkAudioRenderer.hpp
@@ -1,418 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- * This program is free software: you can redistribute it and/or modify- * it under the terms of the GNU General Public License as published by- * the Free Software Foundation, either version 2 of the License, or- * (at your option) any later version.- *- * This program is distributed in the hope that it will be useful,- * but WITHOUT ANY WARRANTY; without even the implied warranty of- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- * GNU General Public License for more details.- *- * You should have received a copy of the GNU General Public License- * along with this program. If not, see <http://www.gnu.org/licenses/>.- *- * If you would like to incorporate Link into a proprietary software application,- * please contact <link-devs@ableton.com>.- */--#pragma once--#if defined(LINK_AUDIO)--#include <ableton/LinkAudio.hpp>-#include <ableton/link_audio/Buffer.hpp>-#include <ableton/link_audio/Queue.hpp>-#include <ableton/util/FloatIntConversion.hpp>--namespace ableton-{-namespace linkaudio-{--namespace-{--template <typename T>-T cubicInterpolate(const std::array<T, 4>& p, double t)-{- double a = -0.5 * static_cast<double>(p[0]) + 1.5 * static_cast<double>(p[1])- - 1.5 * static_cast<double>(p[2]) + 0.5 * static_cast<double>(p[3]);- double b = static_cast<double>(p[0]) - 2.5 * static_cast<double>(p[1])- + 2.0 * static_cast<double>(p[2]) - 0.5 * static_cast<double>(p[3]);- double c = -0.5 * static_cast<double>(p[0]) + 0.5 * static_cast<double>(p[2]);- auto d = static_cast<double>(p[1]);- return static_cast<T>(a * t * t * t + b * t * t + c * t + d);-}--template <typename T>-T linearInterpolate(T value, T inMin, T inMax, T outMin, T outMax)-{- return (value - inMin) * (outMax - outMin) / (inMax - inMin) + outMin;-}--} // namespace--template <typename Link>-class LinkAudioRenderer-{- struct Buffer- {- std::array<double, 512> mSamples; // Should at least hold max network buffer size- LinkAudioSource::BufferHandle::Info mInfo;- };- using Queue = link_audio::Queue<Buffer>;--public:- LinkAudioRenderer(Link& link, double& sampleRate)- : mLink(link)- , mSink(mLink, "A Sink", 4096)- , mSampleRate(sampleRate)- {- auto queue = Queue(2048, {});- mpQueueWriter = std::make_shared<typename Queue::Writer>(std::move(queue.writer()));- mpQueueReader = std::make_shared<typename Queue::Reader>(std::move(queue.reader()));- }-- ~LinkAudioRenderer() { mpSource.reset(); }-- void send(double* pSamples,- size_t numFrames,- typename Link::SessionState sessionState,- double sampleRate,- const std::chrono::microseconds hostTime,- double quantum)- {- // We can only send audio if the sink can provide a buffer to write to- auto buffer = LinkAudioSink::BufferHandle(mSink);- if (buffer)- {- // The sink expects 16 bit integers so the doubles have to be converted- for (auto i = 0u; i < numFrames; ++i)- {- buffer.samples[i] = ableton::util::floatToInt16(pSamples[i]);- }-- // The buffer is commited to Link Audio with the required timing information- const auto beatsAtBufferBegin = sessionState.beatAtTime(hostTime, quantum);- buffer.commit(sessionState,- beatsAtBufferBegin,- quantum,- static_cast<uint32_t>(numFrames),- 1, // mono- static_cast<uint32_t>(sampleRate));- }- }-- void receive(double* pRightSamples,- size_t numFrames,- typename Link::SessionState sessionState,- double sampleRate,- const std::chrono::microseconds hostTime,- double quantum)- {- // Get all slots from the queue- while (mpQueueReader->retainSlot())- {- }-- // Calculate the beat range we want to render to the output buffer- constexpr auto kLatencyInBeats = 4;- const auto targetBeatsAtBufferBegin =- sessionState.beatAtTime(hostTime, quantum) - kLatencyInBeats;- const auto targetBeatsAtBufferEnd =- sessionState.beatAtTime(- hostTime- + std::chrono::duration_cast<std::chrono::microseconds>(- std::chrono::duration<double>((double(numFrames)) / sampleRate)),- quantum)- - kLatencyInBeats;-- // Drop slots that are too old while we are not rendering- while (!moStartReadPos && mpQueueReader->numRetainedSlots() > 0)- {- if ((*mpQueueReader)[0]->mInfo.endBeats(sessionState, quantum)- < targetBeatsAtBufferBegin)- {- mpQueueReader->releaseSlot();- }- else- {- break;- }- }-- // Return early if there is no audio buffer to read from- if (mpQueueReader->numRetainedSlots() == 0)- {- moLastFrameIdx = std::nullopt;- moStartReadPos = std::nullopt;- mBuffered = 0;- return;- }-- // Return early if the next buffer is too new and we are not rendering- if (!moStartReadPos- && (*mpQueueReader)[0]->mInfo.beginBeats(sessionState, quantum)- > targetBeatsAtBufferBegin)- {- moLastFrameIdx = std::nullopt;- moStartReadPos = std::nullopt;- mBuffered = 0;- return;- }-- // Initialize start read position if not set- if (!moStartReadPos)- {- const auto& info = (*mpQueueReader)[0]->mInfo;- const auto startBufferBegin = *info.beginBeats(sessionState, quantum);- const auto startBufferEnd = *info.endBeats(sessionState, quantum);-- // Calculate initial position from target beat- moStartReadPos = linearInterpolate(targetBeatsAtBufferBegin,- startBufferBegin,- startBufferEnd,- 0.0,- double(info.numFrames));- }-- const auto startFramePos = *moStartReadPos;-- // Loop through queue to find end beat and collect total frames- auto totalFrames = 0.0;- auto foundEnd = false;-- for (auto i = 0u; i < mpQueueReader->numRetainedSlots(); ++i)- {- const auto& info = (*mpQueueReader)[i]->mInfo;- const auto bufferBegin = *info.beginBeats(sessionState, quantum);- const auto bufferEnd = *info.endBeats(sessionState, quantum);-- if (targetBeatsAtBufferEnd >= bufferBegin && targetBeatsAtBufferEnd < bufferEnd)- {- const auto targetBeatsFrame = linearInterpolate(- targetBeatsAtBufferEnd, bufferBegin, bufferEnd, 0.0, double(info.numFrames));-- totalFrames += targetBeatsFrame;- foundEnd = true;- break;- }- else- {- totalFrames += double(info.numFrames);- }- }-- // We don't have enough frames buffered- if (!foundEnd)- {- moLastFrameIdx = std::nullopt;- moStartReadPos = std::nullopt;- mBuffered = 0;- return;- }-- // Take the frames we have already rendered into account- totalFrames -= startFramePos;-- // Beat time jump, we can't continue rendering- if (totalFrames <= 0.0)- {- moLastFrameIdx = std::nullopt;- moStartReadPos = std::nullopt;- mBuffered = 0;- return;- }-- // The increment is how many source frames to advance per output frame- // This automatically handles both tempo changes and sample rate differences by- // re-pitching the audio- const auto frameIncrement = totalFrames / double(numFrames);- auto readPos = startFramePos;-- // Helper to get sample at index, handling buffer boundaries- auto getSample = [&](size_t idx) -> double- {- size_t bufferIdx = 0;- size_t currentIdx = idx;-- while (bufferIdx < mpQueueReader->numRetainedSlots())- {- auto& currentBuffer = *((*mpQueueReader)[bufferIdx]);- if (currentIdx < currentBuffer.mInfo.numFrames)- {- return currentBuffer.mSamples[currentIdx];- }- currentIdx -= currentBuffer.mInfo.numFrames;- ++bufferIdx;- }-- return 0.0;- };-- for (auto frame = 0u; frame < numFrames; ++frame)- {- const auto framePos = readPos + frame * frameIncrement;- const auto frameIdx = static_cast<size_t>(std::floor(framePos));- const auto t = framePos - std::floor(framePos);-- // Update the interpolator cache- while (!moLastFrameIdx || (moLastFrameIdx && frameIdx > *moLastFrameIdx))- {- mReceiverSampleCache[3] = mReceiverSampleCache[2];- mReceiverSampleCache[2] = mReceiverSampleCache[1];- mReceiverSampleCache[1] = mReceiverSampleCache[0];- mReceiverSampleCache[0] = (frameIdx > 0) ? getSample(frameIdx - 1) : getSample(0);- moLastFrameIdx = moLastFrameIdx ? (*moLastFrameIdx + 1) : frameIdx;- }-- // Write the output frame- pRightSamples[frame] = cubicInterpolate(mReceiverSampleCache, t);-- // Drop buffer if we've moved past it- const auto& currentInfo = (*mpQueueReader)[0]->mInfo;- if (frameIdx >= currentInfo.numFrames)- {- readPos -= double(currentInfo.numFrames);- moLastFrameIdx = frameIdx - currentInfo.numFrames;- mpQueueReader->releaseSlot();- }- }-- // Update the read position for the next buffer- *moStartReadPos = readPos + double(numFrames) * frameIncrement;-- // Calculate buffered time- auto buffered =- -static_cast<float>(*moStartReadPos) / float((*mpQueueReader)[0]->mInfo.sampleRate);- if (mpQueueReader->numRetainedSlots() > 0)- {- for (auto i = 1u; i < mpQueueReader->numRetainedSlots(); ++i)- {- const auto& info = (*mpQueueReader)[i]->mInfo;- buffered += float(info.numFrames) / float(info.sampleRate);- }- }- mBuffered = buffered;- }-- void operator()(double* pLeftSamples,- double* pRightSamples,- size_t numFrames,- typename Link::SessionState sessionState,- double sampleRate,- const std::chrono::microseconds hostTime,- double quantum)- {- // Send the left channel to Link- send(pLeftSamples, numFrames, sessionState, sampleRate, hostTime, quantum);-- // Write the received audio to the right channel- receive(pRightSamples, numFrames, sessionState, sampleRate, hostTime, quantum);- }--- bool hasSource() const { return mpSource != nullptr; }-- void removeSource()- {- if (mpSource)- {- mpSource.reset();-- while (mpQueueReader->retainSlot())- {- }-- while (mpQueueReader->numRetainedSlots() > 0)- {- mpQueueReader->releaseSlot();- }-- moLastFrameIdx = std::nullopt;- moStartReadPos = std::nullopt;- }- }-- float buffered() const { return mBuffered; }-- void createSource(const ChannelId& channelId)- {- mpSource = std::make_unique<LinkAudioSource>(- mLink,- channelId,- [this](ableton::LinkAudioSource::BufferHandle bufferHandle)- { onSourceBuffer(bufferHandle); });- }-- void onSourceBuffer(const LinkAudioSource::BufferHandle bufferHandle)- {- // When we receive a buffer from Link, we prime it for the audio rendering callback.- // This runs on the main Link thread, so we should not block it for too long.- if (mpQueueWriter->retainSlot())- {- auto& buffer = *((*mpQueueWriter)[0]);- buffer.mInfo = bufferHandle.info;- buffer.mInfo.numChannels = 1;-- for (auto i = 0u; i < bufferHandle.info.numFrames; ++i)- {- buffer.mSamples[i] = util::int16ToFloat<double>(- bufferHandle.samples[i * bufferHandle.info.numChannels]);- }-- mpQueueWriter->releaseSlot();- }- }-- Link& mLink;- LinkAudioSink mSink;- std::unique_ptr<LinkAudioSource> mpSource;- double& mSampleRate;-- std::optional<double> moStartReadPos;- std::atomic<float> mBuffered = 0;--private:- std::shared_ptr<typename Queue::Writer> mpQueueWriter;- std::shared_ptr<typename Queue::Reader> mpQueueReader;-- std::array<double, 4> mReceiverSampleCache = {{0.0, 0.0, 0.0, 0.0}};- std::optional<size_t> moLastFrameIdx = std::nullopt;-};--} // namespace linkaudio-} // namespace ableton--#else--namespace ableton-{-namespace linkaudio-{--template <typename Link>-class LinkAudioRenderer-{-public:- LinkAudioRenderer(Link&, double&) {}-- // In case we don't support LinkAudio we just copy the left output buffer to the right- void operator()(double* pLeftSamples,- double* pRightSamples,- size_t numFrames,- typename Link::SessionState,- double,- const std::chrono::microseconds,- double)- {- std::copy_n(pLeftSamples, numFrames, pRightSamples);- }-};--} // namespace linkaudio-} // namespace ableton--#endif
link/extensions/abl_link/include/abl_link.h view
@@ -18,7 +18,6 @@ */ #include <stdbool.h>-#include <stddef.h> #include <stdint.h> #ifdef __cplusplus@@ -62,52 +61,52 @@ */ /*! @brief The representation of an abl_link instance*/- struct abl_link+ typedef struct abl_link { void *impl;- };+ } abl_link; /*! @brief Construct a new abl_link instance with an initial tempo. * Thread-safe: yes * Realtime-safe: no */- struct abl_link abl_link_create(double bpm);+ abl_link abl_link_create(double bpm); /*! @brief Delete an abl_link instance. * Thread-safe: yes * Realtime-safe: no */- void abl_link_destroy(struct abl_link link);+ void abl_link_destroy(abl_link link); /*! @brief Is Link currently enabled? * Thread-safe: yes * Realtime-safe: yes */- bool abl_link_is_enabled(struct abl_link link);+ bool abl_link_is_enabled(abl_link link); /*! @brief Enable/disable Link. * Thread-safe: yes * Realtime-safe: no */- void abl_link_enable(struct abl_link link, bool enable);+ void abl_link_enable(abl_link link, bool enable); /*! @brief: Is start/stop synchronization enabled? * Thread-safe: yes- * Realtime-safe: yes+ * Realtime-safe: no */- bool abl_link_is_start_stop_sync_enabled(struct abl_link link);+ bool abl_link_is_start_stop_sync_enabled(abl_link link); /*! @brief: Enable start/stop synchronization. * Thread-safe: yes- * Realtime-safe: yes+ * Realtime-safe: no */- void abl_link_enable_start_stop_sync(struct abl_link link, bool enabled);+ void abl_link_enable_start_stop_sync(abl_link link, bool enabled); /*! @brief How many peers are currently connected in a Link session? * Thread-safe: yes * Realtime-safe: yes */- uint64_t abl_link_num_peers(struct abl_link link);+ uint64_t abl_link_num_peers(abl_link link); /*! @brief Register a callback to be notified when the number of * peers in the Link session changes.@@ -116,9 +115,9 @@ * * @discussion The callback is invoked on a Link-managed thread. */- void abl_link_set_num_peers_callback(struct abl_link link,- void (*callback)(uint64_t num_peers, void *context),- void *context);+ typedef void (*abl_link_num_peers_callback)(uint64_t num_peers, void *context);+ void abl_link_set_num_peers_callback(+ abl_link link, abl_link_num_peers_callback callback, void *context); /*! @brief Register a callback to be notified when the session * tempo changes.@@ -127,8 +126,9 @@ * * @discussion The callback is invoked on a Link-managed thread. */+ typedef void (*abl_link_tempo_callback)(double tempo, void *context); void abl_link_set_tempo_callback(- struct abl_link link, void (*callback)(double tempo, void *context), void *context);+ abl_link link, abl_link_tempo_callback callback, void *context); /*! brief: Register a callback to be notified when the state of * start/stop isPlaying changes.@@ -137,15 +137,15 @@ * * @discussion The callback is invoked on a Link-managed thread. */- void abl_link_set_start_stop_callback(struct abl_link link,- void (*callback)(bool is_playing, void *context),- void *context);+ typedef void (*abl_link_start_stop_callback)(bool is_playing, void *context);+ void abl_link_set_start_stop_callback(+ abl_link link, abl_link_start_stop_callback callback, void *context); /*! brief: Get the current link clock time in microseconds. * Thread-safe: yes * Realtime-safe: yes */- int64_t abl_link_clock_micros(struct abl_link link);+ int64_t abl_link_clock_micros(abl_link link); /*! @brief The representation of the current local state of a client in a Link Session *@@ -163,7 +163,7 @@ * joining or leaving a Link session. After joining a Link session * start/stop change requests will be communicated to all connected peers. */- typedef struct abl_link_session_state // NOLINT(modernize-use-using)+ typedef struct abl_link_session_state { void *impl; } abl_link_session_state;@@ -194,7 +194,7 @@ * session_state should not be created on the audio thread. */ void abl_link_capture_audio_session_state(- struct abl_link link, abl_link_session_state session_state);+ abl_link link, abl_link_session_state session_state); /*! @brief Commit the given Session State to the Link session from the * audio thread.@@ -206,11 +206,11 @@ * communicated to other peers in the session. */ void abl_link_commit_audio_session_state(- struct abl_link link, abl_link_session_state session_state);+ abl_link link, abl_link_session_state session_state); /*! @brief Capture the current Link Session State from an application thread.- * Thread-safe: yes- * Realtime-safe: no+ * Thread-safe: no+ * Realtime-safe: yes * * @discussion Provides a mechanism for capturing the Link Session State from an * application thread (other than the audio thread). After capturing the session_state@@ -218,7 +218,7 @@ * scope. */ void abl_link_capture_app_session_state(- struct abl_link link, abl_link_session_state session_state);+ abl_link link, abl_link_session_state session_state); /*! @brief Commit the given Session State to the Link session from an * application thread.@@ -230,7 +230,7 @@ * session. */ void abl_link_commit_app_session_state(- struct abl_link link, abl_link_session_state session_state);+ abl_link link, abl_link_session_state session_state); /*! @brief: The tempo of the timeline, in Beats Per Minute. *@@ -317,19 +317,19 @@ * join. */ void abl_link_force_beat_at_time(- abl_link_session_state session_state, double beat, int64_t time, double quantum);+ abl_link_session_state session_state, double beat, uint64_t time, double quantum); /*! @brief: Set if transport should be playing or stopped, taking effect at the given * time. */ void abl_link_set_is_playing(- abl_link_session_state session_state, bool is_playing, int64_t time);+ abl_link_session_state session_state, bool is_playing, uint64_t time); /*! @brief: Is transport playing? */ bool abl_link_is_playing(abl_link_session_state session_state); /*! @brief: Get the time at which a transport start/stop occurs */- int64_t abl_link_time_for_is_playing(abl_link_session_state session_state);+ uint64_t abl_link_time_for_is_playing(abl_link_session_state session_state); /*! @brief: Convenience function to attempt to map the given beat to the time * when transport is starting to play in context of the given quantum.@@ -343,254 +343,9 @@ void abl_link_set_is_playing_and_request_beat_at_time( abl_link_session_state session_state, bool is_playing,- int64_t time,+ uint64_t time, double beat, double quantum);-- /*! @brief Is Link Audio enabled- * Thread-safe: yes- * Realtime-safe: yes- */- bool abl_link_audio_is_link_audio_enabled(struct abl_link link);-- /*! @brief Enable or disable audio.- * Thread-safe: yes- * Realtime-safe: no- */- void abl_link_audio_enable_link_audio(struct abl_link link, bool enabled);-- /*! @brief Get the local peer name for identification in the Link session.- *- * @discussion Writes the peer name into @p buffer as a null-terminated string,- * truncating if necessary. Returns the number of bytes required to store the full- * name, excluding the null terminator — identical to the snprintf convention.- * If the return value is >= @p buffer_size, the output was truncated.- * Passing NULL or 0 for @p buffer / @p buffer_size returns the required size- * without writing anything.- *- * Thread-safe: yes- * Realtime-safe: no- */- size_t abl_link_audio_peer_name(struct abl_link link, char *buffer, size_t buffer_size);-- /*! @brief Change the local peer name for identification in the Link session.- * Thread-safe: yes- * Realtime-safe: no- */- void abl_link_audio_set_peer_name(struct abl_link link, const char *name);-- /*! @brief Identifier for Link Audio channels/peers/sessions. */- struct abl_link_audio_channel_id- {- uint8_t bytes[8];- };-- struct abl_link_audio_peer_id- {- uint8_t bytes[8];- };-- struct abl_link_audio_session_id- {- uint8_t bytes[8];- };-- /*! @brief A Link Audio channel description.- *- * @discussion The id and peer_id are persistent for the lifetime of a channel.- * The name and peer_name may change over time and are meant for display purposes.- */- struct abl_link_audio_channel- {- struct abl_link_audio_channel_id id;- const char *name;- struct abl_link_audio_peer_id peer_id;- const char *peer_name;- };-- /*! @brief A list of Link Audio channels. */- struct abl_link_audio_channel_list- {- struct abl_link_audio_channel *channels;- size_t count;- };-- /*! @brief Get the list of available Link Audio channels.- * Thread-safe: yes- * Realtime-safe: no- */- struct abl_link_audio_channel_list abl_link_audio_get_channels(struct abl_link link);-- /*! @brief Free a channel list returned by abl_link_audio_get_channels. */- void abl_link_audio_free_channel_list(struct abl_link_audio_channel_list list);-- /*! @brief Register a callback to be notified when the set of available- * audio channels changes. This will be called when channels are discovered or- * disappear and when names change.- * Thread-safe: yes- * Realtime-safe: no- *- * @discussion The callback is invoked on a Link-managed thread.- */- void abl_link_audio_set_channels_changed_callback(- struct abl_link link, void (*callback)(void *context), void *context);-- /*! @brief The representation of an abl_link_audio_sink instance */- struct abl_link_audio_sink- {- void *impl;- };-- /*! @brief Construct a Link Audio sink to announce an audio channel. */- struct abl_link_audio_sink abl_link_audio_sink_create(- struct abl_link link, const char *name, size_t max_num_samples);-- /*! @brief Destroy a Link Audio sink. */- void abl_link_audio_sink_destroy(struct abl_link_audio_sink sink);-- /*! @brief Get the name of a Link Audio sink.- *- * @discussion Writes the sink name into @p buffer as a null-terminated string,- * truncating if necessary. Returns the number of bytes required to store the full- * name, excluding the null terminator — identical to the snprintf convention.- * If the return value is >= @p buffer_size, the output was truncated.- * Passing NULL or 0 for @p buffer / @p buffer_size returns the required size- * without writing anything.- *- * Thread-safe: yes- * Realtime-safe: no- */- size_t abl_link_audio_sink_name(- struct abl_link_audio_sink sink, char *buffer, size_t buffer_size);-- /*! @brief Set the name of a Link Audio sink.- * Thread-safe: yes- * Realtime-safe: no- */- void abl_link_audio_sink_set_name(struct abl_link_audio_sink sink, const char *name);-- /*! @brief Request a maximum buffer size for future buffers.- * Thread-safe: yes- * Realtime-safe: yes- */- void abl_link_audio_sink_request_max_num_samples(- struct abl_link_audio_sink sink, size_t num_samples);-- /*! @brief Get the current maximum number of samples a buffer handle can hold.- * Thread-safe: yes- * Realtime-safe: yes- */- size_t abl_link_audio_sink_max_num_samples(struct abl_link_audio_sink sink);-- /*! @brief Handle to a buffer for writing audio samples. */- struct abl_link_audio_sink_buffer_handle- {- void *impl;- int16_t *samples;- size_t max_num_samples;- };-- /*! @brief Retain a buffer for writing audio samples. Only one buffer can be retained- * at a time. The handle must not outlive the sink it was created from.- * Thread-safe: no- * Realtime-safe: yes- */- struct abl_link_audio_sink_buffer_handle abl_link_audio_sink_retain_buffer(- struct abl_link_audio_sink sink);-- /*! @brief Check if a buffer handle is valid.- * Thread-safe: no- * Realtime-safe: yes- */- bool abl_link_audio_sink_buffer_is_valid(- const struct abl_link_audio_sink_buffer_handle *handle);-- /*! @brief Commit a buffer after writing samples. The handle is invalid after this.- * num_frames * num_channels must not exceed max_num_samples. The session state,- * quantum, and beats_at_buffer_begin must match those used for rendering.- * Thread-safe: no- * Realtime-safe: yes- */- bool abl_link_audio_sink_buffer_commit(struct abl_link_audio_sink_buffer_handle *handle,- abl_link_session_state session_state,- double beats_at_buffer_begin,- double quantum,- size_t num_frames,- size_t num_channels,- uint32_t sample_rate);-- /*! @brief Release a retained buffer without committing. The handle is invalid after- * this.- * Thread-safe: no- * Realtime-safe: yes- */- void abl_link_audio_sink_buffer_release(- struct abl_link_audio_sink_buffer_handle *handle);-- /*! @brief Buffer metadata for received audio. */- struct abl_link_audio_source_buffer_info- {- size_t num_channels;- size_t num_frames;- uint32_t sample_rate;- uint64_t count;- double session_beat_time;- double tempo;- struct abl_link_audio_session_id session_id;- };-- /*! @brief Map the beat time at the begin of the buffer to the local Link session state.- * @return True if the buffer originates from the same Link Session and out_beats is- * set.- */- bool abl_link_audio_source_buffer_info_begin_beats(- const struct abl_link_audio_source_buffer_info *info,- abl_link_session_state session_state,- double quantum,- double *out_beats);-- /*! @brief Map the beat time at the end of the buffer to the local Link session state.- * @return True if the buffer originates from the same Link Session and out_beats is- * set.- */- bool abl_link_audio_source_buffer_info_end_beats(- const struct abl_link_audio_source_buffer_info *info,- abl_link_session_state session_state,- double quantum,- double *out_beats);-- /*! @brief Buffer provided to Link Audio source callbacks. */- struct abl_link_audio_source_buffer- {- int16_t *samples;- struct abl_link_audio_source_buffer_info info;- };-- /*! @brief The representation of an abl_link_audio_source instance */- struct abl_link_audio_source- {- void *impl;- };-- /*! @brief Construct a Link Audio source for a given channel.- * @param callback Invoked on a Link-managed thread when a source buffer is received.- * Neither the buffer pointer nor its samples pointer remain valid- * after the callback returns.- */- struct abl_link_audio_source abl_link_audio_source_create(struct abl_link link,- struct abl_link_audio_channel_id channel_id,- void (*callback)(const struct abl_link_audio_source_buffer *buffer, void *context),- void *context);-- /*! @brief Destroy a Link Audio source. */- void abl_link_audio_source_destroy(struct abl_link_audio_source source);-- /*! @brief Get the channel ID of the corresponding source.- * Thread-safe: yes- * Realtime-safe: yes- */- struct abl_link_audio_channel_id abl_link_audio_source_id(- struct abl_link_audio_source source); #ifdef __cplusplus } // extern "C"
link/extensions/abl_link/src/abl_link.cpp view
@@ -18,135 +18,70 @@ */ #include <abl_link.h>-#include <ableton/LinkAudio.hpp>--#include <algorithm>-#include <cstdlib>-#include <cstring>-#include <string>--namespace-{-struct abl_link_audio_channel_id toChannelId(const ableton::link_audio::Id &id)-{- struct abl_link_audio_channel_id out{};- std::copy(id.begin(), id.end(), out.bytes);- return out;-}--struct abl_link_audio_peer_id toPeerId(const ableton::link_audio::Id &id)-{- struct abl_link_audio_peer_id out{};- std::copy(id.begin(), id.end(), out.bytes);- return out;-}--struct abl_link_audio_session_id toSessionId(const ableton::link_audio::Id &id)-{- struct abl_link_audio_session_id out{};- std::copy(id.begin(), id.end(), out.bytes);- return out;-}--ableton::link_audio::Id toCppChannelId(const struct abl_link_audio_channel_id &id)-{- ableton::link_audio::Id out{};- std::copy(id.bytes, id.bytes + sizeof(id.bytes), out.begin());- return out;-}--ableton::link_audio::Id toCppSessionId(const struct abl_link_audio_session_id &id)-{- ableton::link_audio::Id out{};- std::copy(id.bytes, id.bytes + sizeof(id.bytes), out.begin());- return out;-}--char *copyCString(const std::string &value)-{- auto *buffer = static_cast<char *>(std::malloc(value.size() + 1));- if (buffer)- {- std::memcpy(buffer, value.c_str(), value.size() + 1);- }- return buffer;-}--size_t copyStringToBuffer(const std::string &src, char *buffer, size_t buffer_size)-{- if (buffer && buffer_size > 0)- {- const auto toCopy = std::min(buffer_size - 1, src.size());- std::memcpy(buffer, src.c_str(), toCopy);- buffer[toCopy] = '\0';- }- return src.size();-}-} // namespace+#include <ableton/Link.hpp> extern "C" {- struct abl_link abl_link_create(double bpm)+ abl_link abl_link_create(double bpm) {- return {reinterpret_cast<void *>(new ableton::LinkAudio(bpm, std::string{}))};+ return abl_link{reinterpret_cast<void *>(new ableton::Link(bpm))}; } - void abl_link_destroy(struct abl_link link)+ void abl_link_destroy(abl_link link) {- delete reinterpret_cast<ableton::LinkAudio *>(link.impl);+ delete reinterpret_cast<ableton::Link *>(link.impl); } - bool abl_link_is_enabled(struct abl_link link)+ bool abl_link_is_enabled(abl_link link) {- return reinterpret_cast<ableton::LinkAudio *>(link.impl)->isEnabled();+ return reinterpret_cast<ableton::Link *>(link.impl)->isEnabled(); } - void abl_link_enable(struct abl_link link, bool enabled)+ void abl_link_enable(abl_link link, bool enabled) {- reinterpret_cast<ableton::LinkAudio *>(link.impl)->enable(enabled);+ reinterpret_cast<ableton::Link *>(link.impl)->enable(enabled); } - bool abl_link_is_start_stop_sync_enabled(struct abl_link link)+ bool abl_link_is_start_stop_sync_enabled(abl_link link) {- return reinterpret_cast<ableton::LinkAudio *>(link.impl)->isStartStopSyncEnabled();+ return reinterpret_cast<ableton::Link *>(link.impl)->isStartStopSyncEnabled(); } - void abl_link_enable_start_stop_sync(struct abl_link link, bool enabled)+ void abl_link_enable_start_stop_sync(abl_link link, bool enabled) {- reinterpret_cast<ableton::LinkAudio *>(link.impl)->enableStartStopSync(enabled);+ reinterpret_cast<ableton::Link *>(link.impl)->enableStartStopSync(enabled); } - uint64_t abl_link_num_peers(struct abl_link link)+ uint64_t abl_link_num_peers(abl_link link) {- return reinterpret_cast<ableton::LinkAudio *>(link.impl)->numPeers();+ return reinterpret_cast<ableton::Link *>(link.impl)->numPeers(); } - void abl_link_set_num_peers_callback(struct abl_link link,- void (*callback)(uint64_t num_peers, void *context),- void *context)+ void abl_link_set_num_peers_callback(+ abl_link link, abl_link_num_peers_callback callback, void *context) {- reinterpret_cast<ableton::LinkAudio *>(link.impl)->setNumPeersCallback(- [callback, context](std::size_t numPeers)- { (*callback)(static_cast<uint64_t>(numPeers), context); });+ reinterpret_cast<ableton::Link *>(link.impl)->setNumPeersCallback(+ [callback, context](+ std::size_t numPeers) { (*callback)(static_cast<uint64_t>(numPeers), context); }); } void abl_link_set_tempo_callback(- struct abl_link link, void (*callback)(double tempo, void *context), void *context)+ abl_link link, abl_link_tempo_callback callback, void *context) {- reinterpret_cast<ableton::LinkAudio *>(link.impl)->setTempoCallback(+ reinterpret_cast<ableton::Link *>(link.impl)->setTempoCallback( [callback, context](double tempo) { (*callback)(tempo, context); }); } void abl_link_set_start_stop_callback(- struct abl_link link, void (*callback)(bool isPlaying, void *context), void *context)+ abl_link link, abl_link_start_stop_callback callback, void *context) {- reinterpret_cast<ableton::LinkAudio *>(link.impl)->setStartStopCallback(+ reinterpret_cast<ableton::Link *>(link.impl)->setStartStopCallback( [callback, context](bool isPlaying) { (*callback)(isPlaying, context); }); } - int64_t abl_link_clock_micros(struct abl_link link)+ int64_t abl_link_clock_micros(abl_link link) {- return reinterpret_cast<ableton::LinkAudio *>(link.impl)->clock().micros().count();+ return reinterpret_cast<ableton::Link *>(link.impl)->clock().micros().count(); } abl_link_session_state abl_link_create_session_state(void)@@ -161,30 +96,30 @@ } void abl_link_capture_app_session_state(- struct abl_link link, abl_link_session_state session_state)+ abl_link link, abl_link_session_state session_state) { *reinterpret_cast<ableton::Link::SessionState *>(session_state.impl) =- reinterpret_cast<ableton::LinkAudio *>(link.impl)->captureAppSessionState();+ reinterpret_cast<ableton::Link *>(link.impl)->captureAppSessionState(); } void abl_link_commit_app_session_state(- struct abl_link link, abl_link_session_state session_state)+ abl_link link, abl_link_session_state session_state) {- reinterpret_cast<ableton::LinkAudio *>(link.impl)->commitAppSessionState(+ reinterpret_cast<ableton::Link *>(link.impl)->commitAppSessionState( *reinterpret_cast<ableton::Link::SessionState *>(session_state.impl)); } void abl_link_capture_audio_session_state(- struct abl_link link, abl_link_session_state session_state)+ abl_link link, abl_link_session_state session_state) { *reinterpret_cast<ableton::Link::SessionState *>(session_state.impl) =- reinterpret_cast<ableton::LinkAudio *>(link.impl)->captureAudioSessionState();+ reinterpret_cast<ableton::Link *>(link.impl)->captureAudioSessionState(); } void abl_link_commit_audio_session_state(- struct abl_link link, abl_link_session_state session_state)+ abl_link link, abl_link_session_state session_state) {- reinterpret_cast<ableton::LinkAudio *>(link.impl)->commitAudioSessionState(+ reinterpret_cast<ableton::Link *>(link.impl)->commitAudioSessionState( *reinterpret_cast<ableton::Link::SessionState *>(session_state.impl)); } @@ -231,14 +166,14 @@ } void abl_link_force_beat_at_time(- abl_link_session_state session_state, double beat, int64_t time, double quantum)+ abl_link_session_state session_state, double beat, uint64_t time, double quantum) { reinterpret_cast<ableton::Link::SessionState *>(session_state.impl) ->forceBeatAtTime(beat, std::chrono::microseconds{time}, quantum); } void abl_link_set_is_playing(- abl_link_session_state session_state, bool is_playing, int64_t time)+ abl_link_session_state session_state, bool is_playing, uint64_t time) { reinterpret_cast<ableton::Link::SessionState *>(session_state.impl) ->setIsPlaying(is_playing, std::chrono::microseconds(time));@@ -250,9 +185,9 @@ ->isPlaying(); } - int64_t abl_link_time_for_is_playing(abl_link_session_state session_state)+ uint64_t abl_link_time_for_is_playing(abl_link_session_state session_state) {- return static_cast<int64_t>(+ return static_cast<uint64_t>( reinterpret_cast<ableton::Link::SessionState *>(session_state.impl) ->timeForIsPlaying() .count());@@ -268,299 +203,12 @@ void abl_link_set_is_playing_and_request_beat_at_time( abl_link_session_state session_state, bool is_playing,- int64_t time,+ uint64_t time, double beat, double quantum) { reinterpret_cast<ableton::Link::SessionState *>(session_state.impl) ->setIsPlayingAndRequestBeatAtTime( is_playing, std::chrono::microseconds{time}, beat, quantum);- }-- bool abl_link_audio_is_link_audio_enabled(struct abl_link link)- {- return reinterpret_cast<ableton::LinkAudio *>(link.impl)->isLinkAudioEnabled();- }-- void abl_link_audio_enable_link_audio(struct abl_link link, bool enabled)- {- reinterpret_cast<ableton::LinkAudio *>(link.impl)->enableLinkAudio(enabled);- }-- size_t abl_link_audio_peer_name(struct abl_link link, char *buffer, size_t buffer_size)- {- return copyStringToBuffer(- reinterpret_cast<ableton::LinkAudio *>(link.impl)->peerName(), buffer, buffer_size);- }-- void abl_link_audio_set_peer_name(struct abl_link link, const char *name)- {- reinterpret_cast<ableton::LinkAudio *>(link.impl)->setPeerName(name);- }-- struct abl_link_audio_channel_list abl_link_audio_get_channels(struct abl_link link)- {- struct abl_link_audio_channel_list result{};- const auto channels = reinterpret_cast<ableton::LinkAudio *>(link.impl)->channels();- result.count = channels.size();- if (result.count == 0)- {- return result;- }-- result.channels = static_cast<struct abl_link_audio_channel *>(- std::calloc(result.count, sizeof(struct abl_link_audio_channel)));- if (!result.channels)- {- result.count = 0;- return result;- }-- for (size_t i = 0; i < result.count; ++i)- {- const auto &channel = channels[i];- result.channels[i].id = toChannelId(channel.id);- result.channels[i].peer_id = toPeerId(channel.peerId);- result.channels[i].name = copyCString(channel.name);- result.channels[i].peer_name = copyCString(channel.peerName);- }-- return result;- }-- void abl_link_audio_free_channel_list(struct abl_link_audio_channel_list list)- {- if (!list.channels)- {- return;- }- for (size_t i = 0; i < list.count; ++i)- {- std::free(const_cast<char *>(list.channels[i].name));- std::free(const_cast<char *>(list.channels[i].peer_name));- }- std::free(list.channels);- }-- void abl_link_audio_set_channels_changed_callback(- struct abl_link link, void (*callback)(void *context), void *context)- {- reinterpret_cast<ableton::LinkAudio *>(link.impl)->setChannelsChangedCallback(- [callback, context]()- {- if (callback)- {- (*callback)(context);- }- });- }-- struct abl_link_audio_sink abl_link_audio_sink_create(- struct abl_link link, const char *name, size_t max_num_samples)- {- return {reinterpret_cast<void *>(new ableton::LinkAudioSink(- *reinterpret_cast<ableton::LinkAudio *>(link.impl), name, max_num_samples))};- }-- void abl_link_audio_sink_destroy(struct abl_link_audio_sink sink)- {- delete reinterpret_cast<ableton::LinkAudioSink *>(sink.impl);- }-- size_t abl_link_audio_sink_name(- struct abl_link_audio_sink sink, char *buffer, size_t buffer_size)- {- return copyStringToBuffer(- reinterpret_cast<ableton::LinkAudioSink *>(sink.impl)->name(), buffer, buffer_size);- }-- void abl_link_audio_sink_set_name(struct abl_link_audio_sink sink, const char *name)- {- reinterpret_cast<ableton::LinkAudioSink *>(sink.impl)->setName(name);- }-- void abl_link_audio_sink_request_max_num_samples(- struct abl_link_audio_sink sink, size_t num_samples)- {- reinterpret_cast<ableton::LinkAudioSink *>(sink.impl)->requestMaxNumSamples(- num_samples);- }-- size_t abl_link_audio_sink_max_num_samples(struct abl_link_audio_sink sink)- {- return reinterpret_cast<ableton::LinkAudioSink *>(sink.impl)->maxNumSamples();- }-- struct abl_link_audio_sink_buffer_handle abl_link_audio_sink_retain_buffer(- struct abl_link_audio_sink sink)- {- struct abl_link_audio_sink_buffer_handle result{};- auto *cppSink = reinterpret_cast<ableton::LinkAudioSink *>(sink.impl);- auto *cppHandle = new ableton::LinkAudioSink::BufferHandle(*cppSink);- result.impl = cppHandle;- result.samples = cppHandle->samples;- result.max_num_samples = cppHandle->maxNumSamples;- return result;- }-- bool abl_link_audio_sink_buffer_is_valid(- const struct abl_link_audio_sink_buffer_handle *handle)- {- if (!handle || !handle->impl)- {- return false;- }- const auto *cppHandle =- reinterpret_cast<const ableton::LinkAudioSink::BufferHandle *>(handle->impl);- return static_cast<bool>(*cppHandle);- }-- bool abl_link_audio_sink_buffer_commit(struct abl_link_audio_sink_buffer_handle *handle,- abl_link_session_state session_state,- double beats_at_buffer_begin,- double quantum,- size_t num_frames,- size_t num_channels,- uint32_t sample_rate)- {- if (!handle || !handle->impl)- {- return false;- }- auto *cppHandle =- reinterpret_cast<ableton::LinkAudioSink::BufferHandle *>(handle->impl);- const auto *state =- reinterpret_cast<ableton::Link::SessionState *>(session_state.impl);- const auto result = cppHandle->commit(- *state, beats_at_buffer_begin, quantum, num_frames, num_channels, sample_rate);- delete cppHandle;- handle->impl = nullptr;- handle->samples = nullptr;- handle->max_num_samples = 0;- return result;- }-- void abl_link_audio_sink_buffer_release(- struct abl_link_audio_sink_buffer_handle *handle)- {- if (!handle || !handle->impl)- {- return;- }- delete reinterpret_cast<ableton::LinkAudioSink::BufferHandle *>(handle->impl);- handle->impl = nullptr;- handle->samples = nullptr;- handle->max_num_samples = 0;- }-- bool abl_link_audio_source_buffer_info_begin_beats(- const struct abl_link_audio_source_buffer_info *info,- abl_link_session_state session_state,- double quantum,- double *out_beats)- {- if (!info || !out_beats || !session_state.impl)- {- return false;- }- if (info->sample_rate == 0)- {- return false;- }- auto cppInfo = ableton::LinkAudioSource::BufferHandle::Info{};- cppInfo.numChannels = info->num_channels;- cppInfo.numFrames = info->num_frames;- cppInfo.sampleRate = info->sample_rate;- cppInfo.count = info->count;- cppInfo.sessionBeatTime = info->session_beat_time;- cppInfo.tempo = info->tempo;- cppInfo.sessionId = toCppSessionId(info->session_id);-- const auto *state =- reinterpret_cast<const ableton::Link::SessionState *>(session_state.impl);- const auto beats = cppInfo.beginBeats(*state, quantum);- if (!beats)- {- return false;- }- *out_beats = *beats;- return true;- }-- bool abl_link_audio_source_buffer_info_end_beats(- const struct abl_link_audio_source_buffer_info *info,- abl_link_session_state session_state,- double quantum,- double *out_beats)- {- if (!info || !out_beats || !session_state.impl)- {- return false;- }- if (info->sample_rate == 0)- {- return false;- }- auto cppInfo = ableton::LinkAudioSource::BufferHandle::Info{};- cppInfo.numChannels = info->num_channels;- cppInfo.numFrames = info->num_frames;- cppInfo.sampleRate = info->sample_rate;- cppInfo.count = info->count;- cppInfo.sessionBeatTime = info->session_beat_time;- cppInfo.tempo = info->tempo;- cppInfo.sessionId = toCppSessionId(info->session_id);-- const auto *state =- reinterpret_cast<const ableton::Link::SessionState *>(session_state.impl);- const auto beats = cppInfo.endBeats(*state, quantum);- if (!beats)- {- return false;- }- *out_beats = *beats;- return true;- }-- struct abl_link_audio_source abl_link_audio_source_create(struct abl_link link,- struct abl_link_audio_channel_id channel_id,- void (*callback)(const struct abl_link_audio_source_buffer *buffer, void *context),- void *context)- {- auto *cppLink = reinterpret_cast<ableton::LinkAudio *>(link.impl);- const auto id = toCppChannelId(channel_id);- return {reinterpret_cast<void *>(new ableton::LinkAudioSource(*cppLink, id,- [callback, context](ableton::LinkAudioSource::BufferHandle handle)- {- if (!callback)- {- return;- }- struct abl_link_audio_source_buffer buffer{};- buffer.samples = handle.samples;- buffer.info.num_channels = handle.info.numChannels;- buffer.info.num_frames = handle.info.numFrames;- buffer.info.sample_rate = handle.info.sampleRate;- buffer.info.count = handle.info.count;- buffer.info.session_beat_time = handle.info.sessionBeatTime;- buffer.info.tempo = handle.info.tempo;- buffer.info.session_id = toSessionId(handle.info.sessionId);- callback(&buffer, context);- }))};- }-- void abl_link_audio_source_destroy(struct abl_link_audio_source source)- {- delete reinterpret_cast<ableton::LinkAudioSource *>(source.impl);- }-- struct abl_link_audio_channel_id abl_link_audio_source_id(- struct abl_link_audio_source source)- {- if (!source.impl)- {- struct abl_link_audio_channel_id empty{};- return empty;- }- return toChannelId(reinterpret_cast<ableton::LinkAudioSource *>(source.impl)->id()); } }
link/include/ableton/Link.hpp view
@@ -22,8 +22,7 @@ #pragma once -#include <ableton/link/ApiConfig.hpp>-+#include <ableton/platforms/Config.hpp> #include <chrono> #include <mutex> @@ -104,13 +103,13 @@ /*! @brief: Is start/stop synchronization enabled? * Thread-safe: yes- * Realtime-safe: yes+ * Realtime-safe: no */ bool isStartStopSyncEnabled() const; /*! @brief: Enable start/stop synchronization. * Thread-safe: yes- * Realtime-safe: yes+ * Realtime-safe: no */ void enableStartStopSync(bool bEnable); @@ -245,9 +244,6 @@ public: SessionState(const link::ApiState state, const bool bRespectQuantum); - bool operator==(const SessionState& other) const;- bool operator!=(const SessionState& other) const;- /*! @brief: The tempo of the timeline, in Beats Per Minute. * * @discussion This is a stable value that is appropriate for display@@ -365,23 +361,23 @@ /*! @brief: Convenience function to start or stop transport at a given time and * attempt to map the given beat to this time in context of the given quantum. */- void setIsPlayingAndRequestBeatAtTime(bool isPlaying,- std::chrono::microseconds time,- double beat,- double quantum);+ void setIsPlayingAndRequestBeatAtTime(+ bool isPlaying, std::chrono::microseconds time, double beat, double quantum); private:- template <typename SessionState>- friend const link::ApiState& detail::linkApiState(const SessionState& sessionState);- friend BasicLink<Clock>; link::ApiState mOriginalState; link::ApiState mState; bool mbRespectQuantum; }; -protected:- using Controller = ableton::link::ApiController<Clock>;+private:+ using Controller = ableton::link::Controller<link::PeerCountCallback,+ link::TempoCallback,+ link::StartStopStateCallback,+ Clock,+ link::platform::Random,+ link::platform::IoContext>; std::mutex mCallbackMutex; link::PeerCountCallback mPeerCountCallback = [](std::size_t) {};
link/include/ableton/Link.ipp view
@@ -30,14 +30,11 @@ inline typename BasicLink<Clock>::SessionState toSessionState( const link::ClientState& state, const bool isConnected) {- return {{state.timeline,- state.timelineSessionId,- {state.startStopState.isPlaying, state.startStopState.time}},- isConnected};+ return {{state.timeline, {state.startStopState.isPlaying, state.startStopState.time}},+ isConnected}; } -inline link::IncomingClientState toIncomingClientState(- const link::ApiState& state,+inline link::IncomingClientState toIncomingClientState(const link::ApiState& state, const link::ApiState& originalState, const std::chrono::microseconds timestamp) {@@ -47,8 +44,7 @@ const auto startStopState = originalState.startStopState != state.startStopState ? link::OptionalClientStartStopState{{state.startStopState.isPlaying,- state.startStopState.time,- timestamp}}+ state.startStopState.time, timestamp}} : link::OptionalClientStartStopState{}; return {timeline, startStopState, timestamp}; }@@ -57,20 +53,16 @@ template <typename Clock> inline BasicLink<Clock>::BasicLink(const double bpm)- : mController(- link::Tempo(bpm),- [this](const std::size_t peers)- {+ : mController(link::Tempo(bpm),+ [this](const std::size_t peers) { std::lock_guard<std::mutex> lock(mCallbackMutex); mPeerCountCallback(peers); },- [this](const link::Tempo tempo)- {+ [this](const link::Tempo tempo) { std::lock_guard<std::mutex> lock(mCallbackMutex); mTempoCallback(tempo); },- [this](const bool isPlaying)- {+ [this](const bool isPlaying) { std::lock_guard<std::mutex> lock(mCallbackMutex); mStartStopCallback(isPlaying); },@@ -171,8 +163,8 @@ // Link::SessionState template <typename Clock>-inline BasicLink<Clock>::SessionState::SessionState(const link::ApiState state,- const bool bRespectQuantum)+inline BasicLink<Clock>::SessionState::SessionState(+ const link::ApiState state, const bool bRespectQuantum) : mOriginalState(state) , mState(state) , mbRespectQuantum(bRespectQuantum)@@ -180,19 +172,6 @@ } template <typename Clock>-inline bool BasicLink<Clock>::SessionState::operator==(const SessionState& other) const-{- return std::tie(mOriginalState, mState, mbRespectQuantum)- == std::tie(other.mOriginalState, other.mState, other.mbRespectQuantum);-}--template <typename Clock>-inline bool BasicLink<Clock>::SessionState::operator!=(const SessionState& other) const-{- return !(operator==(other));-}--template <typename Clock> inline double BasicLink<Clock>::SessionState::tempo() const { return mState.timeline.tempo.bpm();@@ -238,19 +217,18 @@ { if (mbRespectQuantum) {- time = timeAtBeat(- link::nextPhaseMatch(- link::Beats{beatAtTime(time, quantum)}, link::Beats{beat}, link::Beats{quantum})- .floating(),+ time = timeAtBeat(link::nextPhaseMatch(link::Beats{beatAtTime(time, quantum)},+ link::Beats{beat}, link::Beats{quantum})+ .floating(), quantum); } forceBeatAtTime(beat, time, quantum); } inline void forceBeatAtTimeImpl(link::Timeline& timeline,- const link::Beats beat,- const std::chrono::microseconds time,- const link::Beats quantum)+ const link::Beats beat,+ const std::chrono::microseconds time,+ const link::Beats quantum) { // There are two components to the beat adjustment: a phase shift // and a beat magnitude adjustment.
− link/include/ableton/LinkAudio.hpp
@@ -1,358 +0,0 @@-/*! @file LinkAudio.hpp- * @copyright 2025, Ableton AG, Berlin. All rights reserved.- * @brief Library for cross-device shared tempo, quantized beat grid, and sharing audio- *- * @license:- * This program is free software: you can redistribute it and/or modify- * it under the terms of the GNU General Public License as published by- * the Free Software Foundation, either version 2 of the License, or- * (at your option) any later version.- *- * This program is distributed in the hope that it will be useful,- * but WITHOUT ANY WARRANTY; without even the implied warranty of- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- * GNU General Public License for more details.- *- * You should have received a copy of the GNU General Public License- * along with this program. If not, see <http://www.gnu.org/licenses/>.- *- * If you would like to incorporate Link into a proprietary software application,- * please contact <link-devs@ableton.com>.- */--#pragma once--#define LINK_AUDIO YES--#include <ableton/link_audio/ApiConfig.hpp>--#include <memory>-#include <optional>-#include <string>-#include <vector>--namespace ableton-{--/*! @class LinkAudio and BasicLinkAudio- * @brief LinkAudio provides the Link functionality plus audio sharing.- * To enable audio sharing include this header and replace the Link class with the- * LinkAudio and Link should not be used simultaneously.- *- * @discussion- * LinkAudio provides the same functionality as Link. See Link.hpp for the respective- * documentation. On top of that, LinkAudio allows to announce and discover audio- * channels in a Link session. When sending and receiving audio, the Link beat time grid- * and quantum can be used to align audio from different peers.- *- * Channels in a Link session are represented as sinks on the sending side and sources on- * the receiving side.- * Sinks only send audio if at least one corresponding source is present in the session.- * Audio buffers are interleaved and samples are represented as 16-bit signed integers.- */--template <typename Clock>-class BasicLinkAudio : public BasicLink<Clock>-{-public:- /*! @brief Construct with an initial tempo and local peer name for identification in the- * Link session. Names longer than 256 characters will be truncated.- */- BasicLinkAudio(double bpm, std::string name);-- ~BasicLinkAudio();-- /*! @brief Is audio currently enabled?- * Thread-safe: yes- * Realtime-safe: yes- */- bool isLinkAudioEnabled() const;-- /*! @brief Enable or disable audio.- * Thread-safe: yes- * Realtime-safe: no- */- void enableLinkAudio(bool bEnable);-- /*! @brief Get the local peer name for identification in the Link session.- * Thread-safe: yes- * Realtime-safe: no- */- std::string peerName() const;-- /*! @brief Change the local peer name for identification in the Link session.- * Names longer than 256 characters will be truncated.- * Thread-safe: yes- * Realtime-safe: no- */- void setPeerName(std::string name);-- /*! @brief Register a callback to be notified when the set of available- * audio channels changes. This will be called when channels are discovered or- * disappeared and when names change.- * Thread-safe: yes- * Realtime-safe: no- *- * @discussion The callback is invoked on a Link-managed thread.- * @param callback The callback signature is: void ()- */- template <typename Callback>- void setChannelsChangedCallback(Callback callback);-- /*! @struct Channel- * @brief Describes an audio channel available in the Link session.- * @discussion- * The unique identifiers for channels and peers are persistent for the lifetime of a- * channel. Names may change over time and are meant for display purposes.- */- struct Channel- {- ChannelId id; /*!< Unique identifier for the channel. */- std::string name; /*!< Name of the channel. */- PeerId peerId; /*!< Identifier of the peer providing the channel. */- std::string peerName; /*!< Name of the peer providing the channel. */- };-- /*! @brief Get the list of currently available audio channels in the session.- * Thread-safe: yes- * Realtime-safe: no- */- std::vector<Channel> channels() const;-- /*! @brief Call a function on the Link thread.- * Thread-safe: yes- * Realtime-safe: no- *- * @discussion The function will be called on the Link thread, which is managed by the- * LinkAudio instance. This is useful for setting the thread priority for example.- * @param func The function signature is: void ()- */- template <typename Function>- void callOnLinkThread(Function func);--private:- using Controller = ableton::link::ApiController<Clock>;-- link_audio::ChannelsChangedCallback mChannelsChangedCallback = []() {};-};--class LinkAudio : public BasicLinkAudio<link::platform::Clock>-{-public:- using Clock = link::platform::Clock;-- LinkAudio(double bpm, std::string name)- : BasicLinkAudio<Clock>(bpm, name)- {- }--private:- friend class LinkAudioSink;- friend class LinkAudioSource;-};--/*! @class LinkAudioSink- * @brief Announces an audio channel to the Link session.- *- * @discussion- * The announced channel is visible to other peers for the lifetime of the sink.- * The sink can be used to write audio samples, which will be sent to peers that have- * respective sources.- */-class LinkAudioSink-{-public:- /*! @brief Construct a LinkAudioSink with a LinkAudio instance, a name of the audio- * channel, and the maximum buffer size in samples. This buffer size should account for- * the number of channels times the number of samples per channel in one audio- * callback. Names longer than 256 characters will be truncated.- */- template <typename LinkAudio>- LinkAudioSink(LinkAudio& link, std::string name, size_t maxNumSamples);-- LinkAudioSink(const LinkAudioSink&) = default;- LinkAudioSink& operator=(const LinkAudioSink&) = default;- LinkAudioSink(LinkAudioSink&&) = default;- LinkAudioSink& operator=(LinkAudioSink&&) = default;-- /*! @brief Get the name of the channel.- * Thread-safe: no- * Realtime-safe: no- */- std::string name() const;-- /*! @brief Set the name of this channel. Names longer than 256 characters will be- * truncated.- * Thread-safe: no- * Realtime-safe: no- */- void setName(std::string name);-- /*! @brief Request a maximum buffer size for future buffers.- * Thread-safe: yes- * Realtime-safe: yes- *- * @discussion Increase the number of samples retained buffer handles can hold. If the- * requested number of samples is smaller than the current maximum number of samples- * this is a no-op.- */- void requestMaxNumSamples(size_t numSamples);-- /*! @brief Get the current maximum number of samples a buffer handle can hold.- * Thread-safe: yes- * Realtime-safe: yes- */- size_t maxNumSamples() const;-- /*! @struct BufferHandle- * @brief Handle to a buffer for writing audio samples.- */- struct BufferHandle- {- /*! @brief Retain a buffer for writing audio samples. Only on BufferHandle can be- * retained at a time. A BufferHandle should never outlive the LinkAudioSink it was- * created from.- * Thread-safe: no- * Realtime-safe: yes- */- BufferHandle(LinkAudioSink&);-- BufferHandle(const BufferHandle&) = delete;- BufferHandle(BufferHandle&& other) = delete;- BufferHandle& operator=(const BufferHandle&) = delete;- BufferHandle& operator=(BufferHandle&& other) = delete;-- ~BufferHandle();-- /*! @brief Check if the handle is valid. Make sure to check this before- * using the handle. The handle may be invalid if no corresponding source exists or- * no buffer is available.- *- * Thread-safe: no- * Realtime-safe: yes- */- operator bool() const;- int16_t* samples; /*!< Pointer to the buffer for writing samples. */- size_t maxNumSamples; /*!< Maximum number of samples that can be written. */--- /*! @brief Commit the buffer after writing samples. After this the buffer the object- * should not be used anymore.- * @param sessionState The current Link session state.- * @param beatsAtBufferBegin Beat at the start of the buffer.- * @param quantum Quantum value for beat mapping.- * @param numFrames Number of frames written. numFrames * numChannels may not exceed- * maxNumSamples.- * @param numChannels Number of channels. Can be 1 for mono or 2 for stereo.- * @param sampleRate Sample rate in Hz.- * @return True if the buffer was successfully committed.- *- * Thread-safe: no- * Realtime-safe: yes- *- * @discussion The Link session state, the quantum, and the beats at buffer begin- * must be same as used for rendering the audio locally. Changes to the Link session- * state should always be made before rendering and eventually writing the buffer.- */- template <typename SessionState>- bool commit(const SessionState&,- double beatsAtBufferBegin,- double quantum,- size_t numFrames,- size_t numChannels,- uint32_t sampleRate);-- private:- std::weak_ptr<link_audio::Sink> mpSink;- link_audio::Buffer<int16_t>* mpBuffer;- };--private:- friend struct BufferHandle;- std::shared_ptr<link_audio::Sink> mpImpl;-};--/*! @class LinkAudioSource- * @brief Receives audio streams from other peers in the Link session.- *- * @discussion- * LinkAudioSource allows an application to subscribe to an audio channel- * published by another peer, receiving buffers as they become available.- */-class LinkAudioSource-{-public:- struct BufferHandle;-- /*! @brief Construct a LinkAudioSource to receive audio for a specifc channel.- * @param link The LinkAudio instance.- * @param id The ID of the channel to be received.- * @param callback Callback invoked on a Link-managed thread when a buffer is received.- * The callback signature is: void (BufferHandle bufferHandle)- */- template <typename LinkAudio, typename Callback>- LinkAudioSource(LinkAudio& link, ChannelId id, Callback callback);-- LinkAudioSource(const LinkAudioSource&) = default;- LinkAudioSource& operator=(const LinkAudioSource&) = default;- LinkAudioSource(LinkAudioSource&&) = default;- LinkAudioSource& operator=(LinkAudioSource&&) = default;-- ~LinkAudioSource();-- /*! @brief Get the channel ID of the corresponding source.- * Thread-safe: yes- * Realtime-safe: yes- */- ChannelId id() const;-- /*! @struct BufferHandle- * @brief Handle to a buffer containing received audio samples.- */- struct BufferHandle- {- /*! @struct Info- * @brief Metadata about the received audio buffer.- */- struct Info- {- size_t numChannels; /*!< Number of channels in the buffer. */- size_t numFrames; /*!< Number of frames in the buffer. */- uint32_t sampleRate; /*!< Sample rate in Hz. */- uint64_t count; /*!< Sequence number of the buffer. */- double sessionBeatTime; /*!< Use beginBeats() to map this to local beat time. */- double tempo; /*!< Tempo in beats per minute. */- SessionId sessionId; /*!< ID of the session the buffer belongs to. */-- /*! @brief Map the beat time at the begin of the buffer to the local Link session- * state.- * @param sessionState The current Link session state.- * @param quantum Quantum value for beat mapping.- * @return Local beat time at buffer begin. Returns nullopt if the buffer- * originates from a different Link Session.- */- template <typename SessionState>- std::optional<double> beginBeats(const SessionState&, double quantum) const;-- /*! @brief Map the beat time at the end of the buffer to the local Link session- * state.- * @param sessionState The current Link session state.- * @param quantum Quantum value for beat mapping.- * @return Local beat time at buffer end. Returns nullopt if the buffer- * originates from a different Link Session.- */- template <typename SessionState>- std::optional<double> endBeats(const SessionState&, double quantum) const;- };-- int16_t* samples; /*!< Pointer to the buffer of received samples. */- Info info; /*!< Information about the buffer. */- };--private:- std::shared_ptr<link_audio::Source> mpImpl;-};--} // namespace ableton--#include <ableton/LinkAudio.ipp>
− link/include/ableton/LinkAudio.ipp
@@ -1,267 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- * This program is free software: you can redistribute it and/or modify- * it under the terms of the GNU General Public License as published by- * the Free Software Foundation, either version 2 of the License, or- * (at your option) any later version.- *- * This program is distributed in the hope that it will be useful,- * but WITHOUT ANY WARRANTY; without even the implied warranty of- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- * GNU General Public License for more details.- *- * You should have received a copy of the GNU General Public License- * along with this program. If not, see <http://www.gnu.org/licenses/>.- *- * If you would like to incorporate Link into a proprietary software application,- * please contact <link-devs@ableton.com>.- */--#pragma once--#include <string>--namespace ableton-{--template <typename Clock>-inline BasicLinkAudio<Clock>::BasicLinkAudio(const double bpm, std::string name)- : BasicLink<Clock>(bpm)-{- setPeerName(name);- this->mController.setChannelsChangedCallback(- [&]()- {- std::lock_guard<std::mutex> lock(this->mCallbackMutex);- mChannelsChangedCallback();- });-}--template <typename Clock>-inline BasicLinkAudio<Clock>::~BasicLinkAudio()-{- this->mController.setChannelsChangedCallback([]() {});-}--template <typename Clock>-inline bool BasicLinkAudio<Clock>::isLinkAudioEnabled() const-{- return this->mController.isLinkAudioEnabled();-}--template <typename Clock>-inline void BasicLinkAudio<Clock>::enableLinkAudio(const bool bEnable)-{- this->mController.enableLinkAudio(bEnable);-}--template <typename Clock>-inline std::string BasicLinkAudio<Clock>::peerName() const-{- return this->mController.name();-}--template <typename Clock>-inline void BasicLinkAudio<Clock>::setPeerName(std::string name)-{- if (name.size() > link_audio::v1::kMaxNameSize)- {- name.resize(link_audio::v1::kMaxNameSize);- }- this->mController.setName(std::move(name));-}--template <typename Clock>-template <typename Callback>-inline void BasicLinkAudio<Clock>::setChannelsChangedCallback(Callback callback)-{- std::lock_guard<std::mutex> lock(this->mCallbackMutex);- mChannelsChangedCallback = callback;-}--template <typename Clock>-inline std::vector<typename BasicLinkAudio<Clock>::Channel> BasicLinkAudio<- Clock>::channels() const-{- auto channels = this->mController.channels();- auto result = std::vector<typename BasicLinkAudio<Clock>::Channel>{};- result.reserve(channels.size());- for (auto& channel : channels)- {- result.push_back(typename BasicLinkAudio<Clock>::Channel{- channel.id, channel.name, channel.peerId, channel.peerName});- }- return result;-}--template <typename Clock>-template <typename Function>-inline void BasicLinkAudio<Clock>::callOnLinkThread(Function func)-{- this->mController.callOnLinkThread(std::move(func));-}--template <typename LinkAudio>-inline LinkAudioSink::LinkAudioSink(LinkAudio& link,- std::string name,- size_t maxNumSamples)- : mpImpl{link.mController.addSink(name.size() > link_audio::v1::kMaxNameSize- ? name.substr(0, link_audio::v1::kMaxNameSize)- : std::move(name),- maxNumSamples)}-{-}--inline std::string LinkAudioSink::name() const-{- return mpImpl->name();-}--inline void LinkAudioSink::setName(std::string name)-{- if (name.size() > link_audio::v1::kMaxNameSize)- {- name.resize(link_audio::v1::kMaxNameSize);- }- mpImpl->setName(std::move(name));-}--inline LinkAudioSink::BufferHandle::BufferHandle(LinkAudioSink& sink)- : samples(nullptr)- , maxNumSamples(0)- , mpSink(sink.mpImpl)- , mpBuffer(nullptr)-{- if (auto pBuffer = sink.mpImpl->retainBuffer())- {- samples = pBuffer->mSamples.data();- maxNumSamples = pBuffer->mSamples.size();- mpBuffer = pBuffer;- }-}--inline LinkAudioSink::BufferHandle::~BufferHandle()-{- // BufferHandle should not outlive the LinkAudioSink it was created from- assert(mpSink.lock());-- if (mpBuffer)- {- if (auto pSink = mpSink.lock())- {- pSink->releaseBuffer();- }- }-}--inline LinkAudioSink::BufferHandle::operator bool() const-{- return mpBuffer != nullptr;-}--template <typename SessionState>-inline bool LinkAudioSink::BufferHandle::commit(const SessionState& sessionState,- const double beatsAtBufferBegin,- const double quantum,- const size_t numFrames,- const size_t numChannels,- const uint32_t sampleRate)-{- const auto result = static_cast<bool>(*this) && (numChannels == 1 || numChannels == 2)- && maxNumSamples >= numFrames * numChannels;-- if (result && mpBuffer)- {- if (auto pSink = mpSink.lock())- {- pSink->releaseAndCommitBuffer(detail::linkApiState(sessionState).timeline,- detail::linkApiState(sessionState).timelineSessionId,- beatsAtBufferBegin,- quantum,- numFrames,- numChannels,- sampleRate);- }- }-- mpBuffer = nullptr;-- return result;-}--template <typename SessionState>-inline std::optional<double> LinkAudioSource::BufferHandle::Info::beginBeats(- const SessionState& sessionState, const double quantum) const-{- const auto& state = detail::linkApiState(sessionState);- if (state.timelineSessionId != sessionId)- {- return std::nullopt;- }-- return link_audio::beatAtGlobalBeat(- state.timeline, link::Beats{sessionBeatTime}, link::Beats{quantum})- .floating();-}---template <typename SessionState>-inline std::optional<double> LinkAudioSource::BufferHandle::Info::endBeats(- const SessionState& sessionState, const double quantum) const-{- const auto& state = detail::linkApiState(sessionState);- if (state.timelineSessionId != sessionId)- {- return std::nullopt;- }-- const auto durationSeconds =- static_cast<double>(numFrames) / static_cast<double>(sampleRate);- const auto beatsPerSecond = tempo / 60.0;- const auto endBeats = link::Beats{sessionBeatTime + durationSeconds * beatsPerSecond};- return link_audio::beatAtGlobalBeat(state.timeline, endBeats, link::Beats{quantum})- .floating();-}---template <typename LinkAudio, typename Callback>-inline LinkAudioSource::LinkAudioSource(LinkAudio& link, ChannelId id, Callback callback)- : mpImpl{link.mController.addSource(- std::move(id),- [callback](auto handle)- {- auto info = LinkAudioSource::BufferHandle::Info{};- info.numChannels = handle.mBuffer.mNumChannels;- info.numFrames = handle.mBuffer.mNumFrames;- info.sampleRate = handle.mBuffer.mSampleRate;- info.count = handle.mBuffer.mCount;- info.sessionBeatTime = handle.mBuffer.mBeginBeats.floating();- info.tempo = handle.mBuffer.mTempo.bpm();- info.sessionId = handle.mBuffer.mSessionId;-- callback(LinkAudioSource::BufferHandle{handle.mpSamples, info});- })}-{-}--inline LinkAudioSource::~LinkAudioSource()-{- mpImpl->setCallback([](auto) {});-}--inline void LinkAudioSink::requestMaxNumSamples(size_t numSamples)-{- mpImpl->requestMaxNumSamples(numSamples);-}--inline size_t LinkAudioSink::maxNumSamples() const-{- return mpImpl->maxNumSamples();-}--inline ChannelId LinkAudioSource::id() const-{- return mpImpl->id();-}--} // namespace ableton
link/include/ableton/discovery/AsioTypes.hpp view
@@ -32,14 +32,8 @@ using UdpSocket = LINK_ASIO_NAMESPACE::ip::udp::socket; using UdpEndpoint = LINK_ASIO_NAMESPACE::ip::udp::endpoint; -template <typename... Args>-inline IpAddress makeAddress(Args&&... args)-{- return LINK_ASIO_NAMESPACE::ip::make_address(std::forward<Args>(args)...);-}- template <typename AsioAddrType>-AsioAddrType makeAddressFromBytes(const char* pAddr)+AsioAddrType makeAddress(const char* pAddr) { using namespace std; typename AsioAddrType::bytes_type bytes;@@ -48,7 +42,7 @@ } template <typename AsioAddrType>-AsioAddrType makeAddressFromBytes(const char* pAddr, uint32_t scopeId)+AsioAddrType makeAddress(const char* pAddr, uint32_t scopeId) { using namespace std; typename AsioAddrType::bytes_type bytes;
link/include/ableton/discovery/InterfaceScanner.hpp view
@@ -38,8 +38,8 @@ using Timer = typename util::Injected<IoContext>::type::Timer; InterfaceScanner(const std::chrono::seconds period,- util::Injected<Callback> callback,- util::Injected<IoContext> io)+ util::Injected<Callback> callback,+ util::Injected<IoContext> io) : mPeriod(period) , mCallback(std::move(callback)) , mIo(std::move(io))@@ -73,14 +73,12 @@ // setup the next scanning mTimer.expires_from_now(mPeriod); using ErrorCode = typename Timer::ErrorCode;- mTimer.async_wait(- [this](const ErrorCode e)+ mTimer.async_wait([this](const ErrorCode e) {+ if (!e) {- if (!e)- {- scan();- }- });+ scan();+ }+ }); } private:
link/include/ableton/discovery/IpInterface.hpp view
@@ -29,13 +29,15 @@ inline UdpEndpoint multicastEndpointV4() {- return {makeAddress("224.76.78.75"), 20808};+ return {IpAddressV4::from_string("224.76.78.75"), 20808}; } inline UdpEndpoint multicastEndpointV6(uint64_t scopeId) { // This is a non-permanently-assigned link-local multicast address (RFC4291)- return {makeAddress("ff12::8080%" + std::to_string(scopeId)), 20808};+ return {+ ::LINK_ASIO_NAMESPACE::ip::make_address("ff12::8080%" + std::to_string(scopeId)),+ 20808}; } // Type tags for dispatching between unicast and multicast packets@@ -70,9 +72,8 @@ } - std::size_t send(const uint8_t* const pData,- const size_t numBytes,- const UdpEndpoint& to)+ std::size_t send(+ const uint8_t* const pData, const size_t numBytes, const UdpEndpoint& to) { return mSendSocket.send(pData, numBytes, to); }@@ -90,7 +91,10 @@ SocketReceiver<MulticastTag, Handler>(std::move(handler))); } - UdpEndpoint endpoint() const { return mSendSocket.endpoint(); }+ UdpEndpoint endpoint() const+ {+ return mSendSocket.endpoint();+ } private: template <typename Tag, typename Handler>@@ -116,8 +120,8 @@ }; template <std::size_t MaxPacketSize, typename IoContext>-IpInterface<IoContext, MaxPacketSize> makeIpInterface(util::Injected<IoContext> io,- const IpAddress& addr)+IpInterface<IoContext, MaxPacketSize> makeIpInterface(+ util::Injected<IoContext> io, const IpAddress& addr) { return {std::move(io), addr}; }
link/include/ableton/discovery/NetworkByteStreamSerializable.hpp view
@@ -32,8 +32,6 @@ #include <chrono> #include <cstdint>-#include <iterator>-#include <string> #include <type_traits> #include <utility> #include <vector>@@ -87,7 +85,7 @@ // Default size implementation. Works for primitive types. template <typename T,- typename std::enable_if<std::is_fundamental<T>::value>::type* = nullptr>+ typename std::enable_if<std::is_fundamental<T>::value>::type* = nullptr> std::uint32_t sizeInByteStream(T) { return sizeof(T);@@ -242,25 +240,6 @@ } }; -// int16_t in terms of uint16_t-template <typename It>-It toNetworkByteStream(int16_t i, It out)-{- return toNetworkByteStream(reinterpret_cast<const uint16_t&>(i), std::move(out));-}--template <>-struct Deserialize<int16_t>-{- template <typename It>- static std::pair<int16_t, It> fromNetworkByteStream(It begin, It end)- {- auto result =- Deserialize<uint16_t>::fromNetworkByteStream(std::move(begin), std::move(end));- return std::make_pair(reinterpret_cast<const int16_t&>(result.first), result.second);- }-};- // bool inline std::uint32_t sizeInByteStream(bool) {@@ -295,7 +274,7 @@ It toNetworkByteStream(const std::chrono::microseconds micros, It out) { static_assert(sizeof(int64_t) == sizeof(std::chrono::microseconds::rep),- "The size of microseconds::rep must match the size of int64_t.");+ "The size of microseconds::rep must matche the size of int64_t."); return toNetworkByteStream(static_cast<int64_t>(micros.count()), std::move(out)); } @@ -312,34 +291,6 @@ } }; -// string-inline std::uint32_t sizeInByteStream(const std::string& str)-{- return sizeof(std::uint32_t) + static_cast<std::uint32_t>(str.size());-}--template <typename It>-It toNetworkByteStream(const std::string& str, It out)-{- static_assert(sizeof(std::uint8_t) == sizeof(char),- "The size of char must match the size of uint8_t.");- out = toNetworkByteStream(static_cast<std::uint32_t>(str.size()), out);- return std::copy(str.begin(), str.end(), out);-}--template <>-struct Deserialize<std::string>-{- template <typename It>- static std::pair<std::string, It> fromNetworkByteStream(It bytesBegin, It bytesEnd)- {- const auto result = Deserialize<uint32_t>::fromNetworkByteStream(- std::move(bytesBegin), std::move(bytesEnd));- const auto endIt = std::next(result.second, result.first);- return std::make_pair(std::string(result.second, endIt), endIt);- }-};- namespace detail { @@ -368,9 +319,9 @@ template <typename T, typename BytesIt, typename InsertIt> BytesIt deserializeContainer(BytesIt bytesBegin,- const BytesIt bytesEnd,- InsertIt contBegin,- const std::uint32_t maxElements)+ const BytesIt bytesEnd,+ InsertIt contBegin,+ const std::uint32_t maxElements) { using namespace std; std::uint32_t numElements = 0;@@ -434,17 +385,15 @@ struct Deserialize<std::vector<T, Alloc>> { template <typename It>- static std::pair<std::vector<T, Alloc>, It> fromNetworkByteStream(It bytesBegin,- It bytesEnd)+ static std::pair<std::vector<T, Alloc>, It> fromNetworkByteStream(+ It bytesBegin, It bytesEnd) { using namespace std; auto result_size = Deserialize<uint32_t>::fromNetworkByteStream(std::move(bytesBegin), bytesEnd); vector<T, Alloc> result; auto resultIt = detail::deserializeContainer<T>(std::move(result_size.second),- std::move(bytesEnd),- back_inserter(result),- result_size.first);+ std::move(bytesEnd), back_inserter(result), result_size.first); return make_pair(std::move(result), std::move(resultIt)); } };@@ -489,9 +438,8 @@ It toNetworkByteStream(const std::tuple<X, Y, Z>& tup, It out) { return toNetworkByteStream(- std::get<2>(tup),- toNetworkByteStream(- std::get<1>(tup), toNetworkByteStream(std::get<0>(tup), std::move(out))));+ std::get<2>(tup), toNetworkByteStream(std::get<1>(tup),+ toNetworkByteStream(std::get<0>(tup), std::move(out)))); } template <typename X, typename Y, typename Z>
link/include/ableton/discovery/Payload.hpp view
@@ -166,8 +166,8 @@ // Concatenate payloads together into a single payload template <typename RhsFirst, typename RhsRest>- friend PayloadSum<RhsFirst, RhsRest> operator+(Payload lhs,- Payload<RhsFirst, RhsRest> rhs)+ friend PayloadSum<RhsFirst, RhsRest> operator+(+ Payload lhs, Payload<RhsFirst, RhsRest> rhs) { return {std::move(lhs.mFirst), std::move(lhs.mRest) + std::move(rhs)}; }@@ -200,7 +200,10 @@ return rhs; } - friend std::size_t sizeInByteStream(const Payload&) { return 0; }+ friend std::size_t sizeInByteStream(const Payload&)+ {+ return 0;+ } template <typename It> friend It toNetworkByteStream(const Payload&, It streamIt)@@ -233,7 +236,10 @@ template <> struct PayloadBuilder<> {- Payload<> operator()() { return {}; }+ Payload<> operator()()+ {+ return {};+ } }; // Parse payloads to values@@ -252,17 +258,20 @@ } template <typename It, typename FirstHandler, typename... RestHandlers>- static void collectHandlers(detail::HandlerMap<It>& map,- FirstHandler handler,- RestHandlers... rest)+ static void collectHandlers(+ detail::HandlerMap<It>& map, FirstHandler handler, RestHandlers... rest) { using namespace std;- map[First::key] = [handler](const It begin, const It end)- {+ map[First::key] = [handler](const It begin, const It end) { const auto res = First::fromNetworkByteStream(begin, end); if (res.second != end) {- throw range_error("Parsing payload failed");+ std::ostringstream stringStream;+ stringStream << "Parsing payload entry " << First::key+ << " did not consume the expected number of bytes. "+ << " Expected: " << distance(begin, end)+ << ", Actual: " << distance(begin, res.second);+ throw range_error(stringStream.str()); } handler(res.first); };
link/include/ableton/discovery/PeerGateway.hpp view
@@ -42,8 +42,8 @@ using TimerError = typename Timer::ErrorCode; PeerGateway(util::Injected<Messenger> messenger,- util::Injected<PeerObserver> observer,- util::Injected<IoContext> io)+ util::Injected<PeerObserver> observer,+ util::Injected<IoContext> io) : mpImpl(new Impl(std::move(messenger), std::move(observer), std::move(io))) { mpImpl->listen();@@ -57,7 +57,10 @@ { } - void updateState(NodeState state) { mpImpl->updateState(std::move(state)); }+ void updateState(NodeState state)+ {+ mpImpl->updateState(std::move(state));+ } private: using PeerTimeout = std::pair<std::chrono::system_clock::time_point, NodeId>;@@ -66,8 +69,8 @@ struct Impl : std::enable_shared_from_this<Impl> { Impl(util::Injected<Messenger> messenger,- util::Injected<PeerObserver> observer,- util::Injected<IoContext> io)+ util::Injected<PeerObserver> observer,+ util::Injected<IoContext> io) : mMessenger(std::move(messenger)) , mObserver(std::move(observer)) , mIo(std::move(io))@@ -88,7 +91,10 @@ } } - void listen() { mMessenger->receive(util::makeAsyncSafe(this->shared_from_this())); }+ void listen()+ {+ mMessenger->receive(util::makeAsyncSafe(this->shared_from_this()));+ } // Operators for handling incoming messages void operator()(const PeerState<NodeState>& msg)@@ -144,13 +150,10 @@ const auto endExpired = lower_bound(begin(mPeerTimeouts), end(mPeerTimeouts), test, TimeoutCompare{}); - for_each(begin(mPeerTimeouts),- endExpired,- [this](const PeerTimeout& pto)- {- info(mIo->log()) << "pruning peer " << pto.second;- peerTimedOut(*mObserver, pto.second);- });+ for_each(begin(mPeerTimeouts), endExpired, [this](const PeerTimeout& pto) {+ info(mIo->log()) << "pruning peer " << pto.second;+ peerTimedOut(*mObserver, pto.second);+ }); mPeerTimeouts.erase(begin(mPeerTimeouts), endExpired); scheduleNextPruning(); }@@ -168,14 +171,12 @@ << mPeerTimeouts.front().second; mPruneTimer.expires_at(t);- mPruneTimer.async_wait(- [this](const TimerError e)+ mPruneTimer.async_wait([this](const TimerError e) {+ if (!e) {- if (!e)- {- pruneExpiredPeers();- }- });+ pruneExpiredPeers();+ }+ }); } } @@ -189,10 +190,8 @@ typename PeerTimeouts::iterator findPeer(const NodeId& peerId) {- return std::find_if(begin(mPeerTimeouts),- end(mPeerTimeouts),- [&peerId](const PeerTimeout& pto)- { return pto.second == peerId; });+ return std::find_if(begin(mPeerTimeouts), end(mPeerTimeouts),+ [&peerId](const PeerTimeout& pto) { return pto.second == peerId; }); } util::Injected<Messenger> mMessenger;@@ -223,13 +222,12 @@ template <typename PeerObserver, typename StateQuery, typename IoContext> using Gateway = PeerGateway<Messenger<StateQuery, typename util::Injected<IoContext>::type&>,- PeerObserver,- IoContext>;+ PeerObserver,+ IoContext>; // Factory function to bind a PeerGateway to an IpInterface with the given address. template <typename PeerObserver, typename NodeState, typename IoContext>-Gateway<PeerObserver, NodeState, IoContext> makeGateway(- util::Injected<IoContext> io,+Gateway<PeerObserver, NodeState, IoContext> makeGateway(util::Injected<IoContext> io, const IpAddress& addr, util::Injected<PeerObserver> observer, NodeState state)
link/include/ableton/discovery/PeerGateways.hpp view
@@ -35,17 +35,15 @@ { public: using IoType = typename util::Injected<IoContext>::type;- using FactoryType = typename util::Injected<GatewayFactory>::type;- using Gateway = std::invoke_result_t<FactoryType,- NodeState,- util::Injected<IoType&>,- const discovery::IpAddress&>;+ using Gateway = decltype(std::declval<GatewayFactory>()(std::declval<NodeState>(),+ std::declval<util::Injected<IoType&>>(),+ std::declval<IpAddress>())); using GatewayMap = std::map<IpAddress, Gateway>; PeerGateways(const std::chrono::seconds rescanPeriod,- NodeState state,- util::Injected<GatewayFactory> factory,- util::Injected<IoContext> io)+ NodeState state,+ GatewayFactory factory,+ util::Injected<IoContext> io) : mIo(std::move(io)) { mpScannerCallback =@@ -69,7 +67,6 @@ void enable(const bool bEnable) { mpScannerCallback->mGateways.clear();- mpScannerCallback->mFactory->gatewaysChanged(); mpScanner->enable(bEnable); } @@ -94,7 +91,6 @@ { if (mpScannerCallback->mGateways.erase(gatewayAddr)) {- mpScannerCallback->mFactory->gatewaysChanged(); // If we erased a gateway, rescan again immediately so that // we will re-initialize it if it's still present mpScanner->scan();@@ -104,7 +100,7 @@ private: struct Callback {- Callback(NodeState state, util::Injected<GatewayFactory> factory, IoType& io)+ Callback(NodeState state, GatewayFactory factory, IoType& io) : mState(std::move(state)) , mFactory(std::move(factory)) , mIo(io)@@ -118,26 +114,18 @@ // Get the set of current addresses. vector<IpAddress> curAddrs; curAddrs.reserve(mGateways.size());- transform(std::begin(mGateways),- std::end(mGateways),- back_inserter(curAddrs),- [](const typename GatewayMap::value_type& vt) { return vt.first; });+ transform(std::begin(mGateways), std::end(mGateways), back_inserter(curAddrs),+ [](const typename GatewayMap::value_type& vt) { return vt.first; }); // Now use set_difference to determine the set of addresses that // are new and the set of cur addresses that are no longer there vector<IpAddress> newAddrs;- set_difference(std::begin(range),- std::end(range),- std::begin(curAddrs),- std::end(curAddrs),- back_inserter(newAddrs));+ set_difference(std::begin(range), std::end(range), std::begin(curAddrs),+ std::end(curAddrs), back_inserter(newAddrs)); vector<IpAddress> staleAddrs;- set_difference(std::begin(curAddrs),- std::end(curAddrs),- std::begin(range),- std::end(range),- back_inserter(staleAddrs));+ set_difference(std::begin(curAddrs), std::end(curAddrs), std::begin(range),+ std::end(range), back_inserter(staleAddrs)); // Remove the stale addresses for (const auto& addr : staleAddrs)@@ -151,7 +139,7 @@ try { info(mIo.log()) << "initializing peer gateway on interface " << addr;- mGateways.emplace(addr, (*mFactory)(mState, util::injectRef(mIo), addr));+ mGateways.emplace(addr, mFactory(mState, util::injectRef(mIo), addr)); } catch (const runtime_error& e) {@@ -159,15 +147,10 @@ << " reason: " << e.what(); } }-- if (!staleAddrs.empty() || !newAddrs.empty())- {- mFactory->gatewaysChanged();- } } NodeState mState;- util::Injected<GatewayFactory> mFactory;+ GatewayFactory mFactory; IoType& mIo; GatewayMap mGateways; };@@ -183,12 +166,13 @@ std::unique_ptr<PeerGateways<NodeState, GatewayFactory, IoContext>> makePeerGateways( const std::chrono::seconds rescanPeriod, NodeState state,- util::Injected<GatewayFactory> factory,+ GatewayFactory factory, util::Injected<IoContext> io) {+ using namespace std; using Gateways = PeerGateways<NodeState, GatewayFactory, IoContext>;- return std::make_unique<Gateways>(- rescanPeriod, std::move(state), std::move(factory), std::move(io));+ return unique_ptr<Gateways>{+ new Gateways{rescanPeriod, std::move(state), std::move(factory), std::move(io)}}; } } // namespace discovery
link/include/ableton/discovery/Service.hpp view
@@ -32,9 +32,7 @@ public: using ServicePeerGateways = PeerGateways<NodeState, GatewayFactory, IoContext>; - Service(NodeState state,- util::Injected<GatewayFactory> factory,- util::Injected<IoContext> io)+ Service(NodeState state, GatewayFactory factory, util::Injected<IoContext> io) : mEnabled(false) , mGateways( std::chrono::seconds(5), std::move(state), std::move(factory), std::move(io))@@ -47,7 +45,10 @@ mGateways.enable(bEnable); } - bool isEnabled() const { return mEnabled; }+ bool isEnabled() const+ {+ return mEnabled;+ } // Asynchronously operate on the current set of peer gateways. The // handler will be invoked in the service's io context.@@ -57,7 +58,10 @@ mGateways.withGateways(std::move(handler)); } - void updateNodeState(const NodeState& state) { mGateways.updateNodeState(state); }+ void updateNodeState(const NodeState& state)+ {+ mGateways.updateNodeState(state);+ } // Repair the gateway with the given address if possible. Its // sockets may have been closed, for example, and the gateway needs
link/include/ableton/discovery/UdpMessenger.hpp view
@@ -57,20 +57,20 @@ // Throws UdpSendException template <typename Interface, typename NodeId, typename Payload> void sendUdpMessage(Interface& iface,- NodeId from,- const uint8_t ttl,- const v1::MessageType messageType,- const Payload& payload,- const UdpEndpoint& to)+ NodeId from,+ const uint8_t ttl,+ const v1::MessageType messageType,+ const Payload& payload,+ const UdpEndpoint& to) { using namespace std; v1::MessageBuffer buffer; const auto messageBegin = begin(buffer);+ const auto messageEnd =+ v1::detail::encodeMessage(std::move(from), ttl, messageType, payload, messageBegin);+ const auto numBytes = static_cast<size_t>(distance(messageBegin, messageEnd)); try {- const auto messageEnd =- v1::detail::encodeMessage(std::move(from), ttl, messageType, payload, messageBegin);- const auto numBytes = static_cast<size_t>(distance(messageBegin, messageEnd)); iface.send(buffer.data(), numBytes, to); } catch (const std::runtime_error& err)@@ -93,10 +93,10 @@ using TimePoint = typename Timer::TimePoint; UdpMessenger(util::Injected<Interface> iface,- NodeState state,- util::Injected<IoContext> io,- const uint8_t ttl,- const uint8_t ttlRatio)+ NodeState state,+ util::Injected<IoContext> io,+ const uint8_t ttl,+ const uint8_t ttlRatio) : mpImpl(std::make_shared<Impl>( std::move(iface), std::move(state), std::move(io), ttl, ttlRatio)) {@@ -130,12 +130,18 @@ } } - void updateState(NodeState state) { mpImpl->updateState(std::move(state)); }+ void updateState(NodeState state)+ {+ mpImpl->updateState(std::move(state));+ } // Broadcast the current state of the system to all peers. May throw // std::runtime_error if assembling a broadcast message fails or if // there is an error at the transport layer. Throws on failure.- void broadcastState() { mpImpl->broadcastState(); }+ void broadcastState()+ {+ mpImpl->broadcastState();+ } // Asynchronous receive function for incoming messages from peers. Will // return immediately and the handler will be invoked when a message@@ -151,10 +157,10 @@ struct Impl : std::enable_shared_from_this<Impl> { Impl(util::Injected<Interface> iface,- NodeState state,- util::Injected<IoContext> io,- const uint8_t ttl,- const uint8_t ttlRatio)+ NodeState state,+ util::Injected<IoContext> io,+ const uint8_t ttl,+ const uint8_t ttlRatio) : mIo(std::move(io)) , mInterface(std::move(iface)) , mState(std::move(state))@@ -170,8 +176,8 @@ template <typename Handler> void setReceiveHandler(Handler handler) {- mPeerStateHandler = [handler](PeerState<NodeState> state)- { handler(std::move(state)); };+ mPeerStateHandler = [handler](+ PeerState<NodeState> state) { handler(std::move(state)); }; mByeByeHandler = [handler](ByeBye<NodeId> byeBye) { handler(std::move(byeBye)); }; }@@ -180,26 +186,20 @@ { if (mInterface->endpoint().address().is_v4()) {- sendUdpMessage(*mInterface,- mState.ident(),- 0,- v1::kByeBye,- makePayload(),- multicastEndpointV4());+ sendUdpMessage(*mInterface, mState.ident(), 0, v1::kByeBye, makePayload(),+ multicastEndpointV4()); } if (mInterface->endpoint().address().is_v6()) {- sendUdpMessage(- *mInterface,- mState.ident(),- 0,- v1::kByeBye,- makePayload(),+ sendUdpMessage(*mInterface, mState.ident(), 0, v1::kByeBye, makePayload(), multicastEndpointV6(mInterface->endpoint().address().to_v6().scope_id())); } } - void updateState(NodeState state) { mState = std::move(state); }+ void updateState(NodeState state)+ {+ mState = std::move(state);+ } void broadcastState() {@@ -218,14 +218,12 @@ // scheduled to try again. We want to keep trying at our // interval as long as this instance is alive. mTimer.expires_from_now(delay > milliseconds{0} ? delay : nominalBroadcastPeriod);- mTimer.async_wait(- [this](const TimerError e)+ mTimer.async_wait([this](const TimerError e) {+ if (!e) {- if (!e)- {- broadcastState();- }- });+ broadcastState();+ }+ }); // If we're not delaying, broadcast now if (delay < milliseconds{1})@@ -237,8 +235,7 @@ } if (mInterface->endpoint().address().is_v6()) {- sendPeerState(- v1::kAlive,+ sendPeerState(v1::kAlive, multicastEndpointV6(mInterface->endpoint().address().to_v6().scope_id())); } }@@ -246,16 +243,9 @@ void sendPeerState(const v1::MessageType messageType, const UdpEndpoint& to) {- try- {- sendUdpMessage(- *mInterface, mState.ident(), mTtl, messageType, toPayload(mState), to);- mLastBroadcastTime = mTimer.now();- }- catch (const UdpSendException& err)- {- debug(mIo->log()) << "Failed to send peer state message: " << err.what();- }+ sendUdpMessage(+ *mInterface, mState.ident(), mTtl, messageType, toPayload(mState), to);+ mLastBroadcastTime = mTimer.now(); } void sendResponse(const UdpEndpoint& to)@@ -271,10 +261,8 @@ } template <typename Tag, typename It>- void operator()(Tag tag,- const UdpEndpoint& from,- const It messageBegin,- const It messageEnd)+ void operator()(+ Tag tag, const UdpEndpoint& from, const It messageBegin, const It messageEnd) { auto result = v1::parseMessageHeader<NodeId>(messageBegin, messageEnd); @@ -282,33 +270,50 @@ // Ignore messages from self and other groups if (header.ident != mState.ident() && header.groupId == 0) {- debug(mIo->log()) << "Received message type "- << static_cast<int>(header.messageType) << " from peer "- << header.ident;+ // On Linux multicast messages are sent to all sockets registered to the multicast+ // group. To avoid duplicate message handling and invalid response messages we+ // check if the message is coming from an endpoint that is in the same subnet as+ // the interface.+ auto ignoreIpV4Message = false;+ if (from.address().is_v4() && mInterface->endpoint().address().is_v4())+ {+ const auto subnet = LINK_ASIO_NAMESPACE::ip::make_network_v4(+ mInterface->endpoint().address().to_v4(), 24);+ const auto fromAddr =+ LINK_ASIO_NAMESPACE::ip::make_network_v4(from.address().to_v4(), 32);+ ignoreIpV4Message = !fromAddr.is_subnet_of(subnet);+ } - switch (header.messageType)+ if (!ignoreIpV4Message) {- case v1::kAlive:- sendResponse(from);- receivePeerState(std::move(result.first), result.second, messageEnd);- break;- case v1::kResponse:- receivePeerState(std::move(result.first), result.second, messageEnd);- break;- case v1::kByeBye:- receiveByeBye(std::move(result.first.ident));- break;- default:- info(mIo->log()) << "Unknown message received of type: " << header.messageType;+ debug(mIo->log()) << "Received message type "+ << static_cast<int>(header.messageType) << " from peer "+ << header.ident;++ switch (header.messageType)+ {+ case v1::kAlive:+ sendResponse(from);+ receivePeerState(std::move(result.first), result.second, messageEnd);+ break;+ case v1::kResponse:+ receivePeerState(std::move(result.first), result.second, messageEnd);+ break;+ case v1::kByeBye:+ receiveByeBye(std::move(result.first.ident));+ break;+ default:+ info(mIo->log()) << "Unknown message received of type: "+ << header.messageType;+ } } } listen(tag); } template <typename It>- void receivePeerState(v1::MessageHeader<NodeId> header,- It payloadBegin,- It payloadEnd)+ void receivePeerState(+ v1::MessageHeader<NodeId> header, It payloadBegin, It payloadEnd) { try {
− link/include/ableton/discovery/UnicastIpInterface.hpp
@@ -1,99 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- * This program is free software: you can redistribute it and/or modify- * it under the terms of the GNU General Public License as published by- * the Free Software Foundation, either version 2 of the License, or- * (at your option) any later version.- *- * This program is distributed in the hope that it will be useful,- * but WITHOUT ANY WARRANTY; without even the implied warranty of- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- * GNU General Public License for more details.- *- * You should have received a copy of the GNU General Public License- * along with this program. If not, see <http://www.gnu.org/licenses/>.- *- * If you would like to incorporate Link into a proprietary software application,- * please contact <link-devs@ableton.com>.- */--#pragma once--#include <ableton/discovery/AsioTypes.hpp>-#include <ableton/util/Injected.hpp>-#include <memory>-#include <stdexcept>--namespace ableton-{-namespace link_audio-{--template <typename IoContext, std::size_t MaxPacketSize>-class UnicastIpInterface-{-public:- using Socket = typename util::Injected<IoContext>::type::template Socket<MaxPacketSize>;-- UnicastIpInterface(util::Injected<IoContext> io, const discovery::IpAddress& addr)- : mSocket(io->template openUnicastSocket<MaxPacketSize>(addr))- {- }-- UnicastIpInterface(const UnicastIpInterface&) = delete;- UnicastIpInterface& operator=(const UnicastIpInterface&) = delete;-- UnicastIpInterface(UnicastIpInterface&& rhs)- : mSocket(std::move(rhs.mSocket))- {- }-- std::size_t send(const uint8_t* const pData,- const size_t numBytes,- const discovery::UdpEndpoint& to)- {- return mSocket.send(pData, numBytes, to);- }-- template <typename Handler>- void receive(Handler handler)- {- mSocket.receive(SocketReceiver<Handler>(std::move(handler)));- }-- discovery::UdpEndpoint endpoint() const { return mSocket.endpoint(); }--private:- template <typename Handler>- struct SocketReceiver- {- SocketReceiver(Handler handler)- : mHandler(std::move(handler))- {- }-- template <typename It>- void operator()(const discovery::UdpEndpoint& from,- const It messageBegin,- const It messageEnd)- {- mHandler(from, messageBegin, messageEnd);- }-- Handler mHandler;- };-- Socket mSocket;-};--template <std::size_t MaxPacketSize, typename IoContext>-std::shared_ptr<UnicastIpInterface<IoContext, MaxPacketSize>>-makeSharedUnicastIpInterface(util::Injected<IoContext> io,- const discovery::IpAddress& addr)-{- return std::make_shared<UnicastIpInterface<IoContext, MaxPacketSize>>(- std::move(io), addr);-}--} // namespace link_audio-} // namespace ableton
link/include/ableton/discovery/test/Interface.hpp view
@@ -19,11 +19,7 @@ #pragma once -#include <ableton/discovery/AsioTypes.hpp> #include <ableton/util/Log.hpp>-#include <functional>-#include <utility>-#include <vector> namespace ableton {@@ -42,9 +38,8 @@ { } - void send(const uint8_t* const bytes,- const size_t numBytes,- const UdpEndpoint& endpoint)+ void send(+ const uint8_t* const bytes, const size_t numBytes, const UdpEndpoint& endpoint) { sentMessages.push_back( std::make_pair(std::vector<uint8_t>{bytes, bytes + numBytes}, endpoint));@@ -54,15 +49,9 @@ void receive(Callback callback, Tag tag) { mCallback = [callback, tag](- const UdpEndpoint& from, const std::vector<uint8_t>& buffer)- { callback(tag, from, begin(buffer), end(buffer)); };- }-- template <typename Callback>- void receive(Callback callback)- {- mCallback = [callback](const auto& from, const auto& buffer)- { callback(from, begin(buffer), end(buffer)); };+ const UdpEndpoint& from, const std::vector<uint8_t>& buffer) {+ callback(tag, from, begin(buffer), end(buffer));+ }; } template <typename It>@@ -72,7 +61,10 @@ mCallback(from, buffer); } - UdpEndpoint endpoint() const { return mEndpoint; }+ UdpEndpoint endpoint() const+ {+ return mEndpoint;+ } using SentMessage = std::pair<std::vector<uint8_t>, UdpEndpoint>; std::vector<SentMessage> sentMessages;
link/include/ableton/discovery/test/PayloadEntries.hpp view
@@ -122,7 +122,10 @@ return std::make_pair(std::move(foobar), std::move(result.second)); } - FoobarTuple asTuple() const { return std::make_tuple(fooVals, barVals); }+ FoobarTuple asTuple() const+ {+ return std::make_tuple(fooVals, barVals);+ } }; } // namespace test
link/include/ableton/discovery/test/Socket.hpp view
@@ -33,13 +33,16 @@ class Socket { public:- Socket(util::test::IoService&) {}+ Socket(util::test::IoService&)+ {+ } - friend void configureUnicastSocket(Socket&, const IpAddressV4&) {}+ friend void configureUnicastSocket(Socket&, const IpAddressV4&)+ {+ } - std::size_t send(const uint8_t* const pData,- const size_t numBytes,- const discovery::UdpEndpoint& to)+ std::size_t send(+ const uint8_t* const pData, const size_t numBytes, const discovery::UdpEndpoint& to) { sentMessages.push_back( std::make_pair(std::vector<uint8_t>{pData, pData + numBytes}, to));@@ -49,8 +52,9 @@ template <typename Handler> void receive(Handler handler) {- mCallback = [handler](const UdpEndpoint& from, const std::vector<uint8_t>& buffer)- { handler(from, begin(buffer), end(buffer)); };+ mCallback = [handler](const UdpEndpoint& from, const std::vector<uint8_t>& buffer) {+ handler(from, begin(buffer), end(buffer));+ }; } template <typename It>@@ -60,7 +64,10 @@ mCallback(from, buffer); } - UdpEndpoint endpoint() const { return UdpEndpoint({}, 0); }+ UdpEndpoint endpoint() const+ {+ return UdpEndpoint({}, 0);+ } using SentMessage = std::pair<std::vector<uint8_t>, UdpEndpoint>; std::vector<SentMessage> sentMessages;
link/include/ableton/discovery/v1/Messages.hpp view
@@ -61,12 +61,9 @@ template <typename It> friend It toNetworkByteStream(const MessageHeader& header, It out) {- return discovery::toNetworkByteStream(- header.ident,- discovery::toNetworkByteStream(- header.groupId,- discovery::toNetworkByteStream(- header.ttl,+ return discovery::toNetworkByteStream(header.ident,+ discovery::toNetworkByteStream(header.groupId,+ discovery::toNetworkByteStream(header.ttl, discovery::toNetworkByteStream(header.messageType, std::move(out))))); } @@ -100,10 +97,10 @@ // Must have at least kMaxMessageSize bytes available in the output stream template <typename NodeId, typename Payload, typename It> It encodeMessage(NodeId from,- const uint8_t ttl,- const MessageType messageType,- const Payload& payload,- It out)+ const uint8_t ttl,+ const MessageType messageType,+ const Payload& payload,+ It out) { using namespace std; const MessageHeader<NodeId> header = {messageType, ttl, 0, std::move(from)};@@ -113,9 +110,8 @@ if (messageSize < kMaxMessageSize) { return toNetworkByteStream(- payload,- toNetworkByteStream(- header, copy(begin(kProtocolHeader), end(kProtocolHeader), std::move(out))));+ payload, toNetworkByteStream(header,+ copy(begin(kProtocolHeader), end(kProtocolHeader), std::move(out)))); } else {
− link/include/ableton/link/ApiConfig.hpp
@@ -1,46 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- * This program is free software: you can redistribute it and/or modify- * it under the terms of the GNU General Public License as published by- * the Free Software Foundation, either version 2 of the License, or- * (at your option) any later version.- *- * This program is distributed in the hope that it will be useful,- * but WITHOUT ANY WARRANTY; without even the implied warranty of- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- * GNU General Public License for more details.- *- * You should have received a copy of the GNU General Public License- * along with this program. If not, see <http://www.gnu.org/licenses/>.- *- * If you would like to incorporate Link into a proprietary software application,- * please contact <link-devs@ableton.com>.- */--#pragma once--#ifndef LINK_API_CONTROLLER--#include <ableton/platforms/Config.hpp>--#include <ableton/link/SessionController.hpp>--namespace ableton-{-namespace link-{--template <typename Clock>-using ApiController = SessionController<PeerCountCallback,- TempoCallback,- StartStopStateCallback,- Clock,- platform::Random,- platform::IoContext>;--} // namespace link-} // namespace ableton--#define LINK_API_CONTROLLER YES--#endif
link/include/ableton/link/Beats.hpp view
@@ -42,13 +42,25 @@ { } - double floating() const { return static_cast<double>(mValue) / 1e6; }+ double floating() const+ {+ return static_cast<double>(mValue) / 1e6;+ } - std::int64_t microBeats() const { return mValue; }+ std::int64_t microBeats() const+ {+ return mValue;+ } - Beats operator-() const { return Beats{-mValue}; }+ Beats operator-() const+ {+ return Beats{-mValue};+ } - friend Beats abs(const Beats b) { return Beats{std::abs(b.mValue)}; }+ friend Beats abs(const Beats b)+ {+ return Beats{std::abs(b.mValue)};+ } friend Beats operator+(const Beats lhs, const Beats rhs) {
link/include/ableton/link/ClientSessionTimelines.hpp view
@@ -33,8 +33,7 @@ const double kMinBpm = 20.0; const double kMaxBpm = 999.0; return {Tempo{(std::min)((std::max)(timeline.tempo.bpm(), kMinBpm), kMaxBpm)},- timeline.beatOrigin,- timeline.timeOrigin};+ timeline.beatOrigin, timeline.timeOrigin}; } // Given an existing client timeline, a session timeline, and the@@ -43,9 +42,9 @@ // previous timeline so that curClient.toBeats(atTime) == // result.toBeats(atTime). inline Timeline updateClientTimelineFromSession(const Timeline curClient,- const Timeline session,- const std::chrono::microseconds atTime,- const GhostXForm xform)+ const Timeline session,+ const std::chrono::microseconds atTime,+ const GhostXForm xform) { // An intermediate timeline representing the continuation of the // existing client timeline with the tempo from the session timeline.@@ -64,9 +63,9 @@ inline Timeline updateSessionTimelineFromClient(const Timeline curSession,- const Timeline client,- const std::chrono::microseconds atTime,- const GhostXForm xform)+ const Timeline client,+ const std::chrono::microseconds atTime,+ const GhostXForm xform) { // The client timeline was constructed so that it's timeOrigin // corresponds to beat 0 on the session timeline.@@ -95,7 +94,7 @@ // but we must also make sure that it's > curSession.beatOrigin // because otherwise it will get ignored. const auto newBeatOrigin = (std::max)(curSession.toBeats(xform.hostToGhost(atTime)),- curSession.beatOrigin + Beats{INT64_C(1)});+ curSession.beatOrigin + Beats{INT64_C(1)}); return {client.tempo, newBeatOrigin, tempTl.fromBeats(newBeatOrigin)}; } }
link/include/ableton/link/Controller.hpp view
@@ -28,9 +28,7 @@ #include <ableton/link/SessionState.hpp> #include <ableton/link/Sessions.hpp> #include <ableton/link/StartStopState.hpp>-#include <ableton/util/TripleBuffer.hpp>--#include <chrono>+#include <ableton/link/TripleBuffer.hpp> #include <condition_variable> #include <mutex> @@ -54,27 +52,22 @@ { using namespace std::chrono; return {clampTempo(Timeline{tempo, Beats{0.}, microseconds{0}}),- StartStopState{false, Beats{0.}, microseconds{0}},- initXForm(clock)};+ StartStopState{false, Beats{0.}, microseconds{0}}, initXForm(clock)}; } -inline ClientState initClientState(const SessionState& sessionState, SessionId sessionId)+inline ClientState initClientState(const SessionState& sessionState) { const auto hostTime = sessionState.ghostXForm.ghostToHost(std::chrono::microseconds{0}); return { Timeline{sessionState.timeline.tempo, sessionState.timeline.beatOrigin, hostTime},- std::move(sessionId), ClientStartStopState{sessionState.startStopState.isPlaying, hostTime, hostTime}}; } inline RtClientState initRtClientState(const ClientState& clientState) { using namespace std::chrono;- return {clientState.timeline,- clientState.timelineSessionId,- clientState.startStopState,- microseconds{0},- microseconds{0}};+ return {+ clientState.timeline, clientState.startStopState, microseconds{0}, microseconds{0}}; } // The timespan in which local modifications to the timeline will be@@ -123,55 +116,50 @@ // The main Link controller template <typename PeerCountCallback,- typename TempoCallback,- typename StartStopStateCallback,- typename Clock,- typename Random,- typename IoContext,- typename SessionController>+ typename TempoCallback,+ typename StartStopStateCallback,+ typename Clock,+ typename Random,+ typename IoContext> class Controller { public: Controller(Tempo tempo,- PeerCountCallback peerCallback,- TempoCallback tempoCallback,- StartStopStateCallback startStopStateCallback,- Clock clock)+ PeerCountCallback peerCallback,+ TempoCallback tempoCallback,+ StartStopStateCallback startStopStateCallback,+ Clock clock) : mTempoCallback(std::move(tempoCallback)) , mStartStopStateCallback(std::move(startStopStateCallback)) , mClock(std::move(clock)) , mNodeId(NodeId::random<Random>()) , mSessionId(mNodeId) , mSessionState(detail::initSessionState(tempo, mClock))- , mClientState(detail::initClientState(mSessionState, mSessionId))+ , mClientState(detail::initClientState(mSessionState)) , mLastIsPlayingForStartStopStateCallback(false) , mRtClientState(detail::initRtClientState(mClientState.get())) , mHasPendingRtClientStates(false)- , mpSessionController{static_cast<SessionController*>(this)} , mSessionPeerCounter(*this, std::move(peerCallback)) , mEnabled(false) , mStartStopSyncEnabled(false) , mIo(IoContext{UdpSendExceptionHandler{this}})+ , mRtClientStateSetter(*this) , mPeers(util::injectRef(*mIo),- SessionMembershipCallback{this},- SessionTimelineCallback{*this},- SessionStartStopStateCallback{*this},- SawAudioEndpointCallback{this})+ std::ref(mSessionPeerCounter),+ SessionTimelineCallback{*this},+ SessionStartStopStateCallback{*this}) , mSessions( {mSessionId, mSessionState.timeline, {mSessionState.ghostXForm, mClock.micros()}}, util::injectRef(mPeers),- MeasurePeer{this},- JoinSessionCallback{this},+ MeasurePeer{*this},+ JoinSessionCallback{*this}, util::injectRef(*mIo), mClock)- , mDiscovery(- std::make_pair(- NodeState{- mNodeId, mSessionId, mSessionState.timeline, mSessionState.startStopState},- mSessionState.ghostXForm),- util::injectVal(GatewayFactory{this}),+ , mDiscovery(std::make_pair(NodeState{mNodeId, mSessionId, mSessionState.timeline,+ mSessionState.startStopState},+ mSessionState.ghostXForm),+ GatewayFactory{*this}, util::injectRef(*mIo))- , mRtClientStateSetter(*this) { } @@ -181,6 +169,26 @@ Controller& operator=(const Controller&) = delete; Controller& operator=(Controller&&) = delete; + ~Controller()+ {+ std::mutex mutex;+ std::condition_variable condition;+ auto stopped = false;++ mIo->async([this, &mutex, &condition, &stopped]() {+ mEnabled = false;+ mDiscovery.enable(false);+ std::unique_lock<std::mutex> lock(mutex);+ stopped = true;+ condition.notify_one();+ });++ std::unique_lock<std::mutex> lock(mutex);+ condition.wait(lock, [&stopped] { return stopped; });++ mIo->stop();+ }+ void enable(const bool bEnable) { const bool bWasEnabled = mEnabled.exchange(bEnable);@@ -190,38 +198,51 @@ } } - bool isEnabled() const { return mEnabled; }+ bool isEnabled() const+ {+ return mEnabled;+ } - void enableStartStopSync(const bool bEnable) { mStartStopSyncEnabled = bEnable; }+ void enableStartStopSync(const bool bEnable)+ {+ mStartStopSyncEnabled = bEnable;+ } - bool isStartStopSyncEnabled() const { return mStartStopSyncEnabled; }+ bool isStartStopSyncEnabled() const+ {+ return mStartStopSyncEnabled;+ } - std::size_t numPeers() const { return mSessionPeerCounter.mSessionPeerCount; }+ std::size_t numPeers() const+ {+ return mSessionPeerCounter.mSessionPeerCount;+ } // Get the current Link client state. Thread-safe but may block, so // it cannot be used from audio thread.- ClientState clientState() const { return mClientState.get(); }+ ClientState clientState() const+ {+ return mClientState.get();+ } // Set the client state to be used, starting at the given time. // Thread-safe but may block, so it cannot be used from audio thread. void setClientState(IncomingClientState newClientState) {- mClientState.update(- [&](ClientState& clientState)+ mClientState.update([&](ClientState& clientState) {+ if (newClientState.timeline) {- if (newClientState.timeline)- {- *newClientState.timeline = clampTempo(*newClientState.timeline);- clientState.timeline = *newClientState.timeline;- }- if (newClientState.startStopState)- {- // Prevent updating client start stop state with an outdated start stop state- *newClientState.startStopState = detail::selectPreferredStartStopState(- clientState.startStopState, *newClientState.startStopState);- clientState.startStopState = *newClientState.startStopState;- }- });+ *newClientState.timeline = clampTempo(*newClientState.timeline);+ clientState.timeline = *newClientState.timeline;+ }+ if (newClientState.startStopState)+ {+ // Prevent updating client start stop state with an outdated start stop state+ *newClientState.startStopState = detail::selectPreferredStartStopState(+ clientState.startStopState, *newClientState.startStopState);+ clientState.startStopState = *newClientState.startStopState;+ }+ }); mIo->async([this, newClientState] { handleClientState(newClientState); }); } @@ -246,22 +267,20 @@ { const auto clientState = mClientState.getRt(); - if (timelineGracePeriodOver)+ if (timelineGracePeriodOver && clientState.timeline != mRtClientState.timeline) { mRtClientState.timeline = clientState.timeline;- mRtClientState.timelineSessionId = clientState.timelineSessionId; } - if (startStopStateGracePeriodOver)+ if (startStopStateGracePeriodOver+ && clientState.startStopState != mRtClientState.startStopState) { mRtClientState.startStopState = clientState.startStopState; } } } - return {mRtClientState.timeline,- mRtClientState.timelineSessionId,- mRtClientState.startStopState};+ return {mRtClientState.timeline, mRtClientState.startStopState}; } // should only be called from the audio thread@@ -303,7 +322,7 @@ } } -protected:+private: std::chrono::microseconds makeRtTimestamp(const std::chrono::microseconds now) const { return isEnabled() ? now : std::chrono::microseconds(0);@@ -313,13 +332,11 @@ { bool shouldInvokeCallback = false; - mClientState.update(- [&](ClientState& clientState)- {- shouldInvokeCallback =- mLastIsPlayingForStartStopStateCallback != clientState.startStopState.isPlaying;- mLastIsPlayingForStartStopStateCallback = clientState.startStopState.isPlaying;- });+ mClientState.update([&](ClientState& clientState) {+ shouldInvokeCallback =+ mLastIsPlayingForStartStopStateCallback != clientState.startStopState.isPlaying;+ mLastIsPlayingForStartStopStateCallback = clientState.startStopState.isPlaying;+ }); if (shouldInvokeCallback) {@@ -330,10 +347,10 @@ void updateDiscovery() { // Push the change to the discovery service- mDiscovery.updateNodeState(std::make_pair(- NodeState{- mNodeId, mSessionId, mSessionState.timeline, mSessionState.startStopState},- mSessionState.ghostXForm));+ mDiscovery.updateNodeState(+ std::make_pair(NodeState{mNodeId, mSessionId, mSessionState.timeline,+ mSessionState.startStopState},+ mSessionState.ghostXForm)); } void updateSessionTiming(Timeline newTimeline, const GhostXForm newXForm)@@ -353,26 +370,19 @@ } // Update the client timeline and start stop state based on the new session timing- mClientState.update(- [&](ClientState& clientState)+ mClientState.update([&](ClientState& clientState) {+ clientState.timeline = updateClientTimelineFromSession(clientState.timeline,+ mSessionState.timeline, mClock.micros(), mSessionState.ghostXForm);+ // Don't pass the start stop state to the client when start stop sync is disabled+ // or when we have a default constructed start stop state+ if (mStartStopSyncEnabled && mSessionState.startStopState != StartStopState{}) {- clientState.timeline =- updateClientTimelineFromSession(clientState.timeline,- mSessionState.timeline,- mClock.micros(),- mSessionState.ghostXForm);- clientState.timelineSessionId = mSessionId;- // Don't pass the start stop state to the client when start stop sync is- // disabled or when we have a default constructed start stop state- if (mStartStopSyncEnabled && mSessionState.startStopState != StartStopState{})- {- std::lock_guard<std::mutex> startStopStateLock(mSessionStateGuard);- clientState.startStopState =- detail::mapStartStopStateFromSessionToClient(mSessionState.startStopState,- mSessionState.timeline,- mSessionState.ghostXForm);- }- });+ std::lock_guard<std::mutex> startStopStateLock(mSessionStateGuard);+ clientState.startStopState =+ detail::mapStartStopStateFromSessionToClient(mSessionState.startStopState,+ mSessionState.timeline, mSessionState.ghostXForm);+ }+ }); if (oldTimeline.tempo != newTimeline.tempo) {@@ -386,11 +396,14 @@ debug(mIo->log()) << "Received timeline with tempo: " << timeline.tempo.bpm() << " for session: " << id; updateSessionTiming(mSessions.sawSessionTimeline(std::move(id), std::move(timeline)),- mSessionState.ghostXForm);- mpSessionController->updateDiscoveryCallback();+ mSessionState.ghostXForm);+ updateDiscovery(); } - void resetSessionStartStopState() { mSessionState.startStopState = StartStopState{}; }+ void resetSessionStartStopState()+ {+ mSessionState.startStopState = StartStopState{};+ } void handleStartStopStateFromSession(SessionId sessionId, StartStopState startStopState) {@@ -406,16 +419,14 @@ // Always propagate the session start stop state so even a client that doesn't have // the feature enabled can function as a relay.- mpSessionController->updateDiscoveryCallback();+ updateDiscovery(); if (mStartStopSyncEnabled) {- mClientState.update(- [&](ClientState& clientState)- {- clientState.startStopState = detail::mapStartStopStateFromSessionToClient(- startStopState, mSessionState.timeline, mSessionState.ghostXForm);- });+ mClientState.update([&](ClientState& clientState) {+ clientState.startStopState = detail::mapStartStopStateFromSessionToClient(+ startStopState, mSessionState.timeline, mSessionState.ghostXForm);+ }); invokeStartStopStateCallbackIfChanged(); } }@@ -427,11 +438,8 @@ if (clientState.timeline) {- auto sessionTimeline =- updateSessionTimelineFromClient(mSessionState.timeline,- *clientState.timeline,- clientState.timelineTimestamp,- mSessionState.ghostXForm);+ auto sessionTimeline = updateSessionTimelineFromClient(mSessionState.timeline,+ *clientState.timeline, clientState.timelineTimestamp, mSessionState.ghostXForm); mSessions.resetTimeline(sessionTimeline); mPeers.setSessionTimeline(mSessionId, sessionTimeline);@@ -447,15 +455,12 @@ mSessionState.ghostXForm.hostToGhost(clientState.startStopState->timestamp); if (newGhostTime > mSessionState.startStopState.timestamp) {- mClientState.update(- [&](ClientState& currentClientState)- {- mSessionState.startStopState =- detail::mapStartStopStateFromClientToSession(*clientState.startStopState,- mSessionState.timeline,- mSessionState.ghostXForm);- currentClientState.startStopState = *clientState.startStopState;- });+ mClientState.update([&](ClientState& currentClientState) {+ mSessionState.startStopState =+ detail::mapStartStopStateFromClientToSession(*clientState.startStopState,+ mSessionState.timeline, mSessionState.ghostXForm);+ currentClientState.startStopState = *clientState.startStopState;+ }); mustUpdateDiscovery = true; }@@ -463,7 +468,7 @@ if (mustUpdateDiscovery) {- mpSessionController->updateDiscoveryCallback();+ updateDiscovery(); } invokeStartStopStateCallbackIfChanged();@@ -471,21 +476,19 @@ void handleRtClientState(IncomingClientState clientState) {- mClientState.update(- [&](ClientState& currentClientState)+ mClientState.update([&](ClientState& currentClientState) {+ if (clientState.timeline) {- if (clientState.timeline)- {- currentClientState.timeline = *clientState.timeline;- }- if (clientState.startStopState)- {- // Prevent updating client start stop state with an outdated start stop state- *clientState.startStopState = detail::selectPreferredStartStopState(- currentClientState.startStopState, *clientState.startStopState);- currentClientState.startStopState = *clientState.startStopState;- }- });+ currentClientState.timeline = *clientState.timeline;+ }+ if (clientState.startStopState)+ {+ // Prevent updating client start stop state with an outdated start stop state+ *clientState.startStopState = detail::selectPreferredStartStopState(+ currentClientState.startStopState, *clientState.startStopState);+ currentClientState.startStopState = *clientState.startStopState;+ }+ }); handleClientState(clientState); mHasPendingRtClientStates = false;@@ -504,13 +507,13 @@ } updateSessionTiming(session.timeline, session.measurement.xform);- mpSessionController->updateDiscoveryCallback();+ updateDiscovery(); if (sessionIdChanged) { debug(mIo->log()) << "Joining session " << session.sessionId << " with tempo " << session.timeline.tempo.bpm();- mpSessionController->sessionMembershipCallback();+ mSessionPeerCounter(); } } @@ -525,15 +528,14 @@ // the beat on the old session timeline corresponding to the // current host time and mapping it to the new ghost time // representation of the current host time.- const auto newTl = Timeline{- mSessionState.timeline.tempo,+ const auto newTl = Timeline{mSessionState.timeline.tempo, mSessionState.timeline.toBeats(mSessionState.ghostXForm.hostToGhost(hostTime)), xform.hostToGhost(hostTime)}; resetSessionStartStopState(); updateSessionTiming(newTl, xform);- mpSessionController->updateDiscoveryCallback();+ updateDiscovery(); mSessions.resetSession({mNodeId, newTl, {xform, hostTime}}); mPeers.resetPeers();@@ -553,25 +555,27 @@ { using CallbackDispatcher = typename IoContext::template LockFreeCallbackDispatcher<std::function<void()>,- std::chrono::milliseconds>;+ std::chrono::milliseconds>; RtClientStateSetter(Controller& controller) : mController(controller) , mCallbackDispatcher(- [this]- {- mController.mIo->async(- [this]() { mController.mpSessionController->updateRtStatesCallback(); });+ [this] {+ mController.mIo->async([this]() {+ // Process the pending client states first to make sure we don't push one+ // after we have joined a running session when enabling+ processPendingClientStates();+ updateEnabled();+ }); }, detail::kRtHandlerFallbackPeriod) { } - void start() { mCallbackDispatcher.start(); }-- void stop() { mCallbackDispatcher.stop(); }-- void invoke() { mCallbackDispatcher.invoke(); }+ void invoke()+ {+ mCallbackDispatcher.invoke();+ } void push(const IncomingClientState clientState) {@@ -631,8 +635,8 @@ Controller& mController; // Use separate TripleBuffers for the Timeline and the StartStopState so we read the // latest set value from either optional.- util::TripleBuffer<std::pair<std::chrono::microseconds, Timeline>> mTimelineBuffer;- util::TripleBuffer<ClientStartStopState> mStartStopStateBuffer;+ TripleBuffer<std::pair<std::chrono::microseconds, Timeline>> mTimelineBuffer;+ TripleBuffer<ClientStartStopState> mStartStopStateBuffer; CallbackDispatcher mCallbackDispatcher; }; @@ -646,26 +650,6 @@ Controller& mController; }; - struct SawAudioEndpointCallback- {- void operator()(NodeId peerId,- std::optional<discovery::UdpEndpoint> endpoint,- discovery::IpAddress gateway)- {- mpController->mpSessionController->sawAudioEndpointCallback(- peerId, endpoint, gateway);- }-- Controller* mpController;- };-- struct SessionMembershipCallback- {- void operator()() { mpController->mpSessionController->sessionMembershipCallback(); }-- Controller* mpController;- };- struct SessionPeerCounter { SessionPeerCounter(Controller& controller, PeerCountCallback callback)@@ -702,22 +686,12 @@ template <typename Peer, typename Handler> void operator()(Peer peer, Handler handler) {- mpController->mpSessionController->measurePeerCallback(- std::move(peer), std::move(handler));- }-- Controller* mpController;- };-- template <typename Peer, typename Handler>- void measurePeer(Peer peer, Handler handler)- {- mDiscovery.withGateways(- [peer, handler](auto begin, const auto end)- {+ using It = typename Discovery::ServicePeerGateways::GatewayMap::iterator;+ using ValueType = typename Discovery::ServicePeerGateways::GatewayMap::value_type;+ mController.mDiscovery.withGateways([peer, handler](It begin, const It end) { const auto addr = peer.second;- const auto it =- std::find_if(begin, end, [&addr](const auto& vt) { return vt.first == addr; });+ const auto it = std::find_if(+ begin, end, [&addr](const ValueType& vt) { return vt.first == addr; }); if (it != end) { it->second->measurePeer(std::move(peer.first), std::move(handler));@@ -729,54 +703,27 @@ handler(GhostXForm{}); } });- }-- struct JoinSessionCallback- {- void operator()(Session session)- {- mpController->mpSessionController->joinSessionCallback(std::move(session)); } - Controller* mpController;+ Controller& mController; }; - void shutdown()+ struct JoinSessionCallback {- if (mIoStopped)+ void operator()(Session session) {- return;+ mController.joinSession(std::move(session)); } - std::mutex mutex;- std::condition_variable condition;-- this->mIo->async(- [this, &mutex, &condition]()- {- mRtClientStateSetter.stop();-- mEnabled = false;- mDiscovery.enable(false);-- std::unique_lock<std::mutex> lock(mutex);- mIoStopped = true;- condition.notify_one();- });-- std::unique_lock<std::mutex> lock(mutex);- condition.wait(lock, [&]() { return mIoStopped.load(); });-- this->mIo->stop();- }+ Controller& mController;+ }; using IoType = typename util::Injected<IoContext>::type; using ControllerPeers = Peers<IoType&,- SessionMembershipCallback,- SessionTimelineCallback,- SessionStartStopStateCallback,- SawAudioEndpointCallback>;+ std::reference_wrapper<SessionPeerCounter>,+ SessionTimelineCallback,+ SessionStartStopStateCallback>; using ControllerGateway = Gateway<typename ControllerPeers::GatewayObserver, Clock, IoType&>;@@ -785,24 +732,15 @@ struct GatewayFactory { GatewayPtr operator()(std::pair<NodeState, GhostXForm> state,- util::Injected<IoType&> io,- const discovery::IpAddress& addr)- {- return GatewayPtr{new ControllerGateway{- std::move(io),- addr,- util::injectVal(makeGatewayObserver(mpController->mPeers, addr)),- std::move(state.first),- std::move(state.second),- mpController->mClock}};- }-- void gatewaysChanged()+ util::Injected<IoType&> io,+ const discovery::IpAddress& addr) {- mpController->mpSessionController->gatewaysChangedCallback();+ return GatewayPtr{new ControllerGateway{std::move(io), addr,+ util::injectVal(makeGatewayObserver(mController.mPeers, addr)),+ std::move(state.first), std::move(state.second), mController.mClock}}; } - Controller* mpController;+ Controller& mController; }; struct UdpSendExceptionHandler@@ -811,9 +749,9 @@ void operator()(const Exception exception) {- mpController->mIo->async(- [this, exception]- { mpController->mDiscovery.repairGateway(exception.interfaceAddr); });+ mpController->mIo->async([this, exception] {+ mpController->mDiscovery.repairGateway(exception.interfaceAddr);+ }); } Controller* mpController;@@ -834,8 +772,6 @@ mutable RtClientState mRtClientState; std::atomic<bool> mHasPendingRtClientStates; - SessionController* mpSessionController;- SessionPeerCounter mSessionPeerCounter; std::atomic<bool> mEnabled;@@ -843,23 +779,22 @@ std::atomic<bool> mStartStopSyncEnabled; util::Injected<IoContext> mIo;- std::atomic<bool> mIoStopped{false}; + RtClientStateSetter mRtClientStateSetter;+ ControllerPeers mPeers; using ControllerSessions = Sessions<ControllerPeers&,- MeasurePeer,- JoinSessionCallback,- typename util::Injected<IoContext>::type&,- Clock>;+ MeasurePeer,+ JoinSessionCallback,+ typename util::Injected<IoContext>::type&,+ Clock>; ControllerSessions mSessions; using Discovery = discovery::Service<std::pair<NodeState, GhostXForm>,- typename util::Injected<GatewayFactory>::type,- typename util::Injected<IoContext>::type&>;+ GatewayFactory,+ typename util::Injected<IoContext>::type&>; Discovery mDiscovery;-- RtClientStateSetter mRtClientStateSetter; }; } // namespace link
− link/include/ableton/link/EndpointV4.hpp
@@ -1,75 +0,0 @@-/* Copyright 2016, Ableton AG, Berlin. All rights reserved.- *- * This program is free software: you can redistribute it and/or modify- * it under the terms of the GNU General Public License as published by- * the Free Software Foundation, either version 2 of the License, or- * (at your option) any later version.- *- * This program is distributed in the hope that it will be useful,- * but WITHOUT ANY WARRANTY; without even the implied warranty of- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- * GNU General Public License for more details.- *- * You should have received a copy of the GNU General Public License- * along with this program. If not, see <http://www.gnu.org/licenses/>.- *- * If you would like to incorporate Link into a proprietary software application,- * please contact <link-devs@ableton.com>.- */--#pragma once--#include <ableton/discovery/AsioTypes.hpp>-#include <ableton/discovery/NetworkByteStreamSerializable.hpp>-#include <cassert>--namespace ableton-{-namespace link-{--template <std::int32_t Key = 'mep4'>-struct EndpointV4-{- static constexpr std::int32_t key = Key;-- // Model the NetworkByteStreamSerializable concept- friend std::uint32_t sizeInByteStream(const EndpointV4<Key> mep)- {- if (mep.ep.address().is_v6())- {- return 0;- }- return discovery::sizeInByteStream(- static_cast<std::uint32_t>(mep.ep.address().to_v4().to_uint()))- + discovery::sizeInByteStream(mep.ep.port());- }-- template <typename It>- friend It toNetworkByteStream(const EndpointV4<Key> mep, It out)- {- assert(mep.ep.address().is_v4());- return discovery::toNetworkByteStream(- mep.ep.port(),- discovery::toNetworkByteStream(- static_cast<std::uint32_t>(mep.ep.address().to_v4().to_uint()), std::move(out)));- }-- template <typename It>- static std::pair<EndpointV4<Key>, It> fromNetworkByteStream(It begin, It end)- {- using namespace std;- auto addrRes =- discovery::Deserialize<std::uint32_t>::fromNetworkByteStream(std::move(begin), end);- auto portRes = discovery::Deserialize<std::uint16_t>::fromNetworkByteStream(- std::move(addrRes.second), end);- return make_pair(EndpointV4<Key>{{discovery::IpAddressV4{std::move(addrRes.first)},- std::move(portRes.first)}},- std::move(portRes.second));- }-- discovery::UdpEndpoint ep;-};--} // namespace link-} // namespace ableton
− link/include/ableton/link/EndpointV6.hpp
@@ -1,75 +0,0 @@-/* Copyright 2023, Ableton AG, Berlin. All rights reserved.- *- * This program is free software: you can redistribute it and/or modify- * it under the terms of the GNU General Public License as published by- * the Free Software Foundation, either version 2 of the License, or- * (at your option) any later version.- *- * This program is distributed in the hope that it will be useful,- * but WITHOUT ANY WARRANTY; without even the implied warranty of- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- * GNU General Public License for more details.- *- * You should have received a copy of the GNU General Public License- * along with this program. If not, see <http://www.gnu.org/licenses/>.- *- * If you would like to incorporate Link into a proprietary software application,- * please contact <link-devs@ableton.com>.- */--#pragma once--#include <ableton/discovery/NetworkByteStreamSerializable.hpp>-#include <ableton/platforms/asio/AsioWrapper.hpp>-#include <cassert>--namespace ableton-{-namespace link-{--template <std::int32_t Key>-struct EndpointV6-{- static constexpr std::int32_t key = Key;-- // Model the NetworkByteStreamSerializable concept- friend std::uint32_t sizeInByteStream(const EndpointV6<Key> mep)- {- if (mep.ep.address().is_v4())- {- return 0;- }- return discovery::sizeInByteStream(mep.ep.address().to_v6().to_bytes())- + discovery::sizeInByteStream(mep.ep.port());- }-- template <typename It>- friend It toNetworkByteStream(const EndpointV6<Key> mep, It out)- {- assert(mep.ep.address().is_v6());- return discovery::toNetworkByteStream(- mep.ep.port(),- discovery::toNetworkByteStream(- mep.ep.address().to_v6().to_bytes(), std::move(out)));- }-- template <typename It>- static std::pair<EndpointV6<Key>, It> fromNetworkByteStream(It begin, It end)- {- using namespace std;- auto addrRes =- discovery::Deserialize<discovery::IpAddressV6::bytes_type>::fromNetworkByteStream(- std::move(begin), end);- auto portRes = discovery::Deserialize<std::uint16_t>::fromNetworkByteStream(- std::move(addrRes.second), end);- return make_pair(EndpointV6<Key>{{discovery::IpAddressV6{std::move(addrRes.first)},- std::move(portRes.first)}},- std::move(portRes.second));- }-- discovery::UdpEndpoint ep;-};--} // namespace link-} // namespace ableton
link/include/ableton/link/Gateway.hpp view
@@ -23,8 +23,6 @@ #include <ableton/link/MeasurementService.hpp> #include <ableton/link/PeerState.hpp> -#include <optional>- namespace ableton { namespace link@@ -35,24 +33,21 @@ { public: Gateway(util::Injected<IoContext> io,- discovery::IpAddress addr,- util::Injected<PeerObserver> observer,- NodeState nodeState,- GhostXForm ghostXForm,- Clock clock,- std::optional<discovery::UdpEndpoint> audioEndpoint = std::nullopt)+ discovery::IpAddress addr,+ util::Injected<PeerObserver> observer,+ NodeState nodeState,+ GhostXForm ghostXForm,+ Clock clock) : mIo(std::move(io)) , mMeasurement(addr,- nodeState.sessionId,- std::move(ghostXForm),- std::move(clock),- util::injectRef(*mIo))- , moAudioEndpoint(audioEndpoint)- , mPeerGateway(discovery::makeGateway(- util::injectRef(*mIo),+ nodeState.sessionId,+ std::move(ghostXForm),+ std::move(clock),+ util::injectRef(*mIo))+ , mPeerGateway(discovery::makeGateway(util::injectRef(*mIo), std::move(addr), std::move(observer),- PeerState{std::move(nodeState), mMeasurement.endpoint(), moAudioEndpoint}))+ PeerState{std::move(nodeState), mMeasurement.endpoint()})) { } @@ -62,7 +57,6 @@ Gateway(Gateway&& rhs) : mIo(std::move(rhs.mIo)) , mMeasurement(std::move(rhs.mMeasurement))- , moAudioEndpoint(std::move(rhs.moAudioEndpoint)) , mPeerGateway(std::move(rhs.mPeerGateway)) { }@@ -71,7 +65,6 @@ { mIo = std::move(rhs.mIo); mMeasurement = std::move(rhs.mMeasurement);- moAudioEndpoint = std::move(rhs.moAudioEndpoint); mPeerGateway = std::move(rhs.mPeerGateway); return *this; }@@ -79,13 +72,7 @@ void updateNodeState(std::pair<NodeState, GhostXForm> state) { mMeasurement.updateNodeState(state.first.sessionId, state.second);- mPeerGateway.updateState(- PeerState{std::move(state.first), mMeasurement.endpoint(), moAudioEndpoint});- }-- void updateAudioEndpoint(std::optional<discovery::UdpEndpoint> audioEndpoint)- {- moAudioEndpoint = audioEndpoint;+ mPeerGateway.updateState(PeerState{std::move(state.first), mMeasurement.endpoint()}); } template <typename Handler>@@ -97,7 +84,6 @@ private: util::Injected<IoContext> mIo; MeasurementService<Clock, typename util::Injected<IoContext>::type&> mMeasurement;- std::optional<discovery::UdpEndpoint> moAudioEndpoint; discovery::Gateway<PeerObserver, PeerState, typename util::Injected<IoContext>::type&> mPeerGateway; };
link/include/ableton/link/Measurement.hpp view
@@ -39,25 +39,20 @@ { using Callback = std::function<void(std::vector<double>&)>; using Micros = std::chrono::microseconds;- using Socket =- typename util::Injected<IoContext>::type::template Socket<v1::kMaxMessageSize>; static const std::size_t kNumberDataPoints = 100; static const std::size_t kNumberMeasurements = 5; Measurement(const PeerState& state,- Callback callback,- discovery::IpAddress address,- Clock clock,- util::Injected<IoContext> io,- Socket& socket)- : mpImpl(std::make_shared<Impl>(std::move(state),- std::move(callback),- std::move(address),- std::move(clock),- std::move(io),- socket))+ Callback callback,+ discovery::IpAddress address,+ Clock clock,+ util::Injected<IoContext> io)+ : mIo(std::move(io))+ , mpImpl(std::make_shared<Impl>(+ std::move(state), std::move(callback), std::move(address), std::move(clock), mIo)) {+ mpImpl->listen(); } Measurement(const Measurement&) = delete;@@ -65,44 +60,36 @@ Measurement(const Measurement&&) = delete; Measurement& operator=(Measurement&&) = delete; - template <typename It>- void operator()(const discovery::UdpEndpoint& from,- const It messageBegin,- const It messageEnd)- {- (*mpImpl)(from, messageBegin, messageEnd);- }- struct Impl : std::enable_shared_from_this<Impl> {+ using Socket =+ typename util::Injected<IoContext>::type::template Socket<v1::kMaxMessageSize>; using Timer = typename util::Injected<IoContext>::type::Timer; using Log = typename util::Injected<IoContext>::type::Log; Impl(const PeerState& state,- Callback callback,- discovery::IpAddress address,- Clock clock,- util::Injected<IoContext> io,- Socket& socket)- : mIo(std::move(io))- , mSocket(socket)+ Callback callback,+ discovery::IpAddress address,+ Clock clock,+ util::Injected<IoContext> io)+ : mSocket(io->template openUnicastSocket<v1::kMaxMessageSize>(address)) , mSessionId(state.nodeState.sessionId) , mCallback(std::move(callback)) , mClock(std::move(clock))- , mTimer(mIo->makeTimer())+ , mTimer(io->makeTimer()) , mMeasurementsStarted(0)- , mLog(channel(mIo->log(), "Measurement on gateway@" + address.to_string()))+ , mLog(channel(io->log(), "Measurement on gateway@" + address.to_string())) , mSuccess(false) {- if (state.measurementEndpoint.address().is_v4())+ if (state.endpoint.address().is_v4()) {- mEndpoint = state.measurementEndpoint;+ mEndpoint = state.endpoint; } else {- auto v6Address = state.measurementEndpoint.address().to_v6();+ auto v6Address = state.endpoint.address().to_v6(); v6Address.scope_id(address.to_v6().scope_id());- mEndpoint = {v6Address, state.measurementEndpoint.port()};+ mEndpoint = {v6Address, state.endpoint.port()}; } const auto ht = HostTime{mClock.micros()};@@ -114,31 +101,33 @@ { mTimer.cancel(); mTimer.expires_from_now(std::chrono::milliseconds(50));- mTimer.async_wait(- [this](const typename Timer::ErrorCode e)+ mTimer.async_wait([this](const typename Timer::ErrorCode e) {+ if (!e) {- if (!e)+ if (mMeasurementsStarted < kNumberMeasurements) {- if (mMeasurementsStarted < kNumberMeasurements)- {- const auto ht = HostTime{mClock.micros()};- sendPing(mEndpoint, discovery::makePayload(ht));- ++mMeasurementsStarted;- resetTimer();- }- else- {- fail();- }+ const auto ht = HostTime{mClock.micros()};+ sendPing(mEndpoint, discovery::makePayload(ht));+ ++mMeasurementsStarted;+ resetTimer(); }- });+ else+ {+ fail();+ }+ }+ }); } + void listen()+ {+ mSocket.receive(util::makeAsyncSafe(this->shared_from_this()));+ }+ // Operator to handle incoming messages on the interface template <typename It>- void operator()(const discovery::UdpEndpoint& from,- const It messageBegin,- const It messageEnd)+ void operator()(+ const discovery::UdpEndpoint& from, const It messageBegin, const It messageEnd) { using namespace std; const auto result = v1::parseMessageHeader(messageBegin, messageEnd);@@ -158,8 +147,7 @@ try { discovery::parsePayload<SessionMembership, GHostTime, PrevGHostTime, HostTime>(- payloadBegin,- messageEnd,+ payloadBegin, messageEnd, [&sessionId](const SessionMembership& sms) { sessionId = sms.sessionId; }, [&ghostTime](GHostTime gt) { ghostTime = std::move(gt.time); }, [&prevGHostTime](PrevGHostTime gt) { prevGHostTime = std::move(gt.time); },@@ -168,6 +156,7 @@ catch (const std::runtime_error& err) { warning(mLog) << "Failed parsing payload, caught exception: " << err.what();+ listen(); return; } @@ -179,7 +168,9 @@ discovery::makePayload(HostTime{hostTime}, PrevGHostTime{ghostTime}); sendPing(from, payload);+ listen(); + if (ghostTime != Micros{0} && prevHostTime != Micros{0}) { mData.push_back(@@ -211,6 +202,7 @@ else { debug(mLog) << "Received invalid message from " << from;+ listen(); } } @@ -238,34 +230,17 @@ mTimer.cancel(); mSuccess = true; debug(mLog) << "Measuring " << mEndpoint << " done.";- std::weak_ptr<Impl> pHandle = this->shared_from_this();- mIo->async(- [pHandle]()- {- if (auto pLocked = pHandle.lock())- {- pLocked->mCallback(pLocked->mData);- }- });+ mCallback(mData); } void fail() {+ mData.clear(); debug(mLog) << "Measuring " << mEndpoint << " failed.";- std::weak_ptr<Impl> pHandle = this->shared_from_this();- mIo->async(- [pHandle]()- {- if (auto pLocked = pHandle.lock())- {- pLocked->mData.clear();- pLocked->mCallback(pLocked->mData);- }- });+ mCallback(mData); } - util::Injected<IoContext> mIo;- Socket& mSocket;+ Socket mSocket; SessionId mSessionId; discovery::UdpEndpoint mEndpoint; std::vector<double> mData;@@ -277,6 +252,7 @@ bool mSuccess; }; + util::Injected<IoContext> mIo; std::shared_ptr<Impl> mpImpl; };
+ link/include/ableton/link/MeasurementEndpointV4.hpp view
@@ -0,0 +1,75 @@+/* Copyright 2016, Ableton AG, Berlin. All rights reserved.+ *+ * This program is free software: you can redistribute it and/or modify+ * it under the terms of the GNU General Public License as published by+ * the Free Software Foundation, either version 2 of the License, or+ * (at your option) any later version.+ *+ * This program is distributed in the hope that it will be useful,+ * but WITHOUT ANY WARRANTY; without even the implied warranty of+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+ * GNU General Public License for more details.+ *+ * You should have received a copy of the GNU General Public License+ * along with this program. If not, see <http://www.gnu.org/licenses/>.+ *+ * If you would like to incorporate Link into a proprietary software application,+ * please contact <link-devs@ableton.com>.+ */++#pragma once++#include <ableton/discovery/AsioTypes.hpp>+#include <ableton/discovery/NetworkByteStreamSerializable.hpp>+#include <cassert>++namespace ableton+{+namespace link+{++struct MeasurementEndpointV4+{+ static const std::int32_t key = 'mep4';+ static_assert(key == 0x6d657034, "Unexpected byte order");++ // Model the NetworkByteStreamSerializable concept+ friend std::uint32_t sizeInByteStream(const MeasurementEndpointV4 mep)+ {+ if (mep.ep.address().is_v6())+ {+ return 0;+ }+ return discovery::sizeInByteStream(+ static_cast<std::uint32_t>(mep.ep.address().to_v4().to_ulong()))+ + discovery::sizeInByteStream(mep.ep.port());+ }++ template <typename It>+ friend It toNetworkByteStream(const MeasurementEndpointV4 mep, It out)+ {+ assert(mep.ep.address().is_v4());+ return discovery::toNetworkByteStream(mep.ep.port(),+ discovery::toNetworkByteStream(+ static_cast<std::uint32_t>(mep.ep.address().to_v4().to_ulong()), std::move(out)));+ }++ template <typename It>+ static std::pair<MeasurementEndpointV4, It> fromNetworkByteStream(It begin, It end)+ {+ using namespace std;+ auto addrRes =+ discovery::Deserialize<std::uint32_t>::fromNetworkByteStream(std::move(begin), end);+ auto portRes = discovery::Deserialize<std::uint16_t>::fromNetworkByteStream(+ std::move(addrRes.second), end);+ return make_pair(+ MeasurementEndpointV4{+ {discovery::IpAddressV4{std::move(addrRes.first)}, std::move(portRes.first)}},+ std::move(portRes.second));+ }++ discovery::UdpEndpoint ep;+};++} // namespace link+} // namespace ableton
+ link/include/ableton/link/MeasurementEndpointV6.hpp view
@@ -0,0 +1,75 @@+/* Copyright 2023, Ableton AG, Berlin. All rights reserved.+ *+ * This program is free software: you can redistribute it and/or modify+ * it under the terms of the GNU General Public License as published by+ * the Free Software Foundation, either version 2 of the License, or+ * (at your option) any later version.+ *+ * This program is distributed in the hope that it will be useful,+ * but WITHOUT ANY WARRANTY; without even the implied warranty of+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+ * GNU General Public License for more details.+ *+ * You should have received a copy of the GNU General Public License+ * along with this program. If not, see <http://www.gnu.org/licenses/>.+ *+ * If you would like to incorporate Link into a proprietary software application,+ * please contact <link-devs@ableton.com>.+ */++#pragma once++#include <ableton/discovery/NetworkByteStreamSerializable.hpp>+#include <ableton/platforms/asio/AsioWrapper.hpp>+#include <cassert>++namespace ableton+{+namespace link+{++struct MeasurementEndpointV6+{+ static const std::int32_t key = 'mep6';+ static_assert(key == 0x6d657036, "Unexpected byte order");++ // Model the NetworkByteStreamSerializable concept+ friend std::uint32_t sizeInByteStream(const MeasurementEndpointV6 mep)+ {+ if (mep.ep.address().is_v4())+ {+ return 0;+ }+ return discovery::sizeInByteStream(mep.ep.address().to_v6().to_bytes())+ + discovery::sizeInByteStream(mep.ep.port());+ }++ template <typename It>+ friend It toNetworkByteStream(const MeasurementEndpointV6 mep, It out)+ {+ assert(mep.ep.address().is_v6());+ return discovery::toNetworkByteStream(+ mep.ep.port(), discovery::toNetworkByteStream(+ mep.ep.address().to_v6().to_bytes(), std::move(out)));+ }++ template <typename It>+ static std::pair<MeasurementEndpointV6, It> fromNetworkByteStream(It begin, It end)+ {+ using namespace std;+ auto addrRes =+ discovery::Deserialize<discovery::IpAddressV6::bytes_type>::fromNetworkByteStream(+ std::move(begin), end);+ auto portRes = discovery::Deserialize<std::uint16_t>::fromNetworkByteStream(+ std::move(addrRes.second), end);+ return make_pair(+ MeasurementEndpointV6{+ {discovery::IpAddressV6{std::move(addrRes.first)}, std::move(portRes.first)}},+ std::move(portRes.second));+ }++ discovery::UdpEndpoint ep;+};++} // namespace link+} // namespace ableton
link/include/ableton/link/MeasurementService.hpp view
@@ -39,19 +39,22 @@ class MeasurementService { public:- using IoType = typename util::Injected<IoContext>::type;- using MeasurementInstance = Measurement<Clock, IoType&>;+ using IoType = util::Injected<IoContext>;+ using MeasurementInstance = Measurement<Clock, IoContext>; MeasurementService(discovery::IpAddress address,- SessionId sessionId,- GhostXForm ghostXForm,- Clock clock,- util::Injected<IoContext> io)+ SessionId sessionId,+ GhostXForm ghostXForm,+ Clock clock,+ IoType io) : mClock(std::move(clock))- , mpImpl(std::make_shared<Impl>(- address, std::move(sessionId), std::move(ghostXForm), mClock, std::move(io)))+ , mIo(std::move(io))+ , mPingResponder(std::move(address),+ std::move(sessionId),+ std::move(ghostXForm),+ mClock,+ util::injectRef(*mIo)) {- mpImpl->listen(); } MeasurementService(const MeasurementService&) = delete;@@ -59,10 +62,13 @@ void updateNodeState(const SessionId& sessionId, const GhostXForm& xform) {- mpImpl->updateNodeState(sessionId, xform);+ mPingResponder.updateNodeState(sessionId, xform); } - discovery::UdpEndpoint endpoint() const { return mpImpl->socket().endpoint(); }+ discovery::UdpEndpoint endpoint() const+ {+ return mPingResponder.endpoint();+ } // Measure the peer and invoke the handler with a GhostXForm template <typename Handler>@@ -71,83 +77,28 @@ using namespace std; const auto nodeId = state.nodeState.nodeId;- auto addr = mpImpl->socket().endpoint().address();- auto callback = CompletionCallback<Handler>{mpImpl, nodeId, handler};+ auto addr = mPingResponder.endpoint().address();+ auto callback = CompletionCallback<Handler>{*this, nodeId, handler}; try {- mpImpl->mMeasurementMap[nodeId] =- std::make_unique<MeasurementInstance>(state,- std::move(callback),- std::move(addr),- mClock,- util::injectRef(*(mpImpl->mIo)),- mpImpl->socket());+ mMeasurementMap[nodeId] =+ std::unique_ptr<MeasurementInstance>(new MeasurementInstance{+ state, std::move(callback), std::move(addr), mClock, mIo}); } catch (const runtime_error& err) {- info(mpImpl->mIo->log()) << "gateway@" + addr.to_string()- << " Failed to measure. Reason: " << err.what();+ info(mIo->log()) << "gateway@" + addr.to_string()+ << " Failed to measure. Reason: " << err.what(); handler(GhostXForm{}); } } - struct Impl : std::enable_shared_from_this<Impl>- {- using Socket = typename IoType::template Socket<v1::kMaxMessageSize>;-- Impl(discovery::IpAddress address,- SessionId sessionId,- GhostXForm ghostXForm,- Clock clock,- util::Injected<IoContext> io)- : mIo(std::move(io))- , mSocket((*mIo).template openUnicastSocket<v1::kMaxMessageSize>(address))- , mPingResponder(mSocket,- std::move(sessionId),- std::move(ghostXForm),- clock,- util::injectRef(*mIo))- {- }-- void updateNodeState(const SessionId& sessionId, const GhostXForm& xform)- {- mPingResponder.updateNodeState(sessionId, xform);- }-- template <typename It>- void operator()(const discovery::UdpEndpoint& from,- const It messageBegin,- const It messageEnd)- {- mPingResponder(from, messageBegin, messageEnd);-- for (auto it = mMeasurementMap.begin(); it != mMeasurementMap.end(); ++it)- {- (*(it->second))(from, messageBegin, messageEnd);- }-- listen();- }-- void listen() { mSocket.receive(util::makeAsyncSafe(this->shared_from_this())); }-- Socket& socket() { return mSocket; }-- using MeasurementMap = std::map<NodeId, std::unique_ptr<MeasurementInstance>>;-- util::Injected<IoContext> mIo;- Socket mSocket;- PingResponder<Clock, IoType&> mPingResponder;- MeasurementMap mMeasurementMap;- };- private: template <typename Handler> struct CompletionCallback {- void operator()(std::vector<double> data)+ void operator()(std::vector<double>& data) { using namespace std; using std::chrono::microseconds;@@ -158,7 +109,7 @@ // gone by the time the block gets executed. auto nodeId = mNodeId; auto handler = mHandler;- auto& measurementMap = mpImpl->mMeasurementMap;+ auto& measurementMap = mMeasurementService.mMeasurementMap; const auto it = measurementMap.find(nodeId); if (it != measurementMap.end()) {@@ -174,7 +125,7 @@ } } - std::shared_ptr<Impl> mpImpl;+ MeasurementService& mMeasurementService; NodeId mNodeId; Handler mHandler; };@@ -182,9 +133,11 @@ // Make sure the measurement map outlives the IoContext so that the rest of // the members are guaranteed to be valid when any final handlers // are begin run.-+ using MeasurementMap = std::map<NodeId, std::unique_ptr<MeasurementInstance>>;+ MeasurementMap mMeasurementMap; Clock mClock;- std::shared_ptr<Impl> mpImpl;+ IoType mIo;+ PingResponder<Clock, IoContext> mPingResponder; }; } // namespace link
link/include/ableton/link/NodeId.hpp view
@@ -23,7 +23,6 @@ #include <algorithm> #include <array> #include <cstdint>-#include <iomanip> #include <string> namespace ableton@@ -56,18 +55,7 @@ friend std::ostream& operator<<(std::ostream& stream, const NodeId& id) {- const auto flags = stream.flags();- const auto fill = stream.fill();-- stream << "0x" << std::hex << std::setfill('0');- for (const auto byte : id)- {- stream << std::setw(2) << static_cast<int>(byte);- }-- stream.flags(flags);- stream.fill(fill);- return stream;+ return stream << std::string{id.cbegin(), id.cend()}; } template <typename It>
link/include/ableton/link/NodeState.hpp view
@@ -35,7 +35,10 @@ using Payload = decltype(discovery::makePayload(Timeline{}, SessionMembership{}, StartStopState{})); - NodeId ident() const { return nodeId; }+ NodeId ident() const+ {+ return nodeId;+ } friend bool operator==(const NodeState& lhs, const NodeState& rhs) {@@ -54,14 +57,13 @@ { using namespace std; auto nodeState = NodeState{std::move(nodeId), {}, {}, {}};- discovery::parsePayload<Timeline, SessionMembership, StartStopState>(- std::move(begin),- std::move(end),- [&nodeState](Timeline tl) { nodeState.timeline = std::move(tl); },- [&nodeState](SessionMembership membership)- { nodeState.sessionId = std::move(membership.sessionId); },- [&nodeState](StartStopState ststst)- { nodeState.startStopState = std::move(ststst); });+ discovery::parsePayload<Timeline, SessionMembership, StartStopState>(std::move(begin),+ std::move(end), [&nodeState](Timeline tl) { nodeState.timeline = std::move(tl); },+ [&nodeState](SessionMembership membership) {+ nodeState.sessionId = std::move(membership.sessionId);+ },+ [&nodeState](+ StartStopState ststst) { nodeState.startStopState = std::move(ststst); }); return nodeState; }
+ link/include/ableton/link/Optional.hpp view
@@ -0,0 +1,97 @@+/* Copyright 2017, Ableton AG, Berlin. All rights reserved.+ *+ * This program is free software: you can redistribute it and/or modify+ * it under the terms of the GNU General Public License as published by+ * the Free Software Foundation, either version 2 of the License, or+ * (at your option) any later version.+ *+ * This program is distributed in the hope that it will be useful,+ * but WITHOUT ANY WARRANTY; without even the implied warranty of+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+ * GNU General Public License for more details.+ *+ * You should have received a copy of the GNU General Public License+ * along with this program. If not, see <http://www.gnu.org/licenses/>.+ *+ * If you would like to incorporate Link into a proprietary software application,+ * please contact <link-devs@ableton.com>.+ */++#pragma once++#include <cassert>+#include <utility>++namespace ableton+{+namespace link+{++// Subset of the C++ 17 std::optional API. T has to be default constructible.+template <typename T>+struct Optional+{+ Optional()+ : mHasValue(false)+ {+ }++ explicit Optional(T value)+ : mValue(std::move(value))+ , mHasValue(true)+ {+ }++ Optional(const Optional&) = default;++ Optional(Optional&& other)+ : mValue(std::move(other.mValue))+ , mHasValue(other.mHasValue)+ {+ }++ Optional& operator=(const Optional&) = default;++ Optional& operator=(Optional&& other)+ {+ mValue = std::move(other.mValue);+ mHasValue = other.mHasValue;+ return *this;+ }++ explicit operator bool() const+ {+ return mHasValue;+ }++ const T& operator*() const+ {+ assert(mHasValue);+ return mValue;+ }++ T& operator*()+ {+ assert(mHasValue);+ return mValue;+ }++ const T* operator->() const+ {+ assert(mHasValue);+ return &mValue;+ }++ T* operator->()+ {+ assert(mHasValue);+ return &mValue;+ }++private:+ T mValue;+ bool mHasValue;+};++} // namespace link+} // namespace ableton
link/include/ableton/link/PeerState.hpp view
@@ -20,12 +20,10 @@ #pragma once #include <ableton/discovery/Payload.hpp>-#include <ableton/link/EndpointV4.hpp>-#include <ableton/link/EndpointV6.hpp>+#include <ableton/link/MeasurementEndpointV4.hpp>+#include <ableton/link/MeasurementEndpointV6.hpp> #include <ableton/link/NodeState.hpp> -#include <optional>- namespace ableton { namespace link@@ -37,96 +35,61 @@ struct PeerState {- static constexpr std::int32_t kMep4Key = 'mep4';- using MeasurementEndpointV4 = EndpointV4<kMep4Key>;- static_assert(MeasurementEndpointV4::key == 0x6d657034, "Unexpected byte order");-- static constexpr std::int32_t kMep6Key = 'mep6';- using MeasurementEndpointV6 = EndpointV6<kMep6Key>;- static_assert(MeasurementEndpointV6::key == 0x6d657036, "Unexpected byte order");-- static constexpr std::int32_t kAep4Key = 'aep4';- using AudioEndpointV4 = EndpointV4<kAep4Key>;- static_assert(AudioEndpointV4::key == 0x61657034, "Unexpected byte order");-- static constexpr std::int32_t kAep6Key = 'aep6';- using AudioEndpointV6 = EndpointV6<kAep6Key>;- static_assert(AudioEndpointV6::key == 0x61657036, "Unexpected byte order");- using IdType = NodeId; - IdType ident() const { return nodeState.ident(); }+ IdType ident() const+ {+ return nodeState.ident();+ } - SessionId sessionId() const { return nodeState.sessionId; }+ SessionId sessionId() const+ {+ return nodeState.sessionId;+ } - Timeline timeline() const { return nodeState.timeline; }+ Timeline timeline() const+ {+ return nodeState.timeline;+ } - StartStopState startStopState() const { return nodeState.startStopState; }+ StartStopState startStopState() const+ {+ return nodeState.startStopState;+ } friend bool operator==(const PeerState& lhs, const PeerState& rhs) {- return lhs.nodeState == rhs.nodeState- && lhs.measurementEndpoint == rhs.measurementEndpoint- && lhs.audioEndpoint == rhs.audioEndpoint;+ return lhs.nodeState == rhs.nodeState && lhs.endpoint == rhs.endpoint; } - friend auto toPayload(const PeerState& state)- -> decltype(std::declval<NodeState::Payload>()- + discovery::makePayload(MeasurementEndpointV4{{}})- + discovery::makePayload(MeasurementEndpointV6{{}})- + discovery::makePayload(AudioEndpointV4{{}})- + discovery::makePayload(AudioEndpointV6{{}}))+ friend auto toPayload(const PeerState& state) -> decltype(+ std::declval<NodeState::Payload>() + discovery::makePayload(MeasurementEndpointV4{{}})+ + discovery::makePayload(MeasurementEndpointV6{{}})) { // This implements a switch if either an IPv4 or IPv6 endpoint is serialized. // MeasurementEndpoints that contain an endpoint that does not match the IP protocol // version return a sizeInByteStream() of zero and won't be serialized. return toPayload(state.nodeState)- + discovery::makePayload(MeasurementEndpointV4{state.measurementEndpoint})- + discovery::makePayload(MeasurementEndpointV6{state.measurementEndpoint})- + discovery::makePayload(AudioEndpointV4{- state.audioEndpoint- ? *state.audioEndpoint- : discovery::UdpEndpoint{discovery::makeAddress("::"), {}}})- + discovery::makePayload(AudioEndpointV6{- state.audioEndpoint- ? *state.audioEndpoint- : discovery::UdpEndpoint{discovery::makeAddress("0.0.0.0"), {}}-- });+ + discovery::makePayload(MeasurementEndpointV4{state.endpoint})+ + discovery::makePayload(MeasurementEndpointV6{state.endpoint}); } template <typename It> static PeerState fromPayload(NodeId id, It begin, It end) { using namespace std;- auto peerState = PeerState{NodeState::fromPayload(std::move(id), begin, end), {}, {}};+ auto peerState = PeerState{NodeState::fromPayload(std::move(id), begin, end), {}}; - discovery::parsePayload<MeasurementEndpointV4,- MeasurementEndpointV6,- AudioEndpointV4,- AudioEndpointV6>(- std::move(begin),- std::move(end),- [&peerState](MeasurementEndpointV4 me4)- { peerState.measurementEndpoint = std::move(me4.ep); },- [&peerState](MeasurementEndpointV6 me6)- { peerState.measurementEndpoint = std::move(me6.ep); },- [&peerState](AudioEndpointV4 ae4)- {- peerState.audioEndpoint =- std::optional<discovery::UdpEndpoint>(std::move(ae4.ep));- },- [&peerState](AudioEndpointV6 ae6)- {- peerState.audioEndpoint =- std::optional<discovery::UdpEndpoint>(std::move(ae6.ep));- });+ discovery::parsePayload<MeasurementEndpointV4, MeasurementEndpointV6>(+ std::move(begin), std::move(end),+ [&peerState](MeasurementEndpointV4 me4) { peerState.endpoint = std::move(me4.ep); },+ [&peerState](+ MeasurementEndpointV6 me6) { peerState.endpoint = std::move(me6.ep); }); return peerState; } NodeState nodeState;- discovery::UdpEndpoint measurementEndpoint;- std::optional<discovery::UdpEndpoint> audioEndpoint;+ discovery::UdpEndpoint endpoint; }; } // namespace link
link/include/ableton/link/Peers.hpp view
@@ -38,10 +38,9 @@ // whenever a new combination of these values is seen template <typename IoContext,- typename SessionMembershipCallback,- typename SessionTimelineCallback,- typename SessionStartStopStateCallback,- typename AudioEndpointCallback>+ typename SessionMembershipCallback,+ typename SessionTimelineCallback,+ typename SessionStartStopStateCallback> class Peers { // non-movable private implementation type@@ -51,15 +50,11 @@ using Peer = std::pair<PeerState, discovery::IpAddress>; Peers(util::Injected<IoContext> io,- SessionMembershipCallback membership,- SessionTimelineCallback timeline,- SessionStartStopStateCallback startStop,- AudioEndpointCallback audioEndpoint)- : mpImpl(std::make_shared<Impl>(std::move(io),- std::move(membership),- std::move(timeline),- std::move(startStop),- std::move(audioEndpoint)))+ SessionMembershipCallback membership,+ SessionTimelineCallback timeline,+ SessionStartStopStateCallback startStop)+ : mpImpl(std::make_shared<Impl>(+ std::move(io), std::move(membership), std::move(timeline), std::move(startStop))) { } @@ -80,10 +75,8 @@ { using namespace std; auto peerVec = sessionPeers(sid);- auto last = unique(begin(peerVec),- end(peerVec),- [](const Peer& a, const Peer& b)- { return a.first.ident() == b.first.ident(); });+ auto last = unique(begin(peerVec), end(peerVec),+ [](const Peer& a, const Peer& b) { return a.first.ident() == b.first.ident(); }); return static_cast<size_t>(distance(begin(peerVec), last)); } @@ -113,7 +106,10 @@ remove_if(begin(peerVec), end(peerVec), SessionMemberPred{sid}), end(peerVec)); } - void resetPeers() { mpImpl->mPeers.clear(); }+ void resetPeers()+ {+ mpImpl->mPeers.clear();+ } // Observer type that monitors peer discovery on a particular // gateway and relays the information to a Peers instance.@@ -151,21 +147,21 @@ auto pImpl = observer.mpImpl; auto addr = observer.mAddr; assert(pImpl);- pImpl->sawPeerOnGateway(state, std::move(addr));+ pImpl->sawPeerOnGateway(std::move(state), std::move(addr)); } friend void peerLeft(GatewayObserver& observer, const NodeId& id) { auto pImpl = observer.mpImpl; auto addr = observer.mAddr;- pImpl->peerLeftGateway(id, std::move(addr));+ pImpl->peerLeftGateway(std::move(id), std::move(addr)); } friend void peerTimedOut(GatewayObserver& observer, const NodeId& id) { auto pImpl = observer.mpImpl; auto addr = observer.mAddr;- pImpl->peerLeftGateway(id, std::move(addr));+ pImpl->peerLeftGateway(std::move(id), std::move(addr)); } std::shared_ptr<Impl> mpImpl;@@ -182,15 +178,13 @@ struct Impl { Impl(util::Injected<IoContext> io,- SessionMembershipCallback membership,- SessionTimelineCallback timeline,- SessionStartStopStateCallback startStop,- AudioEndpointCallback audioEndpointCallback)+ SessionMembershipCallback membership,+ SessionTimelineCallback timeline,+ SessionStartStopStateCallback startStop) : mIo(std::move(io)) , mSessionMembershipCallback(std::move(membership)) , mSessionTimelineCallback(std::move(timeline)) , mSessionStartStopStateCallback(std::move(startStop))- , mAudioEndpointCallback(std::move(audioEndpointCallback)) { } @@ -206,7 +200,7 @@ bool isNewSessionStartStopState = !sessionStartStopStateExists(peerSession, peerStartStopState); - auto peer = make_pair(peerState, gatewayAddr);+ auto peer = make_pair(std::move(peerState), std::move(gatewayAddr)); const auto idRange = equal_range(begin(mPeers), end(mPeers), peer, PeerIdComp{}); bool didSessionMembershipChange = false;@@ -220,10 +214,9 @@ { // We've seen this peer before... does it have a new session? didSessionMembershipChange =- all_of(idRange.first,- idRange.second,- [&peerSession](const Peer& test)- { return test.first.sessionId() != peerSession; });+ all_of(idRange.first, idRange.second, [&peerSession](const Peer& test) {+ return test.first.sessionId() != peerSession;+ }); // was it on this gateway? const auto addrRange =@@ -260,19 +253,15 @@ { mSessionMembershipCallback(); }-- mAudioEndpointCallback(peerState.ident(), peerState.audioEndpoint, gatewayAddr); } void peerLeftGateway(const NodeId& nodeId, const discovery::IpAddress& gatewayAddr) { using namespace std; - auto it =- find_if(begin(mPeers),- end(mPeers),- [&](const Peer& peer)- { return peer.first.ident() == nodeId && peer.second == gatewayAddr; });+ auto it = find_if(begin(mPeers), end(mPeers), [&](const Peer& peer) {+ return peer.first.ident() == nodeId && peer.second == gatewayAddr;+ }); bool didSessionMembershipChange = false; if (it != end(mPeers))@@ -291,11 +280,10 @@ { using namespace std; - mPeers.erase(remove_if(begin(mPeers),- end(mPeers),- [&gatewayAddr](const Peer& peer)- { return peer.second == gatewayAddr; }),- end(mPeers));+ mPeers.erase(+ remove_if(begin(mPeers), end(mPeers),+ [&gatewayAddr](const Peer& peer) { return peer.second == gatewayAddr; }),+ end(mPeers)); mSessionMembershipCallback(); }@@ -304,27 +292,23 @@ bool hasPeerWith(const SessionId& sessionId, Predicate predicate) { using namespace std;- return find_if(- begin(mPeers),- end(mPeers),- [&](const Peer& peer)- { return peer.first.sessionId() == sessionId && predicate(peer.first); })- != end(mPeers);+ return find_if(begin(mPeers), end(mPeers), [&](const Peer& peer) {+ return peer.first.sessionId() == sessionId && predicate(peer.first);+ }) != end(mPeers); } bool sessionTimelineExists(const SessionId& session, const Timeline& timeline) { return hasPeerWith(session,- [&](const PeerState& peerState)- { return peerState.timeline() == timeline; });+ [&](const PeerState& peerState) { return peerState.timeline() == timeline; }); } - bool sessionStartStopStateExists(const SessionId& sessionId,- const StartStopState& startStopState)+ bool sessionStartStopStateExists(+ const SessionId& sessionId, const StartStopState& startStopState) {- return hasPeerWith(sessionId,- [&](const PeerState& peerState)- { return peerState.startStopState() == startStopState; });+ return hasPeerWith(sessionId, [&](const PeerState& peerState) {+ return peerState.startStopState() == startStopState;+ }); } struct PeerIdComp@@ -347,13 +331,15 @@ SessionMembershipCallback mSessionMembershipCallback; SessionTimelineCallback mSessionTimelineCallback; SessionStartStopStateCallback mSessionStartStopStateCallback;- AudioEndpointCallback mAudioEndpointCallback; std::vector<Peer> mPeers; // sorted by peerId, unique by (peerId, addr) }; struct SessionMemberPred {- bool operator()(const Peer& peer) const { return peer.first.sessionId() == sid; }+ bool operator()(const Peer& peer) const+ {+ return peer.first.sessionId() == sid;+ } const SessionId& sid; };@@ -362,26 +348,20 @@ }; template <typename Io,- typename SessionMembershipCallback,- typename SessionTimelineCallback,- typename SessionStartStopStateCallback,- typename AudioEndpointCallback>+ typename SessionMembershipCallback,+ typename SessionTimelineCallback,+ typename SessionStartStopStateCallback> Peers<Io,- SessionMembershipCallback,- SessionTimelineCallback,- SessionStartStopStateCallback,- AudioEndpointCallback>+ SessionMembershipCallback,+ SessionTimelineCallback,+ SessionStartStopStateCallback> makePeers(util::Injected<Io> io,- SessionMembershipCallback membershipCallback,- SessionTimelineCallback timelineCallback,- SessionStartStopStateCallback startStopStateCallback,- AudioEndpointCallback audioEndpointCallback)+ SessionMembershipCallback membershipCallback,+ SessionTimelineCallback timelineCallback,+ SessionStartStopStateCallback startStopStateCallback) {- return {std::move(io),- std::move(membershipCallback),- std::move(timelineCallback),- std::move(startStopStateCallback),- std::move(audioEndpointCallback)};+ return {std::move(io), std::move(membershipCallback), std::move(timelineCallback),+ std::move(startStopStateCallback)}; } } // namespace link
link/include/ableton/link/Phase.hpp view
@@ -73,9 +73,8 @@ // time. The phase of the resulting beat value can be calculated with // phase(beats, quantum). The result will deviate by up to +- // (quantum/2) beats compared to the result of tl.toBeats(time).-inline Beats toPhaseEncodedBeats(const Timeline& tl,- const std::chrono::microseconds time,- const Beats quantum)+inline Beats toPhaseEncodedBeats(+ const Timeline& tl, const std::chrono::microseconds time, const Beats quantum) { const auto beat = tl.toBeats(time); return closestPhaseMatch(beat, beat - tl.beatOrigin, quantum);@@ -84,9 +83,8 @@ // The inverse of toPhaseEncodedBeats. Given a phase encoded beat // value from the given timeline and quantum, find the time value that // it maps to.-inline std::chrono::microseconds fromPhaseEncodedBeats(const Timeline& tl,- const Beats beat,- const Beats quantum)+inline std::chrono::microseconds fromPhaseEncodedBeats(+ const Timeline& tl, const Beats beat, const Beats quantum) { const auto fromOrigin = beat - tl.beatOrigin; const auto originOffset = fromOrigin - phase(fromOrigin, quantum);
link/include/ableton/link/PingResponder.hpp view
@@ -36,21 +36,23 @@ template <typename Clock, typename IoContext> class PingResponder {- using IoType = typename util::Injected<IoContext>::type;- using Socket = typename IoType::template Socket<v1::kMaxMessageSize>;+ using IoType = util::Injected<IoContext&>;+ using Socket = typename IoType::type::template Socket<v1::kMaxMessageSize>; public:- PingResponder(Socket& socket,- SessionId sessionId,- GhostXForm ghostXForm,- Clock clock,- util::Injected<IoContext> io)- : mpImpl(std::make_shared<Impl>(socket,- std::move(sessionId),- std::move(ghostXForm),- std::move(clock),- std::move(io)))+ PingResponder(discovery::IpAddress address,+ SessionId sessionId,+ GhostXForm ghostXForm,+ Clock clock,+ IoType io)+ : mIo(io)+ , mpImpl(std::make_shared<Impl>(std::move(address),+ std::move(sessionId),+ std::move(ghostXForm),+ std::move(clock),+ std::move(io))) {+ mpImpl->listen(); } PingResponder(const PingResponder&) = delete;@@ -62,36 +64,42 @@ mpImpl->mGhostXForm = std::move(xform); } - discovery::UdpEndpoint endpoint() const { return mpImpl->mSocket.endpoint(); }-- discovery::IpAddress address() const { return endpoint().address(); }+ discovery::UdpEndpoint endpoint() const+ {+ return mpImpl->mSocket.endpoint();+ } - Socket socket() const { return mpImpl->mSocket; }+ discovery::IpAddress address() const+ {+ return endpoint().address();+ } - template <typename It>- void operator()(const discovery::UdpEndpoint& from,- const It messageBegin,- const It messageEnd)+ Socket socket() const {- (*mpImpl)(from, messageBegin, messageEnd);+ return mpImpl->mSocket; } private: struct Impl : std::enable_shared_from_this<Impl> {- Impl(Socket& socket,- SessionId sessionId,- GhostXForm ghostXForm,- Clock clock,- util::Injected<IoContext> io)+ Impl(discovery::IpAddress address,+ SessionId sessionId,+ GhostXForm ghostXForm,+ Clock clock,+ IoType io) : mSessionId(std::move(sessionId)) , mGhostXForm(std::move(ghostXForm)) , mClock(std::move(clock))- , mLog(channel(io->log(), "gateway@" + socket.endpoint().address().to_string()))- , mSocket(socket)+ , mLog(channel(io->log(), "gateway@" + address.to_string()))+ , mSocket(io->template openUnicastSocket<v1::kMaxMessageSize>(address)) { } + void listen()+ {+ mSocket.receive(util::makeAsyncSafe(this->shared_from_this()));+ }+ // Operator to handle incoming messages on the interface template <typename It> void operator()(const discovery::UdpEndpoint& from, const It begin, const It end)@@ -124,6 +132,7 @@ { info(mLog) << " Received invalid Message from " << from << "."; }+ listen(); } template <typename It>@@ -150,10 +159,11 @@ SessionId mSessionId; GhostXForm mGhostXForm; Clock mClock;- typename IoType::Log mLog;- Socket& mSocket;+ typename IoType::type::Log mLog;+ Socket mSocket; }; + IoType mIo; std::shared_ptr<Impl> mpImpl; };
− link/include/ableton/link/SessionController.hpp
@@ -1,106 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- * This program is free software: you can redistribute it and/or modify- * it under the terms of the GNU General Public License as published by- * the Free Software Foundation, either version 2 of the License, or- * (at your option) any later version.- *- * This program is distributed in the hope that it will be useful,- * but WITHOUT ANY WARRANTY; without even the implied warranty of- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- * GNU General Public License for more details.- *- * You should have received a copy of the GNU General Public License- * along with this program. If not, see <http://www.gnu.org/licenses/>.- *- * If you would like to incorporate Link into a proprietary software application,- * please contact <link-devs@ableton.com>.- */--#pragma once--#include <ableton/link/Controller.hpp>--#include <optional>--namespace ableton-{-namespace link-{--template <typename PeerCountCallback,- typename TempoCallback,- typename StartStopStateCallback,- typename Clock,- typename Random,- typename IoContext>-class SessionController : public Controller<PeerCountCallback,- TempoCallback,- StartStopStateCallback,- Clock,- Random,- IoContext,- SessionController<PeerCountCallback,- TempoCallback,- StartStopStateCallback,- Clock,- Random,- IoContext>>-{-public:- using LinkController = Controller<PeerCountCallback,- TempoCallback,- StartStopStateCallback,- Clock,- Random,- IoContext,- SessionController<PeerCountCallback,- TempoCallback,- StartStopStateCallback,- Clock,- Random,- IoContext>>;-- SessionController(Tempo tempo,- PeerCountCallback peerCallback,- TempoCallback tempoCallback,- StartStopStateCallback startStopStateCallback,- Clock clock)- : LinkController(tempo, peerCallback, tempoCallback, startStopStateCallback, clock)- {- this->mRtClientStateSetter.start();- }-- ~SessionController() { this->shutdown(); }-- void sessionMembershipCallback() { this->mSessionPeerCounter(); }-- void joinSessionCallback(const Session& session) { this->joinSession(session); }-- template <typename Peer, typename Handler>- void measurePeerCallback(Peer peer, Handler handler)- {- this->measurePeer(std::move(peer), std::move(handler));- }-- void updateDiscoveryCallback() { this->updateDiscovery(); }-- void gatewaysChangedCallback() {}-- void updateRtStatesCallback()- {- // Process the pending client states first to make sure we don't push one- // after we have joined a running session when enabling- this->mRtClientStateSetter.processPendingClientStates();- this->mRtClientStateSetter.updateEnabled();- }-- void sawAudioEndpointCallback(NodeId,- std::optional<discovery::UdpEndpoint>,- discovery::IpAddress)- {- }-};--} // namespace link-} // namespace ableton
link/include/ableton/link/SessionState.hpp view
@@ -19,21 +19,20 @@ #pragma once -#include <ableton/link/SessionId.hpp>+#include <ableton/link/Optional.hpp> #include <ableton/link/StartStopState.hpp> #include <ableton/link/Timeline.hpp>-#include <ableton/util/TripleBuffer.hpp>+#include <ableton/link/TripleBuffer.hpp> #include <mutex>-#include <optional> namespace ableton { namespace link { -using OptionalTimeline = std::optional<Timeline>;-using OptionalStartStopState = std::optional<StartStopState>;-using OptionalClientStartStopState = std::optional<ClientStartStopState>;+using OptionalTimeline = Optional<Timeline>;+using OptionalStartStopState = Optional<StartStopState>;+using OptionalClientStartStopState = Optional<ClientStartStopState>; struct SessionState {@@ -56,7 +55,6 @@ } Timeline timeline;- SessionId timelineSessionId; ClientStartStopState startStopState; }; @@ -82,18 +80,20 @@ return mState; } - ClientState getRt() const { return mRtState.read(); }+ ClientState getRt() const+ {+ return mRtState.read();+ } private: mutable std::mutex mMutex; ClientState mState;- mutable util::TripleBuffer<ClientState> mRtState;+ mutable TripleBuffer<ClientState> mRtState; }; struct RtClientState { Timeline timeline;- SessionId timelineSessionId; ClientStartStopState startStopState; std::chrono::microseconds timelineTimestamp; std::chrono::microseconds startStopStateTimestamp;@@ -108,33 +108,9 @@ struct ApiState {- friend bool operator==(const ApiState& lhs, const ApiState& rhs)- {- return std::tie(lhs.timeline, lhs.timelineSessionId, lhs.startStopState)- == std::tie(rhs.timeline, rhs.timelineSessionId, rhs.startStopState);- }-- friend bool operator!=(const ApiState& lhs, const ApiState& rhs)- {- return !(lhs == rhs);- }- Timeline timeline;- SessionId timelineSessionId; ApiStartStopState startStopState; }; } // namespace link---namespace detail-{-template <typename SessionState>-const link::ApiState& linkApiState(const SessionState& sessionState)-{- return sessionState.mState;-}--} // namespace detail- } // namespace ableton
link/include/ableton/link/Sessions.hpp view
@@ -42,21 +42,21 @@ }; template <typename Peers,- typename MeasurePeer,- typename JoinSessionCallback,- typename IoContext,- typename Clock>+ typename MeasurePeer,+ typename JoinSessionCallback,+ typename IoContext,+ typename Clock> class Sessions { public: using Timer = typename util::Injected<IoContext>::type::Timer; Sessions(Session init,- util::Injected<Peers> peers,- MeasurePeer measure,- JoinSessionCallback join,- util::Injected<IoContext> io,- Clock clock)+ util::Injected<Peers> peers,+ MeasurePeer measure,+ JoinSessionCallback join,+ util::Injected<IoContext> io,+ Clock clock) : mPeers(std::move(peers)) , mMeasure(std::move(measure)) , mCallback(std::move(join))@@ -73,7 +73,10 @@ mOtherSessions.clear(); } - void resetTimeline(Timeline timeline) { mCurrent.timeline = std::move(timeline); }+ void resetTimeline(Timeline timeline)+ {+ mCurrent.timeline = std::move(timeline);+ } // Consider the observed session/timeline pair and return a possibly // new timeline that should be used going forward.@@ -114,10 +117,8 @@ if (!peers.empty()) { // first criteria: always prefer the founding peer- const auto it = find_if(begin(peers),- end(peers),- [&session](const Peer& peer)- { return session.sessionId == peer.first.ident(); });+ const auto it = find_if(begin(peers), end(peers),+ [&session](const Peer& peer) { return session.sessionId == peer.first.ident(); }); // TODO: second criteria should be degree. We don't have that // represented yet so just use the first peer for now auto peer = it == end(peers) ? peers.front() : *it;@@ -160,7 +161,7 @@ const auto ghostDiff = newGhost - curGhost; if (ghostDiff > SESSION_EPS || (std::abs(ghostDiff.count()) < SESSION_EPS.count()- && id < mCurrent.sessionId))+ && id < mCurrent.sessionId)) { // The new session wins, switch over to it auto current = mCurrent;@@ -184,15 +185,13 @@ { // set a timer to re-measure the active session after a period mTimer.expires_from_now(std::chrono::microseconds{30000000});- mTimer.async_wait(- [this](const typename Timer::ErrorCode e)+ mTimer.async_wait([this](const typename Timer::ErrorCode e) {+ if (!e) {- if (!e)- {- launchSessionMeasurement(mCurrent);- scheduleRemeasurement();- }- });+ launchSessionMeasurement(mCurrent);+ scheduleRemeasurement();+ }+ }); } void handleFailedMeasurement(const SessionId& id)@@ -281,10 +280,10 @@ }; template <typename Peers,- typename MeasurePeer,- typename JoinSessionCallback,- typename IoContext,- typename Clock>+ typename MeasurePeer,+ typename JoinSessionCallback,+ typename IoContext,+ typename Clock> Sessions<Peers, MeasurePeer, JoinSessionCallback, IoContext, Clock> makeSessions( Session init, util::Injected<Peers> peers,@@ -294,12 +293,8 @@ Clock clock) { using namespace std;- return {std::move(init),- std::move(peers),- std::move(measure),- std::move(join),- std::move(io),- std::move(clock)};+ return {std::move(init), std::move(peers), std::move(measure), std::move(join),+ std::move(io), std::move(clock)}; } } // namespace link
link/include/ableton/link/StartStopState.hpp view
@@ -42,9 +42,8 @@ StartStopState() = default; - StartStopState(const bool aIsPlaying,- const Beats aBeats,- const std::chrono::microseconds aTimestamp)+ StartStopState(+ const bool aIsPlaying, const Beats aBeats, const std::chrono::microseconds aTimestamp) : isPlaying(aIsPlaying) , beats(aBeats) , timestamp(aTimestamp)@@ -102,8 +101,8 @@ ClientStartStopState() = default; ClientStartStopState(const bool aIsPlaying,- const std::chrono::microseconds aTime,- const std::chrono::microseconds aTimestamp)+ const std::chrono::microseconds aTime,+ const std::chrono::microseconds aTimestamp) : isPlaying(aIsPlaying) , time(aTime) , timestamp(aTimestamp)
link/include/ableton/link/Tempo.hpp view
@@ -42,7 +42,10 @@ { } - double bpm() const { return mValue; }+ double bpm() const+ {+ return mValue;+ } std::chrono::microseconds microsPerBeat() const {@@ -52,8 +55,8 @@ // Given the tempo, convert a time to a beat value Beats microsToBeats(const std::chrono::microseconds micros) const {- return Beats{static_cast<double>(micros.count())- / static_cast<double>(microsPerBeat().count())};+ return Beats{+ static_cast<double>(micros.count()) / static_cast<double>(microsPerBeat().count())}; } // Given the tempo, convert a beat to a time value
+ link/include/ableton/link/TripleBuffer.hpp view
@@ -0,0 +1,121 @@+/* Copyright 2022, Ableton AG, Berlin. All rights reserved.+ *+ * This program is free software: you can redistribute it and/or modify+ * it under the terms of the GNU General Public License as published by+ * the Free Software Foundation, either version 2 of the License, or+ * (at your option) any later version.+ *+ * This program is distributed in the hope that it will be useful,+ * but WITHOUT ANY WARRANTY; without even the implied warranty of+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+ * GNU General Public License for more details.+ *+ * You should have received a copy of the GNU General Public License+ * along with this program. If not, see <http://www.gnu.org/licenses/>.+ *+ * If you would like to incorporate Link into a proprietary software application,+ * please contact <link-devs@ableton.com>.+ */+++#pragma once++#include <ableton/link/Optional.hpp>++#include <array>+#include <atomic>+#include <cassert>+#include <cstdint>++namespace ableton+{+namespace link+{++template <typename T>+struct TripleBuffer+{+public:+ TripleBuffer()+ : mBuffers{{{}, {}, {}}}+ {+ assert(mState.is_lock_free());+ }++ explicit TripleBuffer(const T& initial)+ : mBuffers{{initial, initial, initial}}+ {+ assert(mState.is_lock_free());+ }++ TripleBuffer(const TripleBuffer&) = delete;+ TripleBuffer& operator=(const TripleBuffer&) = delete;++ T read() noexcept+ {+ loadReadBuffer();+ return mBuffers[mReadIndex];+ }++ Optional<T> readNew()+ {+ if (loadReadBuffer())+ {+ return Optional<T>(mBuffers[mReadIndex]);+ }+ return {};+ }++ template <typename U>+ void write(U&& value)+ {+ mBuffers[mWriteIndex] = std::forward<U>(value);++ const auto prevState =+ mState.exchange(makeState(mWriteIndex, true), std::memory_order_acq_rel);++ mWriteIndex = backIndex(prevState);+ }++private:+ bool loadReadBuffer()+ {+ auto state = mState.load(std::memory_order_acquire);+ auto isNew = isNewWrite(state);+ if (isNew)+ {+ const auto prevState =+ mState.exchange(makeState(mReadIndex, false), std::memory_order_acq_rel);++ mReadIndex = backIndex(prevState);+ }+ return isNew;+ }++ using BackingState = uint32_t;++ static constexpr bool isNewWrite(const BackingState state)+ {+ return (state & 0x0000FFFFu) != 0;+ }++ static constexpr uint32_t backIndex(const BackingState state)+ {+ return state >> 16;+ }++ static constexpr BackingState makeState(+ const uint32_t backBufferIndex, const bool isWrite)+ {+ return (backBufferIndex << 16) | uint32_t(isWrite);+ }++ std::atomic<BackingState> mState{makeState(1u, false)}; // Reader and writer+ uint32_t mReadIndex = 0u; // Reader only+ uint32_t mWriteIndex = 2u; // Writer only++ std::array<T, 3> mBuffers{};+};++} // namespace link+} // namespace ableton
link/include/ableton/link/v1/Messages.hpp view
@@ -87,9 +87,8 @@ if (messageSize < kMaxMessageSize) { return toNetworkByteStream(- payload,- toNetworkByteStream(- header, copy(begin(kProtocolHeader), end(kProtocolHeader), std::move(out))));+ payload, toNetworkByteStream(header,+ copy(begin(kProtocolHeader), end(kProtocolHeader), std::move(out)))); } else {@@ -126,7 +125,7 @@ // proceed to parse the stream. if (std::distance(bytesBegin, bytesEnd) >= minMessageSize && std::equal(- begin(detail::kProtocolHeader), end(detail::kProtocolHeader), bytesBegin))+ begin(detail::kProtocolHeader), end(detail::kProtocolHeader), bytesBegin)) { std::tie(header, bytesBegin) = MessageHeader::fromNetworkByteStream(bytesBegin + protocolHeaderSize, bytesEnd);
− link/include/ableton/link_audio/ApiConfig.hpp
@@ -1,56 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- * This program is free software: you can redistribute it and/or modify- * it under the terms of the GNU General Public License as published by- * the Free Software Foundation, either version 2 of the License, or- * (at your option) any later version.- *- * This program is distributed in the hope that it will be useful,- * but WITHOUT ANY WARRANTY; without even the implied warranty of- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- * GNU General Public License for more details.- *- * You should have received a copy of the GNU General Public License- * along with this program. If not, see <http://www.gnu.org/licenses/>.- *- * If you would like to incorporate Link into a proprietary software application,- * please contact <link-devs@ableton.com>.- */--#pragma once--#ifndef LINK_API_CONTROLLER--#include <ableton/platforms/Config.hpp>--#include <ableton/link_audio/Buffer.hpp>-#include <ableton/link_audio/Id.hpp>-#include <ableton/link_audio/SessionController.hpp>-#include <ableton/link_audio/Sink.hpp>--namespace ableton-{-namespace link-{--template <typename Clock>-using ApiController = ableton::link_audio::SessionController<PeerCountCallback,- TempoCallback,- StartStopStateCallback,- Clock,- platform::Random,- platform::IoContext>;--} // namespace link--using ChannelId = link_audio::Id;-using PeerId = link_audio::Id;-using SessionId = link_audio::Id;--} // namespace ableton--#define LINK_API_CONTROLLER YES--#endif--#include <ableton/Link.hpp>
− link/include/ableton/link_audio/AudioBuffer.hpp
@@ -1,245 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- * This program is free software: you can redistribute it and/or modify- * it under the terms of the GNU General Public License as published by- * the Free Software Foundation, either version 2 of the License, or- * (at your option) any later version.- *- * This program is distributed in the hope that it will be useful,- * but WITHOUT ANY WARRANTY; without even the implied warranty of- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- * GNU General Public License for more details.- *- * You should have received a copy of the GNU General Public License- * along with this program. If not, see <http://www.gnu.org/licenses/>.- *- * If you would like to incorporate Link into a proprietary software application,- * please contact <link-devs@ableton.com>.- */--#pragma once--#include <ableton/discovery/NetworkByteStreamSerializable.hpp>-#include <ableton/link/Beats.hpp>-#include <ableton/link/Tempo.hpp>-#include <ableton/link_audio/Id.hpp>-#include <ableton/link_audio/v1/Messages.hpp>-#include <algorithm>-#include <array>-#include <numeric>-#include <tuple>-#include <vector>--namespace ableton-{-namespace link_audio-{--using Beats = link::Beats;-using Tempo = link::Tempo;--enum Codec : uint8_t-{- kInvalid = 0,- kPCM_i16 = 1,-};-struct AudioBuffer-{- static constexpr std::int32_t key = '_abu';- static_assert(key == 0x5f616275, "Unexpected byte order");-- static constexpr std::uint32_t kNonAudioBytes = 50;- static constexpr uint32_t kMaxAudioBytes = v1::kMaxPayloadSize - kNonAudioBytes;-- struct Chunk- {- friend std::uint32_t sizeInByteStream(const Chunk& chunk)- {- return discovery::sizeInByteStream(chunk.count)- + discovery::sizeInByteStream(chunk.numFrames)- + sizeInByteStream(chunk.beginBeats) + sizeInByteStream(chunk.tempo);- }-- template <typename It>- friend It toNetworkByteStream(const Chunk& chunk, It out)- {- out = toNetworkByteStream(- chunk.tempo,- toNetworkByteStream(- chunk.beginBeats,- discovery::toNetworkByteStream(- chunk.numFrames, discovery::toNetworkByteStream(chunk.count, out))));- return out;- }-- template <typename It>- static std::pair<Chunk, It> fromNetworkByteStream(It begin, It end)- {- using namespace std;-- auto [count, countEnd] =- discovery::Deserialize<uint64_t>::fromNetworkByteStream(begin, end);- auto [numFrames, numFramesEnd] =- discovery::Deserialize<uint16_t>::fromNetworkByteStream(countEnd, end);- auto [beginBeats, beginBeatsEnd] =- discovery::Deserialize<Beats>::fromNetworkByteStream(numFramesEnd, end);- auto [tempo, tempoEnd] =- discovery::Deserialize<Tempo>::fromNetworkByteStream(beginBeatsEnd, end);- return make_pair(Chunk{count, numFrames, beginBeats, tempo}, tempoEnd);- }-- friend bool operator==(const Chunk& lhs, const Chunk& rhs)- {- return std::tie(lhs.count, lhs.numFrames, lhs.beginBeats, lhs.tempo)- == std::tie(rhs.count, rhs.numFrames, rhs.beginBeats, rhs.tempo);- }-- uint64_t count;- uint16_t numFrames;- Beats beginBeats;- Tempo tempo;- };-- using Chunks = std::vector<Chunk>;- using Bytes = std::array<uint8_t, kMaxAudioBytes>;-- uint32_t numFrames() const- {- return std::accumulate(chunks.begin(),- chunks.end(),- 0u,- [](uint32_t sum, const Chunk& chunk)- { return sum + chunk.numFrames; });- }-- // Model the NetworkByteStreamSerializable concept- friend std::uint32_t sizeInByteStream(const AudioBuffer& buffer)- {- return discovery::sizeInByteStream(buffer.channelId)- + discovery::sizeInByteStream(buffer.sessionId)- + discovery::sizeInByteStream(buffer.chunks)- + discovery::sizeInByteStream(static_cast<uint8_t>(buffer.codec))- + discovery::sizeInByteStream(static_cast<uint32_t>(buffer.sampleRate))- + discovery::sizeInByteStream(static_cast<int8_t>(buffer.numChannels))- + discovery::sizeInByteStream(static_cast<int16_t>(buffer.numBytes))- + static_cast<uint32_t>(buffer.numBytes);- }-- template <typename It>- friend It toNetworkByteStream(const AudioBuffer& buffer, It out)- {- assert(buffer.codec != Codec::kInvalid);-- out = discovery::toNetworkByteStream(- static_cast<uint16_t>(buffer.numBytes),- discovery::toNetworkByteStream(- static_cast<uint8_t>(buffer.numChannels),- discovery::toNetworkByteStream(- static_cast<uint32_t>(buffer.sampleRate),- discovery::toNetworkByteStream(- static_cast<uint8_t>(buffer.codec),- discovery::toNetworkByteStream(- buffer.chunks,- discovery::toNetworkByteStream(- buffer.sessionId,- discovery::toNetworkByteStream(buffer.channelId, out)))))));-- return std::copy_n(buffer.bytes.begin(), buffer.numBytes, out);- }-- template <typename It>- static It fromNetworkByteStream(AudioBuffer& audioBuffer, It begin, It end)- {- using namespace std;-- auto [channelId, channelIdEnd] =- discovery::Deserialize<Id>::fromNetworkByteStream(begin, end);- audioBuffer.channelId = channelId;-- auto [sessionId, sessionIdEnd] =- discovery::Deserialize<Id>::fromNetworkByteStream(channelIdEnd, end);- audioBuffer.sessionId = sessionId;-- auto [chunks, chunksEnd] =- discovery::Deserialize<Chunks>::fromNetworkByteStream(sessionIdEnd, end);- audioBuffer.chunks = chunks;-- if (chunks.empty())- {- throw runtime_error("Invalid audio buffer: no chunks.");- }-- auto [codec, codecEnd] =- discovery::Deserialize<uint8_t>::fromNetworkByteStream(chunksEnd, end);- audioBuffer.codec = static_cast<Codec>(codec);-- if (codec == Codec::kInvalid)- {- throw runtime_error("Invalid codec.");- }-- auto [sampleRate, sampleRateEnd] =- discovery::Deserialize<uint32_t>::fromNetworkByteStream(codecEnd, end);- audioBuffer.sampleRate = sampleRate;-- auto [numChannels, numChannelsEnd] =- discovery::Deserialize<uint8_t>::fromNetworkByteStream(sampleRateEnd, end);- audioBuffer.numChannels = numChannels;-- auto [numBytes, numBytesEnd] =- discovery::Deserialize<uint16_t>::fromNetworkByteStream(numChannelsEnd, end);- audioBuffer.numBytes = numBytes;-- if (codec == Codec::kPCM_i16- && audioBuffer.numFrames() * numChannels * sizeof(int16_t) != numBytes)- {- throw range_error("Byte count / frame count mismatch.");- }-- if (std::distance(numBytesEnd, end) > numBytes || numBytesEnd + numBytes > end)- {- throw range_error("Invalid byte count.");- }-- std::copy_n(numBytesEnd, numBytes, audioBuffer.bytes.begin());-- return numBytesEnd + numBytes;- }-- friend bool operator==(const AudioBuffer& lhs, const AudioBuffer& rhs)- {- return std::tie(lhs.channelId,- lhs.sessionId,- lhs.sampleRate,- lhs.chunks,- lhs.numChannels,- lhs.numBytes)- == std::tie(rhs.channelId,- rhs.sessionId,- rhs.sampleRate,- rhs.chunks,- rhs.numChannels,- rhs.numBytes)- && std::equal(lhs.bytes.begin(),- lhs.bytes.begin() + lhs.numBytes,- begin(rhs.bytes),- begin(rhs.bytes) + rhs.numBytes);- }-- friend bool operator!=(const AudioBuffer& lhs, const AudioBuffer& rhs)- {- return !(lhs == rhs);- }-- Id channelId;- Id sessionId;- Chunks chunks;- Codec codec;- uint32_t sampleRate;- uint8_t numChannels;- uint16_t numBytes;- Bytes bytes;-};--} // namespace link_audio-} // namespace ableton
− link/include/ableton/link_audio/BeatTimeMapping.hpp
@@ -1,50 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- * This program is free software: you can redistribute it and/or modify- * it under the terms of the GNU General Public License as published by- * the Free Software Foundation, either version 2 of the License, or- * (at your option) any later version.- *- * This program is distributed in the hope that it will be useful,- * but WITHOUT ANY WARRANTY; without even the implied warranty of- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- * GNU General Public License for more details.- *- * You should have received a copy of the GNU General Public License- * along with this program. If not, see <http://www.gnu.org/licenses/>.- *- * If you would like to incorporate Link into a proprietary software application,- * please contact <link-devs@ableton.com>.- */--#pragma once--#include <ableton/link/Beats.hpp>-#include <ableton/link/Phase.hpp>-#include <ableton/link/Timeline.hpp>--namespace ableton-{-namespace link_audio-{--static inline link::Beats globalBeatAtBeat(const link::Timeline& timeline,- link::Beats targetBeat,- link::Beats quantum)-{- const auto beatsDiff =- link::toPhaseEncodedBeats(timeline, timeline.timeOrigin, quantum);- return targetBeat - beatsDiff;-}--static inline link::Beats beatAtGlobalBeat(const link::Timeline& timeline,- link::Beats globalBeat,- link::Beats quantum)-{- const auto beatsDiff =- link::toPhaseEncodedBeats(timeline, timeline.timeOrigin, quantum);- return globalBeat + beatsDiff;-}--} // namespace link_audio-} // namespace ableton
− link/include/ableton/link_audio/Buffer.hpp
@@ -1,67 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- * This program is free software: you can redistribute it and/or modify- * it under the terms of the GNU General Public License as published by- * the Free Software Foundation, either version 2 of the License, or- * (at your option) any later version.- *- * This program is distributed in the hope that it will be useful,- * but WITHOUT ANY WARRANTY; without even the implied warranty of- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- * GNU General Public License for more details.- *- * You should have received a copy of the GNU General Public License- * along with this program. If not, see <http://www.gnu.org/licenses/>.- *- * If you would like to incorporate Link into a proprietary software application,- * please contact <link-devs@ableton.com>.- */--#pragma once--#include <ableton/link/Beats.hpp>-#include <ableton/link/Tempo.hpp>-#include <ableton/link_audio/Id.hpp>-#include <vector>--namespace ableton-{-namespace link_audio-{--template <typename SampleFormat>-struct Buffer-{- using SampleFormatType = SampleFormat;- using Samples = std::vector<SampleFormat>;-- Buffer(uint32_t numSamples)- : mSamples(numSamples)- {- }-- uint32_t mSampleRate;- uint32_t mNumChannels;- uint32_t mNumFrames;- Samples mSamples;- link::Beats mBeginBeats;- link::Tempo mTempo;- uint64_t mCount;- Id mSessionId;-};--template <typename Buffer>-struct BufferCallbackHandle-{- BufferCallbackHandle(const Buffer& buffer, typename Buffer::SampleFormatType* pSamples)- : mBuffer(buffer)- , mpSamples(pSamples)- {- }-- const Buffer& mBuffer;- typename Buffer::SampleFormatType* mpSamples;-};--} // namespace link_audio-} // namespace ableton
− link/include/ableton/link_audio/ChannelAnnouncements.hpp
@@ -1,180 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- * This program is free software: you can redistribute it and/or modify- * it under the terms of the GNU General Public License as published by- * the Free Software Foundation, either version 2 of the License, or- * (at your option) any later version.- *- * This program is distributed in the hope that it will be useful,- * but WITHOUT ANY WARRANTY; without even the implied warranty of- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- * GNU General Public License for more details.- *- * You should have received a copy of the GNU General Public License- * along with this program. If not, see <http://www.gnu.org/licenses/>.- *- * If you would like to incorporate Link into a proprietary software application,- * please contact <link-devs@ableton.com>.- */--#pragma once--#include <ableton/discovery/NetworkByteStreamSerializable.hpp>-#include <ableton/link_audio/Id.hpp>--namespace ableton-{-namespace link_audio-{--struct ChannelAnnouncement-{- std::string name;- Id id;-- // Model the NetworkByteStreamSerializable concept- friend std::uint32_t sizeInByteStream(const ChannelAnnouncement& channel)- {- return discovery::sizeInByteStream(channel.name)- + discovery::sizeInByteStream(channel.id);- }-- template <typename It>- friend It toNetworkByteStream(const ChannelAnnouncement& channel, It out)- {- return discovery::toNetworkByteStream(- channel.id, discovery::toNetworkByteStream(channel.name, std::move(out)));- }-- template <typename It>- static std::pair<ChannelAnnouncement, It> fromNetworkByteStream(It begin, It end)- {- auto [name, nameEnd] =- discovery::Deserialize<std::string>::fromNetworkByteStream(begin, end);- auto [id, idEnd] = discovery::Deserialize<Id>::fromNetworkByteStream(nameEnd, end);- return std::make_pair(ChannelAnnouncement{std::move(name), std::move(id)}, idEnd);- }-- friend bool operator==(const ChannelAnnouncement& lhs, const ChannelAnnouncement& rhs)- {- return std::tie(lhs.name, lhs.id) == std::tie(rhs.name, rhs.id);- }-};-;---struct ChannelAnnouncements-{- static constexpr std::int32_t key = 'auca';- static_assert(key == 0x61756361, "Unexpected byte order");-- std::vector<ChannelAnnouncement> channels;-- // Model the NetworkByteStreamSerializable concept- friend std::uint32_t sizeInByteStream(const ChannelAnnouncements& announcements)- {- return discovery::sizeInByteStream(announcements.channels);- }-- template <typename It>- friend It toNetworkByteStream(const ChannelAnnouncements& announcements, It out)- {- return discovery::toNetworkByteStream(announcements.channels, std::move(out));- }-- template <typename It>- static std::pair<ChannelAnnouncements, It> fromNetworkByteStream(It begin, It end)- {- auto [channels, announcementsEnd] =- discovery::Deserialize<std::vector<ChannelAnnouncement>>::fromNetworkByteStream(- std::move(begin), end);- return std::make_pair(ChannelAnnouncements{channels}, announcementsEnd);- }-- friend bool operator==(const ChannelAnnouncements& lhs, const ChannelAnnouncements& rhs)- {- return lhs.channels == rhs.channels;- }-- friend bool operator!=(const ChannelAnnouncements& lhs, const ChannelAnnouncements& rhs)- {- return !(lhs == rhs);- }-};--struct ChannelBye-{- Id id;-- // Model the NetworkByteStreamSerializable concept- friend std::uint32_t sizeInByteStream(const ChannelBye& bye)- {- return discovery::sizeInByteStream(bye.id);- }-- template <typename It>- friend It toNetworkByteStream(const ChannelBye& bye, It out)- {- return discovery::toNetworkByteStream(bye.id, std::move(out));- }-- template <typename It>- static std::pair<ChannelBye, It> fromNetworkByteStream(It begin, It end)- {- auto [bye, byeEnd] =- discovery::Deserialize<Id>::fromNetworkByteStream(std::move(begin), end);- return std::make_pair(ChannelBye{bye}, byeEnd);- }-- friend bool operator==(const ChannelBye& lhs, const ChannelBye& rhs)- {- return lhs.id == rhs.id;- }-- friend bool operator!=(const ChannelBye& lhs, const ChannelBye& rhs)- {- return !(lhs == rhs);- }-};--struct ChannelByes-{- static constexpr std::int32_t key = 'aucb';- static_assert(key == 0x61756362, "Unexpected byte order");-- std::vector<ChannelBye> byes;-- // Model the NetworkByteStreamSerializable concept- friend std::uint32_t sizeInByteStream(const ChannelByes& channels)- {- return discovery::sizeInByteStream(channels.byes);- }-- template <typename It>- friend It toNetworkByteStream(const ChannelByes& channels, It out)- {- return discovery::toNetworkByteStream(channels.byes, std::move(out));- }-- template <typename It>- static std::pair<ChannelByes, It> fromNetworkByteStream(It begin, It end)- {- auto [byes, byesEnd] =- discovery::Deserialize<std::vector<ChannelBye>>::fromNetworkByteStream(- std::move(begin), end);- return std::make_pair(ChannelByes{byes}, byesEnd);- }-- friend bool operator==(const ChannelByes& lhs, const ChannelByes& rhs)- {- return lhs.byes == rhs.byes;- }-- friend bool operator!=(const ChannelByes& lhs, const ChannelByes& rhs)- {- return !(lhs == rhs);- }-};--} // namespace link_audio-} // namespace ableton
− link/include/ableton/link_audio/ChannelId.hpp
@@ -1,63 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- * This program is free software: you can redistribute it and/or modify- * it under the terms of the GNU General Public License as published by- * the Free Software Foundation, either version 2 of the License, or- * (at your option) any later version.- *- * This program is distributed in the hope that it will be useful,- * but WITHOUT ANY WARRANTY; without even the implied warranty of- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- * GNU General Public License for more details.- *- * You should have received a copy of the GNU General Public License- * along with this program. If not, see <http://www.gnu.org/licenses/>.- *- * If you would like to incorporate Link into a proprietary software application,- * please contact <link-devs@ableton.com>.- */--#pragma once--#include <ableton/discovery/NetworkByteStreamSerializable.hpp>-#include <ableton/link_audio/Id.hpp>--namespace ableton-{-namespace link_audio-{--struct ChannelId-{- static const std::int32_t key = 'chid';- static_assert(key == 0x63686964, "Unexpected byte order");-- friend bool operator==(const ChannelId& lhs, const ChannelId& rhs)- {- return lhs.id == rhs.id;- }-- // Model the NetworkByteStreamSerializable concept- friend std::uint32_t sizeInByteStream(const ChannelId& cid)- {- return discovery::sizeInByteStream(cid.id);- }-- template <typename It>- friend It toNetworkByteStream(const ChannelId& cid, It out)- {- return discovery::toNetworkByteStream(cid.id, std::move(out));- }-- template <typename It>- static std::pair<ChannelId, It> fromNetworkByteStream(It begin, It end)- {- auto [result, itEnd] = discovery::Deserialize<Id>::fromNetworkByteStream(begin, end);- return std::make_pair(ChannelId{std::move(result)}, itEnd);- }-- Id id;-};--} // namespace link_audio-} // namespace ableton
− link/include/ableton/link_audio/ChannelRequests.hpp
@@ -1,92 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- * This program is free software: you can redistribute it and/or modify- * it under the terms of the GNU General Public License as published by- * the Free Software Foundation, either version 2 of the License, or- * (at your option) any later version.- *- * This program is distributed in the hope that it will be useful,- * but WITHOUT ANY WARRANTY; without even the implied warranty of- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- * GNU General Public License for more details.- *- * You should have received a copy of the GNU General Public License- * along with this program. If not, see <http://www.gnu.org/licenses/>.- *- * If you would like to incorporate Link into a proprietary software application,- * please contact <link-devs@ableton.com>.- */--#pragma once--#include <ableton/discovery/NetworkByteStreamSerializable.hpp>-#include <ableton/discovery/Payload.hpp>-#include <ableton/link_audio/ChannelId.hpp>--namespace ableton-{-namespace link_audio-{--struct ChannelRequest-{- using Payload = decltype(discovery::makePayload(ChannelId{}));-- friend bool operator==(const ChannelRequest& lhs, const ChannelRequest& rhs)- {- return std::tie(lhs.peerId, lhs.channelId) == std::tie(rhs.peerId, rhs.channelId);- }-- friend Payload toPayload(const ChannelRequest& request)- {- return discovery::makePayload(ChannelId{request.channelId});- }-- template <typename It>- static ChannelRequest fromPayload(Id peerId, It begin, It end)- {- using namespace std;- auto request = ChannelRequest{std::move(peerId)};- discovery::parsePayload<ChannelId>(std::move(begin),- std::move(end),- [&request](ChannelId cid)- { request.channelId = std::move(cid.id); });- return request;- }-- Id peerId;- Id channelId;-};--struct ChannelStopRequest-{- using Payload = decltype(discovery::makePayload(ChannelId{}));-- friend bool operator==(const ChannelStopRequest& lhs, const ChannelStopRequest& rhs)- {- return std::tie(lhs.peerId, lhs.channelId) == std::tie(rhs.peerId, rhs.channelId);- }-- friend Payload toPayload(const ChannelStopRequest& request)- {- return discovery::makePayload(ChannelId{request.channelId});- }-- template <typename It>- static ChannelStopRequest fromPayload(Id peerId, It begin, It end)- {- using namespace std;- auto request = ChannelStopRequest{std::move(peerId), {}};- discovery::parsePayload<ChannelId>(std::move(begin),- std::move(end),- [&request](ChannelId cid)- { request.channelId = std::move(cid.id); });- return request;- }-- Id peerId;- Id channelId;-};--} // namespace link_audio-} // namespace ableton
− link/include/ableton/link_audio/Channels.hpp
@@ -1,594 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- * This program is free software: you can redistribute it and/or modify- * it under the terms of the GNU General Public License as published by- * the Free Software Foundation, either version 2 of the License, or- * (at your option) any later version.- *- * This program is distributed in the hope that it will be useful,- * but WITHOUT ANY WARRANTY; without even the implied warranty of- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- * GNU General Public License for more details.- *- * You should have received a copy of the GNU General Public License- * along with this program. If not, see <http://www.gnu.org/licenses/>.- *- * If you would like to incorporate Link into a proprietary software application,- * please contact <link-devs@ableton.com>.- */--#pragma once--#include <ableton/discovery/AsioTypes.hpp>-#include <ableton/link_audio/ChannelAnnouncements.hpp>-#include <ableton/link_audio/Id.hpp>-#include <ableton/link_audio/PeerAnnouncement.hpp>-#include <ableton/util/Injected.hpp>-#include <algorithm>-#include <cassert>-#include <chrono>-#include <map>-#include <memory>-#include <optional>-#include <stdexcept>-#include <string>-#include <tuple>-#include <vector>--namespace ableton-{-namespace link_audio-{--template <typename IoContext, typename Callback, typename Interface>-class Channels-{- // non-movable private implementation type- struct Impl;--public:- struct SendHandler- {- SendHandler(discovery::UdpEndpoint endpoint, std::shared_ptr<Interface> interface)- : mEndpoint(endpoint)- , mpInterface(interface)- {- }-- std::size_t operator()(const uint8_t* const pData, const size_t numBytes)- {- if (auto interface = mpInterface.lock())- {- try- {- return interface->send(pData, numBytes, mEndpoint);- }- catch (const std::runtime_error&)- {- }- }- return 0;- }-- discovery::UdpEndpoint endpoint() const { return mEndpoint; }-- private:- discovery::UdpEndpoint mEndpoint;- std::weak_ptr<Interface> mpInterface;- };-- struct Channel- {- std::string name;- Id id;- std::string peerName;- Id peerId;- Id sessionId;-- friend bool operator==(const Channel& lhs, const Channel& rhs)- {- return std::tie(lhs.name, lhs.id, lhs.peerName, lhs.peerId, lhs.sessionId)- == std::tie(rhs.name, rhs.id, rhs.peerName, rhs.peerId, rhs.sessionId);- }- };-- struct ChannelInfo- {- Channel channel;- discovery::IpAddress gatewayAddr;- };-- struct ChannelInfoCompare- {- bool operator()(const ChannelInfo& lhs, const ChannelInfo& rhs) const- {- if (lhs.channel.sessionId == rhs.channel.sessionId)- {- if (lhs.channel.peerId == rhs.channel.peerId)- {- if (lhs.channel.id == rhs.channel.id)- {- return lhs.gatewayAddr < rhs.gatewayAddr;- }- return lhs.channel.channelId < rhs.channel.channelId;- }- return lhs.channel.peerId < rhs.channel.peerId;- }- return lhs.channel.sessionId < rhs.channel.sessionId;- }- };-- Channels(util::Injected<IoContext> io, Callback callback)- : mpImpl(std::make_shared<Impl>(std::move(io), std::move(callback)))- {- }-- std::vector<Channel> sessionChannels(const link::SessionId& sessionId) const- {- using namespace std;- vector<Channel> result;- auto& channelsVec = mpImpl->mChannels;- for (const auto& channel : mpImpl->mChannels)- {- if (channel.channel.sessionId == sessionId)- {- result.push_back(channel.channel);- }- }- return result;- }-- std::vector<Channel> uniqueSessionChannels(const link::SessionId& sessionId) const- {- auto channels = sessionChannels(sessionId);- auto it = std::unique(begin(channels),- end(channels),- [](const auto& a, const auto& b) { return a.id == b.id; });- return {begin(channels), it};- }-- std::optional<SendHandler> peerSendHandler(const Id peerId) const- {- auto it = mpImpl->mPeerSendHandlers.find(peerId);- return it != mpImpl->mPeerSendHandlers.end() ? std::optional{it->second.handler}- : std::nullopt;- }-- std::optional<SendHandler> channelSendHandler(const Id channelId) const- {- const auto& channels = mpImpl->mChannels;- const auto it =- std::find_if(begin(channels),- end(channels),- [&](const auto& info) { return info.channel.id == channelId; });- return it != end(channels) ? peerSendHandler(it->channel.peerId) : std::nullopt;- }-- template <typename PeerIdIt>- void prunePeerChannels(PeerIdIt connectedPeersBegin, PeerIdIt connectedPeersEnd)- {- mpImpl->prunePeerChannels(connectedPeersBegin, connectedPeersEnd);- }-- struct GatewayObserver- {- using GatewayObserverAnnouncement = PeerAnnouncement;- using GatewayObserverNodeId = link::NodeId;-- GatewayObserver(std::shared_ptr<Impl> pImpl, discovery::IpAddress addr)- : mpImpl(std::move(pImpl))- , mAddr(std::move(addr))- {- }-- GatewayObserver(const GatewayObserver&) = delete;-- GatewayObserver(GatewayObserver&& rhs)- : mpImpl(std::move(rhs.mpImpl))- , mAddr(std::move(rhs.mAddr))- {- }-- ~GatewayObserver()- {- // Check to handle the moved from case- if (mpImpl)- {- mpImpl->gatewayClosed(mAddr);- }- }-- // model the observer concept from Channels- template <typename Announcement>- friend void sawAnnouncement(GatewayObserver& observer, Announcement announcement)- {- auto pImpl = observer.mpImpl;- auto addr = observer.mAddr;- assert(pImpl);- pImpl->sawAnnouncementOnGateway(std::move(announcement), std::move(addr));- }-- template <typename It>- friend void channelsLeft(GatewayObserver& observer, It channelsBegin, It channelsEnd)- {- auto pImpl = observer.mpImpl;- auto addr = observer.mAddr;- pImpl->channelsLeftGateway(std::move(addr), channelsBegin, channelsEnd);- }-- std::shared_ptr<Impl> mpImpl;- discovery::IpAddress mAddr;- };-- // Factory function for the gateway observer- friend GatewayObserver makeGatewayObserver(Channels& channels,- discovery::IpAddress addr)- {- return GatewayObserver{channels.mpImpl, std::move(addr)};- }--private:- using Timer = typename util::Injected<IoContext>::type::Timer;- using TimerError = typename Timer::ErrorCode;- using TimePoint = typename Timer::TimePoint;-- struct TimeoutCompare- {- bool operator()(const std::tuple<TimePoint, discovery::IpAddress, Id>& lhs,- const std::tuple<TimePoint, discovery::IpAddress, Id>& rhs) const- {- return std::get<TimePoint>(lhs) < std::get<TimePoint>(rhs);- }- };-- struct Impl- {- Impl(util::Injected<IoContext> io, Callback callback)- : mIo(std::move(io))- , mCallback(std::move(callback))- , mPruneTimer(mIo->makeTimer())- {- }-- template <typename Announcement>- void sawAnnouncementOnGateway(Announcement incoming, discovery::IpAddress gatewayAddr)- {- using namespace std;-- const auto peerSession = incoming.announcement.sessionId;- const auto nodeId = incoming.announcement.nodeId;- const auto peerInfo = incoming.announcement.peerInfo;- const auto peerAudioChannels = incoming.announcement.channels.channels;- const auto ttl = incoming.ttl;- auto sendHandler = SendHandler(incoming.from, incoming.pInterface);- const auto networkQuality = incoming.networkQuality;- bool didChannelsChange = false;-- for (const auto& peerChannel : peerAudioChannels)- {- const auto channelInfo = ChannelInfo{- {peerChannel.name, peerChannel.id, peerInfo.name, nodeId, peerSession},- gatewayAddr};-- {- const auto timeout =- std::find_if(begin(mChannelTimeouts),- end(mChannelTimeouts),- [&](const auto& timeout)- {- return std::get<discovery::IpAddress>(timeout) == gatewayAddr- && std::get<Id>(timeout) == channelInfo.channel.id;- });- if (timeout != end(mChannelTimeouts))- {- mChannelTimeouts.erase(timeout);- }-- auto newTo = std::make_tuple(mPruneTimer.now() + std::chrono::seconds(ttl),- gatewayAddr,- channelInfo.channel.id);- mChannelTimeouts.insert(- upper_bound(- begin(mChannelTimeouts), end(mChannelTimeouts), newTo, TimeoutCompare{}),- newTo);- }-- const auto idRange = equal_range(begin(mChannels),- end(mChannels),- channelInfo,- [](const auto& a, const auto& b)- { return a.channel.id < b.channel.id; });-- if (idRange.first == idRange.second)- {- // This channel is not currently known on any gateway- didChannelsChange = true;- mChannels.insert(idRange.first, std::move(channelInfo));- }- else- {- // was it on this gateway?- const auto addrRange = equal_range(idRange.first,- idRange.second,- channelInfo,- [](const auto& a, const auto& b)- { return a.gatewayAddr < b.gatewayAddr; });-- if (addrRange.first == addrRange.second)- {- // First time on this gateway, add it- mChannels.insert(addrRange.first, std::move(channelInfo));- }- else- {- // We have an entry for this channel on this gateway, update it- // callback if the name of the first entry changed-- auto cmp = [](const auto& lhs, const auto& rhs)- {- return std::tie(lhs.name, lhs.sessionId, lhs.peerName, lhs.peerId)- == std::tie(rhs.name, rhs.sessionId, rhs.peerName, rhs.peerId);- };- const auto firstChannelChanged =- addrRange.first == idRange.first- && !cmp(addrRange.first->channel, channelInfo.channel);- didChannelsChange = didChannelsChange || firstChannelChanged;- *addrRange.first = std::move(channelInfo);- }- }- }-- if (mPeerSendHandlers.count(nodeId) == 0)- {- mPeerSendHandlers.emplace(nodeId, PeerSendHandler{sendHandler, networkQuality});- }- else if (mPeerSendHandlers.at(nodeId).networkQuality < networkQuality)- {- mPeerSendHandlers.insert_or_assign(- nodeId, PeerSendHandler{sendHandler, networkQuality});- }-- // Invoke callbacks outside the critical section- if (didChannelsChange)- {- mCallback();- }-- scheduleNextPruning();- }-- template <typename PeerIdIt>- void prunePeerSendHandlers(PeerIdIt connectedPeersBegin, PeerIdIt connectedPeersEnd)- {- using namespace std;- for (auto it = begin(mPeerSendHandlers); it != end(mPeerSendHandlers);)- {- if (none_of(connectedPeersBegin,- connectedPeersEnd,- [&](const auto& peerId) { return peerId == it->first; }))- {- it = mPeerSendHandlers.erase(it);- }- else- {- ++it;- }- }- }-- void pruneSendHandlers()- {- using namespace std;- auto peerIds = vector<Id>{};- peerIds.reserve(mChannels.size());- transform(begin(mChannels),- end(mChannels),- back_inserter(peerIds),- [](const auto& info) { return info.channel.peerId; });- prunePeerSendHandlers(begin(peerIds), end(peerIds));- }-- template <typename PeerIdIt>- void prunePeerChannels(PeerIdIt connectedPeersBegin, PeerIdIt connectedPeersEnd)- {- using namespace std;-- vector<Id> removedChannelIds;- for (const auto& info : mChannels)- {- if (none_of(connectedPeersBegin,- connectedPeersEnd,- [&](const auto& peerId) { return peerId == info.channel.peerId; }))- {- removedChannelIds.push_back(info.channel.id);- }- }-- auto it = remove_if(begin(mChannels),- end(mChannels),- [&](auto& info)- {- return none_of(connectedPeersBegin,- connectedPeersEnd,- [&](const auto& peerId)- { return peerId == info.channel.peerId; });- });-- const auto channelsChanged = it != end(mChannels);- mChannels.erase(it, end(mChannels));-- mChannelTimeouts.erase(- remove_if(begin(mChannelTimeouts),- end(mChannelTimeouts),- [&](const auto& timeout)- {- const auto& id = std::get<Id>(timeout);- return find(begin(removedChannelIds), end(removedChannelIds), id)- != end(removedChannelIds);- }),- end(mChannelTimeouts));-- scheduleNextPruning();-- prunePeerSendHandlers(connectedPeersBegin, connectedPeersEnd);-- if (channelsChanged)- {- mCallback();- }- }-- template <typename It>- void channelsLeftGateway(const discovery::IpAddress& gatewayAddr,- It channelsBegin,- It channelsEnd)- {- using namespace std;-- auto channelsChanged = false;-- for (auto byeIt = channelsBegin; byeIt != channelsEnd; ++byeIt)- {- auto bye = *byeIt;-- auto it = remove_if(- begin(mChannels),- end(mChannels),- [&](const auto& info)- { return info.gatewayAddr == gatewayAddr && bye == info.channel.id; });- channelsChanged = it != end(mChannels);- mChannels.erase(it, end(mChannels));-- mChannelTimeouts.erase(remove_if(begin(mChannelTimeouts),- end(mChannelTimeouts),- [&](const auto& timeout)- {- return std::get<discovery::IpAddress>(timeout)- == gatewayAddr- && std::get<Id>(timeout) == bye;- }),- end(mChannelTimeouts));- }-- scheduleNextPruning();-- if (channelsChanged)- {- pruneSendHandlers();- mCallback();- }- }-- void gatewayClosed(const discovery::IpAddress& gatewayAddr)- {- using namespace std;- auto it =- remove_if(begin(mChannels),- end(mChannels),- [&](const auto& info) { return info.gatewayAddr == gatewayAddr; });-- const auto channelsChanged = it != end(mChannels);-- mChannels.erase(it, end(mChannels));-- mChannelTimeouts.erase(- std::remove_if(- begin(mChannelTimeouts),- end(mChannelTimeouts),- [&](const auto& timeout)- { return std::get<discovery::IpAddress>(timeout) == gatewayAddr; }),- end(mChannelTimeouts));-- scheduleNextPruning();-- if (channelsChanged)- {- pruneSendHandlers();- mCallback();- }- }-- void pruneExpiredChannels()- {- using namespace std;-- const auto test = make_tuple(mPruneTimer.now(), discovery::IpAddress{}, Id{});-- const auto endExpired = lower_bound(- begin(mChannelTimeouts), end(mChannelTimeouts), test, TimeoutCompare{});-- auto channelsChanged = false;- if (endExpired != begin(mChannelTimeouts))- {- channelsChanged = true;-- for_each(- begin(mChannelTimeouts),- endExpired,- [&](const auto& timeout)- {- const auto& id = std::get<Id>(timeout);- const auto& gatewayAddr = std::get<discovery::IpAddress>(timeout);-- auto it = remove_if(- begin(mChannels),- end(mChannels),- [&](const auto& info)- { return info.channel.id == id && info.gatewayAddr == gatewayAddr; });-- mChannels.erase(it, end(mChannels));- });- }-- mChannelTimeouts.erase(begin(mChannelTimeouts), endExpired);-- scheduleNextPruning();-- if (channelsChanged)- {- pruneSendHandlers();- mCallback();- }- }-- void scheduleNextPruning()- {- if (!mChannelTimeouts.empty())- {- // Add a second of padding to the timer to avoid over-eager timeouts- const auto t =- std::get<TimePoint>(mChannelTimeouts.front()) + std::chrono::seconds(1);- mPruneTimer.expires_at(t);- mPruneTimer.async_wait(- [this](const TimerError e)- {- if (!e)- {- pruneExpiredChannels();- }- });- }- }-- util::Injected<IoContext> mIo;- Callback mCallback;- std::vector<ChannelInfo> mChannels;-- struct PeerSendHandler- {- SendHandler handler;- double networkQuality;- };- std::map<Id, PeerSendHandler> mPeerSendHandlers;-- using ChannelTimeout = std::tuple<TimePoint, discovery::IpAddress, Id>;- using ChannelTimeouts = std::vector<ChannelTimeout>;- ChannelTimeouts mChannelTimeouts;- Timer mPruneTimer;- };-- std::shared_ptr<Impl> mpImpl;-};--} // namespace link_audio-} // namespace ableton
− link/include/ableton/link_audio/Controller.hpp
@@ -1,388 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- * This program is free software: you can redistribute it and/or modify- * it under the terms of the GNU General Public License as published by- * the Free Software Foundation, either version 2 of the License, or- * (at your option) any later version.- *- * This program is distributed in the hope that it will be useful,- * but WITHOUT ANY WARRANTY; without even the implied warranty of- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- * GNU General Public License for more details.- *- * You should have received a copy of the GNU General Public License- * along with this program. If not, see <http://www.gnu.org/licenses/>.- *- * If you would like to incorporate Link into a proprietary software application,- * please contact <link-devs@ableton.com>.- */--#pragma once--#include <ableton/discovery/AsioTypes.hpp>-#include <ableton/link/Controller.hpp>-#include <ableton/link_audio/Channels.hpp>-#include <ableton/link_audio/Id.hpp>-#include <ableton/link_audio/MainProcessor.hpp>-#include <ableton/link_audio/PeerGateways.hpp>-#include <ableton/link_audio/PeerInfo.hpp>-#include <ableton/link_audio/UdpMessenger.hpp>-#include <ableton/util/Injected.hpp>-#include <ableton/util/Locked.hpp>-#include <algorithm>-#include <atomic>-#include <functional>-#include <optional>-#include <set>-#include <vector>--namespace ableton-{-namespace link_audio-{--using ChannelsChangedCallback = std::function<void()>;-using CallOnThreadFunction = std::function<void()>;--template <typename PeerCountCallback,- typename TempoCallback,- typename StartStopStateCallback,- typename Clock,- typename Random,- typename IoContext,- typename SessionController>-class Controller : public link::Controller<PeerCountCallback,- TempoCallback,- StartStopStateCallback,- Clock,- Random,- IoContext,- SessionController>-{-public:- using LinkController = link::Controller<PeerCountCallback,- TempoCallback,- StartStopStateCallback,- Clock,- Random,- IoContext,- SessionController>;-- Controller(link::Tempo tempo,- link::PeerCountCallback peerCallback,- link::TempoCallback tempoCallback,- link::StartStopStateCallback startStopStateCallback,- Clock clock)- : LinkController(tempo, peerCallback, tempoCallback, startStopStateCallback, clock)- , mChannelsChangedCallback{[]() {}}- , mApiChannels({})- , mIsLinkAudioEnabledByUser(false)- , mIsLinkAudioEffectivlyEnabled(false)- , mPeerInfo({})- , mChannels(util::injectRef(*(this->mIo)), ChannelsChanged{this})- , mProcessor{util::injectRef(*(this->mIo)), util::injectVal(ChannelsCallback{this})}- , mGateways{util::injectVal(GatewayFactory{this}), util::injectRef(*(this->mIo))}- {- }-- void enableLinkAudio(bool enabled)- {- mIsLinkAudioEnabledByUser = enabled;- this->mRtClientStateSetter.invoke();- }-- bool isLinkAudioEnabled() const { return mIsLinkAudioEnabledByUser; }--- std::string name() const { return mPeerInfo.read().name; }-- void setName(std::string name)- {- this->mIo->async(- [this, name = std::move(name)]()- {- mPeerInfo.update([&, name = std::move(name)](auto& pi)- { pi.name = std::move(name); });- if (this->mpSessionController)- {- this->mpSessionController->updateDiscoveryCallback();- }- });- }-- void callOnLinkThread(CallOnThreadFunction func)- {- this->mIo->async([func = std::move(func)]() { func(); });- }-- SharedSink addSink(std::string name, size_t maxNumSamples)- {- auto id = Id::random<Random>();- auto sink = std::make_shared<Sink>(name, maxNumSamples, id);-- this->mIo->async(- [this, sink]()- {- this->mProcessor.addSink(- sink, util::injectVal(GetSender{this}), util::injectVal(GetNodeId{this}));- if (this->mpSessionController)- {- this->mpSessionController->updateDiscoveryCallback();- }- });-- return sink;- }-- SharedSource addSource(Id channelId, Source::Callback callback)- {- auto source = std::make_shared<Source>(std::move(channelId), std::move(callback));-- this->mIo->async(- [this, source]()- {- mProcessor.addSource(- source, util::injectVal(GetSender{this}), util::injectVal(GetNodeId{this}));- });-- return source;- }-- void setChannelsChangedCallback(ChannelsChangedCallback callback)- {- this->mIo->async([&, callback = std::move(callback)]()- { mChannelsChangedCallback = callback; });- }-- auto channels() const { return mApiChannels.read(); }--protected:- void updateIsLinkAudioEnabled()- {- const auto shouldBeEnabled = this->mEnabled && mIsLinkAudioEnabledByUser;- if (shouldBeEnabled && !mIsLinkAudioEffectivlyEnabled)- {- mIsLinkAudioEffectivlyEnabled = true;- this->mpSessionController->gatewaysChangedCallback();- }- else if (!shouldBeEnabled && mIsLinkAudioEffectivlyEnabled)- {- mIsLinkAudioEffectivlyEnabled = false;- mGateways.clear();- }- }-- void updateAudioDiscovery()- {- mGateways.updateAnnouncement(PeerAnnouncement{this->mNodeId,- this->mSessionId,- mPeerInfo.read(),- mProcessor.channelAnnouncements()});- }-- void updateLinkAudio()- {- auto peers = std::set<link::NodeId>();-- for (const auto& sessionPeer : this->mPeers.sessionPeers(this->mSessionId))- {- peers.insert(sessionPeer.first.nodeState.ident());- }-- mGateways.updateSessionPeers(begin(peers), end(peers));-- // Remove channels for peers that are no longer in the session- mChannels.prunePeerChannels(peers.begin(), peers.end());-- updateApiChannels();- }-- void sawLinkAudioEndpoint(link::NodeId peerId,- std::optional<discovery::UdpEndpoint> endpoint,- discovery::IpAddress gateway)- {- mGateways.sawLinkAudioEndpoint(peerId, endpoint, gateway);- }-- void updateLinkAudioGateways()- {- auto gateways = std::vector<discovery::IpAddress>();- this->mDiscovery.withGateways(- [&](auto begin, auto end)- { std::for_each(begin, end, [&](auto& it) { gateways.push_back(it.first); }); });-- if (mIsLinkAudioEffectivlyEnabled)- {- mGateways.updateGateways(std::move(gateways));- updateLinkAudio();- }- else- {- mGateways.clear();- }- }-- void updateAudioEndpoints(std::vector<discovery::UdpEndpoint> endpoints)- {- this->mDiscovery.withGateways(- [&](auto begin, auto end)- {- std::for_each(begin,- end,- [&](auto& gateway)- {- auto it = std::find_if(endpoints.begin(),- endpoints.end(),- [&](const auto& ep)- { return ep.address() == gateway.first; });- if (it != endpoints.end())- {- gateway.second->updateAudioEndpoint(*it);- }- else- {- gateway.second->updateAudioEndpoint(std::nullopt);- }- });- });- this->updateDiscovery();- }-- void updateApiChannels()- {- auto channelsChanged = false;- auto currentChannels = mChannels.uniqueSessionChannels(this->mSessionId);-- std::sort(currentChannels.begin(),- currentChannels.end(),- [](const auto& a, const auto& b)- {- if (a.peerName == b.peerName)- {- return a.name < b.name;- }- return a.peerName < b.peerName;- });-- mApiChannels.update(- [&](auto& apiChannels)- {- if (apiChannels != currentChannels)- {- apiChannels = currentChannels;- channelsChanged = true;- }- });-- if (channelsChanged)- {- mChannelsChangedCallback();- }- }-- struct ChannelsChanged- {- void operator()() { mpController->updateApiChannels(); }-- Controller* mpController;- };--- using Interface = MessengerInterface<typename util::Injected<IoContext>::type&>;- using ControllerChannels = Channels<IoContext&, ChannelsChanged, Interface>;- using SendHandler = typename ControllerChannels::SendHandler;-- struct GetSender- {- std::optional<SendHandler> forChannel(const Id& id)- {- return mpController->mChannels.channelSendHandler(id);- }-- std::optional<SendHandler> forPeer(const Id& id)- {- return mpController->mChannels.peerSendHandler(id);- }-- Controller* mpController;- };-- struct GetNodeId- {- const link::NodeId& operator()() const { return mpController->mNodeId; }-- Controller* mpController;- };-- struct ChannelsCallback- {- void operator()()- {- if (mpController && mpController->mpSessionController)- {- mpController->mpSessionController->updateDiscoveryCallback();- }- }-- Controller* mpController;- };-- using ControllerMainProcessor =- MainProcessor<ChannelsCallback, GetSender, GetNodeId, Random, IoContext&>;- using ControllerMessengerPtr =- MessengerPtr<ControllerMainProcessor&,- typename ControllerChannels::GatewayObserver,- typename util::Injected<IoContext>::type&>;-- struct GatewayFactory- {- ControllerMessengerPtr operator()(const discovery::IpAddress& addr)- {- return makeMessengerPtr(- util::injectRef(mpController->mProcessor),- util::injectRef(*(mpController->mIo)),- addr,- util::injectVal(makeGatewayObserver(mpController->mChannels, addr)),- PeerAnnouncement{mpController->mNodeId,- mpController->mSessionId,- mpController->mPeerInfo.read(),- mpController->mProcessor.channelAnnouncements()});- }-- void gatewaysChanged()- {- std::vector<discovery::UdpEndpoint> endpoints;- mpController->mGateways.withGateways(- [&](auto begin, auto end)- {- endpoints.reserve(std::distance(begin, end));- std::transform(begin,- end,- std::back_inserter(endpoints),- [](auto gateway) { return gateway.second->endpoint(); });- });- mpController->updateAudioEndpoints(std::move(endpoints));- }-- Controller* mpController;- };-- void stopAudio()- {- mIsLinkAudioEnabledByUser = false;- updateIsLinkAudioEnabled();- mProcessor.stop();- }-- ChannelsChangedCallback mChannelsChangedCallback;- util::Locked<std::vector<typename ControllerChannels::Channel>> mApiChannels;- std::atomic_bool mIsLinkAudioEnabledByUser;- bool mIsLinkAudioEffectivlyEnabled;- util::Locked<PeerInfo> mPeerInfo;- ControllerChannels mChannels;- ControllerMainProcessor mProcessor;- PeerGateways<GatewayFactory, IoContext&> mGateways;-};--} // namespace link_audio-} // namespace ableton
− link/include/ableton/link_audio/Encoder.hpp
@@ -1,69 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- * This program is free software: you can redistribute it and/or modify- * it under the terms of the GNU General Public License as published by- * the Free Software Foundation, either version 2 of the License, or- * (at your option) any later version.- *- * This program is distributed in the hope that it will be useful,- * but WITHOUT ANY WARRANTY; without even the implied warranty of- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- * GNU General Public License for more details.- *- * You should have received a copy of the GNU General Public License- * along with this program. If not, see <http://www.gnu.org/licenses/>.- *- * If you would like to incorporate Link into a proprietary software application,- * please contact <link-devs@ableton.com>.- */--#pragma once--#include <ableton/link_audio/AudioBuffer.hpp>-#include <ableton/link_audio/Buffer.hpp>-#include <ableton/link_audio/Id.hpp>-#include <ableton/link_audio/PCMCodec.hpp>-#include <ableton/link_audio/Resizer.hpp>-#include <ableton/util/Injected.hpp>-#include <array>-#include <memory>-#include <stdexcept>--namespace ableton-{-namespace link_audio-{--template <typename Sender, typename SampleFormat>-struct Encoder-{- // TODO: Find the best size for audio buffer messages- // For now we take RFC 791 as a reference. Nodes must be able to process IP messages of- // at least 576 bytes.- static constexpr uint32_t kMaxAudioBytes =- 576 - v1::kHeaderSize - AudioBuffer::kNonAudioBytes;- static_assert(kMaxAudioBytes <= v1::kMaxPayloadSize);-- Encoder(util::Injected<Sender> sender, Id channelId)- : mProcessor(- util::injectVal(PCMEncoder<SampleFormat, Sender>(std::move(sender), channelId)))- {- }-- void operator()(const Buffer<SampleFormat>& input)- {- mProcessor(input.mSamples.data(),- input.mNumFrames,- input.mNumChannels,- input.mSampleRate,- input.mBeginBeats,- input.mTempo,- input.mSessionId);- }--private:- Resizer<SampleFormat, PCMEncoder<SampleFormat, Sender>, kMaxAudioBytes> mProcessor;-};--} // namespace link_audio-} // namespace ableton
− link/include/ableton/link_audio/Id.hpp
@@ -1,32 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- * This program is free software: you can redistribute it and/or modify- * it under the terms of the GNU General Public License as published by- * the Free Software Foundation, either version 2 of the License, or- * (at your option) any later version.- *- * This program is distributed in the hope that it will be useful,- * but WITHOUT ANY WARRANTY; without even the implied warranty of- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- * GNU General Public License for more details.- *- * You should have received a copy of the GNU General Public License- * along with this program. If not, see <http://www.gnu.org/licenses/>.- *- * If you would like to incorporate Link into a proprietary software application,- * please contact <link-devs@ableton.com>.- */--#pragma once--#include <ableton/link/NodeId.hpp>--namespace ableton-{-namespace link_audio-{--using Id = ableton::link::NodeId;--} // namespace link_audio-} // namespace ableton
− link/include/ableton/link_audio/MainProcessor.hpp
@@ -1,242 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- * This program is free software: you can redistribute it and/or modify- * it under the terms of the GNU General Public License as published by- * the Free Software Foundation, either version 2 of the License, or- * (at your option) any later version.- *- * This program is distributed in the hope that it will be useful,- * but WITHOUT ANY WARRANTY; without even the implied warranty of- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- * GNU General Public License for more details.- *- * You should have received a copy of the GNU General Public License- * along with this program. If not, see <http://www.gnu.org/licenses/>.- *- * If you would like to incorporate Link into a proprietary software application,- * please contact <link-devs@ableton.com>.- */--#pragma once--#include <ableton/link_audio/ChannelAnnouncements.hpp>-#include <ableton/link_audio/Sink.hpp>-#include <ableton/link_audio/SinkProcessor.hpp>-#include <ableton/link_audio/Source.hpp>-#include <ableton/link_audio/SourceProcessor.hpp>-#include <ableton/util/Injected.hpp>-#include <ableton/util/SafeAsyncHandler.hpp>--namespace ableton-{-namespace link_audio-{--using SharedSink = std::shared_ptr<Sink>;-using SharedSource = std::shared_ptr<Source>;--template <typename ChannelsChangedCallback,- typename GetSender,- typename GetNodeId,- typename Random,- typename IoContext>-struct MainProcessor-{- using IoType = typename util::Injected<IoContext>::type;-- static constexpr auto kProcessTimerPeriod = std::chrono::milliseconds(1);-- MainProcessor(util::Injected<IoContext> io,- util::Injected<ChannelsChangedCallback> callback)- : mpImpl(std::make_shared<Impl>(std::move(io), std::move(callback)))- {- }-- ~MainProcessor() { stop(); }-- void stop() { mpImpl->stop(); }-- void addSink(SharedSink pSink,- util::Injected<GetSender> getSender,- util::Injected<GetNodeId> getNodeId)- {- mpImpl->addSink(pSink, std::move(getSender), std::move(getNodeId));- }-- void addSource(SharedSource pSource,- util::Injected<GetSender> getSender,- util::Injected<GetNodeId> getNodeId)- {- mpImpl->addSource(pSource, std::move(getSender), std::move(getNodeId));- }-- ChannelAnnouncements channelAnnouncements() const- {- return mpImpl->channelAnnouncements();- }-- template <typename Request>- void receiveChannelRequest(Request request, uint8_t ttl)- {- mpImpl->receiveChannelRequest(std::move(request), ttl);- }-- template <typename It>- void receiveAudioBuffer(It begin, It end)- {- mpImpl->receiveAudioBuffer(begin, end);- }--private:- struct Impl : std::enable_shared_from_this<Impl>- {- using Timer = typename util::Injected<IoContext>::type::Timer;- using MainSinkProcessor = SinkProcessor<GetSender, GetNodeId, IoContext&>;- using MainSourceProcessor = SourceProcessor<GetSender, GetNodeId, IoContext&>;-- Impl(util::Injected<IoContext> io, util::Injected<ChannelsChangedCallback> callback)- : mIo{std::move(io)}- , mChannelsChangedCallback{std::move(callback)}- , mProcessTimer{mIo->makeTimer()}- {- }-- void addSink(SharedSink pSink,- util::Injected<GetSender> getSender,- util::Injected<GetNodeId> getNodeId)- {- auto processor = std::make_unique<MainSinkProcessor>(- util::injectRef(*mIo), pSink, std::move(getSender), std::move(getNodeId));- mSinks.push_back(std::move(processor));- start();- }-- void addSource(SharedSource pSource,- util::Injected<GetSender> getSender,- util::Injected<GetNodeId> getNodeId)- {- auto pProcessor = std::make_unique<MainSourceProcessor>(- util::injectRef(*mIo), pSource, std::move(getSender), std::move(getNodeId));- mSources.push_back(std::move(pProcessor));- start();- }-- void start() { (*this)(); }-- void stop() { mProcessTimer.cancel(); }-- void operator()()- {- processSinks();- processSources();- if (!mSinks.empty() || !mSources.empty())- {- mProcessTimer.expires_from_now(kProcessTimerPeriod);- mProcessTimer.async_wait(- [this](const auto e)- {- if (!e)- {- (*this)();- }- });- }- }-- void processSinks()- {- auto channelsChanged = false;-- for (auto it = mSinks.begin(); it != mSinks.end();)- {- if ((*it)->nameChanged())- {- channelsChanged = true;- }-- if ((*it)->process())- {- ++it;- }- else- {- it = mSinks.erase(it);- channelsChanged = true;- }- }-- if (channelsChanged)- {- (*mChannelsChangedCallback)();- }- }-- void processSources()- {- auto channelsChanged = false;-- for (auto it = mSources.begin(); it != mSources.end();)- {- if ((*it)->process())- {- ++it;- }- else- {- it = mSources.erase(it);- }- }- }-- ChannelAnnouncements channelAnnouncements() const- {- auto announcements = ChannelAnnouncements{};- for (auto& sink : mSinks)- {- announcements.channels.emplace_back(- ChannelAnnouncement{sink->name(), sink->id()});- }- return announcements;- }-- template <typename Request>- void receiveChannelRequest(Request request, uint8_t ttl)- {- auto it =- std::find_if(mSinks.begin(),- mSinks.end(),- [&](const auto& pSink) { return request.channelId == pSink->id(); });- if (it != mSinks.end())- {- it->get()->receiveChannelRequest(std::move(request), ttl);- }- }-- template <typename It>- void receiveAudioBuffer(It begin, It end)- {- static auto audioBuffer = AudioBuffer{};- AudioBuffer::fromNetworkByteStream(audioBuffer, begin, end);-- auto it = std::find_if(mSources.begin(),- mSources.end(),- [&](const auto& pSource)- { return audioBuffer.channelId == pSource->id(); });- if (it != mSources.end())- {- it->get()->receiveAudioBuffer(audioBuffer);- }- }-- util::Injected<IoContext> mIo;- util::Injected<ChannelsChangedCallback> mChannelsChangedCallback;- std::vector<std::unique_ptr<MainSinkProcessor>> mSinks;- std::vector<std::unique_ptr<MainSourceProcessor>> mSources;- Timer mProcessTimer;- };-- std::shared_ptr<Impl> mpImpl;-};--} // namespace link_audio-} // namespace ableton
− link/include/ableton/link_audio/NetworkMetrics.hpp
@@ -1,82 +0,0 @@-#pragma once--#include <array>-#include <chrono>-#include <cmath>-#include <numeric>--namespace ableton-{-namespace link_audio-{--struct NetworkMetricsFilter-{- struct NetworkMetrics- {- double speed;- double jitter;-- double quality() const { return speed / (1.0 + jitter); }-- bool operator<(const NetworkMetrics& other) const- {- return quality() < other.quality();- }- };-- NetworkMetricsFilter()- : mCurrentIndex(0)- , mCount(0)- {- }-- void operator()(std::chrono::microseconds time)- {- mPingPongTimes[mCurrentIndex] = time;- mCurrentIndex = (mCurrentIndex + 1) % kMaxSize;- if (mCount < kMaxSize)- {- ++mCount;- }- }-- NetworkMetrics metrics() const- {- if (mCount == 0)- {- return {0.0, 0.0};- }-- double sum =- std::accumulate(mPingPongTimes.begin(),- mPingPongTimes.begin() + mCount,- 0.0,- [](auto acc, const auto& time) { return acc + time.count(); });- double avgRTT = sum / mCount;-- double speed = avgRTT != 0.0 ? 1e6 / avgRTT : 0.0;-- double variance = 0.0;- for (size_t i = 0; i < mCount; ++i)- {- double diff = mPingPongTimes[i].count() - avgRTT;- variance += diff * diff;- }- variance /= mCount;- double jitter = std::sqrt(variance);-- return {speed, (1e4 - 1e4 * mCount / kMaxSize) + jitter};- }-- double quality() const { return metrics().quality(); }--private:- static constexpr size_t kMaxSize = 10;- std::array<std::chrono::microseconds, kMaxSize> mPingPongTimes;- size_t mCurrentIndex;- size_t mCount;-};--} // namespace link_audio-} // namespace ableton
− link/include/ableton/link_audio/PCMCodec.hpp
@@ -1,116 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- * This program is free software: you can redistribute it and/or modify- * it under the terms of the GNU General Public License as published by- * the Free Software Foundation, either version 2 of the License, or- * (at your option) any later version.- *- * This program is distributed in the hope that it will be useful,- * but WITHOUT ANY WARRANTY; without even the implied warranty of- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- * GNU General Public License for more details.- *- * You should have received a copy of the GNU General Public License- * along with this program. If not, see <http://www.gnu.org/licenses/>.- *- * If you would like to incorporate Link into a proprietary software application,- * please contact <link-devs@ableton.com>.- */--#pragma once--#include <ableton/discovery/NetworkByteStreamSerializable.hpp>-#include <ableton/link_audio/AudioBuffer.hpp>-#include <ableton/link_audio/Buffer.hpp>-#include <ableton/util/Injected.hpp>-#include <memory>--namespace ableton-{-namespace link_audio-{--template <typename SampleFormat, typename Sender>-struct PCMEncoder-{- PCMEncoder(util::Injected<Sender> sender, Id channelId)- : mSender(std::move(sender))- {- mOutputBuffer.channelId = channelId;- }-- void operator()(const SampleFormat* samples,- const AudioBuffer::Chunks& chunks,- const uint32_t numChannels,- const uint32_t sampleRate,- const Id sessionId)- {- mOutputBuffer.chunks = chunks;- mOutputBuffer.codec = Codec::kPCM_i16;- mOutputBuffer.sampleRate = sampleRate;- mOutputBuffer.numChannels = numChannels;- mOutputBuffer.sessionId = sessionId;-- auto it = mOutputBuffer.bytes.begin();- const auto numSamples = mOutputBuffer.numFrames() * mOutputBuffer.numChannels;- assert(numSamples * sizeof(int16_t) <= AudioBuffer::kMaxAudioBytes);- for (auto sample = 0u; sample < numSamples; ++sample)- {- it = discovery::toNetworkByteStream(samples[sample], it);- }- mOutputBuffer.numBytes =- static_cast<uint32_t>(std::distance(mOutputBuffer.bytes.begin(), it));-- (*mSender)(mOutputBuffer);- }-- AudioBuffer mOutputBuffer;- util::Injected<Sender> mSender;-};--template <typename SampleFormat, typename Successor>-struct PCMDecoder-{- PCMDecoder(util::Injected<Successor> successor, uint32_t cacheSize)- : mBuffer(cacheSize)- , mSuccessor(std::move(successor))- {- }-- void operator()(const AudioBuffer& input)- {- auto it = input.bytes.begin();- auto numSamples = 0u;- auto inputEnd = input.bytes.begin() + input.numBytes;- while (it != inputEnd)- {- auto [sample, next] =- discovery::Deserialize<SampleFormat>::fromNetworkByteStream(it, inputEnd);- mBuffer.mSamples[numSamples] = sample;- ++numSamples;- it = next;- }-- auto pSamples = mBuffer.mSamples.data();-- for (const auto& [count, numFrames, beginBeats, tempo] : input.chunks)- {- mBuffer.mNumFrames = numFrames;- mBuffer.mNumChannels = input.numChannels;- mBuffer.mSampleRate = input.sampleRate;- mBuffer.mBeginBeats = beginBeats;- mBuffer.mTempo = tempo;- mBuffer.mCount = count;- mBuffer.mSessionId = input.sessionId;-- (*mSuccessor)(BufferCallbackHandle<Buffer<SampleFormat>>{mBuffer, pSamples});- pSamples += numFrames * input.numChannels;- }- }-- Buffer<SampleFormat> mBuffer;- util::Injected<Successor> mSuccessor;-};--} // namespace link_audio-} // namespace ableton
− link/include/ableton/link_audio/PeerAnnouncement.hpp
@@ -1,78 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- * This program is free software: you can redistribute it and/or modify- * it under the terms of the GNU General Public License as published by- * the Free Software Foundation, either version 2 of the License, or- * (at your option) any later version.- *- * This program is distributed in the hope that it will be useful,- * but WITHOUT ANY WARRANTY; without even the implied warranty of- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- * GNU General Public License for more details.- *- * You should have received a copy of the GNU General Public License- * along with this program. If not, see <http://www.gnu.org/licenses/>.- *- * If you would like to incorporate Link into a proprietary software application,- * please contact <link-devs@ableton.com>.- */--#pragma once--#include <ableton/discovery/Payload.hpp>-#include <ableton/link/NodeId.hpp>-#include <ableton/link/SessionId.hpp>-#include <ableton/link_audio/ChannelAnnouncements.hpp>-#include <ableton/link_audio/PeerInfo.hpp>--namespace ableton-{-namespace link_audio-{--struct PeerAnnouncement-{- using IdType = link::NodeId;-- using Payload = decltype(discovery::makePayload(- link::SessionMembership{}, PeerInfo{}, ChannelAnnouncements{}));-- link::NodeId ident() const { return nodeId; }-- friend bool operator==(const PeerAnnouncement& lhs, const PeerAnnouncement& rhs)- {- return std::tie(lhs.nodeId, lhs.sessionId, lhs.peerInfo, lhs.channels)- == std::tie(rhs.nodeId, rhs.sessionId, rhs.peerInfo, rhs.channels);- }-- friend Payload toPayload(const PeerAnnouncement& announcement)- {- return discovery::makePayload(link::SessionMembership{announcement.sessionId},- announcement.peerInfo,- announcement.channels);- }-- template <typename It>- static PeerAnnouncement fromPayload(link::NodeId nodeId, It begin, It end)- {- using namespace std;- auto announcement = PeerAnnouncement{std::move(nodeId), {}, {}};- discovery::parsePayload<link::SessionMembership, PeerInfo, ChannelAnnouncements>(- std::move(begin),- std::move(end),- [&announcement](link::SessionMembership membership)- { announcement.sessionId = std::move(membership.sessionId); },- [&announcement](PeerInfo pi) { announcement.peerInfo = std::move(pi); },- [&announcement](ChannelAnnouncements chs)- { announcement.channels = std::move(chs); });- return announcement;- }-- link::NodeId nodeId;- link::SessionId sessionId;- PeerInfo peerInfo;- ChannelAnnouncements channels;-};--} // namespace link_audio-} // namespace ableton
− link/include/ableton/link_audio/PeerGateways.hpp
@@ -1,154 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- * This program is free software: you can redistribute it and/or modify- * it under the terms of the GNU General Public License as published by- * the Free Software Foundation, either version 2 of the License, or- * (at your option) any later version.- *- * This program is distributed in the hope that it will be useful,- * but WITHOUT ANY WARRANTY; without even the implied warranty of- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- * GNU General Public License for more details.- *- * You should have received a copy of the GNU General Public License- * along with this program. If not, see <http://www.gnu.org/licenses/>.- *- * If you would like to incorporate Link into a proprietary software application,- * please contact <link-devs@ableton.com>.- */--#pragma once--#include <ableton/discovery/AsioTypes.hpp>-#include <ableton/link/NodeId.hpp>-#include <ableton/util/Injected.hpp>-#include <algorithm>-#include <map>-#include <memory>-#include <optional>-#include <type_traits>-#include <vector>--namespace ableton-{-namespace link_audio-{--template <typename GatewayFactory, typename IoContext>-struct PeerGateways-{- using FactoryType = typename util::Injected<GatewayFactory>::type;- using GatewayPtr = std::invoke_result_t<FactoryType, const discovery::IpAddress&>;- using GatewayMap = std::map<discovery::IpAddress, GatewayPtr>;-- PeerGateways(util::Injected<GatewayFactory> factory, util::Injected<IoContext> io)- : mIo(std::move(io))- , mFactory(std::move(factory))- {- }-- template <typename Handler>- void forEachGateway(Handler handler)- {- for (auto it = mGateways.begin(); it != mGateways.end(); ++it)- {- handler(it->second);- }- }-- template <typename Handler>- void withGateways(Handler handler)- {- handler(mGateways.begin(), mGateways.end());- }-- void clear()- {- mGateways.clear();- mFactory->gatewaysChanged();- }-- template <typename Announcement>- void updateAnnouncement(const Announcement& announcement)- {- for (const auto& gateway : mGateways)- {- gateway.second->updateAnnouncement(announcement);- }- }-- void updateGateways(std::vector<discovery::IpAddress> linkGateways)- {- using namespace std;-- vector<discovery::IpAddress> curAddrs;- curAddrs.reserve(mGateways.size());- transform(mGateways.begin(),- mGateways.end(),- back_inserter(curAddrs),- [](const auto& gateway) { return gateway.first; });-- vector<discovery::IpAddress> staleAddrs;- set_difference(curAddrs.begin(),- curAddrs.end(),- linkGateways.begin(),- linkGateways.end(),- back_inserter(staleAddrs));-- for (const auto& addr : staleAddrs)- {- mGateways.erase(addr);- }-- vector<discovery::IpAddress> newAddrs;- set_difference(linkGateways.begin(),- linkGateways.end(),- curAddrs.begin(),- curAddrs.end(),- back_inserter(newAddrs));-- for (const auto& addr : newAddrs)- {- try- {- info(mIo->log()) << "initializing audio gateway on interface " << addr;- mGateways.emplace(addr, (*mFactory)(addr));- }- catch (const std::runtime_error& e)- {- warning(mIo->log()) << "failed to init audio gateway on interface " << addr- << " reason: " << e.what();- }- }-- if (!staleAddrs.empty() || !newAddrs.empty())- {- mFactory->gatewaysChanged();- }- }-- template <typename It>- void updateSessionPeers(It peersBegin, It peersEnd)- {- forEachGateway([&](auto& gateway)- { gateway->pruneChannelsEndpoints(peersBegin, peersEnd); });- }-- void sawLinkAudioEndpoint(link::NodeId peerId,- std::optional<discovery::UdpEndpoint> endpoint,- discovery::IpAddress gateway)- {- if (auto it = mGateways.find(gateway); it != mGateways.end())- {- it->second->sawLinkAudioEndpoint(peerId, endpoint);- }- }--private:- util::Injected<IoContext> mIo;- GatewayMap mGateways;- util::Injected<GatewayFactory> mFactory;-};--} // namespace link_audio-} // namespace ableton
− link/include/ableton/link_audio/PeerInfo.hpp
@@ -1,75 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- * This program is free software: you can redistribute it and/or modify- * it under the terms of the GNU General Public License as published by- * the Free Software Foundation, either version 2 of the License, or- * (at your option) any later version.- *- * This program is distributed in the hope that it will be useful,- * but WITHOUT ANY WARRANTY; without even the implied warranty of- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- * GNU General Public License for more details.- *- * You should have received a copy of the GNU General Public License- * along with this program. If not, see <http://www.gnu.org/licenses/>.- *- * If you would like to incorporate Link into a proprietary software application,- * please contact <link-devs@ableton.com>.- */--#pragma once--#include <ableton/discovery/NetworkByteStreamSerializable.hpp>-#include <cstdint>-#include <string>-#include <tuple>--namespace ableton-{-namespace link_audio-{--struct PeerInfo-{- static const std::int32_t key = '__pi';- static_assert(key == 0x5f5f7069, "Unexpected byte order");-- friend bool operator==(const PeerInfo& lhs, const PeerInfo& rhs)- {- return std::tie(lhs.name) == std::tie(rhs.name);- }-- friend bool operator!=(const PeerInfo& lhs, const PeerInfo& rhs)- {- return !(lhs == rhs);- }-- // Model the NetworkByteStreamSerializable concept- friend std::uint32_t sizeInByteStream(const PeerInfo& tl)- {- return discovery::sizeInByteStream(tl.name);- }-- template <typename It>- friend It toNetworkByteStream(const PeerInfo& tl, It out)- {- return discovery::toNetworkByteStream(tl.name, std::move(out));- }-- template <typename It>- static std::pair<PeerInfo, It> fromNetworkByteStream(It begin, It end)- {- using namespace std;- using namespace discovery;- PeerInfo peerInfo;- auto result =- Deserialize<std::string>::fromNetworkByteStream(std::move(begin), std::move(end));- peerInfo.name = std::move(result.first);- return make_pair(std::move(peerInfo), std::move(result.second));- }-- std::string name;-};--} // namespace link_audio-} // namespace ableton
− link/include/ableton/link_audio/Queue.hpp
@@ -1,217 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- * This program is free software: you can redistribute it and/or modify- * it under the terms of the GNU General Public License as published by- * the Free Software Foundation, either version 2 of the License, or- * (at your option) any later version.- *- * This program is distributed in the hope that it will be useful,- * but WITHOUT ANY WARRANTY; without even the implied warranty of- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- * GNU General Public License for more details.- *- * You should have received a copy of the GNU General Public License- * along with this program. If not, see <http://www.gnu.org/licenses/>.- *- * If you would like to incorporate Link into a proprietary software application,- * please contact <link-devs@ableton.com>.- */--#pragma once--#include <atomic>-#include <memory>-#include <vector>--namespace ableton-{-namespace link_audio-{--template <typename T>-struct Queue-{-private:- struct Impl;--public:- struct Writer- {- using SlotType = T;-- Writer(const Writer&) = delete;- Writer& operator=(const Writer&) = delete;-- Writer(Writer&&) = default;- Writer& operator=(Writer&&) = default;-- bool retainSlot()- {- return mpQueue->retainSlot(mpQueue->mWriterEnd, mpQueue->mReaderBegin);- }-- void releaseSlot()- {- mpQueue->releaseSlot(mpQueue->mWriterBegin, mpQueue->mWriterEnd);- }-- size_t numRetainedSlots() const- {- return mpQueue->numRetainedSlots(mpQueue->mWriterBegin, mpQueue->mWriterEnd);- }-- size_t numQueuedSlots() const { return mpQueue->numQueuedSlots(); }-- T* operator[](size_t i) const- {- if (i < numRetainedSlots())- {- i += mpQueue->mWriterBegin.load();- return mpQueue->mData[i % mpQueue->mData.size()].get();- }- return nullptr;- }-- size_t numSlots() const { return mpQueue->numSlots(); }-- private:- friend Queue;-- Writer(std::shared_ptr<Impl> pQueue)- : mpQueue(pQueue)- {- }-- std::shared_ptr<Impl> mpQueue;- };-- struct Reader- {- Reader(const Reader&) = delete;- Reader& operator=(const Reader&) = delete;-- Reader(Reader&&) = default;- Reader& operator=(Reader&&) = default;-- bool retainSlot()- {- return mpQueue->retainSlot(mpQueue->mReaderEnd, mpQueue->mWriterBegin);- }-- void releaseSlot()- {- mpQueue->releaseSlot(mpQueue->mReaderBegin, mpQueue->mReaderEnd);- }-- size_t numRetainedSlots() const- {- return mpQueue->numRetainedSlots(mpQueue->mReaderBegin, mpQueue->mReaderEnd);- }-- size_t numQueuedSlots() const { return mpQueue->numQueuedSlots(); }-- T* operator[](size_t i) const- {- if (i < numRetainedSlots())- {- i += mpQueue->mReaderBegin.load() + 1;- return mpQueue->mData[i % mpQueue->mData.size()].get();- }- return nullptr;- }-- size_t numSlots() const { return mpQueue->numSlots(); }-- private:- friend Queue;-- Reader(std::shared_ptr<Impl> pQueue)- : mpQueue(pQueue)- {- }-- std::shared_ptr<Impl> mpQueue;- };-- Queue(size_t numRetainedSlots, const T& t)- : mpImpl{std::make_shared<Impl>(numRetainedSlots, t)}- {- }-- Writer writer() const { return {mpImpl}; }-- Reader reader() const { return {mpImpl}; }--private:- struct Impl- {- Impl(size_t numRetainedSlots, const T& t)- : mData(numRetainedSlots + 2)- , mWriterBegin(1)- , mWriterEnd(1)- , mReaderBegin(0)- , mReaderEnd(0)- {- for (auto& slot : mData)- {- slot = std::make_unique<T>(t);- }- }-- inline size_t nextIndex(const size_t index) const- {- return (index + 1) % mData.size();- }-- inline bool retainSlot(std::atomic_size_t& aEnd, std::atomic_size_t& aOtherBegin)- {- const auto nextEnd = nextIndex(aEnd.load());- const auto otherBegin = aOtherBegin.load();- if (nextEnd != otherBegin)- {- aEnd.store(nextEnd);- return true;- }- return false;- }-- inline void releaseSlot(std::atomic_size_t& aBegin, std::atomic_size_t& aEnd)- {- const auto begin = aBegin.load();- const auto end = aEnd.load();- if (begin != end)- {- aBegin.store(nextIndex(begin));- }- }-- inline size_t numRetainedSlots(const std::atomic_size_t& aBegin,- const std::atomic_size_t& aEnd) const- {- const auto begin = aBegin.load();- const auto end = aEnd.load();- return begin > end ? end + mData.size() - begin : end - begin;- }-- inline size_t numQueuedSlots() const- {- const auto writerBegin = mWriterBegin.load();- const auto readerEnd = mReaderEnd.load();- return writerBegin > readerEnd ? writerBegin - readerEnd - 1- : writerBegin + mData.size() - readerEnd - 1;- }-- size_t numSlots() const { return mData.size() - 2; }-- std::vector<std::unique_ptr<T>> mData;- std::atomic_size_t mWriterBegin;- std::atomic_size_t mWriterEnd;- std::atomic_size_t mReaderBegin;- std::atomic_size_t mReaderEnd;- };-- std::shared_ptr<Impl> mpImpl;-};--} // namespace link_audio-} // namespace ableton
− link/include/ableton/link_audio/Receivers.hpp
@@ -1,172 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- * This program is free software: you can redistribute it and/or modify- * it under the terms of the GNU General Public License as published by- * the Free Software Foundation, either version 2 of the License, or- * (at your option) any later version.- *- * This program is distributed in the hope that it will be useful,- * but WITHOUT ANY WARRANTY; without even the implied warranty of- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- * GNU General Public License for more details.- *- * You should have received a copy of the GNU General Public License- * along with this program. If not, see <http://www.gnu.org/licenses/>.- *- * If you would like to incorporate Link into a proprietary software application,- * please contact <link-devs@ableton.com>.- */--#pragma once--#include <ableton/link_audio/ChannelRequests.hpp>-#include <ableton/util/Injected.hpp>-#include <chrono>-#include <memory>-#include <utility>-#include <vector>--namespace ableton-{-namespace link_audio-{--template <typename GetSender, typename IoContext>-class Receivers-{- using Timer = typename util::Injected<IoContext>::type::Timer;- using TimePoint = typename Timer::TimePoint;- using OptionalSendHandler =- decltype(std::declval<GetSender>().forChannel(std::declval<Id>()));-- struct Receiver- {- OptionalSendHandler sendHandler;- ChannelRequest request;- TimePoint lastRequest;- };--public:- Receivers(util::Injected<IoContext> io, util::Injected<GetSender> getSender)- : mpImpl(std::make_shared<Impl>(std::move(io), std::move(getSender)))- {- }-- void receiveChannelRequest(ChannelRequest request, uint8_t ttl)- {- mpImpl->receive(std::move(request), ttl);- }-- void receiveChannelRequest(ChannelStopRequest stopRequest, uint8_t ttl)- {- mpImpl->receive(std::move(stopRequest), ttl);- }-- void operator()(const uint8_t* const pData, const size_t numBytes)- {- (*mpImpl)(pData, numBytes);- }-- bool empty() const { return mpImpl->empty(); }--private:- struct Impl- {- Impl(util::Injected<IoContext> io, util::Injected<GetSender> getSender)- : mPruneTimer(io->makeTimer())- , mGetSender(std::move(getSender))- {- }-- void receive(ChannelRequest request, uint8_t ttl)- {- const auto it =- std::find_if(mReceivers.begin(),- mReceivers.end(),- [&](auto& r) { return r.request.peerId == request.peerId; });- if (it != mReceivers.end())- {- mReceivers.erase(it);- }-- const auto now = mPruneTimer.now();- auto receiver = Receiver{- mGetSender->forPeer(request.peerId), request, now + std::chrono::seconds(ttl)};-- mReceivers.insert(upper_bound(mReceivers.begin(),- mReceivers.end(),- receiver,- [](const auto& r1, const auto& r2)- { return r1.lastRequest < r2.lastRequest; }),- std::move(receiver));-- scheduleNextPruning();- }-- void receive(ChannelStopRequest stopRequest, uint8_t)- {- const auto it = std::find_if(mReceivers.begin(),- mReceivers.end(),- [&](const auto& r)- { return r.request.peerId == stopRequest.peerId; });- if (it != mReceivers.end())- {- mReceivers.erase(it);- };- }-- void pruneExpiredReceivers()- {- const auto test = Receiver{{}, {}, mPruneTimer.now()};-- const auto endExpired = std::lower_bound(- mReceivers.begin(),- mReceivers.end(),- test,- [](const auto& r1, const auto& r2) { return r1.lastRequest < r2.lastRequest; });-- mReceivers.erase(mReceivers.begin(), endExpired);- scheduleNextPruning();- }-- void scheduleNextPruning()- {- if (!mReceivers.empty())- {- const auto t = mReceivers.front().lastRequest + std::chrono::seconds(1);-- mPruneTimer.expires_at(t);- mPruneTimer.async_wait(- [this](const auto e)- {- if (!e)- {- pruneExpiredReceivers();- }- });- }- }-- void operator()(const uint8_t* const pData, const size_t numBytes)- {- for (auto& receiver : mReceivers)- {- if (auto& sendHandler = receiver.sendHandler)- {- (*sendHandler)(pData, numBytes);- }- }- }-- bool empty() const { return mReceivers.empty(); }-- Timer mPruneTimer;- util::Injected<GetSender> mGetSender;- std::vector<Receiver> mReceivers; // Invariant: sorted by time_point- };-- std::shared_ptr<Impl> mpImpl;-};--} // namespace link_audio-} // namespace ableton
− link/include/ableton/link_audio/Resizer.hpp
@@ -1,147 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- * This program is free software: you can redistribute it and/or modify- * it under the terms of the GNU General Public License as published by- * the Free Software Foundation, either version 2 of the License, or- * (at your option) any later version.- *- * This program is distributed in the hope that it will be useful,- * but WITHOUT ANY WARRANTY; without even the implied warranty of- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- * GNU General Public License for more details.- *- * You should have received a copy of the GNU General Public License- * along with this program. If not, see <http://www.gnu.org/licenses/>.- *- * If you would like to incorporate Link into a proprietary software- * application, please contact <link-devs@ableton.com>.- */--#pragma once--#include <ableton/link/Beats.hpp>-#include <ableton/link/Tempo.hpp>-#include <ableton/link_audio/AudioBuffer.hpp>-#include <ableton/link_audio/Id.hpp>-#include <ableton/util/Injected.hpp>-#include <algorithm>-#include <array>-#include <cmath>-#include <memory>-#include <tuple>-#include <vector>--namespace ableton-{-namespace link_audio-{--template <typename SampleFormat, typename Successor, size_t KMaxNumBytes>-struct Resizer-{- static constexpr uint32_t kSampleFormatSize =- static_cast<uint32_t>(sizeof(SampleFormat));- static constexpr uint32_t kMaxNumSamples = KMaxNumBytes / kSampleFormatSize;-- Resizer(util::Injected<Successor> successor)- : mSuccessor(std::move(successor))- {- }-- void operator()(const SampleFormat* samples,- uint32_t numFrames,- uint32_t numChannels,- uint32_t sampleRate,- link::Beats beginBeats,- link::Tempo tempo,- Id sessionId)- {- if (mCachedFrames != 0- && (numChannels != mNumChannels || sampleRate != mSampleRate- || sessionId != mSessionId))- {- (*mSuccessor)(mCache.data(), mChunks, mNumChannels, mSampleRate, mSessionId);- mCachedFrames = 0;- mChunks.clear();- }-- if (mCachedFrames == 0)- {- mSampleRate = sampleRate;- mNumChannels = numChannels;- mSessionId = sessionId;- assert(mChunks.empty());- newChunk(beginBeats, tempo);- }- else if (tempo != mChunks.back().tempo && beginBeats != chunkEndBeats(mChunks.back()))- {- newChunk(beginBeats, tempo);- }-- for (auto frame = 0u; frame < numFrames; ++frame)- {- for (auto channel = 0u; channel < mNumChannels; ++channel)- {- mCache[mNumChannels * mCachedFrames + channel] =- samples[mNumChannels * frame + channel];- }- ++mCachedFrames;- ++mChunks.back().numFrames;--- if (mCachedFrames >= ((kMaxNumSamples / mNumChannels)))- {- (*mSuccessor)(mCache.data(), mChunks, mNumChannels, mSampleRate, mSessionId);- mCachedFrames = 0;- const auto nextChunkBeginBeats = chunkEndBeats(mChunks.back());- mChunks.clear();-- // Always create a new chunk when needed - don't lose data- if (frame + 1 < numFrames) // Only if there are more frames to process- {- newChunk(nextChunkBeginBeats, tempo);- }- }- }- }--private:- link::Beats chunkEndBeats(const AudioBuffer::Chunk& chunk)- {- const auto& [count, numFrames, beginBeats, tempo] = chunk;- const auto secondsPerBeat = 60.0 / tempo.bpm();- const auto rangeDuration =- static_cast<double>(numFrames) / static_cast<double>(mSampleRate);- return beginBeats + link::Beats{rangeDuration / secondsPerBeat};- }-- uint32_t mCachedFrames = 0;- uint32_t mAvailableFrames = 0;-- void updateAvailableFrames()- {- const auto availableBytes =- kMaxNumSamples * kSampleFormatSize - discovery::sizeInByteStream(mChunks);- const auto bytesPerFrame = mNumChannels * kSampleFormatSize;- const auto offsetBytes = availableBytes % bytesPerFrame;- mAvailableFrames = (availableBytes - offsetBytes) / bytesPerFrame;- }-- void newChunk(Beats beats, Tempo tempo)- {- mChunks.emplace_back(AudioBuffer::Chunk{++mCount, 0, beats, tempo});- updateAvailableFrames();- }-- std::array<SampleFormat, kMaxNumSamples> mCache;- util::Injected<Successor> mSuccessor;- uint32_t mNumChannels = 0u;- uint32_t mSampleRate = 0u;- Id mSessionId;-- AudioBuffer::Chunks mChunks;- uint64_t mCount = 0;-};--} // namespace link_audio-} // namespace ableton
− link/include/ableton/link_audio/SessionController.hpp
@@ -1,125 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- * This program is free software: you can redistribute it and/or modify- * it under the terms of the GNU General Public License as published by- * the Free Software Foundation, either version 2 of the License, or- * (at your option) any later version.- *- * This program is distributed in the hope that it will be useful,- * but WITHOUT ANY WARRANTY; without even the implied warranty of- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- * GNU General Public License for more details.- *- * You should have received a copy of the GNU General Public License- * along with this program. If not, see <http://www.gnu.org/licenses/>.- *- * If you would like to incorporate Link into a proprietary software application,- * please contact <link-devs@ableton.com>.- */--#pragma once--#include <ableton/link_audio/Controller.hpp>-#include <ableton/link_audio/Id.hpp>--namespace ableton-{-namespace link_audio-{--template <typename PeerCountCallback,- typename TempoCallback,- typename StartStopStateCallback,- typename Clock,- typename Random,- typename IoContext>-class SessionController : public Controller<PeerCountCallback,- TempoCallback,- StartStopStateCallback,- Clock,- Random,- IoContext,- SessionController<PeerCountCallback,- TempoCallback,- StartStopStateCallback,- Clock,- Random,- IoContext>>-{-public:- using LinkAudioController = Controller<PeerCountCallback,- TempoCallback,- StartStopStateCallback,- Clock,- Random,- IoContext,- SessionController<PeerCountCallback,- TempoCallback,- StartStopStateCallback,- Clock,- Random,- IoContext>>;-- SessionController(link::Tempo tempo,- PeerCountCallback peerCallback,- TempoCallback tempoCallback,- StartStopStateCallback startStopStateCallback,- Clock clock)- : LinkAudioController(- tempo, peerCallback, tempoCallback, startStopStateCallback, clock)- {- this->mRtClientStateSetter.start();- }-- ~SessionController()- {- this->mIo->async([this]() { this->stopAudio(); });- this->shutdown();- }-- void sessionMembershipCallback()- {- this->mSessionPeerCounter();- this->updateLinkAudio();- }-- void joinSessionCallback(const link::Session& session)- {- this->joinSession(session);- this->updateLinkAudio();- }-- template <typename Peer, typename Handler>- void measurePeerCallback(Peer peer, Handler handler)- {- this->measurePeer(std::move(peer), std::move(handler));- }-- void updateDiscoveryCallback()- {- this->updateDiscovery();- this->updateAudioDiscovery();- }-- void gatewaysChangedCallback() { this->updateLinkAudioGateways(); }-- void updateRtStatesCallback()- {- // Process the pending client states first to make sure we don't push one- // after we have joined a running session when enabling- this->mRtClientStateSetter.processPendingClientStates();- this->mRtClientStateSetter.updateEnabled();-- this->updateIsLinkAudioEnabled();- }-- void sawAudioEndpointCallback(Id peerId,- std::optional<discovery::UdpEndpoint> endpoint,- discovery::IpAddress gateway)- {- this->sawLinkAudioEndpoint(peerId, endpoint, gateway);- }-};--} // namespace link_audio-} // namespace ableton
− link/include/ableton/link_audio/Sink.hpp
@@ -1,144 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- * This program is free software: you can redistribute it and/or modify- * it under the terms of the GNU General Public License as published by- * the Free Software Foundation, either version 2 of the License, or- * (at your option) any later version.- *- * This program is distributed in the hope that it will be useful,- * but WITHOUT ANY WARRANTY; without even the implied warranty of- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- * GNU General Public License for more details.- *- * You should have received a copy of the GNU General Public License- * along with this program. If not, see <http://www.gnu.org/licenses/>.- *- * If you would like to incorporate Link into a proprietary software application,- * please contact <link-devs@ableton.com>.- */--#include <ableton/link_audio/BeatTimeMapping.hpp>-#include <ableton/link_audio/Buffer.hpp>-#include <ableton/link_audio/Id.hpp>-#include <ableton/link_audio/Queue.hpp>-#include <ableton/util/Locked.hpp>-#include <atomic>-#include <string>--#pragma once--namespace ableton-{-namespace link_audio-{--struct Sink-{- Sink(std::string name, size_t maxNumSamples, Id id)- : mName{std::move(name)}- , mId{std::move(id)}- , mMaxNumSamples{maxNumSamples}- , mQueue(128, {static_cast<uint32_t>(maxNumSamples)})- , mIsConnected(false)- {- }-- void setName(std::string name)- {- mName.update([name = std::move(name)](auto& n) { n = std::move(name); });- mNameIsUpToDate.clear();- }-- std::string name() const { return mName.read(); }-- bool nameChanged() { return !mNameIsUpToDate.test_and_set(); }-- const Id& id() const { return mId; }-- Buffer<int16_t>* retainBuffer()- {- auto queueWriter = mQueue.writer();-- if (!mIsConnected || queueWriter.numRetainedSlots() > 0)- {- return nullptr;- }-- if (!queueWriter.retainSlot())- {- return nullptr;- }-- if (queueWriter[0]->mSamples.size() < mMaxNumSamples)- {- queueWriter.releaseSlot();- return retainBuffer();- }-- return queueWriter[0];- }-- void releaseAndCommitBuffer(const link::Timeline& timeline,- const Id& sessionId,- double beatsAtBufferBegin,- double quantum,- size_t numFrames,- size_t numChannels,- uint32_t sampleRate)- {- auto queueWriter = mQueue.writer();-- if (queueWriter.numRetainedSlots() > 0)- {- auto pBuffer = queueWriter[0];- const auto beginBeats =- globalBeatAtBeat(timeline, link::Beats{beatsAtBufferBegin}, link::Beats{quantum});- pBuffer->mBeginBeats = beginBeats;- pBuffer->mTempo = timeline.tempo;- pBuffer->mNumChannels = static_cast<uint32_t>(numChannels);- pBuffer->mSampleRate = sampleRate;- pBuffer->mNumFrames = static_cast<uint32_t>(numFrames);- pBuffer->mSessionId = sessionId;- queueWriter.releaseSlot();- }- }-- void releaseBuffer()- {- auto queueWriter = mQueue.writer();-- assert(queueWriter.numRetainedSlots() > 0);-- if (queueWriter.numRetainedSlots() > 0)- {- queueWriter[0]->mBeginBeats = link::Beats{0.};- queueWriter[0]->mTempo = link::Tempo{0};- queueWriter.releaseSlot();- }- }-- void requestMaxNumSamples(size_t numSamples) { mMaxNumSamples = numSamples; }-- size_t maxNumSamples() const { return mMaxNumSamples; }-- Buffer<int16_t>* buffer()- {- auto queueWriter = mQueue.writer();- return queueWriter.numRetainedSlots() > 0 ? queueWriter[0] : nullptr;- }-- Queue<Buffer<int16_t>>::Reader reader() { return mQueue.reader(); }-- void setIsConnected(bool isConnected) { mIsConnected = isConnected; }--private:- util::Locked<std::string> mName;- std::atomic_flag mNameIsUpToDate = ATOMIC_FLAG_INIT;- Id mId;- std::atomic<size_t> mMaxNumSamples;- Queue<Buffer<int16_t>> mQueue;- std::atomic<bool> mIsConnected;-};--} // namespace link_audio-} // namespace ableton
− link/include/ableton/link_audio/SinkProcessor.hpp
@@ -1,146 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- * This program is free software: you can redistribute it and/or modify- * it under the terms of the GNU General Public License as published by- * the Free Software Foundation, either version 2 of the License, or- * (at your option) any later version.- *- * This program is distributed in the hope that it will be useful,- * but WITHOUT ANY WARRANTY; without even the implied warranty of- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- * GNU General Public License for more details.- *- * You should have received a copy of the GNU General Public License- * along with this program. If not, see <http://www.gnu.org/licenses/>.- *- * If you would like to incorporate Link into a proprietary software application,- * please contact <link-devs@ableton.com>.- */--#pragma once--#include <ableton/link_audio/Encoder.hpp>-#include <ableton/link_audio/Id.hpp>-#include <ableton/link_audio/Receivers.hpp>-#include <ableton/link_audio/Sink.hpp>-#include <ableton/util/Injected.hpp>-#include <memory>-#include <string>--namespace ableton-{-namespace link_audio-{--template <typename GetSender, typename GetNodeId, typename IoContext>-struct SinkProcessor-{- SinkProcessor(util::Injected<IoContext> io,- std::shared_ptr<Sink> pSink,- util::Injected<GetSender> getSender,- util::Injected<GetNodeId> getNodeId)- : mpImpl(std::make_shared<Impl>(- std::move(io), pSink, std::move(getSender), std::move(getNodeId)))- {- }-- bool process() { return mpImpl->process(); }-- const Id& id() const { return mpImpl->id(); }-- std::string name() const { return mpImpl->name(); }-- bool nameChanged() { return mpImpl->nameChanged(); }-- template <typename Request>- void receiveChannelRequest(Request request, uint8_t ttl)- {- mpImpl->receiveChannelRequest(std::move(request), ttl);- }-- struct Impl : public std::enable_shared_from_this<Impl>- {- struct Sender- {- void operator()(const AudioBuffer& buffer)- {- auto end =- v1::audioBufferMessage((*mpImpl->mGetNodeId)(), buffer, mBuffer.begin());- try- {- mpImpl->mReceivers(mBuffer.data(), std::distance(mBuffer.begin(), end));- }- catch (const std::runtime_error& err)- {- debug(mpImpl->mIo->log()) << "Failed to send message: " << err.what();- }- }-- Impl* mpImpl;- std::array<uint8_t, v1::kMaxMessageSize> mBuffer{};- };-- Impl(util::Injected<IoContext> io,- std::shared_ptr<Sink> pSink,- util::Injected<GetSender> getSender,- util::Injected<GetNodeId> getNodeId)- : mIo(std::move(io))- , mpSink(pSink)- , mQueueReader(pSink->reader())- , mEncoder(util::injectVal(Sender{this}), mpSink->id())- , mReceivers(util::injectRef(*mIo), std::move(getSender))- , mGetNodeId(std::move(getNodeId))- {- }-- bool process()- {- if (mpSink.use_count() <= 1)- {- return false;- }-- while (mQueueReader.retainSlot())- {- if (!mReceivers.empty() && mQueueReader[0]->mTempo > link::Tempo{0})- {- mEncoder(*mQueueReader[0]);- }- if (mQueueReader[0]->mSamples.size() < mpSink->maxNumSamples())- {- mQueueReader[0]->mSamples.resize(mpSink->maxNumSamples());- }- mQueueReader.releaseSlot();- }-- return true;- }-- const Id& id() const { return mpSink->id(); }-- std::string name() const { return mpSink->name(); }-- bool nameChanged() { return mpSink->nameChanged(); }-- template <typename Request>- void receiveChannelRequest(Request request, uint8_t ttl)- {- mReceivers.receiveChannelRequest(std::move(request), ttl);-- mpSink->setIsConnected(!mReceivers.empty());- }-- private:- util::Injected<IoContext> mIo;- std::shared_ptr<Sink> mpSink;- Queue<Buffer<int16_t>>::Reader mQueueReader;- Encoder<Sender, int16_t> mEncoder;- Receivers<GetSender, IoContext> mReceivers;- util::Injected<GetNodeId> mGetNodeId;- };-- std::shared_ptr<Impl> mpImpl;-};--} // namespace link_audio-} // namespace ableton
− link/include/ableton/link_audio/Source.hpp
@@ -1,67 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- * This program is free software: you can redistribute it and/or modify- * it under the terms of the GNU General Public License as published by- * the Free Software Foundation, either version 2 of the License, or- * (at your option) any later version.- *- * This program is distributed in the hope that it will be useful,- * but WITHOUT ANY WARRANTY; without even the implied warranty of- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- * GNU General Public License for more details.- *- * You should have received a copy of the GNU General Public License- * along with this program. If not, see <http://www.gnu.org/licenses/>.- *- * If you would like to incorporate Link into a proprietary software application,- * please contact <link-devs@ableton.com>.- */--#pragma once--#include <ableton/link_audio/Buffer.hpp>-#include <ableton/link_audio/Id.hpp>-#include <ableton/link_audio/Queue.hpp>-#include <ableton/util/Locked.hpp>--#include <atomic>-#include <optional>--namespace ableton-{-namespace link_audio-{--static constexpr auto kSourceQueueSize = std::chrono::milliseconds(10000);--struct Source-{- using Callback = std::function<void(BufferCallbackHandle<Buffer<int16_t>>)>;-- Source(Id id, Callback callback)- : mId(std::move(id))- , mCallback(std::move(callback))- {- }-- const Id& id() const { return mId; }--- void setCallback(Callback newCallback)- {- mCallback.update([newCallback_ = std::move(newCallback)](auto& callback)- { callback = std::move(newCallback_); });- }-- void callback(BufferCallbackHandle<Buffer<int16_t>> buffer)- {- mCallback.update([&](auto& callback) { callback(buffer); });- }--private:- Id mId;- util::Locked<Callback> mCallback;-};--} // namespace link_audio-} // namespace ableton
− link/include/ableton/link_audio/SourceProcessor.hpp
@@ -1,159 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- * This program is free software: you can redistribute it and/or modify- * it under the terms of the GNU General Public License as published by- * the Free Software Foundation, either version 2 of the License, or- * (at your option) any later version.- *- * This program is distributed in the hope that it will be useful,- * but WITHOUT ANY WARRANTY; without even the implied warranty of- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- * GNU General Public License for more details.- *- * You should have received a copy of the GNU General Public License- * along with this program. If not, see <http://www.gnu.org/licenses/>.- *- * If you would like to incorporate Link into a proprietary software application,- * please contact <link-devs@ableton.com>.- */--#pragma once--#include <ableton/link_audio/ChannelAnnouncements.hpp>-#include <ableton/link_audio/ChannelRequests.hpp>-#include <ableton/link_audio/Id.hpp>-#include <ableton/link_audio/PCMCodec.hpp>-#include <ableton/link_audio/Source.hpp>-#include <ableton/link_audio/v1/Messages.hpp>-#include <ableton/util/Injected.hpp>-#include <optional>-#include <string>--namespace ableton-{-namespace link_audio-{--template <typename GetSender, typename GetNodeId, typename IoContext>-struct SourceProcessor-{- using Timer = typename util::Injected<IoContext>::type::Timer;- static constexpr uint8_t kTtl = 5;-- SourceProcessor(util::Injected<IoContext> io,- std::shared_ptr<Source> pSource,- util::Injected<GetSender> getSender,- util::Injected<GetNodeId> getNodeId)- : mpImpl(std::make_shared<Impl>(- std::move(io), pSource, std::move(getSender), std::move(getNodeId)))- {- mpImpl->sendAudioRequest();- }-- ~SourceProcessor()- {- if (mpImpl != nullptr)- {- mpImpl->sendChannelStopRequest();- }- }-- bool process() { return mpImpl->process(); }-- void receiveAudioBuffer(const AudioBuffer& buffer)- {- mpImpl->receiveAudioBuffer(buffer);- }-- const Id& id() const { return mpImpl->id(); }-- struct Impl : public std::enable_shared_from_this<Impl>- {- Impl(util::Injected<IoContext> io,- std::shared_ptr<Source> pSource,- util::Injected<GetSender> getSender,- util::Injected<GetNodeId> getNodeId)- : mTimer(io->makeTimer())- , mpSource(pSource)- , mGetSender(std::move(getSender))- , mGetNodeId(std::move(getNodeId))- , mBuffer(4096 * 2)- , mDecoder(util::injectVal(Callback{this}), 4096)- {- }-- template <typename Payload>- void sendMessage(const Payload& payload,- const v1::MessageType messageType,- const uint8_t ttl)- {- v1::MessageBuffer buffer;- const auto messageBegin = buffer.begin();- const auto messageEnd = v1::detail::encodeMessage(- (*mGetNodeId)(), ttl, messageType, payload, messageBegin);- const auto numBytes = static_cast<size_t>(std::distance(messageBegin, messageEnd));- auto oSender = mGetSender->forChannel(mpSource->id());- if (oSender)- {- try- {- (*oSender)(buffer.data(), numBytes);- }- catch (const std::runtime_error&)- {- }- }- }-- void sendAudioRequest()- {- mTimer.expires_from_now(std::chrono::seconds(kTtl));- mTimer.async_wait(- [this](const auto e)- {- if (!e)- {- sendAudioRequest();- }- });-- const auto request = ChannelRequest{(*mGetNodeId)(), mpSource->id()};- sendMessage(toPayload(request), v1::kChannelRequest, kTtl);- }-- void sendChannelStopRequest()- {- const auto stopRequest = ChannelStopRequest{(*mGetNodeId)(), mpSource->id()};- sendMessage(toPayload(stopRequest), v1::kStopChannelRequest, 0);- }-- bool process() { return mpSource.use_count() > 1; }-- void receiveAudioBuffer(const AudioBuffer& buffer) { mDecoder(buffer); }-- const Id& id() const { return mpSource->id(); }-- private:- struct Callback- {- void operator()(BufferCallbackHandle<Buffer<int16_t>> buffer)- {- pImpl->mpSource->callback(buffer);- }-- Impl* pImpl;- };-- Timer mTimer;- std::shared_ptr<Source> mpSource;- util::Injected<GetSender> mGetSender;- util::Injected<GetNodeId> mGetNodeId;- Buffer<int16_t> mBuffer;- PCMDecoder<int16_t, Callback> mDecoder;- };-- std::shared_ptr<Impl> mpImpl;-};--} // namespace link_audio-} // namespace ableton
− link/include/ableton/link_audio/UdpMessenger.hpp
@@ -1,617 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- * This program is free software: you can redistribute it and/or modify- * it under the terms of the GNU General Public License as published by- * the Free Software Foundation, either version 2 of the License, or- * (at your option) any later version.- *- * This program is distributed in the hope that it will be useful,- * but WITHOUT ANY WARRANTY; without even the implied warranty of- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- * GNU General Public License for more details.- *- * You should have received a copy of the GNU General Public License- * along with this program. If not, see <http://www.gnu.org/licenses/>.- *- * If you would like to incorporate Link into a proprietary software application,- * please contact <link-devs@ableton.com>.- */--#pragma once--#include <ableton/discovery/AsioTypes.hpp>-#include <ableton/discovery/UdpMessenger.hpp>-#include <ableton/discovery/UnicastIpInterface.hpp>-#include <ableton/link/PayloadEntries.hpp>-#include <ableton/link_audio/ChannelRequests.hpp>-#include <ableton/link_audio/NetworkMetrics.hpp>-#include <ableton/link_audio/v1/Messages.hpp>-#include <ableton/util/Injected.hpp>-#include <ableton/util/SafeAsyncHandler.hpp>-#include <algorithm>-#include <chrono>-#include <memory>-#include <optional>-#include <stdexcept>-#include <vector>--namespace ableton-{-namespace link_audio-{--// Throws UdpSendException-template <typename Interface, typename NodeId, typename Payload>-void sendLinkAudioUdpMessage(Interface& iface,- NodeId from,- const uint8_t ttl,- const v1::MessageType messageType,- const Payload& payload,- const discovery::UdpEndpoint& to)-{- using namespace std;- v1::MessageBuffer buffer;- const auto messageBegin = begin(buffer);- try- {- const auto messageEnd =- v1::detail::encodeMessage(std::move(from), ttl, messageType, payload, messageBegin);- const auto numBytes = static_cast<size_t>(distance(messageBegin, messageEnd));- iface.send(buffer.data(), numBytes, to);- }- catch (const std::runtime_error& err)- {- throw discovery::UdpSendException{err, iface.endpoint().address()};- }-}--// UdpMessenger uses a "shared_ptr pImpl" pattern to make it movable-// and to support safe async handler callbacks when receiving messages-// on the given interface.-template <typename ChannelsMessageHandler,- typename Interface,- typename Observer,- typename IoContext>-class UdpMessenger-{-public:- using ObserverType = typename util::Injected<Observer>::type;- using Announcement = typename ObserverType::GatewayObserverAnnouncement;- using NodeId = typename ObserverType::GatewayObserverNodeId;- using Timer = typename util::Injected<IoContext>::type::Timer;- using TimerError = typename Timer::ErrorCode;- using TimePoint = typename Timer::TimePoint;- using SharedInterface = std::shared_ptr<Interface>;-- struct ExtendedAnnouncement- {- link::NodeId ident() const { return announcement.ident(); }-- Announcement announcement;- double networkQuality;- SharedInterface pInterface;- discovery::UdpEndpoint from;- int ttl;- };-- UdpMessenger(util::Injected<ChannelsMessageHandler> handler,- SharedInterface pIface,- Announcement announcement,- util::Injected<IoContext> io,- const uint8_t ttl,- const uint8_t ttlRatio,- util::Injected<Observer> observer)- : mpImpl(std::make_shared<Impl>(std::move(handler),- std::move(pIface),- std::move(announcement),- std::move(io),- ttl,- ttlRatio,- std::move(observer)))- {- // We need to always listen for incoming traffic in order to- // respond to announcement broadcasts- mpImpl->listen();- mpImpl->broadcastAnnouncement();- }-- UdpMessenger(const UdpMessenger&) = delete;- UdpMessenger& operator=(const UdpMessenger&) = delete;-- UdpMessenger(UdpMessenger&& rhs)- : mpImpl(std::move(rhs.mpImpl))- {- }-- ~UdpMessenger()- {- if (mpImpl != nullptr)- {- mpImpl->mTimer.cancel();- mpImpl->sendAudioChannelByes({});- }- }-- void updateAnnouncement(Announcement announcement)- {- mpImpl->updateAnnouncement(std::move(announcement));- }-- discovery::UdpEndpoint endpoint() const { return mpImpl->mpInterface->endpoint(); }-- template <typename It>- void pruneChannelsEndpoints(It peersBegin, It peersEnd)- {- auto it = std::remove_if(- mpImpl->mReceivers.begin(),- mpImpl->mReceivers.end(),- [&](const auto& r)- {- return std::none_of(- peersBegin, peersEnd, [&](const auto& peerId) { return peerId == r.id; });- });-- mpImpl->mReceivers.erase(it, mpImpl->mReceivers.end());- }-- void sawLinkAudioEndpoint(link::NodeId peerId,- std::optional<discovery::UdpEndpoint> endpoint)- {- if (endpoint)- {- if (endpoint->address().is_v6())- {- *endpoint = discovery::ipV6Endpoint(*mpImpl->mpInterface, *endpoint);- }- auto it =- std::find_if(mpImpl->mReceivers.begin(),- mpImpl->mReceivers.end(),- [&](const auto& receiver) { return receiver.endpoint == endpoint; });- if (it == mpImpl->mReceivers.end())- {- mpImpl->mReceivers.push_back({peerId, *endpoint, {}});- }- }- else- {- auto it = std::remove_if(mpImpl->mReceivers.begin(),- mpImpl->mReceivers.end(),- [&](const auto& r) { return r.id == peerId; });-- mpImpl->mReceivers.erase(it, mpImpl->mReceivers.end());- }- }--private:- struct Receiver- {- link::NodeId id;- discovery::UdpEndpoint endpoint;- NetworkMetricsFilter metricsFilter;- };-- struct Impl : std::enable_shared_from_this<Impl>- {- Impl(util::Injected<ChannelsMessageHandler> handler,- SharedInterface pIface,- Announcement announcement,- util::Injected<IoContext> io,- const uint8_t ttl,- const uint8_t ttlRatio,- util::Injected<Observer> observer)- : mIo(std::move(io))- , mChannelsMessageHandler(std::move(handler))- , mpInterface(std::move(pIface))- , mTimer(mIo->makeTimer())- , mLastBroadcastTime{}- , mTtl(ttl)- , mTtlRatio(ttlRatio)- , mObserver(std::move(observer))- {- updateAnnouncement(std::move(announcement));- }-- void sendAudioChannelByes(const ChannelAnnouncements& newAnnouncements)- {- auto channelByes = ChannelByes{};- for (const auto& announcement : mAnnouncements)- {- for (const auto& channel : announcement.channels.channels)- {- if (std::none_of(newAnnouncements.channels.begin(),- newAnnouncements.channels.end(),- [&](const auto& c) { return c.id == channel.id; }))- {- channelByes.byes.push_back({channel.id});- }- }- }-- if (channelByes.byes.size() > 0)- {- auto byesToSend = std::vector<ChannelByes>{{}};-- for (const auto& bye : channelByes.byes)- {- auto addedSize = sizeInByteStream(bye);- if (sizeInByteStream(byesToSend.back()) + addedSize > v1::kMaxPayloadSize)- {- byesToSend.emplace_back();- }- byesToSend.back().byes.push_back(bye);- }-- for (const auto& receiver : mReceivers)- {- for (const auto& byes : byesToSend)- {- try- {- sendLinkAudioUdpMessage(*mpInterface,- mAnnouncements.back().ident(),- mTtl,- v1::kChannelByes,- discovery::makePayload(byes),- receiver.endpoint);- }- catch (const discovery::UdpSendException&)- {- }- }- }- }- }-- void updateAnnouncement(Announcement announcement)- {- sendAudioChannelByes(announcement.channels);- const auto pingPayload = discovery::makePayload(link::HostTime{});- const auto pingSize = sizeInByteStream(pingPayload);- mAnnouncements = {Announcement{- announcement.nodeId, announcement.sessionId, announcement.peerInfo, {}}};-- for (const auto& channel : announcement.channels.channels)- {- const auto channelSize = sizeInByteStream(channel);- // A ping is sent along with the first announcement- auto addedSize =- mAnnouncements.size() == 1 ? channelSize + pingSize : channelSize;- if (sizeInByteStream(toPayload(mAnnouncements.back())) + addedSize- > v1::kMaxPayloadSize)- {- mAnnouncements.push_back(Announcement{- announcement.nodeId, announcement.sessionId, announcement.peerInfo, {}});- }- mAnnouncements.back().channels.channels.push_back(channel);- }- }-- void broadcastAnnouncement()- {- using namespace std::chrono;-- const auto minBroadcastPeriod = milliseconds{50};- const auto nominalBroadcastPeriod = milliseconds(mTtl * 1000 / mTtlRatio);- const auto timeSinceLastBroadcast =- duration_cast<milliseconds>(mTimer.now() - mLastBroadcastTime);-- // The rate is limited to maxBroadcastRate to prevent flooding the network.- const auto delay = minBroadcastPeriod - timeSinceLastBroadcast;-- // Schedule the next broadcast before we actually send the- // message so that if sending throws an exception we are still- // scheduled to try again. We want to keep trying at our- // interval as long as this instance is alive.- mTimer.expires_from_now(delay > milliseconds{0} ? delay : nominalBroadcastPeriod);- mTimer.async_wait(- [this](const TimerError e)- {- if (!e)- {- broadcastAnnouncement();- }- });-- // // If we're not delaying, broadcast now- if (delay < milliseconds{1})- {- debug(mIo->log()) << "Broadcasting Announcement";- sendAnnouncement();- }- }-- void sendAnnouncement()- {- const auto pingTime = std::chrono::duration_cast<std::chrono::microseconds>(- mTimer.now().time_since_epoch());- for (auto& receiver : mReceivers)- {- try- {- // Send one ping per receiver- auto shouldSendPing = true;- for (const auto& announcement : mAnnouncements)- {- if (shouldSendPing)- {- const auto hostTime = link::HostTime{pingTime};- sendLinkAudioUdpMessage(- *mpInterface,- announcement.ident(),- mTtl,- v1::kPeerAnnouncement,- toPayload(announcement) + discovery::makePayload(hostTime),- receiver.endpoint);- shouldSendPing = false;- }- else- {- sendLinkAudioUdpMessage(*mpInterface,- announcement.ident(),- mTtl,- v1::kPeerAnnouncement,- toPayload(announcement),- receiver.endpoint);- }- }- }- catch (const discovery::UdpSendException&)- {- }- }- mLastBroadcastTime = mTimer.now();- }-- void listen() { mpInterface->receive(util::makeAsyncSafe(this->shared_from_this())); }-- template <typename It>- void operator()(const discovery::UdpEndpoint& from,- const It messageBegin,- const It messageEnd)- {- auto result = v1::parseMessageHeader(messageBegin, messageEnd);-- const auto& header = result.first;- // Ignore messages from self and other groups- if (header.ident != mAnnouncements.front().ident() && header.groupId == 0)- {- debug(mIo->log()) << "Received message type "- << static_cast<int>(header.messageType) << " from peer "- << header.ident;-- switch (header.messageType)- {- case v1::kPeerAnnouncement:- receiveAnnouncement(std::move(result.first), result.second, messageEnd, from);- receivePing(result.second, messageEnd, from);- break;- case v1::kChannelByes:- receiveChannelByes(result.second, messageEnd);- break;- case v1::kPong:- receivePong(result.second, messageEnd, from);- break;- case v1::kChannelRequest:- receiveChannelRequest(std::move(result.first), result.second, messageEnd);- break;- case v1::kStopChannelRequest:- receiveChannelStopRequest(std::move(result.first), result.second, messageEnd);- break;- case v1::kAudioBuffer:- receiveAudioBuffer(std::move(result.first), result.second, messageEnd);- break;- default:- info(mIo->log()) << "Unknown message received of type: " << header.messageType;- }- }- listen();- }-- template <typename It>- void receivePing(It payloadBegin, It payloadEnd, discovery::UdpEndpoint from)- {- std::optional<std::chrono::microseconds> oHostTime;- discovery::parsePayload<link::HostTime>(payloadBegin,- payloadEnd,- [&oHostTime](link::HostTime ht)- { oHostTime = std::move(ht.time); });-- if (oHostTime)- {- try- {- sendLinkAudioUdpMessage(*mpInterface,- mAnnouncements.front().ident(),- mTtl,- v1::kPong,- discovery::makePayload(link::HostTime{*oHostTime}),- from);- }- catch (const std::runtime_error& err)- {- return;- }- }- }-- template <typename It>- void receivePong(It payloadBegin, It payloadEnd, discovery::UdpEndpoint from)- {- const auto receiveTime = std::chrono::duration_cast<std::chrono::microseconds>(- mTimer.now().time_since_epoch());- std::chrono::microseconds sendTime{0};-- try- {- discovery::parsePayload<link::HostTime>(payloadBegin,- payloadEnd,- [&sendTime](link::HostTime ht)- { sendTime = std::move(ht.time); });-- auto it =- std::find_if(mReceivers.begin(),- mReceivers.end(),- [&](const auto& receiver) { return receiver.endpoint == from; });- if (it != mReceivers.end())- {- it->metricsFilter(receiveTime - sendTime);- }- }- catch (const std::runtime_error& err)- {- return;- }- }-- template <typename It>- void receiveAnnouncement(v1::MessageHeader header,- It payloadBegin,- It payloadEnd,- discovery::UdpEndpoint from)- {- const auto it =- std::find_if(mReceivers.begin(),- mReceivers.end(),- [&](const auto& receiver) { return receiver.endpoint == from; });-- if (it != mReceivers.end())- {- try- {- auto announcement = Announcement::fromPayload(- std::move(header.ident), std::move(payloadBegin), std::move(payloadEnd));-- sawAnnouncement(*mObserver,- ExtendedAnnouncement{std::move(announcement),- it->metricsFilter.metrics().quality(),- mpInterface,- from,- mTtl});- }- catch (const std::runtime_error& err)- {- info(mIo->log()) << "Ignoring peer announcement message: " << err.what();- }- }- }-- template <typename It>- void receiveChannelByes(It payloadBegin, It payloadEnd)- {- auto byes = ChannelByes{};- discovery::parsePayload<ChannelByes>(- payloadBegin, payloadEnd, [&](const auto& b) { byes = std::move(b); });-- std::vector<NodeId> byesVector;- for (const auto& bye : byes.byes)- {- byesVector.push_back(bye.id);- }-- channelsLeft(*mObserver, begin(byesVector), end(byesVector));- }-- template <typename It>- void receiveChannelRequest(v1::MessageHeader header, It payloadBegin, It payloadEnd)- {- try- {- auto request = ChannelRequest::fromPayload(- std::move(header.ident), std::move(payloadBegin), std::move(payloadEnd));- mChannelsMessageHandler->receiveChannelRequest(request, header.ttl);- }- catch (const std::runtime_error& err)- {- info(mIo->log()) << "Ignoring AudioRequest message: " << err.what();- }- }-- template <typename It>- void receiveChannelStopRequest(v1::MessageHeader header,- It payloadBegin,- It payloadEnd)- {- try- {- auto stopRequest = ChannelStopRequest::fromPayload(- std::move(header.ident), std::move(payloadBegin), std::move(payloadEnd));- mChannelsMessageHandler->receiveChannelRequest(stopRequest, header.ttl);- }- catch (const std::runtime_error& err)- {- info(mIo->log()) << "Ignoring ChannelStopRequest message: " << err.what();- }- }-- template <typename It>- void receiveAudioBuffer(v1::MessageHeader header, It payloadBegin, It payloadEnd)- {- try- {- mChannelsMessageHandler->receiveAudioBuffer(payloadBegin, payloadEnd);- }- catch (const std::runtime_error& err)- {- info(mIo->log()) << "Ignoring AudioBuffer message: " << err.what();- }- }-- util::Injected<IoContext> mIo;- util::Injected<ChannelsMessageHandler> mChannelsMessageHandler;- SharedInterface mpInterface;- std::vector<Announcement> mAnnouncements;- Timer mTimer;- TimePoint mLastBroadcastTime;- uint8_t mTtl;- uint8_t mTtlRatio;- util::Injected<Observer> mObserver;- std::vector<Receiver> mReceivers;- };-- std::shared_ptr<Impl> mpImpl;-};--template <typename IoContext>-using MessengerInterface =- UnicastIpInterface<typename util::Injected<IoContext>::type&, v1::kMaxMessageSize>;-template <typename IoContext>-using MessengerInterface = MessengerInterface<IoContext>;-template <typename ChannelsMessageHandler, typename Observer, typename IoContext>-using Messenger = UdpMessenger<ChannelsMessageHandler,- MessengerInterface<IoContext>,- Observer,- IoContext>;-template <typename ChannelsMessageHandler, typename Observer, typename IoContext>-using MessengerPtr =- std::shared_ptr<Messenger<ChannelsMessageHandler, Observer, IoContext>>;--// Factory function-template <typename ChannelsMessageHandler,- typename Announcement,- typename IoContext,- typename Observer>-MessengerPtr<ChannelsMessageHandler, Observer, IoContext> makeMessengerPtr(- util::Injected<ChannelsMessageHandler> handler,- util::Injected<IoContext> io,- const discovery::IpAddress& addr,- util::Injected<Observer> observer,- Announcement announcement)-{- const uint8_t ttl = 5;- const uint8_t ttlRatio = 20;-- auto pIface =- makeSharedUnicastIpInterface<v1::kMaxMessageSize>(util::injectRef(*io), addr);-- return std::make_shared<Messenger<ChannelsMessageHandler, Observer, IoContext>>(- std::move(handler),- pIface,- std::move(announcement),- std::move(io),- ttl,- ttlRatio,- std::move(observer));-}--} // namespace link_audio-} // namespace ableton
− link/include/ableton/link_audio/v1/Messages.hpp
@@ -1,170 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- * This program is free software: you can redistribute it and/or modify- * it under the terms of the GNU General Public License as published by- * the Free Software Foundation, either version 2 of the License, or- * (at your option) any later version.- *- * This program is distributed in the hope that it will be useful,- * but WITHOUT ANY WARRANTY; without even the implied warranty of- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- * GNU General Public License for more details.- *- * You should have received a copy of the GNU General Public License- * along with this program. If not, see <http://www.gnu.org/licenses/>.- *- * If you would like to incorporate Link into a proprietary software application,- * please contact <link-devs@ableton.com>.- */--#pragma once--#include <ableton/discovery/Payload.hpp>-#include <ableton/link/NodeId.hpp>-#include <array>--namespace ableton-{-namespace link_audio-{-namespace v1-{--// To define the maximum message size, we need to consider the maximum transmission unit-// (MTU) of the network and the IP and UDP header sizes. To avoid fragmentation, the-// message size should be smaller than the MTU. For IPv4 ethernet networks the standard is-// 1500 bytes and for IPv6 it's 1280 bytes. The IPv4 header can be extended to 60 bytes-// while the IPv6 header is fixed at 40 bytes. The UPD header's size is 8 bytes.-static constexpr std::size_t kMaxMessageSize = 1200;-static constexpr std::size_t kHeaderSize = 24;-static constexpr std::size_t kMaxPayloadSize = kMaxMessageSize - kHeaderSize;-static constexpr std::size_t kMaxNameSize = 256;-// Utility typedef for an array of bytes of maximum message size-using MessageBuffer = std::array<uint8_t, v1::kMaxMessageSize>;--using MessageType = uint8_t;-using SessionGroupId = uint16_t;--const MessageType kInvalid = 0;-const MessageType kPeerAnnouncement = 1;-const MessageType kChannelByes = 2;-const MessageType kPong = 3;-const MessageType kChannelRequest = 4;-const MessageType kStopChannelRequest = 5;-const MessageType kAudioBuffer = 6;--struct MessageHeader-{- MessageType messageType;- uint8_t ttl;- SessionGroupId groupId;- link::NodeId ident;-- friend std::uint32_t sizeInByteStream(const MessageHeader& header)- {- return discovery::sizeInByteStream(header.messageType)- + discovery::sizeInByteStream(header.ttl)- + discovery::sizeInByteStream(header.groupId)- + discovery::sizeInByteStream(header.ident);- }-- template <typename It>- friend It toNetworkByteStream(const MessageHeader& header, It out)- {- return discovery::toNetworkByteStream(- header.ident,- discovery::toNetworkByteStream(- header.groupId,- discovery::toNetworkByteStream(- header.ttl,- discovery::toNetworkByteStream(header.messageType, std::move(out)))));- }-- template <typename It>- static std::pair<MessageHeader, It> fromNetworkByteStream(It begin, const It end)- {- using namespace std;-- MessageHeader header;- tie(header.messageType, begin) =- discovery::Deserialize<decltype(header.messageType)>::fromNetworkByteStream(- begin, end);- tie(header.ttl, begin) =- discovery::Deserialize<decltype(header.ttl)>::fromNetworkByteStream(begin, end);- tie(header.groupId, begin) =- discovery::Deserialize<decltype(header.groupId)>::fromNetworkByteStream(begin, end);- tie(header.ident, begin) =- discovery::Deserialize<decltype(header.ident)>::fromNetworkByteStream(begin, end);-- return make_pair(std::move(header), std::move(begin));- }-};--namespace detail-{--// Types that are only used in the sending/parsing of messages, not-// publicly exposed.-using ProtocolHeader = std::array<char, 8>;-const ProtocolHeader kProtocolHeader = {{'c', 'h', 'n', 'n', 'l', 's', 'v', 1}};--// Must have at least kMaxMessageSize bytes available in the output stream-template <typename Payload, typename It>-It encodeMessage(link::NodeId from,- const uint8_t ttl,- const MessageType messageType,- const Payload& payload,- It out)-{- using namespace std;- const MessageHeader header = {messageType, ttl, 0, std::move(from)};- const auto messageSize =- kProtocolHeader.size() + sizeInByteStream(header) + sizeInByteStream(payload);-- if (messageSize <= kMaxMessageSize)- {- return toNetworkByteStream(- payload,- toNetworkByteStream(- header, copy(begin(kProtocolHeader), end(kProtocolHeader), std::move(out))));- }- else- {- throw range_error("Exceeded maximum message size");- }-}--} // namespace detail--template <typename Payload, typename It>-It audioBufferMessage(link::NodeId from, const Payload& payload, It out)-{- return detail::encodeMessage(std::move(from), 0, kAudioBuffer, payload, std::move(out));-}--template <typename It>-std::pair<MessageHeader, It> parseMessageHeader(It bytesBegin, const It bytesEnd)-{- using namespace std;- using ItDiff = typename iterator_traits<It>::difference_type;-- MessageHeader header = {};- const auto protocolHeaderSize = discovery::sizeInByteStream(detail::kProtocolHeader);- const auto minMessageSize =- static_cast<ItDiff>(protocolHeaderSize + sizeInByteStream(header));-- // If there are enough bytes in the stream to make a header and if- // the first bytes in the stream are the protocol header, then- // proceed to parse the stream.- if (distance(bytesBegin, bytesEnd) >= minMessageSize- && equal(begin(detail::kProtocolHeader), end(detail::kProtocolHeader), bytesBegin))- {- tie(header, bytesBegin) =- MessageHeader::fromNetworkByteStream(bytesBegin + protocolHeaderSize, bytesEnd);- }- return make_pair(std::move(header), std::move(bytesBegin));-}--} // namespace v1-} // namespace link_audio-} // namespace ableton
link/include/ableton/platforms/Config.hpp view
@@ -20,7 +20,6 @@ #pragma once #include <ableton/link/Controller.hpp>-#include <ableton/link/SessionController.hpp> #include <ableton/util/Log.hpp> #if defined(LINK_PLATFORM_WINDOWS)@@ -28,7 +27,9 @@ #include <ableton/platforms/stl/Random.hpp> #include <ableton/platforms/windows/Clock.hpp> #include <ableton/platforms/windows/ScanIpIfAddrs.hpp>+#if defined(LINK_WINDOWS_SETTHREADDESCRIPTION) #include <ableton/platforms/windows/ThreadFactory.hpp>+#endif #elif defined(LINK_PLATFORM_MACOSX) #include <ableton/platforms/asio/Context.hpp> #include <ableton/platforms/darwin/Clock.hpp>@@ -46,7 +47,6 @@ #elif defined(ESP_PLATFORM) #include <ableton/platforms/esp32/Clock.hpp> #include <ableton/platforms/esp32/Context.hpp>-#include <ableton/platforms/esp32/Log.hpp> #include <ableton/platforms/esp32/Random.hpp> #include <ableton/platforms/esp32/ScanIpIfAddrs.hpp> #endif@@ -61,36 +61,31 @@ #if defined(LINK_PLATFORM_WINDOWS) using Clock = platforms::windows::Clock; using Random = platforms::stl::Random;-using ThreadPriority = platforms::windows::ThreadPriority; #if defined(LINK_WINDOWS_SETTHREADDESCRIPTION) using IoContext = platforms::LINK_ASIO_NAMESPACE::Context<platforms::windows::ScanIpIfAddrs,- util::NullLog,- platforms::windows::ThreadFactory>;+ util::NullLog,+ platforms::windows::ThreadFactory>; #else using IoContext = platforms::LINK_ASIO_NAMESPACE::Context<platforms::windows::ScanIpIfAddrs,- util::NullLog>;+ util::NullLog>; #endif #elif defined(LINK_PLATFORM_MACOSX) using Clock = platforms::darwin::Clock;-using IoContext =- platforms::LINK_ASIO_NAMESPACE::Context<platforms::posix::ScanIpIfAddrs,- util::NullLog,- platforms::darwin::ThreadFactory>;+using IoContext = platforms::LINK_ASIO_NAMESPACE::Context<platforms::posix::ScanIpIfAddrs,+ util::NullLog,+ platforms::darwin::ThreadFactory>; using Random = platforms::stl::Random;-using ThreadPriority = platforms::darwin::ThreadPriority; #elif defined(LINK_PLATFORM_LINUX) using Clock = platforms::linux_::ClockMonotonicRaw; using Random = platforms::stl::Random;-using ThreadPriority = platforms::linux_::ThreadPriority; #ifdef __linux__-using IoContext =- platforms::LINK_ASIO_NAMESPACE::Context<platforms::posix::ScanIpIfAddrs,- util::NullLog,- platforms::linux_::ThreadFactory>;+using IoContext = platforms::LINK_ASIO_NAMESPACE::Context<platforms::posix::ScanIpIfAddrs,+ util::NullLog,+ platforms::linux_::ThreadFactory>; #else using IoContext = platforms::LINK_ASIO_NAMESPACE::Context<platforms::posix::ScanIpIfAddrs, util::NullLog>;
link/include/ableton/platforms/asio/AsioTimer.hpp view
@@ -43,7 +43,7 @@ public: using ErrorCode = ::LINK_ASIO_NAMESPACE::error_code; using TimePoint = std::chrono::system_clock::time_point;- using IoService = ::LINK_ASIO_NAMESPACE::io_context;+ using IoService = ::LINK_ASIO_NAMESPACE::io_service; using SystemTimer = ::LINK_ASIO_NAMESPACE::system_timer; @@ -82,18 +82,15 @@ template <typename T> void expires_from_now(T duration) {- mpTimer->expires_after(std::move(duration));+ mpTimer->expires_from_now(std::move(duration)); } - void cancel()+ ErrorCode cancel() {- try- {- mpTimer->cancel();- }- catch (...)- {- }+ ErrorCode ec;+ mpTimer->cancel(ec);+ mpAsyncHandler->mpHandler = nullptr;+ return ec; } template <typename Handler>@@ -103,7 +100,10 @@ mpTimer->async_wait(util::makeAsyncSafe(mpAsyncHandler)); } - TimePoint now() const { return std::chrono::system_clock::now(); }+ TimePoint now() const+ {+ return std::chrono::system_clock::now();+ } private: struct AsyncHandler
link/include/ableton/platforms/asio/AsioWrapper.hpp view
@@ -36,8 +36,8 @@ #pragma push_macro("ASIO_NO_TYPEID") #define ASIO_NO_TYPEID 1-#define asio link_asio_1_36_0-#define LINK_ASIO_NAMESPACE link_asio_1_36_0+#define asio link_asio_1_28_0+#define LINK_ASIO_NAMESPACE link_asio_1_28_0 #define ASIO_STANDALONE 1 #endif
link/include/ableton/platforms/asio/Context.hpp view
@@ -23,15 +23,9 @@ #include <ableton/platforms/asio/AsioTimer.hpp> #include <ableton/platforms/asio/LockFreeCallbackDispatcher.hpp> #include <ableton/platforms/asio/Socket.hpp>-#include <memory> #include <thread> #include <utility> -#if defined(__linux__)-#include <netinet/in.h>-#include <sys/socket.h>-#endif- namespace ableton { namespace platforms@@ -65,8 +59,8 @@ template <std::size_t BufferSize> using Socket = Socket<BufferSize>;- using IoService = ::LINK_ASIO_NAMESPACE::io_context;- using Work = ::LINK_ASIO_NAMESPACE::executor_work_guard<IoService::executor_type>;+ using IoService = ::LINK_ASIO_NAMESPACE::io_service;+ using Work = IoService::work; Context() : Context(DefaultHandler{})@@ -76,12 +70,10 @@ template <typename ExceptionHandler> explicit Context(ExceptionHandler exceptHandler) : mpService(new IoService())- , mpWork(new Work(mpService->get_executor()))+ , mpWork(new Work(*mpService)) {- mThread = ThreadFactoryT::makeThread(- "Link Main",- [](IoService& service, ExceptionHandler handler)- {+ mThread = ThreadFactoryT::makeThread("Link Main",+ [](IoService& service, ExceptionHandler handler) { for (;;) { try@@ -95,8 +87,7 @@ } } },- std::ref(*mpService),- std::move(exceptHandler));+ std::ref(*mpService), std::move(exceptHandler)); } Context(const Context&) = delete;@@ -131,21 +122,19 @@ template <std::size_t BufferSize>- Socket<BufferSize> openUnicastSocket(const discovery::IpAddress addr, uint16_t port = 0)+ Socket<BufferSize> openUnicastSocket(const discovery::IpAddress addr) { auto socket = addr.is_v4() ? Socket<BufferSize>{*mpService, ::LINK_ASIO_NAMESPACE::ip::udp::v4()} : Socket<BufferSize>{*mpService, ::LINK_ASIO_NAMESPACE::ip::udp::v6()}; socket.mpImpl->mSocket.set_option( ::LINK_ASIO_NAMESPACE::ip::multicast::enable_loopback(addr.is_loopback()));- socket.mpImpl->mSocket.set_option(- ::LINK_ASIO_NAMESPACE::ip::udp::socket::reuse_address(true)); if (addr.is_v4()) { socket.mpImpl->mSocket.set_option( ::LINK_ASIO_NAMESPACE::ip::multicast::outbound_interface(addr.to_v4())); socket.mpImpl->mSocket.bind(- ::LINK_ASIO_NAMESPACE::ip::udp::endpoint{addr.to_v4(), port});+ ::LINK_ASIO_NAMESPACE::ip::udp::endpoint{addr.to_v4(), 0}); } else if (addr.is_v6()) {@@ -154,7 +143,7 @@ ::LINK_ASIO_NAMESPACE::ip::multicast::outbound_interface( static_cast<unsigned int>(scopeId))); socket.mpImpl->mSocket.bind(- ::LINK_ASIO_NAMESPACE::ip::udp::endpoint{addr.to_v6(), port});+ ::LINK_ASIO_NAMESPACE::ip::udp::endpoint{addr.to_v6(), 0}); } else {@@ -179,22 +168,10 @@ if (addr.is_v4()) {-#if defined(__linux__) && defined(IP_MULTICAST_ALL)- const int disableAll = 0;- if (::setsockopt(socket.mpImpl->mSocket.native_handle(),- IPPROTO_IP,- IP_MULTICAST_ALL,- &disableAll,- sizeof(disableAll))- != 0)- {- throw std::runtime_error("Failed to set IP_MULTICAST_ALL");- }-#endif socket.mpImpl->mSocket.set_option( ::LINK_ASIO_NAMESPACE::ip::multicast::outbound_interface(addr.to_v4())); socket.mpImpl->mSocket.bind({::LINK_ASIO_NAMESPACE::ip::address_v4::any(),- discovery::multicastEndpointV4().port()});+ discovery::multicastEndpointV4().port()}); socket.mpImpl->mSocket.set_option(::LINK_ASIO_NAMESPACE::ip::multicast::join_group( discovery::multicastEndpointV4().address().to_v4(), addr.to_v4())); }@@ -217,16 +194,25 @@ return socket; } - std::vector<discovery::IpAddress> scanNetworkInterfaces() { return mScanIpIfAddrs(); }+ std::vector<discovery::IpAddress> scanNetworkInterfaces()+ {+ return mScanIpIfAddrs();+ } - Timer makeTimer() const { return {*mpService}; }+ Timer makeTimer() const+ {+ return {*mpService};+ } - Log& log() { return mLog; }+ Log& log()+ {+ return mLog;+ } template <typename Handler> void async(Handler handler) {- ::LINK_ASIO_NAMESPACE::post(*mpService, std::move(handler));+ mpService->post(std::move(handler)); } private:@@ -239,11 +225,13 @@ { }; - void operator()(const Exception&) {}+ void operator()(const Exception&)+ {+ } }; - std::unique_ptr<IoService> mpService;- std::unique_ptr<Work> mpWork;+ std::unique_ptr<::LINK_ASIO_NAMESPACE::io_service> mpService;+ std::unique_ptr<::LINK_ASIO_NAMESPACE::io_service::work> mpWork; std::thread mThread; Log mLog; ScanIpIfAddrs mScanIpIfAddrs;
link/include/ableton/platforms/asio/LockFreeCallbackDispatcher.hpp view
@@ -46,33 +46,22 @@ : mCallback(std::move(callback)) , mFallbackPeriod(std::move(fallbackPeriod)) , mRunning(true)+ , mThread(ThreadFactory::makeThread("Link Dispatcher", [this] { run(); })) { } - ~LockFreeCallbackDispatcher() { stop(); }-- void start()+ ~LockFreeCallbackDispatcher() {- mThread = ThreadFactory::makeThread("Link Dispatcher", [this] { run(); });+ mRunning = false;+ mCondition.notify_one();+ mThread.join(); } - void stop()+ void invoke() {- const auto wasRunning = mRunning.exchange(false);- if (!wasRunning)- {- return;- }- mCondition.notify_one();- if (mThread.joinable())- {- mThread.join();- } } - void invoke() { mCondition.notify_one(); }- private: void run() {@@ -82,12 +71,6 @@ std::unique_lock<std::mutex> lock(mMutex); mCondition.wait_for(lock, mFallbackPeriod); }-- if (!mRunning.load())- {- break;- }- mCallback(); } }
link/include/ableton/platforms/asio/Socket.hpp view
@@ -34,7 +34,7 @@ template <std::size_t MaxPacketSize> struct Socket {- Socket(::LINK_ASIO_NAMESPACE::io_context& io, ::LINK_ASIO_NAMESPACE::ip::udp protocol)+ Socket(::LINK_ASIO_NAMESPACE::io_service& io, ::LINK_ASIO_NAMESPACE::ip::udp protocol) : mpImpl(std::make_shared<Impl>(io, protocol)) { }@@ -47,11 +47,10 @@ { } - std::size_t send(const uint8_t* const pData,- const size_t numBytes,- const discovery::UdpEndpoint& to)+ std::size_t send(+ const uint8_t* const pData, const size_t numBytes, const discovery::UdpEndpoint& to) {- assert(numBytes <= MaxPacketSize);+ assert(numBytes < MaxPacketSize); return mpImpl->mSocket.send_to(::LINK_ASIO_NAMESPACE::buffer(pData, numBytes), to); } @@ -61,15 +60,17 @@ mpImpl->mHandler = std::move(handler); mpImpl->mSocket.async_receive_from( ::LINK_ASIO_NAMESPACE::buffer(mpImpl->mReceiveBuffer, MaxPacketSize),- mpImpl->mSenderEndpoint,- util::makeAsyncSafe(mpImpl));+ mpImpl->mSenderEndpoint, util::makeAsyncSafe(mpImpl)); } - discovery::UdpEndpoint endpoint() const { return mpImpl->mSocket.local_endpoint(); }+ discovery::UdpEndpoint endpoint() const+ {+ return mpImpl->mSocket.local_endpoint();+ } struct Impl {- Impl(::LINK_ASIO_NAMESPACE::io_context& io, ::LINK_ASIO_NAMESPACE::ip::udp protocol)+ Impl(::LINK_ASIO_NAMESPACE::io_service& io, ::LINK_ASIO_NAMESPACE::ip::udp protocol) : mSocket(io, protocol) { }@@ -83,8 +84,8 @@ mSocket.close(ec); } - void operator()(const ::LINK_ASIO_NAMESPACE::error_code& error,- const std::size_t numBytes)+ void operator()(+ const ::LINK_ASIO_NAMESPACE::error_code& error, const std::size_t numBytes) { if (!error && numBytes > 0 && numBytes <= MaxPacketSize) {
link/include/ableton/platforms/darwin/Clock.hpp view
@@ -55,9 +55,15 @@ return static_cast<Ticks>(micros.count() / mTicksToMicros); } - Ticks ticks() const { return mach_absolute_time(); }+ Ticks ticks() const+ {+ return mach_absolute_time();+ } - std::chrono::microseconds micros() const { return ticksToMicros(ticks()); }+ std::chrono::microseconds micros() const+ {+ return ticksToMicros(ticks());+ } double mTicksToMicros; };
link/include/ableton/platforms/darwin/ThreadFactory.hpp view
@@ -19,9 +19,6 @@ #pragma once -#include <mach/mach.h>-#include <mach/mach_time.h>-#include <optional> #include <pthread.h> #include <thread> #include <utility>@@ -33,98 +30,16 @@ namespace darwin { -struct ThreadPriority-{- // Captures the current thread priority and sets the thread priority to high.- // Noop if there is already a captured priority- void setHigh()- {- if (!moOriginal)- {- capture();- }-- mach_timebase_info_data_t info;- mach_timebase_info(&info);- const auto machRatio =- static_cast<double>(info.denom) / static_cast<double>(info.numer);- const auto millisecond = machRatio * 1000000;-- struct thread_time_constraint_policy policy;-- // The nominal time interval between the beginnings of two consecutive duty cycles. It- // defines how often the thread expects to run. A nonzero value specifies the thread's- // periodicity.- policy.period =- static_cast<uint32_t>(millisecond * 1); // link_audio::MainController's timer period-- // The amount of CPU time the thread needs during each period. This is the actual- // execution time required per cycle. Needs to be less or equal to the period.- policy.computation = static_cast<uint32_t>(millisecond * 0.2);-- // The maximum real time that may elapse from the start of a period to the end of- // computation. This sets an upper bound on the allowed delay for completing the- // computation. It cannot be less than computation.- policy.constraint = static_cast<uint32_t>(millisecond * 1);-- // A boolean value indicating whether the thread's computation can be interrupted- // (preempted) by other threads. If set to 1, the thread can be preempted; if 0, it- // should run to completion within its constraint.- policy.preemptible = 1;-- thread_policy_set(mach_thread_self(),- THREAD_TIME_CONSTRAINT_POLICY,- reinterpret_cast<thread_policy_t>(&policy),- THREAD_TIME_CONSTRAINT_POLICY_COUNT);- }-- // Resets the thread priority to the previously captured priority.- // Noop if there is no captured thread priority- void reset()- {- if (moOriginal)- {- thread_policy_set(mach_thread_self(),- THREAD_TIME_CONSTRAINT_POLICY,- reinterpret_cast<thread_policy_t>(&*moOriginal),- THREAD_TIME_CONSTRAINT_POLICY_COUNT);- moOriginal = std::nullopt;- }- }--private:- void capture()- {- thread_time_constraint_policy_data_t policy{};- mach_msg_type_number_t count = THREAD_TIME_CONSTRAINT_POLICY_COUNT;- boolean_t getDefault = false;- const auto result = thread_policy_get(mach_thread_self(),- THREAD_TIME_CONSTRAINT_POLICY,- reinterpret_cast<thread_policy_t>(&policy),- &count,- &getDefault);- if (result == KERN_SUCCESS)- {- moOriginal = policy;- }- }-- std::optional<thread_time_constraint_policy_data_t> moOriginal;-};- struct ThreadFactory { template <typename Callable, typename... Args> static std::thread makeThread(std::string name, Callable&& f, Args&&... args) {- return std::thread{[](std::string name, Callable&& f, Args&&... args)- {+ return std::thread{[](std::string name, Callable&& f, Args&&... args) { pthread_setname_np(name.c_str()); f(args...); },- std::move(name),- std::forward<Callable>(f),- std::forward<Args>(args)...};+ std::move(name), std::forward<Callable>(f), std::forward<Args>(args)...}; } };
link/include/ableton/platforms/esp32/Context.hpp view
@@ -24,6 +24,7 @@ #include <ableton/platforms/asio/AsioTimer.hpp> #include <ableton/platforms/asio/Socket.hpp> #include <ableton/platforms/esp32/LockFreeCallbackDispatcher.hpp>+#include <driver/gptimer.h> #include <freertos/FreeRTOS.h> #include <freertos/task.h> @@ -39,10 +40,6 @@ { class ServiceRunner {- // This task used to exclusively poll ASIO with `poll_one()`, with an- // interval of 100 microseconds. Since ASIO uses `select()` internally to- // implement `poll_one()`, we might as well use an event based approach and- // save some CPU cycles by using `io_service::run()` instead. static void run(void* userParams) { auto runner = static_cast<ServiceRunner*>(userParams);@@ -50,7 +47,8 @@ { try {- runner->mpService->run();+ ulTaskNotifyTake(pdTRUE, portMAX_DELAY);+ runner->mpService->poll_one(); } catch (...) {@@ -58,21 +56,41 @@ } } + static void IRAM_ATTR timerIsr(void* userParam)+ {+ static BaseType_t xHigherPriorityTaskWoken = pdFALSE;+ vTaskNotifyGiveFromISR(*((TaskHandle_t*)userParam), &xHigherPriorityTaskWoken);+ if (xHigherPriorityTaskWoken)+ {+ portYIELD_FROM_ISR();+ }+ }+ public: ServiceRunner() : mpService(new ::asio::io_service()) , mpWork(new ::asio::io_service::work(*mpService)) {- xTaskCreatePinnedToCore(run,- "link",- 8192,- this,- 2 | portPRIVILEGE_BIT,- &mTaskHandle,- LINK_ESP_TASK_CORE_ID);+ xTaskCreatePinnedToCore(run, "link", 8192, this, 2 | portPRIVILEGE_BIT,+ &mTaskHandle, LINK_ESP_TASK_CORE_ID);++ const esp_timer_create_args_t timerArgs = {+ .callback = &timerIsr,+ .arg = (void*)&mTaskHandle,+ .dispatch_method = ESP_TIMER_TASK,+ .name = "link",+ .skip_unhandled_events = true,+ };++ ESP_ERROR_CHECK(esp_timer_create(&timerArgs, &mTimer));+ ESP_ERROR_CHECK(esp_timer_start_periodic(mTimer, 100)); } - ~ServiceRunner() { vTaskDelete(mTaskHandle); }+ ~ServiceRunner()+ {+ esp_timer_delete(mTimer);+ vTaskDelete(mTaskHandle);+ } template <typename Handler> void async(Handler handler)@@ -80,10 +98,14 @@ mpService->post(std::move(handler)); } - ::asio::io_service& service() const { return *mpService; }+ ::asio::io_service& service() const+ {+ return *mpService;+ } private: TaskHandle_t mTaskHandle;+ esp_timer_handle_t mTimer; std::unique_ptr<::asio::io_service> mpService; std::unique_ptr<::asio::io_service::work> mpWork; };@@ -116,7 +138,9 @@ { } - void stop() {}+ void stop()+ {+ } template <std::size_t BufferSize> Socket<BufferSize> openUnicastSocket(const ::asio::ip::address& addr)@@ -188,11 +212,20 @@ return socket; } - std::vector<::asio::ip::address> scanNetworkInterfaces() { return mScanIpIfAddrs(); }+ std::vector<::asio::ip::address> scanNetworkInterfaces()+ {+ return mScanIpIfAddrs();+ } - Timer makeTimer() const { return {serviceRunner().service()}; }+ Timer makeTimer() const+ {+ return {serviceRunner().service()};+ } - Log& log() { return mLog; }+ Log& log()+ {+ return mLog;+ } template <typename Handler> void async(Handler handler)@@ -210,7 +243,9 @@ { }; - void operator()(const Exception&) {}+ void operator()(const Exception&)+ {+ } }; static ServiceRunner& serviceRunner()
link/include/ableton/platforms/esp32/LockFreeCallbackDispatcher.hpp view
@@ -47,20 +47,12 @@ , mFallbackPeriod(std::move(fallbackPeriod)) , mRunning(true) {+ xTaskCreate(run, "link", 4096, this, tskIDLE_PRIORITY, &mTaskHandle); } - ~LockFreeCallbackDispatcher() { stop(); }-- void start() { xTaskCreate(run, "link", 4096, this, tskIDLE_PRIORITY, &mTaskHandle); }-- void stop()+ ~LockFreeCallbackDispatcher() {- const auto wasRunning = mRunning.exchange(false);- if (!wasRunning)- {- return;- }-+ mRunning = false; mCondition.notify_one(); vTaskDelete(mTaskHandle); }@@ -84,12 +76,6 @@ std::unique_lock<std::mutex> lock(dispatcher->mMutex); dispatcher->mCondition.wait_for(lock, dispatcher->mFallbackPeriod); }-- if (!dispatcher->mRunning.load())- {- break;- }- dispatcher->mCallback(); vTaskDelay(1); }
− link/include/ableton/platforms/esp32/Log.hpp
@@ -1,138 +0,0 @@-/* Copyright 2025, All rights reserved.- *- * This program is free software: you can redistribute it and/or modify- * it under the terms of the GNU General Public License as published by- * the Free Software Foundation, either version 2 of the License, or- * (at your option) any later version.- *- * This program is distributed in the hope that it will be useful,- * but WITHOUT ANY WARRANTY; without even the implied warranty of- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- * GNU General Public License for more details.- *- * You should have received a copy of the GNU General Public License- * along with this program. If not, see <http://www.gnu.org/licenses/>.- */--#pragma once--#include <esp_log.h>-#include <sstream>-#include <string>--namespace ableton-{-namespace platforms-{-namespace esp32-{--// ESP-IDF logging implementation for Ableton Link-struct EspLog-{- enum class Level- {- Debug,- Info,- Warning,- Error- };-- // Tag used for all Link logging- //- // All Link logging should go through this tag, since ESP-IDF has a lot of- // internal logging and this helps to manage being able to filter.- //- // ESP-IDF has no wildcard filtering support, so for channels we prepend the- // channel name to the message text, since channels can be created based on- // dynamic data, like IP addresses.- static constexpr const char* kTag = "ableton_link";-- EspLog() = default;-- explicit EspLog(std::string context)- : mContext(std::move(context))- {- }-- struct EspLogStream- {- EspLogStream(Level level, const std::string& context)- : mLevel(level)- , mContext(context)- {- }-- EspLogStream(EspLogStream&& rhs)- : mLevel(rhs.mLevel)- , mContext(rhs.mContext)- , mStream(std::move(rhs.mStream))- {- rhs.mMoved = true;- }-- ~EspLogStream()- {- if (!mMoved)- {- std::string msg = mStream.str();- // Prepend context to message if present- if (!mContext.empty())- {- msg = "[" + mContext + "] " + msg;- }- switch (mLevel)- {- case Level::Debug:- ESP_LOGD(kTag, "%s", msg.c_str());- break;- case Level::Info:- ESP_LOGI(kTag, "%s", msg.c_str());- break;- case Level::Warning:- ESP_LOGW(kTag, "%s", msg.c_str());- break;- case Level::Error:- ESP_LOGE(kTag, "%s", msg.c_str());- break;- }- }- }-- template <typename T>- EspLogStream& operator<<(const T& rhs)- {- mStream << rhs;- return *this;- }-- Level mLevel;- const std::string& mContext;- std::ostringstream mStream;- bool mMoved = false;- };-- friend EspLogStream debug(const EspLog& log) { return {Level::Debug, log.mContext}; }-- friend EspLogStream info(const EspLog& log) { return {Level::Info, log.mContext}; }-- friend EspLogStream warning(const EspLog& log)- {- return {Level::Warning, log.mContext};- }-- friend EspLogStream error(const EspLog& log) { return {Level::Error, log.mContext}; }-- friend EspLog channel(const EspLog& log, const std::string& channelName)- {- auto newContext =- log.mContext.empty() ? channelName : log.mContext + "::" + channelName;- return EspLog{std::move(newContext)};- }-- std::string mContext;-};--} // namespace esp32-} // namespace platforms-} // namespace ableton
link/include/ableton/platforms/esp32/ScanIpIfAddrs.hpp view
@@ -19,17 +19,10 @@ #include <ableton/discovery/AsioTypes.hpp> #include <arpa/inet.h>-#include <esp_idf_version.h> #include <esp_netif.h> #include <net/if.h> #include <vector> -// esp_netif_next_unsafe() was introduced in ESP-IDF v5.5 as a rename of-// esp_netif_next() to make the thread-unsafety explicit.-#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 5, 0)-#define esp_netif_next_unsafe esp_netif_next-#endif- namespace ableton { namespace platforms@@ -37,36 +30,26 @@ namespace esp32 { -// ESP32 implementation of ip interface address scanner.-// Uses esp_netif_tcpip_exec() to iterate network interfaces safely from-// the TCPIP thread, where the interface list is guaranteed stable.-// esp_netif_tcpip_exec() is available in ESP-IDF v5.3 and later.+// ESP32 implementation of ip interface address scanner struct ScanIpIfAddrs { std::vector<discovery::IpAddress> operator()() { std::vector<discovery::IpAddress> addrs;- esp_netif_tcpip_exec(- [](void* ctx) -> esp_err_t+ // Get first network interface+ esp_netif_t* esp_netif = esp_netif_next(NULL);+ while (esp_netif)+ {+ // Check if interface is active+ if (esp_netif_is_netif_up(esp_netif)) {- auto& out = *static_cast<std::vector<discovery::IpAddress>*>(ctx);- // Get first network interface- esp_netif_t* esp_netif = esp_netif_next_unsafe(NULL);- while (esp_netif)- {- // Check if interface is active- if (esp_netif_is_netif_up(esp_netif))- {- esp_netif_ip_info_t ip_info;- esp_netif_get_ip_info(esp_netif, &ip_info);- out.emplace_back(::asio::ip::address_v4(ntohl(ip_info.ip.addr)));- }- // Get next network interface- esp_netif = esp_netif_next_unsafe(esp_netif);- }- return ESP_OK;- },- &addrs);+ esp_netif_ip_info_t ip_info;+ esp_netif_get_ip_info(esp_netif, &ip_info);+ addrs.emplace_back(::asio::ip::address_v4(ntohl(ip_info.ip.addr)));+ }+ // Get next network interface+ esp_netif = esp_netif_next(esp_netif);+ } return addrs; } };
link/include/ableton/platforms/linux/ThreadFactory.hpp view
@@ -19,10 +19,8 @@ #pragma once -#include <optional> #include <pthread.h> #include <thread>-#include <utility> namespace ableton {@@ -30,44 +28,6 @@ { namespace linux_ {--struct ThreadPriority-{- void setHigh()- {- if (!moOriginal)- {- capture();- }-- sched_param high{};- high.sched_priority = 35;- pthread_setschedparam(pthread_self(), SCHED_FIFO, &high);- }-- void reset()- {- if (moOriginal)- {- pthread_setschedparam(pthread_self(), moOriginal->first, &moOriginal->second);- moOriginal = std::nullopt;- }- }--private:- void capture()- {- int policy;- sched_param params;- const auto result = pthread_getschedparam(pthread_self(), &policy, ¶ms);- if (result == 0)- {- moOriginal = std::make_pair(policy, params);- }- }-- std::optional<std::pair<int, sched_param>> moOriginal;-}; struct ThreadFactory {
link/include/ableton/platforms/posix/ScanIpIfAddrs.hpp view
@@ -82,49 +82,43 @@ std::map<std::string, discovery::IpAddress> IpInterfaceNames; detail::GetIfAddrs getIfAddrs;- getIfAddrs.withIfAddrs(- [&addrs, &IpInterfaceNames](const struct ifaddrs& interfaces)+ getIfAddrs.withIfAddrs([&addrs, &IpInterfaceNames](const struct ifaddrs& interfaces) {+ const struct ifaddrs* interface;+ for (interface = &interfaces; interface; interface = interface->ifa_next) {- const struct ifaddrs* interface;- for (interface = &interfaces; interface; interface = interface->ifa_next)+ const auto addr =+ reinterpret_cast<const struct sockaddr_in*>(interface->ifa_addr);+ if (addr && interface->ifa_flags & IFF_RUNNING && addr->sin_family == AF_INET) {- const auto addr =- reinterpret_cast<const struct sockaddr_in*>(interface->ifa_addr);- if (addr && interface->ifa_flags & IFF_RUNNING && addr->sin_family == AF_INET)- {- const auto bytes = reinterpret_cast<const char*>(&addr->sin_addr);- const auto address =- discovery::makeAddressFromBytes<discovery::IpAddressV4>(bytes);- addrs.emplace_back(address);- IpInterfaceNames.insert(std::make_pair(interface->ifa_name, address));- }+ const auto bytes = reinterpret_cast<const char*>(&addr->sin_addr);+ const auto address = discovery::makeAddress<discovery::IpAddressV4>(bytes);+ addrs.emplace_back(address);+ IpInterfaceNames.insert(std::make_pair(interface->ifa_name, address)); }- });+ }+ }); - // Add IPv6 addresses as backup in case multicast on IPv4 fails- getIfAddrs.withIfAddrs(- [&addrs, &IpInterfaceNames](const struct ifaddrs& interfaces)+ getIfAddrs.withIfAddrs([&addrs, &IpInterfaceNames](const struct ifaddrs& interfaces) {+ const struct ifaddrs* interface;+ for (interface = &interfaces; interface; interface = interface->ifa_next) {- const struct ifaddrs* interface;- for (interface = &interfaces; interface; interface = interface->ifa_next)+ const auto addr =+ reinterpret_cast<const struct sockaddr_in*>(interface->ifa_addr);+ if (IpInterfaceNames.find(interface->ifa_name) != IpInterfaceNames.end() && addr+ && interface->ifa_flags & IFF_RUNNING && addr->sin_family == AF_INET6) {- const auto addr =- reinterpret_cast<const struct sockaddr_in*>(interface->ifa_addr);- if (IpInterfaceNames.find(interface->ifa_name) != IpInterfaceNames.end() && addr- && interface->ifa_flags & IFF_RUNNING && addr->sin_family == AF_INET6)+ const auto addr6 = reinterpret_cast<const struct sockaddr_in6*>(addr);+ const auto bytes = reinterpret_cast<const char*>(&addr6->sin6_addr);+ const auto scopeId = addr6->sin6_scope_id;+ const auto address =+ discovery::makeAddress<discovery::IpAddressV6>(bytes, scopeId);+ if (!address.is_loopback() && address.is_link_local()) {- const auto addr6 = reinterpret_cast<const struct sockaddr_in6*>(addr);- const auto bytes = reinterpret_cast<const char*>(&addr6->sin6_addr);- const auto scopeId = addr6->sin6_scope_id;- const auto address =- discovery::makeAddressFromBytes<discovery::IpAddressV6>(bytes, scopeId);- if (!address.is_loopback() && address.is_link_local())- {- addrs.emplace_back(address);- }+ addrs.emplace_back(address); } }- });+ }+ }); return addrs; };
link/include/ableton/platforms/stl/Random.hpp view
@@ -36,7 +36,10 @@ { } - uint8_t operator()() { return static_cast<uint8_t>(dist(gen)); }+ uint8_t operator()()+ {+ return static_cast<uint8_t>(dist(gen));+ } std::random_device rd; std::mt19937 gen;
link/include/ableton/platforms/windows/Clock.hpp view
@@ -58,7 +58,10 @@ return count.QuadPart; } - std::chrono::microseconds micros() const { return ticksToMicros(ticks()); }+ std::chrono::microseconds micros() const+ {+ return ticksToMicros(ticks());+ } double mTicksToMicros; };
link/include/ableton/platforms/windows/ScanIpIfAddrs.hpp view
@@ -54,13 +54,10 @@ adapter_addrs = (IP_ADAPTER_ADDRESSES*)malloc(adapter_addrs_buffer_size); assert(adapter_addrs); - DWORD error =- ::GetAdaptersAddresses(AF_UNSPEC,- GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST- | GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_FRIENDLY_NAME,- NULL,- adapter_addrs,- &adapter_addrs_buffer_size);+ DWORD error = ::GetAdaptersAddresses(AF_UNSPEC,+ GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER+ | GAA_FLAG_SKIP_FRIENDLY_NAME,+ NULL, adapter_addrs, &adapter_addrs_buffer_size); if (error == ERROR_SUCCESS) {@@ -109,67 +106,58 @@ std::map<std::string, discovery::IpAddress> IpInterfaceNames; detail::GetIfAddrs getIfAddrs;- getIfAddrs.withIfAddrs(- [&](const IP_ADAPTER_ADDRESSES& interfaces)+ getIfAddrs.withIfAddrs([&](const IP_ADAPTER_ADDRESSES& interfaces) {+ const IP_ADAPTER_ADDRESSES* networkInterface;+ for (networkInterface = &interfaces; networkInterface;+ networkInterface = networkInterface->Next) {- const IP_ADAPTER_ADDRESSES* networkInterface;- for (networkInterface = &interfaces; networkInterface;- networkInterface = networkInterface->Next)+ for (IP_ADAPTER_UNICAST_ADDRESS* address = networkInterface->FirstUnicastAddress;+ NULL != address; address = address->Next) {- for (IP_ADAPTER_UNICAST_ADDRESS* address =- networkInterface->FirstUnicastAddress;- NULL != address;- address = address->Next)+ auto family = address->Address.lpSockaddr->sa_family;+ if (AF_INET == family) {- auto family = address->Address.lpSockaddr->sa_family;- if (AF_INET == family)- {- // IPv4- SOCKADDR_IN* addr4 =- reinterpret_cast<SOCKADDR_IN*>(address->Address.lpSockaddr);- const auto bytes = reinterpret_cast<const char*>(&addr4->sin_addr);- const auto ipv4address =- discovery::makeAddressFromBytes<discovery::IpAddressV4>(bytes);- addrs.emplace_back(ipv4address);- IpInterfaceNames.insert(- std::make_pair(networkInterface->AdapterName, ipv4address));- }+ // IPv4+ SOCKADDR_IN* addr4 =+ reinterpret_cast<SOCKADDR_IN*>(address->Address.lpSockaddr);+ const auto bytes = reinterpret_cast<const char*>(&addr4->sin_addr);+ const auto ipv4address =+ discovery::makeAddress<discovery::IpAddressV4>(bytes);+ addrs.emplace_back(ipv4address);+ IpInterfaceNames.insert(+ std::make_pair(networkInterface->AdapterName, ipv4address)); } }- });+ }+ }); - // Add IPv6 addresses as backup in case multicast on IPv4 fails- getIfAddrs.withIfAddrs(- [&](const IP_ADAPTER_ADDRESSES& interfaces)+ getIfAddrs.withIfAddrs([&](const IP_ADAPTER_ADDRESSES& interfaces) {+ const IP_ADAPTER_ADDRESSES* networkInterface;+ for (networkInterface = &interfaces; networkInterface;+ networkInterface = networkInterface->Next) {- const IP_ADAPTER_ADDRESSES* networkInterface;- for (networkInterface = &interfaces; networkInterface;- networkInterface = networkInterface->Next)+ for (IP_ADAPTER_UNICAST_ADDRESS* address = networkInterface->FirstUnicastAddress;+ NULL != address; address = address->Next) {- for (IP_ADAPTER_UNICAST_ADDRESS* address =- networkInterface->FirstUnicastAddress;- NULL != address;- address = address->Next)+ auto family = address->Address.lpSockaddr->sa_family;+ if (AF_INET6 == family+ && IpInterfaceNames.find(networkInterface->AdapterName)+ != IpInterfaceNames.end()) {- auto family = address->Address.lpSockaddr->sa_family;- if (AF_INET6 == family- && IpInterfaceNames.find(networkInterface->AdapterName)- != IpInterfaceNames.end())+ SOCKADDR_IN6* sockAddr =+ reinterpret_cast<SOCKADDR_IN6*>(address->Address.lpSockaddr);+ const auto scopeId = sockAddr->sin6_scope_id;+ const auto bytes = reinterpret_cast<const char*>(&sockAddr->sin6_addr);+ const auto addr6 =+ discovery::makeAddress<discovery::IpAddressV6>(bytes, scopeId);+ if (!addr6.is_loopback() && addr6.is_link_local()) {- SOCKADDR_IN6* sockAddr =- reinterpret_cast<SOCKADDR_IN6*>(address->Address.lpSockaddr);- const auto scopeId = sockAddr->sin6_scope_id;- const auto bytes = reinterpret_cast<const char*>(&sockAddr->sin6_addr);- const auto addr6 =- discovery::makeAddressFromBytes<discovery::IpAddressV6>(bytes, scopeId);- if (!addr6.is_loopback() && addr6.is_link_local())- {- addrs.emplace_back(addr6);- }+ addrs.emplace_back(addr6); } } }- });+ }+ }); return addrs; }
link/include/ableton/platforms/windows/ThreadFactory.hpp view
@@ -19,9 +19,6 @@ #pragma once -#include <Windows.h>-#include <avrt.h>-#include <optional> #include <processthreadsapi.h> #include <thread> #include <utility>@@ -33,54 +30,20 @@ namespace windows { -struct ThreadPriority-{- void setHigh()- {- if (moOriginal)- {- return;- }-- DWORD taskIndex = 0;- HANDLE handle = ::AvSetMmThreadCharacteristicsW(L"Distribution", &taskIndex);- if (handle)- {- ::AvSetMmThreadPriority(handle, AVRT_PRIORITY_HIGH);- moOriginal = handle;- }- }-- void reset()- {- if (moOriginal)- {- ::AvRevertMmThreadCharacteristics(*moOriginal);- moOriginal = std::nullopt;- }- }--private:- std::optional<HANDLE> moOriginal;-};- struct ThreadFactory { template <typename Callable, typename... Args> static std::thread makeThread(std::string name, Callable&& f, Args&&... args) { return std::thread(- [](std::string name, Callable&& f, Args&&... args)- {+ [](std::string name, Callable&& f, Args&&... args) { assert(name.length() < 20); wchar_t nativeName[20]; mbstowcs(nativeName, name.c_str(), name.length() + 1); SetThreadDescription(GetCurrentThread(), nativeName); f(args...); },- std::move(name),- std::forward<Callable>(f),- std::forward<Args>(args)...);+ std::move(name), std::forward<Callable>(f), std::forward<Args>(args)...); } };
link/include/ableton/platforms/windows/Windows.hpp view
@@ -26,7 +26,7 @@ #define htonll(x) (x) #define ntohll(x) (x) #else-#define htonll(x) (((uint64_t)htonl((x) & 0xFFFFFFFF) << 32) | htonl((x) >> 32))-#define ntohll(x) (((uint64_t)ntohl((x) & 0xFFFFFFFF) << 32) | ntohl((x) >> 32))+#define htonll(x) (((uint64_t)htonl((x)&0xFFFFFFFF) << 32) | htonl((x) >> 32))+#define ntohll(x) (((uint64_t)ntohl((x)&0xFFFFFFFF) << 32) | ntohl((x) >> 32)) #endif #endif
link/include/ableton/test/serial_io/Context.hpp view
@@ -37,8 +37,8 @@ { public: Context(const SchedulerTree::TimePoint& now,- const std::vector<discovery::IpAddress>& ifAddrs,- std::shared_ptr<SchedulerTree> pScheduler)+ const std::vector<discovery::IpAddress>& ifAddrs,+ std::shared_ptr<SchedulerTree> pScheduler) : mNow(now) , mIfAddrs(ifAddrs) , mpScheduler(std::move(pScheduler))@@ -67,7 +67,9 @@ { } - void stop() {}+ void stop()+ {+ } template <typename Handler> void async(Handler handler)@@ -77,13 +79,22 @@ using Timer = serial_io::Timer; - Timer makeTimer() { return {mNextTimerId++, mNow, mpScheduler}; }+ Timer makeTimer()+ {+ return {mNextTimerId++, mNow, mpScheduler};+ } using Log = util::NullLog; - Log& log() { return mLog; }+ Log& log()+ {+ return mLog;+ } - std::vector<discovery::IpAddress> scanNetworkInterfaces() { return mIfAddrs; }+ std::vector<discovery::IpAddress> scanNetworkInterfaces()+ {+ return mIfAddrs;+ } private: const SchedulerTree::TimePoint& mNow;
link/include/ableton/test/serial_io/Fixture.hpp view
@@ -40,7 +40,10 @@ { } - ~Fixture() { flush(); }+ ~Fixture()+ {+ flush();+ } Fixture(const Fixture&) = delete; Fixture& operator=(const Fixture&) = delete;@@ -52,9 +55,15 @@ mIfAddrs = std::move(ifAddrs); } - Context makeIoContext() { return {mNow, mIfAddrs, mpScheduler}; }+ Context makeIoContext()+ {+ return {mNow, mIfAddrs, mpScheduler};+ } - void flush() { mpScheduler->run(); }+ void flush()+ {+ mpScheduler->run();+ } template <typename T, typename Rep> void advanceTime(std::chrono::duration<T, Rep> duration)
link/include/ableton/test/serial_io/Timer.hpp view
@@ -34,8 +34,8 @@ using TimePoint = SchedulerTree::TimePoint; Timer(const SchedulerTree::TimerId timerId,- const TimePoint& now,- std::shared_ptr<SchedulerTree> pScheduler)+ const TimePoint& now,+ std::shared_ptr<SchedulerTree> pScheduler) : mId(timerId) , mNow(now) , mpScheduler(std::move(pScheduler))@@ -93,7 +93,10 @@ pScheduler->setTimer(mId, mExpiration, std::move(handler)); } - TimePoint now() const { return mNow; }+ TimePoint now() const+ {+ return mNow;+ } const SchedulerTree::TimerId mId; const TimePoint& mNow;
− link/include/ableton/util/FloatIntConversion.hpp
@@ -1,54 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- * This program is free software: you can redistribute it and/or modify- * it under the terms of the GNU General Public License as published by- * the Free Software Foundation, either version 2 of the License, or- * (at your option) any later version.- *- * This program is distributed in the hope that it will be useful,- * but WITHOUT ANY WARRANTY; without even the implied warranty of- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- * GNU General Public License for more details.- *- * You should have received a copy of the GNU General Public License- * along with this program. If not, see <http://www.gnu.org/licenses/>.- *- * If you would like to incorporate Link into a proprietary software application,- * please contact <link-devs@ableton.com>.- */---#pragma once--#include <algorithm>-#include <cmath>-#include <cstdint>-#include <limits>--namespace ableton-{-namespace util-{--template <typename T>-int16_t floatToInt16(const T src)-{- static_assert(std::is_same<T, float>::value || std::is_same<T, double>::value);-- constexpr auto kScale = std::numeric_limits<int16_t>::max() + 1;- constexpr auto kMin = T{-1};- constexpr auto kMax = T{1} - T{1} / kScale;- return int16_t(std::round(kScale * std::clamp(src, kMin, kMax)));-}--template <typename T>-T int16ToFloat(const int16_t src)-{- static_assert(std::is_same<T, float>::value || std::is_same<T, double>::value);-- constexpr auto kScale = std::numeric_limits<int16_t>::max() + 1;- return static_cast<T>(src) / kScale;-}--} // namespace util-} // namespace ableton
link/include/ableton/util/Injected.hpp view
@@ -55,13 +55,25 @@ return *this; } - T* operator->() { return &val; }+ T* operator->()+ {+ return &val;+ } - const T* operator->() const { return &val; }+ const T* operator->() const+ {+ return &val;+ } - T& operator*() { return val; }+ T& operator*()+ {+ return val;+ } - const T& operator*() const { return val; }+ const T& operator*() const+ {+ return val;+ } T val; };@@ -98,13 +110,25 @@ return *this; } - T* operator->() { return &ref.get(); }+ T* operator->()+ {+ return &ref.get();+ } - const T* operator->() const { return &ref.get(); }+ const T* operator->() const+ {+ return &ref.get();+ } - T& operator*() { return ref; }+ T& operator*()+ {+ return ref;+ } - const T& operator*() const { return ref; }+ const T& operator*() const+ {+ return ref;+ } std::reference_wrapper<T> ref; };@@ -141,13 +165,25 @@ return *this; } - T* operator->() { return shared.get(); }+ T* operator->()+ {+ return shared.get();+ } - const T* operator->() const { return shared.get(); }+ const T* operator->() const+ {+ return shared.get();+ } - T& operator*() { return *shared; }+ T& operator*()+ {+ return *shared;+ } - const T& operator*() const { return *shared; }+ const T& operator*() const+ {+ return *shared;+ } std::shared_ptr<T> shared; };@@ -184,13 +220,25 @@ return *this; } - T* operator->() { return unique.get(); }+ T* operator->()+ {+ return unique.get();+ } - const T* operator->() const { return unique.get(); }+ const T* operator->() const+ {+ return unique.get();+ } - T& operator*() { return *unique; }+ T& operator*()+ {+ return *unique;+ } - const T& operator*() const { return *unique; }+ const T& operator*() const+ {+ return *unique;+ } std::unique_ptr<T> unique; };
− link/include/ableton/util/Locked.hpp
@@ -1,58 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- * This program is free software: you can redistribute it and/or modify- * it under the terms of the GNU General Public License as published by- * the Free Software Foundation, either version 2 of the License, or- * (at your option) any later version.- *- * This program is distributed in the hope that it will be useful,- * but WITHOUT ANY WARRANTY; without even the implied warranty of- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- * GNU General Public License for more details.- *- * You should have received a copy of the GNU General Public License- * along with this program. If not, see <http://www.gnu.org/licenses/>.- *- * If you would like to incorporate Link into a proprietary software application,- * please contact <link-devs@ableton.com>.- */---#pragma once--#include <mutex>--namespace ableton-{-namespace util-{--template <typename T>-struct Locked-{-public:- Locked(const T& val)- : mVal(val)- {- }-- T read() const- {- std::lock_guard lock(mMutex);- return mVal;- }-- template <typename Handler>- void update(Handler handler)- {- std::lock_guard lock(mMutex);- handler(mVal);- }--private:- T mVal;- mutable std::mutex mMutex;-};--} // namespace util-} // namespace ableton
link/include/ableton/util/Log.hpp view
@@ -20,15 +20,30 @@ return log; } - friend const NullLog& debug(const NullLog& log) { return log; }+ friend const NullLog& debug(const NullLog& log)+ {+ return log;+ } - friend const NullLog& info(const NullLog& log) { return log; }+ friend const NullLog& info(const NullLog& log)+ {+ return log;+ } - friend const NullLog& warning(const NullLog& log) { return log; }+ friend const NullLog& warning(const NullLog& log)+ {+ return log;+ } - friend const NullLog& error(const NullLog& log) { return log; }+ friend const NullLog& error(const NullLog& log)+ {+ return log;+ } - friend NullLog channel(const NullLog&, std::string) { return {}; }+ friend NullLog channel(const NullLog&, std::string)+ {+ return {};+ } }; // std streams-based log@@ -75,13 +90,25 @@ const std::string& mChannelName; }; - friend StdLogStream debug(const StdLog& log) { return {std::clog, log.mChannelName}; }+ friend StdLogStream debug(const StdLog& log)+ {+ return {std::clog, log.mChannelName};+ } - friend StdLogStream info(const StdLog& log) { return {std::clog, log.mChannelName}; }+ friend StdLogStream info(const StdLog& log)+ {+ return {std::clog, log.mChannelName};+ } - friend StdLogStream warning(const StdLog& log) { return {std::clog, log.mChannelName}; }+ friend StdLogStream warning(const StdLog& log)+ {+ return {std::clog, log.mChannelName};+ } - friend StdLogStream error(const StdLog& log) { return {std::cerr, log.mChannelName}; }+ friend StdLogStream error(const StdLog& log)+ {+ return {std::cerr, log.mChannelName};+ } friend StdLog channel(const StdLog& log, const std::string& channelName) {
− link/include/ableton/util/TripleBuffer.hpp
@@ -1,117 +0,0 @@-/* Copyright 2022, Ableton AG, Berlin. All rights reserved.- *- * This program is free software: you can redistribute it and/or modify- * it under the terms of the GNU General Public License as published by- * the Free Software Foundation, either version 2 of the License, or- * (at your option) any later version.- *- * This program is distributed in the hope that it will be useful,- * but WITHOUT ANY WARRANTY; without even the implied warranty of- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- * GNU General Public License for more details.- *- * You should have received a copy of the GNU General Public License- * along with this program. If not, see <http://www.gnu.org/licenses/>.- *- * If you would like to incorporate Link into a proprietary software application,- * please contact <link-devs@ableton.com>.- */---#pragma once--#include <array>-#include <atomic>-#include <cassert>-#include <cstdint>-#include <optional>--namespace ableton-{-namespace util-{--template <typename T>-struct TripleBuffer-{-public:- TripleBuffer()- : mBuffers{{{}, {}, {}}}- {- assert(mState.is_lock_free());- }-- explicit TripleBuffer(const T& initial)- : mBuffers{{initial, initial, initial}}- {- assert(mState.is_lock_free());- }-- TripleBuffer(const TripleBuffer&) = delete;- TripleBuffer& operator=(const TripleBuffer&) = delete;-- T read() noexcept- {- loadReadBuffer();- return mBuffers[mReadIndex];- }-- std::optional<T> readNew()- {- if (loadReadBuffer())- {- return std::optional<T>(mBuffers[mReadIndex]);- }- return std::nullopt;- }-- template <typename U>- void write(U&& value)- {- mBuffers[mWriteIndex] = std::forward<U>(value);-- const auto prevState =- mState.exchange(makeState(mWriteIndex, true), std::memory_order_acq_rel);-- mWriteIndex = backIndex(prevState);- }--private:- bool loadReadBuffer()- {- auto state = mState.load(std::memory_order_acquire);- auto isNew = isNewWrite(state);- if (isNew)- {- const auto prevState =- mState.exchange(makeState(mReadIndex, false), std::memory_order_acq_rel);-- mReadIndex = backIndex(prevState);- }- return isNew;- }-- using BackingState = uint32_t;-- static constexpr bool isNewWrite(const BackingState state)- {- return (state & 0x0000FFFFu) != 0;- }-- static constexpr uint32_t backIndex(const BackingState state) { return state >> 16; }-- static constexpr BackingState makeState(const uint32_t backBufferIndex,- const bool isWrite)- {- return (backBufferIndex << 16) | uint32_t(isWrite);- }-- std::atomic<BackingState> mState{makeState(1u, false)}; // Reader and writer- uint32_t mReadIndex = 0u; // Reader only- uint32_t mWriteIndex = 2u; // Writer only-- std::array<T, 3> mBuffers{};-};--} // namespace util-} // namespace ableton
link/include/ableton/util/test/IoService.hpp view
@@ -41,7 +41,10 @@ { } - void expires_at(std::chrono::system_clock::time_point t) { mpTimer->expires_at(t); }+ void expires_at(std::chrono::system_clock::time_point t)+ {+ mpTimer->expires_at(t);+ } template <typename T, typename Rep> void expires_from_now(std::chrono::duration<T, Rep> duration)@@ -49,7 +52,10 @@ mpTimer->expires_from_now(duration); } - ErrorCode cancel() { return mpTimer->cancel(); }+ ErrorCode cancel()+ {+ return mpTimer->cancel();+ } template <typename Handler> void async_wait(Handler handler)@@ -57,7 +63,10 @@ mpTimer->async_wait(std::move(handler)); } - TimePoint now() const { return mpTimer->now(); }+ TimePoint now() const+ {+ return mpTimer->now();+ } util::test::Timer* mpTimer; };
link/include/ableton/util/test/Timer.hpp view
@@ -70,7 +70,10 @@ mHandler = [handler](ErrorCode ec) { handler(ec); }; } - std::chrono::system_clock::time_point now() const { return mNow; }+ std::chrono::system_clock::time_point now() const+ {+ return mNow;+ } template <typename T, typename Rep> void advance(std::chrono::duration<T, Rep> duration)
link/modules/asio-standalone/asio/include/asio.hpp view
@@ -2,7 +2,7 @@ // asio.hpp // ~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -28,6 +28,7 @@ #include "asio/async_result.hpp" #include "asio/awaitable.hpp" #include "asio/basic_datagram_socket.hpp"+#include "asio/basic_deadline_timer.hpp" #include "asio/basic_file.hpp" #include "asio/basic_io_object.hpp" #include "asio/basic_random_access_file.hpp"@@ -58,27 +59,21 @@ #include "asio/buffered_write_stream_fwd.hpp" #include "asio/buffered_write_stream.hpp" #include "asio/buffers_iterator.hpp"-#include "asio/cancel_after.hpp"-#include "asio/cancel_at.hpp" #include "asio/cancellation_signal.hpp" #include "asio/cancellation_state.hpp" #include "asio/cancellation_type.hpp"-#include "asio/co_composed.hpp" #include "asio/co_spawn.hpp" #include "asio/completion_condition.hpp" #include "asio/compose.hpp"-#include "asio/composed.hpp"-#include "asio/config.hpp" #include "asio/connect.hpp" #include "asio/connect_pipe.hpp" #include "asio/consign.hpp" #include "asio/coroutine.hpp"+#include "asio/deadline_timer.hpp" #include "asio/defer.hpp" #include "asio/deferred.hpp"-#include "asio/default_completion_token.hpp" #include "asio/detached.hpp" #include "asio/dispatch.hpp"-#include "asio/disposition.hpp" #include "asio/error.hpp" #include "asio/error_code.hpp" #include "asio/execution.hpp"@@ -86,15 +81,30 @@ #include "asio/execution/any_executor.hpp" #include "asio/execution/blocking.hpp" #include "asio/execution/blocking_adaptation.hpp"+#include "asio/execution/bulk_execute.hpp"+#include "asio/execution/bulk_guarantee.hpp"+#include "asio/execution/connect.hpp" #include "asio/execution/context.hpp" #include "asio/execution/context_as.hpp"+#include "asio/execution/execute.hpp" #include "asio/execution/executor.hpp" #include "asio/execution/invocable_archetype.hpp" #include "asio/execution/mapping.hpp" #include "asio/execution/occupancy.hpp"+#include "asio/execution/operation_state.hpp" #include "asio/execution/outstanding_work.hpp" #include "asio/execution/prefer_only.hpp"+#include "asio/execution/receiver.hpp"+#include "asio/execution/receiver_invocation_error.hpp" #include "asio/execution/relationship.hpp"+#include "asio/execution/schedule.hpp"+#include "asio/execution/scheduler.hpp"+#include "asio/execution/sender.hpp"+#include "asio/execution/set_done.hpp"+#include "asio/execution/set_error.hpp"+#include "asio/execution/set_value.hpp"+#include "asio/execution/start.hpp"+#include "asio/execution_context.hpp" #include "asio/executor.hpp" #include "asio/executor_work_guard.hpp" #include "asio/file_base.hpp"@@ -103,11 +113,14 @@ #include "asio/generic/raw_protocol.hpp" #include "asio/generic/seq_packet_protocol.hpp" #include "asio/generic/stream_protocol.hpp"+#include "asio/handler_alloc_hook.hpp" #include "asio/handler_continuation_hook.hpp"+#include "asio/handler_invoke_hook.hpp" #include "asio/high_resolution_timer.hpp"-#include "asio/immediate.hpp" #include "asio/io_context.hpp" #include "asio/io_context_strand.hpp"+#include "asio/io_service.hpp"+#include "asio/io_service_strand.hpp" #include "asio/ip/address.hpp" #include "asio/ip/address_v4.hpp" #include "asio/ip/address_v4_iterator.hpp"@@ -181,6 +194,7 @@ #include "asio/this_coro.hpp" #include "asio/thread.hpp" #include "asio/thread_pool.hpp"+#include "asio/time_traits.hpp" #include "asio/use_awaitable.hpp" #include "asio/use_future.hpp" #include "asio/uses_executor.hpp"
link/modules/asio-standalone/asio/include/asio/any_completion_executor.hpp view
@@ -2,7 +2,7 @@ // any_completion_executor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -75,18 +75,20 @@ #endif // !defined(GENERATING_DOCUMENTATION) /// Default constructor.- ASIO_DECL any_completion_executor() noexcept;+ ASIO_DECL any_completion_executor() ASIO_NOEXCEPT; /// Construct in an empty state. Equivalent effects to default constructor.- ASIO_DECL any_completion_executor(nullptr_t) noexcept;+ ASIO_DECL any_completion_executor(nullptr_t) ASIO_NOEXCEPT; /// Copy constructor. ASIO_DECL any_completion_executor(- const any_completion_executor& e) noexcept;+ const any_completion_executor& e) ASIO_NOEXCEPT; +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move constructor. ASIO_DECL any_completion_executor(- any_completion_executor&& e) noexcept;+ any_completion_executor&& e) ASIO_NOEXCEPT;+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Construct to point to the same target as another any_executor. #if defined(GENERATING_DOCUMENTATION)@@ -96,7 +98,7 @@ #else // defined(GENERATING_DOCUMENTATION) template <typename OtherAnyExecutor> any_completion_executor(OtherAnyExecutor e,- constraint_t<+ typename constraint< conditional< !is_same<OtherAnyExecutor, any_completion_executor>::value && is_base_of<execution::detail::any_executor_base,@@ -106,8 +108,8 @@ is_valid_target<OtherAnyExecutor>, false_type >::type::value- > = 0)- : base_type(static_cast<OtherAnyExecutor&&>(e))+ >::type = 0)+ : base_type(ASIO_MOVE_CAST(OtherAnyExecutor)(e)) { } #endif // defined(GENERATING_DOCUMENTATION)@@ -120,7 +122,7 @@ #else // defined(GENERATING_DOCUMENTATION) template <typename OtherAnyExecutor> any_completion_executor(std::nothrow_t, OtherAnyExecutor e,- constraint_t<+ typename constraint< conditional< !is_same<OtherAnyExecutor, any_completion_executor>::value && is_base_of<execution::detail::any_executor_base,@@ -130,19 +132,21 @@ is_valid_target<OtherAnyExecutor>, false_type >::type::value- > = 0) noexcept- : base_type(std::nothrow, static_cast<OtherAnyExecutor&&>(e))+ >::type = 0) ASIO_NOEXCEPT+ : base_type(std::nothrow, ASIO_MOVE_CAST(OtherAnyExecutor)(e)) { } #endif // defined(GENERATING_DOCUMENTATION) /// Construct to point to the same target as another any_executor. ASIO_DECL any_completion_executor(std::nothrow_t,- const any_completion_executor& e) noexcept;+ const any_completion_executor& e) ASIO_NOEXCEPT; +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Construct to point to the same target as another any_executor. ASIO_DECL any_completion_executor(std::nothrow_t,- any_completion_executor&& e) noexcept;+ any_completion_executor&& e) ASIO_NOEXCEPT;+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Construct a polymorphic wrapper for the specified executor. #if defined(GENERATING_DOCUMENTATION)@@ -151,7 +155,7 @@ #else // defined(GENERATING_DOCUMENTATION) template <ASIO_EXECUTION_EXECUTOR Executor> any_completion_executor(Executor e,- constraint_t<+ typename constraint< conditional< !is_same<Executor, any_completion_executor>::value && !is_base_of<execution::detail::any_executor_base,@@ -160,8 +164,8 @@ Executor, supportable_properties_type>, false_type >::type::value- > = 0)- : base_type(static_cast<Executor&&>(e))+ >::type = 0)+ : base_type(ASIO_MOVE_CAST(Executor)(e)) { } #endif // defined(GENERATING_DOCUMENTATION)@@ -173,7 +177,7 @@ #else // defined(GENERATING_DOCUMENTATION) template <ASIO_EXECUTION_EXECUTOR Executor> any_completion_executor(std::nothrow_t, Executor e,- constraint_t<+ typename constraint< conditional< !is_same<Executor, any_completion_executor>::value && !is_base_of<execution::detail::any_executor_base,@@ -182,19 +186,21 @@ Executor, supportable_properties_type>, false_type >::type::value- > = 0) noexcept- : base_type(std::nothrow, static_cast<Executor&&>(e))+ >::type = 0) ASIO_NOEXCEPT+ : base_type(std::nothrow, ASIO_MOVE_CAST(Executor)(e)) { } #endif // defined(GENERATING_DOCUMENTATION) /// Assignment operator. ASIO_DECL any_completion_executor& operator=(- const any_completion_executor& e) noexcept;+ const any_completion_executor& e) ASIO_NOEXCEPT; +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move assignment operator. ASIO_DECL any_completion_executor& operator=(- any_completion_executor&& e) noexcept;+ any_completion_executor&& e) ASIO_NOEXCEPT;+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Assignment operator that sets the polymorphic wrapper to the empty state. ASIO_DECL any_completion_executor& operator=(nullptr_t);@@ -203,7 +209,7 @@ ASIO_DECL ~any_completion_executor(); /// Swap targets with another polymorphic wrapper.- ASIO_DECL void swap(any_completion_executor& other) noexcept;+ ASIO_DECL void swap(any_completion_executor& other) ASIO_NOEXCEPT; /// Obtain a polymorphic wrapper with the specified property. /**@@ -216,9 +222,9 @@ */ template <typename Property> any_completion_executor require(const Property& p,- constraint_t<+ typename constraint< traits::require_member<const base_type&, const Property&>::is_valid- > = 0) const+ >::type = 0) const { return static_cast<const base_type&>(*this).require(p); }@@ -234,9 +240,9 @@ */ template <typename Property> any_completion_executor prefer(const Property& p,- constraint_t<+ typename constraint< traits::prefer_member<const base_type&, const Property&>::is_valid- > = 0) const+ >::type = 0) const { return static_cast<const base_type&>(*this).prefer(p); }
link/modules/asio-standalone/asio/include/asio/any_completion_handler.hpp view
@@ -2,7 +2,7 @@ // any_completion_handler.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -12,16 +12,20 @@ #define ASIO_ANY_COMPLETION_HANDLER_HPP #include "asio/detail/config.hpp"++#if (defined(ASIO_HAS_STD_TUPLE) \+ && defined(ASIO_HAS_MOVE) \+ && defined(ASIO_HAS_VARIADIC_TEMPLATES)) \+ || defined(GENERATING_DOCUMENTATION)+ #include <cstring> #include <functional> #include <memory> #include <utility> #include "asio/any_completion_executor.hpp"-#include "asio/any_io_executor.hpp" #include "asio/associated_allocator.hpp" #include "asio/associated_cancellation_slot.hpp" #include "asio/associated_executor.hpp"-#include "asio/associated_immediate_executor.hpp" #include "asio/cancellation_state.hpp" #include "asio/recycling_allocator.hpp" @@ -35,11 +39,11 @@ public: template <typename S> explicit any_completion_handler_impl_base(S&& slot)- : cancel_state_(static_cast<S&&>(slot), enable_total_cancellation())+ : cancel_state_(ASIO_MOVE_CAST(S)(slot), enable_total_cancellation()) { } - cancellation_slot get_cancellation_slot() const noexcept+ cancellation_slot get_cancellation_slot() const ASIO_NOEXCEPT { return cancel_state_.slot(); }@@ -55,8 +59,8 @@ public: template <typename S, typename H> any_completion_handler_impl(S&& slot, H&& h)- : any_completion_handler_impl_base(static_cast<S&&>(slot)),- handler_(static_cast<H&&>(h))+ : any_completion_handler_impl_base(ASIO_MOVE_CAST(S)(slot)),+ handler_(ASIO_MOVE_CAST(H)(h)) { } @@ -99,7 +103,7 @@ any_completion_handler_impl* ptr = new (uninit_ptr.get()) any_completion_handler_impl(- static_cast<S&&>(slot), static_cast<H&&>(h));+ ASIO_MOVE_CAST(S)(slot), ASIO_MOVE_CAST(H)(h)); uninit_ptr.release(); return ptr;@@ -115,20 +119,13 @@ } any_completion_executor executor(- const any_completion_executor& candidate) const noexcept+ const any_completion_executor& candidate) const ASIO_NOEXCEPT { return any_completion_executor(std::nothrow, (get_associated_executor)(handler_, candidate)); } - any_completion_executor immediate_executor(- const any_io_executor& candidate) const noexcept- {- return any_completion_executor(std::nothrow,- (get_associated_immediate_executor)(handler_, candidate));- }-- void* allocate(std::size_t size, std::size_t align_size) const+ void* allocate(std::size_t size, std::size_t align) const { typename std::allocator_traits< associated_allocator_t<Handler,@@ -137,13 +134,13 @@ (get_associated_allocator)(handler_, asio::recycling_allocator<void>())); - std::size_t space = size + align_size - 1;+ std::size_t space = size + align - 1; unsigned char* base = std::allocator_traits<decltype(alloc)>::allocate( alloc, space + sizeof(std::ptrdiff_t)); void* p = base;- if (detail::align(align_size, size, p, space))+ if (detail::align(align, size, p, space)) { std::ptrdiff_t off = static_cast<unsigned char*>(p) - base; std::memcpy(static_cast<unsigned char*>(p) + size, &off, sizeof(off));@@ -183,11 +180,11 @@ asio::recycling_allocator<void>())}; std::unique_ptr<any_completion_handler_impl, deleter> ptr(this, d);- Handler handler(static_cast<Handler&&>(handler_));+ Handler handler(ASIO_MOVE_CAST(Handler)(handler_)); ptr.reset(); - static_cast<Handler&&>(handler)(- static_cast<Args&&>(args)...);+ ASIO_MOVE_CAST(Handler)(handler)(+ ASIO_MOVE_CAST(Args)(args)...); } private:@@ -210,14 +207,14 @@ void call(any_completion_handler_impl_base* impl, Args... args) const {- call_fn_(impl, static_cast<Args&&>(args)...);+ call_fn_(impl, ASIO_MOVE_CAST(Args)(args)...); } template <typename Handler> static void impl(any_completion_handler_impl_base* impl, Args... args) { static_cast<any_completion_handler_impl<Handler>*>(impl)->call(- static_cast<Args&&>(args)...);+ ASIO_MOVE_CAST(Args)(args)...); } private:@@ -308,36 +305,6 @@ type executor_fn_; }; -class any_completion_handler_immediate_executor_fn-{-public:- using type = any_completion_executor(*)(- any_completion_handler_impl_base*, const any_io_executor&);-- constexpr any_completion_handler_immediate_executor_fn(type fn)- : immediate_executor_fn_(fn)- {- }-- any_completion_executor immediate_executor(- any_completion_handler_impl_base* impl,- const any_io_executor& candidate) const- {- return immediate_executor_fn_(impl, candidate);- }-- template <typename Handler>- static any_completion_executor impl(any_completion_handler_impl_base* impl,- const any_io_executor& candidate)- {- return static_cast<any_completion_handler_impl<Handler>*>(- impl)->immediate_executor(candidate);- }--private:- type immediate_executor_fn_;-};- class any_completion_handler_allocate_fn { public:@@ -400,7 +367,6 @@ class any_completion_handler_fn_table : private any_completion_handler_destroy_fn, private any_completion_handler_executor_fn,- private any_completion_handler_immediate_executor_fn, private any_completion_handler_allocate_fn, private any_completion_handler_deallocate_fn, private any_completion_handler_call_fns<Signatures...>@@ -410,13 +376,11 @@ constexpr any_completion_handler_fn_table( any_completion_handler_destroy_fn::type destroy_fn, any_completion_handler_executor_fn::type executor_fn,- any_completion_handler_immediate_executor_fn::type immediate_executor_fn, any_completion_handler_allocate_fn::type allocate_fn, any_completion_handler_deallocate_fn::type deallocate_fn, CallFns... call_fns) : any_completion_handler_destroy_fn(destroy_fn), any_completion_handler_executor_fn(executor_fn),- any_completion_handler_immediate_executor_fn(immediate_executor_fn), any_completion_handler_allocate_fn(allocate_fn), any_completion_handler_deallocate_fn(deallocate_fn), any_completion_handler_call_fns<Signatures...>(call_fns...)@@ -425,7 +389,6 @@ using any_completion_handler_destroy_fn::destroy; using any_completion_handler_executor_fn::executor;- using any_completion_handler_immediate_executor_fn::immediate_executor; using any_completion_handler_allocate_fn::allocate; using any_completion_handler_deallocate_fn::deallocate; using any_completion_handler_call_fns<Signatures...>::call;@@ -438,7 +401,6 @@ value = any_completion_handler_fn_table<Signatures...>( &any_completion_handler_destroy_fn::impl<Handler>, &any_completion_handler_executor_fn::impl<Handler>,- &any_completion_handler_immediate_executor_fn::impl<Handler>, &any_completion_handler_allocate_fn::impl<Handler>, &any_completion_handler_deallocate_fn::impl<Handler>, &any_completion_handler_call_fn<Signatures>::template impl<Handler>...);@@ -469,7 +431,7 @@ detail::any_completion_handler_impl_base* impl_; constexpr any_completion_handler_allocator(int,- const any_completion_handler<Signatures...>& h) noexcept+ const any_completion_handler<Signatures...>& h) ASIO_NOEXCEPT : fn_table_(h.fn_table_), impl_(h.impl_) {@@ -491,7 +453,7 @@ template <typename U> constexpr any_completion_handler_allocator( const any_completion_handler_allocator<U, Signatures...>& a)- noexcept+ ASIO_NOEXCEPT : fn_table_(a.fn_table_), impl_(a.impl_) {@@ -499,14 +461,14 @@ /// Equality operator. constexpr bool operator==(- const any_completion_handler_allocator& other) const noexcept+ const any_completion_handler_allocator& other) const ASIO_NOEXCEPT { return fn_table_ == other.fn_table_ && impl_ == other.impl_; } /// Inequality operator. constexpr bool operator!=(- const any_completion_handler_allocator& other) const noexcept+ const any_completion_handler_allocator& other) const ASIO_NOEXCEPT { return fn_table_ != other.fn_table_ || impl_ != other.impl_; }@@ -514,15 +476,9 @@ /// Allocate space for @c n objects of the allocator's value type. T* allocate(std::size_t n) const {- if (fn_table_)- {- return static_cast<T*>(- fn_table_->allocate(- impl_, sizeof(T) * n, alignof(T)));- }- std::bad_alloc ex;- asio::detail::throw_exception(ex);- return nullptr;+ return static_cast<T*>(+ fn_table_->allocate(+ impl_, sizeof(T) * n, alignof(T))); } /// Deallocate space for @c n objects of the allocator's value type.@@ -549,7 +505,7 @@ detail::any_completion_handler_impl_base* impl_; constexpr any_completion_handler_allocator(int,- const any_completion_handler<Signatures...>& h) noexcept+ const any_completion_handler<Signatures...>& h) ASIO_NOEXCEPT : fn_table_(h.fn_table_), impl_(h.impl_) {@@ -571,7 +527,7 @@ template <typename U> constexpr any_completion_handler_allocator( const any_completion_handler_allocator<U, Signatures...>& a)- noexcept+ ASIO_NOEXCEPT : fn_table_(a.fn_table_), impl_(a.impl_) {@@ -579,14 +535,14 @@ /// Equality operator. constexpr bool operator==(- const any_completion_handler_allocator& other) const noexcept+ const any_completion_handler_allocator& other) const ASIO_NOEXCEPT { return fn_table_ == other.fn_table_ && impl_ == other.impl_; } /// Inequality operator. constexpr bool operator!=(- const any_completion_handler_allocator& other) const noexcept+ const any_completion_handler_allocator& other) const ASIO_NOEXCEPT { return fn_table_ != other.fn_table_ || impl_ != other.impl_; }@@ -620,9 +576,6 @@ template <typename, typename> friend struct associated_executor; - template <typename, typename>- friend struct associated_immediate_executor;- const detail::any_completion_handler_fn_table<Signatures...>* fn_table_; detail::any_completion_handler_impl_base* impl_; #endif // !defined(GENERATING_DOCUMENTATION)@@ -651,16 +604,16 @@ } /// Construct an @c any_completion_handler to contain the specified target.- template <typename H, typename Handler = decay_t<H>>+ template <typename H, typename Handler = typename decay<H>::type> any_completion_handler(H&& h,- constraint_t<- !is_same<decay_t<H>, any_completion_handler>::value- > = 0)+ typename constraint<+ !is_same<typename decay<H>::type, any_completion_handler>::value+ >::type = 0) : fn_table_( &detail::any_completion_handler_fn_table_instance< Handler, Signatures...>::value), impl_(detail::any_completion_handler_impl<Handler>::create(- (get_associated_cancellation_slot)(h), static_cast<H&&>(h)))+ (get_associated_cancellation_slot)(h), ASIO_MOVE_CAST(H)(h))) { } @@ -668,7 +621,7 @@ /** * After the operation, the moved-from object @c other has no target. */- any_completion_handler(any_completion_handler&& other) noexcept+ any_completion_handler(any_completion_handler&& other) ASIO_NOEXCEPT : fn_table_(other.fn_table_), impl_(other.impl_) {@@ -681,15 +634,15 @@ * After the operation, the moved-from object @c other has no target. */ any_completion_handler& operator=(- any_completion_handler&& other) noexcept+ any_completion_handler&& other) ASIO_NOEXCEPT { any_completion_handler(- static_cast<any_completion_handler&&>(other)).swap(*this);+ ASIO_MOVE_CAST(any_completion_handler)(other)).swap(*this); return *this; } /// Assignment operator that sets the polymorphic wrapper to the empty state.- any_completion_handler& operator=(nullptr_t) noexcept+ any_completion_handler& operator=(nullptr_t) ASIO_NOEXCEPT { any_completion_handler().swap(*this); return *this;@@ -703,34 +656,34 @@ } /// Test if the polymorphic wrapper is empty.- constexpr explicit operator bool() const noexcept+ constexpr explicit operator bool() const ASIO_NOEXCEPT { return impl_ != nullptr; } /// Test if the polymorphic wrapper is non-empty.- constexpr bool operator!() const noexcept+ constexpr bool operator!() const ASIO_NOEXCEPT { return impl_ == nullptr; } /// Swap the content of an @c any_completion_handler with another.- void swap(any_completion_handler& other) noexcept+ void swap(any_completion_handler& other) ASIO_NOEXCEPT { std::swap(fn_table_, other.fn_table_); std::swap(impl_, other.impl_); } /// Get the associated allocator.- allocator_type get_allocator() const noexcept+ allocator_type get_allocator() const ASIO_NOEXCEPT { return allocator_type(0, *this); } /// Get the associated cancellation slot.- cancellation_slot_type get_cancellation_slot() const noexcept+ cancellation_slot_type get_cancellation_slot() const ASIO_NOEXCEPT {- return impl_ ? impl_->get_cancellation_slot() : cancellation_slot_type();+ return impl_->get_cancellation_slot(); } /// Function call operator.@@ -744,12 +697,12 @@ */ template <typename... Args> auto operator()(Args&&... args)- -> decltype(fn_table_->call(impl_, static_cast<Args&&>(args)...))+ -> decltype(fn_table_->call(impl_, ASIO_MOVE_CAST(Args)(args)...)) { if (detail::any_completion_handler_impl_base* impl = impl_) { impl_ = nullptr;- return fn_table_->call(impl, static_cast<Args&&>(args)...);+ return fn_table_->call(impl, ASIO_MOVE_CAST(Args)(args)...); } std::bad_function_call ex; asio::detail::throw_exception(ex);@@ -757,28 +710,28 @@ /// Equality operator. friend constexpr bool operator==(- const any_completion_handler& a, nullptr_t) noexcept+ const any_completion_handler& a, nullptr_t) ASIO_NOEXCEPT { return a.impl_ == nullptr; } /// Equality operator. friend constexpr bool operator==(- nullptr_t, const any_completion_handler& b) noexcept+ nullptr_t, const any_completion_handler& b) ASIO_NOEXCEPT { return nullptr == b.impl_; } /// Inequality operator. friend constexpr bool operator!=(- const any_completion_handler& a, nullptr_t) noexcept+ const any_completion_handler& a, nullptr_t) ASIO_NOEXCEPT { return a.impl_ != nullptr; } /// Inequality operator. friend constexpr bool operator!=(- nullptr_t, const any_completion_handler& b) noexcept+ nullptr_t, const any_completion_handler& b) ASIO_NOEXCEPT { return nullptr != b.impl_; }@@ -790,33 +743,20 @@ using type = any_completion_executor; static type get(const any_completion_handler<Signatures...>& handler,- const Candidate& candidate = Candidate()) noexcept- {- any_completion_executor any_candidate(std::nothrow, candidate);- return handler.fn_table_- ? handler.fn_table_->executor(handler.impl_, any_candidate)- : any_candidate;- }-};--template <typename... Signatures, typename Candidate>-struct associated_immediate_executor<- any_completion_handler<Signatures...>, Candidate>-{- using type = any_completion_executor;-- static type get(const any_completion_handler<Signatures...>& handler,- const Candidate& candidate = Candidate()) noexcept+ const Candidate& candidate = Candidate()) ASIO_NOEXCEPT {- any_io_executor any_candidate(std::nothrow, candidate);- return handler.fn_table_- ? handler.fn_table_->immediate_executor(handler.impl_, any_candidate)- : any_candidate;+ return handler.fn_table_->executor(handler.impl_,+ any_completion_executor(std::nothrow, candidate)); } }; } // namespace asio #include "asio/detail/pop_options.hpp"++#endif // (defined(ASIO_HAS_STD_TUPLE)+ // && defined(ASIO_HAS_MOVE)+ // && defined(ASIO_HAS_VARIADIC_TEMPLATES))+ // || defined(GENERATING_DOCUMENTATION) #endif // ASIO_ANY_COMPLETION_HANDLER_HPP
link/modules/asio-standalone/asio/include/asio/any_io_executor.hpp view
@@ -2,7 +2,7 @@ // any_io_executor.hpp // ~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -87,16 +87,18 @@ #endif // !defined(GENERATING_DOCUMENTATION) /// Default constructor.- ASIO_DECL any_io_executor() noexcept;+ ASIO_DECL any_io_executor() ASIO_NOEXCEPT; /// Construct in an empty state. Equivalent effects to default constructor.- ASIO_DECL any_io_executor(nullptr_t) noexcept;+ ASIO_DECL any_io_executor(nullptr_t) ASIO_NOEXCEPT; /// Copy constructor.- ASIO_DECL any_io_executor(const any_io_executor& e) noexcept;+ ASIO_DECL any_io_executor(const any_io_executor& e) ASIO_NOEXCEPT; +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move constructor.- ASIO_DECL any_io_executor(any_io_executor&& e) noexcept;+ ASIO_DECL any_io_executor(any_io_executor&& e) ASIO_NOEXCEPT;+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Construct to point to the same target as another any_executor. #if defined(GENERATING_DOCUMENTATION)@@ -105,8 +107,8 @@ #else // defined(GENERATING_DOCUMENTATION) template <typename OtherAnyExecutor> any_io_executor(OtherAnyExecutor e,- constraint_t<- conditional_t<+ typename constraint<+ conditional< !is_same<OtherAnyExecutor, any_io_executor>::value && is_base_of<execution::detail::any_executor_base, OtherAnyExecutor>::value,@@ -114,9 +116,9 @@ 0, supportable_properties_type>::template is_valid_target<OtherAnyExecutor>, false_type- >::value- > = 0)- : base_type(static_cast<OtherAnyExecutor&&>(e))+ >::type::value+ >::type = 0)+ : base_type(ASIO_MOVE_CAST(OtherAnyExecutor)(e)) { } #endif // defined(GENERATING_DOCUMENTATION)@@ -129,8 +131,8 @@ #else // defined(GENERATING_DOCUMENTATION) template <typename OtherAnyExecutor> any_io_executor(std::nothrow_t, OtherAnyExecutor e,- constraint_t<- conditional_t<+ typename constraint<+ conditional< !is_same<OtherAnyExecutor, any_io_executor>::value && is_base_of<execution::detail::any_executor_base, OtherAnyExecutor>::value,@@ -138,19 +140,22 @@ 0, supportable_properties_type>::template is_valid_target<OtherAnyExecutor>, false_type- >::value- > = 0) noexcept- : base_type(std::nothrow, static_cast<OtherAnyExecutor&&>(e))+ >::type::value+ >::type = 0) ASIO_NOEXCEPT+ : base_type(std::nothrow, ASIO_MOVE_CAST(OtherAnyExecutor)(e)) { } #endif // defined(GENERATING_DOCUMENTATION) /// Construct to point to the same target as another any_executor. ASIO_DECL any_io_executor(std::nothrow_t,- const any_io_executor& e) noexcept;+ const any_io_executor& e) ASIO_NOEXCEPT; +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Construct to point to the same target as another any_executor.- ASIO_DECL any_io_executor(std::nothrow_t, any_io_executor&& e) noexcept;+ ASIO_DECL any_io_executor(std::nothrow_t,+ any_io_executor&& e) ASIO_NOEXCEPT;+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Construct a polymorphic wrapper for the specified executor. #if defined(GENERATING_DOCUMENTATION)@@ -159,17 +164,17 @@ #else // defined(GENERATING_DOCUMENTATION) template <ASIO_EXECUTION_EXECUTOR Executor> any_io_executor(Executor e,- constraint_t<- conditional_t<+ typename constraint<+ conditional< !is_same<Executor, any_io_executor>::value && !is_base_of<execution::detail::any_executor_base, Executor>::value, execution::detail::is_valid_target_executor< Executor, supportable_properties_type>, false_type- >::value- > = 0)- : base_type(static_cast<Executor&&>(e))+ >::type::value+ >::type = 0)+ : base_type(ASIO_MOVE_CAST(Executor)(e)) { } #endif // defined(GENERATING_DOCUMENTATION)@@ -181,27 +186,30 @@ #else // defined(GENERATING_DOCUMENTATION) template <ASIO_EXECUTION_EXECUTOR Executor> any_io_executor(std::nothrow_t, Executor e,- constraint_t<- conditional_t<+ typename constraint<+ conditional< !is_same<Executor, any_io_executor>::value && !is_base_of<execution::detail::any_executor_base, Executor>::value, execution::detail::is_valid_target_executor< Executor, supportable_properties_type>, false_type- >::value- > = 0) noexcept- : base_type(std::nothrow, static_cast<Executor&&>(e))+ >::type::value+ >::type = 0) ASIO_NOEXCEPT+ : base_type(std::nothrow, ASIO_MOVE_CAST(Executor)(e)) { } #endif // defined(GENERATING_DOCUMENTATION) /// Assignment operator. ASIO_DECL any_io_executor& operator=(- const any_io_executor& e) noexcept;+ const any_io_executor& e) ASIO_NOEXCEPT; +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move assignment operator.- ASIO_DECL any_io_executor& operator=(any_io_executor&& e) noexcept;+ ASIO_DECL any_io_executor& operator=(+ any_io_executor&& e) ASIO_NOEXCEPT;+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Assignment operator that sets the polymorphic wrapper to the empty state. ASIO_DECL any_io_executor& operator=(nullptr_t);@@ -210,7 +218,7 @@ ASIO_DECL ~any_io_executor(); /// Swap targets with another polymorphic wrapper.- ASIO_DECL void swap(any_io_executor& other) noexcept;+ ASIO_DECL void swap(any_io_executor& other) ASIO_NOEXCEPT; /// Obtain a polymorphic wrapper with the specified property. /**@@ -223,9 +231,9 @@ */ template <typename Property> any_io_executor require(const Property& p,- constraint_t<+ typename constraint< traits::require_member<const base_type&, const Property&>::is_valid- > = 0) const+ >::type = 0) const { return static_cast<const base_type&>(*this).require(p); }@@ -241,9 +249,9 @@ */ template <typename Property> any_io_executor prefer(const Property& p,- constraint_t<+ typename constraint< traits::prefer_member<const base_type&, const Property&>::is_valid- > = 0) const+ >::type = 0) const { return static_cast<const base_type&>(*this).prefer(p); }
link/modules/asio-standalone/asio/include/asio/append.hpp view
@@ -2,7 +2,7 @@ // append.hpp // ~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -16,6 +16,11 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"++#if (defined(ASIO_HAS_STD_TUPLE) \+ && defined(ASIO_HAS_VARIADIC_TEMPLATES)) \+ || defined(GENERATING_DOCUMENTATION)+ #include <tuple> #include "asio/detail/type_traits.hpp" @@ -32,9 +37,11 @@ public: /// Constructor. template <typename T, typename... V>- constexpr explicit append_t(T&& completion_token, V&&... values)- : token_(static_cast<T&&>(completion_token)),- values_(static_cast<V&&>(values)...)+ ASIO_CONSTEXPR explicit append_t(+ ASIO_MOVE_ARG(T) completion_token,+ ASIO_MOVE_ARG(V)... values)+ : token_(ASIO_MOVE_CAST(T)(completion_token)),+ values_(ASIO_MOVE_CAST(V)(values)...) { } @@ -47,13 +54,15 @@ /// arguments should be passed additional values after the results of the /// operation. template <typename CompletionToken, typename... Values>-ASIO_NODISCARD inline constexpr-append_t<decay_t<CompletionToken>, decay_t<Values>...>-append(CompletionToken&& completion_token, Values&&... values)+ASIO_NODISCARD inline ASIO_CONSTEXPR append_t<+ typename decay<CompletionToken>::type, typename decay<Values>::type...>+append(ASIO_MOVE_ARG(CompletionToken) completion_token,+ ASIO_MOVE_ARG(Values)... values) {- return append_t<decay_t<CompletionToken>, decay_t<Values>...>(- static_cast<CompletionToken&&>(completion_token),- static_cast<Values&&>(values)...);+ return append_t<+ typename decay<CompletionToken>::type, typename decay<Values>::type...>(+ ASIO_MOVE_CAST(CompletionToken)(completion_token),+ ASIO_MOVE_CAST(Values)(values)...); } } // namespace asio@@ -61,5 +70,9 @@ #include "asio/detail/pop_options.hpp" #include "asio/impl/append.hpp"++#endif // (defined(ASIO_HAS_STD_TUPLE)+ // && defined(ASIO_HAS_VARIADIC_TEMPLATES))+ // || defined(GENERATING_DOCUMENTATION) #endif // ASIO_APPEND_HPP
link/modules/asio-standalone/asio/include/asio/as_tuple.hpp view
@@ -2,7 +2,7 @@ // as_tuple.hpp // ~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -16,6 +16,11 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"++#if (defined(ASIO_HAS_STD_TUPLE) \+ && defined(ASIO_HAS_VARIADIC_TEMPLATES)) \+ || defined(GENERATING_DOCUMENTATION)+ #include "asio/detail/type_traits.hpp" #include "asio/detail/push_options.hpp"@@ -45,18 +50,18 @@ * token is itself defaulted as an argument to allow it to capture a source * location. */- constexpr as_tuple_t(+ ASIO_CONSTEXPR as_tuple_t( default_constructor_tag = default_constructor_tag(), CompletionToken token = CompletionToken())- : token_(static_cast<CompletionToken&&>(token))+ : token_(ASIO_MOVE_CAST(CompletionToken)(token)) { } /// Constructor. template <typename T>- constexpr explicit as_tuple_t(- T&& completion_token)- : token_(static_cast<T&&>(completion_token))+ ASIO_CONSTEXPR explicit as_tuple_t(+ ASIO_MOVE_ARG(T) completion_token)+ : token_(ASIO_MOVE_CAST(T)(completion_token)) { } @@ -71,13 +76,13 @@ /// Construct the adapted executor from the inner executor type. template <typename InnerExecutor1> executor_with_default(const InnerExecutor1& ex,- constraint_t<- conditional_t<+ typename constraint<+ conditional< !is_same<InnerExecutor1, executor_with_default>::value, is_convertible<InnerExecutor1, InnerExecutor>, false_type- >::value- > = 0) noexcept+ >::type::value+ >::type = 0) ASIO_NOEXCEPT : InnerExecutor(ex) { }@@ -85,68 +90,50 @@ /// Type alias to adapt an I/O object to use @c as_tuple_t as its /// default completion token type.+#if defined(ASIO_HAS_ALIAS_TEMPLATES) \+ || defined(GENERATING_DOCUMENTATION) template <typename T> using as_default_on_t = typename T::template rebind_executor<- executor_with_default<typename T::executor_type>>::other;+ executor_with_default<typename T::executor_type> >::other;+#endif // defined(ASIO_HAS_ALIAS_TEMPLATES)+ // || defined(GENERATING_DOCUMENTATION) /// Function helper to adapt an I/O object to use @c as_tuple_t as its /// default completion token type. template <typename T>- static typename decay_t<T>::template rebind_executor<- executor_with_default<typename decay_t<T>::executor_type>+ static typename decay<T>::type::template rebind_executor<+ executor_with_default<typename decay<T>::type::executor_type> >::other- as_default_on(T&& object)+ as_default_on(ASIO_MOVE_ARG(T) object) {- return typename decay_t<T>::template rebind_executor<- executor_with_default<typename decay_t<T>::executor_type>- >::other(static_cast<T&&>(object));+ return typename decay<T>::type::template rebind_executor<+ executor_with_default<typename decay<T>::type::executor_type>+ >::other(ASIO_MOVE_CAST(T)(object)); } //private: CompletionToken token_; }; -/// A function object type that adapts a @ref completion_token to specify that-/// the completion handler arguments should be combined into a single tuple-/// argument.-/**- * May also be used directly as a completion token, in which case it adapts the- * asynchronous operation's default completion token (or asio::deferred- * if no default is available).- */-struct partial_as_tuple+/// Adapt a @ref completion_token to specify that the completion handler+/// arguments should be combined into a single tuple argument.+template <typename CompletionToken>+ASIO_NODISCARD inline+ASIO_CONSTEXPR as_tuple_t<typename decay<CompletionToken>::type>+as_tuple(ASIO_MOVE_ARG(CompletionToken) completion_token) {- /// Default constructor.- constexpr partial_as_tuple()- {- }-- /// Adapt a @ref completion_token to specify that the completion handler- /// arguments should be combined into a single tuple argument.- template <typename CompletionToken>- ASIO_NODISCARD inline- constexpr as_tuple_t<decay_t<CompletionToken>>- operator()(CompletionToken&& completion_token) const- {- return as_tuple_t<decay_t<CompletionToken>>(- static_cast<CompletionToken&&>(completion_token));- }-};--/// A function object that adapts a @ref completion_token to specify that the-/// completion handler arguments should be combined into a single tuple-/// argument.-/**- * May also be used directly as a completion token, in which case it adapts the- * asynchronous operation's default completion token (or asio::deferred- * if no default is available).- */-ASIO_INLINE_VARIABLE constexpr partial_as_tuple as_tuple;+ return as_tuple_t<typename decay<CompletionToken>::type>(+ ASIO_MOVE_CAST(CompletionToken)(completion_token));+} } // namespace asio #include "asio/detail/pop_options.hpp" #include "asio/impl/as_tuple.hpp"++#endif // (defined(ASIO_HAS_STD_TUPLE)+ // && defined(ASIO_HAS_VARIADIC_TEMPLATES))+ // || defined(GENERATING_DOCUMENTATION) #endif // ASIO_AS_TUPLE_HPP
link/modules/asio-standalone/asio/include/asio/associated_allocator.hpp view
@@ -2,7 +2,7 @@ // associated_allocator.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -36,7 +36,9 @@ }; template <typename T>-struct has_allocator_type<T, void_t<typename T::allocator_type>> : true_type+struct has_allocator_type<T,+ typename void_type<typename T::allocator_type>::type>+ : true_type { }; @@ -47,30 +49,33 @@ typedef A type; - static type get(const T&) noexcept+ static type get(const T&) ASIO_NOEXCEPT { return type(); } - static const type& get(const T&, const A& a) noexcept+ static const type& get(const T&, const A& a) ASIO_NOEXCEPT { return a; } }; template <typename T, typename A>-struct associated_allocator_impl<T, A, void_t<typename T::allocator_type>>+struct associated_allocator_impl<T, A,+ typename void_type<typename T::allocator_type>::type> { typedef typename T::allocator_type type; - static auto get(const T& t) noexcept- -> decltype(t.get_allocator())+ static ASIO_AUTO_RETURN_TYPE_PREFIX(type) get(+ const T& t) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((t.get_allocator())) { return t.get_allocator(); } - static auto get(const T& t, const A&) noexcept- -> decltype(t.get_allocator())+ static ASIO_AUTO_RETURN_TYPE_PREFIX(type) get(+ const T& t, const A&) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((t.get_allocator())) { return t.get_allocator(); }@@ -78,12 +83,12 @@ template <typename T, typename A> struct associated_allocator_impl<T, A,- enable_if_t<+ typename enable_if< !has_allocator_type<T>::value- >,- void_t<+ >::type,+ typename void_type< typename associator<associated_allocator, T, A>::type- >> : associator<associated_allocator, T, A>+ >::type> : associator<associated_allocator, T, A> { }; @@ -110,7 +115,7 @@ * get(t,a) and with return type @c type or a (possibly const) reference to @c * type. */-template <typename T, typename Allocator = std::allocator<void>>+template <typename T, typename Allocator = std::allocator<void> > struct associated_allocator #if !defined(GENERATING_DOCUMENTATION) : detail::associated_allocator_impl<T, Allocator>@@ -123,11 +128,11 @@ /// If @c T has a nested type @c allocator_type, returns /// <tt>t.get_allocator()</tt>. Otherwise returns @c type().- static decltype(auto) get(const T& t) noexcept;+ static decltype(auto) get(const T& t) ASIO_NOEXCEPT; /// If @c T has a nested type @c allocator_type, returns /// <tt>t.get_allocator()</tt>. Otherwise returns @c a.- static decltype(auto) get(const T& t, const Allocator& a) noexcept;+ static decltype(auto) get(const T& t, const Allocator& a) ASIO_NOEXCEPT; #endif // defined(GENERATING_DOCUMENTATION) }; @@ -137,7 +142,7 @@ */ template <typename T> ASIO_NODISCARD inline typename associated_allocator<T>::type-get_associated_allocator(const T& t) noexcept+get_associated_allocator(const T& t) ASIO_NOEXCEPT { return associated_allocator<T>::get(t); }@@ -147,17 +152,23 @@ * @returns <tt>associated_allocator<T, Allocator>::get(t, a)</tt> */ template <typename T, typename Allocator>-ASIO_NODISCARD inline auto get_associated_allocator(- const T& t, const Allocator& a) noexcept- -> decltype(associated_allocator<T, Allocator>::get(t, a))+ASIO_NODISCARD inline ASIO_AUTO_RETURN_TYPE_PREFIX2(+ typename associated_allocator<T, Allocator>::type)+get_associated_allocator(const T& t, const Allocator& a) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ associated_allocator<T, Allocator>::get(t, a))) { return associated_allocator<T, Allocator>::get(t, a); } -template <typename T, typename Allocator = std::allocator<void>>+#if defined(ASIO_HAS_ALIAS_TEMPLATES)++template <typename T, typename Allocator = std::allocator<void> > using associated_allocator_t = typename associated_allocator<T, Allocator>::type; +#endif // defined(ASIO_HAS_ALIAS_TEMPLATES)+ namespace detail { template <typename T, typename A, typename = void>@@ -167,19 +178,22 @@ template <typename T, typename A> struct associated_allocator_forwarding_base<T, A,- enable_if_t<+ typename enable_if< is_same< typename associated_allocator<T, A>::asio_associated_allocator_is_unspecialised, void >::value- >>+ >::type> { typedef void asio_associated_allocator_is_unspecialised; }; } // namespace detail +#if defined(ASIO_HAS_STD_REFERENCE_WRAPPER) \+ || defined(GENERATING_DOCUMENTATION)+ /// Specialisation of associated_allocator for @c std::reference_wrapper. template <typename T, typename Allocator> struct associated_allocator<reference_wrapper<T>, Allocator>@@ -193,19 +207,24 @@ /// Forwards the request to get the allocator to the associator specialisation /// for the unwrapped type @c T.- static type get(reference_wrapper<T> t) noexcept+ static type get(reference_wrapper<T> t) ASIO_NOEXCEPT { return associated_allocator<T, Allocator>::get(t.get()); } /// Forwards the request to get the allocator to the associator specialisation /// for the unwrapped type @c T.- static auto get(reference_wrapper<T> t, const Allocator& a) noexcept- -> decltype(associated_allocator<T, Allocator>::get(t.get(), a))+ static ASIO_AUTO_RETURN_TYPE_PREFIX(type) get(+ reference_wrapper<T> t, const Allocator& a) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ associated_allocator<T, Allocator>::get(t.get(), a))) { return associated_allocator<T, Allocator>::get(t.get(), a); } };++#endif // defined(ASIO_HAS_STD_REFERENCE_WRAPPER)+ // || defined(GENERATING_DOCUMENTATION) } // namespace asio
link/modules/asio-standalone/asio/include/asio/associated_cancellation_slot.hpp view
@@ -2,7 +2,7 @@ // associated_cancellation_slot.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -36,8 +36,9 @@ }; template <typename T>-struct has_cancellation_slot_type<T, void_t<typename T::cancellation_slot_type>>- : true_type+struct has_cancellation_slot_type<T,+ typename void_type<typename T::cancellation_slot_type>::type>+ : true_type { }; @@ -48,12 +49,12 @@ typedef S type; - static type get(const T&) noexcept+ static type get(const T&) ASIO_NOEXCEPT { return type(); } - static const type& get(const T&, const S& s) noexcept+ static const type& get(const T&, const S& s) ASIO_NOEXCEPT { return s; }@@ -61,18 +62,20 @@ template <typename T, typename S> struct associated_cancellation_slot_impl<T, S,- void_t<typename T::cancellation_slot_type>>+ typename void_type<typename T::cancellation_slot_type>::type> { typedef typename T::cancellation_slot_type type; - static auto get(const T& t) noexcept- -> decltype(t.get_cancellation_slot())+ static ASIO_AUTO_RETURN_TYPE_PREFIX(type) get(+ const T& t) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((t.get_cancellation_slot())) { return t.get_cancellation_slot(); } - static auto get(const T& t, const S&) noexcept- -> decltype(t.get_cancellation_slot())+ static ASIO_AUTO_RETURN_TYPE_PREFIX(type) get(+ const T& t, const S&) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((t.get_cancellation_slot())) { return t.get_cancellation_slot(); }@@ -80,12 +83,12 @@ template <typename T, typename S> struct associated_cancellation_slot_impl<T, S,- enable_if_t<+ typename enable_if< !has_cancellation_slot_type<T>::value- >,- void_t<+ >::type,+ typename void_type< typename associator<associated_cancellation_slot, T, S>::type- >> : associator<associated_cancellation_slot, T, S>+ >::type> : associator<associated_cancellation_slot, T, S> { }; @@ -126,12 +129,12 @@ /// If @c T has a nested type @c cancellation_slot_type, returns /// <tt>t.get_cancellation_slot()</tt>. Otherwise returns @c type().- static decltype(auto) get(const T& t) noexcept;+ static decltype(auto) get(const T& t) ASIO_NOEXCEPT; /// If @c T has a nested type @c cancellation_slot_type, returns /// <tt>t.get_cancellation_slot()</tt>. Otherwise returns @c s. static decltype(auto) get(const T& t,- const CancellationSlot& s) noexcept;+ const CancellationSlot& s) ASIO_NOEXCEPT; #endif // defined(GENERATING_DOCUMENTATION) }; @@ -141,7 +144,7 @@ */ template <typename T> ASIO_NODISCARD inline typename associated_cancellation_slot<T>::type-get_associated_cancellation_slot(const T& t) noexcept+get_associated_cancellation_slot(const T& t) ASIO_NOEXCEPT { return associated_cancellation_slot<T>::get(t); }@@ -152,17 +155,24 @@ * CancellationSlot>::get(t, st)</tt> */ template <typename T, typename CancellationSlot>-ASIO_NODISCARD inline auto get_associated_cancellation_slot(- const T& t, const CancellationSlot& st) noexcept- -> decltype(associated_cancellation_slot<T, CancellationSlot>::get(t, st))+ASIO_NODISCARD inline ASIO_AUTO_RETURN_TYPE_PREFIX2(+ typename associated_cancellation_slot<T, CancellationSlot>::type)+get_associated_cancellation_slot(const T& t,+ const CancellationSlot& st) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ associated_cancellation_slot<T, CancellationSlot>::get(t, st))) { return associated_cancellation_slot<T, CancellationSlot>::get(t, st); } +#if defined(ASIO_HAS_ALIAS_TEMPLATES)+ template <typename T, typename CancellationSlot = cancellation_slot> using associated_cancellation_slot_t = typename associated_cancellation_slot<T, CancellationSlot>::type; +#endif // defined(ASIO_HAS_ALIAS_TEMPLATES)+ namespace detail { template <typename T, typename S, typename = void>@@ -172,19 +182,22 @@ template <typename T, typename S> struct associated_cancellation_slot_forwarding_base<T, S,- enable_if_t<+ typename enable_if< is_same< typename associated_cancellation_slot<T, S>::asio_associated_cancellation_slot_is_unspecialised, void >::value- >>+ >::type> { typedef void asio_associated_cancellation_slot_is_unspecialised; }; } // namespace detail +#if defined(ASIO_HAS_STD_REFERENCE_WRAPPER) \+ || defined(GENERATING_DOCUMENTATION)+ /// Specialisation of associated_cancellation_slot for @c /// std::reference_wrapper. template <typename T, typename CancellationSlot>@@ -199,20 +212,24 @@ /// Forwards the request to get the cancellation slot to the associator /// specialisation for the unwrapped type @c T.- static type get(reference_wrapper<T> t) noexcept+ static type get(reference_wrapper<T> t) ASIO_NOEXCEPT { return associated_cancellation_slot<T, CancellationSlot>::get(t.get()); } /// Forwards the request to get the cancellation slot to the associator /// specialisation for the unwrapped type @c T.- static auto get(reference_wrapper<T> t, const CancellationSlot& s) noexcept- -> decltype(- associated_cancellation_slot<T, CancellationSlot>::get(t.get(), s))+ static ASIO_AUTO_RETURN_TYPE_PREFIX(type) get(reference_wrapper<T> t,+ const CancellationSlot& s) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ associated_cancellation_slot<T, CancellationSlot>::get(t.get(), s))) { return associated_cancellation_slot<T, CancellationSlot>::get(t.get(), s); } };++#endif // defined(ASIO_HAS_STD_REFERENCE_WRAPPER)+ // || defined(GENERATING_DOCUMENTATION) } // namespace asio
link/modules/asio-standalone/asio/include/asio/associated_executor.hpp view
@@ -2,7 +2,7 @@ // associated_executor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -38,7 +38,8 @@ }; template <typename T>-struct has_executor_type<T, void_t<typename T::executor_type>>+struct has_executor_type<T,+ typename void_type<typename T::executor_type>::type> : true_type { };@@ -50,30 +51,33 @@ typedef E type; - static type get(const T&) noexcept+ static type get(const T&) ASIO_NOEXCEPT { return type(); } - static const type& get(const T&, const E& e) noexcept+ static const type& get(const T&, const E& e) ASIO_NOEXCEPT { return e; } }; template <typename T, typename E>-struct associated_executor_impl<T, E, void_t<typename T::executor_type>>+struct associated_executor_impl<T, E,+ typename void_type<typename T::executor_type>::type> { typedef typename T::executor_type type; - static auto get(const T& t) noexcept- -> decltype(t.get_executor())+ static ASIO_AUTO_RETURN_TYPE_PREFIX(type) get(+ const T& t) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((t.get_executor())) { return t.get_executor(); } - static auto get(const T& t, const E&) noexcept- -> decltype(t.get_executor())+ static ASIO_AUTO_RETURN_TYPE_PREFIX(type) get(+ const T& t, const E&) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((t.get_executor())) { return t.get_executor(); }@@ -81,12 +85,12 @@ template <typename T, typename E> struct associated_executor_impl<T, E,- enable_if_t<+ typename enable_if< !has_executor_type<T>::value- >,- void_t<+ >::type,+ typename void_type< typename associator<associated_executor, T, E>::type- >> : associator<associated_executor, T, E>+ >::type> : associator<associated_executor, T, E> { }; @@ -126,11 +130,11 @@ /// If @c T has a nested type @c executor_type, returns /// <tt>t.get_executor()</tt>. Otherwise returns @c type().- static decltype(auto) get(const T& t) noexcept;+ static decltype(auto) get(const T& t) ASIO_NOEXCEPT; /// If @c T has a nested type @c executor_type, returns /// <tt>t.get_executor()</tt>. Otherwise returns @c ex.- static decltype(auto) get(const T& t, const Executor& ex) noexcept;+ static decltype(auto) get(const T& t, const Executor& ex) ASIO_NOEXCEPT; #endif // defined(GENERATING_DOCUMENTATION) }; @@ -140,7 +144,7 @@ */ template <typename T> ASIO_NODISCARD inline typename associated_executor<T>::type-get_associated_executor(const T& t) noexcept+get_associated_executor(const T& t) ASIO_NOEXCEPT { return associated_executor<T>::get(t); }@@ -150,12 +154,14 @@ * @returns <tt>associated_executor<T, Executor>::get(t, ex)</tt> */ template <typename T, typename Executor>-ASIO_NODISCARD inline auto get_associated_executor(- const T& t, const Executor& ex,- constraint_t<+ASIO_NODISCARD inline ASIO_AUTO_RETURN_TYPE_PREFIX2(+ typename associated_executor<T, Executor>::type)+get_associated_executor(const T& t, const Executor& ex,+ typename constraint< is_executor<Executor>::value || execution::is_executor<Executor>::value- > = 0) noexcept- -> decltype(associated_executor<T, Executor>::get(t, ex))+ >::type = 0) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ associated_executor<T, Executor>::get(t, ex))) { return associated_executor<T, Executor>::get(t, ex); }@@ -169,16 +175,20 @@ ASIO_NODISCARD inline typename associated_executor<T, typename ExecutionContext::executor_type>::type get_associated_executor(const T& t, ExecutionContext& ctx,- constraint_t<is_convertible<ExecutionContext&,- execution_context&>::value> = 0) noexcept+ typename constraint<is_convertible<ExecutionContext&,+ execution_context&>::value>::type = 0) ASIO_NOEXCEPT { return associated_executor<T, typename ExecutionContext::executor_type>::get(t, ctx.get_executor()); } +#if defined(ASIO_HAS_ALIAS_TEMPLATES)+ template <typename T, typename Executor = system_executor> using associated_executor_t = typename associated_executor<T, Executor>::type; +#endif // defined(ASIO_HAS_ALIAS_TEMPLATES)+ namespace detail { template <typename T, typename E, typename = void>@@ -188,19 +198,22 @@ template <typename T, typename E> struct associated_executor_forwarding_base<T, E,- enable_if_t<+ typename enable_if< is_same< typename associated_executor<T, E>::asio_associated_executor_is_unspecialised, void >::value- >>+ >::type> { typedef void asio_associated_executor_is_unspecialised; }; } // namespace detail +#if defined(ASIO_HAS_STD_REFERENCE_WRAPPER) \+ || defined(GENERATING_DOCUMENTATION)+ /// Specialisation of associated_executor for @c std::reference_wrapper. template <typename T, typename Executor> struct associated_executor<reference_wrapper<T>, Executor>@@ -214,19 +227,24 @@ /// Forwards the request to get the executor to the associator specialisation /// for the unwrapped type @c T.- static type get(reference_wrapper<T> t) noexcept+ static type get(reference_wrapper<T> t) ASIO_NOEXCEPT { return associated_executor<T, Executor>::get(t.get()); } /// Forwards the request to get the executor to the associator specialisation /// for the unwrapped type @c T.- static auto get(reference_wrapper<T> t, const Executor& ex) noexcept- -> decltype(associated_executor<T, Executor>::get(t.get(), ex))+ static ASIO_AUTO_RETURN_TYPE_PREFIX(type) get(+ reference_wrapper<T> t, const Executor& ex) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ associated_executor<T, Executor>::get(t.get(), ex))) { return associated_executor<T, Executor>::get(t.get(), ex); } };++#endif // defined(ASIO_HAS_STD_REFERENCE_WRAPPER)+ // || defined(GENERATING_DOCUMENTATION) } // namespace asio
link/modules/asio-standalone/asio/include/asio/associated_immediate_executor.hpp view
@@ -2,7 +2,7 @@ // associated_immediate_executor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -41,7 +41,7 @@ template <typename T> struct has_immediate_executor_type<T,- void_t<typename T::immediate_executor_type>>+ typename void_type<typename T::immediate_executor_type>::type> : true_type { };@@ -49,10 +49,9 @@ template <typename E, typename = void, typename = void> struct default_immediate_executor {- typedef decay_t<require_result_t<E, execution::blocking_t::never_t>> type;+ typedef typename require_result<E, execution::blocking_t::never_t>::type type; - static auto get(const E& e) noexcept- -> decltype(asio::require(e, execution::blocking.never))+ static type get(const E& e) ASIO_NOEXCEPT { return asio::require(e, execution::blocking.never); }@@ -60,57 +59,59 @@ template <typename E> struct default_immediate_executor<E,- enable_if_t<+ typename enable_if< !execution::is_executor<E>::value- >,- enable_if_t<+ >::type,+ typename enable_if< is_executor<E>::value- >>+ >::type> { class type : public E { public: template <typename Executor1> explicit type(const Executor1& e,- constraint_t<- conditional_t<+ typename constraint<+ conditional< !is_same<Executor1, type>::value, is_convertible<Executor1, E>, false_type- >::value- > = 0) noexcept+ >::type::value+ >::type = 0) ASIO_NOEXCEPT : E(e) { } - type(const type& other) noexcept+ type(const type& other) ASIO_NOEXCEPT : E(static_cast<const E&>(other)) { } - type(type&& other) noexcept- : E(static_cast<E&&>(other))+#if defined(ASIO_HAS_MOVE)+ type(type&& other) ASIO_NOEXCEPT+ : E(ASIO_MOVE_CAST(E)(other)) { }+#endif // defined(ASIO_HAS_MOVE) template <typename Function, typename Allocator>- void dispatch(Function&& f, const Allocator& a) const+ void dispatch(ASIO_MOVE_ARG(Function) f, const Allocator& a) const {- this->post(static_cast<Function&&>(f), a);+ this->post(ASIO_MOVE_CAST(Function)(f), a); } - friend bool operator==(const type& a, const type& b) noexcept+ friend bool operator==(const type& a, const type& b) ASIO_NOEXCEPT { return static_cast<const E&>(a) == static_cast<const E&>(b); } - friend bool operator!=(const type& a, const type& b) noexcept+ friend bool operator!=(const type& a, const type& b) ASIO_NOEXCEPT { return static_cast<const E&>(a) != static_cast<const E&>(b); } }; - static type get(const E& e) noexcept+ static type get(const E& e) ASIO_NOEXCEPT { return type(e); }@@ -123,8 +124,9 @@ typedef typename default_immediate_executor<E>::type type; - static auto get(const T&, const E& e) noexcept- -> decltype(default_immediate_executor<E>::get(e))+ static ASIO_AUTO_RETURN_TYPE_PREFIX(type) get(+ const T&, const E& e) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((default_immediate_executor<E>::get(e))) { return default_immediate_executor<E>::get(e); }@@ -132,12 +134,13 @@ template <typename T, typename E> struct associated_immediate_executor_impl<T, E,- void_t<typename T::immediate_executor_type>>+ typename void_type<typename T::immediate_executor_type>::type> { typedef typename T::immediate_executor_type type; - static auto get(const T& t, const E&) noexcept- -> decltype(t.get_immediate_executor())+ static ASIO_AUTO_RETURN_TYPE_PREFIX(type) get(+ const T& t, const E&) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((t.get_immediate_executor())) { return t.get_immediate_executor(); }@@ -145,12 +148,12 @@ template <typename T, typename E> struct associated_immediate_executor_impl<T, E,- enable_if_t<+ typename enable_if< !has_immediate_executor_type<T>::value- >,- void_t<+ >::type,+ typename void_type< typename associator<associated_immediate_executor, T, E>::type- >> : associator<associated_immediate_executor, T, E>+ >::type> : associator<associated_immediate_executor, T, E> { }; @@ -191,7 +194,7 @@ /// If @c T has a nested type @c immediate_executor_type, returns /// <tt>t.get_immediate_executor()</tt>. Otherwise returns /// <tt>asio::require(ex, asio::execution::blocking.never)</tt>.- static decltype(auto) get(const T& t, const Executor& ex) noexcept;+ static decltype(auto) get(const T& t, const Executor& ex) ASIO_NOEXCEPT; #endif // defined(GENERATING_DOCUMENTATION) }; @@ -200,12 +203,14 @@ * @returns <tt>associated_immediate_executor<T, Executor>::get(t, ex)</tt> */ template <typename T, typename Executor>-ASIO_NODISCARD inline auto get_associated_immediate_executor(- const T& t, const Executor& ex,- constraint_t<+ASIO_NODISCARD inline ASIO_AUTO_RETURN_TYPE_PREFIX2(+ typename associated_immediate_executor<T, Executor>::type)+get_associated_immediate_executor(const T& t, const Executor& ex,+ typename constraint< is_executor<Executor>::value || execution::is_executor<Executor>::value- > = 0) noexcept- -> decltype(associated_immediate_executor<T, Executor>::get(t, ex))+ >::type = 0) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ associated_immediate_executor<T, Executor>::get(t, ex))) { return associated_immediate_executor<T, Executor>::get(t, ex); }@@ -219,18 +224,21 @@ ASIO_NODISCARD inline typename associated_immediate_executor<T, typename ExecutionContext::executor_type>::type get_associated_immediate_executor(const T& t, ExecutionContext& ctx,- constraint_t<- is_convertible<ExecutionContext&, execution_context&>::value- > = 0) noexcept+ typename constraint<is_convertible<ExecutionContext&,+ execution_context&>::value>::type = 0) ASIO_NOEXCEPT { return associated_immediate_executor<T, typename ExecutionContext::executor_type>::get(t, ctx.get_executor()); } +#if defined(ASIO_HAS_ALIAS_TEMPLATES)+ template <typename T, typename Executor> using associated_immediate_executor_t = typename associated_immediate_executor<T, Executor>::type; +#endif // defined(ASIO_HAS_ALIAS_TEMPLATES)+ namespace detail { template <typename T, typename E, typename = void>@@ -240,19 +248,22 @@ template <typename T, typename E> struct associated_immediate_executor_forwarding_base<T, E,- enable_if_t<+ typename enable_if< is_same< typename associated_immediate_executor<T, E>::asio_associated_immediate_executor_is_unspecialised, void >::value- >>+ >::type> { typedef void asio_associated_immediate_executor_is_unspecialised; }; } // namespace detail +#if defined(ASIO_HAS_STD_REFERENCE_WRAPPER) \+ || defined(GENERATING_DOCUMENTATION)+ /// Specialisation of associated_immediate_executor for /// @c std::reference_wrapper. template <typename T, typename Executor>@@ -267,12 +278,17 @@ /// Forwards the request to get the executor to the associator specialisation /// for the unwrapped type @c T.- static auto get(reference_wrapper<T> t, const Executor& ex) noexcept- -> decltype(associated_immediate_executor<T, Executor>::get(t.get(), ex))+ static ASIO_AUTO_RETURN_TYPE_PREFIX(type) get(+ reference_wrapper<T> t, const Executor& ex) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ associated_immediate_executor<T, Executor>::get(t.get(), ex))) { return associated_immediate_executor<T, Executor>::get(t.get(), ex); } };++#endif // defined(ASIO_HAS_STD_REFERENCE_WRAPPER)+ // || defined(GENERATING_DOCUMENTATION) } // namespace asio
link/modules/asio-standalone/asio/include/asio/associator.hpp view
@@ -2,7 +2,7 @@ // associator.hpp // ~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -23,7 +23,7 @@ /// Used to generically specialise associators for a type. template <template <typename, typename> class Associator,- typename T, typename DefaultCandidate, typename _ = void>+ typename T, typename DefaultCandidate> struct associator { };
link/modules/asio-standalone/asio/include/asio/async_result.hpp view
@@ -2,967 +2,1670 @@ // async_result.hpp // ~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef ASIO_ASYNC_RESULT_HPP-#define ASIO_ASYNC_RESULT_HPP--#if defined(_MSC_VER) && (_MSC_VER >= 1200)-# pragma once-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)--#include "asio/detail/config.hpp"-#include "asio/detail/type_traits.hpp"--#include "asio/detail/push_options.hpp"--namespace asio {-namespace detail {--template <typename T>-struct is_completion_signature : false_type-{-};--template <typename R, typename... Args>-struct is_completion_signature<R(Args...)> : true_type-{-};--template <typename R, typename... Args>-struct is_completion_signature<R(Args...) &> : true_type-{-};--template <typename R, typename... Args>-struct is_completion_signature<R(Args...) &&> : true_type-{-};--# if defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)--template <typename R, typename... Args>-struct is_completion_signature<R(Args...) noexcept> : true_type-{-};--template <typename R, typename... Args>-struct is_completion_signature<R(Args...) & noexcept> : true_type-{-};--template <typename R, typename... Args>-struct is_completion_signature<R(Args...) && noexcept> : true_type-{-};--# endif // defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)--template <typename... T>-struct are_completion_signatures : false_type-{-};--template <>-struct are_completion_signatures<>- : true_type-{-};--template <typename T0>-struct are_completion_signatures<T0>- : is_completion_signature<T0>-{-};--template <typename T0, typename... TN>-struct are_completion_signatures<T0, TN...>- : integral_constant<bool, (- is_completion_signature<T0>::value- && are_completion_signatures<TN...>::value)>-{-};--} // namespace detail--#if defined(ASIO_HAS_CONCEPTS)--namespace detail {--template <typename T, typename... Args>-ASIO_CONCEPT callable_with = requires(T&& t, Args&&... args)-{- static_cast<T&&>(t)(static_cast<Args&&>(args)...);-};--template <typename T, typename... Signatures>-struct is_completion_handler_for : false_type-{-};--template <typename T, typename R, typename... Args>-struct is_completion_handler_for<T, R(Args...)>- : integral_constant<bool, (callable_with<decay_t<T>, Args...>)>-{-};--template <typename T, typename R, typename... Args>-struct is_completion_handler_for<T, R(Args...) &>- : integral_constant<bool, (callable_with<decay_t<T>&, Args...>)>-{-};--template <typename T, typename R, typename... Args>-struct is_completion_handler_for<T, R(Args...) &&>- : integral_constant<bool, (callable_with<decay_t<T>&&, Args...>)>-{-};--# if defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)--template <typename T, typename R, typename... Args>-struct is_completion_handler_for<T, R(Args...) noexcept>- : integral_constant<bool, (callable_with<decay_t<T>, Args...>)>-{-};--template <typename T, typename R, typename... Args>-struct is_completion_handler_for<T, R(Args...) & noexcept>- : integral_constant<bool, (callable_with<decay_t<T>&, Args...>)>-{-};--template <typename T, typename R, typename... Args>-struct is_completion_handler_for<T, R(Args...) && noexcept>- : integral_constant<bool, (callable_with<decay_t<T>&&, Args...>)>-{-};--# endif // defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)--template <typename T, typename Signature0, typename... SignatureN>-struct is_completion_handler_for<T, Signature0, SignatureN...>- : integral_constant<bool, (- is_completion_handler_for<T, Signature0>::value- && is_completion_handler_for<T, SignatureN...>::value)>-{-};--} // namespace detail--template <typename T>-ASIO_CONCEPT completion_signature =- detail::is_completion_signature<T>::value;--#define ASIO_COMPLETION_SIGNATURE \- ::asio::completion_signature--template <typename T, typename... Signatures>-ASIO_CONCEPT completion_handler_for =- detail::are_completion_signatures<Signatures...>::value- && detail::is_completion_handler_for<T, Signatures...>::value;--#define ASIO_COMPLETION_HANDLER_FOR(sig) \- ::asio::completion_handler_for<sig>-#define ASIO_COMPLETION_HANDLER_FOR2(sig0, sig1) \- ::asio::completion_handler_for<sig0, sig1>-#define ASIO_COMPLETION_HANDLER_FOR3(sig0, sig1, sig2) \- ::asio::completion_handler_for<sig0, sig1, sig2>--#else // defined(ASIO_HAS_CONCEPTS)--#define ASIO_COMPLETION_SIGNATURE typename-#define ASIO_COMPLETION_HANDLER_FOR(sig) typename-#define ASIO_COMPLETION_HANDLER_FOR2(sig0, sig1) typename-#define ASIO_COMPLETION_HANDLER_FOR3(sig0, sig1, sig2) typename--#endif // defined(ASIO_HAS_CONCEPTS)--namespace detail {--template <typename T>-struct is_lvalue_completion_signature : false_type-{-};--template <typename R, typename... Args>-struct is_lvalue_completion_signature<R(Args...) &> : true_type-{-};--# if defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)--template <typename R, typename... Args>-struct is_lvalue_completion_signature<R(Args...) & noexcept> : true_type-{-};--# endif // defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)--template <typename... Signatures>-struct are_any_lvalue_completion_signatures : false_type-{-};--template <typename Sig0>-struct are_any_lvalue_completion_signatures<Sig0>- : is_lvalue_completion_signature<Sig0>-{-};--template <typename Sig0, typename... SigN>-struct are_any_lvalue_completion_signatures<Sig0, SigN...>- : integral_constant<bool, (- is_lvalue_completion_signature<Sig0>::value- || are_any_lvalue_completion_signatures<SigN...>::value)>-{-};--template <typename T>-struct is_rvalue_completion_signature : false_type-{-};--template <typename R, typename... Args>-struct is_rvalue_completion_signature<R(Args...) &&> : true_type-{-};--# if defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)--template <typename R, typename... Args>-struct is_rvalue_completion_signature<R(Args...) && noexcept> : true_type-{-};--# endif // defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)--template <typename... Signatures>-struct are_any_rvalue_completion_signatures : false_type-{-};--template <typename Sig0>-struct are_any_rvalue_completion_signatures<Sig0>- : is_rvalue_completion_signature<Sig0>-{-};--template <typename Sig0, typename... SigN>-struct are_any_rvalue_completion_signatures<Sig0, SigN...>- : integral_constant<bool, (- is_rvalue_completion_signature<Sig0>::value- || are_any_rvalue_completion_signatures<SigN...>::value)>-{-};--template <typename T>-struct simple_completion_signature;--template <typename R, typename... Args>-struct simple_completion_signature<R(Args...)>-{- typedef R type(Args...);-};--template <typename R, typename... Args>-struct simple_completion_signature<R(Args...) &>-{- typedef R type(Args...);-};--template <typename R, typename... Args>-struct simple_completion_signature<R(Args...) &&>-{- typedef R type(Args...);-};--# if defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)--template <typename R, typename... Args>-struct simple_completion_signature<R(Args...) noexcept>-{- typedef R type(Args...);-};--template <typename R, typename... Args>-struct simple_completion_signature<R(Args...) & noexcept>-{- typedef R type(Args...);-};--template <typename R, typename... Args>-struct simple_completion_signature<R(Args...) && noexcept>-{- typedef R type(Args...);-};--# endif // defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)--template <typename CompletionToken,- ASIO_COMPLETION_SIGNATURE... Signatures>-class completion_handler_async_result-{-public:- typedef CompletionToken completion_handler_type;- typedef void return_type;-- explicit completion_handler_async_result(completion_handler_type&)- {- }-- return_type get()- {- }-- template <typename Initiation,- ASIO_COMPLETION_HANDLER_FOR(Signatures...) RawCompletionToken,- typename... Args>- static return_type initiate(Initiation&& initiation,- RawCompletionToken&& token, Args&&... args)- {- static_cast<Initiation&&>(initiation)(- static_cast<RawCompletionToken&&>(token),- static_cast<Args&&>(args)...);- }--private:- completion_handler_async_result(- const completion_handler_async_result&) = delete;- completion_handler_async_result& operator=(- const completion_handler_async_result&) = delete;-};--} // namespace detail--#if defined(GENERATING_DOCUMENTATION)--/// An interface for customising the behaviour of an initiating function.-/**- * The async_result trait is a customisation point that is used within the- * initiating function for an @ref asynchronous_operation. The trait combines:- *- * @li the completion signature (or signatures) that describe the arguments that- * an asynchronous operation will pass to a completion handler;- *- * @li the @ref completion_token type supplied by the caller; and- *- * @li the operation's internal implementation.- *- * Specialisations of the trait must satisfy the @ref async_result_requirements,- * and are reponsible for determining:- *- * @li the concrete completion handler type to be called at the end of the- * asynchronous operation;- *- * @li the initiating function return type;- *- * @li how the return value of the initiating function is obtained; and- *- * @li how and when to launch the operation by invoking the supplied initiation- * function object.- *- * This template may be specialised for user-defined completion token types.- * The primary template assumes that the CompletionToken is the already a- * concrete completion handler.- *- * @note For backwards compatibility, the primary template implements member- * types and functions that are associated with legacy forms of the async_result- * trait. These are annotated as "Legacy" in the documentation below. User- * specialisations of this trait do not need to implement these in order to- * satisfy the @ref async_result_requirements.- *- * In general, implementers of asynchronous operations should use the- * async_initiate function rather than using the async_result trait directly.- */-template <typename CompletionToken,- ASIO_COMPLETION_SIGNATURE... Signatures>-class async_result-{-public:- /// (Legacy.) The concrete completion handler type for the specific signature.- typedef CompletionToken completion_handler_type;-- /// (Legacy.) The return type of the initiating function.- typedef void return_type;-- /// (Legacy.) 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);-- /// (Legacy.) Obtain the value to be returned from the initiating function.- return_type get();-- /// Initiate the asynchronous operation that will produce the result, and- /// obtain the value to be returned from the initiating function.- template <typename Initiation, typename RawCompletionToken, typename... Args>- static return_type initiate(- Initiation&& initiation,- RawCompletionToken&& token,- Args&&... args);--private:- async_result(const async_result&) = delete;- async_result& operator=(const async_result&) = delete;-};--#else // defined(GENERATING_DOCUMENTATION)--template <typename CompletionToken,- ASIO_COMPLETION_SIGNATURE... Signatures>-class async_result :- public conditional_t<- detail::are_any_lvalue_completion_signatures<Signatures...>::value- || !detail::are_any_rvalue_completion_signatures<Signatures...>::value,- detail::completion_handler_async_result<CompletionToken, Signatures...>,- async_result<CompletionToken,- typename detail::simple_completion_signature<Signatures>::type...>- >-{-public:- typedef conditional_t<- detail::are_any_lvalue_completion_signatures<Signatures...>::value- || !detail::are_any_rvalue_completion_signatures<Signatures...>::value,- detail::completion_handler_async_result<CompletionToken, Signatures...>,- async_result<CompletionToken,- typename detail::simple_completion_signature<Signatures>::type...>- > base_type;-- using base_type::base_type;--private:- async_result(const async_result&) = delete;- async_result& operator=(const async_result&) = delete;-};--template <ASIO_COMPLETION_SIGNATURE... Signatures>-class async_result<void, Signatures...>-{- // Empty.-};--#endif // defined(GENERATING_DOCUMENTATION)--/// Helper template to deduce the handler type from a CompletionToken, capture-/// a local copy of the handler, and then create an async_result for the-/// handler.-template <typename CompletionToken,- ASIO_COMPLETION_SIGNATURE... Signatures>-struct async_completion-{- /// The real handler type to be used for the asynchronous operation.- typedef typename asio::async_result<- decay_t<CompletionToken>, Signatures...>::completion_handler_type- completion_handler_type;-- /// 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<conditional_t<- is_same<CompletionToken, completion_handler_type>::value,- completion_handler_type&, CompletionToken&&>>(token)),- result(completion_handler)- {- }-- /// A copy of, or reference to, a real handler object.- conditional_t<- is_same<CompletionToken, completion_handler_type>::value,- completion_handler_type&, completion_handler_type> completion_handler;-- /// The result of the asynchronous operation's initiating function.- async_result<decay_t<CompletionToken>, Signatures...> result;-};--namespace detail {--struct async_result_memfns_base-{- void initiate();-};--template <typename T>-struct async_result_memfns_derived- : T, async_result_memfns_base-{-};--template <typename T, T>-struct async_result_memfns_check-{-};--template <typename>-char (&async_result_initiate_memfn_helper(...))[2];--template <typename T>-char async_result_initiate_memfn_helper(- async_result_memfns_check<- void (async_result_memfns_base::*)(),- &async_result_memfns_derived<T>::initiate>*);--template <typename CompletionToken,- ASIO_COMPLETION_SIGNATURE... Signatures>-struct async_result_has_initiate_memfn- : integral_constant<bool, sizeof(async_result_initiate_memfn_helper<- async_result<decay_t<CompletionToken>, Signatures...>- >(0)) != 1>-{-};--} // namespace detail--#if defined(GENERATING_DOCUMENTATION)-# define ASIO_INITFN_RESULT_TYPE(ct, sig) \- void_or_deduced-# define ASIO_INITFN_RESULT_TYPE2(ct, sig0, sig1) \- void_or_deduced-# define ASIO_INITFN_RESULT_TYPE3(ct, sig0, sig1, sig2) \- void_or_deduced-#else-# define ASIO_INITFN_RESULT_TYPE(ct, sig) \- typename ::asio::async_result< \- typename ::asio::decay<ct>::type, sig>::return_type-# define ASIO_INITFN_RESULT_TYPE2(ct, sig0, sig1) \- typename ::asio::async_result< \- typename ::asio::decay<ct>::type, sig0, sig1>::return_type-# define ASIO_INITFN_RESULT_TYPE3(ct, sig0, sig1, sig2) \- typename ::asio::async_result< \- typename ::asio::decay<ct>::type, sig0, sig1, sig2>::return_type-#define ASIO_HANDLER_TYPE(ct, sig) \- typename ::asio::async_result< \- typename ::asio::decay<ct>::type, sig>::completion_handler_type-#define ASIO_HANDLER_TYPE2(ct, sig0, sig1) \- typename ::asio::async_result< \- typename ::asio::decay<ct>::type, \- sig0, sig1>::completion_handler_type-#define ASIO_HANDLER_TYPE3(ct, sig0, sig1, sig2) \- typename ::asio::async_result< \- typename ::asio::decay<ct>::type, \- sig0, sig1, sig2>::completion_handler_type-#endif--#if defined(GENERATING_DOCUMENTATION)-# define ASIO_INITFN_AUTO_RESULT_TYPE(ct, sig) \- auto-# define ASIO_INITFN_AUTO_RESULT_TYPE2(ct, sig0, sig1) \- auto-# define ASIO_INITFN_AUTO_RESULT_TYPE3(ct, sig0, sig1, sig2) \- auto-#elif defined(ASIO_HAS_RETURN_TYPE_DEDUCTION)-# define ASIO_INITFN_AUTO_RESULT_TYPE(ct, sig) \- auto-# define ASIO_INITFN_AUTO_RESULT_TYPE2(ct, sig0, sig1) \- auto-# define ASIO_INITFN_AUTO_RESULT_TYPE3(ct, sig0, sig1, sig2) \- auto-#else-# define ASIO_INITFN_AUTO_RESULT_TYPE(ct, sig) \- ASIO_INITFN_RESULT_TYPE(ct, sig)-# define ASIO_INITFN_AUTO_RESULT_TYPE2(ct, sig0, sig1) \- ASIO_INITFN_RESULT_TYPE2(ct, sig0, sig1)-# define ASIO_INITFN_AUTO_RESULT_TYPE3(ct, sig0, sig1, sig2) \- ASIO_INITFN_RESULT_TYPE3(ct, sig0, sig1, sig2)-#endif--#if defined(GENERATING_DOCUMENTATION)-# define ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ct, sig) \- auto-# define ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX2(ct, sig0, sig1) \- auto-# define ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX3(ct, sig0, sig1, sig2) \- auto-# define ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(expr)-#elif defined(ASIO_HAS_RETURN_TYPE_DEDUCTION)-# define ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ct, sig) \- auto-# define ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX2(ct, sig0, sig1) \- auto-# define ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX3(ct, sig0, sig1, sig2) \- auto-# define ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(expr)-#else-# define ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ct, sig) \- auto-# define ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX2(ct, sig0, sig1) \- auto-# define ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX3(ct, sig0, sig1, sig2) \- auto-# define ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(expr) -> decltype expr-#endif--#if defined(GENERATING_DOCUMENTATION)-# define ASIO_INITFN_DEDUCED_RESULT_TYPE(ct, sig, expr) \- void_or_deduced-# define ASIO_INITFN_DEDUCED_RESULT_TYPE2(ct, sig0, sig1, expr) \- void_or_deduced-# define ASIO_INITFN_DEDUCED_RESULT_TYPE3(ct, sig0, sig1, sig2, expr) \- void_or_deduced-#else-# define ASIO_INITFN_DEDUCED_RESULT_TYPE(ct, sig, expr) \- decltype expr-# define ASIO_INITFN_DEDUCED_RESULT_TYPE2(ct, sig0, sig1, expr) \- decltype expr-# define ASIO_INITFN_DEDUCED_RESULT_TYPE3(ct, sig0, sig1, sig2, expr) \- decltype expr-#endif--#if defined(GENERATING_DOCUMENTATION)--template <typename CompletionToken,- completion_signature... Signatures,- typename Initiation, typename... Args>-void_or_deduced async_initiate(- Initiation&& initiation,- type_identity_t<CompletionToken>& token,- Args&&... args);--#else // defined(GENERATING_DOCUMENTATION)--template <typename CompletionToken,- ASIO_COMPLETION_SIGNATURE... Signatures,- typename Initiation, typename... Args>-inline auto async_initiate(Initiation&& initiation,- type_identity_t<CompletionToken>& token, Args&&... args)- -> decltype(enable_if_t<- enable_if_t<- detail::are_completion_signatures<Signatures...>::value,- detail::async_result_has_initiate_memfn<- CompletionToken, Signatures...>>::value,- async_result<decay_t<CompletionToken>, Signatures...>>::initiate(- static_cast<Initiation&&>(initiation),- static_cast<CompletionToken&&>(token),- static_cast<Args&&>(args)...))-{- return async_result<decay_t<CompletionToken>, Signatures...>::initiate(- static_cast<Initiation&&>(initiation),- static_cast<CompletionToken&&>(token),- static_cast<Args&&>(args)...);-}--template <- ASIO_COMPLETION_SIGNATURE... Signatures,- typename CompletionToken, typename Initiation, typename... Args>-inline auto async_initiate(Initiation&& initiation,- CompletionToken&& token, Args&&... args)- -> decltype(enable_if_t<- enable_if_t<- detail::are_completion_signatures<Signatures...>::value,- detail::async_result_has_initiate_memfn<- CompletionToken, Signatures...>>::value,- async_result<decay_t<CompletionToken>, Signatures...>>::initiate(- static_cast<Initiation&&>(initiation),- static_cast<CompletionToken&&>(token),- static_cast<Args&&>(args)...))-{- return async_result<decay_t<CompletionToken>, Signatures...>::initiate(- static_cast<Initiation&&>(initiation),- static_cast<CompletionToken&&>(token),- static_cast<Args&&>(args)...);-}--template <typename CompletionToken,- ASIO_COMPLETION_SIGNATURE... Signatures,- typename Initiation, typename... Args>-inline typename enable_if_t<- !enable_if_t<- detail::are_completion_signatures<Signatures...>::value,- detail::async_result_has_initiate_memfn<- CompletionToken, Signatures...>>::value,- async_result<decay_t<CompletionToken>, Signatures...>- >::return_type-async_initiate(Initiation&& initiation,- type_identity_t<CompletionToken>& token, Args&&... args)-{- async_completion<CompletionToken, Signatures...> completion(token);-- static_cast<Initiation&&>(initiation)(- static_cast<- typename async_result<decay_t<CompletionToken>,- Signatures...>::completion_handler_type&&>(- completion.completion_handler),- static_cast<Args&&>(args)...);-- return completion.result.get();-}--template <ASIO_COMPLETION_SIGNATURE... Signatures,- typename CompletionToken, typename Initiation, typename... Args>-inline typename enable_if_t<- !enable_if_t<- detail::are_completion_signatures<Signatures...>::value,- detail::async_result_has_initiate_memfn<- CompletionToken, Signatures...>>::value,- async_result<decay_t<CompletionToken>, Signatures...>- >::return_type-async_initiate(Initiation&& initiation, CompletionToken&& token, Args&&... args)-{- async_completion<CompletionToken, Signatures...> completion(token);-- static_cast<Initiation&&>(initiation)(- static_cast<- typename async_result<decay_t<CompletionToken>,- Signatures...>::completion_handler_type&&>(- completion.completion_handler),- static_cast<Args&&>(args)...);-- return completion.result.get();-}--#endif // defined(GENERATING_DOCUMENTATION)--#if defined(ASIO_HAS_CONCEPTS)--namespace detail {--template <typename... Signatures>-struct initiation_archetype-{- template <completion_handler_for<Signatures...> CompletionHandler>- void operator()(CompletionHandler&&) const- {- }-};--} // namespace detail--template <typename T, typename... Signatures>-ASIO_CONCEPT completion_token_for =- detail::are_completion_signatures<Signatures...>::value- &&- requires(T&& t)- {- async_initiate<T, Signatures...>(- detail::initiation_archetype<Signatures...>{}, t);- };--#define ASIO_COMPLETION_TOKEN_FOR(sig) \- ::asio::completion_token_for<sig>-#define ASIO_COMPLETION_TOKEN_FOR2(sig0, sig1) \- ::asio::completion_token_for<sig0, sig1>-#define ASIO_COMPLETION_TOKEN_FOR3(sig0, sig1, sig2) \- ::asio::completion_token_for<sig0, sig1, sig2>--#else // defined(ASIO_HAS_CONCEPTS)--#define ASIO_COMPLETION_TOKEN_FOR(sig) typename-#define ASIO_COMPLETION_TOKEN_FOR2(sig0, sig1) typename-#define ASIO_COMPLETION_TOKEN_FOR3(sig0, sig1, sig2) typename--#endif // defined(ASIO_HAS_CONCEPTS)--namespace detail {--struct async_operation_probe {};-struct async_operation_probe_result {};--template <typename Call, typename = void>-struct is_async_operation_call : false_type-{-};--template <typename Call>-struct is_async_operation_call<Call,- void_t<- enable_if_t<- is_same<- result_of_t<Call>,- async_operation_probe_result- >::value- >- >- > : true_type-{-};--} // namespace detail--#if !defined(GENERATING_DOCUMENTATION)--template <typename... Signatures>-class async_result<detail::async_operation_probe, Signatures...>-{-public:- typedef detail::async_operation_probe_result return_type;-- template <typename Initiation, typename... InitArgs>- static return_type initiate(Initiation&&,- detail::async_operation_probe, InitArgs&&...)- {- return return_type();- }-};--#endif // !defined(GENERATING_DOCUMENTATION)--#if defined(GENERATING_DOCUMENTATION)--/// The is_async_operation trait detects whether a type @c T and arguments-/// @c Args... may be used to initiate an asynchronous operation.-/**- * Class template @c is_async_operation is a trait is derived from @c true_type- * if the expression <tt>T(Args..., token)</tt> initiates an asynchronous- * operation, where @c token is an unspecified completion token type. Otherwise,- * @c is_async_operation is derived from @c false_type.- */-template <typename T, typename... Args>-struct is_async_operation : integral_constant<bool, automatically_determined>-{-};--#else // defined(GENERATING_DOCUMENTATION)--template <typename T, typename... Args>-struct is_async_operation :- detail::is_async_operation_call<- T(Args..., detail::async_operation_probe)>-{-};--#endif // defined(GENERATING_DOCUMENTATION)--#if defined(ASIO_HAS_CONCEPTS)--template <typename T, typename... Args>-ASIO_CONCEPT async_operation = is_async_operation<T, Args...>::value;--#define ASIO_ASYNC_OPERATION \- ::asio::async_operation-#define ASIO_ASYNC_OPERATION1(a0) \- ::asio::async_operation<a0>-#define ASIO_ASYNC_OPERATION2(a0, a1) \- ::asio::async_operation<a0, a1>-#define ASIO_ASYNC_OPERATION3(a0, a1, a2) \- ::asio::async_operation<a0, a1, a2>--#else // defined(ASIO_HAS_CONCEPTS)--#define ASIO_ASYNC_OPERATION typename-#define ASIO_ASYNC_OPERATION1(a0) typename-#define ASIO_ASYNC_OPERATION2(a0, a1) typename-#define ASIO_ASYNC_OPERATION3(a0, a1, a2) typename--#endif // defined(ASIO_HAS_CONCEPTS)--namespace detail {--struct completion_signature_probe {};--template <typename... T>-struct completion_signature_probe_result-{- template <template <typename...> class Op>- struct apply- {- typedef Op<T...> type;- };-};--template <typename T>-struct completion_signature_probe_result<T>-{- typedef T type;-- template <template <typename...> class Op>- struct apply- {- typedef Op<T> type;- };-};--template <>-struct completion_signature_probe_result<void>-{- template <template <typename...> class Op>- struct apply- {- typedef Op<> type;- };-};--} // namespace detail--#if !defined(GENERATING_DOCUMENTATION)--template <typename... Signatures>-class async_result<detail::completion_signature_probe, Signatures...>-{-public:- typedef detail::completion_signature_probe_result<Signatures...> return_type;-- template <typename Initiation, typename... InitArgs>- static return_type initiate(Initiation&&,- detail::completion_signature_probe, InitArgs&&...)- {- return return_type();- }-};--template <typename Signature>-class async_result<detail::completion_signature_probe, Signature>-{-public:- typedef detail::completion_signature_probe_result<Signature> return_type;-- template <typename Initiation, typename... InitArgs>- static return_type initiate(Initiation&&,- detail::completion_signature_probe, InitArgs&&...)- {- return return_type();- }-};--#endif // !defined(GENERATING_DOCUMENTATION)--#if defined(GENERATING_DOCUMENTATION)--/// The completion_signature_of trait determines the completion signature-/// of an asynchronous operation.-/**- * Class template @c completion_signature_of is a trait with a member type- * alias @c type that denotes the completion signature of the asynchronous- * operation initiated by the expression <tt>T(Args..., token)</tt> operation,- * where @c token is an unspecified completion token type. If the asynchronous- * operation does not have exactly one completion signature, the instantion of- * the trait is well-formed but the member type alias @c type is omitted. If- * the expression <tt>T(Args..., token)</tt> is not an asynchronous operation- * then use of the trait is ill-formed.- */-template <typename T, typename... Args>-struct completion_signature_of-{- typedef automatically_determined type;-};--#else // defined(GENERATING_DOCUMENTATION)--template <typename T, typename... Args>-struct completion_signature_of :- result_of_t<T(Args..., detail::completion_signature_probe)>-{-};--#endif // defined(GENERATING_DOCUMENTATION)--template <typename T, typename... Args>-using completion_signature_of_t =- typename completion_signature_of<T, Args...>::type;--} // namespace asio--#include "asio/detail/pop_options.hpp"--#include "asio/default_completion_token.hpp"+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_ASYNC_RESULT_HPP+#define ASIO_ASYNC_RESULT_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/detail/type_traits.hpp"+#include "asio/detail/variadic_templates.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {++#if defined(ASIO_HAS_CONCEPTS) \+ && defined(ASIO_HAS_VARIADIC_TEMPLATES) \+ && defined(ASIO_HAS_DECLTYPE)++namespace detail {++template <typename T>+struct is_completion_signature : false_type+{+};++template <typename R, typename... Args>+struct is_completion_signature<R(Args...)> : true_type+{+};++#if defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)++template <typename R, typename... Args>+struct is_completion_signature<R(Args...) &> : true_type+{+};++template <typename R, typename... Args>+struct is_completion_signature<R(Args...) &&> : true_type+{+};++# if defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)++template <typename R, typename... Args>+struct is_completion_signature<R(Args...) noexcept> : true_type+{+};++template <typename R, typename... Args>+struct is_completion_signature<R(Args...) & noexcept> : true_type+{+};++template <typename R, typename... Args>+struct is_completion_signature<R(Args...) && noexcept> : true_type+{+};++# endif // defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)+#endif // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)++template <typename... T>+struct are_completion_signatures : false_type+{+};++template <typename T0>+struct are_completion_signatures<T0>+ : is_completion_signature<T0>+{+};++template <typename T0, typename... TN>+struct are_completion_signatures<T0, TN...>+ : integral_constant<bool, (+ is_completion_signature<T0>::value+ && are_completion_signatures<TN...>::value)>+{+};++template <typename T, typename... Args>+ASIO_CONCEPT callable_with = requires(T&& t, Args&&... args)+{+ static_cast<T&&>(t)(static_cast<Args&&>(args)...);+};++template <typename T, typename... Signatures>+struct is_completion_handler_for : false_type+{+};++template <typename T, typename R, typename... Args>+struct is_completion_handler_for<T, R(Args...)>+ : integral_constant<bool, (callable_with<T, Args...>)>+{+};++#if defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)++template <typename T, typename R, typename... Args>+struct is_completion_handler_for<T, R(Args...) &>+ : integral_constant<bool, (callable_with<T&, Args...>)>+{+};++template <typename T, typename R, typename... Args>+struct is_completion_handler_for<T, R(Args...) &&>+ : integral_constant<bool, (callable_with<T&&, Args...>)>+{+};++# if defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)++template <typename T, typename R, typename... Args>+struct is_completion_handler_for<T, R(Args...) noexcept>+ : integral_constant<bool, (callable_with<T, Args...>)>+{+};++template <typename T, typename R, typename... Args>+struct is_completion_handler_for<T, R(Args...) & noexcept>+ : integral_constant<bool, (callable_with<T&, Args...>)>+{+};++template <typename T, typename R, typename... Args>+struct is_completion_handler_for<T, R(Args...) && noexcept>+ : integral_constant<bool, (callable_with<T&&, Args...>)>+{+};++# endif // defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)+#endif // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)++template <typename T, typename Signature0, typename... SignatureN>+struct is_completion_handler_for<T, Signature0, SignatureN...>+ : integral_constant<bool, (+ is_completion_handler_for<T, Signature0>::value+ && is_completion_handler_for<T, SignatureN...>::value)>+{+};++} // namespace detail++template <typename T>+ASIO_CONCEPT completion_signature =+ detail::is_completion_signature<T>::value;++#define ASIO_COMPLETION_SIGNATURE \+ ::asio::completion_signature++template <typename T, typename... Signatures>+ASIO_CONCEPT completion_handler_for =+ detail::are_completion_signatures<Signatures...>::value+ && detail::is_completion_handler_for<T, Signatures...>::value;++#define ASIO_COMPLETION_HANDLER_FOR(sig) \+ ::asio::completion_handler_for<sig>+#define ASIO_COMPLETION_HANDLER_FOR2(sig0, sig1) \+ ::asio::completion_handler_for<sig0, sig1>+#define ASIO_COMPLETION_HANDLER_FOR3(sig0, sig1, sig2) \+ ::asio::completion_handler_for<sig0, sig1, sig2>++#else // defined(ASIO_HAS_CONCEPTS)+ // && defined(ASIO_HAS_VARIADIC_TEMPLATES)+ // && defined(ASIO_HAS_DECLTYPE)++#define ASIO_COMPLETION_SIGNATURE typename+#define ASIO_COMPLETION_HANDLER_FOR(sig) typename+#define ASIO_COMPLETION_HANDLER_FOR2(sig0, sig1) typename+#define ASIO_COMPLETION_HANDLER_FOR3(sig0, sig1, sig2) typename++#endif // defined(ASIO_HAS_CONCEPTS)+ // && defined(ASIO_HAS_VARIADIC_TEMPLATES)+ // && defined(ASIO_HAS_DECLTYPE)++namespace detail {++template <typename T>+struct is_simple_completion_signature : false_type+{+};++template <typename T>+struct simple_completion_signature;++#if defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename R, typename... Args>+struct is_simple_completion_signature<R(Args...)> : true_type+{+};++template <typename... Signatures>+struct are_simple_completion_signatures : false_type+{+};++template <typename Sig0>+struct are_simple_completion_signatures<Sig0>+ : is_simple_completion_signature<Sig0>+{+};++template <typename Sig0, typename... SigN>+struct are_simple_completion_signatures<Sig0, SigN...>+ : integral_constant<bool, (+ is_simple_completion_signature<Sig0>::value+ && are_simple_completion_signatures<SigN...>::value)>+{+};++template <typename R, typename... Args>+struct simple_completion_signature<R(Args...)>+{+ typedef R type(Args...);+};++#if defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)++template <typename R, typename... Args>+struct simple_completion_signature<R(Args...) &>+{+ typedef R type(Args...);+};++template <typename R, typename... Args>+struct simple_completion_signature<R(Args...) &&>+{+ typedef R type(Args...);+};++# if defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)++template <typename R, typename... Args>+struct simple_completion_signature<R(Args...) noexcept>+{+ typedef R type(Args...);+};++template <typename R, typename... Args>+struct simple_completion_signature<R(Args...) & noexcept>+{+ typedef R type(Args...);+};++template <typename R, typename... Args>+struct simple_completion_signature<R(Args...) && noexcept>+{+ typedef R type(Args...);+};++# endif // defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)+#endif // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename R>+struct is_simple_completion_signature<R()> : true_type+{+};++#define ASIO_PRIVATE_SIMPLE_SIG_DEF(n) \+ template <typename R, ASIO_VARIADIC_TPARAMS(n)> \+ struct is_simple_completion_signature<R(ASIO_VARIADIC_TARGS(n))> \+ : true_type \+ { \+ }; \+ /**/+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_SIMPLE_SIG_DEF)+#undef ASIO_PRIVATE_SIMPLE_SIG_DEF++template <typename Sig0 = void, typename Sig1 = void,+ typename Sig2 = void, typename = void>+struct are_simple_completion_signatures : false_type+{+};++template <typename Sig0>+struct are_simple_completion_signatures<Sig0>+ : is_simple_completion_signature<Sig0>+{+};++template <typename Sig0, typename Sig1>+struct are_simple_completion_signatures<Sig0, Sig1>+ : integral_constant<bool,+ (is_simple_completion_signature<Sig0>::value+ && is_simple_completion_signature<Sig1>::value)>+{+};++template <typename Sig0, typename Sig1, typename Sig2>+struct are_simple_completion_signatures<Sig0, Sig1, Sig2>+ : integral_constant<bool,+ (is_simple_completion_signature<Sig0>::value+ && is_simple_completion_signature<Sig1>::value+ && is_simple_completion_signature<Sig2>::value)>+{+};++template <>+struct simple_completion_signature<void>+{+ typedef void type;+};++template <typename R>+struct simple_completion_signature<R()>+{+ typedef R type();+};++#define ASIO_PRIVATE_SIMPLE_SIG_DEF(n) \+ template <typename R, ASIO_VARIADIC_TPARAMS(n)> \+ struct simple_completion_signature<R(ASIO_VARIADIC_TARGS(n))> \+ { \+ typedef R type(ASIO_VARIADIC_TARGS(n)); \+ }; \+ /**/+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_SIMPLE_SIG_DEF)+#undef ASIO_PRIVATE_SIMPLE_SIG_DEF++#if defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)++template <typename R>+struct simple_completion_signature<R() &>+{+ typedef R type();+};++template <typename R>+struct simple_completion_signature<R() &&>+{+ typedef R type();+};++#define ASIO_PRIVATE_SIMPLE_SIG_DEF(n) \+ template <typename R, ASIO_VARIADIC_TPARAMS(n)> \+ struct simple_completion_signature< \+ R(ASIO_VARIADIC_TARGS(n)) &> \+ { \+ typedef R type(ASIO_VARIADIC_TARGS(n)); \+ }; \+ \+ template <typename R, ASIO_VARIADIC_TPARAMS(n)> \+ struct simple_completion_signature< \+ R(ASIO_VARIADIC_TARGS(n)) &&> \+ { \+ typedef R type(ASIO_VARIADIC_TARGS(n)); \+ }; \+ /**/+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_SIMPLE_SIG_DEF)+#undef ASIO_PRIVATE_SIMPLE_SIG_DEF++# if defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)++template <typename R>+struct simple_completion_signature<R() noexcept>+{+ typedef R type();+};++template <typename R>+struct simple_completion_signature<R() & noexcept>+{+ typedef R type();+};++template <typename R>+struct simple_completion_signature<R() && noexcept>+{+ typedef R type();+};++#define ASIO_PRIVATE_SIMPLE_SIG_DEF(n) \+ template <typename R, ASIO_VARIADIC_TPARAMS(n)> \+ struct simple_completion_signature< \+ R(ASIO_VARIADIC_TARGS(n)) noexcept> \+ { \+ typedef R type(ASIO_VARIADIC_TARGS(n)); \+ }; \+ \+ template <typename R, ASIO_VARIADIC_TPARAMS(n)> \+ struct simple_completion_signature< \+ R(ASIO_VARIADIC_TARGS(n)) & noexcept> \+ { \+ typedef R type(ASIO_VARIADIC_TARGS(n)); \+ }; \+ \+ template <typename R, ASIO_VARIADIC_TPARAMS(n)> \+ struct simple_completion_signature< \+ R(ASIO_VARIADIC_TARGS(n)) && noexcept> \+ { \+ typedef R type(ASIO_VARIADIC_TARGS(n)); \+ }; \+ /**/+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_SIMPLE_SIG_DEF)+#undef ASIO_PRIVATE_SIMPLE_SIG_DEF++# endif // defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)+#endif // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++#if defined(ASIO_HAS_VARIADIC_TEMPLATES) \+ || defined(GENERATING_DOCUMENTATION)++# define ASIO_COMPLETION_SIGNATURES_TPARAMS \+ ASIO_COMPLETION_SIGNATURE... Signatures++# define ASIO_COMPLETION_SIGNATURES_TSPECPARAMS \+ ASIO_COMPLETION_SIGNATURE... Signatures++# define ASIO_COMPLETION_SIGNATURES_TARGS Signatures...++# define ASIO_COMPLETION_SIGNATURES_TSIMPLEARGS \+ typename asio::detail::simple_completion_signature< \+ Signatures>::type...++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)+ // || defined(GENERATING_DOCUMENTATION)++# define ASIO_COMPLETION_SIGNATURES_TPARAMS \+ typename Sig0 = void, \+ typename Sig1 = void, \+ typename Sig2 = void++# define ASIO_COMPLETION_SIGNATURES_TSPECPARAMS \+ typename Sig0, \+ typename Sig1, \+ typename Sig2++# define ASIO_COMPLETION_SIGNATURES_TARGS Sig0, Sig1, Sig2++# define ASIO_COMPLETION_SIGNATURES_TSIMPLEARGS \+ typename ::asio::detail::simple_completion_signature<Sig0>::type, \+ typename ::asio::detail::simple_completion_signature<Sig1>::type, \+ typename ::asio::detail::simple_completion_signature<Sig2>::type++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+ // || defined(GENERATING_DOCUMENTATION)++template <typename CompletionToken, ASIO_COMPLETION_SIGNATURES_TPARAMS>+class completion_handler_async_result+{+public:+ typedef CompletionToken completion_handler_type;+ typedef void return_type;++ explicit completion_handler_async_result(completion_handler_type&)+ {+ }++ return_type get()+ {+ }++#if defined(ASIO_HAS_VARIADIC_TEMPLATES)++ template <typename Initiation,+ ASIO_COMPLETION_HANDLER_FOR(Signatures...) RawCompletionToken,+ typename... Args>+ static return_type initiate(+ ASIO_MOVE_ARG(Initiation) initiation,+ ASIO_MOVE_ARG(RawCompletionToken) token,+ ASIO_MOVE_ARG(Args)... args)+ {+ ASIO_MOVE_CAST(Initiation)(initiation)(+ ASIO_MOVE_CAST(RawCompletionToken)(token),+ ASIO_MOVE_CAST(Args)(args)...);+ }++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++ template <typename Initiation, typename RawCompletionToken>+ static return_type initiate(+ ASIO_MOVE_ARG(Initiation) initiation,+ ASIO_MOVE_ARG(RawCompletionToken) token)+ {+ ASIO_MOVE_CAST(Initiation)(initiation)(+ ASIO_MOVE_CAST(RawCompletionToken)(token));+ }++#define ASIO_PRIVATE_INITIATE_DEF(n) \+ template <typename Initiation, \+ typename RawCompletionToken, \+ ASIO_VARIADIC_TPARAMS(n)> \+ static return_type initiate( \+ ASIO_MOVE_ARG(Initiation) initiation, \+ ASIO_MOVE_ARG(RawCompletionToken) token, \+ ASIO_VARIADIC_MOVE_PARAMS(n)) \+ { \+ ASIO_MOVE_CAST(Initiation)(initiation)( \+ ASIO_MOVE_CAST(RawCompletionToken)(token), \+ ASIO_VARIADIC_MOVE_ARGS(n)); \+ } \+ /**/+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_INITIATE_DEF)+#undef ASIO_PRIVATE_INITIATE_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++private:+ completion_handler_async_result(+ const completion_handler_async_result&) ASIO_DELETED;+ completion_handler_async_result& operator=(+ const completion_handler_async_result&) ASIO_DELETED;+};++} // namespace detail++#if defined(GENERATING_DOCUMENTATION)++/// An interface for customising the behaviour of an initiating function.+/**+ * The async_result traits class is used for determining:+ *+ * @li the concrete completion handler type to be called at the end of the+ * asynchronous operation;+ *+ * @li the initiating function return type; and+ *+ * @li how the return value of the initiating function is obtained.+ *+ * The trait allows the handler and return types to be determined at the point+ * where the specific completion handler signature is known.+ *+ * This template may be specialised for user-defined completion token types.+ * The primary template assumes that the CompletionToken is the completion+ * handler.+ */+template <typename CompletionToken, ASIO_COMPLETION_SIGNATURES_TPARAMS>+class async_result+{+public:+ /// The concrete completion handler type for the specific signature.+ typedef CompletionToken completion_handler_type;++ /// The return type of the initiating function.+ typedef void return_type;++ /// Construct an async result from a given handler.+ /**+ * When using a specalised async_result, the constructor has an opportunity+ * to initialise some state associated with the completion handler, which is+ * then returned from the initiating function.+ */+ explicit async_result(completion_handler_type& h);++ /// Obtain the value to be returned from the initiating function.+ return_type get();++ /// Initiate the asynchronous operation that will produce the result, and+ /// obtain the value to be returned from the initiating function.+ template <typename Initiation, typename RawCompletionToken, typename... Args>+ static return_type initiate(+ ASIO_MOVE_ARG(Initiation) initiation,+ ASIO_MOVE_ARG(RawCompletionToken) token,+ ASIO_MOVE_ARG(Args)... args);++private:+ async_result(const async_result&) ASIO_DELETED;+ async_result& operator=(const async_result&) ASIO_DELETED;+};++#else // defined(GENERATING_DOCUMENTATION)++#if defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)++template <typename CompletionToken, ASIO_COMPLETION_SIGNATURES_TPARAMS>+class async_result :+ public conditional<+ detail::are_simple_completion_signatures<+ ASIO_COMPLETION_SIGNATURES_TARGS>::value,+ detail::completion_handler_async_result<+ CompletionToken, ASIO_COMPLETION_SIGNATURES_TARGS>,+ async_result<CompletionToken,+ ASIO_COMPLETION_SIGNATURES_TSIMPLEARGS>+ >::type+{+public:+ typedef typename conditional<+ detail::are_simple_completion_signatures<+ ASIO_COMPLETION_SIGNATURES_TARGS>::value,+ detail::completion_handler_async_result<+ CompletionToken, ASIO_COMPLETION_SIGNATURES_TARGS>,+ async_result<CompletionToken,+ ASIO_COMPLETION_SIGNATURES_TSIMPLEARGS>+ >::type base_type;++ using base_type::base_type;++private:+ async_result(const async_result&) ASIO_DELETED;+ async_result& operator=(const async_result&) ASIO_DELETED;+};++#else // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)++template <typename CompletionToken, ASIO_COMPLETION_SIGNATURES_TPARAMS>+class async_result :+ public detail::completion_handler_async_result<+ CompletionToken, ASIO_COMPLETION_SIGNATURES_TARGS>+{+public:+ explicit async_result(CompletionToken& h)+ : detail::completion_handler_async_result<+ CompletionToken, ASIO_COMPLETION_SIGNATURES_TARGS>(h)+ {+ }++private:+ async_result(const async_result&) ASIO_DELETED;+ async_result& operator=(const async_result&) ASIO_DELETED;+};++#endif // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)++template <ASIO_COMPLETION_SIGNATURES_TSPECPARAMS>+class async_result<void, ASIO_COMPLETION_SIGNATURES_TARGS>+{+ // Empty.+};++#endif // defined(GENERATING_DOCUMENTATION)++/// Helper template to deduce the handler type from a CompletionToken, capture+/// a local copy of the handler, and then create an async_result for the+/// handler.+template <typename CompletionToken, ASIO_COMPLETION_SIGNATURES_TPARAMS>+struct async_completion+{+ /// The real handler type to be used for the asynchronous operation.+ typedef typename asio::async_result<+ typename decay<CompletionToken>::type,+ ASIO_COMPLETION_SIGNATURES_TARGS>::completion_handler_type+ completion_handler_type;++#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)+ /// Constructor.+ /**+ * The constructor creates the concrete completion handler and makes the link+ * between the handler and the asynchronous result.+ */+ explicit async_completion(CompletionToken& token)+ : completion_handler(static_cast<typename conditional<+ is_same<CompletionToken, completion_handler_type>::value,+ completion_handler_type&, CompletionToken&&>::type>(token)),+ result(completion_handler)+ {+ }+#else // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)+ explicit async_completion(typename decay<CompletionToken>::type& token)+ : completion_handler(token),+ result(completion_handler)+ {+ }++ explicit async_completion(const typename decay<CompletionToken>::type& token)+ : completion_handler(token),+ result(completion_handler)+ {+ }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)++ /// A copy of, or reference to, a real handler object.+#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)+ typename conditional<+ is_same<CompletionToken, completion_handler_type>::value,+ completion_handler_type&, completion_handler_type>::type completion_handler;+#else // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)+ completion_handler_type completion_handler;+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)++ /// The result of the asynchronous operation's initiating function.+ async_result<typename decay<CompletionToken>::type,+ ASIO_COMPLETION_SIGNATURES_TARGS> result;+};++namespace detail {++template <typename CompletionToken, ASIO_COMPLETION_SIGNATURES_TPARAMS>+struct async_result_helper+ : async_result<typename decay<CompletionToken>::type,+ ASIO_COMPLETION_SIGNATURES_TARGS>+{+};++struct async_result_memfns_base+{+ void initiate();+};++template <typename T>+struct async_result_memfns_derived+ : T, async_result_memfns_base+{+};++template <typename T, T>+struct async_result_memfns_check+{+};++template <typename>+char (&async_result_initiate_memfn_helper(...))[2];++template <typename T>+char async_result_initiate_memfn_helper(+ async_result_memfns_check<+ void (async_result_memfns_base::*)(),+ &async_result_memfns_derived<T>::initiate>*);++template <typename CompletionToken, ASIO_COMPLETION_SIGNATURES_TPARAMS>+struct async_result_has_initiate_memfn+ : integral_constant<bool, sizeof(async_result_initiate_memfn_helper<+ async_result<typename decay<CompletionToken>::type,+ ASIO_COMPLETION_SIGNATURES_TARGS>+ >(0)) != 1>+{+};++} // namespace detail++#if defined(GENERATING_DOCUMENTATION)+# define ASIO_INITFN_RESULT_TYPE(ct, sig) \+ void_or_deduced+# define ASIO_INITFN_RESULT_TYPE2(ct, sig0, sig1) \+ void_or_deduced+# define ASIO_INITFN_RESULT_TYPE3(ct, sig0, sig1, sig2) \+ void_or_deduced+#elif defined(_MSC_VER) && (_MSC_VER < 1500)+# define ASIO_INITFN_RESULT_TYPE(ct, sig) \+ typename ::asio::detail::async_result_helper< \+ ct, sig>::return_type+# define ASIO_INITFN_RESULT_TYPE2(ct, sig0, sig1) \+ typename ::asio::detail::async_result_helper< \+ ct, sig0, sig1>::return_type+# define ASIO_INITFN_RESULT_TYPE3(ct, sig0, sig1, sig2) \+ typename ::asio::detail::async_result_helper< \+ ct, sig0, sig1, sig2>::return_type+#define ASIO_HANDLER_TYPE(ct, sig) \+ typename ::asio::detail::async_result_helper< \+ ct, sig>::completion_handler_type+#define ASIO_HANDLER_TYPE2(ct, sig0, sig1) \+ typename ::asio::detail::async_result_helper< \+ ct, sig0, sig1>::completion_handler_type+#define ASIO_HANDLER_TYPE3(ct, sig0, sig1, sig2) \+ typename ::asio::detail::async_result_helper< \+ ct, sig0, sig1, sig2>::completion_handler_type+#else+# define ASIO_INITFN_RESULT_TYPE(ct, sig) \+ typename ::asio::async_result< \+ typename ::asio::decay<ct>::type, sig>::return_type+# define ASIO_INITFN_RESULT_TYPE2(ct, sig0, sig1) \+ typename ::asio::async_result< \+ typename ::asio::decay<ct>::type, sig0, sig1>::return_type+# define ASIO_INITFN_RESULT_TYPE3(ct, sig0, sig1, sig2) \+ typename ::asio::async_result< \+ typename ::asio::decay<ct>::type, sig0, sig1, sig2>::return_type+#define ASIO_HANDLER_TYPE(ct, sig) \+ typename ::asio::async_result< \+ typename ::asio::decay<ct>::type, sig>::completion_handler_type+#define ASIO_HANDLER_TYPE2(ct, sig0, sig1) \+ typename ::asio::async_result< \+ typename ::asio::decay<ct>::type, \+ sig0, sig1>::completion_handler_type+#define ASIO_HANDLER_TYPE3(ct, sig0, sig1, sig2) \+ typename ::asio::async_result< \+ typename ::asio::decay<ct>::type, \+ sig0, sig1, sig2>::completion_handler_type+#endif++#if defined(GENERATING_DOCUMENTATION)+# define ASIO_INITFN_AUTO_RESULT_TYPE(ct, sig) \+ auto+# define ASIO_INITFN_AUTO_RESULT_TYPE2(ct, sig0, sig1) \+ auto+# define ASIO_INITFN_AUTO_RESULT_TYPE3(ct, sig0, sig1, sig2) \+ auto+#elif defined(ASIO_HAS_RETURN_TYPE_DEDUCTION)+# define ASIO_INITFN_AUTO_RESULT_TYPE(ct, sig) \+ auto+# define ASIO_INITFN_AUTO_RESULT_TYPE2(ct, sig0, sig1) \+ auto+# define ASIO_INITFN_AUTO_RESULT_TYPE3(ct, sig0, sig1, sig2) \+ auto+#else+# define ASIO_INITFN_AUTO_RESULT_TYPE(ct, sig) \+ ASIO_INITFN_RESULT_TYPE(ct, sig)+# define ASIO_INITFN_AUTO_RESULT_TYPE2(ct, sig0, sig1) \+ ASIO_INITFN_RESULT_TYPE2(ct, sig0, sig1)+# define ASIO_INITFN_AUTO_RESULT_TYPE3(ct, sig0, sig1, sig2) \+ ASIO_INITFN_RESULT_TYPE3(ct, sig0, sig1, sig2)+#endif++#if defined(GENERATING_DOCUMENTATION)+# define ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ct, sig) \+ auto+# define ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX2(ct, sig0, sig1) \+ auto+# define ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX3(ct, sig0, sig1, sig2) \+ auto+# define ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(expr)+#elif defined(ASIO_HAS_RETURN_TYPE_DEDUCTION)+# define ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ct, sig) \+ auto+# define ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX2(ct, sig0, sig1) \+ auto+# define ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX3(ct, sig0, sig1, sig2) \+ auto+# define ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(expr)+#elif defined(ASIO_HAS_DECLTYPE)+# define ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ct, sig) \+ auto+# define ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX2(ct, sig0, sig1) \+ auto+# define ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX3(ct, sig0, sig1, sig2) \+ auto+# define ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(expr) -> decltype expr+#else+# define ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ct, sig) \+ ASIO_INITFN_RESULT_TYPE(ct, sig)+# define ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX2(ct, sig0, sig1) \+ ASIO_INITFN_RESULT_TYPE2(ct, sig0, sig1)+# define ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX3(ct, sig0, sig1, sig2) \+ ASIO_INITFN_RESULT_TYPE3(ct, sig0, sig1, sig2)+# define ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(expr)+#endif++#if defined(GENERATING_DOCUMENTATION)+# define ASIO_INITFN_DEDUCED_RESULT_TYPE(ct, sig, expr) \+ void_or_deduced+# define ASIO_INITFN_DEDUCED_RESULT_TYPE2(ct, sig0, sig1, expr) \+ void_or_deduced+# define ASIO_INITFN_DEDUCED_RESULT_TYPE3(ct, sig0, sig1, sig2, expr) \+ void_or_deduced+#elif defined(ASIO_HAS_DECLTYPE)+# define ASIO_INITFN_DEDUCED_RESULT_TYPE(ct, sig, expr) \+ decltype expr+# define ASIO_INITFN_DEDUCED_RESULT_TYPE2(ct, sig0, sig1, expr) \+ decltype expr+# define ASIO_INITFN_DEDUCED_RESULT_TYPE3(ct, sig0, sig1, sig2, expr) \+ decltype expr+#else+# define ASIO_INITFN_DEDUCED_RESULT_TYPE(ct, sig, expr) \+ ASIO_INITFN_RESULT_TYPE(ct, sig)+# define ASIO_INITFN_DEDUCED_RESULT_TYPE2(ct, sig0, sig1, expr) \+ ASIO_INITFN_RESULT_TYPE2(ct, sig0, sig1)+# define ASIO_INITFN_DEDUCED_RESULT_TYPE3(ct, sig0, sig1, sig2, expr) \+ ASIO_INITFN_RESULT_TYPE3(ct, sig0, sig1, sig2)+#endif++#if defined(GENERATING_DOCUMENTATION)++template <typename CompletionToken,+ completion_signature... Signatures,+ typename Initiation, typename... Args>+void_or_deduced async_initiate(+ ASIO_MOVE_ARG(Initiation) initiation,+ ASIO_NONDEDUCED_MOVE_ARG(CompletionToken),+ ASIO_MOVE_ARG(Args)... args);++#elif defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename CompletionToken,+ ASIO_COMPLETION_SIGNATURE... Signatures,+ typename Initiation, typename... Args>+inline typename constraint<+ detail::async_result_has_initiate_memfn<+ CompletionToken, Signatures...>::value,+ ASIO_INITFN_DEDUCED_RESULT_TYPE(CompletionToken, Signatures...,+ (async_result<typename decay<CompletionToken>::type,+ Signatures...>::initiate(declval<ASIO_MOVE_ARG(Initiation)>(),+ declval<ASIO_MOVE_ARG(CompletionToken)>(),+ declval<ASIO_MOVE_ARG(Args)>()...)))>::type+async_initiate(ASIO_MOVE_ARG(Initiation) initiation,+ ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token,+ ASIO_MOVE_ARG(Args)... args)+{+ return async_result<typename decay<CompletionToken>::type,+ Signatures...>::initiate(ASIO_MOVE_CAST(Initiation)(initiation),+ ASIO_MOVE_CAST(CompletionToken)(token),+ ASIO_MOVE_CAST(Args)(args)...);+}++template <typename CompletionToken,+ ASIO_COMPLETION_SIGNATURE... Signatures,+ typename Initiation, typename... Args>+inline typename constraint<+ !detail::async_result_has_initiate_memfn<+ CompletionToken, Signatures...>::value,+ ASIO_INITFN_RESULT_TYPE(CompletionToken, Signatures...)>::type+async_initiate(ASIO_MOVE_ARG(Initiation) initiation,+ ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token,+ ASIO_MOVE_ARG(Args)... args)+{+ async_completion<CompletionToken, Signatures...> completion(token);++ ASIO_MOVE_CAST(Initiation)(initiation)(+ ASIO_MOVE_CAST(ASIO_HANDLER_TYPE(CompletionToken,+ Signatures...))(completion.completion_handler),+ ASIO_MOVE_CAST(Args)(args)...);++ return completion.result.get();+}++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename CompletionToken,+ ASIO_COMPLETION_SIGNATURE Sig0,+ typename Initiation>+inline typename constraint<+ detail::async_result_has_initiate_memfn<+ CompletionToken, Sig0>::value,+ ASIO_INITFN_DEDUCED_RESULT_TYPE(CompletionToken, Sig0,+ (async_result<typename decay<CompletionToken>::type,+ Sig0>::initiate(declval<ASIO_MOVE_ARG(Initiation)>(),+ declval<ASIO_MOVE_ARG(CompletionToken)>())))>::type+async_initiate(ASIO_MOVE_ARG(Initiation) initiation,+ ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token)+{+ return async_result<typename decay<CompletionToken>::type,+ Sig0>::initiate(ASIO_MOVE_CAST(Initiation)(initiation),+ ASIO_MOVE_CAST(CompletionToken)(token));+}++template <typename CompletionToken,+ ASIO_COMPLETION_SIGNATURE Sig0,+ ASIO_COMPLETION_SIGNATURE Sig1,+ typename Initiation>+inline typename constraint<+ detail::async_result_has_initiate_memfn<+ CompletionToken, Sig0, Sig1>::value,+ ASIO_INITFN_DEDUCED_RESULT_TYPE2(CompletionToken, Sig0, Sig1,+ (async_result<typename decay<CompletionToken>::type,+ Sig0, Sig1>::initiate(declval<ASIO_MOVE_ARG(Initiation)>(),+ declval<ASIO_MOVE_ARG(CompletionToken)>())))>::type+async_initiate(ASIO_MOVE_ARG(Initiation) initiation,+ ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token)+{+ return async_result<typename decay<CompletionToken>::type,+ Sig0, Sig1>::initiate(ASIO_MOVE_CAST(Initiation)(initiation),+ ASIO_MOVE_CAST(CompletionToken)(token));+}++template <typename CompletionToken,+ ASIO_COMPLETION_SIGNATURE Sig0,+ ASIO_COMPLETION_SIGNATURE Sig1,+ ASIO_COMPLETION_SIGNATURE Sig2,+ typename Initiation>+inline typename constraint<+ detail::async_result_has_initiate_memfn<+ CompletionToken, Sig0, Sig1, Sig2>::value,+ ASIO_INITFN_DEDUCED_RESULT_TYPE3(CompletionToken, Sig0, Sig1, Sig2,+ (async_result<typename decay<CompletionToken>::type,+ Sig0, Sig1, Sig2>::initiate(declval<ASIO_MOVE_ARG(Initiation)>(),+ declval<ASIO_MOVE_ARG(CompletionToken)>())))>::type+async_initiate(ASIO_MOVE_ARG(Initiation) initiation,+ ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token)+{+ return async_result<typename decay<CompletionToken>::type,+ Sig0, Sig1, Sig2>::initiate(ASIO_MOVE_CAST(Initiation)(initiation),+ ASIO_MOVE_CAST(CompletionToken)(token));+}++template <typename CompletionToken,+ ASIO_COMPLETION_SIGNATURE Sig0,+ typename Initiation>+inline typename constraint<+ !detail::async_result_has_initiate_memfn<+ CompletionToken, Sig0>::value,+ ASIO_INITFN_RESULT_TYPE(CompletionToken, Sig0)>::type+async_initiate(ASIO_MOVE_ARG(Initiation) initiation,+ ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token)+{+ async_completion<CompletionToken, Sig0> completion(token);++ ASIO_MOVE_CAST(Initiation)(initiation)(+ ASIO_MOVE_CAST(ASIO_HANDLER_TYPE(CompletionToken,+ Sig0))(completion.completion_handler));++ return completion.result.get();+}++template <typename CompletionToken,+ ASIO_COMPLETION_SIGNATURE Sig0,+ ASIO_COMPLETION_SIGNATURE Sig1,+ typename Initiation>+inline typename constraint<+ !detail::async_result_has_initiate_memfn<+ CompletionToken, Sig0, Sig1>::value,+ ASIO_INITFN_RESULT_TYPE2(CompletionToken, Sig0, Sig1)>::type+async_initiate(ASIO_MOVE_ARG(Initiation) initiation,+ ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token)+{+ async_completion<CompletionToken, Sig0, Sig1> completion(token);++ ASIO_MOVE_CAST(Initiation)(initiation)(+ ASIO_MOVE_CAST(ASIO_HANDLER_TYPE2(CompletionToken,+ Sig0, Sig1))(completion.completion_handler));++ return completion.result.get();+}++template <typename CompletionToken,+ ASIO_COMPLETION_SIGNATURE Sig0,+ ASIO_COMPLETION_SIGNATURE Sig1,+ ASIO_COMPLETION_SIGNATURE Sig2,+ typename Initiation>+inline typename constraint<+ !detail::async_result_has_initiate_memfn<+ CompletionToken, Sig0, Sig1, Sig2>::value,+ ASIO_INITFN_RESULT_TYPE3(CompletionToken, Sig0, Sig1, Sig2)>::type+async_initiate(ASIO_MOVE_ARG(Initiation) initiation,+ ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token)+{+ async_completion<CompletionToken, Sig0, Sig1, Sig2> completion(token);++ ASIO_MOVE_CAST(Initiation)(initiation)(+ ASIO_MOVE_CAST(ASIO_HANDLER_TYPE3(CompletionToken,+ Sig0, Sig1, Sig2))(completion.completion_handler));++ return completion.result.get();+}++#define ASIO_PRIVATE_INITIATE_DEF(n) \+ template <typename CompletionToken, \+ ASIO_COMPLETION_SIGNATURE Sig0, \+ typename Initiation, ASIO_VARIADIC_TPARAMS(n)> \+ inline typename constraint< \+ detail::async_result_has_initiate_memfn< \+ CompletionToken, Sig0>::value, \+ ASIO_INITFN_DEDUCED_RESULT_TYPE( \+ CompletionToken, Sig0, \+ (async_result<typename decay<CompletionToken>::type, \+ Sig0>::initiate( \+ declval<ASIO_MOVE_ARG(Initiation)>(), \+ declval<ASIO_MOVE_ARG(CompletionToken)>(), \+ ASIO_VARIADIC_MOVE_DECLVAL(n))))>::type \+ async_initiate(ASIO_MOVE_ARG(Initiation) initiation, \+ ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \+ ASIO_VARIADIC_MOVE_PARAMS(n)) \+ { \+ return async_result<typename decay<CompletionToken>::type, \+ Sig0>::initiate( \+ ASIO_MOVE_CAST(Initiation)(initiation), \+ ASIO_MOVE_CAST(CompletionToken)(token), \+ ASIO_VARIADIC_MOVE_ARGS(n)); \+ } \+ \+ template <typename CompletionToken, \+ ASIO_COMPLETION_SIGNATURE Sig0, \+ ASIO_COMPLETION_SIGNATURE Sig1, \+ typename Initiation, ASIO_VARIADIC_TPARAMS(n)> \+ inline typename constraint< \+ detail::async_result_has_initiate_memfn< \+ CompletionToken, Sig0, Sig1>::value, \+ ASIO_INITFN_DEDUCED_RESULT_TYPE2( \+ CompletionToken, Sig0, Sig1, \+ (async_result<typename decay<CompletionToken>::type, \+ Sig0, Sig1>::initiate( \+ declval<ASIO_MOVE_ARG(Initiation)>(), \+ declval<ASIO_MOVE_ARG(CompletionToken)>(), \+ ASIO_VARIADIC_MOVE_DECLVAL(n))))>::type \+ async_initiate(ASIO_MOVE_ARG(Initiation) initiation, \+ ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \+ ASIO_VARIADIC_MOVE_PARAMS(n)) \+ { \+ return async_result<typename decay<CompletionToken>::type, \+ Sig0, Sig1>::initiate( \+ ASIO_MOVE_CAST(Initiation)(initiation), \+ ASIO_MOVE_CAST(CompletionToken)(token), \+ ASIO_VARIADIC_MOVE_ARGS(n)); \+ } \+ \+ template <typename CompletionToken, \+ ASIO_COMPLETION_SIGNATURE Sig0, \+ ASIO_COMPLETION_SIGNATURE Sig1, \+ ASIO_COMPLETION_SIGNATURE Sig2, \+ typename Initiation, ASIO_VARIADIC_TPARAMS(n)> \+ inline typename constraint< \+ detail::async_result_has_initiate_memfn< \+ CompletionToken, Sig0, Sig1, Sig2>::value, \+ ASIO_INITFN_DEDUCED_RESULT_TYPE3( \+ CompletionToken, Sig0, Sig1, Sig2, \+ (async_result<typename decay<CompletionToken>::type, \+ Sig0, Sig1, Sig2>::initiate( \+ declval<ASIO_MOVE_ARG(Initiation)>(), \+ declval<ASIO_MOVE_ARG(CompletionToken)>(), \+ ASIO_VARIADIC_MOVE_DECLVAL(n))))>::type \+ async_initiate(ASIO_MOVE_ARG(Initiation) initiation, \+ ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \+ ASIO_VARIADIC_MOVE_PARAMS(n)) \+ { \+ return async_result<typename decay<CompletionToken>::type, \+ Sig0, Sig1, Sig2>::initiate( \+ ASIO_MOVE_CAST(Initiation)(initiation), \+ ASIO_MOVE_CAST(CompletionToken)(token), \+ ASIO_VARIADIC_MOVE_ARGS(n)); \+ } \+ \+ template <typename CompletionToken, \+ ASIO_COMPLETION_SIGNATURE Sig0, \+ typename Initiation, ASIO_VARIADIC_TPARAMS(n)> \+ inline typename constraint< \+ !detail::async_result_has_initiate_memfn< \+ CompletionToken, Sig0>::value, \+ ASIO_INITFN_RESULT_TYPE(CompletionToken, Sig0)>::type \+ async_initiate(ASIO_MOVE_ARG(Initiation) initiation, \+ ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \+ ASIO_VARIADIC_MOVE_PARAMS(n)) \+ { \+ async_completion<CompletionToken, \+ Sig0> completion(token); \+ \+ ASIO_MOVE_CAST(Initiation)(initiation)( \+ ASIO_MOVE_CAST(ASIO_HANDLER_TYPE(CompletionToken, \+ Sig0))(completion.completion_handler), \+ ASIO_VARIADIC_MOVE_ARGS(n)); \+ \+ return completion.result.get(); \+ } \+ \+ template <typename CompletionToken, \+ ASIO_COMPLETION_SIGNATURE Sig0, \+ ASIO_COMPLETION_SIGNATURE Sig1, \+ typename Initiation, ASIO_VARIADIC_TPARAMS(n)> \+ inline typename constraint< \+ !detail::async_result_has_initiate_memfn< \+ CompletionToken, Sig0, Sig1>::value, \+ ASIO_INITFN_RESULT_TYPE2(CompletionToken, Sig0, Sig1)>::type \+ async_initiate(ASIO_MOVE_ARG(Initiation) initiation, \+ ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \+ ASIO_VARIADIC_MOVE_PARAMS(n)) \+ { \+ async_completion<CompletionToken, \+ Sig0, Sig1> completion(token); \+ \+ ASIO_MOVE_CAST(Initiation)(initiation)( \+ ASIO_MOVE_CAST(ASIO_HANDLER_TYPE2(CompletionToken, \+ Sig0, Sig1))(completion.completion_handler), \+ ASIO_VARIADIC_MOVE_ARGS(n)); \+ \+ return completion.result.get(); \+ } \+ \+ template <typename CompletionToken, \+ ASIO_COMPLETION_SIGNATURE Sig0, \+ ASIO_COMPLETION_SIGNATURE Sig1, \+ ASIO_COMPLETION_SIGNATURE Sig2, \+ typename Initiation, ASIO_VARIADIC_TPARAMS(n)> \+ inline typename constraint< \+ !detail::async_result_has_initiate_memfn< \+ CompletionToken, Sig0, Sig1, Sig2>::value, \+ ASIO_INITFN_RESULT_TYPE3(CompletionToken, Sig0, Sig1, Sig2)>::type \+ async_initiate(ASIO_MOVE_ARG(Initiation) initiation, \+ ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \+ ASIO_VARIADIC_MOVE_PARAMS(n)) \+ { \+ async_completion<CompletionToken, \+ Sig0, Sig1, Sig2> completion(token); \+ \+ ASIO_MOVE_CAST(Initiation)(initiation)( \+ ASIO_MOVE_CAST(ASIO_HANDLER_TYPE3(CompletionToken, \+ Sig0, Sig1, Sig2))(completion.completion_handler), \+ ASIO_VARIADIC_MOVE_ARGS(n)); \+ \+ return completion.result.get(); \+ } \+ /**/+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_INITIATE_DEF)+#undef ASIO_PRIVATE_INITIATE_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++#if defined(ASIO_HAS_CONCEPTS) \+ && defined(ASIO_HAS_VARIADIC_TEMPLATES) \+ && defined(ASIO_HAS_DECLTYPE)++namespace detail {++template <typename... Signatures>+struct initiation_archetype+{+ template <completion_handler_for<Signatures...> CompletionHandler>+ void operator()(CompletionHandler&&) const+ {+ }+};++} // namespace detail++template <typename T, typename... Signatures>+ASIO_CONCEPT completion_token_for =+ detail::are_completion_signatures<Signatures...>::value+ &&+ requires(T&& t)+ {+ async_initiate<T, Signatures...>(+ detail::initiation_archetype<Signatures...>{}, t);+ };++#define ASIO_COMPLETION_TOKEN_FOR(sig) \+ ::asio::completion_token_for<sig>+#define ASIO_COMPLETION_TOKEN_FOR2(sig0, sig1) \+ ::asio::completion_token_for<sig0, sig1>+#define ASIO_COMPLETION_TOKEN_FOR3(sig0, sig1, sig2) \+ ::asio::completion_token_for<sig0, sig1, sig2>++#else // defined(ASIO_HAS_CONCEPTS)+ // && defined(ASIO_HAS_VARIADIC_TEMPLATES)+ // && defined(ASIO_HAS_DECLTYPE)++#define ASIO_COMPLETION_TOKEN_FOR(sig) typename+#define ASIO_COMPLETION_TOKEN_FOR2(sig0, sig1) typename+#define ASIO_COMPLETION_TOKEN_FOR3(sig0, sig1, sig2) typename++#endif // defined(ASIO_HAS_CONCEPTS)+ // && defined(ASIO_HAS_VARIADIC_TEMPLATES)+ // && defined(ASIO_HAS_DECLTYPE)++namespace detail {++struct async_operation_probe {};+struct async_operation_probe_result {};++template <typename Call, typename = void>+struct is_async_operation_call : false_type+{+};++template <typename Call>+struct is_async_operation_call<Call,+ typename void_type<+ typename enable_if<+ is_same<+ typename result_of<Call>::type,+ async_operation_probe_result+ >::value+ >::type+ >::type> : true_type+{+};++} // namespace detail++#if !defined(GENERATING_DOCUMENTATION)+#if defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename... Signatures>+class async_result<detail::async_operation_probe, Signatures...>+{+public:+ typedef detail::async_operation_probe_result return_type;++ template <typename Initiation, typename... InitArgs>+ static return_type initiate(ASIO_MOVE_ARG(Initiation),+ detail::async_operation_probe, ASIO_MOVE_ARG(InitArgs)...)+ {+ return return_type();+ }+};++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++namespace detail {++struct async_result_probe_base+{+ typedef detail::async_operation_probe_result return_type;++ template <typename Initiation>+ static return_type initiate(ASIO_MOVE_ARG(Initiation),+ detail::async_operation_probe)+ {+ return return_type();+ }++#define ASIO_PRIVATE_INITIATE_DEF(n) \+ template <typename Initiation, ASIO_VARIADIC_TPARAMS(n)> \+ static return_type initiate(ASIO_MOVE_ARG(Initiation), \+ detail::async_operation_probe, \+ ASIO_VARIADIC_UNNAMED_MOVE_PARAMS(n)) \+ { \+ return return_type(); \+ } \+ /**/+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_INITIATE_DEF)+#undef ASIO_PRIVATE_INITIATE_DEF+};++} // namespace detail++template <typename Sig0>+class async_result<detail::async_operation_probe, Sig0>+ : public detail::async_result_probe_base {};++template <typename Sig0, typename Sig1>+class async_result<detail::async_operation_probe, Sig0, Sig1>+ : public detail::async_result_probe_base {};++template <typename Sig0, typename Sig1, typename Sig2>+class async_result<detail::async_operation_probe, Sig0, Sig1, Sig2>+ : public detail::async_result_probe_base {};++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+#endif // !defined(GENERATING_DOCUMENTATION)++#if defined(GENERATING_DOCUMENTATION)++/// The is_async_operation trait detects whether a type @c T and arguments+/// @c Args... may be used to initiate an asynchronous operation.+/**+ * Class template @c is_async_operation is a trait is derived from @c true_type+ * if the expression <tt>T(Args..., token)</tt> initiates an asynchronous+ * operation, where @c token is an unspecified completion token type. Otherwise,+ * @c is_async_operation is derived from @c false_type.+ */+template <typename T, typename... Args>+struct is_async_operation : integral_constant<bool, automatically_determined>+{+};++#elif defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename T, typename... Args>+struct is_async_operation :+ detail::is_async_operation_call<+ T(Args..., detail::async_operation_probe)>+{+};++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename T, typename = void, typename = void, typename = void,+ typename = void, typename = void, typename = void, typename = void,+ typename = void, typename = void>+struct is_async_operation;++template <typename T>+struct is_async_operation<T> :+ detail::is_async_operation_call<+ T(detail::async_operation_probe)>+{+};++#define ASIO_PRIVATE_IS_ASYNC_OP_DEF(n) \+ template <typename T, ASIO_VARIADIC_TPARAMS(n)> \+ struct is_async_operation<T, ASIO_VARIADIC_TARGS(n)> : \+ detail::is_async_operation_call< \+ T(ASIO_VARIADIC_TARGS(n), detail::async_operation_probe)> \+ { \+ }; \+ /**/+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_IS_ASYNC_OP_DEF)+#undef ASIO_PRIVATE_IS_ASYNC_OP_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++#if defined(ASIO_HAS_CONCEPTS) \+ && defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename T, typename... Args>+ASIO_CONCEPT async_operation = is_async_operation<T, Args...>::value;++#define ASIO_ASYNC_OPERATION(t) \+ ::asio::async_operation<t>+#define ASIO_ASYNC_OPERATION1(t, a0) \+ ::asio::async_operation<t, a0>+#define ASIO_ASYNC_OPERATION2(t, a0, a1) \+ ::asio::async_operation<t, a0, a1>+#define ASIO_ASYNC_OPERATION3(t, a0, a1, a2) \+ ::asio::async_operation<t, a0, a1, a2>++#else // defined(ASIO_HAS_CONCEPTS)+ // && defined(ASIO_HAS_VARIADIC_TEMPLATES)++#define ASIO_ASYNC_OPERATION(t) typename+#define ASIO_ASYNC_OPERATION1(t, a0) typename+#define ASIO_ASYNC_OPERATION2(t, a0, a1) typename+#define ASIO_ASYNC_OPERATION3(t, a0, a1, a2) typename++#endif // defined(ASIO_HAS_CONCEPTS)+ // && defined(ASIO_HAS_VARIADIC_TEMPLATES)++namespace detail {++struct completion_signature_probe {};++#if defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename... T>+struct completion_signature_probe_result+{+ template <template <typename...> class Op>+ struct apply+ {+ typedef Op<T...> type;+ };+};++template <typename T>+struct completion_signature_probe_result<T>+{+ typedef T type;++ template <template <typename...> class Op>+ struct apply+ {+ typedef Op<T> type;+ };+};++template <>+struct completion_signature_probe_result<void>+{+ template <template <typename...> class Op>+ struct apply+ {+ typedef Op<> type;+ };+};++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename T>+struct completion_signature_probe_result+{+ typedef T type;+};++template <>+struct completion_signature_probe_result<void>+{+};++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++} // namespace detail++#if !defined(GENERATING_DOCUMENTATION)+#if defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename... Signatures>+class async_result<detail::completion_signature_probe, Signatures...>+{+public:+ typedef detail::completion_signature_probe_result<Signatures...> return_type;++ template <typename Initiation, typename... InitArgs>+ static return_type initiate(ASIO_MOVE_ARG(Initiation),+ detail::completion_signature_probe, ASIO_MOVE_ARG(InitArgs)...)+ {+ return return_type();+ }+};++template <typename Signature>+class async_result<detail::completion_signature_probe, Signature>+{+public:+ typedef detail::completion_signature_probe_result<Signature> return_type;++ template <typename Initiation, typename... InitArgs>+ static return_type initiate(ASIO_MOVE_ARG(Initiation),+ detail::completion_signature_probe, ASIO_MOVE_ARG(InitArgs)...)+ {+ return return_type();+ }+};++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++namespace detail {++template <typename Signature>+class async_result_sig_probe_base+{+public:+ typedef detail::completion_signature_probe_result<Signature> return_type;++ template <typename Initiation>+ static return_type initiate(ASIO_MOVE_ARG(Initiation),+ detail::async_operation_probe)+ {+ return return_type();+ }++#define ASIO_PRIVATE_INITIATE_DEF(n) \+ template <typename Initiation, ASIO_VARIADIC_TPARAMS(n)> \+ static return_type initiate(ASIO_MOVE_ARG(Initiation), \+ detail::completion_signature_probe, \+ ASIO_VARIADIC_UNNAMED_MOVE_PARAMS(n)) \+ { \+ return return_type(); \+ } \+ /**/+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_INITIATE_DEF)+#undef ASIO_PRIVATE_INITIATE_DEF+};++} // namespace detail++template <>+class async_result<detail::completion_signature_probe>+ : public detail::async_result_sig_probe_base<void> {};++template <typename Sig0>+class async_result<detail::completion_signature_probe, Sig0>+ : public detail::async_result_sig_probe_base<Sig0> {};++template <typename Sig0, typename Sig1>+class async_result<detail::completion_signature_probe, Sig0, Sig1>+ : public detail::async_result_sig_probe_base<void> {};++template <typename Sig0, typename Sig1, typename Sig2>+class async_result<detail::completion_signature_probe, Sig0, Sig1, Sig2>+ : public detail::async_result_sig_probe_base<void> {};++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+#endif // !defined(GENERATING_DOCUMENTATION)++#if defined(GENERATING_DOCUMENTATION)++/// The completion_signature_of trait determines the completion signature+/// of an asynchronous operation.+/**+ * Class template @c completion_signature_of is a trait with a member type+ * alias @c type that denotes the completion signature of the asynchronous+ * operation initiated by the expression <tt>T(Args..., token)</tt> operation,+ * where @c token is an unspecified completion token type. If the asynchronous+ * operation does not have exactly one completion signature, the instantion of+ * the trait is well-formed but the member type alias @c type is omitted. If+ * the expression <tt>T(Args..., token)</tt> is not an asynchronous operation+ * then use of the trait is ill-formed.+ */+template <typename T, typename... Args>+struct completion_signature_of+{+ typedef automatically_determined type;+};++template <typename T, typename... Args>+using completion_signature_of_t =+ typename completion_signature_of<T, Args...>::type;++#elif defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename T, typename... Args>+struct completion_signature_of :+ result_of<T(Args..., detail::completion_signature_probe)>::type+{+};++#if defined(ASIO_HAS_ALIAS_TEMPLATES)+template <typename T, typename... Args>+using completion_signature_of_t =+ typename completion_signature_of<T, Args...>::type;+#endif // defined(ASIO_HAS_ALIAS_TEMPLATES)++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename T, typename = void, typename = void, typename = void,+ typename = void, typename = void, typename = void, typename = void,+ typename = void, typename = void>+struct completion_signature_of;++template <typename T>+struct completion_signature_of<T> :+ result_of<T(detail::completion_signature_probe)>::type+{+};++#define ASIO_PRIVATE_COMPLETION_SIG_OF_DEF(n) \+ template <typename T, ASIO_VARIADIC_TPARAMS(n)> \+ struct completion_signature_of<T, ASIO_VARIADIC_TARGS(n)> : \+ result_of< \+ T(ASIO_VARIADIC_TARGS(n), \+ detail::completion_signature_probe)>::type \+ { \+ }; \+ /**/+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_COMPLETION_SIG_OF_DEF)+#undef ASIO_PRIVATE_COMPLETION_SIG_OF_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++namespace detail {++template <typename T, typename = void>+struct default_completion_token_impl+{+ typedef void type;+};++template <typename T>+struct default_completion_token_impl<T,+ typename void_type<typename T::default_completion_token_type>::type>+{+ typedef typename T::default_completion_token_type type;+};++} // namespace detail++#if defined(GENERATING_DOCUMENTATION)++/// Traits type used to determine the default completion token type associated+/// with a type (such as an executor).+/**+ * A program may specialise this traits type if the @c T template parameter in+ * the specialisation is a user-defined type.+ *+ * Specialisations of this trait may provide a nested typedef @c type, which is+ * a default-constructible completion token type.+ */+template <typename T>+struct default_completion_token+{+ /// If @c T has a nested type @c default_completion_token_type,+ /// <tt>T::default_completion_token_type</tt>. Otherwise the typedef @c type+ /// is not defined.+ typedef see_below type;+};+#else+template <typename T>+struct default_completion_token+ : detail::default_completion_token_impl<T>+{+};+#endif++#if defined(ASIO_HAS_ALIAS_TEMPLATES)++template <typename T>+using default_completion_token_t = typename default_completion_token<T>::type;++#endif // defined(ASIO_HAS_ALIAS_TEMPLATES)++#if defined(ASIO_HAS_DEFAULT_FUNCTION_TEMPLATE_ARGUMENTS)++#define ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(e) \+ = typename ::asio::default_completion_token<e>::type+#define ASIO_DEFAULT_COMPLETION_TOKEN(e) \+ = typename ::asio::default_completion_token<e>::type()++#else // defined(ASIO_HAS_DEFAULT_FUNCTION_TEMPLATE_ARGUMENTS)++#define ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(e)+#define ASIO_DEFAULT_COMPLETION_TOKEN(e)++#endif // defined(ASIO_HAS_DEFAULT_FUNCTION_TEMPLATE_ARGUMENTS)++} // namespace asio++#include "asio/detail/pop_options.hpp" #endif // ASIO_ASYNC_RESULT_HPP
link/modules/asio-standalone/asio/include/asio/awaitable.hpp view
@@ -2,7 +2,7 @@ // awaitable.hpp // ~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -136,9 +136,6 @@ #include "asio/detail/pop_options.hpp" #include "asio/impl/awaitable.hpp"-#if defined(ASIO_HEADER_ONLY)-# include "asio/impl/awaitable.ipp"-#endif // defined(ASIO_HEADER_ONLY) #endif // defined(ASIO_HAS_CO_AWAIT) || defined(GENERATING_DOCUMENTATION)
link/modules/asio-standalone/asio/include/asio/basic_datagram_socket.hpp view
@@ -2,7 +2,7 @@ // basic_datagram_socket.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -113,9 +113,9 @@ */ template <typename ExecutionContext> explicit basic_datagram_socket(ExecutionContext& context,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- > = 0)+ >::type = 0) : basic_socket<Protocol, Executor>(context) { }@@ -151,10 +151,10 @@ template <typename ExecutionContext> basic_datagram_socket(ExecutionContext& context, const protocol_type& protocol,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- > = defaulted_constraint())+ >::type = defaulted_constraint()) : basic_socket<Protocol, Executor>(context, protocol) { }@@ -198,9 +198,9 @@ template <typename ExecutionContext> basic_datagram_socket(ExecutionContext& context, const endpoint_type& endpoint,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- > = 0)+ >::type = 0) : basic_socket<Protocol, Executor>(context, endpoint) { }@@ -243,13 +243,14 @@ template <typename ExecutionContext> basic_datagram_socket(ExecutionContext& context, const protocol_type& protocol, const native_handle_type& native_socket,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- > = 0)+ >::type = 0) : basic_socket<Protocol, Executor>(context, protocol, native_socket) { } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move-construct a basic_datagram_socket from another. /** * This constructor moves a datagram socket from one object to another.@@ -261,7 +262,7 @@ * constructed using the @c basic_datagram_socket(const executor_type&) * constructor. */- basic_datagram_socket(basic_datagram_socket&& other) noexcept+ basic_datagram_socket(basic_datagram_socket&& other) ASIO_NOEXCEPT : basic_socket<Protocol, Executor>(std::move(other)) { }@@ -298,10 +299,10 @@ */ template <typename Protocol1, typename Executor1> basic_datagram_socket(basic_datagram_socket<Protocol1, Executor1>&& other,- constraint_t<+ typename constraint< is_convertible<Protocol1, Protocol>::value && is_convertible<Executor1, Executor>::value- > = 0)+ >::type = 0) : basic_socket<Protocol, Executor>(std::move(other)) { }@@ -320,15 +321,16 @@ * constructor. */ template <typename Protocol1, typename Executor1>- constraint_t<+ typename constraint< is_convertible<Protocol1, Protocol>::value && is_convertible<Executor1, Executor>::value, basic_datagram_socket&- > operator=(basic_datagram_socket<Protocol1, Executor1>&& other)+ >::type operator=(basic_datagram_socket<Protocol1, Executor1>&& other) { basic_socket<Protocol, Executor>::operator=(std::move(other)); return *this; }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Destroys the socket. /**@@ -345,7 +347,7 @@ * call will block until the data has been sent successfully or an error * occurs. *- * @param buffers One or more data buffers to be sent on the socket.+ * @param buffers One ore more data buffers to be sent on the socket. * * @returns The number of bytes sent. *@@ -377,7 +379,7 @@ * call will block until the data has been sent successfully or an error * occurs. *- * @param buffers One or more data buffers to be sent on the socket.+ * @param buffers One ore more data buffers to be sent on the socket. * * @param flags Flags specifying how the send call is to be made. *@@ -447,7 +449,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -477,14 +479,18 @@ */ template <typename ConstBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) WriteToken = default_completion_token_t<executor_type>>- auto async_send(const ConstBufferSequence& buffers,- WriteToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ std::size_t)) WriteToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+ void (asio::error_code, std::size_t))+ async_send(const ConstBufferSequence& buffers,+ ASIO_MOVE_ARG(WriteToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<WriteToken, void (asio::error_code, std::size_t)>( declval<initiate_async_send>(), token,- buffers, socket_base::message_flags(0)))+ buffers, socket_base::message_flags(0)))) { return async_initiate<WriteToken, void (asio::error_code, std::size_t)>(@@ -517,7 +523,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -538,14 +544,18 @@ */ template <typename ConstBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) WriteToken = default_completion_token_t<executor_type>>- auto async_send(const ConstBufferSequence& buffers,+ std::size_t)) WriteToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+ void (asio::error_code, std::size_t))+ async_send(const ConstBufferSequence& buffers, socket_base::message_flags flags,- WriteToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ ASIO_MOVE_ARG(WriteToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<WriteToken, void (asio::error_code, std::size_t)>(- declval<initiate_async_send>(), token, buffers, flags))+ declval<initiate_async_send>(), token, buffers, flags))) { return async_initiate<WriteToken, void (asio::error_code, std::size_t)>(@@ -666,7 +676,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -695,15 +705,19 @@ */ template <typename ConstBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) WriteToken = default_completion_token_t<executor_type>>- auto async_send_to(const ConstBufferSequence& buffers,+ std::size_t)) WriteToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+ void (asio::error_code, std::size_t))+ async_send_to(const ConstBufferSequence& buffers, const endpoint_type& destination,- WriteToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ ASIO_MOVE_ARG(WriteToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<WriteToken, void (asio::error_code, std::size_t)>( declval<initiate_async_send_to>(), token, buffers,- destination, socket_base::message_flags(0)))+ destination, socket_base::message_flags(0)))) { return async_initiate<WriteToken, void (asio::error_code, std::size_t)>(@@ -739,7 +753,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -756,15 +770,19 @@ */ template <typename ConstBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) WriteToken = default_completion_token_t<executor_type>>- auto async_send_to(const ConstBufferSequence& buffers,+ std::size_t)) WriteToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+ void (asio::error_code, std::size_t))+ async_send_to(const ConstBufferSequence& buffers, const endpoint_type& destination, socket_base::message_flags flags,- WriteToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ ASIO_MOVE_ARG(WriteToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<WriteToken, void (asio::error_code, std::size_t)>( declval<initiate_async_send_to>(), token,- buffers, destination, flags))+ buffers, destination, flags))) { return async_initiate<WriteToken, void (asio::error_code, std::size_t)>(@@ -884,7 +902,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -915,14 +933,18 @@ */ template <typename MutableBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) ReadToken = default_completion_token_t<executor_type>>- auto async_receive(const MutableBufferSequence& buffers,- ReadToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ std::size_t)) ReadToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+ async_receive(const MutableBufferSequence& buffers,+ ASIO_MOVE_ARG(ReadToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<ReadToken, void (asio::error_code, std::size_t)>( declval<initiate_async_receive>(), token,- buffers, socket_base::message_flags(0)))+ buffers, socket_base::message_flags(0)))) { return async_initiate<ReadToken, void (asio::error_code, std::size_t)>(@@ -955,7 +977,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -976,14 +998,18 @@ */ template <typename MutableBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) ReadToken = default_completion_token_t<executor_type>>- auto async_receive(const MutableBufferSequence& buffers,+ std::size_t)) ReadToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+ async_receive(const MutableBufferSequence& buffers, socket_base::message_flags flags,- ReadToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ ASIO_MOVE_ARG(ReadToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<ReadToken, void (asio::error_code, std::size_t)>(- declval<initiate_async_receive>(), token, buffers, flags))+ declval<initiate_async_receive>(), token, buffers, flags))) { return async_initiate<ReadToken, void (asio::error_code, std::size_t)>(@@ -1026,7 +1052,7 @@ asio::detail::throw_error(ec, "receive_from"); return s; }-+ /// Receive a datagram with the endpoint of the sender. /** * This function is used to receive a datagram. The function call will block@@ -1053,7 +1079,7 @@ asio::detail::throw_error(ec, "receive_from"); return s; }-+ /// Receive a datagram with the endpoint of the sender. /** * This function is used to receive a datagram. The function call will block@@ -1107,7 +1133,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -1133,15 +1159,19 @@ */ template <typename MutableBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) ReadToken = default_completion_token_t<executor_type>>- auto async_receive_from(const MutableBufferSequence& buffers,+ std::size_t)) ReadToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+ async_receive_from(const MutableBufferSequence& buffers, endpoint_type& sender_endpoint,- ReadToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ ASIO_MOVE_ARG(ReadToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<ReadToken, void (asio::error_code, std::size_t)>( declval<initiate_async_receive_from>(), token, buffers,- &sender_endpoint, socket_base::message_flags(0)))+ &sender_endpoint, socket_base::message_flags(0)))) { return async_initiate<ReadToken, void (asio::error_code, std::size_t)>(@@ -1179,7 +1209,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -1196,15 +1226,19 @@ */ template <typename MutableBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) ReadToken = default_completion_token_t<executor_type>>- auto async_receive_from(const MutableBufferSequence& buffers,+ std::size_t)) ReadToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+ async_receive_from(const MutableBufferSequence& buffers, endpoint_type& sender_endpoint, socket_base::message_flags flags,- ReadToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ ASIO_MOVE_ARG(ReadToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<ReadToken, void (asio::error_code, std::size_t)>( declval<initiate_async_receive_from>(), token,- buffers, &sender_endpoint, flags))+ buffers, &sender_endpoint, flags))) { return async_initiate<ReadToken, void (asio::error_code, std::size_t)>(@@ -1214,12 +1248,12 @@ private: // Disallow copying and assignment.- basic_datagram_socket(const basic_datagram_socket&) = delete;+ basic_datagram_socket(const basic_datagram_socket&) ASIO_DELETED; basic_datagram_socket& operator=(- const basic_datagram_socket&) = delete;+ const basic_datagram_socket&) ASIO_DELETED; class initiate_async_send- {+ { public: typedef Executor executor_type; @@ -1228,13 +1262,13 @@ { } - const executor_type& get_executor() const noexcept+ const executor_type& get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template <typename WriteHandler, typename ConstBufferSequence>- void operator()(WriteHandler&& handler,+ void operator()(ASIO_MOVE_ARG(WriteHandler) handler, const ConstBufferSequence& buffers, socket_base::message_flags flags) const {@@ -1262,13 +1296,13 @@ { } - const executor_type& get_executor() const noexcept+ const executor_type& get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template <typename WriteHandler, typename ConstBufferSequence>- void operator()(WriteHandler&& handler,+ void operator()(ASIO_MOVE_ARG(WriteHandler) handler, const ConstBufferSequence& buffers, const endpoint_type& destination, socket_base::message_flags flags) const {@@ -1296,13 +1330,13 @@ { } - const executor_type& get_executor() const noexcept+ const executor_type& get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template <typename ReadHandler, typename MutableBufferSequence>- void operator()(ReadHandler&& handler,+ void operator()(ASIO_MOVE_ARG(ReadHandler) handler, const MutableBufferSequence& buffers, socket_base::message_flags flags) const {@@ -1330,13 +1364,13 @@ { } - const executor_type& get_executor() const noexcept+ const executor_type& get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template <typename ReadHandler, typename MutableBufferSequence>- void operator()(ReadHandler&& handler,+ void operator()(ASIO_MOVE_ARG(ReadHandler) handler, const MutableBufferSequence& buffers, endpoint_type* sender_endpoint, socket_base::message_flags flags) const {
link/modules/asio-standalone/asio/include/asio/basic_deadline_timer.hpp view
@@ -2,7 +2,7 @@ // basic_deadline_timer.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -17,8 +17,6 @@ #include "asio/detail/config.hpp" -#if !defined(ASIO_NO_DEPRECATED)- #if defined(ASIO_HAS_BOOST_DATE_TIME) \ || defined(GENERATING_DOCUMENTATION) @@ -37,8 +35,7 @@ namespace asio { -/// (Deprecated: Use basic_waitable_timer.) Provides waitable timer-/// functionality.+/// Provides waitable timer functionality. /** * The basic_deadline_timer class template provides the ability to perform a * blocking or asynchronous wait for a timer to expire.@@ -66,7 +63,7 @@ * timer.wait(); * @endcode *- * @par+ * @par * Performing an asynchronous wait: * @code * void handler(const asio::error_code& error)@@ -181,9 +178,9 @@ */ template <typename ExecutionContext> explicit basic_deadline_timer(ExecutionContext& context,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- > = 0)+ >::type = 0) : impl_(0, 0, context) { }@@ -219,9 +216,9 @@ */ template <typename ExecutionContext> basic_deadline_timer(ExecutionContext& context, const time_type& expiry_time,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- > = 0)+ >::type = 0) : impl_(0, 0, context) { asio::error_code ec;@@ -263,9 +260,9 @@ template <typename ExecutionContext> basic_deadline_timer(ExecutionContext& context, const duration_type& expiry_time,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- > = 0)+ >::type = 0) : impl_(0, 0, context) { asio::error_code ec;@@ -274,6 +271,7 @@ asio::detail::throw_error(ec, "expires_from_now"); } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move-construct a basic_deadline_timer from another. /** * This constructor moves a timer from one object to another.@@ -307,6 +305,7 @@ impl_ = std::move(other.impl_); return *this; }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Destroys the timer. /**@@ -318,7 +317,7 @@ } /// Get the executor associated with the object.- const executor_type& get_executor() noexcept+ const executor_type& get_executor() ASIO_NOEXCEPT { return impl_.get_executor(); }@@ -633,7 +632,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code) @endcode@@ -650,12 +649,15 @@ */ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code))- WaitToken = default_completion_token_t<executor_type>>- auto async_wait(- WaitToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ WaitToken ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WaitToken,+ void (asio::error_code))+ async_wait(+ ASIO_MOVE_ARG(WaitToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<WaitToken, void (asio::error_code)>(- declval<initiate_async_wait>(), token))+ declval<initiate_async_wait>(), token))) { return async_initiate<WaitToken, void (asio::error_code)>( initiate_async_wait(this), token);@@ -663,9 +665,9 @@ private: // Disallow copying and assignment.- basic_deadline_timer(const basic_deadline_timer&) = delete;+ basic_deadline_timer(const basic_deadline_timer&) ASIO_DELETED; basic_deadline_timer& operator=(- const basic_deadline_timer&) = delete;+ const basic_deadline_timer&) ASIO_DELETED; class initiate_async_wait {@@ -677,13 +679,13 @@ { } - const executor_type& get_executor() const noexcept+ const executor_type& get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template <typename WaitHandler>- void operator()(WaitHandler&& handler) const+ void operator()(ASIO_MOVE_ARG(WaitHandler) handler) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a WaitHandler.@@ -709,7 +711,5 @@ #endif // defined(ASIO_HAS_BOOST_DATE_TIME) // || defined(GENERATING_DOCUMENTATION)--#endif // !defined(ASIO_NO_DEPRECATED) #endif // ASIO_BASIC_DEADLINE_TIMER_HPP
link/modules/asio-standalone/asio/include/asio/basic_file.hpp view
@@ -2,7 +2,7 @@ // basic_file.hpp // ~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -21,7 +21,6 @@ || defined(GENERATING_DOCUMENTATION) #include <string>-#include <utility> #include "asio/any_io_executor.hpp" #include "asio/async_result.hpp" #include "asio/detail/cstdint.hpp"@@ -40,6 +39,10 @@ # include "asio/detail/io_uring_file_service.hpp" #endif +#if defined(ASIO_HAS_MOVE)+# include <utility>+#endif // defined(ASIO_HAS_MOVE)+ #include "asio/detail/push_options.hpp" namespace asio {@@ -109,10 +112,10 @@ */ template <typename ExecutionContext> explicit basic_file(ExecutionContext& context,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- > = defaulted_constraint())+ >::type = defaulted_constraint()) : impl_(0, 0, context) { }@@ -128,20 +131,6 @@ * * @param open_flags A set of flags that determine how the file should be * opened.- *- * Exactly one of the following file_base::flags values must be specified:- *- * @li flags::read_only- * @li flags::write_only- * @li flags::read_write- *- * The following flags may be bitwise or-ed in addition:- *- * @li flags::append- * @li flags::create- * @li flags::exclusive- * @li flags::truncate- * @li flags::sync_all_on_write */ explicit basic_file(const executor_type& ex, const char* path, file_base::flags open_flags)@@ -152,7 +141,7 @@ asio::detail::throw_error(ec, "open"); } - /// Construct and open a basic_file.+ /// Construct a basic_file without opening it. /** * This constructor initialises a file and opens it. *@@ -164,28 +153,14 @@ * * @param open_flags A set of flags that determine how the file should be * opened.- *- * Exactly one of the following file_base::flags values must be specified:- *- * @li flags::read_only- * @li flags::write_only- * @li flags::read_write- *- * The following flags may be bitwise or-ed in addition:- *- * @li flags::append- * @li flags::create- * @li flags::exclusive- * @li flags::truncate- * @li flags::sync_all_on_write */ template <typename ExecutionContext> explicit basic_file(ExecutionContext& context, const char* path, file_base::flags open_flags,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- > = defaulted_constraint())+ >::type = defaulted_constraint()) : impl_(0, 0, context) { asio::error_code ec;@@ -204,20 +179,6 @@ * * @param open_flags A set of flags that determine how the file should be * opened.- *- * Exactly one of the following file_base::flags values must be specified:- *- * @li flags::read_only- * @li flags::write_only- * @li flags::read_write- *- * The following flags may be bitwise or-ed in addition:- *- * @li flags::append- * @li flags::create- * @li flags::exclusive- * @li flags::truncate- * @li flags::sync_all_on_write */ explicit basic_file(const executor_type& ex, const std::string& path, file_base::flags open_flags)@@ -229,7 +190,7 @@ asio::detail::throw_error(ec, "open"); } - /// Construct and open a basic_file.+ /// Construct a basic_file without opening it. /** * This constructor initialises a file and opens it. *@@ -241,28 +202,14 @@ * * @param open_flags A set of flags that determine how the file should be * opened.- *- * Exactly one of the following file_base::flags values must be specified:- *- * @li flags::read_only- * @li flags::write_only- * @li flags::read_write- *- * The following flags may be bitwise or-ed in addition:- *- * @li flags::append- * @li flags::create- * @li flags::exclusive- * @li flags::truncate- * @li flags::sync_all_on_write */ template <typename ExecutionContext> explicit basic_file(ExecutionContext& context, const std::string& path, file_base::flags open_flags,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- > = defaulted_constraint())+ >::type = defaulted_constraint()) : impl_(0, 0, context) { asio::error_code ec;@@ -305,10 +252,10 @@ */ template <typename ExecutionContext> basic_file(ExecutionContext& context, const native_handle_type& native_file,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- > = defaulted_constraint())+ >::type = defaulted_constraint()) : impl_(0, 0, context) { asio::error_code ec;@@ -317,6 +264,7 @@ asio::detail::throw_error(ec, "assign"); } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move-construct a basic_file from another. /** * This constructor moves a file from one object to another.@@ -327,7 +275,7 @@ * @note Following the move, the moved-from object is in the same state as if * constructed using the @c basic_file(const executor_type&) constructor. */- basic_file(basic_file&& other) noexcept+ basic_file(basic_file&& other) ASIO_NOEXCEPT : impl_(std::move(other.impl_)) { }@@ -364,10 +312,10 @@ */ template <typename Executor1> basic_file(basic_file<Executor1>&& other,- constraint_t<+ typename constraint< is_convertible<Executor1, Executor>::value, defaulted_constraint- > = defaulted_constraint())+ >::type = defaulted_constraint()) : impl_(std::move(other.impl_)) { }@@ -383,18 +331,19 @@ * constructed using the @c basic_file(const executor_type&) constructor. */ template <typename Executor1>- constraint_t<+ typename constraint< is_convertible<Executor1, Executor>::value, basic_file&- > operator=(basic_file<Executor1>&& other)+ >::type operator=(basic_file<Executor1>&& other) { basic_file tmp(std::move(other)); impl_ = std::move(tmp.impl_); return *this; }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Get the executor associated with the object.- const executor_type& get_executor() noexcept+ const executor_type& get_executor() ASIO_NOEXCEPT { return impl_.get_executor(); }@@ -410,20 +359,6 @@ * * @throws asio::system_error Thrown on failure. *- * Exactly one of the following file_base::flags values must be specified:- *- * @li flags::read_only- * @li flags::write_only- * @li flags::read_write- *- * The following flags may be bitwise or-ed in addition:- *- * @li flags::append- * @li flags::create- * @li flags::exclusive- * @li flags::truncate- * @li flags::sync_all_on_write- * * @par Example * @code * asio::stream_file file(my_context);@@ -446,20 +381,6 @@ * @param open_flags A set of flags that determine how the file should be * opened. *- * Exactly one of the following file_base::flags values must be specified:- *- * @li flags::read_only- * @li flags::write_only- * @li flags::read_write- *- * The following flags may be bitwise or-ed in addition:- *- * @li flags::append- * @li flags::create- * @li flags::exclusive- * @li flags::truncate- * @li flags::sync_all_on_write- * * @param ec Set to indicate what error occurred, if any. * * @par Example@@ -491,20 +412,6 @@ * * @throws asio::system_error Thrown on failure. *- * Exactly one of the following file_base::flags values must be specified:- *- * @li flags::read_only- * @li flags::write_only- * @li flags::read_write- *- * The following flags may be bitwise or-ed in addition:- *- * @li flags::append- * @li flags::create- * @li flags::exclusive- * @li flags::truncate- * @li flags::sync_all_on_write- * * @par Example * @code * asio::stream_file file(my_context);@@ -530,20 +437,6 @@ * * @param ec Set to indicate what error occurred, if any. *- * Exactly one of the following file_base::flags values must be specified:- *- * @li flags::read_only- * @li flags::write_only- * @li flags::read_write- *- * The following flags may be bitwise or-ed in addition:- *- * @li flags::append- * @li flags::create- * @li flags::exclusive- * @li flags::truncate- * @li flags::sync_all_on_write- * * @par Example * @code * asio::stream_file file(my_context);@@ -922,8 +815,8 @@ private: // Disallow copying and assignment.- basic_file(const basic_file&) = delete;- basic_file& operator=(const basic_file&) = delete;+ basic_file(const basic_file&) ASIO_DELETED;+ basic_file& operator=(const basic_file&) ASIO_DELETED; }; } // namespace asio
link/modules/asio-standalone/asio/include/asio/basic_io_object.hpp view
@@ -2,7 +2,7 @@ // basic_io_object.hpp // ~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -16,16 +16,13 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"--#if !defined(ASIO_NO_DEPRECATED) \- || defined(GENERATING_DOCUMENTATION)- #include "asio/io_context.hpp" #include "asio/detail/push_options.hpp" namespace asio { +#if defined(ASIO_HAS_MOVE) namespace detail { // Type trait used to determine whether a service supports move.@@ -48,13 +45,14 @@ static_cast<implementation_type*>(0))) == 1; }; }+#endif // defined(ASIO_HAS_MOVE) -/// (Deprecated) Base class for all I/O objects.+/// Base class for all I/O objects. /** * @note All I/O objects are non-copyable. However, when using C++0x, certain * I/O objects do support move construction and move assignment. */-#if defined(GENERATING_DOCUMENTATION)+#if !defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) template <typename IoObjectService> #else template <typename IoObjectService,@@ -69,7 +67,9 @@ /// The underlying implementation type of I/O object. typedef typename service_type::implementation_type implementation_type; - /// Get the io_context associated with the object.+#if !defined(ASIO_NO_DEPRECATED)+ /// (Deprecated: Use get_executor().) Get the io_context associated with the+ /// object. /** * This function may be used to obtain the io_context object that the I/O * object uses to dispatch handlers for asynchronous operations.@@ -82,7 +82,8 @@ return service_.get_io_context(); } - /// Get the io_context associated with the object.+ /// (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.@@ -94,12 +95,13 @@ { return service_.get_io_context(); }+#endif // !defined(ASIO_NO_DEPRECATED) /// The type of the executor associated with the object. typedef asio::io_context::executor_type executor_type; /// Get the executor associated with the object.- executor_type get_executor() noexcept+ executor_type get_executor() ASIO_NOEXCEPT { return service_.get_io_context().get_executor(); }@@ -188,6 +190,7 @@ implementation_type implementation_; }; +#if defined(ASIO_HAS_MOVE) // Specialisation for movable objects. template <typename IoObjectService> class basic_io_object<IoObjectService, true>@@ -196,6 +199,7 @@ typedef IoObjectService service_type; typedef typename service_type::implementation_type implementation_type; +#if !defined(ASIO_NO_DEPRECATED) asio::io_context& get_io_context() { return service_->get_io_context();@@ -205,10 +209,11 @@ { return service_->get_io_context(); }+#endif // !defined(ASIO_NO_DEPRECATED) typedef asio::io_context::executor_type executor_type; - executor_type get_executor() noexcept+ executor_type get_executor() ASIO_NOEXCEPT { return service_->get_io_context().get_executor(); }@@ -276,12 +281,10 @@ IoObjectService* service_; implementation_type implementation_; };+#endif // defined(ASIO_HAS_MOVE) } // namespace asio #include "asio/detail/pop_options.hpp"--#endif // !defined(ASIO_NO_DEPRECATED)- // || defined(GENERATING_DOCUMENTATION) #endif // ASIO_BASIC_IO_OBJECT_HPP
link/modules/asio-standalone/asio/include/asio/basic_random_access_file.hpp view
@@ -2,7 +2,7 @@ // basic_random_access_file.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -107,10 +107,10 @@ */ template <typename ExecutionContext> explicit basic_random_access_file(ExecutionContext& context,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- > = defaulted_constraint())+ >::type = defaulted_constraint()) : basic_file<Executor>(context) { }@@ -153,10 +153,10 @@ template <typename ExecutionContext> basic_random_access_file(ExecutionContext& context, const char* path, file_base::flags open_flags,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- > = defaulted_constraint())+ >::type = defaulted_constraint()) : basic_file<Executor>(context, path, open_flags) { }@@ -199,10 +199,10 @@ template <typename ExecutionContext> basic_random_access_file(ExecutionContext& context, const std::string& path, file_base::flags open_flags,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- > = defaulted_constraint())+ >::type = defaulted_constraint()) : basic_file<Executor>(context, path, open_flags) { }@@ -241,14 +241,15 @@ template <typename ExecutionContext> basic_random_access_file(ExecutionContext& context, const native_handle_type& native_file,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- > = defaulted_constraint())+ >::type = defaulted_constraint()) : basic_file<Executor>(context, native_file) { } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move-construct a basic_random_access_file from another. /** * This constructor moves a random-access file from one object to another.@@ -260,7 +261,7 @@ * constructed using the @c basic_random_access_file(const executor_type&) * constructor. */- basic_random_access_file(basic_random_access_file&& other) noexcept+ basic_random_access_file(basic_random_access_file&& other) ASIO_NOEXCEPT : basic_file<Executor>(std::move(other)) { }@@ -297,10 +298,10 @@ */ template <typename Executor1> basic_random_access_file(basic_random_access_file<Executor1>&& other,- constraint_t<+ typename constraint< is_convertible<Executor1, Executor>::value, defaulted_constraint- > = defaulted_constraint())+ >::type = defaulted_constraint()) : basic_file<Executor>(std::move(other)) { }@@ -319,14 +320,15 @@ * constructor. */ template <typename Executor1>- constraint_t<+ typename constraint< is_convertible<Executor1, Executor>::value, basic_random_access_file&- > operator=(basic_random_access_file<Executor1>&& other)+ >::type operator=(basic_random_access_file<Executor1>&& other) { basic_file<Executor>::operator=(std::move(other)); return *this; }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Destroys the file. /**@@ -427,7 +429,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -457,13 +459,18 @@ */ template <typename ConstBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) WriteToken = default_completion_token_t<executor_type>>- auto async_write_some_at(uint64_t offset, const ConstBufferSequence& buffers,- WriteToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ std::size_t)) WriteToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+ void (asio::error_code, std::size_t))+ async_write_some_at(uint64_t offset,+ const ConstBufferSequence& buffers,+ ASIO_MOVE_ARG(WriteToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<WriteToken, void (asio::error_code, std::size_t)>(- declval<initiate_async_write_some_at>(), token, offset, buffers))+ declval<initiate_async_write_some_at>(), token, offset, buffers))) { return async_initiate<WriteToken, void (asio::error_code, std::size_t)>(@@ -562,7 +569,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -593,13 +600,18 @@ */ template <typename MutableBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) ReadToken = default_completion_token_t<executor_type>>- auto async_read_some_at(uint64_t offset, const MutableBufferSequence& buffers,- ReadToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ std::size_t)) ReadToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+ async_read_some_at(uint64_t offset,+ const MutableBufferSequence& buffers,+ ASIO_MOVE_ARG(ReadToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<ReadToken, void (asio::error_code, std::size_t)>(- declval<initiate_async_read_some_at>(), token, offset, buffers))+ declval<initiate_async_read_some_at>(), token, offset, buffers))) { return async_initiate<ReadToken, void (asio::error_code, std::size_t)>(@@ -608,9 +620,9 @@ private: // Disallow copying and assignment.- basic_random_access_file(const basic_random_access_file&) = delete;+ basic_random_access_file(const basic_random_access_file&) ASIO_DELETED; basic_random_access_file& operator=(- const basic_random_access_file&) = delete;+ const basic_random_access_file&) ASIO_DELETED; class initiate_async_write_some_at {@@ -622,13 +634,13 @@ { } - const executor_type& get_executor() const noexcept+ const executor_type& get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template <typename WriteHandler, typename ConstBufferSequence>- void operator()(WriteHandler&& handler,+ void operator()(ASIO_MOVE_ARG(WriteHandler) handler, uint64_t offset, const ConstBufferSequence& buffers) const { // If you get an error on the following line it means that your handler@@ -655,13 +667,13 @@ { } - const executor_type& get_executor() const noexcept+ const executor_type& get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template <typename ReadHandler, typename MutableBufferSequence>- void operator()(ReadHandler&& handler,+ void operator()(ASIO_MOVE_ARG(ReadHandler) handler, uint64_t offset, const MutableBufferSequence& buffers) const { // If you get an error on the following line it means that your handler
link/modules/asio-standalone/asio/include/asio/basic_raw_socket.hpp view
@@ -2,7 +2,7 @@ // basic_raw_socket.hpp // ~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -113,9 +113,9 @@ */ template <typename ExecutionContext> explicit basic_raw_socket(ExecutionContext& context,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- > = 0)+ >::type = 0) : basic_socket<Protocol, Executor>(context) { }@@ -150,10 +150,10 @@ */ template <typename ExecutionContext> basic_raw_socket(ExecutionContext& context, const protocol_type& protocol,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- > = defaulted_constraint())+ >::type = defaulted_constraint()) : basic_socket<Protocol, Executor>(context, protocol) { }@@ -196,9 +196,9 @@ */ template <typename ExecutionContext> basic_raw_socket(ExecutionContext& context, const endpoint_type& endpoint,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- > = 0)+ >::type = 0) : basic_socket<Protocol, Executor>(context, endpoint) { }@@ -241,13 +241,14 @@ template <typename ExecutionContext> basic_raw_socket(ExecutionContext& context, const protocol_type& protocol, const native_handle_type& native_socket,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- > = 0)+ >::type = 0) : basic_socket<Protocol, Executor>(context, protocol, native_socket) { } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move-construct a basic_raw_socket from another. /** * This constructor moves a raw socket from one object to another.@@ -259,7 +260,7 @@ * constructed using the @c basic_raw_socket(const executor_type&) * constructor. */- basic_raw_socket(basic_raw_socket&& other) noexcept+ basic_raw_socket(basic_raw_socket&& other) ASIO_NOEXCEPT : basic_socket<Protocol, Executor>(std::move(other)) { }@@ -295,10 +296,10 @@ */ template <typename Protocol1, typename Executor1> basic_raw_socket(basic_raw_socket<Protocol1, Executor1>&& other,- constraint_t<+ typename constraint< is_convertible<Protocol1, Protocol>::value && is_convertible<Executor1, Executor>::value- > = 0)+ >::type = 0) : basic_socket<Protocol, Executor>(std::move(other)) { }@@ -315,15 +316,16 @@ * constructor. */ template <typename Protocol1, typename Executor1>- constraint_t<+ typename constraint< is_convertible<Protocol1, Protocol>::value && is_convertible<Executor1, Executor>::value, basic_raw_socket&- > operator=(basic_raw_socket<Protocol1, Executor1>&& other)+ >::type operator=(basic_raw_socket<Protocol1, Executor1>&& other) { basic_socket<Protocol, Executor>::operator=(std::move(other)); return *this; }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Destroys the socket. /**@@ -339,7 +341,7 @@ * This function is used to send data on the raw socket. The function call * will block until the data has been sent successfully or an error occurs. *- * @param buffers One or more data buffers to be sent on the socket.+ * @param buffers One ore more data buffers to be sent on the socket. * * @returns The number of bytes sent. *@@ -370,7 +372,7 @@ * This function is used to send data on the raw socket. The function call * will block until the data has been sent successfully or an error occurs. *- * @param buffers One or more data buffers to be sent on the socket.+ * @param buffers One ore more data buffers to be sent on the socket. * * @param flags Flags specifying how the send call is to be made. *@@ -439,7 +441,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -469,14 +471,18 @@ */ template <typename ConstBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) WriteToken = default_completion_token_t<executor_type>>- auto async_send(const ConstBufferSequence& buffers,- WriteToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ std::size_t)) WriteToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+ void (asio::error_code, std::size_t))+ async_send(const ConstBufferSequence& buffers,+ ASIO_MOVE_ARG(WriteToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<WriteToken, void (asio::error_code, std::size_t)>( declval<initiate_async_send>(), token,- buffers, socket_base::message_flags(0)))+ buffers, socket_base::message_flags(0)))) { return async_initiate<WriteToken, void (asio::error_code, std::size_t)>(@@ -509,7 +515,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -530,14 +536,18 @@ */ template <typename ConstBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) WriteToken = default_completion_token_t<executor_type>>- auto async_send(const ConstBufferSequence& buffers,+ std::size_t)) WriteToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+ void (asio::error_code, std::size_t))+ async_send(const ConstBufferSequence& buffers, socket_base::message_flags flags,- WriteToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ ASIO_MOVE_ARG(WriteToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<WriteToken, void (asio::error_code, std::size_t)>(- declval<initiate_async_send>(), token, buffers, flags))+ declval<initiate_async_send>(), token, buffers, flags))) { return async_initiate<WriteToken, void (asio::error_code, std::size_t)>(@@ -658,7 +668,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -687,15 +697,19 @@ */ template <typename ConstBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) WriteToken = default_completion_token_t<executor_type>>- auto async_send_to(const ConstBufferSequence& buffers,+ std::size_t)) WriteToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+ void (asio::error_code, std::size_t))+ async_send_to(const ConstBufferSequence& buffers, const endpoint_type& destination,- WriteToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ ASIO_MOVE_ARG(WriteToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<WriteToken, void (asio::error_code, std::size_t)>( declval<initiate_async_send_to>(), token, buffers,- destination, socket_base::message_flags(0)))+ destination, socket_base::message_flags(0)))) { return async_initiate<WriteToken, void (asio::error_code, std::size_t)>(@@ -731,7 +745,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -748,15 +762,19 @@ */ template <typename ConstBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) WriteToken = default_completion_token_t<executor_type>>- auto async_send_to(const ConstBufferSequence& buffers,+ std::size_t)) WriteToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+ void (asio::error_code, std::size_t))+ async_send_to(const ConstBufferSequence& buffers, const endpoint_type& destination, socket_base::message_flags flags,- WriteToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ ASIO_MOVE_ARG(WriteToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<WriteToken, void (asio::error_code, std::size_t)>( declval<initiate_async_send_to>(), token,- buffers, destination, flags))+ buffers, destination, flags))) { return async_initiate<WriteToken, void (asio::error_code, std::size_t)>(@@ -876,7 +894,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -907,14 +925,18 @@ */ template <typename MutableBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) ReadToken = default_completion_token_t<executor_type>>- auto async_receive(const MutableBufferSequence& buffers,- ReadToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ std::size_t)) ReadToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+ async_receive(const MutableBufferSequence& buffers,+ ASIO_MOVE_ARG(ReadToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<ReadToken, void (asio::error_code, std::size_t)>( declval<initiate_async_receive>(), token,- buffers, socket_base::message_flags(0)))+ buffers, socket_base::message_flags(0)))) { return async_initiate<ReadToken, void (asio::error_code, std::size_t)>(@@ -947,7 +969,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -969,14 +991,17 @@ template <typename MutableBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, std::size_t)) ReadToken- = default_completion_token_t<executor_type>>- auto async_receive(const MutableBufferSequence& buffers,+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+ async_receive(const MutableBufferSequence& buffers, socket_base::message_flags flags,- ReadToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ ASIO_MOVE_ARG(ReadToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<ReadToken, void (asio::error_code, std::size_t)>(- declval<initiate_async_receive>(), token, buffers, flags))+ declval<initiate_async_receive>(), token, buffers, flags))) { return async_initiate<ReadToken, void (asio::error_code, std::size_t)>(@@ -1019,7 +1044,7 @@ asio::detail::throw_error(ec, "receive_from"); return s; }-+ /// Receive raw data with the endpoint of the sender. /** * This function is used to receive raw data. The function call will block@@ -1046,7 +1071,7 @@ asio::detail::throw_error(ec, "receive_from"); return s; }-+ /// Receive raw data with the endpoint of the sender. /** * This function is used to receive raw data. The function call will block@@ -1100,7 +1125,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -1126,16 +1151,19 @@ */ template <typename MutableBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) ReadToken = default_completion_token_t<executor_type>>- auto async_receive_from(const MutableBufferSequence& buffers,+ std::size_t)) ReadToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+ async_receive_from(const MutableBufferSequence& buffers, endpoint_type& sender_endpoint,- ReadToken&& token- = default_completion_token_t<executor_type>())- -> decltype(+ ASIO_MOVE_ARG(ReadToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<ReadToken, void (asio::error_code, std::size_t)>( declval<initiate_async_receive_from>(), token, buffers,- &sender_endpoint, socket_base::message_flags(0)))+ &sender_endpoint, socket_base::message_flags(0)))) { return async_initiate<ReadToken, void (asio::error_code, std::size_t)>(@@ -1173,7 +1201,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -1191,15 +1219,18 @@ template <typename MutableBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, std::size_t)) ReadToken- = default_completion_token_t<executor_type>>- auto async_receive_from(const MutableBufferSequence& buffers,+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+ async_receive_from(const MutableBufferSequence& buffers, endpoint_type& sender_endpoint, socket_base::message_flags flags,- ReadToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ ASIO_MOVE_ARG(ReadToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<ReadToken, void (asio::error_code, std::size_t)>( declval<initiate_async_receive_from>(), token,- buffers, &sender_endpoint, flags))+ buffers, &sender_endpoint, flags))) { return async_initiate<ReadToken, void (asio::error_code, std::size_t)>(@@ -1209,8 +1240,8 @@ private: // Disallow copying and assignment.- basic_raw_socket(const basic_raw_socket&) = delete;- basic_raw_socket& operator=(const basic_raw_socket&) = delete;+ basic_raw_socket(const basic_raw_socket&) ASIO_DELETED;+ basic_raw_socket& operator=(const basic_raw_socket&) ASIO_DELETED; class initiate_async_send {@@ -1222,13 +1253,13 @@ { } - const executor_type& get_executor() const noexcept+ const executor_type& get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template <typename WriteHandler, typename ConstBufferSequence>- void operator()(WriteHandler&& handler,+ void operator()(ASIO_MOVE_ARG(WriteHandler) handler, const ConstBufferSequence& buffers, socket_base::message_flags flags) const {@@ -1256,13 +1287,13 @@ { } - const executor_type& get_executor() const noexcept+ const executor_type& get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template <typename WriteHandler, typename ConstBufferSequence>- void operator()(WriteHandler&& handler,+ void operator()(ASIO_MOVE_ARG(WriteHandler) handler, const ConstBufferSequence& buffers, const endpoint_type& destination, socket_base::message_flags flags) const {@@ -1290,13 +1321,13 @@ { } - const executor_type& get_executor() const noexcept+ const executor_type& get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template <typename ReadHandler, typename MutableBufferSequence>- void operator()(ReadHandler&& handler,+ void operator()(ASIO_MOVE_ARG(ReadHandler) handler, const MutableBufferSequence& buffers, socket_base::message_flags flags) const {@@ -1324,13 +1355,13 @@ { } - const executor_type& get_executor() const noexcept+ const executor_type& get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template <typename ReadHandler, typename MutableBufferSequence>- void operator()(ReadHandler&& handler,+ void operator()(ASIO_MOVE_ARG(ReadHandler) handler, const MutableBufferSequence& buffers, endpoint_type* sender_endpoint, socket_base::message_flags flags) const {
link/modules/asio-standalone/asio/include/asio/basic_readable_pipe.hpp view
@@ -2,7 +2,7 @@ // basic_readable_pipe.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -21,7 +21,6 @@ || defined(GENERATING_DOCUMENTATION) #include <string>-#include <utility> #include "asio/any_io_executor.hpp" #include "asio/async_result.hpp" #include "asio/detail/handler_type_requirements.hpp"@@ -39,6 +38,10 @@ # include "asio/detail/reactive_descriptor_service.hpp" #endif +#if defined(ASIO_HAS_MOVE)+# include <utility>+#endif // defined(ASIO_HAS_MOVE)+ #include "asio/detail/push_options.hpp" namespace asio {@@ -109,10 +112,10 @@ */ template <typename ExecutionContext> explicit basic_readable_pipe(ExecutionContext& context,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- > = defaulted_constraint())+ >::type = defaulted_constraint()) : impl_(0, 0, context) { }@@ -156,9 +159,9 @@ template <typename ExecutionContext> basic_readable_pipe(ExecutionContext& context, const native_handle_type& native_pipe,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- > = 0)+ >::type = 0) : impl_(0, 0, context) { asio::error_code ec;@@ -167,6 +170,7 @@ asio::detail::throw_error(ec, "assign"); } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move-construct a basic_readable_pipe from another. /** * This constructor moves a pipe from one object to another.@@ -217,10 +221,10 @@ */ template <typename Executor1> basic_readable_pipe(basic_readable_pipe<Executor1>&& other,- constraint_t<+ typename constraint< is_convertible<Executor1, Executor>::value, defaulted_constraint- > = defaulted_constraint())+ >::type = defaulted_constraint()) : impl_(std::move(other.impl_)) { }@@ -237,15 +241,16 @@ * constructor. */ template <typename Executor1>- constraint_t<+ typename constraint< is_convertible<Executor1, Executor>::value, basic_readable_pipe&- > operator=(basic_readable_pipe<Executor1>&& other)+ >::type operator=(basic_readable_pipe<Executor1>&& other) { basic_readable_pipe tmp(std::move(other)); impl_ = std::move(tmp.impl_); return *this; }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Destroys the pipe. /**@@ -258,7 +263,7 @@ } /// Get the executor associated with the object.- const executor_type& get_executor() noexcept+ const executor_type& get_executor() ASIO_NOEXCEPT { return impl_.get_executor(); }@@ -534,7 +539,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -556,13 +561,17 @@ */ template <typename MutableBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) ReadToken = default_completion_token_t<executor_type>>- auto async_read_some(const MutableBufferSequence& buffers,- ReadToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ std::size_t)) ReadToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+ async_read_some(const MutableBufferSequence& buffers,+ ASIO_MOVE_ARG(ReadToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<ReadToken, void (asio::error_code, std::size_t)>(- declval<initiate_async_read_some>(), token, buffers))+ declval<initiate_async_read_some>(), token, buffers))) { return async_initiate<ReadToken, void (asio::error_code, std::size_t)>(@@ -571,8 +580,8 @@ private: // Disallow copying and assignment.- basic_readable_pipe(const basic_readable_pipe&) = delete;- basic_readable_pipe& operator=(const basic_readable_pipe&) = delete;+ basic_readable_pipe(const basic_readable_pipe&) ASIO_DELETED;+ basic_readable_pipe& operator=(const basic_readable_pipe&) ASIO_DELETED; class initiate_async_read_some {@@ -584,13 +593,13 @@ { } - const executor_type& get_executor() const noexcept+ const executor_type& get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template <typename ReadHandler, typename MutableBufferSequence>- void operator()(ReadHandler&& handler,+ void operator()(ASIO_MOVE_ARG(ReadHandler) handler, const MutableBufferSequence& buffers) const { // If you get an error on the following line it means that your handler
link/modules/asio-standalone/asio/include/asio/basic_seq_packet_socket.hpp view
@@ -2,7 +2,7 @@ // basic_seq_packet_socket.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -111,9 +111,9 @@ */ template <typename ExecutionContext> explicit basic_seq_packet_socket(ExecutionContext& context,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- > = 0)+ >::type = 0) : basic_socket<Protocol, Executor>(context) { }@@ -154,10 +154,10 @@ template <typename ExecutionContext> basic_seq_packet_socket(ExecutionContext& context, const protocol_type& protocol,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- > = defaulted_constraint())+ >::type = defaulted_constraint()) : basic_socket<Protocol, Executor>(context, protocol) { }@@ -202,9 +202,9 @@ template <typename ExecutionContext> basic_seq_packet_socket(ExecutionContext& context, const endpoint_type& endpoint,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- > = 0)+ >::type = 0) : basic_socket<Protocol, Executor>(context, endpoint) { }@@ -247,13 +247,14 @@ template <typename ExecutionContext> basic_seq_packet_socket(ExecutionContext& context, const protocol_type& protocol, const native_handle_type& native_socket,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- > = 0)+ >::type = 0) : basic_socket<Protocol, Executor>(context, protocol, native_socket) { } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move-construct a basic_seq_packet_socket from another. /** * This constructor moves a sequenced packet socket from one object to@@ -266,7 +267,7 @@ * constructed using the @c basic_seq_packet_socket(const executor_type&) * constructor. */- basic_seq_packet_socket(basic_seq_packet_socket&& other) noexcept+ basic_seq_packet_socket(basic_seq_packet_socket&& other) ASIO_NOEXCEPT : basic_socket<Protocol, Executor>(std::move(other)) { }@@ -304,10 +305,10 @@ */ template <typename Protocol1, typename Executor1> basic_seq_packet_socket(basic_seq_packet_socket<Protocol1, Executor1>&& other,- constraint_t<+ typename constraint< is_convertible<Protocol1, Protocol>::value && is_convertible<Executor1, Executor>::value- > = 0)+ >::type = 0) : basic_socket<Protocol, Executor>(std::move(other)) { }@@ -326,15 +327,16 @@ * constructor. */ template <typename Protocol1, typename Executor1>- constraint_t<+ typename constraint< is_convertible<Protocol1, Protocol>::value && is_convertible<Executor1, Executor>::value, basic_seq_packet_socket&- > operator=(basic_seq_packet_socket<Protocol1, Executor1>&& other)+ >::type operator=(basic_seq_packet_socket<Protocol1, Executor1>&& other) { basic_socket<Protocol, Executor>::operator=(std::move(other)); return *this; }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Destroys the socket. /**@@ -430,7 +432,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -457,15 +459,17 @@ template <typename ConstBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, std::size_t)) WriteToken- = default_completion_token_t<executor_type>>- auto async_send(const ConstBufferSequence& buffers,+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+ void (asio::error_code, std::size_t))+ async_send(const ConstBufferSequence& buffers, socket_base::message_flags flags,- WriteToken&& token- = default_completion_token_t<executor_type>())- -> decltype(+ ASIO_MOVE_ARG(WriteToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<WriteToken, void (asio::error_code, std::size_t)>(- declval<initiate_async_send>(), token, buffers, flags))+ declval<initiate_async_send>(), token, buffers, flags))) { return async_initiate<WriteToken, void (asio::error_code, std::size_t)>(@@ -620,7 +624,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -647,15 +651,19 @@ */ template <typename MutableBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) ReadToken = default_completion_token_t<executor_type>>- auto async_receive(const MutableBufferSequence& buffers,+ std::size_t)) ReadToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+ async_receive(const MutableBufferSequence& buffers, socket_base::message_flags& out_flags,- ReadToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ ASIO_MOVE_ARG(ReadToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<ReadToken, void (asio::error_code, std::size_t)>( declval<initiate_async_receive_with_flags>(), token,- buffers, socket_base::message_flags(0), &out_flags))+ buffers, socket_base::message_flags(0), &out_flags))) { return async_initiate<ReadToken, void (asio::error_code, std::size_t)>(@@ -694,7 +702,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -723,16 +731,20 @@ */ template <typename MutableBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) ReadToken = default_completion_token_t<executor_type>>- auto async_receive(const MutableBufferSequence& buffers,+ std::size_t)) ReadToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+ async_receive(const MutableBufferSequence& buffers, socket_base::message_flags in_flags, socket_base::message_flags& out_flags,- ReadToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ ASIO_MOVE_ARG(ReadToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<ReadToken, void (asio::error_code, std::size_t)>( declval<initiate_async_receive_with_flags>(),- token, buffers, in_flags, &out_flags))+ token, buffers, in_flags, &out_flags))) { return async_initiate<ReadToken, void (asio::error_code, std::size_t)>(@@ -742,9 +754,9 @@ private: // Disallow copying and assignment.- basic_seq_packet_socket(const basic_seq_packet_socket&) = delete;+ basic_seq_packet_socket(const basic_seq_packet_socket&) ASIO_DELETED; basic_seq_packet_socket& operator=(- const basic_seq_packet_socket&) = delete;+ const basic_seq_packet_socket&) ASIO_DELETED; class initiate_async_send {@@ -756,13 +768,13 @@ { } - const executor_type& get_executor() const noexcept+ const executor_type& get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template <typename WriteHandler, typename ConstBufferSequence>- void operator()(WriteHandler&& handler,+ void operator()(ASIO_MOVE_ARG(WriteHandler) handler, const ConstBufferSequence& buffers, socket_base::message_flags flags) const {@@ -790,13 +802,13 @@ { } - const executor_type& get_executor() const noexcept+ const executor_type& get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template <typename ReadHandler, typename MutableBufferSequence>- void operator()(ReadHandler&& handler,+ void operator()(ASIO_MOVE_ARG(ReadHandler) handler, const MutableBufferSequence& buffers, socket_base::message_flags in_flags, socket_base::message_flags* out_flags) const
link/modules/asio-standalone/asio/include/asio/basic_serial_port.hpp view
@@ -2,7 +2,7 @@ // basic_serial_port.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying@@ -22,7 +22,6 @@ || defined(GENERATING_DOCUMENTATION) #include <string>-#include <utility> #include "asio/any_io_executor.hpp" #include "asio/async_result.hpp" #include "asio/detail/handler_type_requirements.hpp"@@ -39,6 +38,10 @@ # include "asio/detail/posix_serial_port_service.hpp" #endif +#if defined(ASIO_HAS_MOVE)+# include <utility>+#endif // defined(ASIO_HAS_MOVE)+ #include "asio/detail/push_options.hpp" namespace asio {@@ -109,10 +112,10 @@ */ template <typename ExecutionContext> explicit basic_serial_port(ExecutionContext& context,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- > = defaulted_constraint())+ >::type = defaulted_constraint()) : impl_(0, 0, context) { }@@ -151,9 +154,9 @@ */ template <typename ExecutionContext> basic_serial_port(ExecutionContext& context, const char* device,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- > = 0)+ >::type = 0) : impl_(0, 0, context) { asio::error_code ec;@@ -195,9 +198,9 @@ */ template <typename ExecutionContext> basic_serial_port(ExecutionContext& context, const std::string& device,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- > = 0)+ >::type = 0) : impl_(0, 0, context) { asio::error_code ec;@@ -244,9 +247,9 @@ template <typename ExecutionContext> basic_serial_port(ExecutionContext& context, const native_handle_type& native_serial_port,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- > = 0)+ >::type = 0) : impl_(0, 0, context) { asio::error_code ec;@@ -255,6 +258,7 @@ asio::detail::throw_error(ec, "assign"); } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move-construct a basic_serial_port from another. /** * This constructor moves a serial port from one object to another.@@ -306,10 +310,10 @@ */ template <typename Executor1> basic_serial_port(basic_serial_port<Executor1>&& other,- constraint_t<+ typename constraint< is_convertible<Executor1, Executor>::value, defaulted_constraint- > = defaulted_constraint())+ >::type = defaulted_constraint()) : impl_(std::move(other.impl_)) { }@@ -327,15 +331,16 @@ * constructor. */ template <typename Executor1>- constraint_t<+ typename constraint< is_convertible<Executor1, Executor>::value, basic_serial_port&- > operator=(basic_serial_port<Executor1>&& other)+ >::type operator=(basic_serial_port<Executor1>&& other) { basic_serial_port tmp(std::move(other)); impl_ = std::move(tmp.impl_); return *this; }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Destroys the serial port. /**@@ -348,7 +353,7 @@ } /// Get the executor associated with the object.- const executor_type& get_executor() noexcept+ const executor_type& get_executor() ASIO_NOEXCEPT { return impl_.get_executor(); }@@ -724,7 +729,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -755,13 +760,17 @@ */ template <typename ConstBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) WriteToken = default_completion_token_t<executor_type>>- auto async_write_some(const ConstBufferSequence& buffers,- WriteToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ std::size_t)) WriteToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+ void (asio::error_code, std::size_t))+ async_write_some(const ConstBufferSequence& buffers,+ ASIO_MOVE_ARG(WriteToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<WriteToken, void (asio::error_code, std::size_t)>(- declval<initiate_async_write_some>(), token, buffers))+ declval<initiate_async_write_some>(), token, buffers))) { return async_initiate<WriteToken, void (asio::error_code, std::size_t)>(@@ -854,7 +863,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -886,13 +895,17 @@ */ template <typename MutableBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) ReadToken = default_completion_token_t<executor_type>>- auto async_read_some(const MutableBufferSequence& buffers,- ReadToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ std::size_t)) ReadToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+ async_read_some(const MutableBufferSequence& buffers,+ ASIO_MOVE_ARG(ReadToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<ReadToken, void (asio::error_code, std::size_t)>(- declval<initiate_async_read_some>(), token, buffers))+ declval<initiate_async_read_some>(), token, buffers))) { return async_initiate<ReadToken, void (asio::error_code, std::size_t)>(@@ -901,8 +914,8 @@ private: // Disallow copying and assignment.- basic_serial_port(const basic_serial_port&) = delete;- basic_serial_port& operator=(const basic_serial_port&) = delete;+ basic_serial_port(const basic_serial_port&) ASIO_DELETED;+ basic_serial_port& operator=(const basic_serial_port&) ASIO_DELETED; class initiate_async_write_some {@@ -914,13 +927,13 @@ { } - const executor_type& get_executor() const noexcept+ const executor_type& get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template <typename WriteHandler, typename ConstBufferSequence>- void operator()(WriteHandler&& handler,+ void operator()(ASIO_MOVE_ARG(WriteHandler) handler, const ConstBufferSequence& buffers) const { // If you get an error on the following line it means that your handler@@ -947,13 +960,13 @@ { } - const executor_type& get_executor() const noexcept+ const executor_type& get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template <typename ReadHandler, typename MutableBufferSequence>- void operator()(ReadHandler&& handler,+ void operator()(ASIO_MOVE_ARG(ReadHandler) handler, const MutableBufferSequence& buffers) const { // If you get an error on the following line it means that your handler
link/modules/asio-standalone/asio/include/asio/basic_signal_set.hpp view
@@ -2,7 +2,7 @@ // basic_signal_set.hpp // ~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -134,10 +134,10 @@ */ template <typename ExecutionContext> explicit basic_signal_set(ExecutionContext& context,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- > = defaulted_constraint())+ >::type = defaulted_constraint()) : impl_(0, 0, context) { }@@ -180,10 +180,10 @@ */ template <typename ExecutionContext> basic_signal_set(ExecutionContext& context, int signal_number_1,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- > = defaulted_constraint())+ >::type = defaulted_constraint()) : impl_(0, 0, context) { asio::error_code ec;@@ -239,10 +239,10 @@ template <typename ExecutionContext> basic_signal_set(ExecutionContext& context, int signal_number_1, int signal_number_2,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- > = defaulted_constraint())+ >::type = defaulted_constraint()) : impl_(0, 0, context) { asio::error_code ec;@@ -308,10 +308,10 @@ template <typename ExecutionContext> basic_signal_set(ExecutionContext& context, int signal_number_1, int signal_number_2, int signal_number_3,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- > = defaulted_constraint())+ >::type = defaulted_constraint()) : impl_(0, 0, context) { asio::error_code ec;@@ -334,7 +334,7 @@ } /// Get the executor associated with the object.- const executor_type& get_executor() noexcept+ const executor_type& get_executor() ASIO_NOEXCEPT { return impl_.get_executor(); }@@ -573,7 +573,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, int) @endcode@@ -587,20 +587,18 @@ * @li @c cancellation_type::partial * * @li @c cancellation_type::total- *- * @note Unlike the POSIX function @c signal, @c async_wait executes its- * completion handler as specified in the @ref async_op_requirements. This- * means it places no async-signal safety restrictions on what work can be- * performed in a completion handler. */ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, int))- SignalToken = default_completion_token_t<executor_type>>- auto async_wait(- SignalToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ SignalToken ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(SignalToken,+ void (asio::error_code, int))+ async_wait(+ ASIO_MOVE_ARG(SignalToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<SignalToken, void (asio::error_code, int)>(- declval<initiate_async_wait>(), token))+ declval<initiate_async_wait>(), token))) { return async_initiate<SignalToken, void (asio::error_code, int)>( initiate_async_wait(this), token);@@ -608,8 +606,8 @@ private: // Disallow copying and assignment.- basic_signal_set(const basic_signal_set&) = delete;- basic_signal_set& operator=(const basic_signal_set&) = delete;+ basic_signal_set(const basic_signal_set&) ASIO_DELETED;+ basic_signal_set& operator=(const basic_signal_set&) ASIO_DELETED; class initiate_async_wait {@@ -621,13 +619,13 @@ { } - const executor_type& get_executor() const noexcept+ const executor_type& get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template <typename SignalHandler>- void operator()(SignalHandler&& handler) const+ void operator()(ASIO_MOVE_ARG(SignalHandler) handler) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a SignalHandler.
link/modules/asio-standalone/asio/include/asio/basic_socket.hpp view
@@ -2,7 +2,7 @@ // basic_socket.hpp // ~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -15,7 +15,6 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <utility> #include "asio/any_io_executor.hpp" #include "asio/detail/config.hpp" #include "asio/async_result.hpp"@@ -39,6 +38,10 @@ # include "asio/detail/reactive_socket_service.hpp" #endif +#if defined(ASIO_HAS_MOVE)+# include <utility>+#endif // defined(ASIO_HAS_MOVE)+ #include "asio/detail/push_options.hpp" namespace asio {@@ -131,9 +134,9 @@ */ template <typename ExecutionContext> explicit basic_socket(ExecutionContext& context,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- > = 0)+ >::type = 0) : impl_(0, 0, context) { }@@ -171,10 +174,10 @@ */ template <typename ExecutionContext> basic_socket(ExecutionContext& context, const protocol_type& protocol,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- > = defaulted_constraint())+ >::type = defaulted_constraint()) : impl_(0, 0, context) { asio::error_code ec;@@ -226,9 +229,9 @@ */ template <typename ExecutionContext> basic_socket(ExecutionContext& context, const endpoint_type& endpoint,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- > = 0)+ >::type = 0) : impl_(0, 0, context) { asio::error_code ec;@@ -279,9 +282,9 @@ template <typename ExecutionContext> basic_socket(ExecutionContext& context, const protocol_type& protocol, const native_handle_type& native_socket,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- > = 0)+ >::type = 0) : impl_(0, 0, context) { asio::error_code ec;@@ -290,6 +293,7 @@ asio::detail::throw_error(ec, "assign"); } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move-construct a basic_socket from another. /** * This constructor moves a socket from one object to another.@@ -300,7 +304,7 @@ * @note Following the move, the moved-from object is in the same state as if * constructed using the @c basic_socket(const executor_type&) constructor. */- basic_socket(basic_socket&& other) noexcept+ basic_socket(basic_socket&& other) ASIO_NOEXCEPT : impl_(std::move(other.impl_)) { }@@ -337,10 +341,10 @@ */ template <typename Protocol1, typename Executor1> basic_socket(basic_socket<Protocol1, Executor1>&& other,- constraint_t<+ typename constraint< is_convertible<Protocol1, Protocol>::value && is_convertible<Executor1, Executor>::value- > = 0)+ >::type = 0) : impl_(std::move(other.impl_)) { }@@ -356,19 +360,20 @@ * constructed using the @c basic_socket(const executor_type&) constructor. */ template <typename Protocol1, typename Executor1>- constraint_t<+ typename constraint< is_convertible<Protocol1, Protocol>::value && is_convertible<Executor1, Executor>::value, basic_socket&- > operator=(basic_socket<Protocol1, Executor1>&& other)+ >::type operator=(basic_socket<Protocol1, Executor1>&& other) { basic_socket tmp(std::move(other)); impl_ = std::move(tmp.impl_); return *this; }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Get the executor associated with the object.- const executor_type& get_executor() noexcept+ const executor_type& get_executor() ASIO_NOEXCEPT { return impl_.get_executor(); }@@ -927,7 +932,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code) @endcode@@ -962,13 +967,16 @@ */ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code))- ConnectToken = default_completion_token_t<executor_type>>- auto async_connect(const endpoint_type& peer_endpoint,- ConnectToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ ConnectToken ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ConnectToken,+ void (asio::error_code))+ async_connect(const endpoint_type& peer_endpoint,+ ASIO_MOVE_ARG(ConnectToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<ConnectToken, void (asio::error_code)>(- declval<initiate_async_connect>(), token,- peer_endpoint, declval<asio::error_code&>()))+ declval<initiate_async_connect>(), token,+ peer_endpoint, declval<asio::error_code&>()))) { asio::error_code open_ec; if (!is_open())@@ -1779,7 +1787,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code) @endcode@@ -1813,12 +1821,15 @@ */ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code))- WaitToken = default_completion_token_t<executor_type>>- auto async_wait(wait_type w,- WaitToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ WaitToken ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WaitToken,+ void (asio::error_code))+ async_wait(wait_type w,+ ASIO_MOVE_ARG(WaitToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<WaitToken, void (asio::error_code)>(- declval<initiate_async_wait>(), token, w))+ declval<initiate_async_wait>(), token, w))) { return async_initiate<WaitToken, void (asio::error_code)>( initiate_async_wait(this), token, w);@@ -1850,8 +1861,8 @@ private: // Disallow copying and assignment.- basic_socket(const basic_socket&) = delete;- basic_socket& operator=(const basic_socket&) = delete;+ basic_socket(const basic_socket&) ASIO_DELETED;+ basic_socket& operator=(const basic_socket&) ASIO_DELETED; class initiate_async_connect {@@ -1863,13 +1874,13 @@ { } - const executor_type& get_executor() const noexcept+ const executor_type& get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template <typename ConnectHandler>- void operator()(ConnectHandler&& handler,+ void operator()(ASIO_MOVE_ARG(ConnectHandler) handler, const endpoint_type& peer_endpoint, const asio::error_code& open_ec) const {@@ -1881,7 +1892,7 @@ { asio::post(self_->impl_.get_executor(), asio::detail::bind_handler(- static_cast<ConnectHandler&&>(handler), open_ec));+ ASIO_MOVE_CAST(ConnectHandler)(handler), open_ec)); } else {@@ -1906,13 +1917,13 @@ { } - const executor_type& get_executor() const noexcept+ const executor_type& get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template <typename WaitHandler>- void operator()(WaitHandler&& handler, wait_type w) const+ void operator()(ASIO_MOVE_ARG(WaitHandler) handler, wait_type w) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a WaitHandler.
link/modules/asio-standalone/asio/include/asio/basic_socket_acceptor.hpp view
@@ -2,7 +2,7 @@ // basic_socket_acceptor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -15,7 +15,6 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <utility> #include "asio/detail/config.hpp" #include "asio/any_io_executor.hpp" #include "asio/basic_socket.hpp"@@ -38,6 +37,10 @@ # include "asio/detail/reactive_socket_service.hpp" #endif +#if defined(ASIO_HAS_MOVE)+# include <utility>+#endif // defined(ASIO_HAS_MOVE)+ #include "asio/detail/push_options.hpp" namespace asio {@@ -148,9 +151,9 @@ */ template <typename ExecutionContext> explicit basic_socket_acceptor(ExecutionContext& context,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- > = 0)+ >::type = 0) : impl_(0, 0, context) { }@@ -190,10 +193,10 @@ template <typename ExecutionContext> basic_socket_acceptor(ExecutionContext& context, const protocol_type& protocol,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- > = defaulted_constraint())+ >::type = defaulted_constraint()) : impl_(0, 0, context) { asio::error_code ec;@@ -279,9 +282,9 @@ template <typename ExecutionContext> basic_socket_acceptor(ExecutionContext& context, const endpoint_type& endpoint, bool reuse_addr = true,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- > = 0)+ >::type = 0) : impl_(0, 0, context) { asio::error_code ec;@@ -344,9 +347,9 @@ template <typename ExecutionContext> basic_socket_acceptor(ExecutionContext& context, const protocol_type& protocol, const native_handle_type& native_acceptor,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- > = 0)+ >::type = 0) : impl_(0, 0, context) { asio::error_code ec;@@ -355,6 +358,7 @@ asio::detail::throw_error(ec, "assign"); } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move-construct a basic_socket_acceptor from another. /** * This constructor moves an acceptor from one object to another.@@ -366,7 +370,7 @@ * constructed using the @c basic_socket_acceptor(const executor_type&) * constructor. */- basic_socket_acceptor(basic_socket_acceptor&& other) noexcept+ basic_socket_acceptor(basic_socket_acceptor&& other) ASIO_NOEXCEPT : impl_(std::move(other.impl_)) { }@@ -406,10 +410,10 @@ */ template <typename Protocol1, typename Executor1> basic_socket_acceptor(basic_socket_acceptor<Protocol1, Executor1>&& other,- constraint_t<+ typename constraint< is_convertible<Protocol1, Protocol>::value && is_convertible<Executor1, Executor>::value- > = 0)+ >::type = 0) : impl_(std::move(other.impl_)) { }@@ -427,16 +431,17 @@ * constructor. */ template <typename Protocol1, typename Executor1>- constraint_t<+ typename constraint< is_convertible<Protocol1, Protocol>::value && is_convertible<Executor1, Executor>::value, basic_socket_acceptor&- > operator=(basic_socket_acceptor<Protocol1, Executor1>&& other)+ >::type operator=(basic_socket_acceptor<Protocol1, Executor1>&& other) { basic_socket_acceptor tmp(std::move(other)); impl_ = std::move(tmp.impl_); return *this; }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Destroys the acceptor. /**@@ -449,7 +454,7 @@ } /// Get the executor associated with the object.- const executor_type& get_executor() noexcept+ const executor_type& get_executor() ASIO_NOEXCEPT { return impl_.get_executor(); }@@ -1213,7 +1218,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code) @endcode@@ -1249,12 +1254,15 @@ */ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code))- WaitToken = default_completion_token_t<executor_type>>- auto async_wait(wait_type w,- WaitToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ WaitToken ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WaitToken,+ void (asio::error_code))+ async_wait(wait_type w,+ ASIO_MOVE_ARG(WaitToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<WaitToken, void (asio::error_code)>(- declval<initiate_async_wait>(), token, w))+ declval<initiate_async_wait>(), token, w))) { return async_initiate<WaitToken, void (asio::error_code)>( initiate_async_wait(this), token, w);@@ -1281,9 +1289,9 @@ */ template <typename Protocol1, typename Executor1> void accept(basic_socket<Protocol1, Executor1>& peer,- constraint_t<+ typename constraint< is_convertible<Protocol, Protocol1>::value- > = 0)+ >::type = 0) { asio::error_code ec; impl_.get_service().accept(impl_.get_implementation(),@@ -1317,9 +1325,9 @@ template <typename Protocol1, typename Executor1> ASIO_SYNC_OP_VOID accept( basic_socket<Protocol1, Executor1>& peer, asio::error_code& ec,- constraint_t<+ typename constraint< is_convertible<Protocol, Protocol1>::value- > = 0)+ >::type = 0) { impl_.get_service().accept(impl_.get_implementation(), peer, static_cast<endpoint_type*>(0), ec);@@ -1348,7 +1356,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code) @endcode@@ -1383,16 +1391,19 @@ */ template <typename Protocol1, typename Executor1, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code))- AcceptToken = default_completion_token_t<executor_type>>- auto async_accept(basic_socket<Protocol1, Executor1>& peer,- AcceptToken&& token = default_completion_token_t<executor_type>(),- constraint_t<+ AcceptToken ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(AcceptToken,+ void (asio::error_code))+ async_accept(basic_socket<Protocol1, Executor1>& peer,+ ASIO_MOVE_ARG(AcceptToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type),+ typename constraint< is_convertible<Protocol, Protocol1>::value- > = 0)- -> decltype(+ >::type = 0)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<AcceptToken, void (asio::error_code)>(- declval<initiate_async_accept>(), token,- &peer, static_cast<endpoint_type*>(0)))+ declval<initiate_async_accept>(), token,+ &peer, static_cast<endpoint_type*>(0)))) { return async_initiate<AcceptToken, void (asio::error_code)>( initiate_async_accept(this), token,@@ -1496,7 +1507,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code) @endcode@@ -1513,19 +1524,23 @@ */ template <typename Executor1, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code))- AcceptToken = default_completion_token_t<executor_type>>- auto async_accept(basic_socket<protocol_type, Executor1>& peer,+ AcceptToken ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(AcceptToken,+ void (asio::error_code))+ async_accept(basic_socket<protocol_type, Executor1>& peer, endpoint_type& peer_endpoint,- AcceptToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ ASIO_MOVE_ARG(AcceptToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<AcceptToken, void (asio::error_code)>(- declval<initiate_async_accept>(), token, &peer, &peer_endpoint))+ declval<initiate_async_accept>(), token, &peer, &peer_endpoint))) { return async_initiate<AcceptToken, void (asio::error_code)>( initiate_async_accept(this), token, &peer, &peer_endpoint); } #endif // !defined(ASIO_NO_EXTENSIONS) +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Accept a new connection. /** * This function is used to accept a new connection from a peer. The function@@ -1616,7 +1631,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code,@@ -1655,17 +1670,22 @@ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, typename Protocol::socket::template rebind_executor< executor_type>::other)) MoveAcceptToken- = default_completion_token_t<executor_type>>- auto async_accept(- MoveAcceptToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(MoveAcceptToken,+ void (asio::error_code,+ typename Protocol::socket::template+ rebind_executor<executor_type>::other))+ async_accept(+ ASIO_MOVE_ARG(MoveAcceptToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<MoveAcceptToken, void (asio::error_code, typename Protocol::socket::template rebind_executor<executor_type>::other)>( declval<initiate_async_move_accept>(), token,- declval<const executor_type&>(), static_cast<endpoint_type*>(0),+ declval<executor_type>(), static_cast<endpoint_type*>(0), static_cast<typename Protocol::socket::template- rebind_executor<executor_type>::other*>(0)))+ rebind_executor<executor_type>::other*>(0)))) { return async_initiate<MoveAcceptToken, void (asio::error_code, typename Protocol::socket::template@@ -1702,10 +1722,10 @@ template <typename Executor1> typename Protocol::socket::template rebind_executor<Executor1>::other accept(const Executor1& ex,- constraint_t<+ typename constraint< is_executor<Executor1>::value || execution::is_executor<Executor1>::value- > = 0)+ >::type = 0) { asio::error_code ec; typename Protocol::socket::template@@ -1742,9 +1762,9 @@ typename Protocol::socket::template rebind_executor< typename ExecutionContext::executor_type>::other accept(ExecutionContext& context,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- > = 0)+ >::type = 0) { asio::error_code ec; typename Protocol::socket::template rebind_executor<@@ -1785,10 +1805,10 @@ template <typename Executor1> typename Protocol::socket::template rebind_executor<Executor1>::other accept(const Executor1& ex, asio::error_code& ec,- constraint_t<+ typename constraint< is_executor<Executor1>::value || execution::is_executor<Executor1>::value- > = 0)+ >::type = 0) { typename Protocol::socket::template rebind_executor<Executor1>::other peer(ex);@@ -1828,9 +1848,9 @@ typename Protocol::socket::template rebind_executor< typename ExecutionContext::executor_type>::other accept(ExecutionContext& context, asio::error_code& ec,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- > = 0)+ >::type = 0) { typename Protocol::socket::template rebind_executor< typename ExecutionContext::executor_type>::other peer(context);@@ -1866,7 +1886,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code,@@ -1904,17 +1924,22 @@ template <typename Executor1, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, typename Protocol::socket::template rebind_executor<- constraint_t<is_executor<Executor1>::value+ typename constraint<is_executor<Executor1>::value || execution::is_executor<Executor1>::value,- Executor1>>::other)) MoveAcceptToken- = default_completion_token_t<executor_type>>- auto async_accept(const Executor1& ex,- MoveAcceptToken&& token = default_completion_token_t<executor_type>(),- constraint_t<+ Executor1>::type>::other)) MoveAcceptToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(MoveAcceptToken,+ void (asio::error_code,+ typename Protocol::socket::template rebind_executor<+ Executor1>::other))+ async_accept(const Executor1& ex,+ ASIO_MOVE_ARG(MoveAcceptToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type),+ typename constraint< is_executor<Executor1>::value || execution::is_executor<Executor1>::value- > = 0)- -> decltype(+ >::type = 0)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<MoveAcceptToken, void (asio::error_code, typename Protocol::socket::template rebind_executor<@@ -1922,7 +1947,7 @@ declval<initiate_async_move_accept>(), token, ex, static_cast<endpoint_type*>(0), static_cast<typename Protocol::socket::template- rebind_executor<Executor1>::other*>(0)))+ rebind_executor<Executor1>::other*>(0)))) { return async_initiate<MoveAcceptToken, void (asio::error_code,@@ -1962,7 +1987,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code,@@ -2001,13 +2026,18 @@ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, typename Protocol::socket::template rebind_executor< typename ExecutionContext::executor_type>::other)) MoveAcceptToken- = default_completion_token_t<executor_type>>- auto async_accept(ExecutionContext& context,- MoveAcceptToken&& token = default_completion_token_t<executor_type>(),- constraint_t<+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(MoveAcceptToken,+ void (asio::error_code,+ typename Protocol::socket::template rebind_executor<+ typename ExecutionContext::executor_type>::other))+ async_accept(ExecutionContext& context,+ ASIO_MOVE_ARG(MoveAcceptToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type),+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- > = 0)- -> decltype(+ >::type = 0)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<MoveAcceptToken, void (asio::error_code, typename Protocol::socket::template rebind_executor<@@ -2015,7 +2045,7 @@ declval<initiate_async_move_accept>(), token, context.get_executor(), static_cast<endpoint_type*>(0), static_cast<typename Protocol::socket::template rebind_executor<- typename ExecutionContext::executor_type>::other*>(0)))+ typename ExecutionContext::executor_type>::other*>(0)))) { return async_initiate<MoveAcceptToken, void (asio::error_code,@@ -2132,7 +2162,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code,@@ -2172,17 +2202,22 @@ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, typename Protocol::socket::template rebind_executor< executor_type>::other)) MoveAcceptToken- = default_completion_token_t<executor_type>>- auto async_accept(endpoint_type& peer_endpoint,- MoveAcceptToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(MoveAcceptToken,+ void (asio::error_code,+ typename Protocol::socket::template+ rebind_executor<executor_type>::other))+ async_accept(endpoint_type& peer_endpoint,+ ASIO_MOVE_ARG(MoveAcceptToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<MoveAcceptToken, void (asio::error_code, typename Protocol::socket::template rebind_executor<executor_type>::other)>( declval<initiate_async_move_accept>(), token,- declval<const executor_type&>(), &peer_endpoint,+ declval<executor_type>(), &peer_endpoint, static_cast<typename Protocol::socket::template- rebind_executor<executor_type>::other*>(0)))+ rebind_executor<executor_type>::other*>(0)))) { return async_initiate<MoveAcceptToken, void (asio::error_code, typename Protocol::socket::template@@ -2224,10 +2259,10 @@ template <typename Executor1> typename Protocol::socket::template rebind_executor<Executor1>::other accept(const Executor1& ex, endpoint_type& peer_endpoint,- constraint_t<+ typename constraint< is_executor<Executor1>::value || execution::is_executor<Executor1>::value- > = 0)+ >::type = 0) { asio::error_code ec; typename Protocol::socket::template@@ -2270,9 +2305,9 @@ typename Protocol::socket::template rebind_executor< typename ExecutionContext::executor_type>::other accept(ExecutionContext& context, endpoint_type& peer_endpoint,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- > = 0)+ >::type = 0) { asio::error_code ec; typename Protocol::socket::template rebind_executor<@@ -2320,10 +2355,10 @@ typename Protocol::socket::template rebind_executor<Executor1>::other accept(const executor_type& ex, endpoint_type& peer_endpoint, asio::error_code& ec,- constraint_t<+ typename constraint< is_executor<Executor1>::value || execution::is_executor<Executor1>::value- > = 0)+ >::type = 0) { typename Protocol::socket::template rebind_executor<Executor1>::other peer(ex);@@ -2370,9 +2405,9 @@ typename ExecutionContext::executor_type>::other accept(ExecutionContext& context, endpoint_type& peer_endpoint, asio::error_code& ec,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- > = 0)+ >::type = 0) { typename Protocol::socket::template rebind_executor< typename ExecutionContext::executor_type>::other peer(context);@@ -2414,7 +2449,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code,@@ -2453,24 +2488,29 @@ template <typename Executor1, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, typename Protocol::socket::template rebind_executor<- constraint_t<is_executor<Executor1>::value+ typename constraint<is_executor<Executor1>::value || execution::is_executor<Executor1>::value,- Executor1>>::other)) MoveAcceptToken- = default_completion_token_t<executor_type>>- auto async_accept(const Executor1& ex, endpoint_type& peer_endpoint,- MoveAcceptToken&& token = default_completion_token_t<executor_type>(),- constraint_t<+ Executor1>::type>::other)) MoveAcceptToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(MoveAcceptToken,+ void (asio::error_code,+ typename Protocol::socket::template rebind_executor<+ Executor1>::other))+ async_accept(const Executor1& ex, endpoint_type& peer_endpoint,+ ASIO_MOVE_ARG(MoveAcceptToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type),+ typename constraint< is_executor<Executor1>::value || execution::is_executor<Executor1>::value- > = 0)- -> decltype(+ >::type = 0)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<MoveAcceptToken, void (asio::error_code, typename Protocol::socket::template rebind_executor< Executor1>::other)>( declval<initiate_async_move_accept>(), token, ex, &peer_endpoint, static_cast<typename Protocol::socket::template- rebind_executor<Executor1>::other*>(0)))+ rebind_executor<Executor1>::other*>(0)))) { return async_initiate<MoveAcceptToken, void (asio::error_code,@@ -2514,7 +2554,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code,@@ -2554,13 +2594,19 @@ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, typename Protocol::socket::template rebind_executor< typename ExecutionContext::executor_type>::other)) MoveAcceptToken- = default_completion_token_t<executor_type>>- auto async_accept(ExecutionContext& context, endpoint_type& peer_endpoint,- MoveAcceptToken&& token = default_completion_token_t<executor_type>(),- constraint_t<+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(MoveAcceptToken,+ void (asio::error_code,+ typename Protocol::socket::template rebind_executor<+ typename ExecutionContext::executor_type>::other))+ async_accept(ExecutionContext& context,+ endpoint_type& peer_endpoint,+ ASIO_MOVE_ARG(MoveAcceptToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type),+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- > = 0)- -> decltype(+ >::type = 0)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<MoveAcceptToken, void (asio::error_code, typename Protocol::socket::template rebind_executor<@@ -2568,7 +2614,7 @@ declval<initiate_async_move_accept>(), token, context.get_executor(), &peer_endpoint, static_cast<typename Protocol::socket::template rebind_executor<- typename ExecutionContext::executor_type>::other*>(0)))+ typename ExecutionContext::executor_type>::other*>(0)))) { return async_initiate<MoveAcceptToken, void (asio::error_code,@@ -2579,12 +2625,13 @@ static_cast<typename Protocol::socket::template rebind_executor< typename ExecutionContext::executor_type>::other*>(0)); }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) private: // Disallow copying and assignment.- basic_socket_acceptor(const basic_socket_acceptor&) = delete;+ basic_socket_acceptor(const basic_socket_acceptor&) ASIO_DELETED; basic_socket_acceptor& operator=(- const basic_socket_acceptor&) = delete;+ const basic_socket_acceptor&) ASIO_DELETED; class initiate_async_wait {@@ -2596,13 +2643,13 @@ { } - const executor_type& get_executor() const noexcept+ const executor_type& get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template <typename WaitHandler>- void operator()(WaitHandler&& handler, wait_type w) const+ void operator()(ASIO_MOVE_ARG(WaitHandler) handler, wait_type w) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a WaitHandler.@@ -2628,13 +2675,13 @@ { } - const executor_type& get_executor() const noexcept+ const executor_type& get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template <typename AcceptHandler, typename Protocol1, typename Executor1>- void operator()(AcceptHandler&& handler,+ void operator()(ASIO_MOVE_ARG(AcceptHandler) handler, basic_socket<Protocol1, Executor1>* peer, endpoint_type* peer_endpoint) const {@@ -2662,13 +2709,13 @@ { } - const executor_type& get_executor() const noexcept+ const executor_type& get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template <typename MoveAcceptHandler, typename Executor1, typename Socket>- void operator()(MoveAcceptHandler&& handler,+ void operator()(ASIO_MOVE_ARG(MoveAcceptHandler) handler, const Executor1& peer_ex, endpoint_type* peer_endpoint, Socket*) const { // If you get an error on the following line it means that your handler
link/modules/asio-standalone/asio/include/asio/basic_socket_iostream.hpp view
@@ -2,7 +2,7 @@ // basic_socket_iostream.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -23,6 +23,55 @@ #include <ostream> #include "asio/basic_socket_streambuf.hpp" +#if !defined(ASIO_HAS_VARIADIC_TEMPLATES)++# include "asio/detail/variadic_templates.hpp"++// A macro that should expand to:+// template <typename T1, ..., typename Tn>+// explicit basic_socket_iostream(T1 x1, ..., Tn xn)+// : std::basic_iostream<char>(+// &this->detail::socket_iostream_base<+// Protocol, Clock, WaitTraits>::streambuf_)+// {+// if (rdbuf()->connect(x1, ..., xn) == 0)+// this->setstate(std::ios_base::failbit);+// }+// This macro should only persist within this file.++# define ASIO_PRIVATE_CTR_DEF(n) \+ template <ASIO_VARIADIC_TPARAMS(n)> \+ explicit basic_socket_iostream(ASIO_VARIADIC_BYVAL_PARAMS(n)) \+ : std::basic_iostream<char>( \+ &this->detail::socket_iostream_base< \+ Protocol, Clock, WaitTraits>::streambuf_) \+ { \+ this->setf(std::ios_base::unitbuf); \+ if (rdbuf()->connect(ASIO_VARIADIC_BYVAL_ARGS(n)) == 0) \+ this->setstate(std::ios_base::failbit); \+ } \+ /**/++// A macro that should expand to:+// template <typename T1, ..., typename Tn>+// void connect(T1 x1, ..., Tn xn)+// {+// if (rdbuf()->connect(x1, ..., xn) == 0)+// this->setstate(std::ios_base::failbit);+// }+// This macro should only persist within this file.++# define ASIO_PRIVATE_CONNECT_DEF(n) \+ template <ASIO_VARIADIC_TPARAMS(n)> \+ void connect(ASIO_VARIADIC_BYVAL_PARAMS(n)) \+ { \+ if (rdbuf()->connect(ASIO_VARIADIC_BYVAL_ARGS(n)) == 0) \+ this->setstate(std::ios_base::failbit); \+ } \+ /**/++#endif // !defined(ASIO_HAS_VARIADIC_TEMPLATES)+ #include "asio/detail/push_options.hpp" namespace asio {@@ -38,6 +87,7 @@ { } +#if defined(ASIO_HAS_MOVE) socket_iostream_base(socket_iostream_base&& other) : streambuf_(std::move(other.streambuf_)) {@@ -53,6 +103,7 @@ streambuf_ = std::move(other.streambuf_); return *this; }+#endif // defined(ASIO_HAS_MOVE) basic_socket_streambuf<Protocol, Clock, WaitTraits> streambuf_; };@@ -64,8 +115,16 @@ // Forward declaration with defaulted arguments. template <typename Protocol,+#if defined(ASIO_HAS_BOOST_DATE_TIME) \+ && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)+ typename Clock = boost::posix_time::ptime,+ typename WaitTraits = time_traits<Clock> >+#else // defined(ASIO_HAS_BOOST_DATE_TIME)+ // && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) typename Clock = chrono::steady_clock,- typename WaitTraits = wait_traits<Clock>>+ typename WaitTraits = wait_traits<Clock> >+#endif // defined(ASIO_HAS_BOOST_DATE_TIME)+ // && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) class basic_socket_iostream; #endif // !defined(ASIO_BASIC_SOCKET_IOSTREAM_FWD_DECL)@@ -74,7 +133,7 @@ #if defined(GENERATING_DOCUMENTATION) template <typename Protocol, typename Clock = chrono::steady_clock,- typename WaitTraits = wait_traits<Clock>>+ typename WaitTraits = wait_traits<Clock> > #else // defined(GENERATING_DOCUMENTATION) template <typename Protocol, typename Clock, typename WaitTraits> #endif // defined(GENERATING_DOCUMENTATION)@@ -83,7 +142,16 @@ public std::basic_iostream<char> { private:+ // These typedefs are intended keep this class's implementation independent+ // of whether it's using Boost.DateClock, Boost.Chrono or std::chrono.+#if defined(ASIO_HAS_BOOST_DATE_TIME) \+ && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)+ typedef WaitTraits traits_helper;+#else // defined(ASIO_HAS_BOOST_DATE_TIME)+ // && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) typedef detail::chrono_time_traits<Clock, WaitTraits> traits_helper;+#endif // defined(ASIO_HAS_BOOST_DATE_TIME)+ // && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) public: /// The protocol type.@@ -96,12 +164,22 @@ 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 WaitTraits::time_point time_point; + /// (Deprecated: Use duration.) The duration type.+ typedef typename WaitTraits::duration_type duration_type;+ /// The duration type. typedef typename WaitTraits::duration duration; #else+# if !defined(ASIO_NO_DEPRECATED)+ typedef typename traits_helper::time_type time_type;+ typedef typename traits_helper::duration_type duration_type;+# endif // !defined(ASIO_NO_DEPRECATED) typedef typename traits_helper::time_type time_point; typedef typename traits_helper::duration_type duration; #endif@@ -115,6 +193,7 @@ this->setf(std::ios_base::unitbuf); } +#if defined(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<@@ -126,6 +205,8 @@ this->setf(std::ios_base::unitbuf); } +#if defined(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<@@ -144,13 +225,20 @@ Protocol, Clock, WaitTraits>::operator=(std::move(other)); return *this; }+#endif // defined(ASIO_HAS_STD_IOSTREAM_MOVE)+ // || defined(GENERATING_DOCUMENTATION)+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) +#if defined(GENERATING_DOCUMENTATION) /// Establish a connection to an endpoint corresponding to a resolver query. /** * This constructor automatically establishes a connection based on the * supplied resolver query parameters. The arguments are used to construct * a resolver query object. */+ template <typename T1, ..., typename TN>+ explicit basic_socket_iostream(T1 t1, ..., TN tn);+#elif defined(ASIO_HAS_VARIADIC_TEMPLATES) template <typename... T> explicit basic_socket_iostream(T... x) : std::basic_iostream<char>(@@ -161,19 +249,29 @@ if (rdbuf()->connect(x...) == 0) this->setstate(std::ios_base::failbit); }+#else+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_CTR_DEF)+#endif +#if defined(GENERATING_DOCUMENTATION) /// Establish a connection to an endpoint corresponding to a resolver query. /** * This function automatically establishes a connection based on the supplied * resolver query parameters. The arguments are used to construct a resolver * query object. */+ template <typename T1, ..., typename TN>+ void connect(T1 t1, ..., TN tn);+#elif defined(ASIO_HAS_VARIADIC_TEMPLATES) template <typename... T> void connect(T... x) { if (rdbuf()->connect(x...) == 0) this->setstate(std::ios_base::failbit); }+#else+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_CONNECT_DEF)+#endif /// Close the connection. void close()@@ -213,6 +311,18 @@ return rdbuf()->error(); } +#if !defined(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_point expires_at() const+ {+ return rdbuf()->expires_at();+ }+#endif // !defined(ASIO_NO_DEPRECATED)+ /// Get the stream's expiry time as an absolute time. /** * @return An absolute time value representing the stream's expiry time.@@ -250,16 +360,47 @@ rdbuf()->expires_after(expiry_time); } +#if !defined(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 expires_from_now() const+ {+ return rdbuf()->expires_from_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+ * completed using the internal buffers) will fail with the error+ * asio::error::operation_aborted.+ *+ * @param expiry_time The expiry time to be used for the timer.+ */+ void expires_from_now(const duration& expiry_time)+ {+ rdbuf()->expires_from_now(expiry_time);+ }+#endif // !defined(ASIO_NO_DEPRECATED)+ private: // Disallow copying and assignment.- basic_socket_iostream(const basic_socket_iostream&) = delete;+ basic_socket_iostream(const basic_socket_iostream&) ASIO_DELETED; basic_socket_iostream& operator=(- const basic_socket_iostream&) = delete;+ const basic_socket_iostream&) ASIO_DELETED; }; } // namespace asio #include "asio/detail/pop_options.hpp"++#if !defined(ASIO_HAS_VARIADIC_TEMPLATES)+# undef ASIO_PRIVATE_CTR_DEF+# undef ASIO_PRIVATE_CONNECT_DEF+#endif // !defined(ASIO_HAS_VARIADIC_TEMPLATES) #endif // !defined(ASIO_NO_IOSTREAM)
link/modules/asio-standalone/asio/include/asio/basic_socket_streambuf.hpp view
@@ -2,7 +2,7 @@ // basic_socket_streambuf.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -27,8 +27,48 @@ #include "asio/detail/memory.hpp" #include "asio/detail/throw_error.hpp" #include "asio/io_context.hpp"-#include "asio/steady_timer.hpp" +#if defined(ASIO_HAS_BOOST_DATE_TIME) \+ && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)+# include "asio/detail/deadline_timer_service.hpp"+#else // defined(ASIO_HAS_BOOST_DATE_TIME)+ // && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)+# include "asio/steady_timer.hpp"+#endif // defined(ASIO_HAS_BOOST_DATE_TIME)+ // && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)++#if !defined(ASIO_HAS_VARIADIC_TEMPLATES)++# include "asio/detail/variadic_templates.hpp"++// A macro that should expand to:+// template <typename T1, ..., typename Tn>+// basic_socket_streambuf* connect(T1 x1, ..., Tn xn)+// {+// init_buffers();+// typedef typename Protocol::resolver resolver_type;+// resolver_type resolver(socket().get_executor());+// connect_to_endpoints(+// resolver.resolve(x1, ..., xn, ec_));+// return !ec_ ? this : 0;+// }+// This macro should only persist within this file.++# define ASIO_PRIVATE_CONNECT_DEF(n) \+ template <ASIO_VARIADIC_TPARAMS(n)> \+ basic_socket_streambuf* connect(ASIO_VARIADIC_BYVAL_PARAMS(n)) \+ { \+ init_buffers(); \+ typedef typename Protocol::resolver resolver_type; \+ resolver_type resolver(socket().get_executor()); \+ connect_to_endpoints( \+ resolver.resolve(ASIO_VARIADIC_BYVAL_ARGS(n), ec_)); \+ return !ec_ ? this : 0; \+ } \+ /**/++#endif // !defined(ASIO_HAS_VARIADIC_TEMPLATES)+ #include "asio/detail/push_options.hpp" namespace asio {@@ -73,8 +113,16 @@ // Forward declaration with defaulted arguments. template <typename Protocol,+#if defined(ASIO_HAS_BOOST_DATE_TIME) \+ && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)+ typename Clock = boost::posix_time::ptime,+ typename WaitTraits = time_traits<Clock> >+#else // defined(ASIO_HAS_BOOST_DATE_TIME)+ // && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) typename Clock = chrono::steady_clock,- typename WaitTraits = wait_traits<Clock>>+ typename WaitTraits = wait_traits<Clock> >+#endif // defined(ASIO_HAS_BOOST_DATE_TIME)+ // && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) class basic_socket_streambuf; #endif // !defined(ASIO_BASIC_SOCKET_STREAMBUF_FWD_DECL)@@ -83,7 +131,7 @@ #if defined(GENERATING_DOCUMENTATION) template <typename Protocol, typename Clock = chrono::steady_clock,- typename WaitTraits = wait_traits<Clock>>+ typename WaitTraits = wait_traits<Clock> > #else // defined(GENERATING_DOCUMENTATION) template <typename Protocol, typename Clock, typename WaitTraits> #endif // defined(GENERATING_DOCUMENTATION)@@ -91,10 +139,23 @@ : public std::streambuf, private detail::socket_streambuf_io_context, private detail::socket_streambuf_buffers,+#if defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION) private basic_socket<Protocol>+#else // defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)+ public basic_socket<Protocol>+#endif // defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION) { private:+ // These typedefs are intended keep this class's implementation independent+ // of whether it's using Boost.DateClock, Boost.Chrono or std::chrono.+#if defined(ASIO_HAS_BOOST_DATE_TIME) \+ && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)+ typedef WaitTraits traits_helper;+#else // defined(ASIO_HAS_BOOST_DATE_TIME)+ // && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) typedef detail::chrono_time_traits<Clock, WaitTraits> traits_helper;+#endif // defined(ASIO_HAS_BOOST_DATE_TIME)+ // && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) public: /// The protocol type.@@ -107,12 +168,22 @@ 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 WaitTraits::time_point time_point; + /// (Deprecated: Use duration.) The duration type.+ typedef typename WaitTraits::duration_type duration_type;+ /// The duration type. typedef typename WaitTraits::duration duration; #else+# if !defined(ASIO_NO_DEPRECATED)+ typedef typename traits_helper::time_type time_type;+ typedef typename traits_helper::duration_type duration_type;+# endif // !defined(ASIO_NO_DEPRECATED) typedef typename traits_helper::time_type time_point; typedef typename traits_helper::duration_type duration; #endif@@ -126,6 +197,7 @@ init_buffers(); } +#if defined(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),@@ -169,6 +241,7 @@ other.init_buffers(); return *this; }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Destructor flushes buffered data. virtual ~basic_socket_streambuf()@@ -192,6 +265,7 @@ return !ec_ ? this : 0; } +#if defined(GENERATING_DOCUMENTATION) /// Establish a connection. /** * This function automatically establishes a connection based on the supplied@@ -201,6 +275,9 @@ * @return \c this if a connection was successfully established, a null * pointer otherwise. */+ template <typename T1, ..., typename TN>+ basic_socket_streambuf* connect(T1 t1, ..., TN tn);+#elif defined(ASIO_HAS_VARIADIC_TEMPLATES) template <typename... T> basic_socket_streambuf* connect(T... x) {@@ -210,6 +287,9 @@ connect_to_endpoints(resolver.resolve(x..., ec_)); return !ec_ ? this : 0; }+#else+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_CONNECT_DEF)+#endif /// Close the connection. /**@@ -241,6 +321,30 @@ return ec_; } +#if !defined(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 asio::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(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@@ -279,6 +383,33 @@ expiry_time_ = traits_helper::add(traits_helper::now(), expiry_time); } +#if !defined(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 expires_from_now() const+ {+ return traits_helper::subtract(expires_at(), traits_helper::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+ * completed using the internal buffers) will fail with the error+ * asio::error::operation_aborted.+ *+ * @param expiry_time The expiry time to be used for the timer.+ */+ void expires_from_now(const duration& expiry_time)+ {+ expiry_time_ = traits_helper::add(traits_helper::now(), expiry_time);+ }+#endif // !defined(ASIO_NO_DEPRECATED)+ protected: int_type underflow() {@@ -428,9 +559,9 @@ private: // Disallow copying and assignment.- basic_socket_streambuf(const basic_socket_streambuf&) = delete;+ basic_socket_streambuf(const basic_socket_streambuf&) ASIO_DELETED; basic_socket_streambuf& operator=(- const basic_socket_streambuf&) = delete;+ const basic_socket_streambuf&) ASIO_DELETED; void init_buffers() {@@ -528,7 +659,14 @@ // Helper function to get the maximum expiry time. static time_point max_expiry_time() {+#if defined(ASIO_HAS_BOOST_DATE_TIME) \+ && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)+ return boost::posix_time::pos_infin;+#else // defined(ASIO_HAS_BOOST_DATE_TIME)+ // && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) return (time_point::max)();+#endif // defined(ASIO_HAS_BOOST_DATE_TIME)+ // && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) } enum { putback_max = 8 };@@ -539,6 +677,10 @@ } // namespace asio #include "asio/detail/pop_options.hpp"++#if !defined(ASIO_HAS_VARIADIC_TEMPLATES)+# undef ASIO_PRIVATE_CONNECT_DEF+#endif // !defined(ASIO_HAS_VARIADIC_TEMPLATES) #endif // !defined(ASIO_NO_IOSTREAM)
link/modules/asio-standalone/asio/include/asio/basic_stream_file.hpp view
@@ -2,7 +2,7 @@ // basic_stream_file.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -106,10 +106,10 @@ */ template <typename ExecutionContext> explicit basic_stream_file(ExecutionContext& context,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- > = defaulted_constraint())+ >::type = defaulted_constraint()) : basic_file<Executor>(context) { this->impl_.get_service().set_is_stream(@@ -161,10 +161,10 @@ template <typename ExecutionContext> basic_stream_file(ExecutionContext& context, const char* path, file_base::flags open_flags,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- > = defaulted_constraint())+ >::type = defaulted_constraint()) : basic_file<Executor>(context) { asio::error_code ec;@@ -221,10 +221,10 @@ template <typename ExecutionContext> basic_stream_file(ExecutionContext& context, const std::string& path, file_base::flags open_flags,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- > = defaulted_constraint())+ >::type = defaulted_constraint()) : basic_file<Executor>(context) { asio::error_code ec;@@ -272,16 +272,17 @@ template <typename ExecutionContext> basic_stream_file(ExecutionContext& context, const native_handle_type& native_file,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- > = defaulted_constraint())+ >::type = defaulted_constraint()) : basic_file<Executor>(context, native_file) { this->impl_.get_service().set_is_stream( this->impl_.get_implementation(), true); } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move-construct a basic_stream_file from another. /** * This constructor moves a stream file from one object to another.@@ -293,7 +294,7 @@ * constructed using the @c basic_stream_file(const executor_type&) * constructor. */- basic_stream_file(basic_stream_file&& other) noexcept+ basic_stream_file(basic_stream_file&& other) ASIO_NOEXCEPT : basic_file<Executor>(std::move(other)) { }@@ -329,10 +330,10 @@ */ template <typename Executor1> basic_stream_file(basic_stream_file<Executor1>&& other,- constraint_t<+ typename constraint< is_convertible<Executor1, Executor>::value, defaulted_constraint- > = defaulted_constraint())+ >::type = defaulted_constraint()) : basic_file<Executor>(std::move(other)) { }@@ -349,14 +350,15 @@ * constructor. */ template <typename Executor1>- constraint_t<+ typename constraint< is_convertible<Executor1, Executor>::value, basic_stream_file&- > operator=(basic_stream_file<Executor1>&& other)+ >::type operator=(basic_stream_file<Executor1>&& other) { basic_file<Executor>::operator=(std::move(other)); return *this; }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Destroys the file. /**@@ -490,7 +492,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -520,13 +522,17 @@ */ template <typename ConstBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) WriteToken = default_completion_token_t<executor_type>>- auto async_write_some(const ConstBufferSequence& buffers,- WriteToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ std::size_t)) WriteToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+ void (asio::error_code, std::size_t))+ async_write_some(const ConstBufferSequence& buffers,+ ASIO_MOVE_ARG(WriteToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<WriteToken, void (asio::error_code, std::size_t)>(- declval<initiate_async_write_some>(), token, buffers))+ declval<initiate_async_write_some>(), token, buffers))) { return async_initiate<WriteToken, void (asio::error_code, std::size_t)>(@@ -618,7 +624,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -649,13 +655,17 @@ */ template <typename MutableBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) ReadToken = default_completion_token_t<executor_type>>- auto async_read_some(const MutableBufferSequence& buffers,- ReadToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ std::size_t)) ReadToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+ async_read_some(const MutableBufferSequence& buffers,+ ASIO_MOVE_ARG(ReadToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<ReadToken, void (asio::error_code, std::size_t)>(- declval<initiate_async_read_some>(), token, buffers))+ declval<initiate_async_read_some>(), token, buffers))) { return async_initiate<ReadToken, void (asio::error_code, std::size_t)>(@@ -664,8 +674,8 @@ private: // Disallow copying and assignment.- basic_stream_file(const basic_stream_file&) = delete;- basic_stream_file& operator=(const basic_stream_file&) = delete;+ basic_stream_file(const basic_stream_file&) ASIO_DELETED;+ basic_stream_file& operator=(const basic_stream_file&) ASIO_DELETED; class initiate_async_write_some {@@ -677,13 +687,13 @@ { } - const executor_type& get_executor() const noexcept+ const executor_type& get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template <typename WriteHandler, typename ConstBufferSequence>- void operator()(WriteHandler&& handler,+ void operator()(ASIO_MOVE_ARG(WriteHandler) handler, const ConstBufferSequence& buffers) const { // If you get an error on the following line it means that your handler@@ -710,13 +720,13 @@ { } - const executor_type& get_executor() const noexcept+ const executor_type& get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template <typename ReadHandler, typename MutableBufferSequence>- void operator()(ReadHandler&& handler,+ void operator()(ASIO_MOVE_ARG(ReadHandler) handler, const MutableBufferSequence& buffers) const { // If you get an error on the following line it means that your handler
link/modules/asio-standalone/asio/include/asio/basic_stream_socket.hpp view
@@ -2,7 +2,7 @@ // basic_stream_socket.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -116,9 +116,9 @@ */ template <typename ExecutionContext> explicit basic_stream_socket(ExecutionContext& context,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- > = 0)+ >::type = 0) : basic_socket<Protocol, Executor>(context) { }@@ -155,10 +155,10 @@ */ template <typename ExecutionContext> basic_stream_socket(ExecutionContext& context, const protocol_type& protocol,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- > = defaulted_constraint())+ >::type = defaulted_constraint()) : basic_socket<Protocol, Executor>(context, protocol) { }@@ -201,9 +201,9 @@ */ template <typename ExecutionContext> basic_stream_socket(ExecutionContext& context, const endpoint_type& endpoint,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- > = 0)+ >::type = 0) : basic_socket<Protocol, Executor>(context, endpoint) { }@@ -246,13 +246,14 @@ template <typename ExecutionContext> basic_stream_socket(ExecutionContext& context, const protocol_type& protocol, const native_handle_type& native_socket,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- > = 0)+ >::type = 0) : basic_socket<Protocol, Executor>(context, protocol, native_socket) { } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move-construct a basic_stream_socket from another. /** * This constructor moves a stream socket from one object to another.@@ -264,7 +265,7 @@ * constructed using the @c basic_stream_socket(const executor_type&) * constructor. */- basic_stream_socket(basic_stream_socket&& other) noexcept+ basic_stream_socket(basic_stream_socket&& other) ASIO_NOEXCEPT : basic_socket<Protocol, Executor>(std::move(other)) { }@@ -300,10 +301,10 @@ */ template <typename Protocol1, typename Executor1> basic_stream_socket(basic_stream_socket<Protocol1, Executor1>&& other,- constraint_t<+ typename constraint< is_convertible<Protocol1, Protocol>::value && is_convertible<Executor1, Executor>::value- > = 0)+ >::type = 0) : basic_socket<Protocol, Executor>(std::move(other)) { }@@ -320,15 +321,16 @@ * constructor. */ template <typename Protocol1, typename Executor1>- constraint_t<+ typename constraint< is_convertible<Protocol1, Protocol>::value && is_convertible<Executor1, Executor>::value, basic_stream_socket&- > operator=(basic_stream_socket<Protocol1, Executor1>&& other)+ >::type operator=(basic_stream_socket<Protocol1, Executor1>&& other) { basic_socket<Protocol, Executor>::operator=(std::move(other)); return *this; }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Destroys the socket. /**@@ -461,7 +463,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -491,14 +493,18 @@ */ template <typename ConstBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) WriteToken = default_completion_token_t<executor_type>>- auto async_send(const ConstBufferSequence& buffers,- WriteToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ std::size_t)) WriteToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+ void (asio::error_code, std::size_t))+ async_send(const ConstBufferSequence& buffers,+ ASIO_MOVE_ARG(WriteToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<WriteToken, void (asio::error_code, std::size_t)>( declval<initiate_async_send>(), token,- buffers, socket_base::message_flags(0)))+ buffers, socket_base::message_flags(0)))) { return async_initiate<WriteToken, void (asio::error_code, std::size_t)>(@@ -531,7 +537,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -561,14 +567,18 @@ */ template <typename ConstBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) WriteToken = default_completion_token_t<executor_type>>- auto async_send(const ConstBufferSequence& buffers,+ std::size_t)) WriteToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+ void (asio::error_code, std::size_t))+ async_send(const ConstBufferSequence& buffers, socket_base::message_flags flags,- WriteToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ ASIO_MOVE_ARG(WriteToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<WriteToken, void (asio::error_code, std::size_t)>(- declval<initiate_async_send>(), token, buffers, flags))+ declval<initiate_async_send>(), token, buffers, flags))) { return async_initiate<WriteToken, void (asio::error_code, std::size_t)>(@@ -703,7 +713,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -735,14 +745,18 @@ */ template <typename MutableBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) ReadToken = default_completion_token_t<executor_type>>- auto async_receive(const MutableBufferSequence& buffers,- ReadToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ std::size_t)) ReadToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+ async_receive(const MutableBufferSequence& buffers,+ ASIO_MOVE_ARG(ReadToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<ReadToken, void (asio::error_code, std::size_t)>( declval<initiate_async_receive>(), token,- buffers, socket_base::message_flags(0)))+ buffers, socket_base::message_flags(0)))) { return async_initiate<ReadToken, void (asio::error_code, std::size_t)>(@@ -775,7 +789,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -807,14 +821,18 @@ */ template <typename MutableBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) ReadToken = default_completion_token_t<executor_type>>- auto async_receive(const MutableBufferSequence& buffers,+ std::size_t)) ReadToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+ async_receive(const MutableBufferSequence& buffers, socket_base::message_flags flags,- ReadToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ ASIO_MOVE_ARG(ReadToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<ReadToken, void (asio::error_code, std::size_t)>(- declval<initiate_async_receive>(), token, buffers, flags))+ declval<initiate_async_receive>(), token, buffers, flags))) { return async_initiate<ReadToken, void (asio::error_code, std::size_t)>(@@ -905,7 +923,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -935,14 +953,18 @@ */ template <typename ConstBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) WriteToken = default_completion_token_t<executor_type>>- auto async_write_some(const ConstBufferSequence& buffers,- WriteToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ std::size_t)) WriteToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+ void (asio::error_code, std::size_t))+ async_write_some(const ConstBufferSequence& buffers,+ ASIO_MOVE_ARG(WriteToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<WriteToken, void (asio::error_code, std::size_t)>( declval<initiate_async_send>(), token,- buffers, socket_base::message_flags(0)))+ buffers, socket_base::message_flags(0)))) { return async_initiate<WriteToken, void (asio::error_code, std::size_t)>(@@ -1036,7 +1058,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -1067,14 +1089,18 @@ */ template <typename MutableBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) ReadToken = default_completion_token_t<executor_type>>- auto async_read_some(const MutableBufferSequence& buffers,- ReadToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ std::size_t)) ReadToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+ async_read_some(const MutableBufferSequence& buffers,+ ASIO_MOVE_ARG(ReadToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<ReadToken, void (asio::error_code, std::size_t)>( declval<initiate_async_receive>(), token,- buffers, socket_base::message_flags(0)))+ buffers, socket_base::message_flags(0)))) { return async_initiate<ReadToken, void (asio::error_code, std::size_t)>(@@ -1084,8 +1110,8 @@ private: // Disallow copying and assignment.- basic_stream_socket(const basic_stream_socket&) = delete;- basic_stream_socket& operator=(const basic_stream_socket&) = delete;+ basic_stream_socket(const basic_stream_socket&) ASIO_DELETED;+ basic_stream_socket& operator=(const basic_stream_socket&) ASIO_DELETED; class initiate_async_send {@@ -1097,13 +1123,13 @@ { } - const executor_type& get_executor() const noexcept+ const executor_type& get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template <typename WriteHandler, typename ConstBufferSequence>- void operator()(WriteHandler&& handler,+ void operator()(ASIO_MOVE_ARG(WriteHandler) handler, const ConstBufferSequence& buffers, socket_base::message_flags flags) const {@@ -1131,13 +1157,13 @@ { } - const executor_type& get_executor() const noexcept+ const executor_type& get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template <typename ReadHandler, typename MutableBufferSequence>- void operator()(ReadHandler&& handler,+ void operator()(ASIO_MOVE_ARG(ReadHandler) handler, const MutableBufferSequence& buffers, socket_base::message_flags flags) const {
link/modules/asio-standalone/asio/include/asio/basic_streambuf.hpp view
@@ -2,7 +2,7 @@ // basic_streambuf.hpp // ~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -103,7 +103,7 @@ * @endcode */ #if defined(GENERATING_DOCUMENTATION)-template <typename Allocator = std::allocator<char>>+template <typename Allocator = std::allocator<char> > #else template <typename Allocator> #endif@@ -119,8 +119,8 @@ /// The type used to represent the output sequence as a list of buffers. typedef implementation_defined mutable_buffers_type; #else- typedef const_buffer const_buffers_type;- typedef mutable_buffer mutable_buffers_type;+ typedef ASIO_CONST_BUFFER const_buffers_type;+ typedef ASIO_MUTABLE_BUFFER mutable_buffers_type; #endif /// Construct a basic_streambuf object.@@ -155,7 +155,7 @@ * } * @endcode */- std::size_t size() const noexcept+ std::size_t size() const ASIO_NOEXCEPT { return pptr() - gptr(); }@@ -165,7 +165,7 @@ * @returns The allowed maximum of the sum of the sizes of the input sequence * and output sequence. */- std::size_t max_size() const noexcept+ std::size_t max_size() const ASIO_NOEXCEPT { return max_size_; }@@ -175,7 +175,7 @@ * @returns The current total capacity of the streambuf, i.e. for both the * input sequence and output sequence. */- std::size_t capacity() const noexcept+ std::size_t capacity() const ASIO_NOEXCEPT { return buffer_.capacity(); }@@ -189,7 +189,7 @@ * @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 noexcept+ const_buffers_type data() const ASIO_NOEXCEPT { return asio::buffer(asio::const_buffer(gptr(), (pptr() - gptr()) * sizeof(char_type)));@@ -361,7 +361,7 @@ /// Adapts basic_streambuf to the dynamic buffer sequence type requirements. #if defined(GENERATING_DOCUMENTATION)-template <typename Allocator = std::allocator<char>>+template <typename Allocator = std::allocator<char> > #else template <typename Allocator> #endif@@ -383,37 +383,39 @@ } /// Copy construct a basic_streambuf_ref.- basic_streambuf_ref(const basic_streambuf_ref& other) noexcept+ basic_streambuf_ref(const basic_streambuf_ref& other) ASIO_NOEXCEPT : sb_(other.sb_) { } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move construct a basic_streambuf_ref.- basic_streambuf_ref(basic_streambuf_ref&& other) noexcept+ basic_streambuf_ref(basic_streambuf_ref&& other) ASIO_NOEXCEPT : sb_(other.sb_) { }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Get the size of the input sequence.- std::size_t size() const noexcept+ std::size_t size() const ASIO_NOEXCEPT { return sb_.size(); } /// Get the maximum size of the dynamic buffer.- std::size_t max_size() const noexcept+ std::size_t max_size() const ASIO_NOEXCEPT { return sb_.max_size(); } /// Get the current capacity of the dynamic buffer.- std::size_t capacity() const noexcept+ std::size_t capacity() const ASIO_NOEXCEPT { return sb_.capacity(); } /// Get a list of buffers that represents the input sequence.- const_buffers_type data() const noexcept+ const_buffers_type data() const ASIO_NOEXCEPT { return sb_.data(); }
link/modules/asio-standalone/asio/include/asio/basic_streambuf_fwd.hpp view
@@ -2,7 +2,7 @@ // basic_streambuf_fwd.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -23,10 +23,10 @@ namespace asio { -template <typename Allocator = std::allocator<char>>+template <typename Allocator = std::allocator<char> > class basic_streambuf; -template <typename Allocator = std::allocator<char>>+template <typename Allocator = std::allocator<char> > class basic_streambuf_ref; } // namespace asio
link/modules/asio-standalone/asio/include/asio/basic_waitable_timer.hpp view
@@ -2,7 +2,7 @@ // basic_waitable_timer.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -17,7 +17,6 @@ #include "asio/detail/config.hpp" #include <cstddef>-#include <utility> #include "asio/any_io_executor.hpp" #include "asio/detail/chrono_time_traits.hpp" #include "asio/detail/deadline_timer_service.hpp"@@ -28,6 +27,10 @@ #include "asio/error.hpp" #include "asio/wait_traits.hpp" +#if defined(ASIO_HAS_MOVE)+# include <utility>+#endif // defined(ASIO_HAS_MOVE)+ #include "asio/detail/push_options.hpp" namespace asio {@@ -75,7 +78,7 @@ * timer.wait(); * @endcode *- * @par+ * @par * Performing an asynchronous wait (C++11): * @code * void handler(const asio::error_code& error)@@ -191,9 +194,9 @@ */ template <typename ExecutionContext> explicit basic_waitable_timer(ExecutionContext& context,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- > = 0)+ >::type = 0) : impl_(0, 0, context) { }@@ -230,9 +233,9 @@ template <typename ExecutionContext> explicit basic_waitable_timer(ExecutionContext& context, const time_point& expiry_time,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- > = 0)+ >::type = 0) : impl_(0, 0, context) { asio::error_code ec;@@ -273,9 +276,9 @@ template <typename ExecutionContext> explicit basic_waitable_timer(ExecutionContext& context, const duration& expiry_time,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- > = 0)+ >::type = 0) : impl_(0, 0, context) { asio::error_code ec;@@ -284,6 +287,7 @@ asio::detail::throw_error(ec, "expires_after"); } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move-construct a basic_waitable_timer from another. /** * This constructor moves a timer from one object to another.@@ -336,9 +340,9 @@ template <typename Executor1> basic_waitable_timer( basic_waitable_timer<Clock, WaitTraits, Executor1>&& other,- constraint_t<+ typename constraint< is_convertible<Executor1, Executor>::value- > = 0)+ >::type = 0) : impl_(std::move(other.impl_)) { }@@ -356,15 +360,16 @@ * constructor. */ template <typename Executor1>- constraint_t<+ typename constraint< is_convertible<Executor1, Executor>::value, basic_waitable_timer&- > operator=(basic_waitable_timer<Clock, WaitTraits, Executor1>&& other)+ >::type operator=(basic_waitable_timer<Clock, WaitTraits, Executor1>&& other) { basic_waitable_timer tmp(std::move(other)); impl_ = std::move(tmp.impl_); return *this; }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Destroys the timer. /**@@ -376,7 +381,7 @@ } /// Get the executor associated with the object.- const executor_type& get_executor() noexcept+ const executor_type& get_executor() ASIO_NOEXCEPT { return impl_.get_executor(); }@@ -411,6 +416,36 @@ return s; } +#if !defined(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+ * be invoked with the asio::error::operation_aborted error code.+ *+ * Cancelling the timer does not change the expiry time.+ *+ * @param ec Set to indicate what error occurred, if any.+ *+ * @return The number of asynchronous operations that were cancelled.+ *+ * @note If the timer has already expired when cancel() is called, then the+ * handlers for asynchronous wait operations will:+ *+ * @li have already been invoked; or+ *+ * @li have been queued for invocation in the near future.+ *+ * These handlers can no longer be cancelled, and therefore are passed an+ * error code that indicates the successful completion of the wait operation.+ */+ std::size_t cancel(asio::error_code& ec)+ {+ return impl_.get_service().cancel(impl_.get_implementation(), ec);+ }+#endif // !defined(ASIO_NO_DEPRECATED)+ /// Cancels one asynchronous operation that is waiting on the timer. /** * This function forces the completion of one pending asynchronous wait@@ -444,6 +479,49 @@ return s; } +#if !defined(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+ * handler for the cancelled operation will be invoked with the+ * asio::error::operation_aborted error code.+ *+ * Cancelling the timer does not change the expiry time.+ *+ * @param ec Set to indicate what error occurred, if any.+ *+ * @return The number of asynchronous operations that were cancelled. That is,+ * either 0 or 1.+ *+ * @note If the timer has already expired when cancel_one() is called, then+ * the handlers for asynchronous wait operations will:+ *+ * @li have already been invoked; or+ *+ * @li have been queued for invocation in the near future.+ *+ * These handlers can no longer be cancelled, and therefore are passed an+ * error code that indicates the successful completion of the wait operation.+ */+ std::size_t cancel_one(asio::error_code& ec)+ {+ return impl_.get_service().cancel_one(impl_.get_implementation(), ec);+ }++ /// (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 impl_.get_service().expires_at(impl_.get_implementation());+ }+#endif // !defined(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.@@ -485,6 +563,38 @@ return s; } +#if !defined(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+ * be invoked with the asio::error::operation_aborted error code.+ *+ * @param expiry_time The expiry time to be used for the timer.+ *+ * @param ec Set to indicate what error occurred, if any.+ *+ * @return The number of asynchronous operations that were cancelled.+ *+ * @note If the timer has already expired when expires_at() is called, then+ * the handlers for asynchronous wait operations will:+ *+ * @li have already been invoked; or+ *+ * @li have been queued for invocation in the near future.+ *+ * These handlers can no longer be cancelled, and therefore are passed an+ * error code that indicates the successful completion of the wait operation.+ */+ std::size_t expires_at(const time_point& expiry_time,+ asio::error_code& ec)+ {+ return impl_.get_service().expires_at(+ impl_.get_implementation(), expiry_time, ec);+ }+#endif // !defined(ASIO_NO_DEPRECATED)+ /// Set the timer's expiry time relative to now. /** * This function sets the expiry time. Any pending asynchronous wait@@ -516,6 +626,80 @@ return s; } +#if !defined(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 impl_.get_service().expires_from_now(impl_.get_implementation());+ }++ /// (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+ * be invoked with the asio::error::operation_aborted error code.+ *+ * @param expiry_time The expiry time to be used for the timer.+ *+ * @return The number of asynchronous operations that were cancelled.+ *+ * @throws asio::system_error Thrown on failure.+ *+ * @note If the timer has already expired when expires_from_now() is called,+ * then the handlers for asynchronous wait operations will:+ *+ * @li have already been invoked; or+ *+ * @li have been queued for invocation in the near future.+ *+ * These handlers can no longer be cancelled, and therefore are passed an+ * error code that indicates the successful completion of the wait operation.+ */+ std::size_t expires_from_now(const duration& expiry_time)+ {+ asio::error_code ec;+ std::size_t s = impl_.get_service().expires_from_now(+ impl_.get_implementation(), expiry_time, ec);+ asio::detail::throw_error(ec, "expires_from_now");+ return s;+ }++ /// (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+ * be invoked with the asio::error::operation_aborted error code.+ *+ * @param expiry_time The expiry time to be used for the timer.+ *+ * @param ec Set to indicate what error occurred, if any.+ *+ * @return The number of asynchronous operations that were cancelled.+ *+ * @note If the timer has already expired when expires_from_now() is called,+ * then the handlers for asynchronous wait operations will:+ *+ * @li have already been invoked; or+ *+ * @li have been queued for invocation in the near future.+ *+ * These handlers can no longer be cancelled, and therefore are passed an+ * error code that indicates the successful completion of the wait operation.+ */+ std::size_t expires_from_now(const duration& expiry_time,+ asio::error_code& ec)+ {+ return impl_.get_service().expires_from_now(+ impl_.get_implementation(), expiry_time, ec);+ }+#endif // !defined(ASIO_NO_DEPRECATED)+ /// Perform a blocking wait on the timer. /** * This function is used to wait for the timer to expire. This function@@ -567,7 +751,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code) @endcode@@ -584,12 +768,15 @@ */ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code))- WaitToken = default_completion_token_t<executor_type>>- auto async_wait(- WaitToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ WaitToken ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(+ WaitToken, void (asio::error_code))+ async_wait(+ ASIO_MOVE_ARG(WaitToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<WaitToken, void (asio::error_code)>(- declval<initiate_async_wait>(), token))+ declval<initiate_async_wait>(), token))) { return async_initiate<WaitToken, void (asio::error_code)>( initiate_async_wait(this), token);@@ -597,8 +784,9 @@ private: // Disallow copying and assignment.- basic_waitable_timer(const basic_waitable_timer&) = delete;- basic_waitable_timer& operator=(const basic_waitable_timer&) = delete;+ basic_waitable_timer(const basic_waitable_timer&) ASIO_DELETED;+ basic_waitable_timer& operator=(+ const basic_waitable_timer&) ASIO_DELETED; class initiate_async_wait {@@ -610,13 +798,13 @@ { } - const executor_type& get_executor() const noexcept+ const executor_type& get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template <typename WaitHandler>- void operator()(WaitHandler&& handler) const+ void operator()(ASIO_MOVE_ARG(WaitHandler) handler) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a WaitHandler.@@ -634,7 +822,7 @@ detail::io_object_impl< detail::deadline_timer_service<- detail::chrono_time_traits<Clock, WaitTraits>>,+ detail::chrono_time_traits<Clock, WaitTraits> >, executor_type > impl_; };
link/modules/asio-standalone/asio/include/asio/basic_writable_pipe.hpp view
@@ -2,7 +2,7 @@ // basic_writable_pipe.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -21,7 +21,6 @@ || defined(GENERATING_DOCUMENTATION) #include <string>-#include <utility> #include "asio/any_io_executor.hpp" #include "asio/async_result.hpp" #include "asio/detail/handler_type_requirements.hpp"@@ -39,6 +38,10 @@ # include "asio/detail/reactive_descriptor_service.hpp" #endif +#if defined(ASIO_HAS_MOVE)+# include <utility>+#endif // defined(ASIO_HAS_MOVE)+ #include "asio/detail/push_options.hpp" namespace asio {@@ -109,10 +112,10 @@ */ template <typename ExecutionContext> explicit basic_writable_pipe(ExecutionContext& context,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- > = defaulted_constraint())+ >::type = defaulted_constraint()) : impl_(0, 0, context) { }@@ -156,9 +159,9 @@ template <typename ExecutionContext> basic_writable_pipe(ExecutionContext& context, const native_handle_type& native_pipe,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- > = 0)+ >::type = 0) : impl_(0, 0, context) { asio::error_code ec;@@ -167,6 +170,7 @@ asio::detail::throw_error(ec, "assign"); } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move-construct a basic_writable_pipe from another. /** * This constructor moves a pipe from one object to another.@@ -217,10 +221,10 @@ */ template <typename Executor1> basic_writable_pipe(basic_writable_pipe<Executor1>&& other,- constraint_t<+ typename constraint< is_convertible<Executor1, Executor>::value, defaulted_constraint- > = defaulted_constraint())+ >::type = defaulted_constraint()) : impl_(std::move(other.impl_)) { }@@ -237,15 +241,16 @@ * constructor. */ template <typename Executor1>- constraint_t<+ typename constraint< is_convertible<Executor1, Executor>::value, basic_writable_pipe&- > operator=(basic_writable_pipe<Executor1>&& other)+ >::type operator=(basic_writable_pipe<Executor1>&& other) { basic_writable_pipe tmp(std::move(other)); impl_ = std::move(tmp.impl_); return *this; }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Destroys the pipe. /**@@ -258,7 +263,7 @@ } /// Get the executor associated with the object.- const executor_type& get_executor() noexcept+ const executor_type& get_executor() ASIO_NOEXCEPT { return impl_.get_executor(); }@@ -532,7 +537,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -552,13 +557,17 @@ */ template <typename ConstBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) WriteToken = default_completion_token_t<executor_type>>- auto async_write_some(const ConstBufferSequence& buffers,- WriteToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ std::size_t)) WriteToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+ void (asio::error_code, std::size_t))+ async_write_some(const ConstBufferSequence& buffers,+ ASIO_MOVE_ARG(WriteToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<WriteToken, void (asio::error_code, std::size_t)>(- declval<initiate_async_write_some>(), token, buffers))+ declval<initiate_async_write_some>(), token, buffers))) { return async_initiate<WriteToken, void (asio::error_code, std::size_t)>(@@ -567,8 +576,8 @@ private: // Disallow copying and assignment.- basic_writable_pipe(const basic_writable_pipe&) = delete;- basic_writable_pipe& operator=(const basic_writable_pipe&) = delete;+ basic_writable_pipe(const basic_writable_pipe&) ASIO_DELETED;+ basic_writable_pipe& operator=(const basic_writable_pipe&) ASIO_DELETED; class initiate_async_write_some {@@ -580,13 +589,13 @@ { } - const executor_type& get_executor() const noexcept+ const executor_type& get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template <typename WriteHandler, typename ConstBufferSequence>- void operator()(WriteHandler&& handler,+ void operator()(ASIO_MOVE_ARG(WriteHandler) handler, const ConstBufferSequence& buffers) const { // If you get an error on the following line it means that your handler
link/modules/asio-standalone/asio/include/asio/bind_allocator.hpp view
@@ -2,7 +2,7 @@ // bind_allocator.hpp // ~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -16,12 +16,11 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"+#include "asio/detail/type_traits.hpp"+#include "asio/detail/variadic_templates.hpp" #include "asio/associated_allocator.hpp"-#include "asio/associated_executor.hpp" #include "asio/associator.hpp" #include "asio/async_result.hpp"-#include "asio/detail/initiation_base.hpp"-#include "asio/detail/type_traits.hpp" #include "asio/detail/push_options.hpp" @@ -38,7 +37,8 @@ }; template <typename T>-struct allocator_binder_result_type<T, void_t<typename T::result_type>>+struct allocator_binder_result_type<T,+ typename void_type<typename T::result_type>::type> { typedef typename T::result_type result_type; protected:@@ -99,7 +99,8 @@ struct allocator_binder_argument_type {}; template <typename T>-struct allocator_binder_argument_type<T, void_t<typename T::argument_type>>+struct allocator_binder_argument_type<T,+ typename void_type<typename T::argument_type>::type> { typedef typename T::argument_type argument_type; };@@ -124,7 +125,7 @@ template <typename T> struct allocator_binder_argument_types<T,- void_t<typename T::first_argument_type>>+ typename void_type<typename T::first_argument_type>::type> { typedef typename T::first_argument_type first_argument_type; typedef typename T::second_argument_type second_argument_type;@@ -144,6 +145,21 @@ typedef A2 second_argument_type; }; +// Helper to enable SFINAE on zero-argument operator() below.++template <typename T, typename = void>+struct allocator_binder_result_of0+{+ typedef void type;+};++template <typename T>+struct allocator_binder_result_of0<T,+ typename void_type<typename result_of<T()>::type>::type>+{+ typedef typename result_of<T()>::type type;+};+ } // namespace detail /// A call wrapper type to bind an allocator of type @c Allocator@@ -231,9 +247,10 @@ * @c U. */ template <typename U>- allocator_binder(const allocator_type& s, U&& u)+ allocator_binder(const allocator_type& s,+ ASIO_MOVE_ARG(U) u) : allocator_(s),- target_(static_cast<U&&>(u))+ target_(ASIO_MOVE_CAST(U)(u)) { } @@ -245,7 +262,8 @@ } /// Construct a copy, but specify a different allocator.- allocator_binder(const allocator_type& s, const allocator_binder& other)+ allocator_binder(const allocator_type& s,+ const allocator_binder& other) : allocator_(s), target_(other.get()) {@@ -258,9 +276,8 @@ * constructible from type @c U. */ template <typename U, typename OtherAllocator>- allocator_binder(const allocator_binder<U, OtherAllocator>& other,- constraint_t<is_constructible<Allocator, OtherAllocator>::value> = 0,- constraint_t<is_constructible<T, U>::value> = 0)+ allocator_binder(+ const allocator_binder<U, OtherAllocator>& other) : allocator_(other.get_allocator()), target_(other.get()) {@@ -274,18 +291,19 @@ */ template <typename U, typename OtherAllocator> allocator_binder(const allocator_type& s,- const allocator_binder<U, OtherAllocator>& other,- constraint_t<is_constructible<T, U>::value> = 0)+ const allocator_binder<U, OtherAllocator>& other) : allocator_(s), target_(other.get()) { } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)+ /// Move constructor. allocator_binder(allocator_binder&& other)- : allocator_(static_cast<allocator_type&&>(+ : allocator_(ASIO_MOVE_CAST(allocator_type)( other.get_allocator())),- target_(static_cast<T&&>(other.get()))+ target_(ASIO_MOVE_CAST(T)(other.get())) { } @@ -293,19 +311,17 @@ allocator_binder(const allocator_type& s, allocator_binder&& other) : allocator_(s),- target_(static_cast<T&&>(other.get()))+ target_(ASIO_MOVE_CAST(T)(other.get())) { } /// Move construct from a different allocator wrapper type. template <typename U, typename OtherAllocator> allocator_binder(- allocator_binder<U, OtherAllocator>&& other,- constraint_t<is_constructible<Allocator, OtherAllocator>::value> = 0,- constraint_t<is_constructible<T, U>::value> = 0)- : allocator_(static_cast<OtherAllocator&&>(+ allocator_binder<U, OtherAllocator>&& other)+ : allocator_(ASIO_MOVE_CAST(OtherAllocator)( other.get_allocator())),- target_(static_cast<U&&>(other.get()))+ target_(ASIO_MOVE_CAST(U)(other.get())) { } @@ -313,148 +329,162 @@ /// specify a different allocator. template <typename U, typename OtherAllocator> allocator_binder(const allocator_type& s,- allocator_binder<U, OtherAllocator>&& other,- constraint_t<is_constructible<T, U>::value> = 0)+ allocator_binder<U, OtherAllocator>&& other) : allocator_(s),- target_(static_cast<U&&>(other.get()))+ target_(ASIO_MOVE_CAST(U)(other.get())) { } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)+ /// Destructor. ~allocator_binder() { } /// Obtain a reference to the target object.- target_type& get() noexcept+ target_type& get() ASIO_NOEXCEPT { return target_; } /// Obtain a reference to the target object.- const target_type& get() const noexcept+ const target_type& get() const ASIO_NOEXCEPT { return target_; } /// Obtain the associated allocator.- allocator_type get_allocator() const noexcept+ allocator_type get_allocator() const ASIO_NOEXCEPT { return allocator_; } +#if defined(GENERATING_DOCUMENTATION)++ template <typename... Args> auto operator()(Args&& ...);+ template <typename... Args> auto operator()(Args&& ...) const;++#elif defined(ASIO_HAS_VARIADIC_TEMPLATES)+ /// Forwarding function call operator. template <typename... Args>- result_of_t<T(Args...)> operator()(Args&&... args) &+ typename result_of<T(Args...)>::type operator()(+ ASIO_MOVE_ARG(Args)... args) {- return target_(static_cast<Args&&>(args)...);+ return target_(ASIO_MOVE_CAST(Args)(args)...); } /// Forwarding function call operator. template <typename... Args>- result_of_t<T(Args...)> operator()(Args&&... args) &&+ typename result_of<T(Args...)>::type operator()(+ ASIO_MOVE_ARG(Args)... args) const {- return static_cast<T&&>(target_)(static_cast<Args&&>(args)...);+ return target_(ASIO_MOVE_CAST(Args)(args)...); } - /// Forwarding function call operator.- template <typename... Args>- result_of_t<T(Args...)> operator()(Args&&... args) const&+#elif defined(ASIO_HAS_STD_TYPE_TRAITS) && !defined(_MSC_VER)++ typename detail::allocator_binder_result_of0<T>::type operator()() {- return target_(static_cast<Args&&>(args)...);+ return target_(); } -private:- Allocator allocator_;- T target_;-};+ typename detail::allocator_binder_result_of0<T>::type+ operator()() const+ {+ return target_();+ } -/// A function object type that adapts a @ref completion_token to specify that-/// the completion handler should have the supplied allocator as its associated-/// allocator.-/**- * May also be used directly as a completion token, in which case it adapts the- * asynchronous operation's default completion token (or asio::deferred- * if no default is available).- */-template <typename Allocator>-struct partial_allocator_binder-{- /// Constructor that specifies associated allocator.- explicit partial_allocator_binder(const Allocator& ex)- : allocator_(ex)+#define ASIO_PRIVATE_BINDER_CALL_DEF(n) \+ template <ASIO_VARIADIC_TPARAMS(n)> \+ typename result_of<T(ASIO_VARIADIC_TARGS(n))>::type operator()( \+ ASIO_VARIADIC_MOVE_PARAMS(n)) \+ { \+ return target_(ASIO_VARIADIC_MOVE_ARGS(n)); \+ } \+ \+ template <ASIO_VARIADIC_TPARAMS(n)> \+ typename result_of<T(ASIO_VARIADIC_TARGS(n))>::type operator()( \+ ASIO_VARIADIC_MOVE_PARAMS(n)) const \+ { \+ return target_(ASIO_VARIADIC_MOVE_ARGS(n)); \+ } \+ /**/+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_BINDER_CALL_DEF)+#undef ASIO_PRIVATE_BINDER_CALL_DEF++#else // defined(ASIO_HAS_STD_TYPE_TRAITS) && !defined(_MSC_VER)++ typedef typename detail::allocator_binder_result_type<+ T>::result_type_or_void result_type_or_void;++ result_type_or_void operator()() {+ return target_(); } - /// Adapt a @ref completion_token to specify that the completion handler- /// should have the allocator as its associated allocator.- template <typename CompletionToken>- ASIO_NODISCARD inline- constexpr allocator_binder<decay_t<CompletionToken>, Allocator>- operator()(CompletionToken&& completion_token) const+ result_type_or_void operator()() const {- return allocator_binder<decay_t<CompletionToken>, Allocator>(- allocator_, static_cast<CompletionToken&&>(completion_token));+ return target_(); } -//private:+#define ASIO_PRIVATE_BINDER_CALL_DEF(n) \+ template <ASIO_VARIADIC_TPARAMS(n)> \+ result_type_or_void operator()( \+ ASIO_VARIADIC_MOVE_PARAMS(n)) \+ { \+ return target_(ASIO_VARIADIC_MOVE_ARGS(n)); \+ } \+ \+ template <ASIO_VARIADIC_TPARAMS(n)> \+ result_type_or_void operator()( \+ ASIO_VARIADIC_MOVE_PARAMS(n)) const \+ { \+ return target_(ASIO_VARIADIC_MOVE_ARGS(n)); \+ } \+ /**/+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_BINDER_CALL_DEF)+#undef ASIO_PRIVATE_BINDER_CALL_DEF++#endif // defined(ASIO_HAS_STD_TYPE_TRAITS) && !defined(_MSC_VER)++private: Allocator allocator_;+ T target_; }; -/// Create a partial completion token that associates an allocator.-template <typename Allocator>-ASIO_NODISCARD inline partial_allocator_binder<Allocator>-bind_allocator(const Allocator& ex)-{- return partial_allocator_binder<Allocator>(ex);-}- /// Associate an object of type @c T with an allocator of type /// @c Allocator. template <typename Allocator, typename T>-ASIO_NODISCARD inline allocator_binder<decay_t<T>, Allocator>-bind_allocator(const Allocator& s, T&& t)+ASIO_NODISCARD inline allocator_binder<typename decay<T>::type, Allocator>+bind_allocator(const Allocator& s, ASIO_MOVE_ARG(T) t) {- return allocator_binder<decay_t<T>, Allocator>(s, static_cast<T&&>(t));+ return allocator_binder<+ typename decay<T>::type, Allocator>(+ s, ASIO_MOVE_CAST(T)(t)); } #if !defined(GENERATING_DOCUMENTATION) namespace detail { -template <typename TargetAsyncResult, typename Allocator, typename = void>-class allocator_binder_completion_handler_async_result+template <typename TargetAsyncResult,+ typename Allocator, typename = void>+struct allocator_binder_async_result_completion_handler_type {-public:- template <typename T>- explicit allocator_binder_completion_handler_async_result(T&)- {- } }; template <typename TargetAsyncResult, typename Allocator>-class allocator_binder_completion_handler_async_result<- TargetAsyncResult, Allocator,- void_t<typename TargetAsyncResult::completion_handler_type>>+struct allocator_binder_async_result_completion_handler_type<+ TargetAsyncResult, Allocator,+ typename void_type<+ typename TargetAsyncResult::completion_handler_type+ >::type> {-private:- TargetAsyncResult target_;--public: typedef allocator_binder< typename TargetAsyncResult::completion_handler_type, Allocator> completion_handler_type;-- explicit allocator_binder_completion_handler_async_result(- typename TargetAsyncResult::completion_handler_type& handler)- : target_(handler)- {- }-- auto get() -> decltype(target_.get())- {- return target_.get();- } }; template <typename TargetAsyncResult, typename = void>@@ -464,7 +494,10 @@ template <typename TargetAsyncResult> struct allocator_binder_async_result_return_type<- TargetAsyncResult, void_type<typename TargetAsyncResult::return_type>>+ TargetAsyncResult,+ typename void_type<+ typename TargetAsyncResult::return_type+ >::type> { typedef typename TargetAsyncResult::return_type return_type; };@@ -473,122 +506,219 @@ template <typename T, typename Allocator, typename Signature> class async_result<allocator_binder<T, Allocator>, Signature> :- public detail::allocator_binder_completion_handler_async_result<- async_result<T, Signature>, Allocator>,+ public detail::allocator_binder_async_result_completion_handler_type<+ async_result<T, Signature>, Allocator>, public detail::allocator_binder_async_result_return_type<- async_result<T, Signature>>+ async_result<T, Signature> > { public: explicit async_result(allocator_binder<T, Allocator>& b)- : detail::allocator_binder_completion_handler_async_result<- async_result<T, Signature>, Allocator>(b.get())+ : target_(b.get()) { } + typename async_result<T, Signature>::return_type get()+ {+ return target_.get();+ }+ template <typename Initiation>- struct init_wrapper : detail::initiation_base<Initiation>+ struct init_wrapper {- using detail::initiation_base<Initiation>::initiation_base;+ template <typename Init>+ init_wrapper(const Allocator& allocator, ASIO_MOVE_ARG(Init) init)+ : allocator_(allocator),+ initiation_(ASIO_MOVE_CAST(Init)(init))+ {+ } +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+ template <typename Handler, typename... Args>- void operator()(Handler&& handler, const Allocator& a, Args&&... args) &&+ void operator()(+ ASIO_MOVE_ARG(Handler) handler,+ ASIO_MOVE_ARG(Args)... args) {- static_cast<Initiation&&>(*this)(- allocator_binder<decay_t<Handler>, Allocator>(- a, static_cast<Handler&&>(handler)),- static_cast<Args&&>(args)...);+ ASIO_MOVE_CAST(Initiation)(initiation_)(+ allocator_binder<+ typename decay<Handler>::type, Allocator>(+ allocator_, ASIO_MOVE_CAST(Handler)(handler)),+ ASIO_MOVE_CAST(Args)(args)...); } template <typename Handler, typename... Args>- void operator()(Handler&& handler,- const Allocator& a, Args&&... args) const &+ void operator()(+ ASIO_MOVE_ARG(Handler) handler,+ ASIO_MOVE_ARG(Args)... args) const {- static_cast<const Initiation&>(*this)(- allocator_binder<decay_t<Handler>, Allocator>(- a, static_cast<Handler&&>(handler)),- static_cast<Args&&>(args)...);+ initiation_(+ allocator_binder<+ typename decay<Handler>::type, Allocator>(+ allocator_, ASIO_MOVE_CAST(Handler)(handler)),+ ASIO_MOVE_CAST(Args)(args)...); }++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++ template <typename Handler>+ void operator()(+ ASIO_MOVE_ARG(Handler) handler)+ {+ ASIO_MOVE_CAST(Initiation)(initiation_)(+ allocator_binder<+ typename decay<Handler>::type, Allocator>(+ allocator_, ASIO_MOVE_CAST(Handler)(handler)));+ }++ template <typename Handler>+ void operator()(+ ASIO_MOVE_ARG(Handler) handler) const+ {+ initiation_(+ allocator_binder<+ typename decay<Handler>::type, Allocator>(+ allocator_, ASIO_MOVE_CAST(Handler)(handler)));+ }++#define ASIO_PRIVATE_INIT_WRAPPER_DEF(n) \+ template <typename Handler, ASIO_VARIADIC_TPARAMS(n)> \+ void operator()( \+ ASIO_MOVE_ARG(Handler) handler, \+ ASIO_VARIADIC_MOVE_PARAMS(n)) \+ { \+ ASIO_MOVE_CAST(Initiation)(initiation_)( \+ allocator_binder< \+ typename decay<Handler>::type, Allocator>( \+ allocator_, ASIO_MOVE_CAST(Handler)(handler)), \+ ASIO_VARIADIC_MOVE_ARGS(n)); \+ } \+ \+ template <typename Handler, ASIO_VARIADIC_TPARAMS(n)> \+ void operator()( \+ ASIO_MOVE_ARG(Handler) handler, \+ ASIO_VARIADIC_MOVE_PARAMS(n)) const \+ { \+ initiation_( \+ allocator_binder< \+ typename decay<Handler>::type, Allocator>( \+ allocator_, ASIO_MOVE_CAST(Handler)(handler)), \+ ASIO_VARIADIC_MOVE_ARGS(n)); \+ } \+ /**/+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_INIT_WRAPPER_DEF)+#undef ASIO_PRIVATE_INIT_WRAPPER_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++ Allocator allocator_;+ Initiation initiation_; }; +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+ template <typename Initiation, typename RawCompletionToken, typename... Args>- static auto initiate(Initiation&& initiation,- RawCompletionToken&& token, Args&&... args)- -> decltype(- async_initiate<- conditional_t<- is_const<remove_reference_t<RawCompletionToken>>::value, const T, T>,- Signature>(- declval<init_wrapper<decay_t<Initiation>>>(),- token.get(), token.get_allocator(), static_cast<Args&&>(args)...))+ static ASIO_INITFN_DEDUCED_RESULT_TYPE(T, Signature,+ (async_initiate<T, Signature>(+ declval<init_wrapper<typename decay<Initiation>::type> >(),+ declval<RawCompletionToken>().get(),+ declval<ASIO_MOVE_ARG(Args)>()...)))+ initiate(+ ASIO_MOVE_ARG(Initiation) initiation,+ ASIO_MOVE_ARG(RawCompletionToken) token,+ ASIO_MOVE_ARG(Args)... args) {- return async_initiate<- conditional_t<- is_const<remove_reference_t<RawCompletionToken>>::value, const T, T>,- Signature>(- init_wrapper<decay_t<Initiation>>(- static_cast<Initiation&&>(initiation)),- token.get(), token.get_allocator(), static_cast<Args&&>(args)...);+ return async_initiate<T, Signature>(+ init_wrapper<typename decay<Initiation>::type>(+ token.get_allocator(),+ ASIO_MOVE_CAST(Initiation)(initiation)),+ token.get(), ASIO_MOVE_CAST(Args)(args)...); } -private:- async_result(const async_result&) = delete;- async_result& operator=(const async_result&) = delete;-- async_result<T, Signature> target_;-};+#else // defined(ASIO_HAS_VARIADIC_TEMPLATES) -template <typename Allocator, typename... Signatures>-struct async_result<partial_allocator_binder<Allocator>, Signatures...>-{- template <typename Initiation, typename RawCompletionToken, typename... Args>- static auto initiate(Initiation&& initiation,- RawCompletionToken&& token, Args&&... args)- -> decltype(- async_initiate<Signatures...>(- static_cast<Initiation&&>(initiation),- allocator_binder<- default_completion_token_t<associated_executor_t<Initiation>>,- Allocator>(token.allocator_,- default_completion_token_t<associated_executor_t<Initiation>>{}),- static_cast<Args&&>(args)...))+ template <typename Initiation, typename RawCompletionToken>+ static ASIO_INITFN_DEDUCED_RESULT_TYPE(T, Signature,+ (async_initiate<T, Signature>(+ declval<init_wrapper<typename decay<Initiation>::type> >(),+ declval<RawCompletionToken>().get())))+ initiate(+ ASIO_MOVE_ARG(Initiation) initiation,+ ASIO_MOVE_ARG(RawCompletionToken) token) {- return async_initiate<Signatures...>(- static_cast<Initiation&&>(initiation),- allocator_binder<- default_completion_token_t<associated_executor_t<Initiation>>,- Allocator>(token.allocator_,- default_completion_token_t<associated_executor_t<Initiation>>{}),- static_cast<Args&&>(args)...);+ return async_initiate<T, Signature>(+ init_wrapper<typename decay<Initiation>::type>(+ token.get_allocator(),+ ASIO_MOVE_CAST(Initiation)(initiation)),+ token.get()); }++#define ASIO_PRIVATE_INITIATE_DEF(n) \+ template <typename Initiation, typename RawCompletionToken, \+ ASIO_VARIADIC_TPARAMS(n)> \+ static ASIO_INITFN_DEDUCED_RESULT_TYPE(T, Signature, \+ (async_initiate<T, Signature>( \+ declval<init_wrapper<typename decay<Initiation>::type> >(), \+ declval<RawCompletionToken>().get(), \+ ASIO_VARIADIC_MOVE_DECLVAL(n)))) \+ initiate( \+ ASIO_MOVE_ARG(Initiation) initiation, \+ ASIO_MOVE_ARG(RawCompletionToken) token, \+ ASIO_VARIADIC_MOVE_PARAMS(n)) \+ { \+ return async_initiate<T, Signature>( \+ init_wrapper<typename decay<Initiation>::type>( \+ token.get_allocator(), \+ ASIO_MOVE_CAST(Initiation)(initiation)), \+ token.get(), ASIO_VARIADIC_MOVE_ARGS(n)); \+ } \+ /**/+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_INITIATE_DEF)+#undef ASIO_PRIVATE_INITIATE_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++private:+ async_result(const async_result&) ASIO_DELETED;+ async_result& operator=(const async_result&) ASIO_DELETED;++ async_result<T, Signature> target_; }; template <template <typename, typename> class Associator, typename T, typename Allocator, typename DefaultCandidate>-struct associator<Associator, allocator_binder<T, Allocator>, DefaultCandidate>+struct associator<Associator,+ allocator_binder<T, Allocator>,+ DefaultCandidate> : Associator<T, DefaultCandidate> {- static typename Associator<T, DefaultCandidate>::type get(- const allocator_binder<T, Allocator>& b) noexcept+ static typename Associator<T, DefaultCandidate>::type+ get(const allocator_binder<T, Allocator>& b) ASIO_NOEXCEPT { return Associator<T, DefaultCandidate>::get(b.get()); } - static auto get(const allocator_binder<T, Allocator>& b,- const DefaultCandidate& c) noexcept- -> decltype(Associator<T, DefaultCandidate>::get(b.get(), c))+ static ASIO_AUTO_RETURN_TYPE_PREFIX2(+ typename Associator<T, DefaultCandidate>::type)+ get(const allocator_binder<T, Allocator>& b,+ const DefaultCandidate& c) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ Associator<T, DefaultCandidate>::get(b.get(), c))) { return Associator<T, DefaultCandidate>::get(b.get(), c); } }; template <typename T, typename Allocator, typename Allocator1>-struct associated_allocator<allocator_binder<T, Allocator>, Allocator1>+struct associated_allocator<+ allocator_binder<T, Allocator>,+ Allocator1> { typedef Allocator type; - static auto get(const allocator_binder<T, Allocator>& b,- const Allocator1& = Allocator1()) noexcept- -> decltype(b.get_allocator())+ static ASIO_AUTO_RETURN_TYPE_PREFIX(type) get(+ const allocator_binder<T, Allocator>& b,+ const Allocator1& = Allocator1()) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((b.get_allocator())) { return b.get_allocator(); }
link/modules/asio-standalone/asio/include/asio/bind_cancellation_slot.hpp view
@@ -2,7 +2,7 @@ // bind_cancellation_slot.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -16,12 +16,11 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"+#include "asio/detail/type_traits.hpp"+#include "asio/detail/variadic_templates.hpp" #include "asio/associated_cancellation_slot.hpp"-#include "asio/associated_executor.hpp" #include "asio/associator.hpp" #include "asio/async_result.hpp"-#include "asio/detail/initiation_base.hpp"-#include "asio/detail/type_traits.hpp" #include "asio/detail/push_options.hpp" @@ -38,7 +37,8 @@ }; template <typename T>-struct cancellation_slot_binder_result_type<T, void_t<typename T::result_type>>+struct cancellation_slot_binder_result_type<T,+ typename void_type<typename T::result_type>::type> { typedef typename T::result_type result_type; protected:@@ -100,7 +100,7 @@ template <typename T> struct cancellation_slot_binder_argument_type<T,- void_t<typename T::argument_type>>+ typename void_type<typename T::argument_type>::type> { typedef typename T::argument_type argument_type; };@@ -125,7 +125,7 @@ template <typename T> struct cancellation_slot_binder_argument_types<T,- void_t<typename T::first_argument_type>>+ typename void_type<typename T::first_argument_type>::type> { typedef typename T::first_argument_type first_argument_type; typedef typename T::second_argument_type second_argument_type;@@ -145,6 +145,21 @@ typedef A2 second_argument_type; }; +// Helper to enable SFINAE on zero-argument operator() below.++template <typename T, typename = void>+struct cancellation_slot_binder_result_of0+{+ typedef void type;+};++template <typename T>+struct cancellation_slot_binder_result_of0<T,+ typename void_type<typename result_of<T()>::type>::type>+{+ typedef typename result_of<T()>::type type;+};+ } // namespace detail /// A call wrapper type to bind a cancellation slot of type @c CancellationSlot@@ -232,9 +247,10 @@ * @c U. */ template <typename U>- cancellation_slot_binder(const cancellation_slot_type& s, U&& u)+ cancellation_slot_binder(const cancellation_slot_type& s,+ ASIO_MOVE_ARG(U) u) : slot_(s),- target_(static_cast<U&&>(u))+ target_(ASIO_MOVE_CAST(U)(u)) { } @@ -261,10 +277,7 @@ */ template <typename U, typename OtherCancellationSlot> cancellation_slot_binder(- const cancellation_slot_binder<U, OtherCancellationSlot>& other,- constraint_t<is_constructible<CancellationSlot,- OtherCancellationSlot>::value> = 0,- constraint_t<is_constructible<T, U>::value> = 0)+ const cancellation_slot_binder<U, OtherCancellationSlot>& other) : slot_(other.get_cancellation_slot()), target_(other.get()) {@@ -278,18 +291,19 @@ */ template <typename U, typename OtherCancellationSlot> cancellation_slot_binder(const cancellation_slot_type& s,- const cancellation_slot_binder<U, OtherCancellationSlot>& other,- constraint_t<is_constructible<T, U>::value> = 0)+ const cancellation_slot_binder<U, OtherCancellationSlot>& other) : slot_(s), target_(other.get()) { } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)+ /// Move constructor. cancellation_slot_binder(cancellation_slot_binder&& other)- : slot_(static_cast<cancellation_slot_type&&>(+ : slot_(ASIO_MOVE_CAST(cancellation_slot_type)( other.get_cancellation_slot())),- target_(static_cast<T&&>(other.get()))+ target_(ASIO_MOVE_CAST(T)(other.get())) { } @@ -298,20 +312,17 @@ cancellation_slot_binder(const cancellation_slot_type& s, cancellation_slot_binder&& other) : slot_(s),- target_(static_cast<T&&>(other.get()))+ target_(ASIO_MOVE_CAST(T)(other.get())) { } /// Move construct from a different cancellation slot wrapper type. template <typename U, typename OtherCancellationSlot> cancellation_slot_binder(- cancellation_slot_binder<U, OtherCancellationSlot>&& other,- constraint_t<is_constructible<CancellationSlot,- OtherCancellationSlot>::value> = 0,- constraint_t<is_constructible<T, U>::value> = 0)- : slot_(static_cast<OtherCancellationSlot&&>(+ cancellation_slot_binder<U, OtherCancellationSlot>&& other)+ : slot_(ASIO_MOVE_CAST(OtherCancellationSlot)( other.get_cancellation_slot())),- target_(static_cast<U&&>(other.get()))+ target_(ASIO_MOVE_CAST(U)(other.get())) { } @@ -319,111 +330,141 @@ /// specify a different cancellation slot. template <typename U, typename OtherCancellationSlot> cancellation_slot_binder(const cancellation_slot_type& s,- cancellation_slot_binder<U, OtherCancellationSlot>&& other,- constraint_t<is_constructible<T, U>::value> = 0)+ cancellation_slot_binder<U, OtherCancellationSlot>&& other) : slot_(s),- target_(static_cast<U&&>(other.get()))+ target_(ASIO_MOVE_CAST(U)(other.get())) { } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)+ /// Destructor. ~cancellation_slot_binder() { } /// Obtain a reference to the target object.- target_type& get() noexcept+ target_type& get() ASIO_NOEXCEPT { return target_; } /// Obtain a reference to the target object.- const target_type& get() const noexcept+ const target_type& get() const ASIO_NOEXCEPT { return target_; } /// Obtain the associated cancellation slot.- cancellation_slot_type get_cancellation_slot() const noexcept+ cancellation_slot_type get_cancellation_slot() const ASIO_NOEXCEPT { return slot_; } +#if defined(GENERATING_DOCUMENTATION)++ template <typename... Args> auto operator()(Args&& ...);+ template <typename... Args> auto operator()(Args&& ...) const;++#elif defined(ASIO_HAS_VARIADIC_TEMPLATES)+ /// Forwarding function call operator. template <typename... Args>- result_of_t<T(Args...)> operator()(Args&&... args) &+ typename result_of<T(Args...)>::type operator()(+ ASIO_MOVE_ARG(Args)... args) {- return target_(static_cast<Args&&>(args)...);+ return target_(ASIO_MOVE_CAST(Args)(args)...); } /// Forwarding function call operator. template <typename... Args>- result_of_t<T(Args...)> operator()(Args&&... args) &&+ typename result_of<T(Args...)>::type operator()(+ ASIO_MOVE_ARG(Args)... args) const {- return static_cast<T&&>(target_)(static_cast<Args&&>(args)...);+ return target_(ASIO_MOVE_CAST(Args)(args)...); } - /// Forwarding function call operator.- template <typename... Args>- result_of_t<T(Args...)> operator()(Args&&... args) const&+#elif defined(ASIO_HAS_STD_TYPE_TRAITS) && !defined(_MSC_VER)++ typename detail::cancellation_slot_binder_result_of0<T>::type operator()() {- return target_(static_cast<Args&&>(args)...);+ return target_(); } -private:- CancellationSlot slot_;- T target_;-};+ typename detail::cancellation_slot_binder_result_of0<T>::type+ operator()() const+ {+ return target_();+ } -/// A function object type that adapts a @ref completion_token to specify that-/// the completion handler should have the supplied cancellation slot as its-/// associated cancellation slot.-/**- * May also be used directly as a completion token, in which case it adapts the- * asynchronous operation's default completion token (or asio::deferred- * if no default is available).- */-template <typename CancellationSlot>-struct partial_cancellation_slot_binder-{- /// Constructor that specifies associated cancellation slot.- explicit partial_cancellation_slot_binder(const CancellationSlot& ex)- : cancellation_slot_(ex)+#define ASIO_PRIVATE_BINDER_CALL_DEF(n) \+ template <ASIO_VARIADIC_TPARAMS(n)> \+ typename result_of<T(ASIO_VARIADIC_TARGS(n))>::type operator()( \+ ASIO_VARIADIC_MOVE_PARAMS(n)) \+ { \+ return target_(ASIO_VARIADIC_MOVE_ARGS(n)); \+ } \+ \+ template <ASIO_VARIADIC_TPARAMS(n)> \+ typename result_of<T(ASIO_VARIADIC_TARGS(n))>::type operator()( \+ ASIO_VARIADIC_MOVE_PARAMS(n)) const \+ { \+ return target_(ASIO_VARIADIC_MOVE_ARGS(n)); \+ } \+ /**/+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_BINDER_CALL_DEF)+#undef ASIO_PRIVATE_BINDER_CALL_DEF++#else // defined(ASIO_HAS_STD_TYPE_TRAITS) && !defined(_MSC_VER)++ typedef typename detail::cancellation_slot_binder_result_type<+ T>::result_type_or_void result_type_or_void;++ result_type_or_void operator()() {+ return target_(); } - /// Adapt a @ref completion_token to specify that the completion handler- /// should have the cancellation slot as its associated cancellation slot.- template <typename CompletionToken>- ASIO_NODISCARD inline- constexpr cancellation_slot_binder<decay_t<CompletionToken>, CancellationSlot>- operator()(CompletionToken&& completion_token) const+ result_type_or_void operator()() const {- return cancellation_slot_binder<decay_t<CompletionToken>, CancellationSlot>(- static_cast<CompletionToken&&>(completion_token), cancellation_slot_);+ return target_(); } -//private:- CancellationSlot cancellation_slot_;-};+#define ASIO_PRIVATE_BINDER_CALL_DEF(n) \+ template <ASIO_VARIADIC_TPARAMS(n)> \+ result_type_or_void operator()( \+ ASIO_VARIADIC_MOVE_PARAMS(n)) \+ { \+ return target_(ASIO_VARIADIC_MOVE_ARGS(n)); \+ } \+ \+ template <ASIO_VARIADIC_TPARAMS(n)> \+ result_type_or_void operator()( \+ ASIO_VARIADIC_MOVE_PARAMS(n)) const \+ { \+ return target_(ASIO_VARIADIC_MOVE_ARGS(n)); \+ } \+ /**/+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_BINDER_CALL_DEF)+#undef ASIO_PRIVATE_BINDER_CALL_DEF -/// Create a partial completion token that associates a cancellation slot.-template <typename CancellationSlot>-ASIO_NODISCARD inline partial_cancellation_slot_binder<CancellationSlot>-bind_cancellation_slot(const CancellationSlot& ex)-{- return partial_cancellation_slot_binder<CancellationSlot>(ex);-}+#endif // defined(ASIO_HAS_STD_TYPE_TRAITS) && !defined(_MSC_VER) +private:+ CancellationSlot slot_;+ T target_;+};+ /// Associate an object of type @c T with a cancellation slot of type /// @c CancellationSlot. template <typename CancellationSlot, typename T> ASIO_NODISCARD inline-cancellation_slot_binder<decay_t<T>, CancellationSlot>-bind_cancellation_slot(const CancellationSlot& s, T&& t)+cancellation_slot_binder<typename decay<T>::type, CancellationSlot>+bind_cancellation_slot(const CancellationSlot& s, ASIO_MOVE_ARG(T) t) {- return cancellation_slot_binder<decay_t<T>, CancellationSlot>(- s, static_cast<T&&>(t));+ return cancellation_slot_binder<+ typename decay<T>::type, CancellationSlot>(+ s, ASIO_MOVE_CAST(T)(t)); } #if !defined(GENERATING_DOCUMENTATION)@@ -431,39 +472,21 @@ namespace detail { template <typename TargetAsyncResult,- typename CancellationSlot, typename = void>-class cancellation_slot_binder_completion_handler_async_result+ typename CancellationSlot, typename = void>+struct cancellation_slot_binder_async_result_completion_handler_type {-public:- template <typename T>- explicit cancellation_slot_binder_completion_handler_async_result(T&)- {- } }; template <typename TargetAsyncResult, typename CancellationSlot>-class cancellation_slot_binder_completion_handler_async_result<- TargetAsyncResult, CancellationSlot,- void_t<typename TargetAsyncResult::completion_handler_type>>+struct cancellation_slot_binder_async_result_completion_handler_type<+ TargetAsyncResult, CancellationSlot,+ typename void_type<+ typename TargetAsyncResult::completion_handler_type+ >::type> {-private:- TargetAsyncResult target_;--public: typedef cancellation_slot_binder< typename TargetAsyncResult::completion_handler_type, CancellationSlot> completion_handler_type;-- explicit cancellation_slot_binder_completion_handler_async_result(- typename TargetAsyncResult::completion_handler_type& handler)- : target_(handler)- {- }-- auto get() -> decltype(target_.get())- {- return target_.get();- } }; template <typename TargetAsyncResult, typename = void>@@ -473,7 +496,10 @@ template <typename TargetAsyncResult> struct cancellation_slot_binder_async_result_return_type<- TargetAsyncResult, void_t<typename TargetAsyncResult::return_type>>+ TargetAsyncResult,+ typename void_type<+ typename TargetAsyncResult::return_type+ >::type> { typedef typename TargetAsyncResult::return_type return_type; };@@ -482,97 +508,182 @@ template <typename T, typename CancellationSlot, typename Signature> class async_result<cancellation_slot_binder<T, CancellationSlot>, Signature> :- public detail::cancellation_slot_binder_completion_handler_async_result<- async_result<T, Signature>, CancellationSlot>,+ public detail::cancellation_slot_binder_async_result_completion_handler_type<+ async_result<T, Signature>, CancellationSlot>, public detail::cancellation_slot_binder_async_result_return_type<- async_result<T, Signature>>+ async_result<T, Signature> > { public: explicit async_result(cancellation_slot_binder<T, CancellationSlot>& b)- : detail::cancellation_slot_binder_completion_handler_async_result<- async_result<T, Signature>, CancellationSlot>(b.get())+ : target_(b.get()) { } + typename async_result<T, Signature>::return_type get()+ {+ return target_.get();+ }+ template <typename Initiation>- struct init_wrapper : detail::initiation_base<Initiation>+ struct init_wrapper {- using detail::initiation_base<Initiation>::initiation_base;+ template <typename Init>+ init_wrapper(const CancellationSlot& slot, ASIO_MOVE_ARG(Init) init)+ : slot_(slot),+ initiation_(ASIO_MOVE_CAST(Init)(init))+ {+ } +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+ template <typename Handler, typename... Args>- void operator()(Handler&& handler,- const CancellationSlot& slot, Args&&... args) &&+ void operator()(+ ASIO_MOVE_ARG(Handler) handler,+ ASIO_MOVE_ARG(Args)... args) {- static_cast<Initiation&&>(*this)(- cancellation_slot_binder<decay_t<Handler>, CancellationSlot>(- slot, static_cast<Handler&&>(handler)),- static_cast<Args&&>(args)...);+ ASIO_MOVE_CAST(Initiation)(initiation_)(+ cancellation_slot_binder<+ typename decay<Handler>::type, CancellationSlot>(+ slot_, ASIO_MOVE_CAST(Handler)(handler)),+ ASIO_MOVE_CAST(Args)(args)...); } template <typename Handler, typename... Args>- void operator()(Handler&& handler,- const CancellationSlot& slot, Args&&... args) const &+ void operator()(+ ASIO_MOVE_ARG(Handler) handler,+ ASIO_MOVE_ARG(Args)... args) const {- static_cast<const Initiation&>(*this)(- cancellation_slot_binder<decay_t<Handler>, CancellationSlot>(- slot, static_cast<Handler&&>(handler)),- static_cast<Args&&>(args)...);+ initiation_(+ cancellation_slot_binder<+ typename decay<Handler>::type, CancellationSlot>(+ slot_, ASIO_MOVE_CAST(Handler)(handler)),+ ASIO_MOVE_CAST(Args)(args)...); }++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++ template <typename Handler>+ void operator()(+ ASIO_MOVE_ARG(Handler) handler)+ {+ ASIO_MOVE_CAST(Initiation)(initiation_)(+ cancellation_slot_binder<+ typename decay<Handler>::type, CancellationSlot>(+ slot_, ASIO_MOVE_CAST(Handler)(handler)));+ }++ template <typename Handler>+ void operator()(+ ASIO_MOVE_ARG(Handler) handler) const+ {+ initiation_(+ cancellation_slot_binder<+ typename decay<Handler>::type, CancellationSlot>(+ slot_, ASIO_MOVE_CAST(Handler)(handler)));+ }++#define ASIO_PRIVATE_INIT_WRAPPER_DEF(n) \+ template <typename Handler, ASIO_VARIADIC_TPARAMS(n)> \+ void operator()( \+ ASIO_MOVE_ARG(Handler) handler, \+ ASIO_VARIADIC_MOVE_PARAMS(n)) \+ { \+ ASIO_MOVE_CAST(Initiation)(initiation_)( \+ cancellation_slot_binder< \+ typename decay<Handler>::type, CancellationSlot>( \+ slot_, ASIO_MOVE_CAST(Handler)(handler)), \+ ASIO_VARIADIC_MOVE_ARGS(n)); \+ } \+ \+ template <typename Handler, ASIO_VARIADIC_TPARAMS(n)> \+ void operator()( \+ ASIO_MOVE_ARG(Handler) handler, \+ ASIO_VARIADIC_MOVE_PARAMS(n)) const \+ { \+ initiation_( \+ cancellation_slot_binder< \+ typename decay<Handler>::type, CancellationSlot>( \+ slot_, ASIO_MOVE_CAST(Handler)(handler)), \+ ASIO_VARIADIC_MOVE_ARGS(n)); \+ } \+ /**/+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_INIT_WRAPPER_DEF)+#undef ASIO_PRIVATE_INIT_WRAPPER_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++ CancellationSlot slot_;+ Initiation initiation_; }; +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+ template <typename Initiation, typename RawCompletionToken, typename... Args>- static auto initiate(Initiation&& initiation,- RawCompletionToken&& token, Args&&... args)- -> decltype(- async_initiate<- conditional_t<- is_const<remove_reference_t<RawCompletionToken>>::value, const T, T>,- Signature>(- declval<init_wrapper<decay_t<Initiation>>>(),- token.get(), token.get_cancellation_slot(),- static_cast<Args&&>(args)...))+ static ASIO_INITFN_DEDUCED_RESULT_TYPE(T, Signature,+ (async_initiate<T, Signature>(+ declval<init_wrapper<typename decay<Initiation>::type> >(),+ declval<RawCompletionToken>().get(),+ declval<ASIO_MOVE_ARG(Args)>()...)))+ initiate(+ ASIO_MOVE_ARG(Initiation) initiation,+ ASIO_MOVE_ARG(RawCompletionToken) token,+ ASIO_MOVE_ARG(Args)... args) {- return async_initiate<- conditional_t<- is_const<remove_reference_t<RawCompletionToken>>::value, const T, T>,- Signature>(- init_wrapper<decay_t<Initiation>>(- static_cast<Initiation&&>(initiation)),- token.get(), token.get_cancellation_slot(),- static_cast<Args&&>(args)...);+ return async_initiate<T, Signature>(+ init_wrapper<typename decay<Initiation>::type>(+ token.get_cancellation_slot(),+ ASIO_MOVE_CAST(Initiation)(initiation)),+ token.get(), ASIO_MOVE_CAST(Args)(args)...); } -private:- async_result(const async_result&) = delete;- async_result& operator=(const async_result&) = delete;-- async_result<T, Signature> target_;-};+#else // defined(ASIO_HAS_VARIADIC_TEMPLATES) -template <typename CancellationSlot, typename... Signatures>-struct async_result<partial_cancellation_slot_binder<CancellationSlot>,- Signatures...>-{- template <typename Initiation, typename RawCompletionToken, typename... Args>- static auto initiate(Initiation&& initiation,- RawCompletionToken&& token, Args&&... args)- -> decltype(- async_initiate<Signatures...>(- static_cast<Initiation&&>(initiation),- cancellation_slot_binder<- default_completion_token_t<associated_executor_t<Initiation>>,- CancellationSlot>(token.cancellation_slot_,- default_completion_token_t<associated_executor_t<Initiation>>{}),- static_cast<Args&&>(args)...))+ template <typename Initiation, typename RawCompletionToken>+ static ASIO_INITFN_DEDUCED_RESULT_TYPE(T, Signature,+ (async_initiate<T, Signature>(+ declval<init_wrapper<typename decay<Initiation>::type> >(),+ declval<RawCompletionToken>().get())))+ initiate(+ ASIO_MOVE_ARG(Initiation) initiation,+ ASIO_MOVE_ARG(RawCompletionToken) token) {- return async_initiate<Signatures...>(- static_cast<Initiation&&>(initiation),- cancellation_slot_binder<- default_completion_token_t<associated_executor_t<Initiation>>,- CancellationSlot>(token.cancellation_slot_,- default_completion_token_t<associated_executor_t<Initiation>>{}),- static_cast<Args&&>(args)...);+ return async_initiate<T, Signature>(+ init_wrapper<typename decay<Initiation>::type>(+ token.get_cancellation_slot(),+ ASIO_MOVE_CAST(Initiation)(initiation)),+ token.get()); }++#define ASIO_PRIVATE_INITIATE_DEF(n) \+ template <typename Initiation, typename RawCompletionToken, \+ ASIO_VARIADIC_TPARAMS(n)> \+ static ASIO_INITFN_DEDUCED_RESULT_TYPE(T, Signature, \+ (async_initiate<T, Signature>( \+ declval<init_wrapper<typename decay<Initiation>::type> >(), \+ declval<RawCompletionToken>().get(), \+ ASIO_VARIADIC_MOVE_DECLVAL(n)))) \+ initiate( \+ ASIO_MOVE_ARG(Initiation) initiation, \+ ASIO_MOVE_ARG(RawCompletionToken) token, \+ ASIO_VARIADIC_MOVE_PARAMS(n)) \+ { \+ return async_initiate<T, Signature>( \+ init_wrapper<typename decay<Initiation>::type>( \+ token.get_cancellation_slot(), \+ ASIO_MOVE_CAST(Initiation)(initiation)), \+ token.get(), ASIO_VARIADIC_MOVE_ARGS(n)); \+ } \+ /**/+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_INITIATE_DEF)+#undef ASIO_PRIVATE_INITIATE_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++private:+ async_result(const async_result&) ASIO_DELETED;+ async_result& operator=(const async_result&) ASIO_DELETED;++ async_result<T, Signature> target_; }; template <template <typename, typename> class Associator,@@ -582,15 +693,19 @@ DefaultCandidate> : Associator<T, DefaultCandidate> {- static typename Associator<T, DefaultCandidate>::type get(- const cancellation_slot_binder<T, CancellationSlot>& b) noexcept+ static typename Associator<T, DefaultCandidate>::type+ get(const cancellation_slot_binder<T, CancellationSlot>& b)+ ASIO_NOEXCEPT { return Associator<T, DefaultCandidate>::get(b.get()); } - static auto get(const cancellation_slot_binder<T, CancellationSlot>& b,- const DefaultCandidate& c) noexcept- -> decltype(Associator<T, DefaultCandidate>::get(b.get(), c))+ static ASIO_AUTO_RETURN_TYPE_PREFIX2(+ typename Associator<T, DefaultCandidate>::type)+ get(const cancellation_slot_binder<T, CancellationSlot>& b,+ const DefaultCandidate& c) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ Associator<T, DefaultCandidate>::get(b.get(), c))) { return Associator<T, DefaultCandidate>::get(b.get(), c); }@@ -603,9 +718,10 @@ { typedef CancellationSlot type; - static auto get(const cancellation_slot_binder<T, CancellationSlot>& b,- const CancellationSlot1& = CancellationSlot1()) noexcept- -> decltype(b.get_cancellation_slot())+ static ASIO_AUTO_RETURN_TYPE_PREFIX(type) get(+ const cancellation_slot_binder<T, CancellationSlot>& b,+ const CancellationSlot1& = CancellationSlot1()) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((b.get_cancellation_slot())) { return b.get_cancellation_slot(); }
link/modules/asio-standalone/asio/include/asio/bind_executor.hpp view
@@ -2,7 +2,7 @@ // bind_executor.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -16,11 +16,11 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"+#include "asio/detail/type_traits.hpp"+#include "asio/detail/variadic_templates.hpp" #include "asio/associated_executor.hpp" #include "asio/associator.hpp" #include "asio/async_result.hpp"-#include "asio/detail/initiation_base.hpp"-#include "asio/detail/type_traits.hpp" #include "asio/execution/executor.hpp" #include "asio/execution_context.hpp" #include "asio/is_executor.hpp"@@ -41,7 +41,8 @@ }; template <typename T>-struct executor_binder_result_type<T, void_t<typename T::result_type>>+struct executor_binder_result_type<T,+ typename void_type<typename T::result_type>::type> { typedef typename T::result_type result_type; protected:@@ -102,7 +103,8 @@ struct executor_binder_argument_type {}; template <typename T>-struct executor_binder_argument_type<T, void_t<typename T::argument_type>>+struct executor_binder_argument_type<T,+ typename void_type<typename T::argument_type>::type> { typedef typename T::argument_type argument_type; };@@ -127,7 +129,7 @@ template <typename T> struct executor_binder_argument_types<T,- void_t<typename T::first_argument_type>>+ typename void_type<typename T::first_argument_type>::type> { typedef typename T::first_argument_type first_argument_type; typedef typename T::second_argument_type second_argument_type;@@ -158,9 +160,9 @@ { protected: template <typename E, typename U>- executor_binder_base(E&& e, U&& u)- : executor_(static_cast<E&&>(e)),- target_(executor_arg_t(), executor_, static_cast<U&&>(u))+ executor_binder_base(ASIO_MOVE_ARG(E) e, ASIO_MOVE_ARG(U) u)+ : executor_(ASIO_MOVE_CAST(E)(e)),+ target_(executor_arg_t(), executor_, ASIO_MOVE_CAST(U)(u)) { } @@ -173,9 +175,9 @@ { protected: template <typename E, typename U>- executor_binder_base(E&& e, U&& u)- : executor_(static_cast<E&&>(e)),- target_(static_cast<U&&>(u))+ executor_binder_base(ASIO_MOVE_ARG(E) e, ASIO_MOVE_ARG(U) u)+ : executor_(ASIO_MOVE_CAST(E)(e)),+ target_(ASIO_MOVE_CAST(U)(u)) { } @@ -183,6 +185,21 @@ 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 void_type<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@@ -273,8 +290,8 @@ */ template <typename U> executor_binder(executor_arg_t, const executor_type& e,- U&& u)- : base_type(e, static_cast<U&&>(u))+ ASIO_MOVE_ARG(U) u)+ : base_type(e, ASIO_MOVE_CAST(U)(u)) { } @@ -298,9 +315,7 @@ * @c U. */ template <typename U, typename OtherExecutor>- executor_binder(const executor_binder<U, OtherExecutor>& other,- constraint_t<is_constructible<Executor, OtherExecutor>::value> = 0,- constraint_t<is_constructible<T, U>::value> = 0)+ executor_binder(const executor_binder<U, OtherExecutor>& other) : base_type(other.get_executor(), other.get()) { }@@ -313,33 +328,32 @@ */ template <typename U, typename OtherExecutor> executor_binder(executor_arg_t, const executor_type& e,- const executor_binder<U, OtherExecutor>& other,- constraint_t<is_constructible<T, U>::value> = 0)+ const executor_binder<U, OtherExecutor>& other) : base_type(e, other.get()) { } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)+ /// Move constructor. executor_binder(executor_binder&& other)- : base_type(static_cast<executor_type&&>(other.get_executor()),- static_cast<T&&>(other.get()))+ : base_type(ASIO_MOVE_CAST(executor_type)(other.get_executor()),+ 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, static_cast<T&&>(other.get()))+ : base_type(e, 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,- constraint_t<is_constructible<Executor, OtherExecutor>::value> = 0,- constraint_t<is_constructible<T, U>::value> = 0)- : base_type(static_cast<OtherExecutor&&>(other.get_executor()),- static_cast<U&&>(other.get()))+ executor_binder(executor_binder<U, OtherExecutor>&& other)+ : base_type(ASIO_MOVE_CAST(OtherExecutor)(other.get_executor()),+ ASIO_MOVE_CAST(U)(other.get())) { } @@ -347,141 +361,152 @@ /// different executor. template <typename U, typename OtherExecutor> executor_binder(executor_arg_t, const executor_type& e,- executor_binder<U, OtherExecutor>&& other,- constraint_t<is_constructible<T, U>::value> = 0)- : base_type(e, static_cast<U&&>(other.get()))+ executor_binder<U, OtherExecutor>&& other)+ : base_type(e, ASIO_MOVE_CAST(U)(other.get())) { } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)+ /// Destructor. ~executor_binder() { } /// Obtain a reference to the target object.- target_type& get() noexcept+ target_type& get() ASIO_NOEXCEPT { return this->target_; } /// Obtain a reference to the target object.- const target_type& get() const noexcept+ const target_type& get() const ASIO_NOEXCEPT { return this->target_; } /// Obtain the associated executor.- executor_type get_executor() const noexcept+ executor_type get_executor() const ASIO_NOEXCEPT { return this->executor_; } +#if defined(GENERATING_DOCUMENTATION)++ template <typename... Args> auto operator()(Args&& ...);+ template <typename... Args> auto operator()(Args&& ...) const;++#elif defined(ASIO_HAS_VARIADIC_TEMPLATES)+ /// Forwarding function call operator. template <typename... Args>- result_of_t<T(Args...)> operator()(Args&&... args) &+ typename result_of<T(Args...)>::type operator()(+ ASIO_MOVE_ARG(Args)... args) {- return this->target_(static_cast<Args&&>(args)...);+ return this->target_(ASIO_MOVE_CAST(Args)(args)...); } /// Forwarding function call operator. template <typename... Args>- result_of_t<T(Args...)> operator()(Args&&... args) &&+ typename result_of<T(Args...)>::type operator()(+ ASIO_MOVE_ARG(Args)... args) const {- return static_cast<T&&>(this->target_)(static_cast<Args&&>(args)...);+ return this->target_(ASIO_MOVE_CAST(Args)(args)...); } - /// Forwarding function call operator.- template <typename... Args>- result_of_t<T(Args...)> operator()(Args&&... args) const&+#elif defined(ASIO_HAS_STD_TYPE_TRAITS) && !defined(_MSC_VER)++ typename detail::executor_binder_result_of0<T>::type operator()() {- return this->target_(static_cast<Args&&>(args)...);+ return this->target_(); } -private:- typedef detail::executor_binder_base<T, Executor,- uses_executor<T, Executor>::value> base_type;-};+ typename detail::executor_binder_result_of0<T>::type operator()() const+ {+ return this->target_();+ } -/// A function object type that adapts a @ref completion_token to specify that-/// the completion handler should have the supplied executor as its associated-/// executor.-/**- * May also be used directly as a completion token, in which case it adapts the- * asynchronous operation's default completion token (or asio::deferred- * if no default is available).- */-template <typename Executor>-struct partial_executor_binder-{- /// Constructor that specifies associated executor.- explicit partial_executor_binder(const Executor& ex)- : executor_(ex)+#define ASIO_PRIVATE_BIND_EXECUTOR_CALL_DEF(n) \+ template <ASIO_VARIADIC_TPARAMS(n)> \+ typename result_of<T(ASIO_VARIADIC_TARGS(n))>::type operator()( \+ ASIO_VARIADIC_MOVE_PARAMS(n)) \+ { \+ return this->target_(ASIO_VARIADIC_MOVE_ARGS(n)); \+ } \+ \+ template <ASIO_VARIADIC_TPARAMS(n)> \+ typename result_of<T(ASIO_VARIADIC_TARGS(n))>::type operator()( \+ ASIO_VARIADIC_MOVE_PARAMS(n)) const \+ { \+ return this->target_(ASIO_VARIADIC_MOVE_ARGS(n)); \+ } \+ /**/+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_BIND_EXECUTOR_CALL_DEF)+#undef ASIO_PRIVATE_BIND_EXECUTOR_CALL_DEF++#else // defined(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_(); } - /// Adapt a @ref completion_token to specify that the completion handler- /// should have the executor as its associated executor.- template <typename CompletionToken>- ASIO_NODISCARD inline- constexpr executor_binder<decay_t<CompletionToken>, Executor>- operator()(CompletionToken&& completion_token) const+ result_type_or_void operator()() const {- return executor_binder<decay_t<CompletionToken>, Executor>(executor_arg_t(),- static_cast<CompletionToken&&>(completion_token), executor_);+ return this->target_(); } -//private:- Executor executor_;-};+#define ASIO_PRIVATE_BIND_EXECUTOR_CALL_DEF(n) \+ template <ASIO_VARIADIC_TPARAMS(n)> \+ result_type_or_void operator()( \+ ASIO_VARIADIC_MOVE_PARAMS(n)) \+ { \+ return this->target_(ASIO_VARIADIC_MOVE_ARGS(n)); \+ } \+ \+ template <ASIO_VARIADIC_TPARAMS(n)> \+ result_type_or_void operator()( \+ ASIO_VARIADIC_MOVE_PARAMS(n)) const \+ { \+ return this->target_(ASIO_VARIADIC_MOVE_ARGS(n)); \+ } \+ /**/+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_BIND_EXECUTOR_CALL_DEF)+#undef ASIO_PRIVATE_BIND_EXECUTOR_CALL_DEF -/// Create a partial completion token that associates an executor.-template <typename Executor>-ASIO_NODISCARD inline partial_executor_binder<Executor>-bind_executor(const Executor& ex,- constraint_t<- is_executor<Executor>::value || execution::is_executor<Executor>::value- > = 0)-{- return partial_executor_binder<Executor>(ex);-}+#endif // defined(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>-ASIO_NODISCARD inline executor_binder<decay_t<T>, Executor>-bind_executor(const Executor& ex, T&& t,- constraint_t<+ASIO_NODISCARD inline executor_binder<typename decay<T>::type, Executor>+bind_executor(const Executor& ex, ASIO_MOVE_ARG(T) t,+ typename constraint< is_executor<Executor>::value || execution::is_executor<Executor>::value- > = 0)-{- return executor_binder<decay_t<T>, Executor>(- executor_arg_t(), ex, static_cast<T&&>(t));-}--/// Create a partial completion token that associates an execution context's-/// executor.-template <typename ExecutionContext>-ASIO_NODISCARD inline partial_executor_binder<- typename ExecutionContext::executor_type>-bind_executor(ExecutionContext& ctx,- constraint_t<- is_convertible<ExecutionContext&, execution_context&>::value- > = 0)+ >::type = 0) {- return partial_executor_binder<typename ExecutionContext::executor_type>(- ctx.get_executor());+ return executor_binder<typename decay<T>::type, Executor>(+ executor_arg_t(), ex, ASIO_MOVE_CAST(T)(t)); } /// Associate an object of type @c T with an execution context's executor. template <typename ExecutionContext, typename T>-ASIO_NODISCARD inline executor_binder<decay_t<T>,- typename ExecutionContext::executor_type>-bind_executor(ExecutionContext& ctx, T&& t,- constraint_t<- is_convertible<ExecutionContext&, execution_context&>::value- > = 0)+ASIO_NODISCARD inline executor_binder<typename decay<T>::type,+ typename ExecutionContext::executor_type>+bind_executor(ExecutionContext& ctx, ASIO_MOVE_ARG(T) t,+ typename constraint<is_convertible<+ ExecutionContext&, execution_context&>::value>::type = 0) {- return executor_binder<decay_t<T>, typename ExecutionContext::executor_type>(- executor_arg_t(), ctx.get_executor(), static_cast<T&&>(t));+ return executor_binder<typename decay<T>::type,+ typename ExecutionContext::executor_type>(+ executor_arg_t(), ctx.get_executor(), ASIO_MOVE_CAST(T)(t)); } #if !defined(GENERATING_DOCUMENTATION)@@ -504,12 +529,11 @@ template <typename TargetAsyncResult, typename Executor> class executor_binder_completion_handler_async_result<- TargetAsyncResult, Executor,- void_t<typename TargetAsyncResult::completion_handler_type >>+ TargetAsyncResult, Executor,+ typename void_type<+ typename TargetAsyncResult::completion_handler_type+ >::type> {-private:- TargetAsyncResult target_;- public: typedef executor_binder< typename TargetAsyncResult::completion_handler_type, Executor>@@ -521,10 +545,13 @@ { } - auto get() -> decltype(target_.get())+ typename TargetAsyncResult::return_type get() { return target_.get(); }++private:+ TargetAsyncResult target_; }; template <typename TargetAsyncResult, typename = void>@@ -533,8 +560,11 @@ }; template <typename TargetAsyncResult>-struct executor_binder_async_result_return_type<TargetAsyncResult,- void_t<typename TargetAsyncResult::return_type>>+struct executor_binder_async_result_return_type<+ TargetAsyncResult,+ typename void_type<+ typename TargetAsyncResult::return_type+ >::type> { typedef typename TargetAsyncResult::return_type return_type; };@@ -544,9 +574,9 @@ template <typename T, typename Executor, typename Signature> class async_result<executor_binder<T, Executor>, Signature> : public detail::executor_binder_completion_handler_async_result<- async_result<T, Signature>, Executor>,+ async_result<T, Signature>, Executor>, public detail::executor_binder_async_result_return_type<- async_result<T, Signature>>+ async_result<T, Signature> > { public: explicit async_result(executor_binder<T, Executor>& b)@@ -556,78 +586,154 @@ } template <typename Initiation>- struct init_wrapper : detail::initiation_base<Initiation>+ struct init_wrapper {- using detail::initiation_base<Initiation>::initiation_base;+ template <typename Init>+ init_wrapper(const Executor& ex, ASIO_MOVE_ARG(Init) init)+ : ex_(ex),+ initiation_(ASIO_MOVE_CAST(Init)(init))+ {+ } +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+ template <typename Handler, typename... Args>- void operator()(Handler&& handler, const Executor& e, Args&&... args) &&+ void operator()(+ ASIO_MOVE_ARG(Handler) handler,+ ASIO_MOVE_ARG(Args)... args) {- static_cast<Initiation&&>(*this)(- executor_binder<decay_t<Handler>, Executor>(- executor_arg_t(), e, static_cast<Handler&&>(handler)),- static_cast<Args&&>(args)...);+ ASIO_MOVE_CAST(Initiation)(initiation_)(+ executor_binder<typename decay<Handler>::type, Executor>(+ executor_arg_t(), ex_, ASIO_MOVE_CAST(Handler)(handler)),+ ASIO_MOVE_CAST(Args)(args)...); } template <typename Handler, typename... Args>- void operator()(Handler&& handler,- const Executor& e, Args&&... args) const &+ void operator()(+ ASIO_MOVE_ARG(Handler) handler,+ ASIO_MOVE_ARG(Args)... args) const {- static_cast<const Initiation&>(*this)(- executor_binder<decay_t<Handler>, Executor>(- executor_arg_t(), e, static_cast<Handler&&>(handler)),- static_cast<Args&&>(args)...);+ initiation_(+ executor_binder<typename decay<Handler>::type, Executor>(+ executor_arg_t(), ex_, ASIO_MOVE_CAST(Handler)(handler)),+ ASIO_MOVE_CAST(Args)(args)...); }++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++ template <typename Handler>+ void operator()(+ ASIO_MOVE_ARG(Handler) handler)+ {+ ASIO_MOVE_CAST(Initiation)(initiation_)(+ executor_binder<typename decay<Handler>::type, Executor>(+ executor_arg_t(), ex_, ASIO_MOVE_CAST(Handler)(handler)));+ }++ template <typename Handler>+ void operator()(+ ASIO_MOVE_ARG(Handler) handler) const+ {+ initiation_(+ executor_binder<typename decay<Handler>::type, Executor>(+ executor_arg_t(), ex_, ASIO_MOVE_CAST(Handler)(handler)));+ }++#define ASIO_PRIVATE_INIT_WRAPPER_DEF(n) \+ template <typename Handler, ASIO_VARIADIC_TPARAMS(n)> \+ void operator()( \+ ASIO_MOVE_ARG(Handler) handler, \+ ASIO_VARIADIC_MOVE_PARAMS(n)) \+ { \+ ASIO_MOVE_CAST(Initiation)(initiation_)( \+ executor_binder<typename decay<Handler>::type, Executor>( \+ executor_arg_t(), ex_, ASIO_MOVE_CAST(Handler)(handler)), \+ ASIO_VARIADIC_MOVE_ARGS(n)); \+ } \+ \+ template <typename Handler, ASIO_VARIADIC_TPARAMS(n)> \+ void operator()( \+ ASIO_MOVE_ARG(Handler) handler, \+ ASIO_VARIADIC_MOVE_PARAMS(n)) const \+ { \+ initiation_( \+ executor_binder<typename decay<Handler>::type, Executor>( \+ executor_arg_t(), ex_, ASIO_MOVE_CAST(Handler)(handler)), \+ ASIO_VARIADIC_MOVE_ARGS(n)); \+ } \+ /**/+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_INIT_WRAPPER_DEF)+#undef ASIO_PRIVATE_INIT_WRAPPER_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++ Executor ex_;+ Initiation initiation_; }; +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+ template <typename Initiation, typename RawCompletionToken, typename... Args>- static auto initiate(Initiation&& initiation,- RawCompletionToken&& token, Args&&... args)- -> decltype(- async_initiate<- conditional_t<- is_const<remove_reference_t<RawCompletionToken>>::value, const T, T>,- Signature>(- declval<init_wrapper<decay_t<Initiation>>>(),- token.get(), token.get_executor(), static_cast<Args&&>(args)...))+ static ASIO_INITFN_DEDUCED_RESULT_TYPE(T, Signature,+ (async_initiate<T, Signature>(+ declval<init_wrapper<typename decay<Initiation>::type> >(),+ declval<RawCompletionToken>().get(),+ declval<ASIO_MOVE_ARG(Args)>()...)))+ initiate(+ ASIO_MOVE_ARG(Initiation) initiation,+ ASIO_MOVE_ARG(RawCompletionToken) token,+ ASIO_MOVE_ARG(Args)... args) {- return async_initiate<- conditional_t<- is_const<remove_reference_t<RawCompletionToken>>::value, const T, T>,- Signature>(- init_wrapper<decay_t<Initiation>>(- static_cast<Initiation&&>(initiation)),- token.get(), token.get_executor(), static_cast<Args&&>(args)...);+ return async_initiate<T, Signature>(+ init_wrapper<typename decay<Initiation>::type>(+ token.get_executor(), ASIO_MOVE_CAST(Initiation)(initiation)),+ token.get(), ASIO_MOVE_CAST(Args)(args)...); } -private:- async_result(const async_result&) = delete;- async_result& operator=(const async_result&) = delete;-};+#else // defined(ASIO_HAS_VARIADIC_TEMPLATES) -template <typename Executor, typename... Signatures>-struct async_result<partial_executor_binder<Executor>, Signatures...>-{- template <typename Initiation, typename RawCompletionToken, typename... Args>- static auto initiate(Initiation&& initiation,- RawCompletionToken&& token, Args&&... args)- -> decltype(- async_initiate<Signatures...>(- static_cast<Initiation&&>(initiation),- executor_binder<- default_completion_token_t<associated_executor_t<Initiation>>,- Executor>(executor_arg_t(), token.executor_,- default_completion_token_t<associated_executor_t<Initiation>>{}),- static_cast<Args&&>(args)...))+ template <typename Initiation, typename RawCompletionToken>+ static ASIO_INITFN_DEDUCED_RESULT_TYPE(T, Signature,+ (async_initiate<T, Signature>(+ declval<init_wrapper<typename decay<Initiation>::type> >(),+ declval<RawCompletionToken>().get())))+ initiate(+ ASIO_MOVE_ARG(Initiation) initiation,+ ASIO_MOVE_ARG(RawCompletionToken) token) {- return async_initiate<Signatures...>(- static_cast<Initiation&&>(initiation),- executor_binder<- default_completion_token_t<associated_executor_t<Initiation>>,- Executor>(executor_arg_t(), token.executor_,- default_completion_token_t<associated_executor_t<Initiation>>{}),- static_cast<Args&&>(args)...);+ return async_initiate<T, Signature>(+ init_wrapper<typename decay<Initiation>::type>(+ token.get_executor(), ASIO_MOVE_CAST(Initiation)(initiation)),+ token.get()); }++#define ASIO_PRIVATE_INITIATE_DEF(n) \+ template <typename Initiation, typename RawCompletionToken, \+ ASIO_VARIADIC_TPARAMS(n)> \+ static ASIO_INITFN_DEDUCED_RESULT_TYPE(T, Signature, \+ (async_initiate<T, Signature>( \+ declval<init_wrapper<typename decay<Initiation>::type> >(), \+ declval<RawCompletionToken>().get(), \+ ASIO_VARIADIC_MOVE_DECLVAL(n)))) \+ initiate( \+ ASIO_MOVE_ARG(Initiation) initiation, \+ ASIO_MOVE_ARG(RawCompletionToken) token, \+ ASIO_VARIADIC_MOVE_PARAMS(n)) \+ { \+ return async_initiate<T, Signature>( \+ init_wrapper<typename decay<Initiation>::type>( \+ token.get_executor(), ASIO_MOVE_CAST(Initiation)(initiation)), \+ token.get(), ASIO_VARIADIC_MOVE_ARGS(n)); \+ } \+ /**/+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_INITIATE_DEF)+#undef ASIO_PRIVATE_INITIATE_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++private:+ async_result(const async_result&) ASIO_DELETED;+ async_result& operator=(const async_result&) ASIO_DELETED; }; template <template <typename, typename> class Associator,@@ -635,15 +741,18 @@ struct associator<Associator, executor_binder<T, Executor>, DefaultCandidate> : Associator<T, DefaultCandidate> {- static typename Associator<T, DefaultCandidate>::type get(- const executor_binder<T, Executor>& b) noexcept+ static typename Associator<T, DefaultCandidate>::type+ get(const executor_binder<T, Executor>& b) ASIO_NOEXCEPT { return Associator<T, DefaultCandidate>::get(b.get()); } - static auto get(const executor_binder<T, Executor>& b,- const DefaultCandidate& c) noexcept- -> decltype(Associator<T, DefaultCandidate>::get(b.get(), c))+ static ASIO_AUTO_RETURN_TYPE_PREFIX2(+ typename Associator<T, DefaultCandidate>::type)+ get(const executor_binder<T, Executor>& b,+ const DefaultCandidate& c) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ Associator<T, DefaultCandidate>::get(b.get(), c))) { return Associator<T, DefaultCandidate>::get(b.get(), c); }@@ -654,9 +763,10 @@ { typedef Executor type; - static auto get(const executor_binder<T, Executor>& b,- const Executor1& = Executor1()) noexcept- -> decltype(b.get_executor())+ static ASIO_AUTO_RETURN_TYPE_PREFIX(type) get(+ const executor_binder<T, Executor>& b,+ const Executor1& = Executor1()) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((b.get_executor())) { return b.get_executor(); }
link/modules/asio-standalone/asio/include/asio/bind_immediate_executor.hpp view
@@ -1,8 +1,8 @@ // // bind_immediate_executor.hpp-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~+// ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -16,12 +16,11 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"-#include "asio/associated_executor.hpp"+#include "asio/detail/type_traits.hpp"+#include "asio/detail/variadic_templates.hpp" #include "asio/associated_immediate_executor.hpp" #include "asio/associator.hpp" #include "asio/async_result.hpp"-#include "asio/detail/initiation_base.hpp"-#include "asio/detail/type_traits.hpp" #include "asio/detail/push_options.hpp" @@ -38,7 +37,8 @@ }; template <typename T>-struct immediate_executor_binder_result_type<T, void_t<typename T::result_type>>+struct immediate_executor_binder_result_type<T,+ typename void_type<typename T::result_type>::type> { typedef typename T::result_type result_type; protected:@@ -100,7 +100,7 @@ template <typename T> struct immediate_executor_binder_argument_type<T,- void_t<typename T::argument_type>>+ typename void_type<typename T::argument_type>::type> { typedef typename T::argument_type argument_type; };@@ -125,7 +125,7 @@ template <typename T> struct immediate_executor_binder_argument_types<T,- void_t<typename T::first_argument_type>>+ typename void_type<typename T::first_argument_type>::type> { typedef typename T::first_argument_type first_argument_type; typedef typename T::second_argument_type second_argument_type;@@ -145,6 +145,21 @@ typedef A2 second_argument_type; }; +// Helper to enable SFINAE on zero-argument operator() below.++template <typename T, typename = void>+struct immediate_executor_binder_result_of0+{+ typedef void type;+};++template <typename T>+struct immediate_executor_binder_result_of0<T,+ typename void_type<typename result_of<T()>::type>::type>+{+ typedef typename result_of<T()>::type type;+};+ } // namespace detail /// A call wrapper type to bind a immediate executor of type @c Executor@@ -233,9 +248,9 @@ */ template <typename U> immediate_executor_binder(const immediate_executor_type& e,- U&& u)+ ASIO_MOVE_ARG(U) u) : executor_(e),- target_(static_cast<U&&>(u))+ target_(ASIO_MOVE_CAST(U)(u)) { } @@ -262,9 +277,7 @@ */ template <typename U, typename OtherExecutor> immediate_executor_binder(- const immediate_executor_binder<U, OtherExecutor>& other,- constraint_t<is_constructible<Executor, OtherExecutor>::value> = 0,- constraint_t<is_constructible<T, U>::value> = 0)+ const immediate_executor_binder<U, OtherExecutor>& other) : executor_(other.get_immediate_executor()), target_(other.get()) {@@ -278,18 +291,19 @@ */ template <typename U, typename OtherExecutor> immediate_executor_binder(const immediate_executor_type& e,- const immediate_executor_binder<U, OtherExecutor>& other,- constraint_t<is_constructible<T, U>::value> = 0)+ const immediate_executor_binder<U, OtherExecutor>& other) : executor_(e), target_(other.get()) { } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)+ /// Move constructor. immediate_executor_binder(immediate_executor_binder&& other)- : executor_(static_cast<immediate_executor_type&&>(+ : executor_(ASIO_MOVE_CAST(immediate_executor_type)( other.get_immediate_executor())),- target_(static_cast<T&&>(other.get()))+ target_(ASIO_MOVE_CAST(T)(other.get())) { } @@ -298,19 +312,17 @@ immediate_executor_binder(const immediate_executor_type& e, immediate_executor_binder&& other) : executor_(e),- target_(static_cast<T&&>(other.get()))+ target_(ASIO_MOVE_CAST(T)(other.get())) { } /// Move construct from a different immediate executor wrapper type. template <typename U, typename OtherExecutor> immediate_executor_binder(- immediate_executor_binder<U, OtherExecutor>&& other,- constraint_t<is_constructible<Executor, OtherExecutor>::value> = 0,- constraint_t<is_constructible<T, U>::value> = 0)- : executor_(static_cast<OtherExecutor&&>(+ immediate_executor_binder<U, OtherExecutor>&& other)+ : executor_(ASIO_MOVE_CAST(OtherExecutor)( other.get_immediate_executor())),- target_(static_cast<U&&>(other.get()))+ target_(ASIO_MOVE_CAST(U)(other.get())) { } @@ -318,152 +330,163 @@ /// specify a different immediate executor. template <typename U, typename OtherExecutor> immediate_executor_binder(const immediate_executor_type& e,- immediate_executor_binder<U, OtherExecutor>&& other,- constraint_t<is_constructible<T, U>::value> = 0)+ immediate_executor_binder<U, OtherExecutor>&& other) : executor_(e),- target_(static_cast<U&&>(other.get()))+ target_(ASIO_MOVE_CAST(U)(other.get())) { } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)+ /// Destructor. ~immediate_executor_binder() { } /// Obtain a reference to the target object.- target_type& get() noexcept+ target_type& get() ASIO_NOEXCEPT { return target_; } /// Obtain a reference to the target object.- const target_type& get() const noexcept+ const target_type& get() const ASIO_NOEXCEPT { return target_; } /// Obtain the associated immediate executor.- immediate_executor_type get_immediate_executor() const noexcept+ immediate_executor_type get_immediate_executor() const ASIO_NOEXCEPT { return executor_; } +#if defined(GENERATING_DOCUMENTATION)++ template <typename... Args> auto operator()(Args&& ...);+ template <typename... Args> auto operator()(Args&& ...) const;++#elif defined(ASIO_HAS_VARIADIC_TEMPLATES)+ /// Forwarding function call operator. template <typename... Args>- result_of_t<T(Args...)> operator()(Args&&... args) &+ typename result_of<T(Args...)>::type operator()(+ ASIO_MOVE_ARG(Args)... args) {- return target_(static_cast<Args&&>(args)...);+ return target_(ASIO_MOVE_CAST(Args)(args)...); } /// Forwarding function call operator. template <typename... Args>- result_of_t<T(Args...)> operator()(Args&&... args) &&+ typename result_of<T(Args...)>::type operator()(+ ASIO_MOVE_ARG(Args)... args) const {- return static_cast<T&&>(target_)(static_cast<Args&&>(args)...);+ return target_(ASIO_MOVE_CAST(Args)(args)...); } - /// Forwarding function call operator.- template <typename... Args>- result_of_t<T(Args...)> operator()(Args&&... args) const&+#elif defined(ASIO_HAS_STD_TYPE_TRAITS) && !defined(_MSC_VER)++ typename detail::immediate_executor_binder_result_of0<T>::type operator()() {- return target_(static_cast<Args&&>(args)...);+ return target_(); } -private:- Executor executor_;- T target_;-};+ typename detail::immediate_executor_binder_result_of0<T>::type+ operator()() const+ {+ return target_();+ } -/// A function object type that adapts a @ref completion_token to specify that-/// the completion handler should have the supplied executor as its associated-/// immediate executor.-/**- * May also be used directly as a completion token, in which case it adapts the- * asynchronous operation's default completion token (or asio::deferred- * if no default is available).- */-template <typename Executor>-struct partial_immediate_executor_binder-{- /// Constructor that specifies associated executor.- explicit partial_immediate_executor_binder(const Executor& ex)- : executor_(ex)+#define ASIO_PRIVATE_BINDER_CALL_DEF(n) \+ template <ASIO_VARIADIC_TPARAMS(n)> \+ typename result_of<T(ASIO_VARIADIC_TARGS(n))>::type operator()( \+ ASIO_VARIADIC_MOVE_PARAMS(n)) \+ { \+ return target_(ASIO_VARIADIC_MOVE_ARGS(n)); \+ } \+ \+ template <ASIO_VARIADIC_TPARAMS(n)> \+ typename result_of<T(ASIO_VARIADIC_TARGS(n))>::type operator()( \+ ASIO_VARIADIC_MOVE_PARAMS(n)) const \+ { \+ return target_(ASIO_VARIADIC_MOVE_ARGS(n)); \+ } \+ /**/+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_BINDER_CALL_DEF)+#undef ASIO_PRIVATE_BINDER_CALL_DEF++#else // defined(ASIO_HAS_STD_TYPE_TRAITS) && !defined(_MSC_VER)++ typedef typename detail::immediate_executor_binder_result_type<+ T>::result_type_or_void result_type_or_void;++ result_type_or_void operator()() {+ return target_(); } - /// Adapt a @ref completion_token to specify that the completion handler- /// should have the executor as its associated immediate executor.- template <typename CompletionToken>- ASIO_NODISCARD inline- constexpr immediate_executor_binder<decay_t<CompletionToken>, Executor>- operator()(CompletionToken&& completion_token) const+ result_type_or_void operator()() const {- return immediate_executor_binder<decay_t<CompletionToken>, Executor>(- static_cast<CompletionToken&&>(completion_token), executor_);+ return target_(); } -//private:+#define ASIO_PRIVATE_BINDER_CALL_DEF(n) \+ template <ASIO_VARIADIC_TPARAMS(n)> \+ result_type_or_void operator()( \+ ASIO_VARIADIC_MOVE_PARAMS(n)) \+ { \+ return target_(ASIO_VARIADIC_MOVE_ARGS(n)); \+ } \+ \+ template <ASIO_VARIADIC_TPARAMS(n)> \+ result_type_or_void operator()( \+ ASIO_VARIADIC_MOVE_PARAMS(n)) const \+ { \+ return target_(ASIO_VARIADIC_MOVE_ARGS(n)); \+ } \+ /**/+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_BINDER_CALL_DEF)+#undef ASIO_PRIVATE_BINDER_CALL_DEF++#endif // defined(ASIO_HAS_STD_TYPE_TRAITS) && !defined(_MSC_VER)++private: Executor executor_;+ T target_; }; -/// Create a partial completion token that associates an executor.-template <typename Executor>-ASIO_NODISCARD inline partial_immediate_executor_binder<Executor>-bind_immediate_executor(const Executor& ex)-{- return partial_immediate_executor_binder<Executor>(ex);-}- /// Associate an object of type @c T with a immediate executor of type /// @c Executor. template <typename Executor, typename T>-ASIO_NODISCARD inline immediate_executor_binder<decay_t<T>, Executor>-bind_immediate_executor(const Executor& e, T&& t)+ASIO_NODISCARD inline+immediate_executor_binder<typename decay<T>::type, Executor>+bind_immediate_executor(const Executor& e, ASIO_MOVE_ARG(T) t) { return immediate_executor_binder<- decay_t<T>, Executor>(- e, static_cast<T&&>(t));+ typename decay<T>::type, Executor>(+ e, ASIO_MOVE_CAST(T)(t)); } #if !defined(GENERATING_DOCUMENTATION) namespace detail { -template <typename TargetAsyncResult, typename Executor, typename = void>-class immediate_executor_binder_completion_handler_async_result+template <typename TargetAsyncResult,+ typename Executor, typename = void>+struct immediate_executor_binder_async_result_completion_handler_type {-public:- template <typename T>- explicit immediate_executor_binder_completion_handler_async_result(T&)- {- } }; template <typename TargetAsyncResult, typename Executor>-class immediate_executor_binder_completion_handler_async_result<+struct immediate_executor_binder_async_result_completion_handler_type< TargetAsyncResult, Executor,- void_t<+ typename void_type< typename TargetAsyncResult::completion_handler_type- >>+ >::type> {-private:- TargetAsyncResult target_;--public: typedef immediate_executor_binder< typename TargetAsyncResult::completion_handler_type, Executor> completion_handler_type;-- explicit immediate_executor_binder_completion_handler_async_result(- typename TargetAsyncResult::completion_handler_type& handler)- : target_(handler)- {- }-- auto get() -> decltype(target_.get())- {- return target_.get();- } }; template <typename TargetAsyncResult, typename = void>@@ -474,9 +497,9 @@ template <typename TargetAsyncResult> struct immediate_executor_binder_async_result_return_type< TargetAsyncResult,- void_t<+ typename void_type< typename TargetAsyncResult::return_type- >>+ >::type> { typedef typename TargetAsyncResult::return_type return_type; };@@ -485,97 +508,182 @@ template <typename T, typename Executor, typename Signature> class async_result<immediate_executor_binder<T, Executor>, Signature> :- public detail::immediate_executor_binder_completion_handler_async_result<+ public detail::immediate_executor_binder_async_result_completion_handler_type< async_result<T, Signature>, Executor>, public detail::immediate_executor_binder_async_result_return_type<- async_result<T, Signature>>+ async_result<T, Signature> > { public: explicit async_result(immediate_executor_binder<T, Executor>& b)- : detail::immediate_executor_binder_completion_handler_async_result<- async_result<T, Signature>, Executor>(b.get())+ : target_(b.get()) { } + typename async_result<T, Signature>::return_type get()+ {+ return target_.get();+ }+ template <typename Initiation>- struct init_wrapper : detail::initiation_base<Initiation>+ struct init_wrapper {- using detail::initiation_base<Initiation>::initiation_base;+ template <typename Init>+ init_wrapper(const Executor& e, ASIO_MOVE_ARG(Init) init)+ : executor_(e),+ initiation_(ASIO_MOVE_CAST(Init)(init))+ {+ } +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+ template <typename Handler, typename... Args>- void operator()(Handler&& handler, const Executor& e, Args&&... args) &&+ void operator()(+ ASIO_MOVE_ARG(Handler) handler,+ ASIO_MOVE_ARG(Args)... args) {- static_cast<Initiation&&>(*this)(+ ASIO_MOVE_CAST(Initiation)(initiation_)( immediate_executor_binder<- decay_t<Handler>, Executor>(- e, static_cast<Handler&&>(handler)),- static_cast<Args&&>(args)...);+ typename decay<Handler>::type, Executor>(+ executor_, ASIO_MOVE_CAST(Handler)(handler)),+ ASIO_MOVE_CAST(Args)(args)...); } template <typename Handler, typename... Args>- void operator()(Handler&& handler,- const Executor& e, Args&&... args) const &+ void operator()(+ ASIO_MOVE_ARG(Handler) handler,+ ASIO_MOVE_ARG(Args)... args) const {- static_cast<const Initiation&>(*this)(+ initiation_( immediate_executor_binder<- decay_t<Handler>, Executor>(- e, static_cast<Handler&&>(handler)),- static_cast<Args&&>(args)...);+ typename decay<Handler>::type, Executor>(+ executor_, ASIO_MOVE_CAST(Handler)(handler)),+ ASIO_MOVE_CAST(Args)(args)...); }++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++ template <typename Handler>+ void operator()(+ ASIO_MOVE_ARG(Handler) handler)+ {+ ASIO_MOVE_CAST(Initiation)(initiation_)(+ immediate_executor_binder<+ typename decay<Handler>::type, Executor>(+ executor_, ASIO_MOVE_CAST(Handler)(handler)));+ }++ template <typename Handler>+ void operator()(+ ASIO_MOVE_ARG(Handler) handler) const+ {+ initiation_(+ immediate_executor_binder<+ typename decay<Handler>::type, Executor>(+ executor_, ASIO_MOVE_CAST(Handler)(handler)));+ }++#define ASIO_PRIVATE_INIT_WRAPPER_DEF(n) \+ template <typename Handler, ASIO_VARIADIC_TPARAMS(n)> \+ void operator()( \+ ASIO_MOVE_ARG(Handler) handler, \+ ASIO_VARIADIC_MOVE_PARAMS(n)) \+ { \+ ASIO_MOVE_CAST(Initiation)(initiation_)( \+ immediate_executor_binder< \+ typename decay<Handler>::type, Executor>( \+ executor_, ASIO_MOVE_CAST(Handler)(handler)), \+ ASIO_VARIADIC_MOVE_ARGS(n)); \+ } \+ \+ template <typename Handler, ASIO_VARIADIC_TPARAMS(n)> \+ void operator()( \+ ASIO_MOVE_ARG(Handler) handler, \+ ASIO_VARIADIC_MOVE_PARAMS(n)) const \+ { \+ initiation_( \+ immediate_executor_binder< \+ typename decay<Handler>::type, Executor>( \+ executor_, ASIO_MOVE_CAST(Handler)(handler)), \+ ASIO_VARIADIC_MOVE_ARGS(n)); \+ } \+ /**/+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_INIT_WRAPPER_DEF)+#undef ASIO_PRIVATE_INIT_WRAPPER_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++ Executor executor_;+ Initiation initiation_; }; +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+ template <typename Initiation, typename RawCompletionToken, typename... Args>- static auto initiate(Initiation&& initiation,- RawCompletionToken&& token, Args&&... args)- -> decltype(- async_initiate<- conditional_t<- is_const<remove_reference_t<RawCompletionToken>>::value, const T, T>,- Signature>(- declval<init_wrapper<decay_t<Initiation>>>(),- token.get(), token.get_immediate_executor(),- static_cast<Args&&>(args)...))+ static ASIO_INITFN_DEDUCED_RESULT_TYPE(T, Signature,+ (async_initiate<T, Signature>(+ declval<init_wrapper<typename decay<Initiation>::type> >(),+ declval<RawCompletionToken>().get(),+ declval<ASIO_MOVE_ARG(Args)>()...)))+ initiate(+ ASIO_MOVE_ARG(Initiation) initiation,+ ASIO_MOVE_ARG(RawCompletionToken) token,+ ASIO_MOVE_ARG(Args)... args) {- return async_initiate<- conditional_t<- is_const<remove_reference_t<RawCompletionToken>>::value, const T, T>,- Signature>(- init_wrapper<decay_t<Initiation>>(- static_cast<Initiation&&>(initiation)),- token.get(), token.get_immediate_executor(),- static_cast<Args&&>(args)...);+ return async_initiate<T, Signature>(+ init_wrapper<typename decay<Initiation>::type>(+ token.get_immediate_executor(),+ ASIO_MOVE_CAST(Initiation)(initiation)),+ token.get(), ASIO_MOVE_CAST(Args)(args)...); } -private:- async_result(const async_result&) = delete;- async_result& operator=(const async_result&) = delete;-- async_result<T, Signature> target_;-};+#else // defined(ASIO_HAS_VARIADIC_TEMPLATES) -template <typename Executor, typename... Signatures>-struct async_result<partial_immediate_executor_binder<Executor>, Signatures...>-{- template <typename Initiation, typename RawCompletionToken, typename... Args>- static auto initiate(Initiation&& initiation,- RawCompletionToken&& token, Args&&... args)- -> decltype(- async_initiate<Signatures...>(- static_cast<Initiation&&>(initiation),- immediate_executor_binder<- default_completion_token_t<associated_executor_t<Initiation>>,- Executor>(token.executor_,- default_completion_token_t<associated_executor_t<Initiation>>{}),- static_cast<Args&&>(args)...))+ template <typename Initiation, typename RawCompletionToken>+ static ASIO_INITFN_DEDUCED_RESULT_TYPE(T, Signature,+ (async_initiate<T, Signature>(+ declval<init_wrapper<typename decay<Initiation>::type> >(),+ declval<RawCompletionToken>().get())))+ initiate(+ ASIO_MOVE_ARG(Initiation) initiation,+ ASIO_MOVE_ARG(RawCompletionToken) token) {- return async_initiate<Signatures...>(- static_cast<Initiation&&>(initiation),- immediate_executor_binder<- default_completion_token_t<associated_executor_t<Initiation>>,- Executor>(token.executor_,- default_completion_token_t<associated_executor_t<Initiation>>{}),- static_cast<Args&&>(args)...);+ return async_initiate<T, Signature>(+ init_wrapper<typename decay<Initiation>::type>(+ token.get_immediate_executor(),+ ASIO_MOVE_CAST(Initiation)(initiation)),+ token.get()); }++#define ASIO_PRIVATE_INITIATE_DEF(n) \+ template <typename Initiation, typename RawCompletionToken, \+ ASIO_VARIADIC_TPARAMS(n)> \+ static ASIO_INITFN_DEDUCED_RESULT_TYPE(T, Signature, \+ (async_initiate<T, Signature>( \+ declval<init_wrapper<typename decay<Initiation>::type> >(), \+ declval<RawCompletionToken>().get(), \+ ASIO_VARIADIC_MOVE_DECLVAL(n)))) \+ initiate( \+ ASIO_MOVE_ARG(Initiation) initiation, \+ ASIO_MOVE_ARG(RawCompletionToken) token, \+ ASIO_VARIADIC_MOVE_PARAMS(n)) \+ { \+ return async_initiate<T, Signature>( \+ init_wrapper<typename decay<Initiation>::type>( \+ token.get_immediate_executor(), \+ ASIO_MOVE_CAST(Initiation)(initiation)), \+ token.get(), ASIO_VARIADIC_MOVE_ARGS(n)); \+ } \+ /**/+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_INITIATE_DEF)+#undef ASIO_PRIVATE_INITIATE_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++private:+ async_result(const async_result&) ASIO_DELETED;+ async_result& operator=(const async_result&) ASIO_DELETED;++ async_result<T, Signature> target_; }; template <template <typename, typename> class Associator,@@ -585,15 +693,19 @@ DefaultCandidate> : Associator<T, DefaultCandidate> {- static typename Associator<T, DefaultCandidate>::type get(- const immediate_executor_binder<T, Executor>& b) noexcept+ static typename Associator<T, DefaultCandidate>::type+ get(const immediate_executor_binder<T, Executor>& b)+ ASIO_NOEXCEPT { return Associator<T, DefaultCandidate>::get(b.get()); } - static auto get(const immediate_executor_binder<T, Executor>& b,- const DefaultCandidate& c) noexcept- -> decltype(Associator<T, DefaultCandidate>::get(b.get(), c))+ static ASIO_AUTO_RETURN_TYPE_PREFIX2(+ typename Associator<T, DefaultCandidate>::type)+ get(const immediate_executor_binder<T, Executor>& b,+ const DefaultCandidate& c) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ Associator<T, DefaultCandidate>::get(b.get(), c))) { return Associator<T, DefaultCandidate>::get(b.get(), c); }@@ -606,9 +718,10 @@ { typedef Executor type; - static auto get(const immediate_executor_binder<T, Executor>& b,- const Executor1& = Executor1()) noexcept- -> decltype(b.get_immediate_executor())+ static ASIO_AUTO_RETURN_TYPE_PREFIX(type) get(+ const immediate_executor_binder<T, Executor>& b,+ const Executor1& = Executor1()) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((b.get_immediate_executor())) { return b.get_immediate_executor(); }
link/modules/asio-standalone/asio/include/asio/buffer.hpp view
@@ -2,2878 +2,2906 @@ // buffer.hpp // ~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef ASIO_BUFFER_HPP-#define ASIO_BUFFER_HPP--#if defined(_MSC_VER) && (_MSC_VER >= 1200)-# pragma once-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)--#include "asio/detail/config.hpp"-#include <cstddef>-#include <cstring>-#include <limits>-#include <stdexcept>-#include <string>-#include <vector>-#include "asio/detail/array_fwd.hpp"-#include "asio/detail/memory.hpp"-#include "asio/detail/string_view.hpp"-#include "asio/detail/throw_exception.hpp"-#include "asio/detail/type_traits.hpp"-#include "asio/is_contiguous_iterator.hpp"--#if defined(ASIO_MSVC) && (ASIO_MSVC >= 1700)-# if defined(_HAS_ITERATOR_DEBUGGING) && (_HAS_ITERATOR_DEBUGGING != 0)-# if !defined(ASIO_DISABLE_BUFFER_DEBUGGING)-# define ASIO_ENABLE_BUFFER_DEBUGGING-# endif // !defined(ASIO_DISABLE_BUFFER_DEBUGGING)-# endif // defined(_HAS_ITERATOR_DEBUGGING)-#endif // defined(ASIO_MSVC) && (ASIO_MSVC >= 1700)--#if defined(__GNUC__)-# if defined(_GLIBCXX_DEBUG)-# if !defined(ASIO_DISABLE_BUFFER_DEBUGGING)-# define ASIO_ENABLE_BUFFER_DEBUGGING-# endif // !defined(ASIO_DISABLE_BUFFER_DEBUGGING)-# endif // defined(_GLIBCXX_DEBUG)-#endif // defined(__GNUC__)--#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)-# include "asio/detail/functional.hpp"-#endif // ASIO_ENABLE_BUFFER_DEBUGGING--#include "asio/detail/push_options.hpp"--namespace asio {-namespace detail {--#if defined(ASIO_MSVC)--struct span_memfns_base-{- void subspan();-};--template <typename T>-struct span_memfns_derived : T, span_memfns_base-{-};--template <typename T, T>-struct span_memfns_check-{-};--template <typename>-char (&subspan_memfn_helper(...))[2];--template <typename T>-char subspan_memfn_helper(- span_memfns_check<- void (span_memfns_base::*)(),- &span_memfns_derived<T>::subspan>*);--template <typename T>-struct has_subspan_memfn :- integral_constant<bool, sizeof(subspan_memfn_helper<T>(0)) != 1>-{-};--#endif // defined(ASIO_MSVC)--} // namespace detail--class mutable_buffer;-class const_buffer;--/// Holds a buffer that can be modified.-/**- * The mutable_buffer class provides a safe representation of a buffer that can- * be modified. It does not own the underlying data, and so is cheap to copy or- * assign.- *- * @par Accessing Buffer Contents- *- * The contents of a buffer may be accessed using the @c data() and @c size()- * member functions:- *- * @code asio::mutable_buffer b1 = ...;- * std::size_t s1 = b1.size();- * unsigned char* p1 = static_cast<unsigned char*>(b1.data());- * @endcode- *- * 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() noexcept- : data_(0),- size_(0)- {- }-- /// Construct a buffer to represent a given memory range.- mutable_buffer(void* data, std::size_t size) noexcept- : data_(data),- size_(size)- {- }-- /// Construct a buffer from a span of bytes.- template <template <typename, std::size_t> class Span,- typename T, std::size_t Extent>- mutable_buffer(const Span<T, Extent>& span,- constraint_t<- !is_const<T>::value,- defaulted_constraint- > = defaulted_constraint(),- constraint_t<- sizeof(T) == 1,- defaulted_constraint- > = defaulted_constraint(),- constraint_t<-#if defined(ASIO_MSVC)- detail::has_subspan_memfn<Span<T, Extent>>::value,-#else // defined(ASIO_MSVC)- is_same<- decltype(span.subspan(0, 0)),- Span<T, static_cast<std::size_t>(-1)>- >::value,-#endif // defined(ASIO_MSVC)- defaulted_constraint- > = defaulted_constraint())- : data_(span.data()),- size_(span.size())- {- }--#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)- mutable_buffer(void* data, std::size_t size,- asio::detail::function<void()> debug_check)- : data_(data),- size_(size),- debug_check_(debug_check)- {- }-- const asio::detail::function<void()>& get_debug_check() const- {- return debug_check_;- }-#endif // ASIO_ENABLE_BUFFER_DEBUGGING-- /// Get a pointer to the beginning of the memory range.- void* data() const noexcept- {-#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)- if (size_ && debug_check_)- debug_check_();-#endif // ASIO_ENABLE_BUFFER_DEBUGGING- return data_;- }-- /// Get the size of the memory range.- std::size_t size() const noexcept- {- return size_;- }-- /// Move the start of the buffer by the specified number of bytes.- mutable_buffer& operator+=(std::size_t n) 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_;--#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)- asio::detail::function<void()> debug_check_;-#endif // ASIO_ENABLE_BUFFER_DEBUGGING-};--/// Holds a buffer that cannot be modified.-/**- * The const_buffer class provides a safe representation of a buffer that cannot- * be modified. It does not own the underlying data, and so is cheap to copy or- * assign.- *- * @par Accessing Buffer Contents- *- * The contents of a buffer may be accessed using the @c data() and @c size()- * member functions:- *- * @code asio::const_buffer b1 = ...;- * std::size_t s1 = b1.size();- * const unsigned char* p1 = static_cast<const unsigned char*>(b1.data());- * @endcode- *- * 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() noexcept- : data_(0),- size_(0)- {- }-- /// Construct a buffer to represent a given memory range.- const_buffer(const void* data, std::size_t size) noexcept- : data_(data),- size_(size)- {- }-- /// Construct a non-modifiable buffer from a modifiable one.- const_buffer(const mutable_buffer& b) noexcept- : data_(b.data()),- size_(b.size())-#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)- , debug_check_(b.get_debug_check())-#endif // ASIO_ENABLE_BUFFER_DEBUGGING- {- }-- /// Construct a buffer from a span of bytes.- template <template <typename, std::size_t> class Span,- typename T, std::size_t Extent>- const_buffer(const Span<T, Extent>& span,- constraint_t<- sizeof(T) == 1,- defaulted_constraint- > = defaulted_constraint(),- constraint_t<-#if defined(ASIO_MSVC)- detail::has_subspan_memfn<Span<T, Extent>>::value,-#else // defined(ASIO_MSVC)- is_same<- decltype(span.subspan(0, 0)),- Span<T, static_cast<std::size_t>(-1)>- >::value,-#endif // defined(ASIO_MSVC)- defaulted_constraint- > = defaulted_constraint())- : data_(span.data()),- size_(span.size())- {- }--#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)- const_buffer(const void* data, std::size_t size,- asio::detail::function<void()> debug_check)- : data_(data),- size_(size),- debug_check_(debug_check)- {- }-- const asio::detail::function<void()>& get_debug_check() const- {- return debug_check_;- }-#endif // ASIO_ENABLE_BUFFER_DEBUGGING-- /// Get a pointer to the beginning of the memory range.- const void* data() const noexcept- {-#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)- if (size_ && debug_check_)- debug_check_();-#endif // ASIO_ENABLE_BUFFER_DEBUGGING- return data_;- }-- /// Get the size of the memory range.- std::size_t size() const noexcept- {- return size_;- }-- /// Move the start of the buffer by the specified number of bytes.- const_buffer& operator+=(std::size_t n) 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_;--#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)- asio::detail::function<void()> debug_check_;-#endif // ASIO_ENABLE_BUFFER_DEBUGGING-};--/// (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:- /// The type for each element in the list of buffers.- typedef mutable_buffer value_type;-- /// A random-access iterator type that may be used to read elements.- typedef const mutable_buffer* const_iterator;-- /// Get a random-access iterator to the first element.- const_iterator begin() const noexcept- {- return &buf_;- }-- /// Get a random-access iterator for one past the last element.- const_iterator end() const noexcept- {- return &buf_;- }--private:- mutable_buffer buf_;-};--/** @defgroup buffer_sequence_begin asio::buffer_sequence_begin- *- * @brief The asio::buffer_sequence_begin function returns an iterator- * pointing to the first element in a buffer sequence.- */-/*@{*/--/// Get an iterator to the first element in a buffer sequence.-template <typename MutableBuffer>-inline const mutable_buffer* buffer_sequence_begin(const MutableBuffer& b,- constraint_t<- is_convertible<const MutableBuffer*, const mutable_buffer*>::value- > = 0) noexcept-{- return static_cast<const mutable_buffer*>(detail::addressof(b));-}--/// Get an iterator to the first element in a buffer sequence.-template <typename ConstBuffer>-inline const const_buffer* buffer_sequence_begin(const ConstBuffer& b,- constraint_t<- is_convertible<const ConstBuffer*, const const_buffer*>::value- > = 0) noexcept-{- return static_cast<const const_buffer*>(detail::addressof(b));-}--/// Get an iterator to the first element in a buffer sequence.-template <typename ConvertibleToBuffer>-inline const ConvertibleToBuffer* buffer_sequence_begin(- const ConvertibleToBuffer& b,- constraint_t<- !is_convertible<const ConvertibleToBuffer*, const mutable_buffer*>::value- > = 0,- constraint_t<- !is_convertible<const ConvertibleToBuffer*, const const_buffer*>::value- > = 0,- constraint_t<- is_convertible<ConvertibleToBuffer, mutable_buffer>::value- || is_convertible<ConvertibleToBuffer, const_buffer>::value- > = 0) noexcept-{- return detail::addressof(b);-}--/// Get an iterator to the first element in a buffer sequence.-template <typename C>-inline auto buffer_sequence_begin(C& c,- constraint_t<- !is_convertible<const C*, const mutable_buffer*>::value- > = 0,- constraint_t<- !is_convertible<const C*, const const_buffer*>::value- > = 0,- constraint_t<- !is_convertible<C, mutable_buffer>::value- > = 0,- constraint_t<- !is_convertible<C, const_buffer>::value- > = 0) noexcept -> decltype(c.begin())-{- return c.begin();-}--/// Get an iterator to the first element in a buffer sequence.-template <typename C>-inline auto buffer_sequence_begin(const C& c,- constraint_t<- !is_convertible<const C*, const mutable_buffer*>::value- > = 0,- constraint_t<- !is_convertible<const C*, const const_buffer*>::value- > = 0,- constraint_t<- !is_convertible<C, mutable_buffer>::value- > = 0,- constraint_t<- !is_convertible<C, const_buffer>::value- > = 0) noexcept -> decltype(c.begin())-{- return c.begin();-}--/*@}*/--/** @defgroup buffer_sequence_end asio::buffer_sequence_end- *- * @brief The 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.-template <typename MutableBuffer>-inline const mutable_buffer* buffer_sequence_end(const MutableBuffer& b,- constraint_t<- is_convertible<const MutableBuffer*, const mutable_buffer*>::value- > = 0) noexcept-{- return static_cast<const mutable_buffer*>(detail::addressof(b)) + 1;-}--/// Get an iterator to one past the end element in a buffer sequence.-template <typename ConstBuffer>-inline const const_buffer* buffer_sequence_end(const ConstBuffer& b,- constraint_t<- is_convertible<const ConstBuffer*, const const_buffer*>::value- > = 0) noexcept-{- return static_cast<const const_buffer*>(detail::addressof(b)) + 1;-}--/// Get an iterator to one past the end element in a buffer sequence.-template <typename ConvertibleToBuffer>-inline const ConvertibleToBuffer* buffer_sequence_end(- const ConvertibleToBuffer& b,- constraint_t<- !is_convertible<const ConvertibleToBuffer*, const mutable_buffer*>::value- > = 0,- constraint_t<- !is_convertible<const ConvertibleToBuffer*, const const_buffer*>::value- > = 0,- constraint_t<- is_convertible<ConvertibleToBuffer, mutable_buffer>::value- || is_convertible<ConvertibleToBuffer, const_buffer>::value- > = 0) noexcept-{- return detail::addressof(b) + 1;-}--/// Get an iterator to one past the end element in a buffer sequence.-template <typename C>-inline auto buffer_sequence_end(C& c,- constraint_t<- !is_convertible<const C*, const mutable_buffer*>::value- > = 0,- constraint_t<- !is_convertible<const C*, const const_buffer*>::value- > = 0,- constraint_t<- !is_convertible<C, mutable_buffer>::value- > = 0,- constraint_t<- !is_convertible<C, const_buffer>::value- > = 0) noexcept -> 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,- constraint_t<- !is_convertible<const C*, const mutable_buffer*>::value- > = 0,- constraint_t<- !is_convertible<const C*, const const_buffer*>::value- > = 0,- constraint_t<- !is_convertible<C, mutable_buffer>::value- > = 0,- constraint_t<- !is_convertible<C, const_buffer>::value- > = 0) noexcept -> decltype(c.end())-{- return c.end();-}--/*@}*/--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>-struct buffer_sequence_cardinality :- conditional_t<- is_same<BufferSequence, mutable_buffer>::value- || is_same<BufferSequence, const_buffer>::value,- one_buffer, multiple_buffers> {};--template <typename Iterator>-inline std::size_t buffer_size(one_buffer,- Iterator begin, Iterator) noexcept-{- return const_buffer(*begin).size();-}--template <typename Iterator>-inline std::size_t buffer_size(multiple_buffers,- Iterator begin, Iterator end) noexcept-{- std::size_t total_buffer_size = 0;-- Iterator iter = begin;- for (; iter != end; ++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 = asio::buffer_sequence_begin(buffers);- * auto end = asio::buffer_sequence_end(buffers);- * for (; i != end; ++i)- * {- * const_buffer b(*i);- * total_size += b.size();- * }- * return total_size; @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) noexcept-{- return detail::buffer_size(- detail::buffer_sequence_cardinality<BufferSequence>(),- asio::buffer_sequence_begin(b),- asio::buffer_sequence_end(b));-}--/// 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 n) noexcept-{- 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(ASIO_ENABLE_BUFFER_DEBUGGING)- , b.get_debug_check()-#endif // ASIO_ENABLE_BUFFER_DEBUGGING- );-}--/// Create a new modifiable buffer that is offset from the start of another.-/**- * @relates mutable_buffer- */-inline mutable_buffer operator+(std::size_t n,- const mutable_buffer& b) noexcept-{- 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 n) noexcept-{- 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(ASIO_ENABLE_BUFFER_DEBUGGING)- , b.get_debug_check()-#endif // ASIO_ENABLE_BUFFER_DEBUGGING- );-}--/// Create a new non-modifiable buffer that is offset from the start of another.-/**- * @relates const_buffer- */-inline const_buffer operator+(std::size_t n,- const const_buffer& b) noexcept-{- return b + n;-}--#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)-namespace detail {--template <typename Iterator>-class buffer_debug_check-{-public:- buffer_debug_check(Iterator iter)- : iter_(iter)- {- }-- ~buffer_debug_check()- {-#if defined(ASIO_MSVC) && (ASIO_MSVC == 1400)- // MSVC 8's string iterator checking may crash in a std::string::iterator- // object's destructor when the iterator points to an already-destroyed- // std::string object, unless the iterator is cleared first.- iter_ = Iterator();-#endif // defined(ASIO_MSVC) && (ASIO_MSVC == 1400)- }-- void operator()()- {- (void)*iter_;- }--private:- Iterator iter_;-};--} // namespace detail-#endif // ASIO_ENABLE_BUFFER_DEBUGGING--/** @defgroup buffer asio::buffer- *- * @brief The asio::buffer function is used to create a buffer object to- * represent raw memory, an array of POD elements, a vector of POD elements,- * or a std::string.- *- * A buffer object represents a contiguous region of memory as a 2-tuple- * consisting of a pointer and size in bytes. A tuple of the form <tt>{void*,- * size_t}</tt> specifies a mutable (modifiable) region of memory. Similarly, a- * tuple of the form <tt>{const void*, size_t}</tt> specifies a const- * (non-modifiable) region of memory. These two forms correspond to the classes- * mutable_buffer and const_buffer, respectively. To mirror C++'s conversion- * rules, a mutable_buffer is implicitly convertible to a const_buffer, and the- * opposite conversion is not permitted.- *- * The simplest use case involves reading or writing a single buffer of a- * specified size:- *- * @code sock.send(asio::buffer(data, size)); @endcode- *- * In the above example, the return value of asio::buffer meets the- * requirements of the ConstBufferSequence concept so that it may be directly- * passed to the socket's write function. A buffer created for modifiable- * memory also meets the requirements of the MutableBufferSequence concept.- *- * An individual buffer may be created from a builtin array, std::vector,- * std::array or boost::array of POD elements. This helps prevent buffer- * overruns by automatically determining the size of the buffer:- *- * @code char d1[128];- * size_t bytes_transferred = sock.receive(asio::buffer(d1));- *- * std::vector<char> d2(128);- * bytes_transferred = sock.receive(asio::buffer(d2));- *- * std::array<char, 128> d3;- * bytes_transferred = sock.receive(asio::buffer(d3));- *- * boost::array<char, 128> d4;- * bytes_transferred = sock.receive(asio::buffer(d4)); @endcode- *- * In all three cases above, the buffers created are exactly 128 bytes long.- * Note that a vector is @e never automatically resized when creating or using- * a buffer. The buffer size is determined using the vector's <tt>size()</tt>- * member function, and not its capacity.- *- * @par Accessing Buffer Contents- *- * The contents of a buffer may be accessed using the @c data() and @c size()- * member functions:- *- * @code asio::mutable_buffer b1 = ...;- * std::size_t s1 = b1.size();- * unsigned char* p1 = static_cast<unsigned char*>(b1.data());- *- * asio::const_buffer b2 = ...;- * std::size_t s2 = b2.size();- * const void* p2 = b2.data(); @endcode- *- * The @c data() member function permits violations of type safety, so- * uses of it in application code should be carefully considered.- *- * 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 function, the @ref- * buffer_copy function can be used to linearise a sequence of buffers. For- * example:- *- * @code vector<const_buffer> buffers = ...;- *- * vector<unsigned char> data(asio::buffer_size(buffers));- * asio::buffer_copy(asio::buffer(data), buffers); @endcode- *- * Note that @ref buffer_copy is implemented in terms of @c memcpy, and- * consequently it cannot be used to copy between overlapping memory regions.- *- * @par Buffer Invalidation- *- * A buffer object does not have any ownership of the memory it refers to. It- * is the responsibility of the application to ensure the memory region remains- * valid until it is no longer required for an I/O operation. When the memory- * is no longer available, the buffer is said to have been invalidated.- *- * For the asio::buffer overloads that accept an argument of type- * std::vector, the buffer objects returned are invalidated by any vector- * operation that also invalidates all references, pointers and iterators- * referring to the elements in the sequence (C++ Std, 23.2.4)- *- * For the asio::buffer overloads that accept an argument of type- * std::basic_string, the buffer objects returned are invalidated according to- * the rules defined for invalidation of references, pointers and iterators- * referring to elements of the sequence (C++ Std, 21.3).- *- * @par Buffer Arithmetic- *- * Buffer objects may be manipulated using simple arithmetic in a safe way- * which helps prevent buffer overruns. Consider an array initialised as- * follows:- *- * @code boost::array<char, 6> a = { 'a', 'b', 'c', 'd', 'e' }; @endcode- *- * A buffer object @c b1 created using:- *- * @code b1 = asio::buffer(a); @endcode- *- * represents the entire array, <tt>{ 'a', 'b', 'c', 'd', 'e' }</tt>. An- * optional second argument to the asio::buffer function may be used to- * limit the size, in bytes, of the buffer:- *- * @code b2 = asio::buffer(a, 3); @endcode- *- * such that @c b2 represents the data <tt>{ 'a', 'b', 'c' }</tt>. Even if the- * size argument exceeds the actual size of the array, the size of the buffer- * object created will be limited to the array size.- *- * An offset may be applied to an existing buffer to create a new one:- *- * @code b3 = b1 + 2; @endcode- *- * where @c b3 will set to represent <tt>{ 'c', 'd', 'e' }</tt>. If the offset- * exceeds the size of the existing buffer, the newly created buffer will be- * empty.- *- * Both an offset and size may be specified to create a buffer that corresponds- * to a specific range of bytes within an existing buffer:- *- * @code b4 = asio::buffer(b1 + 1, 3); @endcode- *- * so that @c b4 will refer to the bytes <tt>{ 'b', 'c', 'd' }</tt>.- *- * @par Buffers and Scatter-Gather I/O- *- * To read or write using multiple buffers (i.e. scatter-gather I/O), multiple- * buffer objects may be assigned into a container that supports the- * MutableBufferSequence (for read) or ConstBufferSequence (for write) concepts:- *- * @code- * char d1[128];- * std::vector<char> d2(128);- * boost::array<char, 128> d3;- *- * boost::array<mutable_buffer, 3> bufs1 = {- * asio::buffer(d1),- * asio::buffer(d2),- * asio::buffer(d3) };- * bytes_transferred = sock.receive(bufs1);- *- * std::vector<const_buffer> bufs2;- * bufs2.push_back(asio::buffer(d1));- * bufs2.push_back(asio::buffer(d2));- * bufs2.push_back(asio::buffer(d3));- * bytes_transferred = sock.send(bufs2); @endcode- *- * @par Buffer Literals- *- * The `_buf` literal suffix, defined in namespace- * <tt>asio::buffer_literals</tt>, may be used to create @c const_buffer- * objects from string, binary integer, and hexadecimal integer literals.- * For example:- *- * @code- * using namespace asio::buffer_literals;- *- * asio::const_buffer b1 = "hello"_buf;- * asio::const_buffer b2 = 0xdeadbeef_buf;- * asio::const_buffer b3 = 0x0123456789abcdef0123456789abcdef_buf;- * asio::const_buffer b4 = 0b1010101011001100_buf; @endcode- *- * Note that the memory associated with a buffer literal is valid for the- * lifetime of the program. This means that the buffer can be safely used with- * asynchronous operations.- */-/*@{*/--/// Create a new modifiable buffer from an existing buffer.-/**- * @returns <tt>mutable_buffer(b)</tt>.- */-ASIO_NODISCARD inline mutable_buffer buffer(- const mutable_buffer& b) noexcept-{- return mutable_buffer(b);-}--/// Create a new modifiable buffer from an existing buffer.-/**- * @returns A mutable_buffer value equivalent to:- * @code mutable_buffer(- * b.data(),- * min(b.size(), max_size_in_bytes)); @endcode- */-ASIO_NODISCARD inline mutable_buffer buffer(- const mutable_buffer& b,- std::size_t max_size_in_bytes) noexcept-{- return mutable_buffer(- mutable_buffer(b.data(),- b.size() < max_size_in_bytes- ? b.size() : max_size_in_bytes-#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)- , b.get_debug_check()-#endif // ASIO_ENABLE_BUFFER_DEBUGGING- ));-}--/// Create a new non-modifiable buffer from an existing buffer.-/**- * @returns <tt>const_buffer(b)</tt>.- */-ASIO_NODISCARD inline const_buffer buffer(- const const_buffer& b) noexcept-{- return const_buffer(b);-}--/// Create a new non-modifiable buffer from an existing buffer.-/**- * @returns A const_buffer value equivalent to:- * @code const_buffer(- * b.data(),- * min(b.size(), max_size_in_bytes)); @endcode- */-ASIO_NODISCARD inline const_buffer buffer(- const const_buffer& b,- std::size_t max_size_in_bytes) noexcept-{- return const_buffer(b.data(),- b.size() < max_size_in_bytes- ? b.size() : max_size_in_bytes-#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)- , b.get_debug_check()-#endif // ASIO_ENABLE_BUFFER_DEBUGGING- );-}--/// Create a new modifiable buffer that represents the given memory range.-/**- * @returns <tt>mutable_buffer(data, size_in_bytes)</tt>.- */-ASIO_NODISCARD inline mutable_buffer buffer(- void* data, std::size_t size_in_bytes) noexcept-{- return mutable_buffer(data, size_in_bytes);-}--/// Create a new non-modifiable buffer that represents the given memory range.-/**- * @returns <tt>const_buffer(data, size_in_bytes)</tt>.- */-ASIO_NODISCARD inline const_buffer buffer(- const void* data, std::size_t size_in_bytes) noexcept-{- return const_buffer(data, size_in_bytes);-}--/// Create a new modifiable buffer that represents the given POD array.-/**- * @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>-ASIO_NODISCARD inline mutable_buffer buffer(- PodType (&data)[N]) noexcept-{- return mutable_buffer(data, N * sizeof(PodType));-}--/// Create a new modifiable buffer that represents the given POD array.-/**- * @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>-ASIO_NODISCARD inline mutable_buffer buffer(- PodType (&data)[N],- std::size_t max_size_in_bytes) noexcept-{- return 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_buffer value equivalent to:- * @code const_buffer(- * static_cast<const void*>(data),- * N * sizeof(PodType)); @endcode- */-template <typename PodType, std::size_t N>-ASIO_NODISCARD inline const_buffer buffer(- const PodType (&data)[N]) noexcept-{- return const_buffer(data, N * sizeof(PodType));-}--/// Create a new non-modifiable buffer that represents the given POD array.-/**- * @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>-ASIO_NODISCARD inline const_buffer buffer(- const PodType (&data)[N],- std::size_t max_size_in_bytes) noexcept-{- return const_buffer(data,- N * sizeof(PodType) < max_size_in_bytes- ? N * sizeof(PodType) : max_size_in_bytes);-}--/// Create a new modifiable buffer that represents the given POD array.-/**- * @returns A mutable_buffer value equivalent to:- * @code mutable_buffer(- * data.data(),- * data.size() * sizeof(PodType)); @endcode- */-template <typename PodType, std::size_t N>-ASIO_NODISCARD inline mutable_buffer buffer(- boost::array<PodType, N>& data) noexcept-{- return mutable_buffer(- data.c_array(), data.size() * sizeof(PodType));-}--/// Create a new modifiable buffer that represents the given POD array.-/**- * @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>-ASIO_NODISCARD inline mutable_buffer buffer(- boost::array<PodType, N>& data,- std::size_t max_size_in_bytes) noexcept-{- return 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_buffer value equivalent to:- * @code const_buffer(- * data.data(),- * data.size() * sizeof(PodType)); @endcode- */-template <typename PodType, std::size_t N>-ASIO_NODISCARD inline const_buffer buffer(- boost::array<const PodType, N>& data) noexcept-{- return const_buffer(data.data(), data.size() * sizeof(PodType));-}--/// Create a new non-modifiable buffer that represents the given POD array.-/**- * @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>-ASIO_NODISCARD inline const_buffer buffer(- boost::array<const PodType, N>& data,- std::size_t max_size_in_bytes) noexcept-{- return 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_buffer value equivalent to:- * @code const_buffer(- * data.data(),- * data.size() * sizeof(PodType)); @endcode- */-template <typename PodType, std::size_t N>-ASIO_NODISCARD inline const_buffer buffer(- const boost::array<PodType, N>& data) noexcept-{- return const_buffer(data.data(), data.size() * sizeof(PodType));-}--/// Create a new non-modifiable buffer that represents the given POD array.-/**- * @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>-ASIO_NODISCARD inline const_buffer buffer(- const boost::array<PodType, N>& data,- std::size_t max_size_in_bytes) noexcept-{- return const_buffer(data.data(),- data.size() * sizeof(PodType) < max_size_in_bytes- ? data.size() * sizeof(PodType) : max_size_in_bytes);-}--/// Create a new modifiable buffer that represents the given POD array.-/**- * @returns A mutable_buffer value equivalent to:- * @code mutable_buffer(- * data.data(),- * data.size() * sizeof(PodType)); @endcode- */-template <typename PodType, std::size_t N>-ASIO_NODISCARD inline mutable_buffer buffer(- std::array<PodType, N>& data) noexcept-{- return mutable_buffer(data.data(), data.size() * sizeof(PodType));-}--/// Create a new modifiable buffer that represents the given POD array.-/**- * @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>-ASIO_NODISCARD inline mutable_buffer buffer(- std::array<PodType, N>& data,- std::size_t max_size_in_bytes) noexcept-{- return 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_buffer value equivalent to:- * @code const_buffer(- * data.data(),- * data.size() * sizeof(PodType)); @endcode- */-template <typename PodType, std::size_t N>-ASIO_NODISCARD inline const_buffer buffer(- std::array<const PodType, N>& data) noexcept-{- return const_buffer(data.data(), data.size() * sizeof(PodType));-}--/// Create a new non-modifiable buffer that represents the given POD array.-/**- * @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>-ASIO_NODISCARD inline const_buffer buffer(- std::array<const PodType, N>& data,- std::size_t max_size_in_bytes) noexcept-{- return 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_buffer value equivalent to:- * @code const_buffer(- * data.data(),- * data.size() * sizeof(PodType)); @endcode- */-template <typename PodType, std::size_t N>-ASIO_NODISCARD inline const_buffer buffer(- const std::array<PodType, N>& data) noexcept-{- return const_buffer(data.data(), data.size() * sizeof(PodType));-}--/// Create a new non-modifiable buffer that represents the given POD array.-/**- * @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>-ASIO_NODISCARD inline const_buffer buffer(- const std::array<PodType, N>& data,- std::size_t max_size_in_bytes) noexcept-{- return const_buffer(data.data(),- data.size() * sizeof(PodType) < max_size_in_bytes- ? data.size() * sizeof(PodType) : max_size_in_bytes);-}--/// Create a new modifiable buffer that represents the given POD vector.-/**- * @returns A mutable_buffer value equivalent to:- * @code mutable_buffer(- * data.size() ? &data[0] : 0,- * data.size() * sizeof(PodType)); @endcode- *- * @note The buffer is invalidated by any vector operation that would also- * invalidate iterators.- */-template <typename PodType, typename Allocator>-ASIO_NODISCARD inline mutable_buffer buffer(- std::vector<PodType, Allocator>& data) noexcept-{- return mutable_buffer(- data.size() ? &data[0] : 0, data.size() * sizeof(PodType)-#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)- , detail::buffer_debug_check<- typename std::vector<PodType, Allocator>::iterator- >(data.begin())-#endif // ASIO_ENABLE_BUFFER_DEBUGGING- );-}--/// Create a new modifiable buffer that represents the given POD vector.-/**- * @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- *- * @note The buffer is invalidated by any vector operation that would also- * invalidate iterators.- */-template <typename PodType, typename Allocator>-ASIO_NODISCARD inline mutable_buffer buffer(- std::vector<PodType, Allocator>& data,- std::size_t max_size_in_bytes) noexcept-{- return 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(ASIO_ENABLE_BUFFER_DEBUGGING)- , detail::buffer_debug_check<- typename std::vector<PodType, Allocator>::iterator- >(data.begin())-#endif // ASIO_ENABLE_BUFFER_DEBUGGING- );-}--/// Create a new non-modifiable buffer that represents the given POD vector.-/**- * @returns A const_buffer value equivalent to:- * @code const_buffer(- * data.size() ? &data[0] : 0,- * data.size() * sizeof(PodType)); @endcode- *- * @note The buffer is invalidated by any vector operation that would also- * invalidate iterators.- */-template <typename PodType, typename Allocator>-ASIO_NODISCARD inline const_buffer buffer(- const std::vector<PodType, Allocator>& data) noexcept-{- return const_buffer(- data.size() ? &data[0] : 0, data.size() * sizeof(PodType)-#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)- , detail::buffer_debug_check<- typename std::vector<PodType, Allocator>::const_iterator- >(data.begin())-#endif // ASIO_ENABLE_BUFFER_DEBUGGING- );-}--/// Create a new non-modifiable buffer that represents the given POD vector.-/**- * @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- *- * @note The buffer is invalidated by any vector operation that would also- * invalidate iterators.- */-template <typename PodType, typename Allocator>-ASIO_NODISCARD inline const_buffer buffer(- const std::vector<PodType, Allocator>& data,- std::size_t max_size_in_bytes) noexcept-{- return 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(ASIO_ENABLE_BUFFER_DEBUGGING)- , detail::buffer_debug_check<- typename std::vector<PodType, Allocator>::const_iterator- >(data.begin())-#endif // ASIO_ENABLE_BUFFER_DEBUGGING- );-}--/// Create a new modifiable buffer that represents the given string.-/**- * @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>-ASIO_NODISCARD inline mutable_buffer buffer(- std::basic_string<Elem, Traits, Allocator>& data) noexcept-{- return mutable_buffer(data.size() ? &data[0] : 0,- data.size() * sizeof(Elem)-#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)- , detail::buffer_debug_check<- typename std::basic_string<Elem, Traits, Allocator>::iterator- >(data.begin())-#endif // ASIO_ENABLE_BUFFER_DEBUGGING- );-}--/// Create a new modifiable buffer that represents the given string.-/**- * @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>-ASIO_NODISCARD inline mutable_buffer buffer(- std::basic_string<Elem, Traits, Allocator>& data,- std::size_t max_size_in_bytes) noexcept-{- return 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(ASIO_ENABLE_BUFFER_DEBUGGING)- , detail::buffer_debug_check<- typename std::basic_string<Elem, Traits, Allocator>::iterator- >(data.begin())-#endif // ASIO_ENABLE_BUFFER_DEBUGGING- );-}--/// Create a new non-modifiable buffer that represents the given string.-/**- * @returns <tt>const_buffer(data.data(), 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>-ASIO_NODISCARD inline const_buffer buffer(- const std::basic_string<Elem, Traits, Allocator>& data) noexcept-{- return const_buffer(data.data(), data.size() * sizeof(Elem)-#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)- , detail::buffer_debug_check<- typename std::basic_string<Elem, Traits, Allocator>::const_iterator- >(data.begin())-#endif // ASIO_ENABLE_BUFFER_DEBUGGING- );-}--/// Create a new non-modifiable buffer that represents the given string.-/**- * @returns A const_buffer value equivalent to:- * @code const_buffer(- * data.data(),- * 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>-ASIO_NODISCARD inline const_buffer buffer(- const std::basic_string<Elem, Traits, Allocator>& data,- std::size_t max_size_in_bytes) noexcept-{- return const_buffer(data.data(),- data.size() * sizeof(Elem) < max_size_in_bytes- ? data.size() * sizeof(Elem) : max_size_in_bytes-#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)- , detail::buffer_debug_check<- typename std::basic_string<Elem, Traits, Allocator>::const_iterator- >(data.begin())-#endif // ASIO_ENABLE_BUFFER_DEBUGGING- );-}--#if defined(ASIO_HAS_STRING_VIEW) \- || defined(GENERATING_DOCUMENTATION)--/// Create a new non-modifiable buffer that represents the given string_view.-/**- * @returns <tt>mutable_buffer(data.size() ? &data[0] : 0,- * data.size() * sizeof(Elem))</tt>.- */-template <typename Elem, typename Traits>-ASIO_NODISCARD inline const_buffer buffer(- basic_string_view<Elem, Traits> data) noexcept-{- return const_buffer(data.size() ? &data[0] : 0,- data.size() * sizeof(Elem)-#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)- , detail::buffer_debug_check<- typename basic_string_view<Elem, Traits>::iterator- >(data.begin())-#endif // ASIO_ENABLE_BUFFER_DEBUGGING- );-}--/// Create a new non-modifiable buffer that represents the given string.-/**- * @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- */-template <typename Elem, typename Traits>-ASIO_NODISCARD inline const_buffer buffer(- basic_string_view<Elem, Traits> data,- std::size_t max_size_in_bytes) noexcept-{- return 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(ASIO_ENABLE_BUFFER_DEBUGGING)- , detail::buffer_debug_check<- typename basic_string_view<Elem, Traits>::iterator- >(data.begin())-#endif // ASIO_ENABLE_BUFFER_DEBUGGING- );-}--#endif // defined(ASIO_HAS_STRING_VIEW)- // || defined(GENERATING_DOCUMENTATION)--/// Create a new modifiable buffer from a contiguous container.-/**- * @returns A mutable_buffer value equivalent to:- * @code mutable_buffer(- * data.size() ? &data[0] : 0,- * data.size() * sizeof(typename T::value_type)); @endcode- */-template <typename T>-ASIO_NODISCARD inline mutable_buffer buffer(- T& data,- constraint_t<- is_contiguous_iterator<typename T::iterator>::value,- defaulted_constraint- > = defaulted_constraint(),- constraint_t<- !is_convertible<T, const_buffer>::value,- defaulted_constraint- > = defaulted_constraint(),- constraint_t<- !is_convertible<T, mutable_buffer>::value,- defaulted_constraint- > = defaulted_constraint(),- constraint_t<- !is_const<- remove_reference_t<- typename std::iterator_traits<typename T::iterator>::reference- >- >::value,- defaulted_constraint- > = defaulted_constraint()) noexcept-{- return mutable_buffer(- data.size() ? detail::to_address(data.begin()) : 0,- data.size() * sizeof(typename T::value_type));-}--/// Create a new modifiable buffer from a contiguous container.-/**- * @returns A mutable_buffer value equivalent to:- * @code mutable_buffer(- * data.size() ? &data[0] : 0,- * min(- * data.size() * sizeof(typename T::value_type),- * max_size_in_bytes)); @endcode- */-template <typename T>-ASIO_NODISCARD inline mutable_buffer buffer(- T& data, std::size_t max_size_in_bytes,- constraint_t<- is_contiguous_iterator<typename T::iterator>::value,- defaulted_constraint- > = defaulted_constraint(),- constraint_t<- !is_convertible<T, const_buffer>::value,- defaulted_constraint- > = defaulted_constraint(),- constraint_t<- !is_convertible<T, mutable_buffer>::value,- defaulted_constraint- > = defaulted_constraint(),- constraint_t<- !is_const<- remove_reference_t<- typename std::iterator_traits<typename T::iterator>::reference- >- >::value,- defaulted_constraint- > = defaulted_constraint()) noexcept-{- return mutable_buffer(- data.size() ? detail::to_address(data.begin()) : 0,- data.size() * sizeof(typename T::value_type) < max_size_in_bytes- ? data.size() * sizeof(typename T::value_type) : max_size_in_bytes);-}--/// Create a new non-modifiable buffer from a contiguous container.-/**- * @returns A const_buffer value equivalent to:- * @code const_buffer(- * data.size() ? &data[0] : 0,- * data.size() * sizeof(typename T::value_type)); @endcode- */-template <typename T>-ASIO_NODISCARD inline const_buffer buffer(- T& data,- constraint_t<- is_contiguous_iterator<typename T::iterator>::value,- defaulted_constraint- > = defaulted_constraint(),- constraint_t<- !is_convertible<T, const_buffer>::value,- defaulted_constraint- > = defaulted_constraint(),- constraint_t<- !is_convertible<T, mutable_buffer>::value,- defaulted_constraint- > = defaulted_constraint(),- constraint_t<- is_const<- remove_reference_t<- typename std::iterator_traits<typename T::iterator>::reference- >- >::value,- defaulted_constraint- > = defaulted_constraint()) noexcept-{- return const_buffer(- data.size() ? detail::to_address(data.begin()) : 0,- data.size() * sizeof(typename T::value_type));-}--/// Create a new non-modifiable buffer from a contiguous container.-/**- * @returns A const_buffer value equivalent to:- * @code const_buffer(- * data.size() ? &data[0] : 0,- * min(- * data.size() * sizeof(typename T::value_type),- * max_size_in_bytes)); @endcode- */-template <typename T>-ASIO_NODISCARD inline const_buffer buffer(- T& data, std::size_t max_size_in_bytes,- constraint_t<- is_contiguous_iterator<typename T::iterator>::value,- defaulted_constraint- > = defaulted_constraint(),- constraint_t<- !is_convertible<T, const_buffer>::value,- defaulted_constraint- > = defaulted_constraint(),- constraint_t<- !is_convertible<T, mutable_buffer>::value,- defaulted_constraint- > = defaulted_constraint(),- constraint_t<- is_const<- remove_reference_t<- typename std::iterator_traits<typename T::iterator>::reference- >- >::value,- defaulted_constraint- > = defaulted_constraint()) noexcept-{- return const_buffer(- data.size() ? detail::to_address(data.begin()) : 0,- data.size() * sizeof(typename T::value_type) < max_size_in_bytes- ? data.size() * sizeof(typename T::value_type) : max_size_in_bytes);-}--/// Create a new non-modifiable buffer from a contiguous container.-/**- * @returns A const_buffer value equivalent to:- * @code const_buffer(- * data.size() ? &data[0] : 0,- * data.size() * sizeof(typename T::value_type)); @endcode- */-template <typename T>-ASIO_NODISCARD inline const_buffer buffer(- const T& data,- constraint_t<- is_contiguous_iterator<typename T::const_iterator>::value,- defaulted_constraint- > = defaulted_constraint(),- constraint_t<- !is_convertible<T, const_buffer>::value,- defaulted_constraint- > = defaulted_constraint(),- constraint_t<- !is_convertible<T, mutable_buffer>::value,- defaulted_constraint- > = defaulted_constraint()) noexcept-{- return const_buffer(- data.size() ? detail::to_address(data.begin()) : 0,- data.size() * sizeof(typename T::value_type));-}--/// Create a new non-modifiable buffer from a contiguous container.-/**- * @returns A const_buffer value equivalent to:- * @code const_buffer(- * data.size() ? &data[0] : 0,- * min(- * data.size() * sizeof(typename T::value_type),- * max_size_in_bytes)); @endcode- */-template <typename T>-ASIO_NODISCARD inline const_buffer buffer(- const T& data, std::size_t max_size_in_bytes,- constraint_t<- is_contiguous_iterator<typename T::const_iterator>::value,- defaulted_constraint- > = defaulted_constraint(),- constraint_t<- !is_convertible<T, const_buffer>::value,- defaulted_constraint- > = defaulted_constraint(),- constraint_t<- !is_convertible<T, mutable_buffer>::value,- defaulted_constraint- > = defaulted_constraint()) noexcept-{- return const_buffer(- data.size() ? detail::to_address(data.begin()) : 0,- data.size() * sizeof(typename T::value_type) < max_size_in_bytes- ? data.size() * sizeof(typename T::value_type) : max_size_in_bytes);-}--/// Create a new modifiable buffer from a span.-/**- * @returns <tt>mutable_buffer(span)</tt>.- */-template <template <typename, std::size_t> class Span,- typename T, std::size_t Extent>-ASIO_NODISCARD inline mutable_buffer buffer(- const Span<T, Extent>& span,- constraint_t<- !is_const<T>::value,- defaulted_constraint- > = defaulted_constraint(),- constraint_t<- sizeof(T) == 1,- defaulted_constraint- > = defaulted_constraint(),- constraint_t<-#if defined(ASIO_MSVC)- detail::has_subspan_memfn<Span<T, Extent>>::value,-#else // defined(ASIO_MSVC)- is_same<- decltype(span.subspan(0, 0)),- Span<T, static_cast<std::size_t>(-1)>- >::value,-#endif // defined(ASIO_MSVC)- defaulted_constraint- > = defaulted_constraint()) noexcept-{- return mutable_buffer(span);-}--/// Create a new modifiable buffer from a span.-/**- * @returns A mutable_buffer value equivalent to:- * @code mutable_buffer b(span);- * mutable_buffer(- * b.data(),- * min(b.size(), max_size_in_bytes)); @endcode- */-template <template <typename, std::size_t> class Span,- typename T, std::size_t Extent>-ASIO_NODISCARD inline mutable_buffer buffer(- const Span<T, Extent>& span,- std::size_t max_size_in_bytes,- constraint_t<- !is_const<T>::value,- defaulted_constraint- > = defaulted_constraint(),- constraint_t<- sizeof(T) == 1,- defaulted_constraint- > = defaulted_constraint(),- constraint_t<-#if defined(ASIO_MSVC)- detail::has_subspan_memfn<Span<T, Extent>>::value,-#else // defined(ASIO_MSVC)- is_same<- decltype(span.subspan(0, 0)),- Span<T, static_cast<std::size_t>(-1)>- >::value,-#endif // defined(ASIO_MSVC)- defaulted_constraint- > = defaulted_constraint()) noexcept-{- return buffer(mutable_buffer(span), max_size_in_bytes);-}--/// Create a new non-modifiable buffer from a span.-/**- * @returns <tt>const_buffer(span)</tt>.- */-template <template <typename, std::size_t> class Span,- typename T, std::size_t Extent>-ASIO_NODISCARD inline const_buffer buffer(- const Span<const T, Extent>& span,- constraint_t<- sizeof(T) == 1,- defaulted_constraint- > = defaulted_constraint(),- constraint_t<-#if defined(ASIO_MSVC)- detail::has_subspan_memfn<Span<const T, Extent>>::value,-#else // defined(ASIO_MSVC)- is_same<- decltype(span.subspan(0, 0)),- Span<T, static_cast<std::size_t>(-1)>- >::value,-#endif // defined(ASIO_MSVC)- defaulted_constraint- > = defaulted_constraint()) noexcept-{- return const_buffer(span);-}--/// Create a new non-modifiable buffer from a span.-/**- * @returns A const_buffer value equivalent to:- * @code const_buffer b1(b);- * const_buffer(- * b1.data(),- * min(b1.size(), max_size_in_bytes)); @endcode- */-template <template <typename, std::size_t> class Span,- typename T, std::size_t Extent>-ASIO_NODISCARD inline const_buffer buffer(- const Span<const T, Extent>& span,- std::size_t max_size_in_bytes,- constraint_t<- sizeof(T) == 1,- defaulted_constraint- > = defaulted_constraint(),- constraint_t<-#if defined(ASIO_MSVC)- detail::has_subspan_memfn<Span<const T, Extent>>::value,-#else // defined(ASIO_MSVC)- is_same<- decltype(span.subspan(0, 0)),- Span<T, static_cast<std::size_t>(-1)>- >::value,-#endif // defined(ASIO_MSVC)- defaulted_constraint- > = defaulted_constraint()) noexcept-{- return buffer(const_buffer(span), max_size_in_bytes);-}--/*@}*/--/// Adapt a basic_string to the DynamicBuffer requirements.-/**- * Requires that <tt>sizeof(Elem) == 1</tt>.- */-template <typename Elem, typename Traits, typename Allocator>-class dynamic_string_buffer-{-public:- /// The type used to represent a sequence of constant buffers that refers to- /// the underlying memory.- typedef const_buffer const_buffers_type;-- /// The type used to represent a sequence of mutable buffers that refers to- /// the underlying memory.- typedef 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.- * The object stores a reference to the string and the user is responsible- * for ensuring that the string object remains valid while the- * dynamic_string_buffer object, and copies of the object, are in use.- *- * @b DynamicBuffer_v1: Any existing data in the string is treated as the- * dynamic buffer's input sequence.- *- * @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)()) noexcept- : string_(s),-#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)- size_((std::numeric_limits<std::size_t>::max)()),-#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)- max_size_(maximum_size)- {- }-- /// @b DynamicBuffer_v2: Copy construct a dynamic buffer.- dynamic_string_buffer(const dynamic_string_buffer& other) noexcept- : string_(other.string_),-#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)- size_(other.size_),-#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)- max_size_(other.max_size_)- {- }-- /// Move construct a dynamic buffer.- dynamic_string_buffer(dynamic_string_buffer&& other) noexcept- : string_(other.string_),-#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)- size_(other.size_),-#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)- max_size_(other.max_size_)- {- }-- /// @b DynamicBuffer_v1: Get the size of the input sequence.- /// @b DynamicBuffer_v2: Get the current size of the underlying memory.- /**- * @returns @b DynamicBuffer_v1 The current size of the input sequence.- * @b DynamicBuffer_v2: The current size of the underlying string if less than- * max_size(). Otherwise returns max_size().- */- std::size_t size() const noexcept- {-#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)- if (size_ != (std::numeric_limits<std::size_t>::max)())- return size_;-#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)- return (std::min)(string_.size(), max_size());- }-- /// Get the maximum size of the dynamic buffer.- /**- * @returns The allowed maximum size of the underlying memory.- */- std::size_t max_size() const noexcept- {- return max_size_;- }-- /// Get the maximum size that the buffer may grow to without triggering- /// reallocation.- /**- * @returns The current capacity of the underlying string if less than- * max_size(). Otherwise returns max_size().- */- std::size_t capacity() const noexcept- {- return (std::min)(string_.capacity(), max_size());- }--#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)- /// @b DynamicBuffer_v1: 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- * the input sequence.- *- * @note The returned object is invalidated by any @c dynamic_string_buffer- * or @c basic_string member function that resizes or erases the string.- */- const_buffers_type data() const noexcept- {- return const_buffers_type(asio::buffer(string_, size_));- }-#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)-- /// @b DynamicBuffer_v2: Get a sequence of buffers that represents the- /// underlying memory.- /**- * @param pos Position of the first byte to represent in the buffer sequence- *- * @param n The number of bytes to return in the buffer sequence. If the- * underlying memory is shorter, the buffer sequence represents as many bytes- * as are available.- *- * @returns An object of type @c mutable_buffers_type that satisfies- * MutableBufferSequence requirements, representing the basic_string memory.- *- * @note The returned object is invalidated by any @c dynamic_string_buffer- * or @c basic_string member function that resizes or erases the string.- */- mutable_buffers_type data(std::size_t pos, std::size_t n) noexcept- {- return mutable_buffers_type(asio::buffer(- asio::buffer(string_, max_size_) + pos, n));- }-- /// @b DynamicBuffer_v2: Get a sequence of buffers that represents the- /// underlying memory.- /**- * @param pos Position of the first byte to represent in the buffer sequence- *- * @param n The number of bytes to return in the buffer sequence. If the- * underlying memory is shorter, the buffer sequence represents as many bytes- * as are available.- *- * @note The returned object is invalidated by any @c dynamic_string_buffer- * or @c basic_string member function that resizes or erases the string.- */- const_buffers_type data(std::size_t pos,- std::size_t n) const noexcept- {- return const_buffers_type(asio::buffer(- asio::buffer(string_, max_size_) + pos, n));- }--#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)- /// @b DynamicBuffer_v1: 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");- asio::detail::throw_exception(ex);- }-- if (size_ == (std::numeric_limits<std::size_t>::max)())- size_ = string_.size(); // Enable v1 behaviour.-- string_.resize(size_ + n);-- return asio::buffer(asio::buffer(string_) + size_, n);- }-- /// @b DynamicBuffer_v1: 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_);- }-#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)-- /// @b DynamicBuffer_v2: Grow the underlying memory by the specified number of- /// bytes.- /**- * Resizes the string to accommodate an additional @c n bytes at the end.- *- * @throws std::length_error If <tt>size() + n > max_size()</tt>.- */- void grow(std::size_t n)- {- if (size() > max_size() || max_size() - size() < n)- {- std::length_error ex("dynamic_string_buffer too long");- asio::detail::throw_exception(ex);- }-- string_.resize(size() + n);- }-- /// @b DynamicBuffer_v2: Shrink the underlying memory by the specified number- /// of bytes.- /**- * Erases @c n bytes from the end of the string by resizing the basic_string- * object. If @c n is greater than the current size of the string, the string- * is emptied.- */- void shrink(std::size_t n)- {- string_.resize(n > size() ? 0 : size() - n);- }-- /// @b DynamicBuffer_v1: Remove characters from the input sequence.- /// @b DynamicBuffer_v2: Consume the specified number of bytes from the- /// beginning of the underlying memory.- /**- * @b DynamicBuffer_v1: 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.- *- * @b DynamicBuffer_v2: Erases @c n bytes from the beginning of the string.- * If @c n is greater than the current size of the string, the string is- * emptied.- */- void consume(std::size_t n)- {-#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)- if (size_ != (std::numeric_limits<std::size_t>::max)())- {- std::size_t consume_length = (std::min)(n, size_);- string_.erase(0, consume_length);- size_ -= consume_length;- return;- }-#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)- string_.erase(0, n);- }--private:- std::basic_string<Elem, Traits, Allocator>& string_;-#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)- std::size_t size_;-#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)- const std::size_t max_size_;-};--/// Adapt a vector to the DynamicBuffer requirements.-/**- * Requires that <tt>sizeof(Elem) == 1</tt>.- */-template <typename Elem, typename Allocator>-class dynamic_vector_buffer-{-public:- /// The type used to represent a sequence of constant buffers that refers to- /// the underlying memory.- typedef const_buffer const_buffers_type;-- /// The type used to represent a sequence of mutable buffers that refers to- /// the underlying memory.- typedef mutable_buffer mutable_buffers_type;-- /// Construct a dynamic buffer from a vector.- /**- * @param v The vector to be used as backing storage for the dynamic buffer.- * The object stores a reference to the vector and the user is responsible- * for ensuring that the vector object remains valid while the- * dynamic_vector_buffer object, and copies of the object, are in use.- *- * @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)()) noexcept- : vector_(v),-#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)- size_((std::numeric_limits<std::size_t>::max)()),-#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)- max_size_(maximum_size)- {- }-- /// @b DynamicBuffer_v2: Copy construct a dynamic buffer.- dynamic_vector_buffer(const dynamic_vector_buffer& other) noexcept- : vector_(other.vector_),-#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)- size_(other.size_),-#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)- max_size_(other.max_size_)- {- }-- /// Move construct a dynamic buffer.- dynamic_vector_buffer(dynamic_vector_buffer&& other) noexcept- : vector_(other.vector_),-#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)- size_(other.size_),-#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)- max_size_(other.max_size_)- {- }-- /// @b DynamicBuffer_v1: Get the size of the input sequence.- /// @b DynamicBuffer_v2: Get the current size of the underlying memory.- /**- * @returns @b DynamicBuffer_v1 The current size of the input sequence.- * @b DynamicBuffer_v2: The current size of the underlying vector if less than- * max_size(). Otherwise returns max_size().- */- std::size_t size() const noexcept- {-#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)- if (size_ != (std::numeric_limits<std::size_t>::max)())- return size_;-#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)- return (std::min)(vector_.size(), max_size());- }-- /// Get the maximum size of the dynamic buffer.- /**- * @returns @b DynamicBuffer_v1: The allowed maximum of the sum of the sizes- * of the input sequence and output sequence. @b DynamicBuffer_v2: The allowed- * maximum size of the underlying memory.- */- std::size_t max_size() const noexcept- {- return max_size_;- }-- /// Get the maximum size that the buffer may grow to without triggering- /// reallocation.- /**- * @returns @b DynamicBuffer_v1: The current total capacity of the buffer,- * i.e. for both the input sequence and output sequence. @b DynamicBuffer_v2:- * The current capacity of the underlying vector if less than max_size().- * Otherwise returns max_size().- */- std::size_t capacity() const noexcept- {- return (std::min)(vector_.capacity(), max_size());- }--#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)- /// @b DynamicBuffer_v1: 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 vector memory in the- * input sequence.- *- * @note The returned object is invalidated by any @c dynamic_vector_buffer- * or @c vector member function that modifies the input sequence or output- * sequence.- */- const_buffers_type data() const noexcept- {- return const_buffers_type(asio::buffer(vector_, size_));- }-#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)-- /// @b DynamicBuffer_v2: Get a sequence of buffers that represents the- /// underlying memory.- /**- * @param pos Position of the first byte to represent in the buffer sequence- *- * @param n The number of bytes to return in the buffer sequence. If the- * underlying memory is shorter, the buffer sequence represents as many bytes- * as are available.- *- * @returns An object of type @c mutable_buffers_type that satisfies- * MutableBufferSequence requirements, representing the vector memory.- *- * @note The returned object is invalidated by any @c dynamic_vector_buffer- * or @c vector member function that resizes or erases the vector.- */- mutable_buffers_type data(std::size_t pos, std::size_t n) noexcept- {- return mutable_buffers_type(asio::buffer(- asio::buffer(vector_, max_size_) + pos, n));- }-- /// @b DynamicBuffer_v2: Get a sequence of buffers that represents the- /// underlying memory.- /**- * @param pos Position of the first byte to represent in the buffer sequence- *- * @param n The number of bytes to return in the buffer sequence. If the- * underlying memory is shorter, the buffer sequence represents as many bytes- * as are available.- *- * @note The returned object is invalidated by any @c dynamic_vector_buffer- * or @c vector member function that resizes or erases the vector.- */- const_buffers_type data(std::size_t pos,- std::size_t n) const noexcept- {- return const_buffers_type(asio::buffer(- asio::buffer(vector_, max_size_) + pos, n));- }--#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)- /// @b DynamicBuffer_v1: 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- * vector object as necessary.- *- * @returns An object of type @c mutable_buffers_type that satisfies- * MutableBufferSequence requirements, representing vector 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 vector 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");- asio::detail::throw_exception(ex);- }-- if (size_ == (std::numeric_limits<std::size_t>::max)())- size_ = vector_.size(); // Enable v1 behaviour.-- vector_.resize(size_ + n);-- return asio::buffer(asio::buffer(vector_) + size_, n);- }-- /// @b DynamicBuffer_v1: 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_);- }-#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)-- /// @b DynamicBuffer_v2: Grow the underlying memory by the specified number of- /// bytes.- /**- * Resizes the vector to accommodate an additional @c n bytes at the end.- *- * @throws std::length_error If <tt>size() + n > max_size()</tt>.- */- void grow(std::size_t n)- {- if (size() > max_size() || max_size() - size() < n)- {- std::length_error ex("dynamic_vector_buffer too long");- asio::detail::throw_exception(ex);- }-- vector_.resize(size() + n);- }-- /// @b DynamicBuffer_v2: Shrink the underlying memory by the specified number- /// of bytes.- /**- * Erases @c n bytes from the end of the vector by resizing the vector- * object. If @c n is greater than the current size of the vector, the vector- * is emptied.- */- void shrink(std::size_t n)- {- vector_.resize(n > size() ? 0 : size() - n);- }-- /// @b DynamicBuffer_v1: Remove characters from the input sequence.- /// @b DynamicBuffer_v2: Consume the specified number of bytes from the- /// beginning of the underlying memory.- /**- * @b DynamicBuffer_v1: 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.- *- * @b DynamicBuffer_v2: Erases @c n bytes from the beginning of the vector.- * If @c n is greater than the current size of the vector, the vector is- * emptied.- */- void consume(std::size_t n)- {-#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)- if (size_ != (std::numeric_limits<std::size_t>::max)())- {- std::size_t consume_length = (std::min)(n, size_);- vector_.erase(vector_.begin(), vector_.begin() + consume_length);- size_ -= consume_length;- return;- }-#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)- vector_.erase(vector_.begin(), vector_.begin() + (std::min)(size(), n));- }--private:- std::vector<Elem, Allocator>& vector_;-#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)- std::size_t size_;-#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)- const std::size_t max_size_;-};--/** @defgroup dynamic_buffer asio::dynamic_buffer- *- * @brief The 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>.- */-template <typename Elem, typename Traits, typename Allocator>-ASIO_NODISCARD inline-dynamic_string_buffer<Elem, Traits, Allocator> dynamic_buffer(- std::basic_string<Elem, Traits, Allocator>& data) noexcept-{- return dynamic_string_buffer<Elem, Traits, Allocator>(data);-}--/// Create a new dynamic buffer that represents the given string.-/**- * @returns <tt>dynamic_string_buffer<Elem, Traits, Allocator>(data,- * max_size)</tt>.- */-template <typename Elem, typename Traits, typename Allocator>-ASIO_NODISCARD inline-dynamic_string_buffer<Elem, Traits, Allocator> dynamic_buffer(- std::basic_string<Elem, Traits, Allocator>& data,- std::size_t max_size) noexcept-{- return dynamic_string_buffer<Elem, Traits, Allocator>(data, max_size);-}--/// Create a new dynamic buffer that represents the given vector.-/**- * @returns <tt>dynamic_vector_buffer<Elem, Allocator>(data)</tt>.- */-template <typename Elem, typename Allocator>-ASIO_NODISCARD inline-dynamic_vector_buffer<Elem, Allocator> dynamic_buffer(- std::vector<Elem, Allocator>& data) noexcept-{- return dynamic_vector_buffer<Elem, Allocator>(data);-}--/// Create a new dynamic buffer that represents the given vector.-/**- * @returns <tt>dynamic_vector_buffer<Elem, Allocator>(data, max_size)</tt>.- */-template <typename Elem, typename Allocator>-ASIO_NODISCARD inline-dynamic_vector_buffer<Elem, Allocator> dynamic_buffer(- std::vector<Elem, Allocator>& data,- std::size_t max_size) noexcept-{- return dynamic_vector_buffer<Elem, Allocator>(data, max_size);-}--/*@}*/--/** @defgroup buffer_copy asio::buffer_copy- *- * @brief The 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.- */-/*@{*/--namespace detail {--inline std::size_t buffer_copy_1(const mutable_buffer& target,- const const_buffer& source)-{- 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;-}--template <typename TargetIterator, typename SourceIterator>-inline std::size_t buffer_copy(one_buffer, one_buffer,- TargetIterator target_begin, TargetIterator,- SourceIterator source_begin, SourceIterator) noexcept-{- return (buffer_copy_1)(*target_begin, *source_begin);-}--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) noexcept-{- return (buffer_copy_1)(*target_begin,- 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)()) noexcept-{- std::size_t total_bytes_copied = 0;- SourceIterator source_iter = source_begin;-- for (mutable_buffer target_buffer(- asio::buffer(*target_begin, max_bytes_to_copy));- target_buffer.size() && source_iter != source_end; ++source_iter)- {- const_buffer source_buffer(*source_iter);- std::size_t bytes_copied = (buffer_copy_1)(target_buffer, source_buffer);- total_bytes_copied += bytes_copied;- target_buffer += bytes_copied;- }-- return total_bytes_copied;-}--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)()) noexcept-{- std::size_t total_bytes_copied = 0;- TargetIterator target_iter = target_begin;-- for (const_buffer source_buffer(- 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;- }-- return total_bytes_copied;-}--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) noexcept-{- std::size_t total_bytes_copied = 0;-- TargetIterator target_iter = target_begin;- std::size_t target_buffer_offset = 0;-- SourceIterator source_iter = source_begin;- std::size_t source_buffer_offset = 0;-- while (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_1)(target_buffer, source_buffer);- total_bytes_copied += bytes_copied;-- if (bytes_copied == target_buffer.size())- {- ++target_iter;- target_buffer_offset = 0;- }- else- target_buffer_offset += bytes_copied;-- if (bytes_copied == source_buffer.size())- {- ++source_iter;- source_buffer_offset = 0;- }- else- source_buffer_offset += bytes_copied;- }-- return total_bytes_copied;-}--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) noexcept-{- std::size_t total_bytes_copied = 0;-- TargetIterator target_iter = target_begin;- std::size_t target_buffer_offset = 0;-- SourceIterator source_iter = source_begin;- 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_1)(- target_buffer, asio::buffer(source_buffer,- max_bytes_to_copy - total_bytes_copied));- total_bytes_copied += bytes_copied;-- if (bytes_copied == target_buffer.size())- {- ++target_iter;- target_buffer_offset = 0;- }- else- target_buffer_offset += bytes_copied;-- if (bytes_copied == source_buffer.size())- {- ++source_iter;- source_buffer_offset = 0;- }- else- source_buffer_offset += bytes_copied;- }-- return total_bytes_copied;-}--} // namespace detail--/// 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>-inline std::size_t buffer_copy(const MutableBufferSequence& target,- const ConstBufferSequence& source) noexcept-{- return detail::buffer_copy(- detail::buffer_sequence_cardinality<MutableBufferSequence>(),- detail::buffer_sequence_cardinality<ConstBufferSequence>(),- asio::buffer_sequence_begin(target),- asio::buffer_sequence_end(target),- asio::buffer_sequence_begin(source),- asio::buffer_sequence_end(source));-}--/// Copies a limited number of 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.- *- * @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, typename ConstBufferSequence>-inline std::size_t buffer_copy(const MutableBufferSequence& target,- const ConstBufferSequence& source,- std::size_t max_bytes_to_copy) noexcept-{- return detail::buffer_copy(- detail::buffer_sequence_cardinality<MutableBufferSequence>(),- detail::buffer_sequence_cardinality<ConstBufferSequence>(),- asio::buffer_sequence_begin(target),- asio::buffer_sequence_end(target),- asio::buffer_sequence_begin(source),- asio::buffer_sequence_end(source), max_bytes_to_copy);-}--/*@}*/--} // namespace asio--#include "asio/detail/pop_options.hpp"-#include "asio/detail/is_buffer_sequence.hpp"-#include "asio/detail/push_options.hpp"--namespace asio {--/// 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)- : 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)- : asio::detail::is_buffer_sequence<T, const_buffer>-#endif // defined(GENERATING_DOCUMENTATION)-{-};--#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)-/// Trait to determine whether a type satisfies the DynamicBuffer_v1-/// requirements.-template <typename T>-struct is_dynamic_buffer_v1-#if defined(GENERATING_DOCUMENTATION)- : integral_constant<bool, automatically_determined>-#else // defined(GENERATING_DOCUMENTATION)- : asio::detail::is_dynamic_buffer_v1<T>-#endif // defined(GENERATING_DOCUMENTATION)-{-};-#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)--/// Trait to determine whether a type satisfies the DynamicBuffer_v2-/// requirements.-template <typename T>-struct is_dynamic_buffer_v2-#if defined(GENERATING_DOCUMENTATION)- : integral_constant<bool, automatically_determined>-#else // defined(GENERATING_DOCUMENTATION)- : asio::detail::is_dynamic_buffer_v2<T>-#endif // defined(GENERATING_DOCUMENTATION)-{-};--/// Trait to determine whether a type satisfies the DynamicBuffer requirements.-/**- * If @c ASIO_NO_DYNAMIC_BUFFER_V1 is not defined, determines whether the- * type satisfies the DynamicBuffer_v1 requirements. Otherwise, if @c- * ASIO_NO_DYNAMIC_BUFFER_V1 is defined, determines whether the type- * satisfies the DynamicBuffer_v2 requirements.- */-template <typename T>-struct is_dynamic_buffer-#if defined(GENERATING_DOCUMENTATION)- : integral_constant<bool, automatically_determined>-#elif defined(ASIO_NO_DYNAMIC_BUFFER_V1)- : asio::is_dynamic_buffer_v2<T>-#else // defined(ASIO_NO_DYNAMIC_BUFFER_V1)- : asio::is_dynamic_buffer_v1<T>-#endif // defined(ASIO_NO_DYNAMIC_BUFFER_V1)-{-};--namespace buffer_literals {-namespace detail {--template <char... Chars>-struct chars {};--template <unsigned char... Bytes>-struct bytes {};--// Literal processor that converts binary literals to an array of bytes.--template <typename Bytes, char... Chars>-struct bin_literal;--template <unsigned char... Bytes>-struct bin_literal<bytes<Bytes...>>-{- static const std::size_t size = sizeof...(Bytes);- static const unsigned char data[sizeof...(Bytes)];-};--template <unsigned char... Bytes>-const unsigned char bin_literal<bytes<Bytes...>>::data[sizeof...(Bytes)]- = { Bytes... };--template <unsigned char... Bytes, char Bit7, char Bit6, char Bit5,- char Bit4, char Bit3, char Bit2, char Bit1, char Bit0, char... Chars>-struct bin_literal<bytes<Bytes...>, Bit7, Bit6,- Bit5, Bit4, Bit3, Bit2, Bit1, Bit0, Chars...> :- bin_literal<- bytes<Bytes...,- static_cast<unsigned char>(- (Bit7 == '1' ? 0x80 : 0) |- (Bit6 == '1' ? 0x40 : 0) |- (Bit5 == '1' ? 0x20 : 0) |- (Bit4 == '1' ? 0x10 : 0) |- (Bit3 == '1' ? 0x08 : 0) |- (Bit2 == '1' ? 0x04 : 0) |- (Bit1 == '1' ? 0x02 : 0) |- (Bit0 == '1' ? 0x01 : 0))- >, Chars...> {};--template <unsigned char... Bytes, char... Chars>-struct bin_literal<bytes<Bytes...>, Chars...>-{- static_assert(sizeof...(Chars) == 0,- "number of digits in a binary buffer literal must be a multiple of 8");-- static const std::size_t size = 0;- static const unsigned char data[1];-};--template <unsigned char... Bytes, char... Chars>-const unsigned char bin_literal<bytes<Bytes...>, Chars...>::data[1] = {};--// Literal processor that converts hexadecimal literals to an array of bytes.--template <typename Bytes, char... Chars>-struct hex_literal;--template <unsigned char... Bytes>-struct hex_literal<bytes<Bytes...>>-{- static const std::size_t size = sizeof...(Bytes);- static const unsigned char data[sizeof...(Bytes)];-};--template <unsigned char... Bytes>-const unsigned char hex_literal<bytes<Bytes...>>::data[sizeof...(Bytes)]- = { Bytes... };--template <unsigned char... Bytes, char Hi, char Lo, char... Chars>-struct hex_literal<bytes<Bytes...>, Hi, Lo, Chars...> :- hex_literal<- bytes<Bytes...,- static_cast<unsigned char>(- Lo >= 'A' && Lo <= 'F' ? Lo - 'A' + 10 :- (Lo >= 'a' && Lo <= 'f' ? Lo - 'a' + 10 : Lo - '0')) |- ((static_cast<unsigned char>(- Hi >= 'A' && Hi <= 'F' ? Hi - 'A' + 10 :- (Hi >= 'a' && Hi <= 'f' ? Hi - 'a' + 10 : Hi - '0'))) << 4)- >, Chars...> {};--template <unsigned char... Bytes, char Char>-struct hex_literal<bytes<Bytes...>, Char>-{- static_assert(!Char,- "a hexadecimal buffer literal must have an even number of digits");-- static const std::size_t size = 0;- static const unsigned char data[1];-};--template <unsigned char... Bytes, char Char>-const unsigned char hex_literal<bytes<Bytes...>, Char>::data[1] = {};--// Helper template that removes digit separators and then passes the cleaned-// variadic pack of characters to the literal processor.--template <template <typename, char...> class Literal,- typename Clean, char... Raw>-struct remove_separators;--template <template <typename, char...> class Literal,- char... Clean, char... Raw>-struct remove_separators<Literal, chars<Clean...>, '\'', Raw...> :- remove_separators<Literal, chars<Clean...>, Raw...> {};--template <template <typename, char...> class Literal,- char... Clean, char C, char... Raw>-struct remove_separators<Literal, chars<Clean...>, C, Raw...> :- remove_separators<Literal, chars<Clean..., C>, Raw...> {};--template <template <typename, char...> class Literal, char... Clean>-struct remove_separators<Literal, chars<Clean...>> :- Literal<bytes<>, Clean...> {};--// Helper template to determine the literal type based on the prefix.--template <char... Chars>-struct literal;--template <char... Chars>-struct literal<'0', 'b', Chars...> :- remove_separators<bin_literal, chars<>, Chars...>{};--template <char... Chars>-struct literal<'0', 'B', Chars...> :- remove_separators<bin_literal, chars<>, Chars...>{};--template <char... Chars>-struct literal<'0', 'x', Chars...> :- remove_separators<hex_literal, chars<>, Chars...>{};--template <char... Chars>-struct literal<'0', 'X', Chars...> :- remove_separators<hex_literal, chars<>, Chars...>{};--} // namespace detail--/// Literal operator for creating const_buffer objects from string literals.-inline const_buffer operator ""_buf(const char* data, std::size_t n)-{- return const_buffer(data, n);-}--/// Literal operator for creating const_buffer objects from unbounded binary or-/// hexadecimal integer literals.-template <char... Chars>-inline const_buffer operator ""_buf()-{- return const_buffer(- +detail::literal<Chars...>::data,- detail::literal<Chars...>::size);-}--} // namespace buffer_literals+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_BUFFER_HPP+#define ASIO_BUFFER_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include <cstddef>+#include <cstring>+#include <limits>+#include <stdexcept>+#include <string>+#include <vector>+#include "asio/detail/array_fwd.hpp"+#include "asio/detail/memory.hpp"+#include "asio/detail/string_view.hpp"+#include "asio/detail/throw_exception.hpp"+#include "asio/detail/type_traits.hpp"+#include "asio/is_contiguous_iterator.hpp"++#if defined(ASIO_MSVC) && (ASIO_MSVC >= 1700)+# if defined(_HAS_ITERATOR_DEBUGGING) && (_HAS_ITERATOR_DEBUGGING != 0)+# if !defined(ASIO_DISABLE_BUFFER_DEBUGGING)+# define ASIO_ENABLE_BUFFER_DEBUGGING+# endif // !defined(ASIO_DISABLE_BUFFER_DEBUGGING)+# endif // defined(_HAS_ITERATOR_DEBUGGING)+#endif // defined(ASIO_MSVC) && (ASIO_MSVC >= 1700)++#if defined(__GNUC__)+# if defined(_GLIBCXX_DEBUG)+# if !defined(ASIO_DISABLE_BUFFER_DEBUGGING)+# define ASIO_ENABLE_BUFFER_DEBUGGING+# endif // !defined(ASIO_DISABLE_BUFFER_DEBUGGING)+# endif // defined(_GLIBCXX_DEBUG)+#endif // defined(__GNUC__)++#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)+# include "asio/detail/functional.hpp"+#endif // ASIO_ENABLE_BUFFER_DEBUGGING++#if defined(ASIO_HAS_BOOST_WORKAROUND)+# include <boost/detail/workaround.hpp>+# if !defined(__clang__)+# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))+# define ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND+# endif // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))+# elif BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))+# define ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND+# endif // BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))+#endif // defined(ASIO_HAS_BOOST_WORKAROUND)++#if defined(ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND)+# include "asio/detail/type_traits.hpp"+#endif // defined(ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND)++#include "asio/detail/push_options.hpp"++namespace asio {++class mutable_buffer;+class const_buffer;++/// Holds a buffer that can be modified.+/**+ * The mutable_buffer class provides a safe representation of a buffer that can+ * be modified. It does not own the underlying data, and so is cheap to copy or+ * assign.+ *+ * @par Accessing Buffer Contents+ *+ * The contents of a buffer may be accessed using the @c data() and @c size()+ * member functions:+ *+ * @code asio::mutable_buffer b1 = ...;+ * std::size_t s1 = b1.size();+ * unsigned char* p1 = static_cast<unsigned char*>(b1.data());+ * @endcode+ *+ * 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() ASIO_NOEXCEPT+ : data_(0),+ size_(0)+ {+ }++ /// Construct a buffer to represent a given memory range.+ mutable_buffer(void* data, std::size_t size) ASIO_NOEXCEPT+ : data_(data),+ size_(size)+ {+ }++#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)+ mutable_buffer(void* data, std::size_t size,+ asio::detail::function<void()> debug_check)+ : data_(data),+ size_(size),+ debug_check_(debug_check)+ {+ }++ const asio::detail::function<void()>& get_debug_check() const+ {+ return debug_check_;+ }+#endif // ASIO_ENABLE_BUFFER_DEBUGGING++ /// Get a pointer to the beginning of the memory range.+ void* data() const ASIO_NOEXCEPT+ {+#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)+ if (size_ && debug_check_)+ debug_check_();+#endif // ASIO_ENABLE_BUFFER_DEBUGGING+ return data_;+ }++ /// Get the size of the memory range.+ std::size_t size() const ASIO_NOEXCEPT+ {+ return size_;+ }++ /// Move the start of the buffer by the specified number of bytes.+ mutable_buffer& operator+=(std::size_t n) 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_;++#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)+ asio::detail::function<void()> debug_check_;+#endif // ASIO_ENABLE_BUFFER_DEBUGGING+};++#if !defined(ASIO_NO_DEPRECATED)++/// (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+{+public:+ /// The type for each element in the list of buffers.+ typedef mutable_buffer value_type;++ /// A random-access iterator type that may be used to read elements.+ typedef const mutable_buffer* const_iterator;++ /// Construct to represent a given memory range.+ mutable_buffers_1(void* data, std::size_t size) ASIO_NOEXCEPT+ : mutable_buffer(data, size)+ {+ }++#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)+ mutable_buffers_1(void* data, std::size_t size,+ asio::detail::function<void()> debug_check)+ : mutable_buffer(data, size, debug_check)+ {+ }+#endif // ASIO_ENABLE_BUFFER_DEBUGGING++ /// Construct to represent a single modifiable buffer.+ explicit mutable_buffers_1(const mutable_buffer& b) ASIO_NOEXCEPT+ : mutable_buffer(b)+ {+ }++ /// Get a random-access iterator to the first element.+ const_iterator begin() const ASIO_NOEXCEPT+ {+ return this;+ }++ /// Get a random-access iterator for one past the last element.+ const_iterator end() const ASIO_NOEXCEPT+ {+ return begin() + 1;+ }+};++#endif // !defined(ASIO_NO_DEPRECATED)++/// Holds a buffer that cannot be modified.+/**+ * The const_buffer class provides a safe representation of a buffer that cannot+ * be modified. It does not own the underlying data, and so is cheap to copy or+ * assign.+ *+ * @par Accessing Buffer Contents+ *+ * The contents of a buffer may be accessed using the @c data() and @c size()+ * member functions:+ *+ * @code asio::const_buffer b1 = ...;+ * std::size_t s1 = b1.size();+ * const unsigned char* p1 = static_cast<const unsigned char*>(b1.data());+ * @endcode+ *+ * 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() ASIO_NOEXCEPT+ : data_(0),+ size_(0)+ {+ }++ /// Construct a buffer to represent a given memory range.+ const_buffer(const void* data, std::size_t size) ASIO_NOEXCEPT+ : data_(data),+ size_(size)+ {+ }++ /// Construct a non-modifiable buffer from a modifiable one.+ const_buffer(const mutable_buffer& b) ASIO_NOEXCEPT+ : data_(b.data()),+ size_(b.size())+#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)+ , debug_check_(b.get_debug_check())+#endif // ASIO_ENABLE_BUFFER_DEBUGGING+ {+ }++#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)+ const_buffer(const void* data, std::size_t size,+ asio::detail::function<void()> debug_check)+ : data_(data),+ size_(size),+ debug_check_(debug_check)+ {+ }++ const asio::detail::function<void()>& get_debug_check() const+ {+ return debug_check_;+ }+#endif // ASIO_ENABLE_BUFFER_DEBUGGING++ /// Get a pointer to the beginning of the memory range.+ const void* data() const ASIO_NOEXCEPT+ {+#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)+ if (size_ && debug_check_)+ debug_check_();+#endif // ASIO_ENABLE_BUFFER_DEBUGGING+ return data_;+ }++ /// Get the size of the memory range.+ std::size_t size() const ASIO_NOEXCEPT+ {+ return size_;+ }++ /// Move the start of the buffer by the specified number of bytes.+ const_buffer& operator+=(std::size_t n) 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_;++#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)+ asio::detail::function<void()> debug_check_;+#endif // ASIO_ENABLE_BUFFER_DEBUGGING+};++#if !defined(ASIO_NO_DEPRECATED)++/// (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+{+public:+ /// The type for each element in the list of buffers.+ typedef const_buffer value_type;++ /// A random-access iterator type that may be used to read elements.+ typedef const const_buffer* const_iterator;++ /// Construct to represent a given memory range.+ const_buffers_1(const void* data, std::size_t size) ASIO_NOEXCEPT+ : const_buffer(data, size)+ {+ }++#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)+ const_buffers_1(const void* data, std::size_t size,+ asio::detail::function<void()> debug_check)+ : const_buffer(data, size, debug_check)+ {+ }+#endif // ASIO_ENABLE_BUFFER_DEBUGGING++ /// Construct to represent a single non-modifiable buffer.+ explicit const_buffers_1(const const_buffer& b) ASIO_NOEXCEPT+ : const_buffer(b)+ {+ }++ /// Get a random-access iterator to the first element.+ const_iterator begin() const ASIO_NOEXCEPT+ {+ return this;+ }++ /// Get a random-access iterator for one past the last element.+ const_iterator end() const ASIO_NOEXCEPT+ {+ return begin() + 1;+ }+};++#endif // !defined(ASIO_NO_DEPRECATED)++/// (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:+ /// The type for each element in the list of buffers.+ typedef mutable_buffer value_type;++ /// A random-access iterator type that may be used to read elements.+ typedef const mutable_buffer* const_iterator;++ /// Get a random-access iterator to the first element.+ const_iterator begin() const ASIO_NOEXCEPT+ {+ return &buf_;+ }++ /// Get a random-access iterator for one past the last element.+ const_iterator end() const ASIO_NOEXCEPT+ {+ return &buf_;+ }++private:+ mutable_buffer buf_;+};++/** @defgroup buffer_sequence_begin asio::buffer_sequence_begin+ *+ * @brief The asio::buffer_sequence_begin function returns an iterator+ * pointing to the first element in a buffer sequence.+ */+/*@{*/++/// Get an iterator to the first element in a buffer sequence.+template <typename MutableBuffer>+inline const mutable_buffer* buffer_sequence_begin(const MutableBuffer& b,+ typename constraint<+ is_convertible<const MutableBuffer*, const mutable_buffer*>::value+ >::type = 0) ASIO_NOEXCEPT+{+ return static_cast<const mutable_buffer*>(detail::addressof(b));+}++/// Get an iterator to the first element in a buffer sequence.+template <typename ConstBuffer>+inline const const_buffer* buffer_sequence_begin(const ConstBuffer& b,+ typename constraint<+ is_convertible<const ConstBuffer*, const const_buffer*>::value+ >::type = 0) ASIO_NOEXCEPT+{+ return static_cast<const const_buffer*>(detail::addressof(b));+}++#if defined(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,+ typename constraint<+ !is_convertible<const C*, const mutable_buffer*>::value+ && !is_convertible<const C*, const const_buffer*>::value+ >::type = 0) ASIO_NOEXCEPT -> decltype(c.begin())+{+ return c.begin();+}++/// Get an iterator to the first element in a buffer sequence.+template <typename C>+inline auto buffer_sequence_begin(const C& c,+ typename constraint<+ !is_convertible<const C*, const mutable_buffer*>::value+ && !is_convertible<const C*, const const_buffer*>::value+ >::type = 0) ASIO_NOEXCEPT -> decltype(c.begin())+{+ return c.begin();+}++#else // defined(ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION)++template <typename C>+inline typename C::iterator buffer_sequence_begin(C& c,+ typename constraint<+ !is_convertible<const C*, const mutable_buffer*>::value+ && !is_convertible<const C*, const const_buffer*>::value+ >::type = 0) ASIO_NOEXCEPT+{+ return c.begin();+}++template <typename C>+inline typename C::const_iterator buffer_sequence_begin(const C& c,+ typename constraint<+ !is_convertible<const C*, const mutable_buffer*>::value+ && !is_convertible<const C*, const const_buffer*>::value+ >::type = 0) ASIO_NOEXCEPT+{+ return c.begin();+}++#endif // defined(ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION)++/*@}*/++/** @defgroup buffer_sequence_end asio::buffer_sequence_end+ *+ * @brief The 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.+template <typename MutableBuffer>+inline const mutable_buffer* buffer_sequence_end(const MutableBuffer& b,+ typename constraint<+ is_convertible<const MutableBuffer*, const mutable_buffer*>::value+ >::type = 0) ASIO_NOEXCEPT+{+ return static_cast<const mutable_buffer*>(detail::addressof(b)) + 1;+}++/// Get an iterator to one past the end element in a buffer sequence.+template <typename ConstBuffer>+inline const const_buffer* buffer_sequence_end(const ConstBuffer& b,+ typename constraint<+ is_convertible<const ConstBuffer*, const const_buffer*>::value+ >::type = 0) ASIO_NOEXCEPT+{+ return static_cast<const const_buffer*>(detail::addressof(b)) + 1;+}++#if defined(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,+ typename constraint<+ !is_convertible<const C*, const mutable_buffer*>::value+ && !is_convertible<const C*, const const_buffer*>::value+ >::type = 0) ASIO_NOEXCEPT -> 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,+ typename constraint<+ !is_convertible<const C*, const mutable_buffer*>::value+ && !is_convertible<const C*, const const_buffer*>::value+ >::type = 0) ASIO_NOEXCEPT -> decltype(c.end())+{+ return c.end();+}++#else // defined(ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION)++template <typename C>+inline typename C::iterator buffer_sequence_end(C& c,+ typename constraint<+ !is_convertible<const C*, const mutable_buffer*>::value+ && !is_convertible<const C*, const const_buffer*>::value+ >::type = 0) ASIO_NOEXCEPT+{+ return c.end();+}++template <typename C>+inline typename C::const_iterator buffer_sequence_end(const C& c,+ typename constraint<+ !is_convertible<const C*, const mutable_buffer*>::value+ && !is_convertible<const C*, const const_buffer*>::value+ >::type = 0) ASIO_NOEXCEPT+{+ return c.end();+}++#endif // defined(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>+struct buffer_sequence_cardinality :+ conditional<+ is_same<BufferSequence, mutable_buffer>::value+#if !defined(ASIO_NO_DEPRECATED)+ || is_same<BufferSequence, mutable_buffers_1>::value+ || is_same<BufferSequence, const_buffers_1>::value+#endif // !defined(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) ASIO_NOEXCEPT+{+ return const_buffer(*begin).size();+}++template <typename Iterator>+inline std::size_t buffer_size(multiple_buffers,+ Iterator begin, Iterator end) ASIO_NOEXCEPT+{+ std::size_t total_buffer_size = 0;++ Iterator iter = begin;+ for (; iter != end; ++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 = asio::buffer_sequence_begin(buffers);+ * auto end = asio::buffer_sequence_end(buffers);+ * for (; i != end; ++i)+ * {+ * const_buffer b(*i);+ * total_size += b.size();+ * }+ * return total_size; @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) ASIO_NOEXCEPT+{+ return detail::buffer_size(+ detail::buffer_sequence_cardinality<BufferSequence>(),+ asio::buffer_sequence_begin(b),+ asio::buffer_sequence_end(b));+}++#if !defined(ASIO_NO_DEPRECATED)++/** @defgroup buffer_cast asio::buffer_cast+ *+ * @brief (Deprecated: Use the @c data() member function.) The+ * asio::buffer_cast function is used to obtain a pointer to the+ * underlying memory region associated with a buffer.+ *+ * @par Examples:+ *+ * To access the memory of a non-modifiable buffer, use:+ * @code asio::const_buffer b1 = ...;+ * const unsigned char* p1 = asio::buffer_cast<const unsigned char*>(b1);+ * @endcode+ *+ * To access the memory of a modifiable buffer, use:+ * @code asio::mutable_buffer b2 = ...;+ * unsigned char* p2 = asio::buffer_cast<unsigned char*>(b2);+ * @endcode+ *+ * The asio::buffer_cast function permits violations of type safety, so+ * uses of it in application code should be carefully considered.+ */+/*@{*/++/// Cast a non-modifiable buffer to a specified pointer to POD type.+template <typename PointerToPodType>+inline PointerToPodType buffer_cast(const mutable_buffer& b) ASIO_NOEXCEPT+{+ 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) ASIO_NOEXCEPT+{+ return static_cast<PointerToPodType>(b.data());+}++/*@}*/++#endif // !defined(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 n) ASIO_NOEXCEPT+{+ 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(ASIO_ENABLE_BUFFER_DEBUGGING)+ , b.get_debug_check()+#endif // ASIO_ENABLE_BUFFER_DEBUGGING+ );+}++/// Create a new modifiable buffer that is offset from the start of another.+/**+ * @relates mutable_buffer+ */+inline mutable_buffer operator+(std::size_t n,+ const mutable_buffer& b) ASIO_NOEXCEPT+{+ 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 n) ASIO_NOEXCEPT+{+ 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(ASIO_ENABLE_BUFFER_DEBUGGING)+ , b.get_debug_check()+#endif // ASIO_ENABLE_BUFFER_DEBUGGING+ );+}++/// Create a new non-modifiable buffer that is offset from the start of another.+/**+ * @relates const_buffer+ */+inline const_buffer operator+(std::size_t n,+ const const_buffer& b) ASIO_NOEXCEPT+{+ return b + n;+}++#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)+namespace detail {++template <typename Iterator>+class buffer_debug_check+{+public:+ buffer_debug_check(Iterator iter)+ : iter_(iter)+ {+ }++ ~buffer_debug_check()+ {+#if defined(ASIO_MSVC) && (ASIO_MSVC == 1400)+ // MSVC 8's string iterator checking may crash in a std::string::iterator+ // object's destructor when the iterator points to an already-destroyed+ // std::string object, unless the iterator is cleared first.+ iter_ = Iterator();+#endif // defined(ASIO_MSVC) && (ASIO_MSVC == 1400)+ }++ void operator()()+ {+ (void)*iter_;+ }++private:+ Iterator iter_;+};++} // namespace detail+#endif // ASIO_ENABLE_BUFFER_DEBUGGING++/** @defgroup buffer asio::buffer+ *+ * @brief The asio::buffer function is used to create a buffer object to+ * represent raw memory, an array of POD elements, a vector of POD elements,+ * or a std::string.+ *+ * A buffer object represents a contiguous region of memory as a 2-tuple+ * consisting of a pointer and size in bytes. A tuple of the form <tt>{void*,+ * size_t}</tt> specifies a mutable (modifiable) region of memory. Similarly, a+ * tuple of the form <tt>{const void*, size_t}</tt> specifies a const+ * (non-modifiable) region of memory. These two forms correspond to the classes+ * mutable_buffer and const_buffer, respectively. To mirror C++'s conversion+ * rules, a mutable_buffer is implicitly convertible to a const_buffer, and the+ * opposite conversion is not permitted.+ *+ * The simplest use case involves reading or writing a single buffer of a+ * specified size:+ *+ * @code sock.send(asio::buffer(data, size)); @endcode+ *+ * In the above example, the return value of asio::buffer meets the+ * requirements of the ConstBufferSequence concept so that it may be directly+ * passed to the socket's write function. A buffer created for modifiable+ * memory also meets the requirements of the MutableBufferSequence concept.+ *+ * An individual buffer may be created from a builtin array, std::vector,+ * std::array or boost::array of POD elements. This helps prevent buffer+ * overruns by automatically determining the size of the buffer:+ *+ * @code char d1[128];+ * size_t bytes_transferred = sock.receive(asio::buffer(d1));+ *+ * std::vector<char> d2(128);+ * bytes_transferred = sock.receive(asio::buffer(d2));+ *+ * std::array<char, 128> d3;+ * bytes_transferred = sock.receive(asio::buffer(d3));+ *+ * boost::array<char, 128> d4;+ * bytes_transferred = sock.receive(asio::buffer(d4)); @endcode+ *+ * In all three cases above, the buffers created are exactly 128 bytes long.+ * Note that a vector is @e never automatically resized when creating or using+ * a buffer. The buffer size is determined using the vector's <tt>size()</tt>+ * member function, and not its capacity.+ *+ * @par Accessing Buffer Contents+ *+ * The contents of a buffer may be accessed using the @c data() and @c size()+ * member functions:+ *+ * @code asio::mutable_buffer b1 = ...;+ * std::size_t s1 = b1.size();+ * unsigned char* p1 = static_cast<unsigned char*>(b1.data());+ *+ * asio::const_buffer b2 = ...;+ * std::size_t s2 = b2.size();+ * const void* p2 = b2.data(); @endcode+ *+ * The @c data() member function permits violations of type safety, so+ * uses of it in application code should be carefully considered.+ *+ * 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 function, the @ref+ * buffer_copy function can be used to linearise a sequence of buffers. For+ * example:+ *+ * @code vector<const_buffer> buffers = ...;+ *+ * vector<unsigned char> data(asio::buffer_size(buffers));+ * asio::buffer_copy(asio::buffer(data), buffers); @endcode+ *+ * Note that @ref buffer_copy is implemented in terms of @c memcpy, and+ * consequently it cannot be used to copy between overlapping memory regions.+ *+ * @par Buffer Invalidation+ *+ * A buffer object does not have any ownership of the memory it refers to. It+ * is the responsibility of the application to ensure the memory region remains+ * valid until it is no longer required for an I/O operation. When the memory+ * is no longer available, the buffer is said to have been invalidated.+ *+ * For the asio::buffer overloads that accept an argument of type+ * std::vector, the buffer objects returned are invalidated by any vector+ * operation that also invalidates all references, pointers and iterators+ * referring to the elements in the sequence (C++ Std, 23.2.4)+ *+ * For the asio::buffer overloads that accept an argument of type+ * std::basic_string, the buffer objects returned are invalidated according to+ * the rules defined for invalidation of references, pointers and iterators+ * referring to elements of the sequence (C++ Std, 21.3).+ *+ * @par Buffer Arithmetic+ *+ * Buffer objects may be manipulated using simple arithmetic in a safe way+ * which helps prevent buffer overruns. Consider an array initialised as+ * follows:+ *+ * @code boost::array<char, 6> a = { 'a', 'b', 'c', 'd', 'e' }; @endcode+ *+ * A buffer object @c b1 created using:+ *+ * @code b1 = asio::buffer(a); @endcode+ *+ * represents the entire array, <tt>{ 'a', 'b', 'c', 'd', 'e' }</tt>. An+ * optional second argument to the asio::buffer function may be used to+ * limit the size, in bytes, of the buffer:+ *+ * @code b2 = asio::buffer(a, 3); @endcode+ *+ * such that @c b2 represents the data <tt>{ 'a', 'b', 'c' }</tt>. Even if the+ * size argument exceeds the actual size of the array, the size of the buffer+ * object created will be limited to the array size.+ *+ * An offset may be applied to an existing buffer to create a new one:+ *+ * @code b3 = b1 + 2; @endcode+ *+ * where @c b3 will set to represent <tt>{ 'c', 'd', 'e' }</tt>. If the offset+ * exceeds the size of the existing buffer, the newly created buffer will be+ * empty.+ *+ * Both an offset and size may be specified to create a buffer that corresponds+ * to a specific range of bytes within an existing buffer:+ *+ * @code b4 = asio::buffer(b1 + 1, 3); @endcode+ *+ * so that @c b4 will refer to the bytes <tt>{ 'b', 'c', 'd' }</tt>.+ *+ * @par Buffers and Scatter-Gather I/O+ *+ * To read or write using multiple buffers (i.e. scatter-gather I/O), multiple+ * buffer objects may be assigned into a container that supports the+ * MutableBufferSequence (for read) or ConstBufferSequence (for write) concepts:+ *+ * @code+ * char d1[128];+ * std::vector<char> d2(128);+ * boost::array<char, 128> d3;+ *+ * boost::array<mutable_buffer, 3> bufs1 = {+ * asio::buffer(d1),+ * asio::buffer(d2),+ * asio::buffer(d3) };+ * bytes_transferred = sock.receive(bufs1);+ *+ * std::vector<const_buffer> bufs2;+ * bufs2.push_back(asio::buffer(d1));+ * bufs2.push_back(asio::buffer(d2));+ * bufs2.push_back(asio::buffer(d3));+ * bytes_transferred = sock.send(bufs2); @endcode+ *+ * @par Buffer Literals+ *+ * The `_buf` literal suffix, defined in namespace+ * <tt>asio::buffer_literals</tt>, may be used to create @c const_buffer+ * objects from string, binary integer, and hexadecimal integer literals.+ * For example:+ *+ * @code+ * using namespace asio::buffer_literals;+ *+ * asio::const_buffer b1 = "hello"_buf;+ * asio::const_buffer b2 = 0xdeadbeef_buf;+ * asio::const_buffer b3 = 0x0123456789abcdef0123456789abcdef_buf;+ * asio::const_buffer b4 = 0b1010101011001100_buf; @endcode+ *+ * Note that the memory associated with a buffer literal is valid for the+ * lifetime of the program. This means that the buffer can be safely used with+ * asynchronous operations.+ */+/*@{*/++#if defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)+# define ASIO_MUTABLE_BUFFER mutable_buffer+# define ASIO_CONST_BUFFER const_buffer+#else // defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)+# define ASIO_MUTABLE_BUFFER mutable_buffers_1+# define ASIO_CONST_BUFFER const_buffers_1+#endif // defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)++/// Create a new modifiable buffer from an existing buffer.+/**+ * @returns <tt>mutable_buffer(b)</tt>.+ */+ASIO_NODISCARD inline ASIO_MUTABLE_BUFFER buffer(+ const mutable_buffer& b) ASIO_NOEXCEPT+{+ return ASIO_MUTABLE_BUFFER(b);+}++/// Create a new modifiable buffer from an existing buffer.+/**+ * @returns A mutable_buffer value equivalent to:+ * @code mutable_buffer(+ * b.data(),+ * min(b.size(), max_size_in_bytes)); @endcode+ */+ASIO_NODISCARD inline ASIO_MUTABLE_BUFFER buffer(+ const mutable_buffer& b,+ std::size_t max_size_in_bytes) ASIO_NOEXCEPT+{+ return ASIO_MUTABLE_BUFFER(+ mutable_buffer(b.data(),+ b.size() < max_size_in_bytes+ ? b.size() : max_size_in_bytes+#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)+ , b.get_debug_check()+#endif // ASIO_ENABLE_BUFFER_DEBUGGING+ ));+}++/// Create a new non-modifiable buffer from an existing buffer.+/**+ * @returns <tt>const_buffer(b)</tt>.+ */+ASIO_NODISCARD inline ASIO_CONST_BUFFER buffer(+ const const_buffer& b) ASIO_NOEXCEPT+{+ return ASIO_CONST_BUFFER(b);+}++/// Create a new non-modifiable buffer from an existing buffer.+/**+ * @returns A const_buffer value equivalent to:+ * @code const_buffer(+ * b.data(),+ * min(b.size(), max_size_in_bytes)); @endcode+ */+ASIO_NODISCARD inline ASIO_CONST_BUFFER buffer(+ const const_buffer& b,+ std::size_t max_size_in_bytes) ASIO_NOEXCEPT+{+ return ASIO_CONST_BUFFER(b.data(),+ b.size() < max_size_in_bytes+ ? b.size() : max_size_in_bytes+#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)+ , b.get_debug_check()+#endif // ASIO_ENABLE_BUFFER_DEBUGGING+ );+}++/// Create a new modifiable buffer that represents the given memory range.+/**+ * @returns <tt>mutable_buffer(data, size_in_bytes)</tt>.+ */+ASIO_NODISCARD inline ASIO_MUTABLE_BUFFER buffer(+ void* data, std::size_t size_in_bytes) ASIO_NOEXCEPT+{+ return ASIO_MUTABLE_BUFFER(data, size_in_bytes);+}++/// Create a new non-modifiable buffer that represents the given memory range.+/**+ * @returns <tt>const_buffer(data, size_in_bytes)</tt>.+ */+ASIO_NODISCARD inline ASIO_CONST_BUFFER buffer(+ const void* data, std::size_t size_in_bytes) ASIO_NOEXCEPT+{+ return ASIO_CONST_BUFFER(data, size_in_bytes);+}++/// Create a new modifiable buffer that represents the given POD array.+/**+ * @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>+ASIO_NODISCARD inline ASIO_MUTABLE_BUFFER buffer(+ PodType (&data)[N]) ASIO_NOEXCEPT+{+ return ASIO_MUTABLE_BUFFER(data, N * sizeof(PodType));+}+ +/// Create a new modifiable buffer that represents the given POD array.+/**+ * @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>+ASIO_NODISCARD inline ASIO_MUTABLE_BUFFER buffer(+ PodType (&data)[N],+ std::size_t max_size_in_bytes) ASIO_NOEXCEPT+{+ return 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_buffer value equivalent to:+ * @code const_buffer(+ * static_cast<const void*>(data),+ * N * sizeof(PodType)); @endcode+ */+template <typename PodType, std::size_t N>+ASIO_NODISCARD inline ASIO_CONST_BUFFER buffer(+ const PodType (&data)[N]) ASIO_NOEXCEPT+{+ return ASIO_CONST_BUFFER(data, N * sizeof(PodType));+}++/// Create a new non-modifiable buffer that represents the given POD array.+/**+ * @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>+ASIO_NODISCARD inline ASIO_CONST_BUFFER buffer(+ const PodType (&data)[N],+ std::size_t max_size_in_bytes) ASIO_NOEXCEPT+{+ return ASIO_CONST_BUFFER(data,+ N * sizeof(PodType) < max_size_in_bytes+ ? N * sizeof(PodType) : max_size_in_bytes);+}++#if defined(ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND)++// Borland C++ and Sun Studio think the overloads:+//+// unspecified buffer(boost::array<PodType, N>& array ...);+//+// and+//+// unspecified buffer(boost::array<const PodType, N>& array ...);+//+// are ambiguous. This will be worked around by using a buffer_types traits+// class that contains typedefs for the appropriate buffer and container+// classes, based on whether PodType is const or non-const.++namespace detail {++template <bool IsConst>+struct buffer_types_base;++template <>+struct buffer_types_base<false>+{+ typedef mutable_buffer buffer_type;+ typedef ASIO_MUTABLE_BUFFER container_type;+};++template <>+struct buffer_types_base<true>+{+ typedef const_buffer buffer_type;+ typedef ASIO_CONST_BUFFER container_type;+};++template <typename PodType>+struct buffer_types+ : public buffer_types_base<is_const<PodType>::value>+{+};++} // namespace detail++template <typename PodType, std::size_t N>+ASIO_NODISCARD inline+typename detail::buffer_types<PodType>::container_type+buffer(boost::array<PodType, N>& data) ASIO_NOEXCEPT+{+ typedef typename asio::detail::buffer_types<PodType>::buffer_type+ buffer_type;+ typedef typename asio::detail::buffer_types<PodType>::container_type+ container_type;+ return container_type(+ buffer_type(data.c_array(), data.size() * sizeof(PodType)));+}++template <typename PodType, std::size_t N>+ASIO_NODISCARD inline+typename detail::buffer_types<PodType>::container_type+buffer(boost::array<PodType, N>& data,+ std::size_t max_size_in_bytes) ASIO_NOEXCEPT+{+ typedef typename asio::detail::buffer_types<PodType>::buffer_type+ buffer_type;+ typedef typename asio::detail::buffer_types<PodType>::container_type+ container_type;+ return container_type(+ buffer_type(data.c_array(),+ data.size() * sizeof(PodType) < max_size_in_bytes+ ? data.size() * sizeof(PodType) : max_size_in_bytes));+}++#else // defined(ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND)++/// Create a new modifiable buffer that represents the given POD array.+/**+ * @returns A mutable_buffer value equivalent to:+ * @code mutable_buffer(+ * data.data(),+ * data.size() * sizeof(PodType)); @endcode+ */+template <typename PodType, std::size_t N>+ASIO_NODISCARD inline ASIO_MUTABLE_BUFFER buffer(+ boost::array<PodType, N>& data) ASIO_NOEXCEPT+{+ return ASIO_MUTABLE_BUFFER(+ data.c_array(), data.size() * sizeof(PodType));+}++/// Create a new modifiable buffer that represents the given POD array.+/**+ * @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>+ASIO_NODISCARD inline ASIO_MUTABLE_BUFFER buffer(+ boost::array<PodType, N>& data,+ std::size_t max_size_in_bytes) ASIO_NOEXCEPT+{+ return 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_buffer value equivalent to:+ * @code const_buffer(+ * data.data(),+ * data.size() * sizeof(PodType)); @endcode+ */+template <typename PodType, std::size_t N>+ASIO_NODISCARD inline ASIO_CONST_BUFFER buffer(+ boost::array<const PodType, N>& data) ASIO_NOEXCEPT+{+ return ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(PodType));+}++/// Create a new non-modifiable buffer that represents the given POD array.+/**+ * @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>+ASIO_NODISCARD inline ASIO_CONST_BUFFER buffer(+ boost::array<const PodType, N>& data,+ std::size_t max_size_in_bytes) ASIO_NOEXCEPT+{+ return ASIO_CONST_BUFFER(data.data(),+ data.size() * sizeof(PodType) < max_size_in_bytes+ ? data.size() * sizeof(PodType) : max_size_in_bytes);+}++#endif // defined(ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND)++/// Create a new non-modifiable buffer that represents the given POD array.+/**+ * @returns A const_buffer value equivalent to:+ * @code const_buffer(+ * data.data(),+ * data.size() * sizeof(PodType)); @endcode+ */+template <typename PodType, std::size_t N>+ASIO_NODISCARD inline ASIO_CONST_BUFFER buffer(+ const boost::array<PodType, N>& data) ASIO_NOEXCEPT+{+ return ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(PodType));+}++/// Create a new non-modifiable buffer that represents the given POD array.+/**+ * @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>+ASIO_NODISCARD inline ASIO_CONST_BUFFER buffer(+ const boost::array<PodType, N>& data,+ std::size_t max_size_in_bytes) ASIO_NOEXCEPT+{+ return ASIO_CONST_BUFFER(data.data(),+ data.size() * sizeof(PodType) < max_size_in_bytes+ ? data.size() * sizeof(PodType) : max_size_in_bytes);+}++#if defined(ASIO_HAS_STD_ARRAY) || defined(GENERATING_DOCUMENTATION)++/// Create a new modifiable buffer that represents the given POD array.+/**+ * @returns A mutable_buffer value equivalent to:+ * @code mutable_buffer(+ * data.data(),+ * data.size() * sizeof(PodType)); @endcode+ */+template <typename PodType, std::size_t N>+ASIO_NODISCARD inline ASIO_MUTABLE_BUFFER buffer(+ std::array<PodType, N>& data) ASIO_NOEXCEPT+{+ return ASIO_MUTABLE_BUFFER(data.data(), data.size() * sizeof(PodType));+}++/// Create a new modifiable buffer that represents the given POD array.+/**+ * @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>+ASIO_NODISCARD inline ASIO_MUTABLE_BUFFER buffer(+ std::array<PodType, N>& data,+ std::size_t max_size_in_bytes) ASIO_NOEXCEPT+{+ return 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_buffer value equivalent to:+ * @code const_buffer(+ * data.data(),+ * data.size() * sizeof(PodType)); @endcode+ */+template <typename PodType, std::size_t N>+ASIO_NODISCARD inline ASIO_CONST_BUFFER buffer(+ std::array<const PodType, N>& data) ASIO_NOEXCEPT+{+ return ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(PodType));+}++/// Create a new non-modifiable buffer that represents the given POD array.+/**+ * @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>+ASIO_NODISCARD inline ASIO_CONST_BUFFER buffer(+ std::array<const PodType, N>& data,+ std::size_t max_size_in_bytes) ASIO_NOEXCEPT+{+ return 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_buffer value equivalent to:+ * @code const_buffer(+ * data.data(),+ * data.size() * sizeof(PodType)); @endcode+ */+template <typename PodType, std::size_t N>+ASIO_NODISCARD inline ASIO_CONST_BUFFER buffer(+ const std::array<PodType, N>& data) ASIO_NOEXCEPT+{+ return ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(PodType));+}++/// Create a new non-modifiable buffer that represents the given POD array.+/**+ * @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>+ASIO_NODISCARD inline ASIO_CONST_BUFFER buffer(+ const std::array<PodType, N>& data,+ std::size_t max_size_in_bytes) ASIO_NOEXCEPT+{+ return ASIO_CONST_BUFFER(data.data(),+ data.size() * sizeof(PodType) < max_size_in_bytes+ ? data.size() * sizeof(PodType) : max_size_in_bytes);+}++#endif // defined(ASIO_HAS_STD_ARRAY) || defined(GENERATING_DOCUMENTATION)++/// Create a new modifiable buffer that represents the given POD vector.+/**+ * @returns A mutable_buffer value equivalent to:+ * @code mutable_buffer(+ * data.size() ? &data[0] : 0,+ * data.size() * sizeof(PodType)); @endcode+ *+ * @note The buffer is invalidated by any vector operation that would also+ * invalidate iterators.+ */+template <typename PodType, typename Allocator>+ASIO_NODISCARD inline ASIO_MUTABLE_BUFFER buffer(+ std::vector<PodType, Allocator>& data) ASIO_NOEXCEPT+{+ return ASIO_MUTABLE_BUFFER(+ data.size() ? &data[0] : 0, data.size() * sizeof(PodType)+#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)+ , detail::buffer_debug_check<+ typename std::vector<PodType, Allocator>::iterator+ >(data.begin())+#endif // ASIO_ENABLE_BUFFER_DEBUGGING+ );+}++/// Create a new modifiable buffer that represents the given POD vector.+/**+ * @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+ *+ * @note The buffer is invalidated by any vector operation that would also+ * invalidate iterators.+ */+template <typename PodType, typename Allocator>+ASIO_NODISCARD inline ASIO_MUTABLE_BUFFER buffer(+ std::vector<PodType, Allocator>& data,+ std::size_t max_size_in_bytes) ASIO_NOEXCEPT+{+ return 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(ASIO_ENABLE_BUFFER_DEBUGGING)+ , detail::buffer_debug_check<+ typename std::vector<PodType, Allocator>::iterator+ >(data.begin())+#endif // ASIO_ENABLE_BUFFER_DEBUGGING+ );+}++/// Create a new non-modifiable buffer that represents the given POD vector.+/**+ * @returns A const_buffer value equivalent to:+ * @code const_buffer(+ * data.size() ? &data[0] : 0,+ * data.size() * sizeof(PodType)); @endcode+ *+ * @note The buffer is invalidated by any vector operation that would also+ * invalidate iterators.+ */+template <typename PodType, typename Allocator>+ASIO_NODISCARD inline ASIO_CONST_BUFFER buffer(+ const std::vector<PodType, Allocator>& data) ASIO_NOEXCEPT+{+ return ASIO_CONST_BUFFER(+ data.size() ? &data[0] : 0, data.size() * sizeof(PodType)+#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)+ , detail::buffer_debug_check<+ typename std::vector<PodType, Allocator>::const_iterator+ >(data.begin())+#endif // ASIO_ENABLE_BUFFER_DEBUGGING+ );+}++/// Create a new non-modifiable buffer that represents the given POD vector.+/**+ * @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+ *+ * @note The buffer is invalidated by any vector operation that would also+ * invalidate iterators.+ */+template <typename PodType, typename Allocator>+ASIO_NODISCARD inline ASIO_CONST_BUFFER buffer(+ const std::vector<PodType, Allocator>& data,+ std::size_t max_size_in_bytes) ASIO_NOEXCEPT+{+ return 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(ASIO_ENABLE_BUFFER_DEBUGGING)+ , detail::buffer_debug_check<+ typename std::vector<PodType, Allocator>::const_iterator+ >(data.begin())+#endif // ASIO_ENABLE_BUFFER_DEBUGGING+ );+}++/// Create a new modifiable buffer that represents the given string.+/**+ * @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>+ASIO_NODISCARD inline ASIO_MUTABLE_BUFFER buffer(+ std::basic_string<Elem, Traits, Allocator>& data) ASIO_NOEXCEPT+{+ return ASIO_MUTABLE_BUFFER(data.size() ? &data[0] : 0,+ data.size() * sizeof(Elem)+#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)+ , detail::buffer_debug_check<+ typename std::basic_string<Elem, Traits, Allocator>::iterator+ >(data.begin())+#endif // ASIO_ENABLE_BUFFER_DEBUGGING+ );+}++/// Create a new modifiable buffer that represents the given string.+/**+ * @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>+ASIO_NODISCARD inline ASIO_MUTABLE_BUFFER buffer(+ std::basic_string<Elem, Traits, Allocator>& data,+ std::size_t max_size_in_bytes) ASIO_NOEXCEPT+{+ return 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(ASIO_ENABLE_BUFFER_DEBUGGING)+ , detail::buffer_debug_check<+ typename std::basic_string<Elem, Traits, Allocator>::iterator+ >(data.begin())+#endif // ASIO_ENABLE_BUFFER_DEBUGGING+ );+}++/// Create a new non-modifiable buffer that represents the given string.+/**+ * @returns <tt>const_buffer(data.data(), 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>+ASIO_NODISCARD inline ASIO_CONST_BUFFER buffer(+ const std::basic_string<Elem, Traits, Allocator>& data) ASIO_NOEXCEPT+{+ return ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(Elem)+#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)+ , detail::buffer_debug_check<+ typename std::basic_string<Elem, Traits, Allocator>::const_iterator+ >(data.begin())+#endif // ASIO_ENABLE_BUFFER_DEBUGGING+ );+}++/// Create a new non-modifiable buffer that represents the given string.+/**+ * @returns A const_buffer value equivalent to:+ * @code const_buffer(+ * data.data(),+ * 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>+ASIO_NODISCARD inline ASIO_CONST_BUFFER buffer(+ const std::basic_string<Elem, Traits, Allocator>& data,+ std::size_t max_size_in_bytes) ASIO_NOEXCEPT+{+ return ASIO_CONST_BUFFER(data.data(),+ data.size() * sizeof(Elem) < max_size_in_bytes+ ? data.size() * sizeof(Elem) : max_size_in_bytes+#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)+ , detail::buffer_debug_check<+ typename std::basic_string<Elem, Traits, Allocator>::const_iterator+ >(data.begin())+#endif // ASIO_ENABLE_BUFFER_DEBUGGING+ );+}++#if defined(ASIO_HAS_STRING_VIEW) \+ || defined(GENERATING_DOCUMENTATION)++/// Create a new non-modifiable buffer that represents the given string_view.+/**+ * @returns <tt>mutable_buffer(data.size() ? &data[0] : 0,+ * data.size() * sizeof(Elem))</tt>.+ */+template <typename Elem, typename Traits>+ASIO_NODISCARD inline ASIO_CONST_BUFFER buffer(+ basic_string_view<Elem, Traits> data) ASIO_NOEXCEPT+{+ return ASIO_CONST_BUFFER(data.size() ? &data[0] : 0,+ data.size() * sizeof(Elem)+#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)+ , detail::buffer_debug_check<+ typename basic_string_view<Elem, Traits>::iterator+ >(data.begin())+#endif // ASIO_ENABLE_BUFFER_DEBUGGING+ );+}++/// Create a new non-modifiable buffer that represents the given string.+/**+ * @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+ */+template <typename Elem, typename Traits>+ASIO_NODISCARD inline ASIO_CONST_BUFFER buffer(+ basic_string_view<Elem, Traits> data,+ std::size_t max_size_in_bytes) ASIO_NOEXCEPT+{+ return 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(ASIO_ENABLE_BUFFER_DEBUGGING)+ , detail::buffer_debug_check<+ typename basic_string_view<Elem, Traits>::iterator+ >(data.begin())+#endif // ASIO_ENABLE_BUFFER_DEBUGGING+ );+}++#endif // defined(ASIO_HAS_STRING_VIEW)+ // || defined(GENERATING_DOCUMENTATION)++/// Create a new modifiable buffer from a contiguous container.+/**+ * @returns A mutable_buffer value equivalent to:+ * @code mutable_buffer(+ * data.size() ? &data[0] : 0,+ * data.size() * sizeof(typename T::value_type)); @endcode+ */+template <typename T>+ASIO_NODISCARD inline ASIO_MUTABLE_BUFFER buffer(+ T& data,+ typename constraint<+ is_contiguous_iterator<typename T::iterator>::value,+ defaulted_constraint+ >::type = defaulted_constraint(),+ typename constraint<+ !is_convertible<T, const_buffer>::value,+ defaulted_constraint+ >::type = defaulted_constraint(),+ typename constraint<+ !is_convertible<T, mutable_buffer>::value,+ defaulted_constraint+ >::type = defaulted_constraint(),+ typename constraint<+ !is_const<+ typename remove_reference<+ typename std::iterator_traits<typename T::iterator>::reference+ >::type+ >::value,+ defaulted_constraint+ >::type = defaulted_constraint()) ASIO_NOEXCEPT+{+ return ASIO_MUTABLE_BUFFER(+ data.size() ? detail::to_address(data.begin()) : 0,+ data.size() * sizeof(typename T::value_type));+}++/// Create a new modifiable buffer from a contiguous container.+/**+ * @returns A mutable_buffer value equivalent to:+ * @code mutable_buffer(+ * data.size() ? &data[0] : 0,+ * min(+ * data.size() * sizeof(typename T::value_type),+ * max_size_in_bytes)); @endcode+ */+template <typename T>+ASIO_NODISCARD inline ASIO_MUTABLE_BUFFER buffer(+ T& data, std::size_t max_size_in_bytes,+ typename constraint<+ is_contiguous_iterator<typename T::iterator>::value,+ defaulted_constraint+ >::type = defaulted_constraint(),+ typename constraint<+ !is_convertible<T, const_buffer>::value,+ defaulted_constraint+ >::type = defaulted_constraint(),+ typename constraint<+ !is_convertible<T, mutable_buffer>::value,+ defaulted_constraint+ >::type = defaulted_constraint(),+ typename constraint<+ !is_const<+ typename remove_reference<+ typename std::iterator_traits<typename T::iterator>::reference+ >::type+ >::value,+ defaulted_constraint+ >::type = defaulted_constraint()) ASIO_NOEXCEPT+{+ return ASIO_MUTABLE_BUFFER(+ data.size() ? detail::to_address(data.begin()) : 0,+ data.size() * sizeof(typename T::value_type) < max_size_in_bytes+ ? data.size() * sizeof(typename T::value_type) : max_size_in_bytes);+}++/// Create a new non-modifiable buffer from a contiguous container.+/**+ * @returns A const_buffer value equivalent to:+ * @code const_buffer(+ * data.size() ? &data[0] : 0,+ * data.size() * sizeof(typename T::value_type)); @endcode+ */+template <typename T>+ASIO_NODISCARD inline ASIO_CONST_BUFFER buffer(+ T& data,+ typename constraint<+ is_contiguous_iterator<typename T::iterator>::value,+ defaulted_constraint+ >::type = defaulted_constraint(),+ typename constraint<+ !is_convertible<T, const_buffer>::value,+ defaulted_constraint+ >::type = defaulted_constraint(),+ typename constraint<+ !is_convertible<T, mutable_buffer>::value,+ defaulted_constraint+ >::type = defaulted_constraint(),+ typename constraint<+ is_const<+ typename remove_reference<+ typename std::iterator_traits<typename T::iterator>::reference+ >::type+ >::value,+ defaulted_constraint+ >::type = defaulted_constraint()) ASIO_NOEXCEPT+{+ return ASIO_CONST_BUFFER(+ data.size() ? detail::to_address(data.begin()) : 0,+ data.size() * sizeof(typename T::value_type));+}++/// Create a new non-modifiable buffer from a contiguous container.+/**+ * @returns A const_buffer value equivalent to:+ * @code const_buffer(+ * data.size() ? &data[0] : 0,+ * min(+ * data.size() * sizeof(typename T::value_type),+ * max_size_in_bytes)); @endcode+ */+template <typename T>+ASIO_NODISCARD inline ASIO_CONST_BUFFER buffer(+ T& data, std::size_t max_size_in_bytes,+ typename constraint<+ is_contiguous_iterator<typename T::iterator>::value,+ defaulted_constraint+ >::type = defaulted_constraint(),+ typename constraint<+ !is_convertible<T, const_buffer>::value,+ defaulted_constraint+ >::type = defaulted_constraint(),+ typename constraint<+ !is_convertible<T, mutable_buffer>::value,+ defaulted_constraint+ >::type = defaulted_constraint(),+ typename constraint<+ is_const<+ typename remove_reference<+ typename std::iterator_traits<typename T::iterator>::reference+ >::type+ >::value,+ defaulted_constraint+ >::type = defaulted_constraint()) ASIO_NOEXCEPT+{+ return ASIO_CONST_BUFFER(+ data.size() ? detail::to_address(data.begin()) : 0,+ data.size() * sizeof(typename T::value_type) < max_size_in_bytes+ ? data.size() * sizeof(typename T::value_type) : max_size_in_bytes);+}++/// Create a new non-modifiable buffer from a contiguous container.+/**+ * @returns A const_buffer value equivalent to:+ * @code const_buffer(+ * data.size() ? &data[0] : 0,+ * data.size() * sizeof(typename T::value_type)); @endcode+ */+template <typename T>+ASIO_NODISCARD inline ASIO_CONST_BUFFER buffer(+ const T& data,+ typename constraint<+ is_contiguous_iterator<typename T::const_iterator>::value,+ defaulted_constraint+ >::type = defaulted_constraint(),+ typename constraint<+ !is_convertible<T, const_buffer>::value,+ defaulted_constraint+ >::type = defaulted_constraint(),+ typename constraint<+ !is_convertible<T, mutable_buffer>::value,+ defaulted_constraint+ >::type = defaulted_constraint()) ASIO_NOEXCEPT+{+ return ASIO_CONST_BUFFER(+ data.size() ? detail::to_address(data.begin()) : 0,+ data.size() * sizeof(typename T::value_type));+}++/// Create a new non-modifiable buffer from a contiguous container.+/**+ * @returns A const_buffer value equivalent to:+ * @code const_buffer(+ * data.size() ? &data[0] : 0,+ * min(+ * data.size() * sizeof(typename T::value_type),+ * max_size_in_bytes)); @endcode+ */+template <typename T>+ASIO_NODISCARD inline ASIO_CONST_BUFFER buffer(+ const T& data, std::size_t max_size_in_bytes,+ typename constraint<+ is_contiguous_iterator<typename T::const_iterator>::value,+ defaulted_constraint+ >::type = defaulted_constraint(),+ typename constraint<+ !is_convertible<T, const_buffer>::value,+ defaulted_constraint+ >::type = defaulted_constraint(),+ typename constraint<+ !is_convertible<T, mutable_buffer>::value,+ defaulted_constraint+ >::type = defaulted_constraint()) ASIO_NOEXCEPT+{+ return ASIO_CONST_BUFFER(+ data.size() ? detail::to_address(data.begin()) : 0,+ data.size() * sizeof(typename T::value_type) < max_size_in_bytes+ ? data.size() * sizeof(typename T::value_type) : max_size_in_bytes);+}++/*@}*/++/// Adapt a basic_string to the DynamicBuffer requirements.+/**+ * Requires that <tt>sizeof(Elem) == 1</tt>.+ */+template <typename Elem, typename Traits, typename Allocator>+class dynamic_string_buffer+{+public:+ /// The type used to represent a sequence of constant buffers that refers to+ /// the underlying memory.+ typedef ASIO_CONST_BUFFER const_buffers_type;++ /// The type used to represent a sequence of mutable buffers that refers to+ /// the underlying memory.+ typedef 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.+ * The object stores a reference to the string and the user is responsible+ * for ensuring that the string object remains valid while the+ * dynamic_string_buffer object, and copies of the object, are in use.+ *+ * @b DynamicBuffer_v1: Any existing data in the string is treated as the+ * dynamic buffer's input sequence.+ *+ * @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)()) ASIO_NOEXCEPT+ : string_(s),+#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+ size_((std::numeric_limits<std::size_t>::max)()),+#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+ max_size_(maximum_size)+ {+ }++ /// @b DynamicBuffer_v2: Copy construct a dynamic buffer.+ dynamic_string_buffer(const dynamic_string_buffer& other) ASIO_NOEXCEPT+ : string_(other.string_),+#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+ size_(other.size_),+#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+ max_size_(other.max_size_)+ {+ }++#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)+ /// Move construct a dynamic buffer.+ dynamic_string_buffer(dynamic_string_buffer&& other) ASIO_NOEXCEPT+ : string_(other.string_),+#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+ size_(other.size_),+#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+ max_size_(other.max_size_)+ {+ }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)++ /// @b DynamicBuffer_v1: Get the size of the input sequence.+ /// @b DynamicBuffer_v2: Get the current size of the underlying memory.+ /**+ * @returns @b DynamicBuffer_v1 The current size of the input sequence.+ * @b DynamicBuffer_v2: The current size of the underlying string if less than+ * max_size(). Otherwise returns max_size().+ */+ std::size_t size() const ASIO_NOEXCEPT+ {+#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+ if (size_ != (std::numeric_limits<std::size_t>::max)())+ return size_;+#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+ return (std::min)(string_.size(), max_size());+ }++ /// Get the maximum size of the dynamic buffer.+ /**+ * @returns The allowed maximum size of the underlying memory.+ */+ std::size_t max_size() const ASIO_NOEXCEPT+ {+ return max_size_;+ }++ /// Get the maximum size that the buffer may grow to without triggering+ /// reallocation.+ /**+ * @returns The current capacity of the underlying string if less than+ * max_size(). Otherwise returns max_size().+ */+ std::size_t capacity() const ASIO_NOEXCEPT+ {+ return (std::min)(string_.capacity(), max_size());+ }++#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+ /// @b DynamicBuffer_v1: 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+ * the input sequence.+ *+ * @note The returned object is invalidated by any @c dynamic_string_buffer+ * or @c basic_string member function that resizes or erases the string.+ */+ const_buffers_type data() const ASIO_NOEXCEPT+ {+ return const_buffers_type(asio::buffer(string_, size_));+ }+#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)++ /// @b DynamicBuffer_v2: Get a sequence of buffers that represents the+ /// underlying memory.+ /**+ * @param pos Position of the first byte to represent in the buffer sequence+ *+ * @param n The number of bytes to return in the buffer sequence. If the+ * underlying memory is shorter, the buffer sequence represents as many bytes+ * as are available.+ *+ * @returns An object of type @c mutable_buffers_type that satisfies+ * MutableBufferSequence requirements, representing the basic_string memory.+ *+ * @note The returned object is invalidated by any @c dynamic_string_buffer+ * or @c basic_string member function that resizes or erases the string.+ */+ mutable_buffers_type data(std::size_t pos, std::size_t n) ASIO_NOEXCEPT+ {+ return mutable_buffers_type(asio::buffer(+ asio::buffer(string_, max_size_) + pos, n));+ }++ /// @b DynamicBuffer_v2: Get a sequence of buffers that represents the+ /// underlying memory.+ /**+ * @param pos Position of the first byte to represent in the buffer sequence+ *+ * @param n The number of bytes to return in the buffer sequence. If the+ * underlying memory is shorter, the buffer sequence represents as many bytes+ * as are available.+ *+ * @note The returned object is invalidated by any @c dynamic_string_buffer+ * or @c basic_string member function that resizes or erases the string.+ */+ const_buffers_type data(std::size_t pos,+ std::size_t n) const ASIO_NOEXCEPT+ {+ return const_buffers_type(asio::buffer(+ asio::buffer(string_, max_size_) + pos, n));+ }++#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+ /// @b DynamicBuffer_v1: 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");+ asio::detail::throw_exception(ex);+ }++ if (size_ == (std::numeric_limits<std::size_t>::max)())+ size_ = string_.size(); // Enable v1 behaviour.++ string_.resize(size_ + n);++ return asio::buffer(asio::buffer(string_) + size_, n);+ }++ /// @b DynamicBuffer_v1: 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_);+ }+#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)++ /// @b DynamicBuffer_v2: Grow the underlying memory by the specified number of+ /// bytes.+ /**+ * Resizes the string to accommodate an additional @c n bytes at the end.+ *+ * @throws std::length_error If <tt>size() + n > max_size()</tt>.+ */+ void grow(std::size_t n)+ {+ if (size() > max_size() || max_size() - size() < n)+ {+ std::length_error ex("dynamic_string_buffer too long");+ asio::detail::throw_exception(ex);+ }++ string_.resize(size() + n);+ }++ /// @b DynamicBuffer_v2: Shrink the underlying memory by the specified number+ /// of bytes.+ /**+ * Erases @c n bytes from the end of the string by resizing the basic_string+ * object. If @c n is greater than the current size of the string, the string+ * is emptied.+ */+ void shrink(std::size_t n)+ {+ string_.resize(n > size() ? 0 : size() - n);+ }++ /// @b DynamicBuffer_v1: Remove characters from the input sequence.+ /// @b DynamicBuffer_v2: Consume the specified number of bytes from the+ /// beginning of the underlying memory.+ /**+ * @b DynamicBuffer_v1: 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.+ *+ * @b DynamicBuffer_v2: Erases @c n bytes from the beginning of the string.+ * If @c n is greater than the current size of the string, the string is+ * emptied.+ */+ void consume(std::size_t n)+ {+#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+ if (size_ != (std::numeric_limits<std::size_t>::max)())+ {+ std::size_t consume_length = (std::min)(n, size_);+ string_.erase(0, consume_length);+ size_ -= consume_length;+ return;+ }+#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+ string_.erase(0, n);+ }++private:+ std::basic_string<Elem, Traits, Allocator>& string_;+#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+ std::size_t size_;+#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+ const std::size_t max_size_;+};++/// Adapt a vector to the DynamicBuffer requirements.+/**+ * Requires that <tt>sizeof(Elem) == 1</tt>.+ */+template <typename Elem, typename Allocator>+class dynamic_vector_buffer+{+public:+ /// The type used to represent a sequence of constant buffers that refers to+ /// the underlying memory.+ typedef ASIO_CONST_BUFFER const_buffers_type;++ /// The type used to represent a sequence of mutable buffers that refers to+ /// the underlying memory.+ typedef ASIO_MUTABLE_BUFFER mutable_buffers_type;++ /// Construct a dynamic buffer from a vector.+ /**+ * @param v The vector to be used as backing storage for the dynamic buffer.+ * The object stores a reference to the vector and the user is responsible+ * for ensuring that the vector object remains valid while the+ * dynamic_vector_buffer object, and copies of the object, are in use.+ *+ * @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)()) ASIO_NOEXCEPT+ : vector_(v),+#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+ size_((std::numeric_limits<std::size_t>::max)()),+#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+ max_size_(maximum_size)+ {+ }++ /// @b DynamicBuffer_v2: Copy construct a dynamic buffer.+ dynamic_vector_buffer(const dynamic_vector_buffer& other) ASIO_NOEXCEPT+ : vector_(other.vector_),+#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+ size_(other.size_),+#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+ max_size_(other.max_size_)+ {+ }++#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)+ /// Move construct a dynamic buffer.+ dynamic_vector_buffer(dynamic_vector_buffer&& other) ASIO_NOEXCEPT+ : vector_(other.vector_),+#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+ size_(other.size_),+#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+ max_size_(other.max_size_)+ {+ }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)++ /// @b DynamicBuffer_v1: Get the size of the input sequence.+ /// @b DynamicBuffer_v2: Get the current size of the underlying memory.+ /**+ * @returns @b DynamicBuffer_v1 The current size of the input sequence.+ * @b DynamicBuffer_v2: The current size of the underlying vector if less than+ * max_size(). Otherwise returns max_size().+ */+ std::size_t size() const ASIO_NOEXCEPT+ {+#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+ if (size_ != (std::numeric_limits<std::size_t>::max)())+ return size_;+#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+ return (std::min)(vector_.size(), max_size());+ }++ /// Get the maximum size of the dynamic buffer.+ /**+ * @returns @b DynamicBuffer_v1: The allowed maximum of the sum of the sizes+ * of the input sequence and output sequence. @b DynamicBuffer_v2: The allowed+ * maximum size of the underlying memory.+ */+ std::size_t max_size() const ASIO_NOEXCEPT+ {+ return max_size_;+ }++ /// Get the maximum size that the buffer may grow to without triggering+ /// reallocation.+ /**+ * @returns @b DynamicBuffer_v1: The current total capacity of the buffer,+ * i.e. for both the input sequence and output sequence. @b DynamicBuffer_v2:+ * The current capacity of the underlying vector if less than max_size().+ * Otherwise returns max_size().+ */+ std::size_t capacity() const ASIO_NOEXCEPT+ {+ return (std::min)(vector_.capacity(), max_size());+ }++#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+ /// @b DynamicBuffer_v1: 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 vector memory in the+ * input sequence.+ *+ * @note The returned object is invalidated by any @c dynamic_vector_buffer+ * or @c vector member function that modifies the input sequence or output+ * sequence.+ */+ const_buffers_type data() const ASIO_NOEXCEPT+ {+ return const_buffers_type(asio::buffer(vector_, size_));+ }+#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)++ /// @b DynamicBuffer_v2: Get a sequence of buffers that represents the+ /// underlying memory.+ /**+ * @param pos Position of the first byte to represent in the buffer sequence+ *+ * @param n The number of bytes to return in the buffer sequence. If the+ * underlying memory is shorter, the buffer sequence represents as many bytes+ * as are available.+ *+ * @returns An object of type @c mutable_buffers_type that satisfies+ * MutableBufferSequence requirements, representing the vector memory.+ *+ * @note The returned object is invalidated by any @c dynamic_vector_buffer+ * or @c vector member function that resizes or erases the vector.+ */+ mutable_buffers_type data(std::size_t pos, std::size_t n) ASIO_NOEXCEPT+ {+ return mutable_buffers_type(asio::buffer(+ asio::buffer(vector_, max_size_) + pos, n));+ }++ /// @b DynamicBuffer_v2: Get a sequence of buffers that represents the+ /// underlying memory.+ /**+ * @param pos Position of the first byte to represent in the buffer sequence+ *+ * @param n The number of bytes to return in the buffer sequence. If the+ * underlying memory is shorter, the buffer sequence represents as many bytes+ * as are available.+ *+ * @note The returned object is invalidated by any @c dynamic_vector_buffer+ * or @c vector member function that resizes or erases the vector.+ */+ const_buffers_type data(std::size_t pos,+ std::size_t n) const ASIO_NOEXCEPT+ {+ return const_buffers_type(asio::buffer(+ asio::buffer(vector_, max_size_) + pos, n));+ }++#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+ /// @b DynamicBuffer_v1: 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+ * vector object as necessary.+ *+ * @returns An object of type @c mutable_buffers_type that satisfies+ * MutableBufferSequence requirements, representing vector 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 vector 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");+ asio::detail::throw_exception(ex);+ }++ if (size_ == (std::numeric_limits<std::size_t>::max)())+ size_ = vector_.size(); // Enable v1 behaviour.++ vector_.resize(size_ + n);++ return asio::buffer(asio::buffer(vector_) + size_, n);+ }++ /// @b DynamicBuffer_v1: 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_);+ }+#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)++ /// @b DynamicBuffer_v2: Grow the underlying memory by the specified number of+ /// bytes.+ /**+ * Resizes the vector to accommodate an additional @c n bytes at the end.+ *+ * @throws std::length_error If <tt>size() + n > max_size()</tt>.+ */+ void grow(std::size_t n)+ {+ if (size() > max_size() || max_size() - size() < n)+ {+ std::length_error ex("dynamic_vector_buffer too long");+ asio::detail::throw_exception(ex);+ }++ vector_.resize(size() + n);+ }++ /// @b DynamicBuffer_v2: Shrink the underlying memory by the specified number+ /// of bytes.+ /**+ * Erases @c n bytes from the end of the vector by resizing the vector+ * object. If @c n is greater than the current size of the vector, the vector+ * is emptied.+ */+ void shrink(std::size_t n)+ {+ vector_.resize(n > size() ? 0 : size() - n);+ }++ /// @b DynamicBuffer_v1: Remove characters from the input sequence.+ /// @b DynamicBuffer_v2: Consume the specified number of bytes from the+ /// beginning of the underlying memory.+ /**+ * @b DynamicBuffer_v1: 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.+ *+ * @b DynamicBuffer_v2: Erases @c n bytes from the beginning of the vector.+ * If @c n is greater than the current size of the vector, the vector is+ * emptied.+ */+ void consume(std::size_t n)+ {+#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+ if (size_ != (std::numeric_limits<std::size_t>::max)())+ {+ std::size_t consume_length = (std::min)(n, size_);+ vector_.erase(vector_.begin(), vector_.begin() + consume_length);+ size_ -= consume_length;+ return;+ }+#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+ vector_.erase(vector_.begin(), vector_.begin() + (std::min)(size(), n));+ }++private:+ std::vector<Elem, Allocator>& vector_;+#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+ std::size_t size_;+#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+ const std::size_t max_size_;+};++/** @defgroup dynamic_buffer asio::dynamic_buffer+ *+ * @brief The 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>.+ */+template <typename Elem, typename Traits, typename Allocator>+ASIO_NODISCARD inline+dynamic_string_buffer<Elem, Traits, Allocator> dynamic_buffer(+ std::basic_string<Elem, Traits, Allocator>& data) ASIO_NOEXCEPT+{+ return dynamic_string_buffer<Elem, Traits, Allocator>(data);+}++/// Create a new dynamic buffer that represents the given string.+/**+ * @returns <tt>dynamic_string_buffer<Elem, Traits, Allocator>(data,+ * max_size)</tt>.+ */+template <typename Elem, typename Traits, typename Allocator>+ASIO_NODISCARD inline+dynamic_string_buffer<Elem, Traits, Allocator> dynamic_buffer(+ std::basic_string<Elem, Traits, Allocator>& data,+ std::size_t max_size) ASIO_NOEXCEPT+{+ return dynamic_string_buffer<Elem, Traits, Allocator>(data, max_size);+}++/// Create a new dynamic buffer that represents the given vector.+/**+ * @returns <tt>dynamic_vector_buffer<Elem, Allocator>(data)</tt>.+ */+template <typename Elem, typename Allocator>+ASIO_NODISCARD inline+dynamic_vector_buffer<Elem, Allocator> dynamic_buffer(+ std::vector<Elem, Allocator>& data) ASIO_NOEXCEPT+{+ return dynamic_vector_buffer<Elem, Allocator>(data);+}++/// Create a new dynamic buffer that represents the given vector.+/**+ * @returns <tt>dynamic_vector_buffer<Elem, Allocator>(data, max_size)</tt>.+ */+template <typename Elem, typename Allocator>+ASIO_NODISCARD inline+dynamic_vector_buffer<Elem, Allocator> dynamic_buffer(+ std::vector<Elem, Allocator>& data,+ std::size_t max_size) ASIO_NOEXCEPT+{+ return dynamic_vector_buffer<Elem, Allocator>(data, max_size);+}++/*@}*/++/** @defgroup buffer_copy asio::buffer_copy+ *+ * @brief The 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.+ */+/*@{*/++namespace detail {++inline std::size_t buffer_copy_1(const mutable_buffer& target,+ const const_buffer& source)+{+ 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;+}++template <typename TargetIterator, typename SourceIterator>+inline std::size_t buffer_copy(one_buffer, one_buffer,+ TargetIterator target_begin, TargetIterator,+ SourceIterator source_begin, SourceIterator) ASIO_NOEXCEPT+{+ return (buffer_copy_1)(*target_begin, *source_begin);+}++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) ASIO_NOEXCEPT+{+ return (buffer_copy_1)(*target_begin,+ 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)()) ASIO_NOEXCEPT+{+ std::size_t total_bytes_copied = 0;+ SourceIterator source_iter = source_begin;++ for (mutable_buffer target_buffer(+ asio::buffer(*target_begin, max_bytes_to_copy));+ target_buffer.size() && source_iter != source_end; ++source_iter)+ {+ const_buffer source_buffer(*source_iter);+ std::size_t bytes_copied = (buffer_copy_1)(target_buffer, source_buffer);+ total_bytes_copied += bytes_copied;+ target_buffer += bytes_copied;+ }++ return total_bytes_copied;+}++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)()) ASIO_NOEXCEPT+{+ std::size_t total_bytes_copied = 0;+ TargetIterator target_iter = target_begin;++ for (const_buffer source_buffer(+ 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;+ }++ return total_bytes_copied;+}++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) ASIO_NOEXCEPT+{+ std::size_t total_bytes_copied = 0;++ TargetIterator target_iter = target_begin;+ std::size_t target_buffer_offset = 0;++ SourceIterator source_iter = source_begin;+ std::size_t source_buffer_offset = 0;++ while (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_1)(target_buffer, source_buffer);+ total_bytes_copied += bytes_copied;++ if (bytes_copied == target_buffer.size())+ {+ ++target_iter;+ target_buffer_offset = 0;+ }+ else+ target_buffer_offset += bytes_copied;++ if (bytes_copied == source_buffer.size())+ {+ ++source_iter;+ source_buffer_offset = 0;+ }+ else+ source_buffer_offset += bytes_copied;+ }++ return total_bytes_copied;+}++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) ASIO_NOEXCEPT+{+ std::size_t total_bytes_copied = 0;++ TargetIterator target_iter = target_begin;+ std::size_t target_buffer_offset = 0;++ SourceIterator source_iter = source_begin;+ 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_1)(+ target_buffer, asio::buffer(source_buffer,+ max_bytes_to_copy - total_bytes_copied));+ total_bytes_copied += bytes_copied;++ if (bytes_copied == target_buffer.size())+ {+ ++target_iter;+ target_buffer_offset = 0;+ }+ else+ target_buffer_offset += bytes_copied;++ if (bytes_copied == source_buffer.size())+ {+ ++source_iter;+ source_buffer_offset = 0;+ }+ else+ source_buffer_offset += bytes_copied;+ }++ return total_bytes_copied;+}++} // namespace detail++/// 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>+inline std::size_t buffer_copy(const MutableBufferSequence& target,+ const ConstBufferSequence& source) ASIO_NOEXCEPT+{+ return detail::buffer_copy(+ detail::buffer_sequence_cardinality<MutableBufferSequence>(),+ detail::buffer_sequence_cardinality<ConstBufferSequence>(),+ asio::buffer_sequence_begin(target),+ asio::buffer_sequence_end(target),+ asio::buffer_sequence_begin(source),+ asio::buffer_sequence_end(source));+}++/// Copies a limited number of 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.+ *+ * @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, typename ConstBufferSequence>+inline std::size_t buffer_copy(const MutableBufferSequence& target,+ const ConstBufferSequence& source,+ std::size_t max_bytes_to_copy) ASIO_NOEXCEPT+{+ return detail::buffer_copy(+ detail::buffer_sequence_cardinality<MutableBufferSequence>(),+ detail::buffer_sequence_cardinality<ConstBufferSequence>(),+ asio::buffer_sequence_begin(target),+ asio::buffer_sequence_end(target),+ asio::buffer_sequence_begin(source),+ asio::buffer_sequence_end(source), max_bytes_to_copy);+}++/*@}*/++} // namespace asio++#include "asio/detail/pop_options.hpp"+#include "asio/detail/is_buffer_sequence.hpp"+#include "asio/detail/push_options.hpp"++namespace asio {++/// 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)+ : 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)+ : asio::detail::is_buffer_sequence<T, const_buffer>+#endif // defined(GENERATING_DOCUMENTATION)+{+};++#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+/// Trait to determine whether a type satisfies the DynamicBuffer_v1+/// requirements.+template <typename T>+struct is_dynamic_buffer_v1+#if defined(GENERATING_DOCUMENTATION)+ : integral_constant<bool, automatically_determined>+#else // defined(GENERATING_DOCUMENTATION)+ : asio::detail::is_dynamic_buffer_v1<T>+#endif // defined(GENERATING_DOCUMENTATION)+{+};+#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)++/// Trait to determine whether a type satisfies the DynamicBuffer_v2+/// requirements.+template <typename T>+struct is_dynamic_buffer_v2+#if defined(GENERATING_DOCUMENTATION)+ : integral_constant<bool, automatically_determined>+#else // defined(GENERATING_DOCUMENTATION)+ : asio::detail::is_dynamic_buffer_v2<T>+#endif // defined(GENERATING_DOCUMENTATION)+{+};++/// Trait to determine whether a type satisfies the DynamicBuffer requirements.+/**+ * If @c ASIO_NO_DYNAMIC_BUFFER_V1 is not defined, determines whether the+ * type satisfies the DynamicBuffer_v1 requirements. Otherwise, if @c+ * ASIO_NO_DYNAMIC_BUFFER_V1 is defined, determines whether the type+ * satisfies the DynamicBuffer_v2 requirements.+ */+template <typename T>+struct is_dynamic_buffer+#if defined(GENERATING_DOCUMENTATION)+ : integral_constant<bool, automatically_determined>+#elif defined(ASIO_NO_DYNAMIC_BUFFER_V1)+ : asio::is_dynamic_buffer_v2<T>+#else // defined(ASIO_NO_DYNAMIC_BUFFER_V1)+ : asio::is_dynamic_buffer_v1<T>+#endif // defined(ASIO_NO_DYNAMIC_BUFFER_V1)+{+};++#if (defined(ASIO_HAS_USER_DEFINED_LITERALS) \+ && defined(ASIO_HAS_VARIADIC_TEMPLATES)) \+ || defined(GENERATING_DOCUMENTATION)++namespace buffer_literals {+namespace detail {++template <char... Chars>+struct chars {};++template <unsigned char... Bytes>+struct bytes {};++// Literal processor that converts binary literals to an array of bytes.++template <typename Bytes, char... Chars>+struct bin_literal;++template <unsigned char... Bytes>+struct bin_literal<bytes<Bytes...> >+{+ static const std::size_t size = sizeof...(Bytes);+ static const unsigned char data[sizeof...(Bytes)];+};++template <unsigned char... Bytes>+const unsigned char bin_literal<bytes<Bytes...> >::data[sizeof...(Bytes)]+ = { Bytes... };++template <unsigned char... Bytes, char Bit7, char Bit6, char Bit5,+ char Bit4, char Bit3, char Bit2, char Bit1, char Bit0, char... Chars>+struct bin_literal<bytes<Bytes...>, Bit7, Bit6,+ Bit5, Bit4, Bit3, Bit2, Bit1, Bit0, Chars...> :+ bin_literal<+ bytes<Bytes...,+ static_cast<unsigned char>(+ (Bit7 == '1' ? 0x80 : 0) |+ (Bit6 == '1' ? 0x40 : 0) |+ (Bit5 == '1' ? 0x20 : 0) |+ (Bit4 == '1' ? 0x10 : 0) |+ (Bit3 == '1' ? 0x08 : 0) |+ (Bit2 == '1' ? 0x04 : 0) |+ (Bit1 == '1' ? 0x02 : 0) |+ (Bit0 == '1' ? 0x01 : 0))+ >, Chars...> {};++template <unsigned char... Bytes, char... Chars>+struct bin_literal<bytes<Bytes...>, Chars...>+{+ static_assert(sizeof...(Chars) == 0,+ "number of digits in a binary buffer literal must be a multiple of 8");++ static const std::size_t size = 0;+ static const unsigned char data[1];+};++template <unsigned char... Bytes, char... Chars>+const unsigned char bin_literal<bytes<Bytes...>, Chars...>::data[1] = {};++// Literal processor that converts hexadecimal literals to an array of bytes.++template <typename Bytes, char... Chars>+struct hex_literal;++template <unsigned char... Bytes>+struct hex_literal<bytes<Bytes...> >+{+ static const std::size_t size = sizeof...(Bytes);+ static const unsigned char data[sizeof...(Bytes)];+};++template <unsigned char... Bytes>+const unsigned char hex_literal<bytes<Bytes...> >::data[sizeof...(Bytes)]+ = { Bytes... };++template <unsigned char... Bytes, char Hi, char Lo, char... Chars>+struct hex_literal<bytes<Bytes...>, Hi, Lo, Chars...> :+ hex_literal<+ bytes<Bytes...,+ static_cast<unsigned char>(+ Lo >= 'A' && Lo <= 'F' ? Lo - 'A' + 10 :+ (Lo >= 'a' && Lo <= 'f' ? Lo - 'a' + 10 : Lo - '0')) |+ ((static_cast<unsigned char>(+ Hi >= 'A' && Hi <= 'F' ? Hi - 'A' + 10 :+ (Hi >= 'a' && Hi <= 'f' ? Hi - 'a' + 10 : Hi - '0'))) << 4)+ >, Chars...> {};++template <unsigned char... Bytes, char Char>+struct hex_literal<bytes<Bytes...>, Char>+{+ static_assert(!Char,+ "a hexadecimal buffer literal must have an even number of digits");++ static const std::size_t size = 0;+ static const unsigned char data[1];+};++template <unsigned char... Bytes, char Char>+const unsigned char hex_literal<bytes<Bytes...>, Char>::data[1] = {};++// Helper template that removes digit separators and then passes the cleaned+// variadic pack of characters to the literal processor.++template <template <typename, char...> class Literal,+ typename Clean, char... Raw>+struct remove_separators;++template <template <typename, char...> class Literal,+ char... Clean, char... Raw>+struct remove_separators<Literal, chars<Clean...>, '\'', Raw...> :+ remove_separators<Literal, chars<Clean...>, Raw...> {};++template <template <typename, char...> class Literal,+ char... Clean, char C, char... Raw>+struct remove_separators<Literal, chars<Clean...>, C, Raw...> :+ remove_separators<Literal, chars<Clean..., C>, Raw...> {};++template <template <typename, char...> class Literal, char... Clean>+struct remove_separators<Literal, chars<Clean...> > :+ Literal<bytes<>, Clean...> {};++// Helper template to determine the literal type based on the prefix.++template <char... Chars>+struct literal;++template <char... Chars>+struct literal<'0', 'b', Chars...> :+ remove_separators<bin_literal, chars<>, Chars...>{};++template <char... Chars>+struct literal<'0', 'B', Chars...> :+ remove_separators<bin_literal, chars<>, Chars...>{};++template <char... Chars>+struct literal<'0', 'x', Chars...> :+ remove_separators<hex_literal, chars<>, Chars...>{};++template <char... Chars>+struct literal<'0', 'X', Chars...> :+ remove_separators<hex_literal, chars<>, Chars...>{};++} // namespace detail++/// Literal operator for creating const_buffer objects from string literals.+inline ASIO_CONST_BUFFER operator"" _buf(const char* data, std::size_t n)+{+ return ASIO_CONST_BUFFER(data, n);+}++/// Literal operator for creating const_buffer objects from unbounded binary or+/// hexadecimal integer literals.+template <char... Chars>+inline ASIO_CONST_BUFFER operator"" _buf()+{+ return ASIO_CONST_BUFFER(+ +detail::literal<Chars...>::data,+ detail::literal<Chars...>::size);+}++} // namespace buffer_literals++#endif // (defined(ASIO_HAS_USER_DEFINED_LITERALS)+ // && defined(ASIO_HAS_VARIADIC_TEMPLATES))+ // || defined(GENERATING_DOCUMENTATION)+ } // namespace asio #include "asio/detail/pop_options.hpp"
link/modules/asio-standalone/asio/include/asio/buffer_registration.hpp view
@@ -2,7 +2,7 @@ // buffer_registration.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -17,7 +17,6 @@ #include "asio/detail/config.hpp" #include <iterator>-#include <utility> #include <vector> #include "asio/detail/memory.hpp" #include "asio/execution/context.hpp"@@ -32,6 +31,10 @@ # include "asio/detail/io_uring_service.hpp" #endif // defined(ASIO_HAS_IO_URING) +#if defined(ASIO_HAS_MOVE)+# include <utility>+#endif // defined(ASIO_HAS_MOVE)+ #include "asio/detail/push_options.hpp" namespace asio {@@ -41,7 +44,7 @@ { protected: static mutable_registered_buffer make_buffer(const mutable_buffer& b,- const void* scope, int index) noexcept+ const void* scope, int index) ASIO_NOEXCEPT { return mutable_registered_buffer(b, registered_buffer_id(scope, index)); }@@ -55,7 +58,7 @@ * permitted per execution context. */ template <typename MutableBufferSequence,- typename Allocator = std::allocator<void>>+ typename Allocator = std::allocator<void> > class buffer_registration : detail::buffer_registration_base {@@ -79,9 +82,9 @@ buffer_registration(const Executor& ex, const MutableBufferSequence& buffer_sequence, const allocator_type& alloc = allocator_type(),- constraint_t<+ typename constraint< is_executor<Executor>::value || execution::is_executor<Executor>::value- > = 0)+ >::type = 0) : buffer_sequence_(buffer_sequence), buffers_( ASIO_REBIND_ALLOC(allocator_type,@@ -97,9 +100,9 @@ buffer_registration(ExecutionContext& ctx, const MutableBufferSequence& buffer_sequence, const allocator_type& alloc = allocator_type(),- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- > = 0)+ >::type = 0) : buffer_sequence_(buffer_sequence), buffers_( ASIO_REBIND_ALLOC(allocator_type,@@ -110,8 +113,9 @@ asio::buffer_sequence_end(buffer_sequence_)); } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move constructor.- buffer_registration(buffer_registration&& other) noexcept+ buffer_registration(buffer_registration&& other) ASIO_NOEXCEPT : buffer_sequence_(std::move(other.buffer_sequence_)), buffers_(std::move(other.buffers_)) {@@ -120,6 +124,7 @@ other.service_ = 0; #endif // defined(ASIO_HAS_IO_URING) }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Unregisters the buffers. ~buffer_registration()@@ -129,9 +134,11 @@ service_->unregister_buffers(); #endif // defined(ASIO_HAS_IO_URING) }-+ +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move assignment.- buffer_registration& operator=(buffer_registration&& other) noexcept+ buffer_registration& operator=(+ buffer_registration&& other) ASIO_NOEXCEPT { if (this != &other) {@@ -146,58 +153,59 @@ } return *this; }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Get the number of registered buffers.- std::size_t size() const noexcept+ std::size_t size() const ASIO_NOEXCEPT { return buffers_.size(); } /// Get the begin iterator for the sequence of registered buffers.- const_iterator begin() const noexcept+ const_iterator begin() const ASIO_NOEXCEPT { return buffers_.begin(); } /// Get the begin iterator for the sequence of registered buffers.- const_iterator cbegin() const noexcept+ const_iterator cbegin() const ASIO_NOEXCEPT { return buffers_.cbegin(); } /// Get the end iterator for the sequence of registered buffers.- const_iterator end() const noexcept+ const_iterator end() const ASIO_NOEXCEPT { return buffers_.end(); } /// Get the end iterator for the sequence of registered buffers.- const_iterator cend() const noexcept+ const_iterator cend() const ASIO_NOEXCEPT { return buffers_.cend(); } /// Get the buffer at the specified index.- const mutable_registered_buffer& operator[](std::size_t i) noexcept+ const mutable_registered_buffer& operator[](std::size_t i) ASIO_NOEXCEPT { return buffers_[i]; } /// Get the buffer at the specified index.- const mutable_registered_buffer& at(std::size_t i) noexcept+ const mutable_registered_buffer& at(std::size_t i) ASIO_NOEXCEPT { return buffers_.at(i); } private: // Disallow copying and assignment.- buffer_registration(const buffer_registration&) = delete;- buffer_registration& operator=(const buffer_registration&) = delete;+ buffer_registration(const buffer_registration&) ASIO_DELETED;+ buffer_registration& operator=(const buffer_registration&) ASIO_DELETED; // Helper function to get an executor's context. template <typename T> static execution_context& get_context(const T& t,- enable_if_t<execution::is_executor<T>::value>* = 0)+ typename enable_if<execution::is_executor<T>::value>::type* = 0) { return asio::query(t, execution::context); }@@ -205,7 +213,7 @@ // Helper function to get an executor's context. template <typename T> static execution_context& get_context(const T& t,- enable_if_t<!execution::is_executor<T>::value>* = 0)+ typename enable_if<!execution::is_executor<T>::value>::type* = 0) { return t.context(); }@@ -256,15 +264,16 @@ #endif // defined(ASIO_HAS_IO_URING) }; +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Register buffers with an execution context. template <typename Executor, typename MutableBufferSequence> ASIO_NODISCARD inline buffer_registration<MutableBufferSequence> register_buffers(const Executor& ex, const MutableBufferSequence& buffer_sequence,- constraint_t<+ typename constraint< is_executor<Executor>::value || execution::is_executor<Executor>::value- > = 0)+ >::type = 0) { return buffer_registration<MutableBufferSequence>(ex, buffer_sequence); }@@ -275,9 +284,9 @@ buffer_registration<MutableBufferSequence, Allocator> register_buffers(const Executor& ex, const MutableBufferSequence& buffer_sequence, const Allocator& alloc,- constraint_t<+ typename constraint< is_executor<Executor>::value || execution::is_executor<Executor>::value- > = 0)+ >::type = 0) { return buffer_registration<MutableBufferSequence, Allocator>( ex, buffer_sequence, alloc);@@ -289,9 +298,9 @@ buffer_registration<MutableBufferSequence> register_buffers(ExecutionContext& ctx, const MutableBufferSequence& buffer_sequence,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- > = 0)+ >::type = 0) { return buffer_registration<MutableBufferSequence>(ctx, buffer_sequence); }@@ -303,13 +312,14 @@ buffer_registration<MutableBufferSequence, Allocator> register_buffers(ExecutionContext& ctx, const MutableBufferSequence& buffer_sequence, const Allocator& alloc,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- > = 0)+ >::type = 0) { return buffer_registration<MutableBufferSequence, Allocator>( ctx, buffer_sequence, alloc); }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) } // namespace asio
link/modules/asio-standalone/asio/include/asio/buffered_read_stream.hpp view
@@ -2,7 +2,7 @@ // buffered_read_stream.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -55,7 +55,7 @@ { public: /// The type of the next layer.- typedef remove_reference_t<Stream> next_layer_type;+ typedef typename remove_reference<Stream>::type next_layer_type; /// The type of the lowest layer. typedef typename next_layer_type::lowest_layer_type lowest_layer_type;@@ -72,17 +72,17 @@ /// Construct, passing the specified argument to initialise the next layer. template <typename Arg>- explicit buffered_read_stream(Arg&& a)- : next_layer_(static_cast<Arg&&>(a)),+ explicit buffered_read_stream(ASIO_MOVE_OR_LVALUE_ARG(Arg) a)+ : next_layer_(ASIO_MOVE_OR_LVALUE(Arg)(a)), storage_(default_buffer_size) { } /// Construct, passing the specified argument to initialise the next layer. template <typename Arg>- buffered_read_stream(Arg&& a,+ buffered_read_stream(ASIO_MOVE_OR_LVALUE_ARG(Arg) a, std::size_t buffer_size)- : next_layer_(static_cast<Arg&&>(a)),+ : next_layer_(ASIO_MOVE_OR_LVALUE(Arg)(a)), storage_(buffer_size) { }@@ -106,7 +106,7 @@ } /// Get the executor associated with the object.- executor_type get_executor() noexcept+ executor_type get_executor() ASIO_NOEXCEPT { return next_layer_.lowest_layer().get_executor(); }@@ -149,15 +149,20 @@ */ template <typename ConstBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) WriteHandler = default_completion_token_t<executor_type>>- auto async_write_some(const ConstBufferSequence& buffers,- WriteHandler&& handler = default_completion_token_t<executor_type>())- -> decltype(- declval<conditional_t<true, Stream&, WriteHandler>>().async_write_some(- buffers, static_cast<WriteHandler&&>(handler)))+ std::size_t)) WriteHandler+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteHandler,+ void (asio::error_code, std::size_t))+ async_write_some(const ConstBufferSequence& buffers,+ ASIO_MOVE_ARG(WriteHandler) handler+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ declval<typename conditional<true, Stream&, WriteHandler>::type>()+ .async_write_some(buffers,+ ASIO_MOVE_CAST(WriteHandler)(handler)))) { return next_layer_.async_write_some(buffers,- static_cast<WriteHandler&&>(handler));+ ASIO_MOVE_CAST(WriteHandler)(handler)); } /// Fill the buffer with some data. Returns the number of bytes placed in the@@ -175,14 +180,18 @@ */ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) ReadHandler = default_completion_token_t<executor_type>>- auto async_fill(- ReadHandler&& handler = default_completion_token_t<executor_type>())- -> decltype(+ std::size_t)) ReadHandler+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadHandler,+ void (asio::error_code, std::size_t))+ async_fill(+ ASIO_MOVE_ARG(ReadHandler) handler+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<ReadHandler, void (asio::error_code, std::size_t)>(- declval<detail::initiate_async_buffered_fill<Stream>>(),- handler, declval<detail::buffered_stream_storage*>()));+ declval<detail::initiate_async_buffered_fill<Stream> >(),+ handler, declval<detail::buffered_stream_storage*>()))); /// Read some data from the stream. Returns the number of bytes read. Throws /// an exception on failure.@@ -203,14 +212,18 @@ */ template <typename MutableBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) ReadHandler = default_completion_token_t<executor_type>>- auto async_read_some(const MutableBufferSequence& buffers,- ReadHandler&& handler = default_completion_token_t<executor_type>())- -> decltype(+ std::size_t)) ReadHandler+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadHandler,+ void (asio::error_code, std::size_t))+ async_read_some(const MutableBufferSequence& buffers,+ ASIO_MOVE_ARG(ReadHandler) handler+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<ReadHandler, void (asio::error_code, std::size_t)>(- declval<detail::initiate_async_buffered_read_some<Stream>>(),- handler, declval<detail::buffered_stream_storage*>(), buffers));+ declval<detail::initiate_async_buffered_read_some<Stream> >(),+ handler, declval<detail::buffered_stream_storage*>(), buffers))); /// Peek at the incoming data on the stream. Returns the number of bytes read. /// Throws an exception on failure.
link/modules/asio-standalone/asio/include/asio/buffered_read_stream_fwd.hpp view
@@ -2,7 +2,7 @@ // buffered_read_stream_fwd.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/buffered_stream.hpp view
@@ -2,7 +2,7 @@ // buffered_stream.hpp // ~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -46,7 +46,7 @@ { public: /// The type of the next layer.- typedef remove_reference_t<Stream> next_layer_type;+ typedef typename remove_reference<Stream>::type next_layer_type; /// The type of the lowest layer. typedef typename next_layer_type::lowest_layer_type lowest_layer_type;@@ -56,17 +56,17 @@ /// Construct, passing the specified argument to initialise the next layer. template <typename Arg>- explicit buffered_stream(Arg&& a)- : inner_stream_impl_(static_cast<Arg&&>(a)),+ explicit buffered_stream(ASIO_MOVE_OR_LVALUE_ARG(Arg) a)+ : inner_stream_impl_(ASIO_MOVE_OR_LVALUE(Arg)(a)), stream_impl_(inner_stream_impl_) { } /// Construct, passing the specified argument to initialise the next layer. template <typename Arg>- explicit buffered_stream(Arg&& a,+ explicit buffered_stream(ASIO_MOVE_OR_LVALUE_ARG(Arg) a, std::size_t read_buffer_size, std::size_t write_buffer_size)- : inner_stream_impl_(static_cast<Arg&&>(a), write_buffer_size),+ : inner_stream_impl_(ASIO_MOVE_OR_LVALUE(Arg)(a), write_buffer_size), stream_impl_(inner_stream_impl_, read_buffer_size) { }@@ -90,7 +90,7 @@ } /// Get the executor associated with the object.- executor_type get_executor() noexcept+ executor_type get_executor() ASIO_NOEXCEPT { return stream_impl_.lowest_layer().get_executor(); }@@ -131,15 +131,19 @@ */ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) WriteHandler = default_completion_token_t<executor_type>>- auto async_flush(- WriteHandler&& handler = default_completion_token_t<executor_type>())- -> decltype(+ std::size_t)) WriteHandler+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteHandler,+ void (asio::error_code, std::size_t))+ async_flush(+ ASIO_MOVE_ARG(WriteHandler) handler+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( declval<buffered_write_stream<Stream>&>().async_flush(- static_cast<WriteHandler&&>(handler)))+ ASIO_MOVE_CAST(WriteHandler)(handler)))) { return stream_impl_.next_layer().async_flush(- static_cast<WriteHandler&&>(handler));+ ASIO_MOVE_CAST(WriteHandler)(handler)); } /// Write the given data to the stream. Returns the number of bytes written.@@ -167,15 +171,19 @@ */ template <typename ConstBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) WriteHandler = default_completion_token_t<executor_type>>- auto async_write_some(const ConstBufferSequence& buffers,- WriteHandler&& handler = default_completion_token_t<executor_type>())- -> decltype(+ std::size_t)) WriteHandler+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteHandler,+ void (asio::error_code, std::size_t))+ async_write_some(const ConstBufferSequence& buffers,+ ASIO_MOVE_ARG(WriteHandler) handler+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( declval<Stream&>().async_write_some(buffers,- static_cast<WriteHandler&&>(handler)))+ ASIO_MOVE_CAST(WriteHandler)(handler)))) { return stream_impl_.async_write_some(buffers,- static_cast<WriteHandler&&>(handler));+ ASIO_MOVE_CAST(WriteHandler)(handler)); } /// Fill the buffer with some data. Returns the number of bytes placed in the@@ -199,15 +207,19 @@ */ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) ReadHandler = default_completion_token_t<executor_type>>- auto async_fill(- ReadHandler&& handler = default_completion_token_t<executor_type>())- -> decltype(+ std::size_t)) ReadHandler+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadHandler,+ void (asio::error_code, std::size_t))+ async_fill(+ ASIO_MOVE_ARG(ReadHandler) handler+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( declval<buffered_read_stream<- buffered_write_stream<Stream>>&>().async_fill(- static_cast<ReadHandler&&>(handler)))+ buffered_write_stream<Stream> >&>().async_fill(+ ASIO_MOVE_CAST(ReadHandler)(handler)))) {- return stream_impl_.async_fill(static_cast<ReadHandler&&>(handler));+ return stream_impl_.async_fill(ASIO_MOVE_CAST(ReadHandler)(handler)); } /// Read some data from the stream. Returns the number of bytes read. Throws@@ -235,15 +247,19 @@ */ template <typename MutableBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) ReadHandler = default_completion_token_t<executor_type>>- auto async_read_some(const MutableBufferSequence& buffers,- ReadHandler&& handler = default_completion_token_t<executor_type>())- -> decltype(+ std::size_t)) ReadHandler+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadHandler,+ void (asio::error_code, std::size_t))+ async_read_some(const MutableBufferSequence& buffers,+ ASIO_MOVE_ARG(ReadHandler) handler+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( declval<Stream&>().async_read_some(buffers,- static_cast<ReadHandler&&>(handler)))+ ASIO_MOVE_CAST(ReadHandler)(handler)))) { return stream_impl_.async_read_some(buffers,- static_cast<ReadHandler&&>(handler));+ ASIO_MOVE_CAST(ReadHandler)(handler)); } /// Peek at the incoming data on the stream. Returns the number of bytes read.
link/modules/asio-standalone/asio/include/asio/buffered_stream_fwd.hpp view
@@ -2,7 +2,7 @@ // buffered_stream_fwd.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/buffered_write_stream.hpp view
@@ -2,7 +2,7 @@ // buffered_write_stream.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -55,7 +55,7 @@ { public: /// The type of the next layer.- typedef remove_reference_t<Stream> next_layer_type;+ typedef typename remove_reference<Stream>::type next_layer_type; /// The type of the lowest layer. typedef typename next_layer_type::lowest_layer_type lowest_layer_type;@@ -72,17 +72,17 @@ /// Construct, passing the specified argument to initialise the next layer. template <typename Arg>- explicit buffered_write_stream(Arg&& a)- : next_layer_(static_cast<Arg&&>(a)),+ explicit buffered_write_stream(ASIO_MOVE_OR_LVALUE_ARG(Arg) a)+ : next_layer_(ASIO_MOVE_OR_LVALUE(Arg)(a)), storage_(default_buffer_size) { } /// Construct, passing the specified argument to initialise the next layer. template <typename Arg>- buffered_write_stream(Arg&& a,+ buffered_write_stream(ASIO_MOVE_OR_LVALUE_ARG(Arg) a, std::size_t buffer_size)- : next_layer_(static_cast<Arg&&>(a)),+ : next_layer_(ASIO_MOVE_OR_LVALUE(Arg)(a)), storage_(buffer_size) { }@@ -106,7 +106,7 @@ } /// Get the executor associated with the object.- executor_type get_executor() noexcept+ executor_type get_executor() ASIO_NOEXCEPT { return next_layer_.lowest_layer().get_executor(); }@@ -141,14 +141,18 @@ */ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) WriteHandler = default_completion_token_t<executor_type>>- auto async_flush(- WriteHandler&& handler = default_completion_token_t<executor_type>())- -> decltype(+ std::size_t)) WriteHandler+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteHandler,+ void (asio::error_code, std::size_t))+ async_flush(+ ASIO_MOVE_ARG(WriteHandler) handler+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<WriteHandler, void (asio::error_code, std::size_t)>(- declval<detail::initiate_async_buffered_flush<Stream>>(),- handler, declval<detail::buffered_stream_storage*>()));+ declval<detail::initiate_async_buffered_flush<Stream> >(),+ handler, declval<detail::buffered_stream_storage*>()))); /// Write the given data to the stream. Returns the number of bytes written. /// Throws an exception on failure.@@ -169,14 +173,18 @@ */ template <typename ConstBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) WriteHandler = default_completion_token_t<executor_type>>- auto async_write_some(const ConstBufferSequence& buffers,- WriteHandler&& handler = default_completion_token_t<executor_type>())- -> decltype(+ std::size_t)) WriteHandler+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteHandler,+ void (asio::error_code, std::size_t))+ async_write_some(const ConstBufferSequence& buffers,+ ASIO_MOVE_ARG(WriteHandler) handler+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<WriteHandler, void (asio::error_code, std::size_t)>(- declval<detail::initiate_async_buffered_write_some<Stream>>(),- handler, declval<detail::buffered_stream_storage*>(), buffers));+ declval<detail::initiate_async_buffered_write_some<Stream> >(),+ handler, declval<detail::buffered_stream_storage*>(), buffers))); /// Read some data from the stream. Returns the number of bytes read. Throws /// an exception on failure.@@ -203,15 +211,20 @@ */ template <typename MutableBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) ReadHandler = default_completion_token_t<executor_type>>- auto async_read_some(const MutableBufferSequence& buffers,- ReadHandler&& handler = default_completion_token_t<executor_type>())- -> decltype(- declval<conditional_t<true, Stream&, ReadHandler>>().async_read_some(- buffers, static_cast<ReadHandler&&>(handler)))+ std::size_t)) ReadHandler+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadHandler,+ void (asio::error_code, std::size_t))+ async_read_some(const MutableBufferSequence& buffers,+ ASIO_MOVE_ARG(ReadHandler) handler+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ declval<typename conditional<true, Stream&, ReadHandler>::type>()+ .async_read_some(buffers,+ ASIO_MOVE_CAST(ReadHandler)(handler)))) { return next_layer_.async_read_some(buffers,- static_cast<ReadHandler&&>(handler));+ ASIO_MOVE_CAST(ReadHandler)(handler)); } /// Peek at the incoming data on the stream. Returns the number of bytes read.
link/modules/asio-standalone/asio/include/asio/buffered_write_stream_fwd.hpp view
@@ -2,7 +2,7 @@ // buffered_write_stream_fwd.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/buffers_iterator.hpp view
@@ -2,7 +2,7 @@ // buffers_iterator.hpp // ~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -38,7 +38,7 @@ template <typename ByteType> struct byte_type {- typedef add_const_t<ByteType> type;+ typedef typename add_const<ByteType>::type type; }; }; @@ -80,10 +80,30 @@ struct buffers_iterator_types<const_buffer, ByteType> { typedef const_buffer buffer_type;- typedef add_const_t<ByteType> byte_type;+ typedef typename add_const<ByteType>::type byte_type; typedef const const_buffer* const_iterator; };-} // namespace detail++#if !defined(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(ASIO_NO_DEPRECATED)+} /// A random access iterator over the bytes in a buffer sequence. template <typename BufferSequence, typename ByteType = char>
− link/modules/asio-standalone/asio/include/asio/cancel_after.hpp
@@ -1,301 +0,0 @@-//-// cancel_after.hpp-// ~~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef ASIO_CANCEL_AFTER_HPP-#define ASIO_CANCEL_AFTER_HPP--#if defined(_MSC_VER) && (_MSC_VER >= 1200)-# pragma once-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)--#include "asio/detail/config.hpp"-#include "asio/basic_waitable_timer.hpp"-#include "asio/cancellation_type.hpp"-#include "asio/detail/chrono.hpp"-#include "asio/detail/type_traits.hpp"-#include "asio/wait_traits.hpp"--#include "asio/detail/push_options.hpp"--namespace asio {--/// A @ref completion_token adapter that cancels an operation after a timeout.-/**- * The cancel_after_t class is used to indicate that an asynchronous operation- * should be cancelled if not complete before the specified duration has- * elapsed.- */-template <typename CompletionToken, typename Clock,- typename WaitTraits = asio::wait_traits<Clock>>-class cancel_after_t-{-public:- /// Constructor.- template <typename T>- cancel_after_t(T&& completion_token, const typename Clock::duration& timeout,- cancellation_type_t cancel_type = cancellation_type::terminal)- : token_(static_cast<T&&>(completion_token)),- timeout_(timeout),- cancel_type_(cancel_type)- {- }--//private:- CompletionToken token_;- typename Clock::duration timeout_;- cancellation_type_t cancel_type_;-};--/// A @ref completion_token adapter that cancels an operation after a timeout.-/**- * The cancel_after_timer class is used to indicate that an asynchronous- * operation should be cancelled if not complete before the specified duration- * has elapsed.- */-template <typename CompletionToken, typename Clock,- typename WaitTraits = asio::wait_traits<Clock>,- typename Executor = any_io_executor>-class cancel_after_timer-{-public:- /// Constructor.- template <typename T>- cancel_after_timer(T&& completion_token,- basic_waitable_timer<Clock, WaitTraits, Executor>& timer,- const typename Clock::duration& timeout,- cancellation_type_t cancel_type = cancellation_type::terminal)- : token_(static_cast<T&&>(completion_token)),- timer_(timer),- timeout_(timeout),- cancel_type_(cancel_type)- {- }--//private:- CompletionToken token_;- basic_waitable_timer<Clock, WaitTraits, Executor>& timer_;- typename Clock::duration timeout_;- cancellation_type_t cancel_type_;-};--/// A function object type that adapts a @ref completion_token to cancel an-/// operation after a timeout.-/**- * May also be used directly as a completion token, in which case it adapts the- * asynchronous operation's default completion token (or asio::deferred- * if no default is available).- */-template <typename Clock, typename WaitTraits = asio::wait_traits<Clock>>-class partial_cancel_after-{-public:- /// Constructor that specifies the timeout duration and cancellation type.- explicit partial_cancel_after(const typename Clock::duration& timeout,- cancellation_type_t cancel_type = cancellation_type::terminal)- : timeout_(timeout),- cancel_type_(cancel_type)- {- }-- /// Adapt a @ref completion_token to specify that the completion handler- /// arguments should be combined into a single tuple argument.- template <typename CompletionToken>- ASIO_NODISCARD inline- cancel_after_t<decay_t<CompletionToken>, Clock, WaitTraits>- operator()(CompletionToken&& completion_token) const- {- return cancel_after_t<decay_t<CompletionToken>, Clock, WaitTraits>(- static_cast<CompletionToken&&>(completion_token),- timeout_, cancel_type_);- }--//private:- typename Clock::duration timeout_;- cancellation_type_t cancel_type_;-};--/// A function object type that adapts a @ref completion_token to cancel an-/// operation after a timeout.-/**- * May also be used directly as a completion token, in which case it adapts the- * asynchronous operation's default completion token (or asio::deferred- * if no default is available).- */-template <typename Clock, typename WaitTraits = asio::wait_traits<Clock>,- typename Executor = any_io_executor>-class partial_cancel_after_timer-{-public:- /// Constructor that specifies the timeout duration and cancellation type.- explicit partial_cancel_after_timer(- basic_waitable_timer<Clock, WaitTraits, Executor>& timer,- const typename Clock::duration& timeout,- cancellation_type_t cancel_type = cancellation_type::terminal)- : timer_(timer),- timeout_(timeout),- cancel_type_(cancel_type)- {- }-- /// Adapt a @ref completion_token to specify that the completion handler- /// arguments should be combined into a single tuple argument.- template <typename CompletionToken>- ASIO_NODISCARD inline- cancel_after_timer<decay_t<CompletionToken>, Clock, WaitTraits, Executor>- operator()(CompletionToken&& completion_token) const- {- return cancel_after_timer<decay_t<CompletionToken>,- Clock, WaitTraits, Executor>(- static_cast<CompletionToken&&>(completion_token),- timeout_, cancel_type_);- }--//private:- basic_waitable_timer<Clock, WaitTraits, Executor>& timer_;- typename Clock::duration timeout_;- cancellation_type_t cancel_type_;-};--/// Create a partial completion token adapter that cancels an operation if not-/// complete before the specified relative timeout has elapsed.-/**- * @par Thread Safety- * When an asynchronous operation is used with cancel_after, a timer async_wait- * operation is performed in parallel to the main operation. If this parallel- * async_wait completes first, a cancellation request is emitted to cancel the- * main operation. Consequently, the application must ensure that the- * asynchronous operation is performed within an implicit or explicit strand.- */-template <typename Rep, typename Period>-ASIO_NODISCARD inline partial_cancel_after<chrono::steady_clock>-cancel_after(const chrono::duration<Rep, Period>& timeout,- cancellation_type_t cancel_type = cancellation_type::terminal)-{- return partial_cancel_after<chrono::steady_clock>(timeout, cancel_type);-}--/// Create a partial completion token adapter that cancels an operation if not-/// complete before the specified relative timeout has elapsed.-/**- * @par Thread Safety- * When an asynchronous operation is used with cancel_after, a timer async_wait- * operation is performed in parallel to the main operation. If this parallel- * async_wait completes first, a cancellation request is emitted to cancel the- * main operation. Consequently, the application must ensure that the- * asynchronous operation is performed within an implicit or explicit strand.- */-template <typename Clock, typename WaitTraits,- typename Executor, typename Rep, typename Period>-ASIO_NODISCARD inline-partial_cancel_after_timer<Clock, WaitTraits, Executor>-cancel_after(basic_waitable_timer<Clock, WaitTraits, Executor>& timer,- const chrono::duration<Rep, Period>& timeout,- cancellation_type_t cancel_type = cancellation_type::terminal)-{- return partial_cancel_after_timer<Clock, WaitTraits, Executor>(- timer, timeout, cancel_type);-}--/// Adapt a @ref completion_token to cancel an operation if not complete before-/// the specified relative timeout has elapsed.-/**- * @par Thread Safety- * When an asynchronous operation is used with cancel_after, a timer async_wait- * operation is performed in parallel to the main operation. If this parallel- * async_wait completes first, a cancellation request is emitted to cancel the- * main operation. Consequently, the application must ensure that the- * asynchronous operation is performed within an implicit or explicit strand.- */-template <typename Rep, typename Period, typename CompletionToken>-ASIO_NODISCARD inline-cancel_after_t<decay_t<CompletionToken>, chrono::steady_clock>-cancel_after(const chrono::duration<Rep, Period>& timeout,- CompletionToken&& completion_token)-{- return cancel_after_t<decay_t<CompletionToken>, chrono::steady_clock>(- static_cast<CompletionToken&&>(completion_token),- timeout, cancellation_type::terminal);-}--/// Adapt a @ref completion_token to cancel an operation if not complete before-/// the specified relative timeout has elapsed.-/**- * @par Thread Safety- * When an asynchronous operation is used with cancel_after, a timer async_wait- * operation is performed in parallel to the main operation. If this parallel- * async_wait completes first, a cancellation request is emitted to cancel the- * main operation. Consequently, the application must ensure that the- * asynchronous operation is performed within an implicit or explicit strand.- */-template <typename Rep, typename Period, typename CompletionToken>-ASIO_NODISCARD inline-cancel_after_t<decay_t<CompletionToken>, chrono::steady_clock>-cancel_after(const chrono::duration<Rep, Period>& timeout,- cancellation_type_t cancel_type, CompletionToken&& completion_token)-{- return cancel_after_t<decay_t<CompletionToken>, chrono::steady_clock>(- static_cast<CompletionToken&&>(completion_token), timeout, cancel_type);-}--/// Adapt a @ref completion_token to cancel an operation if not complete before-/// the specified relative timeout has elapsed.-/**- * @par Thread Safety- * When an asynchronous operation is used with cancel_after, a timer async_wait- * operation is performed in parallel to the main operation. If this parallel- * async_wait completes first, a cancellation request is emitted to cancel the- * main operation. Consequently, the application must ensure that the- * asynchronous operation is performed within an implicit or explicit strand.- */-template <typename Clock, typename WaitTraits, typename Executor,- typename Rep, typename Period, typename CompletionToken>-ASIO_NODISCARD inline-cancel_after_timer<decay_t<CompletionToken>, Clock, WaitTraits, Executor>-cancel_after(basic_waitable_timer<Clock, WaitTraits, Executor>& timer,- const chrono::duration<Rep, Period>& timeout,- CompletionToken&& completion_token)-{- return cancel_after_timer<decay_t<CompletionToken>,- Clock, WaitTraits, Executor>(- static_cast<CompletionToken&&>(completion_token),- timer, timeout, cancellation_type::terminal);-}--/// Adapt a @ref completion_token to cancel an operation if not complete before-/// the specified relative timeout has elapsed.-/**- * @par Thread Safety- * When an asynchronous operation is used with cancel_after, a timer async_wait- * operation is performed in parallel to the main operation. If this parallel- * async_wait completes first, a cancellation request is emitted to cancel the- * main operation. Consequently, the application must ensure that the- * asynchronous operation is performed within an implicit or explicit strand.- */-template <typename Clock, typename WaitTraits, typename Executor,- typename Rep, typename Period, typename CompletionToken>-ASIO_NODISCARD inline-cancel_after_timer<decay_t<CompletionToken>, chrono::steady_clock>-cancel_after(basic_waitable_timer<Clock, WaitTraits, Executor>& timer,- const chrono::duration<Rep, Period>& timeout,- cancellation_type_t cancel_type, CompletionToken&& completion_token)-{- return cancel_after_timer<decay_t<CompletionToken>,- Clock, WaitTraits, Executor>(- static_cast<CompletionToken&&>(completion_token),- timer, timeout, cancel_type);-}--} // namespace asio--#include "asio/detail/pop_options.hpp"--#include "asio/impl/cancel_after.hpp"--#endif // ASIO_CANCEL_AFTER_HPP
− link/modules/asio-standalone/asio/include/asio/cancel_at.hpp
@@ -1,294 +0,0 @@-//-// cancel_at.hpp-// ~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef ASIO_CANCEL_AT_HPP-#define ASIO_CANCEL_AT_HPP--#if defined(_MSC_VER) && (_MSC_VER >= 1200)-# pragma once-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)--#include "asio/detail/config.hpp"-#include "asio/basic_waitable_timer.hpp"-#include "asio/cancellation_type.hpp"-#include "asio/detail/chrono.hpp"-#include "asio/detail/type_traits.hpp"-#include "asio/wait_traits.hpp"--#include "asio/detail/push_options.hpp"--namespace asio {--/// A @ref completion_token adapter that cancels an operation at a given time.-/**- * The cancel_at_t class is used to indicate that an asynchronous operation- * should be cancelled if not complete at the specified absolute time.- */-template <typename CompletionToken, typename Clock,- typename WaitTraits = asio::wait_traits<Clock>>-class cancel_at_t-{-public:- /// Constructor.- template <typename T>- cancel_at_t(T&& completion_token, const typename Clock::time_point& expiry,- cancellation_type_t cancel_type = cancellation_type::terminal)- : token_(static_cast<T&&>(completion_token)),- expiry_(expiry),- cancel_type_(cancel_type)- {- }--//private:- CompletionToken token_;- typename Clock::time_point expiry_;- cancellation_type_t cancel_type_;-};--/// A @ref completion_token adapter that cancels an operation at a given time.-/**- * The cancel_at_timer class is used to indicate that an asynchronous operation- * should be cancelled if not complete at the specified absolute time.- */-template <typename CompletionToken, typename Clock,- typename WaitTraits = asio::wait_traits<Clock>,- typename Executor = any_io_executor>-class cancel_at_timer-{-public:- /// Constructor.- template <typename T>- cancel_at_timer(T&& completion_token,- basic_waitable_timer<Clock, WaitTraits, Executor>& timer,- const typename Clock::time_point& expiry,- cancellation_type_t cancel_type = cancellation_type::terminal)- : token_(static_cast<T&&>(completion_token)),- timer_(timer),- expiry_(expiry),- cancel_type_(cancel_type)- {- }--//private:- CompletionToken token_;- basic_waitable_timer<Clock, WaitTraits, Executor>& timer_;- typename Clock::time_point expiry_;- cancellation_type_t cancel_type_;-};--/// A function object type that adapts a @ref completion_token to cancel an-/// operation at a given time.-/**- * May also be used directly as a completion token, in which case it adapts the- * asynchronous operation's default completion token (or asio::deferred- * if no default is available).- */-template <typename Clock, typename WaitTraits = asio::wait_traits<Clock>>-class partial_cancel_at-{-public:- /// Constructor that specifies the expiry and cancellation type.- explicit partial_cancel_at(const typename Clock::time_point& expiry,- cancellation_type_t cancel_type = cancellation_type::terminal)- : expiry_(expiry),- cancel_type_(cancel_type)- {- }-- /// Adapt a @ref completion_token to specify that the completion handler- /// arguments should be combined into a single tuple argument.- template <typename CompletionToken>- ASIO_NODISCARD inline- constexpr cancel_at_t<decay_t<CompletionToken>, Clock, WaitTraits>- operator()(CompletionToken&& completion_token) const- {- return cancel_at_t<decay_t<CompletionToken>, Clock, WaitTraits>(- static_cast<CompletionToken&&>(completion_token),- expiry_, cancel_type_);- }--//private:- typename Clock::time_point expiry_;- cancellation_type_t cancel_type_;-};--/// A function object type that adapts a @ref completion_token to cancel an-/// operation at a given time.-/**- * May also be used directly as a completion token, in which case it adapts the- * asynchronous operation's default completion token (or asio::deferred- * if no default is available).- */-template <typename Clock, typename WaitTraits = asio::wait_traits<Clock>,- typename Executor = any_io_executor>-class partial_cancel_at_timer-{-public:- /// Constructor that specifies the expiry and cancellation type.- explicit partial_cancel_at_timer(- basic_waitable_timer<Clock, WaitTraits, Executor>& timer,- const typename Clock::time_point& expiry,- cancellation_type_t cancel_type = cancellation_type::terminal)- : timer_(timer),- expiry_(expiry),- cancel_type_(cancel_type)- {- }-- /// Adapt a @ref completion_token to specify that the completion handler- /// arguments should be combined into a single tuple argument.- template <typename CompletionToken>- ASIO_NODISCARD inline- cancel_at_timer<decay_t<CompletionToken>, Clock, WaitTraits, Executor>- operator()(CompletionToken&& completion_token) const- {- return cancel_at_timer<decay_t<CompletionToken>,- Clock, WaitTraits, Executor>(- static_cast<CompletionToken&&>(completion_token),- timer_, expiry_, cancel_type_);- }--//private:- basic_waitable_timer<Clock, WaitTraits, Executor>& timer_;- typename Clock::time_point expiry_;- cancellation_type_t cancel_type_;-};--/// Create a partial completion token adapter that cancels an operation if not-/// complete by the specified absolute time.-/**- * @par Thread Safety- * When an asynchronous operation is used with cancel_at, a timer async_wait- * operation is performed in parallel to the main operation. If this parallel- * async_wait completes first, a cancellation request is emitted to cancel the- * main operation. Consequently, the application must ensure that the- * asynchronous operation is performed within an implicit or explicit strand.- */-template <typename Clock, typename Duration>-ASIO_NODISCARD inline partial_cancel_at<Clock>-cancel_at(const chrono::time_point<Clock, Duration>& expiry,- cancellation_type_t cancel_type = cancellation_type::terminal)-{- return partial_cancel_at<Clock>(expiry, cancel_type);-}--/// Create a partial completion token adapter that cancels an operation if not-/// complete by the specified absolute time.-/**- * @par Thread Safety- * When an asynchronous operation is used with cancel_at, a timer async_wait- * operation is performed in parallel to the main operation. If this parallel- * async_wait completes first, a cancellation request is emitted to cancel the- * main operation. Consequently, the application must ensure that the- * asynchronous operation is performed within an implicit or explicit strand.- */-template <typename Clock, typename WaitTraits,- typename Executor, typename Duration>-ASIO_NODISCARD inline partial_cancel_at_timer<Clock, WaitTraits, Executor>-cancel_at(basic_waitable_timer<Clock, WaitTraits, Executor>& timer,- const chrono::time_point<Clock, Duration>& expiry,- cancellation_type_t cancel_type = cancellation_type::terminal)-{- return partial_cancel_at_timer<Clock, WaitTraits, Executor>(- timer, expiry, cancel_type);-}--/// Adapt a @ref completion_token to cancel an operation if not complete by the-/// specified absolute time.-/**- * @par Thread Safety- * When an asynchronous operation is used with cancel_at, a timer async_wait- * operation is performed in parallel to the main operation. If this parallel- * async_wait completes first, a cancellation request is emitted to cancel the- * main operation. Consequently, the application must ensure that the- * asynchronous operation is performed within an implicit or explicit strand.- */-template <typename CompletionToken, typename Clock, typename Duration>-ASIO_NODISCARD inline cancel_at_t<decay_t<CompletionToken>, Clock>-cancel_at(const chrono::time_point<Clock, Duration>& expiry,- CompletionToken&& completion_token)-{- return cancel_at_t<decay_t<CompletionToken>, Clock>(- static_cast<CompletionToken&&>(completion_token),- expiry, cancellation_type::terminal);-}--/// Adapt a @ref completion_token to cancel an operation if not complete by the-/// specified absolute time.-/**- * @par Thread Safety- * When an asynchronous operation is used with cancel_at, a timer async_wait- * operation is performed in parallel to the main operation. If this parallel- * async_wait completes first, a cancellation request is emitted to cancel the- * main operation. Consequently, the application must ensure that the- * asynchronous operation is performed within an implicit or explicit strand.- */-template <typename CompletionToken, typename Clock, typename Duration>-ASIO_NODISCARD inline cancel_at_t<decay_t<CompletionToken>, Clock>-cancel_at(const chrono::time_point<Clock, Duration>& expiry,- cancellation_type_t cancel_type, CompletionToken&& completion_token)-{- return cancel_at_t<decay_t<CompletionToken>, Clock>(- static_cast<CompletionToken&&>(completion_token), expiry, cancel_type);-}--/// Adapt a @ref completion_token to cancel an operation if not complete by the-/// specified absolute time.-/**- * @par Thread Safety- * When an asynchronous operation is used with cancel_at, a timer async_wait- * operation is performed in parallel to the main operation. If this parallel- * async_wait completes first, a cancellation request is emitted to cancel the- * main operation. Consequently, the application must ensure that the- * asynchronous operation is performed within an implicit or explicit strand.- */-template <typename CompletionToken, typename Clock,- typename WaitTraits, typename Executor, typename Duration>-ASIO_NODISCARD inline-cancel_at_timer<decay_t<CompletionToken>, Clock, WaitTraits, Executor>-cancel_at(basic_waitable_timer<Clock, WaitTraits, Executor>& timer,- const chrono::time_point<Clock, Duration>& expiry,- CompletionToken&& completion_token)-{- return cancel_at_timer<decay_t<CompletionToken>, Clock, WaitTraits, Executor>(- static_cast<CompletionToken&&>(completion_token),- timer, expiry, cancellation_type::terminal);-}--/// Adapt a @ref completion_token to cancel an operation if not complete by the-/// specified absolute time.-/**- * @par Thread Safety- * When an asynchronous operation is used with cancel_at, a timer async_wait- * operation is performed in parallel to the main operation. If this parallel- * async_wait completes first, a cancellation request is emitted to cancel the- * main operation. Consequently, the application must ensure that the- * asynchronous operation is performed within an implicit or explicit strand.- */-template <typename CompletionToken, typename Clock,- typename WaitTraits, typename Executor, typename Duration>-ASIO_NODISCARD inline-cancel_at_timer<decay_t<CompletionToken>, Clock, WaitTraits, Executor>-cancel_at(basic_waitable_timer<Clock, WaitTraits, Executor>& timer,- const chrono::time_point<Clock, Duration>& expiry,- cancellation_type_t cancel_type, CompletionToken&& completion_token)-{- return cancel_at_timer<decay_t<CompletionToken>, Clock, WaitTraits, Executor>(- static_cast<CompletionToken&&>(completion_token),- timer, expiry, cancel_type);-}--} // namespace asio--#include "asio/detail/pop_options.hpp"--#include "asio/impl/cancel_at.hpp"--#endif // ASIO_CANCEL_AT_HPP
link/modules/asio-standalone/asio/include/asio/cancellation_signal.hpp view
@@ -2,7 +2,7 @@ // cancellation_signal.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -22,6 +22,7 @@ #include "asio/cancellation_type.hpp" #include "asio/detail/cstddef.hpp" #include "asio/detail/type_traits.hpp"+#include "asio/detail/variadic_templates.hpp" #include "asio/detail/push_options.hpp" @@ -32,7 +33,7 @@ { public: virtual void call(cancellation_type_t) = 0;- virtual std::pair<void*, std::size_t> destroy() noexcept = 0;+ virtual std::pair<void*, std::size_t> destroy() ASIO_NOEXCEPT = 0; protected: ~cancellation_handler_base() {}@@ -43,26 +44,45 @@ : public cancellation_handler_base { public:+#if defined(ASIO_HAS_VARIADIC_TEMPLATES) template <typename... Args>- cancellation_handler(std::size_t size, Args&&... args)- : handler_(static_cast<Args&&>(args)...),+ cancellation_handler(std::size_t size, ASIO_MOVE_ARG(Args)... args)+ : handler_(ASIO_MOVE_CAST(Args)(args)...), size_(size) { }+#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)+ cancellation_handler(std::size_t size)+ : handler_(),+ size_(size)+ {+ } +#define ASIO_PRIVATE_HANDLER_CTOR_DEF(n) \+ template <ASIO_VARIADIC_TPARAMS(n)> \+ cancellation_handler(std::size_t size, ASIO_VARIADIC_MOVE_PARAMS(n)) \+ : handler_(ASIO_VARIADIC_MOVE_ARGS(n)), \+ size_(size) \+ { \+ } \+ /**/+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_HANDLER_CTOR_DEF)+#undef ASIO_PRIVATE_HANDLER_CTOR_DEF+#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+ void call(cancellation_type_t type) { handler_(type); } - std::pair<void*, std::size_t> destroy() noexcept+ std::pair<void*, std::size_t> destroy() ASIO_NOEXCEPT { std::pair<void*, std::size_t> mem(this, size_); this->cancellation_handler::~cancellation_handler(); return mem; } - Handler& handler() noexcept+ Handler& handler() ASIO_NOEXCEPT { return handler_; }@@ -84,7 +104,7 @@ class cancellation_signal { public:- constexpr cancellation_signal()+ ASIO_CONSTEXPR cancellation_signal() : handler_(0) { }@@ -103,11 +123,11 @@ * The signal object must remain valid for as long the slot may be used. * Destruction of the signal invalidates the slot. */- cancellation_slot slot() noexcept;+ cancellation_slot slot() ASIO_NOEXCEPT; private:- cancellation_signal(const cancellation_signal&) = delete;- cancellation_signal& operator=(const cancellation_signal&) = delete;+ cancellation_signal(const cancellation_signal&) ASIO_DELETED;+ cancellation_signal& operator=(const cancellation_signal&) ASIO_DELETED; detail::cancellation_handler_base* handler_; };@@ -117,11 +137,13 @@ { public: /// Creates a slot that is not connected to any cancellation signal.- constexpr cancellation_slot()+ ASIO_CONSTEXPR cancellation_slot() : handler_(0) { } +#if defined(ASIO_HAS_VARIADIC_TEMPLATES) \+ || defined(GENERATING_DOCUMENTATION) /// Installs a handler into the slot, constructing the new object directly. /** * Destroys any existing handler in the slot, then installs the new handler,@@ -140,21 +162,58 @@ * be copy constructible or move constructible. */ template <typename CancellationHandler, typename... Args>- CancellationHandler& emplace(Args&&... args)+ CancellationHandler& emplace(ASIO_MOVE_ARG(Args)... args) { typedef detail::cancellation_handler<CancellationHandler> cancellation_handler_type; auto_delete_helper del = { prepare_memory( sizeof(cancellation_handler_type),- alignof(CancellationHandler)) };+ ASIO_ALIGNOF(CancellationHandler)) }; cancellation_handler_type* handler_obj = new (del.mem.first) cancellation_handler_type(- del.mem.second, static_cast<Args&&>(args)...);+ del.mem.second, ASIO_MOVE_CAST(Args)(args)...); del.mem.first = 0; *handler_ = handler_obj; return handler_obj->handler(); }+#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)+ // || defined(GENERATING_DOCUMENTATION)+ template <typename CancellationHandler>+ CancellationHandler& emplace()+ {+ typedef detail::cancellation_handler<CancellationHandler>+ cancellation_handler_type;+ auto_delete_helper del = { prepare_memory(+ sizeof(cancellation_handler_type),+ ASIO_ALIGNOF(CancellationHandler)) };+ cancellation_handler_type* handler_obj =+ new (del.mem.first) cancellation_handler_type(del.mem.second);+ del.mem.first = 0;+ *handler_ = handler_obj;+ return handler_obj->handler();+ } +#define ASIO_PRIVATE_HANDLER_EMPLACE_DEF(n) \+ template <typename CancellationHandler, ASIO_VARIADIC_TPARAMS(n)> \+ CancellationHandler& emplace(ASIO_VARIADIC_MOVE_PARAMS(n)) \+ { \+ typedef detail::cancellation_handler<CancellationHandler> \+ cancellation_handler_type; \+ auto_delete_helper del = { prepare_memory( \+ sizeof(cancellation_handler_type), \+ ASIO_ALIGNOF(CancellationHandler)) }; \+ cancellation_handler_type* handler_obj = \+ new (del.mem.first) cancellation_handler_type( \+ del.mem.second, ASIO_VARIADIC_MOVE_ARGS(n)); \+ del.mem.first = 0; \+ *handler_ = handler_obj; \+ return handler_obj->handler(); \+ } \+ /**/+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_HANDLER_EMPLACE_DEF)+#undef ASIO_PRIVATE_HANDLER_EMPLACE_DEF+#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+ /// Installs a handler into the slot. /** * Destroys any existing handler in the slot, then installs the new handler,@@ -169,10 +228,11 @@ * @returns A reference to the newly installed handler. */ template <typename CancellationHandler>- decay_t<CancellationHandler>& assign(CancellationHandler&& handler)+ typename decay<CancellationHandler>::type& assign(+ ASIO_MOVE_ARG(CancellationHandler) handler) {- return this->emplace<decay_t<CancellationHandler>>(- static_cast<CancellationHandler&&>(handler));+ return this->emplace<typename decay<CancellationHandler>::type>(+ ASIO_MOVE_CAST(CancellationHandler)(handler)); } /// Clears the slot.@@ -182,27 +242,27 @@ ASIO_DECL void clear(); /// Returns whether the slot is connected to a signal.- constexpr bool is_connected() const noexcept+ ASIO_CONSTEXPR bool is_connected() const ASIO_NOEXCEPT { return handler_ != 0; } /// Returns whether the slot is connected and has an installed handler.- constexpr bool has_handler() const noexcept+ ASIO_CONSTEXPR bool has_handler() const ASIO_NOEXCEPT { return handler_ != 0 && *handler_ != 0; } /// Compare two slots for equality.- friend constexpr bool operator==(const cancellation_slot& lhs,- const cancellation_slot& rhs) noexcept+ friend ASIO_CONSTEXPR bool operator==(const cancellation_slot& lhs,+ const cancellation_slot& rhs) ASIO_NOEXCEPT { return lhs.handler_ == rhs.handler_; } /// Compare two slots for inequality.- friend constexpr bool operator!=(const cancellation_slot& lhs,- const cancellation_slot& rhs) noexcept+ friend ASIO_CONSTEXPR bool operator!=(const cancellation_slot& lhs,+ const cancellation_slot& rhs) ASIO_NOEXCEPT { return lhs.handler_ != rhs.handler_; }@@ -210,7 +270,7 @@ private: friend class cancellation_signal; - constexpr cancellation_slot(int,+ ASIO_CONSTEXPR cancellation_slot(int, detail::cancellation_handler_base** handler) : handler_(handler) {@@ -229,7 +289,7 @@ detail::cancellation_handler_base** handler_; }; -inline cancellation_slot cancellation_signal::slot() noexcept+inline cancellation_slot cancellation_signal::slot() ASIO_NOEXCEPT { return cancellation_slot(0, &handler_); }
link/modules/asio-standalone/asio/include/asio/cancellation_state.hpp view
@@ -2,7 +2,7 @@ // cancellation_state.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -32,7 +32,7 @@ { /// Returns <tt>type & Mask</tt>. cancellation_type_t operator()(- cancellation_type_t type) const noexcept+ cancellation_type_t type) const ASIO_NOEXCEPT { return type & Mask; }@@ -80,7 +80,7 @@ { public: /// Construct a disconnected cancellation state.- constexpr cancellation_state() noexcept+ ASIO_CONSTEXPR cancellation_state() ASIO_NOEXCEPT : impl_(0) { }@@ -95,8 +95,8 @@ * attached. */ template <typename CancellationSlot>- constexpr explicit cancellation_state(CancellationSlot slot)- : impl_(slot.is_connected() ? &slot.template emplace<impl<>>() : 0)+ ASIO_CONSTEXPR explicit cancellation_state(CancellationSlot slot)+ : impl_(slot.is_connected() ? &slot.template emplace<impl<> >() : 0) { } @@ -119,9 +119,9 @@ * @li asio::enable_total_cancellation */ template <typename CancellationSlot, typename Filter>- constexpr cancellation_state(CancellationSlot slot, Filter filter)+ ASIO_CONSTEXPR cancellation_state(CancellationSlot slot, Filter filter) : impl_(slot.is_connected()- ? &slot.template emplace<impl<Filter, Filter>>(filter, filter)+ ? &slot.template emplace<impl<Filter, Filter> >(filter, filter) : 0) { }@@ -151,12 +151,12 @@ * @li asio::enable_total_cancellation */ template <typename CancellationSlot, typename InFilter, typename OutFilter>- constexpr cancellation_state(CancellationSlot slot,+ ASIO_CONSTEXPR cancellation_state(CancellationSlot slot, InFilter in_filter, OutFilter out_filter) : impl_(slot.is_connected()- ? &slot.template emplace<impl<InFilter, OutFilter>>(- static_cast<InFilter&&>(in_filter),- static_cast<OutFilter&&>(out_filter))+ ? &slot.template emplace<impl<InFilter, OutFilter> >(+ ASIO_MOVE_CAST(InFilter)(in_filter),+ ASIO_MOVE_CAST(OutFilter)(out_filter)) : 0) { }@@ -165,20 +165,20 @@ /** * This sub-slot is used with the operations that are being composed. */- constexpr cancellation_slot slot() const noexcept+ ASIO_CONSTEXPR cancellation_slot slot() const ASIO_NOEXCEPT { return impl_ ? impl_->signal_.slot() : cancellation_slot(); } /// Returns the cancellation types that have been triggered.- cancellation_type_t cancelled() const noexcept+ cancellation_type_t cancelled() const ASIO_NOEXCEPT { return impl_ ? impl_->cancelled_ : cancellation_type_t(); } /// Clears the specified cancellation types, if they have been triggered. void clear(cancellation_type_t mask = cancellation_type::all)- noexcept+ ASIO_NOEXCEPT { if (impl_) impl_->cancelled_ &= ~mask;@@ -208,8 +208,8 @@ } impl(InFilter in_filter, OutFilter out_filter)- : in_filter_(static_cast<InFilter&&>(in_filter)),- out_filter_(static_cast<OutFilter&&>(out_filter))+ : in_filter_(ASIO_MOVE_CAST(InFilter)(in_filter)),+ out_filter_(ASIO_MOVE_CAST(OutFilter)(out_filter)) { }
link/modules/asio-standalone/asio/include/asio/cancellation_type.hpp view
@@ -2,7 +2,7 @@ // cancellation_type.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -51,7 +51,7 @@ /// Portability typedef. typedef cancellation_type cancellation_type_t; -#else // defined(GENERATING_DOCUMENTATION)+#elif defined(ASIO_HAS_ENUM_CLASS) enum class cancellation_type : unsigned int {@@ -64,13 +64,30 @@ typedef cancellation_type cancellation_type_t; -#endif // defined(GENERATING_DOCUMENTATION)+#else // defined(ASIO_HAS_ENUM_CLASS) +namespace cancellation_type {++enum cancellation_type_t+{+ none = 0,+ terminal = 1,+ partial = 2,+ total = 4,+ all = 0xFFFFFFFF+};++} // namespace cancellation_type++typedef cancellation_type::cancellation_type_t cancellation_type_t;++#endif // defined(ASIO_HAS_ENUM_CLASS)+ /// Negation operator. /** * @relates cancellation_type */-inline constexpr bool operator!(cancellation_type_t x)+inline ASIO_CONSTEXPR bool operator!(cancellation_type_t x) { return static_cast<unsigned int>(x) == 0; }@@ -79,7 +96,7 @@ /** * @relates cancellation_type */-inline constexpr cancellation_type_t operator&(+inline ASIO_CONSTEXPR cancellation_type_t operator&( cancellation_type_t x, cancellation_type_t y) { return static_cast<cancellation_type_t>(@@ -90,7 +107,7 @@ /** * @relates cancellation_type */-inline constexpr cancellation_type_t operator|(+inline ASIO_CONSTEXPR cancellation_type_t operator|( cancellation_type_t x, cancellation_type_t y) { return static_cast<cancellation_type_t>(@@ -101,7 +118,7 @@ /** * @relates cancellation_type */-inline constexpr cancellation_type_t operator^(+inline ASIO_CONSTEXPR cancellation_type_t operator^( cancellation_type_t x, cancellation_type_t y) { return static_cast<cancellation_type_t>(@@ -112,7 +129,7 @@ /** * @relates cancellation_type */-inline constexpr cancellation_type_t operator~(cancellation_type_t x)+inline ASIO_CONSTEXPR cancellation_type_t operator~(cancellation_type_t x) { return static_cast<cancellation_type_t>(~static_cast<unsigned int>(x)); }
− link/modules/asio-standalone/asio/include/asio/co_composed.hpp
@@ -1,1319 +0,0 @@-//-// co_composed.hpp-// ~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef ASIO_CO_COMPOSED_HPP-#define ASIO_CO_COMPOSED_HPP--#if defined(_MSC_VER) && (_MSC_VER >= 1200)-# pragma once-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)--#include "asio/detail/config.hpp"--#if defined(ASIO_HAS_CO_AWAIT) || defined(GENERATING_DOCUMENTATION)--#include <new>-#include <tuple>-#include <variant>-#include "asio/associated_cancellation_slot.hpp"-#include "asio/associator.hpp"-#include "asio/async_result.hpp"-#include "asio/cancellation_state.hpp"-#include "asio/detail/composed_work.hpp"-#include "asio/detail/recycling_allocator.hpp"-#include "asio/detail/throw_error.hpp"-#include "asio/detail/type_traits.hpp"-#include "asio/error.hpp"--#if defined(ASIO_HAS_STD_COROUTINE)-# include <coroutine>-#else // defined(ASIO_HAS_STD_COROUTINE)-# include <experimental/coroutine>-#endif // defined(ASIO_HAS_STD_COROUTINE)--#if defined(ASIO_ENABLE_HANDLER_TRACKING)-# if defined(ASIO_HAS_SOURCE_LOCATION)-# include "asio/detail/source_location.hpp"-# endif // defined(ASIO_HAS_SOURCE_LOCATION)-#endif // defined(ASIO_ENABLE_HANDLER_TRACKING)--#include "asio/detail/push_options.hpp"--namespace asio {-namespace detail {--#if defined(ASIO_HAS_STD_COROUTINE)-using std::coroutine_handle;-using std::suspend_always;-using std::suspend_never;-#else // defined(ASIO_HAS_STD_COROUTINE)-using std::experimental::coroutine_handle;-using std::experimental::suspend_always;-using std::experimental::suspend_never;-#endif // defined(ASIO_HAS_STD_COROUTINE)--using asio::detail::composed_io_executors;-using asio::detail::composed_work;-using asio::detail::composed_work_guard;-using asio::detail::get_composed_io_executor;-using asio::detail::make_composed_io_executors;-using asio::detail::recycling_allocator;-using asio::detail::throw_error;--template <typename Executors, typename Handler, typename Return>-class co_composed_state;--template <typename Executors, typename Handler, typename Return>-class co_composed_handler_base;--template <typename Executors, typename Handler, typename Return>-class co_composed_promise;--template <ASIO_COMPLETION_SIGNATURE... Signatures>-class co_composed_returns-{-};--struct co_composed_on_suspend-{- void (*fn_)(void*) = nullptr;- void* arg_ = nullptr;-};--template <typename... T>-struct co_composed_completion : std::tuple<T&&...>-{- template <typename... U>- co_composed_completion(U&&... u) noexcept- : std::tuple<T&&...>(static_cast<U&&>(u)...)- {- }-};--template <typename Executors, typename Handler,- typename Return, typename Signature>-class co_composed_state_return_overload;--template <typename Executors, typename Handler,- typename Return, typename R, typename... Args>-class co_composed_state_return_overload<- Executors, Handler, Return, R(Args...)>-{-public:- using derived_type = co_composed_state<Executors, Handler, Return>;- using promise_type = co_composed_promise<Executors, Handler, Return>;- using return_type = std::tuple<Args...>;-- void on_cancellation_complete_with(Args... args)- {- derived_type& state = *static_cast<derived_type*>(this);- state.return_value_ = std::make_tuple(std::move(args)...);- state.cancellation_on_suspend_fn(- [](void* p)- {- auto& promise = *static_cast<promise_type*>(p);-- co_composed_handler_base<Executors, Handler,- Return> composed_handler(promise);-- Handler handler(std::move(promise.state().handler_));- return_type result(- std::move(std::get<return_type>(promise.state().return_value_)));-- co_composed_handler_base<Executors, Handler,- Return>(std::move(composed_handler));-- std::apply(std::move(handler), std::move(result));- });- }-};--template <typename Executors, typename Handler, typename Return>-class co_composed_state_return;--template <typename Executors, typename Handler, typename... Signatures>-class co_composed_state_return<- Executors, Handler, co_composed_returns<Signatures...>>- : public co_composed_state_return_overload<Executors,- Handler, co_composed_returns<Signatures...>, Signatures>...-{-public:- using co_composed_state_return_overload<Executors,- Handler, co_composed_returns<Signatures...>,- Signatures>::on_cancellation_complete_with...;--private:- template <typename, typename, typename, typename>- friend class co_composed_promise_return_overload;- template <typename, typename, typename, typename>- friend class co_composed_state_return_overload;-- std::variant<std::monostate,- typename co_composed_state_return_overload<- Executors, Handler, co_composed_returns<Signatures...>,- Signatures>::return_type...> return_value_;-};--template <typename Executors, typename Handler,- typename Return, typename... Signatures>-struct co_composed_state_default_cancellation_on_suspend_impl;--template <typename Executors, typename Handler, typename Return>-struct co_composed_state_default_cancellation_on_suspend_impl<- Executors, Handler, Return>-{- static constexpr void (*fn())(void*)- {- return nullptr;- }-};--template <typename Executors, typename Handler, typename Return,- typename R, typename... Args, typename... Signatures>-struct co_composed_state_default_cancellation_on_suspend_impl<- Executors, Handler, Return, R(Args...), Signatures...>-{- static constexpr void (*fn())(void*)- {- return co_composed_state_default_cancellation_on_suspend_impl<- Executors, Handler, Return, Signatures...>::fn();- }-};--template <typename Executors, typename Handler, typename Return,- typename R, typename... Args, typename... Signatures>-struct co_composed_state_default_cancellation_on_suspend_impl<Executors,- Handler, Return, R(asio::error_code, Args...), Signatures...>-{- using promise_type = co_composed_promise<Executors, Handler, Return>;- using return_type = std::tuple<asio::error_code, Args...>;-- static constexpr void (*fn())(void*)- {- if constexpr ((is_constructible<Args>::value && ...))- {- return [](void* p)- {- auto& promise = *static_cast<promise_type*>(p);-- co_composed_handler_base<Executors, Handler,- Return> composed_handler(promise);-- Handler handler(std::move(promise.state().handler_));-- co_composed_handler_base<Executors, Handler,- Return>(std::move(composed_handler));-- std::move(handler)(- asio::error_code(asio::error::operation_aborted),- Args{}...);- };- }- else- {- return co_composed_state_default_cancellation_on_suspend_impl<- Executors, Handler, Return, Signatures...>::fn();- }- }-};--template <typename Executors, typename Handler, typename Return,- typename R, typename... Args, typename... Signatures>-struct co_composed_state_default_cancellation_on_suspend_impl<Executors,- Handler, Return, R(std::exception_ptr, Args...), Signatures...>-{- using promise_type = co_composed_promise<Executors, Handler, Return>;- using return_type = std::tuple<std::exception_ptr, Args...>;-- static constexpr void (*fn())(void*)- {- if constexpr ((is_constructible<Args>::value && ...))- {- return [](void* p)- {- auto& promise = *static_cast<promise_type*>(p);-- co_composed_handler_base<Executors, Handler,- Return> composed_handler(promise);-- Handler handler(std::move(promise.state().handler_));-- co_composed_handler_base<Executors, Handler,- Return>(std::move(composed_handler));-- std::move(handler)(- std::make_exception_ptr(- asio::system_error(- asio::error::operation_aborted, "co_await")),- Args{}...);- };- }- else- {- return co_composed_state_default_cancellation_on_suspend_impl<- Executors, Handler, Return, Signatures...>::fn();- }- }-};--template <typename Executors, typename Handler, typename Return>-struct co_composed_state_default_cancellation_on_suspend;--template <typename Executors, typename Handler, typename... Signatures>-struct co_composed_state_default_cancellation_on_suspend<- Executors, Handler, co_composed_returns<Signatures...>>- : co_composed_state_default_cancellation_on_suspend_impl<Executors,- Handler, co_composed_returns<Signatures...>, Signatures...>-{-};--template <typename Executors, typename Handler, typename Return>-class co_composed_state_cancellation-{-public:- using cancellation_slot_type = cancellation_slot;-- cancellation_slot_type get_cancellation_slot() const noexcept- {- return cancellation_state_.slot();- }-- cancellation_state get_cancellation_state() const noexcept- {- return cancellation_state_;- }-- void reset_cancellation_state()- {- cancellation_state_ = cancellation_state(- (get_associated_cancellation_slot)(- static_cast<co_composed_state<Executors, Handler, Return>*>(- this)->handler()));- }-- template <typename Filter>- void reset_cancellation_state(Filter filter)- {- cancellation_state_ = cancellation_state(- (get_associated_cancellation_slot)(- static_cast<co_composed_state<Executors, Handler, Return>*>(- this)->handler()), filter, filter);- }-- template <typename InFilter, typename OutFilter>- void reset_cancellation_state(InFilter&& in_filter, OutFilter&& out_filter)- {- cancellation_state_ = cancellation_state(- (get_associated_cancellation_slot)(- static_cast<co_composed_state<Executors, Handler, Return>*>(- this)->handler()),- static_cast<InFilter&&>(in_filter),- static_cast<OutFilter&&>(out_filter));- }-- cancellation_type_t cancelled() const noexcept- {- return cancellation_state_.cancelled();- }-- void clear_cancellation_slot() noexcept- {- cancellation_state_.slot().clear();- }-- [[nodiscard]] bool throw_if_cancelled() const noexcept- {- return throw_if_cancelled_;- }-- void throw_if_cancelled(bool b) noexcept- {- throw_if_cancelled_ = b;- }-- [[nodiscard]] bool complete_if_cancelled() const noexcept- {- return complete_if_cancelled_;- }-- void complete_if_cancelled(bool b) noexcept- {- complete_if_cancelled_ = b;- }--private:- template <typename, typename, typename>- friend class co_composed_promise;- template <typename, typename, typename, typename>- friend class co_composed_state_return_overload;-- void cancellation_on_suspend_fn(void (*fn)(void*))- {- cancellation_on_suspend_fn_ = fn;- }-- void check_for_cancellation_on_transform()- {- if (throw_if_cancelled_ && !!cancelled())- throw_error(asio::error::operation_aborted, "co_await");- }-- bool check_for_cancellation_on_suspend(- co_composed_promise<Executors, Handler, Return>& promise) noexcept- {- if (complete_if_cancelled_ && !!cancelled() && cancellation_on_suspend_fn_)- {- promise.state().work_.reset();- promise.state().on_suspend_->fn_ = cancellation_on_suspend_fn_;- promise.state().on_suspend_->arg_ = &promise;- return false;- }- return true;- }-- cancellation_state cancellation_state_;- void (*cancellation_on_suspend_fn_)(void*) =- co_composed_state_default_cancellation_on_suspend<- Executors, Handler, Return>::fn();- bool throw_if_cancelled_ = false;- bool complete_if_cancelled_ = true;-};--template <typename Executors, typename Handler, typename Return>- requires is_same<- typename associated_cancellation_slot<- Handler, cancellation_slot- >::asio_associated_cancellation_slot_is_unspecialised,- void>::value-class co_composed_state_cancellation<Executors, Handler, Return>-{-public:- void reset_cancellation_state()- {- }-- template <typename Filter>- void reset_cancellation_state(Filter)- {- }-- template <typename InFilter, typename OutFilter>- void reset_cancellation_state(InFilter&&, OutFilter&&)- {- }-- cancellation_type_t cancelled() const noexcept- {- return cancellation_type::none;- }-- void clear_cancellation_slot() noexcept- {- }-- [[nodiscard]] bool throw_if_cancelled() const noexcept- {- return false;- }-- void throw_if_cancelled(bool) noexcept- {- }-- [[nodiscard]] bool complete_if_cancelled() const noexcept- {- return false;- }-- void complete_if_cancelled(bool) noexcept- {- }--private:- template <typename, typename, typename>- friend class co_composed_promise;- template <typename, typename, typename, typename>- friend class co_composed_state_return_overload;-- void cancellation_on_suspend_fn(void (*)(void*))- {- }-- void check_for_cancellation_on_transform() noexcept- {- }-- bool check_for_cancellation_on_suspend(- co_composed_promise<Executors, Handler, Return>&) noexcept- {- return true;- }-};--template <typename Executors, typename Handler, typename Return>-class co_composed_state- : public co_composed_state_return<Executors, Handler, Return>,- public co_composed_state_cancellation<Executors, Handler, Return>-{-public:- using io_executor_type = typename composed_work_guard<- typename composed_work<Executors>::head_type>::executor_type;-- template <typename H>- co_composed_state(composed_io_executors<Executors>&& executors,- H&& h, co_composed_on_suspend& on_suspend)- : work_(std::move(executors)),- handler_(static_cast<H&&>(h)),- on_suspend_(&on_suspend)- {- this->reset_cancellation_state(enable_terminal_cancellation());- }-- io_executor_type get_io_executor() const noexcept- {- return work_.head_.get_executor();- }-- template <typename... Args>- [[nodiscard]] co_composed_completion<Args...> complete(Args&&... args)- requires requires { declval<Handler>()(static_cast<Args&&>(args)...); }- {- return co_composed_completion<Args...>(static_cast<Args&&>(args)...);- }-- const Handler& handler() const noexcept- {- return handler_;- }--private:- template <typename, typename, typename>- friend class co_composed_handler_base;- template <typename, typename, typename>- friend class co_composed_promise;- template <typename, typename, typename, typename>- friend class co_composed_promise_return_overload;- template <typename, typename, typename>- friend class co_composed_state_cancellation;- template <typename, typename, typename, typename>- friend class co_composed_state_return_overload;- template <typename, typename, typename, typename...>- friend struct co_composed_state_default_cancellation_on_suspend_impl;-- composed_work<Executors> work_;- Handler handler_;- co_composed_on_suspend* on_suspend_;-};--template <typename Executors, typename Handler, typename Return>-class co_composed_handler_cancellation-{-public:- using cancellation_slot_type = cancellation_slot;-- cancellation_slot_type get_cancellation_slot() const noexcept- {- return static_cast<- const co_composed_handler_base<Executors, Handler, Return>*>(- this)->promise().state().get_cancellation_slot();- }-};--template <typename Executors, typename Handler, typename Return>- requires is_same<- typename associated_cancellation_slot<- Handler, cancellation_slot- >::asio_associated_cancellation_slot_is_unspecialised,- void>::value-class co_composed_handler_cancellation<Executors, Handler, Return>-{-};--template <typename Executors, typename Handler, typename Return>-class co_composed_handler_base :- public co_composed_handler_cancellation<Executors, Handler, Return>-{-public:- co_composed_handler_base(- co_composed_promise<Executors, Handler, Return>& p) noexcept- : p_(&p)- {- }-- co_composed_handler_base(co_composed_handler_base&& other) noexcept- : p_(std::exchange(other.p_, nullptr))- {- }-- ~co_composed_handler_base()- {- if (p_) [[unlikely]]- p_->destroy();- }-- co_composed_promise<Executors, Handler, Return>& promise() const noexcept- {- return *p_;- }--protected:- void resume(void* result)- {- co_composed_on_suspend on_suspend{};- std::exchange(p_, nullptr)->resume(p_, result, on_suspend);- if (on_suspend.fn_)- on_suspend.fn_(on_suspend.arg_);- }--private:- co_composed_promise<Executors, Handler, Return>* p_;-};--template <typename Executors, typename Handler,- typename Return, typename Signature>-class co_composed_handler;--template <typename Executors, typename Handler,- typename Return, typename R, typename... Args>-class co_composed_handler<Executors, Handler, Return, R(Args...)>- : public co_composed_handler_base<Executors, Handler, Return>-{-public:- using co_composed_handler_base<Executors,- Handler, Return>::co_composed_handler_base;-- using result_type = std::tuple<decay_t<Args>...>;-- template <typename... T>- void operator()(T&&... args)- {- result_type result(static_cast<T&&>(args)...);- this->resume(&result);- }-- static auto on_resume(void* result)- {- auto& args = *static_cast<result_type*>(result);- if constexpr (sizeof...(Args) == 0)- return;- else if constexpr (sizeof...(Args) == 1)- return std::move(std::get<0>(args));- else- return std::move(args);- }-};--template <typename Executors, typename Handler,- typename Return, typename R, typename... Args>-class co_composed_handler<Executors, Handler,- Return, R(asio::error_code, Args...)>- : public co_composed_handler_base<Executors, Handler, Return>-{-public:- using co_composed_handler_base<Executors,- Handler, Return>::co_composed_handler_base;-- using args_type = std::tuple<decay_t<Args>...>;- using result_type = std::tuple<asio::error_code, args_type>;-- template <typename... T>- void operator()(const asio::error_code& ec, T&&... args)- {- result_type result(ec, args_type(static_cast<T&&>(args)...));- this->resume(&result);- }-- static auto on_resume(void* result)- {- auto& [ec, args] = *static_cast<result_type*>(result);- throw_error(ec);- if constexpr (sizeof...(Args) == 0)- return;- else if constexpr (sizeof...(Args) == 1)- return std::move(std::get<0>(args));- else- return std::move(args);- }-};--template <typename Executors, typename Handler,- typename Return, typename R, typename... Args>-class co_composed_handler<Executors, Handler,- Return, R(std::exception_ptr, Args...)>- : public co_composed_handler_base<Executors, Handler, Return>-{-public:- using co_composed_handler_base<Executors,- Handler, Return>::co_composed_handler_base;-- using args_type = std::tuple<decay_t<Args>...>;- using result_type = std::tuple<std::exception_ptr, args_type>;-- template <typename... T>- void operator()(std::exception_ptr ex, T&&... args)- {- result_type result(std::move(ex), args_type(static_cast<T&&>(args)...));- this->resume(&result);- }-- static auto on_resume(void* result)- {- auto& [ex, args] = *static_cast<result_type*>(result);- if (ex)- std::rethrow_exception(ex);- if constexpr (sizeof...(Args) == 0)- return;- else if constexpr (sizeof...(Args) == 1)- return std::move(std::get<0>(args));- else- return std::move(args);- }-};--template <typename Executors, typename Handler, typename Return>-class co_composed_promise_return;--template <typename Executors, typename Handler>-class co_composed_promise_return<Executors, Handler, co_composed_returns<>>-{-public:- auto final_suspend() noexcept- {- return suspend_never();- }-- void return_void() noexcept- {- }-};--template <typename Executors, typename Handler,- typename Return, typename Signature>-class co_composed_promise_return_overload;--template <typename Executors, typename Handler,- typename Return, typename R, typename... Args>-class co_composed_promise_return_overload<- Executors, Handler, Return, R(Args...)>-{-public:- using derived_type = co_composed_promise<Executors, Handler, Return>;- using return_type = std::tuple<Args...>;-- void return_value(std::tuple<Args...>&& value)- {- derived_type& promise = *static_cast<derived_type*>(this);- promise.state().return_value_ = std::move(value);- promise.state().work_.reset();- promise.state().on_suspend_->arg_ = this;- promise.state().on_suspend_->fn_ =- [](void* p)- {- auto& promise = *static_cast<derived_type*>(p);-- co_composed_handler_base<Executors, Handler,- Return> composed_handler(promise);-- Handler handler(std::move(promise.state().handler_));- return_type result(- std::move(std::get<return_type>(promise.state().return_value_)));-- co_composed_handler_base<Executors, Handler,- Return>(std::move(composed_handler));-- std::apply(std::move(handler), std::move(result));- };- }-};--template <typename Executors, typename Handler, typename... Signatures>-class co_composed_promise_return<Executors,- Handler, co_composed_returns<Signatures...>>- : public co_composed_promise_return_overload<Executors,- Handler, co_composed_returns<Signatures...>, Signatures>...-{-public:- auto final_suspend() noexcept- {- return suspend_always();- }-- using co_composed_promise_return_overload<Executors, Handler,- co_composed_returns<Signatures...>, Signatures>::return_value...;--private:- template <typename, typename, typename, typename>- friend class co_composed_promise_return_overload;-};--template <typename Executors, typename Handler, typename Return>-class co_composed_promise- : public co_composed_promise_return<Executors, Handler, Return>-{-public:- template <typename... Args>- void* operator new(std::size_t size,- co_composed_state<Executors, Handler, Return>& state, Args&&...)- {- block_allocator_type allocator(- (get_associated_allocator)(state.handler_,- recycling_allocator<void>()));-- block* base_ptr = std::allocator_traits<block_allocator_type>::allocate(- allocator, blocks(sizeof(allocator_type)) + blocks(size));-- new (static_cast<void*>(base_ptr)) allocator_type(std::move(allocator));-- return base_ptr + blocks(sizeof(allocator_type));- }-- template <typename C, typename... Args>- void* operator new(std::size_t size, C&&,- co_composed_state<Executors, Handler, Return>& state, Args&&...)- {- return co_composed_promise::operator new(size, state);- }-- void operator delete(void* ptr, std::size_t size)- {- block* base_ptr = static_cast<block*>(ptr) - blocks(sizeof(allocator_type));-- allocator_type* allocator_ptr = std::launder(- static_cast<allocator_type*>(static_cast<void*>(base_ptr)));-- block_allocator_type block_allocator(std::move(*allocator_ptr));- allocator_ptr->~allocator_type();-- std::allocator_traits<block_allocator_type>::deallocate(block_allocator,- base_ptr, blocks(sizeof(allocator_type)) + blocks(size));- }-- template <typename... Args>- co_composed_promise(- co_composed_state<Executors, Handler, Return>& state, Args&&...)- : state_(state)- {- }-- template <typename C, typename... Args>- co_composed_promise(C&&,- co_composed_state<Executors, Handler, Return>& state, Args&&...)- : state_(state)- {- }-- void destroy() noexcept- {- coroutine_handle<co_composed_promise>::from_promise(*this).destroy();- }-- void resume(co_composed_promise*& owner, void* result,- co_composed_on_suspend& on_suspend)- {- state_.on_suspend_ = &on_suspend;- state_.clear_cancellation_slot();- owner_ = &owner;- result_ = result;- coroutine_handle<co_composed_promise>::from_promise(*this).resume();- }-- co_composed_state<Executors, Handler, Return>& state() noexcept- {- return state_;- }-- void get_return_object() noexcept- {- }-- auto initial_suspend() noexcept- {- return suspend_never();- }-- void unhandled_exception()- {- if (owner_)- *owner_ = this;- throw;- }-- template <ASIO_ASYNC_OPERATION Op>- auto await_transform(Op&& op,-#if defined(ASIO_ENABLE_HANDLER_TRACKING)-# if defined(ASIO_HAS_SOURCE_LOCATION)- asio::detail::source_location location- = asio::detail::source_location::current(),-# endif // defined(ASIO_HAS_SOURCE_LOCATION)-#endif // defined(ASIO_ENABLE_HANDLER_TRACKING)- constraint_t<is_async_operation<Op>::value> = 0)- {- class [[nodiscard]] awaitable- {- public:- awaitable(Op&& op, co_composed_promise& promise-#if defined(ASIO_ENABLE_HANDLER_TRACKING)-# if defined(ASIO_HAS_SOURCE_LOCATION)- , const asio::detail::source_location& location-# endif // defined(ASIO_HAS_SOURCE_LOCATION)-#endif // defined(ASIO_ENABLE_HANDLER_TRACKING)- )- : op_(static_cast<Op&&>(op)),- promise_(promise)-#if defined(ASIO_ENABLE_HANDLER_TRACKING)-# if defined(ASIO_HAS_SOURCE_LOCATION)- , location_(location)-# endif // defined(ASIO_HAS_SOURCE_LOCATION)-#endif // defined(ASIO_ENABLE_HANDLER_TRACKING)- {- }-- constexpr bool await_ready() const noexcept- {- return false;- }-- void await_suspend(coroutine_handle<co_composed_promise>)- {- if (promise_.state_.check_for_cancellation_on_suspend(promise_))- {- promise_.state_.on_suspend_->arg_ = this;- promise_.state_.on_suspend_->fn_ =- [](void* p)- {-#if defined(ASIO_ENABLE_HANDLER_TRACKING)-# if defined(ASIO_HAS_SOURCE_LOCATION)- ASIO_HANDLER_LOCATION((- static_cast<awaitable*>(p)->location_.file_name(),- static_cast<awaitable*>(p)->location_.line(),- static_cast<awaitable*>(p)->location_.function_name()));-# endif // defined(ASIO_HAS_SOURCE_LOCATION)-#endif // defined(ASIO_ENABLE_HANDLER_TRACKING)- static_cast<Op&&>(static_cast<awaitable*>(p)->op_)(- co_composed_handler<Executors, Handler,- Return, completion_signature_of_t<Op>>(- static_cast<awaitable*>(p)->promise_));- };- }- }-- auto await_resume()- {- return co_composed_handler<Executors, Handler, Return,- completion_signature_of_t<Op>>::on_resume(promise_.result_);- }-- private:- Op&& op_;- co_composed_promise& promise_;-#if defined(ASIO_ENABLE_HANDLER_TRACKING)-# if defined(ASIO_HAS_SOURCE_LOCATION)- asio::detail::source_location location_;-# endif // defined(ASIO_HAS_SOURCE_LOCATION)-#endif // defined(ASIO_ENABLE_HANDLER_TRACKING)- };-- state_.check_for_cancellation_on_transform();- return awaitable{static_cast<Op&&>(op), *this-#if defined(ASIO_ENABLE_HANDLER_TRACKING)-# if defined(ASIO_HAS_SOURCE_LOCATION)- , location-# endif // defined(ASIO_HAS_SOURCE_LOCATION)-#endif // defined(ASIO_ENABLE_HANDLER_TRACKING)- };- }-- template <typename... Args>- auto yield_value(co_composed_completion<Args...>&& result)- {- class [[nodiscard]] awaitable- {- public:- awaitable(co_composed_completion<Args...>&& result,- co_composed_promise& promise)- : result_(std::move(result)),- promise_(promise)- {- }-- constexpr bool await_ready() const noexcept- {- return false;- }-- void await_suspend(coroutine_handle<co_composed_promise>)- {- promise_.state_.work_.reset();- promise_.state_.on_suspend_->arg_ = this;- promise_.state_.on_suspend_->fn_ =- [](void* p)- {- awaitable& a = *static_cast<awaitable*>(p);-- co_composed_handler_base<Executors, Handler,- Return> composed_handler(a.promise_);-- Handler handler(std::move(a.promise_.state_.handler_));- std::tuple<decay_t<Args>...> result(- std::move(static_cast<std::tuple<Args&&...>&>(a.result_)));-- co_composed_handler_base<Executors, Handler,- Return>(std::move(composed_handler));-- std::apply(std::move(handler), std::move(result));- };- }-- void await_resume() noexcept- {- }-- private:- co_composed_completion<Args...> result_;- co_composed_promise& promise_;- };-- return awaitable{std::move(result), *this};- }--private:- using allocator_type =- associated_allocator_t<Handler, recycling_allocator<void>>;-- union block- {- std::max_align_t max_align;- alignas(allocator_type) char pad[alignof(allocator_type)];- };-- using block_allocator_type =- typename std::allocator_traits<allocator_type>- ::template rebind_alloc<block>;-- static constexpr std::size_t blocks(std::size_t size)- {- return (size + sizeof(block) - 1) / sizeof(block);- }-- co_composed_state<Executors, Handler, Return>& state_;- co_composed_promise** owner_ = nullptr;- void* result_ = nullptr;-};--template <typename Implementation, typename Executors, typename... Signatures>-class initiate_co_composed-{-public:- using executor_type = typename composed_io_executors<Executors>::head_type;-- template <typename I>- initiate_co_composed(I&& impl, composed_io_executors<Executors>&& executors)- : implementation_(static_cast<I&&>(impl)),- executors_(std::move(executors))- {- }-- executor_type get_executor() const noexcept- {- return executors_.head_;- }-- template <typename Handler, typename... InitArgs>- void operator()(Handler&& handler, InitArgs&&... init_args) const &- {- using handler_type = decay_t<Handler>;- using returns_type = co_composed_returns<Signatures...>;- co_composed_on_suspend on_suspend{};- implementation_(- co_composed_state<Executors, handler_type, returns_type>(- executors_, static_cast<Handler&&>(handler), on_suspend),- static_cast<InitArgs&&>(init_args)...);- if (on_suspend.fn_)- on_suspend.fn_(on_suspend.arg_);- }-- template <typename Handler, typename... InitArgs>- void operator()(Handler&& handler, InitArgs&&... init_args) &&- {- using handler_type = decay_t<Handler>;- using returns_type = co_composed_returns<Signatures...>;- co_composed_on_suspend on_suspend{};- std::move(implementation_)(- co_composed_state<Executors, handler_type, returns_type>(- std::move(executors_), static_cast<Handler&&>(handler), on_suspend),- static_cast<InitArgs&&>(init_args)...);- if (on_suspend.fn_)- on_suspend.fn_(on_suspend.arg_);- }--private:- Implementation implementation_;- composed_io_executors<Executors> executors_;-};--template <typename Implementation, typename... Signatures>-class initiate_co_composed<Implementation, void(), Signatures...>-{-public:- template <typename I>- initiate_co_composed(I&& impl, composed_io_executors<void()>&&)- : implementation_(static_cast<I&&>(impl))- {- }-- template <typename Handler, typename... InitArgs>- void operator()(Handler&& handler, InitArgs&&... init_args) const &- {- using handler_type = decay_t<Handler>;- using returns_type = co_composed_returns<Signatures...>;- co_composed_on_suspend on_suspend{};- implementation_(- co_composed_state<void(), handler_type, returns_type>(- composed_io_executors<void()>(),- static_cast<Handler&&>(handler), on_suspend),- static_cast<InitArgs&&>(init_args)...);- if (on_suspend.fn_)- on_suspend.fn_(on_suspend.arg_);- }-- template <typename Handler, typename... InitArgs>- void operator()(Handler&& handler, InitArgs&&... init_args) &&- {- using handler_type = decay_t<Handler>;- using returns_type = co_composed_returns<Signatures...>;- co_composed_on_suspend on_suspend{};- std::move(implementation_)(- co_composed_state<void(), handler_type, returns_type>(- composed_io_executors<void()>(),- static_cast<Handler&&>(handler), on_suspend),- static_cast<InitArgs&&>(init_args)...);- if (on_suspend.fn_)- on_suspend.fn_(on_suspend.arg_);- }--private:- Implementation implementation_;-};--template <typename... Signatures, typename Implementation, typename Executors>-inline initiate_co_composed<decay_t<Implementation>, Executors, Signatures...>-make_initiate_co_composed(Implementation&& implementation,- composed_io_executors<Executors>&& executors)-{- return initiate_co_composed<- decay_t<Implementation>, Executors, Signatures...>(- static_cast<Implementation&&>(implementation), std::move(executors));-}--} // namespace detail--#if !defined(GENERATING_DOCUMENTATION)--template <template <typename, typename> class Associator,- typename Executors, typename Handler, typename Return,- typename Signature, typename DefaultCandidate>-struct associator<Associator,- detail::co_composed_handler<Executors, Handler, Return, Signature>,- DefaultCandidate>- : Associator<Handler, DefaultCandidate>-{- static typename Associator<Handler, DefaultCandidate>::type get(- const detail::co_composed_handler<- Executors, Handler, Return, Signature>& h) noexcept- {- return Associator<Handler, DefaultCandidate>::get(- h.promise().state().handler());- }-- static auto get(- const detail::co_composed_handler<- Executors, Handler, Return, Signature>& h,- const DefaultCandidate& c) noexcept- -> decltype(- Associator<Handler, DefaultCandidate>::get(- h.promise().state().handler(), c))- {- return Associator<Handler, DefaultCandidate>::get(- h.promise().state().handler(), c);- }-};--#endif // !defined(GENERATING_DOCUMENTATION)--} // namespace asio--#if !defined(GENERATING_DOCUMENTATION)-# if defined(ASIO_HAS_STD_COROUTINE)-namespace std {-# else // defined(ASIO_HAS_STD_COROUTINE)-namespace std { namespace experimental {-# endif // defined(ASIO_HAS_STD_COROUTINE)--template <typename C, typename Executors,- typename Handler, typename Return, typename... Args>-struct coroutine_traits<void, C&,- asio::detail::co_composed_state<Executors, Handler, Return>, Args...>-{- using promise_type =- asio::detail::co_composed_promise<Executors, Handler, Return>;-};--template <typename C, typename Executors,- typename Handler, typename Return, typename... Args>-struct coroutine_traits<void, C&&,- asio::detail::co_composed_state<Executors, Handler, Return>, Args...>-{- using promise_type =- asio::detail::co_composed_promise<Executors, Handler, Return>;-};--template <typename Executors, typename Handler,- typename Return, typename... Args>-struct coroutine_traits<void,- asio::detail::co_composed_state<Executors, Handler, Return>, Args...>-{- using promise_type =- asio::detail::co_composed_promise<Executors, Handler, Return>;-};--# if defined(ASIO_HAS_STD_COROUTINE)-} // namespace std-# else // defined(ASIO_HAS_STD_COROUTINE)-}} // namespace std::experimental-# endif // defined(ASIO_HAS_STD_COROUTINE)-#endif // !defined(GENERATING_DOCUMENTATION)--namespace asio {--/// Creates an initiation function object that may be used to launch a-/// coroutine-based composed asynchronous operation.-/**- * The co_composed utility simplifies the implementation of composed- * asynchronous operations by automatically adapting a coroutine to be an- * initiation function object for use with @c async_initiate. When awaiting- * asynchronous operations, the coroutine automatically uses a conforming- * intermediate completion handler.- *- * @param implementation A function object that contains the coroutine-based- * implementation of the composed asynchronous operation. The first argument to- * the function object represents the state of the operation, and may be used- * to test for cancellation. The remaining arguments are those passed to @c- * async_initiate after the completion token.- *- * @param io_objects_or_executors Zero or more I/O objects or I/O executors for- * which outstanding work must be maintained while the operation is incomplete.- *- * @par Per-Operation Cancellation- * By default, terminal per-operation cancellation is enabled for composed- * operations that use co_composed. To disable cancellation for the composed- * operation, or to alter its supported cancellation types, call the state's- * @c reset_cancellation_state function.- *- * @par Examples- * The following example illustrates manual error handling and explicit checks- * for cancellation. The completion handler is invoked via a @c co_yield to the- * state's @c complete function, which never returns.- *- * @code template <typename CompletionToken>- * auto async_echo(tcp::socket& socket,- * CompletionToken&& token)- * {- * return asio::async_initiate<- * CompletionToken, void(std::error_code)>(- * asio::co_composed(- * [](auto state, tcp::socket& socket) -> void- * {- * state.reset_cancellation_state(- * asio::enable_terminal_cancellation());- *- * while (!state.cancelled())- * {- * char data[1024];- * auto [e1, n1] =- * co_await socket.async_read_some(- * asio::buffer(data));- *- * if (e1)- * co_yield state.complete(e1);- *- * if (!!state.cancelled())- * co_yield state.complete(- * make_error_code(asio::error::operation_aborted));- *- * auto [e2, n2] =- * co_await asio::async_write(socket,- * asio::buffer(data, n1));- *- * if (e2)- * co_yield state.complete(e2);- * }- * }, socket),- * token, std::ref(socket));- * } @endcode- *- * This next example shows exception-based error handling and implicit checks- * for cancellation. The completion handler is invoked after returning from the- * coroutine via @c co_return. Valid @c co_return values are specified using- * completion signatures passed to the @c co_composed function.- *- * @code template <typename CompletionToken>- * auto async_echo(tcp::socket& socket,- * CompletionToken&& token)- * {- * return asio::async_initiate<- * CompletionToken, void(std::error_code)>(- * asio::co_composed<- * void(std::error_code)>(- * [](auto state, tcp::socket& socket) -> void- * {- * try- * {- * state.throw_if_cancelled(true);- * state.reset_cancellation_state(- * asio::enable_terminal_cancellation());- *- * for (;;)- * {- * char data[1024];- * std::size_t n = co_await socket.async_read_some(- * asio::buffer(data));- *- * co_await asio::async_write(socket,- * asio::buffer(data, n));- * }- * }- * catch (const std::system_error& e)- * {- * co_return {e.code()};- * }- * }, socket),- * token, std::ref(socket));- * } @endcode- */-template <ASIO_COMPLETION_SIGNATURE... Signatures,- typename Implementation, typename... IoObjectsOrExecutors>-inline auto co_composed(Implementation&& implementation,- IoObjectsOrExecutors&&... io_objects_or_executors)-{- return detail::make_initiate_co_composed<Signatures...>(- static_cast<Implementation&&>(implementation),- detail::make_composed_io_executors(- detail::get_composed_io_executor(- static_cast<IoObjectsOrExecutors&&>(- io_objects_or_executors))...));-}--} // namespace asio--#include "asio/detail/pop_options.hpp"--#endif // defined(ASIO_HAS_CO_AWAIT) || defined(GENERATING_DOCUMENTATION)--#endif // ASIO_CO_COMPOSED_HPP
link/modules/asio-standalone/asio/include/asio/co_spawn.hpp view
@@ -2,7 +2,7 @@ // co_spawn.hpp // ~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -113,10 +113,10 @@ co_spawn(const Executor& ex, awaitable<T, AwaitableExecutor> a, CompletionToken&& token ASIO_DEFAULT_COMPLETION_TOKEN(Executor),- constraint_t<+ typename constraint< (is_executor<Executor>::value || execution::is_executor<Executor>::value) && is_convertible<Executor, AwaitableExecutor>::value- > = 0);+ >::type = 0); /// Spawn a new coroutined-based thread of execution. /**@@ -177,10 +177,10 @@ co_spawn(const Executor& ex, awaitable<void, AwaitableExecutor> a, CompletionToken&& token ASIO_DEFAULT_COMPLETION_TOKEN(Executor),- constraint_t<+ typename constraint< (is_executor<Executor>::value || execution::is_executor<Executor>::value) && is_convertible<Executor, AwaitableExecutor>::value- > = 0);+ >::type = 0); /// Spawn a new coroutined-based thread of execution. /**@@ -251,11 +251,11 @@ CompletionToken&& token ASIO_DEFAULT_COMPLETION_TOKEN( typename ExecutionContext::executor_type),- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value && is_convertible<typename ExecutionContext::executor_type, AwaitableExecutor>::value- > = 0);+ >::type = 0); /// Spawn a new coroutined-based thread of execution. /**@@ -318,11 +318,11 @@ CompletionToken&& token ASIO_DEFAULT_COMPLETION_TOKEN( typename ExecutionContext::executor_type),- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value && is_convertible<typename ExecutionContext::executor_type, AwaitableExecutor>::value- > = 0);+ >::type = 0); /// Spawn a new coroutined-based thread of execution. /**@@ -406,16 +406,16 @@ */ template <typename Executor, typename F, ASIO_COMPLETION_TOKEN_FOR(typename detail::awaitable_signature<- result_of_t<F()>>::type) CompletionToken+ typename result_of<F()>::type>::type) CompletionToken ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(Executor)> ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken,- typename detail::awaitable_signature<result_of_t<F()>>::type)+ typename detail::awaitable_signature<typename result_of<F()>::type>::type) co_spawn(const Executor& ex, F&& f, CompletionToken&& token ASIO_DEFAULT_COMPLETION_TOKEN(Executor),- constraint_t<+ typename constraint< is_executor<Executor>::value || execution::is_executor<Executor>::value- > = 0);+ >::type = 0); /// Spawn a new coroutined-based thread of execution. /**@@ -499,18 +499,18 @@ */ template <typename ExecutionContext, typename F, ASIO_COMPLETION_TOKEN_FOR(typename detail::awaitable_signature<- result_of_t<F()>>::type) CompletionToken+ typename result_of<F()>::type>::type) CompletionToken ASIO_DEFAULT_COMPLETION_TOKEN_TYPE( typename ExecutionContext::executor_type)> ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken,- typename detail::awaitable_signature<result_of_t<F()>>::type)+ typename detail::awaitable_signature<typename result_of<F()>::type>::type) co_spawn(ExecutionContext& ctx, F&& f, CompletionToken&& token ASIO_DEFAULT_COMPLETION_TOKEN( typename ExecutionContext::executor_type),- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- > = 0);+ >::type = 0); } // namespace asio
link/modules/asio-standalone/asio/include/asio/completion_condition.hpp view
@@ -2,7 +2,7 @@ // completion_condition.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -17,8 +17,6 @@ #include "asio/detail/config.hpp" #include <cstddef>-#include "asio/detail/type_traits.hpp"-#include "asio/error_code.hpp" #include "asio/detail/push_options.hpp" @@ -99,54 +97,7 @@ std::size_t size_; }; -template <typename T, typename = void>-struct is_completion_condition_helper : false_type-{-};--template <typename T>-struct is_completion_condition_helper<T,- enable_if_t<- is_same<- result_of_t<T(asio::error_code, std::size_t)>,- bool- >::value- >- > : true_type-{-};--template <typename T>-struct is_completion_condition_helper<T,- enable_if_t<- is_same<- result_of_t<T(asio::error_code, std::size_t)>,- std::size_t- >::value- >- > : true_type-{-};- } // namespace detail--#if defined(GENERATING_DOCUMENTATION)--/// Trait for determining whether a function object is a completion condition.-template <typename T>-struct is_completion_condition-{- static constexpr bool value = automatically_determined;-};--#else // defined(GENERATING_DOCUMENTATION)--template <typename T>-struct is_completion_condition : detail::is_completion_condition_helper<T>-{-};--#endif // defined(GENERATING_DOCUMENTATION) /** * @defgroup completion_condition Completion Condition Function Objects
link/modules/asio-standalone/asio/include/asio/compose.hpp view
@@ -2,7 +2,7 @@ // compose.hpp // ~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -16,12 +16,311 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"-#include "asio/composed.hpp"+#include "asio/associated_executor.hpp"+#include "asio/async_result.hpp"+#include "asio/detail/base_from_cancellation_state.hpp"+#include "asio/detail/composed_work.hpp"+#include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_cont_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp"+#include "asio/detail/type_traits.hpp"+#include "asio/detail/variadic_templates.hpp" #include "asio/detail/push_options.hpp" namespace asio {+namespace detail { +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+template <typename Impl, typename Work, typename Handler, typename Signature>+class composed_op;++template <typename Impl, typename Work, typename Handler,+ typename R, typename... Args>+class composed_op<Impl, Work, Handler, R(Args...)>+#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)+template <typename Impl, typename Work, typename Handler, typename Signature>+class composed_op+#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+ : public base_from_cancellation_state<Handler>+{+public:+ template <typename I, typename W, typename H>+ composed_op(ASIO_MOVE_ARG(I) impl,+ ASIO_MOVE_ARG(W) work,+ ASIO_MOVE_ARG(H) handler)+ : base_from_cancellation_state<Handler>(+ handler, enable_terminal_cancellation()),+ impl_(ASIO_MOVE_CAST(I)(impl)),+ work_(ASIO_MOVE_CAST(W)(work)),+ handler_(ASIO_MOVE_CAST(H)(handler)),+ invocations_(0)+ {+ }++#if defined(ASIO_HAS_MOVE)+ composed_op(composed_op&& other)+ : base_from_cancellation_state<Handler>(+ ASIO_MOVE_CAST(base_from_cancellation_state<+ Handler>)(other)),+ impl_(ASIO_MOVE_CAST(Impl)(other.impl_)),+ work_(ASIO_MOVE_CAST(Work)(other.work_)),+ handler_(ASIO_MOVE_CAST(Handler)(other.handler_)),+ invocations_(other.invocations_)+ {+ }+#endif // defined(ASIO_HAS_MOVE)++ typedef typename composed_work_guard<+ typename Work::head_type>::executor_type io_executor_type;++ io_executor_type get_io_executor() const ASIO_NOEXCEPT+ {+ return work_.head_.get_executor();+ }++ typedef typename associated_executor<Handler, io_executor_type>::type+ executor_type;++ executor_type get_executor() const ASIO_NOEXCEPT+ {+ return (get_associated_executor)(handler_, work_.head_.get_executor());+ }++ typedef typename associated_allocator<Handler,+ std::allocator<void> >::type allocator_type;++ allocator_type get_allocator() const ASIO_NOEXCEPT+ {+ return (get_associated_allocator)(handler_, std::allocator<void>());+ }++#if defined(ASIO_HAS_VARIADIC_TEMPLATES)++ template<typename... T>+ void operator()(ASIO_MOVE_ARG(T)... t)+ {+ if (invocations_ < ~0u)+ ++invocations_;+ this->get_cancellation_state().slot().clear();+ impl_(*this, ASIO_MOVE_CAST(T)(t)...);+ }++ void complete(Args... args)+ {+ this->work_.reset();+ ASIO_MOVE_OR_LVALUE(Handler)(this->handler_)(+ ASIO_MOVE_CAST(Args)(args)...);+ }++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++ void operator()()+ {+ if (invocations_ < ~0u)+ ++invocations_;+ this->get_cancellation_state().slot().clear();+ impl_(*this);+ }++ void complete()+ {+ this->work_.reset();+ ASIO_MOVE_OR_LVALUE(Handler)(this->handler_)();+ }++#define ASIO_PRIVATE_COMPOSED_OP_DEF(n) \+ template<ASIO_VARIADIC_TPARAMS(n)> \+ void operator()(ASIO_VARIADIC_MOVE_PARAMS(n)) \+ { \+ if (invocations_ < ~0u) \+ ++invocations_; \+ this->get_cancellation_state().slot().clear(); \+ impl_(*this, ASIO_VARIADIC_MOVE_ARGS(n)); \+ } \+ \+ template<ASIO_VARIADIC_TPARAMS(n)> \+ void complete(ASIO_VARIADIC_MOVE_PARAMS(n)) \+ { \+ this->work_.reset(); \+ ASIO_MOVE_OR_LVALUE(Handler)(this->handler_)( \+ ASIO_VARIADIC_MOVE_ARGS(n)); \+ } \+ /**/+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_COMPOSED_OP_DEF)+#undef ASIO_PRIVATE_COMPOSED_OP_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++ void reset_cancellation_state()+ {+ base_from_cancellation_state<Handler>::reset_cancellation_state(handler_);+ }++ template <typename Filter>+ void reset_cancellation_state(ASIO_MOVE_ARG(Filter) filter)+ {+ base_from_cancellation_state<Handler>::reset_cancellation_state(handler_,+ ASIO_MOVE_CAST(Filter)(filter));+ }++ template <typename InFilter, typename OutFilter>+ void reset_cancellation_state(ASIO_MOVE_ARG(InFilter) in_filter,+ ASIO_MOVE_ARG(OutFilter) out_filter)+ {+ base_from_cancellation_state<Handler>::reset_cancellation_state(handler_,+ ASIO_MOVE_CAST(InFilter)(in_filter),+ ASIO_MOVE_CAST(OutFilter)(out_filter));+ }++ cancellation_type_t cancelled() const ASIO_NOEXCEPT+ {+ return base_from_cancellation_state<Handler>::cancelled();+ }++//private:+ Impl impl_;+ Work work_;+ Handler handler_;+ unsigned invocations_;+};++template <typename Impl, typename Work, typename Handler, typename Signature>+inline asio_handler_allocate_is_deprecated+asio_handler_allocate(std::size_t size,+ composed_op<Impl, Work, Handler, Signature>* this_handler)+{+#if defined(ASIO_NO_DEPRECATED)+ asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+ return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+ return asio_handler_alloc_helpers::allocate(+ size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Impl, typename Work, typename Handler, typename Signature>+inline asio_handler_deallocate_is_deprecated+asio_handler_deallocate(void* pointer, std::size_t size,+ composed_op<Impl, Work, Handler, Signature>* this_handler)+{+ asio_handler_alloc_helpers::deallocate(+ pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Impl, typename Work, typename Handler, typename Signature>+inline bool asio_handler_is_continuation(+ composed_op<Impl, Work, Handler, Signature>* this_handler)+{+ return this_handler->invocations_ > 1 ? true+ : asio_handler_cont_helpers::is_continuation(+ this_handler->handler_);+}++template <typename Function, typename Impl,+ typename Work, typename Handler, typename Signature>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(Function& function,+ composed_op<Impl, Work, Handler, Signature>* this_handler)+{+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Function, typename Impl,+ typename Work, typename Handler, typename Signature>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(const Function& function,+ composed_op<Impl, Work, Handler, Signature>* this_handler)+{+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Signature, typename Executors>+class initiate_composed_op+{+public:+ typedef typename composed_io_executors<Executors>::head_type executor_type;++ template <typename T>+ explicit initiate_composed_op(int, ASIO_MOVE_ARG(T) executors)+ : executors_(ASIO_MOVE_CAST(T)(executors))+ {+ }++ executor_type get_executor() const ASIO_NOEXCEPT+ {+ return executors_.head_;+ }++ template <typename Handler, typename Impl>+ void operator()(ASIO_MOVE_ARG(Handler) handler,+ ASIO_MOVE_ARG(Impl) impl) const+ {+ composed_op<typename decay<Impl>::type, composed_work<Executors>,+ typename decay<Handler>::type, Signature>(+ ASIO_MOVE_CAST(Impl)(impl),+ composed_work<Executors>(executors_),+ ASIO_MOVE_CAST(Handler)(handler))();+ }++private:+ composed_io_executors<Executors> executors_;+};++template <typename Signature, typename Executors>+inline initiate_composed_op<Signature, Executors> make_initiate_composed_op(+ ASIO_MOVE_ARG(composed_io_executors<Executors>) executors)+{+ return initiate_composed_op<Signature, Executors>(0,+ ASIO_MOVE_CAST(composed_io_executors<Executors>)(executors));+}++} // namespace detail++#if !defined(GENERATING_DOCUMENTATION)++template <template <typename, typename> class Associator,+ typename Impl, typename Work, typename Handler,+ typename Signature, typename DefaultCandidate>+struct associator<Associator,+ detail::composed_op<Impl, Work, Handler, Signature>,+ DefaultCandidate>+ : Associator<Handler, DefaultCandidate>+{+ static typename Associator<Handler, DefaultCandidate>::type+ get(const detail::composed_op<Impl, Work, Handler, Signature>& h)+ ASIO_NOEXCEPT+ {+ return Associator<Handler, DefaultCandidate>::get(h.handler_);+ }++ static ASIO_AUTO_RETURN_TYPE_PREFIX2(+ typename Associator<Handler, DefaultCandidate>::type)+ get(const detail::composed_op<Impl, Work, Handler, Signature>& h,+ const DefaultCandidate& c) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ Associator<Handler, DefaultCandidate>::get(h.handler_, c)))+ {+ return Associator<Handler, DefaultCandidate>::get(h.handler_, c);+ }+};++#endif // !defined(GENERATING_DOCUMENTATION)++#if defined(ASIO_HAS_VARIADIC_TEMPLATES) \+ || defined(GENERATING_DOCUMENTATION)+ /// Launch an asynchronous operation with a stateful implementation. /** * The async_compose function simplifies the implementation of composed@@ -40,13 +339,6 @@ * @param io_objects_or_executors Zero or more I/O objects or I/O executors for * which outstanding work must be maintained. *- * @par Per-Operation Cancellation- * By default, terminal per-operation cancellation is enabled for- * composed operations that are implemented using @c async_compose. To- * disable cancellation for the composed operation, or to alter its- * supported cancellation types, call the @c self object's @c- * reset_cancellation_state function.- * * @par Example: * * @code struct async_echo_implementation@@ -90,8 +382,8 @@ * template <typename CompletionToken> * auto async_echo(tcp::socket& socket, * asio::mutable_buffer buffer,- * CompletionToken&& token)- * -> decltype(+ * CompletionToken&& token) ->+ * decltype( * asio::async_compose<CompletionToken, * void(asio::error_code, std::size_t)>( * std::declval<async_echo_implementation>(),@@ -106,20 +398,131 @@ */ template <typename CompletionToken, typename Signature, typename Implementation, typename... IoObjectsOrExecutors>-inline auto async_compose(Implementation&& implementation,- type_identity_t<CompletionToken>& token,- IoObjectsOrExecutors&&... io_objects_or_executors)- -> decltype(+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(CompletionToken, Signature)+async_compose(ASIO_MOVE_ARG(Implementation) implementation,+ ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token,+ ASIO_MOVE_ARG(IoObjectsOrExecutors)... io_objects_or_executors)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<CompletionToken, Signature>(- composed<Signature>(static_cast<Implementation&&>(implementation),- static_cast<IoObjectsOrExecutors&&>(io_objects_or_executors)...),- token))+ detail::make_initiate_composed_op<Signature>(+ detail::make_composed_io_executors(+ detail::get_composed_io_executor(+ ASIO_MOVE_CAST(IoObjectsOrExecutors)(+ io_objects_or_executors))...)),+ token, ASIO_MOVE_CAST(Implementation)(implementation)))) { return async_initiate<CompletionToken, Signature>(- composed<Signature>(static_cast<Implementation&&>(implementation),- static_cast<IoObjectsOrExecutors&&>(io_objects_or_executors)...),- token);+ detail::make_initiate_composed_op<Signature>(+ detail::make_composed_io_executors(+ detail::get_composed_io_executor(+ ASIO_MOVE_CAST(IoObjectsOrExecutors)(+ io_objects_or_executors))...)),+ token, ASIO_MOVE_CAST(Implementation)(implementation)); }++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)+ // || defined(GENERATING_DOCUMENTATION)++template <typename CompletionToken, typename Signature, typename Implementation>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(CompletionToken, Signature)+async_compose(ASIO_MOVE_ARG(Implementation) implementation,+ ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_initiate<CompletionToken, Signature>(+ detail::make_initiate_composed_op<Signature>(+ detail::make_composed_io_executors()),+ token, ASIO_MOVE_CAST(Implementation)(implementation))))+{+ return async_initiate<CompletionToken, Signature>(+ detail::make_initiate_composed_op<Signature>(+ detail::make_composed_io_executors()),+ token, ASIO_MOVE_CAST(Implementation)(implementation));+}++# define ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR(n) \+ ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_##n++# define ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_1 \+ detail::get_composed_io_executor(ASIO_MOVE_CAST(T1)(x1))+# define ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_2 \+ detail::get_composed_io_executor(ASIO_MOVE_CAST(T1)(x1)), \+ detail::get_composed_io_executor(ASIO_MOVE_CAST(T2)(x2))+# define ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_3 \+ detail::get_composed_io_executor(ASIO_MOVE_CAST(T1)(x1)), \+ detail::get_composed_io_executor(ASIO_MOVE_CAST(T2)(x2)), \+ detail::get_composed_io_executor(ASIO_MOVE_CAST(T3)(x3))+# define ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_4 \+ detail::get_composed_io_executor(ASIO_MOVE_CAST(T1)(x1)), \+ detail::get_composed_io_executor(ASIO_MOVE_CAST(T2)(x2)), \+ detail::get_composed_io_executor(ASIO_MOVE_CAST(T3)(x3)), \+ detail::get_composed_io_executor(ASIO_MOVE_CAST(T4)(x4))+# define ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_5 \+ detail::get_composed_io_executor(ASIO_MOVE_CAST(T1)(x1)), \+ detail::get_composed_io_executor(ASIO_MOVE_CAST(T2)(x2)), \+ detail::get_composed_io_executor(ASIO_MOVE_CAST(T3)(x3)), \+ detail::get_composed_io_executor(ASIO_MOVE_CAST(T4)(x4)), \+ detail::get_composed_io_executor(ASIO_MOVE_CAST(T5)(x5))+# define ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_6 \+ detail::get_composed_io_executor(ASIO_MOVE_CAST(T1)(x1)), \+ detail::get_composed_io_executor(ASIO_MOVE_CAST(T2)(x2)), \+ detail::get_composed_io_executor(ASIO_MOVE_CAST(T3)(x3)), \+ detail::get_composed_io_executor(ASIO_MOVE_CAST(T4)(x4)), \+ detail::get_composed_io_executor(ASIO_MOVE_CAST(T5)(x5)), \+ detail::get_composed_io_executor(ASIO_MOVE_CAST(T6)(x6))+# define ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_7 \+ detail::get_composed_io_executor(ASIO_MOVE_CAST(T1)(x1)), \+ detail::get_composed_io_executor(ASIO_MOVE_CAST(T2)(x2)), \+ detail::get_composed_io_executor(ASIO_MOVE_CAST(T3)(x3)), \+ detail::get_composed_io_executor(ASIO_MOVE_CAST(T4)(x4)), \+ detail::get_composed_io_executor(ASIO_MOVE_CAST(T5)(x5)), \+ detail::get_composed_io_executor(ASIO_MOVE_CAST(T6)(x6)), \+ detail::get_composed_io_executor(ASIO_MOVE_CAST(T7)(x7))+# define ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_8 \+ detail::get_composed_io_executor(ASIO_MOVE_CAST(T1)(x1)), \+ detail::get_composed_io_executor(ASIO_MOVE_CAST(T2)(x2)), \+ detail::get_composed_io_executor(ASIO_MOVE_CAST(T3)(x3)), \+ detail::get_composed_io_executor(ASIO_MOVE_CAST(T4)(x4)), \+ detail::get_composed_io_executor(ASIO_MOVE_CAST(T5)(x5)), \+ detail::get_composed_io_executor(ASIO_MOVE_CAST(T6)(x6)), \+ detail::get_composed_io_executor(ASIO_MOVE_CAST(T7)(x7)), \+ detail::get_composed_io_executor(ASIO_MOVE_CAST(T8)(x8))++#define ASIO_PRIVATE_ASYNC_COMPOSE_DEF(n) \+ template <typename CompletionToken, typename Signature, \+ typename Implementation, ASIO_VARIADIC_TPARAMS(n)> \+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(CompletionToken, Signature) \+ async_compose(ASIO_MOVE_ARG(Implementation) implementation, \+ ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \+ ASIO_VARIADIC_MOVE_PARAMS(n)) \+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( \+ async_initiate<CompletionToken, Signature>( \+ detail::make_initiate_composed_op<Signature>( \+ detail::make_composed_io_executors( \+ ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR(n))), \+ token, ASIO_MOVE_CAST(Implementation)(implementation)))) \+ { \+ return async_initiate<CompletionToken, Signature>( \+ detail::make_initiate_composed_op<Signature>( \+ detail::make_composed_io_executors( \+ ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR(n))), \+ token, ASIO_MOVE_CAST(Implementation)(implementation)); \+ } \+ /**/+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_ASYNC_COMPOSE_DEF)+#undef ASIO_PRIVATE_ASYNC_COMPOSE_DEF++#undef ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR+#undef ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_1+#undef ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_2+#undef ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_3+#undef ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_4+#undef ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_5+#undef ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_6+#undef ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_7+#undef ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_8++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+ // || defined(GENERATING_DOCUMENTATION) } // namespace asio
− link/modules/asio-standalone/asio/include/asio/composed.hpp
@@ -1,413 +0,0 @@-//-// composed.hpp-// ~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef ASIO_COMPOSED_HPP-#define ASIO_COMPOSED_HPP--#if defined(_MSC_VER) && (_MSC_VER >= 1200)-# pragma once-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)--#include "asio/detail/config.hpp"-#include "asio/associated_executor.hpp"-#include "asio/async_result.hpp"-#include "asio/detail/base_from_cancellation_state.hpp"-#include "asio/detail/composed_work.hpp"-#include "asio/detail/handler_cont_helpers.hpp"-#include "asio/detail/type_traits.hpp"--#include "asio/detail/push_options.hpp"--namespace asio {-namespace detail {--template <typename Impl, typename Work,- typename Handler, typename... Signatures>-class composed_op;--template <typename Impl, typename Work, typename Handler>-class composed_op<Impl, Work, Handler>- : public base_from_cancellation_state<Handler>-{-public:- template <typename I, typename W, typename H>- composed_op(I&& impl,- W&& work,- H&& handler)- : base_from_cancellation_state<Handler>(- handler, enable_terminal_cancellation()),- impl_(static_cast<I&&>(impl)),- work_(static_cast<W&&>(work)),- handler_(static_cast<H&&>(handler)),- invocations_(0)- {- }-- composed_op(composed_op&& other)- : base_from_cancellation_state<Handler>(- static_cast<base_from_cancellation_state<Handler>&&>(other)),- impl_(static_cast<Impl&&>(other.impl_)),- work_(static_cast<Work&&>(other.work_)),- handler_(static_cast<Handler&&>(other.handler_)),- invocations_(other.invocations_)- {- }-- typedef typename composed_work_guard<- typename Work::head_type>::executor_type io_executor_type;-- io_executor_type get_io_executor() const noexcept- {- return work_.head_.get_executor();- }-- typedef associated_executor_t<Handler, io_executor_type> executor_type;-- executor_type get_executor() const noexcept- {- return (get_associated_executor)(handler_, work_.head_.get_executor());- }-- typedef associated_allocator_t<Handler, std::allocator<void>> allocator_type;-- allocator_type get_allocator() const noexcept- {- return (get_associated_allocator)(handler_, std::allocator<void>());- }-- template <typename... T>- void operator()(T&&... t)- {- if (invocations_ < ~0u)- ++invocations_;- this->get_cancellation_state().slot().clear();- impl_(*this, static_cast<T&&>(t)...);- }-- template <typename... Args>- auto complete(Args&&... args)- -> decltype(declval<Handler>()(static_cast<Args&&>(args)...))- {- return static_cast<Handler&&>(this->handler_)(static_cast<Args&&>(args)...);- }-- void reset_cancellation_state()- {- base_from_cancellation_state<Handler>::reset_cancellation_state(handler_);- }-- template <typename Filter>- void reset_cancellation_state(Filter&& filter)- {- base_from_cancellation_state<Handler>::reset_cancellation_state(handler_,- static_cast<Filter&&>(filter));- }-- template <typename InFilter, typename OutFilter>- void reset_cancellation_state(InFilter&& in_filter,- OutFilter&& out_filter)- {- base_from_cancellation_state<Handler>::reset_cancellation_state(handler_,- static_cast<InFilter&&>(in_filter),- static_cast<OutFilter&&>(out_filter));- }-- cancellation_type_t cancelled() const noexcept- {- return base_from_cancellation_state<Handler>::cancelled();- }--//private:- Impl impl_;- Work work_;- Handler handler_;- unsigned invocations_;-};--template <typename Impl, typename Work, typename Handler,- typename R, typename... Args>-class composed_op<Impl, Work, Handler, R(Args...)>- : public composed_op<Impl, Work, Handler>-{-public:- using composed_op<Impl, Work, Handler>::composed_op;-- template <typename... T>- void operator()(T&&... t)- {- if (this->invocations_ < ~0u)- ++this->invocations_;- this->get_cancellation_state().slot().clear();- this->impl_(*this, static_cast<T&&>(t)...);- }-- void complete(Args... args)- {- this->work_.reset();- static_cast<Handler&&>(this->handler_)(static_cast<Args&&>(args)...);- }-};--template <typename Impl, typename Work, typename Handler,- typename R, typename... Args, typename... Signatures>-class composed_op<Impl, Work, Handler, R(Args...), Signatures...>- : public composed_op<Impl, Work, Handler, Signatures...>-{-public:- using composed_op<Impl, Work, Handler, Signatures...>::composed_op;-- template <typename... T>- void operator()(T&&... t)- {- if (this->invocations_ < ~0u)- ++this->invocations_;- this->get_cancellation_state().slot().clear();- this->impl_(*this, static_cast<T&&>(t)...);- }-- using composed_op<Impl, Work, Handler, Signatures...>::complete;-- void complete(Args... args)- {- this->work_.reset();- static_cast<Handler&&>(this->handler_)(static_cast<Args&&>(args)...);- }-};--template <typename Impl, typename Work, typename Handler, typename Signature>-inline bool asio_handler_is_continuation(- composed_op<Impl, Work, Handler, Signature>* this_handler)-{- return this_handler->invocations_ > 1 ? true- : asio_handler_cont_helpers::is_continuation(- this_handler->handler_);-}--template <typename Implementation, typename Executors, typename... Signatures>-class initiate_composed-{-public:- typedef typename composed_io_executors<Executors>::head_type executor_type;-- template <typename I>- initiate_composed(I&& impl, composed_io_executors<Executors>&& executors)- : implementation_(std::forward<I>(impl)),- executors_(std::move(executors))- {- }-- executor_type get_executor() const noexcept- {- return executors_.head_;- }-- template <typename Handler, typename... Args>- void operator()(Handler&& handler, Args&&... args) const &- {- composed_op<decay_t<Implementation>, composed_work<Executors>,- decay_t<Handler>, Signatures...>(implementation_,- composed_work<Executors>(executors_),- static_cast<Handler&&>(handler))(static_cast<Args&&>(args)...);- }-- template <typename Handler, typename... Args>- void operator()(Handler&& handler, Args&&... args) &&- {- composed_op<decay_t<Implementation>, composed_work<Executors>,- decay_t<Handler>, Signatures...>(- static_cast<Implementation&&>(implementation_),- composed_work<Executors>(executors_),- static_cast<Handler&&>(handler))(static_cast<Args&&>(args)...);- }--private:- Implementation implementation_;- composed_io_executors<Executors> executors_;-};--template <typename Implementation, typename... Signatures>-class initiate_composed<Implementation, void(), Signatures...>-{-public:- template <typename I>- initiate_composed(I&& impl, composed_io_executors<void()>&&)- : implementation_(std::forward<I>(impl))- {- }-- template <typename Handler, typename... Args>- void operator()(Handler&& handler, Args&&... args) const &- {- composed_op<decay_t<Implementation>, composed_work<void()>,- decay_t<Handler>, Signatures...>(implementation_,- composed_work<void()>(composed_io_executors<void()>()),- static_cast<Handler&&>(handler))(static_cast<Args&&>(args)...);- }-- template <typename Handler, typename... Args>- void operator()(Handler&& handler, Args&&... args) &&- {- composed_op<decay_t<Implementation>, composed_work<void()>,- decay_t<Handler>, Signatures...>(- static_cast<Implementation&&>(implementation_),- composed_work<void()>(composed_io_executors<void()>()),- static_cast<Handler&&>(handler))(static_cast<Args&&>(args)...);- }--private:- Implementation implementation_;-};--template <typename... Signatures, typename Implementation, typename Executors>-inline initiate_composed<Implementation, Executors, Signatures...>-make_initiate_composed(Implementation&& implementation,- composed_io_executors<Executors>&& executors)-{- return initiate_composed<decay_t<Implementation>, Executors, Signatures...>(- static_cast<Implementation&&>(implementation),- static_cast<composed_io_executors<Executors>&&>(executors));-}--} // namespace detail--#if !defined(GENERATING_DOCUMENTATION)--template <template <typename, typename> class Associator,- typename Impl, typename Work, typename Handler,- typename Signature, typename DefaultCandidate>-struct associator<Associator,- detail::composed_op<Impl, Work, Handler, Signature>,- DefaultCandidate>- : Associator<Handler, DefaultCandidate>-{- static typename Associator<Handler, DefaultCandidate>::type get(- const detail::composed_op<Impl, Work, Handler, Signature>& h) noexcept- {- return Associator<Handler, DefaultCandidate>::get(h.handler_);- }-- static auto get(const detail::composed_op<Impl, Work, Handler, Signature>& h,- const DefaultCandidate& c) noexcept- -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))- {- return Associator<Handler, DefaultCandidate>::get(h.handler_, c);- }-};--#endif // !defined(GENERATING_DOCUMENTATION)--/// Creates an initiation function object that may be used to launch an-/// asynchronous operation with a stateful implementation.-/**- * The @c composed function simplifies the implementation of composed- * asynchronous operations automatically by wrapping a stateful function object- * for use as an initiation function object.- *- * @param implementation A function object that contains the implementation of- * the composed asynchronous operation. The first argument to the function- * object is a non-const reference to the enclosing intermediate completion- * handler. The remaining arguments are any arguments that originate from the- * completion handlers of any asynchronous operations performed by the- * implementation.- *- * @param io_objects_or_executors Zero or more I/O objects or I/O executors for- * which outstanding work must be maintained.- *- * @par Per-Operation Cancellation- * By default, terminal per-operation cancellation is enabled for composed- * operations that are implemented using @c composed. To disable cancellation- * for the composed operation, or to alter its supported cancellation types,- * call the @c self object's @c reset_cancellation_state function.- *- * @par Example:- *- * @code struct async_echo_implementation- * {- * tcp::socket& socket_;- * asio::mutable_buffer buffer_;- * enum { starting, reading, writing } state_;- *- * template <typename Self>- * void operator()(Self& self,- * asio::error_code error,- * std::size_t n)- * {- * switch (state_)- * {- * case starting:- * state_ = reading;- * socket_.async_read_some(- * buffer_, std::move(self));- * break;- * case reading:- * if (error)- * {- * self.complete(error, 0);- * }- * else- * {- * state_ = writing;- * asio::async_write(socket_, buffer_,- * asio::transfer_exactly(n),- * std::move(self));- * }- * break;- * case writing:- * self.complete(error, n);- * break;- * }- * }- * };- *- * template <typename CompletionToken>- * auto async_echo(tcp::socket& socket,- * asio::mutable_buffer buffer,- * CompletionToken&& token)- * -> decltype(- * asio::async_initiate<CompletionToken,- * void(asio::error_code, std::size_t)>(- * asio::composed(- * async_echo_implementation{socket, buffer,- * async_echo_implementation::starting}, socket),- * token))- * {- * return asio::async_initiate<CompletionToken,- * void(asio::error_code, std::size_t)>(- * asio::composed(- * async_echo_implementation{socket, buffer,- * async_echo_implementation::starting}, socket),- * token, asio::error_code{}, 0);- * } @endcode- */-template <ASIO_COMPLETION_SIGNATURE... Signatures,- typename Implementation, typename... IoObjectsOrExecutors>-inline auto composed(Implementation&& implementation,- IoObjectsOrExecutors&&... io_objects_or_executors)- -> decltype(- detail::make_initiate_composed<Signatures...>(- static_cast<Implementation&&>(implementation),- detail::make_composed_io_executors(- detail::get_composed_io_executor(- static_cast<IoObjectsOrExecutors&&>(- io_objects_or_executors))...)))-{- return detail::make_initiate_composed<Signatures...>(- static_cast<Implementation&&>(implementation),- detail::make_composed_io_executors(- detail::get_composed_io_executor(- static_cast<IoObjectsOrExecutors&&>(- io_objects_or_executors))...));-}--} // namespace asio--#include "asio/detail/pop_options.hpp"--#endif // ASIO_COMPOSE_HPP
− link/modules/asio-standalone/asio/include/asio/config.hpp
@@ -1,193 +0,0 @@-//-// config.hpp-// ~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef ASIO_CONFIG_HPP-#define ASIO_CONFIG_HPP--#if defined(_MSC_VER) && (_MSC_VER >= 1200)-# pragma once-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)--#include "asio/detail/config.hpp"-#include "asio/detail/throw_exception.hpp"-#include "asio/detail/type_traits.hpp"-#include "asio/execution_context.hpp"-#include <cstddef>-#include <string>--#include "asio/detail/push_options.hpp"--namespace asio {--/// Base class for configuration implementations.-class config_service :-#if defined(GENERATING_DOCUMENTATION)- public execution_context::service-#else // defined(GENERATING_DOCUMENTATION)- public detail::execution_context_service_base<config_service>-#endif // defined(GENERATING_DOCUMENTATION)-{-public:-#if defined(GENERATING_DOCUMENTATION)- typedef config_service key_type;-#endif // defined(GENERATING_DOCUMENTATION)-- /// Constructor.- ASIO_DECL explicit config_service(execution_context& ctx);-- /// Shutdown the service.- ASIO_DECL void shutdown() override;-- /// Retrieve a configuration value.- ASIO_DECL virtual const char* get_value(const char* section,- const char* key_name, char* value, std::size_t value_len) const;-};--/// Provides access to the configuration values associated with an execution-/// context.-class config-{-public:- /// Constructor.- /**- * This constructor initialises a @c config object to retrieve configuration- * values associated with the specified execution context.- */- explicit config(execution_context& context)- : service_(use_service<config_service>(context))- {- }-- /// Copy constructor.- config(const config& other) noexcept- : service_(other.service_)- {- }-- /// Retrieve an integral configuration value.- template <typename T>- constraint_t<is_integral<T>::value, T>- get(const char* section, const char* key_name, T default_value) const;--private:- config_service& service_;-};--/// Configures an execution context based on a concurrency hint.-/**- * This configuration service is provided for backwards compatibility with- * the existing concurrency hint mechanism.- *- * @par Example- * @code asio::io_context my_io_context{- * asio::config_from_concurrency_hint{1}}; @endcode- */-class config_from_concurrency_hint : public execution_context::service_maker-{-public:- /// Construct with a default concurrency hint.- ASIO_DECL config_from_concurrency_hint();-- /// Construct with a specified concurrency hint.- explicit config_from_concurrency_hint(int concurrency_hint)- : concurrency_hint_(concurrency_hint)- {- }-- /// Add a concrete service to the specified execution context.- ASIO_DECL void make(execution_context& ctx) const override;--private:- int concurrency_hint_;-};--/// Configures an execution context by reading variables from a string.-/**- * Each variable must be on a line of its own, and of the form:- *- * <tt>section.key=value</tt>- *- * or, if an optional prefix is specified:- *- * <tt>prefix.section.key=value</tt>- *- * Blank lines and lines starting with <tt>#</tt> are ignored. It is also- * permitted to include a comment starting with <tt>#</tt> after the value.- *- * @par Example- * @code asio::io_context my_io_context{- * asio::config_from_string{- * "scheduler.concurrency_hint=10\n"- * "scheduler.locking=1"}}; @endcode- */-class config_from_string : public execution_context::service_maker-{-public:- /// Construct with the default prefix "asio".- explicit config_from_string(std::string s)- : string_(static_cast<std::string&&>(s)),- prefix_()- {- }-- /// Construct with a specified prefix.- config_from_string(std::string s, std::string prefix)- : string_(static_cast<std::string&&>(s)),- prefix_(static_cast<std::string&&>(prefix))- {- }-- /// Add a concrete service to the specified execution context.- ASIO_DECL void make(execution_context& ctx) const override;--private:- std::string string_;- std::string prefix_;-};--/// Configures an execution context by reading environment variables.-/**- * The environment variable names are formed by concatenating the prefix,- * section, and key, with underscore as delimiter, and then converting the- * resulting string to upper case.- *- * @par Example- * @code asio::io_context my_io_context{- * asio::config_from_env{"my_app"}}; @endcode- */-class config_from_env : public execution_context::service_maker-{-public:- /// Construct with the default prefix "asio".- ASIO_DECL config_from_env();-- /// Construct with a specified prefix.- explicit config_from_env(std::string prefix)- : prefix_(static_cast<std::string&&>(prefix))- {- }-- /// Add a concrete service to the specified execution context.- ASIO_DECL void make(execution_context& ctx) const override;--private:- std::string prefix_;-};--} // namespace asio--#include "asio/detail/pop_options.hpp"--#include "asio/impl/config.hpp"-#if defined(ASIO_HEADER_ONLY)-# include "asio/impl/config.ipp"-#endif // defined(ASIO_HEADER_ONLY)--#endif // ASIO_CONFIG_HPP
link/modules/asio-standalone/asio/include/asio/connect.hpp view
@@ -2,7 +2,7 @@ // connect.hpp // ~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -31,97 +31,34 @@ template <typename, typename> class initiate_async_range_connect; template <typename, typename> class initiate_async_iterator_connect; - template <typename T, typename = void, typename = void>- struct is_endpoint_sequence_helper : false_type- {- };+ char (&has_iterator_helper(...))[2]; template <typename T>- struct is_endpoint_sequence_helper<T,- void_t<- decltype(declval<T>().begin())- >,- void_t<- decltype(declval<T>().end())- >- > : true_type- {- };-- template <typename T, typename Iterator, typename = void>- struct is_connect_condition_helper : false_type- {- };-- template <typename T, typename Iterator>- struct is_connect_condition_helper<T, Iterator,- enable_if_t<- is_same<- result_of_t<T(asio::error_code, Iterator)>,- Iterator- >::value- >- > : true_type- {- };-- template <typename T, typename Iterator>- struct is_connect_condition_helper<T, Iterator,- enable_if_t<- is_same<- result_of_t<T(asio::error_code,- decltype(*declval<Iterator>()))>,- bool- >::value- >- > : true_type- {- };+ char has_iterator_helper(T*, typename T::iterator* = 0); - struct default_connect_condition+ template <typename T>+ struct has_iterator_typedef {- template <typename Endpoint>- bool operator()(const asio::error_code&, const Endpoint&)- {- return true;- }+ enum { value = (sizeof((has_iterator_helper)((T*)(0))) == 1) }; }; } // namespace detail -#if defined(GENERATING_DOCUMENTATION)- /// 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 = automatically_determined;-};--/// Trait for determining whether a function object is a connect condition that-/// can be used with @c connect and @c async_connect.-template <typename T, typename Iterator>-struct is_connect_condition-{- /// The value member is true if the type may be used as a connect condition.- static constexpr bool value = automatically_determined;-};--#else // defined(GENERATING_DOCUMENTATION)--template <typename T>-struct is_endpoint_sequence : detail::is_endpoint_sequence_helper<T>-{-};--template <typename T, typename Iterator>-struct is_connect_condition : detail::is_connect_condition_helper<T, Iterator>-{+ static const bool value;+#else+ enum+ {+ value = detail::has_iterator_typedef<T>::value+ };+#endif }; -#endif // defined(GENERATING_DOCUMENTATION)- /** * @defgroup connect asio::connect *@@ -157,9 +94,8 @@ template <typename Protocol, typename Executor, typename EndpointSequence> typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s, const EndpointSequence& endpoints,- constraint_t<- is_endpoint_sequence<EndpointSequence>::value- > = 0);+ typename constraint<is_endpoint_sequence<+ EndpointSequence>::value>::type = 0); /// Establishes a socket connection by trying each endpoint in a sequence. /**@@ -194,10 +130,68 @@ template <typename Protocol, typename Executor, typename EndpointSequence> typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s, const EndpointSequence& endpoints, asio::error_code& ec,- constraint_t<- is_endpoint_sequence<EndpointSequence>::value- > = 0);+ typename constraint<is_endpoint_sequence<+ EndpointSequence>::value>::type = 0); +#if !defined(ASIO_NO_DEPRECATED)+/// (Deprecated: Use range overload.) 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.+ *+ * @returns On success, an iterator denoting the successfully connected+ * endpoint. Otherwise, the end iterator.+ *+ * @throws asio::system_error Thrown on failure. If the sequence is+ * empty, the associated @c error_code is 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 asio::ip::tcp::resolver::iterator.+ */+template <typename Protocol, typename Executor, typename Iterator>+Iterator connect(basic_socket<Protocol, Executor>& s, Iterator begin,+ typename constraint<!is_endpoint_sequence<Iterator>::value>::type = 0);++/// (Deprecated: Use range overload.) 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 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 asio::ip::tcp::resolver::iterator.+ */+template <typename Protocol, typename Executor, typename Iterator>+Iterator connect(basic_socket<Protocol, Executor>& s,+ Iterator begin, asio::error_code& ec,+ typename constraint<!is_endpoint_sequence<Iterator>::value>::type = 0);+#endif // !defined(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@@ -321,13 +315,8 @@ typename EndpointSequence, typename ConnectCondition> typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s, const EndpointSequence& endpoints, ConnectCondition connect_condition,- constraint_t<- is_endpoint_sequence<EndpointSequence>::value- > = 0,- constraint_t<- is_connect_condition<ConnectCondition,- decltype(declval<const EndpointSequence&>().begin())>::value- > = 0);+ typename constraint<is_endpoint_sequence<+ EndpointSequence>::value>::type = 0); /// Establishes a socket connection by trying each endpoint in a sequence. /**@@ -394,14 +383,93 @@ typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s, const EndpointSequence& endpoints, ConnectCondition connect_condition, asio::error_code& ec,- constraint_t<- is_endpoint_sequence<EndpointSequence>::value- > = 0,- constraint_t<- is_connect_condition<ConnectCondition,- decltype(declval<const EndpointSequence&>().begin())>::value- > = 0);+ typename constraint<is_endpoint_sequence<+ EndpointSequence>::value>::type = 0); +#if !defined(ASIO_NO_DEPRECATED)+/// (Deprecated: Use range overload.) 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 asio::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 asio::system_error Thrown on failure. If the sequence is+ * empty, the associated @c error_code is 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 asio::ip::tcp::resolver::iterator.+ */+template <typename Protocol, typename Executor,+ typename Iterator, typename ConnectCondition>+Iterator connect(basic_socket<Protocol, Executor>& s,+ Iterator begin, ConnectCondition connect_condition,+ typename constraint<!is_endpoint_sequence<Iterator>::value>::type = 0);++/// (Deprecated: Use range overload.) 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 asio::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 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 asio::ip::tcp::resolver::iterator.+ */+template <typename Protocol, typename Executor,+ typename Iterator, typename ConnectCondition>+Iterator connect(basic_socket<Protocol, Executor>& s, Iterator begin,+ ConnectCondition connect_condition, asio::error_code& ec,+ typename constraint<!is_endpoint_sequence<Iterator>::value>::type = 0);+#endif // !defined(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@@ -459,10 +527,7 @@ template <typename Protocol, typename Executor, typename Iterator, typename ConnectCondition> Iterator connect(basic_socket<Protocol, Executor>& s, Iterator begin,- Iterator end, ConnectCondition connect_condition,- constraint_t<- is_connect_condition<ConnectCondition, Iterator>::value- > = 0);+ Iterator end, ConnectCondition connect_condition); /// Establishes a socket connection by trying each endpoint in a sequence. /**@@ -531,10 +596,7 @@ typename Iterator, typename ConnectCondition> Iterator connect(basic_socket<Protocol, Executor>& s, Iterator begin, Iterator end, ConnectCondition connect_condition,- asio::error_code& ec,- constraint_t<- is_connect_condition<ConnectCondition, Iterator>::value- > = 0);+ asio::error_code& ec); /*@}*/ @@ -578,7 +640,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, typename Protocol::endpoint) @endcode@@ -626,29 +688,91 @@ template <typename Protocol, typename Executor, typename EndpointSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, typename Protocol::endpoint)) RangeConnectToken- = default_completion_token_t<Executor>>-inline auto async_connect(basic_socket<Protocol, Executor>& s,+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(Executor)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(RangeConnectToken,+ void (asio::error_code, typename Protocol::endpoint))+async_connect(basic_socket<Protocol, Executor>& s, const EndpointSequence& endpoints,- RangeConnectToken&& token = default_completion_token_t<Executor>(),- constraint_t<- is_endpoint_sequence<EndpointSequence>::value- > = 0,- constraint_t<- !is_connect_condition<RangeConnectToken,- decltype(declval<const EndpointSequence&>().begin())>::value- > = 0)- -> decltype(+ ASIO_MOVE_ARG(RangeConnectToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(Executor),+ typename constraint<is_endpoint_sequence<+ EndpointSequence>::value>::type = 0)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<RangeConnectToken, void (asio::error_code, typename Protocol::endpoint)>(- declval<detail::initiate_async_range_connect<Protocol, Executor>>(),- token, endpoints, declval<detail::default_connect_condition>()))-{- return async_initiate<RangeConnectToken,- void (asio::error_code, typename Protocol::endpoint)>(- detail::initiate_async_range_connect<Protocol, Executor>(s),- token, endpoints, detail::default_connect_condition());-}+ declval<detail::initiate_async_range_connect<Protocol, Executor> >(),+ token, endpoints, declval<detail::default_connect_condition>()))); +#if !defined(ASIO_NO_DEPRECATED)+/// (Deprecated: Use range overload.) 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. It is an initiating function for an @ref+ * asynchronous_operation, and always returns immediately.+ *+ * @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 token The @ref completion_token that will be used to produce a+ * completion handler, which will be called when the connect completes.+ * Potential completion tokens include @ref use_future, @ref use_awaitable,+ * @ref yield_context, or a function object with the correct completion+ * signature. The function signature of the completion handler must be:+ * @code void handler(+ * // Result of operation. if the sequence is empty, set to+ * // asio::error::not_found. Otherwise, contains the+ * // error from the last connection attempt.+ * const asio::error_code& error,+ *+ * // On success, an iterator denoting the successfully+ * // connected endpoint. Otherwise, the end iterator.+ * Iterator iterator+ * ); @endcode+ * Regardless of whether the asynchronous operation completes immediately or+ * not, the completion handler will not be invoked from within this function.+ * On immediate completion, invocation of the handler will be performed in a+ * manner equivalent to using asio::post().+ *+ * @par Completion Signature+ * @code void(asio::error_code, Iterator) @endcode+ *+ * @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 asio::ip::tcp::resolver::iterator.+ *+ * @par Per-Operation Cancellation+ * This asynchronous operation supports cancellation for the following+ * asio::cancellation_type values:+ *+ * @li @c cancellation_type::terminal+ *+ * @li @c cancellation_type::partial+ *+ * if they are also supported by the socket's @c async_connect operation.+ */+template <typename Protocol, typename Executor, typename Iterator,+ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+ Iterator)) IteratorConnectToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(Executor)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(IteratorConnectToken,+ void (asio::error_code, Iterator))+async_connect(basic_socket<Protocol, Executor>& s, Iterator begin,+ ASIO_MOVE_ARG(IteratorConnectToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(Executor),+ typename constraint<!is_endpoint_sequence<Iterator>::value>::type = 0)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_initiate<IteratorConnectToken,+ void (asio::error_code, Iterator)>(+ declval<detail::initiate_async_iterator_connect<Protocol, Executor> >(),+ token, begin, Iterator(),+ declval<detail::default_connect_condition>())));+#endif // !defined(ASIO_NO_DEPRECATED)+ /// Asynchronously establishes a socket connection by trying each endpoint in a /// sequence. /**@@ -683,7 +807,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, Iterator) @endcode@@ -716,24 +840,18 @@ */ template <typename Protocol, typename Executor, typename Iterator, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- Iterator)) IteratorConnectToken = default_completion_token_t<Executor>>-inline auto async_connect(- basic_socket<Protocol, Executor>& s, Iterator begin, Iterator end,- IteratorConnectToken&& token = default_completion_token_t<Executor>(),- constraint_t<- !is_connect_condition<IteratorConnectToken, Iterator>::value- > = 0)- -> decltype(+ Iterator)) IteratorConnectToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(Executor)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(IteratorConnectToken,+ void (asio::error_code, Iterator))+async_connect(basic_socket<Protocol, Executor>& s, Iterator begin, Iterator end,+ ASIO_MOVE_ARG(IteratorConnectToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(Executor))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<IteratorConnectToken, void (asio::error_code, Iterator)>(- declval<detail::initiate_async_iterator_connect<Protocol, Executor>>(),- token, begin, end, declval<detail::default_connect_condition>()))-{- return async_initiate<IteratorConnectToken,- void (asio::error_code, Iterator)>(- detail::initiate_async_iterator_connect<Protocol, Executor>(s),- token, begin, end, detail::default_connect_condition());-}+ declval<detail::initiate_async_iterator_connect<Protocol, Executor> >(),+ token, begin, end, declval<detail::default_connect_condition>()))); /// Asynchronously establishes a socket connection by trying each endpoint in a /// sequence.@@ -778,7 +896,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, typename Protocol::endpoint) @endcode@@ -850,29 +968,103 @@ typename EndpointSequence, typename ConnectCondition, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, typename Protocol::endpoint)) RangeConnectToken- = default_completion_token_t<Executor>>-inline auto async_connect(basic_socket<Protocol, Executor>& s,+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(Executor)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(RangeConnectToken,+ void (asio::error_code, typename Protocol::endpoint))+async_connect(basic_socket<Protocol, Executor>& s, const EndpointSequence& endpoints, ConnectCondition connect_condition,- RangeConnectToken&& token = default_completion_token_t<Executor>(),- constraint_t<- is_endpoint_sequence<EndpointSequence>::value- > = 0,- constraint_t<- is_connect_condition<ConnectCondition,- decltype(declval<const EndpointSequence&>().begin())>::value- > = 0)- -> decltype(+ ASIO_MOVE_ARG(RangeConnectToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(Executor),+ typename constraint<is_endpoint_sequence<+ EndpointSequence>::value>::type = 0)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<RangeConnectToken, void (asio::error_code, typename Protocol::endpoint)>(- declval<detail::initiate_async_range_connect<Protocol, Executor>>(),- token, endpoints, connect_condition))-{- return async_initiate<RangeConnectToken,- void (asio::error_code, typename Protocol::endpoint)>(- detail::initiate_async_range_connect<Protocol, Executor>(s),- token, endpoints, connect_condition);-}+ declval<detail::initiate_async_range_connect<Protocol, Executor> >(),+ token, endpoints, connect_condition))); +#if !defined(ASIO_NO_DEPRECATED)+/// (Deprecated: Use range overload.) 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. It is an initiating function for an @ref+ * asynchronous_operation, and always returns immediately.+ *+ * @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 asio::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 token The @ref completion_token that will be used to produce a+ * completion handler, which will be called when the connect completes.+ * Potential completion tokens include @ref use_future, @ref use_awaitable,+ * @ref yield_context, or a function object with the correct completion+ * signature. The function signature of the completion handler must be:+ * @code void handler(+ * // Result of operation. if the sequence is empty, set to+ * // asio::error::not_found. Otherwise, contains the+ * // error from the last connection attempt.+ * const asio::error_code& error,+ *+ * // On success, an iterator denoting the successfully+ * // connected endpoint. Otherwise, the end iterator.+ * Iterator iterator+ * ); @endcode+ * Regardless of whether the asynchronous operation completes immediately or+ * not, the completion handler will not be invoked from within this function.+ * On immediate completion, invocation of the handler will be performed in a+ * manner equivalent to using asio::post().+ *+ * @par Completion Signature+ * @code void(asio::error_code, Iterator) @endcode+ *+ * @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 asio::ip::tcp::resolver::iterator.+ *+ * @par Per-Operation Cancellation+ * This asynchronous operation supports cancellation for the following+ * asio::cancellation_type values:+ *+ * @li @c cancellation_type::terminal+ *+ * @li @c cancellation_type::partial+ *+ * if they are also supported by the socket's @c async_connect operation.+ */+template <typename Protocol, typename Executor,+ typename Iterator, typename ConnectCondition,+ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+ Iterator)) IteratorConnectToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(Executor)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(IteratorConnectToken,+ void (asio::error_code, Iterator))+async_connect(basic_socket<Protocol, Executor>& s, Iterator begin,+ ConnectCondition connect_condition,+ ASIO_MOVE_ARG(IteratorConnectToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(Executor),+ typename constraint<!is_endpoint_sequence<Iterator>::value>::type = 0)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_initiate<IteratorConnectToken,+ void (asio::error_code, Iterator)>(+ declval<detail::initiate_async_iterator_connect<Protocol, Executor> >(),+ token, begin, Iterator(), connect_condition)));+#endif // !defined(ASIO_NO_DEPRECATED)+ /// Asynchronously establishes a socket connection by trying each endpoint in a /// sequence. /**@@ -918,7 +1110,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, Iterator) @endcode@@ -990,24 +1182,19 @@ template <typename Protocol, typename Executor, typename Iterator, typename ConnectCondition, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- Iterator)) IteratorConnectToken = default_completion_token_t<Executor>>-inline auto async_connect(basic_socket<Protocol, Executor>& s,- Iterator begin, Iterator end, ConnectCondition connect_condition,- IteratorConnectToken&& token = default_completion_token_t<Executor>(),- constraint_t<- is_connect_condition<ConnectCondition, Iterator>::value- > = 0)- -> decltype(+ Iterator)) IteratorConnectToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(Executor)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(IteratorConnectToken,+ void (asio::error_code, Iterator))+async_connect(basic_socket<Protocol, Executor>& s, Iterator begin,+ Iterator end, ConnectCondition connect_condition,+ ASIO_MOVE_ARG(IteratorConnectToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(Executor))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<IteratorConnectToken, void (asio::error_code, Iterator)>(- declval<detail::initiate_async_iterator_connect<Protocol, Executor>>(),- token, begin, end, connect_condition))-{- return async_initiate<IteratorConnectToken,- void (asio::error_code, Iterator)>(- detail::initiate_async_iterator_connect<Protocol, Executor>(s),- token, begin, end, connect_condition);-}+ declval<detail::initiate_async_iterator_connect<Protocol, Executor> >(),+ token, begin, end, connect_condition))); /*@}*/ @@ -1017,4 +1204,4 @@ #include "asio/impl/connect.hpp" -#endif // ASIO_CONNECT_HPP+#endif
link/modules/asio-standalone/asio/include/asio/connect_pipe.hpp view
@@ -2,7 +2,7 @@ // connect_pipe.hpp // ~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/consign.hpp view
@@ -1,8 +1,8 @@ // // consign.hpp-// ~~~~~~~~~~~+// ~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -16,6 +16,11 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"++#if (defined(ASIO_HAS_STD_TUPLE) \+ && defined(ASIO_HAS_VARIADIC_TEMPLATES)) \+ || defined(GENERATING_DOCUMENTATION)+ #include <tuple> #include "asio/detail/type_traits.hpp" @@ -36,9 +41,11 @@ public: /// Constructor. template <typename T, typename... V>- constexpr explicit consign_t(T&& completion_token, V&&... values)- : token_(static_cast<T&&>(completion_token)),- values_(static_cast<V&&>(values)...)+ ASIO_CONSTEXPR explicit consign_t(+ ASIO_MOVE_ARG(T) completion_token,+ ASIO_MOVE_ARG(V)... values)+ : token_(ASIO_MOVE_CAST(T)(completion_token)),+ values_(ASIO_MOVE_CAST(V)(values)...) { } @@ -57,13 +64,15 @@ * called. */ template <typename CompletionToken, typename... Values>-ASIO_NODISCARD inline constexpr-consign_t<decay_t<CompletionToken>, decay_t<Values>...>-consign(CompletionToken&& completion_token, Values&&... values)+ASIO_NODISCARD inline ASIO_CONSTEXPR consign_t<+ typename decay<CompletionToken>::type, typename decay<Values>::type...>+consign(ASIO_MOVE_ARG(CompletionToken) completion_token,+ ASIO_MOVE_ARG(Values)... values) {- return consign_t<decay_t<CompletionToken>, decay_t<Values>...>(- static_cast<CompletionToken&&>(completion_token),- static_cast<Values&&>(values)...);+ return consign_t<+ typename decay<CompletionToken>::type, typename decay<Values>::type...>(+ ASIO_MOVE_CAST(CompletionToken)(completion_token),+ ASIO_MOVE_CAST(Values)(values)...); } } // namespace asio@@ -71,5 +80,9 @@ #include "asio/detail/pop_options.hpp" #include "asio/impl/consign.hpp"++#endif // (defined(ASIO_HAS_STD_TUPLE)+ // && defined(ASIO_HAS_VARIADIC_TEMPLATES))+ // || defined(GENERATING_DOCUMENTATION) #endif // ASIO_CONSIGN_HPP
link/modules/asio-standalone/asio/include/asio/coroutine.hpp view
@@ -2,7 +2,7 @@ // coroutine.hpp // ~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -111,7 +111,7 @@ * * @code yield * {- * mutable_buffer b = buffer(*buffer_);+ * mutable_buffers_1 b = buffer(*buffer_); * socket_->async_read_some(b, *this); * } @endcode *@@ -200,7 +200,7 @@ * The @c fork pseudo-keyword is used when "forking" a coroutine, i.e. splitting * it into two (or more) copies. One use of @c fork is in a server, where a new * coroutine is created to handle each client connection:- *+ * * @code reenter (this) * { * do@@ -211,9 +211,9 @@ * } while (is_parent()); * ... client-specific handling follows ... * } @endcode- *+ * * The logical steps involved in a @c fork are:- *+ * * @li @c fork saves the current state of the coroutine. * @li The statement creates a copy of the coroutine and either executes it * immediately or schedules it for later execution.@@ -258,6 +258,7 @@ int value_; }; + namespace detail { class coroutine_ref@@ -265,7 +266,6 @@ public: coroutine_ref(coroutine& c) : value_(c.value_), modified_(false) {} coroutine_ref(coroutine* c) : value_(c->value_), modified_(false) {}- coroutine_ref(const coroutine_ref&) = default; ~coroutine_ref() { if (!modified_) value_ = -1; } operator int() const { return value_; } int& operator=(int v) { modified_ = true; return value_ = v; }
link/modules/asio-standalone/asio/include/asio/deadline_timer.hpp view
@@ -2,7 +2,7 @@ // deadline_timer.hpp // ~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -17,8 +17,6 @@ #include "asio/detail/config.hpp" -#if !defined(ASIO_NO_DEPRECATED)- #if defined(ASIO_HAS_BOOST_DATE_TIME) \ || defined(GENERATING_DOCUMENTATION) @@ -29,15 +27,12 @@ namespace asio { -/// (Deprecated: Use system_timer.) Typedef for the typical usage of timer. Uses-/// a UTC clock.+/// Typedef for the typical usage of timer. Uses a UTC clock. typedef basic_deadline_timer<boost::posix_time::ptime> deadline_timer; } // namespace asio #endif // defined(ASIO_HAS_BOOST_DATE_TIME) // || defined(GENERATING_DOCUMENTATION)--#endif // !defined(ASIO_NO_DEPRECATED) #endif // ASIO_DEADLINE_TIMER_HPP
− link/modules/asio-standalone/asio/include/asio/default_completion_token.hpp
@@ -1,89 +0,0 @@-//-// default_completion_token.hpp-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef ASIO_DEFAULT_COMPLETION_TOKEN_HPP-#define ASIO_DEFAULT_COMPLETION_TOKEN_HPP--#if defined(_MSC_VER) && (_MSC_VER >= 1200)-# pragma once-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)--#include "asio/detail/config.hpp"-#include "asio/detail/type_traits.hpp"--#include "asio/detail/push_options.hpp"--namespace asio {--class deferred_t;--namespace detail {--template <typename T, typename = void>-struct default_completion_token_impl-{- typedef deferred_t type;-};--template <typename T>-struct default_completion_token_impl<T,- void_t<typename T::default_completion_token_type>- >-{- typedef typename T::default_completion_token_type type;-};--} // namespace detail--#if defined(GENERATING_DOCUMENTATION)--/// Traits type used to determine the default completion token type associated-/// with a type (such as an executor).-/**- * A program may specialise this traits type if the @c T template parameter in- * the specialisation is a user-defined type.- *- * Specialisations of this trait may provide a nested typedef @c type, which is- * a default-constructible completion token type.- *- * If not otherwise specialised, the default completion token type is- * asio::deferred_t.- */-template <typename T>-struct default_completion_token-{- /// If @c T has a nested type @c default_completion_token_type,- /// <tt>T::default_completion_token_type</tt>. Otherwise the typedef @c type- /// is asio::deferred_t.- typedef see_below type;-};-#else-template <typename T>-struct default_completion_token- : detail::default_completion_token_impl<T>-{-};-#endif--template <typename T>-using default_completion_token_t = typename default_completion_token<T>::type;--#define ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(e) \- = typename ::asio::default_completion_token<e>::type-#define ASIO_DEFAULT_COMPLETION_TOKEN(e) \- = typename ::asio::default_completion_token<e>::type()--} // namespace asio--#include "asio/detail/pop_options.hpp"--#include "asio/deferred.hpp"--#endif // ASIO_DEFAULT_COMPLETION_TOKEN_HPP
link/modules/asio-standalone/asio/include/asio/defer.hpp view
@@ -2,7 +2,7 @@ // defer.hpp // ~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -79,10 +79,11 @@ * @code void() @endcode */ template <ASIO_COMPLETION_TOKEN_FOR(void()) NullaryToken>-auto defer(NullaryToken&& token)- -> decltype(+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(NullaryToken, void()) defer(+ ASIO_MOVE_ARG(NullaryToken) token)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<NullaryToken, void()>(- declval<detail::initiate_defer>(), token))+ declval<detail::initiate_defer>(), token))) { return async_initiate<NullaryToken, void()>( detail::initiate_defer(), token);@@ -161,18 +162,19 @@ */ template <typename Executor, ASIO_COMPLETION_TOKEN_FOR(void()) NullaryToken- = default_completion_token_t<Executor>>-auto defer(const Executor& ex,- NullaryToken&& token- = default_completion_token_t<Executor>(),- constraint_t<+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(Executor)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(NullaryToken, void()) defer(+ const Executor& ex,+ ASIO_MOVE_ARG(NullaryToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(Executor),+ typename constraint< (execution::is_executor<Executor>::value && can_require<Executor, execution::blocking_t::never_t>::value) || is_executor<Executor>::value- > = 0)- -> decltype(+ >::type = 0)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<NullaryToken, void()>(- declval<detail::initiate_defer_with_executor<Executor>>(), token))+ declval<detail::initiate_defer_with_executor<Executor> >(), token))) { return async_initiate<NullaryToken, void()>( detail::initiate_defer_with_executor<Executor>(ex), token);@@ -193,17 +195,19 @@ */ template <typename ExecutionContext, ASIO_COMPLETION_TOKEN_FOR(void()) NullaryToken- = default_completion_token_t<typename ExecutionContext::executor_type>>-auto defer(ExecutionContext& ctx,- NullaryToken&& token- = default_completion_token_t<typename ExecutionContext::executor_type>(),- constraint_t<- is_convertible<ExecutionContext&, execution_context&>::value- > = 0)- -> decltype(+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+ typename ExecutionContext::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(NullaryToken, void()) defer(+ ExecutionContext& ctx,+ ASIO_MOVE_ARG(NullaryToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(+ typename ExecutionContext::executor_type),+ typename constraint<is_convertible<+ ExecutionContext&, execution_context&>::value>::type = 0)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<NullaryToken, void()>(- declval<detail::initiate_defer_with_executor<- typename ExecutionContext::executor_type>>(), token))+ declval<detail::initiate_defer_with_executor<+ typename ExecutionContext::executor_type> >(), token))) { return async_initiate<NullaryToken, void()>( detail::initiate_defer_with_executor<
link/modules/asio-standalone/asio/include/asio/deferred.hpp view
@@ -2,7 +2,7 @@ // deferred.hpp // ~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -16,6 +16,12 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"++#if (defined(ASIO_HAS_STD_TUPLE) \+ && defined(ASIO_HAS_DECLTYPE) \+ && defined(ASIO_HAS_VARIADIC_TEMPLATES)) \+ || defined(GENERATING_DOCUMENTATION)+ #include <tuple> #include "asio/associator.hpp" #include "asio/async_result.hpp"@@ -61,18 +67,19 @@ { public: template <typename H, typename T>- explicit deferred_sequence_handler(H&& handler, T&& tail)- : handler_(static_cast<H&&>(handler)),- tail_(static_cast<T&&>(tail))+ explicit deferred_sequence_handler(+ ASIO_MOVE_ARG(H) handler, ASIO_MOVE_ARG(T) tail)+ : handler_(ASIO_MOVE_CAST(H)(handler)),+ tail_(ASIO_MOVE_CAST(T)(tail)) { } template <typename... Args>- void operator()(Args&&... args)+ void operator()(ASIO_MOVE_ARG(Args)... args) {- static_cast<Tail&&>(tail_)(- static_cast<Args&&>(args)...)(- static_cast<Handler&&>(handler_));+ ASIO_MOVE_OR_LVALUE(Tail)(tail_)(+ ASIO_MOVE_CAST(Args)(args)...)(+ ASIO_MOVE_OR_LVALUE(Handler)(handler_)); } //private:@@ -87,11 +94,15 @@ struct initiate { template <typename Handler>- void operator()(Handler&& handler, Head head, Tail&& tail)+ void operator()(ASIO_MOVE_ARG(Handler) handler,+ Head head, ASIO_MOVE_ARG(Tail) tail) {- static_cast<Head&&>(head)(- deferred_sequence_handler<decay_t<Handler>, decay_t<Tail>>(- static_cast<Handler&&>(handler), static_cast<Tail&&>(tail)));+ ASIO_MOVE_OR_LVALUE(Head)(head)(+ deferred_sequence_handler<+ typename decay<Handler>::type,+ typename decay<Tail>::type>(+ ASIO_MOVE_CAST(Handler)(handler),+ ASIO_MOVE_CAST(Tail)(tail))); } }; @@ -100,32 +111,40 @@ public: template <typename H, typename T>- constexpr explicit deferred_sequence_base(H&& head, T&& tail)- : head_(static_cast<H&&>(head)),- tail_(static_cast<T&&>(tail))+ ASIO_CONSTEXPR explicit deferred_sequence_base(+ ASIO_MOVE_ARG(H) head, ASIO_MOVE_ARG(T) tail)+ : head_(ASIO_MOVE_CAST(H)(head)),+ tail_(ASIO_MOVE_CAST(T)(tail)) { } template <ASIO_COMPLETION_TOKEN_FOR(Signatures...) CompletionToken>- auto operator()(CompletionToken&& token) &&+ auto operator()(+ ASIO_MOVE_ARG(CompletionToken) token) ASIO_RVALUE_REF_QUAL -> decltype(- async_initiate<CompletionToken, Signatures...>(- initiate(), token, static_cast<Head&&>(this->head_),- static_cast<Tail&&>(this->tail_)))+ asio::async_initiate<CompletionToken, Signatures...>(+ declval<initiate>(), token,+ ASIO_MOVE_OR_LVALUE(Head)(this->head_),+ ASIO_MOVE_OR_LVALUE(Tail)(this->tail_))) {- return async_initiate<CompletionToken, Signatures...>(initiate(),- token, static_cast<Head&&>(head_), static_cast<Tail&&>(tail_));+ return asio::async_initiate<CompletionToken, Signatures...>(+ initiate(), token,+ ASIO_MOVE_OR_LVALUE(Head)(head_),+ ASIO_MOVE_OR_LVALUE(Tail)(tail_)); } +#if defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS) template <ASIO_COMPLETION_TOKEN_FOR(Signatures...) CompletionToken>- auto operator()(CompletionToken&& token) const &+ auto operator()(+ ASIO_MOVE_ARG(CompletionToken) token) const & -> decltype(- async_initiate<CompletionToken, Signatures...>(- initiate(), token, this->head_, this->tail_))+ asio::async_initiate<CompletionToken, Signatures...>(+ initiate(), token, this->head_, this->tail_)) {- return async_initiate<CompletionToken, Signatures...>(+ return asio::async_initiate<CompletionToken, Signatures...>( initiate(), token, head_, tail_); }+#endif // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS) }; // Two-step application of variadic Signatures to determine correct base type.@@ -157,15 +176,17 @@ { /// No effect. template <typename... Args>- void operator()(Args&&...) &&+ void operator()(ASIO_MOVE_ARG(Args)...) ASIO_RVALUE_REF_QUAL { } +#if defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS) /// No effect. template <typename... Args>- void operator()(Args&&...) const &+ void operator()(ASIO_MOVE_ARG(Args)...) const & { }+#endif // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS) }; #if !defined(GENERATING_DOCUMENTATION)@@ -184,10 +205,11 @@ class deferred_function { public:- /// Constructor.+ /// Constructor. template <typename F>- constexpr explicit deferred_function(deferred_init_tag, F&& function)- : function_(static_cast<F&&>(function))+ ASIO_CONSTEXPR explicit deferred_function(+ deferred_init_tag, ASIO_MOVE_ARG(F) function)+ : function_(ASIO_MOVE_CAST(F)(function)) { } @@ -196,24 +218,30 @@ public: template <typename... Args>- auto operator()(Args&&... args) &&+ auto operator()(+ ASIO_MOVE_ARG(Args)... args) ASIO_RVALUE_REF_QUAL -> decltype(- static_cast<Function&&>(this->function_)(static_cast<Args&&>(args)...))+ ASIO_MOVE_CAST(Function)(this->function_)(+ ASIO_MOVE_CAST(Args)(args)...)) {- return static_cast<Function&&>(function_)(static_cast<Args&&>(args)...);+ return ASIO_MOVE_CAST(Function)(function_)(+ ASIO_MOVE_CAST(Args)(args)...); } +#if defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS) template <typename... Args>- auto operator()(Args&&... args) const &- -> decltype(Function(function_)(static_cast<Args&&>(args)...))+ auto operator()(+ ASIO_MOVE_ARG(Args)... args) const &+ -> decltype(Function(function_)(ASIO_MOVE_CAST(Args)(args)...)) {- return Function(function_)(static_cast<Args&&>(args)...);+ return Function(function_)(ASIO_MOVE_CAST(Args)(args)...); }+#endif // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS) }; #if !defined(GENERATING_DOCUMENTATION) template <typename Function>-struct is_deferred<deferred_function<Function>> : true_type+struct is_deferred<deferred_function<Function> > : true_type { }; #endif // !defined(GENERATING_DOCUMENTATION)@@ -228,72 +256,85 @@ struct initiate { template <typename Handler, typename... V>- void operator()(Handler handler, V&&... values)+ void operator()(Handler handler, ASIO_MOVE_ARG(V)... values) {- static_cast<Handler&&>(handler)(static_cast<V&&>(values)...);+ ASIO_MOVE_OR_LVALUE(Handler)(handler)(+ ASIO_MOVE_CAST(V)(values)...); } }; template <typename CompletionToken, std::size_t... I>- auto invoke_helper(CompletionToken&& token, detail::index_sequence<I...>)+ auto invoke_helper(+ ASIO_MOVE_ARG(CompletionToken) token,+ detail::index_sequence<I...>) -> decltype(- async_initiate<CompletionToken, void(Values...)>(initiate(), token,- std::get<I>(static_cast<std::tuple<Values...>&&>(this->values_))...))+ asio::async_initiate<CompletionToken, void(Values...)>(+ initiate(), token,+ std::get<I>(+ ASIO_MOVE_CAST(std::tuple<Values...>)(this->values_))...)) {- return async_initiate<CompletionToken, void(Values...)>(initiate(), token,- std::get<I>(static_cast<std::tuple<Values...>&&>(values_))...);+ return asio::async_initiate<CompletionToken, void(Values...)>(+ initiate(), token,+ std::get<I>(ASIO_MOVE_CAST(std::tuple<Values...>)(values_))...); } +#if defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS) template <typename CompletionToken, std::size_t... I>- auto const_invoke_helper(CompletionToken&& token,+ auto const_invoke_helper(+ ASIO_MOVE_ARG(CompletionToken) token, detail::index_sequence<I...>) -> decltype(- async_initiate<CompletionToken, void(Values...)>(- initiate(), token, std::get<I>(values_)...))+ asio::async_initiate<CompletionToken, void(Values...)>(+ initiate(), token, std::get<I>(values_)...)) {- return async_initiate<CompletionToken, void(Values...)>(+ return asio::async_initiate<CompletionToken, void(Values...)>( initiate(), token, std::get<I>(values_)...); }+#endif // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS) public: /// Construct a deferred asynchronous operation from the arguments to an /// initiation function object. template <typename... V>- constexpr explicit deferred_values(- deferred_init_tag, V&&... values)- : values_(static_cast<V&&>(values)...)+ ASIO_CONSTEXPR explicit deferred_values(+ deferred_init_tag, ASIO_MOVE_ARG(V)... values)+ : values_(ASIO_MOVE_CAST(V)(values)...) { } /// Initiate the deferred operation using the supplied completion token. template <ASIO_COMPLETION_TOKEN_FOR(void(Values...)) CompletionToken>- auto operator()(CompletionToken&& token) &&+ auto operator()(+ ASIO_MOVE_ARG(CompletionToken) token) ASIO_RVALUE_REF_QUAL -> decltype(- this->invoke_helper(- static_cast<CompletionToken&&>(token),- detail::index_sequence_for<Values...>()))+ this->invoke_helper(+ ASIO_MOVE_CAST(CompletionToken)(token),+ detail::index_sequence_for<Values...>())) { return this->invoke_helper(- static_cast<CompletionToken&&>(token),+ ASIO_MOVE_CAST(CompletionToken)(token), detail::index_sequence_for<Values...>()); } +#if defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS) template <ASIO_COMPLETION_TOKEN_FOR(void(Values...)) CompletionToken>- auto operator()(CompletionToken&& token) const &+ auto operator()(+ ASIO_MOVE_ARG(CompletionToken) token) const & -> decltype(- this->const_invoke_helper(- static_cast<CompletionToken&&>(token),- detail::index_sequence_for<Values...>()))+ this->const_invoke_helper(+ ASIO_MOVE_CAST(CompletionToken)(token),+ detail::index_sequence_for<Values...>())) { return this->const_invoke_helper(- static_cast<CompletionToken&&>(token),+ ASIO_MOVE_CAST(CompletionToken)(token), detail::index_sequence_for<Values...>()); }+#endif // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS) }; #if !defined(GENERATING_DOCUMENTATION) template <typename... Values>-struct is_deferred<deferred_values<Values...>> : true_type+struct is_deferred<deferred_values<Values...> > : true_type { }; #endif // !defined(GENERATING_DOCUMENTATION)@@ -303,70 +344,79 @@ class ASIO_NODISCARD deferred_async_operation { private:- typedef decay_t<Initiation> initiation_t;+ typedef typename decay<Initiation>::type initiation_t; initiation_t initiation_;- typedef std::tuple<decay_t<InitArgs>...> init_args_t;+ typedef std::tuple<typename decay<InitArgs>::type...> init_args_t; init_args_t init_args_; template <typename CompletionToken, std::size_t... I>- auto invoke_helper(CompletionToken&& token, detail::index_sequence<I...>)+ auto invoke_helper(+ ASIO_MOVE_ARG(CompletionToken) token,+ detail::index_sequence<I...>) -> decltype(- async_initiate<CompletionToken, Signature>(- static_cast<initiation_t&&>(initiation_), token,- std::get<I>(static_cast<init_args_t&&>(init_args_))...))+ asio::async_initiate<CompletionToken, Signature>(+ ASIO_MOVE_CAST(initiation_t)(initiation_), token,+ std::get<I>(ASIO_MOVE_CAST(init_args_t)(init_args_))...)) {- return async_initiate<CompletionToken, Signature>(- static_cast<initiation_t&&>(initiation_), token,- std::get<I>(static_cast<init_args_t&&>(init_args_))...);+ return asio::async_initiate<CompletionToken, Signature>(+ ASIO_MOVE_CAST(initiation_t)(initiation_), token,+ std::get<I>(ASIO_MOVE_CAST(init_args_t)(init_args_))...); } +#if defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS) template <typename CompletionToken, std::size_t... I>- auto const_invoke_helper(CompletionToken&& token,+ auto const_invoke_helper(+ ASIO_MOVE_ARG(CompletionToken) token, detail::index_sequence<I...>) const & -> decltype(- async_initiate<CompletionToken, Signature>(- conditional_t<true, initiation_t, CompletionToken>(initiation_),- token, std::get<I>(init_args_)...))- {- return async_initiate<CompletionToken, Signature>(+ asio::async_initiate<CompletionToken, Signature>(+ initiation_t(initiation_), token, std::get<I>(init_args_)...))+ {+ return asio::async_initiate<CompletionToken, Signature>( initiation_t(initiation_), token, std::get<I>(init_args_)...); }+#endif // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS) public: /// Construct a deferred asynchronous operation from the arguments to an /// initiation function object. template <typename I, typename... A>- constexpr explicit deferred_async_operation(- deferred_init_tag, I&& initiation, A&&... init_args)- : initiation_(static_cast<I&&>(initiation)),- init_args_(static_cast<A&&>(init_args)...)+ ASIO_CONSTEXPR explicit deferred_async_operation(+ deferred_init_tag, ASIO_MOVE_ARG(I) initiation,+ ASIO_MOVE_ARG(A)... init_args)+ : initiation_(ASIO_MOVE_CAST(I)(initiation)),+ init_args_(ASIO_MOVE_CAST(A)(init_args)...) { } /// Initiate the asynchronous operation using the supplied completion token. template <ASIO_COMPLETION_TOKEN_FOR(Signature) CompletionToken>- auto operator()(CompletionToken&& token) &&+ auto operator()(+ ASIO_MOVE_ARG(CompletionToken) token) ASIO_RVALUE_REF_QUAL -> decltype(- this->invoke_helper(- static_cast<CompletionToken&&>(token),- detail::index_sequence_for<InitArgs...>()))+ this->invoke_helper(+ ASIO_MOVE_CAST(CompletionToken)(token),+ detail::index_sequence_for<InitArgs...>())) { return this->invoke_helper(- static_cast<CompletionToken&&>(token),+ ASIO_MOVE_CAST(CompletionToken)(token), detail::index_sequence_for<InitArgs...>()); } +#if defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS) template <ASIO_COMPLETION_TOKEN_FOR(Signature) CompletionToken>- auto operator()(CompletionToken&& token) const &+ auto operator()(+ ASIO_MOVE_ARG(CompletionToken) token) const & -> decltype(- this->const_invoke_helper(- static_cast<CompletionToken&&>(token),- detail::index_sequence_for<InitArgs...>()))+ this->const_invoke_helper(+ ASIO_MOVE_CAST(CompletionToken)(token),+ detail::index_sequence_for<InitArgs...>())) { return this->const_invoke_helper(- static_cast<CompletionToken&&>(token),+ ASIO_MOVE_CAST(CompletionToken)(token), detail::index_sequence_for<InitArgs...>()); }+#endif // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS) }; /// Encapsulates a deferred asynchronous operation thas has multiple completion@@ -376,75 +426,85 @@ deferred_signatures<Signatures...>, Initiation, InitArgs...> { private:- typedef decay_t<Initiation> initiation_t;+ typedef typename decay<Initiation>::type initiation_t; initiation_t initiation_;- typedef std::tuple<decay_t<InitArgs>...> init_args_t;+ typedef std::tuple<typename decay<InitArgs>::type...> init_args_t; init_args_t init_args_; template <typename CompletionToken, std::size_t... I>- auto invoke_helper(CompletionToken&& token, detail::index_sequence<I...>)+ auto invoke_helper(+ ASIO_MOVE_ARG(CompletionToken) token,+ detail::index_sequence<I...>) -> decltype(- async_initiate<CompletionToken, Signatures...>(- static_cast<initiation_t&&>(initiation_), token,- std::get<I>(static_cast<init_args_t&&>(init_args_))...))+ asio::async_initiate<CompletionToken, Signatures...>(+ ASIO_MOVE_CAST(initiation_t)(initiation_), token,+ std::get<I>(ASIO_MOVE_CAST(init_args_t)(init_args_))...)) {- return async_initiate<CompletionToken, Signatures...>(- static_cast<initiation_t&&>(initiation_), token,- std::get<I>(static_cast<init_args_t&&>(init_args_))...);+ return asio::async_initiate<CompletionToken, Signatures...>(+ ASIO_MOVE_CAST(initiation_t)(initiation_), token,+ std::get<I>(ASIO_MOVE_CAST(init_args_t)(init_args_))...); } +#if defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS) template <typename CompletionToken, std::size_t... I>- auto const_invoke_helper(CompletionToken&& token,+ auto const_invoke_helper(+ ASIO_MOVE_ARG(CompletionToken) token, detail::index_sequence<I...>) const & -> decltype(- async_initiate<CompletionToken, Signatures...>(- initiation_t(initiation_), token, std::get<I>(init_args_)...))- {- return async_initiate<CompletionToken, Signatures...>(+ asio::async_initiate<CompletionToken, Signatures...>(+ initiation_t(initiation_), token, std::get<I>(init_args_)...))+ {+ return asio::async_initiate<CompletionToken, Signatures...>( initiation_t(initiation_), token, std::get<I>(init_args_)...); }+#endif // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS) public: /// Construct a deferred asynchronous operation from the arguments to an /// initiation function object. template <typename I, typename... A>- constexpr explicit deferred_async_operation(- deferred_init_tag, I&& initiation, A&&... init_args)- : initiation_(static_cast<I&&>(initiation)),- init_args_(static_cast<A&&>(init_args)...)+ ASIO_CONSTEXPR explicit deferred_async_operation(+ deferred_init_tag, ASIO_MOVE_ARG(I) initiation,+ ASIO_MOVE_ARG(A)... init_args)+ : initiation_(ASIO_MOVE_CAST(I)(initiation)),+ init_args_(ASIO_MOVE_CAST(A)(init_args)...) { } /// Initiate the asynchronous operation using the supplied completion token. template <ASIO_COMPLETION_TOKEN_FOR(Signatures...) CompletionToken>- auto operator()(CompletionToken&& token) &&+ auto operator()(+ ASIO_MOVE_ARG(CompletionToken) token) ASIO_RVALUE_REF_QUAL -> decltype(- this->invoke_helper(- static_cast<CompletionToken&&>(token),- detail::index_sequence_for<InitArgs...>()))+ this->invoke_helper(+ ASIO_MOVE_CAST(CompletionToken)(token),+ detail::index_sequence_for<InitArgs...>())) { return this->invoke_helper(- static_cast<CompletionToken&&>(token),+ ASIO_MOVE_CAST(CompletionToken)(token), detail::index_sequence_for<InitArgs...>()); } +#if defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS) template <ASIO_COMPLETION_TOKEN_FOR(Signatures...) CompletionToken>- auto operator()(CompletionToken&& token) const &+ auto operator()(+ ASIO_MOVE_ARG(CompletionToken) token) const & -> decltype(- this->const_invoke_helper(- static_cast<CompletionToken&&>(token),- detail::index_sequence_for<InitArgs...>()))+ this->const_invoke_helper(+ ASIO_MOVE_CAST(CompletionToken)(token),+ detail::index_sequence_for<InitArgs...>())) { return this->const_invoke_helper(- static_cast<CompletionToken&&>(token),+ ASIO_MOVE_CAST(CompletionToken)(token), detail::index_sequence_for<InitArgs...>()); }+#endif // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS) }; #if !defined(GENERATING_DOCUMENTATION) template <typename Signature, typename Initiation, typename... InitArgs> struct is_deferred<- deferred_async_operation<Signature, Initiation, InitArgs...>> : true_type+ deferred_async_operation<Signature, Initiation, InitArgs...> > : true_type { }; #endif // !defined(GENERATING_DOCUMENTATION)@@ -456,30 +516,33 @@ { public: template <typename H, typename T>- constexpr explicit deferred_sequence(deferred_init_tag, H&& head, T&& tail)+ ASIO_CONSTEXPR explicit deferred_sequence(deferred_init_tag,+ ASIO_MOVE_ARG(H) head, ASIO_MOVE_ARG(T) tail) : detail::deferred_sequence_types<Head, Tail>::base(- static_cast<H&&>(head), static_cast<T&&>(tail))+ ASIO_MOVE_CAST(H)(head), ASIO_MOVE_CAST(T)(tail)) { } #if defined(GENERATING_DOCUMENTATION) template <typename CompletionToken>- auto operator()(CompletionToken&& token) &&;+ auto operator()(ASIO_MOVE_ARG(CompletionToken) token)+ ASIO_RVALUE_REF_QUAL; template <typename CompletionToken>- auto operator()(CompletionToken&& token) const &;-#endif // defined(GENERATING_DOCUMENTATION)+ auto operator()(ASIO_MOVE_ARG(CompletionToken) token) const &;+#endif // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS) }; #if !defined(GENERATING_DOCUMENTATION) template <typename Head, typename Tail>-struct is_deferred<deferred_sequence<Head, Tail>> : true_type+struct is_deferred<deferred_sequence<Head, Tail> > : true_type { }; #endif // !defined(GENERATING_DOCUMENTATION) /// Used to represent a deferred conditional branch.-template <typename OnTrue = deferred_noop, typename OnFalse = deferred_noop>+template <typename OnTrue = deferred_noop,+ typename OnFalse = deferred_noop> class ASIO_NODISCARD deferred_conditional { private:@@ -487,9 +550,10 @@ // Helper constructor. template <typename T, typename F>- explicit deferred_conditional(bool b, T&& on_true, F&& on_false)- : on_true_(static_cast<T&&>(on_true)),- on_false_(static_cast<F&&>(on_false)),+ explicit deferred_conditional(bool b, ASIO_MOVE_ARG(T) on_true,+ ASIO_MOVE_ARG(F) on_false)+ : on_true_(ASIO_MOVE_CAST(T)(on_true)),+ on_false_(ASIO_MOVE_CAST(F)(on_false)), bool_(b) { }@@ -501,88 +565,94 @@ public: /// Construct a deferred conditional with the value to determine which branch /// will be executed.- constexpr explicit deferred_conditional(bool b)+ ASIO_CONSTEXPR explicit deferred_conditional(bool b) : on_true_(), on_false_(), bool_(b) { } - /// Invoke the conditional branch bsaed on the stored value.+ /// Invoke the conditional branch bsaed on the stored alue. template <typename... Args>- auto operator()(Args&&... args) &&- -> decltype(static_cast<OnTrue&&>(on_true_)(static_cast<Args&&>(args)...))+ auto operator()(ASIO_MOVE_ARG(Args)... args) ASIO_RVALUE_REF_QUAL+ -> decltype(+ ASIO_MOVE_OR_LVALUE(OnTrue)(on_true_)(+ ASIO_MOVE_CAST(Args)(args)...)) { if (bool_) {- return static_cast<OnTrue&&>(on_true_)(static_cast<Args&&>(args)...);+ return ASIO_MOVE_OR_LVALUE(OnTrue)(on_true_)(+ ASIO_MOVE_CAST(Args)(args)...); } else {- return static_cast<OnFalse&&>(on_false_)(static_cast<Args&&>(args)...);+ return ASIO_MOVE_OR_LVALUE(OnFalse)(on_false_)(+ ASIO_MOVE_CAST(Args)(args)...); } } +#if defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS) template <typename... Args>- auto operator()(Args&&... args) const &- -> decltype(on_true_(static_cast<Args&&>(args)...))+ auto operator()(ASIO_MOVE_ARG(Args)... args) const &+ -> decltype(on_true_(ASIO_MOVE_CAST(Args)(args)...)) { if (bool_) {- return on_true_(static_cast<Args&&>(args)...);+ return on_true_(ASIO_MOVE_CAST(Args)(args)...); } else {- return on_false_(static_cast<Args&&>(args)...);+ return on_false_(ASIO_MOVE_CAST(Args)(args)...); } }+#endif // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS) /// Set the true branch of the conditional. template <typename T> deferred_conditional<T, OnFalse> then(T on_true,- constraint_t<+ typename constraint< is_deferred<T>::value- >* = 0,- constraint_t<+ >::type* = 0,+ typename constraint< is_same<- conditional_t<true, OnTrue, T>,+ typename conditional<true, OnTrue, T>::type, deferred_noop >::value- >* = 0) &&+ >::type* = 0) ASIO_RVALUE_REF_QUAL { return deferred_conditional<T, OnFalse>(- bool_, static_cast<T&&>(on_true),- static_cast<OnFalse&&>(on_false_));+ bool_, ASIO_MOVE_CAST(T)(on_true),+ ASIO_MOVE_CAST(OnFalse)(on_false_)); } /// Set the false branch of the conditional. template <typename T> deferred_conditional<OnTrue, T> otherwise(T on_false,- constraint_t<+ typename constraint< is_deferred<T>::value- >* = 0,- constraint_t<+ >::type* = 0,+ typename constraint< !is_same<- conditional_t<true, OnTrue, T>,+ typename conditional<true, OnTrue, T>::type, deferred_noop >::value- >* = 0,- constraint_t<+ >::type* = 0,+ typename constraint< is_same<- conditional_t<true, OnFalse, T>,+ typename conditional<true, OnFalse, T>::type, deferred_noop >::value- >* = 0) &&+ >::type* = 0) ASIO_RVALUE_REF_QUAL { return deferred_conditional<OnTrue, T>(- bool_, static_cast<OnTrue&&>(on_true_),- static_cast<T&&>(on_false));+ bool_, ASIO_MOVE_CAST(OnTrue)(on_true_),+ ASIO_MOVE_CAST(T)(on_false)); } }; #if !defined(GENERATING_DOCUMENTATION) template <typename OnTrue, typename OnFalse>-struct is_deferred<deferred_conditional<OnTrue, OnFalse>> : true_type+struct is_deferred<deferred_conditional<OnTrue, OnFalse> > : true_type { }; #endif // !defined(GENERATING_DOCUMENTATION)@@ -593,11 +663,8 @@ * The deferred_t class is used to indicate that an asynchronous operation * should return a function object which is itself an initiation function. A * deferred_t object may be passed as a completion token to an asynchronous- * operation, typically as the default completion token:- *- * @code auto my_deferred_op = my_socket.async_read_some(my_buffer); @endcode- *- * or by explicitly passing the special value @c asio::deferred:+ * operation, typically using the special value @c asio::deferred. For+ * example: * * @code auto my_deferred_op * = my_socket.async_read_some(my_buffer,@@ -610,7 +677,7 @@ { public: /// Default constructor.- constexpr deferred_t()+ ASIO_CONSTEXPR deferred_t() { } @@ -625,13 +692,13 @@ /// Construct the adapted executor from the inner executor type. template <typename InnerExecutor1> executor_with_default(const InnerExecutor1& ex,- constraint_t<- conditional_t<+ typename constraint<+ conditional< !is_same<InnerExecutor1, executor_with_default>::value, is_convertible<InnerExecutor1, InnerExecutor>, false_type- >::value- > = 0) noexcept+ >::type::value+ >::type = 0) ASIO_NOEXCEPT : InnerExecutor(ex) { }@@ -639,54 +706,59 @@ /// Type alias to adapt an I/O object to use @c deferred_t as its /// default completion token type.+#if defined(ASIO_HAS_ALIAS_TEMPLATES) \+ || defined(GENERATING_DOCUMENTATION) template <typename T> using as_default_on_t = typename T::template rebind_executor<- executor_with_default<typename T::executor_type>>::other;+ executor_with_default<typename T::executor_type> >::other;+#endif // defined(ASIO_HAS_ALIAS_TEMPLATES)+ // || defined(GENERATING_DOCUMENTATION) /// Function helper to adapt an I/O object to use @c deferred_t as its /// default completion token type. template <typename T>- static typename decay_t<T>::template rebind_executor<- executor_with_default<typename decay_t<T>::executor_type>+ static typename decay<T>::type::template rebind_executor<+ executor_with_default<typename decay<T>::type::executor_type> >::other- as_default_on(T&& object)+ as_default_on(ASIO_MOVE_ARG(T) object) {- return typename decay_t<T>::template rebind_executor<- executor_with_default<typename decay_t<T>::executor_type>- >::other(static_cast<T&&>(object));+ return typename decay<T>::type::template rebind_executor<+ executor_with_default<typename decay<T>::type::executor_type>+ >::other(ASIO_MOVE_CAST(T)(object)); } /// Creates a new deferred from a function. template <typename Function>- constraint_t<- !is_deferred<decay_t<Function>>::value,- deferred_function<decay_t<Function>>- > operator()(Function&& function) const+ typename constraint<+ !is_deferred<typename decay<Function>::type>::value,+ deferred_function<typename decay<Function>::type>+ >::type operator()(ASIO_MOVE_ARG(Function) function) const {- return deferred_function<decay_t<Function>>(- deferred_init_tag{}, static_cast<Function&&>(function));+ return deferred_function<typename decay<Function>::type>(+ deferred_init_tag{}, ASIO_MOVE_CAST(Function)(function)); } /// Passes through anything that is already deferred. template <typename T>- constraint_t<- is_deferred<decay_t<T>>::value,- decay_t<T>- > operator()(T&& t) const+ typename constraint<+ is_deferred<typename decay<T>::type>::value,+ typename decay<T>::type+ >::type operator()(ASIO_MOVE_ARG(T) t) const {- return static_cast<T&&>(t);+ return ASIO_MOVE_CAST(T)(t); } /// Returns a deferred operation that returns the provided values. template <typename... Args>- static constexpr deferred_values<decay_t<Args>...> values(Args&&... args)+ static ASIO_CONSTEXPR deferred_values<typename decay<Args>::type...>+ values(ASIO_MOVE_ARG(Args)... args) {- return deferred_values<decay_t<Args>...>(- deferred_init_tag{}, static_cast<Args&&>(args)...);+ return deferred_values<typename decay<Args>::type...>(+ deferred_init_tag{}, ASIO_MOVE_CAST(Args)(args)...); } /// Creates a conditional object for branching deferred operations.- static constexpr deferred_conditional<> when(bool b)+ static ASIO_CONSTEXPR deferred_conditional<> when(bool b) { return deferred_conditional<>(b); }@@ -694,13 +766,15 @@ /// Pipe operator used to chain deferred operations. template <typename Head, typename Tail>-inline auto operator|(Head head, Tail&& tail)- -> constraint_t<+inline auto operator|(Head head, ASIO_MOVE_ARG(Tail) tail)+ -> typename constraint< is_deferred<Head>::value,- decltype(static_cast<Head&&>(head)(static_cast<Tail&&>(tail)))- >+ decltype(ASIO_MOVE_OR_LVALUE(Head)(head)(+ ASIO_MOVE_CAST(Tail)(tail)))+ >::type {- return static_cast<Head&&>(head)(static_cast<Tail&&>(tail));+ return ASIO_MOVE_OR_LVALUE(Head)(head)(+ ASIO_MOVE_CAST(Tail)(tail)); } /// A @ref completion_token object used to specify that an asynchronous@@ -708,12 +782,21 @@ /** * See the documentation for asio::deferred_t for a usage example. */-ASIO_INLINE_VARIABLE constexpr deferred_t deferred;+#if defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)+constexpr deferred_t deferred;+#elif defined(ASIO_MSVC)+__declspec(selectany) deferred_t deferred;+#endif } // namespace asio #include "asio/detail/pop_options.hpp" #include "asio/impl/deferred.hpp"++#endif // (defined(ASIO_HAS_STD_TUPLE)+ // && defined(ASIO_HAS_DECLTYPE))+ // && defined(ASIO_HAS_VARIADIC_TEMPLATES))+ // || defined(GENERATING_DOCUMENTATION) #endif // ASIO_DEFERRED_HPP
link/modules/asio-standalone/asio/include/asio/detached.hpp view
@@ -2,7 +2,7 @@ // detached.hpp // ~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -38,8 +38,8 @@ class detached_t { public:- /// Constructor.- constexpr detached_t()+ /// Constructor. + ASIO_CONSTEXPR detached_t() { } @@ -52,7 +52,7 @@ typedef detached_t default_completion_token_type; /// Construct the adapted executor from the inner executor type.- executor_with_default(const InnerExecutor& ex) noexcept+ executor_with_default(const InnerExecutor& ex) ASIO_NOEXCEPT : InnerExecutor(ex) { }@@ -61,9 +61,9 @@ /// that to construct the adapted executor. template <typename OtherExecutor> executor_with_default(const OtherExecutor& ex,- constraint_t<+ typename constraint< is_convertible<OtherExecutor, InnerExecutor>::value- > = 0) noexcept+ >::type = 0) ASIO_NOEXCEPT : InnerExecutor(ex) { }@@ -71,21 +71,25 @@ /// Type alias to adapt an I/O object to use @c detached_t as its /// default completion token type.+#if defined(ASIO_HAS_ALIAS_TEMPLATES) \+ || defined(GENERATING_DOCUMENTATION) template <typename T> using as_default_on_t = typename T::template rebind_executor<- executor_with_default<typename T::executor_type>>::other;+ executor_with_default<typename T::executor_type> >::other;+#endif // defined(ASIO_HAS_ALIAS_TEMPLATES)+ // || defined(GENERATING_DOCUMENTATION) /// Function helper to adapt an I/O object to use @c detached_t as its /// default completion token type. template <typename T>- static typename decay_t<T>::template rebind_executor<- executor_with_default<typename decay_t<T>::executor_type>+ static typename decay<T>::type::template rebind_executor<+ executor_with_default<typename decay<T>::type::executor_type> >::other- as_default_on(T&& object)+ as_default_on(ASIO_MOVE_ARG(T) object) {- return typename decay_t<T>::template rebind_executor<- executor_with_default<typename decay_t<T>::executor_type>- >::other(static_cast<T&&>(object));+ return typename decay<T>::type::template rebind_executor<+ executor_with_default<typename decay<T>::type::executor_type>+ >::other(ASIO_MOVE_CAST(T)(object)); } }; @@ -94,7 +98,11 @@ /** * See the documentation for asio::detached_t for a usage example. */-ASIO_INLINE_VARIABLE constexpr detached_t detached;+#if defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)+constexpr detached_t detached;+#elif defined(ASIO_MSVC)+__declspec(selectany) detached_t detached;+#endif } // namespace asio
link/modules/asio-standalone/asio/include/asio/detail/array.hpp view
@@ -2,7 +2,7 @@ // detail/array.hpp // ~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -17,12 +17,20 @@ #include "asio/detail/config.hpp" -#include <array>+#if defined(ASIO_HAS_STD_ARRAY)+# include <array>+#else // defined(ASIO_HAS_STD_ARRAY)+# include <boost/array.hpp>+#endif // defined(ASIO_HAS_STD_ARRAY) namespace asio { namespace detail { +#if defined(ASIO_HAS_STD_ARRAY) using std::array;+#else // defined(ASIO_HAS_STD_ARRAY)+using boost::array;+#endif // defined(ASIO_HAS_STD_ARRAY) } // namespace detail } // namespace asio
link/modules/asio-standalone/asio/include/asio/detail/array_fwd.hpp view
@@ -2,7 +2,7 @@ // detail/array_fwd.hpp // ~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -27,6 +27,8 @@ // Standard library components can't be forward declared, so we'll have to // include the array header. Fortunately, it's fairly lightweight and doesn't // add significantly to the compile time.-#include <array>+#if defined(ASIO_HAS_STD_ARRAY)+# include <array>+#endif // defined(ASIO_HAS_STD_ARRAY) #endif // ASIO_DETAIL_ARRAY_FWD_HPP
link/modules/asio-standalone/asio/include/asio/detail/assert.hpp view
@@ -2,7 +2,7 @@ // detail/assert.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/atomic_count.hpp view
@@ -2,7 +2,7 @@ // detail/atomic_count.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -19,9 +19,11 @@ #if !defined(ASIO_HAS_THREADS) // Nothing to include.-#else // !defined(ASIO_HAS_THREADS)+#elif defined(ASIO_HAS_STD_ATOMIC) # include <atomic>-#endif // !defined(ASIO_HAS_THREADS)+#else // defined(ASIO_HAS_STD_ATOMIC)+# include <boost/detail/atomic_count.hpp>+#endif // defined(ASIO_HAS_STD_ATOMIC) namespace asio { namespace detail {@@ -32,7 +34,7 @@ inline void decrement(atomic_count& a, long b) { a -= b; } inline void ref_count_up(atomic_count& a) { ++a; } inline bool ref_count_down(atomic_count& a) { return --a == 0; }-#else // !defined(ASIO_HAS_THREADS)+#elif defined(ASIO_HAS_STD_ATOMIC) typedef std::atomic<long> atomic_count; inline void increment(atomic_count& a, long b) { a += b; } inline void decrement(atomic_count& a, long b) { a -= b; }@@ -51,7 +53,13 @@ } return false; }-#endif // !defined(ASIO_HAS_THREADS)+#else // defined(ASIO_HAS_STD_ATOMIC)+typedef boost::detail::atomic_count atomic_count;+inline void increment(atomic_count& a, long b) { while (b > 0) ++a, --b; }+inline void decrement(atomic_count& a, long b) { while (b > 0) --a, --b; }+inline void ref_count_up(atomic_count& a) { ++a; }+inline bool ref_count_down(atomic_count& a) { return --a == 0; }+#endif // defined(ASIO_HAS_STD_ATOMIC) } // namespace detail } // namespace asio
link/modules/asio-standalone/asio/include/asio/detail/base_from_cancellation_state.hpp view
@@ -2,7 +2,7 @@ // detail/base_from_cancellation_state.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -31,12 +31,12 @@ public: typedef cancellation_slot cancellation_slot_type; - cancellation_slot_type get_cancellation_slot() const noexcept+ cancellation_slot_type get_cancellation_slot() const ASIO_NOEXCEPT { return cancellation_state_.slot(); } - cancellation_state get_cancellation_state() const noexcept+ cancellation_state get_cancellation_state() const ASIO_NOEXCEPT { return cancellation_state_; }@@ -57,12 +57,12 @@ template <typename InFilter, typename OutFilter> base_from_cancellation_state(const Handler& handler,- InFilter&& in_filter,- OutFilter&& out_filter)+ ASIO_MOVE_ARG(InFilter) in_filter,+ ASIO_MOVE_ARG(OutFilter) out_filter) : cancellation_state_( asio::get_associated_cancellation_slot(handler),- static_cast<InFilter&&>(in_filter),- static_cast<OutFilter&&>(out_filter))+ ASIO_MOVE_CAST(InFilter)(in_filter),+ ASIO_MOVE_CAST(OutFilter)(out_filter)) { } @@ -81,16 +81,16 @@ template <typename InFilter, typename OutFilter> void reset_cancellation_state(const Handler& handler,- InFilter&& in_filter,- OutFilter&& out_filter)+ ASIO_MOVE_ARG(InFilter) in_filter,+ ASIO_MOVE_ARG(OutFilter) out_filter) { cancellation_state_ = cancellation_state( asio::get_associated_cancellation_slot(handler),- static_cast<InFilter&&>(in_filter),- static_cast<OutFilter&&>(out_filter));+ ASIO_MOVE_CAST(InFilter)(in_filter),+ ASIO_MOVE_CAST(OutFilter)(out_filter)); } - cancellation_type_t cancelled() const noexcept+ cancellation_type_t cancelled() const ASIO_NOEXCEPT { return cancellation_state_.cancelled(); }@@ -101,18 +101,17 @@ template <typename Handler> class base_from_cancellation_state<Handler,- enable_if_t<+ typename enable_if< is_same< typename associated_cancellation_slot< Handler, cancellation_slot >::asio_associated_cancellation_slot_is_unspecialised, void >::value- >- >+ >::type> { public:- cancellation_state get_cancellation_state() const noexcept+ cancellation_state get_cancellation_state() const ASIO_NOEXCEPT { return cancellation_state(); }@@ -129,8 +128,8 @@ template <typename InFilter, typename OutFilter> base_from_cancellation_state(const Handler&,- InFilter&&,- OutFilter&&)+ ASIO_MOVE_ARG(InFilter),+ ASIO_MOVE_ARG(OutFilter)) { } @@ -145,12 +144,12 @@ template <typename InFilter, typename OutFilter> void reset_cancellation_state(const Handler&,- InFilter&&,- OutFilter&&)+ ASIO_MOVE_ARG(InFilter),+ ASIO_MOVE_ARG(OutFilter)) { } - constexpr cancellation_type_t cancelled() const noexcept+ ASIO_CONSTEXPR cancellation_type_t cancelled() const ASIO_NOEXCEPT { return cancellation_type::none; }
link/modules/asio-standalone/asio/include/asio/detail/base_from_completion_cond.hpp view
@@ -2,7 +2,7 @@ // detail/base_from_completion_cond.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -29,7 +29,7 @@ protected: explicit base_from_completion_cond(CompletionCondition& completion_condition) : completion_condition_(- static_cast<CompletionCondition&&>(completion_condition))+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition)) { }
link/modules/asio-standalone/asio/include/asio/detail/bind_handler.hpp view
@@ -2,7 +2,7 @@ // detail/bind_handler.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -17,7 +17,9 @@ #include "asio/detail/config.hpp" #include "asio/associator.hpp"+#include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_cont_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/type_traits.hpp" #include "asio/detail/push_options.hpp"@@ -30,29 +32,31 @@ { public: template <typename T>- binder0(int, T&& handler)- : handler_(static_cast<T&&>(handler))+ binder0(int, ASIO_MOVE_ARG(T) handler)+ : handler_(ASIO_MOVE_CAST(T)(handler)) { } binder0(Handler& handler)- : handler_(static_cast<Handler&&>(handler))+ : handler_(ASIO_MOVE_CAST(Handler)(handler)) { } +#if defined(ASIO_HAS_MOVE) binder0(const binder0& other) : handler_(other.handler_) { } binder0(binder0&& other)- : handler_(static_cast<Handler&&>(other.handler_))+ : handler_(ASIO_MOVE_CAST(Handler)(other.handler_)) { }+#endif // defined(ASIO_HAS_MOVE) void operator()() {- static_cast<Handler&&>(handler_)();+ ASIO_MOVE_OR_LVALUE(Handler)(handler_)(); } void operator()() const@@ -65,6 +69,32 @@ }; template <typename Handler>+inline asio_handler_allocate_is_deprecated+asio_handler_allocate(std::size_t size,+ binder0<Handler>* this_handler)+{+#if defined(ASIO_NO_DEPRECATED)+ asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+ return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+ return asio_handler_alloc_helpers::allocate(+ size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler>+inline asio_handler_deallocate_is_deprecated+asio_handler_deallocate(void* pointer, std::size_t size,+ binder0<Handler>* this_handler)+{+ asio_handler_alloc_helpers::deallocate(+ pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler> inline bool asio_handler_is_continuation( binder0<Handler>* this_handler) {@@ -72,12 +102,36 @@ this_handler->handler_); } +template <typename Function, typename Handler>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(Function& function,+ binder0<Handler>* this_handler)+{+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Function, typename Handler>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(const Function& function,+ binder0<Handler>* this_handler)+{+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}+ template <typename Handler>-inline binder0<decay_t<Handler>> bind_handler(- Handler&& handler)+inline binder0<typename decay<Handler>::type> bind_handler(+ ASIO_MOVE_ARG(Handler) handler) {- return binder0<decay_t<Handler>>(- 0, static_cast<Handler&&>(handler));+ return binder0<typename decay<Handler>::type>(+ 0, ASIO_MOVE_CAST(Handler)(handler)); } template <typename Handler, typename Arg1>@@ -85,18 +139,19 @@ { public: template <typename T>- binder1(int, T&& handler, const Arg1& arg1)- : handler_(static_cast<T&&>(handler)),+ binder1(int, ASIO_MOVE_ARG(T) handler, const Arg1& arg1)+ : handler_(ASIO_MOVE_CAST(T)(handler)), arg1_(arg1) { } binder1(Handler& handler, const Arg1& arg1)- : handler_(static_cast<Handler&&>(handler)),+ : handler_(ASIO_MOVE_CAST(Handler)(handler)), arg1_(arg1) { } +#if defined(ASIO_HAS_MOVE) binder1(const binder1& other) : handler_(other.handler_), arg1_(other.arg1_)@@ -104,14 +159,15 @@ } binder1(binder1&& other)- : handler_(static_cast<Handler&&>(other.handler_)),- arg1_(static_cast<Arg1&&>(other.arg1_))+ : handler_(ASIO_MOVE_CAST(Handler)(other.handler_)),+ arg1_(ASIO_MOVE_CAST(Arg1)(other.arg1_)) { }+#endif // defined(ASIO_HAS_MOVE) void operator()() {- static_cast<Handler&&>(handler_)(+ ASIO_MOVE_OR_LVALUE(Handler)(handler_)( static_cast<const Arg1&>(arg1_)); } @@ -126,6 +182,32 @@ }; template <typename Handler, typename Arg1>+inline asio_handler_allocate_is_deprecated+asio_handler_allocate(std::size_t size,+ binder1<Handler, Arg1>* this_handler)+{+#if defined(ASIO_NO_DEPRECATED)+ asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+ return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+ return asio_handler_alloc_helpers::allocate(+ size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler, typename Arg1>+inline asio_handler_deallocate_is_deprecated+asio_handler_deallocate(void* pointer, std::size_t size,+ binder1<Handler, Arg1>* this_handler)+{+ asio_handler_alloc_helpers::deallocate(+ pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler, typename Arg1> inline bool asio_handler_is_continuation( binder1<Handler, Arg1>* this_handler) {@@ -133,12 +215,36 @@ this_handler->handler_); } +template <typename Function, typename Handler, typename Arg1>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(Function& function,+ binder1<Handler, Arg1>* this_handler)+{+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Function, typename Handler, typename Arg1>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(const Function& function,+ binder1<Handler, Arg1>* this_handler)+{+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}+ template <typename Handler, typename Arg1>-inline binder1<decay_t<Handler>, Arg1> bind_handler(- Handler&& handler, const Arg1& arg1)+inline binder1<typename decay<Handler>::type, Arg1> bind_handler(+ ASIO_MOVE_ARG(Handler) handler, const Arg1& arg1) {- return binder1<decay_t<Handler>, Arg1>(0,- static_cast<Handler&&>(handler), arg1);+ return binder1<typename decay<Handler>::type, Arg1>(0,+ ASIO_MOVE_CAST(Handler)(handler), arg1); } template <typename Handler, typename Arg1, typename Arg2>@@ -146,21 +252,22 @@ { public: template <typename T>- binder2(int, T&& handler,+ binder2(int, ASIO_MOVE_ARG(T) handler, const Arg1& arg1, const Arg2& arg2)- : handler_(static_cast<T&&>(handler)),+ : handler_(ASIO_MOVE_CAST(T)(handler)), arg1_(arg1), arg2_(arg2) { } binder2(Handler& handler, const Arg1& arg1, const Arg2& arg2)- : handler_(static_cast<Handler&&>(handler)),+ : handler_(ASIO_MOVE_CAST(Handler)(handler)), arg1_(arg1), arg2_(arg2) { } +#if defined(ASIO_HAS_MOVE) binder2(const binder2& other) : handler_(other.handler_), arg1_(other.arg1_),@@ -169,15 +276,16 @@ } binder2(binder2&& other)- : handler_(static_cast<Handler&&>(other.handler_)),- arg1_(static_cast<Arg1&&>(other.arg1_)),- arg2_(static_cast<Arg2&&>(other.arg2_))+ : handler_(ASIO_MOVE_CAST(Handler)(other.handler_)),+ arg1_(ASIO_MOVE_CAST(Arg1)(other.arg1_)),+ arg2_(ASIO_MOVE_CAST(Arg2)(other.arg2_)) { }+#endif // defined(ASIO_HAS_MOVE) void operator()() {- static_cast<Handler&&>(handler_)(+ ASIO_MOVE_OR_LVALUE(Handler)(handler_)( static_cast<const Arg1&>(arg1_), static_cast<const Arg2&>(arg2_)); }@@ -194,6 +302,32 @@ }; template <typename Handler, typename Arg1, typename Arg2>+inline asio_handler_allocate_is_deprecated+asio_handler_allocate(std::size_t size,+ binder2<Handler, Arg1, Arg2>* this_handler)+{+#if defined(ASIO_NO_DEPRECATED)+ asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+ return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+ return asio_handler_alloc_helpers::allocate(+ size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler, typename Arg1, typename Arg2>+inline asio_handler_deallocate_is_deprecated+asio_handler_deallocate(void* pointer, std::size_t size,+ binder2<Handler, Arg1, Arg2>* this_handler)+{+ asio_handler_alloc_helpers::deallocate(+ pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler, typename Arg1, typename Arg2> inline bool asio_handler_is_continuation( binder2<Handler, Arg1, Arg2>* this_handler) {@@ -201,12 +335,36 @@ this_handler->handler_); } +template <typename Function, typename Handler, typename Arg1, typename Arg2>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(Function& function,+ binder2<Handler, Arg1, Arg2>* this_handler)+{+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Function, typename Handler, typename Arg1, typename Arg2>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(const Function& function,+ binder2<Handler, Arg1, Arg2>* this_handler)+{+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}+ template <typename Handler, typename Arg1, typename Arg2>-inline binder2<decay_t<Handler>, Arg1, Arg2> bind_handler(- Handler&& handler, const Arg1& arg1, const Arg2& arg2)+inline binder2<typename decay<Handler>::type, Arg1, Arg2> bind_handler(+ ASIO_MOVE_ARG(Handler) handler, const Arg1& arg1, const Arg2& arg2) {- return binder2<decay_t<Handler>, Arg1, Arg2>(0,- static_cast<Handler&&>(handler), arg1, arg2);+ return binder2<typename decay<Handler>::type, Arg1, Arg2>(0,+ ASIO_MOVE_CAST(Handler)(handler), arg1, arg2); } template <typename Handler, typename Arg1, typename Arg2, typename Arg3>@@ -214,9 +372,9 @@ { public: template <typename T>- binder3(int, T&& handler, const Arg1& arg1,+ binder3(int, ASIO_MOVE_ARG(T) handler, const Arg1& arg1, const Arg2& arg2, const Arg3& arg3)- : handler_(static_cast<T&&>(handler)),+ : handler_(ASIO_MOVE_CAST(T)(handler)), arg1_(arg1), arg2_(arg2), arg3_(arg3)@@ -225,13 +383,14 @@ binder3(Handler& handler, const Arg1& arg1, const Arg2& arg2, const Arg3& arg3)- : handler_(static_cast<Handler&&>(handler)),+ : handler_(ASIO_MOVE_CAST(Handler)(handler)), arg1_(arg1), arg2_(arg2), arg3_(arg3) { } +#if defined(ASIO_HAS_MOVE) binder3(const binder3& other) : handler_(other.handler_), arg1_(other.arg1_),@@ -241,16 +400,17 @@ } binder3(binder3&& other)- : handler_(static_cast<Handler&&>(other.handler_)),- arg1_(static_cast<Arg1&&>(other.arg1_)),- arg2_(static_cast<Arg2&&>(other.arg2_)),- arg3_(static_cast<Arg3&&>(other.arg3_))+ : handler_(ASIO_MOVE_CAST(Handler)(other.handler_)),+ arg1_(ASIO_MOVE_CAST(Arg1)(other.arg1_)),+ arg2_(ASIO_MOVE_CAST(Arg2)(other.arg2_)),+ arg3_(ASIO_MOVE_CAST(Arg3)(other.arg3_)) { }+#endif // defined(ASIO_HAS_MOVE) void operator()() {- static_cast<Handler&&>(handler_)(+ ASIO_MOVE_OR_LVALUE(Handler)(handler_)( static_cast<const Arg1&>(arg1_), static_cast<const Arg2&>(arg2_), static_cast<const Arg3&>(arg3_));@@ -269,6 +429,32 @@ }; template <typename Handler, typename Arg1, typename Arg2, typename Arg3>+inline asio_handler_allocate_is_deprecated+asio_handler_allocate(std::size_t size,+ binder3<Handler, Arg1, Arg2, Arg3>* this_handler)+{+#if defined(ASIO_NO_DEPRECATED)+ asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+ return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+ return asio_handler_alloc_helpers::allocate(+ size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler, typename Arg1, typename Arg2, typename Arg3>+inline asio_handler_deallocate_is_deprecated+asio_handler_deallocate(void* pointer, std::size_t size,+ binder3<Handler, Arg1, Arg2, Arg3>* this_handler)+{+ asio_handler_alloc_helpers::deallocate(+ pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler, typename Arg1, typename Arg2, typename Arg3> inline bool asio_handler_is_continuation( binder3<Handler, Arg1, Arg2, Arg3>* this_handler) {@@ -276,13 +462,39 @@ this_handler->handler_); } +template <typename Function, typename Handler,+ typename Arg1, typename Arg2, typename Arg3>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(Function& function,+ binder3<Handler, Arg1, Arg2, Arg3>* this_handler)+{+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Function, typename Handler,+ typename Arg1, typename Arg2, typename Arg3>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(const Function& function,+ binder3<Handler, Arg1, Arg2, Arg3>* this_handler)+{+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}+ template <typename Handler, typename Arg1, typename Arg2, typename Arg3>-inline binder3<decay_t<Handler>, Arg1, Arg2, Arg3> bind_handler(- Handler&& handler, const Arg1& arg1, const Arg2& arg2,+inline binder3<typename decay<Handler>::type, Arg1, Arg2, Arg3> bind_handler(+ ASIO_MOVE_ARG(Handler) handler, const Arg1& arg1, const Arg2& arg2, const Arg3& arg3) {- return binder3<decay_t<Handler>, Arg1, Arg2, Arg3>(0,- static_cast<Handler&&>(handler), arg1, arg2, arg3);+ return binder3<typename decay<Handler>::type, Arg1, Arg2, Arg3>(0,+ ASIO_MOVE_CAST(Handler)(handler), arg1, arg2, arg3); } template <typename Handler, typename Arg1,@@ -291,9 +503,9 @@ { public: template <typename T>- binder4(int, T&& handler, const Arg1& arg1,+ binder4(int, ASIO_MOVE_ARG(T) handler, const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, const Arg4& arg4)- : handler_(static_cast<T&&>(handler)),+ : handler_(ASIO_MOVE_CAST(T)(handler)), arg1_(arg1), arg2_(arg2), arg3_(arg3),@@ -303,7 +515,7 @@ binder4(Handler& handler, const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, const Arg4& arg4)- : handler_(static_cast<Handler&&>(handler)),+ : handler_(ASIO_MOVE_CAST(Handler)(handler)), arg1_(arg1), arg2_(arg2), arg3_(arg3),@@ -311,6 +523,7 @@ { } +#if defined(ASIO_HAS_MOVE) binder4(const binder4& other) : handler_(other.handler_), arg1_(other.arg1_),@@ -321,17 +534,18 @@ } binder4(binder4&& other)- : handler_(static_cast<Handler&&>(other.handler_)),- arg1_(static_cast<Arg1&&>(other.arg1_)),- arg2_(static_cast<Arg2&&>(other.arg2_)),- arg3_(static_cast<Arg3&&>(other.arg3_)),- arg4_(static_cast<Arg4&&>(other.arg4_))+ : handler_(ASIO_MOVE_CAST(Handler)(other.handler_)),+ arg1_(ASIO_MOVE_CAST(Arg1)(other.arg1_)),+ arg2_(ASIO_MOVE_CAST(Arg2)(other.arg2_)),+ arg3_(ASIO_MOVE_CAST(Arg3)(other.arg3_)),+ arg4_(ASIO_MOVE_CAST(Arg4)(other.arg4_)) { }+#endif // defined(ASIO_HAS_MOVE) void operator()() {- static_cast<Handler&&>(handler_)(+ ASIO_MOVE_OR_LVALUE(Handler)(handler_)( static_cast<const Arg1&>(arg1_), static_cast<const Arg2&>(arg2_), static_cast<const Arg3&>(arg3_),@@ -353,6 +567,34 @@ template <typename Handler, typename Arg1, typename Arg2, typename Arg3, typename Arg4>+inline asio_handler_allocate_is_deprecated+asio_handler_allocate(std::size_t size,+ binder4<Handler, Arg1, Arg2, Arg3, Arg4>* this_handler)+{+#if defined(ASIO_NO_DEPRECATED)+ asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+ return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+ return asio_handler_alloc_helpers::allocate(+ size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler, typename Arg1,+ typename Arg2, typename Arg3, typename Arg4>+inline asio_handler_deallocate_is_deprecated+asio_handler_deallocate(void* pointer, std::size_t size,+ binder4<Handler, Arg1, Arg2, Arg3, Arg4>* this_handler)+{+ asio_handler_alloc_helpers::deallocate(+ pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++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) {@@ -360,14 +602,40 @@ this_handler->handler_); } +template <typename Function, typename Handler, typename Arg1,+ typename Arg2, typename Arg3, typename Arg4>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(Function& function,+ binder4<Handler, Arg1, Arg2, Arg3, Arg4>* this_handler)+{+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Function, typename Handler, typename Arg1,+ typename Arg2, typename Arg3, typename Arg4>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(const Function& function,+ binder4<Handler, Arg1, Arg2, Arg3, Arg4>* this_handler)+{+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}+ template <typename Handler, typename Arg1, typename Arg2, typename Arg3, typename Arg4>-inline binder4<decay_t<Handler>, Arg1, Arg2, Arg3, Arg4>-bind_handler(Handler&& handler, const Arg1& arg1,+inline binder4<typename decay<Handler>::type, Arg1, Arg2, Arg3, Arg4>+bind_handler(ASIO_MOVE_ARG(Handler) handler, const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, const Arg4& arg4) {- return binder4<decay_t<Handler>, Arg1, Arg2, Arg3, Arg4>(0,- static_cast<Handler&&>(handler), arg1, arg2, arg3, arg4);+ return binder4<typename decay<Handler>::type, Arg1, Arg2, Arg3, Arg4>(0,+ ASIO_MOVE_CAST(Handler)(handler), arg1, arg2, arg3, arg4); } template <typename Handler, typename Arg1, typename Arg2,@@ -376,9 +644,9 @@ { public: template <typename T>- binder5(int, T&& handler, const Arg1& arg1,+ binder5(int, ASIO_MOVE_ARG(T) handler, const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, const Arg4& arg4, const Arg5& arg5)- : handler_(static_cast<T&&>(handler)),+ : handler_(ASIO_MOVE_CAST(T)(handler)), arg1_(arg1), arg2_(arg2), arg3_(arg3),@@ -389,7 +657,7 @@ binder5(Handler& handler, const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, const Arg4& arg4, const Arg5& arg5)- : handler_(static_cast<Handler&&>(handler)),+ : handler_(ASIO_MOVE_CAST(Handler)(handler)), arg1_(arg1), arg2_(arg2), arg3_(arg3),@@ -398,6 +666,7 @@ { } +#if defined(ASIO_HAS_MOVE) binder5(const binder5& other) : handler_(other.handler_), arg1_(other.arg1_),@@ -409,18 +678,19 @@ } binder5(binder5&& other)- : handler_(static_cast<Handler&&>(other.handler_)),- arg1_(static_cast<Arg1&&>(other.arg1_)),- arg2_(static_cast<Arg2&&>(other.arg2_)),- arg3_(static_cast<Arg3&&>(other.arg3_)),- arg4_(static_cast<Arg4&&>(other.arg4_)),- arg5_(static_cast<Arg5&&>(other.arg5_))+ : handler_(ASIO_MOVE_CAST(Handler)(other.handler_)),+ arg1_(ASIO_MOVE_CAST(Arg1)(other.arg1_)),+ arg2_(ASIO_MOVE_CAST(Arg2)(other.arg2_)),+ arg3_(ASIO_MOVE_CAST(Arg3)(other.arg3_)),+ arg4_(ASIO_MOVE_CAST(Arg4)(other.arg4_)),+ arg5_(ASIO_MOVE_CAST(Arg5)(other.arg5_)) { }+#endif // defined(ASIO_HAS_MOVE) void operator()() {- static_cast<Handler&&>(handler_)(+ ASIO_MOVE_OR_LVALUE(Handler)(handler_)( static_cast<const Arg1&>(arg1_), static_cast<const Arg2&>(arg2_), static_cast<const Arg3&>(arg3_),@@ -444,6 +714,34 @@ template <typename Handler, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5>+inline asio_handler_allocate_is_deprecated+asio_handler_allocate(std::size_t size,+ binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>* this_handler)+{+#if defined(ASIO_NO_DEPRECATED)+ asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+ return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+ return asio_handler_alloc_helpers::allocate(+ size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler, typename Arg1, typename Arg2,+ typename Arg3, typename Arg4, typename Arg5>+inline asio_handler_deallocate_is_deprecated+asio_handler_deallocate(void* pointer, std::size_t size,+ binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>* this_handler)+{+ asio_handler_alloc_helpers::deallocate(+ pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++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) {@@ -451,37 +749,65 @@ this_handler->handler_); } +template <typename Function, typename Handler, typename Arg1,+ typename Arg2, typename Arg3, typename Arg4, typename Arg5>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(Function& function,+ binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>* this_handler)+{+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Function, typename Handler, typename Arg1,+ typename Arg2, typename Arg3, typename Arg4, typename Arg5>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(const Function& function,+ binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>* this_handler)+{+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}+ template <typename Handler, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5>-inline binder5<decay_t<Handler>, Arg1, Arg2, Arg3, Arg4, Arg5>-bind_handler(Handler&& handler, const Arg1& arg1,+inline binder5<typename decay<Handler>::type, Arg1, Arg2, Arg3, Arg4, Arg5>+bind_handler(ASIO_MOVE_ARG(Handler) handler, const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, const Arg4& arg4, const Arg5& arg5) {- return binder5<decay_t<Handler>, Arg1, Arg2, Arg3, Arg4, Arg5>(0,- static_cast<Handler&&>(handler), arg1, arg2, arg3, arg4, arg5);+ return binder5<typename decay<Handler>::type, Arg1, Arg2, Arg3, Arg4, Arg5>(0,+ ASIO_MOVE_CAST(Handler)(handler), arg1, arg2, arg3, arg4, arg5); } +#if defined(ASIO_HAS_MOVE)+ template <typename Handler, typename Arg1> class move_binder1 { public:- move_binder1(int, Handler&& handler,- Arg1&& arg1)- : handler_(static_cast<Handler&&>(handler)),- arg1_(static_cast<Arg1&&>(arg1))+ move_binder1(int, ASIO_MOVE_ARG(Handler) handler,+ ASIO_MOVE_ARG(Arg1) arg1)+ : handler_(ASIO_MOVE_CAST(Handler)(handler)),+ arg1_(ASIO_MOVE_CAST(Arg1)(arg1)) { } move_binder1(move_binder1&& other)- : handler_(static_cast<Handler&&>(other.handler_)),- arg1_(static_cast<Arg1&&>(other.arg1_))+ : handler_(ASIO_MOVE_CAST(Handler)(other.handler_)),+ arg1_(ASIO_MOVE_CAST(Arg1)(other.arg1_)) { } void operator()() {- static_cast<Handler&&>(handler_)(- static_cast<Arg1&&>(arg1_));+ ASIO_MOVE_OR_LVALUE(Handler)(handler_)(+ ASIO_MOVE_CAST(Arg1)(arg1_)); } //private:@@ -490,6 +816,32 @@ }; template <typename Handler, typename Arg1>+inline asio_handler_allocate_is_deprecated+asio_handler_allocate(std::size_t size,+ move_binder1<Handler, Arg1>* this_handler)+{+#if defined(ASIO_NO_DEPRECATED)+ asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+ return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+ return asio_handler_alloc_helpers::allocate(+ size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler, typename Arg1>+inline asio_handler_deallocate_is_deprecated+asio_handler_deallocate(void* pointer, std::size_t size,+ move_binder1<Handler, Arg1>* this_handler)+{+ asio_handler_alloc_helpers::deallocate(+ pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler, typename Arg1> inline bool asio_handler_is_continuation( move_binder1<Handler, Arg1>* this_handler) {@@ -497,30 +849,42 @@ this_handler->handler_); } +template <typename Function, typename Handler, typename Arg1>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(ASIO_MOVE_ARG(Function) function,+ move_binder1<Handler, Arg1>* this_handler)+{+ asio_handler_invoke_helpers::invoke(+ ASIO_MOVE_CAST(Function)(function), this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}+ template <typename Handler, typename Arg1, typename Arg2> class move_binder2 { public:- move_binder2(int, Handler&& handler,- const Arg1& arg1, Arg2&& arg2)- : handler_(static_cast<Handler&&>(handler)),+ move_binder2(int, ASIO_MOVE_ARG(Handler) handler,+ const Arg1& arg1, ASIO_MOVE_ARG(Arg2) arg2)+ : handler_(ASIO_MOVE_CAST(Handler)(handler)), arg1_(arg1),- arg2_(static_cast<Arg2&&>(arg2))+ arg2_(ASIO_MOVE_CAST(Arg2)(arg2)) { } move_binder2(move_binder2&& other)- : handler_(static_cast<Handler&&>(other.handler_)),- arg1_(static_cast<Arg1&&>(other.arg1_)),- arg2_(static_cast<Arg2&&>(other.arg2_))+ : handler_(ASIO_MOVE_CAST(Handler)(other.handler_)),+ arg1_(ASIO_MOVE_CAST(Arg1)(other.arg1_)),+ arg2_(ASIO_MOVE_CAST(Arg2)(other.arg2_)) { } void operator()() {- static_cast<Handler&&>(handler_)(+ ASIO_MOVE_OR_LVALUE(Handler)(handler_)( static_cast<const Arg1&>(arg1_),- static_cast<Arg2&&>(arg2_));+ ASIO_MOVE_CAST(Arg2)(arg2_)); } //private:@@ -530,6 +894,32 @@ }; template <typename Handler, typename Arg1, typename Arg2>+inline asio_handler_allocate_is_deprecated+asio_handler_allocate(std::size_t size,+ move_binder2<Handler, Arg1, Arg2>* this_handler)+{+#if defined(ASIO_NO_DEPRECATED)+ asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+ return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+ return asio_handler_alloc_helpers::allocate(+ size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler, typename Arg1, typename Arg2>+inline asio_handler_deallocate_is_deprecated+asio_handler_deallocate(void* pointer, std::size_t size,+ move_binder2<Handler, Arg1, Arg2>* this_handler)+{+ asio_handler_alloc_helpers::deallocate(+ pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler, typename Arg1, typename Arg2> inline bool asio_handler_is_continuation( move_binder2<Handler, Arg1, Arg2>* this_handler) {@@ -537,6 +927,20 @@ this_handler->handler_); } +template <typename Function, typename Handler, typename Arg1, typename Arg2>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(ASIO_MOVE_ARG(Function) function,+ move_binder2<Handler, Arg1, Arg2>* this_handler)+{+ asio_handler_invoke_helpers::invoke(+ ASIO_MOVE_CAST(Function)(function), this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++#endif // defined(ASIO_HAS_MOVE)+ } // namespace detail template <template <typename, typename> class Associator,@@ -545,15 +949,18 @@ detail::binder0<Handler>, DefaultCandidate> : Associator<Handler, DefaultCandidate> {- static typename Associator<Handler, DefaultCandidate>::type get(- const detail::binder0<Handler>& h) noexcept+ static typename Associator<Handler, DefaultCandidate>::type+ get(const detail::binder0<Handler>& h) ASIO_NOEXCEPT { return Associator<Handler, DefaultCandidate>::get(h.handler_); } - static auto get(const detail::binder0<Handler>& h,- const DefaultCandidate& c) noexcept- -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))+ static ASIO_AUTO_RETURN_TYPE_PREFIX2(+ typename Associator<Handler, DefaultCandidate>::type)+ get(const detail::binder0<Handler>& h,+ const DefaultCandidate& c) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ Associator<Handler, DefaultCandidate>::get(h.handler_, c))) { return Associator<Handler, DefaultCandidate>::get(h.handler_, c); }@@ -565,15 +972,18 @@ detail::binder1<Handler, Arg1>, DefaultCandidate> : Associator<Handler, DefaultCandidate> {- static typename Associator<Handler, DefaultCandidate>::type get(- const detail::binder1<Handler, Arg1>& h) noexcept+ static typename Associator<Handler, DefaultCandidate>::type+ get(const detail::binder1<Handler, Arg1>& h) ASIO_NOEXCEPT { return Associator<Handler, DefaultCandidate>::get(h.handler_); } - static auto get(const detail::binder1<Handler, Arg1>& h,- const DefaultCandidate& c) noexcept- -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))+ static ASIO_AUTO_RETURN_TYPE_PREFIX2(+ typename Associator<Handler, DefaultCandidate>::type)+ get(const detail::binder1<Handler, Arg1>& h,+ const DefaultCandidate& c) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ Associator<Handler, DefaultCandidate>::get(h.handler_, c))) { return Associator<Handler, DefaultCandidate>::get(h.handler_, c); }@@ -586,15 +996,18 @@ detail::binder2<Handler, Arg1, Arg2>, DefaultCandidate> : Associator<Handler, DefaultCandidate> {- static typename Associator<Handler, DefaultCandidate>::type get(- const detail::binder2<Handler, Arg1, Arg2>& h) noexcept+ static typename Associator<Handler, DefaultCandidate>::type+ get(const detail::binder2<Handler, Arg1, Arg2>& h) ASIO_NOEXCEPT { return Associator<Handler, DefaultCandidate>::get(h.handler_); } - static auto get(const detail::binder2<Handler, Arg1, Arg2>& h,- const DefaultCandidate& c) noexcept- -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))+ static ASIO_AUTO_RETURN_TYPE_PREFIX2(+ typename Associator<Handler, DefaultCandidate>::type)+ get(const detail::binder2<Handler, Arg1, Arg2>& h,+ const DefaultCandidate& c) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ Associator<Handler, DefaultCandidate>::get(h.handler_, c))) { return Associator<Handler, DefaultCandidate>::get(h.handler_, c); }@@ -607,15 +1020,18 @@ detail::binder3<Handler, Arg1, Arg2, Arg3>, DefaultCandidate> : Associator<Handler, DefaultCandidate> {- static typename Associator<Handler, DefaultCandidate>::type get(- const detail::binder3<Handler, Arg1, Arg2, Arg3>& h) noexcept+ static typename Associator<Handler, DefaultCandidate>::type+ get(const detail::binder3<Handler, Arg1, Arg2, Arg3>& h) ASIO_NOEXCEPT { return Associator<Handler, DefaultCandidate>::get(h.handler_); } - static auto get(const detail::binder3<Handler, Arg1, Arg2, Arg3>& h,- const DefaultCandidate& c) noexcept- -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))+ static ASIO_AUTO_RETURN_TYPE_PREFIX2(+ typename Associator<Handler, DefaultCandidate>::type)+ get(const detail::binder3<Handler, Arg1, Arg2, Arg3>& h,+ const DefaultCandidate& c) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ Associator<Handler, DefaultCandidate>::get(h.handler_, c))) { return Associator<Handler, DefaultCandidate>::get(h.handler_, c); }@@ -628,15 +1044,19 @@ detail::binder4<Handler, Arg1, Arg2, Arg3, Arg4>, DefaultCandidate> : Associator<Handler, DefaultCandidate> {- static typename Associator<Handler, DefaultCandidate>::type get(- const detail::binder4<Handler, Arg1, Arg2, Arg3, Arg4>& h) noexcept+ static typename Associator<Handler, DefaultCandidate>::type+ get(const detail::binder4<Handler, Arg1, Arg2, Arg3, Arg4>& h)+ ASIO_NOEXCEPT { return Associator<Handler, DefaultCandidate>::get(h.handler_); } - static auto get(const detail::binder4<Handler, Arg1, Arg2, Arg3, Arg4>& h,- const DefaultCandidate& c) noexcept- -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))+ static ASIO_AUTO_RETURN_TYPE_PREFIX2(+ typename Associator<Handler, DefaultCandidate>::type)+ get(const detail::binder4<Handler, Arg1, Arg2, Arg3, Arg4>& h,+ const DefaultCandidate& c) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ Associator<Handler, DefaultCandidate>::get(h.handler_, c))) { return Associator<Handler, DefaultCandidate>::get(h.handler_, c); }@@ -649,60 +1069,74 @@ detail::binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>, DefaultCandidate> : Associator<Handler, DefaultCandidate> {- static typename Associator<Handler, DefaultCandidate>::type get(- const detail::binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>& h) noexcept+ static typename Associator<Handler, DefaultCandidate>::type+ get(const detail::binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>& h)+ ASIO_NOEXCEPT { return Associator<Handler, DefaultCandidate>::get(h.handler_); } - static auto get(- const detail::binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>& h,- const DefaultCandidate& c) noexcept- -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))+ static ASIO_AUTO_RETURN_TYPE_PREFIX2(+ typename Associator<Handler, DefaultCandidate>::type)+ get(const detail::binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>& h,+ const DefaultCandidate& c) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ Associator<Handler, DefaultCandidate>::get(h.handler_, c))) { return Associator<Handler, DefaultCandidate>::get(h.handler_, c); } }; +#if defined(ASIO_HAS_MOVE)+ template <template <typename, typename> class Associator, typename Handler, typename Arg1, typename DefaultCandidate> struct associator<Associator, detail::move_binder1<Handler, Arg1>, DefaultCandidate> : Associator<Handler, DefaultCandidate> {- static typename Associator<Handler, DefaultCandidate>::type get(- const detail::move_binder1<Handler, Arg1>& h) noexcept+ static typename Associator<Handler, DefaultCandidate>::type+ get(const detail::move_binder1<Handler, Arg1>& h) ASIO_NOEXCEPT { return Associator<Handler, DefaultCandidate>::get(h.handler_); } - static auto get(const detail::move_binder1<Handler, Arg1>& h,- const DefaultCandidate& c) noexcept- -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))+ static ASIO_AUTO_RETURN_TYPE_PREFIX2(+ typename Associator<Handler, DefaultCandidate>::type)+ get(const detail::move_binder1<Handler, Arg1>& h,+ const DefaultCandidate& c) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ Associator<Handler, DefaultCandidate>::get(h.handler_, c))) { return Associator<Handler, DefaultCandidate>::get(h.handler_, c); } }; template <template <typename, typename> class Associator,- typename Handler, typename Arg1, typename Arg2, typename DefaultCandidate>+ typename Handler, typename Arg1, typename Arg2,+ typename DefaultCandidate> struct associator<Associator, detail::move_binder2<Handler, Arg1, Arg2>, DefaultCandidate> : Associator<Handler, DefaultCandidate> {- static typename Associator<Handler, DefaultCandidate>::type get(- const detail::move_binder2<Handler, Arg1, Arg2>& h) noexcept+ static typename Associator<Handler, DefaultCandidate>::type+ get(const detail::move_binder2<Handler, Arg1, Arg2>& h) ASIO_NOEXCEPT { return Associator<Handler, DefaultCandidate>::get(h.handler_); } - static auto get(const detail::move_binder2<Handler, Arg1, Arg2>& h,- const DefaultCandidate& c) noexcept- -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))+ static ASIO_AUTO_RETURN_TYPE_PREFIX2(+ typename Associator<Handler, DefaultCandidate>::type)+ get(const detail::move_binder2<Handler, Arg1, Arg2>& h,+ const DefaultCandidate& c) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ Associator<Handler, DefaultCandidate>::get(h.handler_, c))) { return Associator<Handler, DefaultCandidate>::get(h.handler_, c); } };++#endif // defined(ASIO_HAS_MOVE) } // namespace asio
link/modules/asio-standalone/asio/include/asio/detail/blocking_executor_op.hpp view
@@ -2,7 +2,7 @@ // detail/blocking_executor_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -18,6 +18,7 @@ #include "asio/detail/config.hpp" #include "asio/detail/event.hpp" #include "asio/detail/fenced_block.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/mutex.hpp" #include "asio/detail/scheduler_operation.hpp" @@ -90,7 +91,7 @@ { fenced_block b(fenced_block::half); ASIO_HANDLER_INVOCATION_BEGIN(());- static_cast<Handler&&>(o->handler_)();+ asio_handler_invoke_helpers::invoke(o->handler_, o->handler_); ASIO_HANDLER_INVOCATION_END; } }
link/modules/asio-standalone/asio/include/asio/detail/buffer_resize_guard.hpp view
@@ -2,7 +2,7 @@ // detail/buffer_resize_guard.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/buffer_sequence_adapter.hpp view
@@ -2,7 +2,7 @@ // detail/buffer_sequence_adapter.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -385,7 +385,147 @@ std::size_t total_buffer_size_; }; +#if !defined(ASIO_NO_DEPRECATED)+ template <typename Buffer>+class buffer_sequence_adapter<Buffer, asio::mutable_buffers_1>+ : buffer_sequence_adapter_base+{+public:+ enum { is_single_buffer = true };+ enum { is_registered_buffer = false };++ explicit buffer_sequence_adapter(+ const asio::mutable_buffers_1& buffer_sequence)+ {+ init_native_buffer(buffer_, Buffer(buffer_sequence));+ total_buffer_size_ = buffer_sequence.size();+ }++ native_buffer_type* buffers()+ {+ return &buffer_;+ }++ std::size_t count() const+ {+ return 1;+ }++ std::size_t total_size() const+ {+ return total_buffer_size_;+ }++ registered_buffer_id registered_id() const+ {+ return registered_buffer_id();+ }++ bool all_empty() const+ {+ return total_buffer_size_ == 0;+ }++ static bool all_empty(const asio::mutable_buffers_1& buffer_sequence)+ {+ return buffer_sequence.size() == 0;+ }++ static void validate(const asio::mutable_buffers_1& buffer_sequence)+ {+ buffer_sequence.data();+ }++ static Buffer first(const asio::mutable_buffers_1& buffer_sequence)+ {+ return Buffer(buffer_sequence);+ }++ enum { linearisation_storage_size = 1 };++ static Buffer linearise(const asio::mutable_buffers_1& buffer_sequence,+ const Buffer&)+ {+ return Buffer(buffer_sequence);+ }++private:+ native_buffer_type buffer_;+ std::size_t total_buffer_size_;+};++template <typename Buffer>+class buffer_sequence_adapter<Buffer, asio::const_buffers_1>+ : buffer_sequence_adapter_base+{+public:+ enum { is_single_buffer = true };+ enum { is_registered_buffer = false };++ explicit buffer_sequence_adapter(+ const asio::const_buffers_1& buffer_sequence)+ {+ init_native_buffer(buffer_, Buffer(buffer_sequence));+ total_buffer_size_ = buffer_sequence.size();+ }++ native_buffer_type* buffers()+ {+ return &buffer_;+ }++ std::size_t count() const+ {+ return 1;+ }++ std::size_t total_size() const+ {+ return total_buffer_size_;+ }++ registered_buffer_id registered_id() const+ {+ return registered_buffer_id();+ }++ bool all_empty() const+ {+ return total_buffer_size_ == 0;+ }++ static bool all_empty(const asio::const_buffers_1& buffer_sequence)+ {+ return buffer_sequence.size() == 0;+ }++ static void validate(const asio::const_buffers_1& buffer_sequence)+ {+ buffer_sequence.data();+ }++ static Buffer first(const asio::const_buffers_1& buffer_sequence)+ {+ return Buffer(buffer_sequence);+ }++ enum { linearisation_storage_size = 1 };++ static Buffer linearise(const asio::const_buffers_1& buffer_sequence,+ const Buffer&)+ {+ return Buffer(buffer_sequence);+ }++private:+ native_buffer_type buffer_;+ std::size_t total_buffer_size_;+};++#endif // !defined(ASIO_NO_DEPRECATED)++template <typename Buffer> class buffer_sequence_adapter<Buffer, asio::mutable_registered_buffer> : buffer_sequence_adapter_base {@@ -534,7 +674,7 @@ }; template <typename Buffer, typename Elem>-class buffer_sequence_adapter<Buffer, boost::array<Elem, 2>>+class buffer_sequence_adapter<Buffer, boost::array<Elem, 2> > : buffer_sequence_adapter_base { public:@@ -609,8 +749,10 @@ std::size_t total_buffer_size_; }; +#if defined(ASIO_HAS_STD_ARRAY)+ template <typename Buffer, typename Elem>-class buffer_sequence_adapter<Buffer, std::array<Elem, 2>>+class buffer_sequence_adapter<Buffer, std::array<Elem, 2> > : buffer_sequence_adapter_base { public:@@ -684,6 +826,8 @@ native_buffer_type buffers_[2]; std::size_t total_buffer_size_; };++#endif // defined(ASIO_HAS_STD_ARRAY) } // namespace detail } // namespace asio
link/modules/asio-standalone/asio/include/asio/detail/buffered_stream_storage.hpp view
@@ -2,7 +2,7 @@ // detail/buffered_stream_storage.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -113,7 +113,7 @@ // The offset to the end of the unread data. size_type end_offset_;-+ // The data in the buffer. std::vector<byte_type> buffer_; };
+ link/modules/asio-standalone/asio/include/asio/detail/bulk_executor_op.hpp view
@@ -0,0 +1,89 @@+//+// detail/bulk_executor_op.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_DETAIL_BULK_EXECUTOR_OP_HPP+#define ASIO_DETAIL_BULK_EXECUTOR_OP_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/detail/bind_handler.hpp"+#include "asio/detail/fenced_block.hpp"+#include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp"+#include "asio/detail/scheduler_operation.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {+namespace detail {++template <typename Handler, typename Alloc,+ typename Operation = scheduler_operation>+class bulk_executor_op : public Operation+{+public:+ ASIO_DEFINE_HANDLER_ALLOCATOR_PTR(bulk_executor_op);++ template <typename H>+ bulk_executor_op(ASIO_MOVE_ARG(H) h,+ const Alloc& allocator, std::size_t i)+ : Operation(&bulk_executor_op::do_complete),+ handler_(ASIO_MOVE_CAST(H)(h)),+ allocator_(allocator),+ index_(i)+ {+ }++ static void do_complete(void* owner, Operation* base,+ const asio::error_code& /*ec*/,+ std::size_t /*bytes_transferred*/)+ {+ // Take ownership of the handler object.+ ASIO_ASSUME(base != 0);+ bulk_executor_op* o(static_cast<bulk_executor_op*>(base));+ Alloc allocator(o->allocator_);+ ptr p = { detail::addressof(allocator), o, o };++ ASIO_HANDLER_COMPLETION((*o));++ // Make a copy of the handler so that the memory can be deallocated before+ // the upcall is made. Even if we're not about to make an upcall, a+ // sub-object of the handler may be the true owner of the memory associated+ // with the handler. Consequently, a local copy of the handler is required+ // to ensure that any owning sub-object remains valid until after we have+ // deallocated the memory here.+ detail::binder1<Handler, std::size_t> handler(o->handler_, o->index_);+ p.reset();++ // Make the upcall if required.+ if (owner)+ {+ fenced_block b(fenced_block::half);+ ASIO_HANDLER_INVOCATION_BEGIN(());+ asio_handler_invoke_helpers::invoke(handler, handler.handler_);+ ASIO_HANDLER_INVOCATION_END;+ }+ }++private:+ Handler handler_;+ Alloc allocator_;+ std::size_t index_;+};++} // namespace detail+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_DETAIL_BULK_EXECUTOR_OP_HPP
link/modules/asio-standalone/asio/include/asio/detail/call_stack.hpp view
@@ -2,7 +2,7 @@ // detail/call_stack.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/chrono.hpp view
@@ -2,7 +2,7 @@ // detail/chrono.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -16,11 +16,17 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"-#include <chrono> +#if defined(ASIO_HAS_STD_CHRONO)+# include <chrono>+#elif defined(ASIO_HAS_BOOST_CHRONO)+# include <boost/chrono/system_clocks.hpp>+#endif // defined(ASIO_HAS_BOOST_CHRONO)+ namespace asio { namespace chrono { +#if defined(ASIO_HAS_STD_CHRONO) using std::chrono::duration; using std::chrono::time_point; using std::chrono::duration_cast;@@ -38,6 +44,21 @@ #endif // defined(ASIO_HAS_STD_CHRONO_MONOTONIC_CLOCK) using std::chrono::system_clock; using std::chrono::high_resolution_clock;+#elif defined(ASIO_HAS_BOOST_CHRONO)+using boost::chrono::duration;+using boost::chrono::time_point;+using boost::chrono::duration_cast;+using boost::chrono::nanoseconds;+using boost::chrono::microseconds;+using boost::chrono::milliseconds;+using boost::chrono::seconds;+using boost::chrono::minutes;+using boost::chrono::hours;+using boost::chrono::time_point_cast;+using boost::chrono::system_clock;+using boost::chrono::steady_clock;+using boost::chrono::high_resolution_clock;+#endif // defined(ASIO_HAS_BOOST_CHRONO) } // namespace chrono } // namespace asio
link/modules/asio-standalone/asio/include/asio/detail/chrono_time_traits.hpp view
@@ -2,7 +2,7 @@ // detail/chrono_time_traits.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/completion_handler.hpp view
@@ -2,7 +2,7 @@ // detail/completion_handler.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -35,7 +35,7 @@ completion_handler(Handler& h, const IoExecutor& io_ex) : operation(&completion_handler::do_complete),- handler_(static_cast<Handler&&>(h)),+ handler_(ASIO_MOVE_CAST(Handler)(h)), work_(handler_, io_ex) { }@@ -52,7 +52,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( h->work_)); // Make a copy of the handler so that the memory can be deallocated before@@ -61,7 +61,7 @@ // with the handler. Consequently, a local copy of the handler is required // to ensure that any owning sub-object remains valid until after we have // deallocated the memory here.- Handler handler(static_cast<Handler&&>(h->handler_));+ Handler handler(ASIO_MOVE_CAST(Handler)(h->handler_)); p.h = asio::detail::addressof(handler); p.reset();
− link/modules/asio-standalone/asio/include/asio/detail/completion_message.hpp
@@ -1,127 +0,0 @@-//-// detail/completion_message.hpp-// ~~~~~~~~~~~~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef ASIO_DETAIL_COMPLETION_MESSAGE_HPP-#define ASIO_DETAIL_COMPLETION_MESSAGE_HPP--#if defined(_MSC_VER) && (_MSC_VER >= 1200)-# pragma once-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)--#include "asio/detail/config.hpp"-#include <tuple>-#include "asio/detail/type_traits.hpp"-#include "asio/detail/utility.hpp"--#include "asio/detail/push_options.hpp"--namespace asio {-namespace detail {--template <typename Signature>-class completion_message;--template <typename R>-class completion_message<R()>-{-public:- completion_message(int)- {- }-- template <typename Handler>- void receive(Handler& handler)- {- static_cast<Handler&&>(handler)();- }-};--template <typename R, typename Arg0>-class completion_message<R(Arg0)>-{-public:- template <typename T0>- completion_message(int, T0&& t0)- : arg0_(static_cast<T0&&>(t0))- {- }-- template <typename Handler>- void receive(Handler& handler)- {- static_cast<Handler&&>(handler)(- static_cast<arg0_type&&>(arg0_));- }--private:- typedef decay_t<Arg0> arg0_type;- arg0_type arg0_;-};--template <typename R, typename Arg0, typename Arg1>-class completion_message<R(Arg0, Arg1)>-{-public:- template <typename T0, typename T1>- completion_message(int, T0&& t0, T1&& t1)- : arg0_(static_cast<T0&&>(t0)),- arg1_(static_cast<T1&&>(t1))- {- }-- template <typename Handler>- void receive(Handler& handler)- {- static_cast<Handler&&>(handler)(- static_cast<arg0_type&&>(arg0_),- static_cast<arg1_type&&>(arg1_));- }--private:- typedef decay_t<Arg0> arg0_type;- arg0_type arg0_;- typedef decay_t<Arg1> arg1_type;- arg1_type arg1_;-};--template <typename R, typename... Args>-class completion_message<R(Args...)>-{-public:- template <typename... T>- completion_message(int, T&&... t)- : args_(static_cast<T&&>(t)...)- {- }-- template <typename Handler>- void receive(Handler& h)- {- this->do_receive(h, asio::detail::index_sequence_for<Args...>());- }--private:- template <typename Handler, std::size_t... I>- void do_receive(Handler& h, asio::detail::index_sequence<I...>)- {- static_cast<Handler&&>(h)(- std::get<I>(static_cast<args_type&&>(args_))...);- }-- typedef std::tuple<decay_t<Args>...> args_type;- args_type args_;-};--} // namespace detail-} // namespace asio--#include "asio/detail/pop_options.hpp"--#endif // ASIO_DETAIL_COMPLETION_MESSAGE_HPP
− link/modules/asio-standalone/asio/include/asio/detail/completion_payload.hpp
@@ -1,220 +0,0 @@-//-// detail/completion_payload.hpp-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef ASIO_DETAIL_COMPLETION_PAYLOAD_HPP-#define ASIO_DETAIL_COMPLETION_PAYLOAD_HPP--#if defined(_MSC_VER) && (_MSC_VER >= 1200)-# pragma once-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)--#include "asio/detail/config.hpp"-#include "asio/detail/type_traits.hpp"-#include "asio/error_code.hpp"-#include "asio/detail/completion_message.hpp"--#if defined(ASIO_HAS_STD_VARIANT)-# include <variant>-#else // defined(ASIO_HAS_STD_VARIANT)-# include <new>-#endif // defined(ASIO_HAS_STD_VARIANT)--#include "asio/detail/push_options.hpp"--namespace asio {-namespace detail {--template <typename... Signatures>-class completion_payload;--template <typename R>-class completion_payload<R()>-{-public:- explicit completion_payload(completion_message<R()>)- {- }-- template <typename Handler>- void receive(Handler& handler)- {- static_cast<Handler&&>(handler)();- }-};--template <typename Signature>-class completion_payload<Signature>-{-public:- completion_payload(completion_message<Signature>&& m)- : message_(static_cast<completion_message<Signature>&&>(m))- {- }-- template <typename Handler>- void receive(Handler& handler)- {- message_.receive(handler);- }--private:- completion_message<Signature> message_;-};--#if defined(ASIO_HAS_STD_VARIANT)--template <typename... Signatures>-class completion_payload-{-public:- template <typename Signature>- completion_payload(completion_message<Signature>&& m)- : message_(static_cast<completion_message<Signature>&&>(m))- {- }-- template <typename Handler>- void receive(Handler& handler)- {- std::visit(- [&](auto& message)- {- message.receive(handler);- }, message_);- }--private:- std::variant<completion_message<Signatures>...> message_;-};--#else // defined(ASIO_HAS_STD_VARIANT)--template <typename R1, typename R2>-class completion_payload<R1(), R2(asio::error_code)>-{-public:- typedef completion_message<R1()> void_message_type;- typedef completion_message<R2(asio::error_code)> error_message_type;-- completion_payload(void_message_type&&)- : message_(0, asio::error_code()),- empty_(true)- {- }-- completion_payload(error_message_type&& m)- : message_(static_cast<error_message_type&&>(m)),- empty_(false)- {- }-- template <typename Handler>- void receive(Handler& handler)- {- if (empty_)- completion_message<R1()>(0).receive(handler);- else- message_.receive(handler);- }--private:- error_message_type message_;- bool empty_;-};--template <typename Sig1, typename Sig2>-class completion_payload<Sig1, Sig2>-{-public:- typedef completion_message<Sig1> message_1_type;- typedef completion_message<Sig2> message_2_type;-- completion_payload(message_1_type&& m)- : index_(1)- {- new (&storage_.message_1_) message_1_type(static_cast<message_1_type&&>(m));- }-- completion_payload(message_2_type&& m)- : index_(2)- {- new (&storage_.message_2_) message_2_type(static_cast<message_2_type&&>(m));- }-- completion_payload(completion_payload&& other)- : index_(other.index_)- {- switch (index_)- {- case 1:- new (&storage_.message_1_) message_1_type(- static_cast<message_1_type&&>(other.storage_.message_1_));- break;- case 2:- new (&storage_.message_2_) message_2_type(- static_cast<message_2_type&&>(other.storage_.message_2_));- break;- default:- break;- }- }-- ~completion_payload()- {- switch (index_)- {- case 1:- storage_.message_1_.~message_1_type();- break;- case 2:- storage_.message_2_.~message_2_type();- break;- default:- break;- }- }-- template <typename Handler>- void receive(Handler& handler)- {- switch (index_)- {- case 1:- storage_.message_1_.receive(handler);- break;- case 2:- storage_.message_2_.receive(handler);- break;- default:- break;- }- }--private:- union storage- {- storage() {}- ~storage() {}-- char dummy_;- message_1_type message_1_;- message_2_type message_2_;- } storage_;- unsigned char index_;-};--#endif // defined(ASIO_HAS_STD_VARIANT)--} // namespace detail-} // namespace asio--#include "asio/detail/pop_options.hpp"--#endif // ASIO_DETAIL_COMPLETION_PAYLOAD_HPP
− link/modules/asio-standalone/asio/include/asio/detail/completion_payload_handler.hpp
@@ -1,79 +0,0 @@-//-// detail/completion_payload_handler.hpp-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef ASIO_DETAIL_COMPLETION_PAYLOAD_HANDLER_HPP-#define ASIO_DETAIL_COMPLETION_PAYLOAD_HANDLER_HPP--#if defined(_MSC_VER) && (_MSC_VER >= 1200)-# pragma once-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)--#include "asio/detail/config.hpp"-#include "asio/associator.hpp"--#include "asio/detail/push_options.hpp"--namespace asio {-namespace detail {--template <typename Payload, typename Handler>-class completion_payload_handler-{-public:- completion_payload_handler(Payload&& p, Handler& h)- : payload_(static_cast<Payload&&>(p)),- handler_(static_cast<Handler&&>(h))- {- }-- void operator()()- {- payload_.receive(handler_);- }-- Handler& handler()- {- return handler_;- }--//private:- Payload payload_;- Handler handler_;-};--} // namespace detail--template <template <typename, typename> class Associator,- typename Payload, typename Handler, typename DefaultCandidate>-struct associator<Associator,- detail::completion_payload_handler<Payload, Handler>,- DefaultCandidate>- : Associator<Handler, DefaultCandidate>-{- static typename Associator<Handler, DefaultCandidate>::type get(- const detail::completion_payload_handler<Payload, Handler>& h) noexcept- {- return Associator<Handler, DefaultCandidate>::get(h.handler_);- }-- static auto get(- const detail::completion_payload_handler<Payload, Handler>& h,- const DefaultCandidate& c) noexcept- -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))- {- return Associator<Handler, DefaultCandidate>::get(h.handler_, c);- }-};--} // namespace asio--#include "asio/detail/pop_options.hpp"--#endif // ASIO_DETAIL_COMPLETION_PAYLOAD_HANDLER_HPP
link/modules/asio-standalone/asio/include/asio/detail/composed_work.hpp view
@@ -2,7 +2,7 @@ // detail/composed_work.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -17,6 +17,7 @@ #include "asio/detail/config.hpp" #include "asio/detail/type_traits.hpp"+#include "asio/detail/variadic_templates.hpp" #include "asio/execution/executor.hpp" #include "asio/execution/outstanding_work.hpp" #include "asio/executor_work_guard.hpp"@@ -32,9 +33,11 @@ class composed_work_guard { public:- typedef decay_t<- prefer_result_t<Executor, execution::outstanding_work_t::tracked_t>- > executor_type;+ typedef typename decay<+ typename prefer_result<Executor,+ execution::outstanding_work_t::tracked_t+ >::type+ >::type executor_type; composed_work_guard(const Executor& ex) : executor_(asio::prefer(ex, execution::outstanding_work.tracked))@@ -45,7 +48,7 @@ { } - executor_type get_executor() const noexcept+ executor_type get_executor() const ASIO_NOEXCEPT { return executor_; }@@ -68,7 +71,7 @@ { } - executor_type get_executor() const noexcept+ executor_type get_executor() const ASIO_NOEXCEPT { return system_executor(); }@@ -78,10 +81,9 @@ template <typename Executor> struct composed_work_guard<Executor,- enable_if_t<+ typename enable_if< !execution::is_executor<Executor>::value- >- > : executor_work_guard<Executor>+ >::type> : executor_work_guard<Executor> { composed_work_guard(const Executor& ex) : executor_work_guard<Executor>(ex)@@ -97,7 +99,7 @@ template <> struct composed_io_executors<void()> {- composed_io_executors() noexcept+ composed_io_executors() ASIO_NOEXCEPT : head_(system_executor()) { }@@ -114,7 +116,7 @@ template <typename Head> struct composed_io_executors<void(Head)> {- explicit composed_io_executors(const Head& ex) noexcept+ explicit composed_io_executors(const Head& ex) ASIO_NOEXCEPT : head_(ex) { }@@ -130,11 +132,13 @@ return composed_io_executors<void(Head)>(head); } +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+ template <typename Head, typename... Tail> struct composed_io_executors<void(Head, Tail...)> { explicit composed_io_executors(const Head& head,- const Tail&... tail) noexcept+ const Tail&... tail) ASIO_NOEXCEPT : head_(head), tail_(tail...) {@@ -158,6 +162,45 @@ return composed_io_executors<void(Head, Tail...)>(head, tail...); } +#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++#define ASIO_PRIVATE_COMPOSED_IO_EXECUTORS_DEF(n) \+template <typename Head, ASIO_VARIADIC_TPARAMS(n)> \+struct composed_io_executors<void(Head, ASIO_VARIADIC_TARGS(n))> \+{ \+ explicit composed_io_executors(const Head& head, \+ ASIO_VARIADIC_CONSTREF_PARAMS(n)) ASIO_NOEXCEPT \+ : head_(head), \+ tail_(ASIO_VARIADIC_BYVAL_ARGS(n)) \+ { \+ } \+\+ void reset() \+ { \+ head_.reset(); \+ tail_.reset(); \+ } \+\+ typedef Head head_type; \+ Head head_; \+ composed_io_executors<void(ASIO_VARIADIC_TARGS(n))> tail_; \+}; \+\+template <typename Head, ASIO_VARIADIC_TPARAMS(n)> \+inline composed_io_executors<void(Head, ASIO_VARIADIC_TARGS(n))> \+make_composed_io_executors(const Head& head, \+ ASIO_VARIADIC_CONSTREF_PARAMS(n)) \+{ \+ return composed_io_executors< \+ void(Head, ASIO_VARIADIC_TARGS(n))>( \+ head, ASIO_VARIADIC_BYVAL_ARGS(n)); \+} \+/**/+ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_COMPOSED_IO_EXECUTORS_DEF)+#undef ASIO_PRIVATE_COMPOSED_IO_EXECUTORS_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+ template <typename> struct composed_work; @@ -166,7 +209,7 @@ { typedef composed_io_executors<void()> executors_type; - composed_work(const executors_type&) noexcept+ composed_work(const executors_type&) ASIO_NOEXCEPT : head_(system_executor()) { }@@ -185,7 +228,7 @@ { typedef composed_io_executors<void(Head)> executors_type; - explicit composed_work(const executors_type& ex) noexcept+ explicit composed_work(const executors_type& ex) ASIO_NOEXCEPT : head_(ex.head_) { }@@ -199,12 +242,14 @@ composed_work_guard<Head> head_; }; +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+ template <typename Head, typename... Tail> struct composed_work<void(Head, Tail...)> { typedef composed_io_executors<void(Head, Tail...)> executors_type; - explicit composed_work(const executors_type& ex) noexcept+ explicit composed_work(const executors_type& ex) ASIO_NOEXCEPT : head_(ex.head_), tail_(ex.tail_) {@@ -221,25 +266,56 @@ composed_work<void(Tail...)> tail_; }; +#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++#define ASIO_PRIVATE_COMPOSED_WORK_DEF(n) \+template <typename Head, ASIO_VARIADIC_TPARAMS(n)> \+struct composed_work<void(Head, ASIO_VARIADIC_TARGS(n))> \+{ \+ typedef composed_io_executors<void(Head, \+ ASIO_VARIADIC_TARGS(n))> executors_type; \+\+ explicit composed_work(const executors_type& ex) ASIO_NOEXCEPT \+ : head_(ex.head_), \+ tail_(ex.tail_) \+ { \+ } \+\+ void reset() \+ { \+ head_.reset(); \+ tail_.reset(); \+ } \+\+ typedef Head head_type; \+ composed_work_guard<Head> head_; \+ composed_work<void(ASIO_VARIADIC_TARGS(n))> tail_; \+}; \+/**/+ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_COMPOSED_WORK_DEF)+#undef ASIO_PRIVATE_COMPOSED_WORK_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+ template <typename IoObject> inline typename IoObject::executor_type get_composed_io_executor(IoObject& io_object,- enable_if_t<+ typename enable_if< !is_executor<IoObject>::value- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< !execution::is_executor<IoObject>::value- >* = 0)+ >::type* = 0) { return io_object.get_executor(); } template <typename Executor> inline const Executor& get_composed_io_executor(const Executor& ex,- enable_if_t<+ typename enable_if< is_executor<Executor>::value || execution::is_executor<Executor>::value- >* = 0)+ >::type* = 0) { return ex; }
link/modules/asio-standalone/asio/include/asio/detail/concurrency_hint.hpp view
@@ -2,7 +2,7 @@ // detail/concurrency_hint.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/conditionally_enabled_event.hpp view
@@ -2,7 +2,7 @@ // detail/conditionally_enabled_event.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/conditionally_enabled_mutex.hpp view
@@ -2,7 +2,7 @@ // detail/conditionally_enabled_mutex.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -70,14 +70,6 @@ { if (mutex_.enabled_ && !locked_) {- for (int n = mutex_.spin_count_; n != 0; n -= (n > 0) ? 1 : 0)- {- if (mutex_.mutex_.try_lock())- {- locked_ = true;- return;- }- } mutex_.mutex_.lock(); locked_ = true; }@@ -112,9 +104,8 @@ }; // Constructor.- explicit conditionally_enabled_mutex(bool enabled, int spin_count = 0)- : spin_count_(spin_count),- enabled_(enabled)+ explicit conditionally_enabled_mutex(bool enabled)+ : enabled_(enabled) { } @@ -129,22 +120,11 @@ return enabled_; } - // Get the spin count.- int spin_count() const- {- return spin_count_;- }- // Lock the mutex. void lock() { if (enabled_)- {- for (int n = spin_count_; n != 0; n -= (n > 0) ? 1 : 0)- if (mutex_.try_lock())- return; mutex_.lock();- } } // Unlock the mutex.@@ -158,7 +138,6 @@ friend class scoped_lock; friend class conditionally_enabled_event; asio::detail::mutex mutex_;- const int spin_count_; const bool enabled_; };
link/modules/asio-standalone/asio/include/asio/detail/config.hpp view
@@ -2,1429 +2,2307 @@ // detail/config.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef ASIO_DETAIL_CONFIG_HPP-#define ASIO_DETAIL_CONFIG_HPP--// boostify: non-boost code starts here-#if !defined(ASIO_STANDALONE)-# if !defined(ASIO_ENABLE_BOOST)-# if (__cplusplus >= 201103)-# define ASIO_STANDALONE 1-# elif defined(_MSC_VER) && defined(_MSVC_LANG)-# if (_MSC_VER >= 1900) && (_MSVC_LANG >= 201103)-# define ASIO_STANDALONE 1-# endif // (_MSC_VER >= 1900) && (_MSVC_LANG >= 201103)-# endif // defined(_MSC_VER) && defined(_MSVC_LANG)-# endif // !defined(ASIO_ENABLE_BOOST)-#endif // !defined(ASIO_STANDALONE)--// Make standard library feature macros available.-#if defined(__has_include)-# if __has_include(<version>)-# include <version>-# else // __has_include(<version>)-# include <cstddef>-# endif // __has_include(<version>)-#else // defined(__has_include)-# include <cstddef>-#endif // defined(__has_include)--// boostify: non-boost code ends here-#if defined(ASIO_STANDALONE)-# define ASIO_DISABLE_BOOST_ALIGN 1-# define ASIO_DISABLE_BOOST_ARRAY 1-# define ASIO_DISABLE_BOOST_ASSERT 1-# define ASIO_DISABLE_BOOST_BIND 1-# define ASIO_DISABLE_BOOST_CHRONO 1-# define ASIO_DISABLE_BOOST_DATE_TIME 1-# define ASIO_DISABLE_BOOST_LIMITS 1-# define ASIO_DISABLE_BOOST_REGEX 1-# define ASIO_DISABLE_BOOST_STATIC_CONSTANT 1-# define ASIO_DISABLE_BOOST_THROW_EXCEPTION 1-# define ASIO_DISABLE_BOOST_WORKAROUND 1-#else // defined(ASIO_STANDALONE)-// Boost.Config library is available.-# include <boost/config.hpp>-# include <boost/version.hpp>-# define ASIO_HAS_BOOST_CONFIG 1-#endif // defined(ASIO_STANDALONE)--// Default to a header-only implementation. The user must specifically request-// separate compilation by defining either ASIO_SEPARATE_COMPILATION or-// ASIO_DYN_LINK (as a DLL/shared library implies separate compilation).-#if !defined(ASIO_HEADER_ONLY)-# if !defined(ASIO_SEPARATE_COMPILATION)-# if !defined(ASIO_DYN_LINK)-# define ASIO_HEADER_ONLY 1-# endif // !defined(ASIO_DYN_LINK)-# endif // !defined(ASIO_SEPARATE_COMPILATION)-#endif // !defined(ASIO_HEADER_ONLY)--#if defined(ASIO_HEADER_ONLY)-# define ASIO_DECL inline-#else // defined(ASIO_HEADER_ONLY)-# if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__CODEGEARC__)-// We need to import/export our code only if the user has specifically asked-// for it by defining ASIO_DYN_LINK.-# if defined(ASIO_DYN_LINK)-// Export if this is our own source, otherwise import.-# if defined(ASIO_SOURCE)-# define ASIO_DECL __declspec(dllexport)-# else // defined(ASIO_SOURCE)-# define ASIO_DECL __declspec(dllimport)-# endif // defined(ASIO_SOURCE)-# endif // defined(ASIO_DYN_LINK)-# endif // defined(_MSC_VER) || defined(__BORLANDC__) || defined(__CODEGEARC__)-#endif // defined(ASIO_HEADER_ONLY)--// If ASIO_DECL isn't defined yet define it now.-#if !defined(ASIO_DECL)-# define ASIO_DECL-#endif // !defined(ASIO_DECL)--// Helper macro for documentation.-#define ASIO_UNSPECIFIED(e) e--// Microsoft Visual C++ detection.-#if !defined(ASIO_MSVC)-# if defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_MSVC)-# define ASIO_MSVC BOOST_MSVC-# elif defined(_MSC_VER) && (defined(__INTELLISENSE__) \- || (!defined(__MWERKS__) && !defined(__EDG_VERSION__)))-# define ASIO_MSVC _MSC_VER-# endif // defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_MSVC)-#endif // !defined(ASIO_MSVC)--// Clang / libc++ detection.-#if defined(__clang__)-# if (__cplusplus >= 201103)-# if __has_include(<__config>)-# include <__config>-# if defined(_LIBCPP_VERSION)-# define ASIO_HAS_CLANG_LIBCXX 1-# endif // defined(_LIBCPP_VERSION)-# endif // __has_include(<__config>)-# endif // (__cplusplus >= 201103)-#endif // defined(__clang__)--// Android platform detection.-#if defined(__ANDROID__)-# include <android/api-level.h>-#endif // defined(__ANDROID__)--// Always enabled. Retained for backwards compatibility in user code.-#if !defined(ASIO_DISABLE_CXX11_MACROS)-# define ASIO_HAS_MOVE 1-# define ASIO_MOVE_ARG(type) type&&-# define ASIO_MOVE_ARG2(type1, type2) type1, type2&&-# define ASIO_NONDEDUCED_MOVE_ARG(type) type&-# define ASIO_MOVE_CAST(type) static_cast<type&&>-# define ASIO_MOVE_CAST2(type1, type2) static_cast<type1, type2&&>-# define ASIO_MOVE_OR_LVALUE(type) static_cast<type&&>-# define ASIO_MOVE_OR_LVALUE_ARG(type) type&&-# define ASIO_MOVE_OR_LVALUE_TYPE(type) type-# define ASIO_DELETED = delete-# define ASIO_HAS_VARIADIC_TEMPLATES 1-# define ASIO_HAS_CONSTEXPR 1-# define ASIO_STATIC_CONSTEXPR(type, assignment) \- static constexpr type assignment-# define ASIO_HAS_NOEXCEPT 1-# define ASIO_NOEXCEPT noexcept(true)-# define ASIO_NOEXCEPT_OR_NOTHROW noexcept(true)-# define ASIO_NOEXCEPT_IF(c) noexcept(c)-# define ASIO_HAS_DECLTYPE 1-# define ASIO_AUTO_RETURN_TYPE_PREFIX(t) auto-# define ASIO_AUTO_RETURN_TYPE_PREFIX2(t0, t1) auto-# define ASIO_AUTO_RETURN_TYPE_PREFIX3(t0, t1, t2) auto-# define ASIO_AUTO_RETURN_TYPE_SUFFIX(expr) -> decltype expr-# define ASIO_HAS_ALIAS_TEMPLATES 1-# define ASIO_HAS_DEFAULT_FUNCTION_TEMPLATE_ARGUMENTS 1-# define ASIO_HAS_ENUM_CLASS 1-# define ASIO_HAS_REF_QUALIFIED_FUNCTIONS 1-# define ASIO_LVALUE_REF_QUAL &-# define ASIO_RVALUE_REF_QUAL &&-# define ASIO_HAS_USER_DEFINED_LITERALS 1-# define ASIO_HAS_ALIGNOF 1-# define ASIO_ALIGNOF(T) alignof(T)-# define ASIO_HAS_STD_ALIGN 1-# define ASIO_HAS_STD_SYSTEM_ERROR 1-# define ASIO_ERROR_CATEGORY_NOEXCEPT noexcept(true)-# define ASIO_HAS_STD_ARRAY 1-# define ASIO_HAS_STD_SHARED_PTR 1-# define ASIO_HAS_STD_ALLOCATOR_ARG 1-# define ASIO_HAS_STD_ATOMIC 1-# define ASIO_HAS_STD_CHRONO 1-# define ASIO_HAS_STD_ADDRESSOF 1-# define ASIO_HAS_STD_FUNCTION 1-# define ASIO_HAS_STD_REFERENCE_WRAPPER 1-# define ASIO_HAS_STD_TYPE_TRAITS 1-# define ASIO_HAS_NULLPTR 1-# define ASIO_HAS_CXX11_ALLOCATORS 1-# define ASIO_HAS_CSTDINT 1-# define ASIO_HAS_STD_THREAD 1-# define ASIO_HAS_STD_MUTEX_AND_CONDVAR 1-# define ASIO_HAS_STD_CALL_ONCE 1-# define ASIO_HAS_STD_FUTURE 1-# define ASIO_HAS_STD_TUPLE 1-# define ASIO_HAS_STD_IOSTREAM_MOVE 1-# define ASIO_HAS_STD_EXCEPTION_PTR 1-# define ASIO_HAS_STD_NESTED_EXCEPTION 1-# define ASIO_HAS_STD_HASH 1-#endif // !defined(ASIO_DISABLE_CXX11_MACROS)--// Support for static constexpr with default initialisation.-#if !defined(ASIO_STATIC_CONSTEXPR_DEFAULT_INIT)-# if defined(__GNUC__)-# if (__GNUC__ >= 8)-# define ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(type, name) \- static constexpr const type name{}-# else // (__GNUC__ >= 8)-# define ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(type, name) \- static const type name-# endif // (__GNUC__ >= 8)-# elif defined(ASIO_MSVC)-# define ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(type, name) \- static const type name-# else // defined(ASIO_MSVC)-# define ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(type, name) \- static constexpr const type name{}-# endif // defined(ASIO_MSVC)-#endif // !defined(ASIO_STATIC_CONSTEXPR_DEFAULT_INIT)--// Support noexcept on function types on compilers known to allow it.-#if !defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)-# if !defined(ASIO_DISABLE_NOEXCEPT_FUNCTION_TYPE)-# if defined(__clang__)-# if (__cplusplus >= 202002)-# define ASIO_HAS_NOEXCEPT_FUNCTION_TYPE 1-# endif // (__cplusplus >= 202002)-# elif defined(__GNUC__)-# if (__cplusplus >= 202002)-# define ASIO_HAS_NOEXCEPT_FUNCTION_TYPE 1-# endif // (__cplusplus >= 202002)-# elif defined(ASIO_MSVC)-# if (_MSC_VER >= 1900 && _MSVC_LANG >= 202002)-# define ASIO_HAS_NOEXCEPT_FUNCTION_TYPE 1-# endif // (_MSC_VER >= 1900 && _MSVC_LANG >= 202002)-# endif // defined(ASIO_MSVC)-# endif // !defined(ASIO_DISABLE_NOEXCEPT_FUNCTION_TYPE)-#endif // !defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)--// Support return type deduction on compilers known to allow it.-#if !defined(ASIO_HAS_RETURN_TYPE_DEDUCTION)-# if !defined(ASIO_DISABLE_RETURN_TYPE_DEDUCTION)-# if defined(__clang__)-# if __has_feature(__cxx_return_type_deduction__)-# define ASIO_HAS_RETURN_TYPE_DEDUCTION 1-# endif // __has_feature(__cxx_return_type_deduction__)-# elif (__cplusplus >= 201402)-# define ASIO_HAS_RETURN_TYPE_DEDUCTION 1-# elif defined(__cpp_return_type_deduction)-# if (__cpp_return_type_deduction >= 201304)-# define ASIO_HAS_RETURN_TYPE_DEDUCTION 1-# endif // (__cpp_return_type_deduction >= 201304)-# elif defined(ASIO_MSVC)-# if (_MSC_VER >= 1900 && _MSVC_LANG >= 201402)-# define ASIO_HAS_RETURN_TYPE_DEDUCTION 1-# endif // (_MSC_VER >= 1900 && _MSVC_LANG >= 201402)-# endif // defined(ASIO_MSVC)-# endif // !defined(ASIO_DISABLE_RETURN_TYPE_DEDUCTION)-#endif // !defined(ASIO_HAS_RETURN_TYPE_DEDUCTION)--// Support concepts on compilers known to allow them.-#if !defined(ASIO_HAS_CONCEPTS)-# if !defined(ASIO_DISABLE_CONCEPTS)-# if defined(__cpp_concepts)-# define ASIO_HAS_CONCEPTS 1-# if (__cpp_concepts >= 201707)-# define ASIO_CONCEPT concept-# else // (__cpp_concepts >= 201707)-# define ASIO_CONCEPT concept bool-# endif // (__cpp_concepts >= 201707)-# endif // defined(__cpp_concepts)-# endif // !defined(ASIO_DISABLE_CONCEPTS)-#endif // !defined(ASIO_HAS_CONCEPTS)--// Support concepts on compilers known to allow them.-#if !defined(ASIO_HAS_STD_CONCEPTS)-# if !defined(ASIO_DISABLE_STD_CONCEPTS)-# if defined(ASIO_HAS_CONCEPTS)-# if (__cpp_lib_concepts >= 202002L)-# define ASIO_HAS_STD_CONCEPTS 1-# endif // (__cpp_concepts >= 202002L)-# endif // defined(ASIO_HAS_CONCEPTS)-# endif // !defined(ASIO_DISABLE_STD_CONCEPTS)-#endif // !defined(ASIO_HAS_STD_CONCEPTS)--// Support template variables on compilers known to allow it.-#if !defined(ASIO_HAS_VARIABLE_TEMPLATES)-# if !defined(ASIO_DISABLE_VARIABLE_TEMPLATES)-# if defined(__clang__)-# if (__cplusplus >= 201402)-# if __has_feature(__cxx_variable_templates__)-# define ASIO_HAS_VARIABLE_TEMPLATES 1-# endif // __has_feature(__cxx_variable_templates__)-# endif // (__cplusplus >= 201402)-# elif defined(__GNUC__) && !defined(__INTEL_COMPILER)-# if (__GNUC__ >= 6)-# if (__cplusplus >= 201402)-# define ASIO_HAS_VARIABLE_TEMPLATES 1-# endif // (__cplusplus >= 201402)-# endif // (__GNUC__ >= 6)-# endif // defined(__GNUC__) && !defined(__INTEL_COMPILER)-# if defined(ASIO_MSVC)-# if (_MSC_VER >= 1901)-# define ASIO_HAS_VARIABLE_TEMPLATES 1-# endif // (_MSC_VER >= 1901)-# endif // defined(ASIO_MSVC)-# endif // !defined(ASIO_DISABLE_VARIABLE_TEMPLATES)-#endif // !defined(ASIO_HAS_VARIABLE_TEMPLATES)--// Support SFINAEd template variables on compilers known to allow it.-#if !defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)-# if !defined(ASIO_DISABLE_SFINAE_VARIABLE_TEMPLATES)-# if defined(__clang__)-# if (__cplusplus >= 201703)-# if __has_feature(__cxx_variable_templates__)-# define ASIO_HAS_SFINAE_VARIABLE_TEMPLATES 1-# endif // __has_feature(__cxx_variable_templates__)-# endif // (__cplusplus >= 201703)-# elif defined(__GNUC__)-# if ((__GNUC__ == 8) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 8)-# if (__cplusplus >= 201402)-# define ASIO_HAS_SFINAE_VARIABLE_TEMPLATES 1-# endif // (__cplusplus >= 201402)-# endif // ((__GNUC__ == 8) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 8)-# endif // defined(__GNUC__)-# if defined(ASIO_MSVC)-# if (_MSC_VER >= 1901)-# define ASIO_HAS_SFINAE_VARIABLE_TEMPLATES 1-# endif // (_MSC_VER >= 1901)-# endif // defined(ASIO_MSVC)-# endif // !defined(ASIO_DISABLE_SFINAE_VARIABLE_TEMPLATES)-#endif // !defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)--// Support SFINAE use of constant expressions on compilers known to allow it.-#if !defined(ASIO_HAS_CONSTANT_EXPRESSION_SFINAE)-# if !defined(ASIO_DISABLE_CONSTANT_EXPRESSION_SFINAE)-# if defined(__clang__)-# if (__cplusplus >= 201402)-# define ASIO_HAS_CONSTANT_EXPRESSION_SFINAE 1-# endif // (__cplusplus >= 201402)-# elif defined(__GNUC__) && !defined(__INTEL_COMPILER)-# if (__GNUC__ >= 7)-# if (__cplusplus >= 201402)-# define ASIO_HAS_CONSTANT_EXPRESSION_SFINAE 1-# endif // (__cplusplus >= 201402)-# endif // (__GNUC__ >= 7)-# endif // defined(__GNUC__) && !defined(__INTEL_COMPILER)-# if defined(ASIO_MSVC)-# if (_MSC_VER >= 1901)-# define ASIO_HAS_CONSTANT_EXPRESSION_SFINAE 1-# endif // (_MSC_VER >= 1901)-# endif // defined(ASIO_MSVC)-# endif // !defined(ASIO_DISABLE_CONSTANT_EXPRESSION_SFINAE)-#endif // !defined(ASIO_HAS_CONSTANT_EXPRESSION_SFINAE)--// Enable workarounds for lack of working expression SFINAE.-#if !defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)-# if !defined(ASIO_DISABLE_WORKING_EXPRESSION_SFINAE)-# if !defined(ASIO_MSVC) && !defined(__INTEL_COMPILER)-# if (__cplusplus >= 201103)-# define ASIO_HAS_WORKING_EXPRESSION_SFINAE 1-# endif // (__cplusplus >= 201103)-# elif defined(ASIO_MSVC) && (_MSC_VER >= 1929)-# if (_MSVC_LANG >= 202000)-# define ASIO_HAS_WORKING_EXPRESSION_SFINAE 1-# endif // (_MSVC_LANG >= 202000)-# endif // defined(ASIO_MSVC) && (_MSC_VER >= 1929)-# endif // !defined(ASIO_DISABLE_WORKING_EXPRESSION_SFINAE)-#endif // !defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)--// Support for capturing parameter packs in lambdas.-#if !defined(ASIO_HAS_VARIADIC_LAMBDA_CAPTURES)-# if !defined(ASIO_DISABLE_VARIADIC_LAMBDA_CAPTURES)-# if defined(__GNUC__)-# if (__GNUC__ >= 6)-# define ASIO_HAS_VARIADIC_LAMBDA_CAPTURES 1-# endif // (__GNUC__ >= 6)-# elif defined(ASIO_MSVC)-# if (_MSVC_LANG >= 201103)-# define ASIO_HAS_VARIADIC_LAMBDA_CAPTURES 1-# endif // (_MSC_LANG >= 201103)-# else // defined(ASIO_MSVC)-# if (__cplusplus >= 201103)-# define ASIO_HAS_VARIADIC_LAMBDA_CAPTURES 1-# endif // (__cplusplus >= 201103)-# endif // defined(ASIO_MSVC)-# endif // !defined(ASIO_DISABLE_VARIADIC_LAMBDA_CAPTURES)-#endif // !defined(ASIO_HAS_VARIADIC_LAMBDA_CAPTURES)--// Support for inline variables.-#if !defined(ASIO_HAS_INLINE_VARIABLES)-# if !defined(ASIO_DISABLE_INLINE_VARIABLES)-# if (__cplusplus >= 201703) && (__cpp_inline_variables >= 201606)-# define ASIO_HAS_INLINE_VARIABLES 1-# define ASIO_INLINE_VARIABLE inline-# endif // (__cplusplus >= 201703) && (__cpp_inline_variables >= 201606)-# endif // !defined(ASIO_DISABLE_INLINE_VARIABLES)-#endif // !defined(ASIO_HAS_INLINE_VARIABLES)-#if !defined(ASIO_INLINE_VARIABLE)-# define ASIO_INLINE_VARIABLE-#endif // !defined(ASIO_INLINE_VARIABLE)--// Default alignment.-#if defined(__STDCPP_DEFAULT_NEW_ALIGNMENT__)-# define ASIO_DEFAULT_ALIGN __STDCPP_DEFAULT_NEW_ALIGNMENT__-#elif defined(__GNUC__)-# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)) || (__GNUC__ > 4)-# define ASIO_DEFAULT_ALIGN alignof(std::max_align_t)-# else // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)) || (__GNUC__ > 4)-# define ASIO_DEFAULT_ALIGN alignof(max_align_t)-# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)) || (__GNUC__ > 4)-#else // defined(__GNUC__)-# define ASIO_DEFAULT_ALIGN alignof(std::max_align_t)-#endif // defined(__GNUC__)--// Standard library support for aligned allocation.-#if !defined(ASIO_HAS_STD_ALIGNED_ALLOC)-# if !defined(ASIO_DISABLE_STD_ALIGNED_ALLOC)-# if (__cplusplus >= 201703)-# if defined(__clang__)-# if defined(ASIO_HAS_CLANG_LIBCXX)-# if (_LIBCPP_STD_VER > 14) && defined(_LIBCPP_HAS_ALIGNED_ALLOC) \- && !defined(_LIBCPP_MSVCRT) && !defined(__MINGW32__)-# if defined(__ANDROID__) && (__ANDROID_API__ >= 28)-# define ASIO_HAS_STD_ALIGNED_ALLOC 1-# elif defined(__APPLE__)-# if defined(__MAC_OS_X_VERSION_MIN_REQUIRED)-# if (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101500)-# define ASIO_HAS_STD_ALIGNED_ALLOC 1-# endif // (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101500)-# elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED)-# if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 130000)-# define ASIO_HAS_STD_ALIGNED_ALLOC 1-# endif // (__IPHONE_OS_VERSION_MIN_REQUIRED >= 130000)-# elif defined(__TV_OS_VERSION_MIN_REQUIRED)-# if (__TV_OS_VERSION_MIN_REQUIRED >= 130000)-# define ASIO_HAS_STD_ALIGNED_ALLOC 1-# endif // (__TV_OS_VERSION_MIN_REQUIRED >= 130000)-# elif defined(__WATCH_OS_VERSION_MIN_REQUIRED)-# if (__WATCH_OS_VERSION_MIN_REQUIRED >= 60000)-# define ASIO_HAS_STD_ALIGNED_ALLOC 1-# endif // (__WATCH_OS_VERSION_MIN_REQUIRED >= 60000)-# endif // defined(__WATCH_OS_X_VERSION_MIN_REQUIRED)-# else // defined(__APPLE__)-# define ASIO_HAS_STD_ALIGNED_ALLOC 1-# endif // defined(__APPLE__)-# endif // (_LIBCPP_STD_VER > 14) && defined(_LIBCPP_HAS_ALIGNED_ALLOC)- // && !defined(_LIBCPP_MSVCRT) && !defined(__MINGW32__)-# elif defined(_GLIBCXX_HAVE_ALIGNED_ALLOC)-# define ASIO_HAS_STD_ALIGNED_ALLOC 1-# endif // defined(_GLIBCXX_HAVE_ALIGNED_ALLOC)-# elif defined(__GNUC__)-# if ((__GNUC__ == 7) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 7)-# if defined(_GLIBCXX_HAVE_ALIGNED_ALLOC)-# define ASIO_HAS_STD_ALIGNED_ALLOC 1-# endif // defined(_GLIBCXX_HAVE_ALIGNED_ALLOC)-# endif // ((__GNUC__ == 7) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 7)-# endif // defined(__GNUC__)-# endif // (__cplusplus >= 201703)-# endif // !defined(ASIO_DISABLE_STD_ALIGNED_ALLOC)-#endif // !defined(ASIO_HAS_STD_ALIGNED_ALLOC)--// Boost support for chrono.-#if !defined(ASIO_HAS_BOOST_CHRONO)-# if !defined(ASIO_DISABLE_BOOST_CHRONO)-# if defined(ASIO_HAS_BOOST_CONFIG) && (BOOST_VERSION >= 104700)-# define ASIO_HAS_BOOST_CHRONO 1-# endif // defined(ASIO_HAS_BOOST_CONFIG) && (BOOST_VERSION >= 104700)-# endif // !defined(ASIO_DISABLE_BOOST_CHRONO)-#endif // !defined(ASIO_HAS_BOOST_CHRONO)--// Some form of chrono library is available.-#if !defined(ASIO_HAS_CHRONO)-# if defined(ASIO_HAS_STD_CHRONO) \- || defined(ASIO_HAS_BOOST_CHRONO)-# define ASIO_HAS_CHRONO 1-# endif // defined(ASIO_HAS_STD_CHRONO)- // || defined(ASIO_HAS_BOOST_CHRONO)-#endif // !defined(ASIO_HAS_CHRONO)--// Boost support for the DateTime library.-#if !defined(ASIO_HAS_BOOST_DATE_TIME)-# if !defined(ASIO_DISABLE_BOOST_DATE_TIME)-# define ASIO_HAS_BOOST_DATE_TIME 1-# endif // !defined(ASIO_DISABLE_BOOST_DATE_TIME)-#endif // !defined(ASIO_HAS_BOOST_DATE_TIME)--// Boost support for the Context library's fibers.-#if !defined(ASIO_HAS_BOOST_CONTEXT_FIBER)-# if !defined(ASIO_DISABLE_BOOST_CONTEXT_FIBER)-# if defined(__clang__)-# if (__cplusplus >= 201103)-# define ASIO_HAS_BOOST_CONTEXT_FIBER 1-# endif // (__cplusplus >= 201103)-# elif defined(__GNUC__)-# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4)-# if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)-# define ASIO_HAS_BOOST_CONTEXT_FIBER 1-# endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)-# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4)-# endif // defined(__GNUC__)-# if defined(ASIO_MSVC)-# if (_MSVC_LANG >= 201103)-# define ASIO_HAS_BOOST_CONTEXT_FIBER 1-# endif // (_MSC_LANG >= 201103)-# endif // defined(ASIO_MSVC)-# endif // !defined(ASIO_DISABLE_BOOST_CONTEXT_FIBER)-#endif // !defined(ASIO_HAS_BOOST_CONTEXT_FIBER)--// Standard library support for std::string_view.-#if !defined(ASIO_HAS_STD_STRING_VIEW)-# if !defined(ASIO_DISABLE_STD_STRING_VIEW)-# if defined(__clang__)-# if defined(ASIO_HAS_CLANG_LIBCXX)-# if (__cplusplus >= 201402)-# if __has_include(<string_view>)-# define ASIO_HAS_STD_STRING_VIEW 1-# endif // __has_include(<string_view>)-# endif // (__cplusplus >= 201402)-# else // defined(ASIO_HAS_CLANG_LIBCXX)-# if (__cplusplus >= 201703)-# if __has_include(<string_view>)-# define ASIO_HAS_STD_STRING_VIEW 1-# endif // __has_include(<string_view>)-# endif // (__cplusplus >= 201703)-# endif // defined(ASIO_HAS_CLANG_LIBCXX)-# elif defined(__GNUC__)-# if (__GNUC__ >= 7)-# if (__cplusplus >= 201703)-# define ASIO_HAS_STD_STRING_VIEW 1-# endif // (__cplusplus >= 201703)-# endif // (__GNUC__ >= 7)-# elif defined(ASIO_MSVC)-# if (_MSC_VER >= 1910 && _MSVC_LANG >= 201703)-# define ASIO_HAS_STD_STRING_VIEW 1-# endif // (_MSC_VER >= 1910 && _MSVC_LANG >= 201703)-# endif // defined(ASIO_MSVC)-# endif // !defined(ASIO_DISABLE_STD_STRING_VIEW)-#endif // !defined(ASIO_HAS_STD_STRING_VIEW)--// Standard library support for std::experimental::string_view.-#if !defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW)-# if !defined(ASIO_DISABLE_STD_EXPERIMENTAL_STRING_VIEW)-# if defined(__clang__)-# if defined(ASIO_HAS_CLANG_LIBCXX)-# if (_LIBCPP_VERSION < 7000)-# if (__cplusplus >= 201402)-# if __has_include(<experimental/string_view>)-# define ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW 1-# endif // __has_include(<experimental/string_view>)-# endif // (__cplusplus >= 201402)-# endif // (_LIBCPP_VERSION < 7000)-# else // defined(ASIO_HAS_CLANG_LIBCXX)-# if (__cplusplus >= 201402)-# if __has_include(<experimental/string_view>)-# define ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW 1-# endif // __has_include(<experimental/string_view>)-# endif // (__cplusplus >= 201402)-# endif // // defined(ASIO_HAS_CLANG_LIBCXX)-# elif defined(__GNUC__)-# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)) || (__GNUC__ > 4)-# if (__cplusplus >= 201402)-# define ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW 1-# endif // (__cplusplus >= 201402)-# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)) || (__GNUC__ > 4)-# endif // defined(__GNUC__)-# endif // !defined(ASIO_DISABLE_STD_EXPERIMENTAL_STRING_VIEW)-#endif // !defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW)--// Standard library has a string_view that we can use.-#if !defined(ASIO_HAS_STRING_VIEW)-# if !defined(ASIO_DISABLE_STRING_VIEW)-# if defined(ASIO_HAS_STD_STRING_VIEW)-# define ASIO_HAS_STRING_VIEW 1-# elif defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW)-# define ASIO_HAS_STRING_VIEW 1-# endif // defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW)-# endif // !defined(ASIO_DISABLE_STRING_VIEW)-#endif // !defined(ASIO_HAS_STRING_VIEW)--// Standard library has invoke_result (which supersedes result_of).-#if !defined(ASIO_HAS_STD_INVOKE_RESULT)-# if !defined(ASIO_DISABLE_STD_INVOKE_RESULT)-# if defined(ASIO_MSVC)-# if (_MSC_VER >= 1911 && _MSVC_LANG >= 201703)-# define ASIO_HAS_STD_INVOKE_RESULT 1-# endif // (_MSC_VER >= 1911 && _MSVC_LANG >= 201703)-# else // defined(ASIO_MSVC)-# if (__cplusplus >= 201703) && (__cpp_lib_is_invocable >= 201703)-# define ASIO_HAS_STD_INVOKE_RESULT 1-# endif // (__cplusplus >= 201703) && (__cpp_lib_is_invocable >= 201703)-# endif // defined(ASIO_MSVC)-# endif // !defined(ASIO_DISABLE_STD_INVOKE_RESULT)-#endif // !defined(ASIO_HAS_STD_INVOKE_RESULT)--// Standard library support for std::any.-#if !defined(ASIO_HAS_STD_ANY)-# if !defined(ASIO_DISABLE_STD_ANY)-# if defined(__clang__)-# if (__cplusplus >= 201703)-# if __has_include(<any>)-# define ASIO_HAS_STD_ANY 1-# endif // __has_include(<any>)-# endif // (__cplusplus >= 201703)-# elif defined(__GNUC__)-# if (__GNUC__ >= 7)-# if (__cplusplus >= 201703)-# define ASIO_HAS_STD_ANY 1-# endif // (__cplusplus >= 201703)-# endif // (__GNUC__ >= 7)-# endif // defined(__GNUC__)-# if defined(ASIO_MSVC)-# if (_MSC_VER >= 1910) && (_MSVC_LANG >= 201703)-# define ASIO_HAS_STD_ANY 1-# endif // (_MSC_VER >= 1910) && (_MSVC_LANG >= 201703)-# endif // defined(ASIO_MSVC)-# endif // !defined(ASIO_DISABLE_STD_ANY)-#endif // !defined(ASIO_HAS_STD_ANY)--// Standard library support for std::variant.-#if !defined(ASIO_HAS_STD_VARIANT)-# if !defined(ASIO_DISABLE_STD_VARIANT)-# if defined(__clang__)-# if (__cplusplus >= 201703)-# if __has_include(<variant>)-# define ASIO_HAS_STD_VARIANT 1-# endif // __has_include(<variant>)-# endif // (__cplusplus >= 201703)-# elif defined(__GNUC__)-# if (__GNUC__ >= 7)-# if (__cplusplus >= 201703)-# define ASIO_HAS_STD_VARIANT 1-# endif // (__cplusplus >= 201703)-# endif // (__GNUC__ >= 7)-# endif // defined(__GNUC__)-# if defined(ASIO_MSVC)-# if (_MSC_VER >= 1910) && (_MSVC_LANG >= 201703)-# define ASIO_HAS_STD_VARIANT 1-# endif // (_MSC_VER >= 1910) && (_MSVC_LANG >= 201703)-# endif // defined(ASIO_MSVC)-# endif // !defined(ASIO_DISABLE_STD_VARIANT)-#endif // !defined(ASIO_HAS_STD_VARIANT)--// Standard library support for std::source_location.-#if !defined(ASIO_HAS_STD_SOURCE_LOCATION)-# if !defined(ASIO_DISABLE_STD_SOURCE_LOCATION)-// ...-# endif // !defined(ASIO_DISABLE_STD_SOURCE_LOCATION)-#endif // !defined(ASIO_HAS_STD_SOURCE_LOCATION)--// Standard library support for std::experimental::source_location.-#if !defined(ASIO_HAS_STD_EXPERIMENTAL_SOURCE_LOCATION)-# if !defined(ASIO_DISABLE_STD_EXPERIMENTAL_SOURCE_LOCATION)-# if defined(__GNUC__)-# if (__cplusplus >= 201709)-# if __has_include(<experimental/source_location>)-# define ASIO_HAS_STD_EXPERIMENTAL_SOURCE_LOCATION 1-# endif // __has_include(<experimental/source_location>)-# endif // (__cplusplus >= 201709)-# endif // defined(__GNUC__)-# endif // !defined(ASIO_DISABLE_STD_EXPERIMENTAL_SOURCE_LOCATION)-#endif // !defined(ASIO_HAS_STD_EXPERIMENTAL_SOURCE_LOCATION)--// Standard library has a source_location that we can use.-#if !defined(ASIO_HAS_SOURCE_LOCATION)-# if !defined(ASIO_DISABLE_SOURCE_LOCATION)-# if defined(ASIO_HAS_STD_SOURCE_LOCATION)-# define ASIO_HAS_SOURCE_LOCATION 1-# elif defined(ASIO_HAS_STD_EXPERIMENTAL_SOURCE_LOCATION)-# define ASIO_HAS_SOURCE_LOCATION 1-# endif // defined(ASIO_HAS_STD_EXPERIMENTAL_SOURCE_LOCATION)-# endif // !defined(ASIO_DISABLE_SOURCE_LOCATION)-#endif // !defined(ASIO_HAS_SOURCE_LOCATION)--// Boost support for source_location and system errors.-#if !defined(ASIO_HAS_BOOST_SOURCE_LOCATION)-# if !defined(ASIO_DISABLE_BOOST_SOURCE_LOCATION)-# if defined(ASIO_HAS_BOOST_CONFIG) && (BOOST_VERSION >= 107900)-# define ASIO_HAS_BOOST_SOURCE_LOCATION 1-# endif // defined(ASIO_HAS_BOOST_CONFIG) && (BOOST_VERSION >= 107900)-# endif // !defined(ASIO_DISABLE_BOOST_SOURCE_LOCATION)-#endif // !defined(ASIO_HAS_BOOST_SOURCE_LOCATION)--// Helper macros for working with Boost source locations.-#if defined(ASIO_HAS_BOOST_SOURCE_LOCATION)-# define ASIO_SOURCE_LOCATION_PARAM \- , const boost::source_location& loc-# define ASIO_SOURCE_LOCATION_DEFAULTED_PARAM \- , const boost::source_location& loc = BOOST_CURRENT_LOCATION-# define ASIO_SOURCE_LOCATION_ARG , loc-#else // if defined(ASIO_HAS_BOOST_SOURCE_LOCATION)-# define ASIO_SOURCE_LOCATION_PARAM-# define ASIO_SOURCE_LOCATION_DEFAULTED_PARAM-# define ASIO_SOURCE_LOCATION_ARG-#endif // if defined(ASIO_HAS_BOOST_SOURCE_LOCATION)--// Standard library support for std::index_sequence.-#if !defined(ASIO_HAS_STD_INDEX_SEQUENCE)-# if !defined(ASIO_DISABLE_STD_INDEX_SEQUENCE)-# if defined(__clang__)-# if (__cplusplus >= 201402)-# define ASIO_HAS_STD_INDEX_SEQUENCE 1-# endif // (__cplusplus >= 201402)-# elif defined(__GNUC__)-# if (__GNUC__ >= 7)-# if (__cplusplus >= 201402)-# define ASIO_HAS_STD_INDEX_SEQUENCE 1-# endif // (__cplusplus >= 201402)-# endif // (__GNUC__ >= 7)-# endif // defined(__GNUC__)-# if defined(ASIO_MSVC)-# if (_MSC_VER >= 1910) && (_MSVC_LANG >= 201402)-# define ASIO_HAS_STD_INDEX_SEQUENCE 1-# endif // (_MSC_VER >= 1910) && (_MSVC_LANG >= 201402)-# endif // defined(ASIO_MSVC)-# endif // !defined(ASIO_DISABLE_STD_INDEX_SEQUENCE)-#endif // !defined(ASIO_HAS_STD_INDEX_SEQUENCE)--// Windows App target. Windows but with a limited API.-#if !defined(ASIO_WINDOWS_APP)-# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0603)-# include <winapifamily.h>-# if (WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) \- || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_TV_TITLE)) \- && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)-# define ASIO_WINDOWS_APP 1-# endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)- // && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)-# endif // defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0603)-#endif // !defined(ASIO_WINDOWS_APP)--// Legacy WinRT target. Windows App is preferred.-#if !defined(ASIO_WINDOWS_RUNTIME)-# if !defined(ASIO_WINDOWS_APP)-# if defined(__cplusplus_winrt)-# include <winapifamily.h>-# if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) \- && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)-# define ASIO_WINDOWS_RUNTIME 1-# endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)- // && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)-# endif // defined(__cplusplus_winrt)-# endif // !defined(ASIO_WINDOWS_APP)-#endif // !defined(ASIO_WINDOWS_RUNTIME)--// Windows target. Excludes WinRT but includes Windows App targets.-#if !defined(ASIO_WINDOWS)-# if !defined(ASIO_WINDOWS_RUNTIME)-# if defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_WINDOWS)-# define ASIO_WINDOWS 1-# elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__)-# define ASIO_WINDOWS 1-# elif defined(ASIO_WINDOWS_APP)-# define ASIO_WINDOWS 1-# endif // defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_WINDOWS)-# endif // !defined(ASIO_WINDOWS_RUNTIME)-#endif // !defined(ASIO_WINDOWS)--// Windows: target OS version.-#if defined(ASIO_WINDOWS) || defined(__CYGWIN__)-# if !defined(_WIN32_WINNT) && !defined(_WIN32_WINDOWS)-# if defined(_MSC_VER) || (defined(__BORLANDC__) && !defined(__clang__))-# pragma message( \- "Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately. For example:\n"\- "- add -D_WIN32_WINNT=0x0601 to the compiler command line; or\n"\- "- add _WIN32_WINNT=0x0601 to your project's Preprocessor Definitions.\n"\- "Assuming _WIN32_WINNT=0x0601 (i.e. Windows 7 target).")-# else // defined(_MSC_VER) || (defined(__BORLANDC__) && !defined(__clang__))-# warning Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately.-# warning For example, add -D_WIN32_WINNT=0x0601 to the compiler command line.-# warning Assuming _WIN32_WINNT=0x0601 (i.e. Windows 7 target).-# endif // defined(_MSC_VER) || (defined(__BORLANDC__) && !defined(__clang__))-# define _WIN32_WINNT 0x0601-# endif // !defined(_WIN32_WINNT) && !defined(_WIN32_WINDOWS)-# if defined(_MSC_VER)-# if defined(_WIN32) && !defined(WIN32)-# if !defined(_WINSOCK2API_)-# define WIN32 // Needed for correct types in winsock2.h-# else // !defined(_WINSOCK2API_)-# error Please define the macro WIN32 in your compiler options-# endif // !defined(_WINSOCK2API_)-# endif // defined(_WIN32) && !defined(WIN32)-# endif // defined(_MSC_VER)-# if defined(__BORLANDC__)-# if defined(__WIN32__) && !defined(WIN32)-# if !defined(_WINSOCK2API_)-# define WIN32 // Needed for correct types in winsock2.h-# else // !defined(_WINSOCK2API_)-# error Please define the macro WIN32 in your compiler options-# endif // !defined(_WINSOCK2API_)-# endif // defined(__WIN32__) && !defined(WIN32)-# endif // defined(__BORLANDC__)-# if defined(__CYGWIN__)-# if !defined(__USE_W32_SOCKETS)-# error You must add -D__USE_W32_SOCKETS to your compiler options.-# endif // !defined(__USE_W32_SOCKETS)-# endif // defined(__CYGWIN__)-#endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__)--// Windows: minimise header inclusion.-#if defined(ASIO_WINDOWS) || defined(__CYGWIN__)-# if !defined(ASIO_NO_WIN32_LEAN_AND_MEAN)-# if !defined(WIN32_LEAN_AND_MEAN)-# define WIN32_LEAN_AND_MEAN-# endif // !defined(WIN32_LEAN_AND_MEAN)-# endif // !defined(ASIO_NO_WIN32_LEAN_AND_MEAN)-#endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__)--// Windows: suppress definition of "min" and "max" macros.-#if defined(ASIO_WINDOWS) || defined(__CYGWIN__)-# if !defined(ASIO_NO_NOMINMAX)-# if !defined(NOMINMAX)-# define NOMINMAX 1-# endif // !defined(NOMINMAX)-# endif // !defined(ASIO_NO_NOMINMAX)-#endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__)--// Windows: IO Completion Ports.-#if !defined(ASIO_HAS_IOCP)-# if defined(ASIO_WINDOWS) || defined(__CYGWIN__)-# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0400)-# if !defined(UNDER_CE) && !defined(ASIO_WINDOWS_APP)-# if !defined(ASIO_DISABLE_IOCP)-# define ASIO_HAS_IOCP 1-# endif // !defined(ASIO_DISABLE_IOCP)-# endif // !defined(UNDER_CE) && !defined(ASIO_WINDOWS_APP)-# endif // defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0400)-# endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__)-#endif // !defined(ASIO_HAS_IOCP)--// On POSIX (and POSIX-like) platforms we need to include unistd.h in order to-// get access to the various platform feature macros, e.g. to be able to test-// for threads support.-#if !defined(ASIO_HAS_UNISTD_H)-# if !defined(ASIO_HAS_BOOST_CONFIG)-# if defined(unix) \- || defined(__unix) \- || defined(_XOPEN_SOURCE) \- || defined(_POSIX_SOURCE) \- || (defined(__MACH__) && defined(__APPLE__)) \- || defined(__FreeBSD__) \- || defined(__NetBSD__) \- || defined(__OpenBSD__) \- || defined(__linux__) \- || defined(__HAIKU__)-# define ASIO_HAS_UNISTD_H 1-# endif-# endif // !defined(ASIO_HAS_BOOST_CONFIG)-#endif // !defined(ASIO_HAS_UNISTD_H)-#if defined(ASIO_HAS_UNISTD_H)-# include <unistd.h>-#endif // defined(ASIO_HAS_UNISTD_H)--// Linux: epoll, eventfd, timerfd and io_uring.-#if defined(__linux__)-# include <linux/version.h>-# if !defined(ASIO_HAS_EPOLL)-# if !defined(ASIO_DISABLE_EPOLL)-# if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,45)-# define ASIO_HAS_EPOLL 1-# endif // LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,45)-# endif // !defined(ASIO_DISABLE_EPOLL)-# endif // !defined(ASIO_HAS_EPOLL)-# if !defined(ASIO_HAS_EVENTFD)-# if !defined(ASIO_DISABLE_EVENTFD)-# if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)-# define ASIO_HAS_EVENTFD 1-# endif // LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)-# endif // !defined(ASIO_DISABLE_EVENTFD)-# endif // !defined(ASIO_HAS_EVENTFD)-# if !defined(ASIO_HAS_TIMERFD)-# if defined(ASIO_HAS_EPOLL)-# if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 8)-# define ASIO_HAS_TIMERFD 1-# endif // (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 8)-# endif // defined(ASIO_HAS_EPOLL)-# endif // !defined(ASIO_HAS_TIMERFD)-# if defined(ASIO_HAS_IO_URING)-# if LINUX_VERSION_CODE < KERNEL_VERSION(5,10,0)-# error Linux kernel 5.10 or later is required to support io_uring-# endif // LINUX_VERSION_CODE < KERNEL_VERSION(5,10,0)-# endif // defined(ASIO_HAS_IO_URING)-#endif // defined(__linux__)--// Linux: io_uring is used instead of epoll.-#if !defined(ASIO_HAS_IO_URING_AS_DEFAULT)-# if !defined(ASIO_HAS_EPOLL) && defined(ASIO_HAS_IO_URING)-# define ASIO_HAS_IO_URING_AS_DEFAULT 1-# endif // !defined(ASIO_HAS_EPOLL) && defined(ASIO_HAS_IO_URING)-#endif // !defined(ASIO_HAS_IO_URING_AS_DEFAULT)--// Mac OS X, FreeBSD, NetBSD, OpenBSD: kqueue.-#if (defined(__MACH__) && defined(__APPLE__)) \- || defined(__FreeBSD__) \- || defined(__NetBSD__) \- || defined(__OpenBSD__)-# if !defined(ASIO_HAS_KQUEUE)-# if !defined(ASIO_DISABLE_KQUEUE)-# define ASIO_HAS_KQUEUE 1-# endif // !defined(ASIO_DISABLE_KQUEUE)-# endif // !defined(ASIO_HAS_KQUEUE)-#endif // (defined(__MACH__) && defined(__APPLE__))- // || defined(__FreeBSD__)- // || defined(__NetBSD__)- // || defined(__OpenBSD__)--// Solaris: /dev/poll.-#if defined(__sun)-# if !defined(ASIO_HAS_DEV_POLL)-# if !defined(ASIO_DISABLE_DEV_POLL)-# define ASIO_HAS_DEV_POLL 1-# endif // !defined(ASIO_DISABLE_DEV_POLL)-# endif // !defined(ASIO_HAS_DEV_POLL)-#endif // defined(__sun)--// Serial ports.-#if !defined(ASIO_HAS_SERIAL_PORT)-# if defined(ASIO_HAS_IOCP) \- || !defined(ASIO_WINDOWS) \- && !defined(ASIO_WINDOWS_RUNTIME) \- && !defined(__CYGWIN__)-# if !defined(__SYMBIAN32__)-# if !defined(ASIO_DISABLE_SERIAL_PORT)-# define ASIO_HAS_SERIAL_PORT 1-# endif // !defined(ASIO_DISABLE_SERIAL_PORT)-# endif // !defined(__SYMBIAN32__)-# endif // defined(ASIO_HAS_IOCP)- // || !defined(ASIO_WINDOWS)- // && !defined(ASIO_WINDOWS_RUNTIME)- // && !defined(__CYGWIN__)-#endif // !defined(ASIO_HAS_SERIAL_PORT)--// Windows: stream handles.-#if !defined(ASIO_HAS_WINDOWS_STREAM_HANDLE)-# if !defined(ASIO_DISABLE_WINDOWS_STREAM_HANDLE)-# if defined(ASIO_HAS_IOCP)-# define ASIO_HAS_WINDOWS_STREAM_HANDLE 1-# endif // defined(ASIO_HAS_IOCP)-# endif // !defined(ASIO_DISABLE_WINDOWS_STREAM_HANDLE)-#endif // !defined(ASIO_HAS_WINDOWS_STREAM_HANDLE)--// Windows: random access handles.-#if !defined(ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE)-# if !defined(ASIO_DISABLE_WINDOWS_RANDOM_ACCESS_HANDLE)-# if defined(ASIO_HAS_IOCP)-# define ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE 1-# endif // defined(ASIO_HAS_IOCP)-# endif // !defined(ASIO_DISABLE_WINDOWS_RANDOM_ACCESS_HANDLE)-#endif // !defined(ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE)--// Windows: object handles.-#if !defined(ASIO_HAS_WINDOWS_OBJECT_HANDLE)-# if !defined(ASIO_DISABLE_WINDOWS_OBJECT_HANDLE)-# if defined(ASIO_WINDOWS) || defined(__CYGWIN__)-# if !defined(UNDER_CE) && !defined(ASIO_WINDOWS_APP)-# define ASIO_HAS_WINDOWS_OBJECT_HANDLE 1-# endif // !defined(UNDER_CE) && !defined(ASIO_WINDOWS_APP)-# endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__)-# endif // !defined(ASIO_DISABLE_WINDOWS_OBJECT_HANDLE)-#endif // !defined(ASIO_HAS_WINDOWS_OBJECT_HANDLE)--// Windows: OVERLAPPED wrapper.-#if !defined(ASIO_HAS_WINDOWS_OVERLAPPED_PTR)-# if !defined(ASIO_DISABLE_WINDOWS_OVERLAPPED_PTR)-# if defined(ASIO_HAS_IOCP)-# define ASIO_HAS_WINDOWS_OVERLAPPED_PTR 1-# endif // defined(ASIO_HAS_IOCP)-# endif // !defined(ASIO_DISABLE_WINDOWS_OVERLAPPED_PTR)-#endif // !defined(ASIO_HAS_WINDOWS_OVERLAPPED_PTR)--// POSIX: stream-oriented file descriptors.-#if !defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR)-# if !defined(ASIO_DISABLE_POSIX_STREAM_DESCRIPTOR)-# if !defined(ASIO_WINDOWS) \- && !defined(ASIO_WINDOWS_RUNTIME) \- && !defined(__CYGWIN__)-# define ASIO_HAS_POSIX_STREAM_DESCRIPTOR 1-# endif // !defined(ASIO_WINDOWS)- // && !defined(ASIO_WINDOWS_RUNTIME)- // && !defined(__CYGWIN__)-# endif // !defined(ASIO_DISABLE_POSIX_STREAM_DESCRIPTOR)-#endif // !defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR)--// UNIX domain sockets.-#if !defined(ASIO_HAS_LOCAL_SOCKETS)-# if !defined(ASIO_DISABLE_LOCAL_SOCKETS)-# if !defined(ASIO_WINDOWS_RUNTIME)-# define ASIO_HAS_LOCAL_SOCKETS 1-# endif // !defined(ASIO_WINDOWS_RUNTIME)-# endif // !defined(ASIO_DISABLE_LOCAL_SOCKETS)-#endif // !defined(ASIO_HAS_LOCAL_SOCKETS)--// Files.-#if !defined(ASIO_HAS_FILE)-# if !defined(ASIO_DISABLE_FILE)-# if defined(ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE)-# define ASIO_HAS_FILE 1-# elif defined(ASIO_HAS_IO_URING)-# define ASIO_HAS_FILE 1-# endif // defined(ASIO_HAS_IO_URING)-# endif // !defined(ASIO_DISABLE_FILE)-#endif // !defined(ASIO_HAS_FILE)--// Pipes.-#if !defined(ASIO_HAS_PIPE)-# if defined(ASIO_HAS_IOCP) \- || !defined(ASIO_WINDOWS) \- && !defined(ASIO_WINDOWS_RUNTIME) \- && !defined(__CYGWIN__)-# if !defined(__SYMBIAN32__)-# if !defined(ASIO_DISABLE_PIPE)-# define ASIO_HAS_PIPE 1-# endif // !defined(ASIO_DISABLE_PIPE)-# endif // !defined(__SYMBIAN32__)-# endif // defined(ASIO_HAS_IOCP)- // || !defined(ASIO_WINDOWS)- // && !defined(ASIO_WINDOWS_RUNTIME)- // && !defined(__CYGWIN__)-#endif // !defined(ASIO_HAS_PIPE)--// Can use sigaction() instead of signal().-#if !defined(ASIO_HAS_SIGACTION)-# if !defined(ASIO_DISABLE_SIGACTION)-# if !defined(ASIO_WINDOWS) \- && !defined(ASIO_WINDOWS_RUNTIME) \- && !defined(__CYGWIN__)-# define ASIO_HAS_SIGACTION 1-# endif // !defined(ASIO_WINDOWS)- // && !defined(ASIO_WINDOWS_RUNTIME)- // && !defined(__CYGWIN__)-# endif // !defined(ASIO_DISABLE_SIGACTION)-#endif // !defined(ASIO_HAS_SIGACTION)--// Can use signal().-#if !defined(ASIO_HAS_SIGNAL)-# if !defined(ASIO_DISABLE_SIGNAL)-# if !defined(UNDER_CE)-# define ASIO_HAS_SIGNAL 1-# endif // !defined(UNDER_CE)-# endif // !defined(ASIO_DISABLE_SIGNAL)-#endif // !defined(ASIO_HAS_SIGNAL)--// Can use getaddrinfo() and getnameinfo().-#if !defined(ASIO_HAS_GETADDRINFO)-# if !defined(ASIO_DISABLE_GETADDRINFO)-# if defined(ASIO_WINDOWS) || defined(__CYGWIN__)-# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501)-# define ASIO_HAS_GETADDRINFO 1-# elif defined(UNDER_CE)-# define ASIO_HAS_GETADDRINFO 1-# endif // defined(UNDER_CE)-# elif defined(__MACH__) && defined(__APPLE__)-# if defined(__MAC_OS_X_VERSION_MIN_REQUIRED)-# if (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1050)-# define ASIO_HAS_GETADDRINFO 1-# endif // (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1050)-# else // defined(__MAC_OS_X_VERSION_MIN_REQUIRED)-# define ASIO_HAS_GETADDRINFO 1-# endif // defined(__MAC_OS_X_VERSION_MIN_REQUIRED)-# else // defined(__MACH__) && defined(__APPLE__)-# define ASIO_HAS_GETADDRINFO 1-# endif // defined(__MACH__) && defined(__APPLE__)-# endif // !defined(ASIO_DISABLE_GETADDRINFO)-#endif // !defined(ASIO_HAS_GETADDRINFO)--// Whether standard iostreams are disabled.-#if !defined(ASIO_NO_IOSTREAM)-# if defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_NO_IOSTREAM)-# define ASIO_NO_IOSTREAM 1-# endif // !defined(BOOST_NO_IOSTREAM)-#endif // !defined(ASIO_NO_IOSTREAM)--// Whether exception handling is disabled.-#if !defined(ASIO_NO_EXCEPTIONS)-# if defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_NO_EXCEPTIONS)-# define ASIO_NO_EXCEPTIONS 1-# endif // !defined(BOOST_NO_EXCEPTIONS)-#endif // !defined(ASIO_NO_EXCEPTIONS)--// Whether the typeid operator is supported.-#if !defined(ASIO_NO_TYPEID)-# if defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_NO_TYPEID)-# define ASIO_NO_TYPEID 1-# endif // !defined(BOOST_NO_TYPEID)-#endif // !defined(ASIO_NO_TYPEID)--// Threads.-#if !defined(ASIO_HAS_THREADS)-# if !defined(ASIO_DISABLE_THREADS)-# if defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_HAS_THREADS)-# define ASIO_HAS_THREADS 1-# elif defined(__GNUC__) && !defined(__MINGW32__) \- && !defined(linux) && !defined(__linux) && !defined(__linux__)-# define ASIO_HAS_THREADS 1-# elif defined(_MT) || defined(__MT__)-# define ASIO_HAS_THREADS 1-# elif defined(_REENTRANT)-# define ASIO_HAS_THREADS 1-# elif defined(__APPLE__)-# define ASIO_HAS_THREADS 1-# elif defined(__HAIKU__)-# define ASIO_HAS_THREADS 1-# elif defined(_POSIX_THREADS) && (_POSIX_THREADS + 0 >= 0)-# define ASIO_HAS_THREADS 1-# elif defined(_PTHREADS)-# define ASIO_HAS_THREADS 1-# endif // defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_HAS_THREADS)-# endif // !defined(ASIO_DISABLE_THREADS)-#endif // !defined(ASIO_HAS_THREADS)--// POSIX threads.-#if !defined(ASIO_HAS_PTHREADS)-# if defined(ASIO_HAS_THREADS)-# if defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_HAS_PTHREADS)-# define ASIO_HAS_PTHREADS 1-# elif defined(_POSIX_THREADS) && (_POSIX_THREADS + 0 >= 0)-# define ASIO_HAS_PTHREADS 1-# elif defined(__HAIKU__)-# define ASIO_HAS_PTHREADS 1-# endif // defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_HAS_PTHREADS)-# endif // defined(ASIO_HAS_THREADS)-#endif // !defined(ASIO_HAS_PTHREADS)--// Helper to prevent macro expansion.-#define ASIO_PREVENT_MACRO_SUBSTITUTION--// Helper to define in-class constants.-#if !defined(ASIO_STATIC_CONSTANT)-# if !defined(ASIO_DISABLE_BOOST_STATIC_CONSTANT)-# define ASIO_STATIC_CONSTANT(type, assignment) \- BOOST_STATIC_CONSTANT(type, assignment)-# else // !defined(ASIO_DISABLE_BOOST_STATIC_CONSTANT)-# define ASIO_STATIC_CONSTANT(type, assignment) \- static const type assignment-# endif // !defined(ASIO_DISABLE_BOOST_STATIC_CONSTANT)-#endif // !defined(ASIO_STATIC_CONSTANT)--// Boost align library.-#if !defined(ASIO_HAS_BOOST_ALIGN)-# if !defined(ASIO_DISABLE_BOOST_ALIGN)-# if defined(ASIO_HAS_BOOST_CONFIG) && (BOOST_VERSION >= 105600)-# define ASIO_HAS_BOOST_ALIGN 1-# endif // defined(ASIO_HAS_BOOST_CONFIG) && (BOOST_VERSION >= 105600)-# endif // !defined(ASIO_DISABLE_BOOST_ALIGN)-#endif // !defined(ASIO_HAS_BOOST_ALIGN)--// Boost array library.-#if !defined(ASIO_HAS_BOOST_ARRAY)-# if !defined(ASIO_DISABLE_BOOST_ARRAY)-# define ASIO_HAS_BOOST_ARRAY 1-# endif // !defined(ASIO_DISABLE_BOOST_ARRAY)-#endif // !defined(ASIO_HAS_BOOST_ARRAY)--// Boost assert macro.-#if !defined(ASIO_HAS_BOOST_ASSERT)-# if !defined(ASIO_DISABLE_BOOST_ASSERT)-# define ASIO_HAS_BOOST_ASSERT 1-# endif // !defined(ASIO_DISABLE_BOOST_ASSERT)-#endif // !defined(ASIO_HAS_BOOST_ASSERT)--// Boost limits header.-#if !defined(ASIO_HAS_BOOST_LIMITS)-# if !defined(ASIO_DISABLE_BOOST_LIMITS)-# define ASIO_HAS_BOOST_LIMITS 1-# endif // !defined(ASIO_DISABLE_BOOST_LIMITS)-#endif // !defined(ASIO_HAS_BOOST_LIMITS)--// Boost throw_exception function.-#if !defined(ASIO_HAS_BOOST_THROW_EXCEPTION)-# if !defined(ASIO_DISABLE_BOOST_THROW_EXCEPTION)-# define ASIO_HAS_BOOST_THROW_EXCEPTION 1-# endif // !defined(ASIO_DISABLE_BOOST_THROW_EXCEPTION)-#endif // !defined(ASIO_HAS_BOOST_THROW_EXCEPTION)--// Boost regex library.-#if !defined(ASIO_HAS_BOOST_REGEX)-# if !defined(ASIO_DISABLE_BOOST_REGEX)-# define ASIO_HAS_BOOST_REGEX 1-# endif // !defined(ASIO_DISABLE_BOOST_REGEX)-#endif // !defined(ASIO_HAS_BOOST_REGEX)--// Boost bind function.-#if !defined(ASIO_HAS_BOOST_BIND)-# if !defined(ASIO_DISABLE_BOOST_BIND)-# define ASIO_HAS_BOOST_BIND 1-# endif // !defined(ASIO_DISABLE_BOOST_BIND)-#endif // !defined(ASIO_HAS_BOOST_BIND)--// Boost's BOOST_WORKAROUND macro.-#if !defined(ASIO_HAS_BOOST_WORKAROUND)-# if !defined(ASIO_DISABLE_BOOST_WORKAROUND)-# define ASIO_HAS_BOOST_WORKAROUND 1-# endif // !defined(ASIO_DISABLE_BOOST_WORKAROUND)-#endif // !defined(ASIO_HAS_BOOST_WORKAROUND)--// Microsoft Visual C++'s secure C runtime library.-#if !defined(ASIO_HAS_SECURE_RTL)-# if !defined(ASIO_DISABLE_SECURE_RTL)-# if defined(ASIO_MSVC) \- && (ASIO_MSVC >= 1400) \- && !defined(UNDER_CE)-# define ASIO_HAS_SECURE_RTL 1-# endif // defined(ASIO_MSVC)- // && (ASIO_MSVC >= 1400)- // && !defined(UNDER_CE)-# endif // !defined(ASIO_DISABLE_SECURE_RTL)-#endif // !defined(ASIO_HAS_SECURE_RTL)--// Handler hooking. Disabled for ancient Borland C++ and gcc compilers.-#if !defined(ASIO_HAS_HANDLER_HOOKS)-# if !defined(ASIO_DISABLE_HANDLER_HOOKS)-# if defined(__GNUC__)-# if (__GNUC__ >= 3)-# define ASIO_HAS_HANDLER_HOOKS 1-# endif // (__GNUC__ >= 3)-# elif !defined(__BORLANDC__) || defined(__clang__)-# define ASIO_HAS_HANDLER_HOOKS 1-# endif // !defined(__BORLANDC__) || defined(__clang__)-# endif // !defined(ASIO_DISABLE_HANDLER_HOOKS)-#endif // !defined(ASIO_HAS_HANDLER_HOOKS)--// Support for the __thread keyword extension, or equivalent.-#if !defined(ASIO_DISABLE_THREAD_KEYWORD_EXTENSION)-# if defined(__linux__)-# if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))-# if ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)-# if !defined(__INTEL_COMPILER) && !defined(__ICL) \- && !(defined(__clang__) && defined(__ANDROID__))-# define ASIO_HAS_THREAD_KEYWORD_EXTENSION 1-# define ASIO_THREAD_KEYWORD __thread-# elif defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1100)-# define ASIO_HAS_THREAD_KEYWORD_EXTENSION 1-# endif // defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1100)- // && !(defined(__clang__) && defined(__ANDROID__))-# endif // ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)-# endif // defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))-# endif // defined(__linux__)-# if defined(ASIO_MSVC) && defined(ASIO_WINDOWS_RUNTIME)-# if (_MSC_VER >= 1700)-# define ASIO_HAS_THREAD_KEYWORD_EXTENSION 1-# define ASIO_THREAD_KEYWORD __declspec(thread)-# endif // (_MSC_VER >= 1700)-# endif // defined(ASIO_MSVC) && defined(ASIO_WINDOWS_RUNTIME)-# if defined(__APPLE__)-# if defined(__clang__)-# if defined(__apple_build_version__)-# define ASIO_HAS_THREAD_KEYWORD_EXTENSION 1-# define ASIO_THREAD_KEYWORD __thread-# endif // defined(__apple_build_version__)-# endif // defined(__clang__)-# endif // defined(__APPLE__)-# if !defined(ASIO_HAS_THREAD_KEYWORD_EXTENSION)-# if defined(ASIO_HAS_BOOST_CONFIG)-# if !defined(BOOST_NO_CXX11_THREAD_LOCAL)-# define ASIO_HAS_THREAD_KEYWORD_EXTENSION 1-# define ASIO_THREAD_KEYWORD thread_local-# endif // !defined(BOOST_NO_CXX11_THREAD_LOCAL)-# endif // defined(ASIO_HAS_BOOST_CONFIG)-# endif // !defined(ASIO_HAS_THREAD_KEYWORD_EXTENSION)-#endif // !defined(ASIO_DISABLE_THREAD_KEYWORD_EXTENSION)-#if !defined(ASIO_THREAD_KEYWORD)-# define ASIO_THREAD_KEYWORD __thread-#endif // !defined(ASIO_THREAD_KEYWORD)--// Support for POSIX ssize_t typedef.-#if !defined(ASIO_DISABLE_SSIZE_T)-# if defined(__linux__) \- || (defined(__MACH__) && defined(__APPLE__))-# define ASIO_HAS_SSIZE_T 1-# endif // defined(__linux__)- // || (defined(__MACH__) && defined(__APPLE__))-#endif // !defined(ASIO_DISABLE_SSIZE_T)--// Helper macros to manage transition away from error_code return values.-#if defined(ASIO_NO_DEPRECATED)-# define ASIO_SYNC_OP_VOID void-# define ASIO_SYNC_OP_VOID_RETURN(e) return-#else // defined(ASIO_NO_DEPRECATED)-# define ASIO_SYNC_OP_VOID asio::error_code-# define ASIO_SYNC_OP_VOID_RETURN(e) return e-#endif // defined(ASIO_NO_DEPRECATED)--// Newer gcc, clang need special treatment to suppress unused typedef warnings.-#if defined(__clang__)-# if defined(__apple_build_version__)-# if (__clang_major__ >= 7)-# define ASIO_UNUSED_TYPEDEF __attribute__((__unused__))-# endif // (__clang_major__ >= 7)-# elif ((__clang_major__ == 3) && (__clang_minor__ >= 6)) \- || (__clang_major__ > 3)-# define ASIO_UNUSED_TYPEDEF __attribute__((__unused__))-# endif // ((__clang_major__ == 3) && (__clang_minor__ >= 6))- // || (__clang_major__ > 3)-#elif defined(__GNUC__)-# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4)-# define ASIO_UNUSED_TYPEDEF __attribute__((__unused__))-# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4)-#endif // defined(__GNUC__)-#if !defined(ASIO_UNUSED_TYPEDEF)-# define ASIO_UNUSED_TYPEDEF-#endif // !defined(ASIO_UNUSED_TYPEDEF)--// Some versions of gcc generate spurious warnings about unused variables.-#if defined(__GNUC__)-# if (__GNUC__ >= 4)-# define ASIO_UNUSED_VARIABLE __attribute__((__unused__))-# endif // (__GNUC__ >= 4)-#endif // defined(__GNUC__)-#if !defined(ASIO_UNUSED_VARIABLE)-# define ASIO_UNUSED_VARIABLE-#endif // !defined(ASIO_UNUSED_VARIABLE)--// Helper macro to tell the optimiser what may be assumed to be true.-#if defined(ASIO_MSVC)-# define ASIO_ASSUME(expr) __assume(expr)-#elif defined(__clang__)-# if __has_builtin(__builtin_assume)-# define ASIO_ASSUME(expr) __builtin_assume(expr)-# endif // __has_builtin(__builtin_assume)-#elif defined(__GNUC__)-# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4)-# define ASIO_ASSUME(expr) if (expr) {} else { __builtin_unreachable(); }-# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4)-#endif // defined(__GNUC__)-#if !defined(ASIO_ASSUME)-# define ASIO_ASSUME(expr) (void)0-#endif // !defined(ASIO_ASSUME)--// Support the co_await keyword on compilers known to allow it.-#if !defined(ASIO_HAS_CO_AWAIT)-# if !defined(ASIO_DISABLE_CO_AWAIT)-# if (__cplusplus >= 202002) \- && (__cpp_impl_coroutine >= 201902) && (__cpp_lib_coroutine >= 201902)-# define ASIO_HAS_CO_AWAIT 1-# elif defined(ASIO_MSVC)-# if (_MSC_VER >= 1928) && (_MSVC_LANG >= 201705) && !defined(__clang__)-# define ASIO_HAS_CO_AWAIT 1-# elif (_MSC_FULL_VER >= 190023506)-# if defined(_RESUMABLE_FUNCTIONS_SUPPORTED)-# define ASIO_HAS_CO_AWAIT 1-# endif // defined(_RESUMABLE_FUNCTIONS_SUPPORTED)-# endif // (_MSC_FULL_VER >= 190023506)-# elif defined(__clang__)-# if (__clang_major__ >= 14)-# if (__cplusplus >= 202002) && (__cpp_impl_coroutine >= 201902)-# if __has_include(<coroutine>)-# define ASIO_HAS_CO_AWAIT 1-# endif // __has_include(<coroutine>)-# elif (__cplusplus >= 201703) && (__cpp_coroutines >= 201703)-# if __has_include(<experimental/coroutine>)-# define ASIO_HAS_CO_AWAIT 1-# endif // __has_include(<experimental/coroutine>)-# endif // (__cplusplus >= 201703) && (__cpp_coroutines >= 201703)-# else // (__clang_major__ >= 14)-# if (__cplusplus >= 201703) && (__cpp_coroutines >= 201703)-# if __has_include(<experimental/coroutine>)-# define ASIO_HAS_CO_AWAIT 1-# endif // __has_include(<experimental/coroutine>)-# endif // (__cplusplus >= 201703) && (__cpp_coroutines >= 201703)-# endif // (__clang_major__ >= 14)-# elif defined(__GNUC__)-# if (__cplusplus >= 201709) && (__cpp_impl_coroutine >= 201902)-# if __has_include(<coroutine>)-# define ASIO_HAS_CO_AWAIT 1-# endif // __has_include(<coroutine>)-# endif // (__cplusplus >= 201709) && (__cpp_impl_coroutine >= 201902)-# endif // defined(__GNUC__)-# endif // !defined(ASIO_DISABLE_CO_AWAIT)-#endif // !defined(ASIO_HAS_CO_AWAIT)--// Standard library support for coroutines.-#if !defined(ASIO_HAS_STD_COROUTINE)-# if !defined(ASIO_DISABLE_STD_COROUTINE)-# if defined(ASIO_MSVC)-# if (_MSC_VER >= 1928) && (_MSVC_LANG >= 201705)-# define ASIO_HAS_STD_COROUTINE 1-# endif // (_MSC_VER >= 1928) && (_MSVC_LANG >= 201705)-# elif defined(__clang__)-# if (__clang_major__ >= 14)-# if (__cplusplus >= 202002) && (__cpp_impl_coroutine >= 201902)-# if __has_include(<coroutine>)-# define ASIO_HAS_STD_COROUTINE 1-# endif // __has_include(<coroutine>)-# endif // (__cplusplus >= 202002) && (__cpp_impl_coroutine >= 201902)-# endif // (__clang_major__ >= 14)-# elif defined(__GNUC__)-# if (__cplusplus >= 201709) && (__cpp_impl_coroutine >= 201902)-# if __has_include(<coroutine>)-# define ASIO_HAS_STD_COROUTINE 1-# endif // __has_include(<coroutine>)-# endif // (__cplusplus >= 201709) && (__cpp_impl_coroutine >= 201902)-# endif // defined(__GNUC__)-# endif // !defined(ASIO_DISABLE_STD_COROUTINE)-#endif // !defined(ASIO_HAS_STD_COROUTINE)--// Compiler support for the the [[nodiscard]] attribute.-#if !defined(ASIO_NODISCARD)-# if defined(__has_cpp_attribute)-# if __has_cpp_attribute(nodiscard)-# if (__cplusplus >= 201703)-# define ASIO_NODISCARD [[nodiscard]]-# endif // (__cplusplus >= 201703)-# endif // __has_cpp_attribute(nodiscard)-# endif // defined(__has_cpp_attribute)-#endif // !defined(ASIO_NODISCARD)-#if !defined(ASIO_NODISCARD)-# define ASIO_NODISCARD-#endif // !defined(ASIO_NODISCARD)--// Kernel support for MSG_NOSIGNAL.-#if !defined(ASIO_HAS_MSG_NOSIGNAL)-# if defined(__linux__)-# define ASIO_HAS_MSG_NOSIGNAL 1-# elif defined(_POSIX_VERSION)-# if (_POSIX_VERSION >= 200809L)-# define ASIO_HAS_MSG_NOSIGNAL 1-# endif // _POSIX_VERSION >= 200809L-# endif // defined(_POSIX_VERSION)-#endif // !defined(ASIO_HAS_MSG_NOSIGNAL)--// Standard library support for std::to_address.-#if !defined(ASIO_HAS_STD_TO_ADDRESS)-# if !defined(ASIO_DISABLE_STD_TO_ADDRESS)-# if defined(__clang__)-# if (__cplusplus >= 202002)-# define ASIO_HAS_STD_TO_ADDRESS 1-# endif // (__cplusplus >= 202002)-# elif defined(__GNUC__)-# if (__GNUC__ >= 8)-# if (__cplusplus >= 202002)-# define ASIO_HAS_STD_TO_ADDRESS 1-# endif // (__cplusplus >= 202002)-# endif // (__GNUC__ >= 8)-# endif // defined(__GNUC__)-# if defined(ASIO_MSVC)-# if (_MSC_VER >= 1922) && (_MSVC_LANG >= 202002)-# define ASIO_HAS_STD_TO_ADDRESS 1-# endif // (_MSC_VER >= 1922) && (_MSVC_LANG >= 202002)-# endif // defined(ASIO_MSVC)-# endif // !defined(ASIO_DISABLE_STD_TO_ADDRESS)-#endif // !defined(ASIO_HAS_STD_TO_ADDRESS)--// Standard library support for snprintf.-#if !defined(ASIO_HAS_SNPRINTF)-# if !defined(ASIO_DISABLE_SNPRINTF)-# if defined(__APPLE__)-# define ASIO_HAS_SNPRINTF 1-# endif // defined(__APPLE__)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_DETAIL_CONFIG_HPP+#define ASIO_DETAIL_CONFIG_HPP++// boostify: non-boost code starts here+#if !defined(ASIO_STANDALONE)+# if !defined(ASIO_ENABLE_BOOST)+# if (__cplusplus >= 201103)+# define ASIO_STANDALONE 1+# elif defined(_MSC_VER) && defined(_MSVC_LANG)+# if (_MSC_VER >= 1900) && (_MSVC_LANG >= 201103)+# define ASIO_STANDALONE 1+# endif // (_MSC_VER >= 1900) && (_MSVC_LANG >= 201103)+# endif // defined(_MSC_VER) && defined(_MSVC_LANG)+# endif // !defined(ASIO_ENABLE_BOOST)+#endif // !defined(ASIO_STANDALONE)++// Make standard library feature macros available.+#if defined(__has_include)+# if __has_include(<version>)+# include <version>+# else // __has_include(<version>)+# include <cstddef>+# endif // __has_include(<version>)+#else // defined(__has_include)+# include <cstddef>+#endif // defined(__has_include)++// boostify: non-boost code ends here+#if defined(ASIO_STANDALONE)+# define ASIO_DISABLE_BOOST_ALIGN 1+# define ASIO_DISABLE_BOOST_ARRAY 1+# define ASIO_DISABLE_BOOST_ASSERT 1+# define ASIO_DISABLE_BOOST_BIND 1+# define ASIO_DISABLE_BOOST_CHRONO 1+# define ASIO_DISABLE_BOOST_DATE_TIME 1+# define ASIO_DISABLE_BOOST_LIMITS 1+# define ASIO_DISABLE_BOOST_REGEX 1+# define ASIO_DISABLE_BOOST_STATIC_CONSTANT 1+# define ASIO_DISABLE_BOOST_THROW_EXCEPTION 1+# define ASIO_DISABLE_BOOST_WORKAROUND 1+#else // defined(ASIO_STANDALONE)+// Boost.Config library is available.+# include <boost/config.hpp>+# include <boost/version.hpp>+# define ASIO_HAS_BOOST_CONFIG 1+#endif // defined(ASIO_STANDALONE)++// Default to a header-only implementation. The user must specifically request+// separate compilation by defining either ASIO_SEPARATE_COMPILATION or+// ASIO_DYN_LINK (as a DLL/shared library implies separate compilation).+#if !defined(ASIO_HEADER_ONLY)+# if !defined(ASIO_SEPARATE_COMPILATION)+# if !defined(ASIO_DYN_LINK)+# define ASIO_HEADER_ONLY 1+# endif // !defined(ASIO_DYN_LINK)+# endif // !defined(ASIO_SEPARATE_COMPILATION)+#endif // !defined(ASIO_HEADER_ONLY)++#if defined(ASIO_HEADER_ONLY)+# define ASIO_DECL inline+#else // defined(ASIO_HEADER_ONLY)+# if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__CODEGEARC__)+// We need to import/export our code only if the user has specifically asked+// for it by defining ASIO_DYN_LINK.+# if defined(ASIO_DYN_LINK)+// Export if this is our own source, otherwise import.+# if defined(ASIO_SOURCE)+# define ASIO_DECL __declspec(dllexport)+# else // defined(ASIO_SOURCE)+# define ASIO_DECL __declspec(dllimport)+# endif // defined(ASIO_SOURCE)+# endif // defined(ASIO_DYN_LINK)+# endif // defined(_MSC_VER) || defined(__BORLANDC__) || defined(__CODEGEARC__)+#endif // defined(ASIO_HEADER_ONLY)++// If ASIO_DECL isn't defined yet define it now.+#if !defined(ASIO_DECL)+# define ASIO_DECL+#endif // !defined(ASIO_DECL)++// Helper macro for documentation.+#define ASIO_UNSPECIFIED(e) e++// Microsoft Visual C++ detection.+#if !defined(ASIO_MSVC)+# if defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_MSVC)+# define ASIO_MSVC BOOST_MSVC+# elif defined(_MSC_VER) && (defined(__INTELLISENSE__) \+ || (!defined(__MWERKS__) && !defined(__EDG_VERSION__)))+# define ASIO_MSVC _MSC_VER+# endif // defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_MSVC)+#endif // !defined(ASIO_MSVC)++// Clang / libc++ detection.+#if defined(__clang__)+# if (__cplusplus >= 201103)+# if __has_include(<__config>)+# include <__config>+# if defined(_LIBCPP_VERSION)+# define ASIO_HAS_CLANG_LIBCXX 1+# endif // defined(_LIBCPP_VERSION)+# endif // __has_include(<__config>)+# endif // (__cplusplus >= 201103)+#endif // defined(__clang__)++// Android platform detection.+#if defined(__ANDROID__)+# include <android/api-level.h>+#endif // defined(__ANDROID__)++// Support move construction and assignment on compilers known to allow it.+#if !defined(ASIO_HAS_MOVE)+# if !defined(ASIO_DISABLE_MOVE)+# if defined(__clang__)+# if __has_feature(__cxx_rvalue_references__)+# define ASIO_HAS_MOVE 1+# endif // __has_feature(__cxx_rvalue_references__)+# elif defined(__GNUC__)+# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4)+# if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# define ASIO_HAS_MOVE 1+# endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4)+# endif // defined(__GNUC__)+# if defined(ASIO_MSVC)+# if (_MSC_VER >= 1700)+# define ASIO_HAS_MOVE 1+# endif // (_MSC_VER >= 1700)+# endif // defined(ASIO_MSVC)+# if defined(__INTEL_CXX11_MODE__)+# if defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1500)+# define ASIO_HAS_MOVE 1+# endif // defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1500)+# if defined(__ICL) && (__ICL >= 1500)+# define ASIO_HAS_MOVE 1+# endif // defined(__ICL) && (__ICL >= 1500)+# endif // defined(__INTEL_CXX11_MODE__)+# endif // !defined(ASIO_DISABLE_MOVE)+#endif // !defined(ASIO_HAS_MOVE)++// If ASIO_MOVE_CAST isn't defined, and move support is available, define+// * ASIO_MOVE_ARG,+// * ASIO_NONDEDUCED_MOVE_ARG, and+// * ASIO_MOVE_CAST+// to take advantage of rvalue references and perfect forwarding.+#if defined(ASIO_HAS_MOVE) && !defined(ASIO_MOVE_CAST)+# define ASIO_MOVE_ARG(type) type&&+# define ASIO_MOVE_ARG2(type1, type2) type1, type2&&+# define ASIO_NONDEDUCED_MOVE_ARG(type) type&+# define ASIO_MOVE_CAST(type) static_cast<type&&>+# define ASIO_MOVE_CAST2(type1, type2) static_cast<type1, type2&&>+# define ASIO_MOVE_OR_LVALUE(type) static_cast<type&&>+# define ASIO_MOVE_OR_LVALUE_ARG(type) type&&+# define ASIO_MOVE_OR_LVALUE_TYPE(type) type+#endif // defined(ASIO_HAS_MOVE) && !defined(ASIO_MOVE_CAST)++// If ASIO_MOVE_CAST still isn't defined, default to a C++03-compatible+// implementation. Note that older g++ and MSVC versions don't like it when you+// pass a non-member function through a const reference, so for most compilers+// we'll play it safe and stick with the old approach of passing the handler by+// value.+#if !defined(ASIO_MOVE_CAST)+# if defined(__GNUC__)+# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 1)) || (__GNUC__ > 4)+# define ASIO_MOVE_ARG(type) const type&+# else // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 1)) || (__GNUC__ > 4)+# define ASIO_MOVE_ARG(type) type+# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 1)) || (__GNUC__ > 4)+# elif defined(ASIO_MSVC)+# if (_MSC_VER >= 1400)+# define ASIO_MOVE_ARG(type) const type&+# else // (_MSC_VER >= 1400)+# define ASIO_MOVE_ARG(type) type+# endif // (_MSC_VER >= 1400)+# else+# define ASIO_MOVE_ARG(type) type+# endif+# define ASIO_NONDEDUCED_MOVE_ARG(type) const type&+# define ASIO_MOVE_CAST(type) static_cast<const type&>+# define ASIO_MOVE_CAST2(type1, type2) static_cast<const type1, type2&>+# define ASIO_MOVE_OR_LVALUE(type)+# define ASIO_MOVE_OR_LVALUE_ARG(type) type&+# define ASIO_MOVE_OR_LVALUE_TYPE(type) type&+#endif // !defined(ASIO_MOVE_CAST)++// Support variadic templates on compilers known to allow it.+#if !defined(ASIO_HAS_VARIADIC_TEMPLATES)+# if !defined(ASIO_DISABLE_VARIADIC_TEMPLATES)+# if defined(__clang__)+# if __has_feature(__cxx_variadic_templates__)+# define ASIO_HAS_VARIADIC_TEMPLATES 1+# endif // __has_feature(__cxx_variadic_templates__)+# elif defined(__GNUC__)+# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4)+# if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# define ASIO_HAS_VARIADIC_TEMPLATES 1+# endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4)+# endif // defined(__GNUC__)+# if defined(ASIO_MSVC)+# if (_MSC_VER >= 1900)+# define ASIO_HAS_VARIADIC_TEMPLATES 1+# endif // (_MSC_VER >= 1900)+# endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_VARIADIC_TEMPLATES)+#endif // !defined(ASIO_HAS_VARIADIC_TEMPLATES)+#if !defined(ASIO_ELLIPSIS)+# if defined(ASIO_HAS_VARIADIC_TEMPLATES)+# define ASIO_ELLIPSIS ...+# else // defined(ASIO_HAS_VARIADIC_TEMPLATES)+# define ASIO_ELLIPSIS+# endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+#endif // !defined(ASIO_ELLIPSIS)++// Support deleted functions on compilers known to allow it.+#if !defined(ASIO_DELETED)+# if defined(__clang__)+# if __has_feature(__cxx_deleted_functions__)+# define ASIO_DELETED = delete+# endif // __has_feature(__cxx_deleted_functions__)+# elif defined(__GNUC__)+# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)+# if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# define ASIO_DELETED = delete+# endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)+# endif // defined(__GNUC__)+# if defined(ASIO_MSVC)+# if (_MSC_VER >= 1900)+# define ASIO_DELETED = delete+# endif // (_MSC_VER >= 1900)+# endif // defined(ASIO_MSVC)+# if !defined(ASIO_DELETED)+# define ASIO_DELETED+# endif // !defined(ASIO_DELETED)+#endif // !defined(ASIO_DELETED)++// Support constexpr on compilers known to allow it.+#if !defined(ASIO_HAS_CONSTEXPR)+# if !defined(ASIO_DISABLE_CONSTEXPR)+# if defined(__clang__)+# if __has_feature(__cxx_constexpr__)+# define ASIO_HAS_CONSTEXPR 1+# endif // __has_feature(__cxx_constexpr__)+# elif defined(__GNUC__)+# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4)+# if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# define ASIO_HAS_CONSTEXPR 1+# endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4)+# endif // defined(__GNUC__)+# if defined(ASIO_MSVC)+# if (_MSC_VER >= 1900)+# define ASIO_HAS_CONSTEXPR 1+# endif // (_MSC_VER >= 1900)+# endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_CONSTEXPR)+#endif // !defined(ASIO_HAS_CONSTEXPR)+#if !defined(ASIO_CONSTEXPR)+# if defined(ASIO_HAS_CONSTEXPR)+# define ASIO_CONSTEXPR constexpr+# else // defined(ASIO_HAS_CONSTEXPR)+# define ASIO_CONSTEXPR+# endif // defined(ASIO_HAS_CONSTEXPR)+#endif // !defined(ASIO_CONSTEXPR)+#if !defined(ASIO_STATIC_CONSTEXPR)+# if defined(ASIO_HAS_CONSTEXPR)+# define ASIO_STATIC_CONSTEXPR(type, assignment) \+ static constexpr type assignment+# else // defined(ASIO_HAS_CONSTEXPR)+# define ASIO_STATIC_CONSTEXPR(type, assignment) \+ static const type assignment+# endif // defined(ASIO_HAS_CONSTEXPR)+#endif // !defined(ASIO_STATIC_CONSTEXPR)+#if !defined(ASIO_STATIC_CONSTEXPR_DEFAULT_INIT)+# if defined(ASIO_HAS_CONSTEXPR)+# if defined(__GNUC__)+# if (__GNUC__ >= 8)+# define ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(type, name) \+ static constexpr const type name{}+# else // (__GNUC__ >= 8)+# define ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(type, name) \+ static const type name+# endif // (__GNUC__ >= 8)+# elif defined(ASIO_MSVC)+# define ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(type, name) \+ static const type name+# else // defined(ASIO_MSVC)+# define ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(type, name) \+ static constexpr const type name{}+# endif // defined(ASIO_MSVC)+# else // defined(ASIO_HAS_CONSTEXPR)+# define ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(type, name) \+ static const type name+# endif // defined(ASIO_HAS_CONSTEXPR)+#endif // !defined(ASIO_STATIC_CONSTEXPR_DEFAULT_INIT)++// Support noexcept on compilers known to allow it.+#if !defined(ASIO_HAS_NOEXCEPT)+# if !defined(ASIO_DISABLE_NOEXCEPT)+# if defined(ASIO_HAS_BOOST_CONFIG) && (BOOST_VERSION >= 105300)+# if !defined(BOOST_NO_NOEXCEPT)+# define ASIO_HAS_NOEXCEPT 1+# endif // !defined(BOOST_NO_NOEXCEPT)+# define ASIO_NOEXCEPT BOOST_NOEXCEPT+# define ASIO_NOEXCEPT_OR_NOTHROW BOOST_NOEXCEPT_OR_NOTHROW+# define ASIO_NOEXCEPT_IF(c) BOOST_NOEXCEPT_IF(c)+# elif defined(__clang__)+# if __has_feature(__cxx_noexcept__)+# define ASIO_HAS_NOEXCEPT 1+# endif // __has_feature(__cxx_noexcept__)+# elif defined(__GNUC__)+# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)+# if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# define ASIO_HAS_NOEXCEPT 1+# endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)+# elif defined(ASIO_MSVC)+# if (_MSC_VER >= 1900)+# define ASIO_HAS_NOEXCEPT 1+# endif // (_MSC_VER >= 1900)+# endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_NOEXCEPT)+# if !defined(ASIO_NOEXCEPT)+# endif // !defined(ASIO_NOEXCEPT)+# if !defined(ASIO_NOEXCEPT_OR_NOTHROW)+# endif // !defined(ASIO_NOEXCEPT_OR_NOTHROW)+#endif // !defined(ASIO_HAS_NOEXCEPT)+#if !defined(ASIO_NOEXCEPT)+# if defined(ASIO_HAS_NOEXCEPT)+# define ASIO_NOEXCEPT noexcept(true)+# else // defined(ASIO_HAS_NOEXCEPT)+# define ASIO_NOEXCEPT+# endif // defined(ASIO_HAS_NOEXCEPT)+#endif // !defined(ASIO_NOEXCEPT)+#if !defined(ASIO_NOEXCEPT_OR_NOTHROW)+# if defined(ASIO_HAS_NOEXCEPT)+# define ASIO_NOEXCEPT_OR_NOTHROW noexcept(true)+# else // defined(ASIO_HAS_NOEXCEPT)+# define ASIO_NOEXCEPT_OR_NOTHROW throw()+# endif // defined(ASIO_HAS_NOEXCEPT)+#endif // !defined(ASIO_NOEXCEPT_OR_NOTHROW)+#if !defined(ASIO_NOEXCEPT_IF)+# if defined(ASIO_HAS_NOEXCEPT)+# define ASIO_NOEXCEPT_IF(c) noexcept(c)+# else // defined(ASIO_HAS_NOEXCEPT)+# define ASIO_NOEXCEPT_IF(c)+# endif // defined(ASIO_HAS_NOEXCEPT)+#endif // !defined(ASIO_NOEXCEPT_IF)++// Support noexcept on function types on compilers known to allow it.+#if !defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)+# if !defined(ASIO_DISABLE_NOEXCEPT_FUNCTION_TYPE)+# if defined(__clang__)+# if (__cplusplus >= 202002)+# define ASIO_HAS_NOEXCEPT_FUNCTION_TYPE 1+# endif // (__cplusplus >= 202002)+# elif defined(__GNUC__)+# if (__cplusplus >= 202002)+# define ASIO_HAS_NOEXCEPT_FUNCTION_TYPE 1+# endif // (__cplusplus >= 202002)+# elif defined(ASIO_MSVC)+# if (_MSC_VER >= 1900 && _MSVC_LANG >= 202002)+# define ASIO_HAS_NOEXCEPT_FUNCTION_TYPE 1+# endif // (_MSC_VER >= 1900 && _MSVC_LANG >= 202002)+# endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_NOEXCEPT_FUNCTION_TYPE)+#endif // !defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)++// Support automatic type deduction on compilers known to support it.+#if !defined(ASIO_HAS_DECLTYPE)+# if !defined(ASIO_DISABLE_DECLTYPE)+# if defined(__clang__)+# if __has_feature(__cxx_decltype__)+# define ASIO_HAS_DECLTYPE 1+# endif // __has_feature(__cxx_decltype__)+# elif defined(__GNUC__)+# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4)+# if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# define ASIO_HAS_DECLTYPE 1+# endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4)+# endif // defined(__GNUC__)+# if defined(ASIO_MSVC)+# if (_MSC_VER >= 1800)+# define ASIO_HAS_DECLTYPE 1+# endif // (_MSC_VER >= 1800)+# endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_DECLTYPE)+#endif // !defined(ASIO_HAS_DECLTYPE)+#if defined(ASIO_HAS_DECLTYPE)+# define ASIO_AUTO_RETURN_TYPE_PREFIX(t) auto+# define ASIO_AUTO_RETURN_TYPE_PREFIX2(t0, t1) auto+# define ASIO_AUTO_RETURN_TYPE_PREFIX3(t0, t1, t2) auto+# define ASIO_AUTO_RETURN_TYPE_SUFFIX(expr) -> decltype expr+#else // defined(ASIO_HAS_DECLTYPE)+# define ASIO_AUTO_RETURN_TYPE_PREFIX(t) t+# define ASIO_AUTO_RETURN_TYPE_PREFIX2(t0, t1) t0, t1+# define ASIO_AUTO_RETURN_TYPE_PREFIX3(t0, t1, t2) t0, t1, t2+# define ASIO_AUTO_RETURN_TYPE_SUFFIX(expr)+#endif // defined(ASIO_HAS_DECLTYPE)++// Support alias templates on compilers known to allow it.+#if !defined(ASIO_HAS_ALIAS_TEMPLATES)+# if !defined(ASIO_DISABLE_ALIAS_TEMPLATES)+# if defined(__clang__)+# if __has_feature(__cxx_alias_templates__)+# define ASIO_HAS_ALIAS_TEMPLATES 1+# endif // __has_feature(__cxx_alias_templates__)+# elif defined(__GNUC__)+# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)+# if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# define ASIO_HAS_ALIAS_TEMPLATES 1+# endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)+# endif // defined(__GNUC__)+# if defined(ASIO_MSVC)+# if (_MSC_VER >= 1900)+# define ASIO_HAS_ALIAS_TEMPLATES 1+# endif // (_MSC_VER >= 1900)+# endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_ALIAS_TEMPLATES)+#endif // !defined(ASIO_HAS_ALIAS_TEMPLATES)++// Support return type deduction on compilers known to allow it.+#if !defined(ASIO_HAS_RETURN_TYPE_DEDUCTION)+# if !defined(ASIO_DISABLE_RETURN_TYPE_DEDUCTION)+# if defined(__clang__)+# if __has_feature(__cxx_return_type_deduction__)+# define ASIO_HAS_RETURN_TYPE_DEDUCTION 1+# endif // __has_feature(__cxx_return_type_deduction__)+# elif (__cplusplus >= 201402)+# define ASIO_HAS_RETURN_TYPE_DEDUCTION 1+# elif defined(__cpp_return_type_deduction)+# if (__cpp_return_type_deduction >= 201304)+# define ASIO_HAS_RETURN_TYPE_DEDUCTION 1+# endif // (__cpp_return_type_deduction >= 201304)+# elif defined(ASIO_MSVC)+# if (_MSC_VER >= 1900 && _MSVC_LANG >= 201402)+# define ASIO_HAS_RETURN_TYPE_DEDUCTION 1+# endif // (_MSC_VER >= 1900 && _MSVC_LANG >= 201402)+# endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_RETURN_TYPE_DEDUCTION)+#endif // !defined(ASIO_HAS_RETURN_TYPE_DEDUCTION)++// Support default function template arguments on compilers known to allow it.+#if !defined(ASIO_HAS_DEFAULT_FUNCTION_TEMPLATE_ARGUMENTS)+# if !defined(ASIO_DISABLE_DEFAULT_FUNCTION_TEMPLATE_ARGUMENTS)+# if (__cplusplus >= 201103)+# define ASIO_HAS_DEFAULT_FUNCTION_TEMPLATE_ARGUMENTS 1+# elif defined(ASIO_MSVC)+# if (_MSC_VER >= 1900 && _MSVC_LANG >= 201103)+# define ASIO_HAS_DEFAULT_FUNCTION_TEMPLATE_ARGUMENTS 1+# endif // (_MSC_VER >= 1900 && _MSVC_LANG >= 201103)+# endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_DEFAULT_FUNCTION_TEMPLATE_ARGUMENTS)+#endif // !defined(ASIO_HAS_DEFAULT_FUNCTION_TEMPLATE_ARGUMENTS)++// Support enum classes on compilers known to allow them.+#if !defined(ASIO_HAS_ENUM_CLASS)+# if !defined(ASIO_DISABLE_ENUM_CLASS)+# if (__cplusplus >= 201103)+# define ASIO_HAS_ENUM_CLASS 1+# elif defined(ASIO_MSVC)+# if (_MSC_VER >= 1900 && _MSVC_LANG >= 201103)+# define ASIO_HAS_ENUM_CLASS 1+# endif // (_MSC_VER >= 1900 && _MSVC_LANG >= 201103)+# endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_ENUM_CLASS)+#endif // !defined(ASIO_HAS_ENUM_CLASS)++// Support concepts on compilers known to allow them.+#if !defined(ASIO_HAS_CONCEPTS)+# if !defined(ASIO_DISABLE_CONCEPTS)+# if defined(__cpp_concepts)+# define ASIO_HAS_CONCEPTS 1+# if (__cpp_concepts >= 201707)+# define ASIO_CONCEPT concept+# else // (__cpp_concepts >= 201707)+# define ASIO_CONCEPT concept bool+# endif // (__cpp_concepts >= 201707)+# endif // defined(__cpp_concepts)+# endif // !defined(ASIO_DISABLE_CONCEPTS)+#endif // !defined(ASIO_HAS_CONCEPTS)++// Support concepts on compilers known to allow them.+#if !defined(ASIO_HAS_STD_CONCEPTS)+# if !defined(ASIO_DISABLE_STD_CONCEPTS)+# if defined(ASIO_HAS_CONCEPTS)+# if (__cpp_lib_concepts >= 202002L)+# define ASIO_HAS_STD_CONCEPTS 1+# endif // (__cpp_concepts >= 202002L)+# endif // defined(ASIO_HAS_CONCEPTS)+# endif // !defined(ASIO_DISABLE_STD_CONCEPTS)+#endif // !defined(ASIO_HAS_STD_CONCEPTS)++// Support template variables on compilers known to allow it.+#if !defined(ASIO_HAS_VARIABLE_TEMPLATES)+# if !defined(ASIO_DISABLE_VARIABLE_TEMPLATES)+# if defined(__clang__)+# if (__cplusplus >= 201402)+# if __has_feature(__cxx_variable_templates__)+# define ASIO_HAS_VARIABLE_TEMPLATES 1+# endif // __has_feature(__cxx_variable_templates__)+# endif // (__cplusplus >= 201402)+# elif defined(__GNUC__) && !defined(__INTEL_COMPILER)+# if (__GNUC__ >= 6)+# if (__cplusplus >= 201402)+# define ASIO_HAS_VARIABLE_TEMPLATES 1+# endif // (__cplusplus >= 201402)+# endif // (__GNUC__ >= 6)+# endif // defined(__GNUC__) && !defined(__INTEL_COMPILER)+# if defined(ASIO_MSVC)+# if (_MSC_VER >= 1901)+# define ASIO_HAS_VARIABLE_TEMPLATES 1+# endif // (_MSC_VER >= 1901)+# endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_VARIABLE_TEMPLATES)+#endif // !defined(ASIO_HAS_VARIABLE_TEMPLATES)++// Support SFINAEd template variables on compilers known to allow it.+#if !defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)+# if !defined(ASIO_DISABLE_SFINAE_VARIABLE_TEMPLATES)+# if defined(__clang__)+# if (__cplusplus >= 201703)+# if __has_feature(__cxx_variable_templates__)+# define ASIO_HAS_SFINAE_VARIABLE_TEMPLATES 1+# endif // __has_feature(__cxx_variable_templates__)+# endif // (__cplusplus >= 201703)+# elif defined(__GNUC__)+# if ((__GNUC__ == 8) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 8)+# if (__cplusplus >= 201402)+# define ASIO_HAS_SFINAE_VARIABLE_TEMPLATES 1+# endif // (__cplusplus >= 201402)+# endif // ((__GNUC__ == 8) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 8)+# endif // defined(__GNUC__)+# if defined(ASIO_MSVC)+# if (_MSC_VER >= 1901)+# define ASIO_HAS_SFINAE_VARIABLE_TEMPLATES 1+# endif // (_MSC_VER >= 1901)+# endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_SFINAE_VARIABLE_TEMPLATES)+#endif // !defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)++// Support SFINAE use of constant expressions on compilers known to allow it.+#if !defined(ASIO_HAS_CONSTANT_EXPRESSION_SFINAE)+# if !defined(ASIO_DISABLE_CONSTANT_EXPRESSION_SFINAE)+# if defined(__clang__)+# if (__cplusplus >= 201402)+# define ASIO_HAS_CONSTANT_EXPRESSION_SFINAE 1+# endif // (__cplusplus >= 201402)+# elif defined(__GNUC__) && !defined(__INTEL_COMPILER)+# if (__GNUC__ >= 7)+# if (__cplusplus >= 201402)+# define ASIO_HAS_CONSTANT_EXPRESSION_SFINAE 1+# endif // (__cplusplus >= 201402)+# endif // (__GNUC__ >= 7)+# endif // defined(__GNUC__) && !defined(__INTEL_COMPILER)+# if defined(ASIO_MSVC)+# if (_MSC_VER >= 1901)+# define ASIO_HAS_CONSTANT_EXPRESSION_SFINAE 1+# endif // (_MSC_VER >= 1901)+# endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_CONSTANT_EXPRESSION_SFINAE)+#endif // !defined(ASIO_HAS_CONSTANT_EXPRESSION_SFINAE)++// Enable workarounds for lack of working expression SFINAE.+#if !defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+# if !defined(ASIO_DISABLE_WORKING_EXPRESSION_SFINAE)+# if !defined(ASIO_MSVC) && !defined(__INTEL_COMPILER)+# if (__cplusplus >= 201103)+# define ASIO_HAS_WORKING_EXPRESSION_SFINAE 1+# endif // (__cplusplus >= 201103)+# elif defined(ASIO_MSVC) && (_MSC_VER >= 1929)+# if (_MSVC_LANG >= 202000)+# define ASIO_HAS_WORKING_EXPRESSION_SFINAE 1+# endif // (_MSVC_LANG >= 202000)+# endif // defined(ASIO_MSVC) && (_MSC_VER >= 1929)+# endif // !defined(ASIO_DISABLE_WORKING_EXPRESSION_SFINAE)+#endif // !defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)++// Support ref-qualified functions on compilers known to allow it.+#if !defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)+# if !defined(ASIO_DISABLE_REF_QUALIFIED_FUNCTIONS)+# if defined(__clang__)+# if __has_feature(__cxx_reference_qualified_functions__)+# define ASIO_HAS_REF_QUALIFIED_FUNCTIONS 1+# endif // __has_feature(__cxx_reference_qualified_functions__)+# elif defined(__GNUC__)+# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)) || (__GNUC__ > 4)+# if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# define ASIO_HAS_REF_QUALIFIED_FUNCTIONS 1+# endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)) || (__GNUC__ > 4)+# endif // defined(__GNUC__)+# if defined(ASIO_MSVC)+# if (_MSC_VER >= 1900)+# define ASIO_HAS_REF_QUALIFIED_FUNCTIONS 1+# endif // (_MSC_VER >= 1900)+# endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_REF_QUALIFIED_FUNCTIONS)+#endif // !defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)+#if defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)+# if !defined(ASIO_LVALUE_REF_QUAL)+# define ASIO_LVALUE_REF_QUAL &+# endif // !defined(ASIO_LVALUE_REF_QUAL)+# if !defined(ASIO_RVALUE_REF_QUAL)+# define ASIO_RVALUE_REF_QUAL &&+# endif // !defined(ASIO_RVALUE_REF_QUAL)+#else // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)+# if !defined(ASIO_LVALUE_REF_QUAL)+# define ASIO_LVALUE_REF_QUAL+# endif // !defined(ASIO_LVALUE_REF_QUAL)+# if !defined(ASIO_RVALUE_REF_QUAL)+# define ASIO_RVALUE_REF_QUAL+# endif // !defined(ASIO_RVALUE_REF_QUAL)+#endif // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)++// Support for capturing parameter packs in lambdas.+#if !defined(ASIO_HAS_VARIADIC_LAMBDA_CAPTURES)+# if !defined(ASIO_DISABLE_VARIADIC_LAMBDA_CAPTURES)+# if defined(__GNUC__)+# if (__GNUC__ >= 6)+# define ASIO_HAS_VARIADIC_LAMBDA_CAPTURES 1+# endif // (__GNUC__ >= 6)+# elif defined(ASIO_MSVC)+# if (_MSVC_LANG >= 201103)+# define ASIO_HAS_VARIADIC_LAMBDA_CAPTURES 1+# endif // (_MSC_LANG >= 201103)+# else // defined(ASIO_MSVC)+# if (__cplusplus >= 201103)+# define ASIO_HAS_VARIADIC_LAMBDA_CAPTURES 1+# endif // (__cplusplus >= 201103)+# endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_VARIADIC_LAMBDA_CAPTURES)+#endif // !defined(ASIO_HAS_VARIADIC_LAMBDA_CAPTURES)++// Support for the alignof operator.+#if !defined(ASIO_HAS_ALIGNOF)+# if !defined(ASIO_DISABLE_ALIGNOF)+# if (__cplusplus >= 201103)+# define ASIO_HAS_ALIGNOF 1+# endif // (__cplusplus >= 201103)+# endif // !defined(ASIO_DISABLE_ALIGNOF)+#endif // !defined(ASIO_HAS_ALIGNOF)++#if defined(ASIO_HAS_ALIGNOF)+# define ASIO_ALIGNOF(T) alignof(T)+# if defined(__STDCPP_DEFAULT_NEW_ALIGNMENT__)+# define ASIO_DEFAULT_ALIGN __STDCPP_DEFAULT_NEW_ALIGNMENT__+# elif defined(__GNUC__)+# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)) || (__GNUC__ > 4)+# define ASIO_DEFAULT_ALIGN alignof(std::max_align_t)+# else // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)) || (__GNUC__ > 4)+# define ASIO_DEFAULT_ALIGN alignof(max_align_t)+# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)) || (__GNUC__ > 4)+# else // defined(__GNUC__)+# define ASIO_DEFAULT_ALIGN alignof(std::max_align_t)+# endif // defined(__GNUC__)+#else // defined(ASIO_HAS_ALIGNOF)+# define ASIO_ALIGNOF(T) 1+# define ASIO_DEFAULT_ALIGN 1+#endif // defined(ASIO_HAS_ALIGNOF)++// Support for user-defined literals.+#if !defined(ASIO_HAS_USER_DEFINED_LITERALS)+# if !defined(ASIO_DISABLE_USER_DEFINED_LITERALS)+# if (__cplusplus >= 201103)+# define ASIO_HAS_USER_DEFINED_LITERALS 1+# elif defined(ASIO_MSVC)+# if (_MSC_VER >= 1900 && _MSVC_LANG >= 201103)+# define ASIO_HAS_USER_DEFINED_LITERALS 1+# endif // (_MSC_VER >= 1900 && _MSVC_LANG >= 201103)+# endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_USER_DEFINED_LITERALS)+#endif // !defined(ASIO_HAS_USER_DEFINED_LITERALS)++// Standard library support for aligned allocation.+#if !defined(ASIO_HAS_STD_ALIGNED_ALLOC)+# if !defined(ASIO_DISABLE_STD_ALIGNED_ALLOC)+# if (__cplusplus >= 201703)+# if defined(__clang__)+# if defined(ASIO_HAS_CLANG_LIBCXX)+# if (_LIBCPP_STD_VER > 14) && defined(_LIBCPP_HAS_ALIGNED_ALLOC) \+ && !defined(_LIBCPP_MSVCRT) && !defined(__MINGW32__)+# if defined(__APPLE__)+# if defined(__MAC_OS_X_VERSION_MIN_REQUIRED)+# if (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101500)+# define ASIO_HAS_STD_ALIGNED_ALLOC 1+# endif // (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101500)+# elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED)+# if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 130000)+# define ASIO_HAS_STD_ALIGNED_ALLOC 1+# endif // (__IPHONE_OS_VERSION_MIN_REQUIRED >= 130000)+# elif defined(__TV_OS_VERSION_MIN_REQUIRED)+# if (__TV_OS_VERSION_MIN_REQUIRED >= 130000)+# define ASIO_HAS_STD_ALIGNED_ALLOC 1+# endif // (__TV_OS_VERSION_MIN_REQUIRED >= 130000)+# elif defined(__WATCH_OS_VERSION_MIN_REQUIRED)+# if (__WATCH_OS_VERSION_MIN_REQUIRED >= 60000)+# define ASIO_HAS_STD_ALIGNED_ALLOC 1+# endif // (__WATCH_OS_VERSION_MIN_REQUIRED >= 60000)+# endif // defined(__WATCH_OS_X_VERSION_MIN_REQUIRED)+# else // defined(__APPLE__)+# define ASIO_HAS_STD_ALIGNED_ALLOC 1+# endif // defined(__APPLE__)+# endif // (_LIBCPP_STD_VER > 14) && defined(_LIBCPP_HAS_ALIGNED_ALLOC)+ // && !defined(_LIBCPP_MSVCRT) && !defined(__MINGW32__)+# elif defined(_GLIBCXX_HAVE_ALIGNED_ALLOC)+# define ASIO_HAS_STD_ALIGNED_ALLOC 1+# endif // defined(_GLIBCXX_HAVE_ALIGNED_ALLOC)+# elif defined(__GNUC__)+# if ((__GNUC__ == 7) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 7)+# if defined(_GLIBCXX_HAVE_ALIGNED_ALLOC)+# define ASIO_HAS_STD_ALIGNED_ALLOC 1+# endif // defined(_GLIBCXX_HAVE_ALIGNED_ALLOC)+# endif // ((__GNUC__ == 7) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 7)+# endif // defined(__GNUC__)+# endif // (__cplusplus >= 201703)+# endif // !defined(ASIO_DISABLE_STD_ALIGNED_ALLOC)+#endif // !defined(ASIO_HAS_STD_ALIGNED_ALLOC)++// Standard library support for std::align.+#if !defined(ASIO_HAS_STD_ALIGN)+# if !defined(ASIO_DISABLE_STD_ALIGN)+# if defined(__clang__)+# if defined(ASIO_HAS_CLANG_LIBCXX)+# define ASIO_HAS_STD_ALIGN 1+# elif (__cplusplus >= 201103)+# define ASIO_HAS_STD_ALIGN 1+# endif // (__cplusplus >= 201103)+# elif defined(__GNUC__)+# if (__GNUC__ >= 6)+# if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# define ASIO_HAS_STD_ALIGN 1+# endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# endif // (__GNUC__ >= 6)+# endif // defined(__GNUC__)+# if defined(ASIO_MSVC)+# if (_MSC_VER >= 1700)+# define ASIO_HAS_STD_ALIGN 1+# endif // (_MSC_VER >= 1700)+# endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_STD_ALIGN)+#endif // !defined(ASIO_HAS_STD_ALIGN)++// Standard library support for system errors.+#if !defined(ASIO_HAS_STD_SYSTEM_ERROR)+# if !defined(ASIO_DISABLE_STD_SYSTEM_ERROR)+# if defined(__clang__)+# if defined(ASIO_HAS_CLANG_LIBCXX)+# define ASIO_HAS_STD_SYSTEM_ERROR 1+# elif (__cplusplus >= 201103)+# if __has_include(<system_error>)+# define ASIO_HAS_STD_SYSTEM_ERROR 1+# endif // __has_include(<system_error>)+# endif // (__cplusplus >= 201103)+# elif defined(__GNUC__)+# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4)+# if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# define ASIO_HAS_STD_SYSTEM_ERROR 1+# endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4)+# endif // defined(__GNUC__)+# if defined(ASIO_MSVC)+# if (_MSC_VER >= 1700)+# define ASIO_HAS_STD_SYSTEM_ERROR 1+# endif // (_MSC_VER >= 1700)+# endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_STD_SYSTEM_ERROR)+#endif // !defined(ASIO_HAS_STD_SYSTEM_ERROR)++// Compliant C++11 compilers put noexcept specifiers on error_category members.+#if !defined(ASIO_ERROR_CATEGORY_NOEXCEPT)+# if defined(ASIO_HAS_BOOST_CONFIG) && (BOOST_VERSION >= 105300)+# define ASIO_ERROR_CATEGORY_NOEXCEPT BOOST_NOEXCEPT+# elif defined(__clang__)+# if __has_feature(__cxx_noexcept__)+# define ASIO_ERROR_CATEGORY_NOEXCEPT noexcept(true)+# endif // __has_feature(__cxx_noexcept__)+# elif defined(__GNUC__)+# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)+# if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# define ASIO_ERROR_CATEGORY_NOEXCEPT noexcept(true)+# endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)+# elif defined(ASIO_MSVC)+# if (_MSC_VER >= 1900)+# define ASIO_ERROR_CATEGORY_NOEXCEPT noexcept(true)+# endif // (_MSC_VER >= 1900)+# endif // defined(ASIO_MSVC)+# if !defined(ASIO_ERROR_CATEGORY_NOEXCEPT)+# define ASIO_ERROR_CATEGORY_NOEXCEPT+# endif // !defined(ASIO_ERROR_CATEGORY_NOEXCEPT)+#endif // !defined(ASIO_ERROR_CATEGORY_NOEXCEPT)++// Standard library support for arrays.+#if !defined(ASIO_HAS_STD_ARRAY)+# if !defined(ASIO_DISABLE_STD_ARRAY)+# if defined(__clang__)+# if defined(ASIO_HAS_CLANG_LIBCXX)+# define ASIO_HAS_STD_ARRAY 1+# elif (__cplusplus >= 201103)+# if __has_include(<array>)+# define ASIO_HAS_STD_ARRAY 1+# endif // __has_include(<array>)+# endif // (__cplusplus >= 201103)+# elif defined(__GNUC__)+# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 4)+# if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# define ASIO_HAS_STD_ARRAY 1+# endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 4)+# endif // defined(__GNUC__)+# if defined(ASIO_MSVC)+# if (_MSC_VER >= 1600)+# define ASIO_HAS_STD_ARRAY 1+# endif // (_MSC_VER >= 1600)+# endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_STD_ARRAY)+#endif // !defined(ASIO_HAS_STD_ARRAY)++// Standard library support for shared_ptr and weak_ptr.+#if !defined(ASIO_HAS_STD_SHARED_PTR)+# if !defined(ASIO_DISABLE_STD_SHARED_PTR)+# if defined(__clang__)+# if defined(ASIO_HAS_CLANG_LIBCXX)+# define ASIO_HAS_STD_SHARED_PTR 1+# elif (__cplusplus >= 201103)+# define ASIO_HAS_STD_SHARED_PTR 1+# endif // (__cplusplus >= 201103)+# elif defined(__GNUC__)+# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 4)+# if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# define ASIO_HAS_STD_SHARED_PTR 1+# endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 4)+# endif // defined(__GNUC__)+# if defined(ASIO_MSVC)+# if (_MSC_VER >= 1600)+# define ASIO_HAS_STD_SHARED_PTR 1+# endif // (_MSC_VER >= 1600)+# endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_STD_SHARED_PTR)+#endif // !defined(ASIO_HAS_STD_SHARED_PTR)++// Standard library support for allocator_arg_t.+#if !defined(ASIO_HAS_STD_ALLOCATOR_ARG)+# if !defined(ASIO_DISABLE_STD_ALLOCATOR_ARG)+# if defined(__clang__)+# if defined(ASIO_HAS_CLANG_LIBCXX)+# define ASIO_HAS_STD_ALLOCATOR_ARG 1+# elif (__cplusplus >= 201103)+# define ASIO_HAS_STD_ALLOCATOR_ARG 1+# endif // (__cplusplus >= 201103)+# elif defined(__GNUC__)+# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4)+# if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# define ASIO_HAS_STD_ALLOCATOR_ARG 1+# endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4)+# endif // defined(__GNUC__)+# if defined(ASIO_MSVC)+# if (_MSC_VER >= 1600)+# define ASIO_HAS_STD_ALLOCATOR_ARG 1+# endif // (_MSC_VER >= 1600)+# endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_STD_ALLOCATOR_ARG)+#endif // !defined(ASIO_HAS_STD_ALLOCATOR_ARG)++// Standard library support for atomic operations.+#if !defined(ASIO_HAS_STD_ATOMIC)+# if !defined(ASIO_DISABLE_STD_ATOMIC)+# if defined(__clang__)+# if defined(ASIO_HAS_CLANG_LIBCXX)+# define ASIO_HAS_STD_ATOMIC 1+# elif (__cplusplus >= 201103)+# if __has_include(<atomic>)+# define ASIO_HAS_STD_ATOMIC 1+# endif // __has_include(<atomic>)+# elif defined(__apple_build_version__) && defined(_LIBCPP_VERSION)+# if (__clang_major__ >= 10)+# if __has_include(<atomic>)+# define ASIO_HAS_STD_ATOMIC 1+# endif // __has_include(<atomic>)+# endif // (__clang_major__ >= 10)+# endif // defined(__apple_build_version__) && defined(_LIBCPP_VERSION)+# elif defined(__GNUC__)+# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)+# if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# define ASIO_HAS_STD_ATOMIC 1+# endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)+# endif // defined(__GNUC__)+# if defined(ASIO_MSVC)+# if (_MSC_VER >= 1700)+# define ASIO_HAS_STD_ATOMIC 1+# endif // (_MSC_VER >= 1700)+# endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_STD_ATOMIC)+#endif // !defined(ASIO_HAS_STD_ATOMIC)++// Standard library support for chrono. Some standard libraries (such as the+// libstdc++ shipped with gcc 4.6) provide monotonic_clock as per early C++0x+// drafts, rather than the eventually standardised name of steady_clock.+#if !defined(ASIO_HAS_STD_CHRONO)+# if !defined(ASIO_DISABLE_STD_CHRONO)+# if defined(__clang__)+# if defined(ASIO_HAS_CLANG_LIBCXX)+# define ASIO_HAS_STD_CHRONO 1+# elif (__cplusplus >= 201103)+# if __has_include(<chrono>)+# define ASIO_HAS_STD_CHRONO 1+# endif // __has_include(<chrono>)+# endif // (__cplusplus >= 201103)+# elif defined(__GNUC__)+# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4)+# if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# define ASIO_HAS_STD_CHRONO 1+# if ((__GNUC__ == 4) && (__GNUC_MINOR__ == 6))+# define ASIO_HAS_STD_CHRONO_MONOTONIC_CLOCK 1+# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ == 6))+# endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4)+# endif // defined(__GNUC__)+# if defined(ASIO_MSVC)+# if (_MSC_VER >= 1700)+# define ASIO_HAS_STD_CHRONO 1+# endif // (_MSC_VER >= 1700)+# endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_STD_CHRONO)+#endif // !defined(ASIO_HAS_STD_CHRONO)++// Boost support for chrono.+#if !defined(ASIO_HAS_BOOST_CHRONO)+# if !defined(ASIO_DISABLE_BOOST_CHRONO)+# if defined(ASIO_HAS_BOOST_CONFIG) && (BOOST_VERSION >= 104700)+# define ASIO_HAS_BOOST_CHRONO 1+# endif // defined(ASIO_HAS_BOOST_CONFIG) && (BOOST_VERSION >= 104700)+# endif // !defined(ASIO_DISABLE_BOOST_CHRONO)+#endif // !defined(ASIO_HAS_BOOST_CHRONO)++// Some form of chrono library is available.+#if !defined(ASIO_HAS_CHRONO)+# if defined(ASIO_HAS_STD_CHRONO) \+ || defined(ASIO_HAS_BOOST_CHRONO)+# define ASIO_HAS_CHRONO 1+# endif // defined(ASIO_HAS_STD_CHRONO)+ // || defined(ASIO_HAS_BOOST_CHRONO)+#endif // !defined(ASIO_HAS_CHRONO)++// Boost support for the DateTime library.+#if !defined(ASIO_HAS_BOOST_DATE_TIME)+# if !defined(ASIO_DISABLE_BOOST_DATE_TIME)+# define ASIO_HAS_BOOST_DATE_TIME 1+# endif // !defined(ASIO_DISABLE_BOOST_DATE_TIME)+#endif // !defined(ASIO_HAS_BOOST_DATE_TIME)++// Boost support for the Coroutine library.+#if !defined(ASIO_HAS_BOOST_COROUTINE)+# if !defined(ASIO_DISABLE_BOOST_COROUTINE)+# define ASIO_HAS_BOOST_COROUTINE 1+# endif // !defined(ASIO_DISABLE_BOOST_COROUTINE)+#endif // !defined(ASIO_HAS_BOOST_COROUTINE)++// Boost support for the Context library's fibers.+#if !defined(ASIO_HAS_BOOST_CONTEXT_FIBER)+# if !defined(ASIO_DISABLE_BOOST_CONTEXT_FIBER)+# if defined(__clang__)+# if (__cplusplus >= 201103)+# define ASIO_HAS_BOOST_CONTEXT_FIBER 1+# endif // (__cplusplus >= 201103)+# elif defined(__GNUC__)+# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4)+# if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# define ASIO_HAS_BOOST_CONTEXT_FIBER 1+# endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4)+# endif // defined(__GNUC__)+# if defined(ASIO_MSVC)+# if (_MSVC_LANG >= 201103)+# define ASIO_HAS_BOOST_CONTEXT_FIBER 1+# endif // (_MSC_LANG >= 201103)+# endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_BOOST_CONTEXT_FIBER)+#endif // !defined(ASIO_HAS_BOOST_CONTEXT_FIBER)++// Standard library support for addressof.+#if !defined(ASIO_HAS_STD_ADDRESSOF)+# if !defined(ASIO_DISABLE_STD_ADDRESSOF)+# if defined(__clang__)+# if defined(ASIO_HAS_CLANG_LIBCXX)+# define ASIO_HAS_STD_ADDRESSOF 1+# elif (__cplusplus >= 201103)+# define ASIO_HAS_STD_ADDRESSOF 1+# endif // (__cplusplus >= 201103)+# elif defined(__GNUC__)+# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4)+# if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# define ASIO_HAS_STD_ADDRESSOF 1+# endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4)+# endif // defined(__GNUC__)+# if defined(ASIO_MSVC)+# if (_MSC_VER >= 1700)+# define ASIO_HAS_STD_ADDRESSOF 1+# endif // (_MSC_VER >= 1700)+# endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_STD_ADDRESSOF)+#endif // !defined(ASIO_HAS_STD_ADDRESSOF)++// Standard library support for the function class.+#if !defined(ASIO_HAS_STD_FUNCTION)+# if !defined(ASIO_DISABLE_STD_FUNCTION)+# if defined(__clang__)+# if defined(ASIO_HAS_CLANG_LIBCXX)+# define ASIO_HAS_STD_FUNCTION 1+# elif (__cplusplus >= 201103)+# define ASIO_HAS_STD_FUNCTION 1+# endif // (__cplusplus >= 201103)+# elif defined(__GNUC__)+# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4)+# if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# define ASIO_HAS_STD_FUNCTION 1+# endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4)+# endif // defined(__GNUC__)+# if defined(ASIO_MSVC)+# if (_MSC_VER >= 1700)+# define ASIO_HAS_STD_FUNCTION 1+# endif // (_MSC_VER >= 1700)+# endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_STD_FUNCTION)+#endif // !defined(ASIO_HAS_STD_FUNCTION)++// Standard library support for the reference_wrapper class.+#if !defined(ASIO_HAS_STD_REFERENCE_WRAPPER)+# if !defined(ASIO_DISABLE_STD_REFERENCE_WRAPPER)+# if defined(__clang__)+# if defined(ASIO_HAS_CLANG_LIBCXX)+# define ASIO_HAS_STD_REFERENCE_WRAPPER 1+# elif (__cplusplus >= 201103)+# define ASIO_HAS_STD_REFERENCE_WRAPPER 1+# endif // (__cplusplus >= 201103)+# elif defined(__GNUC__)+# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4)+# if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# define ASIO_HAS_STD_REFERENCE_WRAPPER 1+# endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4)+# endif // defined(__GNUC__)+# if defined(ASIO_MSVC)+# if (_MSC_VER >= 1700)+# define ASIO_HAS_STD_REFERENCE_WRAPPER 1+# endif // (_MSC_VER >= 1700)+# endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_STD_REFERENCE_WRAPPER)+#endif // !defined(ASIO_HAS_STD_REFERENCE_WRAPPER)++// Standard library support for type traits.+#if !defined(ASIO_HAS_STD_TYPE_TRAITS)+# if !defined(ASIO_DISABLE_STD_TYPE_TRAITS)+# if defined(__clang__)+# if defined(ASIO_HAS_CLANG_LIBCXX)+# define ASIO_HAS_STD_TYPE_TRAITS 1+# elif (__cplusplus >= 201103)+# if __has_include(<type_traits>)+# define ASIO_HAS_STD_TYPE_TRAITS 1+# endif // __has_include(<type_traits>)+# endif // (__cplusplus >= 201103)+# elif defined(__GNUC__)+# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4)+# if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# define ASIO_HAS_STD_TYPE_TRAITS 1+# endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4)+# endif // defined(__GNUC__)+# if defined(ASIO_MSVC)+# if (_MSC_VER >= 1700)+# define ASIO_HAS_STD_TYPE_TRAITS 1+# endif // (_MSC_VER >= 1700)+# endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_STD_TYPE_TRAITS)+#endif // !defined(ASIO_HAS_STD_TYPE_TRAITS)++// Standard library support for the nullptr_t type.+#if !defined(ASIO_HAS_NULLPTR)+# if !defined(ASIO_DISABLE_NULLPTR)+# if defined(__clang__)+# if __has_feature(__cxx_nullptr__)+# define ASIO_HAS_NULLPTR 1+# endif // __has_feature(__cxx_nullptr__)+# elif defined(__GNUC__)+# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4)+# if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# define ASIO_HAS_NULLPTR 1+# endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4)+# endif // defined(__GNUC__)+# if defined(ASIO_MSVC)+# if (_MSC_VER >= 1700)+# define ASIO_HAS_NULLPTR 1+# endif // (_MSC_VER >= 1700)+# endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_NULLPTR)+#endif // !defined(ASIO_HAS_NULLPTR)++// Standard library support for the C++11 allocator additions.+#if !defined(ASIO_HAS_CXX11_ALLOCATORS)+# if !defined(ASIO_DISABLE_CXX11_ALLOCATORS)+# if defined(__clang__)+# if defined(ASIO_HAS_CLANG_LIBCXX)+# define ASIO_HAS_CXX11_ALLOCATORS 1+# elif (__cplusplus >= 201103)+# define ASIO_HAS_CXX11_ALLOCATORS 1+# endif // (__cplusplus >= 201103)+# elif defined(__GNUC__)+# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)+# if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# define ASIO_HAS_CXX11_ALLOCATORS 1+# endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)+# endif // defined(__GNUC__)+# if defined(ASIO_MSVC)+# if (_MSC_VER >= 1800)+# define ASIO_HAS_CXX11_ALLOCATORS 1+# endif // (_MSC_VER >= 1800)+# endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_CXX11_ALLOCATORS)+#endif // !defined(ASIO_HAS_CXX11_ALLOCATORS)++// Standard library support for the cstdint header.+#if !defined(ASIO_HAS_CSTDINT)+# if !defined(ASIO_DISABLE_CSTDINT)+# if defined(__clang__)+# if defined(ASIO_HAS_CLANG_LIBCXX)+# define ASIO_HAS_CSTDINT 1+# elif (__cplusplus >= 201103)+# define ASIO_HAS_CSTDINT 1+# endif // (__cplusplus >= 201103)+# elif defined(__GNUC__)+# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4)+# if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# define ASIO_HAS_CSTDINT 1+# endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4)+# endif // defined(__GNUC__)+# if defined(ASIO_MSVC)+# if (_MSC_VER >= 1700)+# define ASIO_HAS_CSTDINT 1+# endif // (_MSC_VER >= 1700)+# endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_CSTDINT)+#endif // !defined(ASIO_HAS_CSTDINT)++// Standard library support for the thread class.+#if !defined(ASIO_HAS_STD_THREAD)+# if !defined(ASIO_DISABLE_STD_THREAD)+# if defined(__clang__)+# if defined(ASIO_HAS_CLANG_LIBCXX)+# define ASIO_HAS_STD_THREAD 1+# elif (__cplusplus >= 201103)+# if __has_include(<thread>)+# define ASIO_HAS_STD_THREAD 1+# endif // __has_include(<thread>)+# endif // (__cplusplus >= 201103)+# elif defined(__GNUC__)+# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)+# if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# define ASIO_HAS_STD_THREAD 1+# endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)+# endif // defined(__GNUC__)+# if defined(ASIO_MSVC)+# if (_MSC_VER >= 1700)+# define ASIO_HAS_STD_THREAD 1+# endif // (_MSC_VER >= 1700)+# endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_STD_THREAD)+#endif // !defined(ASIO_HAS_STD_THREAD)++// Standard library support for the mutex and condition variable classes.+#if !defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR)+# if !defined(ASIO_DISABLE_STD_MUTEX_AND_CONDVAR)+# if defined(__clang__)+# if defined(ASIO_HAS_CLANG_LIBCXX)+# define ASIO_HAS_STD_MUTEX_AND_CONDVAR 1+# elif (__cplusplus >= 201103)+# if __has_include(<mutex>)+# define ASIO_HAS_STD_MUTEX_AND_CONDVAR 1+# endif // __has_include(<mutex>)+# endif // (__cplusplus >= 201103)+# elif defined(__GNUC__)+# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)+# if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# define ASIO_HAS_STD_MUTEX_AND_CONDVAR 1+# endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)+# endif // defined(__GNUC__)+# if defined(ASIO_MSVC)+# if (_MSC_VER >= 1700)+# define ASIO_HAS_STD_MUTEX_AND_CONDVAR 1+# endif // (_MSC_VER >= 1700)+# endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_STD_MUTEX_AND_CONDVAR)+#endif // !defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR)++// Standard library support for the call_once function.+#if !defined(ASIO_HAS_STD_CALL_ONCE)+# if !defined(ASIO_DISABLE_STD_CALL_ONCE)+# if defined(__clang__)+# if defined(ASIO_HAS_CLANG_LIBCXX)+# define ASIO_HAS_STD_CALL_ONCE 1+# elif (__cplusplus >= 201103)+# if __has_include(<mutex>)+# define ASIO_HAS_STD_CALL_ONCE 1+# endif // __has_include(<mutex>)+# endif // (__cplusplus >= 201103)+# elif defined(__GNUC__)+# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)+# if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# define ASIO_HAS_STD_CALL_ONCE 1+# endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)+# endif // defined(__GNUC__)+# if defined(ASIO_MSVC)+# if (_MSC_VER >= 1700)+# define ASIO_HAS_STD_CALL_ONCE 1+# endif // (_MSC_VER >= 1700)+# endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_STD_CALL_ONCE)+#endif // !defined(ASIO_HAS_STD_CALL_ONCE)++// Standard library support for futures.+#if !defined(ASIO_HAS_STD_FUTURE)+# if !defined(ASIO_DISABLE_STD_FUTURE)+# if defined(__clang__)+# if defined(ASIO_HAS_CLANG_LIBCXX)+# define ASIO_HAS_STD_FUTURE 1+# elif (__cplusplus >= 201103)+# if __has_include(<future>)+# define ASIO_HAS_STD_FUTURE 1+# endif // __has_include(<future>)+# endif // (__cplusplus >= 201103)+# elif defined(__GNUC__)+# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)+# if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# define ASIO_HAS_STD_FUTURE 1+# endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)+# endif // defined(__GNUC__)+# if defined(ASIO_MSVC)+# if (_MSC_VER >= 1700)+# define ASIO_HAS_STD_FUTURE 1+# endif // (_MSC_VER >= 1700)+# endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_STD_FUTURE)+#endif // !defined(ASIO_HAS_STD_FUTURE)++// Standard library support for std::tuple.+#if !defined(ASIO_HAS_STD_TUPLE)+# if !defined(ASIO_DISABLE_STD_TUPLE)+# if defined(__clang__)+# if defined(ASIO_HAS_CLANG_LIBCXX)+# define ASIO_HAS_STD_TUPLE 1+# elif (__cplusplus >= 201103)+# if __has_include(<tuple>)+# define ASIO_HAS_STD_TUPLE 1+# endif // __has_include(<tuple>)+# endif // (__cplusplus >= 201103)+# elif defined(__GNUC__)+# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4)+# if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# define ASIO_HAS_STD_TUPLE 1+# endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4)+# endif // defined(__GNUC__)+# if defined(ASIO_MSVC)+# if (_MSC_VER >= 1700)+# define ASIO_HAS_STD_TUPLE 1+# endif // (_MSC_VER >= 1700)+# endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_STD_TUPLE)+#endif // !defined(ASIO_HAS_STD_TUPLE)++// Standard library support for std::string_view.+#if !defined(ASIO_HAS_STD_STRING_VIEW)+# if !defined(ASIO_DISABLE_STD_STRING_VIEW)+# if defined(__clang__)+# if defined(ASIO_HAS_CLANG_LIBCXX)+# if (__cplusplus >= 201402)+# if __has_include(<string_view>)+# define ASIO_HAS_STD_STRING_VIEW 1+# endif // __has_include(<string_view>)+# endif // (__cplusplus >= 201402)+# else // defined(ASIO_HAS_CLANG_LIBCXX)+# if (__cplusplus >= 201703)+# if __has_include(<string_view>)+# define ASIO_HAS_STD_STRING_VIEW 1+# endif // __has_include(<string_view>)+# endif // (__cplusplus >= 201703)+# endif // defined(ASIO_HAS_CLANG_LIBCXX)+# elif defined(__GNUC__)+# if (__GNUC__ >= 7)+# if (__cplusplus >= 201703)+# define ASIO_HAS_STD_STRING_VIEW 1+# endif // (__cplusplus >= 201703)+# endif // (__GNUC__ >= 7)+# elif defined(ASIO_MSVC)+# if (_MSC_VER >= 1910 && _MSVC_LANG >= 201703)+# define ASIO_HAS_STD_STRING_VIEW 1+# endif // (_MSC_VER >= 1910 && _MSVC_LANG >= 201703)+# endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_STD_STRING_VIEW)+#endif // !defined(ASIO_HAS_STD_STRING_VIEW)++// Standard library support for std::experimental::string_view.+#if !defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW)+# if !defined(ASIO_DISABLE_STD_EXPERIMENTAL_STRING_VIEW)+# if defined(__clang__)+# if defined(ASIO_HAS_CLANG_LIBCXX)+# if (_LIBCPP_VERSION < 7000)+# if (__cplusplus >= 201402)+# if __has_include(<experimental/string_view>)+# define ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW 1+# endif // __has_include(<experimental/string_view>)+# endif // (__cplusplus >= 201402)+# endif // (_LIBCPP_VERSION < 7000)+# else // defined(ASIO_HAS_CLANG_LIBCXX)+# if (__cplusplus >= 201402)+# if __has_include(<experimental/string_view>)+# define ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW 1+# endif // __has_include(<experimental/string_view>)+# endif // (__cplusplus >= 201402)+# endif // // defined(ASIO_HAS_CLANG_LIBCXX)+# elif defined(__GNUC__)+# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)) || (__GNUC__ > 4)+# if (__cplusplus >= 201402)+# define ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW 1+# endif // (__cplusplus >= 201402)+# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)) || (__GNUC__ > 4)+# endif // defined(__GNUC__)+# endif // !defined(ASIO_DISABLE_STD_EXPERIMENTAL_STRING_VIEW)+#endif // !defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW)++// Standard library has a string_view that we can use.+#if !defined(ASIO_HAS_STRING_VIEW)+# if !defined(ASIO_DISABLE_STRING_VIEW)+# if defined(ASIO_HAS_STD_STRING_VIEW)+# define ASIO_HAS_STRING_VIEW 1+# elif defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW)+# define ASIO_HAS_STRING_VIEW 1+# endif // defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW)+# endif // !defined(ASIO_DISABLE_STRING_VIEW)+#endif // !defined(ASIO_HAS_STRING_VIEW)++// Standard library support for iostream move construction and assignment.+#if !defined(ASIO_HAS_STD_IOSTREAM_MOVE)+# if !defined(ASIO_DISABLE_STD_IOSTREAM_MOVE)+# if defined(__clang__)+# if (__cplusplus >= 201103)+# define ASIO_HAS_STD_IOSTREAM_MOVE 1+# endif // (__cplusplus >= 201103)+# elif defined(__GNUC__)+# if (__GNUC__ > 4)+# if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# define ASIO_HAS_STD_IOSTREAM_MOVE 1+# endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# endif // (__GNUC__ > 4)+# elif defined(ASIO_MSVC)+# if (_MSC_VER >= 1700)+# define ASIO_HAS_STD_IOSTREAM_MOVE 1+# endif // (_MSC_VER >= 1700)+# endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_STD_IOSTREAM_MOVE)+#endif // !defined(ASIO_HAS_STD_IOSTREAM_MOVE)++// Standard library has invoke_result (which supersedes result_of).+#if !defined(ASIO_HAS_STD_INVOKE_RESULT)+# if !defined(ASIO_DISABLE_STD_INVOKE_RESULT)+# if defined(ASIO_MSVC)+# if (_MSC_VER >= 1911 && _MSVC_LANG >= 201703)+# define ASIO_HAS_STD_INVOKE_RESULT 1+# endif // (_MSC_VER >= 1911 && _MSVC_LANG >= 201703)+# else // defined(ASIO_MSVC)+# if (__cplusplus >= 201703)+# define ASIO_HAS_STD_INVOKE_RESULT 1+# endif // (__cplusplus >= 201703)+# endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_STD_INVOKE_RESULT)+#endif // !defined(ASIO_HAS_STD_INVOKE_RESULT)++// Standard library support for std::exception_ptr and std::current_exception.+#if !defined(ASIO_HAS_STD_EXCEPTION_PTR)+# if !defined(ASIO_DISABLE_STD_EXCEPTION_PTR)+# if defined(__clang__)+# if defined(ASIO_HAS_CLANG_LIBCXX)+# define ASIO_HAS_STD_EXCEPTION_PTR 1+# elif (__cplusplus >= 201103)+# define ASIO_HAS_STD_EXCEPTION_PTR 1+# endif // (__cplusplus >= 201103)+# elif defined(__GNUC__)+# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)+# if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# define ASIO_HAS_STD_EXCEPTION_PTR 1+# endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)+# endif // defined(__GNUC__)+# if defined(ASIO_MSVC)+# if (_MSC_VER >= 1800)+# define ASIO_HAS_STD_EXCEPTION_PTR 1+# endif // (_MSC_VER >= 1800)+# endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_STD_EXCEPTION_PTR)+#endif // !defined(ASIO_HAS_STD_EXCEPTION_PTR)++// Standard library support for std::nested_exception.+#if !defined(ASIO_HAS_STD_NESTED_EXCEPTION)+# if !defined(ASIO_DISABLE_STD_NESTED_EXCEPTION)+# if defined(__clang__)+# if defined(ASIO_HAS_CLANG_LIBCXX)+# define ASIO_HAS_STD_NESTED_EXCEPTION 1+# elif (__cplusplus >= 201103)+# define ASIO_HAS_STD_NESTED_EXCEPTION 1+# endif // (__cplusplus >= 201103)+# elif defined(__GNUC__)+# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)+# if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# define ASIO_HAS_STD_NESTED_EXCEPTION 1+# endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)+# endif // defined(__GNUC__)+# if defined(ASIO_MSVC)+# if (_MSC_VER >= 1900)+# define ASIO_HAS_STD_NESTED_EXCEPTION 1+# endif // (_MSC_VER >= 1900)+# endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_STD_NESTED_EXCEPTION)+#endif // !defined(ASIO_HAS_STD_NESTED_EXCEPTION)++// Standard library support for std::any.+#if !defined(ASIO_HAS_STD_ANY)+# if !defined(ASIO_DISABLE_STD_ANY)+# if defined(__clang__)+# if (__cplusplus >= 201703)+# if __has_include(<any>)+# define ASIO_HAS_STD_ANY 1+# endif // __has_include(<any>)+# endif // (__cplusplus >= 201703)+# elif defined(__GNUC__)+# if (__GNUC__ >= 7)+# if (__cplusplus >= 201703)+# define ASIO_HAS_STD_ANY 1+# endif // (__cplusplus >= 201703)+# endif // (__GNUC__ >= 7)+# endif // defined(__GNUC__)+# if defined(ASIO_MSVC)+# if (_MSC_VER >= 1910) && (_MSVC_LANG >= 201703)+# define ASIO_HAS_STD_ANY 1+# endif // (_MSC_VER >= 1910) && (_MSVC_LANG >= 201703)+# endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_STD_ANY)+#endif // !defined(ASIO_HAS_STD_ANY)++// Standard library support for std::variant.+#if !defined(ASIO_HAS_STD_VARIANT)+# if !defined(ASIO_DISABLE_STD_VARIANT)+# if defined(__clang__)+# if (__cplusplus >= 201703)+# if __has_include(<variant>)+# define ASIO_HAS_STD_VARIANT 1+# endif // __has_include(<variant>)+# endif // (__cplusplus >= 201703)+# elif defined(__GNUC__)+# if (__GNUC__ >= 7)+# if (__cplusplus >= 201703)+# define ASIO_HAS_STD_VARIANT 1+# endif // (__cplusplus >= 201703)+# endif // (__GNUC__ >= 7)+# endif // defined(__GNUC__)+# if defined(ASIO_MSVC)+# if (_MSC_VER >= 1910) && (_MSVC_LANG >= 201703)+# define ASIO_HAS_STD_VARIANT 1+# endif // (_MSC_VER >= 1910) && (_MSVC_LANG >= 201703)+# endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_STD_VARIANT)+#endif // !defined(ASIO_HAS_STD_VARIANT)++// Standard library support for std::source_location.+#if !defined(ASIO_HAS_STD_SOURCE_LOCATION)+# if !defined(ASIO_DISABLE_STD_SOURCE_LOCATION)+// ...+# endif // !defined(ASIO_DISABLE_STD_SOURCE_LOCATION)+#endif // !defined(ASIO_HAS_STD_SOURCE_LOCATION)++// Standard library support for std::experimental::source_location.+#if !defined(ASIO_HAS_STD_EXPERIMENTAL_SOURCE_LOCATION)+# if !defined(ASIO_DISABLE_STD_EXPERIMENTAL_SOURCE_LOCATION)+# if defined(__GNUC__)+# if (__cplusplus >= 201709)+# if __has_include(<experimental/source_location>)+# define ASIO_HAS_STD_EXPERIMENTAL_SOURCE_LOCATION 1+# endif // __has_include(<experimental/source_location>)+# endif // (__cplusplus >= 201709)+# endif // defined(__GNUC__)+# endif // !defined(ASIO_DISABLE_STD_EXPERIMENTAL_SOURCE_LOCATION)+#endif // !defined(ASIO_HAS_STD_EXPERIMENTAL_SOURCE_LOCATION)++// Standard library has a source_location that we can use.+#if !defined(ASIO_HAS_SOURCE_LOCATION)+# if !defined(ASIO_DISABLE_SOURCE_LOCATION)+# if defined(ASIO_HAS_STD_SOURCE_LOCATION)+# define ASIO_HAS_SOURCE_LOCATION 1+# elif defined(ASIO_HAS_STD_EXPERIMENTAL_SOURCE_LOCATION)+# define ASIO_HAS_SOURCE_LOCATION 1+# endif // defined(ASIO_HAS_STD_EXPERIMENTAL_SOURCE_LOCATION)+# endif // !defined(ASIO_DISABLE_SOURCE_LOCATION)+#endif // !defined(ASIO_HAS_SOURCE_LOCATION)++// Boost support for source_location and system errors.+#if !defined(ASIO_HAS_BOOST_SOURCE_LOCATION)+# if !defined(ASIO_DISABLE_BOOST_SOURCE_LOCATION)+# if defined(ASIO_HAS_BOOST_CONFIG) && (BOOST_VERSION >= 107900)+# define ASIO_HAS_BOOST_SOURCE_LOCATION 1+# endif // defined(ASIO_HAS_BOOST_CONFIG) && (BOOST_VERSION >= 107900)+# endif // !defined(ASIO_DISABLE_BOOST_SOURCE_LOCATION)+#endif // !defined(ASIO_HAS_BOOST_SOURCE_LOCATION)++// Helper macros for working with Boost source locations.+#if defined(ASIO_HAS_BOOST_SOURCE_LOCATION)+# define ASIO_SOURCE_LOCATION_PARAM \+ , const boost::source_location& loc+# define ASIO_SOURCE_LOCATION_DEFAULTED_PARAM \+ , const boost::source_location& loc = BOOST_CURRENT_LOCATION+# define ASIO_SOURCE_LOCATION_ARG , loc+#else // if defined(ASIO_HAS_BOOST_SOURCE_LOCATION)+# define ASIO_SOURCE_LOCATION_PARAM+# define ASIO_SOURCE_LOCATION_DEFAULTED_PARAM+# define ASIO_SOURCE_LOCATION_ARG+#endif // if defined(ASIO_HAS_BOOST_SOURCE_LOCATION)++// Standard library support for std::index_sequence.+#if !defined(ASIO_HAS_STD_INDEX_SEQUENCE)+# if !defined(ASIO_DISABLE_STD_INDEX_SEQUENCE)+# if defined(__clang__)+# if (__cplusplus >= 201402)+# define ASIO_HAS_STD_INDEX_SEQUENCE 1+# endif // (__cplusplus >= 201402)+# elif defined(__GNUC__)+# if (__GNUC__ >= 7)+# if (__cplusplus >= 201402)+# define ASIO_HAS_STD_INDEX_SEQUENCE 1+# endif // (__cplusplus >= 201402)+# endif // (__GNUC__ >= 7)+# endif // defined(__GNUC__)+# if defined(ASIO_MSVC)+# if (_MSC_VER >= 1910) && (_MSVC_LANG >= 201402)+# define ASIO_HAS_STD_INDEX_SEQUENCE 1+# endif // (_MSC_VER >= 1910) && (_MSVC_LANG >= 201402)+# endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_STD_INDEX_SEQUENCE)+#endif // !defined(ASIO_HAS_STD_INDEX_SEQUENCE)++// Windows App target. Windows but with a limited API.+#if !defined(ASIO_WINDOWS_APP)+# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0603)+# include <winapifamily.h>+# if (WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) \+ || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_TV_TITLE)) \+ && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)+# define ASIO_WINDOWS_APP 1+# endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)+ // && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)+# endif // defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0603)+#endif // !defined(ASIO_WINDOWS_APP)++// Legacy WinRT target. Windows App is preferred.+#if !defined(ASIO_WINDOWS_RUNTIME)+# if !defined(ASIO_WINDOWS_APP)+# if defined(__cplusplus_winrt)+# include <winapifamily.h>+# if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) \+ && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)+# define ASIO_WINDOWS_RUNTIME 1+# endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)+ // && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)+# endif // defined(__cplusplus_winrt)+# endif // !defined(ASIO_WINDOWS_APP)+#endif // !defined(ASIO_WINDOWS_RUNTIME)++// Windows target. Excludes WinRT but includes Windows App targets.+#if !defined(ASIO_WINDOWS)+# if !defined(ASIO_WINDOWS_RUNTIME)+# if defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_WINDOWS)+# define ASIO_WINDOWS 1+# elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__)+# define ASIO_WINDOWS 1+# elif defined(ASIO_WINDOWS_APP)+# define ASIO_WINDOWS 1+# endif // defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_WINDOWS)+# endif // !defined(ASIO_WINDOWS_RUNTIME)+#endif // !defined(ASIO_WINDOWS)++// Windows: target OS version.+#if defined(ASIO_WINDOWS) || defined(__CYGWIN__)+# if !defined(_WIN32_WINNT) && !defined(_WIN32_WINDOWS)+# if defined(_MSC_VER) || (defined(__BORLANDC__) && !defined(__clang__))+# pragma message( \+ "Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately. For example:\n"\+ "- add -D_WIN32_WINNT=0x0601 to the compiler command line; or\n"\+ "- add _WIN32_WINNT=0x0601 to your project's Preprocessor Definitions.\n"\+ "Assuming _WIN32_WINNT=0x0601 (i.e. Windows 7 target).")+# else // defined(_MSC_VER) || (defined(__BORLANDC__) && !defined(__clang__))+# warning Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately.+# warning For example, add -D_WIN32_WINNT=0x0601 to the compiler command line.+# warning Assuming _WIN32_WINNT=0x0601 (i.e. Windows 7 target).+# endif // defined(_MSC_VER) || (defined(__BORLANDC__) && !defined(__clang__))+# define _WIN32_WINNT 0x0601+# endif // !defined(_WIN32_WINNT) && !defined(_WIN32_WINDOWS)+# if defined(_MSC_VER)+# if defined(_WIN32) && !defined(WIN32)+# if !defined(_WINSOCK2API_)+# define WIN32 // Needed for correct types in winsock2.h+# else // !defined(_WINSOCK2API_)+# error Please define the macro WIN32 in your compiler options+# endif // !defined(_WINSOCK2API_)+# endif // defined(_WIN32) && !defined(WIN32)+# endif // defined(_MSC_VER)+# if defined(__BORLANDC__)+# if defined(__WIN32__) && !defined(WIN32)+# if !defined(_WINSOCK2API_)+# define WIN32 // Needed for correct types in winsock2.h+# else // !defined(_WINSOCK2API_)+# error Please define the macro WIN32 in your compiler options+# endif // !defined(_WINSOCK2API_)+# endif // defined(__WIN32__) && !defined(WIN32)+# endif // defined(__BORLANDC__)+# if defined(__CYGWIN__)+# if !defined(__USE_W32_SOCKETS)+# error You must add -D__USE_W32_SOCKETS to your compiler options.+# endif // !defined(__USE_W32_SOCKETS)+# endif // defined(__CYGWIN__)+#endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__)++// Windows: minimise header inclusion.+#if defined(ASIO_WINDOWS) || defined(__CYGWIN__)+# if !defined(ASIO_NO_WIN32_LEAN_AND_MEAN)+# if !defined(WIN32_LEAN_AND_MEAN)+# define WIN32_LEAN_AND_MEAN+# endif // !defined(WIN32_LEAN_AND_MEAN)+# endif // !defined(ASIO_NO_WIN32_LEAN_AND_MEAN)+#endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__)++// Windows: suppress definition of "min" and "max" macros.+#if defined(ASIO_WINDOWS) || defined(__CYGWIN__)+# if !defined(ASIO_NO_NOMINMAX)+# if !defined(NOMINMAX)+# define NOMINMAX 1+# endif // !defined(NOMINMAX)+# endif // !defined(ASIO_NO_NOMINMAX)+#endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__)++// Windows: IO Completion Ports.+#if !defined(ASIO_HAS_IOCP)+# if defined(ASIO_WINDOWS) || defined(__CYGWIN__)+# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0400)+# if !defined(UNDER_CE) && !defined(ASIO_WINDOWS_APP)+# if !defined(ASIO_DISABLE_IOCP)+# define ASIO_HAS_IOCP 1+# endif // !defined(ASIO_DISABLE_IOCP)+# endif // !defined(UNDER_CE) && !defined(ASIO_WINDOWS_APP)+# endif // defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0400)+# endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__)+#endif // !defined(ASIO_HAS_IOCP)++// On POSIX (and POSIX-like) platforms we need to include unistd.h in order to+// get access to the various platform feature macros, e.g. to be able to test+// for threads support.+#if !defined(ASIO_HAS_UNISTD_H)+# if !defined(ASIO_HAS_BOOST_CONFIG)+# if defined(unix) \+ || defined(__unix) \+ || defined(_XOPEN_SOURCE) \+ || defined(_POSIX_SOURCE) \+ || (defined(__MACH__) && defined(__APPLE__)) \+ || defined(__FreeBSD__) \+ || defined(__NetBSD__) \+ || defined(__OpenBSD__) \+ || defined(__linux__) \+ || defined(__HAIKU__)+# define ASIO_HAS_UNISTD_H 1+# endif+# endif // !defined(ASIO_HAS_BOOST_CONFIG)+#endif // !defined(ASIO_HAS_UNISTD_H)+#if defined(ASIO_HAS_UNISTD_H)+# include <unistd.h>+#endif // defined(ASIO_HAS_UNISTD_H)++// Linux: epoll, eventfd and timerfd.+#if defined(__linux__)+# include <linux/version.h>+# if !defined(ASIO_HAS_EPOLL)+# if !defined(ASIO_DISABLE_EPOLL)+# if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,45)+# define ASIO_HAS_EPOLL 1+# endif // LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,45)+# endif // !defined(ASIO_DISABLE_EPOLL)+# endif // !defined(ASIO_HAS_EPOLL)+# if !defined(ASIO_HAS_EVENTFD)+# if !defined(ASIO_DISABLE_EVENTFD)+# if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)+# define ASIO_HAS_EVENTFD 1+# endif // LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)+# endif // !defined(ASIO_DISABLE_EVENTFD)+# endif // !defined(ASIO_HAS_EVENTFD)+# if !defined(ASIO_HAS_TIMERFD)+# if defined(ASIO_HAS_EPOLL)+# if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 8)+# define ASIO_HAS_TIMERFD 1+# endif // (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 8)+# endif // defined(ASIO_HAS_EPOLL)+# endif // !defined(ASIO_HAS_TIMERFD)+#endif // defined(__linux__)++// Linux: io_uring is used instead of epoll.+#if !defined(ASIO_HAS_IO_URING_AS_DEFAULT)+# if !defined(ASIO_HAS_EPOLL) && defined(ASIO_HAS_IO_URING)+# define ASIO_HAS_IO_URING_AS_DEFAULT 1+# endif // !defined(ASIO_HAS_EPOLL) && defined(ASIO_HAS_IO_URING)+#endif // !defined(ASIO_HAS_IO_URING_AS_DEFAULT)++// Mac OS X, FreeBSD, NetBSD, OpenBSD: kqueue.+#if (defined(__MACH__) && defined(__APPLE__)) \+ || defined(__FreeBSD__) \+ || defined(__NetBSD__) \+ || defined(__OpenBSD__)+# if !defined(ASIO_HAS_KQUEUE)+# if !defined(ASIO_DISABLE_KQUEUE)+# define ASIO_HAS_KQUEUE 1+# endif // !defined(ASIO_DISABLE_KQUEUE)+# endif // !defined(ASIO_HAS_KQUEUE)+#endif // (defined(__MACH__) && defined(__APPLE__))+ // || defined(__FreeBSD__)+ // || defined(__NetBSD__)+ // || defined(__OpenBSD__)++// Solaris: /dev/poll.+#if defined(__sun)+# if !defined(ASIO_HAS_DEV_POLL)+# if !defined(ASIO_DISABLE_DEV_POLL)+# define ASIO_HAS_DEV_POLL 1+# endif // !defined(ASIO_DISABLE_DEV_POLL)+# endif // !defined(ASIO_HAS_DEV_POLL)+#endif // defined(__sun)++// Serial ports.+#if !defined(ASIO_HAS_SERIAL_PORT)+# if defined(ASIO_HAS_IOCP) \+ || !defined(ASIO_WINDOWS) \+ && !defined(ASIO_WINDOWS_RUNTIME) \+ && !defined(__CYGWIN__)+# if !defined(__SYMBIAN32__)+# if !defined(ASIO_DISABLE_SERIAL_PORT)+# define ASIO_HAS_SERIAL_PORT 1+# endif // !defined(ASIO_DISABLE_SERIAL_PORT)+# endif // !defined(__SYMBIAN32__)+# endif // defined(ASIO_HAS_IOCP)+ // || !defined(ASIO_WINDOWS)+ // && !defined(ASIO_WINDOWS_RUNTIME)+ // && !defined(__CYGWIN__)+#endif // !defined(ASIO_HAS_SERIAL_PORT)++// Windows: stream handles.+#if !defined(ASIO_HAS_WINDOWS_STREAM_HANDLE)+# if !defined(ASIO_DISABLE_WINDOWS_STREAM_HANDLE)+# if defined(ASIO_HAS_IOCP)+# define ASIO_HAS_WINDOWS_STREAM_HANDLE 1+# endif // defined(ASIO_HAS_IOCP)+# endif // !defined(ASIO_DISABLE_WINDOWS_STREAM_HANDLE)+#endif // !defined(ASIO_HAS_WINDOWS_STREAM_HANDLE)++// Windows: random access handles.+#if !defined(ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE)+# if !defined(ASIO_DISABLE_WINDOWS_RANDOM_ACCESS_HANDLE)+# if defined(ASIO_HAS_IOCP)+# define ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE 1+# endif // defined(ASIO_HAS_IOCP)+# endif // !defined(ASIO_DISABLE_WINDOWS_RANDOM_ACCESS_HANDLE)+#endif // !defined(ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE)++// Windows: object handles.+#if !defined(ASIO_HAS_WINDOWS_OBJECT_HANDLE)+# if !defined(ASIO_DISABLE_WINDOWS_OBJECT_HANDLE)+# if defined(ASIO_WINDOWS) || defined(__CYGWIN__)+# if !defined(UNDER_CE) && !defined(ASIO_WINDOWS_APP)+# define ASIO_HAS_WINDOWS_OBJECT_HANDLE 1+# endif // !defined(UNDER_CE) && !defined(ASIO_WINDOWS_APP)+# endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__)+# endif // !defined(ASIO_DISABLE_WINDOWS_OBJECT_HANDLE)+#endif // !defined(ASIO_HAS_WINDOWS_OBJECT_HANDLE)++// Windows: OVERLAPPED wrapper.+#if !defined(ASIO_HAS_WINDOWS_OVERLAPPED_PTR)+# if !defined(ASIO_DISABLE_WINDOWS_OVERLAPPED_PTR)+# if defined(ASIO_HAS_IOCP)+# define ASIO_HAS_WINDOWS_OVERLAPPED_PTR 1+# endif // defined(ASIO_HAS_IOCP)+# endif // !defined(ASIO_DISABLE_WINDOWS_OVERLAPPED_PTR)+#endif // !defined(ASIO_HAS_WINDOWS_OVERLAPPED_PTR)++// POSIX: stream-oriented file descriptors.+#if !defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR)+# if !defined(ASIO_DISABLE_POSIX_STREAM_DESCRIPTOR)+# if !defined(ASIO_WINDOWS) \+ && !defined(ASIO_WINDOWS_RUNTIME) \+ && !defined(__CYGWIN__)+# define ASIO_HAS_POSIX_STREAM_DESCRIPTOR 1+# endif // !defined(ASIO_WINDOWS)+ // && !defined(ASIO_WINDOWS_RUNTIME)+ // && !defined(__CYGWIN__)+# endif // !defined(ASIO_DISABLE_POSIX_STREAM_DESCRIPTOR)+#endif // !defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR)++// UNIX domain sockets.+#if !defined(ASIO_HAS_LOCAL_SOCKETS)+# if !defined(ASIO_DISABLE_LOCAL_SOCKETS)+# if !defined(ASIO_WINDOWS_RUNTIME)+# define ASIO_HAS_LOCAL_SOCKETS 1+# endif // !defined(ASIO_WINDOWS_RUNTIME)+# endif // !defined(ASIO_DISABLE_LOCAL_SOCKETS)+#endif // !defined(ASIO_HAS_LOCAL_SOCKETS)++// Files.+#if !defined(ASIO_HAS_FILE)+# if !defined(ASIO_DISABLE_FILE)+# if defined(ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE)+# define ASIO_HAS_FILE 1+# elif defined(ASIO_HAS_IO_URING)+# define ASIO_HAS_FILE 1+# endif // defined(ASIO_HAS_IO_URING)+# endif // !defined(ASIO_DISABLE_FILE)+#endif // !defined(ASIO_HAS_FILE)++// Pipes.+#if !defined(ASIO_HAS_PIPE)+# if defined(ASIO_HAS_IOCP) \+ || !defined(ASIO_WINDOWS) \+ && !defined(ASIO_WINDOWS_RUNTIME) \+ && !defined(__CYGWIN__)+# if !defined(__SYMBIAN32__)+# if !defined(ASIO_DISABLE_PIPE)+# define ASIO_HAS_PIPE 1+# endif // !defined(ASIO_DISABLE_PIPE)+# endif // !defined(__SYMBIAN32__)+# endif // defined(ASIO_HAS_IOCP)+ // || !defined(ASIO_WINDOWS)+ // && !defined(ASIO_WINDOWS_RUNTIME)+ // && !defined(__CYGWIN__)+#endif // !defined(ASIO_HAS_PIPE)++// Can use sigaction() instead of signal().+#if !defined(ASIO_HAS_SIGACTION)+# if !defined(ASIO_DISABLE_SIGACTION)+# if !defined(ASIO_WINDOWS) \+ && !defined(ASIO_WINDOWS_RUNTIME) \+ && !defined(__CYGWIN__)+# define ASIO_HAS_SIGACTION 1+# endif // !defined(ASIO_WINDOWS)+ // && !defined(ASIO_WINDOWS_RUNTIME)+ // && !defined(__CYGWIN__)+# endif // !defined(ASIO_DISABLE_SIGACTION)+#endif // !defined(ASIO_HAS_SIGACTION)++// Can use signal().+#if !defined(ASIO_HAS_SIGNAL)+# if !defined(ASIO_DISABLE_SIGNAL)+# if !defined(UNDER_CE)+# define ASIO_HAS_SIGNAL 1+# endif // !defined(UNDER_CE)+# endif // !defined(ASIO_DISABLE_SIGNAL)+#endif // !defined(ASIO_HAS_SIGNAL)++// Can use getaddrinfo() and getnameinfo().+#if !defined(ASIO_HAS_GETADDRINFO)+# if !defined(ASIO_DISABLE_GETADDRINFO)+# if defined(ASIO_WINDOWS) || defined(__CYGWIN__)+# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501)+# define ASIO_HAS_GETADDRINFO 1+# elif defined(UNDER_CE)+# define ASIO_HAS_GETADDRINFO 1+# endif // defined(UNDER_CE)+# elif defined(__MACH__) && defined(__APPLE__)+# if defined(__MAC_OS_X_VERSION_MIN_REQUIRED)+# if (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1050)+# define ASIO_HAS_GETADDRINFO 1+# endif // (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1050)+# else // defined(__MAC_OS_X_VERSION_MIN_REQUIRED)+# define ASIO_HAS_GETADDRINFO 1+# endif // defined(__MAC_OS_X_VERSION_MIN_REQUIRED)+# else // defined(__MACH__) && defined(__APPLE__)+# define ASIO_HAS_GETADDRINFO 1+# endif // defined(__MACH__) && defined(__APPLE__)+# endif // !defined(ASIO_DISABLE_GETADDRINFO)+#endif // !defined(ASIO_HAS_GETADDRINFO)++// Whether standard iostreams are disabled.+#if !defined(ASIO_NO_IOSTREAM)+# if defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_NO_IOSTREAM)+# define ASIO_NO_IOSTREAM 1+# endif // !defined(BOOST_NO_IOSTREAM)+#endif // !defined(ASIO_NO_IOSTREAM)++// Whether exception handling is disabled.+#if !defined(ASIO_NO_EXCEPTIONS)+# if defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_NO_EXCEPTIONS)+# define ASIO_NO_EXCEPTIONS 1+# endif // !defined(BOOST_NO_EXCEPTIONS)+#endif // !defined(ASIO_NO_EXCEPTIONS)++// Whether the typeid operator is supported.+#if !defined(ASIO_NO_TYPEID)+# if defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_NO_TYPEID)+# define ASIO_NO_TYPEID 1+# endif // !defined(BOOST_NO_TYPEID)+#endif // !defined(ASIO_NO_TYPEID)++// Threads.+#if !defined(ASIO_HAS_THREADS)+# if !defined(ASIO_DISABLE_THREADS)+# if defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_HAS_THREADS)+# define ASIO_HAS_THREADS 1+# elif defined(__GNUC__) && !defined(__MINGW32__) \+ && !defined(linux) && !defined(__linux) && !defined(__linux__)+# define ASIO_HAS_THREADS 1+# elif defined(_MT) || defined(__MT__)+# define ASIO_HAS_THREADS 1+# elif defined(_REENTRANT)+# define ASIO_HAS_THREADS 1+# elif defined(__APPLE__)+# define ASIO_HAS_THREADS 1+# elif defined(__HAIKU__)+# define ASIO_HAS_THREADS 1+# elif defined(_POSIX_THREADS) && (_POSIX_THREADS + 0 >= 0)+# define ASIO_HAS_THREADS 1+# elif defined(_PTHREADS)+# define ASIO_HAS_THREADS 1+# endif // defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_HAS_THREADS)+# endif // !defined(ASIO_DISABLE_THREADS)+#endif // !defined(ASIO_HAS_THREADS)++// POSIX threads.+#if !defined(ASIO_HAS_PTHREADS)+# if defined(ASIO_HAS_THREADS)+# if defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_HAS_PTHREADS)+# define ASIO_HAS_PTHREADS 1+# elif defined(_POSIX_THREADS) && (_POSIX_THREADS + 0 >= 0)+# define ASIO_HAS_PTHREADS 1+# elif defined(__HAIKU__)+# define ASIO_HAS_PTHREADS 1+# endif // defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_HAS_PTHREADS)+# endif // defined(ASIO_HAS_THREADS)+#endif // !defined(ASIO_HAS_PTHREADS)++// Helper to prevent macro expansion.+#define ASIO_PREVENT_MACRO_SUBSTITUTION++// Helper to define in-class constants.+#if !defined(ASIO_STATIC_CONSTANT)+# if !defined(ASIO_DISABLE_BOOST_STATIC_CONSTANT)+# define ASIO_STATIC_CONSTANT(type, assignment) \+ BOOST_STATIC_CONSTANT(type, assignment)+# else // !defined(ASIO_DISABLE_BOOST_STATIC_CONSTANT)+# define ASIO_STATIC_CONSTANT(type, assignment) \+ static const type assignment+# endif // !defined(ASIO_DISABLE_BOOST_STATIC_CONSTANT)+#endif // !defined(ASIO_STATIC_CONSTANT)++// Boost align library.+#if !defined(ASIO_HAS_BOOST_ALIGN)+# if !defined(ASIO_DISABLE_BOOST_ALIGN)+# if defined(ASIO_HAS_BOOST_CONFIG) && (BOOST_VERSION >= 105600)+# define ASIO_HAS_BOOST_ALIGN 1+# endif // defined(ASIO_HAS_BOOST_CONFIG) && (BOOST_VERSION >= 105600)+# endif // !defined(ASIO_DISABLE_BOOST_ALIGN)+#endif // !defined(ASIO_HAS_BOOST_ALIGN)++// Boost array library.+#if !defined(ASIO_HAS_BOOST_ARRAY)+# if !defined(ASIO_DISABLE_BOOST_ARRAY)+# define ASIO_HAS_BOOST_ARRAY 1+# endif // !defined(ASIO_DISABLE_BOOST_ARRAY)+#endif // !defined(ASIO_HAS_BOOST_ARRAY)++// Boost assert macro.+#if !defined(ASIO_HAS_BOOST_ASSERT)+# if !defined(ASIO_DISABLE_BOOST_ASSERT)+# define ASIO_HAS_BOOST_ASSERT 1+# endif // !defined(ASIO_DISABLE_BOOST_ASSERT)+#endif // !defined(ASIO_HAS_BOOST_ASSERT)++// Boost limits header.+#if !defined(ASIO_HAS_BOOST_LIMITS)+# if !defined(ASIO_DISABLE_BOOST_LIMITS)+# define ASIO_HAS_BOOST_LIMITS 1+# endif // !defined(ASIO_DISABLE_BOOST_LIMITS)+#endif // !defined(ASIO_HAS_BOOST_LIMITS)++// Boost throw_exception function.+#if !defined(ASIO_HAS_BOOST_THROW_EXCEPTION)+# if !defined(ASIO_DISABLE_BOOST_THROW_EXCEPTION)+# define ASIO_HAS_BOOST_THROW_EXCEPTION 1+# endif // !defined(ASIO_DISABLE_BOOST_THROW_EXCEPTION)+#endif // !defined(ASIO_HAS_BOOST_THROW_EXCEPTION)++// Boost regex library.+#if !defined(ASIO_HAS_BOOST_REGEX)+# if !defined(ASIO_DISABLE_BOOST_REGEX)+# define ASIO_HAS_BOOST_REGEX 1+# endif // !defined(ASIO_DISABLE_BOOST_REGEX)+#endif // !defined(ASIO_HAS_BOOST_REGEX)++// Boost bind function.+#if !defined(ASIO_HAS_BOOST_BIND)+# if !defined(ASIO_DISABLE_BOOST_BIND)+# define ASIO_HAS_BOOST_BIND 1+# endif // !defined(ASIO_DISABLE_BOOST_BIND)+#endif // !defined(ASIO_HAS_BOOST_BIND)++// Boost's BOOST_WORKAROUND macro.+#if !defined(ASIO_HAS_BOOST_WORKAROUND)+# if !defined(ASIO_DISABLE_BOOST_WORKAROUND)+# define ASIO_HAS_BOOST_WORKAROUND 1+# endif // !defined(ASIO_DISABLE_BOOST_WORKAROUND)+#endif // !defined(ASIO_HAS_BOOST_WORKAROUND)++// Microsoft Visual C++'s secure C runtime library.+#if !defined(ASIO_HAS_SECURE_RTL)+# if !defined(ASIO_DISABLE_SECURE_RTL)+# if defined(ASIO_MSVC) \+ && (ASIO_MSVC >= 1400) \+ && !defined(UNDER_CE)+# define ASIO_HAS_SECURE_RTL 1+# endif // defined(ASIO_MSVC)+ // && (ASIO_MSVC >= 1400)+ // && !defined(UNDER_CE)+# endif // !defined(ASIO_DISABLE_SECURE_RTL)+#endif // !defined(ASIO_HAS_SECURE_RTL)++// Handler hooking. Disabled for ancient Borland C++ and gcc compilers.+#if !defined(ASIO_HAS_HANDLER_HOOKS)+# if !defined(ASIO_DISABLE_HANDLER_HOOKS)+# if defined(__GNUC__)+# if (__GNUC__ >= 3)+# define ASIO_HAS_HANDLER_HOOKS 1+# endif // (__GNUC__ >= 3)+# elif !defined(__BORLANDC__) || defined(__clang__)+# define ASIO_HAS_HANDLER_HOOKS 1+# endif // !defined(__BORLANDC__) || defined(__clang__)+# endif // !defined(ASIO_DISABLE_HANDLER_HOOKS)+#endif // !defined(ASIO_HAS_HANDLER_HOOKS)++// Support for the __thread keyword extension.+#if !defined(ASIO_DISABLE_THREAD_KEYWORD_EXTENSION)+# if defined(__linux__)+# if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))+# if ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)+# if !defined(__INTEL_COMPILER) && !defined(__ICL) \+ && !(defined(__clang__) && defined(__ANDROID__))+# define ASIO_HAS_THREAD_KEYWORD_EXTENSION 1+# define ASIO_THREAD_KEYWORD __thread+# elif defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1100)+# define ASIO_HAS_THREAD_KEYWORD_EXTENSION 1+# endif // defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1100)+ // && !(defined(__clang__) && defined(__ANDROID__))+# endif // ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)+# endif // defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))+# endif // defined(__linux__)+# if defined(ASIO_MSVC) && defined(ASIO_WINDOWS_RUNTIME)+# if (_MSC_VER >= 1700)+# define ASIO_HAS_THREAD_KEYWORD_EXTENSION 1+# define ASIO_THREAD_KEYWORD __declspec(thread)+# endif // (_MSC_VER >= 1700)+# endif // defined(ASIO_MSVC) && defined(ASIO_WINDOWS_RUNTIME)+#endif // !defined(ASIO_DISABLE_THREAD_KEYWORD_EXTENSION)+#if !defined(ASIO_THREAD_KEYWORD)+# define ASIO_THREAD_KEYWORD __thread+#endif // !defined(ASIO_THREAD_KEYWORD)++// Support for POSIX ssize_t typedef.+#if !defined(ASIO_DISABLE_SSIZE_T)+# if defined(__linux__) \+ || (defined(__MACH__) && defined(__APPLE__))+# define ASIO_HAS_SSIZE_T 1+# endif // defined(__linux__)+ // || (defined(__MACH__) && defined(__APPLE__))+#endif // !defined(ASIO_DISABLE_SSIZE_T)++// Helper macros to manage transition away from error_code return values.+#if defined(ASIO_NO_DEPRECATED)+# define ASIO_SYNC_OP_VOID void+# define ASIO_SYNC_OP_VOID_RETURN(e) return+#else // defined(ASIO_NO_DEPRECATED)+# define ASIO_SYNC_OP_VOID asio::error_code+# define ASIO_SYNC_OP_VOID_RETURN(e) return e+#endif // defined(ASIO_NO_DEPRECATED)++// Newer gcc, clang need special treatment to suppress unused typedef warnings.+#if defined(__clang__)+# if defined(__apple_build_version__)+# if (__clang_major__ >= 7)+# define ASIO_UNUSED_TYPEDEF __attribute__((__unused__))+# endif // (__clang_major__ >= 7)+# elif ((__clang_major__ == 3) && (__clang_minor__ >= 6)) \+ || (__clang_major__ > 3)+# define ASIO_UNUSED_TYPEDEF __attribute__((__unused__))+# endif // ((__clang_major__ == 3) && (__clang_minor__ >= 6))+ // || (__clang_major__ > 3)+#elif defined(__GNUC__)+# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4)+# define ASIO_UNUSED_TYPEDEF __attribute__((__unused__))+# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4)+#endif // defined(__GNUC__)+#if !defined(ASIO_UNUSED_TYPEDEF)+# define ASIO_UNUSED_TYPEDEF+#endif // !defined(ASIO_UNUSED_TYPEDEF)++// Some versions of gcc generate spurious warnings about unused variables.+#if defined(__GNUC__)+# if (__GNUC__ >= 4)+# define ASIO_UNUSED_VARIABLE __attribute__((__unused__))+# endif // (__GNUC__ >= 4)+#endif // defined(__GNUC__)+#if !defined(ASIO_UNUSED_VARIABLE)+# define ASIO_UNUSED_VARIABLE+#endif // !defined(ASIO_UNUSED_VARIABLE)++// Helper macro to tell the optimiser what may be assumed to be true.+#if defined(ASIO_MSVC)+# define ASIO_ASSUME(expr) __assume(expr)+#elif defined(__clang__)+# if __has_builtin(__builtin_assume)+# define ASIO_ASSUME(expr) __builtin_assume(expr)+# endif // __has_builtin(__builtin_assume)+#elif defined(__GNUC__)+# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4)+# define ASIO_ASSUME(expr) if (expr) {} else { __builtin_unreachable(); }+# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4)+#endif // defined(__GNUC__)+#if !defined(ASIO_ASSUME)+# define ASIO_ASSUME(expr) (void)0+#endif // !defined(ASIO_ASSUME)++// Support the co_await keyword on compilers known to allow it.+#if !defined(ASIO_HAS_CO_AWAIT)+# if !defined(ASIO_DISABLE_CO_AWAIT)+# if defined(ASIO_MSVC)+# if (_MSC_VER >= 1928) && (_MSVC_LANG >= 201705) && !defined(__clang__)+# define ASIO_HAS_CO_AWAIT 1+# elif (_MSC_FULL_VER >= 190023506)+# if defined(_RESUMABLE_FUNCTIONS_SUPPORTED)+# define ASIO_HAS_CO_AWAIT 1+# endif // defined(_RESUMABLE_FUNCTIONS_SUPPORTED)+# endif // (_MSC_FULL_VER >= 190023506)+# elif defined(__clang__)+# if (__clang_major__ >= 14)+# if (__cplusplus >= 202002) && (__cpp_impl_coroutine >= 201902)+# if __has_include(<coroutine>)+# define ASIO_HAS_CO_AWAIT 1+# endif // __has_include(<coroutine>)+# elif (__cplusplus >= 201703) && (__cpp_coroutines >= 201703)+# if __has_include(<experimental/coroutine>)+# define ASIO_HAS_CO_AWAIT 1+# endif // __has_include(<experimental/coroutine>)+# endif // (__cplusplus >= 201703) && (__cpp_coroutines >= 201703)+# else // (__clang_major__ >= 14)+# if (__cplusplus >= 201703) && (__cpp_coroutines >= 201703)+# if __has_include(<experimental/coroutine>)+# define ASIO_HAS_CO_AWAIT 1+# endif // __has_include(<experimental/coroutine>)+# endif // (__cplusplus >= 201703) && (__cpp_coroutines >= 201703)+# endif // (__clang_major__ >= 14)+# elif defined(__GNUC__)+# if (__cplusplus >= 201709) && (__cpp_impl_coroutine >= 201902)+# if __has_include(<coroutine>)+# define ASIO_HAS_CO_AWAIT 1+# endif // __has_include(<coroutine>)+# endif // (__cplusplus >= 201709) && (__cpp_impl_coroutine >= 201902)+# endif // defined(__GNUC__)+# endif // !defined(ASIO_DISABLE_CO_AWAIT)+#endif // !defined(ASIO_HAS_CO_AWAIT)++// Standard library support for coroutines.+#if !defined(ASIO_HAS_STD_COROUTINE)+# if !defined(ASIO_DISABLE_STD_COROUTINE)+# if defined(ASIO_MSVC)+# if (_MSC_VER >= 1928) && (_MSVC_LANG >= 201705)+# define ASIO_HAS_STD_COROUTINE 1+# endif // (_MSC_VER >= 1928) && (_MSVC_LANG >= 201705)+# elif defined(__clang__)+# if (__clang_major__ >= 14)+# if (__cplusplus >= 202002) && (__cpp_impl_coroutine >= 201902)+# if __has_include(<coroutine>)+# define ASIO_HAS_STD_COROUTINE 1+# endif // __has_include(<coroutine>)+# endif // (__cplusplus >= 202002) && (__cpp_impl_coroutine >= 201902)+# endif // (__clang_major__ >= 14)+# elif defined(__GNUC__)+# if (__cplusplus >= 201709) && (__cpp_impl_coroutine >= 201902)+# if __has_include(<coroutine>)+# define ASIO_HAS_STD_COROUTINE 1+# endif // __has_include(<coroutine>)+# endif // (__cplusplus >= 201709) && (__cpp_impl_coroutine >= 201902)+# endif // defined(__GNUC__)+# endif // !defined(ASIO_DISABLE_STD_COROUTINE)+#endif // !defined(ASIO_HAS_STD_COROUTINE)++// Compiler support for the the [[nodiscard]] attribute.+#if !defined(ASIO_NODISCARD)+# if defined(__has_cpp_attribute)+# if __has_cpp_attribute(nodiscard)+# if (__cplusplus >= 201703)+# define ASIO_NODISCARD [[nodiscard]]+# endif // (__cplusplus >= 201703)+# endif // __has_cpp_attribute(nodiscard)+# endif // defined(__has_cpp_attribute)+#endif // !defined(ASIO_NODISCARD)+#if !defined(ASIO_NODISCARD)+# define ASIO_NODISCARD+#endif // !defined(ASIO_NODISCARD)++// Kernel support for MSG_NOSIGNAL.+#if !defined(ASIO_HAS_MSG_NOSIGNAL)+# if defined(__linux__)+# define ASIO_HAS_MSG_NOSIGNAL 1+# elif defined(_POSIX_VERSION)+# if (_POSIX_VERSION >= 200809L)+# define ASIO_HAS_MSG_NOSIGNAL 1+# endif // _POSIX_VERSION >= 200809L+# endif // defined(_POSIX_VERSION)+#endif // !defined(ASIO_HAS_MSG_NOSIGNAL)++// Standard library support for std::hash.+#if !defined(ASIO_HAS_STD_HASH)+# if !defined(ASIO_DISABLE_STD_HASH)+# if defined(__clang__)+# if defined(ASIO_HAS_CLANG_LIBCXX)+# define ASIO_HAS_STD_HASH 1+# elif (__cplusplus >= 201103)+# define ASIO_HAS_STD_HASH 1+# endif // (__cplusplus >= 201103)+# elif defined(__GNUC__)+# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)+# if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# define ASIO_HAS_STD_HASH 1+# endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)+# endif // defined(__GNUC__)+# if defined(ASIO_MSVC)+# if (_MSC_VER >= 1700)+# define ASIO_HAS_STD_HASH 1+# endif // (_MSC_VER >= 1700)+# endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_STD_HASH)+#endif // !defined(ASIO_HAS_STD_HASH)++// Standard library support for std::to_address.+#if !defined(ASIO_HAS_STD_TO_ADDRESS)+# if !defined(ASIO_DISABLE_STD_TO_ADDRESS)+# if defined(__clang__)+# if (__cplusplus >= 202002)+# define ASIO_HAS_STD_TO_ADDRESS 1+# endif // (__cplusplus >= 202002)+# elif defined(__GNUC__)+# if (__GNUC__ >= 8)+# if (__cplusplus >= 202002)+# define ASIO_HAS_STD_TO_ADDRESS 1+# endif // (__cplusplus >= 202002)+# endif // (__GNUC__ >= 8)+# endif // defined(__GNUC__)+# if defined(ASIO_MSVC)+# if (_MSC_VER >= 1922) && (_MSVC_LANG >= 202002)+# define ASIO_HAS_STD_TO_ADDRESS 1+# endif // (_MSC_VER >= 1922) && (_MSVC_LANG >= 202002)+# endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_STD_TO_ADDRESS)+#endif // !defined(ASIO_HAS_STD_TO_ADDRESS)++// Standard library support for snprintf.+#if !defined(ASIO_HAS_SNPRINTF)+# if !defined(ASIO_DISABLE_SNPRINTF)+# if defined(__apple_build_version__)+# if (__clang_major__ >= 14)+# define ASIO_HAS_SNPRINTF 1+# endif // (__clang_major__ >= 14)+# endif // defined(__apple_build_version__) # endif // !defined(ASIO_DISABLE_SNPRINTF) #endif // !defined(ASIO_HAS_SNPRINTF)
link/modules/asio-standalone/asio/include/asio/detail/consuming_buffers.hpp view
@@ -2,7 +2,7 @@ // detail/consuming_buffers.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -35,17 +35,21 @@ }; template <typename Elem, std::size_t N>-struct prepared_buffers_max<boost::array<Elem, N>>+struct prepared_buffers_max<boost::array<Elem, N> > { enum { value = N }; }; +#if defined(ASIO_HAS_STD_ARRAY)+ template <typename Elem, std::size_t N>-struct prepared_buffers_max<std::array<Elem, N>>+struct prepared_buffers_max<std::array<Elem, N> > { enum { value = N }; }; +#endif // defined(ASIO_HAS_STD_ARRAY)+ // A buffer sequence used to represent a subsequence of the buffers. template <typename Buffer, std::size_t MaxBuffers> struct prepared_buffers@@ -197,39 +201,77 @@ template <> class consuming_buffers<mutable_buffer, mutable_buffer, const mutable_buffer*>- : public consuming_single_buffer<mutable_buffer>+ : public consuming_single_buffer<ASIO_MUTABLE_BUFFER> { public: explicit consuming_buffers(const mutable_buffer& buffer)- : consuming_single_buffer<mutable_buffer>(buffer)+ : consuming_single_buffer<ASIO_MUTABLE_BUFFER>(buffer) { } }; template <> class consuming_buffers<const_buffer, mutable_buffer, const mutable_buffer*>- : public consuming_single_buffer<const_buffer>+ : public consuming_single_buffer<ASIO_CONST_BUFFER> { public: explicit consuming_buffers(const mutable_buffer& buffer)- : consuming_single_buffer<const_buffer>(buffer)+ : consuming_single_buffer<ASIO_CONST_BUFFER>(buffer) { } }; template <> class consuming_buffers<const_buffer, const_buffer, const const_buffer*>- : public consuming_single_buffer<const_buffer>+ : public consuming_single_buffer<ASIO_CONST_BUFFER> { public: explicit consuming_buffers(const const_buffer& buffer)- : consuming_single_buffer<const_buffer>(buffer)+ : consuming_single_buffer<ASIO_CONST_BUFFER>(buffer) { } }; +#if !defined(ASIO_NO_DEPRECATED)+ template <> class consuming_buffers<mutable_buffer,+ mutable_buffers_1, const mutable_buffer*>+ : public consuming_single_buffer<ASIO_MUTABLE_BUFFER>+{+public:+ explicit consuming_buffers(const mutable_buffers_1& buffer)+ : consuming_single_buffer<ASIO_MUTABLE_BUFFER>(buffer)+ {+ }+};++template <>+class consuming_buffers<const_buffer, mutable_buffers_1, const mutable_buffer*>+ : public consuming_single_buffer<ASIO_CONST_BUFFER>+{+public:+ explicit consuming_buffers(const mutable_buffers_1& buffer)+ : consuming_single_buffer<ASIO_CONST_BUFFER>(buffer)+ {+ }+};++template <>+class consuming_buffers<const_buffer, const_buffers_1, const const_buffer*>+ : public consuming_single_buffer<ASIO_CONST_BUFFER>+{+public:+ explicit consuming_buffers(const const_buffers_1& buffer)+ : consuming_single_buffer<ASIO_CONST_BUFFER>(buffer)+ {+ }+};++#endif // !defined(ASIO_NO_DEPRECATED)++template <>+class consuming_buffers<mutable_buffer, mutable_registered_buffer, const mutable_buffer*> : public consuming_single_buffer<mutable_registered_buffer> {@@ -314,6 +356,8 @@ std::size_t total_consumed_; }; +#if defined(ASIO_HAS_STD_ARRAY)+ template <typename Buffer, typename Elem> class consuming_buffers<Buffer, std::array<Elem, 2>, typename std::array<Elem, 2>::const_iterator>@@ -363,6 +407,8 @@ std::array<Elem, 2> buffers_; std::size_t total_consumed_; };++#endif // defined(ASIO_HAS_STD_ARRAY) // Specialisation for null_buffers to ensure that the null_buffers type is // always passed through to the underlying read or write operation.
link/modules/asio-standalone/asio/include/asio/detail/cstddef.hpp view
@@ -2,7 +2,7 @@ // detail/cstddef.hpp // ~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -20,7 +20,11 @@ namespace asio { +#if defined(ASIO_HAS_NULLPTR) using std::nullptr_t;+#else // defined(ASIO_HAS_NULLPTR)+struct nullptr_t {};+#endif // defined(ASIO_HAS_NULLPTR) } // namespace asio
link/modules/asio-standalone/asio/include/asio/detail/cstdint.hpp view
@@ -2,7 +2,7 @@ // detail/cstdint.hpp // ~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -16,10 +16,16 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"-#include <cstdint> +#if defined(ASIO_HAS_CSTDINT)+# include <cstdint>+#else // defined(ASIO_HAS_CSTDINT)+# include <boost/cstdint.hpp>+#endif // defined(ASIO_HAS_CSTDINT)+ namespace asio { +#if defined(ASIO_HAS_CSTDINT) using std::int16_t; using std::int_least16_t; using std::uint16_t;@@ -34,6 +40,22 @@ using std::uint_least64_t; using std::uintptr_t; using std::uintmax_t;+#else // defined(ASIO_HAS_CSTDINT)+using boost::int16_t;+using boost::int_least16_t;+using boost::uint16_t;+using boost::uint_least16_t;+using boost::int32_t;+using boost::int_least32_t;+using boost::uint32_t;+using boost::uint_least32_t;+using boost::int64_t;+using boost::int_least64_t;+using boost::uint64_t;+using boost::uint_least64_t;+using boost::uintptr_t;+using boost::uintmax_t;+#endif // defined(ASIO_HAS_CSTDINT) } // namespace asio
link/modules/asio-standalone/asio/include/asio/detail/date_time_fwd.hpp view
@@ -2,7 +2,7 @@ // detail/date_time_fwd.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/deadline_timer_service.hpp view
@@ -2,7 +2,7 @@ // detail/deadline_timer_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -19,7 +19,6 @@ #include <cstddef> #include "asio/associated_cancellation_slot.hpp" #include "asio/cancellation_type.hpp"-#include "asio/config.hpp" #include "asio/error.hpp" #include "asio/execution_context.hpp" #include "asio/detail/bind_handler.hpp"@@ -29,6 +28,7 @@ #include "asio/detail/socket_ops.hpp" #include "asio/detail/socket_types.hpp" #include "asio/detail/timer_queue.hpp"+#include "asio/detail/timer_queue_ptime.hpp" #include "asio/detail/timer_scheduler.hpp" #include "asio/detail/wait_handler.hpp" #include "asio/detail/wait_op.hpp"@@ -43,19 +43,16 @@ namespace asio { namespace detail { -template <typename TimeTraits>+template <typename Time_Traits> class deadline_timer_service- : public execution_context_service_base<deadline_timer_service<TimeTraits>>+ : public execution_context_service_base<deadline_timer_service<Time_Traits> > { public: // The time type.- typedef typename TimeTraits::time_type time_type;+ typedef typename Time_Traits::time_type time_type; // The duration type.- typedef typename TimeTraits::duration_type duration_type;-- // The allocator type.- typedef execution_context::allocator<void> allocator_type;+ typedef typename Time_Traits::duration_type duration_type; // The implementation type of the timer. This type is dependent on the // underlying implementation of the timer service.@@ -64,15 +61,13 @@ { time_type expiry; bool might_have_pending_waits;- typename timer_queue<TimeTraits, allocator_type>::per_timer_data timer_data;+ typename timer_queue<Time_Traits>::per_timer_data timer_data; }; // Constructor. deadline_timer_service(execution_context& context) : execution_context_service_base<- deadline_timer_service<TimeTraits>>(context),- timer_queue_(allocator_type(context),- config(context).get("timer", "heap_reserve", 0U)),+ deadline_timer_service<Time_Traits> >(context), scheduler_(asio::use_service<timer_scheduler>(context)) { scheduler_.init_task();@@ -108,11 +103,7 @@ void move_construct(implementation_type& impl, implementation_type& other_impl) {- if (other_impl.might_have_pending_waits)- {- scheduler_.move_timer(timer_queue_,- impl.timer_data, other_impl.timer_data);- }+ scheduler_.move_timer(timer_queue_, impl.timer_data, other_impl.timer_data); impl.expiry = other_impl.expiry; other_impl.expiry = time_type();@@ -209,7 +200,7 @@ // Get the expiry time for the timer relative to now. duration_type expires_from_now(const implementation_type& impl) const {- return TimeTraits::subtract(this->expiry(impl), TimeTraits::now());+ return Time_Traits::subtract(this->expiry(impl), Time_Traits::now()); } // Set the expiry time for the timer as an absolute time.@@ -227,7 +218,7 @@ const duration_type& expiry_time, asio::error_code& ec) { return expires_at(impl,- TimeTraits::add(TimeTraits::now(), expiry_time), ec);+ Time_Traits::add(Time_Traits::now(), expiry_time), ec); } // Set the expiry time for the timer relative to now.@@ -235,19 +226,19 @@ const duration_type& expiry_time, asio::error_code& ec) { return expires_at(impl,- TimeTraits::add(TimeTraits::now(), expiry_time), ec);+ Time_Traits::add(Time_Traits::now(), expiry_time), ec); } // Perform a blocking wait on the timer. void wait(implementation_type& impl, asio::error_code& ec) {- time_type now = TimeTraits::now();+ time_type now = Time_Traits::now(); ec = asio::error_code();- while (TimeTraits::less_than(now, impl.expiry) && !ec)+ while (Time_Traits::less_than(now, impl.expiry) && !ec) {- this->do_wait(TimeTraits::to_posix_duration(- TimeTraits::subtract(impl.expiry, now)), ec);- now = TimeTraits::now();+ this->do_wait(Time_Traits::to_posix_duration(+ Time_Traits::subtract(impl.expiry, now)), ec);+ now = Time_Traits::now(); } } @@ -256,7 +247,7 @@ void async_wait(implementation_type& impl, Handler& handler, const IoExecutor& io_ex) {- associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -306,7 +297,7 @@ { public: op_cancellation(deadline_timer_service* s,- typename timer_queue<TimeTraits, allocator_type>::per_timer_data* p)+ typename timer_queue<Time_Traits>::per_timer_data* p) : service_(s), timer_data_(p) {@@ -326,12 +317,11 @@ private: deadline_timer_service* service_;- typename timer_queue<TimeTraits, allocator_type>::per_timer_data*- timer_data_;+ typename timer_queue<Time_Traits>::per_timer_data* timer_data_; }; // The queue of timers.- timer_queue<TimeTraits, allocator_type> timer_queue_;+ timer_queue<Time_Traits> timer_queue_; // The object that schedules and executes timers. Usually a reactor. timer_scheduler& scheduler_;
link/modules/asio-standalone/asio/include/asio/detail/dependent_type.hpp view
@@ -2,7 +2,7 @@ // detail/dependent_type.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/descriptor_ops.hpp view
@@ -2,7 +2,7 @@ // detail/descriptor_ops.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/descriptor_read_op.hpp view
@@ -2,7 +2,7 @@ // detail/descriptor_read_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -97,7 +97,7 @@ Handler& handler, const IoExecutor& io_ex) : descriptor_read_op_base<MutableBufferSequence>(success_ec, descriptor, buffers, &descriptor_read_op::do_complete),- handler_(static_cast<Handler&&>(handler)),+ handler_(ASIO_MOVE_CAST(Handler)(handler)), work_(handler_, io_ex) { }@@ -115,7 +115,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); ASIO_ERROR_LOCATION(o->ec_);@@ -152,7 +152,7 @@ // Take ownership of the operation's outstanding work. immediate_handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); ASIO_ERROR_LOCATION(o->ec_);
link/modules/asio-standalone/asio/include/asio/detail/descriptor_write_op.hpp view
@@ -2,7 +2,7 @@ // detail/descriptor_write_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -96,7 +96,7 @@ Handler& handler, const IoExecutor& io_ex) : descriptor_write_op_base<ConstBufferSequence>(success_ec, descriptor, buffers, &descriptor_write_op::do_complete),- handler_(static_cast<Handler&&>(handler)),+ handler_(ASIO_MOVE_CAST(Handler)(handler)), work_(handler_, io_ex) { }@@ -114,7 +114,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); ASIO_ERROR_LOCATION(o->ec_);@@ -151,7 +151,7 @@ // Take ownership of the operation's outstanding work. immediate_handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); ASIO_ERROR_LOCATION(o->ec_);
link/modules/asio-standalone/asio/include/asio/detail/dev_poll_reactor.hpp view
@@ -2,7 +2,7 @@ // detail/dev_poll_reactor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -108,9 +108,10 @@ { start_op(op_type, descriptor, descriptor_data, op, is_continuation, allow_speculative,- &dev_poll_reactor::call_post_immediate_completion, this);+ &epoll_reactor::call_post_immediate_completion, this); } + // Cancel all operations associated with the given descriptor. The // handlers associated with the descriptor will be invoked with the // operation_aborted error.@@ -140,39 +141,38 @@ ASIO_DECL void cleanup_descriptor_data(per_descriptor_data&); // Add a new timer queue to the reactor.- template <typename TimeTraits, typename Allocator>- void add_timer_queue(timer_queue<TimeTraits, Allocator>& queue);+ template <typename Time_Traits>+ void add_timer_queue(timer_queue<Time_Traits>& queue); // Remove a timer queue from the reactor.- template <typename TimeTraits, typename Allocator>- void remove_timer_queue(timer_queue<TimeTraits, Allocator>& queue);+ template <typename Time_Traits>+ void remove_timer_queue(timer_queue<Time_Traits>& queue); // Schedule a new operation in the given timer queue to expire at the // specified absolute time.- template <typename TimeTraits, typename Allocator>- void schedule_timer(timer_queue<TimeTraits, Allocator>& queue,- const typename TimeTraits::time_type& time,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,- wait_op* op);+ template <typename Time_Traits>+ void schedule_timer(timer_queue<Time_Traits>& queue,+ const typename Time_Traits::time_type& time,+ typename timer_queue<Time_Traits>::per_timer_data& timer, wait_op* op); // Cancel the timer operations associated with the given token. Returns the // number of operations that have been posted or dispatched.- template <typename TimeTraits, typename Allocator>- std::size_t cancel_timer(timer_queue<TimeTraits, Allocator>& queue,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,+ template <typename Time_Traits>+ std::size_t cancel_timer(timer_queue<Time_Traits>& queue,+ typename timer_queue<Time_Traits>::per_timer_data& timer, std::size_t max_cancelled = (std::numeric_limits<std::size_t>::max)()); // Cancel the timer operations associated with the given key.- template <typename TimeTraits, typename Allocator>- void cancel_timer_by_key(timer_queue<TimeTraits, Allocator>& queue,- typename timer_queue<TimeTraits, Allocator>::per_timer_data* timer,+ template <typename Time_Traits>+ void cancel_timer_by_key(timer_queue<Time_Traits>& queue,+ typename timer_queue<Time_Traits>::per_timer_data* timer, void* cancellation_key); // Move the timer operations associated with the given timer.- template <typename TimeTraits, typename Allocator>- void move_timer(timer_queue<TimeTraits, Allocator>& queue,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& target,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& source);+ template <typename Time_Traits>+ void move_timer(timer_queue<Time_Traits>& queue,+ typename timer_queue<Time_Traits>::per_timer_data& target,+ typename timer_queue<Time_Traits>::per_timer_data& source); // Run /dev/poll once until interrupted or events are ready to be dispatched. ASIO_DECL void run(long usec, op_queue<operation>& ops);
link/modules/asio-standalone/asio/include/asio/detail/epoll_reactor.hpp view
@@ -2,7 +2,7 @@ // detail/epoll_reactor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -55,8 +55,11 @@ connect_op = 1, except_op = 2, max_ops = 3 }; // Per-descriptor queues.- struct descriptor_state : operation+ class descriptor_state : operation {+ friend class epoll_reactor;+ friend class object_pool_access;+ descriptor_state* next_; descriptor_state* prev_; @@ -68,7 +71,7 @@ bool try_speculative_[max_ops]; bool shutdown_; - ASIO_DECL descriptor_state(bool locking, int spin_count);+ ASIO_DECL descriptor_state(bool locking); void set_ready_events(uint32_t events) { task_result_ = events; } void add_ready_events(uint32_t events) { task_result_ |= events; } ASIO_DECL operation* perform_io(uint32_t events);@@ -169,39 +172,38 @@ per_descriptor_data& descriptor_data); // Add a new timer queue to the reactor.- template <typename TimeTraits, typename Allocator>- void add_timer_queue(timer_queue<TimeTraits, Allocator>& timer_queue);+ template <typename Time_Traits>+ void add_timer_queue(timer_queue<Time_Traits>& timer_queue); // Remove a timer queue from the reactor.- template <typename TimeTraits, typename Allocator>- void remove_timer_queue(timer_queue<TimeTraits, Allocator>& timer_queue);+ template <typename Time_Traits>+ void remove_timer_queue(timer_queue<Time_Traits>& timer_queue); // Schedule a new operation in the given timer queue to expire at the // specified absolute time.- template <typename TimeTraits, typename Allocator>- void schedule_timer(timer_queue<TimeTraits, Allocator>& queue,- const typename TimeTraits::time_type& time,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,- wait_op* op);+ template <typename Time_Traits>+ void schedule_timer(timer_queue<Time_Traits>& queue,+ const typename Time_Traits::time_type& time,+ typename timer_queue<Time_Traits>::per_timer_data& timer, wait_op* op); // Cancel the timer operations associated with the given token. Returns the // number of operations that have been posted or dispatched.- template <typename TimeTraits, typename Allocator>- std::size_t cancel_timer(timer_queue<TimeTraits, Allocator>& queue,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,+ template <typename Time_Traits>+ std::size_t cancel_timer(timer_queue<Time_Traits>& queue,+ typename timer_queue<Time_Traits>::per_timer_data& timer, std::size_t max_cancelled = (std::numeric_limits<std::size_t>::max)()); // Cancel the timer operations associated with the given key.- template <typename TimeTraits, typename Allocator>- void cancel_timer_by_key(timer_queue<TimeTraits, Allocator>& queue,- typename timer_queue<TimeTraits, Allocator>::per_timer_data* timer,+ template <typename Time_Traits>+ void cancel_timer_by_key(timer_queue<Time_Traits>& queue,+ typename timer_queue<Time_Traits>::per_timer_data* timer, void* cancellation_key); // Move the timer operations associated with the given timer.- template <typename TimeTraits, typename Allocator>- void move_timer(timer_queue<TimeTraits, Allocator>& queue,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& target,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& source);+ template <typename Time_Traits>+ void move_timer(timer_queue<Time_Traits>& queue,+ typename timer_queue<Time_Traits>::per_timer_data& target,+ typename timer_queue<Time_Traits>::per_timer_data& source); // Run epoll once until interrupted or events are ready to be dispatched. ASIO_DECL void run(long usec, op_queue<operation>& ops);@@ -267,18 +269,11 @@ // Whether the service has been shut down. bool shutdown_; - // Whether I/O locking is enabled.- const bool io_locking_;-- // How any times to spin waiting for the I/O mutex.- const int io_locking_spin_count_;- // Mutex to protect access to the registered descriptors. mutex registered_descriptors_mutex_; // Keep track of all registered descriptors.- object_pool<descriptor_state, execution_context::allocator<void>>- registered_descriptors_;+ object_pool<descriptor_state> registered_descriptors_; // Helper class to do post-perform_io cleanup. struct perform_io_cleanup_on_block_exit;
link/modules/asio-standalone/asio/include/asio/detail/event.hpp view
@@ -2,7 +2,7 @@ // detail/event.hpp // ~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -23,8 +23,10 @@ # include "asio/detail/win_event.hpp" #elif defined(ASIO_HAS_PTHREADS) # include "asio/detail/posix_event.hpp"-#else+#elif defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR) # include "asio/detail/std_event.hpp"+#else+# error Only Windows, POSIX and std::condition_variable are supported! #endif namespace asio {@@ -36,7 +38,7 @@ typedef win_event event; #elif defined(ASIO_HAS_PTHREADS) typedef posix_event event;-#else+#elif defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR) typedef std_event event; #endif
link/modules/asio-standalone/asio/include/asio/detail/eventfd_select_interrupter.hpp view
@@ -2,7 +2,7 @@ // detail/eventfd_select_interrupter.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2008 Roelof Naude (roelof.naude at gmail dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying
link/modules/asio-standalone/asio/include/asio/detail/exception.hpp view
@@ -2,7 +2,7 @@ // detail/exception.hpp // ~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -16,13 +16,24 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"-#include <exception> +#if defined(ASIO_HAS_STD_EXCEPTION_PTR)+# include <exception>+#else // defined(ASIO_HAS_STD_EXCEPTION_PTR)+# include <boost/exception_ptr.hpp>+#endif // defined(ASIO_HAS_STD_EXCEPTION_PTR)+ namespace asio { +#if defined(ASIO_HAS_STD_EXCEPTION_PTR) using std::exception_ptr; using std::current_exception; using std::rethrow_exception;+#else // defined(ASIO_HAS_STD_EXCEPTION_PTR)+using boost::exception_ptr;+using boost::current_exception;+using boost::rethrow_exception;+#endif // defined(ASIO_HAS_STD_EXCEPTION_PTR) } // namespace asio
link/modules/asio-standalone/asio/include/asio/detail/executor_function.hpp view
@@ -2,7 +2,7 @@ // detail/executor_function.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -17,6 +17,7 @@ #include "asio/detail/config.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/push_options.hpp"@@ -24,6 +25,8 @@ namespace asio { namespace detail { +#if defined(ASIO_HAS_MOVE)+ // Lightweight, move-only function object wrapper. class executor_function {@@ -35,11 +38,11 @@ typedef impl<F, Alloc> impl_type; typename impl_type::ptr p = { detail::addressof(a), impl_type::ptr::allocate(a), 0 };- impl_ = new (p.v) impl_type(static_cast<F&&>(f), a);+ impl_ = new (p.v) impl_type(ASIO_MOVE_CAST(F)(f), a); p.v = 0; } - executor_function(executor_function&& other) noexcept+ executor_function(executor_function&& other) ASIO_NOEXCEPT : impl_(other.impl_) { other.impl_ = 0;@@ -76,8 +79,8 @@ thread_info_base::executor_function_tag, impl); template <typename F>- impl(F&& f, const Alloc& a)- : function_(static_cast<F&&>(f)),+ impl(ASIO_MOVE_ARG(F) f, const Alloc& a)+ : function_(ASIO_MOVE_CAST(F)(f)), allocator_(a) { complete_ = &executor_function::complete<Function, Alloc>;@@ -103,25 +106,74 @@ // associated with the function. Consequently, a local copy of the function // is required to ensure that any owning sub-object remains valid until // after we have deallocated the memory here.- Function function(static_cast<Function&&>(i->function_));+ Function function(ASIO_MOVE_CAST(Function)(i->function_)); p.reset(); // Make the upcall if required. if (call) {- static_cast<Function&&>(function)();+ asio_handler_invoke_helpers::invoke(function, function); } } impl_base* impl_; }; +#else // defined(ASIO_HAS_MOVE)++// Not so lightweight, copyable function object wrapper.+class executor_function+{+public:+ template <typename F, typename Alloc>+ explicit executor_function(const F& f, const Alloc&)+ : impl_(new impl<typename decay<F>::type>(f))+ {+ }++ void operator()()+ {+ impl_->complete_(impl_.get());+ }++private:+ // Base class for polymorphic function implementations.+ struct impl_base+ {+ void (*complete_)(impl_base*);+ };++ // Polymorphic function implementation.+ template <typename F>+ struct impl : impl_base+ {+ impl(const F& f)+ : function_(f)+ {+ complete_ = &executor_function::complete<F>;+ }++ F function_;+ };++ // Helper to complete function invocation.+ template <typename F>+ static void complete(impl_base* i)+ {+ static_cast<impl<F>*>(i)->function_();+ }++ shared_ptr<impl_base> impl_;+};++#endif // defined(ASIO_HAS_MOVE)+ // Lightweight, non-owning, copyable function object wrapper. class executor_function_view { public: template <typename F>- explicit executor_function_view(F& f) noexcept+ explicit executor_function_view(F& f) ASIO_NOEXCEPT : complete_(&executor_function_view::complete<F>), function_(&f) {
link/modules/asio-standalone/asio/include/asio/detail/executor_op.hpp view
@@ -2,7 +2,7 @@ // detail/executor_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -18,6 +18,7 @@ #include "asio/detail/config.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/scheduler_operation.hpp" #include "asio/detail/push_options.hpp"@@ -33,9 +34,9 @@ ASIO_DEFINE_HANDLER_ALLOCATOR_PTR(executor_op); template <typename H>- executor_op(H&& h, const Alloc& allocator)+ executor_op(ASIO_MOVE_ARG(H) h, const Alloc& allocator) : Operation(&executor_op::do_complete),- handler_(static_cast<H&&>(h)),+ handler_(ASIO_MOVE_CAST(H)(h)), allocator_(allocator) { }@@ -58,7 +59,7 @@ // with the handler. Consequently, a local copy of the handler is required // to ensure that any owning sub-object remains valid until after we have // deallocated the memory here.- Handler handler(static_cast<Handler&&>(o->handler_));+ Handler handler(ASIO_MOVE_CAST(Handler)(o->handler_)); p.reset(); // Make the upcall if required.@@ -66,7 +67,7 @@ { fenced_block b(fenced_block::half); ASIO_HANDLER_INVOCATION_BEGIN(());- static_cast<Handler&&>(handler)();+ asio_handler_invoke_helpers::invoke(handler, handler); ASIO_HANDLER_INVOCATION_END; } }
link/modules/asio-standalone/asio/include/asio/detail/fd_set_adapter.hpp view
@@ -2,7 +2,7 @@ // detail/fd_set_adapter.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/fenced_block.hpp view
@@ -2,7 +2,7 @@ // detail/fenced_block.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -20,8 +20,28 @@ #if !defined(ASIO_HAS_THREADS) \ || defined(ASIO_DISABLE_FENCED_BLOCK) # include "asio/detail/null_fenced_block.hpp"-#else+#elif defined(ASIO_HAS_STD_ATOMIC) # include "asio/detail/std_fenced_block.hpp"+#elif defined(__MACH__) && defined(__APPLE__)+# include "asio/detail/macos_fenced_block.hpp"+#elif defined(__sun)+# include "asio/detail/solaris_fenced_block.hpp"+#elif defined(__GNUC__) && defined(__arm__) \+ && !defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)+# include "asio/detail/gcc_arm_fenced_block.hpp"+#elif defined(__GNUC__) && (defined(__hppa) || defined(__hppa__))+# include "asio/detail/gcc_hppa_fenced_block.hpp"+#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))+# include "asio/detail/gcc_x86_fenced_block.hpp"+#elif defined(__GNUC__) \+ && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)) \+ && !defined(__INTEL_COMPILER) && !defined(__ICL) \+ && !defined(__ICC) && !defined(__ECC) && !defined(__PATHSCALE__)+# include "asio/detail/gcc_sync_fenced_block.hpp"+#elif defined(ASIO_WINDOWS) && !defined(UNDER_CE)+# include "asio/detail/win_fenced_block.hpp"+#else+# include "asio/detail/null_fenced_block.hpp" #endif namespace asio {@@ -30,8 +50,28 @@ #if !defined(ASIO_HAS_THREADS) \ || defined(ASIO_DISABLE_FENCED_BLOCK) typedef null_fenced_block fenced_block;-#else+#elif defined(ASIO_HAS_STD_ATOMIC) typedef std_fenced_block fenced_block;+#elif defined(__MACH__) && defined(__APPLE__)+typedef macos_fenced_block fenced_block;+#elif defined(__sun)+typedef solaris_fenced_block fenced_block;+#elif defined(__GNUC__) && defined(__arm__) \+ && !defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)+typedef gcc_arm_fenced_block fenced_block;+#elif defined(__GNUC__) && (defined(__hppa) || defined(__hppa__))+typedef gcc_hppa_fenced_block fenced_block;+#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))+typedef gcc_x86_fenced_block fenced_block;+#elif defined(__GNUC__) \+ && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)) \+ && !defined(__INTEL_COMPILER) && !defined(__ICL) \+ && !defined(__ICC) && !defined(__ECC) && !defined(__PATHSCALE__)+typedef gcc_sync_fenced_block fenced_block;+#elif defined(ASIO_WINDOWS) && !defined(UNDER_CE)+typedef win_fenced_block fenced_block;+#else+typedef null_fenced_block fenced_block; #endif } // namespace detail
link/modules/asio-standalone/asio/include/asio/detail/functional.hpp view
@@ -2,7 +2,7 @@ // detail/functional.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -16,17 +16,28 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"+ #include <functional> +#if !defined(ASIO_HAS_STD_FUNCTION)+# include <boost/function.hpp>+#endif // !defined(ASIO_HAS_STD_FUNCTION)+ namespace asio { namespace detail { +#if defined(ASIO_HAS_STD_FUNCTION) using std::function;+#else // defined(ASIO_HAS_STD_FUNCTION)+using boost::function;+#endif // defined(ASIO_HAS_STD_FUNCTION) } // namespace detail +#if defined(ASIO_HAS_STD_REFERENCE_WRAPPER) using std::ref; using std::reference_wrapper;+#endif // defined(ASIO_HAS_STD_REFERENCE_WRAPPER) } // namespace asio
link/modules/asio-standalone/asio/include/asio/detail/future.hpp view
@@ -2,7 +2,7 @@ // detail/future.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -16,17 +16,18 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"-#include <future>-+#if defined(ASIO_HAS_STD_FUTURE)+# include <future> // Even though the future header is available, libstdc++ may not implement the // std::future class itself. However, we need to have already included the // future header to reliably test for _GLIBCXX_HAS_GTHREADS.-#if defined(__GNUC__) && !defined(ASIO_HAS_CLANG_LIBCXX)-# if defined(_GLIBCXX_HAS_GTHREADS)+# if defined(__GNUC__) && !defined(ASIO_HAS_CLANG_LIBCXX)+# if defined(_GLIBCXX_HAS_GTHREADS)+# define ASIO_HAS_STD_FUTURE_CLASS 1+# endif // defined(_GLIBCXX_HAS_GTHREADS)+# else // defined(__GNUC__) && !defined(ASIO_HAS_CLANG_LIBCXX) # define ASIO_HAS_STD_FUTURE_CLASS 1-# endif // defined(_GLIBCXX_HAS_GTHREADS)-#else // defined(__GNUC__) && !defined(ASIO_HAS_CLANG_LIBCXX)-# define ASIO_HAS_STD_FUTURE_CLASS 1-#endif // defined(__GNUC__) && !defined(ASIO_HAS_CLANG_LIBCXX)+# endif // defined(__GNUC__) && !defined(ASIO_HAS_CLANG_LIBCXX)+#endif // defined(ASIO_HAS_STD_FUTURE) #endif // ASIO_DETAIL_FUTURE_HPP
+ link/modules/asio-standalone/asio/include/asio/detail/gcc_arm_fenced_block.hpp view
@@ -0,0 +1,91 @@+//+// detail/gcc_arm_fenced_block.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_DETAIL_GCC_ARM_FENCED_BLOCK_HPP+#define ASIO_DETAIL_GCC_ARM_FENCED_BLOCK_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"++#if defined(__GNUC__) && defined(__arm__)++#include "asio/detail/noncopyable.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {+namespace detail {++class gcc_arm_fenced_block+ : private noncopyable+{+public:+ enum half_t { half };+ enum full_t { full };++ // Constructor for a half fenced block.+ explicit gcc_arm_fenced_block(half_t)+ {+ }++ // Constructor for a full fenced block.+ explicit gcc_arm_fenced_block(full_t)+ {+ barrier();+ }++ // Destructor.+ ~gcc_arm_fenced_block()+ {+ barrier();+ }++private:+ static void barrier()+ {+#if defined(__ARM_ARCH_4__) \+ || defined(__ARM_ARCH_4T__) \+ || defined(__ARM_ARCH_5__) \+ || defined(__ARM_ARCH_5E__) \+ || defined(__ARM_ARCH_5T__) \+ || defined(__ARM_ARCH_5TE__) \+ || defined(__ARM_ARCH_5TEJ__) \+ || defined(__ARM_ARCH_6__) \+ || defined(__ARM_ARCH_6J__) \+ || defined(__ARM_ARCH_6K__) \+ || defined(__ARM_ARCH_6Z__) \+ || defined(__ARM_ARCH_6ZK__) \+ || defined(__ARM_ARCH_6T2__)+# if defined(__thumb__)+ // This is just a placeholder and almost certainly not sufficient.+ __asm__ __volatile__ ("" : : : "memory");+# else // defined(__thumb__)+ int a = 0, b = 0;+ __asm__ __volatile__ ("swp %0, %1, [%2]"+ : "=&r"(a) : "r"(1), "r"(&b) : "memory", "cc");+# endif // defined(__thumb__)+#else+ // ARMv7 and later.+ __asm__ __volatile__ ("dmb" : : : "memory");+#endif+ }+};++} // namespace detail+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // defined(__GNUC__) && defined(__arm__)++#endif // ASIO_DETAIL_GCC_ARM_FENCED_BLOCK_HPP
+ link/modules/asio-standalone/asio/include/asio/detail/gcc_hppa_fenced_block.hpp view
@@ -0,0 +1,68 @@+//+// detail/gcc_hppa_fenced_block.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_DETAIL_GCC_HPPA_FENCED_BLOCK_HPP+#define ASIO_DETAIL_GCC_HPPA_FENCED_BLOCK_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"++#if defined(__GNUC__) && (defined(__hppa) || defined(__hppa__))++#include "asio/detail/noncopyable.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {+namespace detail {++class gcc_hppa_fenced_block+ : private noncopyable+{+public:+ enum half_t { half };+ enum full_t { full };++ // Constructor for a half fenced block.+ explicit gcc_hppa_fenced_block(half_t)+ {+ }++ // Constructor for a full fenced block.+ explicit gcc_hppa_fenced_block(full_t)+ {+ barrier();+ }++ // Destructor.+ ~gcc_hppa_fenced_block()+ {+ barrier();+ }++private:+ static void barrier()+ {+ // This is just a placeholder and almost certainly not sufficient.+ __asm__ __volatile__ ("" : : : "memory");+ }+};++} // namespace detail+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // defined(__GNUC__) && (defined(__hppa) || defined(__hppa__))++#endif // ASIO_DETAIL_GCC_HPPA_FENCED_BLOCK_HPP
+ link/modules/asio-standalone/asio/include/asio/detail/gcc_sync_fenced_block.hpp view
@@ -0,0 +1,65 @@+//+// detail/gcc_sync_fenced_block.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_DETAIL_GCC_SYNC_FENCED_BLOCK_HPP+#define ASIO_DETAIL_GCC_SYNC_FENCED_BLOCK_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"++#if defined(__GNUC__) \+ && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)) \+ && !defined(__INTEL_COMPILER) && !defined(__ICL) \+ && !defined(__ICC) && !defined(__ECC) && !defined(__PATHSCALE__)++#include "asio/detail/noncopyable.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {+namespace detail {++class gcc_sync_fenced_block+ : private noncopyable+{+public:+ enum half_or_full_t { half, full };++ // Constructor.+ explicit gcc_sync_fenced_block(half_or_full_t)+ : value_(0)+ {+ __sync_lock_test_and_set(&value_, 1);+ }++ // Destructor.+ ~gcc_sync_fenced_block()+ {+ __sync_lock_release(&value_);+ }++private:+ int value_;+};++} // namespace detail+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // defined(__GNUC__)+ // && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4))+ // && !defined(__INTEL_COMPILER) && !defined(__ICL)+ // && !defined(__ICC) && !defined(__ECC) && !defined(__PATHSCALE__)++#endif // ASIO_DETAIL_GCC_SYNC_FENCED_BLOCK_HPP
+ link/modules/asio-standalone/asio/include/asio/detail/gcc_x86_fenced_block.hpp view
@@ -0,0 +1,99 @@+//+// detail/gcc_x86_fenced_block.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_DETAIL_GCC_X86_FENCED_BLOCK_HPP+#define ASIO_DETAIL_GCC_X86_FENCED_BLOCK_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"++#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))++#include "asio/detail/noncopyable.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {+namespace detail {++class gcc_x86_fenced_block+ : private noncopyable+{+public:+ enum half_t { half };+ enum full_t { full };++ // Constructor for a half fenced block.+ explicit gcc_x86_fenced_block(half_t)+ {+ }++ // Constructor for a full fenced block.+ explicit gcc_x86_fenced_block(full_t)+ {+ lbarrier();+ }++ // Destructor.+ ~gcc_x86_fenced_block()+ {+ sbarrier();+ }++private:+ static int barrier()+ {+ int r = 0, m = 1;+ __asm__ __volatile__ (+ "xchg{l} %0, %1" :+ "=r"(r), "=m"(m) :+ "0"(1), "m"(m) :+ "memory", "cc");+ return r;+ }++ static void lbarrier()+ {+#if defined(__SSE2__)+# if (__GNUC__ >= 4) && !defined(__INTEL_COMPILER) && !defined(__ICL)+ __builtin_ia32_lfence();+# else // (__GNUC__ >= 4) && !defined(__INTEL_COMPILER) && !defined(__ICL)+ __asm__ __volatile__ ("lfence" ::: "memory");+# endif // (__GNUC__ >= 4) && !defined(__INTEL_COMPILER) && !defined(__ICL)+#else // defined(__SSE2__)+ barrier();+#endif // defined(__SSE2__)+ }++ static void sbarrier()+ {+#if defined(__SSE2__)+# if (__GNUC__ >= 4) && !defined(__INTEL_COMPILER) && !defined(__ICL)+ __builtin_ia32_sfence();+# else // (__GNUC__ >= 4) && !defined(__INTEL_COMPILER) && !defined(__ICL)+ __asm__ __volatile__ ("sfence" ::: "memory");+# endif // (__GNUC__ >= 4) && !defined(__INTEL_COMPILER) && !defined(__ICL)+#else // defined(__SSE2__)+ barrier();+#endif // defined(__SSE2__)+ }+};++} // namespace detail+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))++#endif // ASIO_DETAIL_GCC_X86_FENCED_BLOCK_HPP
link/modules/asio-standalone/asio/include/asio/detail/global.hpp view
@@ -2,7 +2,7 @@ // detail/global.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -23,8 +23,10 @@ # include "asio/detail/win_global.hpp" #elif defined(ASIO_HAS_PTHREADS) # include "asio/detail/posix_global.hpp"-#else+#elif defined(ASIO_HAS_STD_CALL_ONCE) # include "asio/detail/std_global.hpp"+#else+# error Only Windows, POSIX and std::call_once are supported! #endif namespace asio {@@ -39,7 +41,7 @@ return win_global<T>(); #elif defined(ASIO_HAS_PTHREADS) return posix_global<T>();-#else+#elif defined(ASIO_HAS_STD_CALL_ONCE) return std_global<T>(); #endif }
link/modules/asio-standalone/asio/include/asio/detail/handler_alloc_helpers.hpp view
@@ -2,7 +2,7 @@ // detail/handler_alloc_helpers.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -17,12 +17,182 @@ #include "asio/detail/config.hpp" #include "asio/detail/memory.hpp"+#include "asio/detail/noncopyable.hpp" #include "asio/detail/recycling_allocator.hpp"+#include "asio/detail/thread_info_base.hpp" #include "asio/associated_allocator.hpp"+#include "asio/handler_alloc_hook.hpp" #include "asio/detail/push_options.hpp" -#define ASIO_DEFINE_TAGGED_HANDLER_PTR(purpose, op) \+// Calls to asio_handler_allocate and asio_handler_deallocate must be made from+// a namespace that does not contain any overloads of these functions. The+// asio_handler_alloc_helpers namespace is defined here for that purpose.+namespace asio_handler_alloc_helpers {++#if defined(ASIO_NO_DEPRECATED)+template <typename Handler>+inline void error_if_hooks_are_defined(Handler& h)+{+ using asio::asio_handler_allocate;+ // If you get an error here it is because some of your handlers still+ // overload asio_handler_allocate, but this hook is no longer used.+ (void)static_cast<asio::asio_handler_allocate_is_no_longer_used>(+ asio_handler_allocate(static_cast<std::size_t>(0),+ asio::detail::addressof(h)));++ using asio::asio_handler_deallocate;+ // If you get an error here it is because some of your handlers still+ // overload asio_handler_deallocate, but this hook is no longer used.+ (void)static_cast<asio::asio_handler_deallocate_is_no_longer_used>(+ asio_handler_deallocate(static_cast<void*>(0),+ static_cast<std::size_t>(0), asio::detail::addressof(h)));+}+#endif // defined(ASIO_NO_DEPRECATED)++template <typename Handler>+inline void* allocate(std::size_t s, Handler& h,+ std::size_t align = ASIO_DEFAULT_ALIGN)+{+#if !defined(ASIO_HAS_HANDLER_HOOKS)+ return asio::aligned_new(align, s);+#elif defined(ASIO_NO_DEPRECATED)+ // The asio_handler_allocate hook is no longer used to obtain memory.+ (void)&error_if_hooks_are_defined<Handler>;+ (void)h;+# if !defined(ASIO_DISABLE_SMALL_BLOCK_RECYCLING)+ return asio::detail::thread_info_base::allocate(+ asio::detail::thread_context::top_of_thread_call_stack(),+ s, align);+# else // !defined(ASIO_DISABLE_SMALL_BLOCK_RECYCLING)+ return asio::aligned_new(align, s);+# endif // !defined(ASIO_DISABLE_SMALL_BLOCK_RECYCLING)+#else+ (void)align;+ using asio::asio_handler_allocate;+ return asio_handler_allocate(s, asio::detail::addressof(h));+#endif+}++template <typename Handler>+inline void deallocate(void* p, std::size_t s, Handler& h)+{+#if !defined(ASIO_HAS_HANDLER_HOOKS)+ asio::aligned_delete(p);+#elif defined(ASIO_NO_DEPRECATED)+ // The asio_handler_allocate hook is no longer used to obtain memory.+ (void)&error_if_hooks_are_defined<Handler>;+ (void)h;+#if !defined(ASIO_DISABLE_SMALL_BLOCK_RECYCLING)+ asio::detail::thread_info_base::deallocate(+ asio::detail::thread_context::top_of_thread_call_stack(), p, s);+#else // !defined(ASIO_DISABLE_SMALL_BLOCK_RECYCLING)+ (void)s;+ asio::aligned_delete(p);+#endif // !defined(ASIO_DISABLE_SMALL_BLOCK_RECYCLING)+#else+ using asio::asio_handler_deallocate;+ asio_handler_deallocate(p, s, asio::detail::addressof(h));+#endif+}++} // namespace asio_handler_alloc_helpers++namespace asio {+namespace detail {++template <typename Handler, typename T>+class hook_allocator+{+public:+ typedef T value_type;++ template <typename U>+ struct rebind+ {+ typedef hook_allocator<Handler, U> other;+ };++ explicit hook_allocator(Handler& h)+ : handler_(h)+ {+ }++ template <typename U>+ hook_allocator(const hook_allocator<Handler, U>& a)+ : handler_(a.handler_)+ {+ }++ T* allocate(std::size_t n)+ {+ return static_cast<T*>(+ asio_handler_alloc_helpers::allocate(+ sizeof(T) * n, handler_, ASIO_ALIGNOF(T)));+ }++ void deallocate(T* p, std::size_t n)+ {+ asio_handler_alloc_helpers::deallocate(p, sizeof(T) * n, handler_);+ }++//private:+ Handler& handler_;+};++template <typename Handler>+class hook_allocator<Handler, void>+{+public:+ typedef void value_type;++ template <typename U>+ struct rebind+ {+ typedef hook_allocator<Handler, U> other;+ };++ explicit hook_allocator(Handler& h)+ : handler_(h)+ {+ }++ template <typename U>+ hook_allocator(const hook_allocator<Handler, U>& a)+ : handler_(a.handler_)+ {+ }++//private:+ Handler& handler_;+};++template <typename Handler, typename Allocator>+struct get_hook_allocator+{+ typedef Allocator type;++ static type get(Handler&, const Allocator& a)+ {+ return a;+ }+};++template <typename Handler, typename T>+struct get_hook_allocator<Handler, std::allocator<T> >+{+ typedef hook_allocator<Handler, T> type;++ static type get(Handler& handler, const std::allocator<T>&)+ {+ return type(handler);+ }+};++} // namespace detail+} // namespace asio++#define ASIO_DEFINE_HANDLER_PTR(op) \ struct ptr \ { \ Handler* h; \@@ -36,12 +206,12 @@ { \ typedef typename ::asio::associated_allocator< \ Handler>::type associated_allocator_type; \- typedef typename ::asio::detail::get_recycling_allocator< \- associated_allocator_type, purpose>::type default_allocator_type; \- ASIO_REBIND_ALLOC(default_allocator_type, op) a( \- ::asio::detail::get_recycling_allocator< \- associated_allocator_type, purpose>::get( \- ::asio::get_associated_allocator(handler))); \+ typedef typename ::asio::detail::get_hook_allocator< \+ Handler, associated_allocator_type>::type hook_allocator_type; \+ ASIO_REBIND_ALLOC(hook_allocator_type, op) a( \+ ::asio::detail::get_hook_allocator< \+ Handler, associated_allocator_type>::get( \+ handler, ::asio::get_associated_allocator(handler))); \ return a.allocate(1); \ } \ void reset() \@@ -55,22 +225,17 @@ { \ typedef typename ::asio::associated_allocator< \ Handler>::type associated_allocator_type; \- typedef typename ::asio::detail::get_recycling_allocator< \- associated_allocator_type, purpose>::type default_allocator_type; \- ASIO_REBIND_ALLOC(default_allocator_type, op) a( \- ::asio::detail::get_recycling_allocator< \- associated_allocator_type, purpose>::get( \- ::asio::get_associated_allocator(*h))); \+ typedef typename ::asio::detail::get_hook_allocator< \+ Handler, associated_allocator_type>::type hook_allocator_type; \+ ASIO_REBIND_ALLOC(hook_allocator_type, op) a( \+ ::asio::detail::get_hook_allocator< \+ Handler, associated_allocator_type>::get( \+ *h, ::asio::get_associated_allocator(*h))); \ a.deallocate(static_cast<op*>(v), 1); \ v = 0; \ } \ } \ } \- /**/--#define ASIO_DEFINE_HANDLER_PTR(op) \- ASIO_DEFINE_TAGGED_HANDLER_PTR( \- ::asio::detail::thread_info_base::default_tag, op ) \ /**/ #define ASIO_DEFINE_TAGGED_HANDLER_ALLOCATOR_PTR(purpose, op) \
link/modules/asio-standalone/asio/include/asio/detail/handler_cont_helpers.hpp view
@@ -2,7 +2,7 @@ // detail/handler_cont_helpers.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ link/modules/asio-standalone/asio/include/asio/detail/handler_invoke_helpers.hpp view
@@ -0,0 +1,80 @@+//+// detail/handler_invoke_helpers.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_DETAIL_HANDLER_INVOKE_HELPERS_HPP+#define ASIO_DETAIL_HANDLER_INVOKE_HELPERS_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/detail/memory.hpp"+#include "asio/handler_invoke_hook.hpp"++#include "asio/detail/push_options.hpp"++// Calls to asio_handler_invoke must be made from a namespace that does not+// contain overloads of this function. The asio_handler_invoke_helpers+// namespace is defined here for that purpose.+namespace asio_handler_invoke_helpers {++#if defined(ASIO_NO_DEPRECATED)+template <typename Function, typename Context>+inline void error_if_hook_is_defined(Function& function, Context& context)+{+ using asio::asio_handler_invoke;+ // If you get an error here it is because some of your handlers still+ // overload asio_handler_invoke, but this hook is no longer used.+ (void)static_cast<asio::asio_handler_invoke_is_no_longer_used>(+ asio_handler_invoke(function, asio::detail::addressof(context)));+}+#endif // defined(ASIO_NO_DEPRECATED)++template <typename Function, typename Context>+inline void invoke(Function& function, Context& context)+{+#if !defined(ASIO_HAS_HANDLER_HOOKS)+ Function tmp(function);+ tmp();+#elif defined(ASIO_NO_DEPRECATED)+ // The asio_handler_invoke hook is no longer used to invoke the function.+ (void)&error_if_hook_is_defined<Function, Context>;+ (void)context;+ function();+#else+ using asio::asio_handler_invoke;+ asio_handler_invoke(function, asio::detail::addressof(context));+#endif+}++template <typename Function, typename Context>+inline void invoke(const Function& function, Context& context)+{+#if !defined(ASIO_HAS_HANDLER_HOOKS)+ Function tmp(function);+ tmp();+#elif defined(ASIO_NO_DEPRECATED)+ // The asio_handler_invoke hook is no longer used to invoke the function.+ (void)&error_if_hook_is_defined<const Function, Context>;+ (void)context;+ Function tmp(function);+ tmp();+#else+ using asio::asio_handler_invoke;+ asio_handler_invoke(function, asio::detail::addressof(context));+#endif+}++} // namespace asio_handler_invoke_helpers++#include "asio/detail/pop_options.hpp"++#endif // ASIO_DETAIL_HANDLER_INVOKE_HELPERS_HPP
link/modules/asio-standalone/asio/include/asio/detail/handler_tracking.hpp view
@@ -2,7 +2,7 @@ // detail/handler_tracking.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -99,8 +99,8 @@ private: // Disallow copying and assignment.- location(const location&) = delete;- location& operator=(const location&) = delete;+ location(const location&) ASIO_DELETED;+ location& operator=(const location&) ASIO_DELETED; friend class handler_tracking; const char* file_;
link/modules/asio-standalone/asio/include/asio/detail/handler_type_requirements.hpp view
@@ -2,7 +2,7 @@ // detail/handler_type_requirements.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -64,7 +64,7 @@ auto zero_arg_copyable_handler_test(Handler h, void*) -> decltype( sizeof(Handler(static_cast<const Handler&>(h))),- (static_cast<Handler&&>(h)()),+ (ASIO_MOVE_OR_LVALUE(Handler)(h)()), char(0)); template <typename Handler>@@ -73,8 +73,8 @@ template <typename Handler, typename Arg1> auto one_arg_handler_test(Handler h, Arg1* a1) -> decltype(- sizeof(Handler(static_cast<Handler&&>(h))),- (static_cast<Handler&&>(h)(*a1)),+ sizeof(Handler(ASIO_MOVE_CAST(Handler)(h))),+ (ASIO_MOVE_OR_LVALUE(Handler)(h)(*a1)), char(0)); template <typename Handler>@@ -83,8 +83,8 @@ template <typename Handler, typename Arg1, typename Arg2> auto two_arg_handler_test(Handler h, Arg1* a1, Arg2* a2) -> decltype(- sizeof(Handler(static_cast<Handler&&>(h))),- (static_cast<Handler&&>(h)(*a1, *a2)),+ sizeof(Handler(ASIO_MOVE_CAST(Handler)(h))),+ (ASIO_MOVE_OR_LVALUE(Handler)(h)(*a1, *a2)), char(0)); template <typename Handler>@@ -93,9 +93,9 @@ template <typename Handler, typename Arg1, typename Arg2> auto two_arg_move_handler_test(Handler h, Arg1* a1, Arg2* a2) -> decltype(- sizeof(Handler(static_cast<Handler&&>(h))),- (static_cast<Handler&&>(h)(- *a1, static_cast<Arg2&&>(*a2))),+ sizeof(Handler(ASIO_MOVE_CAST(Handler)(h))),+ (ASIO_MOVE_OR_LVALUE(Handler)(h)(+ *a1, ASIO_MOVE_CAST(Arg2)(*a2))), char(0)); template <typename Handler>@@ -114,15 +114,43 @@ template <typename T> T& lvref(T); template <typename T> const T& clvref(); template <typename T> const T& clvref(T);+#if defined(ASIO_HAS_MOVE) template <typename T> T rvref(); template <typename T> T rvref(T); template <typename T> T rorlvref();+#else // defined(ASIO_HAS_MOVE)+template <typename T> const T& rvref();+template <typename T> const T& rvref(T);+template <typename T> T& rorlvref();+#endif // defined(ASIO_HAS_MOVE) template <typename T> char argbyv(T); template <int> struct handler_type_requirements { };++#define ASIO_LEGACY_COMPLETION_HANDLER_CHECK( \+ handler_type, handler) \+ \+ typedef ASIO_HANDLER_TYPE(handler_type, \+ void()) asio_true_handler_type; \+ \+ ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \+ sizeof(asio::detail::zero_arg_copyable_handler_test( \+ asio::detail::clvref< \+ asio_true_handler_type>(), 0)) == 1, \+ "CompletionHandler type requirements not met") \+ \+ typedef asio::detail::handler_type_requirements< \+ sizeof( \+ asio::detail::argbyv( \+ asio::detail::clvref< \+ asio_true_handler_type>())) + \+ sizeof( \+ asio::detail::rorlvref< \+ asio_true_handler_type>()(), \+ char(0))> ASIO_UNUSED_TYPEDEF #define ASIO_READ_HANDLER_CHECK( \ handler_type, handler) \
link/modules/asio-standalone/asio/include/asio/detail/handler_work.hpp view
@@ -2,7 +2,7 @@ // detail/handler_work.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -19,11 +19,13 @@ #include "asio/associated_allocator.hpp" #include "asio/associated_executor.hpp" #include "asio/associated_immediate_executor.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/initiate_dispatch.hpp" #include "asio/detail/type_traits.hpp" #include "asio/detail/work_dispatcher.hpp" #include "asio/execution/allocator.hpp" #include "asio/execution/blocking.hpp"+#include "asio/execution/execute.hpp" #include "asio/execution/executor.hpp" #include "asio/execution/outstanding_work.hpp" #include "asio/executor_work_guard.hpp"@@ -45,8 +47,17 @@ namespace execution { +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+ template <typename...> class any_executor; +#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename, typename, typename, typename, typename,+ typename, typename, typename, typename> class any_executor;++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+ } // namespace execution namespace detail { @@ -56,29 +67,31 @@ class handler_work_base { public:- explicit handler_work_base(int, int, const Executor& ex) noexcept+ explicit handler_work_base(int, int, const Executor& ex) ASIO_NOEXCEPT : executor_(asio::prefer(ex, execution::outstanding_work.tracked)) { } template <typename OtherExecutor> handler_work_base(bool /*base1_owns_work*/, const Executor& ex,- const OtherExecutor& /*candidate*/) noexcept+ const OtherExecutor& /*candidate*/) ASIO_NOEXCEPT : executor_(asio::prefer(ex, execution::outstanding_work.tracked)) { } - handler_work_base(const handler_work_base& other) noexcept+ handler_work_base(const handler_work_base& other) ASIO_NOEXCEPT : executor_(other.executor_) { } - handler_work_base(handler_work_base&& other) noexcept- : executor_(static_cast<executor_type&&>(other.executor_))+#if defined(ASIO_HAS_MOVE)+ handler_work_base(handler_work_base&& other) ASIO_NOEXCEPT+ : executor_(ASIO_MOVE_CAST(executor_type)(other.executor_)) { }+#endif // defined(ASIO_HAS_MOVE) - bool owns_work() const noexcept+ bool owns_work() const ASIO_NOEXCEPT { return true; }@@ -86,15 +99,24 @@ template <typename Function, typename Handler> void dispatch(Function& function, Handler& handler) {+#if defined(ASIO_NO_DEPRECATED) asio::prefer(executor_, execution::allocator((get_associated_allocator)(handler))- ).execute(static_cast<Function&&>(function));+ ).execute(ASIO_MOVE_CAST(Function)(function));+#else // defined(ASIO_NO_DEPRECATED)+ execution::execute(+ asio::prefer(executor_,+ execution::allocator((get_associated_allocator)(handler))),+ ASIO_MOVE_CAST(Function)(function));+#endif // defined(ASIO_NO_DEPRECATED) } private:- typedef decay_t<- prefer_result_t<Executor, execution::outstanding_work_t::tracked_t>- > executor_type;+ typedef typename decay<+ typename prefer_result<Executor,+ execution::outstanding_work_t::tracked_t+ >::type+ >::type executor_type; executor_type executor_; };@@ -103,15 +125,14 @@ typename IoContext, typename PolymorphicExecutor> class handler_work_base<Executor, CandidateExecutor, IoContext, PolymorphicExecutor,- enable_if_t<+ typename enable_if< !execution::is_executor<Executor>::value && (!is_same<Executor, PolymorphicExecutor>::value || !is_same<CandidateExecutor, void>::value)- >- >+ >::type> { public:- explicit handler_work_base(int, int, const Executor& ex) noexcept+ explicit handler_work_base(int, int, const Executor& ex) ASIO_NOEXCEPT : executor_(ex), owns_work_(true) {@@ -119,7 +140,7 @@ } handler_work_base(bool /*base1_owns_work*/, const Executor& ex,- const Executor& candidate) noexcept+ const Executor& candidate) ASIO_NOEXCEPT : executor_(ex), owns_work_(ex != candidate) {@@ -129,14 +150,14 @@ template <typename OtherExecutor> handler_work_base(bool /*base1_owns_work*/, const Executor& ex,- const OtherExecutor& /*candidate*/) noexcept+ const OtherExecutor& /*candidate*/) ASIO_NOEXCEPT : executor_(ex), owns_work_(true) { executor_.on_work_started(); } - handler_work_base(const handler_work_base& other) noexcept+ handler_work_base(const handler_work_base& other) ASIO_NOEXCEPT : executor_(other.executor_), owns_work_(other.owns_work_) {@@ -144,12 +165,14 @@ executor_.on_work_started(); } - handler_work_base(handler_work_base&& other) noexcept- : executor_(static_cast<Executor&&>(other.executor_)),+#if defined(ASIO_HAS_MOVE)+ handler_work_base(handler_work_base&& other) ASIO_NOEXCEPT+ : executor_(ASIO_MOVE_CAST(Executor)(other.executor_)), owns_work_(other.owns_work_) { other.owns_work_ = false; }+#endif // defined(ASIO_HAS_MOVE) ~handler_work_base() {@@ -157,7 +180,7 @@ executor_.on_work_finished(); } - bool owns_work() const noexcept+ bool owns_work() const ASIO_NOEXCEPT { return owns_work_; }@@ -165,7 +188,7 @@ template <typename Function, typename Handler> void dispatch(Function& function, Handler& handler) {- executor_.dispatch(static_cast<Function&&>(function),+ executor_.dispatch(ASIO_MOVE_CAST(Function)(function), asio::get_associated_allocator(handler)); } @@ -176,31 +199,30 @@ template <typename Executor, typename IoContext, typename PolymorphicExecutor> class handler_work_base<Executor, void, IoContext, PolymorphicExecutor,- enable_if_t<+ typename enable_if< is_same< Executor, typename IoContext::executor_type >::value- >- >+ >::type> { public: explicit handler_work_base(int, int, const Executor&) { } - bool owns_work() const noexcept+ bool owns_work() const ASIO_NOEXCEPT { return false; } template <typename Function, typename Handler>- void dispatch(Function& function, Handler&)+ void dispatch(Function& function, Handler& handler) { // When using a native implementation, I/O completion handlers are // already dispatched according to the execution context's executor's // rules. We can call the function directly.- static_cast<Function&&>(function)();+ asio_handler_invoke_helpers::invoke(function, handler); } }; @@ -208,7 +230,7 @@ class handler_work_base<Executor, void, IoContext, Executor> { public:- explicit handler_work_base(int, int, const Executor& ex) noexcept+ explicit handler_work_base(int, int, const Executor& ex) ASIO_NOEXCEPT #if !defined(ASIO_NO_TYPEID) : executor_( ex.target_type() == typeid(typename IoContext::executor_type)@@ -222,7 +244,7 @@ } handler_work_base(bool /*base1_owns_work*/, const Executor& ex,- const Executor& candidate) noexcept+ const Executor& candidate) ASIO_NOEXCEPT : executor_(ex != candidate ? ex : Executor()) { if (executor_)@@ -231,23 +253,25 @@ template <typename OtherExecutor> handler_work_base(const Executor& ex,- const OtherExecutor&) noexcept+ const OtherExecutor&) ASIO_NOEXCEPT : executor_(ex) { executor_.on_work_started(); } - handler_work_base(const handler_work_base& other) noexcept+ handler_work_base(const handler_work_base& other) ASIO_NOEXCEPT : executor_(other.executor_) { if (executor_) executor_.on_work_started(); } - handler_work_base(handler_work_base&& other) noexcept- : executor_(static_cast<Executor&&>(other.executor_))+#if defined(ASIO_HAS_MOVE)+ handler_work_base(handler_work_base&& other) ASIO_NOEXCEPT+ : executor_(ASIO_MOVE_CAST(Executor)(other.executor_)) { }+#endif // defined(ASIO_HAS_MOVE) ~handler_work_base() {@@ -255,7 +279,7 @@ executor_.on_work_finished(); } - bool owns_work() const noexcept+ bool owns_work() const ASIO_NOEXCEPT { return !!executor_; }@@ -263,7 +287,7 @@ template <typename Function, typename Handler> void dispatch(Function& function, Handler& handler) {- executor_.dispatch(static_cast<Function&&>(function),+ executor_.dispatch(ASIO_MOVE_CAST(Function)(function), asio::get_associated_allocator(handler)); } @@ -271,15 +295,34 @@ Executor executor_; }; -template <typename... SupportableProperties, typename CandidateExecutor,- typename IoContext, typename PolymorphicExecutor>-class handler_work_base<execution::any_executor<SupportableProperties...>,+template <+#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+ typename... SupportableProperties,+#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)+ typename T1, typename T2, typename T3, typename T4, typename T5,+ typename T6, typename T7, typename T8, typename T9,+#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+ typename CandidateExecutor, typename IoContext,+ typename PolymorphicExecutor>+class handler_work_base<+#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+ execution::any_executor<SupportableProperties...>,+#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)+ execution::any_executor<T1, T2, T3, T4, T5, T6, T7, T8, T9>,+#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) CandidateExecutor, IoContext, PolymorphicExecutor> { public:- typedef execution::any_executor<SupportableProperties...> executor_type;+ typedef+#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+ execution::any_executor<SupportableProperties...>+#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)+ execution::any_executor<T1, T2, T3, T4, T5, T6, T7, T8, T9>+#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+ executor_type; - explicit handler_work_base(int, int, const executor_type& ex) noexcept+ explicit handler_work_base(int, int,+ const executor_type& ex) ASIO_NOEXCEPT #if !defined(ASIO_NO_TYPEID) : executor_( ex.target_type() == typeid(typename IoContext::executor_type)@@ -292,7 +335,7 @@ } handler_work_base(bool base1_owns_work, const executor_type& ex,- const executor_type& candidate) noexcept+ const executor_type& candidate) ASIO_NOEXCEPT : executor_( !base1_owns_work && ex == candidate ? executor_type()@@ -302,22 +345,24 @@ template <typename OtherExecutor> handler_work_base(bool /*base1_owns_work*/, const executor_type& ex,- const OtherExecutor& /*candidate*/) noexcept+ const OtherExecutor& /*candidate*/) ASIO_NOEXCEPT : executor_(asio::prefer(ex, execution::outstanding_work.tracked)) { } - handler_work_base(const handler_work_base& other) noexcept+ handler_work_base(const handler_work_base& other) ASIO_NOEXCEPT : executor_(other.executor_) { } - handler_work_base(handler_work_base&& other) noexcept- : executor_(static_cast<executor_type&&>(other.executor_))+#if defined(ASIO_HAS_MOVE)+ handler_work_base(handler_work_base&& other) ASIO_NOEXCEPT+ : executor_(ASIO_MOVE_CAST(executor_type)(other.executor_)) { }+#endif // defined(ASIO_HAS_MOVE) - bool owns_work() const noexcept+ bool owns_work() const ASIO_NOEXCEPT { return !!executor_; }@@ -325,7 +370,11 @@ template <typename Function, typename Handler> void dispatch(Function& function, Handler&) {- executor_.execute(static_cast<Function&&>(function));+#if defined(ASIO_NO_DEPRECATED)+ executor_.execute(ASIO_MOVE_CAST(Function)(function));+#else // defined(ASIO_NO_DEPRECATED)+ execution::execute(executor_, ASIO_MOVE_CAST(Function)(function));+#endif // defined(ASIO_NO_DEPRECATED) } private:@@ -339,17 +388,16 @@ class handler_work_base< Executor, CandidateExecutor, IoContext, PolymorphicExecutor,- enable_if_t<+ typename enable_if< is_same<Executor, any_completion_executor>::value || is_same<Executor, any_io_executor>::value- >- >+ >::type> { public: typedef Executor executor_type; explicit handler_work_base(int, int,- const executor_type& ex) noexcept+ const executor_type& ex) ASIO_NOEXCEPT #if !defined(ASIO_NO_TYPEID) : executor_( ex.target_type() == typeid(typename IoContext::executor_type)@@ -362,7 +410,7 @@ } handler_work_base(bool base1_owns_work, const executor_type& ex,- const executor_type& candidate) noexcept+ const executor_type& candidate) ASIO_NOEXCEPT : executor_( !base1_owns_work && ex == candidate ? executor_type()@@ -372,22 +420,24 @@ template <typename OtherExecutor> handler_work_base(bool /*base1_owns_work*/, const executor_type& ex,- const OtherExecutor& /*candidate*/) noexcept+ const OtherExecutor& /*candidate*/) ASIO_NOEXCEPT : executor_(asio::prefer(ex, execution::outstanding_work.tracked)) { } - handler_work_base(const handler_work_base& other) noexcept+ handler_work_base(const handler_work_base& other) ASIO_NOEXCEPT : executor_(other.executor_) { } - handler_work_base(handler_work_base&& other) noexcept- : executor_(static_cast<executor_type&&>(other.executor_))+#if defined(ASIO_HAS_MOVE)+ handler_work_base(handler_work_base&& other) ASIO_NOEXCEPT+ : executor_(ASIO_MOVE_CAST(executor_type)(other.executor_)) { }+#endif // defined(ASIO_HAS_MOVE) - bool owns_work() const noexcept+ bool owns_work() const ASIO_NOEXCEPT { return !!executor_; }@@ -395,7 +445,11 @@ template <typename Function, typename Handler> void dispatch(Function& function, Handler&) {- executor_.execute(static_cast<Function&&>(function));+#if defined(ASIO_NO_DEPRECATED)+ executor_.execute(ASIO_MOVE_CAST(Function)(function));+#else // defined(ASIO_NO_DEPRECATED)+ execution::execute(executor_, ASIO_MOVE_CAST(Function)(function));+#endif // defined(ASIO_NO_DEPRECATED) } private:@@ -407,14 +461,15 @@ template <typename Handler, typename IoExecutor, typename = void> class handler_work : handler_work_base<IoExecutor>,- handler_work_base<associated_executor_t<Handler, IoExecutor>, IoExecutor>+ handler_work_base<typename associated_executor<+ Handler, IoExecutor>::type, IoExecutor> { public: typedef handler_work_base<IoExecutor> base1_type;- typedef handler_work_base<associated_executor_t<Handler, IoExecutor>,- IoExecutor> base2_type;+ typedef handler_work_base<typename associated_executor<+ Handler, IoExecutor>::type, IoExecutor> base2_type; - handler_work(Handler& handler, const IoExecutor& io_ex) noexcept+ handler_work(Handler& handler, const IoExecutor& io_ex) ASIO_NOEXCEPT : base1_type(0, 0, io_ex), base2_type(base1_type::owns_work(), asio::get_associated_executor(handler, io_ex), io_ex)@@ -429,7 +484,7 @@ // When using a native implementation, I/O completion handlers are // already dispatched according to the execution context's executor's // rules. We can call the function directly.- static_cast<Function&&>(function)();+ asio_handler_invoke_helpers::invoke(function, handler); } else {@@ -441,19 +496,18 @@ template <typename Handler, typename IoExecutor> class handler_work< Handler, IoExecutor,- enable_if_t<+ typename enable_if< is_same< typename associated_executor<Handler, IoExecutor>::asio_associated_executor_is_unspecialised, void >::value- >- > : handler_work_base<IoExecutor>+ >::type> : handler_work_base<IoExecutor> { public: typedef handler_work_base<IoExecutor> base1_type; - handler_work(Handler&, const IoExecutor& io_ex) noexcept+ handler_work(Handler&, const IoExecutor& io_ex) ASIO_NOEXCEPT : base1_type(0, 0, io_ex) { }@@ -466,7 +520,7 @@ // When using a native implementation, I/O completion handlers are // already dispatched according to the execution context's executor's // rules. We can call the function directly.- static_cast<Function&&>(function)();+ asio_handler_invoke_helpers::invoke(function, handler); } else {@@ -481,22 +535,22 @@ public: typedef handler_work<Handler, IoExecutor> handler_work_type; - explicit immediate_handler_work(handler_work_type&& w)- : handler_work_(static_cast<handler_work_type&&>(w))+ explicit immediate_handler_work(ASIO_MOVE_ARG(handler_work_type) w)+ : handler_work_(ASIO_MOVE_CAST(handler_work_type)(w)) { } template <typename Function> void complete(Function& function, Handler& handler, const void* io_ex) {- typedef associated_immediate_executor_t<Handler, IoExecutor>+ typedef typename associated_immediate_executor<Handler, IoExecutor>::type immediate_ex_type; immediate_ex_type immediate_ex = (get_associated_immediate_executor)( handler, *static_cast<const IoExecutor*>(io_ex)); (initiate_dispatch_with_executor<immediate_ex_type>(immediate_ex))(- static_cast<Function&&>(function));+ ASIO_MOVE_CAST(Function)(function)); } private:
link/modules/asio-standalone/asio/include/asio/detail/hash_map.hpp view
@@ -2,7 +2,7 @@ // detail/hash_map.hpp // ~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/impl/buffer_sequence_adapter.ipp view
@@ -2,7 +2,7 @@ // detail/impl/buffer_sequence_adapter.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/impl/descriptor_ops.ipp view
@@ -2,7 +2,7 @@ // detail/impl/descriptor_ops.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -69,24 +69,18 @@ ::fcntl(d, F_SETFL, flags & ~O_NONBLOCK); #else // defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__) ioctl_arg_type arg = 0;- if ((state & possible_dup) == 0)- {- result = ::ioctl(d, FIONBIO, &arg);- get_last_error(ec, result < 0);- }- if ((state & possible_dup) != 0 # if defined(ENOTTY)- || ec.value() == ENOTTY-# endif // defined(ENOTTY)-# if defined(ENOTCAPABLE)- || ec.value() == ENOTCAPABLE-# endif // defined(ENOTCAPABLE)- )+ result = ::ioctl(d, FIONBIO, &arg);+ get_last_error(ec, result < 0);+ if (ec.value() == ENOTTY) { int flags = ::fcntl(d, F_GETFL, 0); if (flags >= 0) ::fcntl(d, F_SETFL, flags & ~O_NONBLOCK); }+# else // defined(ENOTTY)+ ::ioctl(d, FIONBIO, &arg);+# endif // defined(ENOTTY) #endif // defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__) state &= ~non_blocking; @@ -113,35 +107,26 @@ if (result >= 0) { int flag = (value ? (result | O_NONBLOCK) : (result & ~O_NONBLOCK));- result = (flag != result) ? ::fcntl(d, F_SETFL, flag) : 0;+ result = ::fcntl(d, F_SETFL, flag); get_last_error(ec, result < 0); } #else // defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__) ioctl_arg_type arg = (value ? 1 : 0);- int result = 0;- if ((state & possible_dup) == 0)- {- result = ::ioctl(d, FIONBIO, &arg);- get_last_error(ec, result < 0);- }- if ((state & possible_dup) != 0+ int result = ::ioctl(d, FIONBIO, &arg);+ get_last_error(ec, result < 0); # if defined(ENOTTY)- || ec.value() == ENOTTY-# endif // defined(ENOTTY)-# if defined(ENOTCAPABLE)- || ec.value() == ENOTCAPABLE-# endif // defined(ENOTCAPABLE)- )+ if (ec.value() == ENOTTY) { result = ::fcntl(d, F_GETFL, 0); get_last_error(ec, result < 0); if (result >= 0) { int flag = (value ? (result | O_NONBLOCK) : (result & ~O_NONBLOCK));- result = (flag != result) ? ::fcntl(d, F_SETFL, flag) : 0;+ result = ::fcntl(d, F_SETFL, flag); get_last_error(ec, result < 0); } }+# endif // defined(ENOTTY) #endif // defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__) if (result >= 0)@@ -185,35 +170,26 @@ if (result >= 0) { int flag = (value ? (result | O_NONBLOCK) : (result & ~O_NONBLOCK));- result = (flag != result) ? ::fcntl(d, F_SETFL, flag) : 0;+ result = ::fcntl(d, F_SETFL, flag); get_last_error(ec, result < 0); } #else // defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__) ioctl_arg_type arg = (value ? 1 : 0);- int result = 0;- if ((state & possible_dup) == 0)- {- result = ::ioctl(d, FIONBIO, &arg);- get_last_error(ec, result < 0);- }- if ((state & possible_dup) != 0+ int result = ::ioctl(d, FIONBIO, &arg);+ get_last_error(ec, result < 0); # if defined(ENOTTY)- || ec.value() == ENOTTY-# endif // defined(ENOTTY)-# if defined(ENOTCAPABLE)- || ec.value() == ENOTCAPABLE-# endif // defined(ENOTCAPABLE)- )+ if (ec.value() == ENOTTY) { result = ::fcntl(d, F_GETFL, 0); get_last_error(ec, result < 0); if (result >= 0) { int flag = (value ? (result | O_NONBLOCK) : (result & ~O_NONBLOCK));- result = (flag != result) ? ::fcntl(d, F_SETFL, flag) : 0;+ result = ::fcntl(d, F_SETFL, flag); get_last_error(ec, result < 0); } }+# endif // defined(ENOTTY) #endif // defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__) if (result >= 0)
link/modules/asio-standalone/asio/include/asio/detail/impl/dev_poll_reactor.hpp view
@@ -2,7 +2,7 @@ // detail/impl/dev_poll_reactor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -32,26 +32,22 @@ scheduler_.post_immediate_completion(op, is_continuation); } -template <typename TimeTraits, typename Allocator>-void dev_poll_reactor::add_timer_queue(- timer_queue<TimeTraits, Allocator>& queue)+template <typename Time_Traits>+void dev_poll_reactor::add_timer_queue(timer_queue<Time_Traits>& queue) { do_add_timer_queue(queue); } -template <typename TimeTraits, typename Allocator>-void dev_poll_reactor::remove_timer_queue(- timer_queue<TimeTraits, Allocator>& queue)+template <typename Time_Traits>+void dev_poll_reactor::remove_timer_queue(timer_queue<Time_Traits>& queue) { do_remove_timer_queue(queue); } -template <typename TimeTraits, typename Allocator>-void dev_poll_reactor::schedule_timer(- timer_queue<TimeTraits, Allocator>& queue,- const typename TimeTraits::time_type& time,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,- wait_op* op)+template <typename Time_Traits>+void dev_poll_reactor::schedule_timer(timer_queue<Time_Traits>& queue,+ const typename Time_Traits::time_type& time,+ typename timer_queue<Time_Traits>::per_timer_data& timer, wait_op* op) { asio::detail::mutex::scoped_lock lock(mutex_); @@ -67,10 +63,9 @@ interrupter_.interrupt(); } -template <typename TimeTraits, typename Allocator>-std::size_t dev_poll_reactor::cancel_timer(- timer_queue<TimeTraits, Allocator>& queue,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,+template <typename Time_Traits>+std::size_t dev_poll_reactor::cancel_timer(timer_queue<Time_Traits>& queue,+ typename timer_queue<Time_Traits>::per_timer_data& timer, std::size_t max_cancelled) { asio::detail::mutex::scoped_lock lock(mutex_);@@ -81,10 +76,9 @@ return n; } -template <typename TimeTraits, typename Allocator>-void dev_poll_reactor::cancel_timer_by_key(- timer_queue<TimeTraits, Allocator>& queue,- typename timer_queue<TimeTraits, Allocator>::per_timer_data* timer,+template <typename Time_Traits>+void dev_poll_reactor::cancel_timer_by_key(timer_queue<Time_Traits>& queue,+ typename timer_queue<Time_Traits>::per_timer_data* timer, void* cancellation_key) { asio::detail::mutex::scoped_lock lock(mutex_);@@ -94,10 +88,10 @@ scheduler_.post_deferred_completions(ops); } -template <typename TimeTraits, typename Allocator>-void dev_poll_reactor::move_timer(timer_queue<TimeTraits, Allocator>& queue,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& target,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& source)+template <typename Time_Traits>+void dev_poll_reactor::move_timer(timer_queue<Time_Traits>& queue,+ typename timer_queue<Time_Traits>::per_timer_data& target,+ typename timer_queue<Time_Traits>::per_timer_data& source) { asio::detail::mutex::scoped_lock lock(mutex_); op_queue<operation> ops;
link/modules/asio-standalone/asio/include/asio/detail/impl/dev_poll_reactor.ipp view
@@ -2,7 +2,7 @@ // detail/impl/dev_poll_reactor.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -66,7 +66,7 @@ timer_queues_.get_all_timers(ops); scheduler_.abandon_operations(ops);-}+} void dev_poll_reactor::notify_fork( asio::execution_context::fork_event fork_ev)
link/modules/asio-standalone/asio/include/asio/detail/impl/epoll_reactor.hpp view
@@ -2,7 +2,7 @@ // detail/impl/epoll_reactor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -30,25 +30,22 @@ scheduler_.post_immediate_completion(op, is_continuation); } -template <typename TimeTraits, typename Allocator>-void epoll_reactor::add_timer_queue(- timer_queue<TimeTraits, Allocator>& queue)+template <typename Time_Traits>+void epoll_reactor::add_timer_queue(timer_queue<Time_Traits>& queue) { do_add_timer_queue(queue); } -template <typename TimeTraits, typename Allocator>-void epoll_reactor::remove_timer_queue(- timer_queue<TimeTraits, Allocator>& queue)+template <typename Time_Traits>+void epoll_reactor::remove_timer_queue(timer_queue<Time_Traits>& queue) { do_remove_timer_queue(queue); } -template <typename TimeTraits, typename Allocator>-void epoll_reactor::schedule_timer(timer_queue<TimeTraits, Allocator>& queue,- const typename TimeTraits::time_type& time,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,- wait_op* op)+template <typename Time_Traits>+void epoll_reactor::schedule_timer(timer_queue<Time_Traits>& queue,+ const typename Time_Traits::time_type& time,+ typename timer_queue<Time_Traits>::per_timer_data& timer, wait_op* op) { mutex::scoped_lock lock(mutex_); @@ -64,10 +61,9 @@ update_timeout(); } -template <typename TimeTraits, typename Allocator>-std::size_t epoll_reactor::cancel_timer(- timer_queue<TimeTraits, Allocator>& queue,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,+template <typename Time_Traits>+std::size_t epoll_reactor::cancel_timer(timer_queue<Time_Traits>& queue,+ typename timer_queue<Time_Traits>::per_timer_data& timer, std::size_t max_cancelled) { mutex::scoped_lock lock(mutex_);@@ -78,10 +74,9 @@ return n; } -template <typename TimeTraits, typename Allocator>-void epoll_reactor::cancel_timer_by_key(- timer_queue<TimeTraits, Allocator>& queue,- typename timer_queue<TimeTraits, Allocator>::per_timer_data* timer,+template <typename Time_Traits>+void epoll_reactor::cancel_timer_by_key(timer_queue<Time_Traits>& queue,+ typename timer_queue<Time_Traits>::per_timer_data* timer, void* cancellation_key) { mutex::scoped_lock lock(mutex_);@@ -91,10 +86,10 @@ scheduler_.post_deferred_completions(ops); } -template <typename TimeTraits, typename Allocator>-void epoll_reactor::move_timer(timer_queue<TimeTraits, Allocator>& queue,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& target,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& source)+template <typename Time_Traits>+void epoll_reactor::move_timer(timer_queue<Time_Traits>& queue,+ typename timer_queue<Time_Traits>::per_timer_data& target,+ typename timer_queue<Time_Traits>::per_timer_data& source) { mutex::scoped_lock lock(mutex_); op_queue<operation> ops;
link/modules/asio-standalone/asio/include/asio/detail/impl/epoll_reactor.ipp view
@@ -2,7 +2,7 @@ // detail/impl/epoll_reactor.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -21,7 +21,6 @@ #include <cstddef> #include <sys/epoll.h>-#include "asio/config.hpp" #include "asio/detail/epoll_reactor.hpp" #include "asio/detail/scheduler.hpp" #include "asio/detail/throw_error.hpp"@@ -39,19 +38,13 @@ epoll_reactor::epoll_reactor(asio::execution_context& ctx) : execution_context_service_base<epoll_reactor>(ctx), scheduler_(use_service<scheduler>(ctx)),- mutex_(config(ctx).get("reactor", "registration_locking", true),- config(ctx).get("reactor", "registration_locking_spin_count", 0)),+ mutex_(ASIO_CONCURRENCY_HINT_IS_LOCKING(+ REACTOR_REGISTRATION, scheduler_.concurrency_hint())), interrupter_(), epoll_fd_(do_epoll_create()), timer_fd_(do_timerfd_create()), shutdown_(false),- io_locking_(config(ctx).get("reactor", "io_locking", true)),- io_locking_spin_count_(- config(ctx).get("reactor", "io_locking_spin_count", 0)),- registered_descriptors_mutex_(mutex_.enabled(), mutex_.spin_count()),- registered_descriptors_(execution_context::allocator<void>(ctx),- config(ctx).get("reactor", "preallocated_io_objects", 0U),- io_locking_, io_locking_spin_count_)+ registered_descriptors_mutex_(mutex_.enabled()) { // Add the interrupter's descriptor to epoll. epoll_event ev = { 0, { 0 } };@@ -137,18 +130,14 @@ for (descriptor_state* state = registered_descriptors_.first(); state != 0; state = state->next_) {- if (state->registered_events_ != 0)+ ev.events = state->registered_events_;+ ev.data.ptr = state;+ int result = epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, state->descriptor_, &ev);+ if (result != 0) {- ev.events = state->registered_events_;- ev.data.ptr = state;- int result = epoll_ctl(epoll_fd_,- EPOLL_CTL_ADD, state->descriptor_, &ev);- if (result != 0)- {- asio::error_code ec(errno,- asio::error::get_system_category());- asio::detail::throw_error(ec, "epoll re-registration");- }+ asio::error_code ec(errno,+ asio::error::get_system_category());+ asio::detail::throw_error(ec, "epoll re-registration"); } } }@@ -227,11 +216,7 @@ ev.data.ptr = descriptor_data; int result = epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, descriptor, &ev); if (result != 0)- {- // Don't try to re-register internal descriptor after fork().- descriptor_data->registered_events_ = 0; return errno;- } return 0; }@@ -678,7 +663,8 @@ epoll_reactor::descriptor_state* epoll_reactor::allocate_descriptor_state() { mutex::scoped_lock descriptors_lock(registered_descriptors_mutex_);- return registered_descriptors_.alloc(io_locking_, io_locking_spin_count_);+ return registered_descriptors_.alloc(ASIO_CONCURRENCY_HINT_IS_LOCKING(+ REACTOR_IO, scheduler_.concurrency_hint())); } void epoll_reactor::free_descriptor_state(epoll_reactor::descriptor_state* s)@@ -770,9 +756,9 @@ operation* first_op_; }; -epoll_reactor::descriptor_state::descriptor_state(bool locking, int spin_count)+epoll_reactor::descriptor_state::descriptor_state(bool locking) : operation(&epoll_reactor::descriptor_state::do_complete),- mutex_(locking, spin_count)+ mutex_(locking) { }
link/modules/asio-standalone/asio/include/asio/detail/impl/eventfd_select_interrupter.ipp view
@@ -2,7 +2,7 @@ // detail/impl/eventfd_select_interrupter.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2008 Roelof Naude (roelof.naude at gmail dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying
link/modules/asio-standalone/asio/include/asio/detail/impl/handler_tracking.ipp view
@@ -2,7 +2,7 @@ // detail/impl/handler_tracking.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -25,11 +25,16 @@ #include <cstdarg> #include <cstdio>-#include "asio/detail/chrono.hpp"-#include "asio/detail/chrono_time_traits.hpp" #include "asio/detail/handler_tracking.hpp"-#include "asio/wait_traits.hpp" +#if defined(ASIO_HAS_BOOST_DATE_TIME)+# include "asio/time_traits.hpp"+#elif defined(ASIO_HAS_CHRONO)+# include "asio/detail/chrono.hpp"+# include "asio/detail/chrono_time_traits.hpp"+# include "asio/wait_traits.hpp"+#endif // defined(ASIO_HAS_BOOST_DATE_TIME)+ #if defined(ASIO_WINDOWS_RUNTIME) # include "asio/detail/socket_types.hpp" #elif !defined(ASIO_WINDOWS)@@ -48,10 +53,16 @@ handler_tracking_timestamp() {+#if defined(ASIO_HAS_BOOST_DATE_TIME)+ boost::posix_time::ptime epoch(boost::gregorian::date(1970, 1, 1));+ boost::posix_time::time_duration now =+ boost::posix_time::microsec_clock::universal_time() - epoch;+#elif defined(ASIO_HAS_CHRONO) typedef chrono_time_traits<chrono::system_clock,- asio::wait_traits<chrono::system_clock>> traits_helper;+ asio::wait_traits<chrono::system_clock> > traits_helper; traits_helper::posix_time_duration now( chrono::system_clock::now().time_since_epoch());+#endif seconds = static_cast<uint64_t>(now.total_seconds()); microseconds = static_cast<uint64_t>(now.total_microseconds() % 1000000); }
link/modules/asio-standalone/asio/include/asio/detail/impl/io_uring_descriptor_service.ipp view
@@ -2,7 +2,7 @@ // detail/impl/io_uring_descriptor_service.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -50,7 +50,7 @@ void io_uring_descriptor_service::move_construct( io_uring_descriptor_service::implementation_type& impl, io_uring_descriptor_service::implementation_type& other_impl)- noexcept+ ASIO_NOEXCEPT { impl.descriptor_ = other_impl.descriptor_; other_impl.descriptor_ = -1;
link/modules/asio-standalone/asio/include/asio/detail/impl/io_uring_file_service.ipp view
@@ -2,7 +2,7 @@ // detail/impl/io_uring_file_service.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/impl/io_uring_service.hpp view
@@ -2,7 +2,7 @@ // detail/impl/io_uring_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -30,26 +30,22 @@ scheduler_.post_immediate_completion(op, is_continuation); } -template <typename TimeTraits, typename Allocator>-void io_uring_service::add_timer_queue(- timer_queue<TimeTraits, Allocator>& queue)+template <typename Time_Traits>+void io_uring_service::add_timer_queue(timer_queue<Time_Traits>& queue) { do_add_timer_queue(queue); } -template <typename TimeTraits, typename Allocator>-void io_uring_service::remove_timer_queue(- timer_queue<TimeTraits, Allocator>& queue)+template <typename Time_Traits>+void io_uring_service::remove_timer_queue(timer_queue<Time_Traits>& queue) { do_remove_timer_queue(queue); } -template <typename TimeTraits, typename Allocator>-void io_uring_service::schedule_timer(- timer_queue<TimeTraits, Allocator>& queue,- const typename TimeTraits::time_type& time,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,- wait_op* op)+template <typename Time_Traits>+void io_uring_service::schedule_timer(timer_queue<Time_Traits>& queue,+ const typename Time_Traits::time_type& time,+ typename timer_queue<Time_Traits>::per_timer_data& timer, wait_op* op) { mutex::scoped_lock lock(mutex_); @@ -68,10 +64,9 @@ } } -template <typename TimeTraits, typename Allocator>-std::size_t io_uring_service::cancel_timer(- timer_queue<TimeTraits, Allocator>& queue,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,+template <typename Time_Traits>+std::size_t io_uring_service::cancel_timer(timer_queue<Time_Traits>& queue,+ typename timer_queue<Time_Traits>::per_timer_data& timer, std::size_t max_cancelled) { mutex::scoped_lock lock(mutex_);@@ -82,10 +77,9 @@ return n; } -template <typename TimeTraits, typename Allocator>-void io_uring_service::cancel_timer_by_key(- timer_queue<TimeTraits, Allocator>& queue,- typename timer_queue<TimeTraits, Allocator>::per_timer_data* timer,+template <typename Time_Traits>+void io_uring_service::cancel_timer_by_key(timer_queue<Time_Traits>& queue,+ typename timer_queue<Time_Traits>::per_timer_data* timer, void* cancellation_key) { mutex::scoped_lock lock(mutex_);@@ -95,10 +89,10 @@ scheduler_.post_deferred_completions(ops); } -template <typename TimeTraits, typename Allocator>-void io_uring_service::move_timer(timer_queue<TimeTraits, Allocator>& queue,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& target,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& source)+template <typename Time_Traits>+void io_uring_service::move_timer(timer_queue<Time_Traits>& queue,+ typename timer_queue<Time_Traits>::per_timer_data& target,+ typename timer_queue<Time_Traits>::per_timer_data& source) { mutex::scoped_lock lock(mutex_); op_queue<operation> ops;
link/modules/asio-standalone/asio/include/asio/detail/impl/io_uring_service.ipp view
@@ -2,7 +2,7 @@ // detail/impl/io_uring_service.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -35,21 +35,15 @@ io_uring_service::io_uring_service(asio::execution_context& ctx) : execution_context_service_base<io_uring_service>(ctx), scheduler_(use_service<scheduler>(ctx)),- mutex_(config(ctx).get("reactor", "registration_locking", true),- config(ctx).get("reactor", "registration_locking_spin_count", 0)),+ mutex_(ASIO_CONCURRENCY_HINT_IS_LOCKING(+ REACTOR_REGISTRATION, scheduler_.concurrency_hint())), outstanding_work_(0), submit_sqes_op_(this), pending_sqes_(0), pending_submit_sqes_op_(false), shutdown_(false),- io_locking_(config(ctx).get("reactor", "io_locking", true)),- io_locking_spin_count_(- config(ctx).get("reactor", "io_locking_spin_count", 0)), timeout_(), registration_mutex_(mutex_.enabled()),- registered_io_objects_(execution_context::allocator<void>(ctx),- config(ctx).get("reactor", "preallocated_io_objects", 0U),- io_locking_, io_locking_spin_count_), reactor_(use_service<reactor>(ctx)), reactor_data_(), event_fd_(-1)@@ -441,16 +435,15 @@ ? ::io_uring_peek_cqe(&ring_, &cqe) : ::io_uring_wait_cqe(&ring_, &cqe); - if (local_ops > 0)+ if (result == 0 && usec > 0) {- if (result != 0 || ::io_uring_cqe_get_data(cqe) != &ts)+ if (::io_uring_cqe_get_data(cqe) != &ts) { mutex::scoped_lock lock(mutex_); if (::io_uring_sqe* sqe = get_sqe()) { ++local_ops; ::io_uring_prep_timeout_remove(sqe, reinterpret_cast<__u64>(&ts), 0);- ::io_uring_sqe_set_data(sqe, &ts); submit_sqes(); } }@@ -458,41 +451,37 @@ bool check_timers = false; int count = 0;- while (result == 0 || local_ops > 0)+ while (result == 0) {- if (result == 0)+ if (void* ptr = ::io_uring_cqe_get_data(cqe)) {- if (void* ptr = ::io_uring_cqe_get_data(cqe))+ if (ptr == this) {- if (ptr == this)- {- // The io_uring service was interrupted.- }- else if (ptr == &timer_queues_)- {- check_timers = true;- }- else if (ptr == &timeout_)- {- check_timers = true;- timeout_.tv_sec = 0;- timeout_.tv_nsec = 0;- }- else if (ptr == &ts)- {- --local_ops;- }- else- {- io_queue* io_q = static_cast<io_queue*>(ptr);- io_q->set_result(cqe->res);- ops.push(io_q);- }+ // The io_uring service was interrupted. }- ::io_uring_cqe_seen(&ring_, cqe);- ++count;+ else if (ptr == &timer_queues_)+ {+ check_timers = true;+ }+ else if (ptr == &timeout_)+ {+ check_timers = true;+ timeout_.tv_sec = 0;+ timeout_.tv_nsec = 0;+ }+ else if (ptr == &ts)+ {+ --local_ops;+ }+ else+ {+ io_queue* io_q = static_cast<io_queue*>(ptr);+ io_q->set_result(cqe->res);+ ops.push(io_q);+ } }- result = (count < complete_batch_size || local_ops > 0)+ ::io_uring_cqe_seen(&ring_, cqe);+ result = (++count < complete_batch_size || local_ops > 0) ? ::io_uring_peek_cqe(&ring_, &cqe) : -EAGAIN; } @@ -618,7 +607,9 @@ io_uring_service::io_object* io_uring_service::allocate_io_object() { mutex::scoped_lock registration_lock(registration_mutex_);- return registered_io_objects_.alloc(io_locking_, io_locking_spin_count_);+ return registered_io_objects_.alloc(+ ASIO_CONCURRENCY_HINT_IS_LOCKING(+ REACTOR_IO, scheduler_.concurrency_hint())); } void io_uring_service::free_io_object(io_uring_service::io_object* io_obj)@@ -903,8 +894,8 @@ } } -io_uring_service::io_object::io_object(bool locking, int spin_count)- : mutex_(locking, spin_count)+io_uring_service::io_object::io_object(bool locking)+ : mutex_(locking) { }
link/modules/asio-standalone/asio/include/asio/detail/impl/io_uring_socket_service_base.ipp view
@@ -2,7 +2,7 @@ // detail/io_uring_socket_service_base.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -48,7 +48,7 @@ void io_uring_socket_service_base::base_move_construct( io_uring_socket_service_base::base_implementation_type& impl, io_uring_socket_service_base::base_implementation_type& other_impl)- noexcept+ ASIO_NOEXCEPT { impl.socket_ = other_impl.socket_; other_impl.socket_ = invalid_socket;
link/modules/asio-standalone/asio/include/asio/detail/impl/kqueue_reactor.hpp view
@@ -2,7 +2,7 @@ // detail/impl/kqueue_reactor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2005 Stefan Arentz (stefan at soze dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying@@ -33,25 +33,23 @@ scheduler_.post_immediate_completion(op, is_continuation); } -template <typename TimeTraits, typename Allocator>-void kqueue_reactor::add_timer_queue(timer_queue<TimeTraits, Allocator>& queue)+template <typename Time_Traits>+void kqueue_reactor::add_timer_queue(timer_queue<Time_Traits>& queue) { do_add_timer_queue(queue); } // Remove a timer queue from the reactor.-template <typename TimeTraits, typename Allocator>-void kqueue_reactor::remove_timer_queue(- timer_queue<TimeTraits, Allocator>& queue)+template <typename Time_Traits>+void kqueue_reactor::remove_timer_queue(timer_queue<Time_Traits>& queue) { do_remove_timer_queue(queue); } -template <typename TimeTraits, typename Allocator>-void kqueue_reactor::schedule_timer(timer_queue<TimeTraits, Allocator>& queue,- const typename TimeTraits::time_type& time,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,- wait_op* op)+template <typename Time_Traits>+void kqueue_reactor::schedule_timer(timer_queue<Time_Traits>& queue,+ const typename Time_Traits::time_type& time,+ typename timer_queue<Time_Traits>::per_timer_data& timer, wait_op* op) { mutex::scoped_lock lock(mutex_); @@ -67,10 +65,9 @@ interrupt(); } -template <typename TimeTraits, typename Allocator>-std::size_t kqueue_reactor::cancel_timer(- timer_queue<TimeTraits, Allocator>& queue,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,+template <typename Time_Traits>+std::size_t kqueue_reactor::cancel_timer(timer_queue<Time_Traits>& queue,+ typename timer_queue<Time_Traits>::per_timer_data& timer, std::size_t max_cancelled) { mutex::scoped_lock lock(mutex_);@@ -81,10 +78,9 @@ return n; } -template <typename TimeTraits, typename Allocator>-void kqueue_reactor::cancel_timer_by_key(- timer_queue<TimeTraits, Allocator>& queue,- typename timer_queue<TimeTraits, Allocator>::per_timer_data* timer,+template <typename Time_Traits>+void kqueue_reactor::cancel_timer_by_key(timer_queue<Time_Traits>& queue,+ typename timer_queue<Time_Traits>::per_timer_data* timer, void* cancellation_key) { mutex::scoped_lock lock(mutex_);@@ -94,10 +90,10 @@ scheduler_.post_deferred_completions(ops); } -template <typename TimeTraits, typename Allocator>-void kqueue_reactor::move_timer(timer_queue<TimeTraits, Allocator>& queue,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& target,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& source)+template <typename Time_Traits>+void kqueue_reactor::move_timer(timer_queue<Time_Traits>& queue,+ typename timer_queue<Time_Traits>::per_timer_data& target,+ typename timer_queue<Time_Traits>::per_timer_data& source) { mutex::scoped_lock lock(mutex_); op_queue<operation> ops;
link/modules/asio-standalone/asio/include/asio/detail/impl/kqueue_reactor.ipp view
@@ -2,7 +2,7 @@ // detail/impl/kqueue_reactor.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2005 Stefan Arentz (stefan at soze dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying@@ -20,7 +20,6 @@ #if defined(ASIO_HAS_KQUEUE) -#include "asio/config.hpp" #include "asio/detail/kqueue_reactor.hpp" #include "asio/detail/scheduler.hpp" #include "asio/detail/throw_error.hpp"@@ -47,18 +46,12 @@ kqueue_reactor::kqueue_reactor(asio::execution_context& ctx) : execution_context_service_base<kqueue_reactor>(ctx), scheduler_(use_service<scheduler>(ctx)),- mutex_(config(ctx).get("reactor", "registration_locking", true),- config(ctx).get("reactor", "registration_locking_spin_count", 0)),+ mutex_(ASIO_CONCURRENCY_HINT_IS_LOCKING(+ REACTOR_REGISTRATION, scheduler_.concurrency_hint())), kqueue_fd_(do_kqueue_create()), interrupter_(), shutdown_(false),- io_locking_(config(ctx).get("reactor", "io_locking", true)),- io_locking_spin_count_(- config(ctx).get("reactor", "io_locking_spin_count", 0)),- registered_descriptors_mutex_(mutex_.enabled()),- registered_descriptors_(execution_context::allocator<void>(ctx),- config(ctx).get("reactor", "preallocated_io_objects", 0U),- io_locking_, io_locking_spin_count_)+ registered_descriptors_mutex_(mutex_.enabled()) { struct kevent events[1]; ASIO_KQUEUE_EV_SET(&events[0], interrupter_.read_descriptor(),@@ -569,7 +562,8 @@ kqueue_reactor::descriptor_state* kqueue_reactor::allocate_descriptor_state() { mutex::scoped_lock descriptors_lock(registered_descriptors_mutex_);- return registered_descriptors_.alloc(io_locking_, io_locking_spin_count_);+ return registered_descriptors_.alloc(ASIO_CONCURRENCY_HINT_IS_LOCKING(+ REACTOR_IO, scheduler_.concurrency_hint())); } void kqueue_reactor::free_descriptor_state(kqueue_reactor::descriptor_state* s)
link/modules/asio-standalone/asio/include/asio/detail/impl/null_event.ipp view
@@ -2,7 +2,7 @@ // detail/impl/null_event.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/impl/pipe_select_interrupter.ipp view
@@ -2,7 +2,7 @@ // detail/impl/pipe_select_interrupter.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/impl/posix_event.ipp view
@@ -2,7 +2,7 @@ // detail/impl/posix_event.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/impl/posix_mutex.ipp view
@@ -2,7 +2,7 @@ // detail/impl/posix_mutex.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/impl/posix_serial_port_service.ipp view
@@ -2,7 +2,7 @@ // detail/impl/posix_serial_port_service.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying
link/modules/asio-standalone/asio/include/asio/detail/impl/posix_thread.ipp view
@@ -2,7 +2,7 @@ // detail/impl/posix_thread.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -30,17 +30,16 @@ posix_thread::~posix_thread() {- if (arg_)- std::terminate();+ if (!joined_)+ ::pthread_detach(thread_); } void posix_thread::join() {- if (arg_)+ if (!joined_) {- ::pthread_join(arg_->thread_, 0);- arg_->destroy();- arg_ = 0;+ ::pthread_join(thread_, 0);+ joined_ = true; } } @@ -54,23 +53,24 @@ return 0; } -posix_thread::func_base* posix_thread::start_thread(func_base* arg)+void posix_thread::start_thread(func_base* arg) {- int error = ::pthread_create(&arg->thread_, 0,+ int error = ::pthread_create(&thread_, 0, asio_detail_posix_thread_function, arg); if (error != 0) {- arg->destroy();+ delete arg; asio::error_code ec(error, asio::error::get_system_category()); asio::detail::throw_error(ec, "thread"); }- return arg; } void* asio_detail_posix_thread_function(void* arg) {- static_cast<posix_thread::func_base*>(arg)->run();+ posix_thread::auto_func_base_ptr func = {+ static_cast<posix_thread::func_base*>(arg) };+ func.ptr->run(); return 0; }
link/modules/asio-standalone/asio/include/asio/detail/impl/posix_tss_ptr.ipp view
@@ -2,7 +2,7 @@ // detail/impl/posix_tss_ptr.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/impl/reactive_descriptor_service.ipp view
@@ -2,7 +2,7 @@ // detail/impl/reactive_descriptor_service.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -53,7 +53,7 @@ void reactive_descriptor_service::move_construct( reactive_descriptor_service::implementation_type& impl, reactive_descriptor_service::implementation_type& other_impl)- noexcept+ ASIO_NOEXCEPT { impl.descriptor_ = other_impl.descriptor_; other_impl.descriptor_ = -1;@@ -198,20 +198,18 @@ } void reactive_descriptor_service::do_start_op(implementation_type& impl,- int op_type, reactor_op* op, bool is_continuation,- bool allow_speculative, bool noop, bool needs_non_blocking,- void (*on_immediate)(operation* op, bool, const void*),+ int op_type, reactor_op* op, bool is_continuation, bool is_non_blocking,+ bool noop, void (*on_immediate)(operation* op, bool, const void*), const void* immediate_arg) { if (!noop) {- if ((impl.state_ & descriptor_ops::non_blocking)- || !needs_non_blocking- || descriptor_ops::set_internal_non_blocking(+ if ((impl.state_ & descriptor_ops::non_blocking) ||+ descriptor_ops::set_internal_non_blocking( impl.descriptor_, impl.state_, true, op->ec_)) { reactor_.start_op(op_type, impl.descriptor_, impl.reactor_data_, op,- is_continuation, allow_speculative, on_immediate, immediate_arg);+ is_continuation, is_non_blocking, on_immediate, immediate_arg); return; } }
link/modules/asio-standalone/asio/include/asio/detail/impl/reactive_socket_service_base.ipp view
@@ -2,7 +2,7 @@ // detail/reactive_socket_service_base.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -50,7 +50,7 @@ void reactive_socket_service_base::base_move_construct( reactive_socket_service_base::base_implementation_type& impl, reactive_socket_service_base::base_implementation_type& other_impl)- noexcept+ ASIO_NOEXCEPT { impl.socket_ = other_impl.socket_; other_impl.socket_ = invalid_socket;@@ -234,21 +234,19 @@ } void reactive_socket_service_base::do_start_op(- reactive_socket_service_base::base_implementation_type& impl,- int op_type, reactor_op* op, bool is_continuation,- bool allow_speculative, bool noop, bool needs_non_blocking,+ reactive_socket_service_base::base_implementation_type& impl, int op_type,+ reactor_op* op, bool is_continuation, bool is_non_blocking, bool noop, void (*on_immediate)(operation* op, bool, const void*), const void* immediate_arg) { if (!noop) { if ((impl.state_ & socket_ops::non_blocking)- || !needs_non_blocking || socket_ops::set_internal_non_blocking( impl.socket_, impl.state_, true, op->ec_)) { reactor_.start_op(op_type, impl.socket_, impl.reactor_data_, op,- is_continuation, allow_speculative, on_immediate, immediate_arg);+ is_continuation, is_non_blocking, on_immediate, immediate_arg); return; } }@@ -265,7 +263,7 @@ if (!peer_is_open) { do_start_op(impl, reactor::read_op, op, is_continuation,- true, false, true, on_immediate, immediate_arg);+ true, false, on_immediate, immediate_arg); } else {
link/modules/asio-standalone/asio/include/asio/detail/impl/resolver_service_base.ipp view
@@ -2,7 +2,7 @@ // detail/impl/resolver_service_base.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -16,8 +16,6 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"-#include "asio/config.hpp"-#include "asio/detail/memory.hpp" #include "asio/detail/resolver_service_base.hpp" #include "asio/detail/push_options.hpp"@@ -25,15 +23,70 @@ namespace asio { namespace detail { +class resolver_service_base::work_scheduler_runner+{+public:+ work_scheduler_runner(scheduler_impl& work_scheduler)+ : work_scheduler_(work_scheduler)+ {+ }++ void operator()()+ {+ asio::error_code ec;+ work_scheduler_.run(ec);+ }++private:+ scheduler_impl& work_scheduler_;+};+ resolver_service_base::resolver_service_base(execution_context& context)- : thread_pool_(asio::use_service<resolver_thread_pool>(context))+ : scheduler_(asio::use_service<scheduler_impl>(context)),+ work_scheduler_(new scheduler_impl(context, -1, false)),+ work_thread_(0) {+ work_scheduler_->work_started(); } resolver_service_base::~resolver_service_base() {+ base_shutdown(); } +void resolver_service_base::base_shutdown()+{+ if (work_scheduler_.get())+ {+ work_scheduler_->work_finished();+ work_scheduler_->stop();+ if (work_thread_.get())+ {+ work_thread_->join();+ work_thread_.reset();+ }+ work_scheduler_.reset();+ }+}++void resolver_service_base::base_notify_fork(+ execution_context::fork_event fork_ev)+{+ if (work_thread_.get())+ {+ if (fork_ev == execution_context::fork_prepare)+ {+ work_scheduler_->stop();+ work_thread_->join();+ work_thread_.reset();+ }+ }+ else if (fork_ev != execution_context::fork_prepare)+ {+ work_scheduler_->restart();+ }+}+ void resolver_service_base::construct( resolver_service_base::implementation_type& impl) {@@ -43,7 +96,7 @@ void resolver_service_base::destroy( resolver_service_base::implementation_type& impl) {- ASIO_HANDLER_OPERATION((thread_pool_.context(),+ ASIO_HANDLER_OPERATION((scheduler_.context(), "resolver", &impl, 0, "cancel")); impl.reset();@@ -52,23 +105,49 @@ void resolver_service_base::move_construct(implementation_type& impl, implementation_type& other_impl) {- impl = static_cast<implementation_type&&>(other_impl);+ impl = ASIO_MOVE_CAST(implementation_type)(other_impl); } void resolver_service_base::move_assign(implementation_type& impl, resolver_service_base&, implementation_type& other_impl) { destroy(impl);- impl = static_cast<implementation_type&&>(other_impl);+ impl = ASIO_MOVE_CAST(implementation_type)(other_impl); } void resolver_service_base::cancel( resolver_service_base::implementation_type& impl) {- ASIO_HANDLER_OPERATION((thread_pool_.context(),+ ASIO_HANDLER_OPERATION((scheduler_.context(), "resolver", &impl, 0, "cancel")); impl.reset(static_cast<void*>(0), socket_ops::noop_deleter());+}++void resolver_service_base::start_resolve_op(resolve_op* op)+{+ if (ASIO_CONCURRENCY_HINT_IS_LOCKING(SCHEDULER,+ scheduler_.concurrency_hint()))+ {+ start_work_thread();+ scheduler_.work_started();+ work_scheduler_->post_immediate_completion(op, false);+ }+ else+ {+ op->ec_ = asio::error::operation_not_supported;+ scheduler_.post_immediate_completion(op, false);+ }+}++void resolver_service_base::start_work_thread()+{+ asio::detail::mutex::scoped_lock lock(mutex_);+ if (!work_thread_.get())+ {+ work_thread_.reset(new asio::detail::thread(+ work_scheduler_runner(*work_scheduler_)));+ } } } // namespace detail
− link/modules/asio-standalone/asio/include/asio/detail/impl/resolver_thread_pool.ipp
@@ -1,124 +0,0 @@-//-// detail/impl/resolver_thread_pool.ipp-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef ASIO_DETAIL_IMPL_RESOLVER_THREAD_POOL_IPP-#define ASIO_DETAIL_IMPL_RESOLVER_THREAD_POOL_IPP--#if defined(_MSC_VER) && (_MSC_VER >= 1200)-# pragma once-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)--#include "asio/detail/config.hpp"-#include "asio/config.hpp"-#include "asio/detail/memory.hpp"-#include "asio/detail/resolver_thread_pool.hpp"-#include "asio/error.hpp"--#include "asio/detail/push_options.hpp"--namespace asio {-namespace detail {--class resolver_thread_pool::work_scheduler_runner-{-public:- work_scheduler_runner(scheduler_impl& work_scheduler)- : work_scheduler_(work_scheduler)- {- }-- void operator()()- {- asio::error_code ec;- work_scheduler_.run(ec);- }--private:- scheduler_impl& work_scheduler_;-};--resolver_thread_pool::resolver_thread_pool(execution_context& context)- : execution_context_service_base<resolver_thread_pool>(context),- scheduler_(asio::use_service<scheduler_impl>(context)),- work_scheduler_(scheduler_impl::internal(), context),- work_threads_(execution_context::allocator<void>(context)),- num_work_threads_(config(context).get("resolver", "threads", 0U)),- scheduler_locking_(config(context).get("scheduler", "locking", true)),- shutdown_(false)-{- work_scheduler_.work_started();- if (num_work_threads_ > 0)- start_work_threads();- else- num_work_threads_ = 1;-}--resolver_thread_pool::~resolver_thread_pool()-{- shutdown();-}--void resolver_thread_pool::shutdown()-{- if (!shutdown_)- {- work_scheduler_.work_finished();- work_scheduler_.stop();- work_threads_.join();- work_scheduler_.shutdown();- shutdown_ = true;- }-}--void resolver_thread_pool::notify_fork(execution_context::fork_event fork_ev)-{- if (!work_threads_.empty())- {- if (fork_ev == execution_context::fork_prepare)- {- work_scheduler_.stop();- work_threads_.join();- }- }- else if (fork_ev != execution_context::fork_prepare)- {- work_scheduler_.restart();- }-}--void resolver_thread_pool::start_resolve_op(resolve_op* op)-{- if (scheduler_locking_)- {- start_work_threads();- scheduler_.work_started();- work_scheduler_.post_immediate_completion(op, false);- }- else- {- op->ec_ = asio::error::operation_not_supported;- scheduler_.post_immediate_completion(op, false);- }-}--void resolver_thread_pool::start_work_threads()-{- asio::detail::mutex::scoped_lock lock(mutex_);- if (work_threads_.empty())- for (unsigned int i = 0; i < num_work_threads_; ++i)- work_threads_.create_thread(work_scheduler_runner(work_scheduler_));-}--} // namespace detail-} // namespace asio--#include "asio/detail/pop_options.hpp"--#endif // ASIO_DETAIL_IMPL_RESOLVER_THREAD_POOL_IPP
link/modules/asio-standalone/asio/include/asio/detail/impl/scheduler.ipp view
@@ -2,7 +2,7 @@ // detail/impl/scheduler.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -17,7 +17,7 @@ #include "asio/detail/config.hpp" -#include "asio/config.hpp"+#include "asio/detail/concurrency_hint.hpp" #include "asio/detail/event.hpp" #include "asio/detail/limits.hpp" #include "asio/detail/scheduler.hpp"@@ -109,56 +109,44 @@ }; scheduler::scheduler(asio::execution_context& ctx,- bool own_thread, get_task_func_type get_task)+ int concurrency_hint, bool own_thread, get_task_func_type get_task) : asio::detail::execution_context_service_base<scheduler>(ctx),- one_thread_(config(ctx).get("scheduler", "concurrency_hint", 0) == 1),- mutex_(config(ctx).get("scheduler", "locking", true),- config(ctx).get("scheduler", "locking_spin_count", 0)),+ one_thread_(concurrency_hint == 1+ || !ASIO_CONCURRENCY_HINT_IS_LOCKING(+ SCHEDULER, concurrency_hint)+ || !ASIO_CONCURRENCY_HINT_IS_LOCKING(+ REACTOR_IO, concurrency_hint)),+ mutex_(ASIO_CONCURRENCY_HINT_IS_LOCKING(+ SCHEDULER, concurrency_hint)), task_(0), get_task_(get_task), task_interrupted_(true),+ outstanding_work_(0), stopped_(false), shutdown_(false),- outstanding_work_(0),- task_usec_(config(ctx).get("scheduler", "task_usec", -1L)),- wait_usec_(config(ctx).get("scheduler", "wait_usec", -1L)),- thread_()+ concurrency_hint_(concurrency_hint),+ thread_(0) { ASIO_HANDLER_TRACKING_INIT; if (own_thread) { ++outstanding_work_;- signal_blocker sb;- thread_ = thread(thread_function(this));+ asio::detail::signal_blocker sb;+ thread_ = new asio::detail::thread(thread_function(this)); } } -scheduler::scheduler(scheduler::internal, asio::execution_context& ctx)- : asio::detail::execution_context_service_base<scheduler>(ctx),- one_thread_(false),- mutex_(true, 0),- task_(0),- get_task_(&scheduler::get_default_task),- task_interrupted_(true),- stopped_(false),- shutdown_(false),- outstanding_work_(0),- task_usec_(-1L),- wait_usec_(-1L)-{- ASIO_HANDLER_TRACKING_INIT;-}- scheduler::~scheduler() {- if (thread_.joinable())+ if (thread_) { mutex::scoped_lock lock(mutex_); shutdown_ = true; stop_all_threads(lock); lock.unlock();- thread_.join();+ thread_->join();+ delete thread_; } } @@ -166,12 +154,17 @@ { mutex::scoped_lock lock(mutex_); shutdown_ = true;- if (thread_.joinable())+ if (thread_) stop_all_threads(lock); lock.unlock(); // Join thread to ensure task operation is returned to queue.- thread_.join();+ if (thread_)+ {+ thread_->join();+ delete thread_;+ thread_ = 0;+ } // Destroy handler objects. while (!op_queue_.empty())@@ -467,9 +460,9 @@ if (o == &task_operation_) {- task_interrupted_ = more_handlers || task_usec_ == 0;+ task_interrupted_ = more_handlers; - if (more_handlers && !one_thread_ && wait_usec_ != 0)+ if (more_handlers && !one_thread_) wakeup_event_.unlock_and_signal_one(lock); else lock.unlock();@@ -480,8 +473,7 @@ // Run the task. May throw an exception. Only block if the operation // queue is empty and we're not polling, otherwise we want to return // as soon as possible.- task_->run(more_handlers ? 0 : task_usec_,- this_thread.private_op_queue);+ task_->run(more_handlers ? 0 : -1, this_thread.private_op_queue); } else {@@ -505,19 +497,8 @@ } else {- if (wait_usec_ == 0)- {- lock.unlock();- lock.lock();- }- else- {- wakeup_event_.clear(lock);- if (wait_usec_ > 0)- wakeup_event_.wait_for_usec(lock, wait_usec_);- else- wakeup_event_.wait(lock);- }+ wakeup_event_.clear(lock);+ wakeup_event_.wait(lock); } } @@ -535,7 +516,6 @@ if (o == 0) { wakeup_event_.clear(lock);- usec = (wait_usec_ >= 0 && wait_usec_ < usec) ? wait_usec_ : usec; wakeup_event_.wait_for_usec(lock, usec); usec = 0; // Wait at most once. o = op_queue_.front();@@ -546,10 +526,9 @@ op_queue_.pop(); bool more_handlers = (!op_queue_.empty()); - usec = (task_usec_ >= 0 && task_usec_ < usec) ? task_usec_ : usec;- task_interrupted_ = more_handlers || usec == 0;+ task_interrupted_ = more_handlers; - if (more_handlers && !one_thread_ && wait_usec_ != 0)+ if (more_handlers && !one_thread_) wakeup_event_.unlock_and_signal_one(lock); else lock.unlock();@@ -668,7 +647,7 @@ void scheduler::wake_one_thread_and_unlock( mutex::scoped_lock& lock) {- if (wait_usec_ == 0 || !wakeup_event_.maybe_unlock_and_signal_one(lock))+ if (!wakeup_event_.maybe_unlock_and_signal_one(lock)) { if (!task_interrupted_ && task_) {
link/modules/asio-standalone/asio/include/asio/detail/impl/select_reactor.hpp view
@@ -2,7 +2,7 @@ // detail/impl/select_reactor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -40,27 +40,23 @@ scheduler_.post_immediate_completion(op, is_continuation); } -template <typename TimeTraits, typename Allocator>-void select_reactor::add_timer_queue(- timer_queue<TimeTraits, Allocator>& queue)+template <typename Time_Traits>+void select_reactor::add_timer_queue(timer_queue<Time_Traits>& queue) { do_add_timer_queue(queue); } // Remove a timer queue from the reactor.-template <typename TimeTraits, typename Allocator>-void select_reactor::remove_timer_queue(- timer_queue<TimeTraits, Allocator>& queue)+template <typename Time_Traits>+void select_reactor::remove_timer_queue(timer_queue<Time_Traits>& queue) { do_remove_timer_queue(queue); } -template <typename TimeTraits, typename Allocator>-void select_reactor::schedule_timer(- timer_queue<TimeTraits, Allocator>& queue,- const typename TimeTraits::time_type& time,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,- wait_op* op)+template <typename Time_Traits>+void select_reactor::schedule_timer(timer_queue<Time_Traits>& queue,+ const typename Time_Traits::time_type& time,+ typename timer_queue<Time_Traits>::per_timer_data& timer, wait_op* op) { asio::detail::mutex::scoped_lock lock(mutex_); @@ -76,10 +72,9 @@ interrupter_.interrupt(); } -template <typename TimeTraits, typename Allocator>-std::size_t select_reactor::cancel_timer(- timer_queue<TimeTraits, Allocator>& queue,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,+template <typename Time_Traits>+std::size_t select_reactor::cancel_timer(timer_queue<Time_Traits>& queue,+ typename timer_queue<Time_Traits>::per_timer_data& timer, std::size_t max_cancelled) { asio::detail::mutex::scoped_lock lock(mutex_);@@ -90,10 +85,9 @@ return n; } -template <typename TimeTraits, typename Allocator>-void select_reactor::cancel_timer_by_key(- timer_queue<TimeTraits, Allocator>& queue,- typename timer_queue<TimeTraits, Allocator>::per_timer_data* timer,+template <typename Time_Traits>+void select_reactor::cancel_timer_by_key(timer_queue<Time_Traits>& queue,+ typename timer_queue<Time_Traits>::per_timer_data* timer, void* cancellation_key) { mutex::scoped_lock lock(mutex_);@@ -103,10 +97,10 @@ scheduler_.post_deferred_completions(ops); } -template <typename TimeTraits, typename Allocator>-void select_reactor::move_timer(timer_queue<TimeTraits, Allocator>& queue,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& target,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& source)+template <typename Time_Traits>+void select_reactor::move_timer(timer_queue<Time_Traits>& queue,+ typename timer_queue<Time_Traits>::per_timer_data& target,+ typename timer_queue<Time_Traits>::per_timer_data& source) { asio::detail::mutex::scoped_lock lock(mutex_); op_queue<operation> ops;
link/modules/asio-standalone/asio/include/asio/detail/impl/select_reactor.ipp view
@@ -2,7 +2,7 @@ // detail/impl/select_reactor.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -65,14 +65,14 @@ interrupter_(), #if defined(ASIO_HAS_IOCP) stop_thread_(false),- thread_(),+ thread_(0), restart_reactor_(this), #endif // defined(ASIO_HAS_IOCP) shutdown_(false) { #if defined(ASIO_HAS_IOCP) asio::detail::signal_blocker sb;- thread_ = thread(thread_function(this));+ thread_ = new asio::detail::thread(thread_function(this)); #endif // defined(ASIO_HAS_IOCP) } @@ -87,13 +87,18 @@ shutdown_ = true; #if defined(ASIO_HAS_IOCP) stop_thread_ = true;- if (thread_.joinable())+ if (thread_) interrupter_.interrupt(); #endif // defined(ASIO_HAS_IOCP) lock.unlock(); #if defined(ASIO_HAS_IOCP)- thread_.join();+ if (thread_)+ {+ thread_->join();+ delete thread_;+ thread_ = 0;+ } #endif // defined(ASIO_HAS_IOCP) op_queue<operation> ops;@@ -325,7 +330,12 @@ { select_reactor* reactor = static_cast<restart_reactor*>(base)->reactor_; - reactor->thread_.join();+ if (reactor->thread_)+ {+ reactor->thread_->join();+ delete reactor->thread_;+ reactor->thread_ = 0;+ } asio::detail::mutex::scoped_lock lock(reactor->mutex_); reactor->interrupter_.recreate();@@ -333,7 +343,8 @@ lock.unlock(); asio::detail::signal_blocker sb;- reactor->thread_ = thread(thread_function(reactor));+ reactor->thread_ =+ new asio::detail::thread(thread_function(reactor)); } } #endif // defined(ASIO_HAS_IOCP)
link/modules/asio-standalone/asio/include/asio/detail/impl/service_registry.hpp view
@@ -2,7 +2,7 @@ // detail/impl/service_registry.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -38,18 +38,6 @@ return *static_cast<Service*>(do_use_service(key, factory, &owner)); } -template <typename Service, typename... Args>-Service& service_registry::make_service(Args&&... args)-{- auto_service_ptr new_service =- { create<Service, execution_context>(owner_,- &owner_, static_cast<Args&&>(args)...) };- add_service(static_cast<Service*>(new_service.ptr_));- Service& result = *static_cast<Service*>(new_service.ptr_);- new_service.ptr_ = 0;- return result;-}- template <typename Service> void service_registry::add_service(Service* new_service) {@@ -76,7 +64,8 @@ #if !defined(ASIO_NO_TYPEID) template <typename Service> void service_registry::init_key(execution_context::service::key& key,- enable_if_t<is_base_of<typename Service::key_type, Service>::value>*)+ typename enable_if<+ is_base_of<typename Service::key_type, Service>::value>::type*) { key.type_info_ = &typeid(typeid_wrapper<Service>); key.id_ = 0;@@ -91,22 +80,10 @@ } #endif // !defined(ASIO_NO_TYPEID) -template <typename Service, typename Owner, typename... Args>-execution_context::service* service_registry::create(- execution_context& context, void* owner, Args&&... args)-{- Service* svc = allocate_object<Service>(- execution_context::allocator<void>(context),- *static_cast<Owner*>(owner), static_cast<Args&&>(args)...);- svc->destroy_ = &service_registry::destroy_allocated<Service>;- return svc;-}--template <typename Service>-void service_registry::destroy_allocated(execution_context::service* service)+template <typename Service, typename Owner>+execution_context::service* service_registry::create(void* owner) {- deallocate_object(execution_context::allocator<void>(service->owner_),- static_cast<Service*>(service));+ return new Service(*static_cast<Owner*>(owner)); } } // namespace detail
link/modules/asio-standalone/asio/include/asio/detail/impl/service_registry.ipp view
@@ -2,7 +2,7 @@ // detail/impl/service_registry.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -50,7 +50,7 @@ while (first_service_) { execution_context::service* next_service = first_service_->next_;- first_service_->destroy_(first_service_);+ destroy(first_service_); first_service_ = next_service; } }@@ -104,17 +104,11 @@ return false; } -void service_registry::destroy_added(execution_context::service* service)+void service_registry::destroy(execution_context::service* service) { delete service; } -service_registry::auto_service_ptr::~auto_service_ptr()-{- if (ptr_)- ptr_->destroy_(ptr_);-}- execution_context::service* service_registry::do_use_service( const execution_context::service::key& key, factory_type factory, void* owner)@@ -134,7 +128,7 @@ // at this time to allow for nested calls into this function from the new // service's constructor. lock.unlock();- auto_service_ptr new_service = { factory(owner_, owner) };+ auto_service_ptr new_service = { factory(owner) }; new_service.ptr_->key_ = key; lock.lock(); @@ -174,8 +168,6 @@ } // Take ownership of the service object.- if (!new_service->destroy_)- new_service->destroy_ = &service_registry::destroy_added; new_service->key_ = key; new_service->next_ = first_service_; first_service_ = new_service;
link/modules/asio-standalone/asio/include/asio/detail/impl/signal_set_service.ipp view
@@ -2,7 +2,7 @@ // detail/impl/signal_set_service.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -386,7 +386,6 @@ if (state->flags_[signal_number] != signal_set_base::flags::dont_care) { ec = asio::error::invalid_argument;- delete new_registration; return ec; } struct sigaction sa;@@ -398,7 +397,6 @@ { ec = asio::error_code(errno, asio::error::get_system_category());- delete new_registration; return ec; } state->flags_[signal_number] = f;@@ -658,9 +656,10 @@ // scheduler used to create signal_set objects. if (state->service_list_ != 0) {- if (!config(service->context()).get("scheduler", "locking", true)- || !config(state->service_list_->context()).get(- "scheduler", "locking", true))+ if (!ASIO_CONCURRENCY_HINT_IS_LOCKING(SCHEDULER,+ service->scheduler_.concurrency_hint())+ || !ASIO_CONCURRENCY_HINT_IS_LOCKING(SCHEDULER,+ state->service_list_->scheduler_.concurrency_hint())) { std::logic_error ex( "Thread-unsafe execution context objects require "
link/modules/asio-standalone/asio/include/asio/detail/impl/socket_ops.ipp view
@@ -2,7 +2,7 @@ // detail/impl/socket_ops.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -41,10 +41,6 @@ #endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) // || defined(__MACH__) && defined(__APPLE__) -#if defined(_MSC_VER) && (_MSC_VER >= 1800)-# include <malloc.h>-#endif // defined(_MSC_VER) && (_MSC_VER >= 1800)- #include "asio/detail/push_options.hpp" namespace asio {@@ -343,24 +339,7 @@ ::fcntl(s, F_SETFL, flags & ~O_NONBLOCK); # else // defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__) ioctl_arg_type arg = 0;- if ((state & possible_dup) == 0)- {- result = ::ioctl(s, FIONBIO, &arg);- get_last_error(ec, result < 0);- }- if ((state & possible_dup) != 0-# if defined(ENOTTY)- || ec.value() == ENOTTY-# endif // defined(ENOTTY)-# if defined(ENOTCAPABLE)- || ec.value() == ENOTCAPABLE-# endif // defined(ENOTCAPABLE)- )- {- int flags = ::fcntl(s, F_GETFL, 0);- if (flags >= 0)- ::fcntl(s, F_SETFL, flags & ~O_NONBLOCK);- }+ ::ioctl(s, FIONBIO, &arg); # endif // defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__) #endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) state &= ~non_blocking;@@ -396,36 +375,14 @@ if (result >= 0) { int flag = (value ? (result | O_NONBLOCK) : (result & ~O_NONBLOCK));- result = (flag != result) ? ::fcntl(s, F_SETFL, flag) : 0;+ result = ::fcntl(s, F_SETFL, flag); get_last_error(ec, result < 0); }-#else // defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__)+#else ioctl_arg_type arg = (value ? 1 : 0);- int result = 0;- if ((state & possible_dup) == 0)- {- result = ::ioctl(s, FIONBIO, &arg);- get_last_error(ec, result < 0);- }- if ((state & possible_dup) != 0-# if defined(ENOTTY)- || ec.value() == ENOTTY-# endif // defined(ENOTTY)-# if defined(ENOTCAPABLE)- || ec.value() == ENOTCAPABLE-# endif // defined(ENOTCAPABLE)- )- {- result = ::fcntl(s, F_GETFL, 0);- get_last_error(ec, result < 0);- if (result >= 0)- {- int flag = (value ? (result | O_NONBLOCK) : (result & ~O_NONBLOCK));- result = (flag != result) ? ::fcntl(s, F_SETFL, flag) : 0;- get_last_error(ec, result < 0);- }- }-#endif // defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__)+ int result = ::ioctl(s, FIONBIO, &arg);+ get_last_error(ec, result < 0);+#endif if (result >= 0) {@@ -472,36 +429,14 @@ if (result >= 0) { int flag = (value ? (result | O_NONBLOCK) : (result & ~O_NONBLOCK));- result = (flag != result) ? ::fcntl(s, F_SETFL, flag) : 0;+ result = ::fcntl(s, F_SETFL, flag); get_last_error(ec, result < 0); }-#else // defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__)+#else ioctl_arg_type arg = (value ? 1 : 0);- int result = 0;- if ((state & possible_dup) == 0)- {- result = ::ioctl(s, FIONBIO, &arg);- get_last_error(ec, result < 0);- }- if ((state & possible_dup) != 0-# if defined(ENOTTY)- || ec.value() == ENOTTY-# endif // defined(ENOTTY)-# if defined(ENOTCAPABLE)- || ec.value() == ENOTCAPABLE-# endif // defined(ENOTCAPABLE)- )- {- result = ::fcntl(s, F_GETFL, 0);- get_last_error(ec, result < 0);- if (result >= 0)- {- int flag = (value ? (result | O_NONBLOCK) : (result & ~O_NONBLOCK));- result = (flag != result) ? ::fcntl(s, F_SETFL, flag) : 0;- get_last_error(ec, result < 0);- }- }-#endif // defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__)+ int result = ::ioctl(s, FIONBIO, &arg);+ get_last_error(ec, result < 0);+#endif if (result >= 0) {@@ -2586,11 +2521,9 @@ || if_indextoname(static_cast<unsigned>(scope_id), if_name + 1) == 0) #if defined(ASIO_HAS_SNPRINTF) snprintf(if_name + 1, sizeof(if_name) - 1, "%lu", scope_id);-#elif defined(ASIO_HAS_SECURE_RTL)- sprintf_s(if_name + 1, sizeof(if_name) -1, "%lu", scope_id);-#else // defined(ASIO_HAS_SECURE_RTL)+#else // defined(ASIO_HAS_SNPRINTF) sprintf(if_name + 1, "%lu", scope_id);-#endif // defined(ASIO_HAS_SECURE_RTL)+#endif // defined(ASIO_HAS_SNPRINTF) strcat(dest, if_name); } return result;
link/modules/asio-standalone/asio/include/asio/detail/impl/socket_select_interrupter.ipp view
@@ -2,7 +2,7 @@ // detail/impl/socket_select_interrupter.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -90,7 +90,7 @@ socket_holder server(socket_ops::accept(acceptor.get(), 0, 0, ec)); if (server.get() == invalid_socket) asio::detail::throw_error(ec, "socket_select_interrupter");-+ ioctl_arg_type non_blocking = 1; socket_ops::state_type client_state = 0; if (socket_ops::ioctl(client.get(), client_state,
link/modules/asio-standalone/asio/include/asio/detail/impl/strand_executor_service.hpp view
@@ -2,7 +2,7 @@ // detail/impl/strand_executor_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -16,6 +16,7 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/fenced_block.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/recycling_allocator.hpp" #include "asio/executor_work_guard.hpp" #include "asio/defer.hpp"@@ -33,8 +34,8 @@ public: typedef Allocator allocator_type; - allocator_binder(F&& f, const Allocator& a)- : f_(static_cast<F&&>(f)),+ allocator_binder(ASIO_MOVE_ARG(F) f, const Allocator& a)+ : f_(ASIO_MOVE_CAST(F)(f)), allocator_(a) { }@@ -45,13 +46,15 @@ { } +#if defined(ASIO_HAS_MOVE) allocator_binder(allocator_binder&& other)- : f_(static_cast<F&&>(other.f_)),- allocator_(static_cast<allocator_type&&>(other.allocator_))+ : f_(ASIO_MOVE_CAST(F)(other.f_)),+ allocator_(ASIO_MOVE_CAST(allocator_type)(other.allocator_)) { }+#endif // defined(ASIO_HAS_MOVE) - allocator_type get_allocator() const noexcept+ allocator_type get_allocator() const ASIO_NOEXCEPT { return allocator_; }@@ -68,9 +71,9 @@ template <typename Executor> class strand_executor_service::invoker<Executor,- enable_if_t<+ typename enable_if< execution::is_executor<Executor>::value- >>+ >::type> { public: invoker(const implementation_type& impl, Executor& ex)@@ -85,11 +88,13 @@ { } +#if defined(ASIO_HAS_MOVE) invoker(invoker&& other)- : impl_(static_cast<implementation_type&&>(other.impl_)),- executor_(static_cast<executor_type&&>(other.executor_))+ : impl_(ASIO_MOVE_CAST(implementation_type)(other.impl_)),+ executor_(ASIO_MOVE_CAST(executor_type)(other.executor_)) { }+#endif // defined(ASIO_HAS_MOVE) struct on_invoker_exit {@@ -101,12 +106,22 @@ { recycling_allocator<void> allocator; executor_type ex = this_->executor_;+#if defined(ASIO_NO_DEPRECATED) asio::prefer( asio::require(- static_cast<executor_type&&>(ex),+ ASIO_MOVE_CAST(executor_type)(ex), execution::blocking.never), execution::allocator(allocator)- ).execute(static_cast<invoker&&>(*this_));+ ).execute(ASIO_MOVE_CAST(invoker)(*this_));+#else // defined(ASIO_NO_DEPRECATED)+ execution::execute(+ asio::prefer(+ asio::require(+ ASIO_MOVE_CAST(executor_type)(ex),+ execution::blocking.never),+ execution::allocator(allocator)),+ ASIO_MOVE_CAST(invoker)(*this_));+#endif // defined(ASIO_NO_DEPRECATED) } } };@@ -121,12 +136,12 @@ } private:- typedef decay_t<- prefer_result_t<+ typedef typename decay<+ typename prefer_result< Executor, execution::outstanding_work_t::tracked_t- >- > executor_type;+ >::type+ >::type executor_type; implementation_type impl_; executor_type executor_;@@ -136,9 +151,9 @@ template <typename Executor> class strand_executor_service::invoker<Executor,- enable_if_t<+ typename enable_if< !execution::is_executor<Executor>::value- >>+ >::type> { public: invoker(const implementation_type& impl, Executor& ex)@@ -153,11 +168,13 @@ { } +#if defined(ASIO_HAS_MOVE) invoker(invoker&& other)- : impl_(static_cast<implementation_type&&>(other.impl_)),- work_(static_cast<executor_work_guard<Executor>&&>(other.work_))+ : impl_(ASIO_MOVE_CAST(implementation_type)(other.impl_)),+ work_(ASIO_MOVE_CAST(executor_work_guard<Executor>)(other.work_)) { }+#endif // defined(ASIO_HAS_MOVE) struct on_invoker_exit {@@ -169,7 +186,7 @@ { Executor ex(this_->work_.get_executor()); recycling_allocator<void> allocator;- ex.post(static_cast<invoker&&>(*this_), allocator);+ ex.post(ASIO_MOVE_CAST(invoker)(*this_), allocator); } } };@@ -192,33 +209,33 @@ template <typename Executor, typename Function> inline void strand_executor_service::execute(const implementation_type& impl,- Executor& ex, Function&& function,- enable_if_t<- can_query<Executor, execution::allocator_t<void>>::value- >*)+ Executor& ex, ASIO_MOVE_ARG(Function) function,+ typename enable_if<+ can_query<Executor, execution::allocator_t<void> >::value+ >::type*) { return strand_executor_service::do_execute(impl, ex,- static_cast<Function&&>(function),+ ASIO_MOVE_CAST(Function)(function), asio::query(ex, execution::allocator)); } template <typename Executor, typename Function> inline void strand_executor_service::execute(const implementation_type& impl,- Executor& ex, Function&& function,- enable_if_t<- !can_query<Executor, execution::allocator_t<void>>::value- >*)+ Executor& ex, ASIO_MOVE_ARG(Function) function,+ typename enable_if<+ !can_query<Executor, execution::allocator_t<void> >::value+ >::type*) { return strand_executor_service::do_execute(impl, ex,- static_cast<Function&&>(function),+ ASIO_MOVE_CAST(Function)(function), std::allocator<void>()); } template <typename Executor, typename Function, typename Allocator> void strand_executor_service::do_execute(const implementation_type& impl,- Executor& ex, Function&& function, const Allocator& a)+ Executor& ex, ASIO_MOVE_ARG(Function) function, const Allocator& a) {- typedef decay_t<Function> function_type;+ typedef typename decay<Function>::type function_type; // If the executor is not never-blocking, and we are already in the strand, // then the function can run immediately.@@ -226,17 +243,17 @@ && running_in_this_thread(impl)) { // Make a local, non-const copy of the function.- function_type tmp(static_cast<Function&&>(function));+ function_type tmp(ASIO_MOVE_CAST(Function)(function)); fenced_block b(fenced_block::full);- static_cast<function_type&&>(tmp)();+ asio_handler_invoke_helpers::invoke(tmp, tmp); return; } // Allocate and construct an operation to wrap the function. typedef executor_op<function_type, Allocator> op; typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 };- p.p = new (p.v) op(static_cast<Function&&>(function), a);+ p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(function), a); ASIO_HANDLER_CREATION((impl->service_->context(), *p.p, "strand_executor", impl.get(), 0, "execute"));@@ -246,31 +263,35 @@ p.v = p.p = 0; if (first) {+#if defined(ASIO_NO_DEPRECATED) ex.execute(invoker<Executor>(impl, ex));+#else // defined(ASIO_NO_DEPRECATED)+ execution::execute(ex, invoker<Executor>(impl, ex));+#endif // defined(ASIO_NO_DEPRECATED) } } template <typename Executor, typename Function, typename Allocator> void strand_executor_service::dispatch(const implementation_type& impl,- Executor& ex, Function&& function, const Allocator& a)+ Executor& ex, ASIO_MOVE_ARG(Function) function, const Allocator& a) {- typedef decay_t<Function> function_type;+ typedef typename decay<Function>::type function_type; // If we are already in the strand then the function can run immediately. if (running_in_this_thread(impl)) { // Make a local, non-const copy of the function.- function_type tmp(static_cast<Function&&>(function));+ function_type tmp(ASIO_MOVE_CAST(Function)(function)); fenced_block b(fenced_block::full);- static_cast<function_type&&>(tmp)();+ asio_handler_invoke_helpers::invoke(tmp, tmp); return; } // Allocate and construct an operation to wrap the function. typedef executor_op<function_type, Allocator> op; typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 };- p.p = new (p.v) op(static_cast<Function&&>(function), a);+ p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(function), a); ASIO_HANDLER_CREATION((impl->service_->context(), *p.p, "strand_executor", impl.get(), 0, "dispatch"));@@ -289,14 +310,14 @@ // Request invocation of the given function and return immediately. template <typename Executor, typename Function, typename Allocator> void strand_executor_service::post(const implementation_type& impl,- Executor& ex, Function&& function, const Allocator& a)+ Executor& ex, ASIO_MOVE_ARG(Function) function, const Allocator& a) {- typedef decay_t<Function> function_type;+ typedef typename decay<Function>::type function_type; // Allocate and construct an operation to wrap the function. typedef executor_op<function_type, Allocator> op; typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 };- p.p = new (p.v) op(static_cast<Function&&>(function), a);+ p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(function), a); ASIO_HANDLER_CREATION((impl->service_->context(), *p.p, "strand_executor", impl.get(), 0, "post"));@@ -315,14 +336,14 @@ // Request invocation of the given function and return immediately. template <typename Executor, typename Function, typename Allocator> void strand_executor_service::defer(const implementation_type& impl,- Executor& ex, Function&& function, const Allocator& a)+ Executor& ex, ASIO_MOVE_ARG(Function) function, const Allocator& a) {- typedef decay_t<Function> function_type;+ typedef typename decay<Function>::type function_type; // Allocate and construct an operation to wrap the function. typedef executor_op<function_type, Allocator> op; typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 };- p.p = new (p.v) op(static_cast<Function&&>(function), a);+ p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(function), a); ASIO_HANDLER_CREATION((impl->service_->context(), *p.p, "strand_executor", impl.get(), 0, "defer"));
link/modules/asio-standalone/asio/include/asio/detail/impl/strand_executor_service.ipp view
@@ -2,7 +2,7 @@ // detail/impl/strand_executor_service.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -52,8 +52,7 @@ strand_executor_service::implementation_type strand_executor_service::create_implementation() {- execution_context::allocator<void> alloc(context());- implementation_type new_impl = allocate_shared<strand_impl>(alloc);+ implementation_type new_impl(new strand_impl); new_impl->locked_ = false; new_impl->shutdown_ = false; @@ -65,8 +64,8 @@ mutex_index += (reinterpret_cast<std::size_t>(new_impl.get()) >> 3); mutex_index ^= salt + 0x9e3779b9 + (mutex_index << 6) + (mutex_index >> 2); mutex_index = mutex_index % num_mutexes;- if (!mutexes_[mutex_index])- mutexes_[mutex_index] = allocate_shared<mutex>(alloc);+ if (!mutexes_[mutex_index].get())+ mutexes_[mutex_index].reset(new mutex); new_impl->mutex_ = mutexes_[mutex_index].get(); // Insert implementation into linked list of all implementations.
link/modules/asio-standalone/asio/include/asio/detail/impl/strand_service.hpp view
@@ -2,7 +2,7 @@ // detail/impl/strand_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -18,6 +18,7 @@ #include "asio/detail/completion_handler.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/push_options.hpp"@@ -39,7 +40,7 @@ if (running_in_this_thread(impl)) { fenced_block b(fenced_block::full);- static_cast<Handler&&>(handler)();+ asio_handler_invoke_helpers::invoke(handler, handler); return; }
link/modules/asio-standalone/asio/include/asio/detail/impl/strand_service.ipp view
@@ -2,7 +2,7 @@ // detail/impl/strand_service.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -80,11 +80,8 @@ #endif // defined(ASIO_ENABLE_SEQUENTIAL_STRAND_ALLOCATION) index = index % num_implementations; - if (!implementations_[index])- {- execution_context::allocator<void> alloc(context());- implementations_[index] = allocate_shared<strand_impl>(alloc);- }+ if (!implementations_[index].get())+ implementations_[index].reset(new strand_impl); impl = implementations_[index].get(); }
link/modules/asio-standalone/asio/include/asio/detail/impl/thread_context.ipp view
@@ -2,7 +2,7 @@ // detail/impl/thread_context.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/impl/throw_error.ipp view
@@ -2,7 +2,7 @@ // detail/impl/throw_error.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -37,8 +37,29 @@ const char* location ASIO_SOURCE_LOCATION_PARAM) {+ // boostify: non-boost code starts here+#if defined(ASIO_MSVC) \+ && defined(ASIO_HAS_STD_SYSTEM_ERROR) \+ && (_MSC_VER < 1800)+ // Microsoft's implementation of std::system_error is non-conformant in that+ // it ignores the error code's message when a "what" string is supplied. We'll+ // work around this by explicitly formatting the "what" string.+ std::string what_msg = location;+ what_msg += ": ";+ what_msg += err.message();+ asio::system_error e(err, what_msg);+ asio::detail::throw_exception(e ASIO_SOURCE_LOCATION_ARG);+#else // defined(ASIO_MSVC)+ // && defined(ASIO_HAS_STD_SYSTEM_ERROR)+ // && (_MSC_VER < 1928)+ // boostify: non-boost code ends here asio::system_error e(err, location); asio::detail::throw_exception(e ASIO_SOURCE_LOCATION_ARG);+ // boostify: non-boost code starts here+#endif // defined(ASIO_MSVC)+ // && defined(ASIO_HAS_STD_SYSTEM_ERROR)+ // && (_MSC_VER < 1800)+ // boostify: non-boost code ends here } } // namespace detail
+ link/modules/asio-standalone/asio/include/asio/detail/impl/timer_queue_ptime.ipp view
@@ -0,0 +1,97 @@+//+// detail/impl/timer_queue_ptime.ipp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_DETAIL_IMPL_TIMER_QUEUE_PTIME_IPP+#define ASIO_DETAIL_IMPL_TIMER_QUEUE_PTIME_IPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"++#if defined(ASIO_HAS_BOOST_DATE_TIME)++#include "asio/detail/timer_queue_ptime.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {+namespace detail {++timer_queue<time_traits<boost::posix_time::ptime> >::timer_queue()+{+}++timer_queue<time_traits<boost::posix_time::ptime> >::~timer_queue()+{+}++bool timer_queue<time_traits<boost::posix_time::ptime> >::enqueue_timer(+ const time_type& time, per_timer_data& timer, wait_op* op)+{+ return impl_.enqueue_timer(time, timer, op);+}++bool timer_queue<time_traits<boost::posix_time::ptime> >::empty() const+{+ return impl_.empty();+}++long timer_queue<time_traits<boost::posix_time::ptime> >::wait_duration_msec(+ long max_duration) const+{+ return impl_.wait_duration_msec(max_duration);+}++long timer_queue<time_traits<boost::posix_time::ptime> >::wait_duration_usec(+ long max_duration) const+{+ return impl_.wait_duration_usec(max_duration);+}++void timer_queue<time_traits<boost::posix_time::ptime> >::get_ready_timers(+ op_queue<operation>& ops)+{+ impl_.get_ready_timers(ops);+}++void timer_queue<time_traits<boost::posix_time::ptime> >::get_all_timers(+ op_queue<operation>& ops)+{+ impl_.get_all_timers(ops);+}++std::size_t timer_queue<time_traits<boost::posix_time::ptime> >::cancel_timer(+ per_timer_data& timer, op_queue<operation>& ops, std::size_t max_cancelled)+{+ return impl_.cancel_timer(timer, ops, max_cancelled);+}++void timer_queue<time_traits<boost::posix_time::ptime> >::cancel_timer_by_key(+ per_timer_data* timer, op_queue<operation>& ops, void* cancellation_key)+{+ impl_.cancel_timer_by_key(timer, ops, cancellation_key);+}++void timer_queue<time_traits<boost::posix_time::ptime> >::move_timer(+ per_timer_data& target, per_timer_data& source)+{+ impl_.move_timer(target, source);+}++} // namespace detail+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // defined(ASIO_HAS_BOOST_DATE_TIME)++#endif // ASIO_DETAIL_IMPL_TIMER_QUEUE_PTIME_IPP
link/modules/asio-standalone/asio/include/asio/detail/impl/timer_queue_set.ipp view
@@ -2,7 +2,7 @@ // detail/impl/timer_queue_set.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/impl/win_event.ipp view
@@ -2,7 +2,7 @@ // detail/win_event.ipp // ~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/impl/win_iocp_file_service.ipp view
@@ -2,7 +2,7 @@ // detail/impl/win_iocp_file_service.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -94,48 +94,25 @@ if ((open_flags & file_base::sync_all_on_write) != 0) flags |= FILE_FLAG_WRITE_THROUGH; - impl.offset_ = 0; HANDLE handle = ::CreateFileA(path, access, share, 0, disposition, flags, 0); if (handle != INVALID_HANDLE_VALUE) {- if (disposition == OPEN_ALWAYS)- {- if ((open_flags & file_base::truncate) != 0)- {- if (!::SetEndOfFile(handle))- {- DWORD last_error = ::GetLastError();- ::CloseHandle(handle);- ec.assign(last_error, asio::error::get_system_category());- ASIO_ERROR_LOCATION(ec);- return ec;- }- }- }- if (disposition == OPEN_ALWAYS || disposition == OPEN_EXISTING)+ if (disposition == OPEN_ALWAYS && (open_flags & file_base::truncate) != 0) {- if ((open_flags & file_base::append) != 0)+ if (!::SetEndOfFile(handle)) {- LARGE_INTEGER distance, new_offset;- distance.QuadPart = 0;- if (::SetFilePointerEx(handle, distance, &new_offset, FILE_END))- {- impl.offset_ = static_cast<uint64_t>(new_offset.QuadPart);- }- else- {- DWORD last_error = ::GetLastError();- ::CloseHandle(handle);- ec.assign(last_error, asio::error::get_system_category());- ASIO_ERROR_LOCATION(ec);- return ec;- }+ DWORD last_error = ::GetLastError();+ ::CloseHandle(handle);+ ec.assign(last_error, asio::error::get_system_category());+ ASIO_ERROR_LOCATION(ec);+ return ec; } } handle_service_.assign(impl, handle, ec); if (ec) ::CloseHandle(handle);+ impl.offset_ = 0; ASIO_ERROR_LOCATION(ec); return ec; }
link/modules/asio-standalone/asio/include/asio/detail/impl/win_iocp_handle_service.ipp view
@@ -2,7 +2,7 @@ // detail/impl/win_iocp_handle_service.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying@@ -163,7 +163,7 @@ win_iocp_handle_service::implementation_type& impl) { close_for_destruction(impl);-+ // Remove implementation from linked list of all implementations. asio::detail::mutex::scoped_lock lock(mutex_); if (impl_list_ == &impl)@@ -365,12 +365,12 @@ return 0; } - // Write the data.+ // Write the data. overlapped.Offset = offset & 0xFFFFFFFF; overlapped.OffsetHigh = (offset >> 32) & 0xFFFFFFFF; BOOL ok = ::WriteFile(impl.handle_, buffer.data(), static_cast<DWORD>(buffer.size()), 0, &overlapped);- if (!ok)+ if (!ok) { DWORD last_error = ::GetLastError(); if (last_error != ERROR_IO_PENDING)@@ -446,7 +446,7 @@ ASIO_ERROR_LOCATION(ec); return 0; }-+ // A request to read 0 bytes on a stream handle is a no-op. if (buffer.size() == 0) {@@ -466,7 +466,7 @@ overlapped.OffsetHigh = (offset >> 32) & 0xFFFFFFFF; BOOL ok = ::ReadFile(impl.handle_, buffer.data(), static_cast<DWORD>(buffer.size()), 0, &overlapped);- if (!ok)+ if (!ok) { DWORD last_error = ::GetLastError(); if (last_error != ERROR_IO_PENDING && last_error != ERROR_MORE_DATA)
link/modules/asio-standalone/asio/include/asio/detail/impl/win_iocp_io_context.hpp view
@@ -2,7 +2,7 @@ // detail/impl/win_iocp_io_context.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -22,6 +22,7 @@ #include "asio/detail/completion_handler.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/push_options.hpp"@@ -29,26 +30,24 @@ namespace asio { namespace detail { -template <typename TimeTraits, typename Allocator>+template <typename Time_Traits> void win_iocp_io_context::add_timer_queue(- timer_queue<TimeTraits, Allocator>& queue)+ timer_queue<Time_Traits>& queue) { do_add_timer_queue(queue); } -template <typename TimeTraits, typename Allocator>+template <typename Time_Traits> void win_iocp_io_context::remove_timer_queue(- timer_queue<TimeTraits, Allocator>& queue)+ timer_queue<Time_Traits>& queue) { do_remove_timer_queue(queue); } -template <typename TimeTraits, typename Allocator>-void win_iocp_io_context::schedule_timer(- timer_queue<TimeTraits, Allocator>& queue,- const typename TimeTraits::time_type& time,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,- wait_op* op)+template <typename Time_Traits>+void win_iocp_io_context::schedule_timer(timer_queue<Time_Traits>& queue,+ const typename Time_Traits::time_type& time,+ typename timer_queue<Time_Traits>::per_timer_data& timer, wait_op* op) { // If the service has been shut down we silently discard the timer. if (::InterlockedExchangeAdd(&shutdown_, 0) != 0)@@ -65,10 +64,9 @@ update_timeout(); } -template <typename TimeTraits, typename Allocator>-std::size_t win_iocp_io_context::cancel_timer(- timer_queue<TimeTraits, Allocator>& queue,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,+template <typename Time_Traits>+std::size_t win_iocp_io_context::cancel_timer(timer_queue<Time_Traits>& queue,+ typename timer_queue<Time_Traits>::per_timer_data& timer, std::size_t max_cancelled) { // If the service has been shut down we silently ignore the cancellation.@@ -83,10 +81,9 @@ return n; } -template <typename TimeTraits, typename Allocator>-void win_iocp_io_context::cancel_timer_by_key(- timer_queue<TimeTraits, Allocator>& queue,- typename timer_queue<TimeTraits, Allocator>::per_timer_data* timer,+template <typename Time_Traits>+void win_iocp_io_context::cancel_timer_by_key(timer_queue<Time_Traits>& queue,+ typename timer_queue<Time_Traits>::per_timer_data* timer, void* cancellation_key) { // If the service has been shut down we silently ignore the cancellation.@@ -100,10 +97,10 @@ post_deferred_completions(ops); } -template <typename TimeTraits, typename Allocator>-void win_iocp_io_context::move_timer(timer_queue<TimeTraits, Allocator>& queue,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& to,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& from)+template <typename Time_Traits>+void win_iocp_io_context::move_timer(timer_queue<Time_Traits>& queue,+ typename timer_queue<Time_Traits>::per_timer_data& to,+ typename timer_queue<Time_Traits>::per_timer_data& from) { asio::detail::mutex::scoped_lock lock(dispatch_mutex_); op_queue<operation> ops;
link/modules/asio-standalone/asio/include/asio/detail/impl/win_iocp_io_context.ipp view
@@ -2,7 +2,7 @@ // detail/impl/win_iocp_io_context.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -19,10 +19,10 @@ #if defined(ASIO_HAS_IOCP) -#include "asio/config.hpp" #include "asio/error.hpp" #include "asio/detail/cstdint.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/limits.hpp" #include "asio/detail/thread.hpp" #include "asio/detail/throw_error.hpp"@@ -51,7 +51,7 @@ struct win_iocp_io_context::work_finished_on_block_exit {- ~work_finished_on_block_exit() noexcept(false)+ ~work_finished_on_block_exit() ASIO_NOEXCEPT_IF(false) { io_context_->work_finished(); }@@ -79,7 +79,7 @@ }; win_iocp_io_context::win_iocp_io_context(- asio::execution_context& ctx, bool own_thread)+ asio::execution_context& ctx, int concurrency_hint, bool own_thread) : execution_context_service_base<win_iocp_io_context>(ctx), iocp_(), outstanding_work_(0),@@ -88,13 +88,12 @@ shutdown_(0), gqcs_timeout_(get_gqcs_timeout()), dispatch_required_(0),- concurrency_hint_(config(ctx).get("scheduler", "concurrency_hint", -1))+ concurrency_hint_(concurrency_hint) { ASIO_HANDLER_TRACKING_INIT; iocp_.handle = ::CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0,- static_cast<DWORD>(concurrency_hint_ >= 0- ? concurrency_hint_ : DWORD(~0)));+ static_cast<DWORD>(concurrency_hint >= 0 ? concurrency_hint : DWORD(~0))); if (!iocp_.handle) { DWORD last_error = ::GetLastError();@@ -106,42 +105,17 @@ if (own_thread) { ::InterlockedIncrement(&outstanding_work_);- thread_ = thread(thread_function(this));- }-}--win_iocp_io_context::win_iocp_io_context(- win_iocp_io_context::internal, asio::execution_context& ctx)- : execution_context_service_base<win_iocp_io_context>(ctx),- iocp_(),- outstanding_work_(0),- stopped_(0),- stop_event_posted_(0),- shutdown_(0),- gqcs_timeout_(get_gqcs_timeout()),- dispatch_required_(0),- concurrency_hint_(-1)-{- ASIO_HANDLER_TRACKING_INIT;-- iocp_.handle = ::CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0,- static_cast<DWORD>(concurrency_hint_ >= 0- ? concurrency_hint_ : DWORD(~0)));- if (!iocp_.handle)- {- DWORD last_error = ::GetLastError();- asio::error_code ec(last_error,- asio::error::get_system_category());- asio::detail::throw_error(ec, "iocp");+ thread_.reset(new asio::detail::thread(thread_function(this))); } } win_iocp_io_context::~win_iocp_io_context() {- if (thread_.joinable())+ if (thread_.get()) { stop();- thread_.join();+ thread_->join();+ thread_.reset(); } } @@ -149,17 +123,18 @@ { ::InterlockedExchange(&shutdown_, 1); - if (timer_thread_.joinable())+ if (timer_thread_.get()) { LARGE_INTEGER timeout; timeout.QuadPart = 1; ::SetWaitableTimer(waitable_timer_.handle, &timeout, 1, 0, 0, FALSE); } - if (thread_.joinable())+ if (thread_.get()) { stop();- thread_.join();+ thread_->join();+ thread_.reset(); ::InterlockedDecrement(&outstanding_work_); } @@ -192,7 +167,11 @@ } } - timer_thread_.join();+ if (timer_thread_.get())+ {+ timer_thread_->join();+ timer_thread_.reset();+ } } asio::error_code win_iocp_io_context::register_handle(@@ -593,10 +572,10 @@ &timeout, max_timeout_msec, 0, 0, FALSE); } - if (!timer_thread_.joinable())+ if (!timer_thread_.get()) { timer_thread_function thread_function = { this };- timer_thread_ = thread(thread_function, 65536);+ timer_thread_.reset(new thread(thread_function, 65536)); } } @@ -609,7 +588,7 @@ void win_iocp_io_context::update_timeout() {- if (timer_thread_.joinable())+ if (timer_thread_.get()) { // There's no point updating the waitable timer if the new timeout period // exceeds the maximum timeout. In that case, we might as well wait for the
link/modules/asio-standalone/asio/include/asio/detail/impl/win_iocp_serial_port_service.ipp view
@@ -2,7 +2,7 @@ // detail/impl/win_iocp_serial_port_service.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying
link/modules/asio-standalone/asio/include/asio/detail/impl/win_iocp_socket_service_base.ipp view
@@ -2,7 +2,7 @@ // detail/impl/win_iocp_socket_service_base.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -72,7 +72,7 @@ void win_iocp_socket_service_base::base_move_construct( win_iocp_socket_service_base::base_implementation_type& impl, win_iocp_socket_service_base::base_implementation_type& other_impl)- noexcept+ ASIO_NOEXCEPT { impl.socket_ = other_impl.socket_; other_impl.socket_ = invalid_socket;
link/modules/asio-standalone/asio/include/asio/detail/impl/win_mutex.ipp view
@@ -2,7 +2,7 @@ // detail/impl/win_mutex.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/impl/win_object_handle_service.ipp view
@@ -2,7 +2,7 @@ // detail/impl/win_object_handle_service.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2011 Boris Schaeling (boris@highscore.de) // // Distributed under the Boost Software License, Version 1.0. (See accompanying
link/modules/asio-standalone/asio/include/asio/detail/impl/win_static_mutex.ipp view
@@ -2,7 +2,7 @@ // detail/impl/win_static_mutex.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/impl/win_thread.ipp view
@@ -2,7 +2,7 @@ // detail/impl/win_thread.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -33,30 +33,26 @@ win_thread::~win_thread() {- if (arg_)- std::terminate();+ ::CloseHandle(thread_);++ // The exit_event_ handle is deliberately allowed to leak here since it+ // is an error for the owner of an internal thread not to join() it. } void win_thread::join() {- if (arg_)+ HANDLE handles[2] = { exit_event_, thread_ };+ ::WaitForMultipleObjects(2, handles, FALSE, INFINITE);+ ::CloseHandle(exit_event_);+ if (terminate_threads()) {- HANDLE handles[2] = { arg_->exit_event_, arg_->thread_ };- ::WaitForMultipleObjects(2, handles, FALSE, INFINITE);- ::CloseHandle(arg_->exit_event_);- if (terminate_threads())- {- ::TerminateThread(arg_->thread_, 0);- }- else- {- ::QueueUserAPC(apc_function, arg_->thread_, 0);- ::WaitForSingleObject(arg_->thread_, INFINITE);- }- ::CloseHandle(arg_->thread_);- arg_->destroy();- arg_ = 0;+ ::TerminateThread(thread_, 0); }+ else+ {+ ::QueueUserAPC(apc_function, thread_, 0);+ ::WaitForSingleObject(thread_, INFINITE);+ } } std::size_t win_thread::hardware_concurrency()@@ -66,68 +62,71 @@ return system_info.dwNumberOfProcessors; } -win_thread::func_base* win_thread::start_thread(- func_base* arg, unsigned int stack_size)+void win_thread::start_thread(func_base* arg, unsigned int stack_size) {- arg->entry_event_ = ::CreateEventW(0, true, false, 0);- if (!arg->entry_event_)+ ::HANDLE entry_event = 0;+ arg->entry_event_ = entry_event = ::CreateEventW(0, true, false, 0);+ if (!entry_event) { DWORD last_error = ::GetLastError();- arg->destroy();+ delete arg; asio::error_code ec(last_error, asio::error::get_system_category()); asio::detail::throw_error(ec, "thread.entry_event"); } - arg->exit_event_ = ::CreateEventW(0, true, false, 0);- if (!arg->exit_event_)+ arg->exit_event_ = exit_event_ = ::CreateEventW(0, true, false, 0);+ if (!exit_event_) { DWORD last_error = ::GetLastError();- ::CloseHandle(arg->entry_event_);- arg->destroy();+ delete arg; asio::error_code ec(last_error, asio::error::get_system_category()); asio::detail::throw_error(ec, "thread.exit_event"); } unsigned int thread_id = 0;- arg->thread_ = reinterpret_cast<HANDLE>(::_beginthreadex(0,+ thread_ = reinterpret_cast<HANDLE>(::_beginthreadex(0, stack_size, win_thread_function, arg, 0, &thread_id));- if (!arg->thread_)+ if (!thread_) { DWORD last_error = ::GetLastError();- ::CloseHandle(arg->entry_event_);- ::CloseHandle(arg->exit_event_);- arg->destroy();+ delete arg;+ if (entry_event)+ ::CloseHandle(entry_event);+ if (exit_event_)+ ::CloseHandle(exit_event_); asio::error_code ec(last_error, asio::error::get_system_category()); asio::detail::throw_error(ec, "thread"); } - if (arg->entry_event_)+ if (entry_event) {- ::WaitForSingleObject(arg->entry_event_, INFINITE);- ::CloseHandle(arg->entry_event_);- arg->entry_event_ = 0;+ ::WaitForSingleObject(entry_event, INFINITE);+ ::CloseHandle(entry_event); }-- return arg; } unsigned int __stdcall win_thread_function(void* arg) {- win_thread::func_base* func = static_cast<win_thread::func_base*>(arg);- ::SetEvent(func->entry_event_);+ win_thread::auto_func_base_ptr func = {+ static_cast<win_thread::func_base*>(arg) }; - func->run();+ ::SetEvent(func.ptr->entry_event_); + func.ptr->run();+ // Signal that the thread has finished its work, but rather than returning go // to sleep to put the thread into a well known state. If the thread is being // joined during global object destruction then it may be killed using // TerminateThread (to avoid a deadlock in DllMain). Otherwise, the SleepEx // call will be interrupted using QueueUserAPC and the thread will shut down // cleanly.- ::SetEvent(func->exit_event_);+ HANDLE exit_event = func.ptr->exit_event_;+ delete func.ptr;+ func.ptr = 0;+ ::SetEvent(exit_event); ::SleepEx(INFINITE, TRUE); return 0;
link/modules/asio-standalone/asio/include/asio/detail/impl/win_tss_ptr.ipp view
@@ -2,7 +2,7 @@ // detail/impl/win_tss_ptr.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/impl/winrt_ssocket_service_base.ipp view
@@ -2,7 +2,7 @@ // detail/impl/winrt_ssocket_service_base.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -66,7 +66,7 @@ void winrt_ssocket_service_base::base_move_construct( winrt_ssocket_service_base::base_implementation_type& impl, winrt_ssocket_service_base::base_implementation_type& other_impl)- noexcept+ ASIO_NOEXCEPT { impl.socket_ = other_impl.socket_; other_impl.socket_ = nullptr;
link/modules/asio-standalone/asio/include/asio/detail/impl/winrt_timer_scheduler.hpp view
@@ -2,7 +2,7 @@ // detail/impl/winrt_timer_scheduler.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -24,27 +24,23 @@ namespace asio { namespace detail { -template <typename TimeTraits, typename Allocator>-void winrt_timer_scheduler::add_timer_queue(- timer_queue<TimeTraits, Allocator>& queue)+template <typename Time_Traits>+void winrt_timer_scheduler::add_timer_queue(timer_queue<Time_Traits>& queue) { do_add_timer_queue(queue); } // Remove a timer queue from the reactor.-template <typename TimeTraits, typename Allocator>-void winrt_timer_scheduler::remove_timer_queue(- timer_queue<TimeTraits, Allocator>& queue)+template <typename Time_Traits>+void winrt_timer_scheduler::remove_timer_queue(timer_queue<Time_Traits>& queue) { do_remove_timer_queue(queue); } -template <typename TimeTraits, typename Allocator>-void winrt_timer_scheduler::schedule_timer(- timer_queue<TimeTraits, Allocator>& queue,- const typename TimeTraits::time_type& time,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,- wait_op* op)+template <typename Time_Traits>+void winrt_timer_scheduler::schedule_timer(timer_queue<Time_Traits>& queue,+ const typename Time_Traits::time_type& time,+ typename timer_queue<Time_Traits>::per_timer_data& timer, wait_op* op) { asio::detail::mutex::scoped_lock lock(mutex_); @@ -60,10 +56,9 @@ event_.signal(lock); } -template <typename TimeTraits, typename Allocator>-std::size_t winrt_timer_scheduler::cancel_timer(- timer_queue<TimeTraits, Allocator>& queue,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,+template <typename Time_Traits>+std::size_t winrt_timer_scheduler::cancel_timer(timer_queue<Time_Traits>& queue,+ typename timer_queue<Time_Traits>::per_timer_data& timer, std::size_t max_cancelled) { asio::detail::mutex::scoped_lock lock(mutex_);@@ -74,11 +69,10 @@ return n; } -template <typename TimeTraits, typename Allocator>-void winrt_timer_scheduler::move_timer(- timer_queue<TimeTraits, Allocator>& queue,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& to,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& from)+template <typename Time_Traits>+void winrt_timer_scheduler::move_timer(timer_queue<Time_Traits>& queue,+ typename timer_queue<Time_Traits>::per_timer_data& to,+ typename timer_queue<Time_Traits>::per_timer_data& from) { asio::detail::mutex::scoped_lock lock(mutex_); op_queue<operation> ops;
link/modules/asio-standalone/asio/include/asio/detail/impl/winrt_timer_scheduler.ipp view
@@ -2,7 +2,7 @@ // detail/impl/winrt_timer_scheduler.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -33,11 +33,12 @@ mutex_(), event_(), timer_queues_(),- thread_(),+ thread_(0), stop_thread_(false), shutdown_(false) {- thread_ = thread(bind_handler(&winrt_timer_scheduler::call_run_thread, this));+ thread_ = new asio::detail::thread(+ bind_handler(&winrt_timer_scheduler::call_run_thread, this)); } winrt_timer_scheduler::~winrt_timer_scheduler()@@ -52,7 +53,13 @@ stop_thread_ = true; event_.signal(lock); lock.unlock();- thread_.join();++ if (thread_)+ {+ thread_->join();+ delete thread_;+ thread_ = 0;+ } op_queue<operation> ops; timer_queues_.get_all_timers(ops);
link/modules/asio-standalone/asio/include/asio/detail/impl/winsock_init.ipp view
@@ -2,7 +2,7 @@ // detail/impl/winsock_init.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/initiate_defer.hpp view
@@ -2,7 +2,7 @@ // detail/initiate_defer.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -34,44 +34,62 @@ { public: template <typename CompletionHandler>- void operator()(CompletionHandler&& handler,- enable_if_t<+ void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,+ typename enable_if< execution::is_executor<- associated_executor_t<decay_t<CompletionHandler>>+ typename associated_executor<+ typename decay<CompletionHandler>::type+ >::type >::value- >* = 0) const+ >::type* = 0) const {- associated_executor_t<decay_t<CompletionHandler>> ex(+ typedef typename decay<CompletionHandler>::type handler_t;++ typename associated_executor<handler_t>::type ex( (get_associated_executor)(handler)); - associated_allocator_t<decay_t<CompletionHandler>> alloc(+ typename associated_allocator<handler_t>::type alloc( (get_associated_allocator)(handler)); +#if defined(ASIO_NO_DEPRECATED) asio::prefer( asio::require(ex, execution::blocking.never), execution::relationship.continuation, execution::allocator(alloc) ).execute( asio::detail::bind_handler(- static_cast<CompletionHandler&&>(handler)));+ ASIO_MOVE_CAST(CompletionHandler)(handler)));+#else // defined(ASIO_NO_DEPRECATED)+ execution::execute(+ asio::prefer(+ asio::require(ex, execution::blocking.never),+ execution::relationship.continuation,+ execution::allocator(alloc)),+ asio::detail::bind_handler(+ ASIO_MOVE_CAST(CompletionHandler)(handler)));+#endif // defined(ASIO_NO_DEPRECATED) } template <typename CompletionHandler>- void operator()(CompletionHandler&& handler,- enable_if_t<+ void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,+ typename enable_if< !execution::is_executor<- associated_executor_t<decay_t<CompletionHandler>>+ typename associated_executor<+ typename decay<CompletionHandler>::type+ >::type >::value- >* = 0) const+ >::type* = 0) const {- associated_executor_t<decay_t<CompletionHandler>> ex(+ typedef typename decay<CompletionHandler>::type handler_t;++ typename associated_executor<handler_t>::type ex( (get_associated_executor)(handler)); - associated_allocator_t<decay_t<CompletionHandler>> alloc(+ typename associated_allocator<handler_t>::type alloc( (get_associated_allocator)(handler)); ex.defer(asio::detail::bind_handler(- static_cast<CompletionHandler&&>(handler)), alloc);+ ASIO_MOVE_CAST(CompletionHandler)(handler)), alloc); } }; @@ -86,113 +104,140 @@ { } - executor_type get_executor() const noexcept+ executor_type get_executor() const ASIO_NOEXCEPT { return ex_; } template <typename CompletionHandler>- void operator()(CompletionHandler&& handler,- enable_if_t<+ void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,+ typename enable_if< execution::is_executor<- conditional_t<true, executor_type, CompletionHandler>+ typename conditional<true, executor_type, CompletionHandler>::type >::value- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< !detail::is_work_dispatcher_required<- decay_t<CompletionHandler>,+ typename decay<CompletionHandler>::type, Executor >::value- >* = 0) const+ >::type* = 0) const {- associated_allocator_t<decay_t<CompletionHandler>> alloc(+ typedef typename decay<CompletionHandler>::type handler_t;++ typename associated_allocator<handler_t>::type alloc( (get_associated_allocator)(handler)); +#if defined(ASIO_NO_DEPRECATED) asio::prefer( asio::require(ex_, execution::blocking.never), execution::relationship.continuation, execution::allocator(alloc) ).execute( asio::detail::bind_handler(- static_cast<CompletionHandler&&>(handler)));+ ASIO_MOVE_CAST(CompletionHandler)(handler)));+#else // defined(ASIO_NO_DEPRECATED)+ execution::execute(+ asio::prefer(+ asio::require(ex_, execution::blocking.never),+ execution::relationship.continuation,+ execution::allocator(alloc)),+ asio::detail::bind_handler(+ ASIO_MOVE_CAST(CompletionHandler)(handler)));+#endif // defined(ASIO_NO_DEPRECATED) } template <typename CompletionHandler>- void operator()(CompletionHandler&& handler,- enable_if_t<+ void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,+ typename enable_if< execution::is_executor<- conditional_t<true, executor_type, CompletionHandler>+ typename conditional<true, executor_type, CompletionHandler>::type >::value- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< detail::is_work_dispatcher_required<- decay_t<CompletionHandler>,+ typename decay<CompletionHandler>::type, Executor >::value- >* = 0) const+ >::type* = 0) const {- typedef decay_t<CompletionHandler> handler_t;+ typedef typename decay<CompletionHandler>::type handler_t; - typedef associated_executor_t<handler_t, Executor> handler_ex_t;+ typedef typename associated_executor<+ handler_t, Executor>::type handler_ex_t; handler_ex_t handler_ex((get_associated_executor)(handler, ex_)); - associated_allocator_t<handler_t> alloc(+ typename associated_allocator<handler_t>::type alloc( (get_associated_allocator)(handler)); +#if defined(ASIO_NO_DEPRECATED) asio::prefer( asio::require(ex_, execution::blocking.never), execution::relationship.continuation, execution::allocator(alloc) ).execute( detail::work_dispatcher<handler_t, handler_ex_t>(- static_cast<CompletionHandler&&>(handler), handler_ex));+ ASIO_MOVE_CAST(CompletionHandler)(handler), handler_ex));+#else // defined(ASIO_NO_DEPRECATED)+ execution::execute(+ asio::prefer(+ asio::require(ex_, execution::blocking.never),+ execution::relationship.continuation,+ execution::allocator(alloc)),+ detail::work_dispatcher<handler_t, handler_ex_t>(+ ASIO_MOVE_CAST(CompletionHandler)(handler), handler_ex));+#endif // defined(ASIO_NO_DEPRECATED) } template <typename CompletionHandler>- void operator()(CompletionHandler&& handler,- enable_if_t<+ void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,+ typename enable_if< !execution::is_executor<- conditional_t<true, executor_type, CompletionHandler>+ typename conditional<true, executor_type, CompletionHandler>::type >::value- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< !detail::is_work_dispatcher_required<- decay_t<CompletionHandler>,+ typename decay<CompletionHandler>::type, Executor >::value- >* = 0) const+ >::type* = 0) const {- associated_allocator_t<decay_t<CompletionHandler>> alloc(+ typedef typename decay<CompletionHandler>::type handler_t;++ typename associated_allocator<handler_t>::type alloc( (get_associated_allocator)(handler)); ex_.defer(asio::detail::bind_handler(- static_cast<CompletionHandler&&>(handler)), alloc);+ ASIO_MOVE_CAST(CompletionHandler)(handler)), alloc); } template <typename CompletionHandler>- void operator()(CompletionHandler&& handler,- enable_if_t<+ void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,+ typename enable_if< !execution::is_executor<- conditional_t<true, executor_type, CompletionHandler>+ typename conditional<true, executor_type, CompletionHandler>::type >::value- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< detail::is_work_dispatcher_required<- decay_t<CompletionHandler>,+ typename decay<CompletionHandler>::type, Executor >::value- >* = 0) const+ >::type* = 0) const {- typedef decay_t<CompletionHandler> handler_t;+ typedef typename decay<CompletionHandler>::type handler_t; - typedef associated_executor_t<handler_t, Executor> handler_ex_t;+ typedef typename associated_executor<+ handler_t, Executor>::type handler_ex_t; handler_ex_t handler_ex((get_associated_executor)(handler, ex_)); - associated_allocator_t<handler_t> alloc(+ typename associated_allocator<handler_t>::type alloc( (get_associated_allocator)(handler)); ex_.defer(detail::work_dispatcher<handler_t, handler_ex_t>(- static_cast<CompletionHandler&&>(handler), handler_ex), alloc);+ ASIO_MOVE_CAST(CompletionHandler)(handler),+ handler_ex), alloc); } private:
link/modules/asio-standalone/asio/include/asio/detail/initiate_dispatch.hpp view
@@ -2,7 +2,7 @@ // detail/initiate_dispatch.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -32,40 +32,55 @@ { public: template <typename CompletionHandler>- void operator()(CompletionHandler&& handler,- enable_if_t<+ void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,+ typename enable_if< execution::is_executor<- associated_executor_t<decay_t<CompletionHandler>>+ typename associated_executor<+ typename decay<CompletionHandler>::type+ >::type >::value- >* = 0) const+ >::type* = 0) const {- associated_executor_t<decay_t<CompletionHandler>> ex(+ typedef typename decay<CompletionHandler>::type handler_t;++ typename associated_executor<handler_t>::type ex( (get_associated_executor)(handler)); - associated_allocator_t<decay_t<CompletionHandler>> alloc(+ typename associated_allocator<handler_t>::type alloc( (get_associated_allocator)(handler)); +#if defined(ASIO_NO_DEPRECATED) asio::prefer(ex, execution::allocator(alloc)).execute( asio::detail::bind_handler(- static_cast<CompletionHandler&&>(handler)));+ ASIO_MOVE_CAST(CompletionHandler)(handler)));+#else // defined(ASIO_NO_DEPRECATED)+ execution::execute(+ asio::prefer(ex, execution::allocator(alloc)),+ asio::detail::bind_handler(+ ASIO_MOVE_CAST(CompletionHandler)(handler)));+#endif // defined(ASIO_NO_DEPRECATED) } template <typename CompletionHandler>- void operator()(CompletionHandler&& handler,- enable_if_t<+ void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,+ typename enable_if< !execution::is_executor<- associated_executor_t<decay_t<CompletionHandler>>+ typename associated_executor<+ typename decay<CompletionHandler>::type+ >::type >::value- >* = 0) const+ >::type* = 0) const {- associated_executor_t<decay_t<CompletionHandler>> ex(+ typedef typename decay<CompletionHandler>::type handler_t;++ typename associated_executor<handler_t>::type ex( (get_associated_executor)(handler)); - associated_allocator_t<decay_t<CompletionHandler>> alloc(+ typename associated_allocator<handler_t>::type alloc( (get_associated_allocator)(handler)); ex.dispatch(asio::detail::bind_handler(- static_cast<CompletionHandler&&>(handler)), alloc);+ ASIO_MOVE_CAST(CompletionHandler)(handler)), alloc); } }; @@ -80,105 +95,126 @@ { } - executor_type get_executor() const noexcept+ executor_type get_executor() const ASIO_NOEXCEPT { return ex_; } template <typename CompletionHandler>- void operator()(CompletionHandler&& handler,- enable_if_t<+ void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,+ typename enable_if< execution::is_executor<- conditional_t<true, executor_type, CompletionHandler>+ typename conditional<true, executor_type, CompletionHandler>::type >::value- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< !detail::is_work_dispatcher_required<- decay_t<CompletionHandler>,+ typename decay<CompletionHandler>::type, Executor >::value- >* = 0) const+ >::type* = 0) const {- associated_allocator_t<decay_t<CompletionHandler>> alloc(+ typedef typename decay<CompletionHandler>::type handler_t;++ typename associated_allocator<handler_t>::type alloc( (get_associated_allocator)(handler)); +#if defined(ASIO_NO_DEPRECATED) asio::prefer(ex_, execution::allocator(alloc)).execute( asio::detail::bind_handler(- static_cast<CompletionHandler&&>(handler)));+ ASIO_MOVE_CAST(CompletionHandler)(handler)));+#else // defined(ASIO_NO_DEPRECATED)+ execution::execute(+ asio::prefer(ex_, execution::allocator(alloc)),+ asio::detail::bind_handler(+ ASIO_MOVE_CAST(CompletionHandler)(handler)));+#endif // defined(ASIO_NO_DEPRECATED) } template <typename CompletionHandler>- void operator()(CompletionHandler&& handler,- enable_if_t<+ void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,+ typename enable_if< execution::is_executor<- conditional_t<true, executor_type, CompletionHandler>+ typename conditional<true, executor_type, CompletionHandler>::type >::value- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< detail::is_work_dispatcher_required<- decay_t<CompletionHandler>,+ typename decay<CompletionHandler>::type, Executor >::value- >* = 0) const+ >::type* = 0) const {- typedef decay_t<CompletionHandler> handler_t;+ typedef typename decay<CompletionHandler>::type handler_t; - typedef associated_executor_t<handler_t, Executor> handler_ex_t;+ typedef typename associated_executor<+ handler_t, Executor>::type handler_ex_t; handler_ex_t handler_ex((get_associated_executor)(handler, ex_)); - associated_allocator_t<handler_t> alloc(+ typename associated_allocator<handler_t>::type alloc( (get_associated_allocator)(handler)); +#if defined(ASIO_NO_DEPRECATED) asio::prefer(ex_, execution::allocator(alloc)).execute( detail::work_dispatcher<handler_t, handler_ex_t>(- static_cast<CompletionHandler&&>(handler), handler_ex));+ ASIO_MOVE_CAST(CompletionHandler)(handler), handler_ex));+#else // defined(ASIO_NO_DEPRECATED)+ execution::execute(+ asio::prefer(ex_, execution::allocator(alloc)),+ detail::work_dispatcher<handler_t, handler_ex_t>(+ ASIO_MOVE_CAST(CompletionHandler)(handler), handler_ex));+#endif // defined(ASIO_NO_DEPRECATED) } template <typename CompletionHandler>- void operator()(CompletionHandler&& handler,- enable_if_t<+ void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,+ typename enable_if< !execution::is_executor<- conditional_t<true, executor_type, CompletionHandler>+ typename conditional<true, executor_type, CompletionHandler>::type >::value- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< !detail::is_work_dispatcher_required<- decay_t<CompletionHandler>,+ typename decay<CompletionHandler>::type, Executor >::value- >* = 0) const+ >::type* = 0) const {- associated_allocator_t<decay_t<CompletionHandler>> alloc(+ typedef typename decay<CompletionHandler>::type handler_t;++ typename associated_allocator<handler_t>::type alloc( (get_associated_allocator)(handler)); ex_.dispatch(asio::detail::bind_handler(- static_cast<CompletionHandler&&>(handler)), alloc);+ ASIO_MOVE_CAST(CompletionHandler)(handler)), alloc); } template <typename CompletionHandler>- void operator()(CompletionHandler&& handler,- enable_if_t<+ void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,+ typename enable_if< !execution::is_executor<- conditional_t<true, executor_type, CompletionHandler>+ typename conditional<true, executor_type, CompletionHandler>::type >::value- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< detail::is_work_dispatcher_required<- decay_t<CompletionHandler>,+ typename decay<CompletionHandler>::type, Executor >::value- >* = 0) const+ >::type* = 0) const {- typedef decay_t<CompletionHandler> handler_t;+ typedef typename decay<CompletionHandler>::type handler_t; - typedef associated_executor_t<handler_t, Executor> handler_ex_t;+ typedef typename associated_executor<+ handler_t, Executor>::type handler_ex_t; handler_ex_t handler_ex((get_associated_executor)(handler, ex_)); - associated_allocator_t<handler_t> alloc(+ typename associated_allocator<handler_t>::type alloc( (get_associated_allocator)(handler)); ex_.dispatch(detail::work_dispatcher<handler_t, handler_ex_t>(- static_cast<CompletionHandler&&>(handler), handler_ex), alloc);+ ASIO_MOVE_CAST(CompletionHandler)(handler),+ handler_ex), alloc); } private:
link/modules/asio-standalone/asio/include/asio/detail/initiate_post.hpp view
@@ -2,7 +2,7 @@ // detail/initiate_post.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -34,44 +34,62 @@ { public: template <typename CompletionHandler>- void operator()(CompletionHandler&& handler,- enable_if_t<+ void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,+ typename enable_if< execution::is_executor<- associated_executor_t<decay_t<CompletionHandler>>+ typename associated_executor<+ typename decay<CompletionHandler>::type+ >::type >::value- >* = 0) const+ >::type* = 0) const {- associated_executor_t<decay_t<CompletionHandler>> ex(+ typedef typename decay<CompletionHandler>::type handler_t;++ typename associated_executor<handler_t>::type ex( (get_associated_executor)(handler)); - associated_allocator_t<decay_t<CompletionHandler>> alloc(+ typename associated_allocator<handler_t>::type alloc( (get_associated_allocator)(handler)); +#if defined(ASIO_NO_DEPRECATED) asio::prefer( asio::require(ex, execution::blocking.never), execution::relationship.fork, execution::allocator(alloc) ).execute( asio::detail::bind_handler(- static_cast<CompletionHandler&&>(handler)));+ ASIO_MOVE_CAST(CompletionHandler)(handler)));+#else // defined(ASIO_NO_DEPRECATED)+ execution::execute(+ asio::prefer(+ asio::require(ex, execution::blocking.never),+ execution::relationship.fork,+ execution::allocator(alloc)),+ asio::detail::bind_handler(+ ASIO_MOVE_CAST(CompletionHandler)(handler)));+#endif // defined(ASIO_NO_DEPRECATED) } template <typename CompletionHandler>- void operator()(CompletionHandler&& handler,- enable_if_t<+ void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,+ typename enable_if< !execution::is_executor<- associated_executor_t<decay_t<CompletionHandler>>+ typename associated_executor<+ typename decay<CompletionHandler>::type+ >::type >::value- >* = 0) const+ >::type* = 0) const {- associated_executor_t<decay_t<CompletionHandler>> ex(+ typedef typename decay<CompletionHandler>::type handler_t;++ typename associated_executor<handler_t>::type ex( (get_associated_executor)(handler)); - associated_allocator_t<decay_t<CompletionHandler>> alloc(+ typename associated_allocator<handler_t>::type alloc( (get_associated_allocator)(handler)); ex.post(asio::detail::bind_handler(- static_cast<CompletionHandler&&>(handler)), alloc);+ ASIO_MOVE_CAST(CompletionHandler)(handler)), alloc); } }; @@ -86,113 +104,140 @@ { } - executor_type get_executor() const noexcept+ executor_type get_executor() const ASIO_NOEXCEPT { return ex_; } template <typename CompletionHandler>- void operator()(CompletionHandler&& handler,- enable_if_t<+ void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,+ typename enable_if< execution::is_executor<- conditional_t<true, executor_type, CompletionHandler>+ typename conditional<true, executor_type, CompletionHandler>::type >::value- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< !detail::is_work_dispatcher_required<- decay_t<CompletionHandler>,+ typename decay<CompletionHandler>::type, Executor >::value- >* = 0) const+ >::type* = 0) const {- associated_allocator_t<decay_t<CompletionHandler>> alloc(+ typedef typename decay<CompletionHandler>::type handler_t;++ typename associated_allocator<handler_t>::type alloc( (get_associated_allocator)(handler)); +#if defined(ASIO_NO_DEPRECATED) asio::prefer( asio::require(ex_, execution::blocking.never), execution::relationship.fork, execution::allocator(alloc) ).execute( asio::detail::bind_handler(- static_cast<CompletionHandler&&>(handler)));+ ASIO_MOVE_CAST(CompletionHandler)(handler)));+#else // defined(ASIO_NO_DEPRECATED)+ execution::execute(+ asio::prefer(+ asio::require(ex_, execution::blocking.never),+ execution::relationship.fork,+ execution::allocator(alloc)),+ asio::detail::bind_handler(+ ASIO_MOVE_CAST(CompletionHandler)(handler)));+#endif // defined(ASIO_NO_DEPRECATED) } template <typename CompletionHandler>- void operator()(CompletionHandler&& handler,- enable_if_t<+ void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,+ typename enable_if< execution::is_executor<- conditional_t<true, executor_type, CompletionHandler>+ typename conditional<true, executor_type, CompletionHandler>::type >::value- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< detail::is_work_dispatcher_required<- decay_t<CompletionHandler>,+ typename decay<CompletionHandler>::type, Executor >::value- >* = 0) const+ >::type* = 0) const {- typedef decay_t<CompletionHandler> handler_t;+ typedef typename decay<CompletionHandler>::type handler_t; - typedef associated_executor_t<handler_t, Executor> handler_ex_t;+ typedef typename associated_executor<+ handler_t, Executor>::type handler_ex_t; handler_ex_t handler_ex((get_associated_executor)(handler, ex_)); - associated_allocator_t<handler_t> alloc(+ typename associated_allocator<handler_t>::type alloc( (get_associated_allocator)(handler)); +#if defined(ASIO_NO_DEPRECATED) asio::prefer( asio::require(ex_, execution::blocking.never), execution::relationship.fork, execution::allocator(alloc) ).execute( detail::work_dispatcher<handler_t, handler_ex_t>(- static_cast<CompletionHandler&&>(handler), handler_ex));+ ASIO_MOVE_CAST(CompletionHandler)(handler), handler_ex));+#else // defined(ASIO_NO_DEPRECATED)+ execution::execute(+ asio::prefer(+ asio::require(ex_, execution::blocking.never),+ execution::relationship.fork,+ execution::allocator(alloc)),+ detail::work_dispatcher<handler_t, handler_ex_t>(+ ASIO_MOVE_CAST(CompletionHandler)(handler), handler_ex));+#endif // defined(ASIO_NO_DEPRECATED) } template <typename CompletionHandler>- void operator()(CompletionHandler&& handler,- enable_if_t<+ void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,+ typename enable_if< !execution::is_executor<- conditional_t<true, executor_type, CompletionHandler>+ typename conditional<true, executor_type, CompletionHandler>::type >::value- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< !detail::is_work_dispatcher_required<- decay_t<CompletionHandler>,+ typename decay<CompletionHandler>::type, Executor >::value- >* = 0) const+ >::type* = 0) const {- associated_allocator_t<decay_t<CompletionHandler>> alloc(+ typedef typename decay<CompletionHandler>::type handler_t;++ typename associated_allocator<handler_t>::type alloc( (get_associated_allocator)(handler)); ex_.post(asio::detail::bind_handler(- static_cast<CompletionHandler&&>(handler)), alloc);+ ASIO_MOVE_CAST(CompletionHandler)(handler)), alloc); } template <typename CompletionHandler>- void operator()(CompletionHandler&& handler,- enable_if_t<+ void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,+ typename enable_if< !execution::is_executor<- conditional_t<true, executor_type, CompletionHandler>+ typename conditional<true, executor_type, CompletionHandler>::type >::value- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< detail::is_work_dispatcher_required<- decay_t<CompletionHandler>,+ typename decay<CompletionHandler>::type, Executor >::value- >* = 0) const+ >::type* = 0) const {- typedef decay_t<CompletionHandler> handler_t;+ typedef typename decay<CompletionHandler>::type handler_t; - typedef associated_executor_t<handler_t, Executor> handler_ex_t;+ typedef typename associated_executor<+ handler_t, Executor>::type handler_ex_t; handler_ex_t handler_ex((get_associated_executor)(handler, ex_)); - associated_allocator_t<handler_t> alloc(+ typename associated_allocator<handler_t>::type alloc( (get_associated_allocator)(handler)); ex_.post(detail::work_dispatcher<handler_t, handler_ex_t>(- static_cast<CompletionHandler&&>(handler), handler_ex), alloc);+ ASIO_MOVE_CAST(CompletionHandler)(handler),+ handler_ex), alloc); } private:
− link/modules/asio-standalone/asio/include/asio/detail/initiation_base.hpp
@@ -1,62 +0,0 @@-//-// detail/initiation_base.hpp-// ~~~~~~~~~~~~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef ASIO_DETAIL_INITIATION_BASE_HPP-#define ASIO_DETAIL_INITIATION_BASE_HPP--#if defined(_MSC_VER) && (_MSC_VER >= 1200)-# pragma once-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)--#include "asio/detail/config.hpp"-#include "asio/detail/type_traits.hpp"--#include "asio/detail/push_options.hpp"--namespace asio {-namespace detail {--template <typename Initiation, typename = void>-class initiation_base : public Initiation-{-public:- template <typename I>- explicit initiation_base(I&& initiation)- : Initiation(static_cast<I&&>(initiation))- {- }-};--template <typename Initiation>-class initiation_base<Initiation, enable_if_t<!is_class<Initiation>::value>>-{-public:- template <typename I>- explicit initiation_base(I&& initiation)- : initiation_(static_cast<I&&>(initiation))- {- }-- template <typename... Args>- void operator()(Args&&... args) const- {- initiation_(static_cast<Args&&>(args)...);- }--private:- Initiation initiation_;-};--} // namespace detail-} // namespace asio--#include "asio/detail/pop_options.hpp"--#endif // ASIO_DETAIL_INITIATION_BASE_HPP
link/modules/asio-standalone/asio/include/asio/detail/io_control.hpp view
@@ -2,7 +2,7 @@ // detail/io_control.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/io_object_impl.hpp view
@@ -1,8 +1,8 @@ //-// detail/io_object_impl.hpp-// ~~~~~~~~~~~~~~~~~~~~~~~~~+// io_object_impl.hpp+// ~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -60,6 +60,7 @@ service_->construct(implementation_); } +#if defined(ASIO_HAS_MOVE) // Move-construct an I/O object. io_object_impl(io_object_impl&& other) : service_(&other.get_service()),@@ -87,6 +88,7 @@ service_->converting_move_construct(implementation_, other.get_service(), other.get_implementation()); }+#endif // defined(ASIO_HAS_MOVE) // Destructor. ~io_object_impl()@@ -94,6 +96,7 @@ service_->destroy(implementation_); } +#if defined(ASIO_HAS_MOVE) // Move-assign an I/O object. io_object_impl& operator=(io_object_impl&& other) {@@ -107,9 +110,10 @@ } return *this; }+#endif // defined(ASIO_HAS_MOVE) // Get the executor associated with the object.- const executor_type& get_executor() noexcept+ const executor_type& get_executor() ASIO_NOEXCEPT { return executor_; }@@ -142,7 +146,7 @@ // Helper function to get an executor's context. template <typename T> static execution_context& get_context(const T& t,- enable_if_t<execution::is_executor<T>::value>* = 0)+ typename enable_if<execution::is_executor<T>::value>::type* = 0) { return asio::query(t, execution::context); }@@ -150,7 +154,7 @@ // Helper function to get an executor's context. template <typename T> static execution_context& get_context(const T& t,- enable_if_t<!execution::is_executor<T>::value>* = 0)+ typename enable_if<!execution::is_executor<T>::value>::type* = 0) { return t.context(); }
link/modules/asio-standalone/asio/include/asio/detail/io_uring_descriptor_read_at_op.hpp view
@@ -2,7 +2,7 @@ // detail/io_uring_descriptor_read_at_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -135,7 +135,7 @@ : io_uring_descriptor_read_at_op_base<MutableBufferSequence>( success_ec, descriptor, state, offset, buffers, &io_uring_descriptor_read_at_op::do_complete),- handler_(static_cast<Handler&&>(handler)),+ handler_(ASIO_MOVE_CAST(Handler)(handler)), work_(handler_, io_ex) { }@@ -154,7 +154,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); ASIO_ERROR_LOCATION(o->ec_);
link/modules/asio-standalone/asio/include/asio/detail/io_uring_descriptor_read_op.hpp view
@@ -2,7 +2,7 @@ // detail/io_uring_descriptor_read_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -63,7 +63,7 @@ { ::io_uring_prep_read_fixed(sqe, o->descriptor_, o->bufs_.buffers()->iov_base, o->bufs_.buffers()->iov_len,- -1, o->bufs_.registered_id().native_handle());+ 0, o->bufs_.registered_id().native_handle()); } else {@@ -130,7 +130,7 @@ Handler& handler, const IoExecutor& io_ex) : io_uring_descriptor_read_op_base<MutableBufferSequence>(success_ec, descriptor, state, buffers, &io_uring_descriptor_read_op::do_complete),- handler_(static_cast<Handler&&>(handler)),+ handler_(ASIO_MOVE_CAST(Handler)(handler)), work_(handler_, io_ex) { }@@ -149,7 +149,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); ASIO_ERROR_LOCATION(o->ec_);
link/modules/asio-standalone/asio/include/asio/detail/io_uring_descriptor_service.hpp view
@@ -2,7 +2,7 @@ // detail/io_uring_descriptor_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -85,7 +85,7 @@ // Move-construct a new descriptor implementation. ASIO_DECL void move_construct(implementation_type& impl,- implementation_type& other_impl) noexcept;+ implementation_type& other_impl) ASIO_NOEXCEPT; // Move-assign from another descriptor implementation. ASIO_DECL void move_assign(implementation_type& impl,@@ -209,7 +209,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); int op_type;@@ -304,7 +304,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -340,7 +340,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -409,7 +409,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -494,7 +494,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -530,7 +530,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -596,7 +596,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.
link/modules/asio-standalone/asio/include/asio/detail/io_uring_descriptor_write_at_op.hpp view
@@ -2,7 +2,7 @@ // detail/io_uring_descriptor_write_at_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -129,7 +129,7 @@ : io_uring_descriptor_write_at_op_base<ConstBufferSequence>( success_ec, descriptor, state, offset, buffers, &io_uring_descriptor_write_at_op::do_complete),- handler_(static_cast<Handler&&>(handler)),+ handler_(ASIO_MOVE_CAST(Handler)(handler)), work_(handler_, io_ex) { }@@ -148,7 +148,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); ASIO_ERROR_LOCATION(o->ec_);
link/modules/asio-standalone/asio/include/asio/detail/io_uring_descriptor_write_op.hpp view
@@ -2,7 +2,7 @@ // detail/io_uring_descriptor_write_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -63,7 +63,7 @@ { ::io_uring_prep_write_fixed(sqe, o->descriptor_, o->bufs_.buffers()->iov_base, o->bufs_.buffers()->iov_len,- -1, o->bufs_.registered_id().native_handle());+ 0, o->bufs_.registered_id().native_handle()); } else {@@ -125,7 +125,7 @@ const IoExecutor& io_ex) : io_uring_descriptor_write_op_base<ConstBufferSequence>(success_ec, descriptor, state, buffers, &io_uring_descriptor_write_op::do_complete),- handler_(static_cast<Handler&&>(handler)),+ handler_(ASIO_MOVE_CAST(Handler)(handler)), work_(handler_, io_ex) { }@@ -144,7 +144,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); ASIO_ERROR_LOCATION(o->ec_);
link/modules/asio-standalone/asio/include/asio/detail/io_uring_file_service.hpp view
@@ -2,7 +2,7 @@ // detail/io_uring_file_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/io_uring_null_buffers_op.hpp view
@@ -2,7 +2,7 @@ // detail/io_uring_null_buffers_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -19,6 +19,7 @@ #include "asio/detail/bind_handler.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/io_uring_operation.hpp" #include "asio/detail/memory.hpp"@@ -40,7 +41,7 @@ &io_uring_null_buffers_op::do_prepare, &io_uring_null_buffers_op::do_perform, &io_uring_null_buffers_op::do_complete),- handler_(static_cast<Handler&&>(handler)),+ handler_(ASIO_MOVE_CAST(Handler)(handler)), work_(handler_, io_ex), descriptor_(descriptor), poll_flags_(poll_flags)@@ -73,7 +74,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); ASIO_ERROR_LOCATION(o->ec_);
link/modules/asio-standalone/asio/include/asio/detail/io_uring_operation.hpp view
@@ -2,7 +2,7 @@ // detail/io_uring_operation.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/io_uring_service.hpp view
@@ -2,7 +2,7 @@ // detail/io_uring_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -69,8 +69,11 @@ }; // Per I/O object state.- struct io_object+ class io_object {+ friend class io_uring_service;+ friend class object_pool_access;+ io_object* next_; io_object* prev_; @@ -79,7 +82,7 @@ io_queue queues_[max_ops]; bool shutdown_; - ASIO_DECL io_object(bool locking, int spin_count);+ ASIO_DECL io_object(bool locking); }; // Per I/O object data.@@ -143,39 +146,38 @@ ASIO_DECL void cleanup_io_object(per_io_object_data& io_obj); // Add a new timer queue to the reactor.- template <typename TimeTraits, typename Allocator>- void add_timer_queue(timer_queue<TimeTraits, Allocator>& timer_queue);+ template <typename Time_Traits>+ void add_timer_queue(timer_queue<Time_Traits>& timer_queue); // Remove a timer queue from the reactor.- template <typename TimeTraits, typename Allocator>- void remove_timer_queue(timer_queue<TimeTraits, Allocator>& timer_queue);+ template <typename Time_Traits>+ void remove_timer_queue(timer_queue<Time_Traits>& timer_queue); // Schedule a new operation in the given timer queue to expire at the // specified absolute time.- template <typename TimeTraits, typename Allocator>- void schedule_timer(timer_queue<TimeTraits, Allocator>& queue,- const typename TimeTraits::time_type& time,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,- wait_op* op);+ template <typename Time_Traits>+ void schedule_timer(timer_queue<Time_Traits>& queue,+ const typename Time_Traits::time_type& time,+ typename timer_queue<Time_Traits>::per_timer_data& timer, wait_op* op); // Cancel the timer operations associated with the given token. Returns the // number of operations that have been posted or dispatched.- template <typename TimeTraits, typename Allocator>- std::size_t cancel_timer(timer_queue<TimeTraits, Allocator>& queue,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,+ template <typename Time_Traits>+ std::size_t cancel_timer(timer_queue<Time_Traits>& queue,+ typename timer_queue<Time_Traits>::per_timer_data& timer, std::size_t max_cancelled = (std::numeric_limits<std::size_t>::max)()); // Cancel the timer operations associated with the given key.- template <typename TimeTraits, typename Allocator>- void cancel_timer_by_key(timer_queue<TimeTraits, Allocator>& queue,- typename timer_queue<TimeTraits, Allocator>::per_timer_data* timer,+ template <typename Time_Traits>+ void cancel_timer_by_key(timer_queue<Time_Traits>& queue,+ typename timer_queue<Time_Traits>::per_timer_data* timer, void* cancellation_key); // Move the timer operations associated with the given timer.- template <typename TimeTraits, typename Allocator>- void move_timer(timer_queue<TimeTraits, Allocator>& queue,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& target,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& source);+ template <typename Time_Traits>+ void move_timer(timer_queue<Time_Traits>& queue,+ typename timer_queue<Time_Traits>::per_timer_data& target,+ typename timer_queue<Time_Traits>::per_timer_data& source); // Wait on io_uring once until interrupted or events are ready to be // dispatched.@@ -275,12 +277,6 @@ // Whether the service has been shut down. bool shutdown_; - // Whether I/O locking is enabled.- const bool io_locking_;-- // How any times to spin waiting for the I/O mutex.- const int io_locking_spin_count_;- // The timer queues. timer_queue_set timer_queues_; @@ -292,8 +288,7 @@ mutex registration_mutex_; // Keep track of all registered I/O objects.- object_pool<io_object, execution_context::allocator<void>>- registered_io_objects_;+ object_pool<io_object> registered_io_objects_; // Helper class to do post-perform_io cleanup. struct perform_io_cleanup_on_block_exit;
link/modules/asio-standalone/asio/include/asio/detail/io_uring_socket_accept_op.hpp view
@@ -2,7 +2,7 @@ // detail/io_uring_socket_accept_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -22,6 +22,7 @@ #include "asio/detail/bind_handler.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/io_uring_operation.hpp" #include "asio/detail/memory.hpp"@@ -138,7 +139,7 @@ : io_uring_socket_accept_op_base<Socket, Protocol>( success_ec, socket, state, peer, protocol, peer_endpoint, &io_uring_socket_accept_op::do_complete),- handler_(static_cast<Handler&&>(handler)),+ handler_(ASIO_MOVE_CAST(Handler)(handler)), work_(handler_, io_ex) { }@@ -160,7 +161,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); ASIO_ERROR_LOCATION(o->ec_);@@ -191,6 +192,8 @@ handler_work<Handler, IoExecutor> work_; }; +#if defined(ASIO_HAS_MOVE)+ template <typename Protocol, typename PeerIoExecutor, typename Handler, typename IoExecutor> class io_uring_socket_move_accept_op :@@ -211,7 +214,7 @@ io_uring_socket_accept_op_base<peer_socket_type, Protocol>( success_ec, socket, state, *this, protocol, peer_endpoint, &io_uring_socket_move_accept_op::do_complete),- handler_(static_cast<Handler&&>(handler)),+ handler_(ASIO_MOVE_CAST(Handler)(handler)), work_(handler_, io_ex) { }@@ -234,7 +237,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); ASIO_ERROR_LOCATION(o->ec_);@@ -247,8 +250,8 @@ // deallocated the memory here. detail::move_binder2<Handler, asio::error_code, peer_socket_type>- handler(0, static_cast<Handler&&>(o->handler_), o->ec_,- static_cast<peer_socket_type&&>(*o));+ handler(0, ASIO_MOVE_CAST(Handler)(o->handler_), o->ec_,+ ASIO_MOVE_CAST(peer_socket_type)(*o)); p.h = asio::detail::addressof(handler.handler_); p.reset(); @@ -269,6 +272,8 @@ Handler handler_; handler_work<Handler, IoExecutor> work_; };++#endif // defined(ASIO_HAS_MOVE) } // namespace detail } // namespace asio
link/modules/asio-standalone/asio/include/asio/detail/io_uring_socket_connect_op.hpp view
@@ -2,7 +2,7 @@ // detail/io_uring_socket_connect_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -22,6 +22,7 @@ #include "asio/detail/bind_handler.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/io_uring_operation.hpp" #include "asio/detail/memory.hpp"@@ -80,7 +81,7 @@ Handler& handler, const IoExecutor& io_ex) : io_uring_socket_connect_op_base<Protocol>(success_ec, socket, endpoint, &io_uring_socket_connect_op::do_complete),- handler_(static_cast<Handler&&>(handler)),+ handler_(ASIO_MOVE_CAST(Handler)(handler)), work_(handler_, io_ex) { }@@ -99,7 +100,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); ASIO_ERROR_LOCATION(o->ec_);
link/modules/asio-standalone/asio/include/asio/detail/io_uring_socket_recv_op.hpp view
@@ -2,7 +2,7 @@ // detail/io_uring_socket_recv_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -70,7 +70,7 @@ { ::io_uring_prep_read_fixed(sqe, o->socket_, o->bufs_.buffers()->iov_base, o->bufs_.buffers()->iov_len,- -1, o->bufs_.registered_id().native_handle());+ 0, o->bufs_.registered_id().native_handle()); } else {@@ -145,7 +145,7 @@ Handler& handler, const IoExecutor& io_ex) : io_uring_socket_recv_op_base<MutableBufferSequence>(success_ec, socket, state, buffers, flags, &io_uring_socket_recv_op::do_complete),- handler_(static_cast<Handler&&>(handler)),+ handler_(ASIO_MOVE_CAST(Handler)(handler)), work_(handler_, io_ex) { }@@ -164,7 +164,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); ASIO_ERROR_LOCATION(o->ec_);
link/modules/asio-standalone/asio/include/asio/detail/io_uring_socket_recvfrom_op.hpp view
@@ -1,8 +1,8 @@ // // detail/io_uring_socket_recvfrom_op.hpp-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -146,7 +146,7 @@ : io_uring_socket_recvfrom_op_base<MutableBufferSequence, Endpoint>( success_ec, socket, state, buffers, endpoint, flags, &io_uring_socket_recvfrom_op::do_complete),- handler_(static_cast<Handler&&>(handler)),+ handler_(ASIO_MOVE_CAST(Handler)(handler)), work_(handler_, io_ex) { }@@ -165,7 +165,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); ASIO_ERROR_LOCATION(o->ec_);
link/modules/asio-standalone/asio/include/asio/detail/io_uring_socket_recvmsg_op.hpp view
@@ -2,7 +2,7 @@ // detail/io_uring_socket_recvmsg_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -132,7 +132,7 @@ : io_uring_socket_recvmsg_op_base<MutableBufferSequence>(success_ec, socket, state, buffers, in_flags, out_flags, &io_uring_socket_recvmsg_op::do_complete),- handler_(static_cast<Handler&&>(handler)),+ handler_(ASIO_MOVE_CAST(Handler)(handler)), work_(handler_, io_ex) { }@@ -151,7 +151,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); ASIO_ERROR_LOCATION(o->ec_);
link/modules/asio-standalone/asio/include/asio/detail/io_uring_socket_send_op.hpp view
@@ -2,7 +2,7 @@ // detail/io_uring_socket_send_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -69,7 +69,7 @@ { ::io_uring_prep_write_fixed(sqe, o->socket_, o->bufs_.buffers()->iov_base, o->bufs_.buffers()->iov_len,- -1, o->bufs_.registered_id().native_handle());+ 0, o->bufs_.registered_id().native_handle()); } else {@@ -131,7 +131,7 @@ Handler& handler, const IoExecutor& io_ex) : io_uring_socket_send_op_base<ConstBufferSequence>(success_ec, socket, state, buffers, flags, &io_uring_socket_send_op::do_complete),- handler_(static_cast<Handler&&>(handler)),+ handler_(ASIO_MOVE_CAST(Handler)(handler)), work_(handler_, io_ex) { }@@ -150,7 +150,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); ASIO_ERROR_LOCATION(o->ec_);
link/modules/asio-standalone/asio/include/asio/detail/io_uring_socket_sendto_op.hpp view
@@ -2,7 +2,7 @@ // detail/io_uring_socket_sendto_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -134,7 +134,7 @@ : io_uring_socket_sendto_op_base<ConstBufferSequence, Endpoint>( success_ec, socket, state, buffers, endpoint, flags, &io_uring_socket_sendto_op::do_complete),- handler_(static_cast<Handler&&>(handler)),+ handler_(ASIO_MOVE_CAST(Handler)(handler)), work_(handler_, io_ex) { }@@ -153,7 +153,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); ASIO_ERROR_LOCATION(o->ec_);
link/modules/asio-standalone/asio/include/asio/detail/io_uring_socket_service.hpp view
@@ -2,7 +2,7 @@ // detail/io_uring_socket_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -44,7 +44,7 @@ template <typename Protocol> class io_uring_socket_service :- public execution_context_service_base<io_uring_socket_service<Protocol>>,+ public execution_context_service_base<io_uring_socket_service<Protocol> >, public io_uring_socket_service_base { public:@@ -74,7 +74,7 @@ // Constructor. io_uring_socket_service(execution_context& context) : execution_context_service_base<- io_uring_socket_service<Protocol>>(context),+ io_uring_socket_service<Protocol> >(context), io_uring_socket_service_base(context) { }@@ -87,7 +87,7 @@ // Move-construct a new socket implementation. void move_construct(implementation_type& impl,- implementation_type& other_impl) noexcept+ implementation_type& other_impl) ASIO_NOEXCEPT { this->base_move_construct(impl, other_impl); @@ -275,7 +275,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -310,7 +310,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -398,7 +398,7 @@ int op_type = (flags & socket_base::message_out_of_band) ? io_uring_service::except_op : io_uring_service::read_op; - associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -446,7 +446,7 @@ poll_flags = POLLIN; } - associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -514,7 +514,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -539,6 +539,7 @@ p.v = p.p = 0; } +#if defined(ASIO_HAS_MOVE) // Start an asynchronous accept. The peer_endpoint object must be valid until // the accept's handler is invoked. template <typename PeerIoExecutor, typename Handler, typename IoExecutor>@@ -549,7 +550,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -574,6 +575,7 @@ start_accept_op(impl, p.p, is_continuation, false); p.v = p.p = 0; }+#endif // defined(ASIO_HAS_MOVE) // Connect the socket to the specified endpoint. asio::error_code connect(implementation_type& impl,@@ -593,7 +595,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.
link/modules/asio-standalone/asio/include/asio/detail/io_uring_socket_service_base.hpp view
@@ -2,7 +2,7 @@ // detail/io_uring_socket_service_base.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -72,7 +72,7 @@ // Move-construct a new socket implementation. ASIO_DECL void base_move_construct(base_implementation_type& impl,- base_implementation_type& other_impl) noexcept;+ base_implementation_type& other_impl) ASIO_NOEXCEPT; // Move-assign from another socket implementation. ASIO_DECL void base_move_assign(base_implementation_type& impl,@@ -199,7 +199,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); int op_type;@@ -289,7 +289,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -326,7 +326,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -397,7 +397,7 @@ int op_type = (flags & socket_base::message_out_of_band) ? io_uring_service::except_op : io_uring_service::read_op; - associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -448,7 +448,7 @@ poll_flags = POLLIN; } - associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -517,7 +517,7 @@ int op_type = (in_flags & socket_base::message_out_of_band) ? io_uring_service::except_op : io_uring_service::read_op; - associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -566,7 +566,7 @@ poll_flags = POLLIN; } - associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.
link/modules/asio-standalone/asio/include/asio/detail/io_uring_wait_op.hpp view
@@ -2,7 +2,7 @@ // detail/io_uring_wait_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -19,6 +19,7 @@ #include "asio/detail/bind_handler.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/io_uring_operation.hpp" #include "asio/detail/memory.hpp"@@ -38,7 +39,7 @@ int poll_flags, Handler& handler, const IoExecutor& io_ex) : io_uring_operation(success_ec, &io_uring_wait_op::do_prepare, &io_uring_wait_op::do_perform, &io_uring_wait_op::do_complete),- handler_(static_cast<Handler&&>(handler)),+ handler_(ASIO_MOVE_CAST(Handler)(handler)), work_(handler_, io_ex), descriptor_(descriptor), poll_flags_(poll_flags)@@ -71,7 +72,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); ASIO_ERROR_LOCATION(o->ec_);
link/modules/asio-standalone/asio/include/asio/detail/is_buffer_sequence.hpp view
@@ -2,7 +2,7 @@ // detail/is_buffer_sequence.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -55,25 +55,55 @@ { }; +#if defined(ASIO_HAS_DECLTYPE)+ template <typename> char buffer_sequence_begin_helper(...); template <typename T> char (&buffer_sequence_begin_helper(T* t,- enable_if_t<!is_same<+ typename enable_if<!is_same< decltype(asio::buffer_sequence_begin(*t)),- void>::value>*))[2];+ void>::value>::type*))[2]; +#else // defined(ASIO_HAS_DECLTYPE)+ template <typename>+char (&buffer_sequence_begin_helper(...))[2];++template <typename T>+char buffer_sequence_begin_helper(T* t,+ buffer_sequence_memfns_check<+ void (buffer_sequence_memfns_base::*)(),+ &buffer_sequence_memfns_derived<T>::begin>*);++#endif // defined(ASIO_HAS_DECLTYPE)++#if defined(ASIO_HAS_DECLTYPE)++template <typename> char buffer_sequence_end_helper(...); template <typename T> char (&buffer_sequence_end_helper(T* t,- enable_if_t<!is_same<+ typename enable_if<!is_same< decltype(asio::buffer_sequence_end(*t)),- void>::value>*))[2];+ void>::value>::type*))[2]; +#else // defined(ASIO_HAS_DECLTYPE)+ template <typename>+char (&buffer_sequence_end_helper(...))[2];++template <typename T>+char buffer_sequence_end_helper(T* t,+ buffer_sequence_memfns_check<+ void (buffer_sequence_memfns_base::*)(),+ &buffer_sequence_memfns_derived<T>::end>*);++#endif // defined(ASIO_HAS_DECLTYPE)++template <typename> char (&size_memfn_helper(...))[2]; template <typename T>@@ -157,11 +187,23 @@ template <typename, typename> char (&buffer_sequence_element_type_helper(...))[2]; +#if defined(ASIO_HAS_DECLTYPE)+ template <typename T, typename Buffer> char buffer_sequence_element_type_helper(T* t,- enable_if_t<is_convertible<+ typename enable_if<is_convertible< decltype(*asio::buffer_sequence_begin(*t)),- Buffer>::value>*);+ Buffer>::value>::type*);++#else // defined(ASIO_HAS_DECLTYPE)++template <typename T, typename Buffer>+char buffer_sequence_element_type_helper(+ typename T::const_iterator*,+ typename enable_if<is_convertible<+ typename T::value_type, Buffer>::value>::type*);++#endif // defined(ASIO_HAS_DECLTYPE) template <typename> char (&const_buffers_type_typedef_helper(...))[2];
link/modules/asio-standalone/asio/include/asio/detail/is_executor.hpp view
@@ -2,7 +2,7 @@ // detail/is_executor.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/keyword_tss_ptr.hpp view
@@ -2,7 +2,7 @@ // detail/keyword_tss_ptr.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/kqueue_reactor.hpp view
@@ -2,7 +2,7 @@ // detail/kqueue_reactor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2005 Stefan Arentz (stefan at soze dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying@@ -65,9 +65,11 @@ // Per-descriptor queues. struct descriptor_state {- descriptor_state(bool locking, int spin_count)- : mutex_(locking, spin_count) {}+ descriptor_state(bool locking) : mutex_(locking) {} + friend class kqueue_reactor;+ friend class object_pool_access;+ descriptor_state* next_; descriptor_state* prev_; @@ -170,39 +172,38 @@ per_descriptor_data& descriptor_data); // Add a new timer queue to the reactor.- template <typename TimeTraits, typename Allocator>- void add_timer_queue(timer_queue<TimeTraits, Allocator>& timer_queue);+ template <typename Time_Traits>+ void add_timer_queue(timer_queue<Time_Traits>& queue); // Remove a timer queue from the reactor.- template <typename TimeTraits, typename Allocator>- void remove_timer_queue(timer_queue<TimeTraits, Allocator>& timer_queue);+ template <typename Time_Traits>+ void remove_timer_queue(timer_queue<Time_Traits>& queue); // Schedule a new operation in the given timer queue to expire at the // specified absolute time.- template <typename TimeTraits, typename Allocator>- void schedule_timer(timer_queue<TimeTraits, Allocator>& queue,- const typename TimeTraits::time_type& time,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,- wait_op* op);+ template <typename Time_Traits>+ void schedule_timer(timer_queue<Time_Traits>& queue,+ const typename Time_Traits::time_type& time,+ typename timer_queue<Time_Traits>::per_timer_data& timer, wait_op* op); // Cancel the timer operations associated with the given token. Returns the // number of operations that have been posted or dispatched.- template <typename TimeTraits, typename Allocator>- std::size_t cancel_timer(timer_queue<TimeTraits, Allocator>& queue,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,+ template <typename Time_Traits>+ std::size_t cancel_timer(timer_queue<Time_Traits>& queue,+ typename timer_queue<Time_Traits>::per_timer_data& timer, std::size_t max_cancelled = (std::numeric_limits<std::size_t>::max)()); // Cancel the timer operations associated with the given key.- template <typename TimeTraits, typename Allocator>- void cancel_timer_by_key(timer_queue<TimeTraits, Allocator>& queue,- typename timer_queue<TimeTraits, Allocator>::per_timer_data* timer,+ template <typename Time_Traits>+ void cancel_timer_by_key(timer_queue<Time_Traits>& queue,+ typename timer_queue<Time_Traits>::per_timer_data* timer, void* cancellation_key); // Move the timer operations associated with the given timer.- template <typename TimeTraits, typename Allocator>- void move_timer(timer_queue<TimeTraits, Allocator>& queue,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& target,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& source);+ template <typename Time_Traits>+ void move_timer(timer_queue<Time_Traits>& queue,+ typename timer_queue<Time_Traits>::per_timer_data& target,+ typename timer_queue<Time_Traits>::per_timer_data& source); // Run the kqueue loop. ASIO_DECL void run(long usec, op_queue<operation>& ops);@@ -248,18 +249,11 @@ // Whether the service has been shut down. bool shutdown_; - // Whether I/O locking is enabled.- const bool io_locking_;-- // How any times to spin waiting for the I/O mutex.- const int io_locking_spin_count_;- // Mutex to protect access to the registered descriptors. mutex registered_descriptors_mutex_; // Keep track of all registered descriptors.- object_pool<descriptor_state, execution_context::allocator<void>>- registered_descriptors_;+ object_pool<descriptor_state> registered_descriptors_; }; } // namespace detail
link/modules/asio-standalone/asio/include/asio/detail/limits.hpp view
@@ -16,6 +16,11 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"-#include <limits>++#if defined(ASIO_HAS_BOOST_LIMITS)+# include <boost/limits.hpp>+#else // defined(ASIO_HAS_BOOST_LIMITS)+# include <limits>+#endif // defined(ASIO_HAS_BOOST_LIMITS) #endif // ASIO_DETAIL_LIMITS_HPP
link/modules/asio-standalone/asio/include/asio/detail/local_free_on_block_exit.hpp view
@@ -2,7 +2,7 @@ // detail/local_free_on_block_exit.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ link/modules/asio-standalone/asio/include/asio/detail/macos_fenced_block.hpp view
@@ -0,0 +1,62 @@+//+// detail/macos_fenced_block.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_DETAIL_MACOS_FENCED_BLOCK_HPP+#define ASIO_DETAIL_MACOS_FENCED_BLOCK_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"++#if defined(__MACH__) && defined(__APPLE__)++#include <libkern/OSAtomic.h>+#include "asio/detail/noncopyable.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {+namespace detail {++class macos_fenced_block+ : private noncopyable+{+public:+ enum half_t { half };+ enum full_t { full };++ // Constructor for a half fenced block.+ explicit macos_fenced_block(half_t)+ {+ }++ // Constructor for a full fenced block.+ explicit macos_fenced_block(full_t)+ {+ OSMemoryBarrier();+ }++ // Destructor.+ ~macos_fenced_block()+ {+ OSMemoryBarrier();+ }+};++} // namespace detail+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // defined(__MACH__) && defined(__APPLE__)++#endif // ASIO_DETAIL_MACOS_FENCED_BLOCK_HPP
link/modules/asio-standalone/asio/include/asio/detail/memory.hpp view
@@ -2,7 +2,7 @@ // detail/memory.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -23,20 +23,42 @@ #include "asio/detail/cstdint.hpp" #include "asio/detail/throw_exception.hpp" +#if !defined(ASIO_HAS_STD_SHARED_PTR)+# include <boost/make_shared.hpp>+# include <boost/shared_ptr.hpp>+# include <boost/weak_ptr.hpp>+#endif // !defined(ASIO_HAS_STD_SHARED_PTR)++#if !defined(ASIO_HAS_STD_ADDRESSOF)+# include <boost/utility/addressof.hpp>+#endif // !defined(ASIO_HAS_STD_ADDRESSOF)+ #if !defined(ASIO_HAS_STD_ALIGNED_ALLOC) \- && defined(ASIO_HAS_BOOST_ALIGN)+ && defined(ASIO_HAS_BOOST_ALIGN) \+ && defined(ASIO_HAS_ALIGNOF) # include <boost/align/aligned_alloc.hpp> #endif // !defined(ASIO_HAS_STD_ALIGNED_ALLOC) // && defined(ASIO_HAS_BOOST_ALIGN)+ // && defined(ASIO_HAS_ALIGNOF) namespace asio { namespace detail { -using std::allocate_shared;+#if defined(ASIO_HAS_STD_SHARED_PTR) using std::make_shared; using std::shared_ptr; using std::weak_ptr;+#else // defined(ASIO_HAS_STD_SHARED_PTR)+using boost::make_shared;+using boost::shared_ptr;+using boost::weak_ptr;+#endif // defined(ASIO_HAS_STD_SHARED_PTR)++#if defined(ASIO_HAS_STD_ADDRESSOF) using std::addressof;+#else // defined(ASIO_HAS_STD_ADDRESSOF)+using boost::addressof;+#endif // defined(ASIO_HAS_STD_ADDRESSOF) #if defined(ASIO_HAS_STD_TO_ADDRESS) using std::to_address;@@ -54,39 +76,23 @@ inline void* align(std::size_t alignment, std::size_t size, void*& ptr, std::size_t& space) {+#if defined(ASIO_HAS_STD_ALIGN) return std::align(alignment, size, ptr, space);-}--template <typename T, typename Allocator, typename... Args>-T* allocate_object(const Allocator& a, Args&&... args)-{- typename std::allocator_traits<Allocator>::template rebind_alloc<T> alloc(a);- T* raw = std::allocator_traits<decltype(alloc)>::allocate(alloc, 1);-#if !defined(ASIO_NO_EXCEPTIONS)- try-#endif // !defined(ASIO_NO_EXCEPTIONS)- {- return new (raw) T(static_cast<Args&&>(args)...);- }-#if !defined(ASIO_NO_EXCEPTIONS)- catch (...)- {- std::allocator_traits<decltype(alloc)>::deallocate(alloc, raw, 1);- throw;- }-#endif // !defined(ASIO_NO_EXCEPTIONS)-}--template <typename Allocator, typename T>-void deallocate_object(const Allocator& a, T* ptr)-{- typename std::allocator_traits<Allocator>::template rebind_alloc<T> alloc(a);- std::allocator_traits<decltype(alloc)>::destroy(alloc, ptr);- std::allocator_traits<decltype(alloc)>::deallocate(alloc, ptr, 1);+#else // defined(ASIO_HAS_STD_ALIGN)+ const uintptr_t intptr = reinterpret_cast<uintptr_t>(ptr);+ const uintptr_t aligned = (intptr - 1u + alignment) & -alignment;+ const std::size_t padding = aligned - intptr;+ if (size + padding > space)+ return 0;+ space -= padding;+ ptr = reinterpret_cast<void*>(aligned);+ return ptr;+#endif // defined(ASIO_HAS_STD_ALIGN) } } // namespace detail +#if defined(ASIO_HAS_CXX11_ALLOCATORS) using std::allocator_arg_t; # define ASIO_USES_ALLOCATOR(t) \ namespace std { \@@ -97,10 +103,17 @@ # define ASIO_REBIND_ALLOC(alloc, t) \ typename std::allocator_traits<alloc>::template rebind_alloc<t> /**/+#else // defined(ASIO_HAS_CXX11_ALLOCATORS)+struct allocator_arg_t {};+# define ASIO_USES_ALLOCATOR(t)+# define ASIO_REBIND_ALLOC(alloc, t) \+ typename alloc::template rebind<t>::other+ /**/+#endif // defined(ASIO_HAS_CXX11_ALLOCATORS) inline void* aligned_new(std::size_t align, std::size_t size) {-#if defined(ASIO_HAS_STD_ALIGNED_ALLOC)+#if defined(ASIO_HAS_STD_ALIGNED_ALLOC) && defined(ASIO_HAS_ALIGNOF) align = (align < ASIO_DEFAULT_ALIGN) ? ASIO_DEFAULT_ALIGN : align; size = (size % align == 0) ? size : size + (align - size % align); void* ptr = std::aligned_alloc(align, size);@@ -110,7 +123,7 @@ asio::detail::throw_exception(ex); } return ptr;-#elif defined(ASIO_HAS_BOOST_ALIGN)+#elif defined(ASIO_HAS_BOOST_ALIGN) && defined(ASIO_HAS_ALIGNOF) align = (align < ASIO_DEFAULT_ALIGN) ? ASIO_DEFAULT_ALIGN : align; size = (size % align == 0) ? size : size + (align - size % align); void* ptr = boost::alignment::aligned_alloc(align, size);@@ -120,7 +133,7 @@ asio::detail::throw_exception(ex); } return ptr;-#elif defined(ASIO_MSVC)+#elif defined(ASIO_MSVC) && defined(ASIO_HAS_ALIGNOF) align = (align < ASIO_DEFAULT_ALIGN) ? ASIO_DEFAULT_ALIGN : align; size = (size % align == 0) ? size : size + (align - size % align); void* ptr = _aligned_malloc(size, align);@@ -130,23 +143,23 @@ asio::detail::throw_exception(ex); } return ptr;-#else // defined(ASIO_MSVC)+#else // defined(ASIO_MSVC) && defined(ASIO_HAS_ALIGNOF) (void)align; return ::operator new(size);-#endif // defined(ASIO_MSVC)+#endif // defined(ASIO_MSVC) && defined(ASIO_HAS_ALIGNOF) } inline void aligned_delete(void* ptr) {-#if defined(ASIO_HAS_STD_ALIGNED_ALLOC)+#if defined(ASIO_HAS_STD_ALIGNED_ALLOC) && defined(ASIO_HAS_ALIGNOF) std::free(ptr);-#elif defined(ASIO_HAS_BOOST_ALIGN)+#elif defined(ASIO_HAS_BOOST_ALIGN) && defined(ASIO_HAS_ALIGNOF) boost::alignment::aligned_free(ptr);-#elif defined(ASIO_MSVC)+#elif defined(ASIO_MSVC) && defined(ASIO_HAS_ALIGNOF) _aligned_free(ptr);-#else // defined(ASIO_MSVC)+#else // defined(ASIO_MSVC) && defined(ASIO_HAS_ALIGNOF) ::operator delete(ptr);-#endif // defined(ASIO_MSVC)+#endif // defined(ASIO_MSVC) && defined(ASIO_HAS_ALIGNOF) } } // namespace asio
link/modules/asio-standalone/asio/include/asio/detail/mutex.hpp view
@@ -2,7 +2,7 @@ // detail/mutex.hpp // ~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -23,8 +23,10 @@ # include "asio/detail/win_mutex.hpp" #elif defined(ASIO_HAS_PTHREADS) # include "asio/detail/posix_mutex.hpp"-#else+#elif defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR) # include "asio/detail/std_mutex.hpp"+#else+# error Only Windows, POSIX and std::mutex are supported! #endif namespace asio {@@ -36,7 +38,7 @@ typedef win_mutex mutex; #elif defined(ASIO_HAS_PTHREADS) typedef posix_mutex mutex;-#else+#elif defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR) typedef std_mutex mutex; #endif
link/modules/asio-standalone/asio/include/asio/detail/non_const_lvalue.hpp view
@@ -2,7 +2,7 @@ // detail/non_const_lvalue.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -26,13 +26,24 @@ template <typename T> struct non_const_lvalue {+#if defined(ASIO_HAS_MOVE) explicit non_const_lvalue(T& t)- : value(static_cast<conditional_t<- is_same<T, decay_t<T>>::value, decay_t<T>&, T&&>>(t))+ : value(static_cast<typename conditional<+ is_same<T, typename decay<T>::type>::value,+ typename decay<T>::type&, T&&>::type>(t)) { } - conditional_t<is_same<T, decay_t<T>>::value, decay_t<T>&, decay_t<T>> value;+ typename conditional<is_same<T, typename decay<T>::type>::value,+ typename decay<T>::type&, typename decay<T>::type>::type value;+#else // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)+ explicit non_const_lvalue(const typename decay<T>::type& t)+ : value(t)+ {+ }++ typename decay<T>::type value;+#endif // defined(ASIO_HAS_MOVE) }; } // namespace detail
link/modules/asio-standalone/asio/include/asio/detail/noncopyable.hpp view
@@ -2,7 +2,7 @@ // detail/noncopyable.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/null_event.hpp view
@@ -2,7 +2,7 @@ // detail/null_event.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/null_fenced_block.hpp view
@@ -2,7 +2,7 @@ // detail/null_fenced_block.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/null_global.hpp view
@@ -2,7 +2,7 @@ // detail/null_global.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/null_mutex.hpp view
@@ -2,7 +2,7 @@ // detail/null_mutex.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -39,12 +39,6 @@ // Destructor. ~null_mutex() {- }-- // Try to lock the mutex.- bool try_lock()- {- return true; } // Lock the mutex.
link/modules/asio-standalone/asio/include/asio/detail/null_reactor.hpp view
@@ -2,7 +2,7 @@ // detail/null_reactor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/null_signal_blocker.hpp view
@@ -2,7 +2,7 @@ // detail/null_signal_blocker.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/null_socket_service.hpp view
@@ -2,7 +2,7 @@ // detail/null_socket_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -33,7 +33,7 @@ template <typename Protocol> class null_socket_service :- public execution_context_service_base<null_socket_service<Protocol>>+ public execution_context_service_base<null_socket_service<Protocol> > { public: // The protocol type.@@ -52,7 +52,7 @@ // Constructor. null_socket_service(execution_context& context)- : execution_context_service_base<null_socket_service<Protocol>>(context)+ : execution_context_service_base<null_socket_service<Protocol> >(context) { }
link/modules/asio-standalone/asio/include/asio/detail/null_static_mutex.hpp view
@@ -2,7 +2,7 @@ // detail/null_static_mutex.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -33,12 +33,6 @@ // Initialise the mutex. void init() {- }-- // Try to lock the mutex without blocking.- bool try_lock()- {- return true; } // Lock the mutex.
link/modules/asio-standalone/asio/include/asio/detail/null_thread.hpp view
@@ -2,7 +2,7 @@ // detail/null_thread.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -19,6 +19,7 @@ #if !defined(ASIO_HAS_THREADS) +#include "asio/detail/noncopyable.hpp" #include "asio/detail/throw_error.hpp" #include "asio/error.hpp" @@ -28,13 +29,9 @@ namespace detail { class null_thread+ : private noncopyable { public:- // Construct in a non-joinable state.- null_thread() noexcept- {- }- // Constructor. template <typename Function> null_thread(Function, unsigned int = 0)@@ -43,34 +40,9 @@ asio::error::operation_not_supported, "thread"); } - // Construct with custom allocator.- template <typename Allocator, typename Function>- null_thread(allocator_arg_t, const Allocator&, Function, unsigned int = 0)- {- asio::detail::throw_error(- asio::error::operation_not_supported, "thread");- }-- // Move constructor.- null_thread(null_thread&& other) noexcept- {- }- // Destructor. ~null_thread() {- }-- // Move assignment.- null_thread& operator=(null_thread&& other) noexcept- {- return *this;- }-- // Whether the thread can be joined.- bool joinable() const- {- return false; } // Wait for the thread to exit.
link/modules/asio-standalone/asio/include/asio/detail/null_tss_ptr.hpp view
@@ -2,7 +2,7 @@ // detail/null_tss_ptr.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/object_pool.hpp view
@@ -2,7 +2,7 @@ // detail/object_pool.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -15,34 +15,60 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include "asio/detail/config.hpp"-#include "asio/detail/memory.hpp"+#include "asio/detail/noncopyable.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { -template <typename Object, typename Allocator>+template <typename Object>+class object_pool;++class object_pool_access+{+public:+ template <typename Object>+ static Object* create()+ {+ return new Object;+ }++ template <typename Object, typename Arg>+ static Object* create(Arg arg)+ {+ return new Object(arg);+ }++ template <typename Object>+ static void destroy(Object* o)+ {+ delete o;+ }++ template <typename Object>+ static Object*& next(Object* o)+ {+ return o->next_;+ }++ template <typename Object>+ static Object*& prev(Object* o)+ {+ return o->prev_;+ }+};++template <typename Object> class object_pool+ : private noncopyable { public: // Constructor.- template <typename... Args>- object_pool(const Allocator& allocator,- unsigned int preallocated, Args... args)- : allocator_(allocator),- live_list_(0),+ object_pool()+ : live_list_(0), free_list_(0) {- while (preallocated > 0)- {- Object* o = allocate_object<Object>(allocator_, args...);- o->next_ = free_list_;- o->prev_ = 0;- free_list_ = o;- --preallocated;- } } // Destructor destroys all objects.@@ -58,20 +84,38 @@ return live_list_; } + // Allocate a new object.+ Object* alloc()+ {+ Object* o = free_list_;+ if (o)+ free_list_ = object_pool_access::next(free_list_);+ else+ o = object_pool_access::create<Object>();++ object_pool_access::next(o) = live_list_;+ object_pool_access::prev(o) = 0;+ if (live_list_)+ object_pool_access::prev(live_list_) = o;+ live_list_ = o;++ return o;+ }+ // Allocate a new object with an argument.- template <typename... Args>- Object* alloc(Args... args)+ template <typename Arg>+ Object* alloc(Arg arg) { Object* o = free_list_; if (o)- free_list_ = free_list_->next_;+ free_list_ = object_pool_access::next(free_list_); else- o = allocate_object<Object>(allocator_, args...);+ o = object_pool_access::create<Object>(arg); - o->next_ = live_list_;- o->prev_ = 0;+ object_pool_access::next(o) = live_list_;+ object_pool_access::prev(o) = 0; if (live_list_)- live_list_->prev_ = o;+ object_pool_access::prev(live_list_) = o; live_list_ = o; return o;@@ -81,36 +125,36 @@ void free(Object* o) { if (live_list_ == o)- live_list_ = o->next_;+ live_list_ = object_pool_access::next(o); - if (o->prev_)- o->prev_->next_ = o->next_;+ if (object_pool_access::prev(o))+ {+ object_pool_access::next(object_pool_access::prev(o))+ = object_pool_access::next(o);+ } - if (o->next_)- o->next_->prev_ = o->prev_;+ if (object_pool_access::next(o))+ {+ object_pool_access::prev(object_pool_access::next(o))+ = object_pool_access::prev(o);+ } - o->next_ = free_list_;- o->prev_ = 0;+ object_pool_access::next(o) = free_list_;+ object_pool_access::prev(o) = 0; free_list_ = o; } private:- object_pool(const object_pool&) = delete;- object_pool& operator=(const object_pool&) = delete;- // Helper function to destroy all elements in a list. void destroy_list(Object* list) { while (list) { Object* o = list;- list = o->next_;- deallocate_object(allocator_, o);+ list = object_pool_access::next(o);+ object_pool_access::destroy(o); } }-- // The execution_context allocator used to manage pooled object memory.- Allocator allocator_; // The list of live objects. Object* live_list_;
link/modules/asio-standalone/asio/include/asio/detail/old_win_sdk_compat.hpp view
@@ -2,7 +2,7 @@ // detail/old_win_sdk_compat.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/op_queue.hpp view
@@ -2,7 +2,7 @@ // detail/op_queue.hpp // ~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/operation.hpp view
@@ -2,7 +2,7 @@ // detail/operation.hpp // ~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/pipe_select_interrupter.hpp view
@@ -2,7 +2,7 @@ // detail/pipe_select_interrupter.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/pop_options.hpp view
@@ -2,7 +2,7 @@ // detail/pop_options.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/posix_event.hpp view
@@ -2,7 +2,7 @@ // detail/posix_event.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/posix_fd_set_adapter.hpp view
@@ -2,7 +2,7 @@ // detail/posix_fd_set_adapter.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/posix_global.hpp view
@@ -2,7 +2,7 @@ // detail/posix_global.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/posix_mutex.hpp view
@@ -2,7 +2,7 @@ // detail/posix_mutex.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -43,12 +43,6 @@ ~posix_mutex() { ::pthread_mutex_destroy(&mutex_); // Ignore EBUSY.- }-- // Try to lock the mutex.- bool try_lock()- {- return ::pthread_mutex_trylock(&mutex_) == 0; // Ignore EINVAL. } // Lock the mutex.
link/modules/asio-standalone/asio/include/asio/detail/posix_serial_port_service.hpp view
@@ -2,7 +2,7 @@ // detail/posix_serial_port_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying
link/modules/asio-standalone/asio/include/asio/detail/posix_signal_blocker.hpp view
@@ -2,7 +2,7 @@ // detail/posix_signal_blocker.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/posix_static_mutex.hpp view
@@ -2,7 +2,7 @@ // detail/posix_static_mutex.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/posix_thread.hpp view
@@ -2,7 +2,7 @@ // detail/posix_thread.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -21,7 +21,7 @@ #include <cstddef> #include <pthread.h>-#include "asio/detail/memory.hpp"+#include "asio/detail/noncopyable.hpp" #include "asio/detail/push_options.hpp" @@ -34,53 +34,20 @@ } class posix_thread+ : private noncopyable { public:- // Construct in a non-joinable state.- posix_thread() noexcept- : arg_(0)- {- }- // Constructor. template <typename Function> posix_thread(Function f, unsigned int = 0)- : posix_thread(std::allocator_arg, std::allocator<void>(), f)- {- }-- // Construct with custom allocator.- template <typename Allocator, typename Function>- posix_thread(allocator_arg_t, const Allocator& a,- Function f, unsigned int = 0)- : arg_(start_thread(allocate_object<func<Function, Allocator>>(a, f, a)))- {- }-- // Move constructor.- posix_thread(posix_thread&& other) noexcept- : arg_(other.arg_)+ : joined_(false) {- other.arg_ = 0;+ start_thread(new func<Function>(f)); } // Destructor. ASIO_DECL ~posix_thread(); - // Move assignment.- posix_thread& operator=(posix_thread&& other) noexcept- {- arg_ = other.arg_;- other.arg_ = 0;- return *this;- }-- // Whether the thread can be joined.- bool joinable() const- {- return !!arg_;- }- // Wait for the thread to exit. ASIO_DECL void join(); @@ -95,18 +62,21 @@ public: virtual ~func_base() {} virtual void run() = 0;- virtual void destroy() = 0;- ::pthread_t thread_; }; - template <typename Function, typename Allocator>+ struct auto_func_base_ptr+ {+ func_base* ptr;+ ~auto_func_base_ptr() { delete ptr; }+ };++ template <typename Function> class func : public func_base { public:- func(Function f, const Allocator& a)- : f_(f),- allocator_(a)+ func(Function f)+ : f_(f) { } @@ -115,19 +85,14 @@ f_(); } - virtual void destroy()- {- deallocate_object(allocator_, this);- }- private: Function f_;- Allocator allocator_; }; - ASIO_DECL func_base* start_thread(func_base* arg);+ ASIO_DECL void start_thread(func_base* arg); - func_base* arg_;+ ::pthread_t thread_;+ bool joined_; }; } // namespace detail
link/modules/asio-standalone/asio/include/asio/detail/posix_tss_ptr.hpp view
@@ -2,7 +2,7 @@ // detail/posix_tss_ptr.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/push_options.hpp view
@@ -2,7 +2,7 @@ // detail/push_options.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/reactive_descriptor_service.hpp view
@@ -2,7 +2,7 @@ // detail/reactive_descriptor_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -89,7 +89,7 @@ // Move-construct a new descriptor implementation. ASIO_DECL void move_construct(implementation_type& impl,- implementation_type& other_impl) noexcept;+ implementation_type& other_impl) ASIO_NOEXCEPT; // Move-assign from another descriptor implementation. ASIO_DECL void move_assign(implementation_type& impl,@@ -212,7 +212,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -239,7 +239,7 @@ default: p.p->ec_ = asio::error::invalid_argument; start_op(impl, reactor::read_op, p.p,- is_continuation, false, true, false, &io_ex, 0);+ is_continuation, false, true, &io_ex, 0); p.v = p.p = 0; return; }@@ -252,8 +252,7 @@ &reactor_, &impl.reactor_data_, impl.descriptor_, op_type); } - start_op(impl, op_type, p.p, is_continuation,- false, false, false, &io_ex, 0);+ start_op(impl, op_type, p.p, is_continuation, false, false, &io_ex, 0); p.v = p.p = 0; } @@ -304,7 +303,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -327,7 +326,7 @@ start_op(impl, reactor::write_op, p.p, is_continuation, true, buffer_sequence_adapter<asio::const_buffer,- ConstBufferSequence>::all_empty(buffers), true, &io_ex, 0);+ ConstBufferSequence>::all_empty(buffers), &io_ex, 0); p.v = p.p = 0; } @@ -339,7 +338,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -361,7 +360,7 @@ &impl, impl.descriptor_, "async_write_some(null_buffers)")); start_op(impl, reactor::write_op, p.p,- is_continuation, false, false, false, &io_ex, 0);+ is_continuation, false, false, &io_ex, 0); p.v = p.p = 0; } @@ -413,7 +412,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -436,7 +435,7 @@ start_op(impl, reactor::read_op, p.p, is_continuation, true, buffer_sequence_adapter<asio::mutable_buffer,- MutableBufferSequence>::all_empty(buffers), true, &io_ex, 0);+ MutableBufferSequence>::all_empty(buffers), &io_ex, 0); p.v = p.p = 0; } @@ -448,7 +447,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -470,15 +469,14 @@ &impl, impl.descriptor_, "async_read_some(null_buffers)")); start_op(impl, reactor::read_op, p.p,- is_continuation, false, false, false, &io_ex, 0);+ is_continuation, false, false, &io_ex, 0); p.v = p.p = 0; } private: // Start the asynchronous operation.- ASIO_DECL void do_start_op(implementation_type& impl,- int op_type, reactor_op* op, bool is_continuation,- bool allow_speculative, bool noop, bool needs_non_blocking,+ ASIO_DECL void do_start_op(implementation_type& impl, int op_type,+ reactor_op* op, bool is_continuation, bool is_non_blocking, bool noop, void (*on_immediate)(operation* op, bool, const void*), const void* immediate_arg); @@ -486,20 +484,19 @@ // immediate completion. template <typename Op> void start_op(implementation_type& impl, int op_type, Op* op,- bool is_continuation, bool allow_speculative, bool noop,- bool needs_non_blocking, const void* io_ex, ...)+ bool is_continuation, bool is_non_blocking, bool noop,+ const void* io_ex, ...) {- return do_start_op(impl, op_type, op, is_continuation, allow_speculative,- noop, needs_non_blocking, &Op::do_immediate, io_ex);+ return do_start_op(impl, op_type, op, is_continuation,+ is_non_blocking, noop, &Op::do_immediate, io_ex); } // Start the asynchronous operation for handlers that are not specialised for // immediate completion. template <typename Op>- void start_op(implementation_type& impl, int op_type,- Op* op, bool is_continuation, bool allow_speculative,- bool noop, bool needs_non_blocking, const void*,- enable_if_t<+ void start_op(implementation_type& impl, int op_type, Op* op,+ bool is_continuation, bool is_non_blocking, bool noop, const void*,+ typename enable_if< is_same< typename associated_immediate_executor< typename Op::handler_type,@@ -507,11 +504,10 @@ >::asio_associated_immediate_executor_is_unspecialised, void >::value- >*)+ >::type*) {- return do_start_op(impl, op_type, op, is_continuation,- allow_speculative, noop, needs_non_blocking,- &reactor::call_post_immediate_completion, &reactor_);+ return do_start_op(impl, op_type, op, is_continuation, is_non_blocking,+ noop, &reactor::call_post_immediate_completion, &reactor_); } // Helper class used to implement per-operation cancellation
link/modules/asio-standalone/asio/include/asio/detail/reactive_null_buffers_op.hpp view
@@ -2,7 +2,7 @@ // detail/reactive_null_buffers_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -19,6 +19,7 @@ #include "asio/detail/bind_handler.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/reactor_op.hpp"@@ -41,7 +42,7 @@ Handler& handler, const IoExecutor& io_ex) : reactor_op(success_ec, &reactive_null_buffers_op::do_perform, &reactive_null_buffers_op::do_complete),- handler_(static_cast<Handler&&>(handler)),+ handler_(ASIO_MOVE_CAST(Handler)(handler)), work_(handler_, io_ex) { }@@ -64,7 +65,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); // Make a copy of the handler so that the memory can be deallocated before@@ -99,7 +100,7 @@ // Take ownership of the operation's outstanding work. immediate_handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); // Make a copy of the handler so that the memory can be deallocated before
link/modules/asio-standalone/asio/include/asio/detail/reactive_socket_accept_op.hpp view
@@ -2,7 +2,7 @@ // detail/reactive_socket_accept_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -19,6 +19,7 @@ #include "asio/detail/bind_handler.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/reactor_op.hpp"@@ -107,7 +108,7 @@ : reactive_socket_accept_op_base<Socket, Protocol>( success_ec, socket, state, peer, protocol, peer_endpoint, &reactive_socket_accept_op::do_complete),- handler_(static_cast<Handler&&>(handler)),+ handler_(ASIO_MOVE_CAST(Handler)(handler)), work_(handler_, io_ex) { }@@ -129,7 +130,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); ASIO_ERROR_LOCATION(o->ec_);@@ -169,7 +170,7 @@ // Take ownership of the operation's outstanding work. immediate_handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); ASIO_ERROR_LOCATION(o->ec_);@@ -195,6 +196,8 @@ handler_work<Handler, IoExecutor> work_; }; +#if defined(ASIO_HAS_MOVE)+ template <typename Protocol, typename PeerIoExecutor, typename Handler, typename IoExecutor> class reactive_socket_move_accept_op :@@ -218,7 +221,7 @@ reactive_socket_accept_op_base<peer_socket_type, Protocol>( success_ec, socket, state, *this, protocol, peer_endpoint, &reactive_socket_move_accept_op::do_complete),- handler_(static_cast<Handler&&>(handler)),+ handler_(ASIO_MOVE_CAST(Handler)(handler)), work_(handler_, io_ex) { }@@ -241,7 +244,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); ASIO_ERROR_LOCATION(o->ec_);@@ -254,8 +257,8 @@ // deallocated the memory here. detail::move_binder2<Handler, asio::error_code, peer_socket_type>- handler(0, static_cast<Handler&&>(o->handler_), o->ec_,- static_cast<peer_socket_type&&>(*o));+ handler(0, ASIO_MOVE_CAST(Handler)(o->handler_), o->ec_,+ ASIO_MOVE_CAST(peer_socket_type)(*o)); p.h = asio::detail::addressof(handler.handler_); p.reset(); @@ -284,7 +287,7 @@ // Take ownership of the operation's outstanding work. immediate_handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); ASIO_ERROR_LOCATION(o->ec_);@@ -297,8 +300,8 @@ // deallocated the memory here. detail::move_binder2<Handler, asio::error_code, peer_socket_type>- handler(0, static_cast<Handler&&>(o->handler_), o->ec_,- static_cast<peer_socket_type&&>(*o));+ handler(0, ASIO_MOVE_CAST(Handler)(o->handler_), o->ec_,+ ASIO_MOVE_CAST(peer_socket_type)(*o)); p.h = asio::detail::addressof(handler.handler_); p.reset(); @@ -314,6 +317,8 @@ Handler handler_; handler_work<Handler, IoExecutor> work_; };++#endif // defined(ASIO_HAS_MOVE) } // namespace detail } // namespace asio
link/modules/asio-standalone/asio/include/asio/detail/reactive_socket_connect_op.hpp view
@@ -2,7 +2,7 @@ // detail/reactive_socket_connect_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -19,6 +19,7 @@ #include "asio/detail/bind_handler.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/reactor_op.hpp"@@ -71,7 +72,7 @@ socket_type socket, Handler& handler, const IoExecutor& io_ex) : reactive_socket_connect_op_base(success_ec, socket, &reactive_socket_connect_op::do_complete),- handler_(static_cast<Handler&&>(handler)),+ handler_(ASIO_MOVE_CAST(Handler)(handler)), work_(handler_, io_ex) { }@@ -90,7 +91,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); ASIO_ERROR_LOCATION(o->ec_);@@ -128,7 +129,7 @@ // Take ownership of the operation's outstanding work. immediate_handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); ASIO_ERROR_LOCATION(o->ec_);
link/modules/asio-standalone/asio/include/asio/detail/reactive_socket_recv_op.hpp view
@@ -2,7 +2,7 @@ // detail/reactive_socket_recv_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -20,6 +20,7 @@ #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/reactor_op.hpp"@@ -108,7 +109,7 @@ Handler& handler, const IoExecutor& io_ex) : reactive_socket_recv_op_base<MutableBufferSequence>(success_ec, socket, state, buffers, flags, &reactive_socket_recv_op::do_complete),- handler_(static_cast<Handler&&>(handler)),+ handler_(ASIO_MOVE_CAST(Handler)(handler)), work_(handler_, io_ex) { }@@ -126,7 +127,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); ASIO_ERROR_LOCATION(o->ec_);@@ -163,7 +164,7 @@ // Take ownership of the operation's outstanding work. immediate_handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); ASIO_ERROR_LOCATION(o->ec_);
link/modules/asio-standalone/asio/include/asio/detail/reactive_socket_recvfrom_op.hpp view
@@ -2,7 +2,7 @@ // detail/reactive_socket_recvfrom_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -20,6 +20,7 @@ #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/reactor_op.hpp"@@ -112,7 +113,7 @@ : reactive_socket_recvfrom_op_base<MutableBufferSequence, Endpoint>( success_ec, socket, protocol_type, buffers, endpoint, flags, &reactive_socket_recvfrom_op::do_complete),- handler_(static_cast<Handler&&>(handler)),+ handler_(ASIO_MOVE_CAST(Handler)(handler)), work_(handler_, io_ex) { }@@ -131,7 +132,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); ASIO_ERROR_LOCATION(o->ec_);@@ -169,7 +170,7 @@ // Take ownership of the operation's outstanding work. immediate_handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); ASIO_ERROR_LOCATION(o->ec_);
link/modules/asio-standalone/asio/include/asio/detail/reactive_socket_recvmsg_op.hpp view
@@ -2,7 +2,7 @@ // detail/reactive_socket_recvmsg_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -20,6 +20,7 @@ #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/reactor_op.hpp"@@ -93,7 +94,7 @@ : reactive_socket_recvmsg_op_base<MutableBufferSequence>( success_ec, socket, buffers, in_flags, out_flags, &reactive_socket_recvmsg_op::do_complete),- handler_(static_cast<Handler&&>(handler)),+ handler_(ASIO_MOVE_CAST(Handler)(handler)), work_(handler_, io_ex) { }@@ -112,7 +113,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); ASIO_ERROR_LOCATION(o->ec_);@@ -150,7 +151,7 @@ // Take ownership of the operation's outstanding work. immediate_handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); ASIO_ERROR_LOCATION(o->ec_);
link/modules/asio-standalone/asio/include/asio/detail/reactive_socket_send_op.hpp view
@@ -2,7 +2,7 @@ // detail/reactive_socket_send_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -20,6 +20,7 @@ #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/reactor_op.hpp"@@ -111,7 +112,7 @@ Handler& handler, const IoExecutor& io_ex) : reactive_socket_send_op_base<ConstBufferSequence>(success_ec, socket, state, buffers, flags, &reactive_socket_send_op::do_complete),- handler_(static_cast<Handler&&>(handler)),+ handler_(ASIO_MOVE_CAST(Handler)(handler)), work_(handler_, io_ex) { }@@ -129,7 +130,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); ASIO_ERROR_LOCATION(o->ec_);@@ -166,7 +167,7 @@ // Take ownership of the operation's outstanding work. immediate_handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); ASIO_ERROR_LOCATION(o->ec_);@@ -186,6 +187,7 @@ w.complete(handler, handler.handler_, io_ex); ASIO_HANDLER_INVOCATION_END; }+ private: Handler handler_;
link/modules/asio-standalone/asio/include/asio/detail/reactive_socket_sendto_op.hpp view
@@ -2,7 +2,7 @@ // detail/reactive_socket_sendto_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -20,6 +20,7 @@ #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/reactor_op.hpp"@@ -105,7 +106,7 @@ : reactive_socket_sendto_op_base<ConstBufferSequence, Endpoint>( success_ec, socket, buffers, endpoint, flags, &reactive_socket_sendto_op::do_complete),- handler_(static_cast<Handler&&>(handler)),+ handler_(ASIO_MOVE_CAST(Handler)(handler)), work_(handler_, io_ex) { }@@ -123,7 +124,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); ASIO_ERROR_LOCATION(o->ec_);@@ -160,7 +161,7 @@ // Take ownership of the operation's outstanding work. immediate_handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); ASIO_ERROR_LOCATION(o->ec_);
link/modules/asio-standalone/asio/include/asio/detail/reactive_socket_service.hpp view
@@ -2,7 +2,7 @@ // detail/reactive_socket_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -46,7 +46,7 @@ template <typename Protocol> class reactive_socket_service :- public execution_context_service_base<reactive_socket_service<Protocol>>,+ public execution_context_service_base<reactive_socket_service<Protocol> >, public reactive_socket_service_base { public:@@ -76,7 +76,7 @@ // Constructor. reactive_socket_service(execution_context& context) : execution_context_service_base<- reactive_socket_service<Protocol>>(context),+ reactive_socket_service<Protocol> >(context), reactive_socket_service_base(context) { }@@ -89,7 +89,7 @@ // Move-construct a new socket implementation. void move_construct(implementation_type& impl,- implementation_type& other_impl) noexcept+ implementation_type& other_impl) ASIO_NOEXCEPT { this->base_move_construct(impl, other_impl); @@ -284,7 +284,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -307,7 +307,7 @@ &impl, impl.socket_, "async_send_to")); start_op(impl, reactor::write_op, p.p,- is_continuation, true, false, true, &io_ex, 0);+ is_continuation, true, false, &io_ex, 0); p.v = p.p = 0; } @@ -320,7 +320,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -341,7 +341,7 @@ &impl, impl.socket_, "async_send_to(null_buffers)")); start_op(impl, reactor::write_op, p.p,- is_continuation, false, false, false, &io_ex, 0);+ is_continuation, false, false, &io_ex, 0); p.v = p.p = 0; } @@ -406,7 +406,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -432,7 +432,7 @@ start_op(impl, (flags & socket_base::message_out_of_band) ? reactor::except_op : reactor::read_op,- p.p, is_continuation, true, false, true, &io_ex, 0);+ p.p, is_continuation, true, false, &io_ex, 0); p.v = p.p = 0; } @@ -445,7 +445,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -471,7 +471,7 @@ start_op(impl, (flags & socket_base::message_out_of_band) ? reactor::except_op : reactor::read_op,- p.p, is_continuation, false, false, false, &io_ex, 0);+ p.p, is_continuation, false, false, &io_ex, 0); p.v = p.p = 0; } @@ -516,7 +516,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -541,6 +541,7 @@ p.v = p.p = 0; } +#if defined(ASIO_HAS_MOVE) // Start an asynchronous accept. The peer_endpoint object must be valid until // the accept's handler is invoked. template <typename PeerIoExecutor, typename Handler, typename IoExecutor>@@ -551,7 +552,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -576,6 +577,7 @@ start_accept_op(impl, p.p, is_continuation, false, &io_ex, 0); p.v = p.p = 0; }+#endif // defined(ASIO_HAS_MOVE) // Connect the socket to the specified endpoint. asio::error_code connect(implementation_type& impl,@@ -596,7 +598,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.
link/modules/asio-standalone/asio/include/asio/detail/reactive_socket_service_base.hpp view
@@ -2,7 +2,7 @@ // detail/reactive_socket_service_base.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -75,7 +75,7 @@ // Move-construct a new socket implementation. ASIO_DECL void base_move_construct(base_implementation_type& impl,- base_implementation_type& other_impl) noexcept;+ base_implementation_type& other_impl) ASIO_NOEXCEPT; // Move-assign from another socket implementation. ASIO_DECL void base_move_assign(base_implementation_type& impl,@@ -202,7 +202,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -229,7 +229,7 @@ default: p.p->ec_ = asio::error::invalid_argument; start_op(impl, reactor::read_op, p.p,- is_continuation, false, true, false, &io_ex, 0);+ is_continuation, false, true, &io_ex, 0); p.v = p.p = 0; return; }@@ -242,8 +242,7 @@ &reactor_, &impl.reactor_data_, impl.socket_, op_type); } - start_op(impl, op_type, p.p, is_continuation,- false, false, false, &io_ex, 0);+ start_op(impl, op_type, p.p, is_continuation, false, false, &io_ex, 0); p.v = p.p = 0; } @@ -290,7 +289,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -315,7 +314,7 @@ start_op(impl, reactor::write_op, p.p, is_continuation, true, ((impl.state_ & socket_ops::stream_oriented) && buffer_sequence_adapter<asio::const_buffer,- ConstBufferSequence>::all_empty(buffers)), true, &io_ex, 0);+ ConstBufferSequence>::all_empty(buffers)), &io_ex, 0); p.v = p.p = 0; } @@ -327,7 +326,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -348,7 +347,7 @@ &impl, impl.socket_, "async_send(null_buffers)")); start_op(impl, reactor::write_op, p.p,- is_continuation, false, false, false, &io_ex, 0);+ is_continuation, false, false, &io_ex, 0); p.v = p.p = 0; } @@ -396,7 +395,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -425,7 +424,7 @@ (flags & socket_base::message_out_of_band) == 0, ((impl.state_ & socket_ops::stream_oriented) && buffer_sequence_adapter<asio::mutable_buffer,- MutableBufferSequence>::all_empty(buffers)), true, &io_ex, 0);+ MutableBufferSequence>::all_empty(buffers)), &io_ex, 0); p.v = p.p = 0; } @@ -438,7 +437,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -461,7 +460,7 @@ start_op(impl, (flags & socket_base::message_out_of_band) ? reactor::except_op : reactor::read_op,- p.p, is_continuation, false, false, false, &io_ex, 0);+ p.p, is_continuation, false, false, &io_ex, 0); p.v = p.p = 0; } @@ -507,7 +506,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -533,8 +532,7 @@ (in_flags & socket_base::message_out_of_band) ? reactor::except_op : reactor::read_op, p.p, is_continuation,- (in_flags & socket_base::message_out_of_band) == 0,- false, true, &io_ex, 0);+ (in_flags & socket_base::message_out_of_band) == 0, false, &io_ex, 0); p.v = p.p = 0; } @@ -548,7 +546,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -575,7 +573,7 @@ start_op(impl, (in_flags & socket_base::message_out_of_band) ? reactor::except_op : reactor::read_op,- p.p, is_continuation, false, false, false, &io_ex, 0);+ p.p, is_continuation, false, false, &io_ex, 0); p.v = p.p = 0; } @@ -591,9 +589,8 @@ const native_handle_type& native_socket, asio::error_code& ec); // Start the asynchronous read or write operation.- ASIO_DECL void do_start_op(base_implementation_type& impl,- int op_type, reactor_op* op, bool is_continuation,- bool allow_speculative, bool noop, bool needs_non_blocking,+ ASIO_DECL void do_start_op(base_implementation_type& impl, int op_type,+ reactor_op* op, bool is_continuation, bool is_non_blocking, bool noop, void (*on_immediate)(operation* op, bool, const void*), const void* immediate_arg); @@ -601,20 +598,19 @@ // immediate completion. template <typename Op> void start_op(base_implementation_type& impl, int op_type, Op* op,- bool is_continuation, bool allow_speculative, bool noop,- bool needs_non_blocking, const void* io_ex, ...)+ bool is_continuation, bool is_non_blocking, bool noop,+ const void* io_ex, ...) {- return do_start_op(impl, op_type, op, is_continuation, allow_speculative,- noop, needs_non_blocking, &Op::do_immediate, io_ex);+ return do_start_op(impl, op_type, op, is_continuation,+ is_non_blocking, noop, &Op::do_immediate, io_ex); } // Start the asynchronous operation for handlers that are not specialised for // immediate completion. template <typename Op>- void start_op(base_implementation_type& impl, int op_type,- Op* op, bool is_continuation, bool allow_speculative,- bool noop, bool needs_non_blocking, const void*,- enable_if_t<+ void start_op(base_implementation_type& impl, int op_type, Op* op,+ bool is_continuation, bool is_non_blocking, bool noop, const void*,+ typename enable_if< is_same< typename associated_immediate_executor< typename Op::handler_type,@@ -622,11 +618,10 @@ >::asio_associated_immediate_executor_is_unspecialised, void >::value- >*)+ >::type*) {- return do_start_op(impl, op_type, op, is_continuation,- allow_speculative, noop, needs_non_blocking,- &reactor::call_post_immediate_completion, &reactor_);+ return do_start_op(impl, op_type, op, is_continuation, is_non_blocking,+ noop, &reactor::call_post_immediate_completion, &reactor_); } // Start the asynchronous accept operation.@@ -650,7 +645,7 @@ template <typename Op> void start_accept_op(base_implementation_type& impl, Op* op, bool is_continuation, bool peer_is_open, const void*,- enable_if_t<+ typename enable_if< is_same< typename associated_immediate_executor< typename Op::handler_type,@@ -658,7 +653,7 @@ >::asio_associated_immediate_executor_is_unspecialised, void >::value- >*)+ >::type*) { return do_start_accept_op(impl, op, is_continuation, peer_is_open, &reactor::call_post_immediate_completion, &reactor_);@@ -686,7 +681,7 @@ template <typename Op> void start_connect_op(base_implementation_type& impl, Op* op, bool is_continuation, const void* addr, size_t addrlen, const void*,- enable_if_t<+ typename enable_if< is_same< typename associated_immediate_executor< typename Op::handler_type,@@ -694,7 +689,7 @@ >::asio_associated_immediate_executor_is_unspecialised, void >::value- >*)+ >::type*) { return do_start_connect_op(impl, op, is_continuation, addr, addrlen, &reactor::call_post_immediate_completion, &reactor_);@@ -705,7 +700,7 @@ { public: reactor_op_cancellation(reactor* r,- reactor::per_descriptor_data* p, socket_type d, int o)+ reactor::per_descriptor_data* p, int d, int o) : reactor_(r), reactor_data_(p), descriptor_(d),@@ -728,7 +723,7 @@ private: reactor* reactor_; reactor::per_descriptor_data* reactor_data_;- socket_type descriptor_;+ int descriptor_; int op_type_; };
link/modules/asio-standalone/asio/include/asio/detail/reactive_wait_op.hpp view
@@ -2,7 +2,7 @@ // detail/reactive_wait_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -19,6 +19,7 @@ #include "asio/detail/bind_handler.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/reactor_op.hpp"@@ -41,7 +42,7 @@ Handler& handler, const IoExecutor& io_ex) : reactor_op(success_ec, &reactive_wait_op::do_perform, &reactive_wait_op::do_complete),- handler_(static_cast<Handler&&>(handler)),+ handler_(ASIO_MOVE_CAST(Handler)(handler)), work_(handler_, io_ex) { }@@ -64,7 +65,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); // Make a copy of the handler so that the memory can be deallocated before@@ -99,7 +100,7 @@ // Take ownership of the operation's outstanding work. immediate_handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); // Make a copy of the handler so that the memory can be deallocated before
link/modules/asio-standalone/asio/include/asio/detail/reactor.hpp view
@@ -2,7 +2,7 @@ // detail/reactor.hpp // ~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/reactor_op.hpp view
@@ -2,7 +2,7 @@ // detail/reactor_op.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/reactor_op_queue.hpp view
@@ -2,7 +2,7 @@ // detail/reactor_op_queue.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/recycling_allocator.hpp view
@@ -2,7 +2,7 @@ // detail/recycling_allocator.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -48,25 +48,16 @@ T* allocate(std::size_t n) {-#if !defined(ASIO_DISABLE_SMALL_BLOCK_RECYCLING) void* p = thread_info_base::allocate(Purpose(), thread_context::top_of_thread_call_stack(),- sizeof(T) * n, alignof(T));-#else // !defined(ASIO_DISABLE_SMALL_BLOCK_RECYCLING)- void* p = asio::aligned_new(alignof(T), sizeof(T) * n);-#endif // !defined(ASIO_DISABLE_SMALL_BLOCK_RECYCLING)+ sizeof(T) * n, ASIO_ALIGNOF(T)); return static_cast<T*>(p); } void deallocate(T* p, std::size_t n) {-#if !defined(ASIO_DISABLE_SMALL_BLOCK_RECYCLING) thread_info_base::deallocate(Purpose(), thread_context::top_of_thread_call_stack(), p, sizeof(T) * n);-#else // !defined(ASIO_DISABLE_SMALL_BLOCK_RECYCLING)- (void)n;- asio::aligned_delete(p);-#endif // !defined(ASIO_DISABLE_SMALL_BLOCK_RECYCLING) } };
link/modules/asio-standalone/asio/include/asio/detail/regex_fwd.hpp view
@@ -2,7 +2,7 @@ // detail/regex_fwd.hpp // ~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -17,6 +17,18 @@ #if defined(ASIO_HAS_BOOST_REGEX) +#include <boost/regex_fwd.hpp>+#include <boost/version.hpp>+#if BOOST_VERSION >= 107600+# if defined(BOOST_REGEX_CXX03)+# include <boost/regex/v4/match_flags.hpp>+# else // defined(BOOST_REGEX_CXX03)+# include <boost/regex/v5/match_flags.hpp>+# endif // defined(BOOST_REGEX_CXX03)+#else // BOOST_VERSION >= 107600+# include <boost/regex/v4/match_flags.hpp>+#endif // BOOST_VERSION >= 107600+ namespace boost { template <class BidiIterator>@@ -24,9 +36,6 @@ template <class BidiIterator, class Allocator> class match_results;--template <class CharT, class Traits>-class basic_regex; } // namespace boost
link/modules/asio-standalone/asio/include/asio/detail/resolve_endpoint_op.hpp view
@@ -2,7 +2,7 @@ // detail/resolve_endpoint_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -19,6 +19,7 @@ #include "asio/detail/bind_handler.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/resolve_op.hpp"@@ -59,7 +60,7 @@ cancel_token_(cancel_token), endpoint_(endpoint), scheduler_(sched),- handler_(static_cast<Handler&&>(handler)),+ handler_(ASIO_MOVE_CAST(Handler)(handler)), work_(handler_, io_ex) { }@@ -77,7 +78,7 @@ { // The operation is being run on the worker io_context. Time to perform // the resolver operation.-+ // Perform the blocking endpoint resolution operation. char host_name[NI_MAXHOST] = ""; char service_name[NI_MAXSERV] = "";@@ -99,7 +100,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); // Make a copy of the handler so that the memory can be deallocated
link/modules/asio-standalone/asio/include/asio/detail/resolve_op.hpp view
@@ -2,7 +2,7 @@ // detail/resolve_op.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/resolve_query_op.hpp view
@@ -2,7 +2,7 @@ // detail/resolve_query_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -19,6 +19,7 @@ #include "asio/detail/bind_handler.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/resolve_op.hpp"@@ -60,7 +61,7 @@ cancel_token_(cancel_token), query_(qry), scheduler_(sched),- handler_(static_cast<Handler&&>(handler)),+ handler_(ASIO_MOVE_CAST(Handler)(handler)), work_(handler_, io_ex), addrinfo_(0) {@@ -85,7 +86,7 @@ { // The operation is being run on the worker io_context. Time to perform // the resolver operation.-+ // Perform the blocking host resolution operation. socket_ops::background_getaddrinfo(o->cancel_token_, o->query_.host_name().c_str(), o->query_.service_name().c_str(),@@ -104,7 +105,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); // Make a copy of the handler so that the memory can be deallocated
link/modules/asio-standalone/asio/include/asio/detail/resolver_service.hpp view
@@ -2,7 +2,7 @@ // detail/resolver_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -21,6 +21,7 @@ #include "asio/ip/basic_resolver_query.hpp" #include "asio/ip/basic_resolver_results.hpp"+#include "asio/detail/concurrency_hint.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/resolve_endpoint_op.hpp" #include "asio/detail/resolve_query_op.hpp"@@ -33,7 +34,7 @@ template <typename Protocol> class resolver_service :- public execution_context_service_base<resolver_service<Protocol>>,+ public execution_context_service_base<resolver_service<Protocol> >, public resolver_service_base { public:@@ -52,7 +53,7 @@ // Constructor. resolver_service(execution_context& context)- : execution_context_service_base<resolver_service<Protocol>>(context),+ : execution_context_service_base<resolver_service<Protocol> >(context), resolver_service_base(context) { }@@ -60,8 +61,15 @@ // Destroy all user-defined handler objects owned by the service. void shutdown() {+ this->base_shutdown(); } + // Perform any fork-related housekeeping.+ void notify_fork(execution_context::fork_event fork_ev)+ {+ this->base_notify_fork(fork_ev);+ }+ // Resolve a query to a list of entries. results_type resolve(implementation_type&, const query_type& qry, asio::error_code& ec)@@ -86,12 +94,12 @@ typedef resolve_query_op<Protocol, Handler, IoExecutor> op; typename op::ptr p = { asio::detail::addressof(handler), op::ptr::allocate(handler), 0 };- p.p = new (p.v) op(impl, qry, thread_pool_.scheduler(), handler, io_ex);+ p.p = new (p.v) op(impl, qry, scheduler_, handler, io_ex); - ASIO_HANDLER_CREATION((thread_pool_.context(),+ ASIO_HANDLER_CREATION((scheduler_.context(), *p.p, "resolver", &impl, 0, "async_resolve")); - thread_pool_.start_resolve_op(p.p);+ start_resolve_op(p.p); p.v = p.p = 0; } @@ -119,13 +127,12 @@ typedef resolve_endpoint_op<Protocol, Handler, IoExecutor> op; typename op::ptr p = { asio::detail::addressof(handler), op::ptr::allocate(handler), 0 };- p.p = new (p.v) op(impl, endpoint,- thread_pool_.scheduler(), handler, io_ex);+ p.p = new (p.v) op(impl, endpoint, scheduler_, handler, io_ex); - ASIO_HANDLER_CREATION((thread_pool_.context(),+ ASIO_HANDLER_CREATION((scheduler_.context(), *p.p, "resolver", &impl, 0, "async_resolve")); - thread_pool_.start_resolve_op(p.p);+ start_resolve_op(p.p); p.v = p.p = 0; } };
link/modules/asio-standalone/asio/include/asio/detail/resolver_service_base.hpp view
@@ -2,7 +2,7 @@ // detail/resolver_service_base.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -18,11 +18,13 @@ #include "asio/detail/config.hpp" #include "asio/error.hpp" #include "asio/execution_context.hpp"+#include "asio/detail/mutex.hpp" #include "asio/detail/noncopyable.hpp" #include "asio/detail/resolve_op.hpp"-#include "asio/detail/resolver_thread_pool.hpp" #include "asio/detail/socket_ops.hpp" #include "asio/detail/socket_types.hpp"+#include "asio/detail/scoped_ptr.hpp"+#include "asio/detail/thread.hpp" #if defined(ASIO_HAS_IOCP) # include "asio/detail/win_iocp_io_context.hpp"@@ -48,6 +50,13 @@ // Destructor. ASIO_DECL ~resolver_service_base(); + // Destroy all user-defined handler objects owned by the service.+ ASIO_DECL void base_shutdown();++ // Perform any fork-related housekeeping.+ ASIO_DECL void base_notify_fork(+ execution_context::fork_event fork_ev);+ // Construct a new resolver implementation. ASIO_DECL void construct(implementation_type& impl); @@ -82,6 +91,9 @@ ASIO_DECL void cancel(implementation_type& impl); protected:+ // Helper function to start an asynchronous resolve operation.+ ASIO_DECL void start_resolve_op(resolve_op* op);+ #if !defined(ASIO_WINDOWS_RUNTIME) // Helper class to perform exception-safe cleanup of addrinfo objects. class auto_addrinfo@@ -109,8 +121,29 @@ }; #endif // !defined(ASIO_WINDOWS_RUNTIME) - // Private thread pool used for performing asynchronous host resolution.- resolver_thread_pool& thread_pool_;+ // Helper class to run the work scheduler in a thread.+ class work_scheduler_runner;++ // Start the work scheduler if it's not already running.+ ASIO_DECL void start_work_thread();++ // The scheduler implementation used to post completions.+#if defined(ASIO_HAS_IOCP)+ typedef class win_iocp_io_context scheduler_impl;+#else+ typedef class scheduler scheduler_impl;+#endif+ scheduler_impl& scheduler_;++private:+ // Mutex to protect access to internal data.+ asio::detail::mutex mutex_;++ // Private scheduler used for performing asynchronous host resolution.+ asio::detail::scoped_ptr<scheduler_impl> work_scheduler_;++ // Thread used for running the work io_context's run loop.+ asio::detail::scoped_ptr<asio::detail::thread> work_thread_; }; } // namespace detail
− link/modules/asio-standalone/asio/include/asio/detail/resolver_thread_pool.hpp
@@ -1,105 +0,0 @@-//-// detail/resolver_thread_pool.hpp-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef ASIO_DETAIL_RESOLVER_THREAD_POOL_HPP-#define ASIO_DETAIL_RESOLVER_THREAD_POOL_HPP--#if defined(_MSC_VER) && (_MSC_VER >= 1200)-# pragma once-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)--#include "asio/detail/config.hpp"-#include "asio/execution_context.hpp"-#include "asio/detail/mutex.hpp"-#include "asio/detail/resolve_op.hpp"-#include "asio/detail/scheduler.hpp"-#include "asio/detail/thread_group.hpp"--#if defined(ASIO_HAS_IOCP)-# include "asio/detail/win_iocp_io_context.hpp"-#else // defined(ASIO_HAS_IOCP)-# include "asio/detail/scheduler.hpp"-#endif // defined(ASIO_HAS_IOCP)--#include "asio/detail/push_options.hpp"--namespace asio {-namespace detail {--class resolver_thread_pool :- public execution_context_service_base<resolver_thread_pool>-{-public:-#if defined(ASIO_HAS_IOCP)- typedef class win_iocp_io_context scheduler_impl;-#else- typedef class scheduler scheduler_impl;-#endif-- // Constructor.- ASIO_DECL resolver_thread_pool(execution_context& context);-- // Destructor.- ASIO_DECL ~resolver_thread_pool();-- // Destroy all user-defined handler objects owned by the service.- ASIO_DECL void shutdown();-- // Perform any fork-related housekeeping.- ASIO_DECL void notify_fork(execution_context::fork_event fork_ev);-- // Helper function to start an asynchronous resolve operation.- ASIO_DECL void start_resolve_op(resolve_op* op);-- // Get the underlying scheduler implementation.- scheduler_impl& scheduler()- {- return scheduler_;- }--private:- // Helper class to run the work scheduler in a thread.- class work_scheduler_runner;-- // Start the work scheduler if it's not already running.- ASIO_DECL void start_work_threads();-- // The scheduler implementation used to post completions.- scheduler_impl& scheduler_;-- // Mutex to protect access to internal data.- asio::detail::mutex mutex_;-- // Private scheduler used for performing asynchronous host resolution.- scheduler_impl work_scheduler_;-- // Threads used for running the work scheduler's run loop.- thread_group<execution_context::allocator<void>> work_threads_;-- // The number of threads used to run the work scheduler.- unsigned int num_work_threads_;-- // Whether the scheduler locking is enabled.- bool scheduler_locking_;-- // Whether the scheduler has been shut down.- bool shutdown_;-};--} // namespace detail-} // namespace asio--#include "asio/detail/pop_options.hpp"--#if defined(ASIO_HEADER_ONLY)-# include "asio/detail/impl/resolver_thread_pool.ipp"-#endif // defined(ASIO_HEADER_ONLY)--#endif // ASIO_DETAIL_RESOLVER_THREAD_POOL_HPP
link/modules/asio-standalone/asio/include/asio/detail/scheduler.hpp view
@@ -2,7 +2,7 @@ // detail/scheduler.hpp // ~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -42,21 +42,16 @@ public: typedef scheduler_operation operation; - // Tag type used for constructing as an internal scheduler.- struct internal {};- // The type of a function used to obtain a task instance. typedef scheduler_task* (*get_task_func_type)( asio::execution_context&); - // Constructor.+ // Constructor. Specifies the number of concurrent threads that are likely to+ // run the scheduler. If set to 1 certain optimisation are performed. ASIO_DECL scheduler(asio::execution_context& ctx,- bool own_thread = true,+ int concurrency_hint = 0, bool own_thread = true, get_task_func_type get_task = &scheduler::get_default_task); - // Construct as an internal scheduler.- ASIO_DECL scheduler(internal, asio::execution_context& ctx);- // Destructor. ASIO_DECL ~scheduler(); @@ -140,6 +135,12 @@ // work_started() was previously called for the operations. ASIO_DECL void abandon_operations(op_queue<operation>& ops); + // Get the concurrency hint that was used to initialise the scheduler.+ int concurrency_hint() const+ {+ return concurrency_hint_;+ }+ private: // The mutex type used by this scheduler. typedef conditionally_enabled_mutex mutex;@@ -209,26 +210,23 @@ // Whether the task has been interrupted. bool task_interrupted_; - // Flag to indicate that the dispatcher has been stopped.- bool stopped_;-- // Flag to indicate that the dispatcher has been shut down.- bool shutdown_;- // The count of unfinished work. atomic_count outstanding_work_; // The queue of handlers that are ready to be delivered. op_queue<operation> op_queue_; - // The time limit on running the scheduler task, in microseconds.- const long task_usec_;+ // Flag to indicate that the dispatcher has been stopped.+ bool stopped_; - // The time limit on waiting when the queue is empty, in microseconds.- const long wait_usec_;+ // Flag to indicate that the dispatcher has been shut down.+ bool shutdown_; + // The concurrency hint used to initialise the scheduler.+ const int concurrency_hint_;+ // The thread that is running the scheduler.- asio::detail::thread thread_;+ asio::detail::thread* thread_; }; } // namespace detail
link/modules/asio-standalone/asio/include/asio/detail/scheduler_operation.hpp view
@@ -2,7 +2,7 @@ // detail/scheduler_operation.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/scheduler_task.hpp view
@@ -2,7 +2,7 @@ // detail/scheduler_task.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/scheduler_thread_info.hpp view
@@ -2,7 +2,7 @@ // detail/scheduler_thread_info.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/scoped_lock.hpp view
@@ -2,7 +2,7 @@ // detail/scoped_lock.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/scoped_ptr.hpp view
@@ -2,7 +2,7 @@ // detail/scoped_ptr.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/select_interrupter.hpp view
@@ -2,7 +2,7 @@ // detail/select_interrupter.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/select_reactor.hpp view
@@ -2,7 +2,7 @@ // detail/select_reactor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -152,39 +152,38 @@ per_descriptor_data& source_descriptor_data); // Add a new timer queue to the reactor.- template <typename TimeTraits, typename Allocator>- void add_timer_queue(timer_queue<TimeTraits, Allocator>& queue);+ template <typename Time_Traits>+ void add_timer_queue(timer_queue<Time_Traits>& queue); // Remove a timer queue from the reactor.- template <typename TimeTraits, typename Allocator>- void remove_timer_queue(timer_queue<TimeTraits, Allocator>& queue);+ template <typename Time_Traits>+ void remove_timer_queue(timer_queue<Time_Traits>& queue); // Schedule a new operation in the given timer queue to expire at the // specified absolute time.- template <typename TimeTraits, typename Allocator>- void schedule_timer(timer_queue<TimeTraits, Allocator>& queue,- const typename TimeTraits::time_type& time,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,- wait_op* op);+ template <typename Time_Traits>+ void schedule_timer(timer_queue<Time_Traits>& queue,+ const typename Time_Traits::time_type& time,+ typename timer_queue<Time_Traits>::per_timer_data& timer, wait_op* op); // Cancel the timer operations associated with the given token. Returns the // number of operations that have been posted or dispatched.- template <typename TimeTraits, typename Allocator>- std::size_t cancel_timer(timer_queue<TimeTraits, Allocator>& queue,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,+ template <typename Time_Traits>+ std::size_t cancel_timer(timer_queue<Time_Traits>& queue,+ typename timer_queue<Time_Traits>::per_timer_data& timer, std::size_t max_cancelled = (std::numeric_limits<std::size_t>::max)()); // Cancel the timer operations associated with the given key.- template <typename TimeTraits, typename Allocator>- void cancel_timer_by_key(timer_queue<TimeTraits, Allocator>& queue,- typename timer_queue<TimeTraits, Allocator>::per_timer_data* timer,+ template <typename Time_Traits>+ void cancel_timer_by_key(timer_queue<Time_Traits>& queue,+ typename timer_queue<Time_Traits>::per_timer_data* timer, void* cancellation_key); // Move the timer operations associated with the given timer.- template <typename TimeTraits, typename Allocator>- void move_timer(timer_queue<TimeTraits, Allocator>& queue,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& target,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& source);+ template <typename Time_Traits>+ void move_timer(timer_queue<Time_Traits>& queue,+ typename timer_queue<Time_Traits>::per_timer_data& target,+ typename timer_queue<Time_Traits>::per_timer_data& source); // Run select once until interrupted or events are ready to be dispatched. ASIO_DECL void run(long usec, op_queue<operation>& ops);@@ -244,7 +243,7 @@ bool stop_thread_; // The thread that is running the reactor loop.- asio::detail::thread thread_;+ asio::detail::thread* thread_; // Helper class to join and restart the reactor thread. class restart_reactor : public operation
link/modules/asio-standalone/asio/include/asio/detail/service_registry.hpp view
@@ -2,7 +2,7 @@ // detail/service_registry.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -66,10 +66,6 @@ template <typename Service> Service& use_service(io_context& owner); - // Create and add a service object.- template <typename Service, typename... Args>- Service& make_service(Args&&... args);- // Add a service object. Throws on error, in which case ownership of the // object is retained by the caller. template <typename Service>@@ -80,15 +76,16 @@ bool has_service() const; private:- // Initialise a service's key when the key_type typedef is not available.+ // Initalise a service's key when the key_type typedef is not available. template <typename Service> static void init_key(execution_context::service::key& key, ...); #if !defined(ASIO_NO_TYPEID)- // Initialise a service's key when the key_type typedef is available.+ // Initalise a service's key when the key_type typedef is available. template <typename Service> static void init_key(execution_context::service::key& key,- enable_if_t<is_base_of<typename Service::key_type, Service>::value>*);+ typename enable_if<+ is_base_of<typename Service::key_type, Service>::value>::type*); #endif // !defined(ASIO_NO_TYPEID) // Initialise a service's key based on its id.@@ -109,20 +106,14 @@ const execution_context::service::key& key2); // The type of a factory function used for creating a service instance.- typedef execution_context::service*(*factory_type)(execution_context&, void*);+ typedef execution_context::service*(*factory_type)(void*); // Factory function for creating a service instance.- template <typename Service, typename Owner, typename... Args>- static execution_context::service* create(- execution_context& context, void* owner, Args&&... args);-- // Helper function to destroy an allocated service instance.- template <typename Service>- static void destroy_allocated(execution_context::service* service);+ template <typename Service, typename Owner>+ static execution_context::service* create(void* owner); - // Helper function to destroy an added service instance.- ASIO_DECL static void destroy_added(- execution_context::service* service);+ // Destroy a service instance.+ ASIO_DECL static void destroy(execution_context::service* service); // Helper class to manage service pointers. struct auto_service_ptr;@@ -130,7 +121,7 @@ struct auto_service_ptr { execution_context::service* ptr_;- ASIO_DECL ~auto_service_ptr();+ ~auto_service_ptr() { destroy(ptr_); } }; // Get the service object corresponding to the specified service key. Will
link/modules/asio-standalone/asio/include/asio/detail/signal_blocker.hpp view
@@ -2,7 +2,7 @@ // detail/signal_blocker.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/signal_handler.hpp view
@@ -2,7 +2,7 @@ // detail/signal_handler.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -36,7 +36,7 @@ signal_handler(Handler& h, const IoExecutor& io_ex) : signal_op(&signal_handler::do_complete),- handler_(static_cast<Handler&&>(h)),+ handler_(ASIO_MOVE_CAST(Handler)(h)), work_(handler_, io_ex) { }@@ -53,7 +53,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( h->work_)); // Make a copy of the handler so that the memory can be deallocated before
link/modules/asio-standalone/asio/include/asio/detail/signal_init.hpp view
@@ -2,7 +2,7 @@ // detail/signal_init.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/signal_op.hpp view
@@ -2,7 +2,7 @@ // detail/signal_op.hpp // ~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/signal_set_service.hpp view
@@ -2,7 +2,7 @@ // detail/signal_set_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -173,7 +173,7 @@ void async_wait(implementation_type& impl, Handler& handler, const IoExecutor& io_ex) {- associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.
link/modules/asio-standalone/asio/include/asio/detail/socket_holder.hpp view
@@ -2,7 +2,7 @@ // detail/socket_holder.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/socket_ops.hpp view
@@ -2,7 +2,7 @@ // detail/socket_ops.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/socket_option.hpp view
@@ -2,7 +2,7 @@ // detail/socket_option.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/socket_select_interrupter.hpp view
@@ -2,7 +2,7 @@ // detail/socket_select_interrupter.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/socket_types.hpp view
@@ -2,7 +2,7 @@ // detail/socket_types.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -413,11 +413,7 @@ # endif # define ASIO_OS_DEF_SA_RESTART SA_RESTART # define ASIO_OS_DEF_SA_NOCLDSTOP SA_NOCLDSTOP-# if defined(SA_NOCLDWAIT)-# define ASIO_OS_DEF_SA_NOCLDWAIT SA_NOCLDWAIT-# else // defined(SA_NOCLDWAIT)-# define ASIO_OS_DEF_SA_NOCLDWAIT 0-# endif // defined(SA_NOCLDWAIT)+# define ASIO_OS_DEF_SA_NOCLDWAIT SA_NOCLDWAIT #endif const int custom_socket_option_level = 0xA5100000; const int enable_connection_aborted_option = 1;
+ link/modules/asio-standalone/asio/include/asio/detail/solaris_fenced_block.hpp view
@@ -0,0 +1,62 @@+//+// detail/solaris_fenced_block.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_DETAIL_SOLARIS_FENCED_BLOCK_HPP+#define ASIO_DETAIL_SOLARIS_FENCED_BLOCK_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"++#if defined(__sun)++#include <atomic.h>+#include "asio/detail/noncopyable.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {+namespace detail {++class solaris_fenced_block+ : private noncopyable+{+public:+ enum half_t { half };+ enum full_t { full };++ // Constructor for a half fenced block.+ explicit solaris_fenced_block(half_t)+ {+ }++ // Constructor for a full fenced block.+ explicit solaris_fenced_block(full_t)+ {+ membar_consumer();+ }++ // Destructor.+ ~solaris_fenced_block()+ {+ membar_producer();+ }+};++} // namespace detail+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // defined(__sun)++#endif // ASIO_DETAIL_SOLARIS_FENCED_BLOCK_HPP
link/modules/asio-standalone/asio/include/asio/detail/source_location.hpp view
@@ -2,7 +2,7 @@ // detail/source_location.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/static_mutex.hpp view
@@ -2,7 +2,7 @@ // detail/static_mutex.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -23,8 +23,10 @@ # include "asio/detail/win_static_mutex.hpp" #elif defined(ASIO_HAS_PTHREADS) # include "asio/detail/posix_static_mutex.hpp"-#else+#elif defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR) # include "asio/detail/std_static_mutex.hpp"+#else+# error Only Windows and POSIX are supported! #endif namespace asio {@@ -39,7 +41,7 @@ #elif defined(ASIO_HAS_PTHREADS) typedef posix_static_mutex static_mutex; # define ASIO_STATIC_MUTEX_INIT ASIO_POSIX_STATIC_MUTEX_INIT-#else+#elif defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR) typedef std_static_mutex static_mutex; # define ASIO_STATIC_MUTEX_INIT ASIO_STD_STATIC_MUTEX_INIT #endif
link/modules/asio-standalone/asio/include/asio/detail/std_event.hpp view
@@ -2,7 +2,7 @@ // detail/std_event.hpp // ~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -16,6 +16,9 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"++#if defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR)+ #include <chrono> #include <condition_variable> #include "asio/detail/assert.hpp"@@ -179,5 +182,7 @@ } // namespace asio #include "asio/detail/pop_options.hpp"++#endif // defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR) #endif // ASIO_DETAIL_STD_EVENT_HPP
link/modules/asio-standalone/asio/include/asio/detail/std_fenced_block.hpp view
@@ -2,7 +2,7 @@ // detail/std_fenced_block.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -16,6 +16,9 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"++#if defined(ASIO_HAS_STD_ATOMIC)+ #include <atomic> #include "asio/detail/noncopyable.hpp" @@ -53,5 +56,7 @@ } // namespace asio #include "asio/detail/pop_options.hpp"++#endif // defined(ASIO_HAS_STD_ATOMIC) #endif // ASIO_DETAIL_STD_FENCED_BLOCK_HPP
link/modules/asio-standalone/asio/include/asio/detail/std_global.hpp view
@@ -2,7 +2,7 @@ // detail/std_global.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -16,6 +16,9 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"++#if defined(ASIO_HAS_STD_CALL_ONCE)+ #include <exception> #include <mutex> @@ -61,5 +64,7 @@ } // namespace asio #include "asio/detail/pop_options.hpp"++#endif // defined(ASIO_HAS_STD_CALL_ONCE) #endif // ASIO_DETAIL_STD_GLOBAL_HPP
link/modules/asio-standalone/asio/include/asio/detail/std_mutex.hpp view
@@ -2,7 +2,7 @@ // detail/std_mutex.hpp // ~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -16,6 +16,9 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"++#if defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR)+ #include <mutex> #include "asio/detail/noncopyable.hpp" #include "asio/detail/scoped_lock.hpp"@@ -43,12 +46,6 @@ { } - // Try to lock the mutex.- bool try_lock()- {- return mutex_.try_lock();- }- // Lock the mutex. void lock() {@@ -70,5 +67,7 @@ } // namespace asio #include "asio/detail/pop_options.hpp"++#endif // defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR) #endif // ASIO_DETAIL_STD_MUTEX_HPP
link/modules/asio-standalone/asio/include/asio/detail/std_static_mutex.hpp view
@@ -2,7 +2,7 @@ // detail/std_static_mutex.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -16,6 +16,9 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"++#if defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR)+ #include <mutex> #include "asio/detail/noncopyable.hpp" #include "asio/detail/scoped_lock.hpp"@@ -72,5 +75,7 @@ } // namespace asio #include "asio/detail/pop_options.hpp"++#endif // defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR) #endif // ASIO_DETAIL_STD_STATIC_MUTEX_HPP
link/modules/asio-standalone/asio/include/asio/detail/std_thread.hpp view
@@ -2,7 +2,7 @@ // detail/std_thread.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -16,8 +16,11 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"++#if defined(ASIO_HAS_STD_THREAD)+ #include <thread>-#include "asio/detail/memory.hpp"+#include "asio/detail/noncopyable.hpp" #include "asio/detail/push_options.hpp" @@ -25,14 +28,9 @@ namespace detail { class std_thread+ : private noncopyable { public:- // Construct in a non-joinable state.- std_thread() noexcept- : thread_()- {- }- // Constructor. template <typename Function> std_thread(Function f, unsigned int = 0)@@ -40,35 +38,10 @@ { } - // Construct with custom allocator.- template <typename Allocator, typename Function>- std_thread(allocator_arg_t, const Allocator&, Function f, unsigned int = 0)- : thread_(f)- {- }-- // Move constructor.- std_thread(std_thread&& other) noexcept- : thread_(static_cast<std::thread&&>(other.thread_))- {- }- // Destructor. ~std_thread() {- }-- // Move assignment.- std_thread& operator=(std_thread&& other) noexcept- {- thread_ = static_cast<std::thread&&>(other.thread_);- return *this;- }-- // Whether the thread can be joined.- bool joinable() const- {- return thread_.joinable();+ join(); } // Wait for the thread to exit.@@ -92,5 +65,7 @@ } // namespace asio #include "asio/detail/pop_options.hpp"++#endif // defined(ASIO_HAS_STD_THREAD) #endif // ASIO_DETAIL_STD_THREAD_HPP
link/modules/asio-standalone/asio/include/asio/detail/strand_executor_service.hpp view
@@ -2,7 +2,7 @@ // detail/strand_executor_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -22,6 +22,7 @@ #include "asio/detail/mutex.hpp" #include "asio/detail/op_queue.hpp" #include "asio/detail/scheduler_operation.hpp"+#include "asio/detail/scoped_ptr.hpp" #include "asio/detail/type_traits.hpp" #include "asio/execution.hpp" #include "asio/execution_context.hpp"@@ -89,33 +90,33 @@ // Request invocation of the given function. template <typename Executor, typename Function> static void execute(const implementation_type& impl, Executor& ex,- Function&& function,- enable_if_t<- can_query<Executor, execution::allocator_t<void>>::value- >* = 0);+ ASIO_MOVE_ARG(Function) function,+ typename enable_if<+ can_query<Executor, execution::allocator_t<void> >::value+ >::type* = 0); // Request invocation of the given function. template <typename Executor, typename Function> static void execute(const implementation_type& impl, Executor& ex,- Function&& function,- enable_if_t<- !can_query<Executor, execution::allocator_t<void>>::value- >* = 0);+ ASIO_MOVE_ARG(Function) function,+ typename enable_if<+ !can_query<Executor, execution::allocator_t<void> >::value+ >::type* = 0); // Request invocation of the given function. template <typename Executor, typename Function, typename Allocator> static void dispatch(const implementation_type& impl, Executor& ex,- Function&& function, const Allocator& a);+ ASIO_MOVE_ARG(Function) function, const Allocator& a); // Request invocation of the given function and return immediately. template <typename Executor, typename Function, typename Allocator> static void post(const implementation_type& impl, Executor& ex,- Function&& function, const Allocator& a);+ ASIO_MOVE_ARG(Function) function, const Allocator& a); // Request invocation of the given function and return immediately. template <typename Executor, typename Function, typename Allocator> static void defer(const implementation_type& impl, Executor& ex,- Function&& function, const Allocator& a);+ ASIO_MOVE_ARG(Function) function, const Allocator& a); // Determine whether the strand is running in the current thread. ASIO_DECL static bool running_in_this_thread(@@ -140,7 +141,7 @@ // Helper function to request invocation of the given function. template <typename Executor, typename Function, typename Allocator> static void do_execute(const implementation_type& impl, Executor& ex,- Function&& function, const Allocator& a);+ ASIO_MOVE_ARG(Function) function, const Allocator& a); // Mutex to protect access to the service-wide state. mutex mutex_;@@ -149,7 +150,7 @@ enum { num_mutexes = 193 }; // Pool of mutexes.- shared_ptr<mutex> mutexes_[num_mutexes];+ scoped_ptr<mutex> mutexes_[num_mutexes]; // Extra value used when hashing to prevent recycled memory locations from // getting the same mutex.
link/modules/asio-standalone/asio/include/asio/detail/strand_service.hpp view
@@ -2,7 +2,7 @@ // detail/strand_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -20,6 +20,7 @@ #include "asio/detail/mutex.hpp" #include "asio/detail/op_queue.hpp" #include "asio/detail/operation.hpp"+#include "asio/detail/scoped_ptr.hpp" #include "asio/detail/push_options.hpp" @@ -123,7 +124,7 @@ #endif // defined(ASIO_STRAND_IMPLEMENTATIONS) // Pool of implementations.- shared_ptr<strand_impl> implementations_[num_implementations];+ scoped_ptr<strand_impl> implementations_[num_implementations]; // Extra value used when hashing to prevent recycled memory locations from // getting the same strand implementation.
link/modules/asio-standalone/asio/include/asio/detail/string_view.hpp view
@@ -2,7 +2,7 @@ // detail/string_view.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/thread.hpp view
@@ -2,7 +2,7 @@ // detail/thread.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -29,8 +29,10 @@ # else # include "asio/detail/win_thread.hpp" # endif-#else+#elif defined(ASIO_HAS_STD_THREAD) # include "asio/detail/std_thread.hpp"+#else+# error Only Windows, POSIX and std::thread are supported! #endif namespace asio {@@ -48,7 +50,7 @@ # else typedef win_thread thread; # endif-#else+#elif defined(ASIO_HAS_STD_THREAD) typedef std_thread thread; #endif
link/modules/asio-standalone/asio/include/asio/detail/thread_context.hpp view
@@ -2,7 +2,7 @@ // detail/thread_context.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/thread_group.hpp view
@@ -2,7 +2,7 @@ // detail/thread_group.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -16,7 +16,7 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"-#include "asio/detail/memory.hpp"+#include "asio/detail/scoped_ptr.hpp" #include "asio/detail/thread.hpp" #include "asio/detail/push_options.hpp"@@ -24,14 +24,12 @@ namespace asio { namespace detail { -template <typename Allocator> class thread_group { public: // Constructor initialises an empty thread group.- explicit thread_group(const Allocator& a)- : allocator_(a),- first_(0)+ thread_group()+ : first_(0) { } @@ -45,7 +43,7 @@ template <typename Function> void create_thread(Function f) {- first_ = allocate_object<item>(allocator_, allocator_, f, first_);+ first_ = new item(f, first_); } // Create new threads in the group.@@ -64,7 +62,7 @@ first_->thread_.join(); item* tmp = first_; first_ = first_->next_;- deallocate_object(allocator_, tmp);+ delete tmp; } } @@ -79,8 +77,8 @@ struct item { template <typename Function>- explicit item(const Allocator& a, Function f, item* next)- : thread_(std::allocator_arg, a, f),+ explicit item(Function f, item* next)+ : thread_(f), next_(next) { }@@ -88,9 +86,6 @@ asio::detail::thread thread_; item* next_; };-- // The allocator to be used to create items in the group.- Allocator allocator_; // The first thread in the group. item* first_;
link/modules/asio-standalone/asio/include/asio/detail/thread_info_base.hpp view
@@ -2,7 +2,7 @@ // detail/thread_info_base.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -21,10 +21,12 @@ #include "asio/detail/memory.hpp" #include "asio/detail/noncopyable.hpp" -#if !defined(ASIO_NO_EXCEPTIONS)+#if defined(ASIO_HAS_STD_EXCEPTION_PTR) \+ && !defined(ASIO_NO_EXCEPTIONS) # include <exception> # include "asio/multiple_exceptions.hpp"-#endif // !defined(ASIO_NO_EXCEPTIONS)+#endif // defined(ASIO_HAS_STD_EXCEPTION_PTR)+ // && !defined(ASIO_NO_EXCEPTIONS) #include "asio/detail/push_options.hpp" @@ -89,22 +91,14 @@ }; }; - struct timed_cancel_tag- {- enum- {- cache_size = ASIO_RECYCLING_ALLOCATOR_CACHE_SIZE,- begin_mem_index = parallel_group_tag::end_mem_index,- end_mem_index = begin_mem_index + cache_size- };- };-- enum { max_mem_index = timed_cancel_tag::end_mem_index };+ enum { max_mem_index = parallel_group_tag::end_mem_index }; thread_info_base()-#if !defined(ASIO_NO_EXCEPTIONS)+#if defined(ASIO_HAS_STD_EXCEPTION_PTR) \+ && !defined(ASIO_NO_EXCEPTIONS) : has_pending_exception_(0)-#endif // !defined(ASIO_NO_EXCEPTIONS)+#endif // defined(ASIO_HAS_STD_EXCEPTION_PTR)+ // && !defined(ASIO_NO_EXCEPTIONS) { for (int i = 0; i < max_mem_index; ++i) reusable_memory_[i] = 0;@@ -205,7 +199,8 @@ void capture_current_exception() {-#if !defined(ASIO_NO_EXCEPTIONS)+#if defined(ASIO_HAS_STD_EXCEPTION_PTR) \+ && !defined(ASIO_NO_EXCEPTIONS) switch (has_pending_exception_) { case 0:@@ -221,21 +216,24 @@ default: break; }-#endif // !defined(ASIO_NO_EXCEPTIONS)+#endif // defined(ASIO_HAS_STD_EXCEPTION_PTR)+ // && !defined(ASIO_NO_EXCEPTIONS) } void rethrow_pending_exception() {-#if !defined(ASIO_NO_EXCEPTIONS)+#if defined(ASIO_HAS_STD_EXCEPTION_PTR) \+ && !defined(ASIO_NO_EXCEPTIONS) if (has_pending_exception_ > 0) { has_pending_exception_ = 0; std::exception_ptr ex(- static_cast<std::exception_ptr&&>(+ ASIO_MOVE_CAST(std::exception_ptr)( pending_exception_)); std::rethrow_exception(ex); }-#endif // !defined(ASIO_NO_EXCEPTIONS)+#endif // defined(ASIO_HAS_STD_EXCEPTION_PTR)+ // && !defined(ASIO_NO_EXCEPTIONS) } private:@@ -246,10 +244,12 @@ #endif // defined(ASIO_HAS_IO_URING) void* reusable_memory_[max_mem_index]; -#if !defined(ASIO_NO_EXCEPTIONS)+#if defined(ASIO_HAS_STD_EXCEPTION_PTR) \+ && !defined(ASIO_NO_EXCEPTIONS) int has_pending_exception_; std::exception_ptr pending_exception_;-#endif // !defined(ASIO_NO_EXCEPTIONS)+#endif // defined(ASIO_HAS_STD_EXCEPTION_PTR)+ // && !defined(ASIO_NO_EXCEPTIONS) }; } // namespace detail
link/modules/asio-standalone/asio/include/asio/detail/throw_error.hpp view
@@ -2,7 +2,7 @@ // detail/throw_error.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/throw_exception.hpp view
@@ -2,7 +2,7 @@ // detail/throw_exception.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -30,7 +30,7 @@ // Declare the throw_exception function for all targets. template <typename Exception>-[[noreturn]] void throw_exception(+void throw_exception( const Exception& e ASIO_SOURCE_LOCATION_DEFAULTED_PARAM);
− link/modules/asio-standalone/asio/include/asio/detail/timed_cancel_op.hpp
@@ -1,361 +0,0 @@-//-// detail/timed_cancel_op.hpp-// ~~~~~~~~~~~~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef ASIO_DETAIL_TIMED_CANCEL_OP_HPP-#define ASIO_DETAIL_TIMED_CANCEL_OP_HPP--#if defined(_MSC_VER) && (_MSC_VER >= 1200)-# pragma once-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)--#include "asio/detail/config.hpp"-#include "asio/associated_cancellation_slot.hpp"-#include "asio/associator.hpp"-#include "asio/basic_waitable_timer.hpp"-#include "asio/cancellation_signal.hpp"-#include "asio/detail/atomic_count.hpp"-#include "asio/detail/completion_payload.hpp"-#include "asio/detail/completion_payload_handler.hpp"-#include "asio/detail/handler_alloc_helpers.hpp"-#include "asio/detail/type_traits.hpp"--#include "asio/detail/push_options.hpp"--namespace asio {-namespace detail {--template <typename Op, typename... Signatures>-class timed_cancel_op_handler;--template <typename Op>-class timed_cancel_timer_handler;--template <typename Handler, typename Timer, typename... Signatures>-class timed_cancel_op-{-public:- using handler_type = Handler;-- ASIO_DEFINE_TAGGED_HANDLER_PTR(- thread_info_base::timed_cancel_tag, timed_cancel_op);-- timed_cancel_op(Handler& handler, Timer timer,- cancellation_type_t cancel_type)- : ref_count_(2),- handler_(static_cast<Handler&&>(handler)),- timer_(static_cast<Timer&&>(timer)),- cancellation_type_(cancel_type),- cancel_proxy_(nullptr),- has_payload_(false),- has_pending_timer_wait_(true)- {- }-- ~timed_cancel_op()- {- if (has_payload_)- payload_storage_.payload_.~payload_type();- }-- cancellation_slot get_cancellation_slot() noexcept- {- return cancellation_signal_.slot();- }-- template <typename Initiation, typename... Args>- void start(Initiation&& initiation, Args&&... args)- {- using op_handler_type =- timed_cancel_op_handler<timed_cancel_op, Signatures...>;- op_handler_type op_handler(this);-- using timer_handler_type =- timed_cancel_timer_handler<timed_cancel_op>;- timer_handler_type timer_handler(this);-- associated_cancellation_slot_t<Handler> slot- = (get_associated_cancellation_slot)(handler_);- if (slot.is_connected())- cancel_proxy_ = &slot.template emplace<cancel_proxy>(this);-- timer_.async_wait(static_cast<timer_handler_type&&>(timer_handler));- async_initiate<op_handler_type, Signatures...>(- static_cast<Initiation&&>(initiation),- static_cast<op_handler_type&>(op_handler),- static_cast<Args&&>(args)...);- }-- template <typename Message>- void handle_op(Message&& message)- {- if (cancel_proxy_)- cancel_proxy_->op_ = nullptr;-- new (&payload_storage_.payload_) payload_type(- static_cast<Message&&>(message));- has_payload_ = true;-- if (has_pending_timer_wait_)- {- timer_.cancel();- release();- }- else- {- complete();- }- }-- void handle_timer()- {- has_pending_timer_wait_ = false;-- if (has_payload_)- {- complete();- }- else- {- cancellation_signal_.emit(cancellation_type_);- release();- }- }-- void release()- {- if (--ref_count_ == 0)- {- ptr p = { asio::detail::addressof(handler_), this, this };- Handler handler(static_cast<Handler&&>(handler_));- p.h = asio::detail::addressof(handler);- p.reset();- }- }-- void complete()- {- if (--ref_count_ == 0)- {- ptr p = { asio::detail::addressof(handler_), this, this };- completion_payload_handler<payload_type, Handler> handler(- static_cast<payload_type&&>(payload_storage_.payload_), handler_);- p.h = asio::detail::addressof(handler.handler());- p.reset();- handler();- }- }--//private:- typedef completion_payload<Signatures...> payload_type;-- struct cancel_proxy- {- cancel_proxy(timed_cancel_op* op)- : op_(op)- {- }-- void operator()(cancellation_type_t type)- {- if (op_)- op_->cancellation_signal_.emit(type);- }-- timed_cancel_op* op_;- };-- // The number of handlers that share a reference to the state.- atomic_count ref_count_;-- // The handler to be called when the operation completes.- Handler handler_;-- // The timer used to determine when to cancel the pending operation.- Timer timer_;-- // The cancellation signal and type used to cancel the pending operation.- cancellation_signal cancellation_signal_;- cancellation_type_t cancellation_type_;-- // A proxy cancel handler used to allow cancellation of the timed operation.- cancel_proxy* cancel_proxy_;-- // Arguments to be passed to the completion handler.- union payload_storage- {- payload_storage() {}- ~payload_storage() {}-- char dummy_;- payload_type payload_;- } payload_storage_;-- // Whether the payload storage contains a valid payload.- bool has_payload_;-- // Whether the asynchronous wait on the timer is still pending- bool has_pending_timer_wait_;-};--template <typename Op, typename R, typename... Args>-class timed_cancel_op_handler<Op, R(Args...)>-{-public:- using cancellation_slot_type = cancellation_slot;-- explicit timed_cancel_op_handler(Op* op)- : op_(op)- {- }-- timed_cancel_op_handler(timed_cancel_op_handler&& other) noexcept- : op_(other.op_)- {- other.op_ = nullptr;- }-- ~timed_cancel_op_handler()- {- if (op_)- op_->release();- }-- cancellation_slot_type get_cancellation_slot() const noexcept- {- return op_->get_cancellation_slot();- }-- template <typename... Args2>- enable_if_t<- is_constructible<completion_message<R(Args...)>, int, Args2...>::value- > operator()(Args2&&... args)- {- Op* op = op_;- op_ = nullptr;- typedef completion_message<R(Args...)> message_type;- op->handle_op(message_type(0, static_cast<Args2&&>(args)...));- }--//protected:- Op* op_;-};--template <typename Op, typename R, typename... Args, typename... Signatures>-class timed_cancel_op_handler<Op, R(Args...), Signatures...> :- public timed_cancel_op_handler<Op, Signatures...>-{-public:- using timed_cancel_op_handler<Op, Signatures...>::timed_cancel_op_handler;- using timed_cancel_op_handler<Op, Signatures...>::operator();-- template <typename... Args2>- enable_if_t<- is_constructible<completion_message<R(Args...)>, int, Args2...>::value- > operator()(Args2&&... args)- {- Op* op = this->op_;- this->op_ = nullptr;- typedef completion_message<R(Args...)> message_type;- op->handle_op(message_type(0, static_cast<Args2&&>(args)...));- }-};--template <typename Op>-class timed_cancel_timer_handler-{-public:- using cancellation_slot_type = cancellation_slot;-- explicit timed_cancel_timer_handler(Op* op)- : op_(op)- {- }-- timed_cancel_timer_handler(timed_cancel_timer_handler&& other) noexcept- : op_(other.op_)- {- other.op_ = nullptr;- }-- ~timed_cancel_timer_handler()- {- if (op_)- op_->release();- }-- cancellation_slot_type get_cancellation_slot() const noexcept- {- return cancellation_slot_type();- }-- void operator()(const asio::error_code&)- {- Op* op = op_;- op_ = nullptr;- op->handle_timer();- }--//private:- Op* op_;-};--} // namespace detail--template <template <typename, typename> class Associator,- typename Op, typename... Signatures, typename DefaultCandidate>-struct associator<Associator,- detail::timed_cancel_op_handler<Op, Signatures...>, DefaultCandidate>- : Associator<typename Op::handler_type, DefaultCandidate>-{- static typename Associator<typename Op::handler_type, DefaultCandidate>::type- get(const detail::timed_cancel_op_handler<Op, Signatures...>& h) noexcept- {- return Associator<typename Op::handler_type, DefaultCandidate>::get(- h.op_->handler_);- }-- static auto get(const detail::timed_cancel_op_handler<Op, Signatures...>& h,- const DefaultCandidate& c) noexcept- -> decltype(Associator<typename Op::handler_type, DefaultCandidate>::get(- h.op_->handler_, c))- {- return Associator<typename Op::handler_type, DefaultCandidate>::get(- h.op_->handler_, c);- }-};--template <template <typename, typename> class Associator,- typename Op, typename DefaultCandidate>-struct associator<Associator,- detail::timed_cancel_timer_handler<Op>, DefaultCandidate>- : Associator<typename Op::handler_type, DefaultCandidate>-{- static typename Associator<typename Op::handler_type, DefaultCandidate>::type- get(const detail::timed_cancel_timer_handler<Op>& h) noexcept- {- return Associator<typename Op::handler_type, DefaultCandidate>::get(- h.op_->handler_);- }-- static auto get(const detail::timed_cancel_timer_handler<Op>& h,- const DefaultCandidate& c) noexcept- -> decltype(Associator<typename Op::handler_type, DefaultCandidate>::get(- h.op_->handler_, c))- {- return Associator<typename Op::handler_type, DefaultCandidate>::get(- h.op_->handler_, c);- }-};--} // namespace asio--#include "asio/detail/pop_options.hpp"--#endif // ASIO_DETAIL_TIMED_CANCEL_OP_HPP
link/modules/asio-standalone/asio/include/asio/detail/timer_queue.hpp view
@@ -2,7 +2,7 @@ // detail/timer_queue.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -31,16 +31,16 @@ namespace asio { namespace detail { -template <typename TimeTraits, typename Allocator>+template <typename Time_Traits> class timer_queue : public timer_queue_base { public: // The time type.- typedef typename TimeTraits::time_type time_type;+ typedef typename Time_Traits::time_type time_type; // The duration type.- typedef typename TimeTraits::duration_type duration_type;+ typedef typename Time_Traits::duration_type duration_type; // Per-timer data. class per_timer_data@@ -67,12 +67,10 @@ }; // Constructor.- timer_queue(const Allocator& alloc, std::size_t heap_reserve)+ timer_queue() : timers_(),- heap_(alloc)+ heap_() {- if (heap_reserve > 0)- heap_.reserve(heap_reserve); } // Add a new timer to the queue. Returns true if this is the timer that is@@ -126,8 +124,8 @@ return max_duration; return this->to_msec(- TimeTraits::to_posix_duration(- TimeTraits::subtract(heap_[0].time_, TimeTraits::now())),+ Time_Traits::to_posix_duration(+ Time_Traits::subtract(heap_[0].time_, Time_Traits::now())), max_duration); } @@ -138,8 +136,8 @@ return max_duration; return this->to_usec(- TimeTraits::to_posix_duration(- TimeTraits::subtract(heap_[0].time_, TimeTraits::now())),+ Time_Traits::to_posix_duration(+ Time_Traits::subtract(heap_[0].time_, Time_Traits::now())), max_duration); } @@ -148,8 +146,8 @@ { if (!heap_.empty()) {- const time_type now = TimeTraits::now();- while (!heap_.empty() && !TimeTraits::less_than(now, heap_[0].time_))+ const time_type now = Time_Traits::now();+ while (!heap_.empty() && !Time_Traits::less_than(now, heap_[0].time_)) { per_timer_data* timer = heap_[0].timer_; while (wait_op* op = timer->op_queue_.front())@@ -253,7 +251,7 @@ while (index > 0) { std::size_t parent = (index - 1) / 2;- if (!TimeTraits::less_than(heap_[index].time_, heap_[parent].time_))+ if (!Time_Traits::less_than(heap_[index].time_, heap_[parent].time_)) break; swap_heap(index, parent); index = parent;@@ -267,10 +265,10 @@ while (child < heap_.size()) { std::size_t min_child = (child + 1 == heap_.size()- || TimeTraits::less_than(+ || Time_Traits::less_than( heap_[child].time_, heap_[child + 1].time_)) ? child : child + 1;- if (TimeTraits::less_than(heap_[index].time_, heap_[min_child].time_))+ if (Time_Traits::less_than(heap_[index].time_, heap_[min_child].time_)) break; swap_heap(index, min_child); index = min_child;@@ -305,7 +303,7 @@ swap_heap(index, heap_.size() - 1); timer.heap_index_ = (std::numeric_limits<std::size_t>::max)(); heap_.pop_back();- if (index > 0 && TimeTraits::less_than(+ if (index > 0 && Time_Traits::less_than( heap_[index].time_, heap_[(index - 1) / 2].time_)) up_heap(index); else@@ -380,9 +378,7 @@ }; // The heap of timers, with the earliest timer at the front.- std::vector<heap_entry,- typename std::allocator_traits<Allocator>::template- rebind_alloc<heap_entry>> heap_;+ std::vector<heap_entry> heap_; }; } // namespace detail
link/modules/asio-standalone/asio/include/asio/detail/timer_queue_base.hpp view
@@ -2,7 +2,7 @@ // detail/timer_queue_base.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -57,7 +57,7 @@ timer_queue_base* next_; }; -template <typename TimeTraits, typename Allocator>+template <typename Time_Traits> class timer_queue; } // namespace detail
+ link/modules/asio-standalone/asio/include/asio/detail/timer_queue_ptime.hpp view
@@ -0,0 +1,103 @@+//+// detail/timer_queue_ptime.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_DETAIL_TIMER_QUEUE_PTIME_HPP+#define ASIO_DETAIL_TIMER_QUEUE_PTIME_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"++#if defined(ASIO_HAS_BOOST_DATE_TIME)++#include "asio/time_traits.hpp"+#include "asio/detail/timer_queue.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {+namespace detail {++struct forwarding_posix_time_traits : time_traits<boost::posix_time::ptime> {};++// Template specialisation for the commonly used instantation.+template <>+class timer_queue<time_traits<boost::posix_time::ptime> >+ : public timer_queue_base+{+public:+ // The time type.+ typedef boost::posix_time::ptime time_type;++ // The duration type.+ typedef boost::posix_time::time_duration duration_type;++ // Per-timer data.+ typedef timer_queue<forwarding_posix_time_traits>::per_timer_data+ per_timer_data;++ // Constructor.+ ASIO_DECL timer_queue();++ // Destructor.+ ASIO_DECL virtual ~timer_queue();++ // Add a new timer to the queue. Returns true if this is the timer that is+ // earliest in the queue, in which case the reactor's event demultiplexing+ // function call may need to be interrupted and restarted.+ ASIO_DECL bool enqueue_timer(const time_type& time,+ per_timer_data& timer, wait_op* op);++ // Whether there are no timers in the queue.+ ASIO_DECL virtual bool empty() const;++ // Get the time for the timer that is earliest in the queue.+ ASIO_DECL virtual long wait_duration_msec(long max_duration) const;++ // Get the time for the timer that is earliest in the queue.+ ASIO_DECL virtual long wait_duration_usec(long max_duration) const;++ // Dequeue all timers not later than the current time.+ ASIO_DECL virtual void get_ready_timers(op_queue<operation>& ops);++ // Dequeue all timers.+ ASIO_DECL virtual void get_all_timers(op_queue<operation>& ops);++ // Cancel and dequeue operations for the given timer.+ ASIO_DECL std::size_t cancel_timer(+ per_timer_data& timer, op_queue<operation>& ops,+ std::size_t max_cancelled = (std::numeric_limits<std::size_t>::max)());++ // Cancel and dequeue operations for the given timer and key.+ ASIO_DECL void cancel_timer_by_key(per_timer_data* timer,+ op_queue<operation>& ops, void* cancellation_key);++ // Move operations from one timer to another, empty timer.+ ASIO_DECL void move_timer(per_timer_data& target,+ per_timer_data& source);++private:+ timer_queue<forwarding_posix_time_traits> impl_;+};++} // namespace detail+} // namespace asio++#include "asio/detail/pop_options.hpp"++#if defined(ASIO_HEADER_ONLY)+# include "asio/detail/impl/timer_queue_ptime.ipp"+#endif // defined(ASIO_HEADER_ONLY)++#endif // defined(ASIO_HAS_BOOST_DATE_TIME)++#endif // ASIO_DETAIL_TIMER_QUEUE_PTIME_HPP
link/modules/asio-standalone/asio/include/asio/detail/timer_queue_set.hpp view
@@ -2,7 +2,7 @@ // detail/timer_queue_set.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/timer_scheduler.hpp view
@@ -2,7 +2,7 @@ // detail/timer_scheduler.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/timer_scheduler_fwd.hpp view
@@ -2,7 +2,7 @@ // detail/timer_scheduler_fwd.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/tss_ptr.hpp view
@@ -2,7 +2,7 @@ // detail/tss_ptr.hpp // ~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/type_traits.hpp view
@@ -2,7 +2,7 @@ // detail/type_traits.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -16,174 +16,148 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"-#include <type_traits> +#if defined(ASIO_HAS_STD_TYPE_TRAITS)+# include <type_traits>+#else // defined(ASIO_HAS_STD_TYPE_TRAITS)+# include <boost/type_traits/add_const.hpp>+# include <boost/type_traits/add_lvalue_reference.hpp>+# include <boost/type_traits/aligned_storage.hpp>+# include <boost/type_traits/alignment_of.hpp>+# include <boost/type_traits/conditional.hpp>+# include <boost/type_traits/decay.hpp>+# include <boost/type_traits/has_nothrow_copy.hpp>+# include <boost/type_traits/has_nothrow_destructor.hpp>+# include <boost/type_traits/integral_constant.hpp>+# include <boost/type_traits/is_base_of.hpp>+# include <boost/type_traits/is_class.hpp>+# include <boost/type_traits/is_const.hpp>+# include <boost/type_traits/is_convertible.hpp>+# include <boost/type_traits/is_constructible.hpp>+# include <boost/type_traits/is_copy_constructible.hpp>+# include <boost/type_traits/is_destructible.hpp>+# include <boost/type_traits/is_function.hpp>+# include <boost/type_traits/is_object.hpp>+# include <boost/type_traits/is_pointer.hpp>+# include <boost/type_traits/is_same.hpp>+# include <boost/type_traits/remove_cv.hpp>+# include <boost/type_traits/remove_pointer.hpp>+# include <boost/type_traits/remove_reference.hpp>+# include <boost/utility/declval.hpp>+# include <boost/utility/enable_if.hpp>+# include <boost/utility/result_of.hpp>+#endif // defined(ASIO_HAS_STD_TYPE_TRAITS)+ namespace asio { +#if defined(ASIO_HAS_STD_TYPE_TRAITS) using std::add_const;--template <typename T>-using add_const_t = typename std::add_const<T>::type;- using std::add_lvalue_reference;--template <typename T>-using add_lvalue_reference_t = typename std::add_lvalue_reference<T>::type;--template <std::size_t N, std::size_t A>-struct aligned_storage-{- struct type- {- alignas(A) unsigned char data[N];- };-};-+#if defined(ASIO_MSVC) && (_MSC_VER < 1900)+using std::aligned_storage;+#else // defined(ASIO_MSVC) && (_MSC_VER < 1900) template <std::size_t N, std::size_t A>-using aligned_storage_t = typename aligned_storage<N, A>::type;-+struct aligned_storage { struct type { alignas(A) unsigned char data[N]; }; };+#endif // defined(ASIO_MSVC) && (_MSC_VER < 1900) using std::alignment_of;- using std::conditional;--template <bool C, typename T, typename U>-using conditional_t = typename std::conditional<C, T, U>::type;- using std::decay;--template <typename T>-using decay_t = typename std::decay<T>::type;- using std::declval;- using std::enable_if;--template <bool C, typename T = void>-using enable_if_t = typename std::enable_if<C, T>::type;- using std::false_type;- using std::integral_constant;- using std::is_base_of;- using std::is_class;- using std::is_const;- using std::is_constructible;- using std::is_convertible;- using std::is_copy_constructible;--using std::is_nothrow_default_constructible;- using std::is_destructible;- using std::is_function;--using std::is_integral;- using std::is_move_constructible;- using std::is_nothrow_copy_constructible;--using std::is_nothrow_copy_assignable;- using std::is_nothrow_destructible;--using std::is_nothrow_move_constructible;--using std::is_nothrow_move_assignable;- using std::is_object;- using std::is_pointer;- using std::is_reference;- using std::is_same;- using std::is_scalar;--using std::is_unsigned;- using std::remove_cv;- template <typename T>-using remove_cv_t = typename std::remove_cv<T>::type;--template <typename T>-struct remove_cvref :- std::remove_cv<typename std::remove_reference<T>::type> {};--template <typename T>-using remove_cvref_t = typename remove_cvref<T>::type;-+struct remove_cvref : remove_cv<typename std::remove_reference<T>::type> {}; using std::remove_pointer;--template <typename T>-using remove_pointer_t = typename std::remove_pointer<T>::type;- using std::remove_reference;--template <typename T>-using remove_reference_t = typename std::remove_reference<T>::type;- #if defined(ASIO_HAS_STD_INVOKE_RESULT)- template <typename> struct result_of;- template <typename F, typename... Args> struct result_of<F(Args...)> : std::invoke_result<F, Args...> {};--template <typename T>-using result_of_t = typename result_of<T>::type;- #else // defined(ASIO_HAS_STD_INVOKE_RESULT)- using std::result_of;--template <typename T>-using result_of_t = typename std::result_of<T>::type;- #endif // defined(ASIO_HAS_STD_INVOKE_RESULT)- using std::true_type;+#else // defined(ASIO_HAS_STD_TYPE_TRAITS)+using boost::add_const;+using boost::add_lvalue_reference;+using boost::aligned_storage;+using boost::alignment_of;+template <bool Condition, typename Type = void>+struct enable_if : boost::enable_if_c<Condition, Type> {};+using boost::conditional;+using boost::decay;+using boost::declval;+using boost::false_type;+using boost::integral_constant;+using boost::is_base_of;+using boost::is_class;+using boost::is_const;+using boost::is_constructible;+using boost::is_convertible;+using boost::is_copy_constructible;+using boost::is_destructible;+using boost::is_function;+#if defined(ASIO_HAS_MOVE)+template <typename T>+struct is_move_constructible : false_type {};+#else // defined(ASIO_HAS_MOVE)+template <typename T>+struct is_move_constructible : is_copy_constructible<T> {};+#endif // defined(ASIO_HAS_MOVE)+template <typename T>+struct is_nothrow_copy_constructible : boost::has_nothrow_copy<T> {};+template <typename T>+struct is_nothrow_destructible : boost::has_nothrow_destructor<T> {};+using boost::is_object;+using boost::is_pointer;+using boost::is_reference;+using boost::is_same;+using boost::is_scalar;+using boost::remove_cv;+template <typename T>+struct remove_cvref : remove_cv<typename boost::remove_reference<T>::type> {};+using boost::remove_pointer;+using boost::remove_reference;+using boost::result_of;+using boost::true_type;+#endif // defined(ASIO_HAS_STD_TYPE_TRAITS) -template <typename> struct void_type-{- typedef void type;-};+template <typename> struct void_type { typedef void type; }; -template <typename T>-using void_t = typename void_type<T>::type;+#if defined(ASIO_HAS_VARIADIC_TEMPLATES) template <typename...> struct conjunction : true_type {};- template <typename T> struct conjunction<T> : T {};+template <typename Head, typename... Tail> struct conjunction<Head, Tail...> :+ conditional<Head::value, conjunction<Tail...>, Head>::type {}; -template <typename Head, typename... Tail>-struct conjunction<Head, Tail...> :- conditional_t<Head::value, conjunction<Tail...>, Head> {};+#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) struct defaulted_constraint {- constexpr defaulted_constraint() {}+ ASIO_CONSTEXPR defaulted_constraint() {} }; template <bool Condition, typename Type = int>-struct constraint : std::enable_if<Condition, Type> {};--template <bool Condition, typename Type = int>-using constraint_t = typename constraint<Condition, Type>::type;--template <typename T>-struct type_identity { typedef T type; };--template <typename T>-using type_identity_t = typename type_identity<T>::type;+struct constraint : enable_if<Condition, Type> {}; } // namespace asio
link/modules/asio-standalone/asio/include/asio/detail/utility.hpp view
@@ -2,7 +2,7 @@ // detail/utility.hpp // ~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -27,7 +27,7 @@ using std::index_sequence_for; using std::make_index_sequence; -#else // defined(ASIO_HAS_STD_INDEX_SEQUENCE)+#elif defined(ASIO_HAS_VARIADIC_TEMPLATES) template <std::size_t...> struct index_sequence@@ -38,7 +38,7 @@ struct join_index_sequences; template <std::size_t... I, std::size_t... J>-struct join_index_sequences<index_sequence<I...>, index_sequence<J...>>+struct join_index_sequences<index_sequence<I...>, index_sequence<J...> > { using type = index_sequence<I..., J...>; };@@ -75,7 +75,7 @@ template <std::size_t N> using make_index_sequence = typename index_range<0, N>::type; -#endif // defined(ASIO_HAS_STD_INDEX_SEQUENCE)+#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) } // namespace detail } // namespace asio
+ link/modules/asio-standalone/asio/include/asio/detail/variadic_templates.hpp view
@@ -0,0 +1,294 @@+//+// detail/variadic_templates.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_DETAIL_VARIADIC_TEMPLATES_HPP+#define ASIO_DETAIL_VARIADIC_TEMPLATES_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"++#if !defined(ASIO_HAS_VARIADIC_TEMPLATES)++# define ASIO_VARIADIC_TPARAMS(n) ASIO_VARIADIC_TPARAMS_##n++# define ASIO_VARIADIC_TPARAMS_1 \+ typename T1+# define ASIO_VARIADIC_TPARAMS_2 \+ typename T1, typename T2+# define ASIO_VARIADIC_TPARAMS_3 \+ typename T1, typename T2, typename T3+# define ASIO_VARIADIC_TPARAMS_4 \+ typename T1, typename T2, typename T3, typename T4+# define ASIO_VARIADIC_TPARAMS_5 \+ typename T1, typename T2, typename T3, typename T4, typename T5+# define ASIO_VARIADIC_TPARAMS_6 \+ typename T1, typename T2, typename T3, typename T4, typename T5, \+ typename T6+# define ASIO_VARIADIC_TPARAMS_7 \+ typename T1, typename T2, typename T3, typename T4, typename T5, \+ typename T6, typename T7+# define ASIO_VARIADIC_TPARAMS_8 \+ typename T1, typename T2, typename T3, typename T4, typename T5, \+ typename T6, typename T7, typename T8++# define ASIO_VARIADIC_TARGS(n) ASIO_VARIADIC_TARGS_##n++# define ASIO_VARIADIC_TARGS_1 T1+# define ASIO_VARIADIC_TARGS_2 T1, T2+# define ASIO_VARIADIC_TARGS_3 T1, T2, T3+# define ASIO_VARIADIC_TARGS_4 T1, T2, T3, T4+# define ASIO_VARIADIC_TARGS_5 T1, T2, T3, T4, T5+# define ASIO_VARIADIC_TARGS_6 T1, T2, T3, T4, T5, T6+# define ASIO_VARIADIC_TARGS_7 T1, T2, T3, T4, T5, T6, T7+# define ASIO_VARIADIC_TARGS_8 T1, T2, T3, T4, T5, T6, T7, T8++# define ASIO_VARIADIC_BYVAL_PARAMS(n) \+ ASIO_VARIADIC_BYVAL_PARAMS_##n++# define ASIO_VARIADIC_BYVAL_PARAMS_1 T1 x1+# define ASIO_VARIADIC_BYVAL_PARAMS_2 T1 x1, T2 x2+# define ASIO_VARIADIC_BYVAL_PARAMS_3 T1 x1, T2 x2, T3 x3+# define ASIO_VARIADIC_BYVAL_PARAMS_4 T1 x1, T2 x2, T3 x3, T4 x4+# define ASIO_VARIADIC_BYVAL_PARAMS_5 T1 x1, T2 x2, T3 x3, T4 x4, T5 x5+# define ASIO_VARIADIC_BYVAL_PARAMS_6 T1 x1, T2 x2, T3 x3, T4 x4, T5 x5, \+ T6 x6+# define ASIO_VARIADIC_BYVAL_PARAMS_7 T1 x1, T2 x2, T3 x3, T4 x4, T5 x5, \+ T6 x6, T7 x7+# define ASIO_VARIADIC_BYVAL_PARAMS_8 T1 x1, T2 x2, T3 x3, T4 x4, T5 x5, \+ T6 x6, T7 x7, T8 x8++# define ASIO_VARIADIC_BYVAL_ARGS(n) \+ ASIO_VARIADIC_BYVAL_ARGS_##n++# define ASIO_VARIADIC_BYVAL_ARGS_1 x1+# define ASIO_VARIADIC_BYVAL_ARGS_2 x1, x2+# define ASIO_VARIADIC_BYVAL_ARGS_3 x1, x2, x3+# define ASIO_VARIADIC_BYVAL_ARGS_4 x1, x2, x3, x4+# define ASIO_VARIADIC_BYVAL_ARGS_5 x1, x2, x3, x4, x5+# define ASIO_VARIADIC_BYVAL_ARGS_6 x1, x2, x3, x4, x5, x6+# define ASIO_VARIADIC_BYVAL_ARGS_7 x1, x2, x3, x4, x5, x6, x7+# define ASIO_VARIADIC_BYVAL_ARGS_8 x1, x2, x3, x4, x5, x6, x7, x8++# define ASIO_VARIADIC_CONSTREF_PARAMS(n) \+ ASIO_VARIADIC_CONSTREF_PARAMS_##n++# define ASIO_VARIADIC_CONSTREF_PARAMS_1 \+ const T1& x1+# define ASIO_VARIADIC_CONSTREF_PARAMS_2 \+ const T1& x1, const T2& x2+# define ASIO_VARIADIC_CONSTREF_PARAMS_3 \+ const T1& x1, const T2& x2, const T3& x3+# define ASIO_VARIADIC_CONSTREF_PARAMS_4 \+ const T1& x1, const T2& x2, const T3& x3, const T4& x4+# define ASIO_VARIADIC_CONSTREF_PARAMS_5 \+ const T1& x1, const T2& x2, const T3& x3, const T4& x4, const T5& x5+# define ASIO_VARIADIC_CONSTREF_PARAMS_6 \+ const T1& x1, const T2& x2, const T3& x3, const T4& x4, const T5& x5, \+ const T6& x6+# define ASIO_VARIADIC_CONSTREF_PARAMS_7 \+ const T1& x1, const T2& x2, const T3& x3, const T4& x4, const T5& x5, \+ const T6& x6, const T7& x7+# define ASIO_VARIADIC_CONSTREF_PARAMS_8 \+ const T1& x1, const T2& x2, const T3& x3, const T4& x4, const T5& x5, \+ const T6& x6, const T7& x7, const T8& x8++# define ASIO_VARIADIC_MOVE_PARAMS(n) \+ ASIO_VARIADIC_MOVE_PARAMS_##n++# define ASIO_VARIADIC_MOVE_PARAMS_1 \+ ASIO_MOVE_ARG(T1) x1+# define ASIO_VARIADIC_MOVE_PARAMS_2 \+ ASIO_MOVE_ARG(T1) x1, ASIO_MOVE_ARG(T2) x2+# define ASIO_VARIADIC_MOVE_PARAMS_3 \+ ASIO_MOVE_ARG(T1) x1, ASIO_MOVE_ARG(T2) x2, \+ ASIO_MOVE_ARG(T3) x3+# define ASIO_VARIADIC_MOVE_PARAMS_4 \+ ASIO_MOVE_ARG(T1) x1, ASIO_MOVE_ARG(T2) x2, \+ ASIO_MOVE_ARG(T3) x3, ASIO_MOVE_ARG(T4) x4+# define ASIO_VARIADIC_MOVE_PARAMS_5 \+ ASIO_MOVE_ARG(T1) x1, ASIO_MOVE_ARG(T2) x2, \+ ASIO_MOVE_ARG(T3) x3, ASIO_MOVE_ARG(T4) x4, \+ ASIO_MOVE_ARG(T5) x5+# define ASIO_VARIADIC_MOVE_PARAMS_6 \+ ASIO_MOVE_ARG(T1) x1, ASIO_MOVE_ARG(T2) x2, \+ ASIO_MOVE_ARG(T3) x3, ASIO_MOVE_ARG(T4) x4, \+ ASIO_MOVE_ARG(T5) x5, ASIO_MOVE_ARG(T6) x6+# define ASIO_VARIADIC_MOVE_PARAMS_7 \+ ASIO_MOVE_ARG(T1) x1, ASIO_MOVE_ARG(T2) x2, \+ ASIO_MOVE_ARG(T3) x3, ASIO_MOVE_ARG(T4) x4, \+ ASIO_MOVE_ARG(T5) x5, ASIO_MOVE_ARG(T6) x6, \+ ASIO_MOVE_ARG(T7) x7+# define ASIO_VARIADIC_MOVE_PARAMS_8 \+ ASIO_MOVE_ARG(T1) x1, ASIO_MOVE_ARG(T2) x2, \+ ASIO_MOVE_ARG(T3) x3, ASIO_MOVE_ARG(T4) x4, \+ ASIO_MOVE_ARG(T5) x5, ASIO_MOVE_ARG(T6) x6, \+ ASIO_MOVE_ARG(T7) x7, ASIO_MOVE_ARG(T8) x8++# define ASIO_VARIADIC_UNNAMED_MOVE_PARAMS(n) \+ ASIO_VARIADIC_UNNAMED_MOVE_PARAMS_##n++# define ASIO_VARIADIC_UNNAMED_MOVE_PARAMS_1 \+ ASIO_MOVE_ARG(T1)+# define ASIO_VARIADIC_UNNAMED_MOVE_PARAMS_2 \+ ASIO_MOVE_ARG(T1), ASIO_MOVE_ARG(T2)+# define ASIO_VARIADIC_UNNAMED_MOVE_PARAMS_3 \+ ASIO_MOVE_ARG(T1), ASIO_MOVE_ARG(T2), \+ ASIO_MOVE_ARG(T3)+# define ASIO_VARIADIC_UNNAMED_MOVE_PARAMS_4 \+ ASIO_MOVE_ARG(T1), ASIO_MOVE_ARG(T2), \+ ASIO_MOVE_ARG(T3), ASIO_MOVE_ARG(T4)+# define ASIO_VARIADIC_UNNAMED_MOVE_PARAMS_5 \+ ASIO_MOVE_ARG(T1), ASIO_MOVE_ARG(T2), \+ ASIO_MOVE_ARG(T3), ASIO_MOVE_ARG(T4), \+ ASIO_MOVE_ARG(T5)+# define ASIO_VARIADIC_UNNAMED_MOVE_PARAMS_6 \+ ASIO_MOVE_ARG(T1), ASIO_MOVE_ARG(T2), \+ ASIO_MOVE_ARG(T3), ASIO_MOVE_ARG(T4), \+ ASIO_MOVE_ARG(T5), ASIO_MOVE_ARG(T6)+# define ASIO_VARIADIC_UNNAMED_MOVE_PARAMS_7 \+ ASIO_MOVE_ARG(T1), ASIO_MOVE_ARG(T2), \+ ASIO_MOVE_ARG(T3), ASIO_MOVE_ARG(T4), \+ ASIO_MOVE_ARG(T5), ASIO_MOVE_ARG(T6), \+ ASIO_MOVE_ARG(T7)+# define ASIO_VARIADIC_UNNAMED_MOVE_PARAMS_8 \+ ASIO_MOVE_ARG(T1), ASIO_MOVE_ARG(T2), \+ ASIO_MOVE_ARG(T3), ASIO_MOVE_ARG(T4), \+ ASIO_MOVE_ARG(T5), ASIO_MOVE_ARG(T6), \+ ASIO_MOVE_ARG(T7), ASIO_MOVE_ARG(T8)++# define ASIO_VARIADIC_MOVE_ARGS(n) \+ ASIO_VARIADIC_MOVE_ARGS_##n++# define ASIO_VARIADIC_MOVE_ARGS_1 \+ ASIO_MOVE_CAST(T1)(x1)+# define ASIO_VARIADIC_MOVE_ARGS_2 \+ ASIO_MOVE_CAST(T1)(x1), ASIO_MOVE_CAST(T2)(x2)+# define ASIO_VARIADIC_MOVE_ARGS_3 \+ ASIO_MOVE_CAST(T1)(x1), ASIO_MOVE_CAST(T2)(x2), \+ ASIO_MOVE_CAST(T3)(x3)+# define ASIO_VARIADIC_MOVE_ARGS_4 \+ ASIO_MOVE_CAST(T1)(x1), ASIO_MOVE_CAST(T2)(x2), \+ ASIO_MOVE_CAST(T3)(x3), ASIO_MOVE_CAST(T4)(x4)+# define ASIO_VARIADIC_MOVE_ARGS_5 \+ ASIO_MOVE_CAST(T1)(x1), ASIO_MOVE_CAST(T2)(x2), \+ ASIO_MOVE_CAST(T3)(x3), ASIO_MOVE_CAST(T4)(x4), \+ ASIO_MOVE_CAST(T5)(x5)+# define ASIO_VARIADIC_MOVE_ARGS_6 \+ ASIO_MOVE_CAST(T1)(x1), ASIO_MOVE_CAST(T2)(x2), \+ ASIO_MOVE_CAST(T3)(x3), ASIO_MOVE_CAST(T4)(x4), \+ ASIO_MOVE_CAST(T5)(x5), ASIO_MOVE_CAST(T6)(x6)+# define ASIO_VARIADIC_MOVE_ARGS_7 \+ ASIO_MOVE_CAST(T1)(x1), ASIO_MOVE_CAST(T2)(x2), \+ ASIO_MOVE_CAST(T3)(x3), ASIO_MOVE_CAST(T4)(x4), \+ ASIO_MOVE_CAST(T5)(x5), ASIO_MOVE_CAST(T6)(x6), \+ ASIO_MOVE_CAST(T7)(x7)+# define ASIO_VARIADIC_MOVE_ARGS_8 \+ ASIO_MOVE_CAST(T1)(x1), ASIO_MOVE_CAST(T2)(x2), \+ ASIO_MOVE_CAST(T3)(x3), ASIO_MOVE_CAST(T4)(x4), \+ ASIO_MOVE_CAST(T5)(x5), ASIO_MOVE_CAST(T6)(x6), \+ ASIO_MOVE_CAST(T7)(x7), ASIO_MOVE_CAST(T8)(x8)++# define ASIO_VARIADIC_DECLVAL(n) \+ ASIO_VARIADIC_DECLVAL_##n++# define ASIO_VARIADIC_DECLVAL_1 \+ declval<T1>()+# define ASIO_VARIADIC_DECLVAL_2 \+ declval<T1>(), declval<T2>()+# define ASIO_VARIADIC_DECLVAL_3 \+ declval<T1>(), declval<T2>(), declval<T3>()+# define ASIO_VARIADIC_DECLVAL_4 \+ declval<T1>(), declval<T2>(), declval<T3>(), declval<T4>()+# define ASIO_VARIADIC_DECLVAL_5 \+ declval<T1>(), declval<T2>(), declval<T3>(), declval<T4>(), \+ declval<T5>()+# define ASIO_VARIADIC_DECLVAL_6 \+ declval<T1>(), declval<T2>(), declval<T3>(), declval<T4>(), \+ declval<T5>(), declval<T6>()+# define ASIO_VARIADIC_DECLVAL_7 \+ declval<T1>(), declval<T2>(), declval<T3>(), declval<T4>(), \+ declval<T5>(), declval<T6>(), declval<T7>()+# define ASIO_VARIADIC_DECLVAL_8 \+ declval<T1>(), declval<T2>(), declval<T3>(), declval<T4>(), \+ declval<T5>(), declval<T6>(), declval<T7>(), declval<T8>()++# define ASIO_VARIADIC_MOVE_DECLVAL(n) \+ ASIO_VARIADIC_MOVE_DECLVAL_##n++# define ASIO_VARIADIC_MOVE_DECLVAL_1 \+ declval<ASIO_MOVE_ARG(T1)>()+# define ASIO_VARIADIC_MOVE_DECLVAL_2 \+ declval<ASIO_MOVE_ARG(T1)>(), declval<ASIO_MOVE_ARG(T2)>()+# define ASIO_VARIADIC_MOVE_DECLVAL_3 \+ declval<ASIO_MOVE_ARG(T1)>(), declval<ASIO_MOVE_ARG(T2)>(), \+ declval<ASIO_MOVE_ARG(T3)>()+# define ASIO_VARIADIC_MOVE_DECLVAL_4 \+ declval<ASIO_MOVE_ARG(T1)>(), declval<ASIO_MOVE_ARG(T2)>(), \+ declval<ASIO_MOVE_ARG(T3)>(), declval<ASIO_MOVE_ARG(T4)>()+# define ASIO_VARIADIC_MOVE_DECLVAL_5 \+ declval<ASIO_MOVE_ARG(T1)>(), declval<ASIO_MOVE_ARG(T2)>(), \+ declval<ASIO_MOVE_ARG(T3)>(), declval<ASIO_MOVE_ARG(T4)>(), \+ declval<ASIO_MOVE_ARG(T5)>()+# define ASIO_VARIADIC_MOVE_DECLVAL_6 \+ declval<ASIO_MOVE_ARG(T1)>(), declval<ASIO_MOVE_ARG(T2)>(), \+ declval<ASIO_MOVE_ARG(T3)>(), declval<ASIO_MOVE_ARG(T4)>(), \+ declval<ASIO_MOVE_ARG(T5)>(), declval<ASIO_MOVE_ARG(T6)>()+# define ASIO_VARIADIC_MOVE_DECLVAL_7 \+ declval<ASIO_MOVE_ARG(T1)>(), declval<ASIO_MOVE_ARG(T2)>(), \+ declval<ASIO_MOVE_ARG(T3)>(), declval<ASIO_MOVE_ARG(T4)>(), \+ declval<ASIO_MOVE_ARG(T5)>(), declval<ASIO_MOVE_ARG(T6)>(), \+ declval<ASIO_MOVE_ARG(T7)>()+# define ASIO_VARIADIC_MOVE_DECLVAL_8 \+ declval<ASIO_MOVE_ARG(T1)>(), declval<ASIO_MOVE_ARG(T2)>(), \+ declval<ASIO_MOVE_ARG(T3)>(), declval<ASIO_MOVE_ARG(T4)>(), \+ declval<ASIO_MOVE_ARG(T5)>(), declval<ASIO_MOVE_ARG(T6)>(), \+ declval<ASIO_MOVE_ARG(T7)>(), declval<ASIO_MOVE_ARG(T8)>()++# define ASIO_VARIADIC_DECAY(n) \+ ASIO_VARIADIC_DECAY_##n++# define ASIO_VARIADIC_DECAY_1 \+ typename decay<T1>::type+# define ASIO_VARIADIC_DECAY_2 \+ typename decay<T1>::type, typename decay<T2>::type+# define ASIO_VARIADIC_DECAY_3 \+ typename decay<T1>::type, typename decay<T2>::type, \+ typename decay<T3>::type+# define ASIO_VARIADIC_DECAY_4 \+ typename decay<T1>::type, typename decay<T2>::type, \+ typename decay<T3>::type, typename decay<T4>::type+# define ASIO_VARIADIC_DECAY_5 \+ typename decay<T1>::type, typename decay<T2>::type, \+ typename decay<T3>::type, typename decay<T4>::type, \+ typename decay<T5>::type+# define ASIO_VARIADIC_DECAY_6 \+ typename decay<T1>::type, typename decay<T2>::type, \+ typename decay<T3>::type, typename decay<T4>::type, \+ typename decay<T5>::type, typename decay<T6>::type+# define ASIO_VARIADIC_DECAY_7 \+ typename decay<T1>::type, typename decay<T2>::type, \+ typename decay<T3>::type, typename decay<T4>::type, \+ typename decay<T5>::type, typename decay<T6>::type, \+ typename decay<T7>::type+# define ASIO_VARIADIC_DECAY_8 \+ typename decay<T1>::type, typename decay<T2>::type, \+ typename decay<T3>::type, typename decay<T4>::type, \+ typename decay<T5>::type, typename decay<T6>::type, \+ typename decay<T7>::type, typename decay<T8>::type++# define ASIO_VARIADIC_GENERATE(m) m(1) m(2) m(3) m(4) m(5) m(6) m(7) m(8)+# define ASIO_VARIADIC_GENERATE_5(m) m(1) m(2) m(3) m(4) m(5)++#endif // !defined(ASIO_HAS_VARIADIC_TEMPLATES)++#endif // ASIO_DETAIL_VARIADIC_TEMPLATES_HPP
link/modules/asio-standalone/asio/include/asio/detail/wait_handler.hpp view
@@ -2,7 +2,7 @@ // detail/wait_handler.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -36,7 +36,7 @@ wait_handler(Handler& h, const IoExecutor& io_ex) : wait_op(&wait_handler::do_complete),- handler_(static_cast<Handler&&>(h)),+ handler_(ASIO_MOVE_CAST(Handler)(h)), work_(handler_, io_ex) { }@@ -53,7 +53,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( h->work_)); // Make a copy of the handler so that the memory can be deallocated before
link/modules/asio-standalone/asio/include/asio/detail/wait_op.hpp view
@@ -2,7 +2,7 @@ // detail/wait_op.hpp // ~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/win_event.hpp view
@@ -2,7 +2,7 @@ // detail/win_event.hpp // ~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/win_fd_set_adapter.hpp view
@@ -2,7 +2,7 @@ // detail/win_fd_set_adapter.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ link/modules/asio-standalone/asio/include/asio/detail/win_fenced_block.hpp view
@@ -0,0 +1,90 @@+//+// detail/win_fenced_block.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_DETAIL_WIN_FENCED_BLOCK_HPP+#define ASIO_DETAIL_WIN_FENCED_BLOCK_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"++#if defined(ASIO_WINDOWS) && !defined(UNDER_CE)++#include "asio/detail/socket_types.hpp"+#include "asio/detail/noncopyable.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {+namespace detail {++class win_fenced_block+ : private noncopyable+{+public:+ enum half_t { half };+ enum full_t { full };++ // Constructor for a half fenced block.+ explicit win_fenced_block(half_t)+ {+ }++ // Constructor for a full fenced block.+ explicit win_fenced_block(full_t)+ {+#if defined(__BORLANDC__)+ LONG barrier = 0;+ ::InterlockedExchange(&barrier, 1);+#elif defined(ASIO_MSVC) \+ && ((ASIO_MSVC < 1400) || !defined(MemoryBarrier))+# if defined(_M_IX86)+# pragma warning(push)+# pragma warning(disable:4793)+ LONG barrier;+ __asm { xchg barrier, eax }+# pragma warning(pop)+# endif // defined(_M_IX86)+#else+ MemoryBarrier();+#endif+ }++ // Destructor.+ ~win_fenced_block()+ {+#if defined(__BORLANDC__)+ LONG barrier = 0;+ ::InterlockedExchange(&barrier, 1);+#elif defined(ASIO_MSVC) \+ && ((ASIO_MSVC < 1400) || !defined(MemoryBarrier))+# if defined(_M_IX86)+# pragma warning(push)+# pragma warning(disable:4793)+ LONG barrier;+ __asm { xchg barrier, eax }+# pragma warning(pop)+# endif // defined(_M_IX86)+#else+ MemoryBarrier();+#endif+ }+};++} // namespace detail+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // defined(ASIO_WINDOWS) && !defined(UNDER_CE)++#endif // ASIO_DETAIL_WIN_FENCED_BLOCK_HPP
link/modules/asio-standalone/asio/include/asio/detail/win_global.hpp view
@@ -2,7 +2,7 @@ // detail/win_global.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/win_iocp_file_service.hpp view
@@ -2,7 +2,7 @@ // detail/win_iocp_file_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/win_iocp_handle_read_op.hpp view
@@ -2,7 +2,7 @@ // detail/win_iocp_handle_read_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying@@ -24,6 +24,7 @@ #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/operation.hpp"@@ -44,7 +45,7 @@ Handler& handler, const IoExecutor& io_ex) : operation(&win_iocp_handle_read_op::do_complete), buffers_(buffers),- handler_(static_cast<Handler&&>(handler)),+ handler_(ASIO_MOVE_CAST(Handler)(handler)), work_(handler_, io_ex) { }@@ -64,7 +65,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
link/modules/asio-standalone/asio/include/asio/detail/win_iocp_handle_service.hpp view
@@ -2,7 +2,7 @@ // detail/win_iocp_handle_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying@@ -152,7 +152,7 @@ const ConstBufferSequence& buffers, Handler& handler, const IoExecutor& io_ex) {- associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -182,7 +182,7 @@ uint64_t offset, const ConstBufferSequence& buffers, Handler& handler, const IoExecutor& io_ex) {- associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -233,7 +233,7 @@ const MutableBufferSequence& buffers, Handler& handler, const IoExecutor& io_ex) {- associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -265,7 +265,7 @@ uint64_t offset, const MutableBufferSequence& buffers, Handler& handler, const IoExecutor& io_ex) {- associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.
link/modules/asio-standalone/asio/include/asio/detail/win_iocp_handle_write_op.hpp view
@@ -2,7 +2,7 @@ // detail/win_iocp_handle_write_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying@@ -24,6 +24,7 @@ #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/operation.hpp"@@ -44,7 +45,7 @@ Handler& handler, const IoExecutor& io_ex) : operation(&win_iocp_handle_write_op::do_complete), buffers_(buffers),- handler_(static_cast<Handler&&>(handler)),+ handler_(ASIO_MOVE_CAST(Handler)(handler)), work_(handler_, io_ex) { }@@ -63,7 +64,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
link/modules/asio-standalone/asio/include/asio/detail/win_iocp_io_context.hpp view
@@ -2,7 +2,7 @@ // detail/win_iocp_io_context.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -22,6 +22,7 @@ #include "asio/detail/limits.hpp" #include "asio/detail/mutex.hpp" #include "asio/detail/op_queue.hpp"+#include "asio/detail/scoped_ptr.hpp" #include "asio/detail/socket_types.hpp" #include "asio/detail/thread.hpp" #include "asio/detail/thread_context.hpp"@@ -44,16 +45,10 @@ public thread_context { public:- // Tag type used for constructing as an internal scheduler.- struct internal {};-- // Constructor.- ASIO_DECL win_iocp_io_context(- asio::execution_context& ctx, bool own_thread = true);-- // Construct as an internal scheduler.- ASIO_DECL win_iocp_io_context(internal,- asio::execution_context& ctx);+ // Constructor. Specifies a concurrency hint that is passed through to the+ // underlying I/O completion port.+ ASIO_DECL win_iocp_io_context(asio::execution_context& ctx,+ int concurrency_hint = -1, bool own_thread = true); // Destructor. ASIO_DECL ~win_iocp_io_context();@@ -181,40 +176,45 @@ const asio::error_code& ec, DWORD bytes_transferred = 0); // Add a new timer queue to the service.- template <typename TimeTraits, typename Allocator>- void add_timer_queue(timer_queue<TimeTraits, Allocator>& timer_queue);+ template <typename Time_Traits>+ void add_timer_queue(timer_queue<Time_Traits>& timer_queue); // Remove a timer queue from the service.- template <typename TimeTraits, typename Allocator>- void remove_timer_queue(timer_queue<TimeTraits, Allocator>& timer_queue);+ template <typename Time_Traits>+ void remove_timer_queue(timer_queue<Time_Traits>& timer_queue); // Schedule a new operation in the given timer queue to expire at the // specified absolute time.- template <typename TimeTraits, typename Allocator>- void schedule_timer(timer_queue<TimeTraits, Allocator>& queue,- const typename TimeTraits::time_type& time,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,- wait_op* op);+ template <typename Time_Traits>+ void schedule_timer(timer_queue<Time_Traits>& queue,+ const typename Time_Traits::time_type& time,+ typename timer_queue<Time_Traits>::per_timer_data& timer, wait_op* op); // Cancel the timer associated with the given token. Returns the number of // handlers that have been posted or dispatched.- template <typename TimeTraits, typename Allocator>- std::size_t cancel_timer(timer_queue<TimeTraits, Allocator>& queue,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,+ template <typename Time_Traits>+ std::size_t cancel_timer(timer_queue<Time_Traits>& queue,+ typename timer_queue<Time_Traits>::per_timer_data& timer, std::size_t max_cancelled = (std::numeric_limits<std::size_t>::max)()); // Cancel the timer operations associated with the given key.- template <typename TimeTraits, typename Allocator>- void cancel_timer_by_key(timer_queue<TimeTraits, Allocator>& queue,- typename timer_queue<TimeTraits, Allocator>::per_timer_data* timer,+ template <typename Time_Traits>+ void cancel_timer_by_key(timer_queue<Time_Traits>& queue,+ typename timer_queue<Time_Traits>::per_timer_data* timer, void* cancellation_key); // Move the timer operations associated with the given timer.- template <typename TimeTraits, typename Allocator>- void move_timer(timer_queue<TimeTraits, Allocator>& queue,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& to,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& from);+ template <typename Time_Traits>+ void move_timer(timer_queue<Time_Traits>& queue,+ typename timer_queue<Time_Traits>::per_timer_data& to,+ typename timer_queue<Time_Traits>::per_timer_data& from); + // Get the concurrency hint that was used to initialise the io_context.+ int concurrency_hint() const+ {+ return concurrency_hint_;+ }+ private: #if defined(WINVER) && (WINVER < 0x0500) typedef DWORD dword_ptr_t;@@ -264,7 +264,7 @@ // Flag to indicate whether there is an in-flight stop event. Every event // posted using PostQueuedCompletionStatus consumes non-paged pool, so to- // avoid exhausting this resource we limit the number of outstanding events.+ // avoid exhausting this resouce we limit the number of outstanding events. long stop_event_posted_; // Flag to indicate whether the service has been shut down.@@ -308,7 +308,7 @@ friend struct timer_thread_function; // Background thread used for processing timeouts.- asio::detail::thread timer_thread_;+ scoped_ptr<thread> timer_thread_; // A waitable timer object used for waiting for timeouts. auto_handle waitable_timer_;@@ -329,7 +329,7 @@ const int concurrency_hint_; // The thread that is running the io_context.- asio::detail::thread thread_;+ scoped_ptr<thread> thread_; }; } // namespace detail
link/modules/asio-standalone/asio/include/asio/detail/win_iocp_null_buffers_op.hpp view
@@ -2,7 +2,7 @@ // detail/win_iocp_null_buffers_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -22,6 +22,7 @@ #include "asio/detail/bind_handler.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/reactor_op.hpp"@@ -45,7 +46,7 @@ &win_iocp_null_buffers_op::do_perform, &win_iocp_null_buffers_op::do_complete), cancel_token_(cancel_token),- handler_(static_cast<Handler&&>(handler)),+ handler_(ASIO_MOVE_CAST(Handler)(handler)), work_(handler_, io_ex) { }@@ -70,7 +71,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); // The reactor may have stored a result in the operation object.
link/modules/asio-standalone/asio/include/asio/detail/win_iocp_operation.hpp view
@@ -2,7 +2,7 @@ // detail/win_iocp_operation.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/win_iocp_overlapped_op.hpp view
@@ -2,7 +2,7 @@ // detail/win_iocp_overlapped_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -22,6 +22,7 @@ #include "asio/detail/bind_handler.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/operation.hpp"@@ -40,7 +41,7 @@ win_iocp_overlapped_op(Handler& handler, const IoExecutor& io_ex) : operation(&win_iocp_overlapped_op::do_complete),- handler_(static_cast<Handler&&>(handler)),+ handler_(ASIO_MOVE_CAST(Handler)(handler)), work_(handler_, io_ex) { }@@ -59,7 +60,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); ASIO_ERROR_LOCATION(ec);
link/modules/asio-standalone/asio/include/asio/detail/win_iocp_overlapped_ptr.hpp view
@@ -2,7 +2,7 @@ // detail/win_iocp_overlapped_ptr.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -47,11 +47,11 @@ // Construct an win_iocp_overlapped_ptr to contain the specified handler. template <typename Executor, typename Handler> explicit win_iocp_overlapped_ptr(const Executor& ex,- Handler&& handler)+ ASIO_MOVE_ARG(Handler) handler) : ptr_(0), iocp_service_(0) {- this->reset(ex, static_cast<Handler&&>(handler));+ this->reset(ex, ASIO_MOVE_CAST(Handler)(handler)); } // Destructor automatically frees the OVERLAPPED object unless released.@@ -134,9 +134,9 @@ private: template <typename Executor> static win_iocp_io_context* get_iocp_service(const Executor& ex,- enable_if_t<+ typename enable_if< can_query<const Executor&, execution::context_t>::value- >* = 0)+ >::type* = 0) { return &use_service<win_iocp_io_context>( asio::query(ex, execution::context));@@ -144,9 +144,9 @@ template <typename Executor> static win_iocp_io_context* get_iocp_service(const Executor& ex,- enable_if_t<+ typename enable_if< !can_query<const Executor&, execution::context_t>::value- >* = 0)+ >::type* = 0) { return &use_service<win_iocp_io_context>(ex.context()); }
link/modules/asio-standalone/asio/include/asio/detail/win_iocp_serial_port_service.hpp view
@@ -2,7 +2,7 @@ // detail/win_iocp_serial_port_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying
link/modules/asio-standalone/asio/include/asio/detail/win_iocp_socket_accept_op.hpp view
@@ -2,7 +2,7 @@ // detail/win_iocp_socket_accept_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -22,6 +22,7 @@ #include "asio/detail/bind_handler.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/operation.hpp"@@ -54,7 +55,7 @@ enable_connection_aborted_(enable_connection_aborted), proxy_op_(0), cancel_requested_(0),- handler_(static_cast<Handler&&>(handler)),+ handler_(ASIO_MOVE_CAST(Handler)(handler)), work_(handler_, io_ex) { }@@ -137,7 +138,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); ASIO_ERROR_LOCATION(ec);@@ -178,6 +179,8 @@ handler_work<Handler, IoExecutor> work_; }; +#if defined(ASIO_HAS_MOVE)+ template <typename Protocol, typename PeerIoExecutor, typename Handler, typename IoExecutor> class win_iocp_socket_move_accept_op : public operation@@ -199,7 +202,7 @@ enable_connection_aborted_(enable_connection_aborted), cancel_requested_(0), proxy_op_(0),- handler_(static_cast<Handler&&>(handler)),+ handler_(ASIO_MOVE_CAST(Handler)(handler)), work_(handler_, io_ex) { }@@ -283,7 +286,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); ASIO_ERROR_LOCATION(ec);@@ -296,8 +299,8 @@ // deallocated the memory here. detail::move_binder2<Handler, asio::error_code, peer_socket_type>- handler(0, static_cast<Handler&&>(o->handler_), ec,- static_cast<peer_socket_type&&>(o->peer_));+ handler(0, ASIO_MOVE_CAST(Handler)(o->handler_), ec,+ ASIO_MOVE_CAST(peer_socket_type)(o->peer_)); p.h = asio::detail::addressof(handler.handler_); p.reset(); @@ -328,6 +331,8 @@ Handler handler_; handler_work<Handler, IoExecutor> work_; };++#endif // defined(ASIO_HAS_MOVE) } // namespace detail } // namespace asio
link/modules/asio-standalone/asio/include/asio/detail/win_iocp_socket_connect_op.hpp view
@@ -2,7 +2,7 @@ // detail/win_iocp_socket_connect_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -22,6 +22,7 @@ #include "asio/detail/bind_handler.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/reactor_op.hpp"@@ -68,7 +69,7 @@ Handler& handler, const IoExecutor& io_ex) : win_iocp_socket_connect_op_base(socket, &win_iocp_socket_connect_op::do_complete),- handler_(static_cast<Handler&&>(handler)),+ handler_(ASIO_MOVE_CAST(Handler)(handler)), work_(handler_, io_ex) { }@@ -97,7 +98,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); ASIO_ERROR_LOCATION(ec);
link/modules/asio-standalone/asio/include/asio/detail/win_iocp_socket_recv_op.hpp view
@@ -2,7 +2,7 @@ // detail/win_iocp_socket_recv_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -23,6 +23,7 @@ #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/operation.hpp"@@ -48,7 +49,7 @@ state_(state), cancel_token_(cancel_token), buffers_(buffers),- handler_(static_cast<Handler&&>(handler)),+ handler_(ASIO_MOVE_CAST(Handler)(handler)), work_(handler_, io_ex) { }@@ -68,7 +69,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
link/modules/asio-standalone/asio/include/asio/detail/win_iocp_socket_recvfrom_op.hpp view
@@ -2,7 +2,7 @@ // detail/win_iocp_socket_recvfrom_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -23,6 +23,7 @@ #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/operation.hpp"@@ -50,7 +51,7 @@ endpoint_size_(static_cast<int>(endpoint.capacity())), cancel_token_(cancel_token), buffers_(buffers),- handler_(static_cast<Handler&&>(handler)),+ handler_(ASIO_MOVE_CAST(Handler)(handler)), work_(handler_, io_ex) { }@@ -76,7 +77,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
link/modules/asio-standalone/asio/include/asio/detail/win_iocp_socket_recvmsg_op.hpp view
@@ -1,8 +1,8 @@ // // detail/win_iocp_socket_recvmsg_op.hpp-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -23,6 +23,7 @@ #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/operation.hpp"@@ -50,7 +51,7 @@ cancel_token_(cancel_token), buffers_(buffers), out_flags_(out_flags),- handler_(static_cast<Handler&&>(handler)),+ handler_(ASIO_MOVE_CAST(Handler)(handler)), work_(handler_, io_ex) { }@@ -71,7 +72,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
link/modules/asio-standalone/asio/include/asio/detail/win_iocp_socket_send_op.hpp view
@@ -2,7 +2,7 @@ // detail/win_iocp_socket_send_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -23,6 +23,7 @@ #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/operation.hpp"@@ -46,7 +47,7 @@ : operation(&win_iocp_socket_send_op::do_complete), cancel_token_(cancel_token), buffers_(buffers),- handler_(static_cast<Handler&&>(handler)),+ handler_(ASIO_MOVE_CAST(Handler)(handler)), work_(handler_, io_ex) { }@@ -66,7 +67,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
link/modules/asio-standalone/asio/include/asio/detail/win_iocp_socket_service.hpp view
@@ -2,7 +2,7 @@ // detail/win_iocp_socket_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -27,6 +27,7 @@ #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/mutex.hpp" #include "asio/detail/operation.hpp"@@ -50,7 +51,7 @@ template <typename Protocol> class win_iocp_socket_service :- public execution_context_service_base<win_iocp_socket_service<Protocol>>,+ public execution_context_service_base<win_iocp_socket_service<Protocol> >, public win_iocp_socket_service_base { public:@@ -130,7 +131,7 @@ // Constructor. win_iocp_socket_service(execution_context& context) : execution_context_service_base<- win_iocp_socket_service<Protocol>>(context),+ win_iocp_socket_service<Protocol> >(context), win_iocp_socket_service_base(context) { }@@ -143,7 +144,7 @@ // Move-construct a new socket implementation. void move_construct(implementation_type& impl,- implementation_type& other_impl) noexcept+ implementation_type& other_impl) ASIO_NOEXCEPT { this->base_move_construct(impl, other_impl); @@ -348,7 +349,7 @@ socket_base::message_flags flags, Handler& handler, const IoExecutor& io_ex) {- associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -442,7 +443,7 @@ socket_base::message_flags flags, Handler& handler, const IoExecutor& io_ex) {- associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -474,7 +475,7 @@ endpoint_type& sender_endpoint, socket_base::message_flags flags, Handler& handler, const IoExecutor& io_ex) {- associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -547,7 +548,7 @@ void async_accept(implementation_type& impl, Socket& peer, endpoint_type* peer_endpoint, Handler& handler, const IoExecutor& io_ex) {- associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -579,6 +580,7 @@ p.v = p.p = 0; } +#if defined(ASIO_HAS_MOVE) // Start an asynchronous accept. The peer and peer_endpoint objects // must be valid until the accept's handler is invoked. template <typename PeerIoExecutor, typename Handler, typename IoExecutor>@@ -586,7 +588,7 @@ const PeerIoExecutor& peer_io_ex, endpoint_type* peer_endpoint, Handler& handler, const IoExecutor& io_ex) {- associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -618,6 +620,7 @@ p.p->address_length(), o); p.v = p.p = 0; }+#endif // defined(ASIO_HAS_MOVE) // Connect the socket to the specified endpoint. asio::error_code connect(implementation_type& impl,@@ -635,7 +638,7 @@ const endpoint_type& peer_endpoint, Handler& handler, const IoExecutor& io_ex) {- associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.
link/modules/asio-standalone/asio/include/asio/detail/win_iocp_socket_service_base.hpp view
@@ -2,7 +2,7 @@ // detail/win_iocp_socket_service_base.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -27,6 +27,7 @@ #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/mutex.hpp" #include "asio/detail/operation.hpp"@@ -95,7 +96,7 @@ // Move-construct a new socket implementation. ASIO_DECL void base_move_construct(base_implementation_type& impl,- base_implementation_type& other_impl) noexcept;+ base_implementation_type& other_impl) ASIO_NOEXCEPT; // Move-assign from another socket implementation. ASIO_DECL void base_move_assign(base_implementation_type& impl,@@ -213,7 +214,7 @@ void async_wait(base_implementation_type& impl, socket_base::wait_type w, Handler& handler, const IoExecutor& io_ex) {- associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); bool is_continuation =@@ -297,7 +298,7 @@ const ConstBufferSequence& buffers, socket_base::message_flags flags, Handler& handler, const IoExecutor& io_ex) {- associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -373,7 +374,7 @@ const MutableBufferSequence& buffers, socket_base::message_flags flags, Handler& handler, const IoExecutor& io_ex) {- associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -406,7 +407,7 @@ const null_buffers&, socket_base::message_flags flags, Handler& handler, const IoExecutor& io_ex) {- associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -477,7 +478,7 @@ socket_base::message_flags& out_flags, Handler& handler, const IoExecutor& io_ex) {- associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -509,7 +510,7 @@ socket_base::message_flags& out_flags, Handler& handler, const IoExecutor& io_ex) {- associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -808,7 +809,7 @@ // Pointer to NtSetInformationFile implementation. void* nt_set_info_; - // Mutex to protect access to the linked list of implementations.+ // Mutex to protect access to the linked list of implementations. asio::detail::mutex mutex_; // The head of a linked list of all implementations.
link/modules/asio-standalone/asio/include/asio/detail/win_iocp_thread_info.hpp view
@@ -2,7 +2,7 @@ // detail/win_iocp_thread_info.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/win_iocp_wait_op.hpp view
@@ -2,7 +2,7 @@ // detail/win_iocp_wait_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -23,6 +23,7 @@ #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/reactor_op.hpp"@@ -46,7 +47,7 @@ &win_iocp_wait_op::do_perform, &win_iocp_wait_op::do_complete), cancel_token_(cancel_token),- handler_(static_cast<Handler&&>(handler)),+ handler_(ASIO_MOVE_CAST(Handler)(handler)), work_(handler_, io_ex) { }@@ -71,7 +72,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); // The reactor may have stored a result in the operation object.
link/modules/asio-standalone/asio/include/asio/detail/win_mutex.hpp view
@@ -2,7 +2,7 @@ // detail/win_mutex.hpp // ~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -41,12 +41,6 @@ ~win_mutex() { ::DeleteCriticalSection(&crit_section_);- }-- // Try to lock the mutex.- bool try_lock()- {- return ::TryEnterCriticalSection(&crit_section_) != 0; } // Lock the mutex.
link/modules/asio-standalone/asio/include/asio/detail/win_object_handle_service.hpp view
@@ -2,7 +2,7 @@ // detail/win_object_handle_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2011 Boris Schaeling (boris@highscore.de) // // Distributed under the Boost Software License, Version 1.0. (See accompanying@@ -20,6 +20,7 @@ #if defined(ASIO_HAS_WINDOWS_OBJECT_HANDLE) +#include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/wait_handler.hpp" #include "asio/error.hpp"
link/modules/asio-standalone/asio/include/asio/detail/win_static_mutex.hpp view
@@ -2,7 +2,7 @@ // detail/win_static_mutex.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/win_thread.hpp view
@@ -2,7 +2,7 @@ // detail/win_thread.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -22,7 +22,7 @@ && !defined(UNDER_CE) #include <cstddef>-#include "asio/detail/memory.hpp"+#include "asio/detail/noncopyable.hpp" #include "asio/detail/socket_types.hpp" #include "asio/detail/push_options.hpp"@@ -60,55 +60,22 @@ long win_thread_base<T>::terminate_threads_ = 0; class win_thread- : public win_thread_base<win_thread>+ : private noncopyable,+ public win_thread_base<win_thread> { public:- // Construct in a non-joinable state.- win_thread() noexcept- : arg_(0)- {- }- // Constructor. template <typename Function> win_thread(Function f, unsigned int stack_size = 0)- : win_thread(std::allocator_arg, std::allocator<void>(), f, stack_size)- {- }-- // Construct with custom allocator.- template <typename Allocator, typename Function>- win_thread(allocator_arg_t, const Allocator& a,- Function f, unsigned int stack_size = 0)- : arg_(start_thread(allocate_object<func<Function, Allocator>>(a, f, a),- stack_size))- {- }-- // Move constructor.- win_thread(win_thread&& other) noexcept- : arg_(other.arg_)+ : thread_(0),+ exit_event_(0) {- other.arg_ = 0;+ start_thread(new func<Function>(f), stack_size); } // Destructor. ASIO_DECL ~win_thread(); - // Move assignment.- win_thread& operator=(win_thread&& other) noexcept- {- arg_ = other.arg_;- other.arg_ = 0;- return *this;- }-- // Whether the thread can be joined.- bool joinable() const- {- return !!arg_;- }- // Wait for the thread to exit. ASIO_DECL void join(); @@ -129,20 +96,23 @@ public: virtual ~func_base() {} virtual void run() = 0;- virtual void destroy() = 0;- ::HANDLE thread_; ::HANDLE entry_event_; ::HANDLE exit_event_; }; - template <typename Function, typename Allocator>+ struct auto_func_base_ptr+ {+ func_base* ptr;+ ~auto_func_base_ptr() { delete ptr; }+ };++ template <typename Function> class func : public func_base { public:- func(Function f, const Allocator& a)- : f_(f),- allocator_(a)+ func(Function f)+ : f_(f) { } @@ -151,20 +121,14 @@ f_(); } - virtual void destroy()- {- deallocate_object(allocator_, this);- }- private: Function f_;- Allocator allocator_; }; - ASIO_DECL func_base* start_thread(- func_base* arg, unsigned int stack_size);+ ASIO_DECL void start_thread(func_base* arg, unsigned int stack_size); - func_base* arg_;+ ::HANDLE thread_;+ ::HANDLE exit_event_; }; } // namespace detail
link/modules/asio-standalone/asio/include/asio/detail/win_tss_ptr.hpp view
@@ -2,7 +2,7 @@ // detail/win_tss_ptr.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/winapp_thread.hpp view
@@ -2,7 +2,7 @@ // detail/winapp_thread.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -19,7 +19,8 @@ #if defined(ASIO_WINDOWS) && defined(ASIO_WINDOWS_APP) -#include "asio/detail/memory.hpp"+#include "asio/detail/noncopyable.hpp"+#include "asio/detail/scoped_ptr.hpp" #include "asio/detail/socket_types.hpp" #include "asio/detail/throw_error.hpp" #include "asio/error.hpp"@@ -32,62 +33,37 @@ DWORD WINAPI winapp_thread_function(LPVOID arg); class winapp_thread+ : private noncopyable { public:- // Construct in a non-joinable state.- winapp_thread() noexcept- : arg_(0)- {- }- // Constructor. template <typename Function> winapp_thread(Function f, unsigned int = 0)- : winapp_thread(std::allocator_arg, std::allocator<void>(), f) {- }-- // Construct with custom allocator.- template <typename Allocator, typename Function>- winapp_thread(allocator_arg_t, const Allocator& a,- Function f, unsigned int = 0)- : arg_(start_thread(allocate_object<func<Function, Allocator>>(a, f, a)))- {- }-- // Move constructor.- winapp_thread(winapp_thread&& other) noexcept- : arg_(other.arg_)- {- other.arg_ = 0;+ scoped_ptr<func_base> arg(new func<Function>(f));+ DWORD thread_id = 0;+ thread_ = ::CreateThread(0, 0, winapp_thread_function,+ arg.get(), 0, &thread_id);+ if (!thread_)+ {+ DWORD last_error = ::GetLastError();+ asio::error_code ec(last_error,+ asio::error::get_system_category());+ asio::detail::throw_error(ec, "thread");+ }+ arg.release(); } // Destructor. ~winapp_thread() {- if (arg_)- std::terminate();- }-- // Move assignment.- winapp_thread& operator=(winapp_thread&& other) noexcept- {- arg_ = other.arg_;- other.arg_ = 0;- return *this;- }-- // Whether the thread can be joined.- bool joinable() const- {- return !!arg_;+ ::CloseHandle(thread_); } // Wait for the thread to exit. void join() {- if (arg_)- ::WaitForSingleObjectEx(arg_->thread_, INFINITE, false);+ ::WaitForSingleObjectEx(thread_, INFINITE, false); } // Get number of CPUs.@@ -106,18 +82,15 @@ public: virtual ~func_base() {} virtual void run() = 0;- virtual void destroy() = 0;- ::HANDLE thread_; }; - template <typename Function, typename Allocator>+ template <typename Function> class func : public func_base { public:- func(Function f, const Allocator& a)- : f_(f),- allocator_(a)+ func(Function f)+ : f_(f) { } @@ -126,38 +99,18 @@ f_(); } - virtual void destroy()- {- deallocate_object(allocator_, this);- }- private: Function f_;- Allocator allocator_; }; - func_base* start_thread(func_base* arg)- {- DWORD thread_id = 0;- arg->thread_ = ::CreateThread(0, 0,- winapp_thread_function, arg, 0, &thread_id);- if (!arg->thread_)- {- arg->destroy();- DWORD last_error = ::GetLastError();- asio::error_code ec(last_error,- asio::error::get_system_category());- asio::detail::throw_error(ec, "thread");- }- return arg;- }-- func_base* arg_;+ ::HANDLE thread_; }; inline DWORD WINAPI winapp_thread_function(LPVOID arg) {- static_cast<winapp_thread::func_base*>(arg)->run();+ scoped_ptr<winapp_thread::func_base> func(+ static_cast<winapp_thread::func_base*>(arg));+ func->run(); return 0; } @@ -166,6 +119,6 @@ #include "asio/detail/pop_options.hpp" -#endif // defined(ASIO_WINDOWS) && defined(UNDER_CE)+#endif // defined(ASIO_WINDOWS) && defined(ASIO_WINDOWS_APP) #endif // ASIO_DETAIL_WINAPP_THREAD_HPP
link/modules/asio-standalone/asio/include/asio/detail/wince_thread.hpp view
@@ -2,7 +2,7 @@ // detail/wince_thread.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -19,7 +19,8 @@ #if defined(ASIO_WINDOWS) && defined(UNDER_CE) -#include "asio/detail/memory.hpp"+#include "asio/detail/noncopyable.hpp"+#include "asio/detail/scoped_ptr.hpp" #include "asio/detail/socket_types.hpp" #include "asio/detail/throw_error.hpp" #include "asio/error.hpp"@@ -32,62 +33,37 @@ DWORD WINAPI wince_thread_function(LPVOID arg); class wince_thread+ : private noncopyable { public:- // Construct in a non-joinable state.- wince_thread() noexcept- : arg_(0)- {- }- // Constructor. template <typename Function> wince_thread(Function f, unsigned int = 0)- : wince_thread(std::allocator_arg, std::allocator<void>(), f) {- }-- // Construct with custom allocator.- template <typename Allocator, typename Function>- wince_thread(allocator_arg_t, const Allocator& a,- Function f, unsigned int = 0)- : arg_(start_thread(allocate_object<func<Function, Allocator>>(a, f, a)))- {- }-- // Move constructor.- wince_thread(wince_thread&& other) noexcept- : arg_(other.arg_)- {- other.arg_ = 0;+ scoped_ptr<func_base> arg(new func<Function>(f));+ DWORD thread_id = 0;+ thread_ = ::CreateThread(0, 0, wince_thread_function,+ arg.get(), 0, &thread_id);+ if (!thread_)+ {+ DWORD last_error = ::GetLastError();+ asio::error_code ec(last_error,+ asio::error::get_system_category());+ asio::detail::throw_error(ec, "thread");+ }+ arg.release(); } // Destructor. ~wince_thread() {- if (arg_)- std::terminate();- }-- // Move assignment.- wince_thread& operator=(wince_thread&& other) noexcept- {- arg_ = other.arg_;- other.arg_ = 0;- return *this;- }-- // Whether the thread can be joined.- bool joinable() const- {- return !!arg_;+ ::CloseHandle(thread_); } // Wait for the thread to exit. void join() {- if (arg_)- ::WaitForSingleObject(arg_->thread_, INFINITE);+ ::WaitForSingleObject(thread_, INFINITE); } // Get number of CPUs.@@ -106,18 +82,15 @@ public: virtual ~func_base() {} virtual void run() = 0;- virtual void destroy() = 0;- ::HANDLE thread_; }; - template <typename Function, typename Allocator>+ template <typename Function> class func : public func_base { public:- func(Function f, const Allocator& a)- : f_(f),- allocator_(a)+ func(Function f)+ : f_(f) { } @@ -126,38 +99,18 @@ f_(); } - virtual void destroy()- {- deallocate_object(allocator_, this);- }- private: Function f_;- Allocator allocator_; }; - func_base* start_thread(func_base* arg)- {- DWORD thread_id = 0;- arg->thread_ = ::CreateThread(0, 0,- wince_thread_function, arg, 0, &thread_id);- if (!arg->thread_)- {- arg->destroy();- DWORD last_error = ::GetLastError();- asio::error_code ec(last_error,- asio::error::get_system_category());- asio::detail::throw_error(ec, "thread");- }- return arg;- }-- func_base* arg_;+ ::HANDLE thread_; }; inline DWORD WINAPI wince_thread_function(LPVOID arg) {- static_cast<wince_thread::func_base*>(arg)->run();+ scoped_ptr<wince_thread::func_base> func(+ static_cast<wince_thread::func_base*>(arg));+ func->run(); return 0; }
link/modules/asio-standalone/asio/include/asio/detail/winrt_async_manager.hpp view
@@ -2,7 +2,7 @@ // detail/winrt_async_manager.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/winrt_async_op.hpp view
@@ -2,7 +2,7 @@ // detail/winrt_async_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/winrt_resolve_op.hpp view
@@ -2,7 +2,7 @@ // detail/winrt_resolve_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -22,6 +22,7 @@ #include "asio/detail/bind_handler.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/winrt_async_op.hpp"@@ -53,7 +54,7 @@ Windows::Networking::EndpointPair^>^>( &winrt_resolve_op::do_complete), query_(query),- handler_(static_cast<Handler&&>(handler)),+ handler_(ASIO_MOVE_CAST(Handler)(handler)), work_(handler_, io_ex) { }@@ -70,7 +71,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); results_type results = results_type();
link/modules/asio-standalone/asio/include/asio/detail/winrt_resolver_service.hpp view
@@ -2,7 +2,7 @@ // detail/winrt_resolver_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -42,7 +42,7 @@ template <typename Protocol> class winrt_resolver_service :- public execution_context_service_base<winrt_resolver_service<Protocol>>+ public execution_context_service_base<winrt_resolver_service<Protocol> > { public: // The implementation type of the resolver. A cancellation token is used to@@ -62,7 +62,7 @@ // Constructor. winrt_resolver_service(execution_context& context) : execution_context_service_base<- winrt_resolver_service<Protocol>>(context),+ winrt_resolver_service<Protocol> >(context), scheduler_(use_service<scheduler_impl>(context)), async_manager_(use_service<winrt_async_manager>(context)) {
link/modules/asio-standalone/asio/include/asio/detail/winrt_socket_connect_op.hpp view
@@ -2,7 +2,7 @@ // detail/winrt_socket_connect_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -23,6 +23,7 @@ #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/winrt_async_op.hpp"@@ -42,7 +43,7 @@ winrt_socket_connect_op(Handler& handler, const IoExecutor& io_ex) : winrt_async_op<void>(&winrt_socket_connect_op::do_complete),- handler_(static_cast<Handler&&>(handler)),+ handler_(ASIO_MOVE_CAST(Handler)(handler)), work_(handler_, io_ex) { }@@ -59,7 +60,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); // Make a copy of the handler so that the memory can be deallocated before
link/modules/asio-standalone/asio/include/asio/detail/winrt_socket_recv_op.hpp view
@@ -2,7 +2,7 @@ // detail/winrt_socket_recv_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -23,6 +23,7 @@ #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/winrt_async_op.hpp"@@ -45,7 +46,7 @@ : winrt_async_op<Windows::Storage::Streams::IBuffer^>( &winrt_socket_recv_op::do_complete), buffers_(buffers),- handler_(static_cast<Handler&&>(handler)),+ handler_(ASIO_MOVE_CAST(Handler)(handler)), work_(handler_, io_ex) { }@@ -62,7 +63,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
link/modules/asio-standalone/asio/include/asio/detail/winrt_socket_send_op.hpp view
@@ -2,7 +2,7 @@ // detail/winrt_socket_send_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -23,6 +23,7 @@ #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/winrt_async_op.hpp"@@ -44,7 +45,7 @@ Handler& handler, const IoExecutor& io_ex) : winrt_async_op<unsigned int>(&winrt_socket_send_op::do_complete), buffers_(buffers),- handler_(static_cast<Handler&&>(handler)),+ handler_(ASIO_MOVE_CAST(Handler)(handler)), work_(handler_, io_ex) { }@@ -61,7 +62,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- static_cast<handler_work<Handler, IoExecutor>&&>(+ ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)( o->work_)); #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
link/modules/asio-standalone/asio/include/asio/detail/winrt_ssocket_service.hpp view
@@ -2,7 +2,7 @@ // detail/winrt_ssocket_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -33,7 +33,7 @@ template <typename Protocol> class winrt_ssocket_service :- public execution_context_service_base<winrt_ssocket_service<Protocol>>,+ public execution_context_service_base<winrt_ssocket_service<Protocol> >, public winrt_ssocket_service_base { public:@@ -62,7 +62,7 @@ // Constructor. winrt_ssocket_service(execution_context& context)- : execution_context_service_base<winrt_ssocket_service<Protocol>>(context),+ : execution_context_service_base<winrt_ssocket_service<Protocol> >(context), winrt_ssocket_service_base(context) { }@@ -75,7 +75,7 @@ // Move-construct a new socket implementation. void move_construct(implementation_type& impl,- implementation_type& other_impl) noexcept+ implementation_type& other_impl) ASIO_NOEXCEPT { this->base_move_construct(impl, other_impl);
link/modules/asio-standalone/asio/include/asio/detail/winrt_ssocket_service_base.hpp view
@@ -2,7 +2,7 @@ // detail/winrt_ssocket_service_base.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -77,7 +77,7 @@ // Move-construct a new socket implementation. ASIO_DECL void base_move_construct(base_implementation_type& impl,- base_implementation_type& other_impl) noexcept;+ base_implementation_type& other_impl) ASIO_NOEXCEPT; // Move-assign from another socket implementation. ASIO_DECL void base_move_assign(base_implementation_type& impl,@@ -341,7 +341,7 @@ // The manager that keeps track of outstanding operations. winrt_async_manager& async_manager_; - // Mutex to protect access to the linked list of implementations.+ // Mutex to protect access to the linked list of implementations. asio::detail::mutex mutex_; // The head of a linked list of all implementations.
link/modules/asio-standalone/asio/include/asio/detail/winrt_timer_scheduler.hpp view
@@ -2,7 +2,7 @@ // detail/winrt_timer_scheduler.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -65,33 +65,32 @@ ASIO_DECL void init_task(); // Add a new timer queue to the reactor.- template <typename TimeTraits, typename Allocator>- void add_timer_queue(timer_queue<TimeTraits, Allocator>& queue);+ template <typename Time_Traits>+ void add_timer_queue(timer_queue<Time_Traits>& queue); // Remove a timer queue from the reactor.- template <typename TimeTraits, typename Allocator>- void remove_timer_queue(timer_queue<TimeTraits, Allocator>& queue);+ template <typename Time_Traits>+ void remove_timer_queue(timer_queue<Time_Traits>& queue); // Schedule a new operation in the given timer queue to expire at the // specified absolute time.- template <typename TimeTraits, typename Allocator>- void schedule_timer(timer_queue<TimeTraits, Allocator>& queue,- const typename TimeTraits::time_type& time,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,- wait_op* op);+ template <typename Time_Traits>+ void schedule_timer(timer_queue<Time_Traits>& queue,+ const typename Time_Traits::time_type& time,+ typename timer_queue<Time_Traits>::per_timer_data& timer, wait_op* op); // Cancel the timer operations associated with the given token. Returns the // number of operations that have been posted or dispatched.- template <typename TimeTraits, typename Allocator>- std::size_t cancel_timer(timer_queue<TimeTraits, Allocator>& queue,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,+ template <typename Time_Traits>+ std::size_t cancel_timer(timer_queue<Time_Traits>& queue,+ typename timer_queue<Time_Traits>::per_timer_data& timer, std::size_t max_cancelled = (std::numeric_limits<std::size_t>::max)()); // Move the timer operations associated with the given timer.- template <typename TimeTraits, typename Allocator>- void move_timer(timer_queue<TimeTraits, Allocator>& queue,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& to,- typename timer_queue<TimeTraits, Allocator>::per_timer_data& from);+ template <typename Time_Traits>+ void move_timer(timer_queue<Time_Traits>& queue,+ typename timer_queue<Time_Traits>::per_timer_data& to,+ typename timer_queue<Time_Traits>::per_timer_data& from); private: // Run the select loop in the thread.@@ -124,7 +123,7 @@ timer_queue_set timer_queues_; // The background thread that is waiting for timers to expire.- asio::detail::thread thread_;+ asio::detail::thread* thread_; // Does the background thread need to stop. bool stop_thread_;
link/modules/asio-standalone/asio/include/asio/detail/winrt_utils.hpp view
@@ -2,7 +2,7 @@ // detail/winrt_utils.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/detail/winsock_init.hpp view
@@ -2,7 +2,7 @@ // detail/winsock_init.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -47,7 +47,7 @@ ASIO_DECL static void throw_on_error(data& d); }; -template <int Major = 2, int Minor = 2>+template <int Major = 2, int Minor = 0> class winsock_init : private winsock_init_base { public:
link/modules/asio-standalone/asio/include/asio/detail/work_dispatcher.hpp view
@@ -2,7 +2,7 @@ // detail/work_dispatcher.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -39,13 +39,13 @@ template <typename Handler, typename Executor> struct is_work_dispatcher_required<Handler, Executor,- enable_if_t<+ typename enable_if< is_same< typename associated_executor<Handler, Executor>::asio_associated_executor_is_unspecialised, void >::value- >> : false_type+ >::type> : false_type { }; @@ -54,14 +54,15 @@ { public: template <typename CompletionHandler>- work_dispatcher(CompletionHandler&& handler,+ work_dispatcher(ASIO_MOVE_ARG(CompletionHandler) handler, const Executor& handler_ex)- : handler_(static_cast<CompletionHandler&&>(handler)),+ : handler_(ASIO_MOVE_CAST(CompletionHandler)(handler)), executor_(asio::prefer(handler_ex, execution::outstanding_work.tracked)) { } +#if defined(ASIO_HAS_MOVE) work_dispatcher(const work_dispatcher& other) : handler_(other.handler_), executor_(other.executor_)@@ -69,25 +70,34 @@ } work_dispatcher(work_dispatcher&& other)- : handler_(static_cast<Handler&&>(other.handler_)),- executor_(static_cast<work_executor_type&&>(other.executor_))+ : handler_(ASIO_MOVE_CAST(Handler)(other.handler_)),+ executor_(ASIO_MOVE_CAST(work_executor_type)(other.executor_)) { }+#endif // defined(ASIO_HAS_MOVE) void operator()() {- associated_allocator_t<Handler> alloc((get_associated_allocator)(handler_));+ typename associated_allocator<Handler>::type alloc(+ (get_associated_allocator)(handler_));+#if defined(ASIO_NO_DEPRECATED) asio::prefer(executor_, execution::allocator(alloc)).execute( asio::detail::bind_handler(- static_cast<Handler&&>(handler_)));+ ASIO_MOVE_CAST(Handler)(handler_)));+#else // defined(ASIO_NO_DEPRECATED)+ execution::execute(+ asio::prefer(executor_, execution::allocator(alloc)),+ asio::detail::bind_handler(+ ASIO_MOVE_CAST(Handler)(handler_)));+#endif // defined(ASIO_NO_DEPRECATED) } private:- typedef decay_t<- prefer_result_t<const Executor&,+ typedef typename decay<+ typename prefer_result<const Executor&, execution::outstanding_work_t::tracked_t- >- > work_executor_type;+ >::type+ >::type work_executor_type; Handler handler_; work_executor_type executor_;@@ -97,16 +107,18 @@ template <typename Handler, typename Executor> class work_dispatcher<Handler, Executor,- enable_if_t<!execution::is_executor<Executor>::value>>+ typename enable_if<!execution::is_executor<Executor>::value>::type> { public: template <typename CompletionHandler>- work_dispatcher(CompletionHandler&& handler, const Executor& handler_ex)+ work_dispatcher(ASIO_MOVE_ARG(CompletionHandler) handler,+ const Executor& handler_ex) : work_(handler_ex),- handler_(static_cast<CompletionHandler&&>(handler))+ handler_(ASIO_MOVE_CAST(CompletionHandler)(handler)) { } +#if defined(ASIO_HAS_MOVE) work_dispatcher(const work_dispatcher& other) : work_(other.work_), handler_(other.handler_)@@ -114,17 +126,19 @@ } work_dispatcher(work_dispatcher&& other)- : work_(static_cast<executor_work_guard<Executor>&&>(other.work_)),- handler_(static_cast<Handler&&>(other.handler_))+ : work_(ASIO_MOVE_CAST(executor_work_guard<Executor>)(other.work_)),+ handler_(ASIO_MOVE_CAST(Handler)(other.handler_)) { }+#endif // defined(ASIO_HAS_MOVE) void operator()() {- associated_allocator_t<Handler> alloc((get_associated_allocator)(handler_));+ typename associated_allocator<Handler>::type alloc(+ (get_associated_allocator)(handler_)); work_.get_executor().dispatch( asio::detail::bind_handler(- static_cast<Handler&&>(handler_)), alloc);+ ASIO_MOVE_CAST(Handler)(handler_)), alloc); work_.reset(); }
link/modules/asio-standalone/asio/include/asio/detail/wrapped_handler.hpp view
@@ -2,7 +2,7 @@ // detail/wrapped_handler.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -16,8 +16,9 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/bind_handler.hpp"+#include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_cont_helpers.hpp"-#include "asio/detail/initiate_dispatch.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/push_options.hpp" @@ -42,43 +43,20 @@ } }; -template <typename Dispatcher, typename = void>-struct wrapped_executor-{- typedef Dispatcher executor_type;-- static const Dispatcher& get(const Dispatcher& dispatcher) noexcept- {- return dispatcher;- }-};--template <typename Dispatcher>-struct wrapped_executor<Dispatcher,- void_type<typename Dispatcher::executor_type>>-{- typedef typename Dispatcher::executor_type executor_type;-- static executor_type get(const Dispatcher& dispatcher) noexcept- {- return dispatcher.get_executor();- }-};- template <typename Dispatcher, typename Handler, typename IsContinuation = is_continuation_delegated> class wrapped_handler { public: typedef void result_type;- typedef typename wrapped_executor<Dispatcher>::executor_type executor_type; wrapped_handler(Dispatcher dispatcher, Handler& handler) : dispatcher_(dispatcher),- handler_(static_cast<Handler&&>(handler))+ handler_(ASIO_MOVE_CAST(Handler)(handler)) { } +#if defined(ASIO_HAS_MOVE) wrapped_handler(const wrapped_handler& other) : dispatcher_(other.dispatcher_), handler_(other.handler_)@@ -87,85 +65,71 @@ wrapped_handler(wrapped_handler&& other) : dispatcher_(other.dispatcher_),- handler_(static_cast<Handler&&>(other.handler_))+ handler_(ASIO_MOVE_CAST(Handler)(other.handler_)) { }-- executor_type get_executor() const noexcept- {- return wrapped_executor<Dispatcher>::get(dispatcher_);- }+#endif // defined(ASIO_HAS_MOVE) void operator()() {- detail::initiate_dispatch_with_executor<executor_type>(- this->get_executor())(static_cast<Handler&&>(handler_));+ dispatcher_.dispatch(ASIO_MOVE_CAST(Handler)(handler_)); } void operator()() const {- detail::initiate_dispatch_with_executor<executor_type>(- this->get_executor())(handler_);+ dispatcher_.dispatch(handler_); } template <typename Arg1> void operator()(const Arg1& arg1) {- detail::initiate_dispatch_with_executor<executor_type>(- this->get_executor())(detail::bind_handler(handler_, arg1));+ dispatcher_.dispatch(detail::bind_handler(handler_, arg1)); } template <typename Arg1> void operator()(const Arg1& arg1) const {- detail::initiate_dispatch_with_executor<executor_type>(- this->get_executor())(detail::bind_handler(handler_, arg1));+ dispatcher_.dispatch(detail::bind_handler(handler_, arg1)); } template <typename Arg1, typename Arg2> void operator()(const Arg1& arg1, const Arg2& arg2) {- detail::initiate_dispatch_with_executor<executor_type>(- this->get_executor())(detail::bind_handler(handler_, arg1, arg2));+ dispatcher_.dispatch(detail::bind_handler(handler_, arg1, arg2)); } template <typename Arg1, typename Arg2> void operator()(const Arg1& arg1, const Arg2& arg2) const {- detail::initiate_dispatch_with_executor<executor_type>(- this->get_executor())(detail::bind_handler(handler_, arg1, arg2));+ dispatcher_.dispatch(detail::bind_handler(handler_, arg1, arg2)); } template <typename Arg1, typename Arg2, typename Arg3> void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3) {- detail::initiate_dispatch_with_executor<executor_type>(- this->get_executor())(detail::bind_handler(handler_, arg1, arg2, arg3));+ dispatcher_.dispatch(detail::bind_handler(handler_, arg1, arg2, arg3)); } template <typename Arg1, typename Arg2, typename Arg3> void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3) const {- detail::initiate_dispatch_with_executor<executor_type>(- this->get_executor())(detail::bind_handler(handler_, arg1, arg2, arg3));+ dispatcher_.dispatch(detail::bind_handler(handler_, arg1, arg2, arg3)); } template <typename Arg1, typename Arg2, typename Arg3, typename Arg4> void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, const Arg4& arg4) {- detail::initiate_dispatch_with_executor<executor_type>(- this->get_executor())(- detail::bind_handler(handler_, arg1, arg2, arg3, arg4));+ dispatcher_.dispatch(+ detail::bind_handler(handler_, arg1, arg2, arg3, arg4)); } template <typename Arg1, typename Arg2, typename Arg3, typename Arg4> void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, const Arg4& arg4) const {- detail::initiate_dispatch_with_executor<executor_type>(- this->get_executor())(- detail::bind_handler(handler_, arg1, arg2, arg3, arg4));+ dispatcher_.dispatch(+ detail::bind_handler(handler_, arg1, arg2, arg3, arg4)); } template <typename Arg1, typename Arg2, typename Arg3, typename Arg4,@@ -173,9 +137,8 @@ void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, const Arg4& arg4, const Arg5& arg5) {- detail::initiate_dispatch_with_executor<executor_type>(- this->get_executor())(- detail::bind_handler(handler_, arg1, arg2, arg3, arg4, arg5));+ dispatcher_.dispatch(+ detail::bind_handler(handler_, arg1, arg2, arg3, arg4, arg5)); } template <typename Arg1, typename Arg2, typename Arg3, typename Arg4,@@ -183,9 +146,8 @@ void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, const Arg4& arg4, const Arg5& arg5) const {- detail::initiate_dispatch_with_executor<executor_type>(- this->get_executor())(- detail::bind_handler(handler_, arg1, arg2, arg3, arg4, arg5));+ dispatcher_.dispatch(+ detail::bind_handler(handler_, arg1, arg2, arg3, arg4, arg5)); } //private:@@ -193,11 +155,168 @@ Handler handler_; }; +template <typename Handler, typename Context>+class rewrapped_handler+{+public:+ explicit rewrapped_handler(Handler& handler, const Context& context)+ : context_(context),+ handler_(ASIO_MOVE_CAST(Handler)(handler))+ {+ }++ explicit rewrapped_handler(const Handler& handler, const Context& context)+ : context_(context),+ handler_(handler)+ {+ }++#if defined(ASIO_HAS_MOVE)+ rewrapped_handler(const rewrapped_handler& other)+ : context_(other.context_),+ handler_(other.handler_)+ {+ }++ rewrapped_handler(rewrapped_handler&& other)+ : context_(ASIO_MOVE_CAST(Context)(other.context_)),+ handler_(ASIO_MOVE_CAST(Handler)(other.handler_))+ {+ }+#endif // defined(ASIO_HAS_MOVE)++ void operator()()+ {+ handler_();+ }++ void operator()() const+ {+ handler_();+ }++//private:+ Context context_;+ Handler handler_;+};+ template <typename Dispatcher, typename Handler, typename IsContinuation>+inline asio_handler_allocate_is_deprecated+asio_handler_allocate(std::size_t size,+ wrapped_handler<Dispatcher, Handler, IsContinuation>* this_handler)+{+#if defined(ASIO_NO_DEPRECATED)+ asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+ return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+ return asio_handler_alloc_helpers::allocate(+ size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Dispatcher, typename Handler, typename IsContinuation>+inline asio_handler_deallocate_is_deprecated+asio_handler_deallocate(void* pointer, std::size_t size,+ wrapped_handler<Dispatcher, Handler, IsContinuation>* this_handler)+{+ asio_handler_alloc_helpers::deallocate(+ pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Dispatcher, typename Handler, typename IsContinuation> inline bool asio_handler_is_continuation( wrapped_handler<Dispatcher, Handler, IsContinuation>* this_handler) { return IsContinuation()(this_handler->dispatcher_, this_handler->handler_);+}++template <typename Function, typename Dispatcher,+ typename Handler, typename IsContinuation>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(Function& function,+ wrapped_handler<Dispatcher, Handler, IsContinuation>* this_handler)+{+ this_handler->dispatcher_.dispatch(+ rewrapped_handler<Function, Handler>(+ function, this_handler->handler_));+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Function, typename Dispatcher,+ typename Handler, typename IsContinuation>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(const Function& function,+ wrapped_handler<Dispatcher, Handler, IsContinuation>* this_handler)+{+ this_handler->dispatcher_.dispatch(+ rewrapped_handler<Function, Handler>(+ function, this_handler->handler_));+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler, typename Context>+inline asio_handler_allocate_is_deprecated+asio_handler_allocate(std::size_t size,+ rewrapped_handler<Handler, Context>* this_handler)+{+#if defined(ASIO_NO_DEPRECATED)+ asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+ return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+ return asio_handler_alloc_helpers::allocate(+ size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler, typename Context>+inline asio_handler_deallocate_is_deprecated+asio_handler_deallocate(void* pointer, std::size_t size,+ rewrapped_handler<Handler, Context>* this_handler)+{+ asio_handler_alloc_helpers::deallocate(+ pointer, size, this_handler->context_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Dispatcher, typename Context>+inline bool asio_handler_is_continuation(+ rewrapped_handler<Dispatcher, Context>* this_handler)+{+ return asio_handler_cont_helpers::is_continuation(+ this_handler->context_);+}++template <typename Function, typename Handler, typename Context>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(Function& function,+ rewrapped_handler<Handler, Context>* this_handler)+{+ asio_handler_invoke_helpers::invoke(+ function, this_handler->context_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Function, typename Handler, typename Context>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(const Function& function,+ rewrapped_handler<Handler, Context>* this_handler)+{+ asio_handler_invoke_helpers::invoke(+ function, this_handler->context_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED) } } // namespace detail
link/modules/asio-standalone/asio/include/asio/dispatch.hpp view
@@ -2,7 +2,7 @@ // dispatch.hpp // ~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -69,10 +69,11 @@ * @code void() @endcode */ template <ASIO_COMPLETION_TOKEN_FOR(void()) NullaryToken>-inline auto dispatch(NullaryToken&& token)- -> decltype(+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(NullaryToken, void()) dispatch(+ ASIO_MOVE_ARG(NullaryToken) token)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<NullaryToken, void()>(- declval<detail::initiate_dispatch>(), token))+ declval<detail::initiate_dispatch>(), token))) { return async_initiate<NullaryToken, void()>( detail::initiate_dispatch(), token);@@ -142,15 +143,17 @@ */ template <typename Executor, ASIO_COMPLETION_TOKEN_FOR(void()) NullaryToken- = default_completion_token_t<Executor>>-inline auto dispatch(const Executor& ex,- NullaryToken&& token = default_completion_token_t<Executor>(),- constraint_t<+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(Executor)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(NullaryToken, void()) dispatch(+ const Executor& ex,+ ASIO_MOVE_ARG(NullaryToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(Executor),+ typename constraint< execution::is_executor<Executor>::value || is_executor<Executor>::value- > = 0)- -> decltype(+ >::type = 0)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<NullaryToken, void()>(- declval<detail::initiate_dispatch_with_executor<Executor>>(), token))+ declval<detail::initiate_dispatch_with_executor<Executor> >(), token))) { return async_initiate<NullaryToken, void()>( detail::initiate_dispatch_with_executor<Executor>(ex), token);@@ -172,17 +175,19 @@ */ template <typename ExecutionContext, ASIO_COMPLETION_TOKEN_FOR(void()) NullaryToken- = default_completion_token_t<typename ExecutionContext::executor_type>>-inline auto dispatch(ExecutionContext& ctx,- NullaryToken&& token = default_completion_token_t<- typename ExecutionContext::executor_type>(),- constraint_t<- is_convertible<ExecutionContext&, execution_context&>::value- > = 0)- -> decltype(+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+ typename ExecutionContext::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(NullaryToken, void()) dispatch(+ ExecutionContext& ctx,+ ASIO_MOVE_ARG(NullaryToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(+ typename ExecutionContext::executor_type),+ typename constraint<is_convertible<+ ExecutionContext&, execution_context&>::value>::type = 0)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<NullaryToken, void()>(- declval<detail::initiate_dispatch_with_executor<- typename ExecutionContext::executor_type>>(), token))+ declval<detail::initiate_dispatch_with_executor<+ typename ExecutionContext::executor_type> >(), token))) { return async_initiate<NullaryToken, void()>( detail::initiate_dispatch_with_executor<
− link/modules/asio-standalone/asio/include/asio/disposition.hpp
@@ -1,282 +0,0 @@-//-// disposition.hpp-// ~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef ASIO_DISPOSITION_HPP-#define ASIO_DISPOSITION_HPP--#if defined(_MSC_VER) && (_MSC_VER >= 1200)-# pragma once-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)--#include "asio/detail/config.hpp"-#include "asio/detail/throw_exception.hpp"-#include "asio/detail/type_traits.hpp"-#include "asio/error_code.hpp"-#include "asio/system_error.hpp"-#include <exception>--#include "asio/detail/push_options.hpp"--namespace asio {--/// Traits type to adapt arbitrary error types as dispositions.-/**- * This type may be specialised for user-defined types, to allow them to be- * treated as a disposition by asio.- *- * The primary trait is not defined.- */-#if defined(GENERATING_DOCUMENTATION)-template <typename T>-struct disposition_traits-{- /// Determine whether a disposition represents no error.- static bool not_an_error(const T& d) noexcept;-- /// Throw an exception if the disposition represents an error.- static void throw_exception(T d);-- /// Convert a disposition into an @c exception_ptr.- static std::exception_ptr to_exception_ptr(T d) noexcept;-};-#else // defined(GENERATING_DOCUMENTATION)-template <typename T>-struct disposition_traits;-#endif // defined(GENERATING_DOCUMENTATION)--namespace detail {--template <typename T, typename = void, typename = void,- typename = void, typename = void, typename = void, typename = void>-struct is_disposition_impl : false_type-{-};--template <typename T>-struct is_disposition_impl<T,- enable_if_t<- is_nothrow_default_constructible<T>::value- >,- enable_if_t<- is_nothrow_move_constructible<T>::value- >,- enable_if_t<- is_nothrow_move_assignable<T>::value- >,- enable_if_t<- is_same<- decltype(disposition_traits<T>::not_an_error(declval<const T&>())),- bool- >::value- >,- void_t<- decltype(disposition_traits<T>::throw_exception(declval<T>()))- >,- enable_if_t<- is_same<- decltype(disposition_traits<T>::to_exception_ptr(declval<T>())),- std::exception_ptr- >::value- >> : true_type-{-};--} // namespace detail--/// Trait used for testing whether a type satisfies the requirements of a-/// disposition.-/**- * To be a valid disposition, a type must be nothrow default-constructible,- * nothrow move-constructible, nothrow move-assignable, and there must be a- * specialisation of the disposition_traits template for the type that provides- * the following static member functions:- * @li @c not_an_error: Takes an argument of type <tt>const T&</tt> and returns- * a @c bool.- * @li @c throw_exception: Takes an argument of type <tt>T</tt>. The- * caller of this function must not pass a disposition value for which- * @c not_an_error returns true. This function must not return.- * @li @c to_exception_ptr: Takes an argument of type <tt>T</tt> and returns a- * value of type @c std::exception_ptr.- */-template <typename T>-struct is_disposition :-#if defined(GENERATING_DOCUMENTATION)- integral_constant<bool, automatically_determined>-#else // defined(GENERATING_DOCUMENTATION)- detail::is_disposition_impl<T>-#endif // defined(GENERATING_DOCUMENTATION)-{-};--#if defined(ASIO_HAS_VARIABLE_TEMPLATES)--template <typename T>-constexpr const bool is_disposition_v = is_disposition<T>::value;--#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)--#if defined(ASIO_HAS_CONCEPTS)--template <typename T>-ASIO_CONCEPT disposition = is_disposition<T>::value;--#define ASIO_DISPOSITION ::asio::disposition--#else // defined(ASIO_HAS_CONCEPTS)--#define ASIO_DISPOSITION typename--#endif // defined(ASIO_HAS_CONCEPTS)--/// Specialisation of @c disposition_traits for @c error_code.-template <>-struct disposition_traits<asio::error_code>-{- static bool not_an_error(const asio::error_code& ec) noexcept- {- return !ec;- }-- static void throw_exception(const asio::error_code& ec)- {- detail::throw_exception(asio::system_error(ec));- }-- static std::exception_ptr to_exception_ptr(- const asio::error_code& ec) noexcept- {- return ec- ? std::make_exception_ptr(asio::system_error(ec))- : nullptr;- }-};--/// Specialisation of @c disposition_traits for @c std::exception_ptr.-template <>-struct disposition_traits<std::exception_ptr>-{- static bool not_an_error(const std::exception_ptr& e) noexcept- {- return !e;- }-- static void throw_exception(std::exception_ptr e)- {- std::rethrow_exception(static_cast<std::exception_ptr&&>(e));- }-- static std::exception_ptr to_exception_ptr(std::exception_ptr e) noexcept- {- return e;- }-};--/// A tag type used to indicate the absence of an error.-struct no_error_t-{- /// Default constructor.- constexpr no_error_t()- {- }-- /// Equality operator.- friend constexpr bool operator==(- const no_error_t&, const no_error_t&) noexcept- {- return true;- }-- /// Inequality operator.- friend constexpr bool operator!=(- const no_error_t&, const no_error_t&) noexcept- {- return false;- }-- /// Equality operator, returns true if the disposition does not contain an- /// error.- template <ASIO_DISPOSITION Disposition>- friend constexpr constraint_t<is_disposition<Disposition>::value, bool>- operator==(const no_error_t&, const Disposition& d) noexcept- {- return disposition_traits<Disposition>::not_an_error(d);- }-- /// Equality operator, returns true if the disposition does not contain an- /// error.- template <ASIO_DISPOSITION Disposition>- friend constexpr constraint_t<is_disposition<Disposition>::value, bool>- operator==(const Disposition& d, const no_error_t&) noexcept- {- return disposition_traits<Disposition>::not_an_error(d);- }-- /// Inequality operator, returns true if the disposition contains an error.- template <ASIO_DISPOSITION Disposition>- friend constexpr constraint_t<is_disposition<Disposition>::value, bool>- operator!=(const no_error_t&, const Disposition& d) noexcept- {- return !disposition_traits<Disposition>::not_an_error(d);- }-- /// Inequality operator, returns true if the disposition contains an error.- template <ASIO_DISPOSITION Disposition>- friend constexpr constraint_t<is_disposition<Disposition>::value, bool>- operator!=(const Disposition& d, const no_error_t&) noexcept- {- return !disposition_traits<Disposition>::not_an_error(d);- }-};--/// A special value used to indicate the absence of an error.-ASIO_INLINE_VARIABLE constexpr no_error_t no_error;--/// Specialisation of @c disposition_traits for @c no_error_t.-template <>-struct disposition_traits<no_error_t>-{- static bool not_an_error(no_error_t) noexcept- {- return true;- }-- static void throw_exception(no_error_t)- {- }-- static std::exception_ptr to_exception_ptr(no_error_t) noexcept- {- return std::exception_ptr();- }-};--/// Helper function to throw an exception arising from a disposition.-template <typename Disposition>-inline void throw_exception(Disposition&& d,- constraint_t<is_disposition<decay_t<Disposition>>::value> = 0)-{- disposition_traits<decay_t<Disposition>>::throw_exception(- static_cast<Disposition&&>(d));-}--/// Helper function to convert a disposition to an @c exception_ptr.-template <typename Disposition>-inline std::exception_ptr to_exception_ptr(Disposition&& d,- constraint_t<is_disposition<decay_t<Disposition>>::value> = 0) noexcept-{- return disposition_traits<decay_t<Disposition>>::to_exception_ptr(- static_cast<Disposition&&>(d));-}--} // namespace asio--#include "asio/detail/pop_options.hpp"--#endif // ASIO_DISPOSITION_HPP
link/modules/asio-standalone/asio/include/asio/error.hpp view
@@ -2,7 +2,7 @@ // error.hpp // ~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -304,6 +304,7 @@ } // namespace error } // namespace asio +#if defined(ASIO_HAS_STD_SYSTEM_ERROR) namespace std { template<> struct is_error_code_enum<asio::error::basic_errors>@@ -327,6 +328,7 @@ }; } // namespace std+#endif // defined(ASIO_HAS_STD_SYSTEM_ERROR) namespace asio { namespace error {
link/modules/asio-standalone/asio/include/asio/error_code.hpp view
@@ -2,7 +2,7 @@ // error_code.hpp // ~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -16,17 +16,180 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"-#include <system_error> +#if defined(ASIO_HAS_STD_SYSTEM_ERROR)+# include <system_error>+#else // defined(ASIO_HAS_STD_SYSTEM_ERROR)+# include <string>+# include "asio/detail/noncopyable.hpp"+# if !defined(ASIO_NO_IOSTREAM)+# include <iosfwd>+# endif // !defined(ASIO_NO_IOSTREAM)+#endif // defined(ASIO_HAS_STD_SYSTEM_ERROR)+ #include "asio/detail/push_options.hpp" namespace asio { +#if defined(ASIO_HAS_STD_SYSTEM_ERROR)+ typedef std::error_category error_category;-typedef std::error_code error_code; +#else // defined(ASIO_HAS_STD_SYSTEM_ERROR)++/// Base class for all error categories.+class error_category : private noncopyable+{+public:+ /// Destructor.+ virtual ~error_category()+ {+ }++ /// Returns a string naming the error gategory.+ virtual const char* name() const = 0;++ /// Returns a string describing the error denoted by @c value.+ virtual std::string message(int value) const = 0;++ /// Equality operator to compare two error categories.+ bool operator==(const error_category& rhs) const+ {+ return this == &rhs;+ }++ /// Inequality operator to compare two error categories.+ bool operator!=(const error_category& rhs) const+ {+ return !(*this == rhs);+ }+};++#endif // defined(ASIO_HAS_STD_SYSTEM_ERROR)+ /// Returns the error category used for the system errors produced by asio. extern ASIO_DECL const error_category& system_category();++#if defined(ASIO_HAS_STD_SYSTEM_ERROR)++typedef std::error_code error_code;++#else // defined(ASIO_HAS_STD_SYSTEM_ERROR)++/// Class to represent an error code value.+class error_code+{+public:+ /// Default constructor.+ error_code()+ : value_(0),+ category_(&system_category())+ {+ }++ /// Construct with specific error code and category.+ error_code(int v, const error_category& c)+ : value_(v),+ category_(&c)+ {+ }++ /// Construct from an error code enum.+ template <typename ErrorEnum>+ error_code(ErrorEnum e)+ {+ *this = make_error_code(e);+ }++ /// Clear the error value to the default.+ void clear()+ {+ value_ = 0;+ category_ = &system_category();+ }++ /// Assign a new error value.+ void assign(int v, const error_category& c)+ {+ value_ = v;+ category_ = &c;+ }++ /// Get the error value.+ int value() const+ {+ return value_;+ }++ /// Get the error category.+ const error_category& category() const+ {+ return *category_;+ }++ /// Get the message associated with the error.+ std::string message() const+ {+ return category_->message(value_);+ }++ struct unspecified_bool_type_t+ {+ };++ typedef void (*unspecified_bool_type)(unspecified_bool_type_t);++ static void unspecified_bool_true(unspecified_bool_type_t) {}++ /// Operator returns non-null if there is a non-success error code.+ operator unspecified_bool_type() const+ {+ if (value_ == 0)+ return 0;+ else+ return &error_code::unspecified_bool_true;+ }++ /// Operator to test if the error represents success.+ bool operator!() const+ {+ return value_ == 0;+ }++ /// Equality operator to compare two error objects.+ friend bool operator==(const error_code& e1, const error_code& e2)+ {+ return e1.value_ == e2.value_ && e1.category_ == e2.category_;+ }++ /// Inequality operator to compare two error objects.+ friend bool operator!=(const error_code& e1, const error_code& e2)+ {+ return e1.value_ != e2.value_ || e1.category_ != e2.category_;+ }++private:+ // The value associated with the error code.+ int value_;++ // The category associated with the error code.+ const error_category* category_;+};++# if !defined(ASIO_NO_IOSTREAM)++/// Output an error code.+template <typename Elem, typename Traits>+std::basic_ostream<Elem, Traits>& operator<<(+ std::basic_ostream<Elem, Traits>& os, const error_code& ec)+{+ os << ec.category().name() << ':' << ec.value();+ return os;+}++# endif // !defined(ASIO_NO_IOSTREAM)++#endif // defined(ASIO_HAS_STD_SYSTEM_ERROR) } // namespace asio
link/modules/asio-standalone/asio/include/asio/execution.hpp view
@@ -2,7 +2,7 @@ // execution.hpp // ~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -20,14 +20,29 @@ #include "asio/execution/bad_executor.hpp" #include "asio/execution/blocking.hpp" #include "asio/execution/blocking_adaptation.hpp"+#include "asio/execution/bulk_execute.hpp"+#include "asio/execution/bulk_guarantee.hpp"+#include "asio/execution/connect.hpp" #include "asio/execution/context.hpp" #include "asio/execution/context_as.hpp"+#include "asio/execution/execute.hpp" #include "asio/execution/executor.hpp" #include "asio/execution/invocable_archetype.hpp" #include "asio/execution/mapping.hpp" #include "asio/execution/occupancy.hpp"+#include "asio/execution/operation_state.hpp" #include "asio/execution/outstanding_work.hpp" #include "asio/execution/prefer_only.hpp"+#include "asio/execution/receiver.hpp"+#include "asio/execution/receiver_invocation_error.hpp" #include "asio/execution/relationship.hpp"+#include "asio/execution/schedule.hpp"+#include "asio/execution/scheduler.hpp"+#include "asio/execution/sender.hpp"+#include "asio/execution/set_done.hpp"+#include "asio/execution/set_error.hpp"+#include "asio/execution/set_value.hpp"+#include "asio/execution/start.hpp"+#include "asio/execution/submit.hpp" #endif // ASIO_EXECUTION_HPP
link/modules/asio-standalone/asio/include/asio/execution/allocator.hpp view
@@ -2,7 +2,7 @@ // execution/allocator.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -18,6 +18,8 @@ #include "asio/detail/config.hpp" #include "asio/detail/type_traits.hpp" #include "asio/execution/executor.hpp"+#include "asio/execution/scheduler.hpp"+#include "asio/execution/sender.hpp" #include "asio/is_applicable_property.hpp" #include "asio/traits/query_static_constexpr_member.hpp" #include "asio/traits/static_query.hpp"@@ -35,9 +37,10 @@ template <typename ProtoAllocator> struct allocator_t {- /// The allocator_t property applies to executors.+ /// The allocator_t property applies to executors, senders, and schedulers. template <typename T>- static constexpr bool is_applicable_property_v = is_executor_v<T>;+ static constexpr bool is_applicable_property_v =+ is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>; /// The allocator_t property can be required. static constexpr bool is_requirable = true;@@ -75,12 +78,32 @@ struct allocator_t { #if defined(ASIO_HAS_VARIABLE_TEMPLATES)+# if defined(ASIO_NO_DEPRECATED) template <typename T>- static constexpr bool is_applicable_property_v = is_executor<T>::value;+ ASIO_STATIC_CONSTEXPR(bool,+ is_applicable_property_v = (+ is_executor<T>::value));+# else // defined(ASIO_NO_DEPRECATED)+ template <typename T>+ ASIO_STATIC_CONSTEXPR(bool,+ is_applicable_property_v = (+ is_executor<T>::value+ || conditional<+ is_executor<T>::value,+ false_type,+ is_sender<T>+ >::type::value+ || conditional<+ is_executor<T>::value,+ false_type,+ is_scheduler<T>+ >::type::value+ ));+# endif // defined(ASIO_NO_DEPRECATED) #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) - static constexpr bool is_requirable = true;- static constexpr bool is_preferable = true;+ ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);+ ASIO_STATIC_CONSTEXPR(bool, is_preferable = true); template <typename T> struct static_proxy@@ -89,17 +112,17 @@ struct type { template <typename P>- static constexpr auto query(P&& p)+ static constexpr auto query(ASIO_MOVE_ARG(P) p) noexcept( noexcept(- conditional_t<true, T, P>::query(static_cast<P&&>(p))+ conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p)) ) ) -> decltype(- conditional_t<true, T, P>::query(static_cast<P&&>(p))+ conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p)) ) {- return T::query(static_cast<P&&>(p));+ return T::query(ASIO_MOVE_CAST(P)(p)); } }; #else // defined(ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)@@ -115,19 +138,22 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T>- static constexpr typename query_static_constexpr_member<T>::result_type+ static ASIO_CONSTEXPR+ typename query_static_constexpr_member<T>::result_type static_query()- noexcept(query_static_constexpr_member<T>::is_noexcept)+ ASIO_NOEXCEPT_IF((+ query_static_constexpr_member<T>::is_noexcept)) { return query_static_constexpr_member<T>::value(); } template <typename E, typename T = decltype(allocator_t::static_query<E>())>- static constexpr const T static_query_v = allocator_t::static_query<E>();+ static ASIO_CONSTEXPR const T static_query_v+ = allocator_t::static_query<E>(); #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) - constexpr ProtoAllocator value() const+ ASIO_CONSTEXPR ProtoAllocator value() const { return a_; }@@ -135,7 +161,7 @@ private: friend struct allocator_t<void>; - explicit constexpr allocator_t(const ProtoAllocator& a)+ explicit ASIO_CONSTEXPR allocator_t(const ProtoAllocator& a) : a_(a) { }@@ -154,14 +180,34 @@ struct allocator_t<void> { #if defined(ASIO_HAS_VARIABLE_TEMPLATES)+# if defined(ASIO_NO_DEPRECATED) template <typename T>- static constexpr bool is_applicable_property_v = is_executor<T>::value;+ ASIO_STATIC_CONSTEXPR(bool,+ is_applicable_property_v = (+ is_executor<T>::value));+# else // defined(ASIO_NO_DEPRECATED)+ template <typename T>+ ASIO_STATIC_CONSTEXPR(bool,+ is_applicable_property_v = (+ is_executor<T>::value+ || conditional<+ is_executor<T>::value,+ false_type,+ is_sender<T>+ >::type::value+ || conditional<+ is_executor<T>::value,+ false_type,+ is_scheduler<T>+ >::type::value+ ));+# endif // defined(ASIO_NO_DEPRECATED) #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) - static constexpr bool is_requirable = true;- static constexpr bool is_preferable = true;+ ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);+ ASIO_STATIC_CONSTEXPR(bool, is_preferable = true); - constexpr allocator_t()+ ASIO_CONSTEXPR allocator_t() { } @@ -172,17 +218,17 @@ struct type { template <typename P>- static constexpr auto query(P&& p)+ static constexpr auto query(ASIO_MOVE_ARG(P) p) noexcept( noexcept(- conditional_t<true, T, P>::query(static_cast<P&&>(p))+ conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p)) ) ) -> decltype(- conditional_t<true, T, P>::query(static_cast<P&&>(p))+ conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p)) ) {- return T::query(static_cast<P&&>(p));+ return T::query(ASIO_MOVE_CAST(P)(p)); } }; #else // defined(ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)@@ -198,20 +244,23 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T>- static constexpr typename query_static_constexpr_member<T>::result_type+ static ASIO_CONSTEXPR+ typename query_static_constexpr_member<T>::result_type static_query()- noexcept(query_static_constexpr_member<T>::is_noexcept)+ ASIO_NOEXCEPT_IF((+ query_static_constexpr_member<T>::is_noexcept)) { return query_static_constexpr_member<T>::value(); } template <typename E, typename T = decltype(allocator_t::static_query<E>())>- static constexpr const T static_query_v = allocator_t::static_query<E>();+ static ASIO_CONSTEXPR const T static_query_v+ = allocator_t::static_query<E>(); #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename OtherProtoAllocator>- constexpr allocator_t<OtherProtoAllocator> operator()(+ ASIO_CONSTEXPR allocator_t<OtherProtoAllocator> operator()( const OtherProtoAllocator& a) const { return allocator_t<OtherProtoAllocator>(a);@@ -225,15 +274,44 @@ #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) -ASIO_INLINE_VARIABLE constexpr allocator_t<void> allocator;+#if defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)+constexpr allocator_t<void> allocator;+#else // defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)+template <typename T>+struct allocator_instance+{+ static allocator_t<T> instance;+}; +template <typename T>+allocator_t<T> allocator_instance<T>::instance;++namespace {+static const allocator_t<void>& allocator = allocator_instance<void>::instance;+} // namespace+#endif+ } // namespace execution #if !defined(ASIO_HAS_VARIABLE_TEMPLATES) template <typename T, typename ProtoAllocator>-struct is_applicable_property<T, execution::allocator_t<ProtoAllocator>>- : integral_constant<bool, execution::is_executor<T>::value>+struct is_applicable_property<T, execution::allocator_t<ProtoAllocator> >+ : integral_constant<bool,+ execution::is_executor<T>::value+#if !defined(ASIO_NO_DEPRECATED)+ || conditional<+ execution::is_executor<T>::value,+ false_type,+ execution::is_sender<T>+ >::type::value+ || conditional<+ execution::is_executor<T>::value,+ false_type,+ execution::is_scheduler<T>+ >::type::value+#endif // !defined(ASIO_NO_DEPRECATED)+ > { }; @@ -246,18 +324,18 @@ template <typename T, typename ProtoAllocator> struct static_query<T, execution::allocator_t<ProtoAllocator>,- enable_if_t<+ typename enable_if< execution::allocator_t<ProtoAllocator>::template query_static_constexpr_member<T>::is_valid- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef typename execution::allocator_t<ProtoAllocator>::template query_static_constexpr_member<T>::result_type result_type; - static constexpr result_type value()+ static ASIO_CONSTEXPR result_type value() { return execution::allocator_t<ProtoAllocator>::template query_static_constexpr_member<T>::value();
link/modules/asio-standalone/asio/include/asio/execution/any_executor.hpp view
@@ -2,1924 +2,2654 @@ // execution/any_executor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef ASIO_EXECUTION_ANY_EXECUTOR_HPP-#define ASIO_EXECUTION_ANY_EXECUTOR_HPP--#if defined(_MSC_VER) && (_MSC_VER >= 1200)-# pragma once-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)--#include "asio/detail/config.hpp"-#include <new>-#include <typeinfo>-#include "asio/detail/assert.hpp"-#include "asio/detail/atomic_count.hpp"-#include "asio/detail/cstddef.hpp"-#include "asio/detail/executor_function.hpp"-#include "asio/detail/memory.hpp"-#include "asio/detail/non_const_lvalue.hpp"-#include "asio/detail/scoped_ptr.hpp"-#include "asio/detail/type_traits.hpp"-#include "asio/detail/throw_exception.hpp"-#include "asio/execution/bad_executor.hpp"-#include "asio/execution/blocking.hpp"-#include "asio/execution/executor.hpp"-#include "asio/prefer.hpp"-#include "asio/query.hpp"-#include "asio/require.hpp"--#include "asio/detail/push_options.hpp"--namespace asio {--#if defined(GENERATING_DOCUMENTATION)--namespace execution {--/// Polymorphic executor wrapper.-template <typename... SupportableProperties>-class any_executor-{-public:- /// Default constructor.- any_executor() noexcept;-- /// Construct in an empty state. Equivalent effects to default constructor.- any_executor(nullptr_t) noexcept;-- /// Copy constructor.- any_executor(const any_executor& e) noexcept;-- /// Move constructor.- any_executor(any_executor&& e) noexcept;-- /// Construct to point to the same target as another any_executor.- template <class... OtherSupportableProperties>- any_executor(any_executor<OtherSupportableProperties...> e);-- /// Construct to point to the same target as another any_executor.- template <class... OtherSupportableProperties>- any_executor(std::nothrow_t,- any_executor<OtherSupportableProperties...> e) noexcept;-- /// Construct to point to the same target as another any_executor.- any_executor(std::nothrow_t, const any_executor& e) noexcept;-- /// Construct to point to the same target as another any_executor.- any_executor(std::nothrow_t, any_executor&& e) noexcept;-- /// Construct a polymorphic wrapper for the specified executor.- template <typename Executor>- any_executor(Executor e);-- /// Construct a polymorphic wrapper for the specified executor.- template <typename Executor>- any_executor(std::nothrow_t, Executor e) noexcept;-- /// Assignment operator.- any_executor& operator=(const any_executor& e) noexcept;-- /// Move assignment operator.- any_executor& operator=(any_executor&& e) noexcept;-- /// Assignment operator that sets the polymorphic wrapper to the empty state.- any_executor& operator=(nullptr_t);-- /// Assignment operator to create a polymorphic wrapper for the specified- /// executor.- template <typename Executor>- any_executor& operator=(Executor e);-- /// Destructor.- ~any_executor();-- /// Swap targets with another polymorphic wrapper.- void swap(any_executor& other) noexcept;-- /// Obtain a polymorphic wrapper with the specified property.- /**- * Do not call this function directly. It is intended for use with the- * asio::require and asio::prefer customisation points.- *- * For example:- * @code execution::any_executor<execution::blocking_t::possibly_t> ex = ...;- * auto ex2 = asio::require(ex, execution::blocking.possibly); @endcode- */- template <typename Property>- any_executor require(Property) const;-- /// Obtain a polymorphic wrapper with the specified property.- /**- * Do not call this function directly. It is intended for use with the- * asio::prefer customisation point.- *- * For example:- * @code execution::any_executor<execution::blocking_t::possibly_t> ex = ...;- * auto ex2 = asio::prefer(ex, execution::blocking.possibly); @endcode- */- template <typename Property>- any_executor prefer(Property) const;-- /// Obtain the value associated with the specified property.- /**- * Do not call this function directly. It is intended for use with the- * asio::query customisation point.- *- * For example:- * @code execution::any_executor<execution::occupancy_t> ex = ...;- * size_t n = asio::query(ex, execution::occupancy); @endcode- */- template <typename Property>- typename Property::polymorphic_query_result_type query(Property) const;-- /// Execute the function on the target executor.- /**- * Throws asio::bad_executor if the polymorphic wrapper has no target.- */- template <typename Function>- void execute(Function&& f) const;-- /// Obtain the underlying execution context.- /**- * This function is provided for backward compatibility. It is automatically- * defined when the @c SupportableProperties... list includes a property of- * type <tt>execution::context_as<U></tt>, for some type <tt>U</tt>.- */- automatically_determined context() const;-- /// Determine whether the wrapper has a target executor.- /**- * @returns @c true if the polymorphic wrapper has a target executor,- * otherwise false.- */- explicit operator bool() const noexcept;-- /// Get the type of the target executor.- const type_info& target_type() const noexcept;-- /// Get a pointer to the target executor.- template <typename Executor> Executor* target() noexcept;-- /// Get a pointer to the target executor.- template <typename Executor> const Executor* target() const noexcept;-};--/// Equality operator.-/**- * @relates any_executor- */-template <typename... SupportableProperties>-bool operator==(const any_executor<SupportableProperties...>& a,- const any_executor<SupportableProperties...>& b) noexcept;--/// Equality operator.-/**- * @relates any_executor- */-template <typename... SupportableProperties>-bool operator==(const any_executor<SupportableProperties...>& a,- nullptr_t) noexcept;--/// Equality operator.-/**- * @relates any_executor- */-template <typename... SupportableProperties>-bool operator==(nullptr_t,- const any_executor<SupportableProperties...>& b) noexcept;--/// Inequality operator.-/**- * @relates any_executor- */-template <typename... SupportableProperties>-bool operator!=(const any_executor<SupportableProperties...>& a,- const any_executor<SupportableProperties...>& b) noexcept;--/// Inequality operator.-/**- * @relates any_executor- */-template <typename... SupportableProperties>-bool operator!=(const any_executor<SupportableProperties...>& a,- nullptr_t) noexcept;--/// Inequality operator.-/**- * @relates any_executor- */-template <typename... SupportableProperties>-bool operator!=(nullptr_t,- const any_executor<SupportableProperties...>& b) noexcept;--} // namespace execution--#else // defined(GENERATING_DOCUMENTATION)--namespace execution {--#if !defined(ASIO_EXECUTION_ANY_EXECUTOR_FWD_DECL)-#define ASIO_EXECUTION_ANY_EXECUTOR_FWD_DECL--template <typename... SupportableProperties>-class any_executor;--#endif // !defined(ASIO_EXECUTION_ANY_EXECUTOR_FWD_DECL)--template <typename U>-struct context_as_t;--namespace detail {--// Traits used to detect whether a property is requirable or preferable, taking-// into account that T::is_requirable or T::is_preferable may not not be well-// formed.--template <typename T, typename = void>-struct is_requirable : false_type {};--template <typename T>-struct is_requirable<T, enable_if_t<T::is_requirable>> : true_type {};--template <typename T, typename = void>-struct is_preferable : false_type {};--template <typename T>-struct is_preferable<T, enable_if_t<T::is_preferable>> : true_type {};--// Trait used to detect context_as property, for backward compatibility.--template <typename T>-struct is_context_as : false_type {};--template <typename U>-struct is_context_as<context_as_t<U>> : true_type {};--// Helper template to:-// - Check if a target can supply the supportable properties.-// - Find the first convertible-from-T property in the list.--template <std::size_t I, typename Props>-struct supportable_properties;--template <std::size_t I, typename Prop>-struct supportable_properties<I, void(Prop)>-{- template <typename T>- struct is_valid_target : integral_constant<bool,- (- is_requirable<Prop>::value- ? can_require<T, Prop>::value- : true- )- &&- (- is_preferable<Prop>::value- ? can_prefer<T, Prop>::value- : true- )- &&- (- !is_requirable<Prop>::value && !is_preferable<Prop>::value- ? can_query<T, Prop>::value- : true- )- >- {- };-- struct found- {- static constexpr bool value = true;- typedef Prop type;- typedef typename Prop::polymorphic_query_result_type query_result_type;- static constexpr std::size_t index = I;- };-- struct not_found- {- static constexpr bool value = false;- };-- template <typename T>- struct find_convertible_property :- conditional_t<- is_same<T, Prop>::value || is_convertible<T, Prop>::value,- found,- not_found- > {};-- template <typename T>- struct find_convertible_requirable_property :- conditional_t<- is_requirable<Prop>::value- && (is_same<T, Prop>::value || is_convertible<T, Prop>::value),- found,- not_found- > {};-- template <typename T>- struct find_convertible_preferable_property :- conditional_t<- is_preferable<Prop>::value- && (is_same<T, Prop>::value || is_convertible<T, Prop>::value),- found,- not_found- > {};-- struct find_context_as_property :- conditional_t<- is_context_as<Prop>::value,- found,- not_found- > {};-};--template <std::size_t I, typename Head, typename... Tail>-struct supportable_properties<I, void(Head, Tail...)>-{- template <typename T>- struct is_valid_target : integral_constant<bool,- (- supportable_properties<I,- void(Head)>::template is_valid_target<T>::value- &&- supportable_properties<I + 1,- void(Tail...)>::template is_valid_target<T>::value- )- >- {- };-- template <typename T>- struct find_convertible_property :- conditional_t<- is_convertible<T, Head>::value,- typename supportable_properties<I, void(Head)>::found,- typename supportable_properties<I + 1,- void(Tail...)>::template find_convertible_property<T>- > {};-- template <typename T>- struct find_convertible_requirable_property :- conditional_t<- is_requirable<Head>::value- && is_convertible<T, Head>::value,- typename supportable_properties<I, void(Head)>::found,- typename supportable_properties<I + 1,- void(Tail...)>::template find_convertible_requirable_property<T>- > {};-- template <typename T>- struct find_convertible_preferable_property :- conditional_t<- is_preferable<Head>::value- && is_convertible<T, Head>::value,- typename supportable_properties<I, void(Head)>::found,- typename supportable_properties<I + 1,- void(Tail...)>::template find_convertible_preferable_property<T>- > {};-- struct find_context_as_property :- conditional_t<- is_context_as<Head>::value,- typename supportable_properties<I, void(Head)>::found,- typename supportable_properties<I + 1,- void(Tail...)>::find_context_as_property- > {};-};--template <typename T, typename Props>-struct is_valid_target_executor :- conditional_t<- is_executor<T>::value,- typename supportable_properties<0, Props>::template is_valid_target<T>,- false_type- >-{-};--template <typename Props>-struct is_valid_target_executor<int, Props> : false_type-{-};--class shared_target_executor-{-public:- template <typename E>- shared_target_executor(E&& e, decay_t<E>*& target)- {- impl<decay_t<E>>* i =- new impl<decay_t<E>>(static_cast<E&&>(e));- target = &i->ex_;- impl_ = i;- }-- template <typename E>- shared_target_executor(std::nothrow_t, E&& e, decay_t<E>*& target) noexcept- {- impl<decay_t<E>>* i =- new (std::nothrow) impl<decay_t<E>>(static_cast<E&&>(e));- target = i ? &i->ex_ : 0;- impl_ = i;- }-- shared_target_executor(const shared_target_executor& other) noexcept- : impl_(other.impl_)- {- if (impl_)- asio::detail::ref_count_up(impl_->ref_count_);- }-- shared_target_executor(shared_target_executor&& other) noexcept- : impl_(other.impl_)- {- other.impl_ = 0;- }-- ~shared_target_executor()- {- if (impl_)- if (asio::detail::ref_count_down(impl_->ref_count_))- delete impl_;- }-- void* get() const noexcept- {- return impl_ ? impl_->get() : 0;- }--private:- shared_target_executor& operator=(- const shared_target_executor& other) = delete;-- shared_target_executor& operator=(- shared_target_executor&& other) = delete;-- struct impl_base- {- impl_base() : ref_count_(1) {}- virtual ~impl_base() {}- virtual void* get() = 0;- asio::detail::atomic_count ref_count_;- };-- template <typename Executor>- struct impl : impl_base- {- impl(Executor ex) : ex_(static_cast<Executor&&>(ex)) {}- virtual void* get() { return &ex_; }- Executor ex_;- };-- impl_base* impl_;-};--class any_executor_base-{-public:- any_executor_base() noexcept- : object_fns_(0),- target_(0),- target_fns_(0)- {- }-- template <ASIO_EXECUTION_EXECUTOR Executor>- any_executor_base(Executor ex, false_type)- : target_fns_(target_fns_table<Executor>(- any_executor_base::query_blocking(ex,- can_query<const Executor&, const execution::blocking_t&>())- == execution::blocking.always))- {- any_executor_base::construct_object(ex,- integral_constant<bool,- sizeof(Executor) <= sizeof(object_type)- && alignment_of<Executor>::value <= alignment_of<object_type>::value- >());- }-- template <ASIO_EXECUTION_EXECUTOR Executor>- any_executor_base(std::nothrow_t, Executor ex, false_type) noexcept- : target_fns_(target_fns_table<Executor>(- any_executor_base::query_blocking(ex,- can_query<const Executor&, const execution::blocking_t&>())- == execution::blocking.always))- {- any_executor_base::construct_object(std::nothrow, ex,- integral_constant<bool,- sizeof(Executor) <= sizeof(object_type)- && alignment_of<Executor>::value <= alignment_of<object_type>::value- >());- if (target_ == 0)- {- object_fns_ = 0;- target_fns_ = 0;- }- }-- template <ASIO_EXECUTION_EXECUTOR Executor>- any_executor_base(Executor other, true_type)- : object_fns_(object_fns_table<shared_target_executor>()),- target_fns_(other.target_fns_)- {- Executor* p = 0;- new (&object_) shared_target_executor(- static_cast<Executor&&>(other), p);- target_ = p->template target<void>();- }-- template <ASIO_EXECUTION_EXECUTOR Executor>- any_executor_base(std::nothrow_t,- Executor other, true_type) noexcept- : object_fns_(object_fns_table<shared_target_executor>()),- target_fns_(other.target_fns_)- {- Executor* p = 0;- new (&object_) shared_target_executor(- std::nothrow, static_cast<Executor&&>(other), p);- if (p)- target_ = p->template target<void>();- else- {- target_ = 0;- object_fns_ = 0;- target_fns_ = 0;- }- }-- any_executor_base(const any_executor_base& other) noexcept- {- if (!!other)- {- object_fns_ = other.object_fns_;- target_fns_ = other.target_fns_;- object_fns_->copy(*this, other);- }- else- {- object_fns_ = 0;- target_ = 0;- target_fns_ = 0;- }- }-- ~any_executor_base() noexcept- {- if (!!*this)- object_fns_->destroy(*this);- }-- any_executor_base& operator=(- const any_executor_base& other) noexcept- {- if (this != &other)- {- if (!!*this)- object_fns_->destroy(*this);- if (!!other)- {- object_fns_ = other.object_fns_;- target_fns_ = other.target_fns_;- object_fns_->copy(*this, other);- }- else- {- object_fns_ = 0;- target_ = 0;- target_fns_ = 0;- }- }- return *this;- }-- any_executor_base& operator=(nullptr_t) noexcept- {- if (target_)- object_fns_->destroy(*this);- target_ = 0;- object_fns_ = 0;- target_fns_ = 0;- return *this;- }-- any_executor_base(any_executor_base&& other) noexcept- {- if (other.target_)- {- object_fns_ = other.object_fns_;- target_fns_ = other.target_fns_;- other.object_fns_ = 0;- other.target_fns_ = 0;- object_fns_->move(*this, other);- other.target_ = 0;- }- else- {- object_fns_ = 0;- target_ = 0;- target_fns_ = 0;- }- }-- any_executor_base& operator=(- any_executor_base&& other) noexcept- {- if (this != &other)- {- if (!!*this)- object_fns_->destroy(*this);- if (!!other)- {- object_fns_ = other.object_fns_;- target_fns_ = other.target_fns_;- other.object_fns_ = 0;- other.target_fns_ = 0;- object_fns_->move(*this, other);- other.target_ = 0;- }- else- {- object_fns_ = 0;- target_ = 0;- target_fns_ = 0;- }- }- return *this;- }-- void swap(any_executor_base& other) noexcept- {- if (this != &other)- {- any_executor_base tmp(static_cast<any_executor_base&&>(other));- other = static_cast<any_executor_base&&>(*this);- *this = static_cast<any_executor_base&&>(tmp);- }- }-- template <typename F>- void execute(F&& f) const- {- if (target_)- {- if (target_fns_->blocking_execute != 0)- {- asio::detail::non_const_lvalue<F> f2(f);- target_fns_->blocking_execute(*this, function_view(f2.value));- }- else- {- target_fns_->execute(*this,- function(static_cast<F&&>(f), std::allocator<void>()));- }- }- else- {- bad_executor ex;- asio::detail::throw_exception(ex);- }- }-- template <typename Executor>- Executor* target()- {- return target_ && (is_same<Executor, void>::value- || target_fns_->target_type() == target_type_ex<Executor>())- ? static_cast<Executor*>(target_) : 0;- }-- template <typename Executor>- const Executor* target() const- {- return target_ && (is_same<Executor, void>::value- || target_fns_->target_type() == target_type_ex<Executor>())- ? static_cast<const Executor*>(target_) : 0;- }--#if !defined(ASIO_NO_TYPEID)- const std::type_info& target_type() const- {- return target_ ? target_fns_->target_type() : typeid(void);- }-#else // !defined(ASIO_NO_TYPEID)- const void* target_type() const- {- return target_ ? target_fns_->target_type() : 0;- }-#endif // !defined(ASIO_NO_TYPEID)-- struct unspecified_bool_type_t {};- typedef void (*unspecified_bool_type)(unspecified_bool_type_t);- static void unspecified_bool_true(unspecified_bool_type_t) {}-- operator unspecified_bool_type() const noexcept- {- return target_ ? &any_executor_base::unspecified_bool_true : 0;- }-- bool operator!() const noexcept- {- return target_ == 0;- }--protected:- bool equality_helper(const any_executor_base& other) const noexcept- {- if (target_ == other.target_)- return true;- if (target_ && !other.target_)- return false;- if (!target_ && other.target_)- return false;- if (target_fns_ != other.target_fns_)- return false;- return target_fns_->equal(*this, other);- }-- template <typename Ex>- Ex& object()- {- return *static_cast<Ex*>(static_cast<void*>(&object_));- }-- template <typename Ex>- const Ex& object() const- {- return *static_cast<const Ex*>(static_cast<const void*>(&object_));- }-- struct object_fns- {- void (*destroy)(any_executor_base&);- void (*copy)(any_executor_base&, const any_executor_base&);- void (*move)(any_executor_base&, any_executor_base&);- const void* (*target)(const any_executor_base&);- };-- static void destroy_shared(any_executor_base& ex)- {- typedef shared_target_executor type;- ex.object<type>().~type();- }-- static void copy_shared(any_executor_base& ex1, const any_executor_base& ex2)- {- typedef shared_target_executor type;- new (&ex1.object_) type(ex2.object<type>());- ex1.target_ = ex2.target_;- }-- static void move_shared(any_executor_base& ex1, any_executor_base& ex2)- {- typedef shared_target_executor type;- new (&ex1.object_) type(static_cast<type&&>(ex2.object<type>()));- ex1.target_ = ex2.target_;- ex2.object<type>().~type();- }-- static const void* target_shared(const any_executor_base& ex)- {- typedef shared_target_executor type;- return ex.object<type>().get();- }-- template <typename Obj>- static const object_fns* object_fns_table(- enable_if_t<- is_same<Obj, shared_target_executor>::value- >* = 0)- {- static const object_fns fns =- {- &any_executor_base::destroy_shared,- &any_executor_base::copy_shared,- &any_executor_base::move_shared,- &any_executor_base::target_shared- };- return &fns;- }-- template <typename Obj>- static void destroy_object(any_executor_base& ex)- {- ex.object<Obj>().~Obj();- }-- template <typename Obj>- static void copy_object(any_executor_base& ex1, const any_executor_base& ex2)- {- new (&ex1.object_) Obj(ex2.object<Obj>());- ex1.target_ = &ex1.object<Obj>();- }-- template <typename Obj>- static void move_object(any_executor_base& ex1, any_executor_base& ex2)- {- new (&ex1.object_) Obj(static_cast<Obj&&>(ex2.object<Obj>()));- ex1.target_ = &ex1.object<Obj>();- ex2.object<Obj>().~Obj();- }-- template <typename Obj>- static const void* target_object(const any_executor_base& ex)- {- return &ex.object<Obj>();- }-- template <typename Obj>- static const object_fns* object_fns_table(- enable_if_t<- !is_same<Obj, void>::value- && !is_same<Obj, shared_target_executor>::value- >* = 0)- {- static const object_fns fns =- {- &any_executor_base::destroy_object<Obj>,- &any_executor_base::copy_object<Obj>,- &any_executor_base::move_object<Obj>,- &any_executor_base::target_object<Obj>- };- return &fns;- }-- typedef asio::detail::executor_function function;- typedef asio::detail::executor_function_view function_view;-- struct target_fns- {-#if !defined(ASIO_NO_TYPEID)- const std::type_info& (*target_type)();-#else // !defined(ASIO_NO_TYPEID)- const void* (*target_type)();-#endif // !defined(ASIO_NO_TYPEID)- bool (*equal)(const any_executor_base&, const any_executor_base&);- void (*execute)(const any_executor_base&, function&&);- void (*blocking_execute)(const any_executor_base&, function_view);- };--#if !defined(ASIO_NO_TYPEID)- template <typename Ex>- static const std::type_info& target_type_ex()- {- return typeid(Ex);- }-#else // !defined(ASIO_NO_TYPEID)- template <typename Ex>- static const void* target_type_ex()- {- static int unique_id;- return &unique_id;- }-#endif // !defined(ASIO_NO_TYPEID)-- template <typename Ex>- static bool equal_ex(const any_executor_base& ex1,- const any_executor_base& ex2)- {- const Ex* p1 = ex1.target<Ex>();- const Ex* p2 = ex2.target<Ex>();- ASIO_ASSUME(p1 != 0 && p2 != 0);- return *p1 == *p2;- }-- template <typename Ex>- static void execute_ex(const any_executor_base& ex, function&& f)- {- const Ex* p = ex.target<Ex>();- ASIO_ASSUME(p != 0);- p->execute(static_cast<function&&>(f));- }-- template <typename Ex>- static void blocking_execute_ex(const any_executor_base& ex, function_view f)- {- const Ex* p = ex.target<Ex>();- ASIO_ASSUME(p != 0);- p->execute(f);- }-- template <typename Ex>- static const target_fns* target_fns_table(bool is_always_blocking,- enable_if_t<- !is_same<Ex, void>::value- >* = 0)- {- static const target_fns fns_with_execute =- {- &any_executor_base::target_type_ex<Ex>,- &any_executor_base::equal_ex<Ex>,- &any_executor_base::execute_ex<Ex>,- 0- };-- static const target_fns fns_with_blocking_execute =- {- &any_executor_base::target_type_ex<Ex>,- &any_executor_base::equal_ex<Ex>,- 0,- &any_executor_base::blocking_execute_ex<Ex>- };-- return is_always_blocking ? &fns_with_blocking_execute : &fns_with_execute;- }--#if defined(ASIO_MSVC)-# pragma warning (push)-# pragma warning (disable:4702)-#endif // defined(ASIO_MSVC)-- static void query_fn_void(void*, const void*, const void*)- {- bad_executor ex;- asio::detail::throw_exception(ex);- }-- template <typename Ex, class Prop>- static void query_fn_non_void(void*, const void* ex, const void* prop,- enable_if_t<- asio::can_query<const Ex&, const Prop&>::value- && is_same<typename Prop::polymorphic_query_result_type, void>::value- >*)- {- asio::query(*static_cast<const Ex*>(ex),- *static_cast<const Prop*>(prop));- }-- template <typename Ex, class Prop>- static void query_fn_non_void(void*, const void*, const void*,- enable_if_t<- !asio::can_query<const Ex&, const Prop&>::value- && is_same<typename Prop::polymorphic_query_result_type, void>::value- >*)- {- }-- template <typename Ex, class Prop>- static void query_fn_non_void(void* result, const void* ex, const void* prop,- enable_if_t<- asio::can_query<const Ex&, const Prop&>::value- && !is_same<typename Prop::polymorphic_query_result_type, void>::value- && is_reference<typename Prop::polymorphic_query_result_type>::value- >*)- {- *static_cast<remove_reference_t<- typename Prop::polymorphic_query_result_type>**>(result)- = &static_cast<typename Prop::polymorphic_query_result_type>(- asio::query(*static_cast<const Ex*>(ex),- *static_cast<const Prop*>(prop)));- }-- template <typename Ex, class Prop>- static void query_fn_non_void(void*, const void*, const void*,- enable_if_t<- !asio::can_query<const Ex&, const Prop&>::value- && !is_same<typename Prop::polymorphic_query_result_type, void>::value- && is_reference<typename Prop::polymorphic_query_result_type>::value- >*)- {- std::terminate(); // Combination should not be possible.- }-- template <typename Ex, class Prop>- static void query_fn_non_void(void* result, const void* ex, const void* prop,- enable_if_t<- asio::can_query<const Ex&, const Prop&>::value- && !is_same<typename Prop::polymorphic_query_result_type, void>::value- && is_scalar<typename Prop::polymorphic_query_result_type>::value- >*)- {- *static_cast<typename Prop::polymorphic_query_result_type*>(result)- = static_cast<typename Prop::polymorphic_query_result_type>(- asio::query(*static_cast<const Ex*>(ex),- *static_cast<const Prop*>(prop)));- }-- template <typename Ex, class Prop>- static void query_fn_non_void(void* result, const void*, const void*,- enable_if_t<- !asio::can_query<const Ex&, const Prop&>::value- && !is_same<typename Prop::polymorphic_query_result_type, void>::value- && is_scalar<typename Prop::polymorphic_query_result_type>::value- >*)- {- *static_cast<typename Prop::polymorphic_query_result_type*>(result)- = typename Prop::polymorphic_query_result_type();- }-- template <typename Ex, class Prop>- static void query_fn_non_void(void* result, const void* ex, const void* prop,- enable_if_t<- asio::can_query<const Ex&, const Prop&>::value- && !is_same<typename Prop::polymorphic_query_result_type, void>::value- && !is_reference<typename Prop::polymorphic_query_result_type>::value- && !is_scalar<typename Prop::polymorphic_query_result_type>::value- >*)- {- *static_cast<typename Prop::polymorphic_query_result_type**>(result)- = new typename Prop::polymorphic_query_result_type(- asio::query(*static_cast<const Ex*>(ex),- *static_cast<const Prop*>(prop)));- }-- template <typename Ex, class Prop>- static void query_fn_non_void(void* result, const void*, const void*, ...)- {- *static_cast<typename Prop::polymorphic_query_result_type**>(result)- = new typename Prop::polymorphic_query_result_type();- }-- template <typename Ex, class Prop>- static void query_fn_impl(void* result, const void* ex, const void* prop,- enable_if_t<- is_same<Ex, void>::value- >*)- {- query_fn_void(result, ex, prop);- }-- template <typename Ex, class Prop>- static void query_fn_impl(void* result, const void* ex, const void* prop,- enable_if_t<- !is_same<Ex, void>::value- >*)- {- query_fn_non_void<Ex, Prop>(result, ex, prop, 0);- }-- template <typename Ex, class Prop>- static void query_fn(void* result, const void* ex, const void* prop)- {- query_fn_impl<Ex, Prop>(result, ex, prop, 0);- }-- template <typename Poly, typename Ex, class Prop>- static Poly require_fn_impl(const void*, const void*,- enable_if_t<- is_same<Ex, void>::value- >*)- {- bad_executor ex;- asio::detail::throw_exception(ex);- return Poly();- }-- template <typename Poly, typename Ex, class Prop>- static Poly require_fn_impl(const void* ex, const void* prop,- enable_if_t<- !is_same<Ex, void>::value && Prop::is_requirable- >*)- {- return asio::require(*static_cast<const Ex*>(ex),- *static_cast<const Prop*>(prop));- }-- template <typename Poly, typename Ex, class Prop>- static Poly require_fn_impl(const void*, const void*, ...)- {- return Poly();- }-- template <typename Poly, typename Ex, class Prop>- static Poly require_fn(const void* ex, const void* prop)- {- return require_fn_impl<Poly, Ex, Prop>(ex, prop, 0);- }-- template <typename Poly, typename Ex, class Prop>- static Poly prefer_fn_impl(const void*, const void*,- enable_if_t<- is_same<Ex, void>::value- >*)- {- bad_executor ex;- asio::detail::throw_exception(ex);- return Poly();- }-- template <typename Poly, typename Ex, class Prop>- static Poly prefer_fn_impl(const void* ex, const void* prop,- enable_if_t<- !is_same<Ex, void>::value && Prop::is_preferable- >*)- {- return asio::prefer(*static_cast<const Ex*>(ex),- *static_cast<const Prop*>(prop));- }-- template <typename Poly, typename Ex, class Prop>- static Poly prefer_fn_impl(const void*, const void*, ...)- {- return Poly();- }-- template <typename Poly, typename Ex, class Prop>- static Poly prefer_fn(const void* ex, const void* prop)- {- return prefer_fn_impl<Poly, Ex, Prop>(ex, prop, 0);- }-- template <typename Poly>- struct prop_fns- {- void (*query)(void*, const void*, const void*);- Poly (*require)(const void*, const void*);- Poly (*prefer)(const void*, const void*);- };--#if defined(ASIO_MSVC)-# pragma warning (pop)-#endif // defined(ASIO_MSVC)--private:- template <typename Executor>- static execution::blocking_t query_blocking(const Executor& ex, true_type)- {- return asio::query(ex, execution::blocking);- }-- template <typename Executor>- static execution::blocking_t query_blocking(const Executor&, false_type)- {- return execution::blocking_t();- }-- template <typename Executor>- void construct_object(Executor& ex, true_type)- {- object_fns_ = object_fns_table<Executor>();- target_ = new (&object_) Executor(static_cast<Executor&&>(ex));- }-- template <typename Executor>- void construct_object(Executor& ex, false_type)- {- object_fns_ = object_fns_table<shared_target_executor>();- Executor* p = 0;- new (&object_) shared_target_executor(- static_cast<Executor&&>(ex), p);- target_ = p;- }-- template <typename Executor>- void construct_object(std::nothrow_t,- Executor& ex, true_type) noexcept- {- object_fns_ = object_fns_table<Executor>();- target_ = new (&object_) Executor(static_cast<Executor&&>(ex));- }-- template <typename Executor>- void construct_object(std::nothrow_t,- Executor& ex, false_type) noexcept- {- object_fns_ = object_fns_table<shared_target_executor>();- Executor* p = 0;- new (&object_) shared_target_executor(- std::nothrow, static_cast<Executor&&>(ex), p);- target_ = p;- }--/*private:*/public:-// template <typename...> friend class any_executor;-- typedef aligned_storage<- sizeof(asio::detail::shared_ptr<void>) + sizeof(void*),- alignment_of<asio::detail::shared_ptr<void>>::value- >::type object_type;-- object_type object_;- const object_fns* object_fns_;- void* target_;- const target_fns* target_fns_;-};--template <typename Derived, typename Property, typename = void>-struct any_executor_context-{-};--#if !defined(ASIO_NO_TS_EXECUTORS)--template <typename Derived, typename Property>-struct any_executor_context<Derived, Property, enable_if_t<Property::value>>-{- typename Property::query_result_type context() const- {- return static_cast<const Derived*>(this)->query(typename Property::type());- }-};--#endif // !defined(ASIO_NO_TS_EXECUTORS)--} // namespace detail--template <>-class any_executor<> : public detail::any_executor_base-{-public:- any_executor() noexcept- : detail::any_executor_base()- {- }-- any_executor(nullptr_t) noexcept- : detail::any_executor_base()- {- }-- template <typename Executor>- any_executor(Executor ex,- enable_if_t<- conditional_t<- !is_same<Executor, any_executor>::value- && !is_base_of<detail::any_executor_base, Executor>::value,- is_executor<Executor>,- false_type- >::value- >* = 0)- : detail::any_executor_base(- static_cast<Executor&&>(ex), false_type())- {- }-- template <typename Executor>- any_executor(std::nothrow_t, Executor ex,- enable_if_t<- conditional_t<- !is_same<Executor, any_executor>::value- && !is_base_of<detail::any_executor_base, Executor>::value,- is_executor<Executor>,- false_type- >::value- >* = 0) noexcept- : detail::any_executor_base(std::nothrow,- static_cast<Executor&&>(ex), false_type())- {- }-- template <typename... OtherSupportableProperties>- any_executor(any_executor<OtherSupportableProperties...> other)- : detail::any_executor_base(- static_cast<const detail::any_executor_base&>(other))- {- }-- template <typename... OtherSupportableProperties>- any_executor(std::nothrow_t,- any_executor<OtherSupportableProperties...> other) noexcept- : detail::any_executor_base(- static_cast<const detail::any_executor_base&>(other))- {- }-- any_executor(const any_executor& other) noexcept- : detail::any_executor_base(- static_cast<const detail::any_executor_base&>(other))- {- }-- any_executor(std::nothrow_t, const any_executor& other) noexcept- : detail::any_executor_base(- static_cast<const detail::any_executor_base&>(other))- {- }-- any_executor& operator=(const any_executor& other) noexcept- {- if (this != &other)- {- detail::any_executor_base::operator=(- static_cast<const detail::any_executor_base&>(other));- }- return *this;- }-- any_executor& operator=(nullptr_t p) noexcept- {- detail::any_executor_base::operator=(p);- return *this;- }-- any_executor(any_executor&& other) noexcept- : detail::any_executor_base(- static_cast<any_executor_base&&>(- static_cast<any_executor_base&>(other)))- {- }-- any_executor(std::nothrow_t, any_executor&& other) noexcept- : detail::any_executor_base(- static_cast<any_executor_base&&>(- static_cast<any_executor_base&>(other)))- {- }-- any_executor& operator=(any_executor&& other) noexcept- {- if (this != &other)- {- detail::any_executor_base::operator=(- static_cast<detail::any_executor_base&&>(- static_cast<detail::any_executor_base&>(other)));- }- return *this;- }-- void swap(any_executor& other) noexcept- {- detail::any_executor_base::swap(- static_cast<detail::any_executor_base&>(other));- }-- using detail::any_executor_base::execute;- using detail::any_executor_base::target;- using detail::any_executor_base::target_type;- using detail::any_executor_base::operator unspecified_bool_type;- using detail::any_executor_base::operator!;-- bool equality_helper(const any_executor& other) const noexcept- {- return any_executor_base::equality_helper(other);- }-- template <typename AnyExecutor1, typename AnyExecutor2>- friend enable_if_t<- is_base_of<any_executor, AnyExecutor1>::value- || is_base_of<any_executor, AnyExecutor2>::value,- bool- > operator==(const AnyExecutor1& a,- const AnyExecutor2& b) noexcept- {- return static_cast<const any_executor&>(a).equality_helper(b);- }-- template <typename AnyExecutor>- friend enable_if_t<- is_same<AnyExecutor, any_executor>::value,- bool- > operator==(const AnyExecutor& a, nullptr_t) noexcept- {- return !a;- }-- template <typename AnyExecutor>- friend enable_if_t<- is_same<AnyExecutor, any_executor>::value,- bool- > operator==(nullptr_t, const AnyExecutor& b) noexcept- {- return !b;- }-- template <typename AnyExecutor1, typename AnyExecutor2>- friend enable_if_t<- is_base_of<any_executor, AnyExecutor1>::value- || is_base_of<any_executor, AnyExecutor2>::value,- bool- > operator!=(const AnyExecutor1& a,- const AnyExecutor2& b) noexcept- {- return !static_cast<const any_executor&>(a).equality_helper(b);- }-- template <typename AnyExecutor>- friend enable_if_t<- is_same<AnyExecutor, any_executor>::value,- bool- > operator!=(const AnyExecutor& a, nullptr_t) noexcept- {- return !!a;- }-- template <typename AnyExecutor>- friend enable_if_t<- is_same<AnyExecutor, any_executor>::value,- bool- > operator!=(nullptr_t, const AnyExecutor& b) noexcept- {- return !!b;- }-};--inline void swap(any_executor<>& a, any_executor<>& b) noexcept-{- return a.swap(b);-}--template <typename... SupportableProperties>-class any_executor :- public detail::any_executor_base,- public detail::any_executor_context<- any_executor<SupportableProperties...>,- typename detail::supportable_properties<- 0, void(SupportableProperties...)>::find_context_as_property>-{-public:- any_executor() noexcept- : detail::any_executor_base(),- prop_fns_(prop_fns_table<void>())- {- }-- any_executor(nullptr_t) noexcept- : detail::any_executor_base(),- prop_fns_(prop_fns_table<void>())- {- }-- template <typename Executor>- any_executor(Executor ex,- enable_if_t<- conditional_t<- !is_same<Executor, any_executor>::value- && !is_base_of<detail::any_executor_base, Executor>::value,- detail::is_valid_target_executor<- Executor, void(SupportableProperties...)>,- false_type- >::value- >* = 0)- : detail::any_executor_base(- static_cast<Executor&&>(ex), false_type()),- prop_fns_(prop_fns_table<Executor>())- {- }-- template <typename Executor>- any_executor(std::nothrow_t, Executor ex,- enable_if_t<- conditional_t<- !is_same<Executor, any_executor>::value- && !is_base_of<detail::any_executor_base, Executor>::value,- detail::is_valid_target_executor<- Executor, void(SupportableProperties...)>,- false_type- >::value- >* = 0) noexcept- : detail::any_executor_base(std::nothrow,- static_cast<Executor&&>(ex), false_type()),- prop_fns_(prop_fns_table<Executor>())- {- if (this->template target<void>() == 0)- prop_fns_ = prop_fns_table<void>();- }-- template <typename... OtherSupportableProperties>- any_executor(any_executor<OtherSupportableProperties...> other,- enable_if_t<- conditional_t<- !is_same<- any_executor<OtherSupportableProperties...>,- any_executor- >::value,- typename detail::supportable_properties<- 0, void(SupportableProperties...)>::template is_valid_target<- any_executor<OtherSupportableProperties...>>,- false_type- >::value- >* = 0)- : detail::any_executor_base(- static_cast<any_executor<OtherSupportableProperties...>&&>(other),- true_type()),- prop_fns_(prop_fns_table<any_executor<OtherSupportableProperties...>>())- {- }-- template <typename... OtherSupportableProperties>- any_executor(std::nothrow_t,- any_executor<OtherSupportableProperties...> other,- enable_if_t<- conditional_t<- !is_same<- any_executor<OtherSupportableProperties...>,- any_executor- >::value,- typename detail::supportable_properties<- 0, void(SupportableProperties...)>::template is_valid_target<- any_executor<OtherSupportableProperties...>>,- false_type- >::value- >* = 0) noexcept- : detail::any_executor_base(std::nothrow,- static_cast<any_executor<OtherSupportableProperties...>&&>(other),- true_type()),- prop_fns_(prop_fns_table<any_executor<OtherSupportableProperties...>>())- {- if (this->template target<void>() == 0)- prop_fns_ = prop_fns_table<void>();- }-- any_executor(const any_executor& other) noexcept- : detail::any_executor_base(- static_cast<const detail::any_executor_base&>(other)),- prop_fns_(other.prop_fns_)- {- }-- any_executor(std::nothrow_t, const any_executor& other) noexcept- : detail::any_executor_base(- static_cast<const detail::any_executor_base&>(other)),- prop_fns_(other.prop_fns_)- {- }-- any_executor& operator=(const any_executor& other) noexcept- {- if (this != &other)- {- prop_fns_ = other.prop_fns_;- detail::any_executor_base::operator=(- static_cast<const detail::any_executor_base&>(other));- }- return *this;- }-- any_executor& operator=(nullptr_t p) noexcept- {- prop_fns_ = prop_fns_table<void>();- detail::any_executor_base::operator=(p);- return *this;- }-- any_executor(any_executor&& other) noexcept- : detail::any_executor_base(- static_cast<any_executor_base&&>(- static_cast<any_executor_base&>(other))),- prop_fns_(other.prop_fns_)- {- other.prop_fns_ = prop_fns_table<void>();- }-- any_executor(std::nothrow_t, any_executor&& other) noexcept- : detail::any_executor_base(- static_cast<any_executor_base&&>(- static_cast<any_executor_base&>(other))),- prop_fns_(other.prop_fns_)- {- other.prop_fns_ = prop_fns_table<void>();- }-- any_executor& operator=(any_executor&& other) noexcept- {- if (this != &other)- {- prop_fns_ = other.prop_fns_;- detail::any_executor_base::operator=(- static_cast<detail::any_executor_base&&>(- static_cast<detail::any_executor_base&>(other)));- }- return *this;- }-- void swap(any_executor& other) noexcept- {- if (this != &other)- {- detail::any_executor_base::swap(- static_cast<detail::any_executor_base&>(other));- const prop_fns<any_executor>* tmp_prop_fns = other.prop_fns_;- other.prop_fns_ = prop_fns_;- prop_fns_ = tmp_prop_fns;- }- }-- using detail::any_executor_base::execute;- using detail::any_executor_base::target;- using detail::any_executor_base::target_type;- using detail::any_executor_base::operator unspecified_bool_type;- using detail::any_executor_base::operator!;-- bool equality_helper(const any_executor& other) const noexcept- {- return any_executor_base::equality_helper(other);- }-- template <typename AnyExecutor1, typename AnyExecutor2>- friend enable_if_t<- is_base_of<any_executor, AnyExecutor1>::value- || is_base_of<any_executor, AnyExecutor2>::value,- bool- > operator==(const AnyExecutor1& a,- const AnyExecutor2& b) noexcept- {- return static_cast<const any_executor&>(a).equality_helper(b);- }-- template <typename AnyExecutor>- friend enable_if_t<- is_same<AnyExecutor, any_executor>::value,- bool- > operator==(const AnyExecutor& a, nullptr_t) noexcept- {- return !a;- }-- template <typename AnyExecutor>- friend enable_if_t<- is_same<AnyExecutor, any_executor>::value,- bool- > operator==(nullptr_t, const AnyExecutor& b) noexcept- {- return !b;- }-- template <typename AnyExecutor1, typename AnyExecutor2>- friend enable_if_t<- is_base_of<any_executor, AnyExecutor1>::value- || is_base_of<any_executor, AnyExecutor2>::value,- bool- > operator!=(const AnyExecutor1& a,- const AnyExecutor2& b) noexcept- {- return !static_cast<const any_executor&>(a).equality_helper(b);- }-- template <typename AnyExecutor>- friend enable_if_t<- is_same<AnyExecutor, any_executor>::value,- bool- > operator!=(const AnyExecutor& a, nullptr_t) noexcept- {- return !!a;- }-- template <typename AnyExecutor>- friend enable_if_t<- is_same<AnyExecutor, any_executor>::value,- bool- > operator!=(nullptr_t, const AnyExecutor& b) noexcept- {- return !!b;- }-- template <typename T>- struct find_convertible_property :- detail::supportable_properties<- 0, void(SupportableProperties...)>::template- find_convertible_property<T> {};-- template <typename Property>- void query(const Property& p,- enable_if_t<- is_same<- typename find_convertible_property<Property>::query_result_type,- void- >::value- >* = 0) const- {- if (!target_)- {- bad_executor ex;- asio::detail::throw_exception(ex);- }- typedef find_convertible_property<Property> found;- prop_fns_[found::index].query(0, object_fns_->target(*this),- &static_cast<const typename found::type&>(p));- }-- template <typename Property>- typename find_convertible_property<Property>::query_result_type- query(const Property& p,- enable_if_t<- !is_same<- typename find_convertible_property<Property>::query_result_type,- void- >::value- &&- is_reference<- typename find_convertible_property<Property>::query_result_type- >::value- >* = 0) const- {- if (!target_)- {- bad_executor ex;- asio::detail::throw_exception(ex);- }- typedef find_convertible_property<Property> found;- remove_reference_t<typename found::query_result_type>* result = 0;- prop_fns_[found::index].query(&result, object_fns_->target(*this),- &static_cast<const typename found::type&>(p));- return *result;- }-- template <typename Property>- typename find_convertible_property<Property>::query_result_type- query(const Property& p,- enable_if_t<- !is_same<- typename find_convertible_property<Property>::query_result_type,- void- >::value- &&- is_scalar<- typename find_convertible_property<Property>::query_result_type- >::value- >* = 0) const- {- if (!target_)- {- bad_executor ex;- asio::detail::throw_exception(ex);- }- typedef find_convertible_property<Property> found;- typename found::query_result_type result;- prop_fns_[found::index].query(&result, object_fns_->target(*this),- &static_cast<const typename found::type&>(p));- return result;- }-- template <typename Property>- typename find_convertible_property<Property>::query_result_type- query(const Property& p,- enable_if_t<- !is_same<- typename find_convertible_property<Property>::query_result_type,- void- >::value- &&- !is_reference<- typename find_convertible_property<Property>::query_result_type- >::value- &&- !is_scalar<- typename find_convertible_property<Property>::query_result_type- >::value- >* = 0) const- {- if (!target_)- {- bad_executor ex;- asio::detail::throw_exception(ex);- }- typedef find_convertible_property<Property> found;- typename found::query_result_type* result;- prop_fns_[found::index].query(&result, object_fns_->target(*this),- &static_cast<const typename found::type&>(p));- return *asio::detail::scoped_ptr<- typename found::query_result_type>(result);- }-- template <typename T>- struct find_convertible_requirable_property :- detail::supportable_properties<- 0, void(SupportableProperties...)>::template- find_convertible_requirable_property<T> {};-- template <typename Property>- any_executor require(const Property& p,- enable_if_t<- find_convertible_requirable_property<Property>::value- >* = 0) const- {- if (!target_)- {- bad_executor ex;- asio::detail::throw_exception(ex);- }- typedef find_convertible_requirable_property<Property> found;- return prop_fns_[found::index].require(object_fns_->target(*this),- &static_cast<const typename found::type&>(p));- }-- template <typename T>- struct find_convertible_preferable_property :- detail::supportable_properties<- 0, void(SupportableProperties...)>::template- find_convertible_preferable_property<T> {};-- template <typename Property>- any_executor prefer(const Property& p,- enable_if_t<- find_convertible_preferable_property<Property>::value- >* = 0) const- {- if (!target_)- {- bad_executor ex;- asio::detail::throw_exception(ex);- }- typedef find_convertible_preferable_property<Property> found;- return prop_fns_[found::index].prefer(object_fns_->target(*this),- &static_cast<const typename found::type&>(p));- }--//private:- template <typename Ex>- static const prop_fns<any_executor>* prop_fns_table()- {- static const prop_fns<any_executor> fns[] =- {- {- &detail::any_executor_base::query_fn<- Ex, SupportableProperties>,- &detail::any_executor_base::require_fn<- any_executor, Ex, SupportableProperties>,- &detail::any_executor_base::prefer_fn<- any_executor, Ex, SupportableProperties>- }...- };- return fns;- }-- const prop_fns<any_executor>* prop_fns_;-};--template <typename... SupportableProperties>-inline void swap(any_executor<SupportableProperties...>& a,- any_executor<SupportableProperties...>& b) noexcept-{- return a.swap(b);-}--} // namespace execution-namespace traits {--#if !defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)--template <typename... SupportableProperties>-struct equality_comparable<execution::any_executor<SupportableProperties...>>-{- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;-};--#endif // !defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)--#if !defined(ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)--template <typename F, typename... SupportableProperties>-struct execute_member<execution::any_executor<SupportableProperties...>, F>-{- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = false;- typedef void result_type;-};--#endif // !defined(ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)--#if !defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)--template <typename Prop, typename... SupportableProperties>-struct query_member<- execution::any_executor<SupportableProperties...>, Prop,- enable_if_t<- execution::detail::supportable_properties<- 0, void(SupportableProperties...)>::template- find_convertible_property<Prop>::value- >>-{- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = false;- typedef typename execution::detail::supportable_properties<- 0, void(SupportableProperties...)>::template- find_convertible_property<Prop>::query_result_type result_type;-};--#endif // !defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)--#if !defined(ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)--template <typename Prop, typename... SupportableProperties>-struct require_member<- execution::any_executor<SupportableProperties...>, Prop,- enable_if_t<- execution::detail::supportable_properties<- 0, void(SupportableProperties...)>::template- find_convertible_requirable_property<Prop>::value- >>-{- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = false;- typedef execution::any_executor<SupportableProperties...> result_type;-};--#endif // !defined(ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)--#if !defined(ASIO_HAS_DEDUCED_PREFER_FREE_TRAIT)--template <typename Prop, typename... SupportableProperties>-struct prefer_member<- execution::any_executor<SupportableProperties...>, Prop,- enable_if_t<- execution::detail::supportable_properties<- 0, void(SupportableProperties...)>::template- find_convertible_preferable_property<Prop>::value- >>-{- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = false;- typedef execution::any_executor<SupportableProperties...> result_type;-};-+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_EXECUTION_ANY_EXECUTOR_HPP+#define ASIO_EXECUTION_ANY_EXECUTOR_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include <new>+#include <typeinfo>+#include "asio/detail/assert.hpp"+#include "asio/detail/atomic_count.hpp"+#include "asio/detail/cstddef.hpp"+#include "asio/detail/executor_function.hpp"+#include "asio/detail/memory.hpp"+#include "asio/detail/non_const_lvalue.hpp"+#include "asio/detail/scoped_ptr.hpp"+#include "asio/detail/type_traits.hpp"+#include "asio/detail/throw_exception.hpp"+#include "asio/detail/variadic_templates.hpp"+#include "asio/execution/bad_executor.hpp"+#include "asio/execution/blocking.hpp"+#include "asio/execution/execute.hpp"+#include "asio/execution/executor.hpp"+#include "asio/prefer.hpp"+#include "asio/query.hpp"+#include "asio/require.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {++#if defined(GENERATING_DOCUMENTATION)++namespace execution {++/// Polymorphic executor wrapper.+template <typename... SupportableProperties>+class any_executor+{+public:+ /// Default constructor.+ any_executor() noexcept;++ /// Construct in an empty state. Equivalent effects to default constructor.+ any_executor(nullptr_t) noexcept;++ /// Copy constructor.+ any_executor(const any_executor& e) noexcept;++ /// Move constructor.+ any_executor(any_executor&& e) noexcept;++ /// Construct to point to the same target as another any_executor.+ template <class... OtherSupportableProperties>+ any_executor(any_executor<OtherSupportableProperties...> e);++ /// Construct to point to the same target as another any_executor.+ template <class... OtherSupportableProperties>+ any_executor(std::nothrow_t,+ any_executor<OtherSupportableProperties...> e) noexcept;++ /// Construct to point to the same target as another any_executor.+ any_executor(std::nothrow_t, const any_executor& e) noexcept;++ /// Construct to point to the same target as another any_executor.+ any_executor(std::nothrow_t, any_executor&& e) noexcept;++ /// Construct a polymorphic wrapper for the specified executor.+ template <typename Executor>+ any_executor(Executor e);++ /// Construct a polymorphic wrapper for the specified executor.+ template <typename Executor>+ any_executor(std::nothrow_t, Executor e) noexcept;++ /// Assignment operator.+ any_executor& operator=(const any_executor& e) noexcept;++ /// Move assignment operator.+ any_executor& operator=(any_executor&& e) noexcept;++ /// Assignment operator that sets the polymorphic wrapper to the empty state.+ any_executor& operator=(nullptr_t);++ /// Assignment operator to create a polymorphic wrapper for the specified+ /// executor.+ template <typename Executor>+ any_executor& operator=(Executor e);++ /// Destructor.+ ~any_executor();++ /// Swap targets with another polymorphic wrapper.+ void swap(any_executor& other) noexcept;++ /// Obtain a polymorphic wrapper with the specified property.+ /**+ * Do not call this function directly. It is intended for use with the+ * asio::require and asio::prefer customisation points.+ *+ * For example:+ * @code execution::any_executor<execution::blocking_t::possibly_t> ex = ...;+ * auto ex2 = asio::requre(ex, execution::blocking.possibly); @endcode+ */+ template <typename Property>+ any_executor require(Property) const;++ /// Obtain a polymorphic wrapper with the specified property.+ /**+ * Do not call this function directly. It is intended for use with the+ * asio::prefer customisation point.+ *+ * For example:+ * @code execution::any_executor<execution::blocking_t::possibly_t> ex = ...;+ * auto ex2 = asio::prefer(ex, execution::blocking.possibly); @endcode+ */+ template <typename Property>+ any_executor prefer(Property) const;++ /// Obtain the value associated with the specified property.+ /**+ * Do not call this function directly. It is intended for use with the+ * asio::query customisation point.+ *+ * For example:+ * @code execution::any_executor<execution::occupancy_t> ex = ...;+ * size_t n = asio::query(ex, execution::occupancy); @endcode+ */+ template <typename Property>+ typename Property::polymorphic_query_result_type query(Property) const;++ /// Execute the function on the target executor.+ /**+ * Throws asio::bad_executor if the polymorphic wrapper has no target.+ */+ template <typename Function>+ void execute(Function&& f) const;++ /// Obtain the underlying execution context.+ /**+ * This function is provided for backward compatibility. It is automatically+ * defined when the @c SupportableProperties... list includes a property of+ * type <tt>execution::context_as<U></tt>, for some type <tt>U</tt>.+ */+ automatically_determined context() const;++ /// Determine whether the wrapper has a target executor.+ /**+ * @returns @c true if the polymorphic wrapper has a target executor,+ * otherwise false.+ */+ explicit operator bool() const noexcept;++ /// Get the type of the target executor.+ const type_info& target_type() const noexcept;++ /// Get a pointer to the target executor.+ template <typename Executor> Executor* target() noexcept;++ /// Get a pointer to the target executor.+ template <typename Executor> const Executor* target() const noexcept;+};++/// Equality operator.+/**+ * @relates any_executor+ */+template <typename... SupportableProperties>+bool operator==(const any_executor<SupportableProperties...>& a,+ const any_executor<SupportableProperties...>& b) noexcept;++/// Equality operator.+/**+ * @relates any_executor+ */+template <typename... SupportableProperties>+bool operator==(const any_executor<SupportableProperties...>& a,+ nullptr_t) noexcept;++/// Equality operator.+/**+ * @relates any_executor+ */+template <typename... SupportableProperties>+bool operator==(nullptr_t,+ const any_executor<SupportableProperties...>& b) noexcept;++/// Inequality operator.+/**+ * @relates any_executor+ */+template <typename... SupportableProperties>+bool operator!=(const any_executor<SupportableProperties...>& a,+ const any_executor<SupportableProperties...>& b) noexcept;++/// Inequality operator.+/**+ * @relates any_executor+ */+template <typename... SupportableProperties>+bool operator!=(const any_executor<SupportableProperties...>& a,+ nullptr_t) noexcept;++/// Inequality operator.+/**+ * @relates any_executor+ */+template <typename... SupportableProperties>+bool operator!=(nullptr_t,+ const any_executor<SupportableProperties...>& b) noexcept;++} // namespace execution++#else // defined(GENERATING_DOCUMENTATION)++namespace execution {++#if !defined(ASIO_EXECUTION_ANY_EXECUTOR_FWD_DECL)+#define ASIO_EXECUTION_ANY_EXECUTOR_FWD_DECL++#if defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename... SupportableProperties>+class any_executor;++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename = void, typename = void, typename = void,+ typename = void, typename = void, typename = void,+ typename = void, typename = void, typename = void>+class any_executor;++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++#endif // !defined(ASIO_EXECUTION_ANY_EXECUTOR_FWD_DECL)++template <typename U>+struct context_as_t;++namespace detail {++// Traits used to detect whether a property is requirable or preferable, taking+// into account that T::is_requirable or T::is_preferable may not not be well+// formed.++template <typename T, typename = void>+struct is_requirable : false_type {};++template <typename T>+struct is_requirable<T, typename enable_if<T::is_requirable>::type> :+ true_type {};++template <typename T, typename = void>+struct is_preferable : false_type {};++template <typename T>+struct is_preferable<T, typename enable_if<T::is_preferable>::type> :+ true_type {};++// Trait used to detect context_as property, for backward compatibility.++template <typename T>+struct is_context_as : false_type {};++template <typename U>+struct is_context_as<context_as_t<U> > : true_type {};++// Helper template to:+// - Check if a target can supply the supportable properties.+// - Find the first convertible-from-T property in the list.++template <std::size_t I, typename Props>+struct supportable_properties;++template <std::size_t I, typename Prop>+struct supportable_properties<I, void(Prop)>+{+ template <typename T>+ struct is_valid_target : integral_constant<bool,+ (+ is_requirable<Prop>::value+ ? can_require<T, Prop>::value+ : true+ )+ &&+ (+ is_preferable<Prop>::value+ ? can_prefer<T, Prop>::value+ : true+ )+ &&+ (+ !is_requirable<Prop>::value && !is_preferable<Prop>::value+ ? can_query<T, Prop>::value+ : true+ )+ >+ {+ };++ struct found+ {+ ASIO_STATIC_CONSTEXPR(bool, value = true);+ typedef Prop type;+ typedef typename Prop::polymorphic_query_result_type query_result_type;+ ASIO_STATIC_CONSTEXPR(std::size_t, index = I);+ };++ struct not_found+ {+ ASIO_STATIC_CONSTEXPR(bool, value = false);+ };++ template <typename T>+ struct find_convertible_property :+ conditional<+ is_same<T, Prop>::value || is_convertible<T, Prop>::value,+ found,+ not_found+ >::type {};++ template <typename T>+ struct find_convertible_requirable_property :+ conditional<+ is_requirable<Prop>::value+ && (is_same<T, Prop>::value || is_convertible<T, Prop>::value),+ found,+ not_found+ >::type {};++ template <typename T>+ struct find_convertible_preferable_property :+ conditional<+ is_preferable<Prop>::value+ && (is_same<T, Prop>::value || is_convertible<T, Prop>::value),+ found,+ not_found+ >::type {};++ struct find_context_as_property :+ conditional<+ is_context_as<Prop>::value,+ found,+ not_found+ >::type {};+};++#if defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <std::size_t I, typename Head, typename... Tail>+struct supportable_properties<I, void(Head, Tail...)>+{+ template <typename T>+ struct is_valid_target : integral_constant<bool,+ (+ supportable_properties<I,+ void(Head)>::template is_valid_target<T>::value+ &&+ supportable_properties<I + 1,+ void(Tail...)>::template is_valid_target<T>::value+ )+ >+ {+ };++ template <typename T>+ struct find_convertible_property :+ conditional<+ is_convertible<T, Head>::value,+ typename supportable_properties<I, void(Head)>::found,+ typename supportable_properties<I + 1,+ void(Tail...)>::template find_convertible_property<T>+ >::type {};++ template <typename T>+ struct find_convertible_requirable_property :+ conditional<+ is_requirable<Head>::value+ && is_convertible<T, Head>::value,+ typename supportable_properties<I, void(Head)>::found,+ typename supportable_properties<I + 1,+ void(Tail...)>::template find_convertible_requirable_property<T>+ >::type {};++ template <typename T>+ struct find_convertible_preferable_property :+ conditional<+ is_preferable<Head>::value+ && is_convertible<T, Head>::value,+ typename supportable_properties<I, void(Head)>::found,+ typename supportable_properties<I + 1,+ void(Tail...)>::template find_convertible_preferable_property<T>+ >::type {};++ struct find_context_as_property :+ conditional<+ is_context_as<Head>::value,+ typename supportable_properties<I, void(Head)>::found,+ typename supportable_properties<I + 1,+ void(Tail...)>::find_context_as_property+ >::type {};+};++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++#define ASIO_PRIVATE_ANY_EXECUTOR_PROPS_BASE_DEF(n) \+ template <std::size_t I, \+ typename Head, ASIO_VARIADIC_TPARAMS(n)> \+ struct supportable_properties<I, \+ void(Head, ASIO_VARIADIC_TARGS(n))> \+ { \+ template <typename T> \+ struct is_valid_target : integral_constant<bool, \+ ( \+ supportable_properties<I, \+ void(Head)>::template is_valid_target<T>::value \+ && \+ supportable_properties<I + 1, \+ void(ASIO_VARIADIC_TARGS(n))>::template \+ is_valid_target<T>::value \+ ) \+ > \+ { \+ }; \+ \+ template <typename T> \+ struct find_convertible_property : \+ conditional< \+ is_convertible<T, Head>::value, \+ typename supportable_properties<I, void(Head)>::found, \+ typename supportable_properties<I + 1, \+ void(ASIO_VARIADIC_TARGS(n))>::template \+ find_convertible_property<T> \+ >::type {}; \+ \+ template <typename T> \+ struct find_convertible_requirable_property : \+ conditional< \+ is_requirable<Head>::value \+ && is_convertible<T, Head>::value, \+ typename supportable_properties<I, void(Head)>::found, \+ typename supportable_properties<I + 1, \+ void(ASIO_VARIADIC_TARGS(n))>::template \+ find_convertible_requirable_property<T> \+ >::type {}; \+ \+ template <typename T> \+ struct find_convertible_preferable_property : \+ conditional< \+ is_preferable<Head>::value \+ && is_convertible<T, Head>::value, \+ typename supportable_properties<I, void(Head)>::found, \+ typename supportable_properties<I + 1, \+ void(ASIO_VARIADIC_TARGS(n))>::template \+ find_convertible_preferable_property<T> \+ >::type {}; \+ \+ struct find_context_as_property : \+ conditional< \+ is_context_as<Head>::value, \+ typename supportable_properties<I, void(Head)>::found, \+ typename supportable_properties<I + 1, void( \+ ASIO_VARIADIC_TARGS(n))>::find_context_as_property \+ >::type {}; \+ }; \+ /**/+ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_ANY_EXECUTOR_PROPS_BASE_DEF)+#undef ASIO_PRIVATE_ANY_EXECUTOR_PROPS_BASE_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename T, typename Props>+struct is_valid_target_executor :+ conditional<+ is_executor<T>::value,+ typename supportable_properties<0, Props>::template is_valid_target<T>,+ false_type+ >::type+{+};++template <typename Props>+struct is_valid_target_executor<int, Props> : false_type+{+};++class shared_target_executor+{+public:+ template <typename E>+ shared_target_executor(ASIO_MOVE_ARG(E) e,+ typename decay<E>::type*& target)+ {+ impl<typename decay<E>::type>* i =+ new impl<typename decay<E>::type>(ASIO_MOVE_CAST(E)(e));+ target = &i->ex_;+ impl_ = i;+ }++ template <typename E>+ shared_target_executor(std::nothrow_t, ASIO_MOVE_ARG(E) e,+ typename decay<E>::type*& target) ASIO_NOEXCEPT+ {+ impl<typename decay<E>::type>* i =+ new (std::nothrow) impl<typename decay<E>::type>(+ ASIO_MOVE_CAST(E)(e));+ target = i ? &i->ex_ : 0;+ impl_ = i;+ }++ shared_target_executor(+ const shared_target_executor& other) ASIO_NOEXCEPT+ : impl_(other.impl_)+ {+ if (impl_)+ asio::detail::ref_count_up(impl_->ref_count_);+ }++ shared_target_executor& operator=(+ const shared_target_executor& other) ASIO_NOEXCEPT+ {+ impl_ = other.impl_;+ if (impl_)+ asio::detail::ref_count_up(impl_->ref_count_);+ return *this;+ }++#if defined(ASIO_HAS_MOVE)+ shared_target_executor(+ shared_target_executor&& other) ASIO_NOEXCEPT+ : impl_(other.impl_)+ {+ other.impl_ = 0;+ }++ shared_target_executor& operator=(+ shared_target_executor&& other) ASIO_NOEXCEPT+ {+ impl_ = other.impl_;+ other.impl_ = 0;+ return *this;+ }+#endif // defined(ASIO_HAS_MOVE)++ ~shared_target_executor()+ {+ if (impl_)+ if (asio::detail::ref_count_down(impl_->ref_count_))+ delete impl_;+ }++ void* get() const ASIO_NOEXCEPT+ {+ return impl_ ? impl_->get() : 0;+ }++private:+ struct impl_base+ {+ impl_base() : ref_count_(1) {}+ virtual ~impl_base() {}+ virtual void* get() = 0;+ asio::detail::atomic_count ref_count_;+ };++ template <typename Executor>+ struct impl : impl_base+ {+ impl(Executor ex) : ex_(ASIO_MOVE_CAST(Executor)(ex)) {}+ virtual void* get() { return &ex_; }+ Executor ex_;+ };++ impl_base* impl_;+};++class any_executor_base+{+public:+ any_executor_base() ASIO_NOEXCEPT+ : object_fns_(0),+ target_(0),+ target_fns_(0)+ {+ }++ template <ASIO_EXECUTION_EXECUTOR Executor>+ any_executor_base(Executor ex, false_type)+ : target_fns_(target_fns_table<Executor>(+ any_executor_base::query_blocking(ex,+ can_query<const Executor&, const execution::blocking_t&>())+ == execution::blocking.always))+ {+ any_executor_base::construct_object(ex,+ integral_constant<bool,+ sizeof(Executor) <= sizeof(object_type)+ && alignment_of<Executor>::value <= alignment_of<object_type>::value+ >());+ }++ template <ASIO_EXECUTION_EXECUTOR Executor>+ any_executor_base(std::nothrow_t, Executor ex, false_type) ASIO_NOEXCEPT+ : target_fns_(target_fns_table<Executor>(+ any_executor_base::query_blocking(ex,+ can_query<const Executor&, const execution::blocking_t&>())+ == execution::blocking.always))+ {+ any_executor_base::construct_object(std::nothrow, ex,+ integral_constant<bool,+ sizeof(Executor) <= sizeof(object_type)+ && alignment_of<Executor>::value <= alignment_of<object_type>::value+ >());+ if (target_ == 0)+ {+ object_fns_ = 0;+ target_fns_ = 0;+ }+ }++ template <ASIO_EXECUTION_EXECUTOR Executor>+ any_executor_base(Executor other, true_type)+ : object_fns_(object_fns_table<shared_target_executor>()),+ target_fns_(other.target_fns_)+ {+ Executor* p = 0;+ new (&object_) shared_target_executor(+ ASIO_MOVE_CAST(Executor)(other), p);+ target_ = p->template target<void>();+ }++ template <ASIO_EXECUTION_EXECUTOR Executor>+ any_executor_base(std::nothrow_t,+ Executor other, true_type) ASIO_NOEXCEPT+ : object_fns_(object_fns_table<shared_target_executor>()),+ target_fns_(other.target_fns_)+ {+ Executor* p = 0;+ new (&object_) shared_target_executor(+ std::nothrow, ASIO_MOVE_CAST(Executor)(other), p);+ if (p)+ target_ = p->template target<void>();+ else+ {+ target_ = 0;+ object_fns_ = 0;+ target_fns_ = 0;+ }+ }++ any_executor_base(const any_executor_base& other) ASIO_NOEXCEPT+ {+ if (!!other)+ {+ object_fns_ = other.object_fns_;+ target_fns_ = other.target_fns_;+ object_fns_->copy(*this, other);+ }+ else+ {+ object_fns_ = 0;+ target_ = 0;+ target_fns_ = 0;+ }+ }++ ~any_executor_base() ASIO_NOEXCEPT+ {+ if (!!*this)+ object_fns_->destroy(*this);+ }++ any_executor_base& operator=(+ const any_executor_base& other) ASIO_NOEXCEPT+ {+ if (this != &other)+ {+ if (!!*this)+ object_fns_->destroy(*this);+ if (!!other)+ {+ object_fns_ = other.object_fns_;+ target_fns_ = other.target_fns_;+ object_fns_->copy(*this, other);+ }+ else+ {+ object_fns_ = 0;+ target_ = 0;+ target_fns_ = 0;+ }+ }+ return *this;+ }++ any_executor_base& operator=(nullptr_t) ASIO_NOEXCEPT+ {+ if (target_)+ object_fns_->destroy(*this);+ target_ = 0;+ object_fns_ = 0;+ target_fns_ = 0;+ return *this;+ }++#if defined(ASIO_HAS_MOVE)++ any_executor_base(any_executor_base&& other) ASIO_NOEXCEPT+ {+ if (other.target_)+ {+ object_fns_ = other.object_fns_;+ target_fns_ = other.target_fns_;+ other.object_fns_ = 0;+ other.target_fns_ = 0;+ object_fns_->move(*this, other);+ other.target_ = 0;+ }+ else+ {+ object_fns_ = 0;+ target_ = 0;+ target_fns_ = 0;+ }+ }++ any_executor_base& operator=(+ any_executor_base&& other) ASIO_NOEXCEPT+ {+ if (this != &other)+ {+ if (!!*this)+ object_fns_->destroy(*this);+ if (!!other)+ {+ object_fns_ = other.object_fns_;+ target_fns_ = other.target_fns_;+ other.object_fns_ = 0;+ other.target_fns_ = 0;+ object_fns_->move(*this, other);+ other.target_ = 0;+ }+ else+ {+ object_fns_ = 0;+ target_ = 0;+ target_fns_ = 0;+ }+ }+ return *this;+ }++#endif // defined(ASIO_HAS_MOVE)++ void swap(any_executor_base& other) ASIO_NOEXCEPT+ {+ if (this != &other)+ {+ any_executor_base tmp(ASIO_MOVE_CAST(any_executor_base)(other));+ other = ASIO_MOVE_CAST(any_executor_base)(*this);+ *this = ASIO_MOVE_CAST(any_executor_base)(tmp);+ }+ }++ template <typename F>+ void execute(ASIO_MOVE_ARG(F) f) const+ {+ if (target_)+ {+ if (target_fns_->blocking_execute != 0)+ {+ asio::detail::non_const_lvalue<F> f2(f);+ target_fns_->blocking_execute(*this, function_view(f2.value));+ }+ else+ {+ target_fns_->execute(*this,+ function(ASIO_MOVE_CAST(F)(f), std::allocator<void>()));+ }+ }+ else+ {+ bad_executor ex;+ asio::detail::throw_exception(ex);+ }+ }++ template <typename Executor>+ Executor* target()+ {+ return target_ && (is_same<Executor, void>::value+ || target_fns_->target_type() == target_type_ex<Executor>())+ ? static_cast<Executor*>(target_) : 0;+ }++ template <typename Executor>+ const Executor* target() const+ {+ return target_ && (is_same<Executor, void>::value+ || target_fns_->target_type() == target_type_ex<Executor>())+ ? static_cast<const Executor*>(target_) : 0;+ }++#if !defined(ASIO_NO_TYPEID)+ const std::type_info& target_type() const+ {+ return target_ ? target_fns_->target_type() : typeid(void);+ }+#else // !defined(ASIO_NO_TYPEID)+ const void* target_type() const+ {+ return target_ ? target_fns_->target_type() : 0;+ }+#endif // !defined(ASIO_NO_TYPEID)++ struct unspecified_bool_type_t {};+ typedef void (*unspecified_bool_type)(unspecified_bool_type_t);+ static void unspecified_bool_true(unspecified_bool_type_t) {}++ operator unspecified_bool_type() const ASIO_NOEXCEPT+ {+ return target_ ? &any_executor_base::unspecified_bool_true : 0;+ }++ bool operator!() const ASIO_NOEXCEPT+ {+ return target_ == 0;+ }++protected:+ bool equality_helper(const any_executor_base& other) const ASIO_NOEXCEPT+ {+ if (target_ == other.target_)+ return true;+ if (target_ && !other.target_)+ return false;+ if (!target_ && other.target_)+ return false;+ if (target_fns_ != other.target_fns_)+ return false;+ return target_fns_->equal(*this, other);+ }++ template <typename Ex>+ Ex& object()+ {+ return *static_cast<Ex*>(static_cast<void*>(&object_));+ }++ template <typename Ex>+ const Ex& object() const+ {+ return *static_cast<const Ex*>(static_cast<const void*>(&object_));+ }++ struct object_fns+ {+ void (*destroy)(any_executor_base&);+ void (*copy)(any_executor_base&, const any_executor_base&);+ void (*move)(any_executor_base&, any_executor_base&);+ const void* (*target)(const any_executor_base&);+ };++ static void destroy_shared(any_executor_base& ex)+ {+ typedef shared_target_executor type;+ ex.object<type>().~type();+ }++ static void copy_shared(any_executor_base& ex1, const any_executor_base& ex2)+ {+ typedef shared_target_executor type;+ new (&ex1.object_) type(ex2.object<type>());+ ex1.target_ = ex2.target_;+ }++ static void move_shared(any_executor_base& ex1, any_executor_base& ex2)+ {+ typedef shared_target_executor type;+ new (&ex1.object_) type(ASIO_MOVE_CAST(type)(ex2.object<type>()));+ ex1.target_ = ex2.target_;+ ex2.object<type>().~type();+ }++ static const void* target_shared(const any_executor_base& ex)+ {+ typedef shared_target_executor type;+ return ex.object<type>().get();+ }++ template <typename Obj>+ static const object_fns* object_fns_table(+ typename enable_if<+ is_same<Obj, shared_target_executor>::value+ >::type* = 0)+ {+ static const object_fns fns =+ {+ &any_executor_base::destroy_shared,+ &any_executor_base::copy_shared,+ &any_executor_base::move_shared,+ &any_executor_base::target_shared+ };+ return &fns;+ }++ template <typename Obj>+ static void destroy_object(any_executor_base& ex)+ {+ ex.object<Obj>().~Obj();+ }++ template <typename Obj>+ static void copy_object(any_executor_base& ex1, const any_executor_base& ex2)+ {+ new (&ex1.object_) Obj(ex2.object<Obj>());+ ex1.target_ = &ex1.object<Obj>();+ }++ template <typename Obj>+ static void move_object(any_executor_base& ex1, any_executor_base& ex2)+ {+ new (&ex1.object_) Obj(ASIO_MOVE_CAST(Obj)(ex2.object<Obj>()));+ ex1.target_ = &ex1.object<Obj>();+ ex2.object<Obj>().~Obj();+ }++ template <typename Obj>+ static const void* target_object(const any_executor_base& ex)+ {+ return &ex.object<Obj>();+ }++ template <typename Obj>+ static const object_fns* object_fns_table(+ typename enable_if<+ !is_same<Obj, void>::value+ && !is_same<Obj, shared_target_executor>::value+ >::type* = 0)+ {+ static const object_fns fns =+ {+ &any_executor_base::destroy_object<Obj>,+ &any_executor_base::copy_object<Obj>,+ &any_executor_base::move_object<Obj>,+ &any_executor_base::target_object<Obj>+ };+ return &fns;+ }++ typedef asio::detail::executor_function function;+ typedef asio::detail::executor_function_view function_view;++ struct target_fns+ {+#if !defined(ASIO_NO_TYPEID)+ const std::type_info& (*target_type)();+#else // !defined(ASIO_NO_TYPEID)+ const void* (*target_type)();+#endif // !defined(ASIO_NO_TYPEID)+ bool (*equal)(const any_executor_base&, const any_executor_base&);+ void (*execute)(const any_executor_base&, ASIO_MOVE_ARG(function));+ void (*blocking_execute)(const any_executor_base&, function_view);+ };++#if !defined(ASIO_NO_TYPEID)+ template <typename Ex>+ static const std::type_info& target_type_ex()+ {+ return typeid(Ex);+ }+#else // !defined(ASIO_NO_TYPEID)+ template <typename Ex>+ static const void* target_type_ex()+ {+ static int unique_id;+ return &unique_id;+ }+#endif // !defined(ASIO_NO_TYPEID)++ template <typename Ex>+ static bool equal_ex(const any_executor_base& ex1,+ const any_executor_base& ex2)+ {+ const Ex* p1 = ex1.target<Ex>();+ const Ex* p2 = ex2.target<Ex>();+ ASIO_ASSUME(p1 != 0 && p2 != 0);+ return *p1 == *p2;+ }++ template <typename Ex>+ static void execute_ex(const any_executor_base& ex,+ ASIO_MOVE_ARG(function) f)+ {+ const Ex* p = ex.target<Ex>();+ ASIO_ASSUME(p != 0);+#if defined(ASIO_NO_DEPRECATED)+ p->execute(ASIO_MOVE_CAST(function)(f));+#else // defined(ASIO_NO_DEPRECATED)+ execution::execute(*p, ASIO_MOVE_CAST(function)(f));+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename Ex>+ static void blocking_execute_ex(const any_executor_base& ex, function_view f)+ {+ const Ex* p = ex.target<Ex>();+ ASIO_ASSUME(p != 0);+#if defined(ASIO_NO_DEPRECATED)+ p->execute(f);+#else // defined(ASIO_NO_DEPRECATED)+ execution::execute(*p, f);+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename Ex>+ static const target_fns* target_fns_table(bool is_always_blocking,+ typename enable_if<+ !is_same<Ex, void>::value+ >::type* = 0)+ {+ static const target_fns fns_with_execute =+ {+ &any_executor_base::target_type_ex<Ex>,+ &any_executor_base::equal_ex<Ex>,+ &any_executor_base::execute_ex<Ex>,+ 0+ };++ static const target_fns fns_with_blocking_execute =+ {+ &any_executor_base::target_type_ex<Ex>,+ &any_executor_base::equal_ex<Ex>,+ 0,+ &any_executor_base::blocking_execute_ex<Ex>+ };++ return is_always_blocking ? &fns_with_blocking_execute : &fns_with_execute;+ }++#if defined(ASIO_MSVC)+# pragma warning (push)+# pragma warning (disable:4702)+#endif // defined(ASIO_MSVC)++ static void query_fn_void(void*, const void*, const void*)+ {+ bad_executor ex;+ asio::detail::throw_exception(ex);+ }++ template <typename Ex, class Prop>+ static void query_fn_non_void(void*, const void* ex, const void* prop,+ typename enable_if<+ asio::can_query<const Ex&, const Prop&>::value+ && is_same<typename Prop::polymorphic_query_result_type, void>::value+ >::type*)+ {+ asio::query(*static_cast<const Ex*>(ex),+ *static_cast<const Prop*>(prop));+ }++ template <typename Ex, class Prop>+ static void query_fn_non_void(void*, const void*, const void*,+ typename enable_if<+ !asio::can_query<const Ex&, const Prop&>::value+ && is_same<typename Prop::polymorphic_query_result_type, void>::value+ >::type*)+ {+ }++ template <typename Ex, class Prop>+ static void query_fn_non_void(void* result, const void* ex, const void* prop,+ typename enable_if<+ asio::can_query<const Ex&, const Prop&>::value+ && !is_same<typename Prop::polymorphic_query_result_type, void>::value+ && is_reference<typename Prop::polymorphic_query_result_type>::value+ >::type*)+ {+ *static_cast<typename remove_reference<+ typename Prop::polymorphic_query_result_type>::type**>(result)+ = &static_cast<typename Prop::polymorphic_query_result_type>(+ asio::query(*static_cast<const Ex*>(ex),+ *static_cast<const Prop*>(prop)));+ }++ template <typename Ex, class Prop>+ static void query_fn_non_void(void*, const void*, const void*,+ typename enable_if<+ !asio::can_query<const Ex&, const Prop&>::value+ && !is_same<typename Prop::polymorphic_query_result_type, void>::value+ && is_reference<typename Prop::polymorphic_query_result_type>::value+ >::type*)+ {+ std::terminate(); // Combination should not be possible.+ }++ template <typename Ex, class Prop>+ static void query_fn_non_void(void* result, const void* ex, const void* prop,+ typename enable_if<+ asio::can_query<const Ex&, const Prop&>::value+ && !is_same<typename Prop::polymorphic_query_result_type, void>::value+ && is_scalar<typename Prop::polymorphic_query_result_type>::value+ >::type*)+ {+ *static_cast<typename Prop::polymorphic_query_result_type*>(result)+ = static_cast<typename Prop::polymorphic_query_result_type>(+ asio::query(*static_cast<const Ex*>(ex),+ *static_cast<const Prop*>(prop)));+ }++ template <typename Ex, class Prop>+ static void query_fn_non_void(void* result, const void*, const void*,+ typename enable_if<+ !asio::can_query<const Ex&, const Prop&>::value+ && !is_same<typename Prop::polymorphic_query_result_type, void>::value+ && is_scalar<typename Prop::polymorphic_query_result_type>::value+ >::type*)+ {+ *static_cast<typename Prop::polymorphic_query_result_type*>(result)+ = typename Prop::polymorphic_query_result_type();+ }++ template <typename Ex, class Prop>+ static void query_fn_non_void(void* result, const void* ex, const void* prop,+ typename enable_if<+ asio::can_query<const Ex&, const Prop&>::value+ && !is_same<typename Prop::polymorphic_query_result_type, void>::value+ && !is_reference<typename Prop::polymorphic_query_result_type>::value+ && !is_scalar<typename Prop::polymorphic_query_result_type>::value+ >::type*)+ {+ *static_cast<typename Prop::polymorphic_query_result_type**>(result)+ = new typename Prop::polymorphic_query_result_type(+ asio::query(*static_cast<const Ex*>(ex),+ *static_cast<const Prop*>(prop)));+ }++ template <typename Ex, class Prop>+ static void query_fn_non_void(void* result, const void*, const void*, ...)+ {+ *static_cast<typename Prop::polymorphic_query_result_type**>(result)+ = new typename Prop::polymorphic_query_result_type();+ }++ template <typename Ex, class Prop>+ static void query_fn_impl(void* result, const void* ex, const void* prop,+ typename enable_if<+ is_same<Ex, void>::value+ >::type*)+ {+ query_fn_void(result, ex, prop);+ }++ template <typename Ex, class Prop>+ static void query_fn_impl(void* result, const void* ex, const void* prop,+ typename enable_if<+ !is_same<Ex, void>::value+ >::type*)+ {+ query_fn_non_void<Ex, Prop>(result, ex, prop, 0);+ }++ template <typename Ex, class Prop>+ static void query_fn(void* result, const void* ex, const void* prop)+ {+ query_fn_impl<Ex, Prop>(result, ex, prop, 0);+ }++ template <typename Poly, typename Ex, class Prop>+ static Poly require_fn_impl(const void*, const void*,+ typename enable_if<+ is_same<Ex, void>::value+ >::type*)+ {+ bad_executor ex;+ asio::detail::throw_exception(ex);+ return Poly();+ }++ template <typename Poly, typename Ex, class Prop>+ static Poly require_fn_impl(const void* ex, const void* prop,+ typename enable_if<+ !is_same<Ex, void>::value && Prop::is_requirable+ >::type*)+ {+ return asio::require(*static_cast<const Ex*>(ex),+ *static_cast<const Prop*>(prop));+ }++ template <typename Poly, typename Ex, class Prop>+ static Poly require_fn_impl(const void*, const void*, ...)+ {+ return Poly();+ }++ template <typename Poly, typename Ex, class Prop>+ static Poly require_fn(const void* ex, const void* prop)+ {+ return require_fn_impl<Poly, Ex, Prop>(ex, prop, 0);+ }++ template <typename Poly, typename Ex, class Prop>+ static Poly prefer_fn_impl(const void*, const void*,+ typename enable_if<+ is_same<Ex, void>::value+ >::type*)+ {+ bad_executor ex;+ asio::detail::throw_exception(ex);+ return Poly();+ }++ template <typename Poly, typename Ex, class Prop>+ static Poly prefer_fn_impl(const void* ex, const void* prop,+ typename enable_if<+ !is_same<Ex, void>::value && Prop::is_preferable+ >::type*)+ {+ return asio::prefer(*static_cast<const Ex*>(ex),+ *static_cast<const Prop*>(prop));+ }++ template <typename Poly, typename Ex, class Prop>+ static Poly prefer_fn_impl(const void*, const void*, ...)+ {+ return Poly();+ }++ template <typename Poly, typename Ex, class Prop>+ static Poly prefer_fn(const void* ex, const void* prop)+ {+ return prefer_fn_impl<Poly, Ex, Prop>(ex, prop, 0);+ }++ template <typename Poly>+ struct prop_fns+ {+ void (*query)(void*, const void*, const void*);+ Poly (*require)(const void*, const void*);+ Poly (*prefer)(const void*, const void*);+ };++#if defined(ASIO_MSVC)+# pragma warning (pop)+#endif // defined(ASIO_MSVC)++private:+ template <typename Executor>+ static execution::blocking_t query_blocking(const Executor& ex, true_type)+ {+ return asio::query(ex, execution::blocking);+ }++ template <typename Executor>+ static execution::blocking_t query_blocking(const Executor&, false_type)+ {+ return execution::blocking_t();+ }++ template <typename Executor>+ void construct_object(Executor& ex, true_type)+ {+ object_fns_ = object_fns_table<Executor>();+ target_ = new (&object_) Executor(ASIO_MOVE_CAST(Executor)(ex));+ }++ template <typename Executor>+ void construct_object(Executor& ex, false_type)+ {+ object_fns_ = object_fns_table<shared_target_executor>();+ Executor* p = 0;+ new (&object_) shared_target_executor(+ ASIO_MOVE_CAST(Executor)(ex), p);+ target_ = p;+ }++ template <typename Executor>+ void construct_object(std::nothrow_t,+ Executor& ex, true_type) ASIO_NOEXCEPT+ {+ object_fns_ = object_fns_table<Executor>();+ target_ = new (&object_) Executor(ASIO_MOVE_CAST(Executor)(ex));+ }++ template <typename Executor>+ void construct_object(std::nothrow_t,+ Executor& ex, false_type) ASIO_NOEXCEPT+ {+ object_fns_ = object_fns_table<shared_target_executor>();+ Executor* p = 0;+ new (&object_) shared_target_executor(+ std::nothrow, ASIO_MOVE_CAST(Executor)(ex), p);+ target_ = p;+ }++/*private:*/public:+// template <typename...> friend class any_executor;++ typedef aligned_storage<+ sizeof(asio::detail::shared_ptr<void>) + sizeof(void*),+ alignment_of<asio::detail::shared_ptr<void> >::value+ >::type object_type;++ object_type object_;+ const object_fns* object_fns_;+ void* target_;+ const target_fns* target_fns_;+};++template <typename Derived, typename Property, typename = void>+struct any_executor_context+{+};++#if !defined(ASIO_NO_TS_EXECUTORS)++template <typename Derived, typename Property>+struct any_executor_context<Derived, Property,+ typename enable_if<Property::value>::type>+{+ typename Property::query_result_type context() const+ {+ return static_cast<const Derived*>(this)->query(typename Property::type());+ }+};++#endif // !defined(ASIO_NO_TS_EXECUTORS)++} // namespace detail++template <>+class any_executor<> : public detail::any_executor_base+{+public:+ any_executor() ASIO_NOEXCEPT+ : detail::any_executor_base()+ {+ }++ any_executor(nullptr_t) ASIO_NOEXCEPT+ : detail::any_executor_base()+ {+ }++ template <typename Executor>+ any_executor(Executor ex,+ typename enable_if<+ conditional<+ !is_same<Executor, any_executor>::value+ && !is_base_of<detail::any_executor_base, Executor>::value,+ is_executor<Executor>,+ false_type+ >::type::value+ >::type* = 0)+ : detail::any_executor_base(+ ASIO_MOVE_CAST(Executor)(ex), false_type())+ {+ }++ template <typename Executor>+ any_executor(std::nothrow_t, Executor ex,+ typename enable_if<+ conditional<+ !is_same<Executor, any_executor>::value+ && !is_base_of<detail::any_executor_base, Executor>::value,+ is_executor<Executor>,+ false_type+ >::type::value+ >::type* = 0) ASIO_NOEXCEPT+ : detail::any_executor_base(std::nothrow,+ ASIO_MOVE_CAST(Executor)(ex), false_type())+ {+ }++#if defined(ASIO_HAS_VARIADIC_TEMPLATES)++ template <typename... OtherSupportableProperties>+ any_executor(any_executor<OtherSupportableProperties...> other)+ : detail::any_executor_base(+ static_cast<const detail::any_executor_base&>(other))+ {+ }++ template <typename... OtherSupportableProperties>+ any_executor(std::nothrow_t,+ any_executor<OtherSupportableProperties...> other) ASIO_NOEXCEPT+ : detail::any_executor_base(+ static_cast<const detail::any_executor_base&>(other))+ {+ }++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++ template <typename U0, typename U1, typename U2, typename U3,+ typename U4, typename U5, typename U6, typename U7>+ any_executor(any_executor<U0, U1, U2, U3, U4, U5, U6, U7> other)+ : detail::any_executor_base(+ static_cast<const detail::any_executor_base&>(other))+ {+ }++ template <typename U0, typename U1, typename U2, typename U3,+ typename U4, typename U5, typename U6, typename U7>+ any_executor(std::nothrow_t,+ any_executor<U0, U1, U2, U3, U4, U5, U6, U7> other) ASIO_NOEXCEPT+ : detail::any_executor_base(+ static_cast<const detail::any_executor_base&>(other))+ {+ }++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++ any_executor(const any_executor& other) ASIO_NOEXCEPT+ : detail::any_executor_base(+ static_cast<const detail::any_executor_base&>(other))+ {+ }++ any_executor(std::nothrow_t, const any_executor& other) ASIO_NOEXCEPT+ : detail::any_executor_base(+ static_cast<const detail::any_executor_base&>(other))+ {+ }++ any_executor& operator=(const any_executor& other) ASIO_NOEXCEPT+ {+ if (this != &other)+ {+ detail::any_executor_base::operator=(+ static_cast<const detail::any_executor_base&>(other));+ }+ return *this;+ }++ any_executor& operator=(nullptr_t p) ASIO_NOEXCEPT+ {+ detail::any_executor_base::operator=(p);+ return *this;+ }++#if defined(ASIO_HAS_MOVE)++ any_executor(any_executor&& other) ASIO_NOEXCEPT+ : detail::any_executor_base(+ static_cast<any_executor_base&&>(+ static_cast<any_executor_base&>(other)))+ {+ }++ any_executor(std::nothrow_t, any_executor&& other) ASIO_NOEXCEPT+ : detail::any_executor_base(+ static_cast<any_executor_base&&>(+ static_cast<any_executor_base&>(other)))+ {+ }++ any_executor& operator=(any_executor&& other) ASIO_NOEXCEPT+ {+ if (this != &other)+ {+ detail::any_executor_base::operator=(+ static_cast<detail::any_executor_base&&>(+ static_cast<detail::any_executor_base&>(other)));+ }+ return *this;+ }++#endif // defined(ASIO_HAS_MOVE)++ void swap(any_executor& other) ASIO_NOEXCEPT+ {+ detail::any_executor_base::swap(+ static_cast<detail::any_executor_base&>(other));+ }++ using detail::any_executor_base::execute;+ using detail::any_executor_base::target;+ using detail::any_executor_base::target_type;+ using detail::any_executor_base::operator unspecified_bool_type;+ using detail::any_executor_base::operator!;++ bool equality_helper(const any_executor& other) const ASIO_NOEXCEPT+ {+ return any_executor_base::equality_helper(other);+ }++ template <typename AnyExecutor1, typename AnyExecutor2>+ friend typename enable_if<+ is_base_of<any_executor, AnyExecutor1>::value+ || is_base_of<any_executor, AnyExecutor2>::value,+ bool+ >::type operator==(const AnyExecutor1& a,+ const AnyExecutor2& b) ASIO_NOEXCEPT+ {+ return static_cast<const any_executor&>(a).equality_helper(b);+ }++ template <typename AnyExecutor>+ friend typename enable_if<+ is_same<AnyExecutor, any_executor>::value,+ bool+ >::type operator==(const AnyExecutor& a, nullptr_t) ASIO_NOEXCEPT+ {+ return !a;+ }++ template <typename AnyExecutor>+ friend typename enable_if<+ is_same<AnyExecutor, any_executor>::value,+ bool+ >::type operator==(nullptr_t, const AnyExecutor& b) ASIO_NOEXCEPT+ {+ return !b;+ }++ template <typename AnyExecutor1, typename AnyExecutor2>+ friend typename enable_if<+ is_base_of<any_executor, AnyExecutor1>::value+ || is_base_of<any_executor, AnyExecutor2>::value,+ bool+ >::type operator!=(const AnyExecutor1& a,+ const AnyExecutor2& b) ASIO_NOEXCEPT+ {+ return !static_cast<const any_executor&>(a).equality_helper(b);+ }++ template <typename AnyExecutor>+ friend typename enable_if<+ is_same<AnyExecutor, any_executor>::value,+ bool+ >::type operator!=(const AnyExecutor& a, nullptr_t) ASIO_NOEXCEPT+ {+ return !!a;+ }++ template <typename AnyExecutor>+ friend typename enable_if<+ is_same<AnyExecutor, any_executor>::value,+ bool+ >::type operator!=(nullptr_t, const AnyExecutor& b) ASIO_NOEXCEPT+ {+ return !!b;+ }+};++inline void swap(any_executor<>& a, any_executor<>& b) ASIO_NOEXCEPT+{+ return a.swap(b);+}++#if defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename... SupportableProperties>+class any_executor :+ public detail::any_executor_base,+ public detail::any_executor_context<+ any_executor<SupportableProperties...>,+ typename detail::supportable_properties<+ 0, void(SupportableProperties...)>::find_context_as_property>+{+public:+ any_executor() ASIO_NOEXCEPT+ : detail::any_executor_base(),+ prop_fns_(prop_fns_table<void>())+ {+ }++ any_executor(nullptr_t) ASIO_NOEXCEPT+ : detail::any_executor_base(),+ prop_fns_(prop_fns_table<void>())+ {+ }++ template <typename Executor>+ any_executor(Executor ex,+ typename enable_if<+ conditional<+ !is_same<Executor, any_executor>::value+ && !is_base_of<detail::any_executor_base, Executor>::value,+ detail::is_valid_target_executor<+ Executor, void(SupportableProperties...)>,+ false_type+ >::type::value+ >::type* = 0)+ : detail::any_executor_base(+ ASIO_MOVE_CAST(Executor)(ex), false_type()),+ prop_fns_(prop_fns_table<Executor>())+ {+ }++ template <typename Executor>+ any_executor(std::nothrow_t, Executor ex,+ typename enable_if<+ conditional<+ !is_same<Executor, any_executor>::value+ && !is_base_of<detail::any_executor_base, Executor>::value,+ detail::is_valid_target_executor<+ Executor, void(SupportableProperties...)>,+ false_type+ >::type::value+ >::type* = 0) ASIO_NOEXCEPT+ : detail::any_executor_base(std::nothrow,+ ASIO_MOVE_CAST(Executor)(ex), false_type()),+ prop_fns_(prop_fns_table<Executor>())+ {+ if (this->template target<void>() == 0)+ prop_fns_ = prop_fns_table<void>();+ }++ template <typename... OtherSupportableProperties>+ any_executor(any_executor<OtherSupportableProperties...> other,+ typename enable_if<+ conditional<+ !is_same<+ any_executor<OtherSupportableProperties...>,+ any_executor+ >::value,+ typename detail::supportable_properties<+ 0, void(SupportableProperties...)>::template is_valid_target<+ any_executor<OtherSupportableProperties...> >,+ false_type+ >::type::value+ >::type* = 0)+ : detail::any_executor_base(ASIO_MOVE_CAST(+ any_executor<OtherSupportableProperties...>)(other), true_type()),+ prop_fns_(prop_fns_table<any_executor<OtherSupportableProperties...> >())+ {+ }++ template <typename... OtherSupportableProperties>+ any_executor(std::nothrow_t,+ any_executor<OtherSupportableProperties...> other,+ typename enable_if<+ conditional<+ !is_same<+ any_executor<OtherSupportableProperties...>,+ any_executor+ >::value,+ typename detail::supportable_properties<+ 0, void(SupportableProperties...)>::template is_valid_target<+ any_executor<OtherSupportableProperties...> >,+ false_type+ >::type::value+ >::type* = 0) ASIO_NOEXCEPT+ : detail::any_executor_base(std::nothrow, ASIO_MOVE_CAST(+ any_executor<OtherSupportableProperties...>)(other), true_type()),+ prop_fns_(prop_fns_table<any_executor<OtherSupportableProperties...> >())+ {+ if (this->template target<void>() == 0)+ prop_fns_ = prop_fns_table<void>();+ }++ any_executor(const any_executor& other) ASIO_NOEXCEPT+ : detail::any_executor_base(+ static_cast<const detail::any_executor_base&>(other)),+ prop_fns_(other.prop_fns_)+ {+ }++ any_executor(std::nothrow_t, const any_executor& other) ASIO_NOEXCEPT+ : detail::any_executor_base(+ static_cast<const detail::any_executor_base&>(other)),+ prop_fns_(other.prop_fns_)+ {+ }++ any_executor& operator=(const any_executor& other) ASIO_NOEXCEPT+ {+ if (this != &other)+ {+ prop_fns_ = other.prop_fns_;+ detail::any_executor_base::operator=(+ static_cast<const detail::any_executor_base&>(other));+ }+ return *this;+ }++ any_executor& operator=(nullptr_t p) ASIO_NOEXCEPT+ {+ prop_fns_ = prop_fns_table<void>();+ detail::any_executor_base::operator=(p);+ return *this;+ }++#if defined(ASIO_HAS_MOVE)++ any_executor(any_executor&& other) ASIO_NOEXCEPT+ : detail::any_executor_base(+ static_cast<any_executor_base&&>(+ static_cast<any_executor_base&>(other))),+ prop_fns_(other.prop_fns_)+ {+ other.prop_fns_ = prop_fns_table<void>();+ }++ any_executor(std::nothrow_t, any_executor&& other) ASIO_NOEXCEPT+ : detail::any_executor_base(+ static_cast<any_executor_base&&>(+ static_cast<any_executor_base&>(other))),+ prop_fns_(other.prop_fns_)+ {+ other.prop_fns_ = prop_fns_table<void>();+ }++ any_executor& operator=(any_executor&& other) ASIO_NOEXCEPT+ {+ if (this != &other)+ {+ prop_fns_ = other.prop_fns_;+ detail::any_executor_base::operator=(+ static_cast<detail::any_executor_base&&>(+ static_cast<detail::any_executor_base&>(other)));+ }+ return *this;+ }++#endif // defined(ASIO_HAS_MOVE)++ void swap(any_executor& other) ASIO_NOEXCEPT+ {+ if (this != &other)+ {+ detail::any_executor_base::swap(+ static_cast<detail::any_executor_base&>(other));+ const prop_fns<any_executor>* tmp_prop_fns = other.prop_fns_;+ other.prop_fns_ = prop_fns_;+ prop_fns_ = tmp_prop_fns;+ }+ }++ using detail::any_executor_base::execute;+ using detail::any_executor_base::target;+ using detail::any_executor_base::target_type;+ using detail::any_executor_base::operator unspecified_bool_type;+ using detail::any_executor_base::operator!;++ bool equality_helper(const any_executor& other) const ASIO_NOEXCEPT+ {+ return any_executor_base::equality_helper(other);+ }++ template <typename AnyExecutor1, typename AnyExecutor2>+ friend typename enable_if<+ is_base_of<any_executor, AnyExecutor1>::value+ || is_base_of<any_executor, AnyExecutor2>::value,+ bool+ >::type operator==(const AnyExecutor1& a,+ const AnyExecutor2& b) ASIO_NOEXCEPT+ {+ return static_cast<const any_executor&>(a).equality_helper(b);+ }++ template <typename AnyExecutor>+ friend typename enable_if<+ is_same<AnyExecutor, any_executor>::value,+ bool+ >::type operator==(const AnyExecutor& a, nullptr_t) ASIO_NOEXCEPT+ {+ return !a;+ }++ template <typename AnyExecutor>+ friend typename enable_if<+ is_same<AnyExecutor, any_executor>::value,+ bool+ >::type operator==(nullptr_t, const AnyExecutor& b) ASIO_NOEXCEPT+ {+ return !b;+ }++ template <typename AnyExecutor1, typename AnyExecutor2>+ friend typename enable_if<+ is_base_of<any_executor, AnyExecutor1>::value+ || is_base_of<any_executor, AnyExecutor2>::value,+ bool+ >::type operator!=(const AnyExecutor1& a,+ const AnyExecutor2& b) ASIO_NOEXCEPT+ {+ return !static_cast<const any_executor&>(a).equality_helper(b);+ }++ template <typename AnyExecutor>+ friend typename enable_if<+ is_same<AnyExecutor, any_executor>::value,+ bool+ >::type operator!=(const AnyExecutor& a, nullptr_t) ASIO_NOEXCEPT+ {+ return !!a;+ }++ template <typename AnyExecutor>+ friend typename enable_if<+ is_same<AnyExecutor, any_executor>::value,+ bool+ >::type operator!=(nullptr_t, const AnyExecutor& b) ASIO_NOEXCEPT+ {+ return !!b;+ }++ template <typename T>+ struct find_convertible_property :+ detail::supportable_properties<+ 0, void(SupportableProperties...)>::template+ find_convertible_property<T> {};++ template <typename Property>+ void query(const Property& p,+ typename enable_if<+ is_same<+ typename find_convertible_property<Property>::query_result_type,+ void+ >::value+ >::type* = 0) const+ {+ typedef find_convertible_property<Property> found;+ prop_fns_[found::index].query(0, object_fns_->target(*this),+ &static_cast<const typename found::type&>(p));+ }++ template <typename Property>+ typename find_convertible_property<Property>::query_result_type+ query(const Property& p,+ typename enable_if<+ !is_same<+ typename find_convertible_property<Property>::query_result_type,+ void+ >::value+ &&+ is_reference<+ typename find_convertible_property<Property>::query_result_type+ >::value+ >::type* = 0) const+ {+ typedef find_convertible_property<Property> found;+ typename remove_reference<+ typename found::query_result_type>::type* result = 0;+ prop_fns_[found::index].query(&result, object_fns_->target(*this),+ &static_cast<const typename found::type&>(p));+ return *result;+ }++ template <typename Property>+ typename find_convertible_property<Property>::query_result_type+ query(const Property& p,+ typename enable_if<+ !is_same<+ typename find_convertible_property<Property>::query_result_type,+ void+ >::value+ &&+ is_scalar<+ typename find_convertible_property<Property>::query_result_type+ >::value+ >::type* = 0) const+ {+ typedef find_convertible_property<Property> found;+ typename found::query_result_type result;+ prop_fns_[found::index].query(&result, object_fns_->target(*this),+ &static_cast<const typename found::type&>(p));+ return result;+ }++ template <typename Property>+ typename find_convertible_property<Property>::query_result_type+ query(const Property& p,+ typename enable_if<+ !is_same<+ typename find_convertible_property<Property>::query_result_type,+ void+ >::value+ &&+ !is_reference<+ typename find_convertible_property<Property>::query_result_type+ >::value+ &&+ !is_scalar<+ typename find_convertible_property<Property>::query_result_type+ >::value+ >::type* = 0) const+ {+ typedef find_convertible_property<Property> found;+ typename found::query_result_type* result;+ prop_fns_[found::index].query(&result, object_fns_->target(*this),+ &static_cast<const typename found::type&>(p));+ return *asio::detail::scoped_ptr<+ typename found::query_result_type>(result);+ }++ template <typename T>+ struct find_convertible_requirable_property :+ detail::supportable_properties<+ 0, void(SupportableProperties...)>::template+ find_convertible_requirable_property<T> {};++ template <typename Property>+ any_executor require(const Property& p,+ typename enable_if<+ find_convertible_requirable_property<Property>::value+ >::type* = 0) const+ {+ typedef find_convertible_requirable_property<Property> found;+ return prop_fns_[found::index].require(object_fns_->target(*this),+ &static_cast<const typename found::type&>(p));+ }++ template <typename T>+ struct find_convertible_preferable_property :+ detail::supportable_properties<+ 0, void(SupportableProperties...)>::template+ find_convertible_preferable_property<T> {};++ template <typename Property>+ any_executor prefer(const Property& p,+ typename enable_if<+ find_convertible_preferable_property<Property>::value+ >::type* = 0) const+ {+ typedef find_convertible_preferable_property<Property> found;+ return prop_fns_[found::index].prefer(object_fns_->target(*this),+ &static_cast<const typename found::type&>(p));+ }++//private:+ template <typename Ex>+ static const prop_fns<any_executor>* prop_fns_table()+ {+ static const prop_fns<any_executor> fns[] =+ {+ {+ &detail::any_executor_base::query_fn<+ Ex, SupportableProperties>,+ &detail::any_executor_base::require_fn<+ any_executor, Ex, SupportableProperties>,+ &detail::any_executor_base::prefer_fn<+ any_executor, Ex, SupportableProperties>+ }...+ };+ return fns;+ }++ const prop_fns<any_executor>* prop_fns_;+};++template <typename... SupportableProperties>+inline void swap(any_executor<SupportableProperties...>& a,+ any_executor<SupportableProperties...>& b) ASIO_NOEXCEPT+{+ return a.swap(b);+}++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++#define ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS(n) \+ ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_##n++#define ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_1 \+ { \+ &detail::any_executor_base::query_fn<Ex, T1>, \+ &detail::any_executor_base::require_fn<any_executor, Ex, T1>, \+ &detail::any_executor_base::prefer_fn<any_executor, Ex, T1> \+ }+#define ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_2 \+ ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_1, \+ { \+ &detail::any_executor_base::query_fn<Ex, T2>, \+ &detail::any_executor_base::require_fn<any_executor, Ex, T2>, \+ &detail::any_executor_base::prefer_fn<any_executor, Ex, T2> \+ }+#define ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_3 \+ ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_2, \+ { \+ &detail::any_executor_base::query_fn<Ex, T3>, \+ &detail::any_executor_base::require_fn<any_executor, Ex, T3>, \+ &detail::any_executor_base::prefer_fn<any_executor, Ex, T3> \+ }+#define ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_4 \+ ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_3, \+ { \+ &detail::any_executor_base::query_fn<Ex, T4>, \+ &detail::any_executor_base::require_fn<any_executor, Ex, T4>, \+ &detail::any_executor_base::prefer_fn<any_executor, Ex, T4> \+ }+#define ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_5 \+ ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_4, \+ { \+ &detail::any_executor_base::query_fn<Ex, T5>, \+ &detail::any_executor_base::require_fn<any_executor, Ex, T5>, \+ &detail::any_executor_base::prefer_fn<any_executor, Ex, T5> \+ }+#define ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_6 \+ ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_5, \+ { \+ &detail::any_executor_base::query_fn<Ex, T6>, \+ &detail::any_executor_base::require_fn<any_executor, Ex, T6>, \+ &detail::any_executor_base::prefer_fn<any_executor, Ex, T6> \+ }+#define ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_7 \+ ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_6, \+ { \+ &detail::any_executor_base::query_fn<Ex, T7>, \+ &detail::any_executor_base::require_fn<any_executor, Ex, T7>, \+ &detail::any_executor_base::prefer_fn<any_executor, Ex, T7> \+ }+#define ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_8 \+ ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_7, \+ { \+ &detail::any_executor_base::query_fn<Ex, T8>, \+ &detail::any_executor_base::require_fn<any_executor, Ex, T8>, \+ &detail::any_executor_base::prefer_fn<any_executor, Ex, T8> \+ }++#if defined(ASIO_HAS_MOVE)++# define ASIO_PRIVATE_ANY_EXECUTOR_MOVE_OPS \+ any_executor(any_executor&& other) ASIO_NOEXCEPT \+ : detail::any_executor_base( \+ static_cast<any_executor_base&&>( \+ static_cast<any_executor_base&>(other))), \+ prop_fns_(other.prop_fns_) \+ { \+ other.prop_fns_ = prop_fns_table<void>(); \+ } \+ \+ any_executor(std::nothrow_t, any_executor&& other) ASIO_NOEXCEPT \+ : detail::any_executor_base( \+ static_cast<any_executor_base&&>( \+ static_cast<any_executor_base&>(other))), \+ prop_fns_(other.prop_fns_) \+ { \+ other.prop_fns_ = prop_fns_table<void>(); \+ } \+ \+ any_executor& operator=(any_executor&& other) ASIO_NOEXCEPT \+ { \+ if (this != &other) \+ { \+ prop_fns_ = other.prop_fns_; \+ detail::any_executor_base::operator=( \+ static_cast<detail::any_executor_base&&>( \+ static_cast<detail::any_executor_base&>(other))); \+ } \+ return *this; \+ } \+ /**/+#else // defined(ASIO_HAS_MOVE)++# define ASIO_PRIVATE_ANY_EXECUTOR_MOVE_OPS++#endif // defined(ASIO_HAS_MOVE)++#define ASIO_PRIVATE_ANY_EXECUTOR_DEF(n) \+ template <ASIO_VARIADIC_TPARAMS(n)> \+ class any_executor<ASIO_VARIADIC_TARGS(n)> : \+ public detail::any_executor_base, \+ public detail::any_executor_context< \+ any_executor<ASIO_VARIADIC_TARGS(n)>, \+ typename detail::supportable_properties< \+ 0, void(ASIO_VARIADIC_TARGS(n))>::find_context_as_property> \+ { \+ public: \+ any_executor() ASIO_NOEXCEPT \+ : detail::any_executor_base(), \+ prop_fns_(prop_fns_table<void>()) \+ { \+ } \+ \+ any_executor(nullptr_t) ASIO_NOEXCEPT \+ : detail::any_executor_base(), \+ prop_fns_(prop_fns_table<void>()) \+ { \+ } \+ \+ template <ASIO_EXECUTION_EXECUTOR Executor> \+ any_executor(Executor ex, \+ typename enable_if< \+ conditional< \+ !is_same<Executor, any_executor>::value \+ && !is_base_of<detail::any_executor_base, Executor>::value, \+ detail::is_valid_target_executor< \+ Executor, void(ASIO_VARIADIC_TARGS(n))>, \+ false_type \+ >::type::value \+ >::type* = 0) \+ : detail::any_executor_base(ASIO_MOVE_CAST( \+ Executor)(ex), false_type()), \+ prop_fns_(prop_fns_table<Executor>()) \+ { \+ } \+ \+ template <ASIO_EXECUTION_EXECUTOR Executor> \+ any_executor(std::nothrow_t, Executor ex, \+ typename enable_if< \+ conditional< \+ !is_same<Executor, any_executor>::value \+ && !is_base_of<detail::any_executor_base, Executor>::value, \+ detail::is_valid_target_executor< \+ Executor, void(ASIO_VARIADIC_TARGS(n))>, \+ false_type \+ >::type::value \+ >::type* = 0) ASIO_NOEXCEPT \+ : detail::any_executor_base(std::nothrow, \+ ASIO_MOVE_CAST(Executor)(ex), false_type()), \+ prop_fns_(prop_fns_table<Executor>()) \+ { \+ if (this->template target<void>() == 0) \+ prop_fns_ = prop_fns_table<void>(); \+ } \+ \+ any_executor(const any_executor& other) ASIO_NOEXCEPT \+ : detail::any_executor_base( \+ static_cast<const detail::any_executor_base&>(other)), \+ prop_fns_(other.prop_fns_) \+ { \+ } \+ \+ any_executor(std::nothrow_t, \+ const any_executor& other) ASIO_NOEXCEPT \+ : detail::any_executor_base( \+ static_cast<const detail::any_executor_base&>(other)), \+ prop_fns_(other.prop_fns_) \+ { \+ if (this->template target<void>() == 0) \+ prop_fns_ = prop_fns_table<void>(); \+ } \+ \+ any_executor(any_executor<> other) \+ : detail::any_executor_base(ASIO_MOVE_CAST( \+ any_executor<>)(other), true_type()), \+ prop_fns_(prop_fns_table<any_executor<> >()) \+ { \+ } \+ \+ any_executor(std::nothrow_t, any_executor<> other) ASIO_NOEXCEPT \+ : detail::any_executor_base(std::nothrow, \+ ASIO_MOVE_CAST(any_executor<>)(other), true_type()), \+ prop_fns_(prop_fns_table<any_executor<> >()) \+ { \+ if (this->template target<void>() == 0) \+ prop_fns_ = prop_fns_table<void>(); \+ } \+ \+ template <typename OtherAnyExecutor> \+ any_executor(OtherAnyExecutor other, \+ typename enable_if< \+ conditional< \+ !is_same<OtherAnyExecutor, any_executor>::value \+ && is_base_of<detail::any_executor_base, \+ OtherAnyExecutor>::value, \+ typename detail::supportable_properties< \+ 0, void(ASIO_VARIADIC_TARGS(n))>::template \+ is_valid_target<OtherAnyExecutor>, \+ false_type \+ >::type::value \+ >::type* = 0) \+ : detail::any_executor_base(ASIO_MOVE_CAST( \+ OtherAnyExecutor)(other), true_type()), \+ prop_fns_(prop_fns_table<OtherAnyExecutor>()) \+ { \+ } \+ \+ template <typename OtherAnyExecutor> \+ any_executor(std::nothrow_t, OtherAnyExecutor other, \+ typename enable_if< \+ conditional< \+ !is_same<OtherAnyExecutor, any_executor>::value \+ && is_base_of<detail::any_executor_base, \+ OtherAnyExecutor>::value, \+ typename detail::supportable_properties< \+ 0, void(ASIO_VARIADIC_TARGS(n))>::template \+ is_valid_target<OtherAnyExecutor>, \+ false_type \+ >::type::value \+ >::type* = 0) ASIO_NOEXCEPT \+ : detail::any_executor_base(std::nothrow, \+ ASIO_MOVE_CAST(OtherAnyExecutor)(other), true_type()), \+ prop_fns_(prop_fns_table<OtherAnyExecutor>()) \+ { \+ if (this->template target<void>() == 0) \+ prop_fns_ = prop_fns_table<void>(); \+ } \+ \+ any_executor& operator=(const any_executor& other) ASIO_NOEXCEPT \+ { \+ if (this != &other) \+ { \+ prop_fns_ = other.prop_fns_; \+ detail::any_executor_base::operator=( \+ static_cast<const detail::any_executor_base&>(other)); \+ } \+ return *this; \+ } \+ \+ any_executor& operator=(nullptr_t p) ASIO_NOEXCEPT \+ { \+ prop_fns_ = prop_fns_table<void>(); \+ detail::any_executor_base::operator=(p); \+ return *this; \+ } \+ \+ ASIO_PRIVATE_ANY_EXECUTOR_MOVE_OPS \+ \+ void swap(any_executor& other) ASIO_NOEXCEPT \+ { \+ if (this != &other) \+ { \+ detail::any_executor_base::swap( \+ static_cast<detail::any_executor_base&>(other)); \+ const prop_fns<any_executor>* tmp_prop_fns = other.prop_fns_; \+ other.prop_fns_ = prop_fns_; \+ prop_fns_ = tmp_prop_fns; \+ } \+ } \+ \+ using detail::any_executor_base::execute; \+ using detail::any_executor_base::target; \+ using detail::any_executor_base::target_type; \+ using detail::any_executor_base::operator unspecified_bool_type; \+ using detail::any_executor_base::operator!; \+ \+ bool equality_helper(const any_executor& other) const ASIO_NOEXCEPT \+ { \+ return any_executor_base::equality_helper(other); \+ } \+ \+ template <typename AnyExecutor1, typename AnyExecutor2> \+ friend typename enable_if< \+ is_base_of<any_executor, AnyExecutor1>::value \+ || is_base_of<any_executor, AnyExecutor2>::value, \+ bool \+ >::type operator==(const AnyExecutor1& a, \+ const AnyExecutor2& b) ASIO_NOEXCEPT \+ { \+ return static_cast<const any_executor&>(a).equality_helper(b); \+ } \+ \+ template <typename AnyExecutor> \+ friend typename enable_if< \+ is_same<AnyExecutor, any_executor>::value, \+ bool \+ >::type operator==(const AnyExecutor& a, nullptr_t) ASIO_NOEXCEPT \+ { \+ return !a; \+ } \+ \+ template <typename AnyExecutor> \+ friend typename enable_if< \+ is_same<AnyExecutor, any_executor>::value, \+ bool \+ >::type operator==(nullptr_t, const AnyExecutor& b) ASIO_NOEXCEPT \+ { \+ return !b; \+ } \+ \+ template <typename AnyExecutor1, typename AnyExecutor2> \+ friend typename enable_if< \+ is_base_of<any_executor, AnyExecutor1>::value \+ || is_base_of<any_executor, AnyExecutor2>::value, \+ bool \+ >::type operator!=(const AnyExecutor1& a, \+ const AnyExecutor2& b) ASIO_NOEXCEPT \+ { \+ return !static_cast<const any_executor&>(a).equality_helper(b); \+ } \+ \+ template <typename AnyExecutor> \+ friend typename enable_if< \+ is_same<AnyExecutor, any_executor>::value, \+ bool \+ >::type operator!=(const AnyExecutor& a, nullptr_t) ASIO_NOEXCEPT \+ { \+ return !!a; \+ } \+ \+ template <typename AnyExecutor> \+ friend typename enable_if< \+ is_same<AnyExecutor, any_executor>::value, \+ bool \+ >::type operator!=(nullptr_t, const AnyExecutor& b) ASIO_NOEXCEPT \+ { \+ return !!b; \+ } \+ \+ template <typename T> \+ struct find_convertible_property : \+ detail::supportable_properties< \+ 0, void(ASIO_VARIADIC_TARGS(n))>::template \+ find_convertible_property<T> {}; \+ \+ template <typename Property> \+ void query(const Property& p, \+ typename enable_if< \+ is_same< \+ typename find_convertible_property<Property>::query_result_type, \+ void \+ >::value \+ >::type* = 0) const \+ { \+ typedef find_convertible_property<Property> found; \+ prop_fns_[found::index].query(0, object_fns_->target(*this), \+ &static_cast<const typename found::type&>(p)); \+ } \+ \+ template <typename Property> \+ typename find_convertible_property<Property>::query_result_type \+ query(const Property& p, \+ typename enable_if< \+ !is_same< \+ typename find_convertible_property<Property>::query_result_type, \+ void \+ >::value \+ && \+ is_reference< \+ typename find_convertible_property<Property>::query_result_type \+ >::value \+ >::type* = 0) const \+ { \+ typedef find_convertible_property<Property> found; \+ typename remove_reference< \+ typename found::query_result_type>::type* result; \+ prop_fns_[found::index].query(&result, object_fns_->target(*this), \+ &static_cast<const typename found::type&>(p)); \+ return *result; \+ } \+ \+ template <typename Property> \+ typename find_convertible_property<Property>::query_result_type \+ query(const Property& p, \+ typename enable_if< \+ !is_same< \+ typename find_convertible_property<Property>::query_result_type, \+ void \+ >::value \+ && \+ is_scalar< \+ typename find_convertible_property<Property>::query_result_type \+ >::value \+ >::type* = 0) const \+ { \+ typedef find_convertible_property<Property> found; \+ typename found::query_result_type result; \+ prop_fns_[found::index].query(&result, object_fns_->target(*this), \+ &static_cast<const typename found::type&>(p)); \+ return result; \+ } \+ \+ template <typename Property> \+ typename find_convertible_property<Property>::query_result_type \+ query(const Property& p, \+ typename enable_if< \+ !is_same< \+ typename find_convertible_property<Property>::query_result_type, \+ void \+ >::value \+ && \+ !is_reference< \+ typename find_convertible_property<Property>::query_result_type \+ >::value \+ && \+ !is_scalar< \+ typename find_convertible_property<Property>::query_result_type \+ >::value \+ >::type* = 0) const \+ { \+ typedef find_convertible_property<Property> found; \+ typename found::query_result_type* result; \+ prop_fns_[found::index].query(&result, object_fns_->target(*this), \+ &static_cast<const typename found::type&>(p)); \+ return *asio::detail::scoped_ptr< \+ typename found::query_result_type>(result); \+ } \+ \+ template <typename T> \+ struct find_convertible_requirable_property : \+ detail::supportable_properties< \+ 0, void(ASIO_VARIADIC_TARGS(n))>::template \+ find_convertible_requirable_property<T> {}; \+ \+ template <typename Property> \+ any_executor require(const Property& p, \+ typename enable_if< \+ find_convertible_requirable_property<Property>::value \+ >::type* = 0) const \+ { \+ typedef find_convertible_requirable_property<Property> found; \+ return prop_fns_[found::index].require(object_fns_->target(*this), \+ &static_cast<const typename found::type&>(p)); \+ } \+ \+ template <typename T> \+ struct find_convertible_preferable_property : \+ detail::supportable_properties< \+ 0, void(ASIO_VARIADIC_TARGS(n))>::template \+ find_convertible_preferable_property<T> {}; \+ \+ template <typename Property> \+ any_executor prefer(const Property& p, \+ typename enable_if< \+ find_convertible_preferable_property<Property>::value \+ >::type* = 0) const \+ { \+ typedef find_convertible_preferable_property<Property> found; \+ return prop_fns_[found::index].prefer(object_fns_->target(*this), \+ &static_cast<const typename found::type&>(p)); \+ } \+ \+ template <typename Ex> \+ static const prop_fns<any_executor>* prop_fns_table() \+ { \+ static const prop_fns<any_executor> fns[] = \+ { \+ ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS(n) \+ }; \+ return fns; \+ } \+ \+ const prop_fns<any_executor>* prop_fns_; \+ typedef detail::supportable_properties<0, \+ void(ASIO_VARIADIC_TARGS(n))> supportable_properties_type; \+ }; \+ \+ template <ASIO_VARIADIC_TPARAMS(n)> \+ inline void swap(any_executor<ASIO_VARIADIC_TARGS(n)>& a, \+ any_executor<ASIO_VARIADIC_TARGS(n)>& b) ASIO_NOEXCEPT \+ { \+ return a.swap(b); \+ } \+ /**/+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_ANY_EXECUTOR_DEF)+#undef ASIO_PRIVATE_ANY_EXECUTOR_DEF+#undef ASIO_PRIVATE_ANY_EXECUTOR_MOVE_OPS+#undef ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS+#undef ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_1+#undef ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_2+#undef ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_3+#undef ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_4+#undef ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_5+#undef ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_6+#undef ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_7+#undef ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_8++#endif // if defined(ASIO_HAS_VARIADIC_TEMPLATES)++} // namespace execution+namespace traits {++#if !defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)+#if defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename... SupportableProperties>+struct equality_comparable<execution::any_executor<SupportableProperties...> >+{+ static const bool is_valid = true;+ static const bool is_noexcept = true;+};++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <>+struct equality_comparable<execution::any_executor<> >+{+ static const bool is_valid = true;+ static const bool is_noexcept = true;+};++#define ASIO_PRIVATE_ANY_EXECUTOR_EQUALITY_COMPARABLE_DEF(n) \+ template <ASIO_VARIADIC_TPARAMS(n)> \+ struct equality_comparable< \+ execution::any_executor<ASIO_VARIADIC_TARGS(n)> > \+ { \+ static const bool is_valid = true; \+ static const bool is_noexcept = true; \+ }; \+ /**/+ ASIO_VARIADIC_GENERATE(+ ASIO_PRIVATE_ANY_EXECUTOR_EQUALITY_COMPARABLE_DEF)+#undef ASIO_PRIVATE_ANY_EXECUTOR_EQUALITY_COMPARABLE_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+#endif // !defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)++#if !defined(ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)+#if defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename F, typename... SupportableProperties>+struct execute_member<execution::any_executor<SupportableProperties...>, F>+{+ static const bool is_valid = true;+ static const bool is_noexcept = false;+ typedef void result_type;+};++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename F>+struct execute_member<execution::any_executor<>, F>+{+ static const bool is_valid = true;+ static const bool is_noexcept = false;+ typedef void result_type;+};++#define ASIO_PRIVATE_ANY_EXECUTOR_EXECUTE_MEMBER_DEF(n) \+ template <typename F, ASIO_VARIADIC_TPARAMS(n)> \+ struct execute_member< \+ execution::any_executor<ASIO_VARIADIC_TARGS(n)>, F> \+ { \+ static const bool is_valid = true; \+ static const bool is_noexcept = false; \+ typedef void result_type; \+ }; \+ /**/+ ASIO_VARIADIC_GENERATE(+ ASIO_PRIVATE_ANY_EXECUTOR_EXECUTE_MEMBER_DEF)+#undef ASIO_PRIVATE_ANY_EXECUTOR_EXECUTE_MEMBER_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+#endif // !defined(ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)++#if !defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)+#if defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename Prop, typename... SupportableProperties>+struct query_member<+ execution::any_executor<SupportableProperties...>, Prop,+ typename enable_if<+ execution::detail::supportable_properties<+ 0, void(SupportableProperties...)>::template+ find_convertible_property<Prop>::value+ >::type>+{+ static const bool is_valid = true;+ static const bool is_noexcept = false;+ typedef typename execution::detail::supportable_properties<+ 0, void(SupportableProperties...)>::template+ find_convertible_property<Prop>::query_result_type result_type;+};++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++#define ASIO_PRIVATE_ANY_EXECUTOR_QUERY_MEMBER_DEF(n) \+ template <typename Prop, ASIO_VARIADIC_TPARAMS(n)> \+ struct query_member< \+ execution::any_executor<ASIO_VARIADIC_TARGS(n)>, Prop, \+ typename enable_if< \+ execution::detail::supportable_properties< \+ 0, void(ASIO_VARIADIC_TARGS(n))>::template \+ find_convertible_property<Prop>::value \+ >::type> \+ { \+ static const bool is_valid = true; \+ static const bool is_noexcept = false; \+ typedef typename execution::detail::supportable_properties< \+ 0, void(ASIO_VARIADIC_TARGS(n))>::template \+ find_convertible_property<Prop>::query_result_type result_type; \+ }; \+ /**/+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_ANY_EXECUTOR_QUERY_MEMBER_DEF)+#undef ASIO_PRIVATE_ANY_EXECUTOR_QUERY_MEMBER_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+#endif // !defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)++#if !defined(ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)+#if defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename Prop, typename... SupportableProperties>+struct require_member<+ execution::any_executor<SupportableProperties...>, Prop,+ typename enable_if<+ execution::detail::supportable_properties<+ 0, void(SupportableProperties...)>::template+ find_convertible_requirable_property<Prop>::value+ >::type>+{+ static const bool is_valid = true;+ static const bool is_noexcept = false;+ typedef execution::any_executor<SupportableProperties...> result_type;+};++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++#define ASIO_PRIVATE_ANY_EXECUTOR_REQUIRE_MEMBER_DEF(n) \+ template <typename Prop, ASIO_VARIADIC_TPARAMS(n)> \+ struct require_member< \+ execution::any_executor<ASIO_VARIADIC_TARGS(n)>, Prop, \+ typename enable_if< \+ execution::detail::supportable_properties< \+ 0, void(ASIO_VARIADIC_TARGS(n))>::template \+ find_convertible_requirable_property<Prop>::value \+ >::type> \+ { \+ static const bool is_valid = true; \+ static const bool is_noexcept = false; \+ typedef execution::any_executor<ASIO_VARIADIC_TARGS(n)> result_type; \+ }; \+ /**/+ ASIO_VARIADIC_GENERATE(+ ASIO_PRIVATE_ANY_EXECUTOR_REQUIRE_MEMBER_DEF)+#undef ASIO_PRIVATE_ANY_EXECUTOR_REQUIRE_MEMBER_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+#endif // !defined(ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)++#if !defined(ASIO_HAS_DEDUCED_PREFER_FREE_TRAIT)+#if defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename Prop, typename... SupportableProperties>+struct prefer_member<+ execution::any_executor<SupportableProperties...>, Prop,+ typename enable_if<+ execution::detail::supportable_properties<+ 0, void(SupportableProperties...)>::template+ find_convertible_preferable_property<Prop>::value+ >::type>+{+ static const bool is_valid = true;+ static const bool is_noexcept = false;+ typedef execution::any_executor<SupportableProperties...> result_type;+};++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++#define ASIO_PRIVATE_ANY_EXECUTOR_PREFER_FREE_DEF(n) \+ template <typename Prop, ASIO_VARIADIC_TPARAMS(n)> \+ struct prefer_member< \+ execution::any_executor<ASIO_VARIADIC_TARGS(n)>, Prop, \+ typename enable_if< \+ execution::detail::supportable_properties< \+ 0, void(ASIO_VARIADIC_TARGS(n))>::template \+ find_convertible_preferable_property<Prop>::value \+ >::type> \+ { \+ static const bool is_valid = true; \+ static const bool is_noexcept = false; \+ typedef execution::any_executor<ASIO_VARIADIC_TARGS(n)> result_type; \+ }; \+ /**/+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_ANY_EXECUTOR_PREFER_FREE_DEF)+#undef ASIO_PRIVATE_ANY_EXECUTOR_PREFER_FREE_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) #endif // !defined(ASIO_HAS_DEDUCED_PREFER_FREE_TRAIT) } // namespace traits
link/modules/asio-standalone/asio/include/asio/execution/bad_executor.hpp view
@@ -2,7 +2,7 @@ // execution/bad_executor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -28,10 +28,11 @@ { public: /// Constructor.- ASIO_DECL bad_executor() noexcept;+ ASIO_DECL bad_executor() ASIO_NOEXCEPT; /// Obtain message associated with exception.- ASIO_DECL virtual const char* what() const noexcept;+ ASIO_DECL virtual const char* what() const+ ASIO_NOEXCEPT_OR_NOTHROW; }; } // namespace execution
link/modules/asio-standalone/asio/include/asio/execution/blocking.hpp view
@@ -2,7 +2,7 @@ // execution/blocking.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -17,7 +17,10 @@ #include "asio/detail/config.hpp" #include "asio/detail/type_traits.hpp"+#include "asio/execution/execute.hpp" #include "asio/execution/executor.hpp"+#include "asio/execution/scheduler.hpp"+#include "asio/execution/sender.hpp" #include "asio/is_applicable_property.hpp" #include "asio/prefer.hpp" #include "asio/query.hpp"@@ -41,9 +44,10 @@ /// behaviour of their execution functions. struct blocking_t {- /// The blocking_t property applies to executors.+ /// The blocking_t property applies to executors, senders, and schedulers. template <typename T>- static constexpr bool is_applicable_property_v = is_executor_v<T>;+ static constexpr bool is_applicable_property_v =+ is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>; /// The top-level blocking_t property cannot be required. static constexpr bool is_requirable = false;@@ -59,9 +63,11 @@ /// submitted function object. struct possibly_t {- /// The blocking_t::possibly_t property applies to executors.+ /// The blocking_t::possibly_t property applies to executors, senders, and+ /// schedulers. template <typename T>- static constexpr bool is_applicable_property_v = is_executor_v<T>;+ static constexpr bool is_applicable_property_v =+ is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>; /// The blocking_t::possibly_t property can be required. static constexpr bool is_requirable = true;@@ -87,9 +93,11 @@ /// function object. struct always_t {- /// The blocking_t::always_t property applies to executors.+ /// The blocking_t::always_t property applies to executors, senders, and+ /// schedulers. template <typename T>- static constexpr bool is_applicable_property_v = is_executor_v<T>;+ static constexpr bool is_applicable_property_v =+ is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>; /// The blocking_t::always_t property can be required. static constexpr bool is_requirable = true;@@ -115,9 +123,11 @@ /// submitted function object. struct never_t {- /// The blocking_t::never_t property applies to executors.+ /// The blocking_t::never_t property applies to executors, senders, and+ /// schedulers. template <typename T>- static constexpr bool is_applicable_property_v = is_executor_v<T>;+ static constexpr bool is_applicable_property_v =+ is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>; /// The blocking_t::never_t property can be required. static constexpr bool is_requirable = true;@@ -190,8 +200,8 @@ template <typename Executor, typename Function> void blocking_execute(- Executor&& ex,- Function&& func);+ ASIO_MOVE_ARG(Executor) ex,+ ASIO_MOVE_ARG(Function) func); } // namespace blocking_adaptation @@ -199,34 +209,54 @@ struct blocking_t { #if defined(ASIO_HAS_VARIABLE_TEMPLATES)+# if defined(ASIO_NO_DEPRECATED) template <typename T>- static constexpr bool is_applicable_property_v = is_executor<T>::value;+ ASIO_STATIC_CONSTEXPR(bool,+ is_applicable_property_v = (+ is_executor<T>::value));+# else // defined(ASIO_NO_DEPRECATED)+ template <typename T>+ ASIO_STATIC_CONSTEXPR(bool,+ is_applicable_property_v = (+ is_executor<T>::value+ || conditional<+ is_executor<T>::value,+ false_type,+ is_sender<T>+ >::type::value+ || conditional<+ is_executor<T>::value,+ false_type,+ is_scheduler<T>+ >::type::value+ ));+# endif // defined(ASIO_NO_DEPRECATED) #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) - static constexpr bool is_requirable = false;- static constexpr bool is_preferable = false;+ ASIO_STATIC_CONSTEXPR(bool, is_requirable = false);+ ASIO_STATIC_CONSTEXPR(bool, is_preferable = false); typedef blocking_t polymorphic_query_result_type; typedef detail::blocking::possibly_t<I> possibly_t; typedef detail::blocking::always_t<I> always_t; typedef detail::blocking::never_t<I> never_t; - constexpr blocking_t()+ ASIO_CONSTEXPR blocking_t() : value_(-1) { } - constexpr blocking_t(possibly_t)+ ASIO_CONSTEXPR blocking_t(possibly_t) : value_(0) { } - constexpr blocking_t(always_t)+ ASIO_CONSTEXPR blocking_t(always_t) : value_(1) { } - constexpr blocking_t(never_t)+ ASIO_CONSTEXPR blocking_t(never_t) : value_(2) { }@@ -238,14 +268,16 @@ struct type { template <typename P>- auto query(P&& p) const+ auto query(ASIO_MOVE_ARG(P) p) const noexcept( noexcept(- declval<conditional_t<true, T, P>>().query(static_cast<P&&>(p))+ declval<typename conditional<true, T, P>::type>().query(+ ASIO_MOVE_CAST(P)(p)) ) ) -> decltype(- declval<conditional_t<true, T, P>>().query(static_cast<P&&>(p))+ declval<typename conditional<true, T, P>::type>().query(+ ASIO_MOVE_CAST(P)(p)) ); }; #else // defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)@@ -260,17 +292,17 @@ struct type { template <typename P>- static constexpr auto query(P&& p)+ static constexpr auto query(ASIO_MOVE_ARG(P) p) noexcept( noexcept(- conditional_t<true, T, P>::query(static_cast<P&&>(p))+ conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p)) ) ) -> decltype(- conditional_t<true, T, P>::query(static_cast<P&&>(p))+ conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p)) ) {- return T::query(static_cast<P&&>(p));+ return T::query(ASIO_MOVE_CAST(P)(p)); } }; #else // defined(ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)@@ -290,87 +322,88 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T>- static constexpr+ static ASIO_CONSTEXPR typename query_static_constexpr_member<T>::result_type static_query()- noexcept(query_static_constexpr_member<T>::is_noexcept)+ ASIO_NOEXCEPT_IF((+ query_static_constexpr_member<T>::is_noexcept)) { return query_static_constexpr_member<T>::value(); } template <typename T>- static constexpr+ static ASIO_CONSTEXPR typename traits::static_query<T, possibly_t>::result_type static_query(- enable_if_t<+ typename enable_if< !query_static_constexpr_member<T>::is_valid- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< !query_member<T>::is_valid- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< traits::static_query<T, possibly_t>::is_valid- >* = 0) noexcept+ >::type* = 0) ASIO_NOEXCEPT { return traits::static_query<T, possibly_t>::value(); } template <typename T>- static constexpr+ static ASIO_CONSTEXPR typename traits::static_query<T, always_t>::result_type static_query(- enable_if_t<+ typename enable_if< !query_static_constexpr_member<T>::is_valid- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< !query_member<T>::is_valid- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< !traits::static_query<T, possibly_t>::is_valid- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< traits::static_query<T, always_t>::is_valid- >* = 0) noexcept+ >::type* = 0) ASIO_NOEXCEPT { return traits::static_query<T, always_t>::value(); } template <typename T>- static constexpr+ static ASIO_CONSTEXPR typename traits::static_query<T, never_t>::result_type static_query(- enable_if_t<+ typename enable_if< !query_static_constexpr_member<T>::is_valid- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< !query_member<T>::is_valid- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< !traits::static_query<T, possibly_t>::is_valid- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< !traits::static_query<T, always_t>::is_valid- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< traits::static_query<T, never_t>::is_valid- >* = 0) noexcept+ >::type* = 0) ASIO_NOEXCEPT { return traits::static_query<T, never_t>::value(); } template <typename E, typename T = decltype(blocking_t::static_query<E>())>- static constexpr const T static_query_v+ static ASIO_CONSTEXPR const T static_query_v = blocking_t::static_query<E>(); #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) - friend constexpr bool operator==(+ friend ASIO_CONSTEXPR bool operator==( const blocking_t& a, const blocking_t& b) { return a.value_ == b.value_; } - friend constexpr bool operator!=(+ friend ASIO_CONSTEXPR bool operator!=( const blocking_t& a, const blocking_t& b) { return a.value_ != b.value_;@@ -378,20 +411,22 @@ struct convertible_from_blocking_t {- constexpr convertible_from_blocking_t(blocking_t) {}+ ASIO_CONSTEXPR convertible_from_blocking_t(blocking_t) {} }; template <typename Executor>- friend constexpr blocking_t query(+ friend ASIO_CONSTEXPR blocking_t query( const Executor& ex, convertible_from_blocking_t,- enable_if_t<+ typename enable_if< can_query<const Executor&, possibly_t>::value- >* = 0)+ >::type* = 0) #if !defined(__clang__) // Clang crashes if noexcept is used here. #if defined(ASIO_MSVC) // Visual C++ wants the type to be qualified.- noexcept(is_nothrow_query<const Executor&, blocking_t<>::possibly_t>::value)+ ASIO_NOEXCEPT_IF((+ is_nothrow_query<const Executor&, blocking_t<>::possibly_t>::value)) #else // defined(ASIO_MSVC)- noexcept(is_nothrow_query<const Executor&, possibly_t>::value)+ ASIO_NOEXCEPT_IF((+ is_nothrow_query<const Executor&, possibly_t>::value)) #endif // defined(ASIO_MSVC) #endif // !defined(__clang__) {@@ -399,19 +434,21 @@ } template <typename Executor>- friend constexpr blocking_t query(+ friend ASIO_CONSTEXPR blocking_t query( const Executor& ex, convertible_from_blocking_t,- enable_if_t<+ typename enable_if< !can_query<const Executor&, possibly_t>::value- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< can_query<const Executor&, always_t>::value- >* = 0)+ >::type* = 0) #if !defined(__clang__) // Clang crashes if noexcept is used here. #if defined(ASIO_MSVC) // Visual C++ wants the type to be qualified.- noexcept(is_nothrow_query<const Executor&, blocking_t<>::always_t>::value)+ ASIO_NOEXCEPT_IF((+ is_nothrow_query<const Executor&, blocking_t<>::always_t>::value)) #else // defined(ASIO_MSVC)- noexcept(is_nothrow_query<const Executor&, always_t>::value)+ ASIO_NOEXCEPT_IF((+ is_nothrow_query<const Executor&, always_t>::value)) #endif // defined(ASIO_MSVC) #endif // !defined(__clang__) {@@ -419,22 +456,24 @@ } template <typename Executor>- friend constexpr blocking_t query(+ friend ASIO_CONSTEXPR blocking_t query( const Executor& ex, convertible_from_blocking_t,- enable_if_t<+ typename enable_if< !can_query<const Executor&, possibly_t>::value- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< !can_query<const Executor&, always_t>::value- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< can_query<const Executor&, never_t>::value- >* = 0)+ >::type* = 0) #if !defined(__clang__) // Clang crashes if noexcept is used here. #if defined(ASIO_MSVC) // Visual C++ wants the type to be qualified.- noexcept(is_nothrow_query<const Executor&, blocking_t<>::never_t>::value)+ ASIO_NOEXCEPT_IF((+ is_nothrow_query<const Executor&, blocking_t<>::never_t>::value)) #else // defined(ASIO_MSVC)- noexcept(is_nothrow_query<const Executor&, never_t>::value)+ ASIO_NOEXCEPT_IF((+ is_nothrow_query<const Executor&, never_t>::value)) #endif // defined(ASIO_MSVC) #endif // !defined(__clang__) {@@ -445,6 +484,10 @@ ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(always_t, always); ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(never_t, never); +#if !defined(ASIO_HAS_CONSTEXPR)+ static const blocking_t instance;+#endif // !defined(ASIO_HAS_CONSTEXPR)+ private: int value_; };@@ -456,7 +499,12 @@ #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) +#if !defined(ASIO_HAS_CONSTEXPR) template <int I>+const blocking_t<I> blocking_t<I>::instance;+#endif++template <int I> const typename blocking_t<I>::possibly_t blocking_t<I>::possibly; template <int I>@@ -471,15 +519,35 @@ struct possibly_t { #if defined(ASIO_HAS_VARIABLE_TEMPLATES)+# if defined(ASIO_NO_DEPRECATED) template <typename T>- static constexpr bool is_applicable_property_v = is_executor<T>::value;+ ASIO_STATIC_CONSTEXPR(bool,+ is_applicable_property_v = (+ is_executor<T>::value));+# else // defined(ASIO_NO_DEPRECATED)+ template <typename T>+ ASIO_STATIC_CONSTEXPR(bool,+ is_applicable_property_v = (+ is_executor<T>::value+ || conditional<+ is_executor<T>::value,+ false_type,+ is_sender<T>+ >::type::value+ || conditional<+ is_executor<T>::value,+ false_type,+ is_scheduler<T>+ >::type::value+ ));+# endif // defined(ASIO_NO_DEPRECATED) #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) - static constexpr bool is_requirable = true;- static constexpr bool is_preferable = true;+ ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);+ ASIO_STATIC_CONSTEXPR(bool, is_preferable = true); typedef blocking_t<I> polymorphic_query_result_type; - constexpr possibly_t()+ ASIO_CONSTEXPR possibly_t() { } @@ -496,77 +564,78 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T>- static constexpr+ static ASIO_CONSTEXPR typename query_static_constexpr_member<T>::result_type static_query()- noexcept(query_static_constexpr_member<T>::is_noexcept)+ ASIO_NOEXCEPT_IF((+ query_static_constexpr_member<T>::is_noexcept)) { return query_static_constexpr_member<T>::value(); } template <typename T>- static constexpr possibly_t static_query(- enable_if_t<+ static ASIO_CONSTEXPR possibly_t static_query(+ typename enable_if< !query_static_constexpr_member<T>::is_valid- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< !query_member<T>::is_valid- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< !traits::query_free<T, possibly_t>::is_valid- >* = 0,- enable_if_t<- !can_query<T, always_t<I>>::value- >* = 0,- enable_if_t<- !can_query<T, never_t<I>>::value- >* = 0) noexcept+ >::type* = 0,+ typename enable_if<+ !can_query<T, always_t<I> >::value+ >::type* = 0,+ typename enable_if<+ !can_query<T, never_t<I> >::value+ >::type* = 0) ASIO_NOEXCEPT { return possibly_t(); } template <typename E, typename T = decltype(possibly_t::static_query<E>())>- static constexpr const T static_query_v+ static ASIO_CONSTEXPR const T static_query_v = possibly_t::static_query<E>(); #endif // defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) - static constexpr blocking_t<I> value()+ static ASIO_CONSTEXPR blocking_t<I> value() { return possibly_t(); } - friend constexpr bool operator==(+ friend ASIO_CONSTEXPR bool operator==( const possibly_t&, const possibly_t&) { return true; } - friend constexpr bool operator!=(+ friend ASIO_CONSTEXPR bool operator!=( const possibly_t&, const possibly_t&) { return false; } - friend constexpr bool operator==(+ friend ASIO_CONSTEXPR bool operator==( const possibly_t&, const always_t<I>&) { return false; } - friend constexpr bool operator!=(+ friend ASIO_CONSTEXPR bool operator!=( const possibly_t&, const always_t<I>&) { return true; } - friend constexpr bool operator==(+ friend ASIO_CONSTEXPR bool operator==( const possibly_t&, const never_t<I>&) { return false; } - friend constexpr bool operator!=(+ friend ASIO_CONSTEXPR bool operator!=( const possibly_t&, const never_t<I>&) { return true;@@ -584,110 +653,129 @@ class adapter { public:- adapter(int, const Executor& e) noexcept+ adapter(int, const Executor& e) ASIO_NOEXCEPT : executor_(e) { } - adapter(const adapter& other) noexcept+ adapter(const adapter& other) ASIO_NOEXCEPT : executor_(other.executor_) { } - adapter(adapter&& other) noexcept- : executor_(static_cast<Executor&&>(other.executor_))+#if defined(ASIO_HAS_MOVE)+ adapter(adapter&& other) ASIO_NOEXCEPT+ : executor_(ASIO_MOVE_CAST(Executor)(other.executor_)) { }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) template <int I>- static constexpr always_t<I> query(blocking_t<I>) noexcept+ static ASIO_CONSTEXPR always_t<I> query(+ blocking_t<I>) ASIO_NOEXCEPT { return always_t<I>(); } template <int I>- static constexpr always_t<I> query(possibly_t<I>) noexcept+ static ASIO_CONSTEXPR always_t<I> query(+ possibly_t<I>) ASIO_NOEXCEPT { return always_t<I>(); } template <int I>- static constexpr always_t<I> query(always_t<I>) noexcept+ static ASIO_CONSTEXPR always_t<I> query(+ always_t<I>) ASIO_NOEXCEPT { return always_t<I>(); } template <int I>- static constexpr always_t<I> query(never_t<I>) noexcept+ static ASIO_CONSTEXPR always_t<I> query(+ never_t<I>) ASIO_NOEXCEPT { return always_t<I>(); } template <typename Property>- enable_if_t<+ typename enable_if< can_query<const Executor&, Property>::value,- query_result_t<const Executor&, Property>- > query(const Property& p) const- noexcept(is_nothrow_query<const Executor&, Property>::value)+ typename query_result<const Executor&, Property>::type+ >::type query(const Property& p) const+ ASIO_NOEXCEPT_IF((+ is_nothrow_query<const Executor&, Property>::value)) { return asio::query(executor_, p); } template <int I>- enable_if_t<- can_require<const Executor&, possibly_t<I>>::value,- require_result_t<const Executor&, possibly_t<I>>- > require(possibly_t<I>) const noexcept+ typename enable_if<+ can_require<const Executor&, possibly_t<I> >::value,+ typename require_result<const Executor&, possibly_t<I> >::type+ >::type require(possibly_t<I>) const ASIO_NOEXCEPT { return asio::require(executor_, possibly_t<I>()); } template <int I>- enable_if_t<- can_require<const Executor&, never_t<I>>::value,- require_result_t<const Executor&, never_t<I>>- > require(never_t<I>) const noexcept+ typename enable_if<+ can_require<const Executor&, never_t<I> >::value,+ typename require_result<const Executor&, never_t<I> >::type+ >::type require(never_t<I>) const ASIO_NOEXCEPT { return asio::require(executor_, never_t<I>()); } template <typename Property>- enable_if_t<+ typename enable_if< can_require<const Executor&, Property>::value,- adapter<decay_t<require_result_t<const Executor&, Property>>>- > require(const Property& p) const- noexcept(is_nothrow_require<const Executor&, Property>::value)+ adapter<typename decay<+ typename require_result<const Executor&, Property>::type+ >::type>+ >::type require(const Property& p) const+ ASIO_NOEXCEPT_IF((+ is_nothrow_require<const Executor&, Property>::value)) {- return adapter<decay_t<require_result_t<const Executor&, Property>>>(- 0, asio::require(executor_, p));+ return adapter<typename decay<+ typename require_result<const Executor&, Property>::type+ >::type>(0, asio::require(executor_, p)); } template <typename Property>- enable_if_t<+ typename enable_if< can_prefer<const Executor&, Property>::value,- adapter<decay_t<prefer_result_t<const Executor&, Property>>>- > prefer(const Property& p) const- noexcept(is_nothrow_prefer<const Executor&, Property>::value)+ adapter<typename decay<+ typename prefer_result<const Executor&, Property>::type+ >::type>+ >::type prefer(const Property& p) const+ ASIO_NOEXCEPT_IF((+ is_nothrow_prefer<const Executor&, Property>::value)) {- return adapter<decay_t<prefer_result_t<const Executor&, Property>>>(- 0, asio::prefer(executor_, p));+ return adapter<typename decay<+ typename prefer_result<const Executor&, Property>::type+ >::type>(0, asio::prefer(executor_, p)); } template <typename Function>- enable_if_t<+ typename enable_if<+#if defined(ASIO_NO_DEPRECATED) traits::execute_member<const Executor&, Function>::is_valid- > execute(Function&& f) const+#else // defined(ASIO_NO_DEPRECATED)+ execution::can_execute<const Executor&, Function>::value+#endif // defined(ASIO_NO_DEPRECATED)+ >::type execute(ASIO_MOVE_ARG(Function) f) const { blocking_adaptation::blocking_execute(- executor_, static_cast<Function&&>(f));+ executor_, ASIO_MOVE_CAST(Function)(f)); } - friend bool operator==(const adapter& a, const adapter& b) noexcept+ friend bool operator==(const adapter& a, const adapter& b) ASIO_NOEXCEPT { return a.executor_ == b.executor_; } - friend bool operator!=(const adapter& a, const adapter& b) noexcept+ friend bool operator!=(const adapter& a, const adapter& b) ASIO_NOEXCEPT { return a.executor_ != b.executor_; }@@ -700,15 +788,35 @@ struct always_t { #if defined(ASIO_HAS_VARIABLE_TEMPLATES)+# if defined(ASIO_NO_DEPRECATED) template <typename T>- static constexpr bool is_applicable_property_v = is_executor<T>::value;+ ASIO_STATIC_CONSTEXPR(bool,+ is_applicable_property_v = (+ is_executor<T>::value));+# else // defined(ASIO_NO_DEPRECATED)+ template <typename T>+ ASIO_STATIC_CONSTEXPR(bool,+ is_applicable_property_v = (+ is_executor<T>::value+ || conditional<+ is_executor<T>::value,+ false_type,+ is_sender<T>+ >::type::value+ || conditional<+ is_executor<T>::value,+ false_type,+ is_scheduler<T>+ >::type::value+ ));+# endif // defined(ASIO_NO_DEPRECATED) #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) - static constexpr bool is_requirable = true;- static constexpr bool is_preferable = false;+ ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);+ ASIO_STATIC_CONSTEXPR(bool, is_preferable = false); typedef blocking_t<I> polymorphic_query_result_type; - constexpr always_t()+ ASIO_CONSTEXPR always_t() { } @@ -725,54 +833,57 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T>- static constexpr typename query_static_constexpr_member<T>::result_type+ static ASIO_CONSTEXPR+ typename query_static_constexpr_member<T>::result_type static_query()- noexcept(query_static_constexpr_member<T>::is_noexcept)+ ASIO_NOEXCEPT_IF((+ query_static_constexpr_member<T>::is_noexcept)) { return query_static_constexpr_member<T>::value(); } template <typename E, typename T = decltype(always_t::static_query<E>())>- static constexpr const T static_query_v = always_t::static_query<E>();+ static ASIO_CONSTEXPR const T static_query_v+ = always_t::static_query<E>(); #endif // defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) - static constexpr blocking_t<I> value()+ static ASIO_CONSTEXPR blocking_t<I> value() { return always_t(); } - friend constexpr bool operator==(+ friend ASIO_CONSTEXPR bool operator==( const always_t&, const always_t&) { return true; } - friend constexpr bool operator!=(+ friend ASIO_CONSTEXPR bool operator!=( const always_t&, const always_t&) { return false; } - friend constexpr bool operator==(+ friend ASIO_CONSTEXPR bool operator==( const always_t&, const possibly_t<I>&) { return false; } - friend constexpr bool operator!=(+ friend ASIO_CONSTEXPR bool operator!=( const always_t&, const possibly_t<I>&) { return true; } - friend constexpr bool operator==(+ friend ASIO_CONSTEXPR bool operator==( const always_t&, const never_t<I>&) { return false; } - friend constexpr bool operator!=(+ friend ASIO_CONSTEXPR bool operator!=( const always_t&, const never_t<I>&) { return true;@@ -781,15 +892,15 @@ template <typename Executor> friend adapter<Executor> require( const Executor& e, const always_t&,- enable_if_t<+ typename enable_if< is_executor<Executor>::value- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< traits::static_require< const Executor&, blocking_adaptation::allowed_t<0> >::is_valid- >* = 0)+ >::type* = 0) { return adapter<Executor>(0, e); }@@ -806,15 +917,35 @@ struct never_t { #if defined(ASIO_HAS_VARIABLE_TEMPLATES)+# if defined(ASIO_NO_DEPRECATED) template <typename T>- static constexpr bool is_applicable_property_v = is_executor<T>::value;+ ASIO_STATIC_CONSTEXPR(bool,+ is_applicable_property_v = (+ is_executor<T>::value));+# else // defined(ASIO_NO_DEPRECATED)+ template <typename T>+ ASIO_STATIC_CONSTEXPR(bool,+ is_applicable_property_v = (+ is_executor<T>::value+ || conditional<+ is_executor<T>::value,+ false_type,+ is_sender<T>+ >::type::value+ || conditional<+ is_executor<T>::value,+ false_type,+ is_scheduler<T>+ >::type::value+ ));+# endif // defined(ASIO_NO_DEPRECATED) #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) - static constexpr bool is_requirable = true;- static constexpr bool is_preferable = true;+ ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);+ ASIO_STATIC_CONSTEXPR(bool, is_preferable = true); typedef blocking_t<I> polymorphic_query_result_type; - constexpr never_t()+ ASIO_CONSTEXPR never_t() { } @@ -831,51 +962,58 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T>- static constexpr+ static ASIO_CONSTEXPR typename query_static_constexpr_member<T>::result_type static_query()- noexcept(query_static_constexpr_member<T>::is_noexcept)+ ASIO_NOEXCEPT_IF((+ query_static_constexpr_member<T>::is_noexcept)) { return query_static_constexpr_member<T>::value(); } template <typename E, typename T = decltype(never_t::static_query<E>())>- static constexpr const T static_query_v+ static ASIO_CONSTEXPR const T static_query_v = never_t::static_query<E>(); #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) - static constexpr blocking_t<I> value()+ static ASIO_CONSTEXPR blocking_t<I> value() { return never_t(); } - friend constexpr bool operator==(const never_t&, const never_t&)+ friend ASIO_CONSTEXPR bool operator==(+ const never_t&, const never_t&) { return true; } - friend constexpr bool operator!=(const never_t&, const never_t&)+ friend ASIO_CONSTEXPR bool operator!=(+ const never_t&, const never_t&) { return false; } - friend constexpr bool operator==(const never_t&, const possibly_t<I>&)+ friend ASIO_CONSTEXPR bool operator==(+ const never_t&, const possibly_t<I>&) { return false; } - friend constexpr bool operator!=(const never_t&, const possibly_t<I>&)+ friend ASIO_CONSTEXPR bool operator!=(+ const never_t&, const possibly_t<I>&) { return true; } - friend constexpr bool operator==(const never_t&, const always_t<I>&)+ friend ASIO_CONSTEXPR bool operator==(+ const never_t&, const always_t<I>&) { return false; } - friend constexpr bool operator!=(const never_t&, const always_t<I>&)+ friend ASIO_CONSTEXPR bool operator!=(+ const never_t&, const always_t<I>&) { return true; }@@ -892,7 +1030,11 @@ typedef detail::blocking_t<> blocking_t; -ASIO_INLINE_VARIABLE constexpr blocking_t blocking;+#if defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)+constexpr blocking_t blocking;+#else // defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)+namespace { static const blocking_t& blocking = blocking_t::instance; }+#endif } // namespace execution @@ -900,25 +1042,81 @@ template <typename T> struct is_applicable_property<T, execution::blocking_t>- : integral_constant<bool, execution::is_executor<T>::value>+ : integral_constant<bool,+ execution::is_executor<T>::value+#if !defined(ASIO_NO_DEPRECATED)+ || conditional<+ execution::is_executor<T>::value,+ false_type,+ execution::is_sender<T>+ >::type::value+ || conditional<+ execution::is_executor<T>::value,+ false_type,+ execution::is_scheduler<T>+ >::type::value+#endif // !defined(ASIO_NO_DEPRECATED)+ > { }; template <typename T> struct is_applicable_property<T, execution::blocking_t::possibly_t>- : integral_constant<bool, execution::is_executor<T>::value>+ : integral_constant<bool,+ execution::is_executor<T>::value+#if !defined(ASIO_NO_DEPRECATED)+ || conditional<+ execution::is_executor<T>::value,+ false_type,+ execution::is_sender<T>+ >::type::value+ || conditional<+ execution::is_executor<T>::value,+ false_type,+ execution::is_scheduler<T>+ >::type::value+#endif // !defined(ASIO_NO_DEPRECATED)+ > { }; template <typename T> struct is_applicable_property<T, execution::blocking_t::always_t>- : integral_constant<bool, execution::is_executor<T>::value>+ : integral_constant<bool,+ execution::is_executor<T>::value+#if !defined(ASIO_NO_DEPRECATED)+ || conditional<+ execution::is_executor<T>::value,+ false_type,+ execution::is_sender<T>+ >::type::value+ || conditional<+ execution::is_executor<T>::value,+ false_type,+ execution::is_scheduler<T>+ >::type::value+#endif // !defined(ASIO_NO_DEPRECATED)+ > { }; template <typename T> struct is_applicable_property<T, execution::blocking_t::never_t>- : integral_constant<bool, execution::is_executor<T>::value>+ : integral_constant<bool,+ execution::is_executor<T>::value+#if !defined(ASIO_NO_DEPRECATED)+ || conditional<+ execution::is_executor<T>::value,+ false_type,+ execution::is_sender<T>+ >::type::value+ || conditional<+ execution::is_executor<T>::value,+ false_type,+ execution::is_scheduler<T>+ >::type::value+#endif // !defined(ASIO_NO_DEPRECATED)+ > { }; @@ -930,42 +1128,42 @@ template <typename T> struct query_free_default<T, execution::blocking_t,- enable_if_t<+ typename enable_if< can_query<T, execution::blocking_t::possibly_t>::value- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept =- is_nothrow_query<T, execution::blocking_t::possibly_t>::value;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+ (is_nothrow_query<T, execution::blocking_t::possibly_t>::value)); typedef execution::blocking_t result_type; }; template <typename T> struct query_free_default<T, execution::blocking_t,- enable_if_t<+ typename enable_if< !can_query<T, execution::blocking_t::possibly_t>::value && can_query<T, execution::blocking_t::always_t>::value- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept =- is_nothrow_query<T, execution::blocking_t::always_t>::value;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+ (is_nothrow_query<T, execution::blocking_t::always_t>::value)); typedef execution::blocking_t result_type; }; template <typename T> struct query_free_default<T, execution::blocking_t,- enable_if_t<+ typename enable_if< !can_query<T, execution::blocking_t::possibly_t>::value && !can_query<T, execution::blocking_t::always_t>::value && can_query<T, execution::blocking_t::never_t>::value- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept =- is_nothrow_query<T, execution::blocking_t::never_t>::value;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+ (is_nothrow_query<T, execution::blocking_t::never_t>::value)); typedef execution::blocking_t result_type; };@@ -977,18 +1175,18 @@ template <typename T> struct static_query<T, execution::blocking_t,- enable_if_t<+ typename enable_if< execution::detail::blocking_t<0>:: query_static_constexpr_member<T>::is_valid- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef typename execution::detail::blocking_t<0>:: query_static_constexpr_member<T>::result_type result_type; - static constexpr result_type value()+ static ASIO_CONSTEXPR result_type value() { return execution::blocking_t::query_static_constexpr_member<T>::value(); }@@ -996,21 +1194,21 @@ template <typename T> struct static_query<T, execution::blocking_t,- enable_if_t<+ typename enable_if< !execution::detail::blocking_t<0>:: query_static_constexpr_member<T>::is_valid && !execution::detail::blocking_t<0>:: query_member<T>::is_valid && traits::static_query<T, execution::blocking_t::possibly_t>::is_valid- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef typename traits::static_query<T, execution::blocking_t::possibly_t>::result_type result_type; - static constexpr result_type value()+ static ASIO_CONSTEXPR result_type value() { return traits::static_query<T, execution::blocking_t::possibly_t>::value(); }@@ -1018,22 +1216,22 @@ template <typename T> struct static_query<T, execution::blocking_t,- enable_if_t<+ typename enable_if< !execution::detail::blocking_t<0>:: query_static_constexpr_member<T>::is_valid && !execution::detail::blocking_t<0>:: query_member<T>::is_valid && !traits::static_query<T, execution::blocking_t::possibly_t>::is_valid && traits::static_query<T, execution::blocking_t::always_t>::is_valid- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef typename traits::static_query<T, execution::blocking_t::always_t>::result_type result_type; - static constexpr result_type value()+ static ASIO_CONSTEXPR result_type value() { return traits::static_query<T, execution::blocking_t::always_t>::value(); }@@ -1041,7 +1239,7 @@ template <typename T> struct static_query<T, execution::blocking_t,- enable_if_t<+ typename enable_if< !execution::detail::blocking_t<0>:: query_static_constexpr_member<T>::is_valid && !execution::detail::blocking_t<0>::@@ -1049,15 +1247,15 @@ && !traits::static_query<T, execution::blocking_t::possibly_t>::is_valid && !traits::static_query<T, execution::blocking_t::always_t>::is_valid && traits::static_query<T, execution::blocking_t::never_t>::is_valid- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef typename traits::static_query<T, execution::blocking_t::never_t>::result_type result_type; - static constexpr result_type value()+ static ASIO_CONSTEXPR result_type value() { return traits::static_query<T, execution::blocking_t::never_t>::value(); }@@ -1065,18 +1263,18 @@ template <typename T> struct static_query<T, execution::blocking_t::possibly_t,- enable_if_t<+ typename enable_if< execution::detail::blocking::possibly_t<0>:: query_static_constexpr_member<T>::is_valid- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef typename execution::detail::blocking::possibly_t<0>:: query_static_constexpr_member<T>::result_type result_type; - static constexpr result_type value()+ static ASIO_CONSTEXPR result_type value() { return execution::detail::blocking::possibly_t<0>:: query_static_constexpr_member<T>::value();@@ -1085,7 +1283,7 @@ template <typename T> struct static_query<T, execution::blocking_t::possibly_t,- enable_if_t<+ typename enable_if< !execution::detail::blocking::possibly_t<0>:: query_static_constexpr_member<T>::is_valid && !execution::detail::blocking::possibly_t<0>::@@ -1093,14 +1291,14 @@ && !traits::query_free<T, execution::blocking_t::possibly_t>::is_valid && !can_query<T, execution::blocking_t::always_t>::value && !can_query<T, execution::blocking_t::never_t>::value- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef execution::blocking_t::possibly_t result_type; - static constexpr result_type value()+ static ASIO_CONSTEXPR result_type value() { return result_type(); }@@ -1108,18 +1306,18 @@ template <typename T> struct static_query<T, execution::blocking_t::always_t,- enable_if_t<+ typename enable_if< execution::detail::blocking::always_t<0>:: query_static_constexpr_member<T>::is_valid- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef typename execution::detail::blocking::always_t<0>:: query_static_constexpr_member<T>::result_type result_type; - static constexpr result_type value()+ static ASIO_CONSTEXPR result_type value() { return execution::detail::blocking::always_t<0>:: query_static_constexpr_member<T>::value();@@ -1128,18 +1326,18 @@ template <typename T> struct static_query<T, execution::blocking_t::never_t,- enable_if_t<+ typename enable_if< execution::detail::blocking::never_t<0>:: query_static_constexpr_member<T>::is_valid- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef typename execution::detail::blocking::never_t<0>:: query_static_constexpr_member<T>::result_type result_type; - static constexpr result_type value()+ static ASIO_CONSTEXPR result_type value() { return execution::detail::blocking::never_t<0>:: query_static_constexpr_member<T>::value();@@ -1149,21 +1347,61 @@ #endif // !defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // || !defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) +#if !defined(ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT)++template <typename T>+struct static_require<T, execution::blocking_t::possibly_t,+ typename enable_if<+ static_query<T, execution::blocking_t::possibly_t>::is_valid+ >::type>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid =+ (is_same<typename static_query<T,+ execution::blocking_t::possibly_t>::result_type,+ execution::blocking_t::possibly_t>::value));+};++template <typename T>+struct static_require<T, execution::blocking_t::always_t,+ typename enable_if<+ static_query<T, execution::blocking_t::always_t>::is_valid+ >::type>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid =+ (is_same<typename static_query<T,+ execution::blocking_t::always_t>::result_type,+ execution::blocking_t::always_t>::value));+};++template <typename T>+struct static_require<T, execution::blocking_t::never_t,+ typename enable_if<+ static_query<T, execution::blocking_t::never_t>::is_valid+ >::type>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid =+ (is_same<typename static_query<T,+ execution::blocking_t::never_t>::result_type,+ execution::blocking_t::never_t>::value));+};++#endif // !defined(ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT)+ #if !defined(ASIO_HAS_DEDUCED_REQUIRE_FREE_TRAIT) template <typename T> struct require_free_default<T, execution::blocking_t::always_t,- enable_if_t<- is_same<T, decay_t<T>>::value+ typename enable_if<+ is_same<T, typename decay<T>::type>::value && execution::is_executor<T>::value && traits::static_require< const T&, execution::detail::blocking_adaptation::allowed_t<0> >::is_valid- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = false;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); typedef execution::detail::blocking::adapter<T> result_type; }; @@ -1173,10 +1411,10 @@ template <typename Executor> struct equality_comparable<- execution::detail::blocking::adapter<Executor>>+ execution::detail::blocking::adapter<Executor> > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); }; #endif // !defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)@@ -1187,8 +1425,8 @@ struct execute_member< execution::detail::blocking::adapter<Executor>, Function> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = false;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); typedef void result_type; }; @@ -1199,13 +1437,13 @@ template <typename Executor, int I> struct query_static_constexpr_member< execution::detail::blocking::adapter<Executor>,- execution::detail::blocking_t<I>>+ execution::detail::blocking_t<I> > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef execution::blocking_t::always_t result_type; - static constexpr result_type value() noexcept+ static ASIO_CONSTEXPR result_type value() ASIO_NOEXCEPT { return result_type(); }@@ -1214,13 +1452,13 @@ template <typename Executor, int I> struct query_static_constexpr_member< execution::detail::blocking::adapter<Executor>,- execution::detail::blocking::always_t<I>>+ execution::detail::blocking::always_t<I> > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef execution::blocking_t::always_t result_type; - static constexpr result_type value() noexcept+ static ASIO_CONSTEXPR result_type value() ASIO_NOEXCEPT { return result_type(); }@@ -1229,13 +1467,13 @@ template <typename Executor, int I> struct query_static_constexpr_member< execution::detail::blocking::adapter<Executor>,- execution::detail::blocking::possibly_t<I>>+ execution::detail::blocking::possibly_t<I> > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef execution::blocking_t::always_t result_type; - static constexpr result_type value() noexcept+ static ASIO_CONSTEXPR result_type value() ASIO_NOEXCEPT { return result_type(); }@@ -1244,13 +1482,13 @@ template <typename Executor, int I> struct query_static_constexpr_member< execution::detail::blocking::adapter<Executor>,- execution::detail::blocking::never_t<I>>+ execution::detail::blocking::never_t<I> > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef execution::blocking_t::always_t result_type; - static constexpr result_type value() noexcept+ static ASIO_CONSTEXPR result_type value() ASIO_NOEXCEPT { return result_type(); }@@ -1263,14 +1501,14 @@ template <typename Executor, typename Property> struct query_member< execution::detail::blocking::adapter<Executor>, Property,- enable_if_t<+ typename enable_if< can_query<const Executor&, Property>::value- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept =- is_nothrow_query<Executor, Property>::value;- typedef query_result_t<Executor, Property> result_type;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+ (is_nothrow_query<Executor, Property>::value));+ typedef typename query_result<Executor, Property>::type result_type; }; #endif // !defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)@@ -1281,52 +1519,53 @@ struct require_member< execution::detail::blocking::adapter<Executor>, execution::detail::blocking::possibly_t<I>,- enable_if_t<+ typename enable_if< can_require< const Executor&, execution::detail::blocking::possibly_t<I> >::value- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept =- is_nothrow_require<const Executor&,- execution::detail::blocking::possibly_t<I>>::value;- typedef require_result_t<const Executor&,- execution::detail::blocking::possibly_t<I>> result_type;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+ (is_nothrow_require<const Executor&,+ execution::detail::blocking::possibly_t<I> >::value));+ typedef typename require_result<const Executor&,+ execution::detail::blocking::possibly_t<I> >::type result_type; }; template <typename Executor, int I> struct require_member< execution::detail::blocking::adapter<Executor>, execution::detail::blocking::never_t<I>,- enable_if_t<+ typename enable_if< can_require< const Executor&, execution::detail::blocking::never_t<I> >::value- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept =- is_nothrow_require<const Executor&,- execution::detail::blocking::never_t<I>>::value;- typedef require_result_t<const Executor&,- execution::detail::blocking::never_t<I>> result_type;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+ (is_nothrow_require<const Executor&,+ execution::detail::blocking::never_t<I> >::value));+ typedef typename require_result<const Executor&,+ execution::detail::blocking::never_t<I> >::type result_type; }; template <typename Executor, typename Property> struct require_member< execution::detail::blocking::adapter<Executor>, Property,- enable_if_t<+ typename enable_if< can_require<const Executor&, Property>::value- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept =- is_nothrow_require<Executor, Property>::value;- typedef execution::detail::blocking::adapter<- decay_t<require_result_t<Executor, Property>>> result_type;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+ (is_nothrow_require<Executor, Property>::value));+ typedef execution::detail::blocking::adapter<typename decay<+ typename require_result<Executor, Property>::type+ >::type> result_type; }; #endif // !defined(ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)@@ -1336,15 +1575,16 @@ template <typename Executor, typename Property> struct prefer_member< execution::detail::blocking::adapter<Executor>, Property,- enable_if_t<+ typename enable_if< can_prefer<const Executor&, Property>::value- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept =- is_nothrow_prefer<Executor, Property>::value;- typedef execution::detail::blocking::adapter<- decay_t<prefer_result_t<Executor, Property>>> result_type;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+ (is_nothrow_prefer<Executor, Property>::value));+ typedef execution::detail::blocking::adapter<typename decay<+ typename prefer_result<Executor, Property>::type+ >::type> result_type; }; #endif // !defined(ASIO_HAS_DEDUCED_PREFER_MEMBER_TRAIT)
link/modules/asio-standalone/asio/include/asio/execution/blocking_adaptation.hpp view
@@ -2,7 +2,7 @@ // execution/blocking_adaptation.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -19,7 +19,10 @@ #include "asio/detail/event.hpp" #include "asio/detail/mutex.hpp" #include "asio/detail/type_traits.hpp"+#include "asio/execution/execute.hpp" #include "asio/execution/executor.hpp"+#include "asio/execution/scheduler.hpp"+#include "asio/execution/sender.hpp" #include "asio/is_applicable_property.hpp" #include "asio/prefer.hpp" #include "asio/query.hpp"@@ -44,9 +47,11 @@ /// allowed in order to apply the blocking_adaptation_t::allowed_t property. struct blocking_adaptation_t {- /// The blocking_adaptation_t property applies to executors.+ /// The blocking_adaptation_t property applies to executors, senders, and+ /// schedulers. template <typename T>- static constexpr bool is_applicable_property_v = is_executor_v<T>;+ static constexpr bool is_applicable_property_v =+ is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>; /// The top-level blocking_adaptation_t property cannot be required. static constexpr bool is_requirable = false;@@ -60,9 +65,11 @@ /// A sub-property that indicates that automatic adaptation is not allowed. struct disallowed_t {- /// The blocking_adaptation_t::disallowed_t property applies to executors.+ /// The blocking_adaptation_t::disallowed_t property applies to executors,+ /// senders, and schedulers. template <typename T>- static constexpr bool is_applicable_property_v = is_executor_v<T>;+ static constexpr bool is_applicable_property_v =+ is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>; /// The blocking_adaptation_t::disallowed_t property can be required. static constexpr bool is_requirable = true;@@ -86,9 +93,11 @@ /// A sub-property that indicates that automatic adaptation is allowed. struct allowed_t {- /// The blocking_adaptation_t::allowed_t property applies to executors.+ /// The blocking_adaptation_t::allowed_t property applies to executors,+ /// senders, and schedulers. template <typename T>- static constexpr bool is_applicable_property_v = is_executor_v<T>;+ static constexpr bool is_applicable_property_v =+ is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>; /// The blocking_adaptation_t::allowed_t property can be required. static constexpr bool is_requirable = true;@@ -155,28 +164,48 @@ struct blocking_adaptation_t { #if defined(ASIO_HAS_VARIABLE_TEMPLATES)+# if defined(ASIO_NO_DEPRECATED) template <typename T>- static constexpr bool is_applicable_property_v = is_executor<T>::value;+ ASIO_STATIC_CONSTEXPR(bool,+ is_applicable_property_v = (+ is_executor<T>::value));+# else // defined(ASIO_NO_DEPRECATED)+ template <typename T>+ ASIO_STATIC_CONSTEXPR(bool,+ is_applicable_property_v = (+ is_executor<T>::value+ || conditional<+ is_executor<T>::value,+ false_type,+ is_sender<T>+ >::type::value+ || conditional<+ is_executor<T>::value,+ false_type,+ is_scheduler<T>+ >::type::value+ ));+# endif // defined(ASIO_NO_DEPRECATED) #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) - static constexpr bool is_requirable = false;- static constexpr bool is_preferable = false;+ ASIO_STATIC_CONSTEXPR(bool, is_requirable = false);+ ASIO_STATIC_CONSTEXPR(bool, is_preferable = false); typedef blocking_adaptation_t polymorphic_query_result_type; typedef detail::blocking_adaptation::disallowed_t<I> disallowed_t; typedef detail::blocking_adaptation::allowed_t<I> allowed_t; - constexpr blocking_adaptation_t()+ ASIO_CONSTEXPR blocking_adaptation_t() : value_(-1) { } - constexpr blocking_adaptation_t(disallowed_t)+ ASIO_CONSTEXPR blocking_adaptation_t(disallowed_t) : value_(0) { } - constexpr blocking_adaptation_t(allowed_t)+ ASIO_CONSTEXPR blocking_adaptation_t(allowed_t) : value_(1) { }@@ -188,14 +217,16 @@ struct type { template <typename P>- auto query(P&& p) const+ auto query(ASIO_MOVE_ARG(P) p) const noexcept( noexcept(- declval<conditional_t<true, T, P>>().query(static_cast<P&&>(p))+ declval<typename conditional<true, T, P>::type>().query(+ ASIO_MOVE_CAST(P)(p)) ) ) -> decltype(- declval<conditional_t<true, T, P>>().query(static_cast<P&&>(p))+ declval<typename conditional<true, T, P>::type>().query(+ ASIO_MOVE_CAST(P)(p)) ); }; #else // defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)@@ -210,17 +241,17 @@ struct type { template <typename P>- static constexpr auto query(P&& p)+ static constexpr auto query(ASIO_MOVE_ARG(P) p) noexcept( noexcept(- conditional_t<true, T, P>::query(static_cast<P&&>(p))+ conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p)) ) ) -> decltype(- conditional_t<true, T, P>::query(static_cast<P&&>(p))+ conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p)) ) {- return T::query(static_cast<P&&>(p));+ return T::query(ASIO_MOVE_CAST(P)(p)); } }; #else // defined(ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)@@ -240,64 +271,66 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T>- static constexpr typename query_static_constexpr_member<T>::result_type+ static ASIO_CONSTEXPR+ typename query_static_constexpr_member<T>::result_type static_query()- noexcept(query_static_constexpr_member<T>::is_noexcept)+ ASIO_NOEXCEPT_IF((+ query_static_constexpr_member<T>::is_noexcept)) { return query_static_constexpr_member<T>::value(); } template <typename T>- static constexpr+ static ASIO_CONSTEXPR typename traits::static_query<T, disallowed_t>::result_type static_query(- enable_if_t<+ typename enable_if< !query_static_constexpr_member<T>::is_valid- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< !query_member<T>::is_valid- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< traits::static_query<T, disallowed_t>::is_valid- >* = 0) noexcept+ >::type* = 0) ASIO_NOEXCEPT { return traits::static_query<T, disallowed_t>::value(); } template <typename T>- static constexpr+ static ASIO_CONSTEXPR typename traits::static_query<T, allowed_t>::result_type static_query(- enable_if_t<+ typename enable_if< !query_static_constexpr_member<T>::is_valid- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< !query_member<T>::is_valid- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< !traits::static_query<T, disallowed_t>::is_valid- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< traits::static_query<T, allowed_t>::is_valid- >* = 0) noexcept+ >::type* = 0) ASIO_NOEXCEPT { return traits::static_query<T, allowed_t>::value(); } template <typename E, typename T = decltype(blocking_adaptation_t::static_query<E>())>- static constexpr const T static_query_v+ static ASIO_CONSTEXPR const T static_query_v = blocking_adaptation_t::static_query<E>(); #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) - friend constexpr bool operator==(+ friend ASIO_CONSTEXPR bool operator==( const blocking_adaptation_t& a, const blocking_adaptation_t& b) { return a.value_ == b.value_; } - friend constexpr bool operator!=(+ friend ASIO_CONSTEXPR bool operator!=( const blocking_adaptation_t& a, const blocking_adaptation_t& b) { return a.value_ != b.value_;@@ -305,24 +338,26 @@ struct convertible_from_blocking_adaptation_t {- constexpr convertible_from_blocking_adaptation_t(+ ASIO_CONSTEXPR convertible_from_blocking_adaptation_t( blocking_adaptation_t) { } }; template <typename Executor>- friend constexpr blocking_adaptation_t query(+ friend ASIO_CONSTEXPR blocking_adaptation_t query( const Executor& ex, convertible_from_blocking_adaptation_t,- enable_if_t<+ typename enable_if< can_query<const Executor&, disallowed_t>::value- >* = 0)+ >::type* = 0) #if !defined(__clang__) // Clang crashes if noexcept is used here. #if defined(ASIO_MSVC) // Visual C++ wants the type to be qualified.- noexcept(is_nothrow_query<const Executor&,- blocking_adaptation_t<>::disallowed_t>::value)+ ASIO_NOEXCEPT_IF((+ is_nothrow_query<const Executor&,+ blocking_adaptation_t<>::disallowed_t>::value)) #else // defined(ASIO_MSVC)- noexcept(is_nothrow_query<const Executor&, disallowed_t>::value)+ ASIO_NOEXCEPT_IF((+ is_nothrow_query<const Executor&, disallowed_t>::value)) #endif // defined(ASIO_MSVC) #endif // !defined(__clang__) {@@ -330,20 +365,22 @@ } template <typename Executor>- friend constexpr blocking_adaptation_t query(+ friend ASIO_CONSTEXPR blocking_adaptation_t query( const Executor& ex, convertible_from_blocking_adaptation_t,- enable_if_t<+ typename enable_if< !can_query<const Executor&, disallowed_t>::value- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< can_query<const Executor&, allowed_t>::value- >* = 0)+ >::type* = 0) #if !defined(__clang__) // Clang crashes if noexcept is used here. #if defined(ASIO_MSVC) // Visual C++ wants the type to be qualified.- noexcept(is_nothrow_query<const Executor&,- blocking_adaptation_t<>::allowed_t>::value)+ ASIO_NOEXCEPT_IF((+ is_nothrow_query<const Executor&,+ blocking_adaptation_t<>::allowed_t>::value)) #else // defined(ASIO_MSVC)- noexcept(is_nothrow_query<const Executor&, allowed_t>::value)+ ASIO_NOEXCEPT_IF((+ is_nothrow_query<const Executor&, allowed_t>::value)) #endif // defined(ASIO_MSVC) #endif // !defined(__clang__) {@@ -353,6 +390,10 @@ ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(disallowed_t, disallowed); ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(allowed_t, allowed); +#if !defined(ASIO_HAS_CONSTEXPR)+ static const blocking_adaptation_t instance;+#endif // !defined(ASIO_HAS_CONSTEXPR)+ private: int value_; };@@ -364,7 +405,12 @@ #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) +#if !defined(ASIO_HAS_CONSTEXPR) template <int I>+const blocking_adaptation_t<I> blocking_adaptation_t<I>::instance;+#endif++template <int I> const typename blocking_adaptation_t<I>::disallowed_t blocking_adaptation_t<I>::disallowed; @@ -378,15 +424,35 @@ struct disallowed_t { #if defined(ASIO_HAS_VARIABLE_TEMPLATES)+# if defined(ASIO_NO_DEPRECATED) template <typename T>- static constexpr bool is_applicable_property_v = is_executor<T>::value;+ ASIO_STATIC_CONSTEXPR(bool,+ is_applicable_property_v = (+ is_executor<T>::value));+# else // defined(ASIO_NO_DEPRECATED)+ template <typename T>+ ASIO_STATIC_CONSTEXPR(bool,+ is_applicable_property_v = (+ is_executor<T>::value+ || conditional<+ is_executor<T>::value,+ false_type,+ is_sender<T>+ >::type::value+ || conditional<+ is_executor<T>::value,+ false_type,+ is_scheduler<T>+ >::type::value+ ));+# endif // defined(ASIO_NO_DEPRECATED) #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) - static constexpr bool is_requirable = true;- static constexpr bool is_preferable = true;+ ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);+ ASIO_STATIC_CONSTEXPR(bool, is_preferable = true); typedef blocking_adaptation_t<I> polymorphic_query_result_type; - constexpr disallowed_t()+ ASIO_CONSTEXPR disallowed_t() { } @@ -405,62 +471,55 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T>- static constexpr+ static ASIO_CONSTEXPR typename query_static_constexpr_member<T>::result_type static_query()- noexcept(query_static_constexpr_member<T>::is_noexcept)+ ASIO_NOEXCEPT_IF((+ query_static_constexpr_member<T>::is_noexcept)) { return query_static_constexpr_member<T>::value(); } template <typename T>- static constexpr disallowed_t static_query(- enable_if_t<+ static ASIO_CONSTEXPR disallowed_t static_query(+ typename enable_if< !query_static_constexpr_member<T>::is_valid- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< !query_member<T>::is_valid- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< !traits::query_free<T, disallowed_t>::is_valid- >* = 0,- enable_if_t<- !can_query<T, allowed_t<I>>::value- >* = 0) noexcept+ >::type* = 0,+ typename enable_if<+ !can_query<T, allowed_t<I> >::value+ >::type* = 0) ASIO_NOEXCEPT { return disallowed_t(); } template <typename E, typename T = decltype(disallowed_t::static_query<E>())>- static constexpr const T static_query_v+ static ASIO_CONSTEXPR const T static_query_v = disallowed_t::static_query<E>(); #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) - static constexpr blocking_adaptation_t<I> value()+ static ASIO_CONSTEXPR blocking_adaptation_t<I> value() { return disallowed_t(); } - friend constexpr bool operator==(const disallowed_t&, const disallowed_t&)+ friend ASIO_CONSTEXPR bool operator==(+ const disallowed_t&, const disallowed_t&) { return true; } - friend constexpr bool operator!=(const disallowed_t&, const disallowed_t&)- {- return false;- }-- friend constexpr bool operator==(const disallowed_t&, const allowed_t<I>&)+ friend ASIO_CONSTEXPR bool operator!=(+ const disallowed_t&, const disallowed_t&) { return false; }-- friend constexpr bool operator!=(const disallowed_t&, const allowed_t<I>&)- {- return true;- } }; #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \@@ -470,134 +529,117 @@ #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) -template <typename>-struct is_blocking_adaptation_t : false_type-{-};--template <int I>-struct is_blocking_adaptation_t<blocking_adaptation_t<I>> : true_type-{-};--template <typename>-struct is_allowed_t : false_type-{-};--template <int I>-struct is_allowed_t<allowed_t<I>> : true_type-{-};--template <typename>-struct is_disallowed_t : false_type-{-};--template <int I>-struct is_disallowed_t<disallowed_t<I>> : true_type-{-};- template <typename Executor> class adapter { public:- adapter(int, const Executor& e) noexcept+ adapter(int, const Executor& e) ASIO_NOEXCEPT : executor_(e) { } - adapter(const adapter& other) noexcept+ adapter(const adapter& other) ASIO_NOEXCEPT : executor_(other.executor_) { } - adapter(adapter&& other) noexcept- : executor_(static_cast<Executor&&>(other.executor_))+#if defined(ASIO_HAS_MOVE)+ adapter(adapter&& other) ASIO_NOEXCEPT+ : executor_(ASIO_MOVE_CAST(Executor)(other.executor_)) { }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) template <int I>- static constexpr allowed_t<I> query(blocking_adaptation_t<I>) noexcept+ static ASIO_CONSTEXPR allowed_t<I> query(+ blocking_adaptation_t<I>) ASIO_NOEXCEPT { return allowed_t<I>(); } template <int I>- static constexpr allowed_t<I> query(allowed_t<I>) noexcept+ static ASIO_CONSTEXPR allowed_t<I> query(+ allowed_t<I>) ASIO_NOEXCEPT { return allowed_t<I>(); } template <int I>- static constexpr allowed_t<I> query(disallowed_t<I>) noexcept+ static ASIO_CONSTEXPR allowed_t<I> query(+ disallowed_t<I>) ASIO_NOEXCEPT { return allowed_t<I>(); } template <typename Property>- enable_if_t<- can_query<const Executor&, Property>::value- && !is_blocking_adaptation_t<Property>::value- && !is_allowed_t<Property>::value- && !is_disallowed_t<Property>::value,- query_result_t<const Executor&, Property>- > query(const Property& p) const- noexcept(is_nothrow_query<const Executor&, Property>::value)+ typename enable_if<+ can_query<const Executor&, Property>::value,+ typename query_result<const Executor&, Property>::type+ >::type query(const Property& p) const+ ASIO_NOEXCEPT_IF((+ is_nothrow_query<const Executor&, Property>::value)) { return asio::query(executor_, p); } template <int I>- Executor require(disallowed_t<I>) const noexcept+ Executor require(disallowed_t<I>) const ASIO_NOEXCEPT { return executor_; } template <typename Property>- enable_if_t<- can_require<const Executor&, Property>::value- && !is_blocking_adaptation_t<Property>::value- && !is_allowed_t<Property>::value- && !is_disallowed_t<Property>::value,- adapter<decay_t<require_result_t<const Executor&, Property>>>- > require(const Property& p) const- noexcept(is_nothrow_require<const Executor&, Property>::value)+ typename enable_if<+ can_require<const Executor&, Property>::value,+ adapter<typename decay<+ typename require_result<const Executor&, Property>::type+ >::type>+ >::type require(const Property& p) const+ ASIO_NOEXCEPT_IF((+ is_nothrow_require<const Executor&, Property>::value)) {- return adapter<decay_t<require_result_t<const Executor&, Property>>>(- 0, asio::require(executor_, p));+ return adapter<typename decay<+ typename require_result<const Executor&, Property>::type+ >::type>(0, asio::require(executor_, p)); } template <typename Property>- enable_if_t<- can_prefer<const Executor&, Property>::value- && !is_blocking_adaptation_t<Property>::value- && !is_allowed_t<Property>::value- && !is_disallowed_t<Property>::value,- adapter<decay_t<prefer_result_t<const Executor&, Property>>>- > prefer(const Property& p) const- noexcept(is_nothrow_prefer<const Executor&, Property>::value)+ typename enable_if<+ can_prefer<const Executor&, Property>::value,+ adapter<typename decay<+ typename prefer_result<const Executor&, Property>::type+ >::type>+ >::type prefer(const Property& p) const+ ASIO_NOEXCEPT_IF((+ is_nothrow_prefer<const Executor&, Property>::value)) {- return adapter<decay_t<prefer_result_t<const Executor&, Property>>>(- 0, asio::prefer(executor_, p));+ return adapter<typename decay<+ typename prefer_result<const Executor&, Property>::type+ >::type>(0, asio::prefer(executor_, p)); } template <typename Function>- enable_if_t<+ typename enable_if<+#if defined(ASIO_NO_DEPRECATED) traits::execute_member<const Executor&, Function>::is_valid- > execute(Function&& f) const+#else // defined(ASIO_NO_DEPRECATED)+ execution::can_execute<const Executor&, Function>::value+#endif // defined(ASIO_NO_DEPRECATED)+ >::type execute(ASIO_MOVE_ARG(Function) f) const {- executor_.execute(static_cast<Function&&>(f));+#if defined(ASIO_NO_DEPRECATED)+ executor_.execute(ASIO_MOVE_CAST(Function)(f));+#else // defined(ASIO_NO_DEPRECATED)+ execution::execute(executor_, ASIO_MOVE_CAST(Function)(f));+#endif // defined(ASIO_NO_DEPRECATED) } - friend bool operator==(const adapter& a, const adapter& b) noexcept+ friend bool operator==(const adapter& a, const adapter& b) ASIO_NOEXCEPT { return a.executor_ == b.executor_; } - friend bool operator!=(const adapter& a, const adapter& b) noexcept+ friend bool operator!=(const adapter& a, const adapter& b) ASIO_NOEXCEPT { return a.executor_ != b.executor_; }@@ -610,15 +652,35 @@ struct allowed_t { #if defined(ASIO_HAS_VARIABLE_TEMPLATES)+# if defined(ASIO_NO_DEPRECATED) template <typename T>- static constexpr bool is_applicable_property_v = is_executor<T>::value;+ ASIO_STATIC_CONSTEXPR(bool,+ is_applicable_property_v = (+ is_executor<T>::value));+# else // defined(ASIO_NO_DEPRECATED)+ template <typename T>+ ASIO_STATIC_CONSTEXPR(bool,+ is_applicable_property_v = (+ is_executor<T>::value+ || conditional<+ is_executor<T>::value,+ false_type,+ is_sender<T>+ >::type::value+ || conditional<+ is_executor<T>::value,+ false_type,+ is_scheduler<T>+ >::type::value+ ));+# endif // defined(ASIO_NO_DEPRECATED) #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) - static constexpr bool is_requirable = true;- static constexpr bool is_preferable = false;+ ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);+ ASIO_STATIC_CONSTEXPR(bool, is_preferable = false); typedef blocking_adaptation_t<I> polymorphic_query_result_type; - constexpr allowed_t()+ ASIO_CONSTEXPR allowed_t() { } @@ -637,49 +699,44 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T>- static constexpr typename query_static_constexpr_member<T>::result_type+ static ASIO_CONSTEXPR+ typename query_static_constexpr_member<T>::result_type static_query()- noexcept(query_static_constexpr_member<T>::is_noexcept)+ ASIO_NOEXCEPT_IF((+ query_static_constexpr_member<T>::is_noexcept)) { return query_static_constexpr_member<T>::value(); } template <typename E, typename T = decltype(allowed_t::static_query<E>())>- static constexpr const T static_query_v = allowed_t::static_query<E>();+ static ASIO_CONSTEXPR const T static_query_v+ = allowed_t::static_query<E>(); #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) - static constexpr blocking_adaptation_t<I> value()+ static ASIO_CONSTEXPR blocking_adaptation_t<I> value() { return allowed_t(); } - friend constexpr bool operator==(const allowed_t&, const allowed_t&)+ friend ASIO_CONSTEXPR bool operator==(+ const allowed_t&, const allowed_t&) { return true; } - friend constexpr bool operator!=(const allowed_t&, const allowed_t&)- {- return false;- }-- friend constexpr bool operator==(const allowed_t&, const disallowed_t<I>&)+ friend ASIO_CONSTEXPR bool operator!=(+ const allowed_t&, const allowed_t&) { return false; } - friend constexpr bool operator!=(const allowed_t&, const disallowed_t<I>&)- {- return true;- }- template <typename Executor> friend adapter<Executor> require( const Executor& e, const allowed_t&,- enable_if_t<+ typename enable_if< is_executor<Executor>::value- >* = 0)+ >::type* = 0) { return adapter<Executor>(0, e); }@@ -697,17 +754,21 @@ { public: template <typename F>- blocking_execute_state(F&& f)- : func_(static_cast<F&&>(f)),+ blocking_execute_state(ASIO_MOVE_ARG(F) f)+ : func_(ASIO_MOVE_CAST(F)(f)), is_complete_(false) { } template <typename Executor>- void execute_and_wait(Executor&& ex)+ void execute_and_wait(ASIO_MOVE_ARG(Executor) ex) { handler h = { this };+#if defined(ASIO_NO_DEPRECATED) ex.execute(h);+#else // defined(ASIO_NO_DEPRECATED)+ execution::execute(ASIO_MOVE_CAST(Executor)(ex), h);+#endif // defined(ASIO_NO_DEPRECATED) asio::detail::mutex::scoped_lock lock(mutex_); while (!is_complete_) event_.wait(lock);@@ -744,11 +805,11 @@ template <typename Executor, typename Function> void blocking_execute(- Executor&& ex,- Function&& func)+ ASIO_MOVE_ARG(Executor) ex,+ ASIO_MOVE_ARG(Function) func) {- typedef decay_t<Function> func_t;- blocking_execute_state<func_t> state(static_cast<Function&&>(func));+ typedef typename decay<Function>::type func_t;+ blocking_execute_state<func_t> state(ASIO_MOVE_CAST(Function)(func)); state.execute_and_wait(ex); } @@ -757,7 +818,12 @@ typedef detail::blocking_adaptation_t<> blocking_adaptation_t; -ASIO_INLINE_VARIABLE constexpr blocking_adaptation_t blocking_adaptation;+#if defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)+constexpr blocking_adaptation_t blocking_adaptation;+#else // defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)+namespace { static const blocking_adaptation_t&+ blocking_adaptation = blocking_adaptation_t::instance; }+#endif } // namespace execution @@ -765,19 +831,61 @@ template <typename T> struct is_applicable_property<T, execution::blocking_adaptation_t>- : integral_constant<bool, execution::is_executor<T>::value>+ : integral_constant<bool,+ execution::is_executor<T>::value+#if !defined(ASIO_NO_DEPRECATED)+ || conditional<+ execution::is_executor<T>::value,+ false_type,+ execution::is_sender<T>+ >::type::value+ || conditional<+ execution::is_executor<T>::value,+ false_type,+ execution::is_scheduler<T>+ >::type::value+#endif // !defined(ASIO_NO_DEPRECATED)+ > { }; template <typename T> struct is_applicable_property<T, execution::blocking_adaptation_t::disallowed_t>- : integral_constant<bool, execution::is_executor<T>::value>+ : integral_constant<bool,+ execution::is_executor<T>::value+#if !defined(ASIO_NO_DEPRECATED)+ || conditional<+ execution::is_executor<T>::value,+ false_type,+ execution::is_sender<T>+ >::type::value+ || conditional<+ execution::is_executor<T>::value,+ false_type,+ execution::is_scheduler<T>+ >::type::value+#endif // !defined(ASIO_NO_DEPRECATED)+ > { }; template <typename T> struct is_applicable_property<T, execution::blocking_adaptation_t::allowed_t>- : integral_constant<bool, execution::is_executor<T>::value>+ : integral_constant<bool,+ execution::is_executor<T>::value+#if !defined(ASIO_NO_DEPRECATED)+ || conditional<+ execution::is_executor<T>::value,+ false_type,+ execution::is_sender<T>+ >::type::value+ || conditional<+ execution::is_executor<T>::value,+ false_type,+ execution::is_scheduler<T>+ >::type::value+#endif // !defined(ASIO_NO_DEPRECATED)+ > { }; @@ -789,27 +897,27 @@ template <typename T> struct query_free_default<T, execution::blocking_adaptation_t,- enable_if_t<+ typename enable_if< can_query<T, execution::blocking_adaptation_t::disallowed_t>::value- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept =- is_nothrow_query<T, execution::blocking_adaptation_t::disallowed_t>::value;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = (is_nothrow_query<T,+ execution::blocking_adaptation_t::disallowed_t>::value)); typedef execution::blocking_adaptation_t result_type; }; template <typename T> struct query_free_default<T, execution::blocking_adaptation_t,- enable_if_t<+ typename enable_if< !can_query<T, execution::blocking_adaptation_t::disallowed_t>::value && can_query<T, execution::blocking_adaptation_t::allowed_t>::value- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept =- is_nothrow_query<T, execution::blocking_adaptation_t::allowed_t>::value;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+ (is_nothrow_query<T, execution::blocking_adaptation_t::allowed_t>::value)); typedef execution::blocking_adaptation_t result_type; };@@ -821,18 +929,18 @@ template <typename T> struct static_query<T, execution::blocking_adaptation_t,- enable_if_t<+ typename enable_if< execution::detail::blocking_adaptation_t<0>:: query_static_constexpr_member<T>::is_valid- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef typename execution::detail::blocking_adaptation_t<0>:: query_static_constexpr_member<T>::result_type result_type; - static constexpr result_type value()+ static ASIO_CONSTEXPR result_type value() { return execution::detail::blocking_adaptation_t<0>:: query_static_constexpr_member<T>::value();@@ -841,22 +949,22 @@ template <typename T> struct static_query<T, execution::blocking_adaptation_t,- enable_if_t<+ typename enable_if< !execution::detail::blocking_adaptation_t<0>:: query_static_constexpr_member<T>::is_valid && !execution::detail::blocking_adaptation_t<0>:: query_member<T>::is_valid && traits::static_query<T, execution::blocking_adaptation_t::disallowed_t>::is_valid- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef typename traits::static_query<T, execution::blocking_adaptation_t::disallowed_t>::result_type result_type; - static constexpr result_type value()+ static ASIO_CONSTEXPR result_type value() { return traits::static_query<T, execution::blocking_adaptation_t::disallowed_t>::value();@@ -865,7 +973,7 @@ template <typename T> struct static_query<T, execution::blocking_adaptation_t,- enable_if_t<+ typename enable_if< !execution::detail::blocking_adaptation_t<0>:: query_static_constexpr_member<T>::is_valid && !execution::detail::blocking_adaptation_t<0>::@@ -874,15 +982,15 @@ execution::blocking_adaptation_t::disallowed_t>::is_valid && traits::static_query<T, execution::blocking_adaptation_t::allowed_t>::is_valid- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef typename traits::static_query<T, execution::blocking_adaptation_t::allowed_t>::result_type result_type; - static constexpr result_type value()+ static ASIO_CONSTEXPR result_type value() { return traits::static_query<T, execution::blocking_adaptation_t::allowed_t>::value();@@ -891,18 +999,18 @@ template <typename T> struct static_query<T, execution::blocking_adaptation_t::disallowed_t,- enable_if_t<+ typename enable_if< execution::detail::blocking_adaptation::disallowed_t<0>:: query_static_constexpr_member<T>::is_valid- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef typename execution::detail::blocking_adaptation::disallowed_t<0>:: query_static_constexpr_member<T>::result_type result_type; - static constexpr result_type value()+ static ASIO_CONSTEXPR result_type value() { return execution::detail::blocking_adaptation::disallowed_t<0>:: query_static_constexpr_member<T>::value();@@ -911,7 +1019,7 @@ template <typename T> struct static_query<T, execution::blocking_adaptation_t::disallowed_t,- enable_if_t<+ typename enable_if< !execution::detail::blocking_adaptation::disallowed_t<0>:: query_static_constexpr_member<T>::is_valid && !execution::detail::blocking_adaptation::disallowed_t<0>::@@ -919,14 +1027,14 @@ && !traits::query_free<T, execution::blocking_adaptation_t::disallowed_t>::is_valid && !can_query<T, execution::blocking_adaptation_t::allowed_t>::value- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef execution::blocking_adaptation_t::disallowed_t result_type; - static constexpr result_type value()+ static ASIO_CONSTEXPR result_type value() { return result_type(); }@@ -934,18 +1042,18 @@ template <typename T> struct static_query<T, execution::blocking_adaptation_t::allowed_t,- enable_if_t<+ typename enable_if< execution::detail::blocking_adaptation::allowed_t<0>:: query_static_constexpr_member<T>::is_valid- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef typename execution::detail::blocking_adaptation::allowed_t<0>:: query_static_constexpr_member<T>::result_type result_type; - static constexpr result_type value()+ static ASIO_CONSTEXPR result_type value() { return execution::detail::blocking_adaptation::allowed_t<0>:: query_static_constexpr_member<T>::value();@@ -955,17 +1063,45 @@ #endif // !defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // || !defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) +#if !defined(ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT)++template <typename T>+struct static_require<T, execution::blocking_adaptation_t::disallowed_t,+ typename enable_if<+ static_query<T, execution::blocking_adaptation_t::disallowed_t>::is_valid+ >::type>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid =+ (is_same<typename static_query<T,+ execution::blocking_adaptation_t::disallowed_t>::result_type,+ execution::blocking_adaptation_t::disallowed_t>::value));+};++template <typename T>+struct static_require<T, execution::blocking_adaptation_t::allowed_t,+ typename enable_if<+ static_query<T, execution::blocking_adaptation_t::allowed_t>::is_valid+ >::type>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid =+ (is_same<typename static_query<T,+ execution::blocking_adaptation_t::allowed_t>::result_type,+ execution::blocking_adaptation_t::allowed_t>::value));+};++#endif // !defined(ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT)+ #if !defined(ASIO_HAS_DEDUCED_REQUIRE_FREE_TRAIT) template <typename T> struct require_free_default<T, execution::blocking_adaptation_t::allowed_t,- enable_if_t<- is_same<T, decay_t<T>>::value+ typename enable_if<+ is_same<T, typename decay<T>::type>::value && execution::is_executor<T>::value- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = false;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); typedef execution::detail::blocking_adaptation::adapter<T> result_type; }; @@ -975,10 +1111,10 @@ template <typename Executor> struct equality_comparable<- execution::detail::blocking_adaptation::adapter<Executor>>+ execution::detail::blocking_adaptation::adapter<Executor> > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); }; #endif // !defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)@@ -989,8 +1125,8 @@ struct execute_member< execution::detail::blocking_adaptation::adapter<Executor>, Function> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = false;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); typedef void result_type; }; @@ -1001,13 +1137,13 @@ template <typename Executor, int I> struct query_static_constexpr_member< execution::detail::blocking_adaptation::adapter<Executor>,- execution::detail::blocking_adaptation_t<I>>+ execution::detail::blocking_adaptation_t<I> > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef execution::blocking_adaptation_t::allowed_t result_type; - static constexpr result_type value() noexcept+ static ASIO_CONSTEXPR result_type value() ASIO_NOEXCEPT { return result_type(); }@@ -1016,13 +1152,13 @@ template <typename Executor, int I> struct query_static_constexpr_member< execution::detail::blocking_adaptation::adapter<Executor>,- execution::detail::blocking_adaptation::allowed_t<I>>+ execution::detail::blocking_adaptation::allowed_t<I> > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef execution::blocking_adaptation_t::allowed_t result_type; - static constexpr result_type value() noexcept+ static ASIO_CONSTEXPR result_type value() ASIO_NOEXCEPT { return result_type(); }@@ -1031,13 +1167,13 @@ template <typename Executor, int I> struct query_static_constexpr_member< execution::detail::blocking_adaptation::adapter<Executor>,- execution::detail::blocking_adaptation::disallowed_t<I>>+ execution::detail::blocking_adaptation::disallowed_t<I> > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef execution::blocking_adaptation_t::allowed_t result_type; - static constexpr result_type value() noexcept+ static ASIO_CONSTEXPR result_type value() ASIO_NOEXCEPT { return result_type(); }@@ -1050,14 +1186,14 @@ template <typename Executor, typename Property> struct query_member< execution::detail::blocking_adaptation::adapter<Executor>, Property,- enable_if_t<+ typename enable_if< can_query<const Executor&, Property>::value- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept =- is_nothrow_query<Executor, Property>::value;- typedef query_result_t<Executor, Property> result_type;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+ (is_nothrow_query<Executor, Property>::value));+ typedef typename query_result<Executor, Property>::type result_type; }; #endif // !defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)@@ -1067,25 +1203,26 @@ template <typename Executor, int I> struct require_member< execution::detail::blocking_adaptation::adapter<Executor>,- execution::detail::blocking_adaptation::disallowed_t<I>>+ execution::detail::blocking_adaptation::disallowed_t<I> > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef Executor result_type; }; template <typename Executor, typename Property> struct require_member< execution::detail::blocking_adaptation::adapter<Executor>, Property,- enable_if_t<+ typename enable_if< can_require<const Executor&, Property>::value- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept =- is_nothrow_require<Executor, Property>::value;- typedef execution::detail::blocking_adaptation::adapter<- decay_t<require_result_t<Executor, Property>>> result_type;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+ (is_nothrow_require<Executor, Property>::value));+ typedef execution::detail::blocking_adaptation::adapter<typename decay<+ typename require_result<Executor, Property>::type+ >::type> result_type; }; #endif // !defined(ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)@@ -1095,15 +1232,16 @@ template <typename Executor, typename Property> struct prefer_member< execution::detail::blocking_adaptation::adapter<Executor>, Property,- enable_if_t<+ typename enable_if< can_prefer<const Executor&, Property>::value- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept =- is_nothrow_prefer<Executor, Property>::value;- typedef execution::detail::blocking_adaptation::adapter<- decay_t<prefer_result_t<Executor, Property>>> result_type;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+ (is_nothrow_prefer<Executor, Property>::value));+ typedef execution::detail::blocking_adaptation::adapter<typename decay<+ typename prefer_result<Executor, Property>::type+ >::type> result_type; }; #endif // !defined(ASIO_HAS_DEDUCED_PREFER_MEMBER_TRAIT)
+ link/modules/asio-standalone/asio/include/asio/execution/bulk_execute.hpp view
@@ -0,0 +1,402 @@+//+// execution/bulk_execute.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_EXECUTION_BULK_EXECUTE_HPP+#define ASIO_EXECUTION_BULK_EXECUTE_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"++#if !defined(ASIO_NO_DEPRECATED)++#include "asio/detail/type_traits.hpp"+#include "asio/execution/bulk_guarantee.hpp"+#include "asio/execution/detail/bulk_sender.hpp"+#include "asio/execution/executor.hpp"+#include "asio/execution/sender.hpp"+#include "asio/traits/bulk_execute_member.hpp"+#include "asio/traits/bulk_execute_free.hpp"++#include "asio/detail/push_options.hpp"++#if defined(GENERATING_DOCUMENTATION)++namespace asio {+namespace execution {++/// A customisation point that creates a bulk sender.+/**+ * The name <tt>execution::bulk_execute</tt> denotes a customisation point+ * object. If <tt>is_convertible_v<N, size_t></tt> is true, then the expression+ * <tt>execution::bulk_execute(S, F, N)</tt> for some subexpressions+ * <tt>S</tt>, <tt>F</tt>, and <tt>N</tt> is expression-equivalent to:+ *+ * @li <tt>S.bulk_execute(F, N)</tt>, if that expression is valid. If the+ * function selected does not execute <tt>N</tt> invocations of the function+ * object <tt>F</tt> on the executor <tt>S</tt> in bulk with forward progress+ * guarantee <tt>asio::query(S, execution::bulk_guarantee)</tt>, and+ * the result of that function does not model <tt>sender<void></tt>, the+ * program is ill-formed with no diagnostic required.+ *+ * @li Otherwise, <tt>bulk_execute(S, F, N)</tt>, if that expression is valid,+ * with overload resolution performed in a context that includes the+ * declaration <tt>void bulk_execute();</tt> and that does not include a+ * declaration of <tt>execution::bulk_execute</tt>. If the function selected+ * by overload resolution does not execute <tt>N</tt> invocations of the+ * function object <tt>F</tt> on the executor <tt>S</tt> in bulk with forward+ * progress guarantee <tt>asio::query(E,+ * execution::bulk_guarantee)</tt>, and the result of that function does not+ * model <tt>sender<void></tt>, the program is ill-formed with no diagnostic+ * required.+ *+ * @li Otherwise, if the types <tt>F</tt> and+ * <tt>executor_index_t<remove_cvref_t<S>></tt> model <tt>invocable</tt> and+ * if <tt>asio::query(S, execution::bulk_guarantee)</tt> equals+ * <tt>execution::bulk_guarantee.unsequenced</tt>, then+ *+ * - Evaluates <tt>DECAY_COPY(std::forward<decltype(F)>(F))</tt> on the+ * calling thread to create a function object <tt>cf</tt>. [Note:+ * Additional copies of <tt>cf</tt> may subsequently be created. --end+ * note.]+ *+ * - For each value of <tt>i</tt> in <tt>N</tt>, <tt>cf(i)</tt> (or copy of+ * <tt>cf</tt>)) will be invoked at most once by an execution agent that is+ * unique for each value of <tt>i</tt>.+ *+ * - May block pending completion of one or more invocations of <tt>cf</tt>.+ *+ * - Synchronizes with (C++Std [intro.multithread]) the invocations of+ * <tt>cf</tt>.+ *+ * @li Otherwise, <tt>execution::bulk_execute(S, F, N)</tt> is ill-formed.+ */+inline constexpr unspecified bulk_execute = unspecified;++/// A type trait that determines whether a @c bulk_execute expression is+/// well-formed.+/**+ * Class template @c can_bulk_execute is a trait that is derived from @c+ * true_type if the expression <tt>execution::bulk_execute(std::declval<S>(),+ * std::declval<F>(), std::declval<N>)</tt> is well formed; otherwise @c+ * false_type.+ */+template <typename S, typename F, typename N>+struct can_bulk_execute :+ integral_constant<bool, automatically_determined>+{+};++} // namespace execution+} // namespace asio++#else // defined(GENERATING_DOCUMENTATION)++namespace asio_execution_bulk_execute_fn {++using asio::declval;+using asio::enable_if;+using asio::execution::bulk_guarantee_t;+using asio::execution::detail::bulk_sender;+using asio::execution::executor_index;+using asio::execution::is_sender;+using asio::is_convertible;+using asio::is_same;+using asio::remove_cvref;+using asio::result_of;+using asio::traits::bulk_execute_free;+using asio::traits::bulk_execute_member;+using asio::traits::static_require;++void bulk_execute();++enum overload_type+{+ call_member,+ call_free,+ adapter,+ ill_formed+};++template <typename S, typename Args, typename = void, typename = void,+ typename = void, typename = void, typename = void, typename = void>+struct call_traits+{+ ASIO_STATIC_CONSTEXPR(overload_type, overload = ill_formed);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ typedef void result_type;+};++template <typename S, typename F, typename N>+struct call_traits<S, void(F, N),+ typename enable_if<+ is_convertible<N, std::size_t>::value+ >::type,+ typename enable_if<+ bulk_execute_member<S, F, N>::is_valid+ >::type,+ typename enable_if<+ is_sender<+ typename bulk_execute_member<S, F, N>::result_type+ >::value+ >::type> :+ bulk_execute_member<S, F, N>+{+ ASIO_STATIC_CONSTEXPR(overload_type, overload = call_member);+};++template <typename S, typename F, typename N>+struct call_traits<S, void(F, N),+ typename enable_if<+ is_convertible<N, std::size_t>::value+ >::type,+ typename enable_if<+ !bulk_execute_member<S, F, N>::is_valid+ >::type,+ typename enable_if<+ bulk_execute_free<S, F, N>::is_valid+ >::type,+ typename enable_if<+ is_sender<+ typename bulk_execute_free<S, F, N>::result_type+ >::value+ >::type> :+ bulk_execute_free<S, F, N>+{+ ASIO_STATIC_CONSTEXPR(overload_type, overload = call_free);+};++template <typename S, typename F, typename N>+struct call_traits<S, void(F, N),+ typename enable_if<+ is_convertible<N, std::size_t>::value+ >::type,+ typename enable_if<+ !bulk_execute_member<S, F, N>::is_valid+ >::type,+ typename enable_if<+ !bulk_execute_free<S, F, N>::is_valid+ >::type,+ typename enable_if<+ is_sender<S>::value+ >::type,+ typename enable_if<+ is_same<+ typename result_of<+ F(typename executor_index<typename remove_cvref<S>::type>::type)+ >::type,+ typename result_of<+ F(typename executor_index<typename remove_cvref<S>::type>::type)+ >::type+ >::value+ >::type,+ typename enable_if<+ static_require<S, bulk_guarantee_t::unsequenced_t>::is_valid+ >::type>+{+ ASIO_STATIC_CONSTEXPR(overload_type, overload = adapter);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ typedef bulk_sender<S, F, N> result_type;+};++struct impl+{+#if defined(ASIO_HAS_MOVE)+ template <typename S, typename F, typename N>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<S, void(F, N)>::overload == call_member,+ typename call_traits<S, void(F, N)>::result_type+ >::type+ operator()(S&& s, F&& f, N&& n) const+ ASIO_NOEXCEPT_IF((+ call_traits<S, void(F, N)>::is_noexcept))+ {+ return ASIO_MOVE_CAST(S)(s).bulk_execute(+ ASIO_MOVE_CAST(F)(f), ASIO_MOVE_CAST(N)(n));+ }++ template <typename S, typename F, typename N>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<S, void(F, N)>::overload == call_free,+ typename call_traits<S, void(F, N)>::result_type+ >::type+ operator()(S&& s, F&& f, N&& n) const+ ASIO_NOEXCEPT_IF((+ call_traits<S, void(F, N)>::is_noexcept))+ {+ return bulk_execute(ASIO_MOVE_CAST(S)(s),+ ASIO_MOVE_CAST(F)(f), ASIO_MOVE_CAST(N)(n));+ }++ template <typename S, typename F, typename N>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<S, void(F, N)>::overload == adapter,+ typename call_traits<S, void(F, N)>::result_type+ >::type+ operator()(S&& s, F&& f, N&& n) const+ ASIO_NOEXCEPT_IF((+ call_traits<S, void(F, N)>::is_noexcept))+ {+ return typename call_traits<S, void(F, N)>::result_type(+ ASIO_MOVE_CAST(S)(s), ASIO_MOVE_CAST(F)(f),+ ASIO_MOVE_CAST(N)(n));+ }+#else // defined(ASIO_HAS_MOVE)+ template <typename S, typename F, typename N>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<S, void(const F&, const N&)>::overload == call_member,+ typename call_traits<S, void(const F&, const N&)>::result_type+ >::type+ operator()(S& s, const F& f, const N& n) const+ ASIO_NOEXCEPT_IF((+ call_traits<S, void(const F&, const N&)>::is_noexcept))+ {+ return s.bulk_execute(ASIO_MOVE_CAST(F)(f),+ ASIO_MOVE_CAST(N)(n));+ }++ template <typename S, typename F, typename N>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<S, void(const F&, const N&)>::overload == call_member,+ typename call_traits<S, void(const F&, const N&)>::result_type+ >::type+ operator()(const S& s, const F& f, const N& n) const+ ASIO_NOEXCEPT_IF((+ call_traits<S, void(const F&, const N&)>::is_noexcept))+ {+ return s.bulk_execute(ASIO_MOVE_CAST(F)(f),+ ASIO_MOVE_CAST(N)(n));+ }++ template <typename S, typename F, typename N>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<S, void(const F&, const N&)>::overload == call_free,+ typename call_traits<S, void(const F&, const N&)>::result_type+ >::type+ operator()(S& s, const F& f, const N& n) const+ ASIO_NOEXCEPT_IF((+ call_traits<S, void(const F&, const N&)>::is_noexcept))+ {+ return bulk_execute(s, ASIO_MOVE_CAST(F)(f),+ ASIO_MOVE_CAST(N)(n));+ }++ template <typename S, typename F, typename N>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<S, void(const F&, const N&)>::overload == call_free,+ typename call_traits<S, void(const F&, const N&)>::result_type+ >::type+ operator()(const S& s, const F& f, const N& n) const+ ASIO_NOEXCEPT_IF((+ call_traits<S, void(const F&, const N&)>::is_noexcept))+ {+ return bulk_execute(s, ASIO_MOVE_CAST(F)(f),+ ASIO_MOVE_CAST(N)(n));+ }++ template <typename S, typename F, typename N>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<S, void(const F&, const N&)>::overload == adapter,+ typename call_traits<S, void(const F&, const N&)>::result_type+ >::type+ operator()(S& s, const F& f, const N& n) const+ ASIO_NOEXCEPT_IF((+ call_traits<S, void(const F&, const N&)>::is_noexcept))+ {+ return typename call_traits<S, void(const F&, const N&)>::result_type(+ s, ASIO_MOVE_CAST(F)(f), ASIO_MOVE_CAST(N)(n));+ }++ template <typename S, typename F, typename N>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<S, void(const F&, const N&)>::overload == adapter,+ typename call_traits<S, void(const F&, const N&)>::result_type+ >::type+ operator()(const S& s, const F& f, const N& n) const+ ASIO_NOEXCEPT_IF((+ call_traits<S, void(const F&, const N&)>::is_noexcept))+ {+ return typename call_traits<S, void(const F&, const N&)>::result_type(+ s, ASIO_MOVE_CAST(F)(f), ASIO_MOVE_CAST(N)(n));+ }+#endif // defined(ASIO_HAS_MOVE)+};++template <typename T = impl>+struct static_instance+{+ static const T instance;+};++template <typename T>+const T static_instance<T>::instance = {};++} // namespace asio_execution_bulk_execute_fn+namespace asio {+namespace execution {+namespace {++static ASIO_CONSTEXPR+ const asio_execution_bulk_execute_fn::impl& bulk_execute =+ asio_execution_bulk_execute_fn::static_instance<>::instance;++} // namespace++template <typename S, typename F, typename N>+struct can_bulk_execute :+ integral_constant<bool,+ asio_execution_bulk_execute_fn::call_traits<+ S, void(F, N)>::overload !=+ asio_execution_bulk_execute_fn::ill_formed>+{+};++#if defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename S, typename F, typename N>+constexpr bool can_bulk_execute_v = can_bulk_execute<S, F, N>::value;++#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename S, typename F, typename N>+struct is_nothrow_bulk_execute :+ integral_constant<bool,+ asio_execution_bulk_execute_fn::call_traits<+ S, void(F, N)>::is_noexcept>+{+};++#if defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename S, typename F, typename N>+constexpr bool is_nothrow_bulk_execute_v+ = is_nothrow_bulk_execute<S, F, N>::value;++#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename S, typename F, typename N>+struct bulk_execute_result+{+ typedef typename asio_execution_bulk_execute_fn::call_traits<+ S, void(F, N)>::result_type type;+};++} // namespace execution+} // namespace asio++#endif // defined(GENERATING_DOCUMENTATION)++#include "asio/detail/pop_options.hpp"++#endif // !defined(ASIO_NO_DEPRECATED)++#endif // ASIO_EXECUTION_BULK_EXECUTE_HPP
+ link/modules/asio-standalone/asio/include/asio/execution/bulk_guarantee.hpp view
@@ -0,0 +1,1252 @@+//+// execution/bulk_guarantee.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_EXECUTION_BULK_GUARANTEE_HPP+#define ASIO_EXECUTION_BULK_GUARANTEE_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"++#if !defined(ASIO_NO_DEPRECATED)++#include "asio/detail/type_traits.hpp"+#include "asio/execution/executor.hpp"+#include "asio/execution/scheduler.hpp"+#include "asio/execution/sender.hpp"+#include "asio/is_applicable_property.hpp"+#include "asio/query.hpp"+#include "asio/traits/query_free.hpp"+#include "asio/traits/query_member.hpp"+#include "asio/traits/query_static_constexpr_member.hpp"+#include "asio/traits/static_query.hpp"+#include "asio/traits/static_require.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {++#if defined(GENERATING_DOCUMENTATION)++namespace execution {++/// A property to communicate the forward progress and ordering guarantees of+/// execution agents associated with the bulk execution.+struct bulk_guarantee_t+{+ /// The bulk_guarantee_t property applies to executors, senders, and+ /// schedulers.+ template <typename T>+ static constexpr bool is_applicable_property_v =+ is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;++ /// The top-level bulk_guarantee_t property cannot be required.+ static constexpr bool is_requirable = false;++ /// The top-level bulk_guarantee_t property cannot be preferred.+ static constexpr bool is_preferable = false;++ /// The type returned by queries against an @c any_executor.+ typedef bulk_guarantee_t polymorphic_query_result_type;++ /// A sub-property that indicates that execution agents within the same bulk+ /// execution may be parallelised and vectorised.+ struct unsequenced_t+ {+ /// The bulk_guarantee_t::unsequenced_t property applies to executors,+ /// senders, and schedulers.+ template <typename T>+ static constexpr bool is_applicable_property_v =+ is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;++ /// The bulk_guarantee_t::unsequenced_t property can be required.+ static constexpr bool is_requirable = true;++ /// The bulk_guarantee_t::unsequenced_t property can be preferred.+ static constexpr bool is_preferable = true;++ /// The type returned by queries against an @c any_executor.+ typedef bulk_guarantee_t polymorphic_query_result_type;++ /// Default constructor.+ constexpr unsequenced_t();++ /// Get the value associated with a property object.+ /**+ * @returns unsequenced_t();+ */+ static constexpr bulk_guarantee_t value();+ };++ /// A sub-property that indicates that execution agents within the same bulk+ /// execution may not be parallelised and vectorised.+ struct sequenced_t+ {+ /// The bulk_guarantee_t::sequenced_t property applies to executors,+ /// senders, and schedulers.+ template <typename T>+ static constexpr bool is_applicable_property_v =+ is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;++ /// The bulk_guarantee_t::sequenced_t property can be required.+ static constexpr bool is_requirable = true;++ /// The bulk_guarantee_t::sequenced_t property can be preferred.+ static constexpr bool is_preferable = true;++ /// The type returned by queries against an @c any_executor.+ typedef bulk_guarantee_t polymorphic_query_result_type;++ /// Default constructor.+ constexpr sequenced_t();++ /// Get the value associated with a property object.+ /**+ * @returns sequenced_t();+ */+ static constexpr bulk_guarantee_t value();+ };++ /// A sub-property that indicates that execution agents within the same bulk+ /// execution may be parallelised.+ struct parallel_t+ {+ /// The bulk_guarantee_t::parallel_t property applies to executors,+ /// senders, and schedulers.+ template <typename T>+ static constexpr bool is_applicable_property_v =+ is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;++ /// The bulk_guarantee_t::parallel_t property can be required.+ static constexpr bool is_requirable = true;++ /// The bulk_guarantee_t::parallel_t property can be preferred.+ static constexpr bool is_preferable = true;++ /// The type returned by queries against an @c any_executor.+ typedef bulk_guarantee_t polymorphic_query_result_type;++ /// Default constructor.+ constexpr parallel_t();++ /// Get the value associated with a property object.+ /**+ * @returns parallel_t();+ */+ static constexpr bulk_guarantee_t value();+ };++ /// A special value used for accessing the bulk_guarantee_t::unsequenced_t+ /// property.+ static constexpr unsequenced_t unsequenced;++ /// A special value used for accessing the bulk_guarantee_t::sequenced_t+ /// property.+ static constexpr sequenced_t sequenced;++ /// A special value used for accessing the bulk_guarantee_t::parallel_t+ /// property.+ static constexpr parallel_t parallel;++ /// Default constructor.+ constexpr bulk_guarantee_t();++ /// Construct from a sub-property value.+ constexpr bulk_guarantee_t(unsequenced_t);++ /// Construct from a sub-property value.+ constexpr bulk_guarantee_t(sequenced_t);++ /// Construct from a sub-property value.+ constexpr bulk_guarantee_t(parallel_t);++ /// Compare property values for equality.+ friend constexpr bool operator==(+ const bulk_guarantee_t& a, const bulk_guarantee_t& b) noexcept;++ /// Compare property values for inequality.+ friend constexpr bool operator!=(+ const bulk_guarantee_t& a, const bulk_guarantee_t& b) noexcept;+};++/// A special value used for accessing the bulk_guarantee_t property.+constexpr bulk_guarantee_t bulk_guarantee;++} // namespace execution++#else // defined(GENERATING_DOCUMENTATION)++namespace execution {+namespace detail {+namespace bulk_guarantee {++template <int I> struct unsequenced_t;+template <int I> struct sequenced_t;+template <int I> struct parallel_t;++} // namespace bulk_guarantee++template <int I = 0>+struct bulk_guarantee_t+{+#if defined(ASIO_HAS_VARIABLE_TEMPLATES)+# if defined(ASIO_NO_DEPRECATED)+ template <typename T>+ ASIO_STATIC_CONSTEXPR(bool,+ is_applicable_property_v = (+ is_executor<T>::value));+# else // defined(ASIO_NO_DEPRECATED)+ template <typename T>+ ASIO_STATIC_CONSTEXPR(bool,+ is_applicable_property_v = (+ is_executor<T>::value+ || conditional<+ is_executor<T>::value,+ false_type,+ is_sender<T>+ >::type::value+ || conditional<+ is_executor<T>::value,+ false_type,+ is_scheduler<T>+ >::type::value+ ));+# endif // defined(ASIO_NO_DEPRECATED)+#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++ ASIO_STATIC_CONSTEXPR(bool, is_requirable = false);+ ASIO_STATIC_CONSTEXPR(bool, is_preferable = false);+ typedef bulk_guarantee_t polymorphic_query_result_type;++ typedef detail::bulk_guarantee::unsequenced_t<I> unsequenced_t;+ typedef detail::bulk_guarantee::sequenced_t<I> sequenced_t;+ typedef detail::bulk_guarantee::parallel_t<I> parallel_t;++ ASIO_CONSTEXPR bulk_guarantee_t()+ : value_(-1)+ {+ }++ ASIO_CONSTEXPR bulk_guarantee_t(unsequenced_t)+ : value_(0)+ {+ }++ ASIO_CONSTEXPR bulk_guarantee_t(sequenced_t)+ : value_(1)+ {+ }++ ASIO_CONSTEXPR bulk_guarantee_t(parallel_t)+ : value_(2)+ {+ }++ template <typename T>+ struct proxy+ {+#if defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)+ struct type+ {+ template <typename P>+ auto query(ASIO_MOVE_ARG(P) p) const+ noexcept(+ noexcept(+ declval<typename conditional<true, T, P>::type>().query(+ ASIO_MOVE_CAST(P)(p))+ )+ )+ -> decltype(+ declval<typename conditional<true, T, P>::type>().query(+ ASIO_MOVE_CAST(P)(p))+ );+ };+#else // defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)+ typedef T type;+#endif // defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)+ };++ template <typename T>+ struct static_proxy+ {+#if defined(ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)+ struct type+ {+ template <typename P>+ static constexpr auto query(ASIO_MOVE_ARG(P) p)+ noexcept(+ noexcept(+ conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p))+ )+ )+ -> decltype(+ conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p))+ )+ {+ return T::query(ASIO_MOVE_CAST(P)(p));+ }+ };+#else // defined(ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)+ typedef T type;+#endif // defined(ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)+ };++ template <typename T>+ struct query_member :+ traits::query_member<typename proxy<T>::type, bulk_guarantee_t> {};++ template <typename T>+ struct query_static_constexpr_member :+ traits::query_static_constexpr_member<+ typename static_proxy<T>::type, bulk_guarantee_t> {};++#if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \+ && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)+ template <typename T>+ static ASIO_CONSTEXPR+ typename query_static_constexpr_member<T>::result_type+ static_query()+ ASIO_NOEXCEPT_IF((+ query_static_constexpr_member<T>::is_noexcept))+ {+ return query_static_constexpr_member<T>::value();+ }++ template <typename T>+ static ASIO_CONSTEXPR+ typename traits::static_query<T, unsequenced_t>::result_type+ static_query(+ typename enable_if<+ !query_static_constexpr_member<T>::is_valid+ >::type* = 0,+ typename enable_if<+ !query_member<T>::is_valid+ >::type* = 0,+ typename enable_if<+ traits::static_query<T, unsequenced_t>::is_valid+ >::type* = 0) ASIO_NOEXCEPT+ {+ return traits::static_query<T, unsequenced_t>::value();+ }++ template <typename T>+ static ASIO_CONSTEXPR+ typename traits::static_query<T, sequenced_t>::result_type+ static_query(+ typename enable_if<+ !query_static_constexpr_member<T>::is_valid+ >::type* = 0,+ typename enable_if<+ !query_member<T>::is_valid+ >::type* = 0,+ typename enable_if<+ !traits::static_query<T, unsequenced_t>::is_valid+ >::type* = 0,+ typename enable_if<+ traits::static_query<T, sequenced_t>::is_valid+ >::type* = 0) ASIO_NOEXCEPT+ {+ return traits::static_query<T, sequenced_t>::value();+ }++ template <typename T>+ static ASIO_CONSTEXPR+ typename traits::static_query<T, parallel_t>::result_type+ static_query(+ typename enable_if<+ !query_static_constexpr_member<T>::is_valid+ >::type* = 0,+ typename enable_if<+ !query_member<T>::is_valid+ >::type* = 0,+ typename enable_if<+ !traits::static_query<T, unsequenced_t>::is_valid+ >::type* = 0,+ typename enable_if<+ !traits::static_query<T, sequenced_t>::is_valid+ >::type* = 0,+ typename enable_if<+ traits::static_query<T, parallel_t>::is_valid+ >::type* = 0) ASIO_NOEXCEPT+ {+ return traits::static_query<T, parallel_t>::value();+ }++ template <typename E,+ typename T = decltype(bulk_guarantee_t::static_query<E>())>+ static ASIO_CONSTEXPR const T static_query_v+ = bulk_guarantee_t::static_query<E>();+#endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)+ // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)++ friend ASIO_CONSTEXPR bool operator==(+ const bulk_guarantee_t& a, const bulk_guarantee_t& b)+ {+ return a.value_ == b.value_;+ }++ friend ASIO_CONSTEXPR bool operator!=(+ const bulk_guarantee_t& a, const bulk_guarantee_t& b)+ {+ return a.value_ != b.value_;+ }++ struct convertible_from_bulk_guarantee_t+ {+ ASIO_CONSTEXPR convertible_from_bulk_guarantee_t(bulk_guarantee_t) {}+ };++ template <typename Executor>+ friend ASIO_CONSTEXPR bulk_guarantee_t query(+ const Executor& ex, convertible_from_bulk_guarantee_t,+ typename enable_if<+ can_query<const Executor&, unsequenced_t>::value+ >::type* = 0)+#if !defined(__clang__) // Clang crashes if noexcept is used here.+#if defined(ASIO_MSVC) // Visual C++ wants the type to be qualified.+ ASIO_NOEXCEPT_IF((+ is_nothrow_query<const Executor&,+ bulk_guarantee_t<>::unsequenced_t>::value))+#else // defined(ASIO_MSVC)+ ASIO_NOEXCEPT_IF((+ is_nothrow_query<const Executor&, unsequenced_t>::value))+#endif // defined(ASIO_MSVC)+#endif // !defined(__clang__)+ {+ return asio::query(ex, unsequenced_t());+ }++ template <typename Executor>+ friend ASIO_CONSTEXPR bulk_guarantee_t query(+ const Executor& ex, convertible_from_bulk_guarantee_t,+ typename enable_if<+ !can_query<const Executor&, unsequenced_t>::value+ >::type* = 0,+ typename enable_if<+ can_query<const Executor&, sequenced_t>::value+ >::type* = 0)+#if !defined(__clang__) // Clang crashes if noexcept is used here.+#if defined(ASIO_MSVC) // Visual C++ wants the type to be qualified.+ ASIO_NOEXCEPT_IF((+ is_nothrow_query<const Executor&,+ bulk_guarantee_t<>::sequenced_t>::value))+#else // defined(ASIO_MSVC)+ ASIO_NOEXCEPT_IF((+ is_nothrow_query<const Executor&, sequenced_t>::value))+#endif // defined(ASIO_MSVC)+#endif // !defined(__clang__)+ {+ return asio::query(ex, sequenced_t());+ }++ template <typename Executor>+ friend ASIO_CONSTEXPR bulk_guarantee_t query(+ const Executor& ex, convertible_from_bulk_guarantee_t,+ typename enable_if<+ !can_query<const Executor&, unsequenced_t>::value+ >::type* = 0,+ typename enable_if<+ !can_query<const Executor&, sequenced_t>::value+ >::type* = 0,+ typename enable_if<+ can_query<const Executor&, parallel_t>::value+ >::type* = 0)+#if !defined(__clang__) // Clang crashes if noexcept is used here.+#if defined(ASIO_MSVC) // Visual C++ wants the type to be qualified.+ ASIO_NOEXCEPT_IF((+ is_nothrow_query<const Executor&, bulk_guarantee_t<>::parallel_t>::value))+#else // defined(ASIO_MSVC)+ ASIO_NOEXCEPT_IF((+ is_nothrow_query<const Executor&, parallel_t>::value))+#endif // defined(ASIO_MSVC)+#endif // !defined(__clang__)+ {+ return asio::query(ex, parallel_t());+ }++ ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(unsequenced_t, unsequenced);+ ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(sequenced_t, sequenced);+ ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(parallel_t, parallel);++#if !defined(ASIO_HAS_CONSTEXPR)+ static const bulk_guarantee_t instance;+#endif // !defined(ASIO_HAS_CONSTEXPR)++private:+ int value_;+};++#if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \+ && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)+template <int I> template <typename E, typename T>+const T bulk_guarantee_t<I>::static_query_v;+#endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)+ // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)++#if !defined(ASIO_HAS_CONSTEXPR)+template <int I>+const bulk_guarantee_t<I> bulk_guarantee_t<I>::instance;+#endif++template <int I>+const typename bulk_guarantee_t<I>::unsequenced_t+bulk_guarantee_t<I>::unsequenced;++template <int I>+const typename bulk_guarantee_t<I>::sequenced_t+bulk_guarantee_t<I>::sequenced;++template <int I>+const typename bulk_guarantee_t<I>::parallel_t+bulk_guarantee_t<I>::parallel;++namespace bulk_guarantee {++template <int I = 0>+struct unsequenced_t+{+#if defined(ASIO_HAS_VARIABLE_TEMPLATES)+# if defined(ASIO_NO_DEPRECATED)+ template <typename T>+ ASIO_STATIC_CONSTEXPR(bool,+ is_applicable_property_v = (+ is_executor<T>::value));+# else // defined(ASIO_NO_DEPRECATED)+ template <typename T>+ ASIO_STATIC_CONSTEXPR(bool,+ is_applicable_property_v = (+ is_executor<T>::value+ || conditional<+ is_executor<T>::value,+ false_type,+ is_sender<T>+ >::type::value+ || conditional<+ is_executor<T>::value,+ false_type,+ is_scheduler<T>+ >::type::value+ ));+# endif // defined(ASIO_NO_DEPRECATED)+#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++ ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);+ ASIO_STATIC_CONSTEXPR(bool, is_preferable = true);+ typedef bulk_guarantee_t<I> polymorphic_query_result_type;++ ASIO_CONSTEXPR unsequenced_t()+ {+ }++ template <typename T>+ struct query_member :+ traits::query_member<+ typename bulk_guarantee_t<I>::template proxy<T>::type,+ unsequenced_t> {};++ template <typename T>+ struct query_static_constexpr_member :+ traits::query_static_constexpr_member<+ typename bulk_guarantee_t<I>::template static_proxy<T>::type,+ unsequenced_t> {};++#if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \+ && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)+ template <typename T>+ static ASIO_CONSTEXPR+ typename query_static_constexpr_member<T>::result_type+ static_query()+ ASIO_NOEXCEPT_IF((+ query_static_constexpr_member<T>::is_noexcept))+ {+ return query_static_constexpr_member<T>::value();+ }++ template <typename T>+ static ASIO_CONSTEXPR unsequenced_t static_query(+ typename enable_if<+ !query_static_constexpr_member<T>::is_valid+ >::type* = 0,+ typename enable_if<+ !query_member<T>::is_valid+ >::type* = 0,+ typename enable_if<+ !traits::query_free<T, unsequenced_t>::is_valid+ >::type* = 0,+ typename enable_if<+ !can_query<T, sequenced_t<I> >::value+ >::type* = 0,+ typename enable_if<+ !can_query<T, parallel_t<I> >::value+ >::type* = 0) ASIO_NOEXCEPT+ {+ return unsequenced_t();+ }++ template <typename E, typename T = decltype(unsequenced_t::static_query<E>())>+ static ASIO_CONSTEXPR const T static_query_v+ = unsequenced_t::static_query<E>();+#endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)+ // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)++ static ASIO_CONSTEXPR bulk_guarantee_t<I> value()+ {+ return unsequenced_t();+ }++ friend ASIO_CONSTEXPR bool operator==(+ const unsequenced_t&, const unsequenced_t&)+ {+ return true;+ }++ friend ASIO_CONSTEXPR bool operator!=(+ const unsequenced_t&, const unsequenced_t&)+ {+ return false;+ }++ friend ASIO_CONSTEXPR bool operator==(+ const unsequenced_t&, const sequenced_t<I>&)+ {+ return false;+ }++ friend ASIO_CONSTEXPR bool operator!=(+ const unsequenced_t&, const sequenced_t<I>&)+ {+ return true;+ }++ friend ASIO_CONSTEXPR bool operator==(+ const unsequenced_t&, const parallel_t<I>&)+ {+ return false;+ }++ friend ASIO_CONSTEXPR bool operator!=(+ const unsequenced_t&, const parallel_t<I>&)+ {+ return true;+ }+};++#if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \+ && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)+template <int I> template <typename E, typename T>+const T unsequenced_t<I>::static_query_v;+#endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)+ // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)++template <int I = 0>+struct sequenced_t+{+#if defined(ASIO_HAS_VARIABLE_TEMPLATES)+# if defined(ASIO_NO_DEPRECATED)+ template <typename T>+ ASIO_STATIC_CONSTEXPR(bool,+ is_applicable_property_v = (+ is_executor<T>::value));+# else // defined(ASIO_NO_DEPRECATED)+ template <typename T>+ ASIO_STATIC_CONSTEXPR(bool,+ is_applicable_property_v = (+ is_executor<T>::value+ || conditional<+ is_executor<T>::value,+ false_type,+ is_sender<T>+ >::type::value+ || conditional<+ is_executor<T>::value,+ false_type,+ is_scheduler<T>+ >::type::value+ ));+# endif // defined(ASIO_NO_DEPRECATED)+#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++ ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);+ ASIO_STATIC_CONSTEXPR(bool, is_preferable = true);+ typedef bulk_guarantee_t<I> polymorphic_query_result_type;++ ASIO_CONSTEXPR sequenced_t()+ {+ }++ template <typename T>+ struct query_member :+ traits::query_member<+ typename bulk_guarantee_t<I>::template proxy<T>::type,+ sequenced_t> {};++ template <typename T>+ struct query_static_constexpr_member :+ traits::query_static_constexpr_member<+ typename bulk_guarantee_t<I>::template static_proxy<T>::type,+ sequenced_t> {};++#if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \+ && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)+ template <typename T>+ static ASIO_CONSTEXPR+ typename query_static_constexpr_member<T>::result_type+ static_query()+ ASIO_NOEXCEPT_IF((+ query_static_constexpr_member<T>::is_noexcept))+ {+ return query_static_constexpr_member<T>::value();+ }++ template <typename E, typename T = decltype(sequenced_t::static_query<E>())>+ static ASIO_CONSTEXPR const T static_query_v+ = sequenced_t::static_query<E>();+#endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)+ // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)++ static ASIO_CONSTEXPR bulk_guarantee_t<I> value()+ {+ return sequenced_t();+ }++ friend ASIO_CONSTEXPR bool operator==(+ const sequenced_t&, const sequenced_t&)+ {+ return true;+ }++ friend ASIO_CONSTEXPR bool operator!=(+ const sequenced_t&, const sequenced_t&)+ {+ return false;+ }++ friend ASIO_CONSTEXPR bool operator==(+ const sequenced_t&, const unsequenced_t<I>&)+ {+ return false;+ }++ friend ASIO_CONSTEXPR bool operator!=(+ const sequenced_t&, const unsequenced_t<I>&)+ {+ return true;+ }++ friend ASIO_CONSTEXPR bool operator==(+ const sequenced_t&, const parallel_t<I>&)+ {+ return false;+ }++ friend ASIO_CONSTEXPR bool operator!=(+ const sequenced_t&, const parallel_t<I>&)+ {+ return true;+ }+};++#if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \+ && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)+template <int I> template <typename E, typename T>+const T sequenced_t<I>::static_query_v;+#endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)+ // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)++template <int I>+struct parallel_t+{+#if defined(ASIO_HAS_VARIABLE_TEMPLATES)+# if defined(ASIO_NO_DEPRECATED)+ template <typename T>+ ASIO_STATIC_CONSTEXPR(bool,+ is_applicable_property_v = (+ is_executor<T>::value));+# else // defined(ASIO_NO_DEPRECATED)+ template <typename T>+ ASIO_STATIC_CONSTEXPR(bool,+ is_applicable_property_v = (+ is_executor<T>::value+ || conditional<+ is_executor<T>::value,+ false_type,+ is_sender<T>+ >::type::value+ || conditional<+ is_executor<T>::value,+ false_type,+ is_scheduler<T>+ >::type::value+ ));+# endif // defined(ASIO_NO_DEPRECATED)+#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++ ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);+ ASIO_STATIC_CONSTEXPR(bool, is_preferable = true);+ typedef bulk_guarantee_t<I> polymorphic_query_result_type;++ ASIO_CONSTEXPR parallel_t()+ {+ }++ template <typename T>+ struct query_member :+ traits::query_member<+ typename bulk_guarantee_t<I>::template proxy<T>::type,+ parallel_t> {};++ template <typename T>+ struct query_static_constexpr_member :+ traits::query_static_constexpr_member<+ typename bulk_guarantee_t<I>::template static_proxy<T>::type,+ parallel_t> {};++#if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \+ && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)+ template <typename T>+ static ASIO_CONSTEXPR+ typename query_static_constexpr_member<T>::result_type+ static_query()+ ASIO_NOEXCEPT_IF((+ query_static_constexpr_member<T>::is_noexcept))+ {+ return query_static_constexpr_member<T>::value();+ }++ template <typename E, typename T = decltype(parallel_t::static_query<E>())>+ static ASIO_CONSTEXPR const T static_query_v+ = parallel_t::static_query<E>();+#endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)+ // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)++ static ASIO_CONSTEXPR bulk_guarantee_t<I> value()+ {+ return parallel_t();+ }++ friend ASIO_CONSTEXPR bool operator==(+ const parallel_t&, const parallel_t&)+ {+ return true;+ }++ friend ASIO_CONSTEXPR bool operator!=(+ const parallel_t&, const parallel_t&)+ {+ return false;+ }++ friend ASIO_CONSTEXPR bool operator==(+ const parallel_t&, const unsequenced_t<I>&)+ {+ return false;+ }++ friend ASIO_CONSTEXPR bool operator!=(+ const parallel_t&, const unsequenced_t<I>&)+ {+ return true;+ }++ friend ASIO_CONSTEXPR bool operator==(+ const parallel_t&, const sequenced_t<I>&)+ {+ return false;+ }++ friend ASIO_CONSTEXPR bool operator!=(+ const parallel_t&, const sequenced_t<I>&)+ {+ return true;+ }+};++#if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \+ && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)+template <int I> template <typename E, typename T>+const T parallel_t<I>::static_query_v;+#endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)+ // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)++} // namespace bulk_guarantee+} // namespace detail++typedef detail::bulk_guarantee_t<> bulk_guarantee_t;++#if defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)+constexpr bulk_guarantee_t bulk_guarantee;+#else // defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)+namespace { static const bulk_guarantee_t&+ bulk_guarantee = bulk_guarantee_t::instance; }+#endif++} // namespace execution++#if !defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename T>+struct is_applicable_property<T, execution::bulk_guarantee_t>+ : integral_constant<bool,+ execution::is_executor<T>::value+ || conditional<+ execution::is_executor<T>::value,+ false_type,+ execution::is_sender<T>+ >::type::value+ || conditional<+ execution::is_executor<T>::value,+ false_type,+ execution::is_scheduler<T>+ >::type::value>+{+};++template <typename T>+struct is_applicable_property<T, execution::bulk_guarantee_t::unsequenced_t>+ : integral_constant<bool,+ execution::is_executor<T>::value+ || conditional<+ execution::is_executor<T>::value,+ false_type,+ execution::is_sender<T>+ >::type::value+ || conditional<+ execution::is_executor<T>::value,+ false_type,+ execution::is_scheduler<T>+ >::type::value>+{+};++template <typename T>+struct is_applicable_property<T, execution::bulk_guarantee_t::sequenced_t>+ : integral_constant<bool,+ execution::is_executor<T>::value+ || conditional<+ execution::is_executor<T>::value,+ false_type,+ execution::is_sender<T>+ >::type::value+ || conditional<+ execution::is_executor<T>::value,+ false_type,+ execution::is_scheduler<T>+ >::type::value>+{+};++template <typename T>+struct is_applicable_property<T, execution::bulk_guarantee_t::parallel_t>+ : integral_constant<bool,+ execution::is_executor<T>::value+ || conditional<+ execution::is_executor<T>::value,+ false_type,+ execution::is_sender<T>+ >::type::value+ || conditional<+ execution::is_executor<T>::value,+ false_type,+ execution::is_scheduler<T>+ >::type::value>+{+};++#endif // !defined(ASIO_HAS_VARIABLE_TEMPLATES)++namespace traits {++#if !defined(ASIO_HAS_DEDUCED_QUERY_FREE_TRAIT)++template <typename T>+struct query_free_default<T, execution::bulk_guarantee_t,+ typename enable_if<+ can_query<T, execution::bulk_guarantee_t::unsequenced_t>::value+ >::type>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+ (is_nothrow_query<T, execution::bulk_guarantee_t::unsequenced_t>::value));++ typedef execution::bulk_guarantee_t result_type;+};++template <typename T>+struct query_free_default<T, execution::bulk_guarantee_t,+ typename enable_if<+ !can_query<T, execution::bulk_guarantee_t::unsequenced_t>::value+ && can_query<T, execution::bulk_guarantee_t::sequenced_t>::value+ >::type>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+ (is_nothrow_query<T, execution::bulk_guarantee_t::sequenced_t>::value));++ typedef execution::bulk_guarantee_t result_type;+};++template <typename T>+struct query_free_default<T, execution::bulk_guarantee_t,+ typename enable_if<+ !can_query<T, execution::bulk_guarantee_t::unsequenced_t>::value+ && !can_query<T, execution::bulk_guarantee_t::sequenced_t>::value+ && can_query<T, execution::bulk_guarantee_t::parallel_t>::value+ >::type>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+ (is_nothrow_query<T, execution::bulk_guarantee_t::parallel_t>::value));++ typedef execution::bulk_guarantee_t result_type;+};++#endif // !defined(ASIO_HAS_DEDUCED_QUERY_FREE_TRAIT)++#if !defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \+ || !defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)++template <typename T>+struct static_query<T, execution::bulk_guarantee_t,+ typename enable_if<+ execution::detail::bulk_guarantee_t<0>::+ query_static_constexpr_member<T>::is_valid+ >::type>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);++ typedef typename execution::detail::bulk_guarantee_t<0>::+ query_static_constexpr_member<T>::result_type result_type;++ static ASIO_CONSTEXPR result_type value()+ {+ return execution::detail::bulk_guarantee_t<0>::+ query_static_constexpr_member<T>::value();+ }+};++template <typename T>+struct static_query<T, execution::bulk_guarantee_t,+ typename enable_if<+ !execution::detail::bulk_guarantee_t<0>::+ query_static_constexpr_member<T>::is_valid+ && !execution::detail::bulk_guarantee_t<0>::+ query_member<T>::is_valid+ && traits::static_query<T,+ execution::bulk_guarantee_t::unsequenced_t>::is_valid+ >::type>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);++ typedef typename traits::static_query<T,+ execution::bulk_guarantee_t::unsequenced_t>::result_type result_type;++ static ASIO_CONSTEXPR result_type value()+ {+ return traits::static_query<T,+ execution::bulk_guarantee_t::unsequenced_t>::value();+ }+};++template <typename T>+struct static_query<T, execution::bulk_guarantee_t,+ typename enable_if<+ !execution::detail::bulk_guarantee_t<0>::+ query_static_constexpr_member<T>::is_valid+ && !execution::detail::bulk_guarantee_t<0>::+ query_member<T>::is_valid+ && !traits::static_query<T,+ execution::bulk_guarantee_t::unsequenced_t>::is_valid+ && traits::static_query<T,+ execution::bulk_guarantee_t::sequenced_t>::is_valid+ >::type>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);++ typedef typename traits::static_query<T,+ execution::bulk_guarantee_t::sequenced_t>::result_type result_type;++ static ASIO_CONSTEXPR result_type value()+ {+ return traits::static_query<T,+ execution::bulk_guarantee_t::sequenced_t>::value();+ }+};++template <typename T>+struct static_query<T, execution::bulk_guarantee_t,+ typename enable_if<+ !execution::detail::bulk_guarantee_t<0>::+ query_static_constexpr_member<T>::is_valid+ && !execution::detail::bulk_guarantee_t<0>::+ query_member<T>::is_valid+ && !traits::static_query<T,+ execution::bulk_guarantee_t::unsequenced_t>::is_valid+ && !traits::static_query<T,+ execution::bulk_guarantee_t::sequenced_t>::is_valid+ && traits::static_query<T,+ execution::bulk_guarantee_t::parallel_t>::is_valid+ >::type>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);++ typedef typename traits::static_query<T,+ execution::bulk_guarantee_t::parallel_t>::result_type result_type;++ static ASIO_CONSTEXPR result_type value()+ {+ return traits::static_query<T,+ execution::bulk_guarantee_t::parallel_t>::value();+ }+};++template <typename T>+struct static_query<T, execution::bulk_guarantee_t::unsequenced_t,+ typename enable_if<+ execution::detail::bulk_guarantee::unsequenced_t<0>::+ query_static_constexpr_member<T>::is_valid+ >::type>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);++ typedef typename execution::detail::bulk_guarantee::unsequenced_t<0>::+ query_static_constexpr_member<T>::result_type result_type;++ static ASIO_CONSTEXPR result_type value()+ {+ return execution::detail::bulk_guarantee::unsequenced_t<0>::+ query_static_constexpr_member<T>::value();+ }+};++template <typename T>+struct static_query<T, execution::bulk_guarantee_t::unsequenced_t,+ typename enable_if<+ !execution::detail::bulk_guarantee::unsequenced_t<0>::+ query_static_constexpr_member<T>::is_valid+ && !execution::detail::bulk_guarantee::unsequenced_t<0>::+ query_member<T>::is_valid+ && !traits::query_free<T,+ execution::bulk_guarantee_t::unsequenced_t>::is_valid+ && !can_query<T, execution::bulk_guarantee_t::sequenced_t>::value+ && !can_query<T, execution::bulk_guarantee_t::parallel_t>::value+ >::type>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);++ typedef execution::bulk_guarantee_t::unsequenced_t result_type;++ static ASIO_CONSTEXPR result_type value()+ {+ return result_type();+ }+};++template <typename T>+struct static_query<T, execution::bulk_guarantee_t::sequenced_t,+ typename enable_if<+ execution::detail::bulk_guarantee::sequenced_t<0>::+ query_static_constexpr_member<T>::is_valid+ >::type>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);++ typedef typename execution::detail::bulk_guarantee::sequenced_t<0>::+ query_static_constexpr_member<T>::result_type result_type;++ static ASIO_CONSTEXPR result_type value()+ {+ return execution::detail::bulk_guarantee::sequenced_t<0>::+ query_static_constexpr_member<T>::value();+ }+};++template <typename T>+struct static_query<T, execution::bulk_guarantee_t::parallel_t,+ typename enable_if<+ execution::detail::bulk_guarantee::parallel_t<0>::+ query_static_constexpr_member<T>::is_valid+ >::type>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);++ typedef typename execution::detail::bulk_guarantee::parallel_t<0>::+ query_static_constexpr_member<T>::result_type result_type;++ static ASIO_CONSTEXPR result_type value()+ {+ return execution::detail::bulk_guarantee::parallel_t<0>::+ query_static_constexpr_member<T>::value();+ }+};++#endif // !defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)+ // || !defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)++#if !defined(ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT)++template <typename T>+struct static_require<T, execution::bulk_guarantee_t::unsequenced_t,+ typename enable_if<+ static_query<T, execution::bulk_guarantee_t::unsequenced_t>::is_valid+ >::type>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid =+ (is_same<typename static_query<T,+ execution::bulk_guarantee_t::unsequenced_t>::result_type,+ execution::bulk_guarantee_t::unsequenced_t>::value));+};++template <typename T>+struct static_require<T, execution::bulk_guarantee_t::sequenced_t,+ typename enable_if<+ static_query<T, execution::bulk_guarantee_t::sequenced_t>::is_valid+ >::type>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid =+ (is_same<typename static_query<T,+ execution::bulk_guarantee_t::sequenced_t>::result_type,+ execution::bulk_guarantee_t::sequenced_t>::value));+};++template <typename T>+struct static_require<T, execution::bulk_guarantee_t::parallel_t,+ typename enable_if<+ static_query<T, execution::bulk_guarantee_t::parallel_t>::is_valid+ >::type>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid =+ (is_same<typename static_query<T,+ execution::bulk_guarantee_t::parallel_t>::result_type,+ execution::bulk_guarantee_t::parallel_t>::value));+};++#endif // !defined(ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT)++} // namespace traits++#endif // defined(GENERATING_DOCUMENTATION)++} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // !defined(ASIO_NO_DEPRECATED)++#endif // ASIO_EXECUTION_BULK_GUARANTEE_HPP
+ link/modules/asio-standalone/asio/include/asio/execution/connect.hpp view
@@ -0,0 +1,494 @@+//+// execution/connect.hpp+// ~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_EXECUTION_CONNECT_HPP+#define ASIO_EXECUTION_CONNECT_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"++#if !defined(ASIO_NO_DEPRECATED)++#include "asio/detail/type_traits.hpp"+#include "asio/execution/detail/as_invocable.hpp"+#include "asio/execution/detail/as_operation.hpp"+#include "asio/execution/detail/as_receiver.hpp"+#include "asio/execution/executor.hpp"+#include "asio/execution/operation_state.hpp"+#include "asio/execution/receiver.hpp"+#include "asio/execution/sender.hpp"+#include "asio/traits/connect_member.hpp"+#include "asio/traits/connect_free.hpp"++#include "asio/detail/push_options.hpp"++#if defined(GENERATING_DOCUMENTATION)++namespace asio {+namespace execution {++/// A customisation point that connects a sender to a receiver.+/**+ * The name <tt>execution::connect</tt> denotes a customisation point object.+ * For some subexpressions <tt>s</tt> and <tt>r</tt>, let <tt>S</tt> be a type+ * such that <tt>decltype((s))</tt> is <tt>S</tt> and let <tt>R</tt> be a type+ * such that <tt>decltype((r))</tt> is <tt>R</tt>. The expression+ * <tt>execution::connect(s, r)</tt> is expression-equivalent to:+ *+ * @li <tt>s.connect(r)</tt>, if that expression is valid, if its type+ * satisfies <tt>operation_state</tt>, and if <tt>S</tt> satisfies+ * <tt>sender</tt>.+ *+ * @li Otherwise, <tt>connect(s, r)</tt>, if that expression is valid, if its+ * type satisfies <tt>operation_state</tt>, and if <tt>S</tt> satisfies+ * <tt>sender</tt>, with overload resolution performed in a context that+ * includes the declaration <tt>void connect();</tt> and that does not include+ * a declaration of <tt>execution::connect</tt>.+ *+ * @li Otherwise, <tt>as_operation{s, r}</tt>, if <tt>r</tt> is not an instance+ * of <tt>as_receiver<F, S></tt> for some type <tt>F</tt>, and if+ * <tt>receiver_of<R> && executor_of<remove_cvref_t<S>,+ * as_invocable<remove_cvref_t<R>, S>></tt> is <tt>true</tt>, where+ * <tt>as_operation</tt> is an implementation-defined class equivalent to+ * @code template <class S, class R>+ * struct as_operation+ * {+ * remove_cvref_t<S> e_;+ * remove_cvref_t<R> r_;+ * void start() noexcept try {+ * execution::execute(std::move(e_),+ * as_invocable<remove_cvref_t<R>, S>{r_});+ * } catch(...) {+ * execution::set_error(std::move(r_), current_exception());+ * }+ * }; @endcode+ * and <tt>as_invocable</tt> is a class template equivalent to the following:+ * @code template<class R>+ * struct as_invocable+ * {+ * R* r_;+ * explicit as_invocable(R& r) noexcept+ * : r_(std::addressof(r)) {}+ * as_invocable(as_invocable && other) noexcept+ * : r_(std::exchange(other.r_, nullptr)) {}+ * ~as_invocable() {+ * if(r_)+ * execution::set_done(std::move(*r_));+ * }+ * void operator()() & noexcept try {+ * execution::set_value(std::move(*r_));+ * r_ = nullptr;+ * } catch(...) {+ * execution::set_error(std::move(*r_), current_exception());+ * r_ = nullptr;+ * }+ * };+ * @endcode+ *+ * @li Otherwise, <tt>execution::connect(s, r)</tt> is ill-formed.+ */+inline constexpr unspecified connect = unspecified;++/// A type trait that determines whether a @c connect expression is+/// well-formed.+/**+ * Class template @c can_connect is a trait that is derived from+ * @c true_type if the expression <tt>execution::connect(std::declval<S>(),+ * std::declval<R>())</tt> is well formed; otherwise @c false_type.+ */+template <typename S, typename R>+struct can_connect :+ integral_constant<bool, automatically_determined>+{+};++/// A type trait to determine the result of a @c connect expression.+template <typename S, typename R>+struct connect_result+{+ /// The type of the connect expression.+ /**+ * The type of the expression <tt>execution::connect(std::declval<S>(),+ * std::declval<R>())</tt>.+ */+ typedef automatically_determined type;+};++/// A type alis to determine the result of a @c connect expression.+template <typename S, typename R>+using connect_result_t = typename connect_result<S, R>::type;++} // namespace execution+} // namespace asio++#else // defined(GENERATING_DOCUMENTATION)++namespace asio_execution_connect_fn {++using asio::conditional;+using asio::declval;+using asio::enable_if;+using asio::execution::detail::as_invocable;+using asio::execution::detail::as_operation;+using asio::execution::detail::is_as_receiver;+using asio::execution::is_executor_of;+using asio::execution::is_operation_state;+using asio::execution::is_receiver;+using asio::execution::is_sender;+using asio::false_type;+using asio::remove_cvref;+using asio::traits::connect_free;+using asio::traits::connect_member;++void connect();++enum overload_type+{+ call_member,+ call_free,+ adapter,+ ill_formed+};++template <typename S, typename R, typename = void,+ typename = void, typename = void, typename = void>+struct call_traits+{+ ASIO_STATIC_CONSTEXPR(overload_type, overload = ill_formed);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ typedef void result_type;+};++template <typename S, typename R>+struct call_traits<S, void(R),+ typename enable_if<+ connect_member<S, R>::is_valid+ >::type,+ typename enable_if<+ is_operation_state<typename connect_member<S, R>::result_type>::value+ >::type,+ typename enable_if<+ is_sender<typename remove_cvref<S>::type>::value+ >::type> :+ connect_member<S, R>+{+ ASIO_STATIC_CONSTEXPR(overload_type, overload = call_member);+};++template <typename S, typename R>+struct call_traits<S, void(R),+ typename enable_if<+ !connect_member<S, R>::is_valid+ >::type,+ typename enable_if<+ connect_free<S, R>::is_valid+ >::type,+ typename enable_if<+ is_operation_state<typename connect_free<S, R>::result_type>::value+ >::type,+ typename enable_if<+ is_sender<typename remove_cvref<S>::type>::value+ >::type> :+ connect_free<S, R>+{+ ASIO_STATIC_CONSTEXPR(overload_type, overload = call_free);+};++template <typename S, typename R>+struct call_traits<S, void(R),+ typename enable_if<+ !connect_member<S, R>::is_valid+ >::type,+ typename enable_if<+ !connect_free<S, R>::is_valid+ >::type,+ typename enable_if<+ is_receiver<R>::value+ >::type,+ typename enable_if<+ conditional<+ !is_as_receiver<+ typename remove_cvref<R>::type+ >::value,+ is_executor_of<+ typename remove_cvref<S>::type,+ as_invocable<typename remove_cvref<R>::type, S>+ >,+ false_type+ >::type::value+ >::type>+{+ ASIO_STATIC_CONSTEXPR(overload_type, overload = adapter);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ typedef as_operation<S, R> result_type;+};++struct impl+{+#if defined(ASIO_HAS_MOVE)+ template <typename S, typename R>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<S, void(R)>::overload == call_member,+ typename call_traits<S, void(R)>::result_type+ >::type+ operator()(S&& s, R&& r) const+ ASIO_NOEXCEPT_IF((+ call_traits<S, void(R)>::is_noexcept))+ {+ return ASIO_MOVE_CAST(S)(s).connect(ASIO_MOVE_CAST(R)(r));+ }++ template <typename S, typename R>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<S, void(R)>::overload == call_free,+ typename call_traits<S, void(R)>::result_type+ >::type+ operator()(S&& s, R&& r) const+ ASIO_NOEXCEPT_IF((+ call_traits<S, void(R)>::is_noexcept))+ {+ return connect(ASIO_MOVE_CAST(S)(s), ASIO_MOVE_CAST(R)(r));+ }++ template <typename S, typename R>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<S, void(R)>::overload == adapter,+ typename call_traits<S, void(R)>::result_type+ >::type+ operator()(S&& s, R&& r) const+ ASIO_NOEXCEPT_IF((+ call_traits<S, void(R)>::is_noexcept))+ {+ return typename call_traits<S, void(R)>::result_type(+ ASIO_MOVE_CAST(S)(s), ASIO_MOVE_CAST(R)(r));+ }+#else // defined(ASIO_HAS_MOVE)+ template <typename S, typename R>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<S&, void(R&)>::overload == call_member,+ typename call_traits<S&, void(R&)>::result_type+ >::type+ operator()(S& s, R& r) const+ ASIO_NOEXCEPT_IF((+ call_traits<S&, void(R&)>::is_noexcept))+ {+ return s.connect(r);+ }++ template <typename S, typename R>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<const S&, void(R&)>::overload == call_member,+ typename call_traits<const S&, void(R&)>::result_type+ >::type+ operator()(const S& s, R& r) const+ ASIO_NOEXCEPT_IF((+ call_traits<const S&, void(R&)>::is_noexcept))+ {+ return s.connect(r);+ }++ template <typename S, typename R>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<S&, void(R&)>::overload == call_free,+ typename call_traits<S&, void(R&)>::result_type+ >::type+ operator()(S& s, R& r) const+ ASIO_NOEXCEPT_IF((+ call_traits<S&, void(R&)>::is_noexcept))+ {+ return connect(s, r);+ }++ template <typename S, typename R>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<const S&, void(R&)>::overload == call_free,+ typename call_traits<const S&, void(R&)>::result_type+ >::type+ operator()(const S& s, R& r) const+ ASIO_NOEXCEPT_IF((+ call_traits<const S&, void(R&)>::is_noexcept))+ {+ return connect(s, r);+ }++ template <typename S, typename R>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<S&, void(R&)>::overload == adapter,+ typename call_traits<S&, void(R&)>::result_type+ >::type+ operator()(S& s, R& r) const+ ASIO_NOEXCEPT_IF((+ call_traits<S&, void(R&)>::is_noexcept))+ {+ return typename call_traits<S&, void(R&)>::result_type(s, r);+ }++ template <typename S, typename R>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<const S&, void(R&)>::overload == adapter,+ typename call_traits<const S&, void(R&)>::result_type+ >::type+ operator()(const S& s, R& r) const+ ASIO_NOEXCEPT_IF((+ call_traits<const S&, void(R&)>::is_noexcept))+ {+ return typename call_traits<const S&, void(R&)>::result_type(s, r);+ }++ template <typename S, typename R>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<S&, void(const R&)>::overload == call_member,+ typename call_traits<S&, void(const R&)>::result_type+ >::type+ operator()(S& s, const R& r) const+ ASIO_NOEXCEPT_IF((+ call_traits<S&, void(const R&)>::is_noexcept))+ {+ return s.connect(r);+ }++ template <typename S, typename R>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<const S&, void(const R&)>::overload == call_member,+ typename call_traits<const S&, void(const R&)>::result_type+ >::type+ operator()(const S& s, const R& r) const+ ASIO_NOEXCEPT_IF((+ call_traits<const S&, void(const R&)>::is_noexcept))+ {+ return s.connect(r);+ }++ template <typename S, typename R>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<S&, void(const R&)>::overload == call_free,+ typename call_traits<S&, void(const R&)>::result_type+ >::type+ operator()(S& s, const R& r) const+ ASIO_NOEXCEPT_IF((+ call_traits<S&, void(const R&)>::is_noexcept))+ {+ return connect(s, r);+ }++ template <typename S, typename R>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<const S&, void(const R&)>::overload == call_free,+ typename call_traits<const S&, void(const R&)>::result_type+ >::type+ operator()(const S& s, const R& r) const+ ASIO_NOEXCEPT_IF((+ call_traits<const S&, void(const R&)>::is_noexcept))+ {+ return connect(s, r);+ }++ template <typename S, typename R>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<S&, void(const R&)>::overload == adapter,+ typename call_traits<S&, void(const R&)>::result_type+ >::type+ operator()(S& s, const R& r) const+ ASIO_NOEXCEPT_IF((+ call_traits<S&, void(const R&)>::is_noexcept))+ {+ return typename call_traits<S&, void(const R&)>::result_type(s, r);+ }++ template <typename S, typename R>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<const S&, void(const R&)>::overload == adapter,+ typename call_traits<const S&, void(const R&)>::result_type+ >::type+ operator()(const S& s, const R& r) const+ ASIO_NOEXCEPT_IF((+ call_traits<const S&, void(const R&)>::is_noexcept))+ {+ return typename call_traits<const S&, void(const R&)>::result_type(s, r);+ }+#endif // defined(ASIO_HAS_MOVE)+};++template <typename T = impl>+struct static_instance+{+ static const T instance;+};++template <typename T>+const T static_instance<T>::instance = {};++} // namespace asio_execution_connect_fn+namespace asio {+namespace execution {+namespace {++static ASIO_CONSTEXPR const asio_execution_connect_fn::impl&+ connect = asio_execution_connect_fn::static_instance<>::instance;++} // namespace++template <typename S, typename R>+struct can_connect :+ integral_constant<bool,+ asio_execution_connect_fn::call_traits<S, void(R)>::overload !=+ asio_execution_connect_fn::ill_formed>+{+};++#if defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename S, typename R>+constexpr bool can_connect_v = can_connect<S, R>::value;++#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename S, typename R>+struct is_nothrow_connect :+ integral_constant<bool,+ asio_execution_connect_fn::call_traits<S, void(R)>::is_noexcept>+{+};++#if defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename S, typename R>+constexpr bool is_nothrow_connect_v+ = is_nothrow_connect<S, R>::value;++#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename S, typename R>+struct connect_result+{+ typedef typename asio_execution_connect_fn::call_traits<+ S, void(R)>::result_type type;+};++#if defined(ASIO_HAS_ALIAS_TEMPLATES)++template <typename S, typename R>+using connect_result_t = typename connect_result<S, R>::type;++#endif // defined(ASIO_HAS_ALIAS_TEMPLATES)++} // namespace execution+} // namespace asio++#endif // defined(GENERATING_DOCUMENTATION)++#include "asio/detail/pop_options.hpp"++#endif // !defined(ASIO_NO_DEPRECATED)++#endif // ASIO_EXECUTION_CONNECT_HPP
link/modules/asio-standalone/asio/include/asio/execution/context.hpp view
@@ -2,7 +2,7 @@ // execution/context.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -18,6 +18,8 @@ #include "asio/detail/config.hpp" #include "asio/detail/type_traits.hpp" #include "asio/execution/executor.hpp"+#include "asio/execution/scheduler.hpp"+#include "asio/execution/sender.hpp" #include "asio/is_applicable_property.hpp" #include "asio/traits/query_static_constexpr_member.hpp" #include "asio/traits/static_query.hpp"@@ -38,9 +40,10 @@ /// with an executor. struct context_t {- /// The context_t property applies to executors.+ /// The context_t property applies to executors, senders, and schedulers. template <typename T>- static constexpr bool is_applicable_property_v = is_executor_v<T>;+ static constexpr bool is_applicable_property_v =+ is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>; /// The context_t property cannot be required. static constexpr bool is_requirable = false;@@ -66,18 +69,38 @@ struct context_t { #if defined(ASIO_HAS_VARIABLE_TEMPLATES)+# if defined(ASIO_NO_DEPRECATED) template <typename T>- static constexpr bool is_applicable_property_v = is_executor<T>::value;+ ASIO_STATIC_CONSTEXPR(bool,+ is_applicable_property_v = (+ is_executor<T>::value));+# else // defined(ASIO_NO_DEPRECATED)+ template <typename T>+ ASIO_STATIC_CONSTEXPR(bool,+ is_applicable_property_v = (+ is_executor<T>::value+ || conditional<+ is_executor<T>::value,+ false_type,+ is_sender<T>+ >::type::value+ || conditional<+ is_executor<T>::value,+ false_type,+ is_scheduler<T>+ >::type::value+ ));+# endif // defined(ASIO_NO_DEPRECATED) #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) - static constexpr bool is_requirable = false;- static constexpr bool is_preferable = false;+ ASIO_STATIC_CONSTEXPR(bool, is_requirable = false);+ ASIO_STATIC_CONSTEXPR(bool, is_preferable = false); #if defined(ASIO_HAS_STD_ANY) typedef std::any polymorphic_query_result_type; #endif // defined(ASIO_HAS_STD_ANY) - constexpr context_t()+ ASIO_CONSTEXPR context_t() { } @@ -88,17 +111,17 @@ struct type { template <typename P>- static constexpr auto query(P&& p)+ static constexpr auto query(ASIO_MOVE_ARG(P) p) noexcept( noexcept(- conditional_t<true, T, P>::query(static_cast<P&&>(p))+ conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p)) ) ) -> decltype(- conditional_t<true, T, P>::query(static_cast<P&&>(p))+ conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p)) ) {- return T::query(static_cast<P&&>(p));+ return T::query(ASIO_MOVE_CAST(P)(p)); } }; #else // defined(ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)@@ -114,17 +137,24 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T>- static constexpr typename query_static_constexpr_member<T>::result_type+ static ASIO_CONSTEXPR+ typename query_static_constexpr_member<T>::result_type static_query()- noexcept(query_static_constexpr_member<T>::is_noexcept)+ ASIO_NOEXCEPT_IF((+ query_static_constexpr_member<T>::is_noexcept)) { return query_static_constexpr_member<T>::value(); } template <typename E, typename T = decltype(context_t::static_query<E>())>- static constexpr const T static_query_v = context_t::static_query<E>();+ static ASIO_CONSTEXPR const T static_query_v+ = context_t::static_query<E>(); #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)++#if !defined(ASIO_HAS_CONSTEXPR)+ static const context_t instance;+#endif // !defined(ASIO_HAS_CONSTEXPR) }; #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \@@ -134,11 +164,20 @@ #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) +#if !defined(ASIO_HAS_CONSTEXPR)+template <int I>+const context_t<I> context_t<I>::instance;+#endif+ } // namespace detail typedef detail::context_t<> context_t; -ASIO_INLINE_VARIABLE constexpr context_t context;+#if defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)+constexpr context_t context;+#else // defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)+namespace { static const context_t& context = context_t::instance; }+#endif } // namespace execution @@ -146,7 +185,21 @@ template <typename T> struct is_applicable_property<T, execution::context_t>- : integral_constant<bool, execution::is_executor<T>::value>+ : integral_constant<bool,+ execution::is_executor<T>::value+#if !defined(ASIO_NO_DEPRECATED)+ || conditional<+ execution::is_executor<T>::value,+ false_type,+ execution::is_sender<T>+ >::type::value+ || conditional<+ execution::is_executor<T>::value,+ false_type,+ execution::is_scheduler<T>+ >::type::value+#endif // !defined(ASIO_NO_DEPRECATED)+ > { }; @@ -159,18 +212,18 @@ template <typename T> struct static_query<T, execution::context_t,- enable_if_t<+ typename enable_if< execution::detail::context_t<0>:: query_static_constexpr_member<T>::is_valid- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef typename execution::detail::context_t<0>:: query_static_constexpr_member<T>::result_type result_type; - static constexpr result_type value()+ static ASIO_CONSTEXPR result_type value() { return execution::detail::context_t<0>:: query_static_constexpr_member<T>::value();
link/modules/asio-standalone/asio/include/asio/execution/context_as.hpp view
@@ -2,7 +2,7 @@ // execution/context_as.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -19,6 +19,8 @@ #include "asio/detail/type_traits.hpp" #include "asio/execution/context.hpp" #include "asio/execution/executor.hpp"+#include "asio/execution/scheduler.hpp"+#include "asio/execution/sender.hpp" #include "asio/is_applicable_property.hpp" #include "asio/query.hpp" #include "asio/traits/query_static_constexpr_member.hpp"@@ -37,9 +39,10 @@ template <typename U> struct context_as_t {- /// The context_as_t property applies to executors.+ /// The context_as_t property applies to executors, senders, and schedulers. template <typename T>- static constexpr bool is_applicable_property_v = is_executor_v<T>;+ static constexpr bool is_applicable_property_v =+ is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>; /// The context_t property cannot be required. static constexpr bool is_requirable = false;@@ -65,54 +68,77 @@ struct context_as_t { #if defined(ASIO_HAS_VARIABLE_TEMPLATES)+# if defined(ASIO_NO_DEPRECATED) template <typename U>- static constexpr bool is_applicable_property_v = is_executor<U>::value;+ ASIO_STATIC_CONSTEXPR(bool,+ is_applicable_property_v = (+ is_executor<U>::value));+# else // defined(ASIO_NO_DEPRECATED)+ template <typename U>+ ASIO_STATIC_CONSTEXPR(bool,+ is_applicable_property_v = (+ is_executor<U>::value+ || conditional<+ is_executor<U>::value,+ false_type,+ is_sender<U>+ >::type::value+ || conditional<+ is_executor<U>::value,+ false_type,+ is_scheduler<U>+ >::type::value+ ));+# endif // defined(ASIO_NO_DEPRECATED) #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) - static constexpr bool is_requirable = false;- static constexpr bool is_preferable = false;+ ASIO_STATIC_CONSTEXPR(bool, is_requirable = false);+ ASIO_STATIC_CONSTEXPR(bool, is_preferable = false); typedef T polymorphic_query_result_type; - constexpr context_as_t()+ ASIO_CONSTEXPR context_as_t() { } - constexpr context_as_t(context_t)+ ASIO_CONSTEXPR context_as_t(context_t) { } #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename E>- static constexpr+ static ASIO_CONSTEXPR typename context_t::query_static_constexpr_member<E>::result_type static_query()- noexcept(context_t::query_static_constexpr_member<E>::is_noexcept)+ ASIO_NOEXCEPT_IF((+ context_t::query_static_constexpr_member<E>::is_noexcept)) { return context_t::query_static_constexpr_member<E>::value(); } template <typename E, typename U = decltype(context_as_t::static_query<E>())>- static constexpr const U static_query_v+ static ASIO_CONSTEXPR const U static_query_v = context_as_t::static_query<E>(); #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename Executor, typename U>- friend constexpr U query(+ friend ASIO_CONSTEXPR U query( const Executor& ex, const context_as_t<U>&,- enable_if_t<+ typename enable_if< is_same<T, U>::value- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< can_query<const Executor&, const context_t&>::value- >* = 0)+ >::type* = 0) #if !defined(__clang__) // Clang crashes if noexcept is used here. #if defined(ASIO_MSVC) // Visual C++ wants the type to be qualified.- noexcept(is_nothrow_query<const Executor&, const context_t&>::value)+ ASIO_NOEXCEPT_IF((+ is_nothrow_query<const Executor&, const context_t&>::value)) #else // defined(ASIO_MSVC)- noexcept(is_nothrow_query<const Executor&, const context_t&>::value)+ ASIO_NOEXCEPT_IF((+ is_nothrow_query<const Executor&, const context_t&>::value)) #endif // defined(ASIO_MSVC) #endif // !defined(__clang__) {@@ -127,11 +153,13 @@ #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) -#if defined(ASIO_HAS_VARIABLE_TEMPLATES) \+#if (defined(ASIO_HAS_VARIABLE_TEMPLATES) \+ && defined(ASIO_HAS_CONSTEXPR)) \ || defined(GENERATING_DOCUMENTATION) template <typename T> constexpr context_as_t<T> context_as{};-#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)+#endif // (defined(ASIO_HAS_VARIABLE_TEMPLATES)+ // && defined(ASIO_HAS_CONSTEXPR)) // || defined(GENERATING_DOCUMENTATION) } // namespace execution@@ -139,8 +167,22 @@ #if !defined(ASIO_HAS_VARIABLE_TEMPLATES) template <typename T, typename U>-struct is_applicable_property<T, execution::context_as_t<U>>- : integral_constant<bool, execution::is_executor<T>::value>+struct is_applicable_property<T, execution::context_as_t<U> >+ : integral_constant<bool,+ execution::is_executor<T>::value+#if !defined(ASIO_NO_DEPRECATED)+ || conditional<+ execution::is_executor<T>::value,+ false_type,+ execution::is_sender<T>+ >::type::value+ || conditional<+ execution::is_executor<T>::value,+ false_type,+ execution::is_scheduler<T>+ >::type::value+#endif // !defined(ASIO_NO_DEPRECATED)+ > { }; @@ -153,9 +195,9 @@ template <typename T, typename U> struct static_query<T, execution::context_as_t<U>,- enable_if_t<+ typename enable_if< static_query<T, execution::context_t>::is_valid- >> : static_query<T, execution::context_t>+ >::type> : static_query<T, execution::context_t> { }; @@ -166,13 +208,13 @@ template <typename T, typename U> struct query_free<T, execution::context_as_t<U>,- enable_if_t<- can_query<const T&, const execution::context_t&>::value- >>+ typename enable_if<+ can_query<const T&, const execution::context_t&>::value+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept =- is_nothrow_query<const T&, const execution::context_t&>::value;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+ (is_nothrow_query<const T&, const execution::context_t&>::value)); typedef U result_type; };
+ link/modules/asio-standalone/asio/include/asio/execution/detail/as_invocable.hpp view
@@ -0,0 +1,152 @@+//+// execution/detail/as_invocable.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_EXECUTION_DETAIL_AS_INVOCABLE_HPP+#define ASIO_EXECUTION_DETAIL_AS_INVOCABLE_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/detail/atomic_count.hpp"+#include "asio/detail/memory.hpp"+#include "asio/detail/type_traits.hpp"+#include "asio/execution/receiver_invocation_error.hpp"+#include "asio/execution/set_done.hpp"+#include "asio/execution/set_error.hpp"+#include "asio/execution/set_value.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {+namespace execution {+namespace detail {++#if defined(ASIO_HAS_MOVE)++template <typename Receiver, typename>+struct as_invocable+{+ Receiver* receiver_;++ explicit as_invocable(Receiver& r) ASIO_NOEXCEPT+ : receiver_(asio::detail::addressof(r))+ {+ }++ as_invocable(as_invocable&& other) ASIO_NOEXCEPT+ : receiver_(other.receiver_)+ {+ other.receiver_ = 0;+ }++ ~as_invocable()+ {+ if (receiver_)+ execution::set_done(ASIO_MOVE_OR_LVALUE(Receiver)(*receiver_));+ }++ void operator()() ASIO_LVALUE_REF_QUAL ASIO_NOEXCEPT+ {+#if !defined(ASIO_NO_EXCEPTIONS)+ try+ {+#endif // !defined(ASIO_NO_EXCEPTIONS)+ execution::set_value(ASIO_MOVE_CAST(Receiver)(*receiver_));+ receiver_ = 0;+#if !defined(ASIO_NO_EXCEPTIONS)+ }+ catch (...)+ {+#if defined(ASIO_HAS_STD_EXCEPTION_PTR)+ execution::set_error(ASIO_MOVE_CAST(Receiver)(*receiver_),+ std::make_exception_ptr(receiver_invocation_error()));+ receiver_ = 0;+#else // defined(ASIO_HAS_STD_EXCEPTION_PTR)+ std::terminate();+#endif // defined(ASIO_HAS_STD_EXCEPTION_PTR)+ }+#endif // !defined(ASIO_NO_EXCEPTIONS)+ }+};++#else // defined(ASIO_HAS_MOVE)++template <typename Receiver, typename>+struct as_invocable+{+ Receiver* receiver_;+ asio::detail::shared_ptr<asio::detail::atomic_count> ref_count_;++ explicit as_invocable(Receiver& r,+ const asio::detail::shared_ptr<+ asio::detail::atomic_count>& c) ASIO_NOEXCEPT+ : receiver_(asio::detail::addressof(r)),+ ref_count_(c)+ {+ }++ as_invocable(const as_invocable& other) ASIO_NOEXCEPT+ : receiver_(other.receiver_),+ ref_count_(other.ref_count_)+ {+ ++(*ref_count_);+ }++ ~as_invocable()+ {+ if (--(*ref_count_) == 0)+ execution::set_done(*receiver_);+ }++ void operator()() ASIO_LVALUE_REF_QUAL ASIO_NOEXCEPT+ {+#if !defined(ASIO_NO_EXCEPTIONS)+ try+ {+#endif // !defined(ASIO_NO_EXCEPTIONS)+ execution::set_value(*receiver_);+ ++(*ref_count_);+ }+#if !defined(ASIO_NO_EXCEPTIONS)+ catch (...)+ {+#if defined(ASIO_HAS_STD_EXCEPTION_PTR)+ execution::set_error(*receiver_,+ std::make_exception_ptr(receiver_invocation_error()));+ ++(*ref_count_);+#else // defined(ASIO_HAS_STD_EXCEPTION_PTR)+ std::terminate();+#endif // defined(ASIO_HAS_STD_EXCEPTION_PTR)+ }+#endif // !defined(ASIO_NO_EXCEPTIONS)+ }+};++#endif // defined(ASIO_HAS_MOVE)++template <typename T>+struct is_as_invocable : false_type+{+};++template <typename Function, typename T>+struct is_as_invocable<as_invocable<Function, T> > : true_type+{+};++} // namespace detail+} // namespace execution+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_EXECUTION_DETAIL_AS_INVOCABLE_HPP
+ link/modules/asio-standalone/asio/include/asio/execution/detail/as_operation.hpp view
@@ -0,0 +1,109 @@+//+// execution/detail/as_operation.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_EXECUTION_DETAIL_AS_OPERATION_HPP+#define ASIO_EXECUTION_DETAIL_AS_OPERATION_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/detail/memory.hpp"+#include "asio/detail/type_traits.hpp"+#include "asio/execution/detail/as_invocable.hpp"+#include "asio/execution/execute.hpp"+#include "asio/execution/set_error.hpp"+#include "asio/traits/start_member.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {+namespace execution {+namespace detail {++template <typename Executor, typename Receiver>+struct as_operation+{+ typename remove_cvref<Executor>::type ex_;+ typename remove_cvref<Receiver>::type receiver_;+#if !defined(ASIO_HAS_MOVE)+ asio::detail::shared_ptr<asio::detail::atomic_count> ref_count_;+#endif // !defined(ASIO_HAS_MOVE)++ template <typename E, typename R>+ explicit as_operation(ASIO_MOVE_ARG(E) e, ASIO_MOVE_ARG(R) r)+ : ex_(ASIO_MOVE_CAST(E)(e)),+ receiver_(ASIO_MOVE_CAST(R)(r))+#if !defined(ASIO_HAS_MOVE)+ , ref_count_(new asio::detail::atomic_count(1))+#endif // !defined(ASIO_HAS_MOVE)+ {+ }++ void start() ASIO_NOEXCEPT+ {+#if !defined(ASIO_NO_EXCEPTIONS)+ try+ {+#endif // !defined(ASIO_NO_EXCEPTIONS)+#if defined(ASIO_NO_DEPRECATED)+ ex_.execute(+#else // defined(ASIO_NO_DEPRECATED)+ execution::execute(+ ASIO_MOVE_CAST(typename remove_cvref<Executor>::type)(ex_),+#endif // defined(ASIO_NO_DEPRECATED)+ as_invocable<typename remove_cvref<Receiver>::type,+ Executor>(receiver_+#if !defined(ASIO_HAS_MOVE)+ , ref_count_+#endif // !defined(ASIO_HAS_MOVE)+ ));+#if !defined(ASIO_NO_EXCEPTIONS)+ }+ catch (...)+ {+#if defined(ASIO_HAS_STD_EXCEPTION_PTR)+ execution::set_error(+ ASIO_MOVE_OR_LVALUE(+ typename remove_cvref<Receiver>::type)(+ receiver_),+ std::current_exception());+#else // defined(ASIO_HAS_STD_EXCEPTION_PTR)+ std::terminate();+#endif // defined(ASIO_HAS_STD_EXCEPTION_PTR)+ }+#endif // !defined(ASIO_NO_EXCEPTIONS)+ }+};++} // namespace detail+} // namespace execution+namespace traits {++#if !defined(ASIO_HAS_DEDUCED_START_MEMBER_TRAIT)++template <typename Executor, typename Receiver>+struct start_member<+ asio::execution::detail::as_operation<Executor, Receiver> >+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ typedef void result_type;+};++#endif // !defined(ASIO_HAS_DEDUCED_START_MEMBER_TRAIT)++} // namespace traits+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_EXECUTION_DETAIL_AS_OPERATION_HPP
+ link/modules/asio-standalone/asio/include/asio/execution/detail/as_receiver.hpp view
@@ -0,0 +1,128 @@+//+// execution/detail/as_receiver.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_EXECUTION_DETAIL_AS_RECEIVER_HPP+#define ASIO_EXECUTION_DETAIL_AS_RECEIVER_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/detail/type_traits.hpp"+#include "asio/traits/set_done_member.hpp"+#include "asio/traits/set_error_member.hpp"+#include "asio/traits/set_value_member.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {+namespace execution {+namespace detail {++template <typename Function, typename>+struct as_receiver+{+ Function f_;++ template <typename F>+ explicit as_receiver(ASIO_MOVE_ARG(F) f, int)+ : f_(ASIO_MOVE_CAST(F)(f))+ {+ }++#if defined(ASIO_MSVC) && defined(ASIO_HAS_MOVE)+ as_receiver(as_receiver&& other)+ : f_(ASIO_MOVE_CAST(Function)(other.f_))+ {+ }+#endif // defined(ASIO_MSVC) && defined(ASIO_HAS_MOVE)++ void set_value()+ ASIO_NOEXCEPT_IF(noexcept(declval<Function&>()()))+ {+ f_();+ }++ template <typename E>+ void set_error(E) ASIO_NOEXCEPT+ {+ std::terminate();+ }++ void set_done() ASIO_NOEXCEPT+ {+ }+};++template <typename T>+struct is_as_receiver : false_type+{+};++template <typename Function, typename T>+struct is_as_receiver<as_receiver<Function, T> > : true_type+{+};++} // namespace detail+} // namespace execution+namespace traits {++#if !defined(ASIO_HAS_DEDUCED_SET_VALUE_MEMBER_TRAIT)++template <typename Function, typename T>+struct set_value_member<+ asio::execution::detail::as_receiver<Function, T>, void()>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+#if defined(ASIO_HAS_NOEXCEPT)+ ASIO_STATIC_CONSTEXPR(bool,+ is_noexcept = noexcept(declval<Function&>()()));+#else // defined(ASIO_HAS_NOEXCEPT)+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+#endif // defined(ASIO_HAS_NOEXCEPT)+ typedef void result_type;+};++#endif // !defined(ASIO_HAS_DEDUCED_SET_VALUE_MEMBER_TRAIT)++#if !defined(ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)++template <typename Function, typename T, typename E>+struct set_error_member<+ asio::execution::detail::as_receiver<Function, T>, E>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ typedef void result_type;+};++#endif // !defined(ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)++#if !defined(ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)++template <typename Function, typename T>+struct set_done_member<+ asio::execution::detail::as_receiver<Function, T> >+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ typedef void result_type;+};++#endif // !defined(ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)++} // namespace traits+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_EXECUTION_DETAIL_AS_RECEIVER_HPP
+ link/modules/asio-standalone/asio/include/asio/execution/detail/bulk_sender.hpp view
@@ -0,0 +1,261 @@+//+// execution/detail/bulk_sender.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_EXECUTION_DETAIL_BULK_SENDER_HPP+#define ASIO_EXECUTION_DETAIL_BULK_SENDER_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/detail/type_traits.hpp"+#include "asio/execution/connect.hpp"+#include "asio/execution/executor.hpp"+#include "asio/execution/set_done.hpp"+#include "asio/execution/set_error.hpp"+#include "asio/traits/connect_member.hpp"+#include "asio/traits/set_done_member.hpp"+#include "asio/traits/set_error_member.hpp"+#include "asio/traits/set_value_member.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {+namespace execution {+namespace detail {++template <typename Receiver, typename Function, typename Number, typename Index>+struct bulk_receiver+{+ typename remove_cvref<Receiver>::type receiver_;+ typename decay<Function>::type f_;+ typename decay<Number>::type n_;++ template <typename R, typename F, typename N>+ explicit bulk_receiver(ASIO_MOVE_ARG(R) r,+ ASIO_MOVE_ARG(F) f, ASIO_MOVE_ARG(N) n)+ : receiver_(ASIO_MOVE_CAST(R)(r)),+ f_(ASIO_MOVE_CAST(F)(f)),+ n_(ASIO_MOVE_CAST(N)(n))+ {+ }++ void set_value()+ {+ for (Index i = 0; i < n_; ++i)+ f_(i);++ execution::set_value(+ ASIO_MOVE_OR_LVALUE(+ typename remove_cvref<Receiver>::type)(receiver_));+ }++ template <typename Error>+ void set_error(ASIO_MOVE_ARG(Error) e) ASIO_NOEXCEPT+ {+ execution::set_error(+ ASIO_MOVE_OR_LVALUE(+ typename remove_cvref<Receiver>::type)(receiver_),+ ASIO_MOVE_CAST(Error)(e));+ }++ void set_done() ASIO_NOEXCEPT+ {+ execution::set_done(+ ASIO_MOVE_OR_LVALUE(+ typename remove_cvref<Receiver>::type)(receiver_));+ }+};++template <typename Sender, typename Receiver,+ typename Function, typename Number>+struct bulk_receiver_traits+{+ typedef bulk_receiver<+ Receiver, Function, Number,+ typename execution::executor_index<+ typename remove_cvref<Sender>::type+ >::type+ > type;++#if defined(ASIO_HAS_MOVE)+ typedef type arg_type;+#else // defined(ASIO_HAS_MOVE)+ typedef const type& arg_type;+#endif // defined(ASIO_HAS_MOVE)+};++template <typename Sender, typename Function, typename Number>+struct bulk_sender : sender_base+{+ typename remove_cvref<Sender>::type sender_;+ typename decay<Function>::type f_;+ typename decay<Number>::type n_;++ template <typename S, typename F, typename N>+ explicit bulk_sender(ASIO_MOVE_ARG(S) s,+ ASIO_MOVE_ARG(F) f, ASIO_MOVE_ARG(N) n)+ : sender_(ASIO_MOVE_CAST(S)(s)),+ f_(ASIO_MOVE_CAST(F)(f)),+ n_(ASIO_MOVE_CAST(N)(n))+ {+ }++ template <typename Receiver>+ typename connect_result<+ ASIO_MOVE_OR_LVALUE_TYPE(typename remove_cvref<Sender>::type),+ typename bulk_receiver_traits<+ Sender, Receiver, Function, Number+ >::arg_type+ >::type connect(ASIO_MOVE_ARG(Receiver) r,+ typename enable_if<+ can_connect<+ typename remove_cvref<Sender>::type,+ typename bulk_receiver_traits<+ Sender, Receiver, Function, Number+ >::arg_type+ >::value+ >::type* = 0) ASIO_RVALUE_REF_QUAL ASIO_NOEXCEPT+ {+ return execution::connect(+ ASIO_MOVE_OR_LVALUE(typename remove_cvref<Sender>::type)(sender_),+ typename bulk_receiver_traits<Sender, Receiver, Function, Number>::type(+ ASIO_MOVE_CAST(Receiver)(r),+ ASIO_MOVE_CAST(typename decay<Function>::type)(f_),+ ASIO_MOVE_CAST(typename decay<Number>::type)(n_)));+ }++ template <typename Receiver>+ typename connect_result<+ const typename remove_cvref<Sender>::type&,+ typename bulk_receiver_traits<+ Sender, Receiver, Function, Number+ >::arg_type+ >::type connect(ASIO_MOVE_ARG(Receiver) r,+ typename enable_if<+ can_connect<+ const typename remove_cvref<Sender>::type&,+ typename bulk_receiver_traits<+ Sender, Receiver, Function, Number+ >::arg_type+ >::value+ >::type* = 0) const ASIO_LVALUE_REF_QUAL ASIO_NOEXCEPT+ {+ return execution::connect(sender_,+ typename bulk_receiver_traits<Sender, Receiver, Function, Number>::type(+ ASIO_MOVE_CAST(Receiver)(r), f_, n_));+ }+};++} // namespace detail+} // namespace execution+namespace traits {++#if !defined(ASIO_HAS_DEDUCED_SET_VALUE_MEMBER_TRAIT)++template <typename Receiver, typename Function, typename Number, typename Index>+struct set_value_member<+ execution::detail::bulk_receiver<Receiver, Function, Number, Index>,+ void()>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ typedef void result_type;+};++#endif // !defined(ASIO_HAS_DEDUCED_SET_VALUE_MEMBER_TRAIT)++#if !defined(ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)++template <typename Receiver, typename Function,+ typename Number, typename Index, typename Error>+struct set_error_member<+ execution::detail::bulk_receiver<Receiver, Function, Number, Index>,+ Error>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ typedef void result_type;+};++#endif // !defined(ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)++#if !defined(ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)++template <typename Receiver, typename Function, typename Number, typename Index>+struct set_done_member<+ execution::detail::bulk_receiver<Receiver, Function, Number, Index> >+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ typedef void result_type;+};++#endif // !defined(ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)++#if !defined(ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT)++template <typename Sender, typename Function,+ typename Number, typename Receiver>+struct connect_member<+ execution::detail::bulk_sender<Sender, Function, Number>,+ Receiver,+ typename enable_if<+ execution::can_connect<+ ASIO_MOVE_OR_LVALUE_TYPE(typename remove_cvref<Sender>::type),+ typename execution::detail::bulk_receiver_traits<+ Sender, Receiver, Function, Number+ >::arg_type+ >::value+ >::type>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ typedef typename execution::connect_result<+ ASIO_MOVE_OR_LVALUE_TYPE(typename remove_cvref<Sender>::type),+ typename execution::detail::bulk_receiver_traits<+ Sender, Receiver, Function, Number+ >::arg_type+ >::type result_type;+};++template <typename Sender, typename Function,+ typename Number, typename Receiver>+struct connect_member<+ const execution::detail::bulk_sender<Sender, Function, Number>,+ Receiver,+ typename enable_if<+ execution::can_connect<+ const typename remove_cvref<Sender>::type&,+ typename execution::detail::bulk_receiver_traits<+ Sender, Receiver, Function, Number+ >::arg_type+ >::value+ >::type>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ typedef typename execution::connect_result<+ const typename remove_cvref<Sender>::type&,+ typename execution::detail::bulk_receiver_traits<+ Sender, Receiver, Function, Number+ >::arg_type+ >::type result_type;+};++#endif // !defined(ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT)++} // namespace traits+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_EXECUTION_DETAIL_BULK_SENDER_HPP
+ link/modules/asio-standalone/asio/include/asio/execution/detail/submit_receiver.hpp view
@@ -0,0 +1,233 @@+//+// execution/detail/submit_receiver.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_EXECUTION_DETAIL_SUBMIT_RECEIVER_HPP+#define ASIO_EXECUTION_DETAIL_SUBMIT_RECEIVER_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/detail/type_traits.hpp"+#include "asio/detail/variadic_templates.hpp"+#include "asio/execution/connect.hpp"+#include "asio/execution/receiver.hpp"+#include "asio/execution/set_done.hpp"+#include "asio/execution/set_error.hpp"+#include "asio/execution/set_value.hpp"+#include "asio/traits/set_done_member.hpp"+#include "asio/traits/set_error_member.hpp"+#include "asio/traits/set_value_member.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {+namespace execution {+namespace detail {++template <typename Sender, typename Receiver>+struct submit_receiver;++template <typename Sender, typename Receiver>+struct submit_receiver_wrapper+{+ submit_receiver<Sender, Receiver>* p_;++ explicit submit_receiver_wrapper(submit_receiver<Sender, Receiver>* p)+ : p_(p)+ {+ }++#if defined(ASIO_HAS_VARIADIC_TEMPLATES)++ template <typename... Args>+ typename enable_if<is_receiver_of<Receiver, Args...>::value>::type+ set_value(ASIO_MOVE_ARG(Args)... args) ASIO_RVALUE_REF_QUAL+ ASIO_NOEXCEPT_IF((is_nothrow_receiver_of<Receiver, Args...>::value))+ {+ execution::set_value(+ ASIO_MOVE_OR_LVALUE(+ typename remove_cvref<Receiver>::type)(p_->r_),+ ASIO_MOVE_CAST(Args)(args)...);+ delete p_;+ }++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++ void set_value() ASIO_RVALUE_REF_QUAL+ ASIO_NOEXCEPT_IF((is_nothrow_receiver_of<Receiver>::value))+ {+ execution::set_value(+ ASIO_MOVE_OR_LVALUE(+ typename remove_cvref<Receiver>::type)(p_->r_));+ delete p_;+ }++#define ASIO_PRIVATE_SUBMIT_RECEIVER_SET_VALUE_DEF(n) \+ template <ASIO_VARIADIC_TPARAMS(n)> \+ typename enable_if<is_receiver_of<Receiver, \+ ASIO_VARIADIC_TARGS(n)>::value>::type \+ set_value(ASIO_VARIADIC_MOVE_PARAMS(n)) ASIO_RVALUE_REF_QUAL \+ ASIO_NOEXCEPT_IF((is_nothrow_receiver_of< \+ Receiver, ASIO_VARIADIC_TARGS(n)>::value)) \+ { \+ execution::set_value( \+ ASIO_MOVE_OR_LVALUE( \+ typename remove_cvref<Receiver>::type)(p_->r_), \+ ASIO_VARIADIC_MOVE_ARGS(n)); \+ delete p_; \+ } \+ /**/+ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_SUBMIT_RECEIVER_SET_VALUE_DEF)+#undef ASIO_PRIVATE_SUBMIT_RECEIVER_SET_VALUE_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++ template <typename E>+ void set_error(ASIO_MOVE_ARG(E) e)+ ASIO_RVALUE_REF_QUAL ASIO_NOEXCEPT+ {+ execution::set_error(+ ASIO_MOVE_OR_LVALUE(+ typename remove_cvref<Receiver>::type)(p_->r_),+ ASIO_MOVE_CAST(E)(e));+ delete p_;+ }++ void set_done() ASIO_RVALUE_REF_QUAL ASIO_NOEXCEPT+ {+ execution::set_done(+ ASIO_MOVE_OR_LVALUE(+ typename remove_cvref<Receiver>::type)(p_->r_));+ delete p_;+ }+};++template <typename Sender, typename Receiver>+struct submit_receiver+{+ typename remove_cvref<Receiver>::type r_;+#if defined(ASIO_HAS_MOVE)+ typename connect_result<Sender,+ submit_receiver_wrapper<Sender, Receiver> >::type state_;+#else // defined(ASIO_HAS_MOVE)+ typename connect_result<Sender,+ const submit_receiver_wrapper<Sender, Receiver>& >::type state_;+#endif // defined(ASIO_HAS_MOVE)++#if defined(ASIO_HAS_MOVE)+ template <typename S, typename R>+ explicit submit_receiver(ASIO_MOVE_ARG(S) s, ASIO_MOVE_ARG(R) r)+ : r_(ASIO_MOVE_CAST(R)(r)),+ state_(execution::connect(ASIO_MOVE_CAST(S)(s),+ submit_receiver_wrapper<Sender, Receiver>(this)))+ {+ }+#else // defined(ASIO_HAS_MOVE)+ explicit submit_receiver(Sender s, Receiver r)+ : r_(r),+ state_(execution::connect(s,+ submit_receiver_wrapper<Sender, Receiver>(this)))+ {+ }+#endif // defined(ASIO_HAS_MOVE)+};++} // namespace detail+} // namespace execution+namespace traits {++#if !defined(ASIO_HAS_DEDUCED_SET_VALUE_MEMBER_TRAIT)++#if defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename Sender, typename Receiver, typename... Args>+struct set_value_member<+ asio::execution::detail::submit_receiver_wrapper<+ Sender, Receiver>,+ void(Args...)>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+ (asio::execution::is_nothrow_receiver_of<Receiver, Args...>::value));+ typedef void result_type;+};++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename Sender, typename Receiver>+struct set_value_member<+ asio::execution::detail::submit_receiver_wrapper<+ Sender, Receiver>,+ void()>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+ asio::execution::is_nothrow_receiver_of<Receiver>::value);+ typedef void result_type;+};++#define ASIO_PRIVATE_SUBMIT_RECEIVER_TRAIT_DEF(n) \+ template <typename Sender, typename Receiver, \+ ASIO_VARIADIC_TPARAMS(n)> \+ struct set_value_member< \+ asio::execution::detail::submit_receiver_wrapper< \+ Sender, Receiver>, \+ void(ASIO_VARIADIC_TARGS(n))> \+ { \+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true); \+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = \+ (asio::execution::is_nothrow_receiver_of<Receiver, \+ ASIO_VARIADIC_TARGS(n)>::value)); \+ typedef void result_type; \+ }; \+ /**/+ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_SUBMIT_RECEIVER_TRAIT_DEF)+#undef ASIO_PRIVATE_SUBMIT_RECEIVER_TRAIT_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++#endif // !defined(ASIO_HAS_DEDUCED_SET_VALUE_MEMBER_TRAIT)++#if !defined(ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)++template <typename Sender, typename Receiver, typename E>+struct set_error_member<+ asio::execution::detail::submit_receiver_wrapper<+ Sender, Receiver>, E>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ typedef void result_type;+};++#endif // !defined(ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)++#if !defined(ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)++template <typename Sender, typename Receiver>+struct set_done_member<+ asio::execution::detail::submit_receiver_wrapper<+ Sender, Receiver> >+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ typedef void result_type;+};++#endif // !defined(ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)++} // namespace traits+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_EXECUTION_DETAIL_SUBMIT_RECEIVER_HPP
+ link/modules/asio-standalone/asio/include/asio/execution/detail/void_receiver.hpp view
@@ -0,0 +1,90 @@+//+// execution/detail/void_receiver.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_EXECUTION_DETAIL_VOID_RECEIVER_HPP+#define ASIO_EXECUTION_DETAIL_VOID_RECEIVER_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/traits/set_done_member.hpp"+#include "asio/traits/set_error_member.hpp"+#include "asio/traits/set_value_member.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {+namespace execution {+namespace detail {++struct void_receiver+{+ void set_value() ASIO_NOEXCEPT+ {+ }++ template <typename E>+ void set_error(ASIO_MOVE_ARG(E)) ASIO_NOEXCEPT+ {+ }++ void set_done() ASIO_NOEXCEPT+ {+ }+};++} // namespace detail+} // namespace execution+namespace traits {++#if !defined(ASIO_HAS_DEDUCED_SET_VALUE_MEMBER_TRAIT)++template <>+struct set_value_member<asio::execution::detail::void_receiver, void()>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ typedef void result_type;+};++#endif // !defined(ASIO_HAS_DEDUCED_SET_VALUE_MEMBER_TRAIT)++#if !defined(ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)++template <typename E>+struct set_error_member<asio::execution::detail::void_receiver, E>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ typedef void result_type;+};++#endif // !defined(ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)++#if !defined(ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)++template <>+struct set_done_member<asio::execution::detail::void_receiver>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ typedef void result_type;+};++#endif // !defined(ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)++} // namespace traits+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_EXECUTION_DETAIL_VOID_RECEIVER_HPP
+ link/modules/asio-standalone/asio/include/asio/execution/execute.hpp view
@@ -0,0 +1,290 @@+//+// execution/execute.hpp+// ~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_EXECUTION_EXECUTE_HPP+#define ASIO_EXECUTION_EXECUTE_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"++#if !defined(ASIO_NO_DEPRECATED)++#include "asio/detail/type_traits.hpp"+#include "asio/execution/detail/as_invocable.hpp"+#include "asio/execution/detail/as_receiver.hpp"+#include "asio/traits/execute_member.hpp"+#include "asio/traits/execute_free.hpp"++#include "asio/detail/push_options.hpp"++#if defined(GENERATING_DOCUMENTATION)++namespace asio {+namespace execution {++/// (Deprecated: Use @c execute member function.) A customisation point that+/// executes a function on an executor.+/**+ * The name <tt>execution::execute</tt> denotes a customisation point object.+ *+ * For some subexpressions <tt>e</tt> and <tt>f</tt>, let <tt>E</tt> be a type+ * such that <tt>decltype((e))</tt> is <tt>E</tt> and let <tt>F</tt> be a type+ * such that <tt>decltype((f))</tt> is <tt>F</tt>. The expression+ * <tt>execution::execute(e, f)</tt> is ill-formed if <tt>F</tt> does not model+ * <tt>invocable</tt>, or if <tt>E</tt> does not model either <tt>executor</tt>+ * or <tt>sender</tt>. Otherwise, it is expression-equivalent to:+ *+ * @li <tt>e.execute(f)</tt>, if that expression is valid. If the function+ * selected does not execute the function object <tt>f</tt> on the executor+ * <tt>e</tt>, the program is ill-formed with no diagnostic required.+ *+ * @li Otherwise, <tt>execute(e, f)</tt>, if that expression is valid, with+ * overload resolution performed in a context that includes the declaration+ * <tt>void execute();</tt> and that does not include a declaration of+ * <tt>execution::execute</tt>. If the function selected by overload+ * resolution does not execute the function object <tt>f</tt> on the executor+ * <tt>e</tt>, the program is ill-formed with no diagnostic required.+ */+inline constexpr unspecified execute = unspecified;++/// (Deprecated.) A type trait that determines whether an @c execute expression+/// is well-formed.+/**+ * Class template @c can_execute is a trait that is derived from+ * @c true_type if the expression <tt>execution::execute(std::declval<T>(),+ * std::declval<F>())</tt> is well formed; otherwise @c false_type.+ */+template <typename T, typename F>+struct can_execute :+ integral_constant<bool, automatically_determined>+{+};++} // namespace execution+} // namespace asio++#else // defined(GENERATING_DOCUMENTATION)++namespace asio {+namespace execution {++template <typename T, typename R>+struct is_sender_to;++namespace detail {++template <typename S, typename R>+void submit_helper(ASIO_MOVE_ARG(S) s, ASIO_MOVE_ARG(R) r);++} // namespace detail+} // namespace execution+} // namespace asio+namespace asio_execution_execute_fn {++using asio::conditional;+using asio::decay;+using asio::declval;+using asio::enable_if;+using asio::execution::detail::as_receiver;+using asio::execution::detail::is_as_invocable;+using asio::execution::is_sender_to;+using asio::false_type;+using asio::result_of;+using asio::traits::execute_free;+using asio::traits::execute_member;+using asio::true_type;+using asio::void_type;++void execute();++enum overload_type+{+ call_member,+ call_free,+ adapter,+ ill_formed+};++template <typename Impl, typename T, typename F, typename = void,+ typename = void, typename = void, typename = void, typename = void>+struct call_traits+{+ ASIO_STATIC_CONSTEXPR(overload_type, overload = ill_formed);+};++template <typename Impl, typename T, typename F>+struct call_traits<Impl, T, void(F),+ typename enable_if<+ execute_member<typename Impl::template proxy<T>::type, F>::is_valid+ >::type> :+ execute_member<typename Impl::template proxy<T>::type, F>+{+ ASIO_STATIC_CONSTEXPR(overload_type, overload = call_member);+};++template <typename Impl, typename T, typename F>+struct call_traits<Impl, T, void(F),+ typename enable_if<+ !execute_member<typename Impl::template proxy<T>, F>::is_valid+ >::type,+ typename enable_if<+ execute_free<T, F>::is_valid+ >::type> :+ execute_free<T, F>+{+ ASIO_STATIC_CONSTEXPR(overload_type, overload = call_free);+};++template <typename Impl, typename T, typename F>+struct call_traits<Impl, T, void(F),+ typename enable_if<+ !execute_member<typename Impl::template proxy<T>::type, F>::is_valid+ >::type,+ typename enable_if<+ !execute_free<T, F>::is_valid+ >::type,+ typename void_type<+ typename result_of<typename decay<F>::type&()>::type+ >::type,+ typename enable_if<+ !is_as_invocable<typename decay<F>::type>::value+ >::type,+ typename enable_if<+ is_sender_to<T, as_receiver<typename decay<F>::type, T> >::value+ >::type>+{+ ASIO_STATIC_CONSTEXPR(overload_type, overload = adapter);+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ typedef void result_type;+};++struct impl+{+ template <typename T>+ struct proxy+ {+#if defined(ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)+ struct type+ {+ template <typename F>+ auto execute(ASIO_MOVE_ARG(F) f)+ noexcept(+ noexcept(+ declval<typename conditional<true, T, F>::type>().execute(+ ASIO_MOVE_CAST(F)(f))+ )+ )+ -> decltype(+ declval<typename conditional<true, T, F>::type>().execute(+ ASIO_MOVE_CAST(F)(f))+ );+ };+#else // defined(ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)+ typedef T type;+#endif // defined(ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)+ };++ template <typename T, typename F>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<impl, T, void(F)>::overload == call_member,+ typename call_traits<impl, T, void(F)>::result_type+ >::type+ operator()(+ ASIO_MOVE_ARG(T) t,+ ASIO_MOVE_ARG(F) f) const+ ASIO_NOEXCEPT_IF((+ call_traits<impl, T, void(F)>::is_noexcept))+ {+ return ASIO_MOVE_CAST(T)(t).execute(ASIO_MOVE_CAST(F)(f));+ }++ template <typename T, typename F>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<impl, T, void(F)>::overload == call_free,+ typename call_traits<impl, T, void(F)>::result_type+ >::type+ operator()(+ ASIO_MOVE_ARG(T) t,+ ASIO_MOVE_ARG(F) f) const+ ASIO_NOEXCEPT_IF((+ call_traits<impl, T, void(F)>::is_noexcept))+ {+ return execute(ASIO_MOVE_CAST(T)(t), ASIO_MOVE_CAST(F)(f));+ }++ template <typename T, typename F>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<impl, T, void(F)>::overload == adapter,+ typename call_traits<impl, T, void(F)>::result_type+ >::type+ operator()(+ ASIO_MOVE_ARG(T) t,+ ASIO_MOVE_ARG(F) f) const+ ASIO_NOEXCEPT_IF((+ call_traits<impl, T, void(F)>::is_noexcept))+ {+ return asio::execution::detail::submit_helper(+ ASIO_MOVE_CAST(T)(t),+ as_receiver<typename decay<F>::type, T>(+ ASIO_MOVE_CAST(F)(f), 0));+ }+};++template <typename T = impl>+struct static_instance+{+ static const T instance;+};++template <typename T>+const T static_instance<T>::instance = {};++} // namespace asio_execution_execute_fn+namespace asio {+namespace execution {+namespace {++static ASIO_CONSTEXPR const asio_execution_execute_fn::impl&+ execute = asio_execution_execute_fn::static_instance<>::instance;++} // namespace++typedef asio_execution_execute_fn::impl execute_t;++template <typename T, typename F>+struct can_execute :+ integral_constant<bool,+ asio_execution_execute_fn::call_traits<+ execute_t, T, void(F)>::overload !=+ asio_execution_execute_fn::ill_formed>+{+};++#if defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename T, typename F>+constexpr bool can_execute_v = can_execute<T, F>::value;++#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++} // namespace execution+} // namespace asio++#endif // defined(GENERATING_DOCUMENTATION)++#include "asio/detail/pop_options.hpp"++#endif // !defined(ASIO_NO_DEPRECATED)++#endif // ASIO_EXECUTION_EXECUTE_HPP
link/modules/asio-standalone/asio/include/asio/execution/executor.hpp view
@@ -2,7 +2,7 @@ // execution/executor.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -21,10 +21,16 @@ #include "asio/traits/equality_comparable.hpp" #include "asio/traits/execute_member.hpp" -#if defined(ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT) \+#if !defined(ASIO_NO_DEPRECATED)+# include "asio/execution/execute.hpp"+#endif // !defined(ASIO_NO_DEPRECATED)++#if defined(ASIO_HAS_DEDUCED_EXECUTE_FREE_TRAIT) \+ && defined(ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT) \ && defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT) # define ASIO_HAS_DEDUCED_EXECUTION_IS_EXECUTOR_TRAIT 1-#endif // defined(ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)+#endif // defined(ASIO_HAS_DEDUCED_EXECUTE_FREE_TRAIT)+ // && defined(ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT) // && defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT) #include "asio/detail/push_options.hpp"@@ -42,33 +48,78 @@ template <typename T, typename F> struct is_executor_of_impl<T, F,- enable_if_t<- traits::execute_member<add_const_t<T>, F>::is_valid- >,- void_t<- result_of_t<decay_t<F>&()>- >,- enable_if_t<- is_constructible<decay_t<F>, F>::value- >,- enable_if_t<- is_move_constructible<decay_t<F>>::value- >,- enable_if_t<+#if defined(ASIO_NO_DEPRECATED)+ typename enable_if<+ traits::execute_member<typename add_const<T>::type, F>::is_valid+ >::type,+#else // defined(ASIO_NO_DEPRECATED)+ typename enable_if<+ can_execute<typename add_const<T>::type, F>::value+ >::type,+#endif // defined(ASIO_NO_DEPRECATED)+ typename void_type<+ typename result_of<typename decay<F>::type&()>::type+ >::type,+ typename enable_if<+ is_constructible<typename decay<F>::type, F>::value+ >::type,+ typename enable_if<+ is_move_constructible<typename decay<F>::type>::value+ >::type,+#if defined(ASIO_HAS_NOEXCEPT)+ typename enable_if< is_nothrow_copy_constructible<T>::value- >,- enable_if_t<+ >::type,+ typename enable_if< is_nothrow_destructible<T>::value- >,- enable_if_t<+ >::type,+#else // defined(ASIO_HAS_NOEXCEPT)+ typename enable_if<+ is_copy_constructible<T>::value+ >::type,+ typename enable_if<+ is_destructible<T>::value+ >::type,+#endif // defined(ASIO_HAS_NOEXCEPT)+ typename enable_if< traits::equality_comparable<T>::is_valid- >,- enable_if_t<+ >::type,+ typename enable_if< traits::equality_comparable<T>::is_noexcept- >> : true_type+ >::type> : true_type { }; +template <typename T, typename = void>+struct executor_shape+{+ typedef std::size_t type;+};++template <typename T>+struct executor_shape<T,+ typename void_type<+ typename T::shape_type+ >::type>+{+ typedef typename T::shape_type type;+};++template <typename T, typename Default, typename = void>+struct executor_index+{+ typedef Default type;+};++template <typename T, typename Default>+struct executor_index<T, Default,+ typename void_type<+ typename T::index_type+ >::type>+{+ typedef typename T::index_type type;+};+ } // namespace detail /// The is_executor trait detects whether a type T satisfies the@@ -91,7 +142,7 @@ #if defined(ASIO_HAS_VARIABLE_TEMPLATES) template <typename T>-constexpr const bool is_executor_v = is_executor<T>::value;+ASIO_CONSTEXPR const bool is_executor_v = is_executor<T>::value; #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) @@ -107,6 +158,101 @@ #define ASIO_EXECUTION_EXECUTOR typename #endif // defined(ASIO_HAS_CONCEPTS)++/// The is_executor_of trait detects whether a type T satisfies the+/// execution::executor_of concept for some set of value arguments.+/**+ * Class template @c is_executor_of is a type trait that is derived from @c+ * true_type if the type @c T meets the concept definition for an executor+ * that is invocable with a function object of type @c F, otherwise @c+ * false_type.+ */+template <typename T, typename F>+struct is_executor_of :+#if defined(GENERATING_DOCUMENTATION)+ integral_constant<bool, automatically_determined>+#else // defined(GENERATING_DOCUMENTATION)+ integral_constant<bool,+ is_executor<T>::value && detail::is_executor_of_impl<T, F>::value+ >+#endif // defined(GENERATING_DOCUMENTATION)+{+};++#if defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename T, typename F>+ASIO_CONSTEXPR const bool is_executor_of_v =+ is_executor_of<T, F>::value;++#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++#if defined(ASIO_HAS_CONCEPTS)++template <typename T, typename F>+ASIO_CONCEPT executor_of = is_executor_of<T, F>::value;++#define ASIO_EXECUTION_EXECUTOR_OF(f) \+ ::asio::execution::executor_of<f>++#else // defined(ASIO_HAS_CONCEPTS)++#define ASIO_EXECUTION_EXECUTOR_OF typename++#endif // defined(ASIO_HAS_CONCEPTS)++/// The executor_shape trait detects the type used by an executor to represent+/// the shape of a bulk operation.+/**+ * Class template @c executor_shape is a type trait with a nested type alias+ * @c type whose type is @c T::shape_type if @c T::shape_type is valid,+ * otherwise @c std::size_t.+ */+template <typename T>+struct executor_shape+#if !defined(GENERATING_DOCUMENTATION)+ : detail::executor_shape<T>+#endif // !defined(GENERATING_DOCUMENTATION)+{+#if defined(GENERATING_DOCUMENTATION)+ /// @c T::shape_type if @c T::shape_type is valid, otherwise @c std::size_t.+ typedef automatically_determined type;+#endif // defined(GENERATING_DOCUMENTATION)+};++#if defined(ASIO_HAS_ALIAS_TEMPLATES)++template <typename T>+using executor_shape_t = typename executor_shape<T>::type;++#endif // defined(ASIO_HAS_ALIAS_TEMPLATES)++/// The executor_index trait detects the type used by an executor to represent+/// an index within a bulk operation.+/**+ * Class template @c executor_index is a type trait with a nested type alias+ * @c type whose type is @c T::index_type if @c T::index_type is valid,+ * otherwise @c executor_shape_t<T>.+ */+template <typename T>+struct executor_index+#if !defined(GENERATING_DOCUMENTATION)+ : detail::executor_index<T, typename executor_shape<T>::type>+#endif // !defined(GENERATING_DOCUMENTATION)+{+#if defined(GENERATING_DOCUMENTATION)+ /// @c T::index_type if @c T::index_type is valid, otherwise+ /// @c executor_shape_t<T>.+ typedef automatically_determined type;+#endif // defined(GENERATING_DOCUMENTATION)+};++#if defined(ASIO_HAS_ALIAS_TEMPLATES)++template <typename T>+using executor_index_t = typename executor_index<T>::type;++#endif // defined(ASIO_HAS_ALIAS_TEMPLATES) } // namespace execution } // namespace asio
link/modules/asio-standalone/asio/include/asio/execution/impl/bad_executor.ipp view
@@ -1,8 +1,8 @@ //-// execution/impl/bad_executor.ipp-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+// exection/impl/bad_executor.ipp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -23,11 +23,11 @@ namespace asio { namespace execution { -bad_executor::bad_executor() noexcept+bad_executor::bad_executor() ASIO_NOEXCEPT { } -const char* bad_executor::what() const noexcept+const char* bad_executor::what() const ASIO_NOEXCEPT_OR_NOTHROW { return "bad executor"; }
+ link/modules/asio-standalone/asio/include/asio/execution/impl/receiver_invocation_error.ipp view
@@ -0,0 +1,36 @@+//+// exection/impl/receiver_invocation_error.ipp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_EXECUTION_IMPL_RECEIVER_INVOCATION_ERROR_IPP+#define ASIO_EXECUTION_IMPL_RECEIVER_INVOCATION_ERROR_IPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/execution/receiver_invocation_error.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {+namespace execution {++receiver_invocation_error::receiver_invocation_error()+ : std::runtime_error("receiver invocation error")+{+}++} // namespace execution+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_EXECUTION_IMPL_RECEIVER_INVOCATION_ERROR_IPP
link/modules/asio-standalone/asio/include/asio/execution/invocable_archetype.hpp view
@@ -2,7 +2,7 @@ // execution/invocable_archetype.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -17,6 +17,7 @@ #include "asio/detail/config.hpp" #include "asio/detail/type_traits.hpp"+#include "asio/detail/variadic_templates.hpp" #include "asio/detail/push_options.hpp" @@ -27,11 +28,38 @@ /// execution::executor concept. struct invocable_archetype {+#if !defined(GENERATING_DOCUMENTATION)+ // Necessary for compatibility with a C++03 implementation of result_of.+ typedef void result_type;+#endif // !defined(GENERATING_DOCUMENTATION)++#if defined(ASIO_HAS_VARIADIC_TEMPLATES) \+ || defined(GENERATING_DOCUMENTATION)+ /// Function call operator. template <typename... Args>- void operator()(Args&&...)+ void operator()(ASIO_MOVE_ARG(Args)...) { }++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)+ // || defined(GENERATING_DOCUMENTATION)++ void operator()()+ {+ }++#define ASIO_PRIVATE_INVOCABLE_ARCHETYPE_CALL_DEF(n) \+ template <ASIO_VARIADIC_TPARAMS(n)> \+ void operator()(ASIO_VARIADIC_UNNAMED_MOVE_PARAMS(n)) \+ { \+ } \+ /**/+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_INVOCABLE_ARCHETYPE_CALL_DEF)+#undef ASIO_PRIVATE_INVOCABLE_ARCHETYPE_CALL_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+ // || defined(GENERATING_DOCUMENTATION) }; } // namespace execution
link/modules/asio-standalone/asio/include/asio/execution/mapping.hpp view
@@ -2,7 +2,7 @@ // execution/mapping.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -18,6 +18,8 @@ #include "asio/detail/config.hpp" #include "asio/detail/type_traits.hpp" #include "asio/execution/executor.hpp"+#include "asio/execution/scheduler.hpp"+#include "asio/execution/sender.hpp" #include "asio/is_applicable_property.hpp" #include "asio/query.hpp" #include "asio/traits/query_free.hpp"@@ -38,9 +40,10 @@ /// of execution agents on to threads of execution. struct mapping_t {- /// The mapping_t property applies to executors.+ /// The mapping_t property applies to executors, senders, and schedulers. template <typename T>- static constexpr bool is_applicable_property_v = is_executor_v<T>;+ static constexpr bool is_applicable_property_v =+ is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>; /// The top-level mapping_t property cannot be required. static constexpr bool is_requirable = false;@@ -55,9 +58,11 @@ /// threads of execution. struct thread_t {- /// The mapping_t::thread_t property applies to executors.+ /// The mapping_t::thread_t property applies to executors, senders, and+ /// schedulers. template <typename T>- static constexpr bool is_applicable_property_v = is_executor_v<T>;+ static constexpr bool is_applicable_property_v =+ is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>; /// The mapping_t::thread_t property can be required. static constexpr bool is_requirable = true;@@ -82,9 +87,11 @@ /// new threads of execution. struct new_thread_t {- /// The mapping_t::new_thread_t property applies to executors.+ /// The mapping_t::new_thread_t property applies to executors, senders, and+ /// schedulers. template <typename T>- static constexpr bool is_applicable_property_v = is_executor_v<T>;+ static constexpr bool is_applicable_property_v =+ is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>; /// The mapping_t::new_thread_t property can be required. static constexpr bool is_requirable = true;@@ -109,9 +116,11 @@ /// implementation-defined. struct other_t {- /// The mapping_t::other_t property applies to executors.+ /// The mapping_t::other_t property applies to executors, senders, and+ /// schedulers. template <typename T>- static constexpr bool is_applicable_property_v = is_executor_v<T>;+ static constexpr bool is_applicable_property_v =+ is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>; /// The mapping_t::other_t property can be required. static constexpr bool is_requirable = true;@@ -183,34 +192,54 @@ struct mapping_t { #if defined(ASIO_HAS_VARIABLE_TEMPLATES)+# if defined(ASIO_NO_DEPRECATED) template <typename T>- static constexpr bool is_applicable_property_v = is_executor<T>::value;+ ASIO_STATIC_CONSTEXPR(bool,+ is_applicable_property_v = (+ is_executor<T>::value));+# else // defined(ASIO_NO_DEPRECATED)+ template <typename T>+ ASIO_STATIC_CONSTEXPR(bool,+ is_applicable_property_v = (+ is_executor<T>::value+ || conditional<+ is_executor<T>::value,+ false_type,+ is_sender<T>+ >::type::value+ || conditional<+ is_executor<T>::value,+ false_type,+ is_scheduler<T>+ >::type::value+ ));+# endif // defined(ASIO_NO_DEPRECATED) #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) - static constexpr bool is_requirable = false;- static constexpr bool is_preferable = false;+ ASIO_STATIC_CONSTEXPR(bool, is_requirable = false);+ ASIO_STATIC_CONSTEXPR(bool, is_preferable = false); typedef mapping_t polymorphic_query_result_type; typedef detail::mapping::thread_t<I> thread_t; typedef detail::mapping::new_thread_t<I> new_thread_t; typedef detail::mapping::other_t<I> other_t; - constexpr mapping_t()+ ASIO_CONSTEXPR mapping_t() : value_(-1) { } - constexpr mapping_t(thread_t)+ ASIO_CONSTEXPR mapping_t(thread_t) : value_(0) { } - constexpr mapping_t(new_thread_t)+ ASIO_CONSTEXPR mapping_t(new_thread_t) : value_(1) { } - constexpr mapping_t(other_t)+ ASIO_CONSTEXPR mapping_t(other_t) : value_(2) { }@@ -222,14 +251,16 @@ struct type { template <typename P>- auto query(P&& p) const+ auto query(ASIO_MOVE_ARG(P) p) const noexcept( noexcept(- declval<conditional_t<true, T, P>>().query(static_cast<P&&>(p))+ declval<typename conditional<true, T, P>::type>().query(+ ASIO_MOVE_CAST(P)(p)) ) ) -> decltype(- declval<conditional_t<true, T, P>>().query(static_cast<P&&>(p))+ declval<typename conditional<true, T, P>::type>().query(+ ASIO_MOVE_CAST(P)(p)) ); }; #else // defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)@@ -244,17 +275,17 @@ struct type { template <typename P>- static constexpr auto query(P&& p)+ static constexpr auto query(ASIO_MOVE_ARG(P) p) noexcept( noexcept(- conditional_t<true, T, P>::query(static_cast<P&&>(p))+ conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p)) ) ) -> decltype(- conditional_t<true, T, P>::query(static_cast<P&&>(p))+ conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p)) ) {- return T::query(static_cast<P&&>(p));+ return T::query(ASIO_MOVE_CAST(P)(p)); } }; #else // defined(ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)@@ -274,87 +305,88 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T>- static constexpr+ static ASIO_CONSTEXPR typename query_static_constexpr_member<T>::result_type static_query()- noexcept(query_static_constexpr_member<T>::is_noexcept)+ ASIO_NOEXCEPT_IF((+ query_static_constexpr_member<T>::is_noexcept)) { return query_static_constexpr_member<T>::value(); } template <typename T>- static constexpr+ static ASIO_CONSTEXPR typename traits::static_query<T, thread_t>::result_type static_query(- enable_if_t<+ typename enable_if< !query_static_constexpr_member<T>::is_valid- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< !query_member<T>::is_valid- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< traits::static_query<T, thread_t>::is_valid- >* = 0) noexcept+ >::type* = 0) ASIO_NOEXCEPT { return traits::static_query<T, thread_t>::value(); } template <typename T>- static constexpr+ static ASIO_CONSTEXPR typename traits::static_query<T, new_thread_t>::result_type static_query(- enable_if_t<+ typename enable_if< !query_static_constexpr_member<T>::is_valid- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< !query_member<T>::is_valid- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< !traits::static_query<T, thread_t>::is_valid- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< traits::static_query<T, new_thread_t>::is_valid- >* = 0) noexcept+ >::type* = 0) ASIO_NOEXCEPT { return traits::static_query<T, new_thread_t>::value(); } template <typename T>- static constexpr+ static ASIO_CONSTEXPR typename traits::static_query<T, other_t>::result_type static_query(- enable_if_t<+ typename enable_if< !query_static_constexpr_member<T>::is_valid- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< !query_member<T>::is_valid- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< !traits::static_query<T, thread_t>::is_valid- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< !traits::static_query<T, new_thread_t>::is_valid- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< traits::static_query<T, other_t>::is_valid- >* = 0) noexcept+ >::type* = 0) ASIO_NOEXCEPT { return traits::static_query<T, other_t>::value(); } template <typename E, typename T = decltype(mapping_t::static_query<E>())>- static constexpr const T static_query_v+ static ASIO_CONSTEXPR const T static_query_v = mapping_t::static_query<E>(); #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) - friend constexpr bool operator==(+ friend ASIO_CONSTEXPR bool operator==( const mapping_t& a, const mapping_t& b) { return a.value_ == b.value_; } - friend constexpr bool operator!=(+ friend ASIO_CONSTEXPR bool operator!=( const mapping_t& a, const mapping_t& b) { return a.value_ != b.value_;@@ -362,20 +394,22 @@ struct convertible_from_mapping_t {- constexpr convertible_from_mapping_t(mapping_t) {}+ ASIO_CONSTEXPR convertible_from_mapping_t(mapping_t) {} }; template <typename Executor>- friend constexpr mapping_t query(+ friend ASIO_CONSTEXPR mapping_t query( const Executor& ex, convertible_from_mapping_t,- enable_if_t<+ typename enable_if< can_query<const Executor&, thread_t>::value- >* = 0)+ >::type* = 0) #if !defined(__clang__) // Clang crashes if noexcept is used here. #if defined(ASIO_MSVC) // Visual C++ wants the type to be qualified.- noexcept(is_nothrow_query<const Executor&, mapping_t<>::thread_t>::value)+ ASIO_NOEXCEPT_IF((+ is_nothrow_query<const Executor&, mapping_t<>::thread_t>::value)) #else // defined(ASIO_MSVC)- noexcept(is_nothrow_query<const Executor&, thread_t>::value)+ ASIO_NOEXCEPT_IF((+ is_nothrow_query<const Executor&, thread_t>::value)) #endif // defined(ASIO_MSVC) #endif // !defined(__clang__) {@@ -383,20 +417,21 @@ } template <typename Executor>- friend constexpr mapping_t query(+ friend ASIO_CONSTEXPR mapping_t query( const Executor& ex, convertible_from_mapping_t,- enable_if_t<+ typename enable_if< !can_query<const Executor&, thread_t>::value- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< can_query<const Executor&, new_thread_t>::value- >* = 0)+ >::type* = 0) #if !defined(__clang__) // Clang crashes if noexcept is used here. #if defined(ASIO_MSVC) // Visual C++ wants the type to be qualified.- noexcept(- is_nothrow_query<const Executor&, mapping_t<>::new_thread_t>::value)+ ASIO_NOEXCEPT_IF((+ is_nothrow_query<const Executor&, mapping_t<>::new_thread_t>::value)) #else // defined(ASIO_MSVC)- noexcept(is_nothrow_query<const Executor&, new_thread_t>::value)+ ASIO_NOEXCEPT_IF((+ is_nothrow_query<const Executor&, new_thread_t>::value)) #endif // defined(ASIO_MSVC) #endif // !defined(__clang__) {@@ -404,22 +439,24 @@ } template <typename Executor>- friend constexpr mapping_t query(+ friend ASIO_CONSTEXPR mapping_t query( const Executor& ex, convertible_from_mapping_t,- enable_if_t<+ typename enable_if< !can_query<const Executor&, thread_t>::value- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< !can_query<const Executor&, new_thread_t>::value- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< can_query<const Executor&, other_t>::value- >* = 0)+ >::type* = 0) #if !defined(__clang__) // Clang crashes if noexcept is used here. #if defined(ASIO_MSVC) // Visual C++ wants the type to be qualified.- noexcept(is_nothrow_query<const Executor&, mapping_t<>::other_t>::value)+ ASIO_NOEXCEPT_IF((+ is_nothrow_query<const Executor&, mapping_t<>::other_t>::value)) #else // defined(ASIO_MSVC)- noexcept(is_nothrow_query<const Executor&, other_t>::value)+ ASIO_NOEXCEPT_IF((+ is_nothrow_query<const Executor&, other_t>::value)) #endif // defined(ASIO_MSVC) #endif // !defined(__clang__) {@@ -430,6 +467,10 @@ ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(new_thread_t, new_thread); ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(other_t, other); +#if !defined(ASIO_HAS_CONSTEXPR)+ static const mapping_t instance;+#endif // !defined(ASIO_HAS_CONSTEXPR)+ private: int value_; };@@ -441,7 +482,12 @@ #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) +#if !defined(ASIO_HAS_CONSTEXPR) template <int I>+const mapping_t<I> mapping_t<I>::instance;+#endif++template <int I> const typename mapping_t<I>::thread_t mapping_t<I>::thread; template <int I>@@ -456,15 +502,35 @@ struct thread_t { #if defined(ASIO_HAS_VARIABLE_TEMPLATES)+# if defined(ASIO_NO_DEPRECATED) template <typename T>- static constexpr bool is_applicable_property_v = is_executor<T>::value;+ ASIO_STATIC_CONSTEXPR(bool,+ is_applicable_property_v = (+ is_executor<T>::value));+# else // defined(ASIO_NO_DEPRECATED)+ template <typename T>+ ASIO_STATIC_CONSTEXPR(bool,+ is_applicable_property_v = (+ is_executor<T>::value+ || conditional<+ is_executor<T>::value,+ false_type,+ is_sender<T>+ >::type::value+ || conditional<+ is_executor<T>::value,+ false_type,+ is_scheduler<T>+ >::type::value+ ));+# endif // defined(ASIO_NO_DEPRECATED) #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) - static constexpr bool is_requirable = true;- static constexpr bool is_preferable = true;+ ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);+ ASIO_STATIC_CONSTEXPR(bool, is_preferable = true); typedef mapping_t<I> polymorphic_query_result_type; - constexpr thread_t()+ ASIO_CONSTEXPR thread_t() { } @@ -481,75 +547,58 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T>- static constexpr+ static ASIO_CONSTEXPR typename query_static_constexpr_member<T>::result_type static_query()- noexcept(query_static_constexpr_member<T>::is_noexcept)+ ASIO_NOEXCEPT_IF((+ query_static_constexpr_member<T>::is_noexcept)) { return query_static_constexpr_member<T>::value(); } template <typename T>- static constexpr thread_t static_query(- enable_if_t<+ static ASIO_CONSTEXPR thread_t static_query(+ typename enable_if< !query_static_constexpr_member<T>::is_valid- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< !query_member<T>::is_valid- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< !traits::query_free<T, thread_t>::is_valid- >* = 0,- enable_if_t<- !can_query<T, new_thread_t<I>>::value- >* = 0,- enable_if_t<- !can_query<T, other_t<I>>::value- >* = 0) noexcept+ >::type* = 0,+ typename enable_if<+ !can_query<T, new_thread_t<I> >::value+ >::type* = 0,+ typename enable_if<+ !can_query<T, other_t<I> >::value+ >::type* = 0) ASIO_NOEXCEPT { return thread_t(); } template <typename E, typename T = decltype(thread_t::static_query<E>())>- static constexpr const T static_query_v+ static ASIO_CONSTEXPR const T static_query_v = thread_t::static_query<E>(); #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) - static constexpr mapping_t<I> value()+ static ASIO_CONSTEXPR mapping_t<I> value() { return thread_t(); } - friend constexpr bool operator==(const thread_t&, const thread_t&)- {- return true;- }-- friend constexpr bool operator!=(const thread_t&, const thread_t&)- {- return false;- }-- friend constexpr bool operator==(const thread_t&, const new_thread_t<I>&)- {- return false;- }-- friend constexpr bool operator!=(const thread_t&, const new_thread_t<I>&)+ friend ASIO_CONSTEXPR bool operator==(+ const thread_t&, const thread_t&) { return true; } - friend constexpr bool operator==(const thread_t&, const other_t<I>&)+ friend ASIO_CONSTEXPR bool operator!=(+ const thread_t&, const thread_t&) { return false; }-- friend constexpr bool operator!=(const thread_t&, const other_t<I>&)- {- return true;- } }; #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \@@ -563,15 +612,35 @@ struct new_thread_t { #if defined(ASIO_HAS_VARIABLE_TEMPLATES)+# if defined(ASIO_NO_DEPRECATED) template <typename T>- static constexpr bool is_applicable_property_v = is_executor<T>::value;+ ASIO_STATIC_CONSTEXPR(bool,+ is_applicable_property_v = (+ is_executor<T>::value));+# else // defined(ASIO_NO_DEPRECATED)+ template <typename T>+ ASIO_STATIC_CONSTEXPR(bool,+ is_applicable_property_v = (+ is_executor<T>::value+ || conditional<+ is_executor<T>::value,+ false_type,+ is_sender<T>+ >::type::value+ || conditional<+ is_executor<T>::value,+ false_type,+ is_scheduler<T>+ >::type::value+ ));+# endif // defined(ASIO_NO_DEPRECATED) #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) - static constexpr bool is_requirable = true;- static constexpr bool is_preferable = true;+ ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);+ ASIO_STATIC_CONSTEXPR(bool, is_preferable = true); typedef mapping_t<I> polymorphic_query_result_type; - constexpr new_thread_t()+ ASIO_CONSTEXPR new_thread_t() { } @@ -588,52 +657,37 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T>- static constexpr typename query_static_constexpr_member<T>::result_type+ static ASIO_CONSTEXPR+ typename query_static_constexpr_member<T>::result_type static_query()- noexcept(query_static_constexpr_member<T>::is_noexcept)+ ASIO_NOEXCEPT_IF((+ query_static_constexpr_member<T>::is_noexcept)) { return query_static_constexpr_member<T>::value(); } template <typename E, typename T = decltype(new_thread_t::static_query<E>())>- static constexpr const T static_query_v = new_thread_t::static_query<E>();+ static ASIO_CONSTEXPR const T static_query_v+ = new_thread_t::static_query<E>(); #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) - static constexpr mapping_t<I> value()+ static ASIO_CONSTEXPR mapping_t<I> value() { return new_thread_t(); } - friend constexpr bool operator==(const new_thread_t&, const new_thread_t&)- {- return true;- }-- friend constexpr bool operator!=(const new_thread_t&, const new_thread_t&)- {- return false;- }-- friend constexpr bool operator==(const new_thread_t&, const thread_t<I>&)- {- return false;- }-- friend constexpr bool operator!=(const new_thread_t&, const thread_t<I>&)+ friend ASIO_CONSTEXPR bool operator==(+ const new_thread_t&, const new_thread_t&) { return true; } - friend constexpr bool operator==(const new_thread_t&, const other_t<I>&)+ friend ASIO_CONSTEXPR bool operator!=(+ const new_thread_t&, const new_thread_t&) { return false; }-- friend constexpr bool operator!=(const new_thread_t&, const other_t<I>&)- {- return true;- } }; #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \@@ -647,15 +701,35 @@ struct other_t { #if defined(ASIO_HAS_VARIABLE_TEMPLATES)+# if defined(ASIO_NO_DEPRECATED) template <typename T>- static constexpr bool is_applicable_property_v = is_executor<T>::value;+ ASIO_STATIC_CONSTEXPR(bool,+ is_applicable_property_v = (+ is_executor<T>::value));+# else // defined(ASIO_NO_DEPRECATED)+ template <typename T>+ ASIO_STATIC_CONSTEXPR(bool,+ is_applicable_property_v = (+ is_executor<T>::value+ || conditional<+ is_executor<T>::value,+ false_type,+ is_sender<T>+ >::type::value+ || conditional<+ is_executor<T>::value,+ false_type,+ is_scheduler<T>+ >::type::value+ ));+# endif // defined(ASIO_NO_DEPRECATED) #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) - static constexpr bool is_requirable = true;- static constexpr bool is_preferable = true;+ ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);+ ASIO_STATIC_CONSTEXPR(bool, is_preferable = true); typedef mapping_t<I> polymorphic_query_result_type; - constexpr other_t()+ ASIO_CONSTEXPR other_t() { } @@ -672,53 +746,37 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T>- static constexpr+ static ASIO_CONSTEXPR typename query_static_constexpr_member<T>::result_type static_query()- noexcept(query_static_constexpr_member<T>::is_noexcept)+ ASIO_NOEXCEPT_IF((+ query_static_constexpr_member<T>::is_noexcept)) { return query_static_constexpr_member<T>::value(); } template <typename E, typename T = decltype(other_t::static_query<E>())>- static constexpr const T static_query_v = other_t::static_query<E>();+ static ASIO_CONSTEXPR const T static_query_v+ = other_t::static_query<E>(); #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) - static constexpr mapping_t<I> value()+ static ASIO_CONSTEXPR mapping_t<I> value() { return other_t(); } - friend constexpr bool operator==(const other_t&, const other_t&)- {- return true;- }-- friend constexpr bool operator!=(const other_t&, const other_t&)- {- return false;- }-- friend constexpr bool operator==(const other_t&, const thread_t<I>&)- {- return false;- }-- friend constexpr bool operator!=(const other_t&, const thread_t<I>&)+ friend ASIO_CONSTEXPR bool operator==(+ const other_t&, const other_t&) { return true; } - friend constexpr bool operator==(const other_t&, const new_thread_t<I>&)+ friend ASIO_CONSTEXPR bool operator!=(+ const other_t&, const other_t&) { return false; }-- friend constexpr bool operator!=(const other_t&, const new_thread_t<I>&)- {- return true;- } }; #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \@@ -733,7 +791,11 @@ typedef detail::mapping_t<> mapping_t; -ASIO_INLINE_VARIABLE constexpr mapping_t mapping;+#if defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)+constexpr mapping_t mapping;+#else // defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)+namespace { static const mapping_t& mapping = mapping_t::instance; }+#endif } // namespace execution @@ -741,25 +803,81 @@ template <typename T> struct is_applicable_property<T, execution::mapping_t>- : integral_constant<bool, execution::is_executor<T>::value>+ : integral_constant<bool,+ execution::is_executor<T>::value+#if !defined(ASIO_NO_DEPRECATED)+ || conditional<+ execution::is_executor<T>::value,+ false_type,+ execution::is_sender<T>+ >::type::value+ || conditional<+ execution::is_executor<T>::value,+ false_type,+ execution::is_scheduler<T>+ >::type::value+#endif // !defined(ASIO_NO_DEPRECATED)+ > { }; template <typename T> struct is_applicable_property<T, execution::mapping_t::thread_t>- : integral_constant<bool, execution::is_executor<T>::value>+ : integral_constant<bool,+ execution::is_executor<T>::value+#if !defined(ASIO_NO_DEPRECATED)+ || conditional<+ execution::is_executor<T>::value,+ false_type,+ execution::is_sender<T>+ >::type::value+ || conditional<+ execution::is_executor<T>::value,+ false_type,+ execution::is_scheduler<T>+ >::type::value+#endif // !defined(ASIO_NO_DEPRECATED)+ > { }; template <typename T> struct is_applicable_property<T, execution::mapping_t::new_thread_t>- : integral_constant<bool, execution::is_executor<T>::value>+ : integral_constant<bool,+ execution::is_executor<T>::value+#if !defined(ASIO_NO_DEPRECATED)+ || conditional<+ execution::is_executor<T>::value,+ false_type,+ execution::is_sender<T>+ >::type::value+ || conditional<+ execution::is_executor<T>::value,+ false_type,+ execution::is_scheduler<T>+ >::type::value+#endif // !defined(ASIO_NO_DEPRECATED)+ > { }; template <typename T> struct is_applicable_property<T, execution::mapping_t::other_t>- : integral_constant<bool, execution::is_executor<T>::value>+ : integral_constant<bool,+ execution::is_executor<T>::value+#if !defined(ASIO_NO_DEPRECATED)+ || conditional<+ execution::is_executor<T>::value,+ false_type,+ execution::is_sender<T>+ >::type::value+ || conditional<+ execution::is_executor<T>::value,+ false_type,+ execution::is_scheduler<T>+ >::type::value+#endif // !defined(ASIO_NO_DEPRECATED)+ > { }; @@ -771,42 +889,42 @@ template <typename T> struct query_free_default<T, execution::mapping_t,- enable_if_t<+ typename enable_if< can_query<T, execution::mapping_t::thread_t>::value- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept =- is_nothrow_query<T, execution::mapping_t::thread_t>::value;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+ (is_nothrow_query<T, execution::mapping_t::thread_t>::value)); typedef execution::mapping_t result_type; }; template <typename T> struct query_free_default<T, execution::mapping_t,- enable_if_t<+ typename enable_if< !can_query<T, execution::mapping_t::thread_t>::value && can_query<T, execution::mapping_t::new_thread_t>::value- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept =- is_nothrow_query<T, execution::mapping_t::new_thread_t>::value;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+ (is_nothrow_query<T, execution::mapping_t::new_thread_t>::value)); typedef execution::mapping_t result_type; }; template <typename T> struct query_free_default<T, execution::mapping_t,- enable_if_t<+ typename enable_if< !can_query<T, execution::mapping_t::thread_t>::value && !can_query<T, execution::mapping_t::new_thread_t>::value && can_query<T, execution::mapping_t::other_t>::value- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept =- is_nothrow_query<T, execution::mapping_t::other_t>::value;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+ (is_nothrow_query<T, execution::mapping_t::other_t>::value)); typedef execution::mapping_t result_type; };@@ -818,18 +936,18 @@ template <typename T> struct static_query<T, execution::mapping_t,- enable_if_t<+ typename enable_if< execution::detail::mapping_t<0>:: query_static_constexpr_member<T>::is_valid- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef typename execution::detail::mapping_t<0>:: query_static_constexpr_member<T>::result_type result_type; - static constexpr result_type value()+ static ASIO_CONSTEXPR result_type value() { return execution::detail::mapping_t<0>:: query_static_constexpr_member<T>::value();@@ -838,21 +956,21 @@ template <typename T> struct static_query<T, execution::mapping_t,- enable_if_t<+ typename enable_if< !execution::detail::mapping_t<0>:: query_static_constexpr_member<T>::is_valid && !execution::detail::mapping_t<0>:: query_member<T>::is_valid && traits::static_query<T, execution::mapping_t::thread_t>::is_valid- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef typename traits::static_query<T, execution::mapping_t::thread_t>::result_type result_type; - static constexpr result_type value()+ static ASIO_CONSTEXPR result_type value() { return traits::static_query<T, execution::mapping_t::thread_t>::value(); }@@ -860,22 +978,22 @@ template <typename T> struct static_query<T, execution::mapping_t,- enable_if_t<+ typename enable_if< !execution::detail::mapping_t<0>:: query_static_constexpr_member<T>::is_valid && !execution::detail::mapping_t<0>:: query_member<T>::is_valid && !traits::static_query<T, execution::mapping_t::thread_t>::is_valid && traits::static_query<T, execution::mapping_t::new_thread_t>::is_valid- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef typename traits::static_query<T, execution::mapping_t::new_thread_t>::result_type result_type; - static constexpr result_type value()+ static ASIO_CONSTEXPR result_type value() { return traits::static_query<T, execution::mapping_t::new_thread_t>::value(); }@@ -883,7 +1001,7 @@ template <typename T> struct static_query<T, execution::mapping_t,- enable_if_t<+ typename enable_if< !execution::detail::mapping_t<0>:: query_static_constexpr_member<T>::is_valid && !execution::detail::mapping_t<0>::@@ -891,15 +1009,15 @@ && !traits::static_query<T, execution::mapping_t::thread_t>::is_valid && !traits::static_query<T, execution::mapping_t::new_thread_t>::is_valid && traits::static_query<T, execution::mapping_t::other_t>::is_valid- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef typename traits::static_query<T, execution::mapping_t::other_t>::result_type result_type; - static constexpr result_type value()+ static ASIO_CONSTEXPR result_type value() { return traits::static_query<T, execution::mapping_t::other_t>::value(); }@@ -907,18 +1025,18 @@ template <typename T> struct static_query<T, execution::mapping_t::thread_t,- enable_if_t<+ typename enable_if< execution::detail::mapping::thread_t<0>:: query_static_constexpr_member<T>::is_valid- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef typename execution::detail::mapping::thread_t<0>:: query_static_constexpr_member<T>::result_type result_type; - static constexpr result_type value()+ static ASIO_CONSTEXPR result_type value() { return execution::detail::mapping::thread_t<0>:: query_static_constexpr_member<T>::value();@@ -927,7 +1045,7 @@ template <typename T> struct static_query<T, execution::mapping_t::thread_t,- enable_if_t<+ typename enable_if< !execution::detail::mapping::thread_t<0>:: query_static_constexpr_member<T>::is_valid && !execution::detail::mapping::thread_t<0>::@@ -935,14 +1053,14 @@ && !traits::query_free<T, execution::mapping_t::thread_t>::is_valid && !can_query<T, execution::mapping_t::new_thread_t>::value && !can_query<T, execution::mapping_t::other_t>::value- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef execution::mapping_t::thread_t result_type; - static constexpr result_type value()+ static ASIO_CONSTEXPR result_type value() { return result_type(); }@@ -950,18 +1068,18 @@ template <typename T> struct static_query<T, execution::mapping_t::new_thread_t,- enable_if_t<+ typename enable_if< execution::detail::mapping::new_thread_t<0>:: query_static_constexpr_member<T>::is_valid- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef typename execution::detail::mapping::new_thread_t<0>:: query_static_constexpr_member<T>::result_type result_type; - static constexpr result_type value()+ static ASIO_CONSTEXPR result_type value() { return execution::detail::mapping::new_thread_t<0>:: query_static_constexpr_member<T>::value();@@ -970,18 +1088,18 @@ template <typename T> struct static_query<T, execution::mapping_t::other_t,- enable_if_t<+ typename enable_if< execution::detail::mapping::other_t<0>:: query_static_constexpr_member<T>::is_valid- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef typename execution::detail::mapping::other_t<0>:: query_static_constexpr_member<T>::result_type result_type; - static constexpr result_type value()+ static ASIO_CONSTEXPR result_type value() { return execution::detail::mapping::other_t<0>:: query_static_constexpr_member<T>::value();@@ -990,6 +1108,46 @@ #endif // !defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // || !defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)++#if !defined(ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT)++template <typename T>+struct static_require<T, execution::mapping_t::thread_t,+ typename enable_if<+ static_query<T, execution::mapping_t::thread_t>::is_valid+ >::type>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid =+ (is_same<typename static_query<T,+ execution::mapping_t::thread_t>::result_type,+ execution::mapping_t::thread_t>::value));+};++template <typename T>+struct static_require<T, execution::mapping_t::new_thread_t,+ typename enable_if<+ static_query<T, execution::mapping_t::new_thread_t>::is_valid+ >::type>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid =+ (is_same<typename static_query<T,+ execution::mapping_t::new_thread_t>::result_type,+ execution::mapping_t::new_thread_t>::value));+};++template <typename T>+struct static_require<T, execution::mapping_t::other_t,+ typename enable_if<+ static_query<T, execution::mapping_t::other_t>::is_valid+ >::type>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid =+ (is_same<typename static_query<T,+ execution::mapping_t::other_t>::result_type,+ execution::mapping_t::other_t>::value));+};++#endif // !defined(ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT) } // namespace traits
link/modules/asio-standalone/asio/include/asio/execution/occupancy.hpp view
@@ -2,7 +2,7 @@ // execution/occupancy.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -18,6 +18,8 @@ #include "asio/detail/config.hpp" #include "asio/detail/type_traits.hpp" #include "asio/execution/executor.hpp"+#include "asio/execution/scheduler.hpp"+#include "asio/execution/sender.hpp" #include "asio/is_applicable_property.hpp" #include "asio/traits/query_static_constexpr_member.hpp" #include "asio/traits/static_query.hpp"@@ -34,9 +36,10 @@ /// should occupy the associated execution context. struct occupancy_t {- /// The occupancy_t property applies to executors.+ /// The occupancy_t property applies to executors, senders, and schedulers. template <typename T>- static constexpr bool is_applicable_property_v = is_executor_v<T>;+ static constexpr bool is_applicable_property_v =+ is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>; /// The occupancy_t property cannot be required. static constexpr bool is_requirable = false;@@ -62,15 +65,35 @@ struct occupancy_t { #if defined(ASIO_HAS_VARIABLE_TEMPLATES)+# if defined(ASIO_NO_DEPRECATED) template <typename T>- static constexpr bool is_applicable_property_v = is_executor<T>::value;+ ASIO_STATIC_CONSTEXPR(bool,+ is_applicable_property_v = (+ is_executor<T>::value));+# else // defined(ASIO_NO_DEPRECATED)+ template <typename T>+ ASIO_STATIC_CONSTEXPR(bool,+ is_applicable_property_v = (+ is_executor<T>::value+ || conditional<+ is_executor<T>::value,+ false_type,+ is_sender<T>+ >::type::value+ || conditional<+ is_executor<T>::value,+ false_type,+ is_scheduler<T>+ >::type::value+ ));+# endif // defined(ASIO_NO_DEPRECATED) #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) - static constexpr bool is_requirable = false;- static constexpr bool is_preferable = false;+ ASIO_STATIC_CONSTEXPR(bool, is_requirable = false);+ ASIO_STATIC_CONSTEXPR(bool, is_preferable = false); typedef std::size_t polymorphic_query_result_type; - constexpr occupancy_t()+ ASIO_CONSTEXPR occupancy_t() { } @@ -81,17 +104,17 @@ struct type { template <typename P>- static constexpr auto query(P&& p)+ static constexpr auto query(ASIO_MOVE_ARG(P) p) noexcept( noexcept(- conditional_t<true, T, P>::query(static_cast<P&&>(p))+ conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p)) ) ) -> decltype(- conditional_t<true, T, P>::query(static_cast<P&&>(p))+ conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p)) ) {- return T::query(static_cast<P&&>(p));+ return T::query(ASIO_MOVE_CAST(P)(p)); } }; #else // defined(ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)@@ -107,17 +130,24 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T>- static constexpr typename query_static_constexpr_member<T>::result_type+ static ASIO_CONSTEXPR+ typename query_static_constexpr_member<T>::result_type static_query()- noexcept(query_static_constexpr_member<T>::is_noexcept)+ ASIO_NOEXCEPT_IF((+ query_static_constexpr_member<T>::is_noexcept)) { return query_static_constexpr_member<T>::value(); } template <typename E, typename T = decltype(occupancy_t::static_query<E>())>- static constexpr const T static_query_v = occupancy_t::static_query<E>();+ static ASIO_CONSTEXPR const T static_query_v+ = occupancy_t::static_query<E>(); #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)++#if !defined(ASIO_HAS_CONSTEXPR)+ static const occupancy_t instance;+#endif // !defined(ASIO_HAS_CONSTEXPR) }; #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \@@ -127,11 +157,20 @@ #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) +#if !defined(ASIO_HAS_CONSTEXPR)+template <int I>+const occupancy_t<I> occupancy_t<I>::instance;+#endif+ } // namespace detail typedef detail::occupancy_t<> occupancy_t; -ASIO_INLINE_VARIABLE constexpr occupancy_t occupancy;+#if defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)+constexpr occupancy_t occupancy;+#else // defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)+namespace { static const occupancy_t& occupancy = occupancy_t::instance; }+#endif } // namespace execution @@ -139,7 +178,21 @@ template <typename T> struct is_applicable_property<T, execution::occupancy_t>- : integral_constant<bool, execution::is_executor<T>::value>+ : integral_constant<bool,+ execution::is_executor<T>::value+#if !defined(ASIO_NO_DEPRECATED)+ || conditional<+ execution::is_executor<T>::value,+ false_type,+ execution::is_sender<T>+ >::type::value+ || conditional<+ execution::is_executor<T>::value,+ false_type,+ execution::is_scheduler<T>+ >::type::value+#endif // !defined(ASIO_NO_DEPRECATED)+ > { }; @@ -152,18 +205,18 @@ template <typename T> struct static_query<T, execution::occupancy_t,- enable_if_t<+ typename enable_if< execution::detail::occupancy_t<0>:: query_static_constexpr_member<T>::is_valid- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef typename execution::detail::occupancy_t<0>:: query_static_constexpr_member<T>::result_type result_type; - static constexpr result_type value()+ static ASIO_CONSTEXPR result_type value() { return execution::detail::occupancy_t<0>:: query_static_constexpr_member<T>::value();
+ link/modules/asio-standalone/asio/include/asio/execution/operation_state.hpp view
@@ -0,0 +1,99 @@+//+// execution/operation_state.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_EXECUTION_OPERATION_STATE_HPP+#define ASIO_EXECUTION_OPERATION_STATE_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"++#if !defined(ASIO_NO_DEPRECATED)++#include "asio/detail/type_traits.hpp"+#include "asio/execution/start.hpp"++#if defined(ASIO_HAS_DEDUCED_START_FREE_TRAIT) \+ && defined(ASIO_HAS_DEDUCED_START_MEMBER_TRAIT)+# define ASIO_HAS_DEDUCED_EXECUTION_IS_OPERATION_STATE_TRAIT 1+#endif // defined(ASIO_HAS_DEDUCED_START_FREE_TRAIT)+ // && defined(ASIO_HAS_DEDUCED_START_MEMBER_TRAIT)++#include "asio/detail/push_options.hpp"++namespace asio {+namespace execution {+namespace detail {++template <typename T>+struct is_operation_state_base :+ integral_constant<bool,+ is_destructible<T>::value+ && is_object<T>::value+ >+{+};++} // namespace detail++/// The is_operation_state trait detects whether a type T satisfies the+/// execution::operation_state concept.+/**+ * Class template @c is_operation_state is a type trait that is derived from+ * @c true_type if the type @c T meets the concept definition for an+ * @c operation_state, otherwise @c false_type.+ */+template <typename T>+struct is_operation_state :+#if defined(GENERATING_DOCUMENTATION)+ integral_constant<bool, automatically_determined>+#else // defined(GENERATING_DOCUMENTATION)+ conditional<+ can_start<typename add_lvalue_reference<T>::type>::value+ && is_nothrow_start<typename add_lvalue_reference<T>::type>::value,+ detail::is_operation_state_base<T>,+ false_type+ >::type+#endif // defined(GENERATING_DOCUMENTATION)+{+};++#if defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename T>+ASIO_CONSTEXPR const bool is_operation_state_v =+ is_operation_state<T>::value;++#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++#if defined(ASIO_HAS_CONCEPTS)++template <typename T>+ASIO_CONCEPT operation_state = is_operation_state<T>::value;++#define ASIO_EXECUTION_OPERATION_STATE \+ ::asio::execution::operation_state++#else // defined(ASIO_HAS_CONCEPTS)++#define ASIO_EXECUTION_OPERATION_STATE typename++#endif // defined(ASIO_HAS_CONCEPTS)++} // namespace execution+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // !defined(ASIO_NO_DEPRECATED)++#endif // ASIO_EXECUTION_OPERATION_STATE_HPP
link/modules/asio-standalone/asio/include/asio/execution/outstanding_work.hpp view
@@ -2,7 +2,7 @@ // execution/outstanding_work.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -18,6 +18,8 @@ #include "asio/detail/config.hpp" #include "asio/detail/type_traits.hpp" #include "asio/execution/executor.hpp"+#include "asio/execution/scheduler.hpp"+#include "asio/execution/sender.hpp" #include "asio/is_applicable_property.hpp" #include "asio/query.hpp" #include "asio/traits/query_free.hpp"@@ -37,9 +39,11 @@ /// A property to describe whether task submission is likely in the future. struct outstanding_work_t {- /// The outstanding_work_t property applies to executors.+ /// The outstanding_work_t property applies to executors, senders, and+ /// schedulers. template <typename T>- static constexpr bool is_applicable_property_v = is_executor_v<T>;+ static constexpr bool is_applicable_property_v =+ is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>; /// The top-level outstanding_work_t property cannot be required. static constexpr bool is_requirable = false;@@ -54,9 +58,11 @@ /// future submission of a function object. struct untracked_t {- /// The outstanding_work_t::untracked_t property applies to executors.+ /// The outstanding_work_t::untracked_t property applies to executors,+ /// senders, and schedulers. template <typename T>- static constexpr bool is_applicable_property_v = is_executor_v<T>;+ static constexpr bool is_applicable_property_v =+ is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>; /// The outstanding_work_t::untracked_t property can be required. static constexpr bool is_requirable = true;@@ -81,9 +87,11 @@ /// future submission of a function object. struct tracked_t {- /// The outstanding_work_t::untracked_t property applies to executors.+ /// The outstanding_work_t::untracked_t property applies to executors,+ /// senders, and schedulers. template <typename T>- static constexpr bool is_applicable_property_v = is_executor_v<T>;+ static constexpr bool is_applicable_property_v =+ is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>; /// The outstanding_work_t::tracked_t property can be required. static constexpr bool is_requirable = true;@@ -150,28 +158,48 @@ struct outstanding_work_t { #if defined(ASIO_HAS_VARIABLE_TEMPLATES)+# if defined(ASIO_NO_DEPRECATED) template <typename T>- static constexpr bool is_applicable_property_v = is_executor<T>::value;+ ASIO_STATIC_CONSTEXPR(bool,+ is_applicable_property_v = (+ is_executor<T>::value));+# else // defined(ASIO_NO_DEPRECATED)+ template <typename T>+ ASIO_STATIC_CONSTEXPR(bool,+ is_applicable_property_v = (+ is_executor<T>::value+ || conditional<+ is_executor<T>::value,+ false_type,+ is_sender<T>+ >::type::value+ || conditional<+ is_executor<T>::value,+ false_type,+ is_scheduler<T>+ >::type::value+ ));+# endif // defined(ASIO_NO_DEPRECATED) #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) - static constexpr bool is_requirable = false;- static constexpr bool is_preferable = false;+ ASIO_STATIC_CONSTEXPR(bool, is_requirable = false);+ ASIO_STATIC_CONSTEXPR(bool, is_preferable = false); typedef outstanding_work_t polymorphic_query_result_type; typedef detail::outstanding_work::untracked_t<I> untracked_t; typedef detail::outstanding_work::tracked_t<I> tracked_t; - constexpr outstanding_work_t()+ ASIO_CONSTEXPR outstanding_work_t() : value_(-1) { } - constexpr outstanding_work_t(untracked_t)+ ASIO_CONSTEXPR outstanding_work_t(untracked_t) : value_(0) { } - constexpr outstanding_work_t(tracked_t)+ ASIO_CONSTEXPR outstanding_work_t(tracked_t) : value_(1) { }@@ -183,14 +211,16 @@ struct type { template <typename P>- auto query(P&& p) const+ auto query(ASIO_MOVE_ARG(P) p) const noexcept( noexcept(- declval<conditional_t<true, T, P>>().query(static_cast<P&&>(p))+ declval<typename conditional<true, T, P>::type>().query(+ ASIO_MOVE_CAST(P)(p)) ) ) -> decltype(- declval<conditional_t<true, T, P>>().query(static_cast<P&&>(p))+ declval<typename conditional<true, T, P>::type>().query(+ ASIO_MOVE_CAST(P)(p)) ); }; #else // defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)@@ -205,17 +235,17 @@ struct type { template <typename P>- static constexpr auto query(P&& p)+ static constexpr auto query(ASIO_MOVE_ARG(P) p) noexcept( noexcept(- conditional_t<true, T, P>::query(static_cast<P&&>(p))+ conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p)) ) ) -> decltype(- conditional_t<true, T, P>::query(static_cast<P&&>(p))+ conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p)) ) {- return T::query(static_cast<P&&>(p));+ return T::query(ASIO_MOVE_CAST(P)(p)); } }; #else // defined(ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)@@ -235,65 +265,66 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T>- static constexpr+ static ASIO_CONSTEXPR typename query_static_constexpr_member<T>::result_type static_query()- noexcept(query_static_constexpr_member<T>::is_noexcept)+ ASIO_NOEXCEPT_IF((+ query_static_constexpr_member<T>::is_noexcept)) { return query_static_constexpr_member<T>::value(); } template <typename T>- static constexpr+ static ASIO_CONSTEXPR typename traits::static_query<T, untracked_t>::result_type static_query(- enable_if_t<+ typename enable_if< !query_static_constexpr_member<T>::is_valid- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< !query_member<T>::is_valid- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< traits::static_query<T, untracked_t>::is_valid- >* = 0) noexcept+ >::type* = 0) ASIO_NOEXCEPT { return traits::static_query<T, untracked_t>::value(); } template <typename T>- static constexpr+ static ASIO_CONSTEXPR typename traits::static_query<T, tracked_t>::result_type static_query(- enable_if_t<+ typename enable_if< !query_static_constexpr_member<T>::is_valid- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< !query_member<T>::is_valid- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< !traits::static_query<T, untracked_t>::is_valid- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< traits::static_query<T, tracked_t>::is_valid- >* = 0) noexcept+ >::type* = 0) ASIO_NOEXCEPT { return traits::static_query<T, tracked_t>::value(); } template <typename E, typename T = decltype(outstanding_work_t::static_query<E>())>- static constexpr const T static_query_v+ static ASIO_CONSTEXPR const T static_query_v = outstanding_work_t::static_query<E>(); #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) - friend constexpr bool operator==(+ friend ASIO_CONSTEXPR bool operator==( const outstanding_work_t& a, const outstanding_work_t& b) { return a.value_ == b.value_; } - friend constexpr bool operator!=(+ friend ASIO_CONSTEXPR bool operator!=( const outstanding_work_t& a, const outstanding_work_t& b) { return a.value_ != b.value_;@@ -301,23 +332,25 @@ struct convertible_from_outstanding_work_t {- constexpr convertible_from_outstanding_work_t(outstanding_work_t)+ ASIO_CONSTEXPR convertible_from_outstanding_work_t(outstanding_work_t) { } }; template <typename Executor>- friend constexpr outstanding_work_t query(+ friend ASIO_CONSTEXPR outstanding_work_t query( const Executor& ex, convertible_from_outstanding_work_t,- enable_if_t<+ typename enable_if< can_query<const Executor&, untracked_t>::value- >* = 0)+ >::type* = 0) #if !defined(__clang__) // Clang crashes if noexcept is used here. #if defined(ASIO_MSVC) // Visual C++ wants the type to be qualified.- noexcept(is_nothrow_query<const Executor&,- outstanding_work_t<>::untracked_t>::value)+ ASIO_NOEXCEPT_IF((+ is_nothrow_query<const Executor&,+ outstanding_work_t<>::untracked_t>::value)) #else // defined(ASIO_MSVC)- noexcept(is_nothrow_query<const Executor&, untracked_t>::value)+ ASIO_NOEXCEPT_IF((+ is_nothrow_query<const Executor&, untracked_t>::value)) #endif // defined(ASIO_MSVC) #endif // !defined(__clang__) {@@ -325,20 +358,22 @@ } template <typename Executor>- friend constexpr outstanding_work_t query(+ friend ASIO_CONSTEXPR outstanding_work_t query( const Executor& ex, convertible_from_outstanding_work_t,- enable_if_t<+ typename enable_if< !can_query<const Executor&, untracked_t>::value- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< can_query<const Executor&, tracked_t>::value- >* = 0)+ >::type* = 0) #if !defined(__clang__) // Clang crashes if noexcept is used here. #if defined(ASIO_MSVC) // Visual C++ wants the type to be qualified.- noexcept(is_nothrow_query<const Executor&,- outstanding_work_t<>::tracked_t>::value)+ ASIO_NOEXCEPT_IF((+ is_nothrow_query<const Executor&,+ outstanding_work_t<>::tracked_t>::value)) #else // defined(ASIO_MSVC)- noexcept(is_nothrow_query<const Executor&, tracked_t>::value)+ ASIO_NOEXCEPT_IF((+ is_nothrow_query<const Executor&, tracked_t>::value)) #endif // defined(ASIO_MSVC) #endif // !defined(__clang__) {@@ -348,6 +383,10 @@ ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(untracked_t, untracked); ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(tracked_t, tracked); +#if !defined(ASIO_HAS_CONSTEXPR)+ static const outstanding_work_t instance;+#endif // !defined(ASIO_HAS_CONSTEXPR)+ private: int value_; };@@ -359,7 +398,12 @@ #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) +#if !defined(ASIO_HAS_CONSTEXPR) template <int I>+const outstanding_work_t<I> outstanding_work_t<I>::instance;+#endif++template <int I> const typename outstanding_work_t<I>::untracked_t outstanding_work_t<I>::untracked; @@ -373,15 +417,35 @@ struct untracked_t { #if defined(ASIO_HAS_VARIABLE_TEMPLATES)+# if defined(ASIO_NO_DEPRECATED) template <typename T>- static constexpr bool is_applicable_property_v = is_executor<T>::value;+ ASIO_STATIC_CONSTEXPR(bool,+ is_applicable_property_v = (+ is_executor<T>::value));+# else // defined(ASIO_NO_DEPRECATED)+ template <typename T>+ ASIO_STATIC_CONSTEXPR(bool,+ is_applicable_property_v = (+ is_executor<T>::value+ || conditional<+ is_executor<T>::value,+ false_type,+ is_sender<T>+ >::type::value+ || conditional<+ is_executor<T>::value,+ false_type,+ is_scheduler<T>+ >::type::value+ ));+# endif // defined(ASIO_NO_DEPRECATED) #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) - static constexpr bool is_requirable = true;- static constexpr bool is_preferable = true;+ ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);+ ASIO_STATIC_CONSTEXPR(bool, is_preferable = true); typedef outstanding_work_t<I> polymorphic_query_result_type; - constexpr untracked_t()+ ASIO_CONSTEXPR untracked_t() { } @@ -399,61 +463,55 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T>- static constexpr+ static ASIO_CONSTEXPR typename query_static_constexpr_member<T>::result_type static_query()- noexcept(query_static_constexpr_member<T>::is_noexcept)+ ASIO_NOEXCEPT_IF((+ query_static_constexpr_member<T>::is_noexcept)) { return query_static_constexpr_member<T>::value(); } template <typename T>- static constexpr untracked_t static_query(- enable_if_t<+ static ASIO_CONSTEXPR untracked_t static_query(+ typename enable_if< !query_static_constexpr_member<T>::is_valid- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< !query_member<T>::is_valid- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< !traits::query_free<T, untracked_t>::is_valid- >* = 0,- enable_if_t<- !can_query<T, tracked_t<I>>::value- >* = 0) noexcept+ >::type* = 0,+ typename enable_if<+ !can_query<T, tracked_t<I> >::value+ >::type* = 0) ASIO_NOEXCEPT { return untracked_t(); } template <typename E, typename T = decltype(untracked_t::static_query<E>())>- static constexpr const T static_query_v = untracked_t::static_query<E>();+ static ASIO_CONSTEXPR const T static_query_v+ = untracked_t::static_query<E>(); #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) - static constexpr outstanding_work_t<I> value()+ static ASIO_CONSTEXPR outstanding_work_t<I> value() { return untracked_t(); } - friend constexpr bool operator==(const untracked_t&, const untracked_t&)+ friend ASIO_CONSTEXPR bool operator==(+ const untracked_t&, const untracked_t&) { return true; } - friend constexpr bool operator!=(const untracked_t&, const untracked_t&)- {- return false;- }-- friend constexpr bool operator==(const untracked_t&, const tracked_t<I>&)+ friend ASIO_CONSTEXPR bool operator!=(+ const untracked_t&, const untracked_t&) { return false; }-- friend constexpr bool operator!=(const untracked_t&, const tracked_t<I>&)- {- return true;- } }; #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \@@ -467,15 +525,35 @@ struct tracked_t { #if defined(ASIO_HAS_VARIABLE_TEMPLATES)+# if defined(ASIO_NO_DEPRECATED) template <typename T>- static constexpr bool is_applicable_property_v = is_executor<T>::value;+ ASIO_STATIC_CONSTEXPR(bool,+ is_applicable_property_v = (+ is_executor<T>::value));+# else // defined(ASIO_NO_DEPRECATED)+ template <typename T>+ ASIO_STATIC_CONSTEXPR(bool,+ is_applicable_property_v = (+ is_executor<T>::value+ || conditional<+ is_executor<T>::value,+ false_type,+ is_sender<T>+ >::type::value+ || conditional<+ is_executor<T>::value,+ false_type,+ is_scheduler<T>+ >::type::value+ ));+# endif // defined(ASIO_NO_DEPRECATED) #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) - static constexpr bool is_requirable = true;- static constexpr bool is_preferable = true;+ ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);+ ASIO_STATIC_CONSTEXPR(bool, is_preferable = true); typedef outstanding_work_t<I> polymorphic_query_result_type; - constexpr tracked_t()+ ASIO_CONSTEXPR tracked_t() { } @@ -493,43 +571,37 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T>- static constexpr+ static ASIO_CONSTEXPR typename query_static_constexpr_member<T>::result_type static_query()- noexcept(query_static_constexpr_member<T>::is_noexcept)+ ASIO_NOEXCEPT_IF((+ query_static_constexpr_member<T>::is_noexcept)) { return query_static_constexpr_member<T>::value(); } template <typename E, typename T = decltype(tracked_t::static_query<E>())>- static constexpr const T static_query_v = tracked_t::static_query<E>();+ static ASIO_CONSTEXPR const T static_query_v+ = tracked_t::static_query<E>(); #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) - static constexpr outstanding_work_t<I> value()+ static ASIO_CONSTEXPR outstanding_work_t<I> value() { return tracked_t(); } - friend constexpr bool operator==(const tracked_t&, const tracked_t&)+ friend ASIO_CONSTEXPR bool operator==(+ const tracked_t&, const tracked_t&) { return true; } - friend constexpr bool operator!=(const tracked_t&, const tracked_t&)- {- return false;- }-- friend constexpr bool operator==(const tracked_t&, const untracked_t<I>&)+ friend ASIO_CONSTEXPR bool operator!=(+ const tracked_t&, const tracked_t&) { return false; }-- friend constexpr bool operator!=(const tracked_t&, const untracked_t<I>&)- {- return true;- } }; #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \@@ -544,7 +616,12 @@ typedef detail::outstanding_work_t<> outstanding_work_t; -ASIO_INLINE_VARIABLE constexpr outstanding_work_t outstanding_work;+#if defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)+constexpr outstanding_work_t outstanding_work;+#else // defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)+namespace { static const outstanding_work_t&+ outstanding_work = outstanding_work_t::instance; }+#endif } // namespace execution @@ -552,19 +629,61 @@ template <typename T> struct is_applicable_property<T, execution::outstanding_work_t>- : integral_constant<bool, execution::is_executor<T>::value>+ : integral_constant<bool,+ execution::is_executor<T>::value+#if !defined(ASIO_NO_DEPRECATED)+ || conditional<+ execution::is_executor<T>::value,+ false_type,+ execution::is_sender<T>+ >::type::value+ || conditional<+ execution::is_executor<T>::value,+ false_type,+ execution::is_scheduler<T>+ >::type::value+#endif // !defined(ASIO_NO_DEPRECATED)+ > { }; template <typename T> struct is_applicable_property<T, execution::outstanding_work_t::untracked_t>- : integral_constant<bool, execution::is_executor<T>::value>+ : integral_constant<bool,+ execution::is_executor<T>::value+#if !defined(ASIO_NO_DEPRECATED)+ || conditional<+ execution::is_executor<T>::value,+ false_type,+ execution::is_sender<T>+ >::type::value+ || conditional<+ execution::is_executor<T>::value,+ false_type,+ execution::is_scheduler<T>+ >::type::value+#endif // !defined(ASIO_NO_DEPRECATED)+ > { }; template <typename T> struct is_applicable_property<T, execution::outstanding_work_t::tracked_t>- : integral_constant<bool, execution::is_executor<T>::value>+ : integral_constant<bool,+ execution::is_executor<T>::value+#if !defined(ASIO_NO_DEPRECATED)+ || conditional<+ execution::is_executor<T>::value,+ false_type,+ execution::is_sender<T>+ >::type::value+ || conditional<+ execution::is_executor<T>::value,+ false_type,+ execution::is_scheduler<T>+ >::type::value+#endif // !defined(ASIO_NO_DEPRECATED)+ > { }; @@ -576,27 +695,27 @@ template <typename T> struct query_free_default<T, execution::outstanding_work_t,- enable_if_t<+ typename enable_if< can_query<T, execution::outstanding_work_t::untracked_t>::value- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept =- is_nothrow_query<T, execution::outstanding_work_t::untracked_t>::value;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+ (is_nothrow_query<T, execution::outstanding_work_t::untracked_t>::value)); typedef execution::outstanding_work_t result_type; }; template <typename T> struct query_free_default<T, execution::outstanding_work_t,- enable_if_t<+ typename enable_if< !can_query<T, execution::outstanding_work_t::untracked_t>::value && can_query<T, execution::outstanding_work_t::tracked_t>::value- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept =- is_nothrow_query<T, execution::outstanding_work_t::tracked_t>::value;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+ (is_nothrow_query<T, execution::outstanding_work_t::tracked_t>::value)); typedef execution::outstanding_work_t result_type; };@@ -608,18 +727,18 @@ template <typename T> struct static_query<T, execution::outstanding_work_t,- enable_if_t<+ typename enable_if< execution::detail::outstanding_work_t<0>:: query_static_constexpr_member<T>::is_valid- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef typename execution::detail::outstanding_work_t<0>:: query_static_constexpr_member<T>::result_type result_type; - static constexpr result_type value()+ static ASIO_CONSTEXPR result_type value() { return execution::detail::outstanding_work_t<0>:: query_static_constexpr_member<T>::value();@@ -628,22 +747,22 @@ template <typename T> struct static_query<T, execution::outstanding_work_t,- enable_if_t<+ typename enable_if< !execution::detail::outstanding_work_t<0>:: query_static_constexpr_member<T>::is_valid && !execution::detail::outstanding_work_t<0>:: query_member<T>::is_valid && traits::static_query<T, execution::outstanding_work_t::untracked_t>::is_valid- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef typename traits::static_query<T, execution::outstanding_work_t::untracked_t>::result_type result_type; - static constexpr result_type value()+ static ASIO_CONSTEXPR result_type value() { return traits::static_query<T, execution::outstanding_work_t::untracked_t>::value();@@ -652,7 +771,7 @@ template <typename T> struct static_query<T, execution::outstanding_work_t,- enable_if_t<+ typename enable_if< !execution::detail::outstanding_work_t<0>:: query_static_constexpr_member<T>::is_valid && !execution::detail::outstanding_work_t<0>::@@ -661,15 +780,15 @@ execution::outstanding_work_t::untracked_t>::is_valid && traits::static_query<T, execution::outstanding_work_t::tracked_t>::is_valid- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef typename traits::static_query<T, execution::outstanding_work_t::tracked_t>::result_type result_type; - static constexpr result_type value()+ static ASIO_CONSTEXPR result_type value() { return traits::static_query<T, execution::outstanding_work_t::tracked_t>::value();@@ -678,18 +797,18 @@ template <typename T> struct static_query<T, execution::outstanding_work_t::untracked_t,- enable_if_t<+ typename enable_if< execution::detail::outstanding_work::untracked_t<0>:: query_static_constexpr_member<T>::is_valid- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef typename execution::detail::outstanding_work::untracked_t<0>:: query_static_constexpr_member<T>::result_type result_type; - static constexpr result_type value()+ static ASIO_CONSTEXPR result_type value() { return execution::detail::outstanding_work::untracked_t<0>:: query_static_constexpr_member<T>::value();@@ -698,7 +817,7 @@ template <typename T> struct static_query<T, execution::outstanding_work_t::untracked_t,- enable_if_t<+ typename enable_if< !execution::detail::outstanding_work::untracked_t<0>:: query_static_constexpr_member<T>::is_valid && !execution::detail::outstanding_work::untracked_t<0>::@@ -706,14 +825,14 @@ && !traits::query_free<T, execution::outstanding_work_t::untracked_t>::is_valid && !can_query<T, execution::outstanding_work_t::tracked_t>::value- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef execution::outstanding_work_t::untracked_t result_type; - static constexpr result_type value()+ static ASIO_CONSTEXPR result_type value() { return result_type(); }@@ -721,18 +840,18 @@ template <typename T> struct static_query<T, execution::outstanding_work_t::tracked_t,- enable_if_t<+ typename enable_if< execution::detail::outstanding_work::tracked_t<0>:: query_static_constexpr_member<T>::is_valid- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef typename execution::detail::outstanding_work::tracked_t<0>:: query_static_constexpr_member<T>::result_type result_type; - static constexpr result_type value()+ static ASIO_CONSTEXPR result_type value() { return execution::detail::outstanding_work::tracked_t<0>:: query_static_constexpr_member<T>::value();@@ -741,6 +860,34 @@ #endif // !defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // || !defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)++#if !defined(ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT)++template <typename T>+struct static_require<T, execution::outstanding_work_t::untracked_t,+ typename enable_if<+ static_query<T, execution::outstanding_work_t::untracked_t>::is_valid+ >::type>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid =+ (is_same<typename static_query<T,+ execution::outstanding_work_t::untracked_t>::result_type,+ execution::outstanding_work_t::untracked_t>::value));+};++template <typename T>+struct static_require<T, execution::outstanding_work_t::tracked_t,+ typename enable_if<+ static_query<T, execution::outstanding_work_t::tracked_t>::is_valid+ >::type>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid =+ (is_same<typename static_query<T,+ execution::outstanding_work_t::tracked_t>::result_type,+ execution::outstanding_work_t::tracked_t>::value));+};++#endif // !defined(ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT) } // namespace traits
link/modules/asio-standalone/asio/include/asio/execution/prefer_only.hpp view
@@ -2,7 +2,7 @@ // execution/prefer_only.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -65,17 +65,16 @@ template <typename InnerProperty, typename = void> struct prefer_only_is_preferable {- static constexpr bool is_preferable = false;+ ASIO_STATIC_CONSTEXPR(bool, is_preferable = false); }; template <typename InnerProperty> struct prefer_only_is_preferable<InnerProperty,- enable_if_t<+ typename enable_if< InnerProperty::is_preferable- >- >+ >::type> {- static constexpr bool is_preferable = true;+ ASIO_STATIC_CONSTEXPR(bool, is_preferable = true); }; template <typename InnerProperty, typename = void>@@ -85,10 +84,9 @@ template <typename InnerProperty> struct prefer_only_polymorphic_query_result_type<InnerProperty,- void_t<+ typename void_type< typename InnerProperty::polymorphic_query_result_type- >- >+ >::type> { typedef typename InnerProperty::polymorphic_query_result_type polymorphic_query_result_type;@@ -105,14 +103,14 @@ } }; -#if defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#if defined(ASIO_HAS_DECLTYPE) \+ && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) template <typename InnerProperty> struct prefer_only_property<InnerProperty,- void_t<+ typename void_type< decltype(asio::declval<const InnerProperty>().value())- >- >+ >::type> { InnerProperty property; @@ -121,15 +119,17 @@ { } - constexpr auto value() const- noexcept(noexcept(asio::declval<const InnerProperty>().value()))+ ASIO_CONSTEXPR auto value() const+ ASIO_NOEXCEPT_IF((+ noexcept(asio::declval<const InnerProperty>().value()))) -> decltype(asio::declval<const InnerProperty>().value()) { return property.value(); } }; -#else // defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#else // defined(ASIO_HAS_DECLTYPE)+ // && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) struct prefer_only_memfns_base {@@ -158,12 +158,11 @@ template <typename InnerProperty> struct prefer_only_property<InnerProperty,- enable_if_t<+ typename enable_if< sizeof(prefer_only_value_memfn_helper<InnerProperty>(0)) != 1 && !is_same<typename InnerProperty::polymorphic_query_result_type, void>::value- >- >+ >::type> { InnerProperty property; @@ -172,14 +171,15 @@ { } - constexpr typename InnerProperty::polymorphic_query_result_type+ ASIO_CONSTEXPR typename InnerProperty::polymorphic_query_result_type value() const { return property.value(); } }; -#endif // defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#endif // defined(ASIO_HAS_DECLTYPE)+ // && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) } // namespace detail @@ -189,9 +189,9 @@ detail::prefer_only_polymorphic_query_result_type<InnerProperty>, detail::prefer_only_property<InnerProperty> {- static constexpr bool is_requirable = false;+ ASIO_STATIC_CONSTEXPR(bool, is_requirable = false); - constexpr prefer_only(const InnerProperty& p)+ ASIO_CONSTEXPR prefer_only(const InnerProperty& p) : detail::prefer_only_property<InnerProperty>(p) { }@@ -199,33 +199,35 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T>- static constexpr+ static ASIO_CONSTEXPR typename traits::static_query<T, InnerProperty>::result_type static_query()- noexcept(traits::static_query<T, InnerProperty>::is_noexcept)+ ASIO_NOEXCEPT_IF((+ traits::static_query<T, InnerProperty>::is_noexcept)) { return traits::static_query<T, InnerProperty>::value(); } template <typename E, typename T = decltype(prefer_only::static_query<E>())>- static constexpr const T static_query_v+ static ASIO_CONSTEXPR const T static_query_v = prefer_only::static_query<E>(); #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename Executor, typename Property>- friend constexpr- prefer_result_t<const Executor&, const InnerProperty&>+ friend ASIO_CONSTEXPR+ typename prefer_result<const Executor&, const InnerProperty&>::type prefer(const Executor& ex, const prefer_only<Property>& p,- enable_if_t<+ typename enable_if< is_same<Property, InnerProperty>::value- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< can_prefer<const Executor&, const InnerProperty&>::value- >* = 0)+ >::type* = 0) #if !defined(ASIO_MSVC) \ && !defined(__clang__) // Clang crashes if noexcept is used here.- noexcept(is_nothrow_prefer<const Executor&, const InnerProperty&>::value)+ ASIO_NOEXCEPT_IF((+ is_nothrow_prefer<const Executor&, const InnerProperty&>::value)) #endif // !defined(ASIO_MSVC) // && !defined(__clang__) {@@ -233,18 +235,19 @@ } template <typename Executor, typename Property>- friend constexpr- query_result_t<const Executor&, const InnerProperty&>+ friend ASIO_CONSTEXPR+ typename query_result<const Executor&, const InnerProperty&>::type query(const Executor& ex, const prefer_only<Property>& p,- enable_if_t<+ typename enable_if< is_same<Property, InnerProperty>::value- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< can_query<const Executor&, const InnerProperty&>::value- >* = 0)+ >::type* = 0) #if !defined(ASIO_MSVC) \ && !defined(__clang__) // Clang crashes if noexcept is used here.- noexcept(is_nothrow_query<const Executor&, const InnerProperty&>::value)+ ASIO_NOEXCEPT_IF((+ is_nothrow_query<const Executor&, const InnerProperty&>::value)) #endif // !defined(ASIO_MSVC) // && !defined(__clang__) {@@ -262,7 +265,7 @@ } // namespace execution template <typename T, typename InnerProperty>-struct is_applicable_property<T, execution::prefer_only<InnerProperty>>+struct is_applicable_property<T, execution::prefer_only<InnerProperty> > : is_applicable_property<T, InnerProperty> { };@@ -273,7 +276,7 @@ || !defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T, typename InnerProperty>-struct static_query<T, execution::prefer_only<InnerProperty>> :+struct static_query<T, execution::prefer_only<InnerProperty> > : static_query<T, const InnerProperty&> { };@@ -285,16 +288,16 @@ template <typename T, typename InnerProperty> struct prefer_free_default<T, execution::prefer_only<InnerProperty>,- enable_if_t<+ typename enable_if< can_prefer<const T&, const InnerProperty&>::value- >- >+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept =- is_nothrow_prefer<const T&, const InnerProperty&>::value;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+ (is_nothrow_prefer<const T&, const InnerProperty&>::value)); - typedef prefer_result_t<const T&, const InnerProperty&> result_type;+ typedef typename prefer_result<const T&,+ const InnerProperty&>::type result_type; }; #endif // !defined(ASIO_HAS_DEDUCED_PREFER_FREE_TRAIT)@@ -303,16 +306,16 @@ template <typename T, typename InnerProperty> struct query_free<T, execution::prefer_only<InnerProperty>,- enable_if_t<+ typename enable_if< can_query<const T&, const InnerProperty&>::value- >- >+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept =- is_nothrow_query<const T&, const InnerProperty&>::value;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+ (is_nothrow_query<const T&, const InnerProperty&>::value)); - typedef query_result_t<const T&, const InnerProperty&> result_type;+ typedef typename query_result<const T&,+ const InnerProperty&>::type result_type; }; #endif // !defined(ASIO_HAS_DEDUCED_QUERY_FREE_TRAIT)
+ link/modules/asio-standalone/asio/include/asio/execution/receiver.hpp view
@@ -0,0 +1,285 @@+//+// execution/receiver.hpp+// ~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_EXECUTION_RECEIVER_HPP+#define ASIO_EXECUTION_RECEIVER_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"++#if !defined(ASIO_NO_DEPRECATED)++#include "asio/detail/type_traits.hpp"+#include "asio/detail/variadic_templates.hpp"+#include "asio/execution/set_done.hpp"+#include "asio/execution/set_error.hpp"+#include "asio/execution/set_value.hpp"++#if defined(ASIO_HAS_STD_EXCEPTION_PTR)+# include <exception>+#else // defined(ASIO_HAS_STD_EXCEPTION_PTR)+# include "asio/error_code.hpp"+#endif // defined(ASIO_HAS_STD_EXCEPTION_PTR)++#if defined(ASIO_HAS_DEDUCED_SET_DONE_FREE_TRAIT) \+ && defined(ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT) \+ && defined(ASIO_HAS_DEDUCED_SET_ERROR_FREE_TRAIT) \+ && defined(ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT) \+ && defined(ASIO_HAS_DEDUCED_SET_VALUE_FREE_TRAIT) \+ && defined(ASIO_HAS_DEDUCED_SET_VALUE_MEMBER_TRAIT) \+ && defined(ASIO_HAS_DEDUCED_RECEIVER_OF_FREE_TRAIT) \+ && defined(ASIO_HAS_DEDUCED_RECEIVER_OF_MEMBER_TRAIT)+# define ASIO_HAS_DEDUCED_EXECUTION_IS_RECEIVER_TRAIT 1+#endif // defined(ASIO_HAS_DEDUCED_SET_DONE_FREE_TRAIT)+ // && defined(ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)+ // && defined(ASIO_HAS_DEDUCED_SET_ERROR_FREE_TRAIT)+ // && defined(ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)+ // && defined(ASIO_HAS_DEDUCED_SET_VALUE_FREE_TRAIT)+ // && defined(ASIO_HAS_DEDUCED_SET_VALUE_MEMBER_TRAIT)+ // && defined(ASIO_HAS_DEDUCED_RECEIVER_OF_FREE_TRAIT)+ // && defined(ASIO_HAS_DEDUCED_RECEIVER_OF_MEMBER_TRAIT)++#include "asio/detail/push_options.hpp"++namespace asio {+namespace execution {+namespace detail {++template <typename T, typename E>+struct is_receiver_base :+ integral_constant<bool,+ is_move_constructible<typename remove_cvref<T>::type>::value+ && is_constructible<typename remove_cvref<T>::type, T>::value+ >+{+};++} // namespace detail++#if defined(ASIO_HAS_STD_EXCEPTION_PTR)+# define ASIO_EXECUTION_RECEIVER_ERROR_DEFAULT = std::exception_ptr+#else // defined(ASIO_HAS_STD_EXCEPTION_PTR)+# define ASIO_EXECUTION_RECEIVER_ERROR_DEFAULT \+ = ::asio::error_code+#endif // defined(ASIO_HAS_STD_EXCEPTION_PTR)++/// The is_receiver trait detects whether a type T satisfies the+/// execution::receiver concept.+/**+ * Class template @c is_receiver is a type trait that is derived from @c+ * true_type if the type @c T meets the concept definition for a receiver for+ * error type @c E, otherwise @c false_type.+ */+template <typename T, typename E ASIO_EXECUTION_RECEIVER_ERROR_DEFAULT>+struct is_receiver :+#if defined(GENERATING_DOCUMENTATION)+ integral_constant<bool, automatically_determined>+#else // defined(GENERATING_DOCUMENTATION)+ conditional<+ can_set_done<typename remove_cvref<T>::type>::value+ && is_nothrow_set_done<typename remove_cvref<T>::type>::value+ && can_set_error<typename remove_cvref<T>::type, E>::value+ && is_nothrow_set_error<typename remove_cvref<T>::type, E>::value,+ detail::is_receiver_base<T, E>,+ false_type+ >::type+#endif // defined(GENERATING_DOCUMENTATION)+{+};++#if defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename T, typename E ASIO_EXECUTION_RECEIVER_ERROR_DEFAULT>+ASIO_CONSTEXPR const bool is_receiver_v = is_receiver<T, E>::value;++#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++#if defined(ASIO_HAS_CONCEPTS)++template <typename T, typename E ASIO_EXECUTION_RECEIVER_ERROR_DEFAULT>+ASIO_CONCEPT receiver = is_receiver<T, E>::value;++#define ASIO_EXECUTION_RECEIVER ::asio::execution::receiver++#else // defined(ASIO_HAS_CONCEPTS)++#define ASIO_EXECUTION_RECEIVER typename++#endif // defined(ASIO_HAS_CONCEPTS)++#if defined(ASIO_HAS_VARIADIC_TEMPLATES) \+ || defined(GENERATING_DOCUMENTATION)++/// The is_receiver_of trait detects whether a type T satisfies the+/// execution::receiver_of concept for some set of value arguments.+/**+ * Class template @c is_receiver_of is a type trait that is derived from @c+ * true_type if the type @c T meets the concept definition for a receiver for+ * value arguments @c Vs, otherwise @c false_type.+ */+template <typename T, typename... Vs>+struct is_receiver_of :+#if defined(GENERATING_DOCUMENTATION)+ integral_constant<bool, automatically_determined>+#else // defined(GENERATING_DOCUMENTATION)+ conditional<+ is_receiver<T>::value,+ can_set_value<typename remove_cvref<T>::type, Vs...>,+ false_type+ >::type+#endif // defined(GENERATING_DOCUMENTATION)+{+};++#if defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename T, typename... Vs>+ASIO_CONSTEXPR const bool is_receiver_of_v =+ is_receiver_of<T, Vs...>::value;++#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++#if defined(ASIO_HAS_CONCEPTS)++template <typename T, typename... Vs>+ASIO_CONCEPT receiver_of = is_receiver_of<T, Vs...>::value;++#define ASIO_EXECUTION_RECEIVER_OF_0 \+ ::asio::execution::receiver_of++#define ASIO_EXECUTION_RECEIVER_OF_1(v) \+ ::asio::execution::receiver_of<v>++#else // defined(ASIO_HAS_CONCEPTS)++#define ASIO_EXECUTION_RECEIVER_OF_0 typename+#define ASIO_EXECUTION_RECEIVER_OF_1(v) typename++#endif // defined(ASIO_HAS_CONCEPTS)++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)+ // || defined(GENERATING_DOCUMENTATION)++template <typename T, typename = void,+ typename = void, typename = void, typename = void, typename = void,+ typename = void, typename = void, typename = void, typename = void>+struct is_receiver_of;++template <typename T>+struct is_receiver_of<T> :+ conditional<+ is_receiver<T>::value,+ can_set_value<typename remove_cvref<T>::type>,+ false_type+ >::type+{+};++#define ASIO_PRIVATE_RECEIVER_OF_TRAITS_DEF(n) \+ template <typename T, ASIO_VARIADIC_TPARAMS(n)> \+ struct is_receiver_of<T, ASIO_VARIADIC_TARGS(n)> : \+ conditional< \+ conditional<true, is_receiver<T>, void>::type::value, \+ can_set_value< \+ typename remove_cvref<T>::type, \+ ASIO_VARIADIC_TARGS(n)>, \+ false_type \+ >::type \+ { \+ }; \+ /**/+ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_RECEIVER_OF_TRAITS_DEF)+#undef ASIO_PRIVATE_RECEIVER_OF_TRAITS_DEF++#define ASIO_EXECUTION_RECEIVER_OF_0 typename+#define ASIO_EXECUTION_RECEIVER_OF_1(v) typename++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+ // || defined(GENERATING_DOCUMENTATION)++#if defined(ASIO_HAS_VARIADIC_TEMPLATES) \+ || defined(GENERATING_DOCUMENTATION)++/// The is_nothrow_receiver_of trait detects whether a type T satisfies the+/// execution::receiver_of concept for some set of value arguments, with a+/// noexcept @c set_value operation.+/**+ * Class template @c is_nothrow_receiver_of is a type trait that is derived+ * from @c true_type if the type @c T meets the concept definition for a+ * receiver for value arguments @c Vs, and the expression+ * <tt>execution::set_value(declval<T>(), declval<Ts>()...)</tt> is noexcept,+ * otherwise @c false_type.+ */+template <typename T, typename... Vs>+struct is_nothrow_receiver_of :+#if defined(GENERATING_DOCUMENTATION)+ integral_constant<bool, automatically_determined>+#else // defined(GENERATING_DOCUMENTATION)+ integral_constant<bool,+ is_receiver_of<T, Vs...>::value+ && is_nothrow_set_value<typename remove_cvref<T>::type, Vs...>::value+ >+#endif // defined(GENERATING_DOCUMENTATION)+{+};++#if defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename T, typename... Vs>+ASIO_CONSTEXPR const bool is_nothrow_receiver_of_v =+ is_nothrow_receiver_of<T, Vs...>::value;++#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)+ // || defined(GENERATING_DOCUMENTATION)++template <typename T, typename = void,+ typename = void, typename = void, typename = void, typename = void,+ typename = void, typename = void, typename = void, typename = void>+struct is_nothrow_receiver_of;++template <typename T>+struct is_nothrow_receiver_of<T> :+ integral_constant<bool,+ is_receiver_of<T>::value+ && is_nothrow_set_value<typename remove_cvref<T>::type>::value+ >+{+};++#define ASIO_PRIVATE_NOTHROW_RECEIVER_OF_TRAITS_DEF(n) \+ template <typename T, ASIO_VARIADIC_TPARAMS(n)> \+ struct is_nothrow_receiver_of<T, ASIO_VARIADIC_TARGS(n)> : \+ integral_constant<bool, \+ is_receiver_of<T, ASIO_VARIADIC_TARGS(n)>::value \+ && is_nothrow_set_value<typename remove_cvref<T>::type, \+ ASIO_VARIADIC_TARGS(n)>::value \+ > \+ { \+ }; \+ /**/+ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_NOTHROW_RECEIVER_OF_TRAITS_DEF)+#undef ASIO_PRIVATE_NOTHROW_RECEIVER_OF_TRAITS_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+ // || defined(GENERATING_DOCUMENTATION)++} // namespace execution+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // !defined(ASIO_NO_DEPRECATED)++#endif // ASIO_EXECUTION_RECEIVER_HPP
+ link/modules/asio-standalone/asio/include/asio/execution/receiver_invocation_error.hpp view
@@ -0,0 +1,48 @@+//+// execution/receiver_invocation_error.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_EXECUTION_RECEIVER_INVOCATION_ERROR_HPP+#define ASIO_EXECUTION_RECEIVER_INVOCATION_ERROR_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include <stdexcept>++#include "asio/detail/push_options.hpp"++namespace asio {+namespace execution {++/// Exception reported via @c set_error when an exception escapes from+/// @c set_value.+class receiver_invocation_error+ : public std::runtime_error+#if defined(ASIO_HAS_STD_NESTED_EXCEPTION)+ , public std::nested_exception+#endif // defined(ASIO_HAS_STD_NESTED_EXCEPTION)+{+public:+ /// Constructor.+ ASIO_DECL receiver_invocation_error();+};++} // namespace execution+} // namespace asio++#include "asio/detail/pop_options.hpp"++#if defined(ASIO_HEADER_ONLY)+# include "asio/execution/impl/receiver_invocation_error.ipp"+#endif // defined(ASIO_HEADER_ONLY)++#endif // ASIO_EXECUTION_RECEIVER_INVOCATION_ERROR_HPP
link/modules/asio-standalone/asio/include/asio/execution/relationship.hpp view
@@ -2,7 +2,7 @@ // execution/relationship.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -18,6 +18,8 @@ #include "asio/detail/config.hpp" #include "asio/detail/type_traits.hpp" #include "asio/execution/executor.hpp"+#include "asio/execution/scheduler.hpp"+#include "asio/execution/sender.hpp" #include "asio/is_applicable_property.hpp" #include "asio/query.hpp" #include "asio/traits/query_free.hpp"@@ -38,9 +40,10 @@ /// the calling context. struct relationship_t {- /// The relationship_t property applies to executors.+ /// The relationship_t property applies to executors, senders, and schedulers. template <typename T>- static constexpr bool is_applicable_property_v = is_executor_v<T>;+ static constexpr bool is_applicable_property_v =+ is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>; /// The top-level relationship_t property cannot be required. static constexpr bool is_requirable = false;@@ -55,9 +58,11 @@ /// continuation of the calling context. struct fork_t {- /// The relationship_t::fork_t property applies to executors.+ /// The relationship_t::fork_t property applies to executors, senders, and+ /// schedulers. template <typename T>- static constexpr bool is_applicable_property_v = is_executor_v<T>;+ static constexpr bool is_applicable_property_v =+ is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>; /// The relationship_t::fork_t property can be required. static constexpr bool is_requirable = true;@@ -82,9 +87,11 @@ /// of the calling context. struct continuation_t {- /// The relationship_t::continuation_t property applies to executors.+ /// The relationship_t::continuation_t property applies to executors,+ /// senders, and schedulers. template <typename T>- static constexpr bool is_applicable_property_v = is_executor_v<T>;+ static constexpr bool is_applicable_property_v =+ is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>; /// The relationship_t::continuation_t property can be required. static constexpr bool is_requirable = true;@@ -150,28 +157,48 @@ struct relationship_t { #if defined(ASIO_HAS_VARIABLE_TEMPLATES)+# if defined(ASIO_NO_DEPRECATED) template <typename T>- static constexpr bool is_applicable_property_v = is_executor<T>::value;+ ASIO_STATIC_CONSTEXPR(bool,+ is_applicable_property_v = (+ is_executor<T>::value));+# else // defined(ASIO_NO_DEPRECATED)+ template <typename T>+ ASIO_STATIC_CONSTEXPR(bool,+ is_applicable_property_v = (+ is_executor<T>::value+ || conditional<+ is_executor<T>::value,+ false_type,+ is_sender<T>+ >::type::value+ || conditional<+ is_executor<T>::value,+ false_type,+ is_scheduler<T>+ >::type::value+ ));+# endif // defined(ASIO_NO_DEPRECATED) #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) - static constexpr bool is_requirable = false;- static constexpr bool is_preferable = false;+ ASIO_STATIC_CONSTEXPR(bool, is_requirable = false);+ ASIO_STATIC_CONSTEXPR(bool, is_preferable = false); typedef relationship_t polymorphic_query_result_type; typedef detail::relationship::fork_t<I> fork_t; typedef detail::relationship::continuation_t<I> continuation_t; - constexpr relationship_t()+ ASIO_CONSTEXPR relationship_t() : value_(-1) { } - constexpr relationship_t(fork_t)+ ASIO_CONSTEXPR relationship_t(fork_t) : value_(0) { } - constexpr relationship_t(continuation_t)+ ASIO_CONSTEXPR relationship_t(continuation_t) : value_(1) { }@@ -183,14 +210,16 @@ struct type { template <typename P>- auto query(P&& p) const+ auto query(ASIO_MOVE_ARG(P) p) const noexcept( noexcept(- declval<conditional_t<true, T, P>>().query(static_cast<P&&>(p))+ declval<typename conditional<true, T, P>::type>().query(+ ASIO_MOVE_CAST(P)(p)) ) ) -> decltype(- declval<conditional_t<true, T, P>>().query(static_cast<P&&>(p))+ declval<typename conditional<true, T, P>::type>().query(+ ASIO_MOVE_CAST(P)(p)) ); }; #else // defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)@@ -205,17 +234,17 @@ struct type { template <typename P>- static constexpr auto query(P&& p)+ static constexpr auto query(ASIO_MOVE_ARG(P) p) noexcept( noexcept(- conditional_t<true, T, P>::query(static_cast<P&&>(p))+ conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p)) ) ) -> decltype(- conditional_t<true, T, P>::query(static_cast<P&&>(p))+ conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p)) ) {- return T::query(static_cast<P&&>(p));+ return T::query(ASIO_MOVE_CAST(P)(p)); } }; #else // defined(ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)@@ -235,65 +264,66 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T>- static constexpr+ static ASIO_CONSTEXPR typename query_static_constexpr_member<T>::result_type static_query()- noexcept(query_static_constexpr_member<T>::is_noexcept)+ ASIO_NOEXCEPT_IF((+ query_static_constexpr_member<T>::is_noexcept)) { return query_static_constexpr_member<T>::value(); } template <typename T>- static constexpr+ static ASIO_CONSTEXPR typename traits::static_query<T, fork_t>::result_type static_query(- enable_if_t<+ typename enable_if< !query_static_constexpr_member<T>::is_valid- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< !query_member<T>::is_valid- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< traits::static_query<T, fork_t>::is_valid- >* = 0) noexcept+ >::type* = 0) ASIO_NOEXCEPT { return traits::static_query<T, fork_t>::value(); } template <typename T>- static constexpr+ static ASIO_CONSTEXPR typename traits::static_query<T, continuation_t>::result_type static_query(- enable_if_t<+ typename enable_if< !query_static_constexpr_member<T>::is_valid- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< !query_member<T>::is_valid- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< !traits::static_query<T, fork_t>::is_valid- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< traits::static_query<T, continuation_t>::is_valid- >* = 0) noexcept+ >::type* = 0) ASIO_NOEXCEPT { return traits::static_query<T, continuation_t>::value(); } template <typename E, typename T = decltype(relationship_t::static_query<E>())>- static constexpr const T static_query_v+ static ASIO_CONSTEXPR const T static_query_v = relationship_t::static_query<E>(); #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) - friend constexpr bool operator==(+ friend ASIO_CONSTEXPR bool operator==( const relationship_t& a, const relationship_t& b) { return a.value_ == b.value_; } - friend constexpr bool operator!=(+ friend ASIO_CONSTEXPR bool operator!=( const relationship_t& a, const relationship_t& b) { return a.value_ != b.value_;@@ -301,22 +331,24 @@ struct convertible_from_relationship_t {- constexpr convertible_from_relationship_t(relationship_t)+ ASIO_CONSTEXPR convertible_from_relationship_t(relationship_t) { } }; template <typename Executor>- friend constexpr relationship_t query(+ friend ASIO_CONSTEXPR relationship_t query( const Executor& ex, convertible_from_relationship_t,- enable_if_t<+ typename enable_if< can_query<const Executor&, fork_t>::value- >* = 0)+ >::type* = 0) #if !defined(__clang__) // Clang crashes if noexcept is used here. #if defined(ASIO_MSVC) // Visual C++ wants the type to be qualified.- noexcept(is_nothrow_query<const Executor&, relationship_t<>::fork_t>::value)+ ASIO_NOEXCEPT_IF((+ is_nothrow_query<const Executor&, relationship_t<>::fork_t>::value)) #else // defined(ASIO_MSVC)- noexcept(is_nothrow_query<const Executor&, fork_t>::value)+ ASIO_NOEXCEPT_IF((+ is_nothrow_query<const Executor&, fork_t>::value)) #endif // defined(ASIO_MSVC) #endif // !defined(__clang__) {@@ -324,20 +356,22 @@ } template <typename Executor>- friend constexpr relationship_t query(+ friend ASIO_CONSTEXPR relationship_t query( const Executor& ex, convertible_from_relationship_t,- enable_if_t<+ typename enable_if< !can_query<const Executor&, fork_t>::value- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< can_query<const Executor&, continuation_t>::value- >* = 0)+ >::type* = 0) #if !defined(__clang__) // Clang crashes if noexcept is used here. #if defined(ASIO_MSVC) // Visual C++ wants the type to be qualified.- noexcept(is_nothrow_query<const Executor&,- relationship_t<>::continuation_t>::value)+ ASIO_NOEXCEPT_IF((+ is_nothrow_query<const Executor&,+ relationship_t<>::continuation_t>::value)) #else // defined(ASIO_MSVC)- noexcept(is_nothrow_query<const Executor&, continuation_t>::value)+ ASIO_NOEXCEPT_IF((+ is_nothrow_query<const Executor&, continuation_t>::value)) #endif // defined(ASIO_MSVC) #endif // !defined(__clang__) {@@ -347,6 +381,10 @@ ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(fork_t, fork); ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(continuation_t, continuation); +#if !defined(ASIO_HAS_CONSTEXPR)+ static const relationship_t instance;+#endif // !defined(ASIO_HAS_CONSTEXPR)+ private: int value_; };@@ -358,10 +396,16 @@ #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) +#if !defined(ASIO_HAS_CONSTEXPR) template <int I>-const typename relationship_t<I>::fork_t relationship_t<I>::fork;+const relationship_t<I> relationship_t<I>::instance;+#endif template <int I>+const typename relationship_t<I>::fork_t+relationship_t<I>::fork;++template <int I> const typename relationship_t<I>::continuation_t relationship_t<I>::continuation; @@ -371,15 +415,35 @@ struct fork_t { #if defined(ASIO_HAS_VARIABLE_TEMPLATES)+# if defined(ASIO_NO_DEPRECATED) template <typename T>- static constexpr bool is_applicable_property_v = is_executor<T>::value;+ ASIO_STATIC_CONSTEXPR(bool,+ is_applicable_property_v = (+ is_executor<T>::value));+# else // defined(ASIO_NO_DEPRECATED)+ template <typename T>+ ASIO_STATIC_CONSTEXPR(bool,+ is_applicable_property_v = (+ is_executor<T>::value+ || conditional<+ is_executor<T>::value,+ false_type,+ is_sender<T>+ >::type::value+ || conditional<+ is_executor<T>::value,+ false_type,+ is_scheduler<T>+ >::type::value+ ));+# endif // defined(ASIO_NO_DEPRECATED) #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) - static constexpr bool is_requirable = true;- static constexpr bool is_preferable = true;+ ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);+ ASIO_STATIC_CONSTEXPR(bool, is_preferable = true); typedef relationship_t<I> polymorphic_query_result_type; - constexpr fork_t()+ ASIO_CONSTEXPR fork_t() { } @@ -396,61 +460,55 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T>- static constexpr typename query_static_constexpr_member<T>::result_type+ static ASIO_CONSTEXPR+ typename query_static_constexpr_member<T>::result_type static_query()- noexcept(query_static_constexpr_member<T>::is_noexcept)+ ASIO_NOEXCEPT_IF((+ query_static_constexpr_member<T>::is_noexcept)) { return query_static_constexpr_member<T>::value(); } template <typename T>- static constexpr fork_t static_query(- enable_if_t<+ static ASIO_CONSTEXPR fork_t static_query(+ typename enable_if< !query_static_constexpr_member<T>::is_valid- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< !query_member<T>::is_valid- >* = 0,- enable_if_t<+ >::type* = 0,+ typename enable_if< !traits::query_free<T, fork_t>::is_valid- >* = 0,- enable_if_t<- !can_query<T, continuation_t<I>>::value- >* = 0) noexcept+ >::type* = 0,+ typename enable_if<+ !can_query<T, continuation_t<I> >::value+ >::type* = 0) ASIO_NOEXCEPT { return fork_t(); } template <typename E, typename T = decltype(fork_t::static_query<E>())>- static constexpr const T static_query_v+ static ASIO_CONSTEXPR const T static_query_v = fork_t::static_query<E>(); #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) - static constexpr relationship_t<I> value()+ static ASIO_CONSTEXPR relationship_t<I> value() { return fork_t(); } - friend constexpr bool operator==(const fork_t&, const fork_t&)+ friend ASIO_CONSTEXPR bool operator==(+ const fork_t&, const fork_t&) { return true; } - friend constexpr bool operator!=(const fork_t&, const fork_t&)- {- return false;- }-- friend constexpr bool operator==(const fork_t&, const continuation_t<I>&)+ friend ASIO_CONSTEXPR bool operator!=(+ const fork_t&, const fork_t&) { return false; }-- friend constexpr bool operator!=(const fork_t&, const continuation_t<I>&)- {- return true;- } }; #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \@@ -464,15 +522,35 @@ struct continuation_t { #if defined(ASIO_HAS_VARIABLE_TEMPLATES)+# if defined(ASIO_NO_DEPRECATED) template <typename T>- static constexpr bool is_applicable_property_v = is_executor<T>::value;+ ASIO_STATIC_CONSTEXPR(bool,+ is_applicable_property_v = (+ is_executor<T>::value));+# else // defined(ASIO_NO_DEPRECATED)+ template <typename T>+ ASIO_STATIC_CONSTEXPR(bool,+ is_applicable_property_v = (+ is_executor<T>::value+ || conditional<+ is_executor<T>::value,+ false_type,+ is_sender<T>+ >::type::value+ || conditional<+ is_executor<T>::value,+ false_type,+ is_scheduler<T>+ >::type::value+ ));+# endif // defined(ASIO_NO_DEPRECATED) #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) - static constexpr bool is_requirable = true;- static constexpr bool is_preferable = true;+ ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);+ ASIO_STATIC_CONSTEXPR(bool, is_preferable = true); typedef relationship_t<I> polymorphic_query_result_type; - constexpr continuation_t()+ ASIO_CONSTEXPR continuation_t() { } @@ -490,44 +568,38 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T>- static constexpr typename query_static_constexpr_member<T>::result_type+ static ASIO_CONSTEXPR+ typename query_static_constexpr_member<T>::result_type static_query()- noexcept(query_static_constexpr_member<T>::is_noexcept)+ ASIO_NOEXCEPT_IF((+ query_static_constexpr_member<T>::is_noexcept)) { return query_static_constexpr_member<T>::value(); } template <typename E, typename T = decltype(continuation_t::static_query<E>())>- static constexpr const T static_query_v+ static ASIO_CONSTEXPR const T static_query_v = continuation_t::static_query<E>(); #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) - static constexpr relationship_t<I> value()+ static ASIO_CONSTEXPR relationship_t<I> value() { return continuation_t(); } - friend constexpr bool operator==(const continuation_t&, const continuation_t&)+ friend ASIO_CONSTEXPR bool operator==(+ const continuation_t&, const continuation_t&) { return true; } - friend constexpr bool operator!=(const continuation_t&, const continuation_t&)- {- return false;- }-- friend constexpr bool operator==(const continuation_t&, const fork_t<I>&)+ friend ASIO_CONSTEXPR bool operator!=(+ const continuation_t&, const continuation_t&) { return false; }-- friend constexpr bool operator!=(const continuation_t&, const fork_t<I>&)- {- return true;- } }; #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \@@ -542,7 +614,12 @@ typedef detail::relationship_t<> relationship_t; -ASIO_INLINE_VARIABLE constexpr relationship_t relationship;+#if defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)+constexpr relationship_t relationship;+#else // defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)+namespace { static const relationship_t&+ relationship = relationship_t::instance; }+#endif } // namespace execution @@ -550,19 +627,61 @@ template <typename T> struct is_applicable_property<T, execution::relationship_t>- : integral_constant<bool, execution::is_executor<T>::value>+ : integral_constant<bool,+ execution::is_executor<T>::value+#if !defined(ASIO_NO_DEPRECATED)+ || conditional<+ execution::is_executor<T>::value,+ false_type,+ execution::is_sender<T>+ >::type::value+ || conditional<+ execution::is_executor<T>::value,+ false_type,+ execution::is_scheduler<T>+ >::type::value+#endif // !defined(ASIO_NO_DEPRECATED)+ > { }; template <typename T> struct is_applicable_property<T, execution::relationship_t::fork_t>- : integral_constant<bool, execution::is_executor<T>::value>+ : integral_constant<bool,+ execution::is_executor<T>::value+#if !defined(ASIO_NO_DEPRECATED)+ || conditional<+ execution::is_executor<T>::value,+ false_type,+ execution::is_sender<T>+ >::type::value+ || conditional<+ execution::is_executor<T>::value,+ false_type,+ execution::is_scheduler<T>+ >::type::value+#endif // !defined(ASIO_NO_DEPRECATED)+ > { }; template <typename T> struct is_applicable_property<T, execution::relationship_t::continuation_t>- : integral_constant<bool, execution::is_executor<T>::value>+ : integral_constant<bool,+ execution::is_executor<T>::value+#if !defined(ASIO_NO_DEPRECATED)+ || conditional<+ execution::is_executor<T>::value,+ false_type,+ execution::is_sender<T>+ >::type::value+ || conditional<+ execution::is_executor<T>::value,+ false_type,+ execution::is_scheduler<T>+ >::type::value+#endif // !defined(ASIO_NO_DEPRECATED)+ > { }; @@ -574,27 +693,27 @@ template <typename T> struct query_free_default<T, execution::relationship_t,- enable_if_t<+ typename enable_if< can_query<T, execution::relationship_t::fork_t>::value- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept =- is_nothrow_query<T, execution::relationship_t::fork_t>::value;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+ (is_nothrow_query<T, execution::relationship_t::fork_t>::value)); typedef execution::relationship_t result_type; }; template <typename T> struct query_free_default<T, execution::relationship_t,- enable_if_t<+ typename enable_if< !can_query<T, execution::relationship_t::fork_t>::value && can_query<T, execution::relationship_t::continuation_t>::value- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept =- is_nothrow_query<T, execution::relationship_t::continuation_t>::value;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+ (is_nothrow_query<T, execution::relationship_t::continuation_t>::value)); typedef execution::relationship_t result_type; };@@ -606,18 +725,18 @@ template <typename T> struct static_query<T, execution::relationship_t,- enable_if_t<+ typename enable_if< execution::detail::relationship_t<0>:: query_static_constexpr_member<T>::is_valid- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef typename execution::detail::relationship_t<0>:: query_static_constexpr_member<T>::result_type result_type; - static constexpr result_type value()+ static ASIO_CONSTEXPR result_type value() { return execution::detail::relationship_t<0>:: query_static_constexpr_member<T>::value();@@ -626,22 +745,22 @@ template <typename T> struct static_query<T, execution::relationship_t,- enable_if_t<+ typename enable_if< !execution::detail::relationship_t<0>:: query_static_constexpr_member<T>::is_valid && !execution::detail::relationship_t<0>:: query_member<T>::is_valid && traits::static_query<T, execution::relationship_t::fork_t>::is_valid- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef typename traits::static_query<T, execution::relationship_t::fork_t>::result_type result_type; - static constexpr result_type value()+ static ASIO_CONSTEXPR result_type value() { return traits::static_query<T, execution::relationship_t::fork_t>::value();@@ -650,7 +769,7 @@ template <typename T> struct static_query<T, execution::relationship_t,- enable_if_t<+ typename enable_if< !execution::detail::relationship_t<0>:: query_static_constexpr_member<T>::is_valid && !execution::detail::relationship_t<0>::@@ -659,15 +778,15 @@ execution::relationship_t::fork_t>::is_valid && traits::static_query<T, execution::relationship_t::continuation_t>::is_valid- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef typename traits::static_query<T, execution::relationship_t::continuation_t>::result_type result_type; - static constexpr result_type value()+ static ASIO_CONSTEXPR result_type value() { return traits::static_query<T, execution::relationship_t::continuation_t>::value();@@ -676,18 +795,18 @@ template <typename T> struct static_query<T, execution::relationship_t::fork_t,- enable_if_t<+ typename enable_if< execution::detail::relationship::fork_t<0>:: query_static_constexpr_member<T>::is_valid- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef typename execution::detail::relationship::fork_t<0>:: query_static_constexpr_member<T>::result_type result_type; - static constexpr result_type value()+ static ASIO_CONSTEXPR result_type value() { return execution::detail::relationship::fork_t<0>:: query_static_constexpr_member<T>::value();@@ -696,7 +815,7 @@ template <typename T> struct static_query<T, execution::relationship_t::fork_t,- enable_if_t<+ typename enable_if< !execution::detail::relationship::fork_t<0>:: query_static_constexpr_member<T>::is_valid && !execution::detail::relationship::fork_t<0>::@@ -704,14 +823,14 @@ && !traits::query_free<T, execution::relationship_t::fork_t>::is_valid && !can_query<T, execution::relationship_t::continuation_t>::value- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef execution::relationship_t::fork_t result_type; - static constexpr result_type value()+ static ASIO_CONSTEXPR result_type value() { return result_type(); }@@ -719,18 +838,18 @@ template <typename T> struct static_query<T, execution::relationship_t::continuation_t,- enable_if_t<+ typename enable_if< execution::detail::relationship::continuation_t<0>:: query_static_constexpr_member<T>::is_valid- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef typename execution::detail::relationship::continuation_t<0>:: query_static_constexpr_member<T>::result_type result_type; - static constexpr result_type value()+ static ASIO_CONSTEXPR result_type value() { return execution::detail::relationship::continuation_t<0>:: query_static_constexpr_member<T>::value();@@ -739,6 +858,34 @@ #endif // !defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // || !defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)++#if !defined(ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT)++template <typename T>+struct static_require<T, execution::relationship_t::fork_t,+ typename enable_if<+ static_query<T, execution::relationship_t::fork_t>::is_valid+ >::type>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid =+ (is_same<typename static_query<T,+ execution::relationship_t::fork_t>::result_type,+ execution::relationship_t::fork_t>::value));+};++template <typename T>+struct static_require<T, execution::relationship_t::continuation_t,+ typename enable_if<+ static_query<T, execution::relationship_t::continuation_t>::is_valid+ >::type>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid =+ (is_same<typename static_query<T,+ execution::relationship_t::continuation_t>::result_type,+ execution::relationship_t::continuation_t>::value));+};++#endif // !defined(ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT) } // namespace traits
+ link/modules/asio-standalone/asio/include/asio/execution/schedule.hpp view
@@ -0,0 +1,292 @@+//+// execution/schedule.hpp+// ~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_EXECUTION_SCHEDULE_HPP+#define ASIO_EXECUTION_SCHEDULE_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"++#if !defined(ASIO_NO_DEPRECATED)++#include "asio/detail/type_traits.hpp"+#include "asio/execution/executor.hpp"+#include "asio/traits/schedule_member.hpp"+#include "asio/traits/schedule_free.hpp"++#include "asio/detail/push_options.hpp"++#if defined(GENERATING_DOCUMENTATION)++namespace asio {+namespace execution {++/// A customisation point that is used to obtain a sender from a scheduler.+/**+ * The name <tt>execution::schedule</tt> denotes a customisation point object.+ * For some subexpression <tt>s</tt>, let <tt>S</tt> be a type such that+ * <tt>decltype((s))</tt> is <tt>S</tt>. The expression+ * <tt>execution::schedule(s)</tt> is expression-equivalent to:+ *+ * @li <tt>s.schedule()</tt>, if that expression is valid and its type models+ * <tt>sender</tt>.+ *+ * @li Otherwise, <tt>schedule(s)</tt>, if that expression is valid and its+ * type models <tt>sender</tt> with overload resolution performed in a context+ * that includes the declaration <tt>void schedule();</tt> and that does not+ * include a declaration of <tt>execution::schedule</tt>.+ *+ * @li Otherwise, <tt>S</tt> if <tt>S</tt> satisfies <tt>executor</tt>.+ *+ * @li Otherwise, <tt>execution::schedule(s)</tt> is ill-formed.+ */+inline constexpr unspecified schedule = unspecified;++/// A type trait that determines whether a @c schedule expression is+/// well-formed.+/**+ * Class template @c can_schedule is a trait that is derived from @c true_type+ * if the expression <tt>execution::schedule(std::declval<S>())</tt> is well+ * formed; otherwise @c false_type.+ */+template <typename S>+struct can_schedule :+ integral_constant<bool, automatically_determined>+{+};++} // namespace execution+} // namespace asio++#else // defined(GENERATING_DOCUMENTATION)++namespace asio_execution_schedule_fn {++using asio::decay;+using asio::declval;+using asio::enable_if;+using asio::execution::is_executor;+using asio::traits::schedule_free;+using asio::traits::schedule_member;++void schedule();++enum overload_type+{+ identity,+ call_member,+ call_free,+ ill_formed+};++template <typename S, typename = void, typename = void, typename = void>+struct call_traits+{+ ASIO_STATIC_CONSTEXPR(overload_type, overload = ill_formed);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ typedef void result_type;+};++template <typename S>+struct call_traits<S,+ typename enable_if<+ schedule_member<S>::is_valid+ >::type> :+ schedule_member<S>+{+ ASIO_STATIC_CONSTEXPR(overload_type, overload = call_member);+};++template <typename S>+struct call_traits<S,+ typename enable_if<+ !schedule_member<S>::is_valid+ >::type,+ typename enable_if<+ schedule_free<S>::is_valid+ >::type> :+ schedule_free<S>+{+ ASIO_STATIC_CONSTEXPR(overload_type, overload = call_free);+};++template <typename S>+struct call_traits<S,+ typename enable_if<+ !schedule_member<S>::is_valid+ >::type,+ typename enable_if<+ !schedule_free<S>::is_valid+ >::type,+ typename enable_if<+ is_executor<typename decay<S>::type>::value+ >::type>+{+ ASIO_STATIC_CONSTEXPR(overload_type, overload = identity);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);++#if defined(ASIO_HAS_MOVE)+ typedef ASIO_MOVE_ARG(S) result_type;+#else // defined(ASIO_HAS_MOVE)+ typedef ASIO_MOVE_ARG(typename decay<S>::type) result_type;+#endif // defined(ASIO_HAS_MOVE)+};++struct impl+{+ template <typename S>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<S>::overload == identity,+ typename call_traits<S>::result_type+ >::type+ operator()(ASIO_MOVE_ARG(S) s) const+ ASIO_NOEXCEPT_IF((+ call_traits<S>::is_noexcept))+ {+ return ASIO_MOVE_CAST(S)(s);+ }++#if defined(ASIO_HAS_MOVE)+ template <typename S>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<S>::overload == call_member,+ typename call_traits<S>::result_type+ >::type+ operator()(S&& s) const+ ASIO_NOEXCEPT_IF((+ call_traits<S>::is_noexcept))+ {+ return ASIO_MOVE_CAST(S)(s).schedule();+ }++ template <typename S>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<S>::overload == call_free,+ typename call_traits<S>::result_type+ >::type+ operator()(S&& s) const+ ASIO_NOEXCEPT_IF((+ call_traits<S>::is_noexcept))+ {+ return schedule(ASIO_MOVE_CAST(S)(s));+ }+#else // defined(ASIO_HAS_MOVE)+ template <typename S>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<S&>::overload == call_member,+ typename call_traits<S&>::result_type+ >::type+ operator()(S& s) const+ ASIO_NOEXCEPT_IF((+ call_traits<S&>::is_noexcept))+ {+ return s.schedule();+ }++ template <typename S>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<const S&>::overload == call_member,+ typename call_traits<const S&>::result_type+ >::type+ operator()(const S& s) const+ ASIO_NOEXCEPT_IF((+ call_traits<const S&>::is_noexcept))+ {+ return s.schedule();+ }++ template <typename S>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<S&>::overload == call_free,+ typename call_traits<S&>::result_type+ >::type+ operator()(S& s) const+ ASIO_NOEXCEPT_IF((+ call_traits<S&>::is_noexcept))+ {+ return schedule(s);+ }++ template <typename S>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<const S&>::overload == call_free,+ typename call_traits<const S&>::result_type+ >::type+ operator()(const S& s) const+ ASIO_NOEXCEPT_IF((+ call_traits<const S&>::is_noexcept))+ {+ return schedule(s);+ }+#endif // defined(ASIO_HAS_MOVE)+};++template <typename T = impl>+struct static_instance+{+ static const T instance;+};++template <typename T>+const T static_instance<T>::instance = {};++} // namespace asio_execution_schedule_fn+namespace asio {+namespace execution {+namespace {++static ASIO_CONSTEXPR const asio_execution_schedule_fn::impl&+ schedule = asio_execution_schedule_fn::static_instance<>::instance;++} // namespace++template <typename S>+struct can_schedule :+ integral_constant<bool,+ asio_execution_schedule_fn::call_traits<S>::overload !=+ asio_execution_schedule_fn::ill_formed>+{+};++#if defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename S>+constexpr bool can_schedule_v = can_schedule<S>::value;++#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename S>+struct is_nothrow_schedule :+ integral_constant<bool,+ asio_execution_schedule_fn::call_traits<S>::is_noexcept>+{+};++#if defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename S>+constexpr bool is_nothrow_schedule_v+ = is_nothrow_schedule<S>::value;++#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++} // namespace execution+} // namespace asio++#endif // defined(GENERATING_DOCUMENTATION)++#include "asio/detail/pop_options.hpp"++#endif // !defined(ASIO_NO_DEPRECATED)++#endif // ASIO_EXECUTION_SCHEDULE_HPP
+ link/modules/asio-standalone/asio/include/asio/execution/scheduler.hpp view
@@ -0,0 +1,91 @@+//+// execution/scheduler.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_EXECUTION_SCHEDULER_HPP+#define ASIO_EXECUTION_SCHEDULER_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"++#if !defined(ASIO_NO_DEPRECATED)++#include "asio/detail/type_traits.hpp"+#include "asio/execution/schedule.hpp"+#include "asio/traits/equality_comparable.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {+namespace execution {+namespace detail {++template <typename T>+struct is_scheduler_base :+ integral_constant<bool,+ is_copy_constructible<typename remove_cvref<T>::type>::value+ && traits::equality_comparable<typename remove_cvref<T>::type>::is_valid+ >+{+};++} // namespace detail++/// The is_scheduler trait detects whether a type T satisfies the+/// execution::scheduler concept.+/**+ * Class template @c is_scheduler is a type trait that is derived from @c+ * true_type if the type @c T meets the concept definition for a scheduler for+ * error type @c E, otherwise @c false_type.+ */+template <typename T>+struct is_scheduler :+#if defined(GENERATING_DOCUMENTATION)+ integral_constant<bool, automatically_determined>+#else // defined(GENERATING_DOCUMENTATION)+ conditional<+ can_schedule<T>::value,+ detail::is_scheduler_base<T>,+ false_type+ >::type+#endif // defined(GENERATING_DOCUMENTATION)+{+};++#if defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename T>+ASIO_CONSTEXPR const bool is_scheduler_v = is_scheduler<T>::value;++#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++#if defined(ASIO_HAS_CONCEPTS)++template <typename T>+ASIO_CONCEPT scheduler = is_scheduler<T>::value;++#define ASIO_EXECUTION_SCHEDULER ::asio::execution::scheduler++#else // defined(ASIO_HAS_CONCEPTS)++#define ASIO_EXECUTION_SCHEDULER typename++#endif // defined(ASIO_HAS_CONCEPTS)++} // namespace execution+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // !defined(ASIO_NO_DEPRECATED)++#endif // ASIO_EXECUTION_SCHEDULER_HPP
+ link/modules/asio-standalone/asio/include/asio/execution/sender.hpp view
@@ -0,0 +1,316 @@+//+// execution/sender.hpp+// ~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_EXECUTION_SENDER_HPP+#define ASIO_EXECUTION_SENDER_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"++#if !defined(ASIO_NO_DEPRECATED)++#include "asio/detail/type_traits.hpp"+#include "asio/execution/detail/as_invocable.hpp"+#include "asio/execution/detail/void_receiver.hpp"+#include "asio/execution/executor.hpp"+#include "asio/execution/receiver.hpp"++#include "asio/detail/push_options.hpp"++#if defined(ASIO_HAS_ALIAS_TEMPLATES) \+ && defined(ASIO_HAS_VARIADIC_TEMPLATES) \+ && defined(ASIO_HAS_DECLTYPE) \+ && !defined(ASIO_MSVC) || (_MSC_VER >= 1910)+# define ASIO_HAS_DEDUCED_EXECUTION_IS_TYPED_SENDER_TRAIT 1+#endif // defined(ASIO_HAS_ALIAS_TEMPLATES)+ // && defined(ASIO_HAS_VARIADIC_TEMPLATES)+ // && defined(ASIO_HAS_DECLTYPE)+ // && !defined(ASIO_MSVC) || (_MSC_VER >= 1910)++namespace asio {+namespace execution {+namespace detail {++namespace sender_base_ns { struct sender_base {}; }++template <typename S, typename = void>+struct sender_traits_base+{+ typedef void asio_execution_sender_traits_base_is_unspecialised;+};++template <typename S>+struct sender_traits_base<S,+ typename enable_if<+ is_base_of<sender_base_ns::sender_base, S>::value+ >::type>+{+};++template <typename S, typename = void, typename = void, typename = void>+struct has_sender_types : false_type+{+};++#if defined(ASIO_HAS_DEDUCED_EXECUTION_IS_TYPED_SENDER_TRAIT)++template <+ template <+ template <typename...> class Tuple,+ template <typename...> class Variant+ > class>+struct has_value_types+{+ typedef void type;+};++template <+ template <+ template <typename...> class Variant+ > class>+struct has_error_types+{+ typedef void type;+};++template <typename S>+struct has_sender_types<S,+ typename has_value_types<S::template value_types>::type,+ typename has_error_types<S::template error_types>::type,+ typename conditional<S::sends_done, void, void>::type> : true_type+{+};++template <typename S>+struct sender_traits_base<S,+ typename enable_if<+ has_sender_types<S>::value+ >::type>+{+ template <+ template <typename...> class Tuple,+ template <typename...> class Variant>+ using value_types = typename S::template value_types<Tuple, Variant>;++ template <template <typename...> class Variant>+ using error_types = typename S::template error_types<Variant>;++ ASIO_STATIC_CONSTEXPR(bool, sends_done = S::sends_done);+};++#endif // defined(ASIO_HAS_DEDUCED_EXECUTION_IS_TYPED_SENDER_TRAIT)++template <typename S>+struct sender_traits_base<S,+ typename enable_if<+ !has_sender_types<S>::value+ && detail::is_executor_of_impl<S,+ as_invocable<void_receiver, S> >::value+ >::type>+{+#if defined(ASIO_HAS_DEDUCED_EXECUTION_IS_TYPED_SENDER_TRAIT) \+ && defined(ASIO_HAS_STD_EXCEPTION_PTR)++ template <+ template <typename...> class Tuple,+ template <typename...> class Variant>+ using value_types = Variant<Tuple<>>;++ template <template <typename...> class Variant>+ using error_types = Variant<std::exception_ptr>;++ ASIO_STATIC_CONSTEXPR(bool, sends_done = true);++#endif // defined(ASIO_HAS_DEDUCED_EXECUTION_IS_TYPED_SENDER_TRAIT)+ // && defined(ASIO_HAS_STD_EXCEPTION_PTR)+};++} // namespace detail++/// Base class used for tagging senders.+#if defined(GENERATING_DOCUMENTATION)+typedef unspecified sender_base;+#else // defined(GENERATING_DOCUMENTATION)+typedef detail::sender_base_ns::sender_base sender_base;+#endif // defined(GENERATING_DOCUMENTATION)++/// Traits for senders.+template <typename S>+struct sender_traits+#if !defined(GENERATING_DOCUMENTATION)+ : detail::sender_traits_base<S>+#endif // !defined(GENERATING_DOCUMENTATION)+{+};++namespace detail {++template <typename S, typename = void>+struct has_sender_traits : true_type+{+};++template <typename S>+struct has_sender_traits<S,+ typename enable_if<+ is_same<+ typename asio::execution::sender_traits<+ S>::asio_execution_sender_traits_base_is_unspecialised,+ void+ >::value+ >::type> : false_type+{+};++} // namespace detail++/// The is_sender trait detects whether a type T satisfies the+/// execution::sender concept.++/**+ * Class template @c is_sender is a type trait that is derived from @c+ * true_type if the type @c T meets the concept definition for a sender,+ * otherwise @c false_type.+ */+template <typename T>+struct is_sender :+#if defined(GENERATING_DOCUMENTATION)+ integral_constant<bool, automatically_determined>+#else // defined(GENERATING_DOCUMENTATION)+ conditional<+ detail::has_sender_traits<typename remove_cvref<T>::type>::value,+ is_move_constructible<typename remove_cvref<T>::type>,+ false_type+ >::type+#endif // defined(GENERATING_DOCUMENTATION)+{+};++#if defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename T>+ASIO_CONSTEXPR const bool is_sender_v = is_sender<T>::value;++#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++#if defined(ASIO_HAS_CONCEPTS)++template <typename T>+ASIO_CONCEPT sender = is_sender<T>::value;++#define ASIO_EXECUTION_SENDER ::asio::execution::sender++#else // defined(ASIO_HAS_CONCEPTS)++#define ASIO_EXECUTION_SENDER typename++#endif // defined(ASIO_HAS_CONCEPTS)++template <typename S, typename R>+struct can_connect;++/// The is_sender_to trait detects whether a type T satisfies the+/// execution::sender_to concept for some receiver.+/**+ * Class template @c is_sender_to is a type trait that is derived from @c+ * true_type if the type @c T meets the concept definition for a sender+ * for some receiver type R, otherwise @c false.+ */+template <typename T, typename R>+struct is_sender_to :+#if defined(GENERATING_DOCUMENTATION)+ integral_constant<bool, automatically_determined>+#else // defined(GENERATING_DOCUMENTATION)+ integral_constant<bool,+ is_sender<T>::value+ && is_receiver<R>::value+ && can_connect<T, R>::value+ >+#endif // defined(GENERATING_DOCUMENTATION)+{+};++#if defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename T, typename R>+ASIO_CONSTEXPR const bool is_sender_to_v =+ is_sender_to<T, R>::value;++#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++#if defined(ASIO_HAS_CONCEPTS)++template <typename T, typename R>+ASIO_CONCEPT sender_to = is_sender_to<T, R>::value;++#define ASIO_EXECUTION_SENDER_TO(r) \+ ::asio::execution::sender_to<r>++#else // defined(ASIO_HAS_CONCEPTS)++#define ASIO_EXECUTION_SENDER_TO(r) typename++#endif // defined(ASIO_HAS_CONCEPTS)++/// The is_typed_sender trait detects whether a type T satisfies the+/// execution::typed_sender concept.+/**+ * Class template @c is_typed_sender is a type trait that is derived from @c+ * true_type if the type @c T meets the concept definition for a typed sender,+ * otherwise @c false.+ */+template <typename T>+struct is_typed_sender :+#if defined(GENERATING_DOCUMENTATION)+ integral_constant<bool, automatically_determined>+#else // defined(GENERATING_DOCUMENTATION)+ integral_constant<bool,+ is_sender<T>::value+ && detail::has_sender_types<+ sender_traits<typename remove_cvref<T>::type> >::value+ >+#endif // defined(GENERATING_DOCUMENTATION)+{+};++#if defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename T>+ASIO_CONSTEXPR const bool is_typed_sender_v = is_typed_sender<T>::value;++#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++#if defined(ASIO_HAS_CONCEPTS)++template <typename T>+ASIO_CONCEPT typed_sender = is_typed_sender<T>::value;++#define ASIO_EXECUTION_TYPED_SENDER \+ ::asio::execution::typed_sender++#else // defined(ASIO_HAS_CONCEPTS)++#define ASIO_EXECUTION_TYPED_SENDER typename++#endif // defined(ASIO_HAS_CONCEPTS)++} // namespace execution+} // namespace asio++#include "asio/detail/pop_options.hpp"++#include "asio/execution/connect.hpp"++#endif // !defined(ASIO_NO_DEPRECATED)++#endif // ASIO_EXECUTION_SENDER_HPP
+ link/modules/asio-standalone/asio/include/asio/execution/set_done.hpp view
@@ -0,0 +1,255 @@+//+// execution/set_done.hpp+// ~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_EXECUTION_SET_DONE_HPP+#define ASIO_EXECUTION_SET_DONE_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"++#if !defined(ASIO_NO_DEPRECATED)++#include "asio/detail/type_traits.hpp"+#include "asio/traits/set_done_member.hpp"+#include "asio/traits/set_done_free.hpp"++#include "asio/detail/push_options.hpp"++#if defined(GENERATING_DOCUMENTATION)++namespace asio {+namespace execution {++/// A customisation point that delivers a done notification to a receiver.+/**+ * The name <tt>execution::set_done</tt> denotes a customisation point object.+ * The expression <tt>execution::set_done(R)</tt> for some subexpression+ * <tt>R</tt> is expression-equivalent to:+ *+ * @li <tt>R.set_done()</tt>, if that expression is valid. If the function+ * selected does not signal the receiver <tt>R</tt>'s done channel, the+ * program is ill-formed with no diagnostic required.+ *+ * @li Otherwise, <tt>set_done(R)</tt>, if that expression is valid, with+ * overload resolution performed in a context that includes the declaration+ * <tt>void set_done();</tt> and that does not include a declaration of+ * <tt>execution::set_done</tt>. If the function selected by overload+ * resolution does not signal the receiver <tt>R</tt>'s done channel, the+ * program is ill-formed with no diagnostic required.+ *+ * @li Otherwise, <tt>execution::set_done(R)</tt> is ill-formed.+ */+inline constexpr unspecified set_done = unspecified;++/// A type trait that determines whether a @c set_done expression is+/// well-formed.+/**+ * Class template @c can_set_done is a trait that is derived from+ * @c true_type if the expression <tt>execution::set_done(std::declval<R>(),+ * std::declval<E>())</tt> is well formed; otherwise @c false_type.+ */+template <typename R>+struct can_set_done :+ integral_constant<bool, automatically_determined>+{+};++} // namespace execution+} // namespace asio++#else // defined(GENERATING_DOCUMENTATION)++namespace asio_execution_set_done_fn {++using asio::decay;+using asio::declval;+using asio::enable_if;+using asio::traits::set_done_free;+using asio::traits::set_done_member;++void set_done();++enum overload_type+{+ call_member,+ call_free,+ ill_formed+};++template <typename R, typename = void, typename = void>+struct call_traits+{+ ASIO_STATIC_CONSTEXPR(overload_type, overload = ill_formed);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ typedef void result_type;+};++template <typename R>+struct call_traits<R,+ typename enable_if<+ set_done_member<R>::is_valid+ >::type> :+ set_done_member<R>+{+ ASIO_STATIC_CONSTEXPR(overload_type, overload = call_member);+};++template <typename R>+struct call_traits<R,+ typename enable_if<+ !set_done_member<R>::is_valid+ >::type,+ typename enable_if<+ set_done_free<R>::is_valid+ >::type> :+ set_done_free<R>+{+ ASIO_STATIC_CONSTEXPR(overload_type, overload = call_free);+};++struct impl+{+#if defined(ASIO_HAS_MOVE)+ template <typename R>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<R>::overload == call_member,+ typename call_traits<R>::result_type+ >::type+ operator()(R&& r) const+ ASIO_NOEXCEPT_IF((+ call_traits<R>::is_noexcept))+ {+ return ASIO_MOVE_CAST(R)(r).set_done();+ }++ template <typename R>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<R>::overload == call_free,+ typename call_traits<R>::result_type+ >::type+ operator()(R&& r) const+ ASIO_NOEXCEPT_IF((+ call_traits<R>::is_noexcept))+ {+ return set_done(ASIO_MOVE_CAST(R)(r));+ }+#else // defined(ASIO_HAS_MOVE)+ template <typename R>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<R&>::overload == call_member,+ typename call_traits<R&>::result_type+ >::type+ operator()(R& r) const+ ASIO_NOEXCEPT_IF((+ call_traits<R&>::is_noexcept))+ {+ return r.set_done();+ }++ template <typename R>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<const R&>::overload == call_member,+ typename call_traits<const R&>::result_type+ >::type+ operator()(const R& r) const+ ASIO_NOEXCEPT_IF((+ call_traits<const R&>::is_noexcept))+ {+ return r.set_done();+ }++ template <typename R>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<R&>::overload == call_free,+ typename call_traits<R&>::result_type+ >::type+ operator()(R& r) const+ ASIO_NOEXCEPT_IF((+ call_traits<R&>::is_noexcept))+ {+ return set_done(r);+ }++ template <typename R>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<const R&>::overload == call_free,+ typename call_traits<const R&>::result_type+ >::type+ operator()(const R& r) const+ ASIO_NOEXCEPT_IF((+ call_traits<const R&>::is_noexcept))+ {+ return set_done(r);+ }+#endif // defined(ASIO_HAS_MOVE)+};++template <typename T = impl>+struct static_instance+{+ static const T instance;+};++template <typename T>+const T static_instance<T>::instance = {};++} // namespace asio_execution_set_done_fn+namespace asio {+namespace execution {+namespace {++static ASIO_CONSTEXPR const asio_execution_set_done_fn::impl&+ set_done = asio_execution_set_done_fn::static_instance<>::instance;++} // namespace++template <typename R>+struct can_set_done :+ integral_constant<bool,+ asio_execution_set_done_fn::call_traits<R>::overload !=+ asio_execution_set_done_fn::ill_formed>+{+};++#if defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename R>+constexpr bool can_set_done_v = can_set_done<R>::value;++#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename R>+struct is_nothrow_set_done :+ integral_constant<bool,+ asio_execution_set_done_fn::call_traits<R>::is_noexcept>+{+};++#if defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename R>+constexpr bool is_nothrow_set_done_v+ = is_nothrow_set_done<R>::value;++#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++} // namespace execution+} // namespace asio++#endif // defined(GENERATING_DOCUMENTATION)++#include "asio/detail/pop_options.hpp"++#endif // !defined(ASIO_NO_DEPRECATED)++#endif // ASIO_EXECUTION_SET_DONE_HPP
+ link/modules/asio-standalone/asio/include/asio/execution/set_error.hpp view
@@ -0,0 +1,255 @@+//+// execution/set_error.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_EXECUTION_SET_ERROR_HPP+#define ASIO_EXECUTION_SET_ERROR_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"++#if !defined(ASIO_NO_DEPRECATED)++#include "asio/detail/type_traits.hpp"+#include "asio/traits/set_error_member.hpp"+#include "asio/traits/set_error_free.hpp"++#include "asio/detail/push_options.hpp"++#if defined(GENERATING_DOCUMENTATION)++namespace asio {+namespace execution {++/// A customisation point that delivers an error notification to a receiver.+/**+ * The name <tt>execution::set_error</tt> denotes a customisation point object.+ * The expression <tt>execution::set_error(R, E)</tt> for some subexpressions+ * <tt>R</tt> and <tt>E</tt> are expression-equivalent to:+ *+ * @li <tt>R.set_error(E)</tt>, if that expression is valid. If the function+ * selected does not send the error <tt>E</tt> to the receiver <tt>R</tt>'s+ * error channel, the program is ill-formed with no diagnostic required.+ *+ * @li Otherwise, <tt>set_error(R, E)</tt>, if that expression is valid, with+ * overload resolution performed in a context that includes the declaration+ * <tt>void set_error();</tt> and that does not include a declaration of+ * <tt>execution::set_error</tt>. If the function selected by overload+ * resolution does not send the error <tt>E</tt> to the receiver <tt>R</tt>'s+ * error channel, the program is ill-formed with no diagnostic required.+ *+ * @li Otherwise, <tt>execution::set_error(R, E)</tt> is ill-formed.+ */+inline constexpr unspecified set_error = unspecified;++/// A type trait that determines whether a @c set_error expression is+/// well-formed.+/**+ * Class template @c can_set_error is a trait that is derived from+ * @c true_type if the expression <tt>execution::set_error(std::declval<R>(),+ * std::declval<E>())</tt> is well formed; otherwise @c false_type.+ */+template <typename R, typename E>+struct can_set_error :+ integral_constant<bool, automatically_determined>+{+};++} // namespace execution+} // namespace asio++#else // defined(GENERATING_DOCUMENTATION)++namespace asio_execution_set_error_fn {++using asio::decay;+using asio::declval;+using asio::enable_if;+using asio::traits::set_error_free;+using asio::traits::set_error_member;++void set_error();++enum overload_type+{+ call_member,+ call_free,+ ill_formed+};++template <typename R, typename E, typename = void, typename = void>+struct call_traits+{+ ASIO_STATIC_CONSTEXPR(overload_type, overload = ill_formed);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ typedef void result_type;+};++template <typename R, typename E>+struct call_traits<R, void(E),+ typename enable_if<+ set_error_member<R, E>::is_valid+ >::type> :+ set_error_member<R, E>+{+ ASIO_STATIC_CONSTEXPR(overload_type, overload = call_member);+};++template <typename R, typename E>+struct call_traits<R, void(E),+ typename enable_if<+ !set_error_member<R, E>::is_valid+ >::type,+ typename enable_if<+ set_error_free<R, E>::is_valid+ >::type> :+ set_error_free<R, E>+{+ ASIO_STATIC_CONSTEXPR(overload_type, overload = call_free);+};++struct impl+{+#if defined(ASIO_HAS_MOVE)+ template <typename R, typename E>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<R, void(E)>::overload == call_member,+ typename call_traits<R, void(E)>::result_type+ >::type+ operator()(R&& r, E&& e) const+ ASIO_NOEXCEPT_IF((+ call_traits<R, void(E)>::is_noexcept))+ {+ return ASIO_MOVE_CAST(R)(r).set_error(ASIO_MOVE_CAST(E)(e));+ }++ template <typename R, typename E>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<R, void(E)>::overload == call_free,+ typename call_traits<R, void(E)>::result_type+ >::type+ operator()(R&& r, E&& e) const+ ASIO_NOEXCEPT_IF((+ call_traits<R, void(E)>::is_noexcept))+ {+ return set_error(ASIO_MOVE_CAST(R)(r), ASIO_MOVE_CAST(E)(e));+ }+#else // defined(ASIO_HAS_MOVE)+ template <typename R, typename E>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<R&, void(const E&)>::overload == call_member,+ typename call_traits<R&, void(const E&)>::result_type+ >::type+ operator()(R& r, const E& e) const+ ASIO_NOEXCEPT_IF((+ call_traits<R&, void(const E&)>::is_noexcept))+ {+ return r.set_error(e);+ }++ template <typename R, typename E>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<const R&, void(const E&)>::overload == call_member,+ typename call_traits<const R&, void(const E&)>::result_type+ >::type+ operator()(const R& r, const E& e) const+ ASIO_NOEXCEPT_IF((+ call_traits<const R&, void(const E&)>::is_noexcept))+ {+ return r.set_error(e);+ }++ template <typename R, typename E>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<R&, void(const E&)>::overload == call_free,+ typename call_traits<R&, void(const E&)>::result_type+ >::type+ operator()(R& r, const E& e) const+ ASIO_NOEXCEPT_IF((+ call_traits<R&, void(const E&)>::is_noexcept))+ {+ return set_error(r, e);+ }++ template <typename R, typename E>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<const R&, void(const E&)>::overload == call_free,+ typename call_traits<const R&, void(const E&)>::result_type+ >::type+ operator()(const R& r, const E& e) const+ ASIO_NOEXCEPT_IF((+ call_traits<const R&, void(const E&)>::is_noexcept))+ {+ return set_error(r, e);+ }+#endif // defined(ASIO_HAS_MOVE)+};++template <typename T = impl>+struct static_instance+{+ static const T instance;+};++template <typename T>+const T static_instance<T>::instance = {};++} // namespace asio_execution_set_error_fn+namespace asio {+namespace execution {+namespace {++static ASIO_CONSTEXPR const asio_execution_set_error_fn::impl&+ set_error = asio_execution_set_error_fn::static_instance<>::instance;++} // namespace++template <typename R, typename E>+struct can_set_error :+ integral_constant<bool,+ asio_execution_set_error_fn::call_traits<R, void(E)>::overload !=+ asio_execution_set_error_fn::ill_formed>+{+};++#if defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename R, typename E>+constexpr bool can_set_error_v = can_set_error<R, E>::value;++#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename R, typename E>+struct is_nothrow_set_error :+ integral_constant<bool,+ asio_execution_set_error_fn::call_traits<R, void(E)>::is_noexcept>+{+};++#if defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename R, typename E>+constexpr bool is_nothrow_set_error_v+ = is_nothrow_set_error<R, E>::value;++#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++} // namespace execution+} // namespace asio++#endif // defined(GENERATING_DOCUMENTATION)++#include "asio/detail/pop_options.hpp"++#endif // !defined(ASIO_NO_DEPRECATED)++#endif // ASIO_EXECUTION_SET_ERROR_HPP
+ link/modules/asio-standalone/asio/include/asio/execution/set_value.hpp view
@@ -0,0 +1,488 @@+//+// execution/set_value.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_EXECUTION_SET_VALUE_HPP+#define ASIO_EXECUTION_SET_VALUE_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"++#if !defined(ASIO_NO_DEPRECATED)++#include "asio/detail/type_traits.hpp"+#include "asio/detail/variadic_templates.hpp"+#include "asio/traits/set_value_member.hpp"+#include "asio/traits/set_value_free.hpp"++#include "asio/detail/push_options.hpp"++#if defined(GENERATING_DOCUMENTATION)++namespace asio {+namespace execution {++/// A customisation point that delivers a value to a receiver.+/**+ * The name <tt>execution::set_value</tt> denotes a customisation point object.+ * The expression <tt>execution::set_value(R, Vs...)</tt> for some+ * subexpressions <tt>R</tt> and <tt>Vs...</tt> is expression-equivalent to:+ *+ * @li <tt>R.set_value(Vs...)</tt>, if that expression is valid. If the+ * function selected does not send the value(s) <tt>Vs...</tt> to the receiver+ * <tt>R</tt>'s value channel, the program is ill-formed with no diagnostic+ * required.+ *+ * @li Otherwise, <tt>set_value(R, Vs...)</tt>, if that expression is valid,+ * with overload resolution performed in a context that includes the+ * declaration <tt>void set_value();</tt> and that does not include a+ * declaration of <tt>execution::set_value</tt>. If the function selected by+ * overload resolution does not send the value(s) <tt>Vs...</tt> to the+ * receiver <tt>R</tt>'s value channel, the program is ill-formed with no+ * diagnostic required.+ *+ * @li Otherwise, <tt>execution::set_value(R, Vs...)</tt> is ill-formed.+ */+inline constexpr unspecified set_value = unspecified;++/// A type trait that determines whether a @c set_value expression is+/// well-formed.+/**+ * Class template @c can_set_value is a trait that is derived from+ * @c true_type if the expression <tt>execution::set_value(std::declval<R>(),+ * std::declval<Vs>()...)</tt> is well formed; otherwise @c false_type.+ */+template <typename R, typename... Vs>+struct can_set_value :+ integral_constant<bool, automatically_determined>+{+};++} // namespace execution+} // namespace asio++#else // defined(GENERATING_DOCUMENTATION)++namespace asio_execution_set_value_fn {++using asio::decay;+using asio::declval;+using asio::enable_if;+using asio::traits::set_value_free;+using asio::traits::set_value_member;++void set_value();++enum overload_type+{+ call_member,+ call_free,+ ill_formed+};++template <typename R, typename Vs, typename = void, typename = void>+struct call_traits+{+ ASIO_STATIC_CONSTEXPR(overload_type, overload = ill_formed);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ typedef void result_type;+};++template <typename R, typename Vs>+struct call_traits<R, Vs,+ typename enable_if<+ set_value_member<R, Vs>::is_valid+ >::type> :+ set_value_member<R, Vs>+{+ ASIO_STATIC_CONSTEXPR(overload_type, overload = call_member);+};++template <typename R, typename Vs>+struct call_traits<R, Vs,+ typename enable_if<+ !set_value_member<R, Vs>::is_valid+ >::type,+ typename enable_if<+ set_value_free<R, Vs>::is_valid+ >::type> :+ set_value_free<R, Vs>+{+ ASIO_STATIC_CONSTEXPR(overload_type, overload = call_free);+};++struct impl+{+#if defined(ASIO_HAS_MOVE)++#if defined(ASIO_HAS_VARIADIC_TEMPLATES)++ template <typename R, typename... Vs>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<R, void(Vs...)>::overload == call_member,+ typename call_traits<R, void(Vs...)>::result_type+ >::type+ operator()(R&& r, Vs&&... v) const+ ASIO_NOEXCEPT_IF((+ call_traits<R, void(Vs...)>::is_noexcept))+ {+ return ASIO_MOVE_CAST(R)(r).set_value(ASIO_MOVE_CAST(Vs)(v)...);+ }++ template <typename R, typename... Vs>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<R, void(Vs...)>::overload == call_free,+ typename call_traits<R, void(Vs...)>::result_type+ >::type+ operator()(R&& r, Vs&&... v) const+ ASIO_NOEXCEPT_IF((+ call_traits<R, void(Vs...)>::is_noexcept))+ {+ return set_value(ASIO_MOVE_CAST(R)(r),+ ASIO_MOVE_CAST(Vs)(v)...);+ }++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++ template <typename R>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<R, void()>::overload == call_member,+ typename call_traits<R, void()>::result_type+ >::type+ operator()(R&& r) const+ ASIO_NOEXCEPT_IF((+ call_traits<R, void()>::is_noexcept))+ {+ return ASIO_MOVE_CAST(R)(r).set_value();+ }++ template <typename R>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<R, void()>::overload == call_free,+ typename call_traits<R, void()>::result_type+ >::type+ operator()(R&& r) const+ ASIO_NOEXCEPT_IF((+ call_traits<R, void()>::is_noexcept))+ {+ return set_value(ASIO_MOVE_CAST(R)(r));+ }++#define ASIO_PRIVATE_SET_VALUE_CALL_DEF(n) \+ template <typename R, ASIO_VARIADIC_TPARAMS(n)> \+ ASIO_CONSTEXPR typename enable_if< \+ call_traits<R, \+ void(ASIO_VARIADIC_TARGS(n))>::overload == call_member, \+ typename call_traits<R, void(ASIO_VARIADIC_TARGS(n))>::result_type \+ >::type \+ operator()(R&& r, ASIO_VARIADIC_MOVE_PARAMS(n)) const \+ ASIO_NOEXCEPT_IF(( \+ call_traits<R, void(ASIO_VARIADIC_TARGS(n))>::is_noexcept)) \+ { \+ return ASIO_MOVE_CAST(R)(r).set_value( \+ ASIO_VARIADIC_MOVE_ARGS(n)); \+ } \+ \+ template <typename R, ASIO_VARIADIC_TPARAMS(n)> \+ ASIO_CONSTEXPR typename enable_if< \+ call_traits<R, void(ASIO_VARIADIC_TARGS(n))>::overload == call_free, \+ typename call_traits<R, void(ASIO_VARIADIC_TARGS(n))>::result_type \+ >::type \+ operator()(R&& r, ASIO_VARIADIC_MOVE_PARAMS(n)) const \+ ASIO_NOEXCEPT_IF(( \+ call_traits<R, void(ASIO_VARIADIC_TARGS(n))>::is_noexcept)) \+ { \+ return set_value(ASIO_MOVE_CAST(R)(r), \+ ASIO_VARIADIC_MOVE_ARGS(n)); \+ } \+ /**/+ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_SET_VALUE_CALL_DEF)+#undef ASIO_PRIVATE_SET_VALUE_CALL_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++#else // defined(ASIO_HAS_MOVE)++#if defined(ASIO_HAS_VARIADIC_TEMPLATES)++ template <typename R, typename... Vs>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<R&, void(const Vs&...)>::overload == call_member,+ typename call_traits<R&, void(const Vs&...)>::result_type+ >::type+ operator()(R& r, const Vs&... v) const+ ASIO_NOEXCEPT_IF((+ call_traits<R&, void(const Vs&...)>::is_noexcept))+ {+ return r.set_value(v...);+ }++ template <typename R, typename... Vs>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<const R&, void(const Vs&...)>::overload == call_member,+ typename call_traits<const R&, void(const Vs&...)>::result_type+ >::type+ operator()(const R& r, const Vs&... v) const+ ASIO_NOEXCEPT_IF((+ call_traits<const R&, void(const Vs&...)>::is_noexcept))+ {+ return r.set_value(v...);+ }++ template <typename R, typename... Vs>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<R&, void(const Vs&...)>::overload == call_free,+ typename call_traits<R&, void(const Vs&...)>::result_type+ >::type+ operator()(R& r, const Vs&... v) const+ ASIO_NOEXCEPT_IF((+ call_traits<R&, void(const Vs&...)>::is_noexcept))+ {+ return set_value(r, v...);+ }++ template <typename R, typename... Vs>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<const R&, void(const Vs&...)>::overload == call_free,+ typename call_traits<const R&, void(const Vs&...)>::result_type+ >::type+ operator()(const R& r, const Vs&... v) const+ ASIO_NOEXCEPT_IF((+ call_traits<const R&, void(const Vs&...)>::is_noexcept))+ {+ return set_value(r, v...);+ }++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++ template <typename R>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<R&, void()>::overload == call_member,+ typename call_traits<R&, void()>::result_type+ >::type+ operator()(R& r) const+ ASIO_NOEXCEPT_IF((+ call_traits<R&, void()>::is_noexcept))+ {+ return r.set_value();+ }++ template <typename R>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<const R&, void()>::overload == call_member,+ typename call_traits<const R&, void()>::result_type+ >::type+ operator()(const R& r) const+ ASIO_NOEXCEPT_IF((+ call_traits<const R&, void()>::is_noexcept))+ {+ return r.set_value();+ }++ template <typename R>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<R&, void()>::overload == call_free,+ typename call_traits<R&, void()>::result_type+ >::type+ operator()(R& r) const+ ASIO_NOEXCEPT_IF((+ call_traits<R&, void()>::is_noexcept))+ {+ return set_value(r);+ }++ template <typename R>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<const R&, void()>::overload == call_free,+ typename call_traits<const R&, void()>::result_type+ >::type+ operator()(const R& r) const+ ASIO_NOEXCEPT_IF((+ call_traits<const R&, void()>::is_noexcept))+ {+ return set_value(r);+ }++#define ASIO_PRIVATE_SET_VALUE_CALL_DEF(n) \+ template <typename R, ASIO_VARIADIC_TPARAMS(n)> \+ ASIO_CONSTEXPR typename enable_if< \+ call_traits<R&, \+ void(ASIO_VARIADIC_TARGS(n))>::overload == call_member, \+ typename call_traits<R&, void(ASIO_VARIADIC_TARGS(n))>::result_type \+ >::type \+ operator()(R& r, ASIO_VARIADIC_MOVE_PARAMS(n)) const \+ ASIO_NOEXCEPT_IF(( \+ call_traits<R&, void(ASIO_VARIADIC_TARGS(n))>::is_noexcept)) \+ { \+ return r.set_value(ASIO_VARIADIC_MOVE_ARGS(n)); \+ } \+ \+ template <typename R, ASIO_VARIADIC_TPARAMS(n)> \+ ASIO_CONSTEXPR typename enable_if< \+ call_traits<const R&, \+ void(ASIO_VARIADIC_TARGS(n))>::overload == call_member, \+ typename call_traits<const R&, \+ void(ASIO_VARIADIC_TARGS(n))>::result_type \+ >::type \+ operator()(const R& r, ASIO_VARIADIC_MOVE_PARAMS(n)) const \+ ASIO_NOEXCEPT_IF(( \+ call_traits<const R&, void(ASIO_VARIADIC_TARGS(n))>::is_noexcept)) \+ { \+ return r.set_value(ASIO_VARIADIC_MOVE_ARGS(n)); \+ } \+ \+ template <typename R, ASIO_VARIADIC_TPARAMS(n)> \+ ASIO_CONSTEXPR typename enable_if< \+ call_traits<R&, \+ void(ASIO_VARIADIC_TARGS(n))>::overload == call_free, \+ typename call_traits<R&, void(ASIO_VARIADIC_TARGS(n))>::result_type \+ >::type \+ operator()(R& r, ASIO_VARIADIC_MOVE_PARAMS(n)) const \+ ASIO_NOEXCEPT_IF(( \+ call_traits<R&, void(ASIO_VARIADIC_TARGS(n))>::is_noexcept)) \+ { \+ return set_value(r, ASIO_VARIADIC_MOVE_ARGS(n)); \+ } \+ \+ template <typename R, ASIO_VARIADIC_TPARAMS(n)> \+ ASIO_CONSTEXPR typename enable_if< \+ call_traits<const R&, \+ void(ASIO_VARIADIC_TARGS(n))>::overload == call_free, \+ typename call_traits<const R&, \+ void(ASIO_VARIADIC_TARGS(n))>::result_type \+ >::type \+ operator()(const R& r, ASIO_VARIADIC_MOVE_PARAMS(n)) const \+ ASIO_NOEXCEPT_IF(( \+ call_traits<const R&, void(ASIO_VARIADIC_TARGS(n))>::is_noexcept)) \+ { \+ return set_value(r, ASIO_VARIADIC_MOVE_ARGS(n)); \+ } \+ /**/+ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_SET_VALUE_CALL_DEF)+#undef ASIO_PRIVATE_SET_VALUE_CALL_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++#endif // defined(ASIO_HAS_MOVE)+};++template <typename T = impl>+struct static_instance+{+ static const T instance;+};++template <typename T>+const T static_instance<T>::instance = {};++} // namespace asio_execution_set_value_fn+namespace asio {+namespace execution {+namespace {++static ASIO_CONSTEXPR const asio_execution_set_value_fn::impl&+ set_value = asio_execution_set_value_fn::static_instance<>::instance;++} // namespace++#if defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename R, typename... Vs>+struct can_set_value :+ integral_constant<bool,+ asio_execution_set_value_fn::call_traits<R, void(Vs...)>::overload !=+ asio_execution_set_value_fn::ill_formed>+{+};++#if defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename R, typename... Vs>+constexpr bool can_set_value_v = can_set_value<R, Vs...>::value;++#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename R, typename... Vs>+struct is_nothrow_set_value :+ integral_constant<bool,+ asio_execution_set_value_fn::call_traits<R, void(Vs...)>::is_noexcept>+{+};++#if defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename R, typename... Vs>+constexpr bool is_nothrow_set_value_v+ = is_nothrow_set_value<R, Vs...>::value;++#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename R, typename = void,+ typename = void, typename = void, typename = void, typename = void,+ typename = void, typename = void, typename = void, typename = void>+struct can_set_value;++template <typename R, typename = void,+ typename = void, typename = void, typename = void, typename = void,+ typename = void, typename = void, typename = void, typename = void>+struct is_nothrow_set_value;++template <typename R>+struct can_set_value<R> :+ integral_constant<bool,+ asio_execution_set_value_fn::call_traits<R, void()>::overload !=+ asio_execution_set_value_fn::ill_formed>+{+};++template <typename R>+struct is_nothrow_set_value<R> :+ integral_constant<bool,+ asio_execution_set_value_fn::call_traits<R, void()>::is_noexcept>+{+};++#define ASIO_PRIVATE_SET_VALUE_TRAITS_DEF(n) \+ template <typename R, ASIO_VARIADIC_TPARAMS(n)> \+ struct can_set_value<R, ASIO_VARIADIC_TARGS(n)> : \+ integral_constant<bool, \+ asio_execution_set_value_fn::call_traits<R, \+ void(ASIO_VARIADIC_TARGS(n))>::overload != \+ asio_execution_set_value_fn::ill_formed> \+ { \+ }; \+ \+ template <typename R, ASIO_VARIADIC_TPARAMS(n)> \+ struct is_nothrow_set_value<R, ASIO_VARIADIC_TARGS(n)> : \+ integral_constant<bool, \+ asio_execution_set_value_fn::call_traits<R, \+ void(ASIO_VARIADIC_TARGS(n))>::is_noexcept> \+ { \+ }; \+ /**/+ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_SET_VALUE_TRAITS_DEF)+#undef ASIO_PRIVATE_SET_VALUE_TRAITS_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++} // namespace execution+} // namespace asio++#endif // defined(GENERATING_DOCUMENTATION)++#include "asio/detail/pop_options.hpp"++#endif // !defined(ASIO_NO_DEPRECATED)++#endif // ASIO_EXECUTION_SET_VALUE_HPP
+ link/modules/asio-standalone/asio/include/asio/execution/start.hpp view
@@ -0,0 +1,252 @@+//+// execution/start.hpp+// ~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_EXECUTION_START_HPP+#define ASIO_EXECUTION_START_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"++#if !defined(ASIO_NO_DEPRECATED)++#include "asio/detail/type_traits.hpp"+#include "asio/traits/start_member.hpp"+#include "asio/traits/start_free.hpp"++#include "asio/detail/push_options.hpp"++#if defined(GENERATING_DOCUMENTATION)++namespace asio {+namespace execution {++/// A customisation point that notifies an operation state object to start+/// its associated operation.+/**+ * The name <tt>execution::start</tt> denotes a customisation point object.+ * The expression <tt>execution::start(R)</tt> for some subexpression+ * <tt>R</tt> is expression-equivalent to:+ *+ * @li <tt>R.start()</tt>, if that expression is valid.+ *+ * @li Otherwise, <tt>start(R)</tt>, if that expression is valid, with+ * overload resolution performed in a context that includes the declaration+ * <tt>void start();</tt> and that does not include a declaration of+ * <tt>execution::start</tt>.+ *+ * @li Otherwise, <tt>execution::start(R)</tt> is ill-formed.+ */+inline constexpr unspecified start = unspecified;++/// A type trait that determines whether a @c start expression is+/// well-formed.+/**+ * Class template @c can_start is a trait that is derived from+ * @c true_type if the expression <tt>execution::start(std::declval<R>(),+ * std::declval<E>())</tt> is well formed; otherwise @c false_type.+ */+template <typename R>+struct can_start :+ integral_constant<bool, automatically_determined>+{+};++} // namespace execution+} // namespace asio++#else // defined(GENERATING_DOCUMENTATION)++namespace asio_execution_start_fn {++using asio::decay;+using asio::declval;+using asio::enable_if;+using asio::traits::start_free;+using asio::traits::start_member;++void start();++enum overload_type+{+ call_member,+ call_free,+ ill_formed+};++template <typename R, typename = void, typename = void>+struct call_traits+{+ ASIO_STATIC_CONSTEXPR(overload_type, overload = ill_formed);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ typedef void result_type;+};++template <typename R>+struct call_traits<R,+ typename enable_if<+ start_member<R>::is_valid+ >::type> :+ start_member<R>+{+ ASIO_STATIC_CONSTEXPR(overload_type, overload = call_member);+};++template <typename R>+struct call_traits<R,+ typename enable_if<+ !start_member<R>::is_valid+ >::type,+ typename enable_if<+ start_free<R>::is_valid+ >::type> :+ start_free<R>+{+ ASIO_STATIC_CONSTEXPR(overload_type, overload = call_free);+};++struct impl+{+#if defined(ASIO_HAS_MOVE)+ template <typename R>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<R>::overload == call_member,+ typename call_traits<R>::result_type+ >::type+ operator()(R&& r) const+ ASIO_NOEXCEPT_IF((+ call_traits<R>::is_noexcept))+ {+ return ASIO_MOVE_CAST(R)(r).start();+ }++ template <typename R>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<R>::overload == call_free,+ typename call_traits<R>::result_type+ >::type+ operator()(R&& r) const+ ASIO_NOEXCEPT_IF((+ call_traits<R>::is_noexcept))+ {+ return start(ASIO_MOVE_CAST(R)(r));+ }+#else // defined(ASIO_HAS_MOVE)+ template <typename R>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<R&>::overload == call_member,+ typename call_traits<R&>::result_type+ >::type+ operator()(R& r) const+ ASIO_NOEXCEPT_IF((+ call_traits<R&>::is_noexcept))+ {+ return r.start();+ }++ template <typename R>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<const R&>::overload == call_member,+ typename call_traits<const R&>::result_type+ >::type+ operator()(const R& r) const+ ASIO_NOEXCEPT_IF((+ call_traits<const R&>::is_noexcept))+ {+ return r.start();+ }++ template <typename R>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<R&>::overload == call_free,+ typename call_traits<R&>::result_type+ >::type+ operator()(R& r) const+ ASIO_NOEXCEPT_IF((+ call_traits<R&>::is_noexcept))+ {+ return start(r);+ }++ template <typename R>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<const R&>::overload == call_free,+ typename call_traits<const R&>::result_type+ >::type+ operator()(const R& r) const+ ASIO_NOEXCEPT_IF((+ call_traits<const R&>::is_noexcept))+ {+ return start(r);+ }+#endif // defined(ASIO_HAS_MOVE)+};++template <typename T = impl>+struct static_instance+{+ static const T instance;+};++template <typename T>+const T static_instance<T>::instance = {};++} // namespace asio_execution_start_fn+namespace asio {+namespace execution {+namespace {++static ASIO_CONSTEXPR const asio_execution_start_fn::impl&+ start = asio_execution_start_fn::static_instance<>::instance;++} // namespace++template <typename R>+struct can_start :+ integral_constant<bool,+ asio_execution_start_fn::call_traits<R>::overload !=+ asio_execution_start_fn::ill_formed>+{+};++#if defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename R>+constexpr bool can_start_v = can_start<R>::value;++#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename R>+struct is_nothrow_start :+ integral_constant<bool,+ asio_execution_start_fn::call_traits<R>::is_noexcept>+{+};++#if defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename R>+constexpr bool is_nothrow_start_v+ = is_nothrow_start<R>::value;++#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++} // namespace execution+} // namespace asio++#endif // defined(GENERATING_DOCUMENTATION)++#include "asio/detail/pop_options.hpp"++#endif // !defined(ASIO_NO_DEPRECATED)++#endif // ASIO_EXECUTION_START_HPP
+ link/modules/asio-standalone/asio/include/asio/execution/submit.hpp view
@@ -0,0 +1,455 @@+//+// execution/submit.hpp+// ~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_EXECUTION_SUBMIT_HPP+#define ASIO_EXECUTION_SUBMIT_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"++#if !defined(ASIO_NO_DEPRECATED)++#include "asio/detail/type_traits.hpp"+#include "asio/execution/detail/submit_receiver.hpp"+#include "asio/execution/executor.hpp"+#include "asio/execution/receiver.hpp"+#include "asio/execution/sender.hpp"+#include "asio/execution/start.hpp"+#include "asio/traits/submit_member.hpp"+#include "asio/traits/submit_free.hpp"++#include "asio/detail/push_options.hpp"++#if defined(GENERATING_DOCUMENTATION)++namespace asio {+namespace execution {++/// A customisation point that submits a sender to a receiver.+/**+ * The name <tt>execution::submit</tt> denotes a customisation point object. For+ * some subexpressions <tt>s</tt> and <tt>r</tt>, let <tt>S</tt> be a type such+ * that <tt>decltype((s))</tt> is <tt>S</tt> and let <tt>R</tt> be a type such+ * that <tt>decltype((r))</tt> is <tt>R</tt>. The expression+ * <tt>execution::submit(s, r)</tt> is ill-formed if <tt>sender_to<S, R></tt> is+ * not <tt>true</tt>. Otherwise, it is expression-equivalent to:+ *+ * @li <tt>s.submit(r)</tt>, if that expression is valid and <tt>S</tt> models+ * <tt>sender</tt>. If the function selected does not submit the receiver+ * object <tt>r</tt> via the sender <tt>s</tt>, the program is ill-formed with+ * no diagnostic required.+ *+ * @li Otherwise, <tt>submit(s, r)</tt>, if that expression is valid and+ * <tt>S</tt> models <tt>sender</tt>, with overload resolution performed in a+ * context that includes the declaration <tt>void submit();</tt> and that does+ * not include a declaration of <tt>execution::submit</tt>. If the function+ * selected by overload resolution does not submit the receiver object+ * <tt>r</tt> via the sender <tt>s</tt>, the program is ill-formed with no+ * diagnostic required.+ *+ * @li Otherwise, <tt>execution::start((new submit_receiver<S,+ * R>{s,r})->state_)</tt>, where <tt>submit_receiver</tt> is an+ * implementation-defined class template equivalent to:+ * @code template<class S, class R>+ * struct submit_receiver {+ * struct wrap {+ * submit_receiver * p_;+ * template<class...As>+ * requires receiver_of<R, As...>+ * void set_value(As&&... as) &&+ * noexcept(is_nothrow_receiver_of_v<R, As...>) {+ * execution::set_value(std::move(p_->r_), (As&&) as...);+ * delete p_;+ * }+ * template<class E>+ * requires receiver<R, E>+ * void set_error(E&& e) && noexcept {+ * execution::set_error(std::move(p_->r_), (E&&) e);+ * delete p_;+ * }+ * void set_done() && noexcept {+ * execution::set_done(std::move(p_->r_));+ * delete p_;+ * }+ * };+ * remove_cvref_t<R> r_;+ * connect_result_t<S, wrap> state_;+ * submit_receiver(S&& s, R&& r)+ * : r_((R&&) r)+ * , state_(execution::connect((S&&) s, wrap{this})) {}+ * };+ * @endcode+ */+inline constexpr unspecified submit = unspecified;++/// A type trait that determines whether a @c submit expression is+/// well-formed.+/**+ * Class template @c can_submit is a trait that is derived from+ * @c true_type if the expression <tt>execution::submit(std::declval<R>(),+ * std::declval<E>())</tt> is well formed; otherwise @c false_type.+ */+template <typename S, typename R>+struct can_submit :+ integral_constant<bool, automatically_determined>+{+};++} // namespace execution+} // namespace asio++#else // defined(GENERATING_DOCUMENTATION)++namespace asio_execution_submit_fn {++using asio::declval;+using asio::enable_if;+using asio::execution::is_sender_to;+using asio::traits::submit_free;+using asio::traits::submit_member;++void submit();++enum overload_type+{+ call_member,+ call_free,+ adapter,+ ill_formed+};++template <typename S, typename R, typename = void,+ typename = void, typename = void>+struct call_traits+{+ ASIO_STATIC_CONSTEXPR(overload_type, overload = ill_formed);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ typedef void result_type;+};++template <typename S, typename R>+struct call_traits<S, void(R),+ typename enable_if<+ submit_member<S, R>::is_valid+ >::type,+ typename enable_if<+ is_sender_to<S, R>::value+ >::type> :+ submit_member<S, R>+{+ ASIO_STATIC_CONSTEXPR(overload_type, overload = call_member);+};++template <typename S, typename R>+struct call_traits<S, void(R),+ typename enable_if<+ !submit_member<S, R>::is_valid+ >::type,+ typename enable_if<+ submit_free<S, R>::is_valid+ >::type,+ typename enable_if<+ is_sender_to<S, R>::value+ >::type> :+ submit_free<S, R>+{+ ASIO_STATIC_CONSTEXPR(overload_type, overload = call_free);+};++template <typename S, typename R>+struct call_traits<S, void(R),+ typename enable_if<+ !submit_member<S, R>::is_valid+ >::type,+ typename enable_if<+ !submit_free<S, R>::is_valid+ >::type,+ typename enable_if<+ is_sender_to<S, R>::value+ >::type>+{+ ASIO_STATIC_CONSTEXPR(overload_type, overload = adapter);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ typedef void result_type;+};++struct impl+{+#if defined(ASIO_HAS_MOVE)+ template <typename S, typename R>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<S, void(R)>::overload == call_member,+ typename call_traits<S, void(R)>::result_type+ >::type+ operator()(S&& s, R&& r) const+ ASIO_NOEXCEPT_IF((+ call_traits<S, void(R)>::is_noexcept))+ {+ return ASIO_MOVE_CAST(S)(s).submit(ASIO_MOVE_CAST(R)(r));+ }++ template <typename S, typename R>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<S, void(R)>::overload == call_free,+ typename call_traits<S, void(R)>::result_type+ >::type+ operator()(S&& s, R&& r) const+ ASIO_NOEXCEPT_IF((+ call_traits<S, void(R)>::is_noexcept))+ {+ return submit(ASIO_MOVE_CAST(S)(s), ASIO_MOVE_CAST(R)(r));+ }++ template <typename S, typename R>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<S, void(R)>::overload == adapter,+ typename call_traits<S, void(R)>::result_type+ >::type+ operator()(S&& s, R&& r) const+ ASIO_NOEXCEPT_IF((+ call_traits<S, void(R)>::is_noexcept))+ {+ return asio::execution::start(+ (new asio::execution::detail::submit_receiver<S, R>(+ ASIO_MOVE_CAST(S)(s), ASIO_MOVE_CAST(R)(r)))->state_);+ }+#else // defined(ASIO_HAS_MOVE)+ template <typename S, typename R>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<S&, void(R&)>::overload == call_member,+ typename call_traits<S&, void(R&)>::result_type+ >::type+ operator()(S& s, R& r) const+ ASIO_NOEXCEPT_IF((+ call_traits<S&, void(R&)>::is_noexcept))+ {+ return s.submit(r);+ }++ template <typename S, typename R>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<const S&, void(R&)>::overload == call_member,+ typename call_traits<const S&, void(R&)>::result_type+ >::type+ operator()(const S& s, R& r) const+ ASIO_NOEXCEPT_IF((+ call_traits<const S&, void(R&)>::is_noexcept))+ {+ return s.submit(r);+ }++ template <typename S, typename R>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<S&, void(R&)>::overload == call_free,+ typename call_traits<S&, void(R&)>::result_type+ >::type+ operator()(S& s, R& r) const+ ASIO_NOEXCEPT_IF((+ call_traits<S&, void(R&)>::is_noexcept))+ {+ return submit(s, r);+ }++ template <typename S, typename R>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<const S&, void(R&)>::overload == call_free,+ typename call_traits<const S&, void(R&)>::result_type+ >::type+ operator()(const S& s, R& r) const+ ASIO_NOEXCEPT_IF((+ call_traits<const S&, void(R&)>::is_noexcept))+ {+ return submit(s, r);+ }++ template <typename S, typename R>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<S&, void(R&)>::overload == adapter,+ typename call_traits<S&, void(R&)>::result_type+ >::type+ operator()(S& s, R& r) const+ ASIO_NOEXCEPT_IF((+ call_traits<S&, void(R&)>::is_noexcept))+ {+ return asio::execution::start(+ (new asio::execution::detail::submit_receiver<+ S&, R&>(s, r))->state_);+ }++ template <typename S, typename R>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<const S&, void(R&)>::overload == adapter,+ typename call_traits<const S&, void(R&)>::result_type+ >::type+ operator()(const S& s, R& r) const+ ASIO_NOEXCEPT_IF((+ call_traits<const S&, void(R&)>::is_noexcept))+ {+ asio::execution::start(+ (new asio::execution::detail::submit_receiver<+ const S&, R&>(s, r))->state_);+ }++ template <typename S, typename R>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<S&, void(const R&)>::overload == call_member,+ typename call_traits<S&, void(const R&)>::result_type+ >::type+ operator()(S& s, const R& r) const+ ASIO_NOEXCEPT_IF((+ call_traits<S&, void(const R&)>::is_noexcept))+ {+ return s.submit(r);+ }++ template <typename S, typename R>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<const S&, void(const R&)>::overload == call_member,+ typename call_traits<const S&, void(const R&)>::result_type+ >::type+ operator()(const S& s, const R& r) const+ ASIO_NOEXCEPT_IF((+ call_traits<const S&, void(const R&)>::is_noexcept))+ {+ return s.submit(r);+ }++ template <typename S, typename R>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<S&, void(const R&)>::overload == call_free,+ typename call_traits<S&, void(const R&)>::result_type+ >::type+ operator()(S& s, const R& r) const+ ASIO_NOEXCEPT_IF((+ call_traits<S&, void(const R&)>::is_noexcept))+ {+ return submit(s, r);+ }++ template <typename S, typename R>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<const S&, void(const R&)>::overload == call_free,+ typename call_traits<const S&, void(const R&)>::result_type+ >::type+ operator()(const S& s, const R& r) const+ ASIO_NOEXCEPT_IF((+ call_traits<const S&, void(const R&)>::is_noexcept))+ {+ return submit(s, r);+ }++ template <typename S, typename R>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<S&, void(const R&)>::overload == adapter,+ typename call_traits<S&, void(const R&)>::result_type+ >::type+ operator()(S& s, const R& r) const+ ASIO_NOEXCEPT_IF((+ call_traits<S&, void(const R&)>::is_noexcept))+ {+ asio::execution::start(+ (new asio::execution::detail::submit_receiver<+ S&, const R&>(s, r))->state_);+ }++ template <typename S, typename R>+ ASIO_CONSTEXPR typename enable_if<+ call_traits<const S&, void(const R&)>::overload == adapter,+ typename call_traits<const S&, void(const R&)>::result_type+ >::type+ operator()(const S& s, const R& r) const+ ASIO_NOEXCEPT_IF((+ call_traits<const S&, void(const R&)>::is_noexcept))+ {+ asio::execution::start(+ (new asio::execution::detail::submit_receiver<+ const S&, const R&>(s, r))->state_);+ }+#endif // defined(ASIO_HAS_MOVE)+};++template <typename T = impl>+struct static_instance+{+ static const T instance;+};++template <typename T>+const T static_instance<T>::instance = {};++} // namespace asio_execution_submit_fn+namespace asio {+namespace execution {+namespace {++static ASIO_CONSTEXPR const asio_execution_submit_fn::impl&+ submit = asio_execution_submit_fn::static_instance<>::instance;++} // namespace++template <typename S, typename R>+struct can_submit :+ integral_constant<bool,+ asio_execution_submit_fn::call_traits<S, void(R)>::overload !=+ asio_execution_submit_fn::ill_formed>+{+};++#if defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename S, typename R>+constexpr bool can_submit_v = can_submit<S, R>::value;++#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename S, typename R>+struct is_nothrow_submit :+ integral_constant<bool,+ asio_execution_submit_fn::call_traits<S, void(R)>::is_noexcept>+{+};++#if defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename S, typename R>+constexpr bool is_nothrow_submit_v+ = is_nothrow_submit<S, R>::value;++#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename S, typename R>+struct submit_result+{+ typedef typename asio_execution_submit_fn::call_traits<+ S, void(R)>::result_type type;+};++namespace detail {++template <typename S, typename R>+void submit_helper(ASIO_MOVE_ARG(S) s, ASIO_MOVE_ARG(R) r)+{+ execution::submit(ASIO_MOVE_CAST(S)(s), ASIO_MOVE_CAST(R)(r));+}++} // namespace detail+} // namespace execution+} // namespace asio++#endif // defined(GENERATING_DOCUMENTATION)++#include "asio/detail/pop_options.hpp"++#endif // !defined(ASIO_NO_DEPRECATED)++#endif // ASIO_EXECUTION_SUBMIT_HPP
link/modules/asio-standalone/asio/include/asio/execution_context.hpp view
@@ -2,7 +2,7 @@ // execution_context.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -19,8 +19,8 @@ #include <cstddef> #include <stdexcept> #include <typeinfo>-#include "asio/detail/memory.hpp" #include "asio/detail/noncopyable.hpp"+#include "asio/detail/variadic_templates.hpp" #include "asio/detail/push_options.hpp" @@ -106,51 +106,13 @@ : private noncopyable { public:- template <typename T> class allocator; class id; class service;- class service_maker; public: /// Constructor. ASIO_DECL execution_context(); - /// Constructor.- /**- * @param a An allocator that will be used for allocating objects that are- * associated with the context, such as services and internal state for I/O- * objects.- */- template <typename Allocator>- execution_context(allocator_arg_t, const Allocator& a);-- /// Constructor.- /**- * Construct with a service maker, to create an initial set of services that- * will be installed into the execution context at construction time.- *- * @param initial_services Used to create the initial services. The @c make- * function will be called once at the end of execution_context construction.- */- ASIO_DECL explicit execution_context(- const service_maker& initial_services);-- /// Constructor.- /**- * Construct with a service maker, to create an initial set of services that- * will be installed into the execution context at construction time.- *- * @param a An allocator that will be used for allocating objects that are- * associated with the context, such as services and internal state for I/O- * objects.- *- * @param initial_services Used to create the initial services. The @c make- * function will be called once at the end of execution_context construction.- */- template <typename Allocator>- execution_context(allocator_arg_t, const Allocator& a,- const service_maker& initial_services);- /// Destructor. ASIO_DECL ~execution_context(); @@ -262,6 +224,8 @@ template <typename Service> friend Service& use_service(io_context& ioc); +#if defined(GENERATING_DOCUMENTATION)+ /// Creates a service object and adds it to the execution_context. /** * This function is used to add a service to the execution_context.@@ -277,6 +241,27 @@ template <typename Service, typename... Args> friend Service& make_service(execution_context& e, Args&&... args); +#elif defined(ASIO_HAS_VARIADIC_TEMPLATES)++ template <typename Service, typename... Args>+ friend Service& make_service(execution_context& e,+ ASIO_MOVE_ARG(Args)... args);++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++ template <typename Service>+ friend Service& make_service(execution_context& e);++#define ASIO_PRIVATE_MAKE_SERVICE_DEF(n) \+ template <typename Service, ASIO_VARIADIC_TPARAMS(n)> \+ friend Service& make_service(execution_context& e, \+ ASIO_VARIADIC_MOVE_PARAMS(n)); \+ /**/+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_MAKE_SERVICE_DEF)+#undef ASIO_PRIVATE_MAKE_SERVICE_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+ /// (Deprecated: Use make_service().) Add a service object to the /// execution_context. /**@@ -313,150 +298,8 @@ friend bool has_service(execution_context& e); private:- class allocator_impl_base;- template <typename Allocator> class allocator_impl;-- // Helper constructors to perform non-templated parts of context construction.- ASIO_DECL explicit execution_context(allocator_impl_base* alloc);- ASIO_DECL execution_context(allocator_impl_base* alloc,- const service_maker& initial_services);-- // The allocator used for all services and other context-wide allocations.- struct auto_allocator_ptr- {- allocator_impl_base* ptr_;- ~auto_allocator_ptr();- } allocator_;- // The service registry.- detail::service_registry* service_registry_;-};--class execution_context::allocator_impl_base-{-public:- virtual void destroy() = 0;- virtual void* allocate(std::size_t size, std::size_t align) = 0;- virtual void deallocate(void* ptr, std::size_t size, std::size_t align) = 0;--protected:- ASIO_DECL virtual ~allocator_impl_base();-};--template <typename Allocator>-class execution_context::allocator_impl- : public execution_context::allocator_impl_base-{-public:- allocator_impl(const Allocator& alloc) : allocator_(alloc) {}- void destroy();- void* allocate(std::size_t size, std::size_t align);- void deallocate(void* ptr, std::size_t size, std::size_t align);--private:- Allocator allocator_;-};--template <typename T>-class execution_context::allocator-{-public:- /// The type of objects that may be allocated by the allocator.- typedef T value_type;-- /// Rebinds an allocator to another value type.- template <typename U>- struct rebind- {- /// Specifies the type of the rebound allocator.- typedef allocator<U> other;- };-- /// Construct an allocator that is associated with an execution context.- explicit constexpr allocator(execution_context& e) noexcept- : impl_(e.allocator_.ptr_)- {- }-- /// Construct from another @c allocator for a different value type.- template <typename U>- constexpr allocator(const allocator<U>& a) noexcept- : impl_(a.impl_)- {- }-- /// Equality operator.- constexpr bool operator==(const allocator& other) const noexcept- {- return impl_ == other.impl_;- }-- /// Inequality operator.- constexpr bool operator!=(const allocator& other) const noexcept- {- return impl_ != other.impl_;- }-- /// Allocate space for @c n objects of the allocator's value type.- T* allocate(std::size_t n) const- {- return static_cast<T*>(impl_->allocate(sizeof(T) * n, alignof(T)));- }-- /// Deallocate space for @c n objects of the allocator's value type.- void deallocate(T* p, std::size_t n) const- {- impl_->deallocate(p, sizeof(T) * n, alignof(T));- }--private:- template <typename> friend class execution_context::allocator;- allocator_impl_base* impl_;-};--template <>-class execution_context::allocator<void>-{-public:- /// @c void as no objects can be allocated through a proto-allocator.- typedef void value_type;-- /// Rebinds an allocator to another value type.- template <typename U>- struct rebind- {- /// Specifies the type of the rebound allocator.- typedef allocator<U> other;- };-- /// Construct an allocator that is associated with an execution context.- explicit constexpr allocator(execution_context& e) noexcept- : impl_(e.allocator_.ptr_)- {- }-- /// Construct from another @c allocator for a different value type.- template <typename U>- constexpr allocator(const allocator<U>& a) noexcept- : impl_(a.impl_)- {- }-- /// Equality operator.- constexpr bool operator==(const allocator& other) const noexcept- {- return impl_ == other.impl_;- }-- /// Inequality operator.- constexpr bool operator!=(const allocator& other) const noexcept- {- return impl_ != other.impl_;- }--private:- template <typename> friend class execution_context::allocator;- allocator_impl_base* impl_;+ asio::detail::service_registry* service_registry_; }; /// Class used to uniquely identify a service.@@ -468,7 +311,7 @@ id() {} }; -/// Base class for all execution context services.+/// Base class for all io_context services. class execution_context::service : private noncopyable {@@ -499,7 +342,7 @@ ASIO_DECL virtual void notify_fork( execution_context::fork_event event); - friend class detail::service_registry;+ friend class asio::detail::service_registry; struct key { key() : type_info_(0), id_(0) {}@@ -509,24 +352,6 @@ execution_context& owner_; service* next_;- void (*destroy_)(service*);-};--/// Base class for all execution context service makers.-/**- * A service maker is called by the execution context to create services that- * need to be installed into the execution context at construction time.- */-class execution_context::service_maker- : private noncopyable-{-public:- /// Make services to be added to the execution context.- virtual void make(execution_context& context) const = 0;--protected:- /// Destructor.- ASIO_DECL virtual ~service_maker(); }; /// Exception thrown when trying to add a duplicate service to an
link/modules/asio-standalone/asio/include/asio/executor.hpp view
@@ -2,7 +2,7 @@ // executor.hpp // ~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -19,7 +19,6 @@ #if !defined(ASIO_NO_TS_EXECUTORS) -#include <new> #include <typeinfo> #include "asio/detail/cstddef.hpp" #include "asio/detail/executor_function.hpp"@@ -37,11 +36,11 @@ { public: /// Constructor.- ASIO_DECL bad_executor() noexcept;+ ASIO_DECL bad_executor() ASIO_NOEXCEPT; /// Obtain message associated with exception. ASIO_DECL virtual const char* what() const- noexcept;+ ASIO_NOEXCEPT_OR_NOTHROW; }; /// Polymorphic wrapper for executors.@@ -49,53 +48,36 @@ { public: /// Default constructor.- executor() noexcept+ executor() ASIO_NOEXCEPT : impl_(0) { } /// Construct from nullptr.- executor(nullptr_t) noexcept+ executor(nullptr_t) ASIO_NOEXCEPT : impl_(0) { } /// Copy constructor.- executor(const executor& other) noexcept+ executor(const executor& other) ASIO_NOEXCEPT : impl_(other.clone()) { } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move constructor.- executor(executor&& other) noexcept+ executor(executor&& other) ASIO_NOEXCEPT : impl_(other.impl_) { other.impl_ = 0; }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Construct a polymorphic wrapper for the specified executor. template <typename Executor> executor(Executor e); - /// Construct a polymorphic executor that points to the same target as- /// another polymorphic executor.- executor(std::nothrow_t, const executor& other) noexcept- : impl_(other.clone())- {- }-- /// Construct a polymorphic executor that moves the target from another- /// polymorphic executor.- executor(std::nothrow_t, executor&& other) noexcept- : impl_(other.impl_)- {- other.impl_ = 0;- }-- /// Construct a polymorphic wrapper for the specified executor.- template <typename Executor>- executor(std::nothrow_t, Executor e) noexcept;- /// Allocator-aware constructor to create a polymorphic wrapper for the /// specified executor. template <typename Executor, typename Allocator>@@ -108,24 +90,26 @@ } /// Assignment operator.- executor& operator=(const executor& other) noexcept+ executor& operator=(const executor& other) ASIO_NOEXCEPT { destroy(); impl_ = other.clone(); return *this; } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) // Move assignment operator.- executor& operator=(executor&& other) noexcept+ executor& operator=(executor&& other) ASIO_NOEXCEPT { destroy(); impl_ = other.impl_; other.impl_ = 0; return *this; }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Assignment operator for nullptr_t.- executor& operator=(nullptr_t) noexcept+ executor& operator=(nullptr_t) ASIO_NOEXCEPT { destroy(); impl_ = 0;@@ -135,9 +119,9 @@ /// Assignment operator to create a polymorphic wrapper for the specified /// executor. template <typename Executor>- executor& operator=(Executor&& e) noexcept+ executor& operator=(ASIO_MOVE_ARG(Executor) e) ASIO_NOEXCEPT {- executor tmp(static_cast<Executor&&>(e));+ executor tmp(ASIO_MOVE_CAST(Executor)(e)); destroy(); impl_ = tmp.impl_; tmp.impl_ = 0;@@ -145,19 +129,19 @@ } /// Obtain the underlying execution context.- execution_context& context() const noexcept+ execution_context& context() const ASIO_NOEXCEPT { return get_impl()->context(); } /// Inform the executor that it has some outstanding work to do.- void on_work_started() const noexcept+ void on_work_started() const ASIO_NOEXCEPT { get_impl()->on_work_started(); } /// Inform the executor that some work is no longer outstanding.- void on_work_finished() const noexcept+ void on_work_finished() const ASIO_NOEXCEPT { get_impl()->on_work_finished(); }@@ -176,7 +160,7 @@ * internal storage needed for function invocation. */ template <typename Function, typename Allocator>- void dispatch(Function&& f, const Allocator& a) const;+ void dispatch(ASIO_MOVE_ARG(Function) f, const Allocator& a) const; /// Request the executor to invoke the given function object. /**@@ -192,7 +176,7 @@ * internal storage needed for function invocation. */ template <typename Function, typename Allocator>- void post(Function&& f, const Allocator& a) const;+ void post(ASIO_MOVE_ARG(Function) f, const Allocator& a) const; /// Request the executor to invoke the given function object. /**@@ -208,14 +192,14 @@ * internal storage needed for function invocation. */ template <typename Function, typename Allocator>- void defer(Function&& f, const Allocator& a) const;+ void defer(ASIO_MOVE_ARG(Function) f, const Allocator& a) const; struct unspecified_bool_type_t {}; typedef void (*unspecified_bool_type)(unspecified_bool_type_t); static void unspecified_bool_true(unspecified_bool_type_t) {} /// Operator to test if the executor contains a valid target.- operator unspecified_bool_type() const noexcept+ operator unspecified_bool_type() const ASIO_NOEXCEPT { return impl_ ? &executor::unspecified_bool_true : 0; }@@ -226,12 +210,12 @@ * otherwise, <tt>typeid(void)</tt>. */ #if !defined(ASIO_NO_TYPEID) || defined(GENERATING_DOCUMENTATION)- const std::type_info& target_type() const noexcept+ const std::type_info& target_type() const ASIO_NOEXCEPT { return impl_ ? impl_->target_type() : typeid(void); } #else // !defined(ASIO_NO_TYPEID) || defined(GENERATING_DOCUMENTATION)- const void* target_type() const noexcept+ const void* target_type() const ASIO_NOEXCEPT { return impl_ ? impl_->target_type() : 0; }@@ -243,7 +227,7 @@ * executor target; otherwise, a null pointer. */ template <typename Executor>- Executor* target() noexcept;+ Executor* target() ASIO_NOEXCEPT; /// Obtain a pointer to the target executor object. /**@@ -251,11 +235,11 @@ * executor target; otherwise, a null pointer. */ template <typename Executor>- const Executor* target() const noexcept;+ const Executor* target() const ASIO_NOEXCEPT; /// Compare two executors for equality. friend bool operator==(const executor& a,- const executor& b) noexcept+ const executor& b) ASIO_NOEXCEPT { if (a.impl_ == b.impl_) return true;@@ -266,7 +250,7 @@ /// Compare two executors for inequality. friend bool operator!=(const executor& a,- const executor& b) noexcept+ const executor& b) ASIO_NOEXCEPT { return !(a == b); }@@ -297,18 +281,18 @@ class impl_base { public:- virtual impl_base* clone() const noexcept = 0;- virtual void destroy() noexcept = 0;- virtual execution_context& context() noexcept = 0;- virtual void on_work_started() noexcept = 0;- virtual void on_work_finished() noexcept = 0;- virtual void dispatch(function&&) = 0;- virtual void post(function&&) = 0;- virtual void defer(function&&) = 0;- virtual type_id_result_type target_type() const noexcept = 0;- virtual void* target() noexcept = 0;- virtual const void* target() const noexcept = 0;- virtual bool equals(const impl_base* e) const noexcept = 0;+ virtual impl_base* clone() const ASIO_NOEXCEPT = 0;+ virtual void destroy() ASIO_NOEXCEPT = 0;+ virtual execution_context& context() ASIO_NOEXCEPT = 0;+ virtual void on_work_started() ASIO_NOEXCEPT = 0;+ virtual void on_work_finished() ASIO_NOEXCEPT = 0;+ virtual void dispatch(ASIO_MOVE_ARG(function)) = 0;+ virtual void post(ASIO_MOVE_ARG(function)) = 0;+ virtual void defer(ASIO_MOVE_ARG(function)) = 0;+ virtual type_id_result_type target_type() const ASIO_NOEXCEPT = 0;+ virtual void* target() ASIO_NOEXCEPT = 0;+ virtual const void* target() const ASIO_NOEXCEPT = 0;+ virtual bool equals(const impl_base* e) const ASIO_NOEXCEPT = 0; protected: impl_base(bool fast_dispatch) : fast_dispatch_(fast_dispatch) {}@@ -331,13 +315,13 @@ } // Helper function to clone another implementation.- impl_base* clone() const noexcept+ impl_base* clone() const ASIO_NOEXCEPT { return impl_ ? impl_->clone() : 0; } // Helper function to destroy an implementation.- void destroy() noexcept+ void destroy() ASIO_NOEXCEPT { if (impl_) impl_->destroy();
link/modules/asio-standalone/asio/include/asio/executor_work_guard.hpp view
@@ -2,7 +2,7 @@ // executor_work_guard.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -49,13 +49,13 @@ /** * Stores a copy of @c e and calls <tt>on_work_started()</tt> on it. */- explicit executor_work_guard(const executor_type& e) noexcept;+ explicit executor_work_guard(const executor_type& e) ASIO_NOEXCEPT; /// Copy constructor.- executor_work_guard(const executor_work_guard& other) noexcept;+ executor_work_guard(const executor_work_guard& other) ASIO_NOEXCEPT; /// Move constructor.- executor_work_guard(executor_work_guard&& other) noexcept;+ executor_work_guard(executor_work_guard&& other) ASIO_NOEXCEPT; /// Destructor. /**@@ -65,17 +65,17 @@ ~executor_work_guard(); /// Obtain the associated executor.- executor_type get_executor() const noexcept;+ executor_type get_executor() const ASIO_NOEXCEPT; /// Whether the executor_work_guard object owns some outstanding work.- bool owns_work() const noexcept;+ bool owns_work() const ASIO_NOEXCEPT; /// Indicate that the work is no longer outstanding. /** * Unless the object has already been reset, or is in a moved-from state, * calls <tt>on_work_finished()</tt> on the stored executor. */- void reset() noexcept;+ void reset() ASIO_NOEXCEPT; }; #endif // defined(GENERATING_DOCUMENTATION)@@ -86,21 +86,21 @@ template <typename Executor> class executor_work_guard<Executor,- enable_if_t<+ typename enable_if< is_executor<Executor>::value- >>+ >::type> { public: typedef Executor executor_type; - explicit executor_work_guard(const executor_type& e) noexcept+ explicit executor_work_guard(const executor_type& e) ASIO_NOEXCEPT : executor_(e), owns_(true) { executor_.on_work_started(); } - executor_work_guard(const executor_work_guard& other) noexcept+ executor_work_guard(const executor_work_guard& other) ASIO_NOEXCEPT : executor_(other.executor_), owns_(other.owns_) {@@ -108,12 +108,14 @@ executor_.on_work_started(); } - executor_work_guard(executor_work_guard&& other) noexcept- : executor_(static_cast<Executor&&>(other.executor_)),+#if defined(ASIO_HAS_MOVE)+ executor_work_guard(executor_work_guard&& other) ASIO_NOEXCEPT+ : executor_(ASIO_MOVE_CAST(Executor)(other.executor_)), owns_(other.owns_) { other.owns_ = false; }+#endif // defined(ASIO_HAS_MOVE) ~executor_work_guard() {@@ -121,17 +123,17 @@ executor_.on_work_finished(); } - executor_type get_executor() const noexcept+ executor_type get_executor() const ASIO_NOEXCEPT { return executor_; } - bool owns_work() const noexcept+ bool owns_work() const ASIO_NOEXCEPT { return owns_; } - void reset() noexcept+ void reset() ASIO_NOEXCEPT { if (owns_) {@@ -152,17 +154,17 @@ template <typename Executor> class executor_work_guard<Executor,- enable_if_t<+ typename enable_if< !is_executor<Executor>::value- >,- enable_if_t<+ >::type,+ typename enable_if< execution::is_executor<Executor>::value- >>+ >::type> { public: typedef Executor executor_type; - explicit executor_work_guard(const executor_type& e) noexcept+ explicit executor_work_guard(const executor_type& e) ASIO_NOEXCEPT : executor_(e), owns_(true) {@@ -170,7 +172,7 @@ execution::outstanding_work.tracked)); } - executor_work_guard(const executor_work_guard& other) noexcept+ executor_work_guard(const executor_work_guard& other) ASIO_NOEXCEPT : executor_(other.executor_), owns_(other.owns_) {@@ -181,19 +183,21 @@ } } - executor_work_guard(executor_work_guard&& other) noexcept- : executor_(static_cast<Executor&&>(other.executor_)),+#if defined(ASIO_HAS_MOVE)+ executor_work_guard(executor_work_guard&& other) ASIO_NOEXCEPT+ : executor_(ASIO_MOVE_CAST(Executor)(other.executor_)), owns_(other.owns_) { if (owns_) { new (&work_) work_type(- static_cast<work_type&&>(+ ASIO_MOVE_CAST(work_type)( *static_cast<work_type*>( static_cast<void*>(&other.work_)))); other.owns_ = false; } }+#endif // defined(ASIO_HAS_MOVE) ~executor_work_guard() {@@ -201,17 +205,17 @@ static_cast<work_type*>(static_cast<void*>(&work_))->~work_type(); } - executor_type get_executor() const noexcept+ executor_type get_executor() const ASIO_NOEXCEPT { return executor_; } - bool owns_work() const noexcept+ bool owns_work() const ASIO_NOEXCEPT { return owns_; } - void reset() noexcept+ void reset() ASIO_NOEXCEPT { if (owns_) {@@ -224,15 +228,16 @@ // Disallow assignment. executor_work_guard& operator=(const executor_work_guard&); - typedef decay_t<- prefer_result_t<+ typedef typename decay<+ typename prefer_result< const executor_type&, execution::outstanding_work_t::tracked_t- >- > work_type;+ >::type+ >::type work_type; executor_type executor_;- aligned_storage_t<sizeof(work_type), alignment_of<work_type>::value> work_;+ typename aligned_storage<sizeof(work_type),+ alignment_of<work_type>::value>::type work_; bool owns_; }; @@ -247,9 +252,9 @@ template <typename Executor> ASIO_NODISCARD inline executor_work_guard<Executor> make_work_guard(const Executor& ex,- constraint_t<+ typename constraint< is_executor<Executor>::value || execution::is_executor<Executor>::value- > = 0)+ >::type = 0) { return executor_work_guard<Executor>(ex); }@@ -265,9 +270,9 @@ ASIO_NODISCARD inline executor_work_guard<typename ExecutionContext::executor_type> make_work_guard(ExecutionContext& ctx,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- > = 0)+ >::type = 0) { return executor_work_guard<typename ExecutionContext::executor_type>( ctx.get_executor());@@ -284,15 +289,15 @@ template <typename T> ASIO_NODISCARD inline executor_work_guard<- typename constraint_t<+ typename constraint< !is_executor<T>::value && !execution::is_executor<T>::value && !is_convertible<T&, execution_context&>::value, associated_executor<T>- >::type>+ >::type::type> make_work_guard(const T& t) {- return executor_work_guard<associated_executor_t<T>>(+ return executor_work_guard<typename associated_executor<T>::type>( associated_executor<T>::get(t)); } @@ -310,13 +315,13 @@ */ template <typename T, typename Executor> ASIO_NODISCARD inline-executor_work_guard<associated_executor_t<T, Executor>>+executor_work_guard<typename associated_executor<T, Executor>::type> make_work_guard(const T& t, const Executor& ex,- constraint_t<+ typename constraint< is_executor<Executor>::value || execution::is_executor<Executor>::value- > = 0)+ >::type = 0) {- return executor_work_guard<associated_executor_t<T, Executor>>(+ return executor_work_guard<typename associated_executor<T, Executor>::type>( associated_executor<T, Executor>::get(t, ex)); } @@ -333,24 +338,24 @@ * ctx.get_executor())</tt>. */ template <typename T, typename ExecutionContext>-ASIO_NODISCARD inline executor_work_guard<- associated_executor_t<T, typename ExecutionContext::executor_type>>+ASIO_NODISCARD inline executor_work_guard<typename associated_executor<T,+ typename ExecutionContext::executor_type>::type> make_work_guard(const T& t, ExecutionContext& ctx,- constraint_t<+ typename constraint< !is_executor<T>::value- > = 0,- constraint_t<+ >::type = 0,+ typename constraint< !execution::is_executor<T>::value- > = 0,- constraint_t<+ >::type = 0,+ typename constraint< !is_convertible<T&, execution_context&>::value- > = 0,- constraint_t<+ >::type = 0,+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- > = 0)+ >::type = 0) {- return executor_work_guard<- associated_executor_t<T, typename ExecutionContext::executor_type>>(+ return executor_work_guard<typename associated_executor<T,+ typename ExecutionContext::executor_type>::type>( associated_executor<T, typename ExecutionContext::executor_type>::get( t, ctx.get_executor())); }
+ link/modules/asio-standalone/asio/include/asio/experimental/append.hpp view
@@ -0,0 +1,36 @@+//+// experimental/append.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_EXPERIMENTAL_APPEND_HPP+#define ASIO_EXPERIMENTAL_APPEND_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/append.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {+namespace experimental {++#if !defined(ASIO_NO_DEPRECATED)+using asio::append_t;+using asio::append;+#endif // !defined(ASIO_NO_DEPRECATED)++} // namespace experimental+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_EXPERIMENTAL_APPEND_HPP
link/modules/asio-standalone/asio/include/asio/experimental/as_single.hpp view
@@ -2,7 +2,7 @@ // experimental/as_single.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -47,18 +47,18 @@ * token is itself defaulted as an argument to allow it to capture a source * location. */- constexpr as_single_t(+ ASIO_CONSTEXPR as_single_t( default_constructor_tag = default_constructor_tag(), CompletionToken token = CompletionToken())- : token_(static_cast<CompletionToken&&>(token))+ : token_(ASIO_MOVE_CAST(CompletionToken)(token)) { } /// Constructor. template <typename T>- constexpr explicit as_single_t(- T&& completion_token)- : token_(static_cast<T&&>(completion_token))+ ASIO_CONSTEXPR explicit as_single_t(+ ASIO_MOVE_ARG(T) completion_token)+ : token_(ASIO_MOVE_CAST(T)(completion_token)) { } @@ -71,7 +71,7 @@ typedef as_single_t default_completion_token_type; /// Construct the adapted executor from the inner executor type.- executor_with_default(const InnerExecutor& ex) noexcept+ executor_with_default(const InnerExecutor& ex) ASIO_NOEXCEPT : InnerExecutor(ex) { }@@ -80,9 +80,9 @@ /// that to construct the adapted executor. template <typename OtherExecutor> executor_with_default(const OtherExecutor& ex,- constraint_t<+ typename constraint< is_convertible<OtherExecutor, InnerExecutor>::value- > = 0) noexcept+ >::type = 0) ASIO_NOEXCEPT : InnerExecutor(ex) { }@@ -90,21 +90,25 @@ /// Type alias to adapt an I/O object to use @c as_single_t as its /// default completion token type.+#if defined(ASIO_HAS_ALIAS_TEMPLATES) \+ || defined(GENERATING_DOCUMENTATION) template <typename T> using as_default_on_t = typename T::template rebind_executor<- executor_with_default<typename T::executor_type>>::other;+ executor_with_default<typename T::executor_type> >::other;+#endif // defined(ASIO_HAS_ALIAS_TEMPLATES)+ // || defined(GENERATING_DOCUMENTATION) /// Function helper to adapt an I/O object to use @c as_single_t as its /// default completion token type. template <typename T>- static typename decay_t<T>::template rebind_executor<- executor_with_default<typename decay_t<T>::executor_type>+ static typename decay<T>::type::template rebind_executor<+ executor_with_default<typename decay<T>::type::executor_type> >::other- as_default_on(T&& object)+ as_default_on(ASIO_MOVE_ARG(T) object) {- return typename decay_t<T>::template rebind_executor<- executor_with_default<typename decay_t<T>::executor_type>- >::other(static_cast<T&&>(object));+ return typename decay<T>::type::template rebind_executor<+ executor_with_default<typename decay<T>::type::executor_type>+ >::other(ASIO_MOVE_CAST(T)(object)); } //private:@@ -115,11 +119,11 @@ /// arguments should be combined into a single argument. template <typename CompletionToken> ASIO_NODISCARD inline-constexpr as_single_t<decay_t<CompletionToken>>-as_single(CompletionToken&& completion_token)+ASIO_CONSTEXPR as_single_t<typename decay<CompletionToken>::type>+as_single(ASIO_MOVE_ARG(CompletionToken) completion_token) {- return as_single_t<decay_t<CompletionToken>>(- static_cast<CompletionToken&&>(completion_token));+ return as_single_t<typename decay<CompletionToken>::type>(+ ASIO_MOVE_CAST(CompletionToken)(completion_token)); } } // namespace experimental
+ link/modules/asio-standalone/asio/include/asio/experimental/as_tuple.hpp view
@@ -0,0 +1,36 @@+//+// experimental/as_tuple.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_EXPERIMENTAL_AS_TUPLE_HPP+#define ASIO_EXPERIMENTAL_AS_TUPLE_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/as_tuple.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {+namespace experimental {++#if !defined(ASIO_NO_DEPRECATED)+using asio::as_tuple_t;+using asio::as_tuple;+#endif // !defined(ASIO_NO_DEPRECATED)++} // namespace experimental+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_EXPERIMENTAL_AS_TUPLE_HPP
link/modules/asio-standalone/asio/include/asio/experimental/awaitable_operators.hpp view
@@ -2,7 +2,7 @@ // experimental/awaitable_operators.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -22,8 +22,8 @@ #include <variant> #include "asio/awaitable.hpp" #include "asio/co_spawn.hpp"-#include "asio/deferred.hpp" #include "asio/detail/type_traits.hpp"+#include "asio/experimental/deferred.hpp" #include "asio/experimental/parallel_group.hpp" #include "asio/multiple_exceptions.hpp" #include "asio/this_coro.hpp"@@ -37,28 +37,28 @@ template <typename T, typename Executor> awaitable<T, Executor> awaitable_wrap(awaitable<T, Executor> a,- constraint_t<is_constructible<T>::value>* = 0)+ typename constraint<is_constructible<T>::value>::type* = 0) { return a; } template <typename T, typename Executor> awaitable<std::optional<T>, Executor> awaitable_wrap(awaitable<T, Executor> a,- constraint_t<!is_constructible<T>::value>* = 0)+ typename constraint<!is_constructible<T>::value>::type* = 0) { co_return std::optional<T>(co_await std::move(a)); } template <typename T>-T& awaitable_unwrap(conditional_t<true, T, void>& r,- constraint_t<is_constructible<T>::value>* = 0)+T& awaitable_unwrap(typename conditional<true, T, void>::type& r,+ typename constraint<is_constructible<T>::value>::type* = 0) { return r; } template <typename T>-T& awaitable_unwrap(std::optional<conditional_t<true, T, void>>& r,- constraint_t<!is_constructible<T>::value>* = 0)+T& awaitable_unwrap(std::optional<typename conditional<true, T, void>::type>& r,+ typename constraint<!is_constructible<T>::value>::type* = 0) { return *r; }
link/modules/asio-standalone/asio/include/asio/experimental/basic_channel.hpp view
@@ -2,7 +2,7 @@ // experimental/basic_channel.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -110,9 +110,8 @@ template <typename... PayloadSignatures, ASIO_COMPLETION_TOKEN_FOR(PayloadSignatures...) CompletionToken>- auto do_async_receive(- asio::detail::completion_payload<PayloadSignatures...>*,- CompletionToken&& token)+ auto do_async_receive(detail::channel_payload<PayloadSignatures...>*,+ ASIO_MOVE_ARG(CompletionToken) token) -> decltype( async_initiate<CompletionToken, PayloadSignatures...>( declval<initiate_async_receive>(), token))@@ -168,10 +167,10 @@ */ template <typename ExecutionContext> basic_channel(ExecutionContext& context, std::size_t max_buffer_size = 0,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- > = defaulted_constraint())+ >::type = defaulted_constraint()) : service_(&asio::use_service<service_type>(context)), impl_(), executor_(context.get_executor())@@ -179,6 +178,7 @@ service_->construct(impl_, max_buffer_size); } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move-construct a basic_channel from another. /** * This constructor moves a channel from one object to another.@@ -236,13 +236,13 @@ template <typename Executor1> basic_channel( basic_channel<Executor1, Traits, Signatures...>&& other,- constraint_t<+ typename constraint< is_convertible<Executor1, Executor>::value- > = 0)+ >::type = 0) : service_(other.service_), executor_(other.executor_) {- service_->move_construct(impl_, other.impl_);+ service_->move_construct(impl_, *other.service_, other.impl_); } /// Move-assign a basic_channel from another.@@ -259,10 +259,10 @@ * constructor. */ template <typename Executor1>- constraint_t<+ typename constraint< is_convertible<Executor1, Executor>::value, basic_channel&- > operator=(basic_channel<Executor1, Traits, Signatures...>&& other)+ >::type operator=(basic_channel<Executor1, Traits, Signatures...>&& other) { if (this != &other) {@@ -273,6 +273,7 @@ } return *this; }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Destructor. ~basic_channel()@@ -281,19 +282,19 @@ } /// Get the executor associated with the object.- const executor_type& get_executor() noexcept+ const executor_type& get_executor() ASIO_NOEXCEPT { return executor_; } /// Get the capacity of the channel's buffer.- std::size_t capacity() noexcept+ std::size_t capacity() ASIO_NOEXCEPT { return service_->capacity(impl_); } /// Determine whether the channel is open.- bool is_open() const noexcept+ bool is_open() const ASIO_NOEXCEPT { return service_->is_open(impl_); }@@ -322,7 +323,7 @@ } /// Determine whether a message can be received without blocking.- bool ready() const noexcept+ bool ready() const ASIO_NOEXCEPT { return service_->ready(impl_); }@@ -336,38 +337,14 @@ * @returns @c true on success, @c false on failure. */ template <typename... Args>- bool try_send(Args&&... args);-- /// Try to send a message without blocking, using dispatch semantics to call- /// the receive operation's completion handler.- /**- * Fails if the buffer is full and there are no waiting receive operations.- *- * The receive operation's completion handler may be called from inside this- * function.- *- * @returns @c true on success, @c false on failure.- */- template <typename... Args>- bool try_send_via_dispatch(Args&&... args);+ bool try_send(ASIO_MOVE_ARG(Args)... args); /// Try to send a number of messages without blocking. /** * @returns The number of messages that were sent. */ template <typename... Args>- std::size_t try_send_n(std::size_t count, Args&&... args);-- /// Try to send a number of messages without blocking, using dispatch- /// semantics to call the receive operations' completion handlers.- /**- * The receive operations' completion handlers may be called from inside this- * function.- *- * @returns The number of messages that were sent.- */- template <typename... Args>- std::size_t try_send_n_via_dispatch(std::size_t count, Args&&... args);+ std::size_t try_send_n(std::size_t count, ASIO_MOVE_ARG(Args)... args); /// Asynchronously send a message. /**@@ -377,8 +354,8 @@ template <typename... Args, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code)) CompletionToken ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>- auto async_send(Args&&... args,- CompletionToken&& token);+ auto async_send(ASIO_MOVE_ARG(Args)... args,+ ASIO_MOVE_ARG(CompletionToken) token); #endif // defined(GENERATING_DOCUMENTATION) @@ -389,9 +366,9 @@ * @returns @c true on success, @c false on failure. */ template <typename Handler>- bool try_receive(Handler&& handler)+ bool try_receive(ASIO_MOVE_ARG(Handler) handler) {- return service_->try_receive(impl_, static_cast<Handler&&>(handler));+ return service_->try_receive(impl_, ASIO_MOVE_CAST(Handler)(handler)); } /// Asynchronously receive a message.@@ -403,22 +380,22 @@ template <typename CompletionToken ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)> auto async_receive(- CompletionToken&& token+ ASIO_MOVE_ARG(CompletionToken) token ASIO_DEFAULT_COMPLETION_TOKEN(Executor)) #if !defined(GENERATING_DOCUMENTATION) -> decltype( this->do_async_receive(static_cast<payload_type*>(0),- static_cast<CompletionToken&&>(token)))+ ASIO_MOVE_CAST(CompletionToken)(token))) #endif // !defined(GENERATING_DOCUMENTATION) { return this->do_async_receive(static_cast<payload_type*>(0),- static_cast<CompletionToken&&>(token));+ ASIO_MOVE_CAST(CompletionToken)(token)); } private: // Disallow copying and assignment.- basic_channel(const basic_channel&) = delete;- basic_channel& operator=(const basic_channel&) = delete;+ basic_channel(const basic_channel&) ASIO_DELETED;+ basic_channel& operator=(const basic_channel&) ASIO_DELETED; template <typename, typename, typename...> friend class detail::channel_send_functions;@@ -426,7 +403,7 @@ // Helper function to get an executor's context. template <typename T> static execution_context& get_context(const T& t,- enable_if_t<execution::is_executor<T>::value>* = 0)+ typename enable_if<execution::is_executor<T>::value>::type* = 0) { return asio::query(t, execution::context); }@@ -434,7 +411,7 @@ // Helper function to get an executor's context. template <typename T> static execution_context& get_context(const T& t,- enable_if_t<!execution::is_executor<T>::value>* = 0)+ typename enable_if<!execution::is_executor<T>::value>::type* = 0) { return t.context(); }@@ -449,18 +426,18 @@ { } - const executor_type& get_executor() const noexcept+ const executor_type& get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template <typename SendHandler>- void operator()(SendHandler&& handler,- payload_type&& payload) const+ void operator()(ASIO_MOVE_ARG(SendHandler) handler,+ ASIO_MOVE_ARG(payload_type) payload) const { asio::detail::non_const_lvalue<SendHandler> handler2(handler); self_->service_->async_send(self_->impl_,- static_cast<payload_type&&>(payload),+ ASIO_MOVE_CAST(payload_type)(payload), handler2.value, self_->get_executor()); } @@ -478,13 +455,13 @@ { } - const executor_type& get_executor() const noexcept+ const executor_type& get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template <typename ReceiveHandler>- void operator()(ReceiveHandler&& handler) const+ void operator()(ASIO_MOVE_ARG(ReceiveHandler) handler) const { asio::detail::non_const_lvalue<ReceiveHandler> handler2(handler); self_->service_->async_receive(self_->impl_,
link/modules/asio-standalone/asio/include/asio/experimental/basic_concurrent_channel.hpp view
@@ -2,7 +2,7 @@ // experimental/basic_concurrent_channel.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -110,9 +110,8 @@ template <typename... PayloadSignatures, ASIO_COMPLETION_TOKEN_FOR(PayloadSignatures...) CompletionToken>- auto do_async_receive(- asio::detail::completion_payload<PayloadSignatures...>*,- CompletionToken&& token)+ auto do_async_receive(detail::channel_payload<PayloadSignatures...>*,+ ASIO_MOVE_ARG(CompletionToken) token) -> decltype( async_initiate<CompletionToken, PayloadSignatures...>( declval<initiate_async_receive>(), token))@@ -170,10 +169,10 @@ template <typename ExecutionContext> basic_concurrent_channel(ExecutionContext& context, std::size_t max_buffer_size = 0,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- > = defaulted_constraint())+ >::type = defaulted_constraint()) : service_(&asio::use_service<service_type>(context)), impl_(), executor_(context.get_executor())@@ -181,6 +180,7 @@ service_->construct(impl_, max_buffer_size); } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move-construct a basic_concurrent_channel from another. /** * This constructor moves a channel from one object to another.@@ -242,13 +242,13 @@ template <typename Executor1> basic_concurrent_channel( basic_concurrent_channel<Executor1, Traits, Signatures...>&& other,- constraint_t<+ typename constraint< is_convertible<Executor1, Executor>::value- > = 0)+ >::type = 0) : service_(other.service_), executor_(other.executor_) {- service_->move_construct(impl_, other.impl_);+ service_->move_construct(impl_, *other.service_, other.impl_); } /// Move-assign a basic_concurrent_channel from another.@@ -265,10 +265,10 @@ * constructor. */ template <typename Executor1>- constraint_t<+ typename constraint< is_convertible<Executor1, Executor>::value, basic_concurrent_channel&- > operator=(+ >::type operator=( basic_concurrent_channel<Executor1, Traits, Signatures...>&& other) { if (this != &other)@@ -280,6 +280,7 @@ } return *this; }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Destructor. ~basic_concurrent_channel()@@ -288,19 +289,19 @@ } /// Get the executor associated with the object.- const executor_type& get_executor() noexcept+ const executor_type& get_executor() ASIO_NOEXCEPT { return executor_; } /// Get the capacity of the channel's buffer.- std::size_t capacity() noexcept+ std::size_t capacity() ASIO_NOEXCEPT { return service_->capacity(impl_); } /// Determine whether the channel is open.- bool is_open() const noexcept+ bool is_open() const ASIO_NOEXCEPT { return service_->is_open(impl_); }@@ -329,7 +330,7 @@ } /// Determine whether a message can be received without blocking.- bool ready() const noexcept+ bool ready() const ASIO_NOEXCEPT { return service_->ready(impl_); }@@ -343,45 +344,21 @@ * @returns @c true on success, @c false on failure. */ template <typename... Args>- bool try_send(Args&&... args);-- /// Try to send a message without blocking, using dispatch semantics to call- /// the receive operation's completion handler.- /**- * Fails if the buffer is full and there are no waiting receive operations.- *- * The receive operation's completion handler may be called from inside this- * function.- *- * @returns @c true on success, @c false on failure.- */- template <typename... Args>- bool try_send_via_dispatch(Args&&... args);+ bool try_send(ASIO_MOVE_ARG(Args)... args); /// Try to send a number of messages without blocking. /** * @returns The number of messages that were sent. */ template <typename... Args>- std::size_t try_send_n(std::size_t count, Args&&... args);-- /// Try to send a number of messages without blocking, using dispatch- /// semantics to call the receive operations' completion handlers.- /**- * The receive operations' completion handlers may be called from inside this- * function.- *- * @returns The number of messages that were sent.- */- template <typename... Args>- std::size_t try_send_n_via_dispatch(std::size_t count, Args&&... args);+ std::size_t try_send_n(std::size_t count, ASIO_MOVE_ARG(Args)... args); /// Asynchronously send a message. template <typename... Args, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code)) CompletionToken ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>- auto async_send(Args&&... args,- CompletionToken&& token);+ auto async_send(ASIO_MOVE_ARG(Args)... args,+ ASIO_MOVE_ARG(CompletionToken) token); #endif // defined(GENERATING_DOCUMENTATION) @@ -392,33 +369,33 @@ * @returns @c true on success, @c false on failure. */ template <typename Handler>- bool try_receive(Handler&& handler)+ bool try_receive(ASIO_MOVE_ARG(Handler) handler) {- return service_->try_receive(impl_, static_cast<Handler&&>(handler));+ return service_->try_receive(impl_, ASIO_MOVE_CAST(Handler)(handler)); } /// Asynchronously receive a message. template <typename CompletionToken ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)> auto async_receive(- CompletionToken&& token+ ASIO_MOVE_ARG(CompletionToken) token ASIO_DEFAULT_COMPLETION_TOKEN(Executor)) #if !defined(GENERATING_DOCUMENTATION) -> decltype( this->do_async_receive(static_cast<payload_type*>(0),- static_cast<CompletionToken&&>(token)))+ ASIO_MOVE_CAST(CompletionToken)(token))) #endif // !defined(GENERATING_DOCUMENTATION) { return this->do_async_receive(static_cast<payload_type*>(0),- static_cast<CompletionToken&&>(token));+ ASIO_MOVE_CAST(CompletionToken)(token)); } private: // Disallow copying and assignment. basic_concurrent_channel(- const basic_concurrent_channel&) = delete;+ const basic_concurrent_channel&) ASIO_DELETED; basic_concurrent_channel& operator=(- const basic_concurrent_channel&) = delete;+ const basic_concurrent_channel&) ASIO_DELETED; template <typename, typename, typename...> friend class detail::channel_send_functions;@@ -426,7 +403,7 @@ // Helper function to get an executor's context. template <typename T> static execution_context& get_context(const T& t,- enable_if_t<execution::is_executor<T>::value>* = 0)+ typename enable_if<execution::is_executor<T>::value>::type* = 0) { return asio::query(t, execution::context); }@@ -434,7 +411,7 @@ // Helper function to get an executor's context. template <typename T> static execution_context& get_context(const T& t,- enable_if_t<!execution::is_executor<T>::value>* = 0)+ typename enable_if<!execution::is_executor<T>::value>::type* = 0) { return t.context(); }@@ -449,18 +426,18 @@ { } - const executor_type& get_executor() const noexcept+ const executor_type& get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template <typename SendHandler>- void operator()(SendHandler&& handler,- payload_type&& payload) const+ void operator()(ASIO_MOVE_ARG(SendHandler) handler,+ ASIO_MOVE_ARG(payload_type) payload) const { asio::detail::non_const_lvalue<SendHandler> handler2(handler); self_->service_->async_send(self_->impl_,- static_cast<payload_type&&>(payload),+ ASIO_MOVE_CAST(payload_type)(payload), handler2.value, self_->get_executor()); } @@ -478,13 +455,13 @@ { } - const executor_type& get_executor() const noexcept+ const executor_type& get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template <typename ReceiveHandler>- void operator()(ReceiveHandler&& handler) const+ void operator()(ASIO_MOVE_ARG(ReceiveHandler) handler) const { asio::detail::non_const_lvalue<ReceiveHandler> handler2(handler); self_->service_->async_receive(self_->impl_,
link/modules/asio-standalone/asio/include/asio/experimental/cancellation_condition.hpp view
@@ -2,7 +2,7 @@ // experimental/cancellation_condition.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -16,8 +16,9 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"+#include <exception> #include "asio/cancellation_type.hpp"-#include "asio/disposition.hpp"+#include "asio/error_code.hpp" #include "asio/detail/type_traits.hpp" #include "asio/detail/push_options.hpp"@@ -30,7 +31,8 @@ { public: template <typename... Args>- constexpr cancellation_type_t operator()(Args&&...) const noexcept+ ASIO_CONSTEXPR cancellation_type_t operator()(+ Args&&...) const ASIO_NOEXCEPT { return cancellation_type::none; }@@ -40,14 +42,15 @@ class wait_for_one { public:- constexpr explicit wait_for_one(+ ASIO_CONSTEXPR explicit wait_for_one( cancellation_type_t cancel_type = cancellation_type::all) : cancel_type_(cancel_type) { } template <typename... Args>- constexpr cancellation_type_t operator()(Args&&...) const noexcept+ ASIO_CONSTEXPR cancellation_type_t operator()(+ Args&&...) const ASIO_NOEXCEPT { return cancel_type_; }@@ -64,30 +67,36 @@ class wait_for_one_success { public:- constexpr explicit wait_for_one_success(+ ASIO_CONSTEXPR explicit wait_for_one_success( cancellation_type_t cancel_type = cancellation_type::all) : cancel_type_(cancel_type) { } - constexpr cancellation_type_t- operator()() const noexcept+ ASIO_CONSTEXPR cancellation_type_t+ operator()() const ASIO_NOEXCEPT { return cancel_type_; } template <typename E, typename... Args>- constexpr constraint_t<!is_disposition<E>::value, cancellation_type_t>- operator()(const E&, Args&&...) const noexcept+ ASIO_CONSTEXPR typename constraint<+ !is_same<typename decay<E>::type, asio::error_code>::value+ && !is_same<typename decay<E>::type, std::exception_ptr>::value,+ cancellation_type_t+ >::type operator()(const E&, Args&&...) const ASIO_NOEXCEPT { return cancel_type_; } template <typename E, typename... Args>- constexpr constraint_t<is_disposition<E>::value, cancellation_type_t>- operator()(const E& e, Args&&...) const noexcept+ ASIO_CONSTEXPR typename constraint<+ is_same<typename decay<E>::type, asio::error_code>::value+ || is_same<typename decay<E>::type, std::exception_ptr>::value,+ cancellation_type_t+ >::type operator()(const E& e, Args&&...) const ASIO_NOEXCEPT {- return e != no_error ? cancellation_type::none : cancel_type_;+ return !!e ? cancellation_type::none : cancel_type_; } private:@@ -102,29 +111,36 @@ class wait_for_one_error { public:- constexpr explicit wait_for_one_error(+ ASIO_CONSTEXPR explicit wait_for_one_error( cancellation_type_t cancel_type = cancellation_type::all) : cancel_type_(cancel_type) { } - constexpr cancellation_type_t operator()() const noexcept+ ASIO_CONSTEXPR cancellation_type_t+ operator()() const ASIO_NOEXCEPT { return cancellation_type::none; } template <typename E, typename... Args>- constexpr constraint_t<!is_disposition<E>::value, cancellation_type_t>- operator()(const E&, Args&&...) const noexcept+ ASIO_CONSTEXPR typename constraint<+ !is_same<typename decay<E>::type, asio::error_code>::value+ && !is_same<typename decay<E>::type, std::exception_ptr>::value,+ cancellation_type_t+ >::type operator()(const E&, Args&&...) const ASIO_NOEXCEPT { return cancellation_type::none; } template <typename E, typename... Args>- constexpr constraint_t<is_disposition<E>::value, cancellation_type_t>- operator()(const E& e, Args&&...) const noexcept+ ASIO_CONSTEXPR typename constraint<+ is_same<typename decay<E>::type, asio::error_code>::value+ || is_same<typename decay<E>::type, std::exception_ptr>::value,+ cancellation_type_t+ >::type operator()(const E& e, Args&&...) const ASIO_NOEXCEPT {- return e != no_error ? cancel_type_ : cancellation_type::none;+ return !!e ? cancel_type_ : cancellation_type::none; } private:
link/modules/asio-standalone/asio/include/asio/experimental/channel.hpp view
@@ -2,7 +2,7 @@ // experimental/channel.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -42,10 +42,10 @@ template <typename ExecutorOrSignature> struct channel_type<ExecutorOrSignature,- enable_if_t<+ typename enable_if< is_executor<ExecutorOrSignature>::value || execution::is_executor<ExecutorOrSignature>::value- >>+ >::type> { template <typename... Signatures> struct inner@@ -58,15 +58,9 @@ } // namespace detail /// Template type alias for common use of channel.-#if defined(GENERATING_DOCUMENTATION) template <typename ExecutorOrSignature, typename... Signatures>-using channel = basic_channel<- specified_executor_or_any_io_executor, channel_traits<>, signatures...>;-#else // defined(GENERATING_DOCUMENTATION)-template <typename ExecutorOrSignature, typename... Signatures> using channel = typename detail::channel_type< ExecutorOrSignature>::template inner<Signatures...>::type;-#endif // defined(GENERATING_DOCUMENTATION) } // namespace experimental } // namespace asio
link/modules/asio-standalone/asio/include/asio/experimental/channel_error.hpp view
@@ -2,7 +2,7 @@ // experimental/channel_error.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -49,6 +49,7 @@ } // namespace experimental } // namespace asio +#if defined(ASIO_HAS_STD_SYSTEM_ERROR) namespace std { template<> struct is_error_code_enum<@@ -58,6 +59,7 @@ }; } // namespace std+#endif // defined(ASIO_HAS_STD_SYSTEM_ERROR) namespace asio { namespace experimental {
link/modules/asio-standalone/asio/include/asio/experimental/channel_traits.hpp view
@@ -2,7 +2,7 @@ // experimental/channel_traits.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -102,7 +102,7 @@ static void invoke_receive_cancelled(F f) { const asio::error_code e = error::channel_cancelled;- static_cast<F&&>(f)(e);+ ASIO_MOVE_OR_LVALUE(F)(f)(e); } typedef R receive_closed_signature(asio::error_code);@@ -111,7 +111,7 @@ static void invoke_receive_closed(F f) { const asio::error_code e = error::channel_closed;- static_cast<F&&>(f)(e);+ ASIO_MOVE_OR_LVALUE(F)(f)(e); } }; @@ -136,7 +136,7 @@ static void invoke_receive_cancelled(F f) { const asio::error_code e = error::channel_cancelled;- static_cast<F&&>(f)(e, decay_t<Args>()...);+ ASIO_MOVE_OR_LVALUE(F)(f)(e, typename decay<Args>::type()...); } typedef R receive_closed_signature(asio::error_code, Args...);@@ -145,7 +145,7 @@ static void invoke_receive_closed(F f) { const asio::error_code e = error::channel_closed;- static_cast<F&&>(f)(e, decay_t<Args>()...);+ ASIO_MOVE_OR_LVALUE(F)(f)(e, typename decay<Args>::type()...); } }; @@ -170,7 +170,7 @@ static void invoke_receive_cancelled(F f) { const asio::error_code e = error::channel_cancelled;- static_cast<F&&>(f)(+ ASIO_MOVE_OR_LVALUE(F)(f)( std::make_exception_ptr(asio::system_error(e))); } @@ -180,7 +180,7 @@ static void invoke_receive_closed(F f) { const asio::error_code e = error::channel_closed;- static_cast<F&&>(f)(+ ASIO_MOVE_OR_LVALUE(F)(f)( std::make_exception_ptr(asio::system_error(e))); } };@@ -206,9 +206,9 @@ static void invoke_receive_cancelled(F f) { const asio::error_code e = error::channel_cancelled;- static_cast<F&&>(f)(+ ASIO_MOVE_OR_LVALUE(F)(f)( std::make_exception_ptr(asio::system_error(e)),- decay_t<Args>()...);+ typename decay<Args>::type()...); } typedef R receive_closed_signature(std::exception_ptr, Args...);@@ -217,9 +217,9 @@ static void invoke_receive_closed(F f) { const asio::error_code e = error::channel_closed;- static_cast<F&&>(f)(+ ASIO_MOVE_OR_LVALUE(F)(f)( std::make_exception_ptr(asio::system_error(e)),- decay_t<Args>()...);+ typename decay<Args>::type()...); } }; @@ -244,7 +244,7 @@ static void invoke_receive_cancelled(F f) { const asio::error_code e = error::channel_cancelled;- static_cast<F&&>(f)(e);+ ASIO_MOVE_OR_LVALUE(F)(f)(e); } typedef R receive_closed_signature(asio::error_code);@@ -253,7 +253,7 @@ static void invoke_receive_closed(F f) { const asio::error_code e = error::channel_closed;- static_cast<F&&>(f)(e);+ ASIO_MOVE_OR_LVALUE(F)(f)(e); } }; @@ -278,7 +278,7 @@ static void invoke_receive_cancelled(F f) { const asio::error_code e = error::channel_cancelled;- static_cast<F&&>(f)(e);+ ASIO_MOVE_OR_LVALUE(F)(f)(e); } typedef R receive_closed_signature(asio::error_code);@@ -287,7 +287,7 @@ static void invoke_receive_closed(F f) { const asio::error_code e = error::channel_closed;- static_cast<F&&>(f)(e);+ ASIO_MOVE_OR_LVALUE(F)(f)(e); } };
link/modules/asio-standalone/asio/include/asio/experimental/co_composed.hpp view
@@ -2,7 +2,7 @@ // experimental/co_composed.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -16,18 +16,129 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"-#include "asio/co_composed.hpp"+#include "asio/async_result.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace experimental { -using asio::co_composed;+/// Creates an initiation function object that may be used to launch a+/// coroutine-based composed asynchronous operation.+/**+ * The experimental::co_composed utility simplifies the implementation of+ * composed asynchronous operations by automatically adapting a coroutine to be+ * an initiation function object for use with @c async_initiate. When awaiting+ * asynchronous operations, the coroutine automatically uses a conforming+ * intermediate completion handler.+ *+ * @param implementation A function object that contains the coroutine-based+ * implementation of the composed asynchronous operation. The first argument to+ * the function object represents the state of the operation, and may be used+ * to test for cancellation. The remaining arguments are those passed to @c+ * async_initiate after the completion token.+ *+ * @param io_objects_or_executors Zero or more I/O objects or I/O executors for+ * which outstanding work must be maintained while the operation is incomplete.+ *+ * @par Per-Operation Cancellation+ * By default, per-operation cancellation is disabled for composed operations+ * that use experimental::co_composed. It must be explicitly enabled by calling+ * the state's @c reset_cancellation_state function.+ *+ * @par Examples+ * The following example illustrates manual error handling and explicit checks+ * for cancellation. The completion handler is invoked via a @c co_yield to the+ * state's @c complete function, which never returns.+ *+ * @code template <typename CompletionToken>+ * auto async_echo(tcp::socket& socket,+ * CompletionToken&& token)+ * {+ * return asio::async_initiate<+ * CompletionToken, void(std::error_code)>(+ * asio::experimental::co_composed(+ * [](auto state, tcp::socket& socket) -> void+ * {+ * state.reset_cancellation_state(+ * asio::enable_terminal_cancellation());+ *+ * while (!state.cancelled())+ * {+ * char data[1024];+ * auto [e1, n1] =+ * co_await socket.async_read_some(+ * asio::buffer(data),+ * asio::as_tuple(asio::deferred));+ *+ * if (e1)+ * co_yield state.complete(e1);+ *+ * if (!!state.cancelled())+ * co_yield state.complete(+ * make_error_code(asio::error::operation_aborted));+ *+ * auto [e2, n2] =+ * co_await asio::async_write(socket,+ * asio::buffer(data, n1),+ * asio::as_tuple(asio::deferred));+ *+ * if (e2)+ * co_yield state.complete(e2);+ * }+ * }, socket),+ * token, std::ref(socket));+ * } @endcode+ *+ * This next example shows exception-based error handling and implicit checks+ * for cancellation. The completion handler is invoked after returning from the+ * coroutine via @c co_return. Valid @c co_return values are specified using+ * completion signatures passed to the @c co_composed function.+ *+ * @code template <typename CompletionToken>+ * auto async_echo(tcp::socket& socket,+ * CompletionToken&& token)+ * {+ * return asio::async_initiate<+ * CompletionToken, void(std::error_code)>(+ * asio::experimental::co_composed<+ * void(std::error_code)>(+ * [](auto state, tcp::socket& socket) -> void+ * {+ * try+ * {+ * state.throw_if_cancelled(true);+ * state.reset_cancellation_state(+ * asio::enable_terminal_cancellation());+ *+ * for (;;)+ * {+ * char data[1024];+ * std::size_t n = co_await socket.async_read_some(+ * asio::buffer(data), asio::deferred);+ *+ * co_await asio::async_write(socket,+ * asio::buffer(data, n), asio::deferred);+ * }+ * }+ * catch (const std::system_error& e)+ * {+ * co_return {e.code()};+ * }+ * }, socket),+ * token, std::ref(socket));+ * } @endcode+ */+template <completion_signature... Signatures,+ typename Implementation, typename... IoObjectsOrExecutors>+auto co_composed(Implementation&& implementation,+ IoObjectsOrExecutors&&... io_objects_or_executors); } // namespace experimental } // namespace asio #include "asio/detail/pop_options.hpp"++#include "asio/experimental/impl/co_composed.hpp" #endif // ASIO_EXPERIMENTAL_CO_COMPOSED_HPP
link/modules/asio-standalone/asio/include/asio/experimental/co_spawn.hpp view
@@ -18,10 +18,10 @@ #include "asio/detail/config.hpp" #include <utility> #include "asio/compose.hpp"-#include "asio/deferred.hpp" #include "asio/detail/type_traits.hpp" #include "asio/experimental/coro.hpp"-#include "asio/prepend.hpp"+#include "asio/experimental/deferred.hpp"+#include "asio/experimental/prepend.hpp" #include "asio/redirect_error.hpp" #include "asio/detail/push_options.hpp"
link/modules/asio-standalone/asio/include/asio/experimental/concurrent_channel.hpp view
@@ -2,7 +2,7 @@ // experimental/concurrent_channel.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -42,10 +42,10 @@ template <typename ExecutorOrSignature> struct concurrent_channel_type<ExecutorOrSignature,- enable_if_t<+ typename enable_if< is_executor<ExecutorOrSignature>::value || execution::is_executor<ExecutorOrSignature>::value- >>+ >::type> { template <typename... Signatures> struct inner@@ -58,15 +58,9 @@ } // namespace detail /// Template type alias for common use of channel.-#if defined(GENERATING_DOCUMENTATION) template <typename ExecutorOrSignature, typename... Signatures>-using concurrent_channel = basic_concurrent_channel<- specified_executor_or_any_io_executor, channel_traits<>, signatures...>;-#else // defined(GENERATING_DOCUMENTATION)-template <typename ExecutorOrSignature, typename... Signatures> using concurrent_channel = typename detail::concurrent_channel_type< ExecutorOrSignature>::template inner<Signatures...>::type;-#endif // defined(GENERATING_DOCUMENTATION) } // namespace experimental } // namespace asio
+ link/modules/asio-standalone/asio/include/asio/experimental/deferred.hpp view
@@ -0,0 +1,36 @@+//+// experimental/deferred.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_EXPERIMENTAL_DEFERRED_HPP+#define ASIO_EXPERIMENTAL_DEFERRED_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/deferred.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {+namespace experimental {++#if !defined(ASIO_NO_DEPRECATED)+using asio::deferred_t;+using asio::deferred;+#endif // !defined(ASIO_NO_DEPRECATED)++} // namespace experimental+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_EXPERIMENTAL_DEFERRED_HPP
+ link/modules/asio-standalone/asio/include/asio/experimental/detail/channel_handler.hpp view
@@ -0,0 +1,80 @@+//+// experimental/detail/channel_handler.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_EXPERIMENTAL_DETAIL_CHANNEL_HANDLER_HPP+#define ASIO_EXPERIMENTAL_DETAIL_CHANNEL_HANDLER_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/associator.hpp"+#include "asio/experimental/detail/channel_payload.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {+namespace experimental {+namespace detail {++template <typename Payload, typename Handler>+class channel_handler+{+public:+ channel_handler(ASIO_MOVE_ARG(Payload) p, Handler& h)+ : payload_(ASIO_MOVE_CAST(Payload)(p)),+ handler_(ASIO_MOVE_CAST(Handler)(h))+ {+ }++ void operator()()+ {+ payload_.receive(handler_);+ }++//private:+ Payload payload_;+ Handler handler_;+};++} // namespace detail+} // namespace experimental++template <template <typename, typename> class Associator,+ typename Payload, typename Handler, typename DefaultCandidate>+struct associator<Associator,+ experimental::detail::channel_handler<Payload, Handler>,+ DefaultCandidate>+ : Associator<Handler, DefaultCandidate>+{+ static typename Associator<Handler, DefaultCandidate>::type+ get(const experimental::detail::channel_handler<Payload, Handler>& h)+ ASIO_NOEXCEPT+ {+ return Associator<Handler, DefaultCandidate>::get(h.handler_);+ }++ static ASIO_AUTO_RETURN_TYPE_PREFIX2(+ typename Associator<Handler, DefaultCandidate>::type)+ get(const experimental::detail::channel_handler<Payload, Handler>& h,+ const DefaultCandidate& c) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ Associator<Handler, DefaultCandidate>::get(h.handler_, c)))+ {+ return Associator<Handler, DefaultCandidate>::get(h.handler_, c);+ }+};++} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_EXPERIMENTAL_DETAIL_CHANNEL_HANDLER_HPP
+ link/modules/asio-standalone/asio/include/asio/experimental/detail/channel_message.hpp view
@@ -0,0 +1,129 @@+//+// experimental/detail/channel_message.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_EXPERIMENTAL_DETAIL_CHANNEL_MESSAGE_HPP+#define ASIO_EXPERIMENTAL_DETAIL_CHANNEL_MESSAGE_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include <tuple>+#include "asio/detail/type_traits.hpp"+#include "asio/detail/utility.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {+namespace experimental {+namespace detail {++template <typename Signature>+class channel_message;++template <typename R>+class channel_message<R()>+{+public:+ channel_message(int)+ {+ }++ template <typename Handler>+ void receive(Handler& handler)+ {+ ASIO_MOVE_OR_LVALUE(Handler)(handler)();+ }+};++template <typename R, typename Arg0>+class channel_message<R(Arg0)>+{+public:+ template <typename T0>+ channel_message(int, ASIO_MOVE_ARG(T0) t0)+ : arg0_(ASIO_MOVE_CAST(T0)(t0))+ {+ }++ template <typename Handler>+ void receive(Handler& handler)+ {+ ASIO_MOVE_OR_LVALUE(Handler)(handler)(+ ASIO_MOVE_CAST(arg0_type)(arg0_));+ }++private:+ typedef typename decay<Arg0>::type arg0_type;+ arg0_type arg0_;+};++template <typename R, typename Arg0, typename Arg1>+class channel_message<R(Arg0, Arg1)>+{+public:+ template <typename T0, typename T1>+ channel_message(int, ASIO_MOVE_ARG(T0) t0, ASIO_MOVE_ARG(T1) t1)+ : arg0_(ASIO_MOVE_CAST(T0)(t0)),+ arg1_(ASIO_MOVE_CAST(T1)(t1))+ {+ }++ template <typename Handler>+ void receive(Handler& handler)+ {+ ASIO_MOVE_OR_LVALUE(Handler)(handler)(+ ASIO_MOVE_CAST(arg0_type)(arg0_),+ ASIO_MOVE_CAST(arg1_type)(arg1_));+ }++private:+ typedef typename decay<Arg0>::type arg0_type;+ arg0_type arg0_;+ typedef typename decay<Arg1>::type arg1_type;+ arg1_type arg1_;+};++template <typename R, typename... Args>+class channel_message<R(Args...)>+{+public:+ template <typename... T>+ channel_message(int, ASIO_MOVE_ARG(T)... t)+ : args_(ASIO_MOVE_CAST(T)(t)...)+ {+ }++ template <typename Handler>+ void receive(Handler& h)+ {+ this->do_receive(h, asio::detail::index_sequence_for<Args...>());+ }++private:+ template <typename Handler, std::size_t... I>+ void do_receive(Handler& h, asio::detail::index_sequence<I...>)+ {+ ASIO_MOVE_OR_LVALUE(Handler)(h)(+ std::get<I>(ASIO_MOVE_CAST(args_type)(args_))...);+ }++ typedef std::tuple<typename decay<Args>::type...> args_type;+ args_type args_;+};++} // namespace detail+} // namespace experimental+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_EXPERIMENTAL_DETAIL_CHANNEL_MESSAGE_HPP
link/modules/asio-standalone/asio/include/asio/experimental/detail/channel_operation.hpp view
@@ -2,7 +2,7 @@ // experimental/detail/channel_operation.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -39,7 +39,7 @@ class channel_operation ASIO_INHERIT_TRACKED_HANDLER { public:- template <typename Executor, typename = void, typename = void>+ template <typename Executor, typename = void> class handler_work_base; template <typename Handler, typename IoExecutor, typename = void>@@ -55,10 +55,9 @@ { destroy_op = 0, immediate_op = 1,- post_op = 2,- dispatch_op = 3,- cancel_op = 4,- close_op = 5+ complete_op = 2,+ cancel_op = 3,+ close_op = 4 }; typedef void (*func_type)(channel_operation*, action, void*);@@ -84,96 +83,44 @@ void* cancellation_key_; }; -template <typename Executor, typename, typename>+template <typename Executor, typename> class channel_operation::handler_work_base { public:- typedef decay_t<- prefer_result_t<Executor,+ typedef typename decay<+ typename prefer_result<Executor, execution::outstanding_work_t::tracked_t- >- > executor_type;+ >::type+ >::type executor_type; handler_work_base(int, const Executor& ex) : executor_(asio::prefer(ex, execution::outstanding_work.tracked)) { } - const executor_type& get_executor() const noexcept+ const executor_type& get_executor() const ASIO_NOEXCEPT { return executor_; } - template <typename IoExecutor, typename Function, typename Handler>- void post(const IoExecutor& io_exec, Function& function, Handler&)- {- (asio::detail::initiate_post_with_executor<IoExecutor>(io_exec))(- static_cast<Function&&>(function));- }- template <typename Function, typename Handler>- void dispatch(Function& function, Handler& handler)- {- associated_allocator_t<Handler> allocator =- (get_associated_allocator)(handler);-- asio::prefer(executor_,- execution::allocator(allocator)- ).execute(static_cast<Function&&>(function));- }--private:- executor_type executor_;-};--template <typename Executor>-class channel_operation::handler_work_base<Executor,- enable_if_t<- execution::is_executor<Executor>::value- >,- enable_if_t<- can_require<Executor, execution::blocking_t::never_t>::value- >- >-{-public:- typedef decay_t<- prefer_result_t<Executor,- execution::outstanding_work_t::tracked_t- >- > executor_type;-- handler_work_base(int, const Executor& ex)- : executor_(asio::prefer(ex, execution::outstanding_work.tracked))- {- }-- const executor_type& get_executor() const noexcept- {- return executor_;- }-- template <typename IoExecutor, typename Function, typename Handler>- void post(const IoExecutor&, Function& function, Handler& handler)+ void post(Function& function, Handler& handler) {- associated_allocator_t<Handler> allocator =+ typename associated_allocator<Handler>::type allocator = (get_associated_allocator)(handler); +#if defined(ASIO_NO_DEPRECATED) asio::prefer( asio::require(executor_, execution::blocking.never), execution::allocator(allocator)- ).execute(static_cast<Function&&>(function));- }-- template <typename Function, typename Handler>- void dispatch(Function& function, Handler& handler)- {- associated_allocator_t<Handler> allocator =- (get_associated_allocator)(handler);-- asio::prefer(executor_,- execution::allocator(allocator)- ).execute(static_cast<Function&&>(function));+ ).execute(ASIO_MOVE_CAST(Function)(function));+#else // defined(ASIO_NO_DEPRECATED)+ execution::execute(+ asio::prefer(+ asio::require(executor_, execution::blocking.never),+ execution::allocator(allocator)),+ ASIO_MOVE_CAST(Function)(function));+#endif // defined(ASIO_NO_DEPRECATED) } private:@@ -184,10 +131,9 @@ template <typename Executor> class channel_operation::handler_work_base<Executor,- enable_if_t<+ typename enable_if< !execution::is_executor<Executor>::value- >- >+ >::type> { public: typedef Executor executor_type;@@ -197,29 +143,19 @@ { } - executor_type get_executor() const noexcept+ executor_type get_executor() const ASIO_NOEXCEPT { return work_.get_executor(); } - template <typename IoExecutor, typename Function, typename Handler>- void post(const IoExecutor&, Function& function, Handler& handler)- {- associated_allocator_t<Handler> allocator =- (get_associated_allocator)(handler);-- work_.get_executor().post(- static_cast<Function&&>(function), allocator);- }- template <typename Function, typename Handler>- void dispatch(Function& function, Handler& handler)+ void post(Function& function, Handler& handler) {- associated_allocator_t<Handler> allocator =+ typename associated_allocator<Handler>::type allocator = (get_associated_allocator)(handler); - work_.get_executor().dispatch(- static_cast<Function&&>(function), allocator);+ work_.get_executor().post(+ ASIO_MOVE_CAST(Function)(function), allocator); } private:@@ -232,123 +168,110 @@ class channel_operation::handler_work : channel_operation::handler_work_base<IoExecutor>, channel_operation::handler_work_base<- associated_executor_t<Handler, IoExecutor>, IoExecutor>+ typename associated_executor<Handler, IoExecutor>::type, IoExecutor> { public: typedef channel_operation::handler_work_base<IoExecutor> base1_type; typedef channel_operation::handler_work_base<- associated_executor_t<Handler, IoExecutor>, IoExecutor>+ typename associated_executor<Handler, IoExecutor>::type, IoExecutor> base2_type; - handler_work(Handler& handler, const IoExecutor& io_ex) noexcept+ handler_work(Handler& handler, const IoExecutor& io_ex) ASIO_NOEXCEPT : base1_type(0, io_ex), base2_type(0, (get_associated_executor)(handler, io_ex)) { } template <typename Function>- void post(Function& function, Handler& handler)- {- base2_type::post(base1_type::get_executor(), function, handler);- }-- template <typename Function>- void dispatch(Function& function, Handler& handler)+ void complete(Function& function, Handler& handler) {- base2_type::dispatch(function, handler);+ base2_type::post(function, handler); } template <typename Function> void immediate(Function& function, Handler& handler, ...) {- typedef associated_immediate_executor_t<Handler,- typename base1_type::executor_type> immediate_ex_type;+ typedef typename associated_immediate_executor<Handler,+ typename base1_type::executor_type>::type immediate_ex_type; immediate_ex_type immediate_ex = (get_associated_immediate_executor)( handler, base1_type::get_executor()); (asio::detail::initiate_dispatch_with_executor<immediate_ex_type>(- immediate_ex))(static_cast<Function&&>(function));+ immediate_ex))(ASIO_MOVE_CAST(Function)(function)); } template <typename Function> void immediate(Function& function, Handler&,- enable_if_t<+ typename enable_if< is_same< typename associated_immediate_executor<- conditional_t<false, Function, Handler>,+ typename conditional<false, Function, Handler>::type, typename base1_type::executor_type>:: asio_associated_immediate_executor_is_unspecialised, void >::value- >*)+ >::type*) { (asio::detail::initiate_post_with_executor< typename base1_type::executor_type>( base1_type::get_executor()))(- static_cast<Function&&>(function));+ ASIO_MOVE_CAST(Function)(function)); } }; template <typename Handler, typename IoExecutor> class channel_operation::handler_work< Handler, IoExecutor,- enable_if_t<+ typename enable_if< is_same< typename associated_executor<Handler, IoExecutor>::asio_associated_executor_is_unspecialised, void >::value- >- > : handler_work_base<IoExecutor>+ >::type> : handler_work_base<IoExecutor> { public: typedef channel_operation::handler_work_base<IoExecutor> base1_type; - handler_work(Handler&, const IoExecutor& io_ex) noexcept+ handler_work(Handler&, const IoExecutor& io_ex) ASIO_NOEXCEPT : base1_type(0, io_ex) { } template <typename Function>- void post(Function& function, Handler& handler)- {- base1_type::post(base1_type::get_executor(), function, handler);- }-- template <typename Function>- void dispatch(Function& function, Handler& handler)+ void complete(Function& function, Handler& handler) {- base1_type::dispatch(function, handler);+ base1_type::post(function, handler); } template <typename Function> void immediate(Function& function, Handler& handler, ...) {- typedef associated_immediate_executor_t<Handler,- typename base1_type::executor_type> immediate_ex_type;+ typedef typename associated_immediate_executor<Handler,+ typename base1_type::executor_type>::type immediate_ex_type; immediate_ex_type immediate_ex = (get_associated_immediate_executor)( handler, base1_type::get_executor()); (asio::detail::initiate_dispatch_with_executor<immediate_ex_type>(- immediate_ex))(static_cast<Function&&>(function));+ immediate_ex))(ASIO_MOVE_CAST(Function)(function)); } template <typename Function> void immediate(Function& function, Handler& handler,- enable_if_t<+ typename enable_if< is_same< typename associated_immediate_executor<- conditional_t<false, Function, Handler>,+ typename conditional<false, Function, Handler>::type, typename base1_type::executor_type>:: asio_associated_immediate_executor_is_unspecialised, void >::value- >*)+ >::type*) {- base1_type::post(base1_type::get_executor(), function, handler);+ base1_type::post(function, handler); } };
+ link/modules/asio-standalone/asio/include/asio/experimental/detail/channel_payload.hpp view
@@ -0,0 +1,139 @@+//+// experimental/detail/channel_payload.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_EXPERIMENTAL_DETAIL_CHANNEL_PAYLOAD_HPP+#define ASIO_EXPERIMENTAL_DETAIL_CHANNEL_PAYLOAD_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/detail/type_traits.hpp"+#include "asio/error_code.hpp"+#include "asio/experimental/detail/channel_message.hpp"++#if defined(ASIO_HAS_STD_VARIANT)+# include <variant>+#endif // defined(ASIO_HAS_STD_VARIANT)++#include "asio/detail/push_options.hpp"++namespace asio {+namespace experimental {+namespace detail {++template <typename... Signatures>+class channel_payload;++template <typename R>+class channel_payload<R()>+{+public:+ explicit channel_payload(channel_message<R()>)+ {+ }++ template <typename Handler>+ void receive(Handler& handler)+ {+ ASIO_MOVE_OR_LVALUE(Handler)(handler)();+ }+};++template <typename Signature>+class channel_payload<Signature>+{+public:+ channel_payload(ASIO_MOVE_ARG(channel_message<Signature>) m)+ : message_(ASIO_MOVE_CAST(channel_message<Signature>)(m))+ {+ }++ template <typename Handler>+ void receive(Handler& handler)+ {+ message_.receive(handler);+ }++private:+ channel_message<Signature> message_;+};++#if defined(ASIO_HAS_STD_VARIANT)++template <typename... Signatures>+class channel_payload+{+public:+ template <typename Signature>+ channel_payload(ASIO_MOVE_ARG(channel_message<Signature>) m)+ : message_(ASIO_MOVE_CAST(channel_message<Signature>)(m))+ {+ }++ template <typename Handler>+ void receive(Handler& handler)+ {+ std::visit(+ [&](auto& message)+ {+ message.receive(handler);+ }, message_);+ }++private:+ std::variant<channel_message<Signatures>...> message_;+};++#else // defined(ASIO_HAS_STD_VARIANT)++template <typename R1, typename R2>+class channel_payload<R1(), R2(asio::error_code)>+{+public:+ typedef channel_message<R1()> void_message_type;+ typedef channel_message<R2(asio::error_code)> error_message_type;++ channel_payload(ASIO_MOVE_ARG(void_message_type))+ : message_(0, asio::error_code()),+ empty_(true)+ {+ }++ channel_payload(ASIO_MOVE_ARG(error_message_type) m)+ : message_(ASIO_MOVE_CAST(error_message_type)(m)),+ empty_(false)+ {+ }++ template <typename Handler>+ void receive(Handler& handler)+ {+ if (empty_)+ channel_message<R1()>(0).receive(handler);+ else+ message_.receive(handler);+ }++private:+ error_message_type message_;+ bool empty_;+};++#endif // defined(ASIO_HAS_STD_VARIANT)++} // namespace detail+} // namespace experimental+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_EXPERIMENTAL_DETAIL_CHANNEL_PAYLOAD_HPP
link/modules/asio-standalone/asio/include/asio/experimental/detail/channel_receive_op.hpp view
@@ -2,7 +2,7 @@ // experimental/detail/channel_receive_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -17,10 +17,11 @@ #include "asio/detail/config.hpp" #include "asio/detail/bind_handler.hpp"-#include "asio/detail/completion_handler.hpp" #include "asio/detail/handler_alloc_helpers.hpp" #include "asio/error.hpp"+#include "asio/experimental/detail/channel_handler.hpp" #include "asio/experimental/detail/channel_operation.hpp"+#include "asio/experimental/detail/channel_payload.hpp" #include "asio/detail/push_options.hpp" @@ -37,14 +38,9 @@ func_(this, immediate_op, &payload); } - void post(Payload payload)- {- func_(this, post_op, &payload);- }-- void dispatch(Payload payload)+ void complete(Payload payload) {- func_(this, dispatch_op, &payload);+ func_(this, complete_op, &payload); } protected:@@ -63,7 +59,7 @@ template <typename... Args> channel_receive_op(Handler& handler, const IoExecutor& io_ex) : channel_receive<Payload>(&channel_receive_op::do_action),- handler_(static_cast<Handler&&>(handler)),+ handler_(ASIO_MOVE_CAST(Handler)(handler)), work_(handler_, io_ex) { }@@ -79,8 +75,8 @@ // Take ownership of the operation's outstanding work. channel_operation::handler_work<Handler, IoExecutor> w(- static_cast<channel_operation::handler_work<Handler, IoExecutor>&&>(- o->work_));+ ASIO_MOVE_CAST2(channel_operation::handler_work<+ Handler, IoExecutor>)(o->work_)); // Make a copy of the handler so that the memory can be deallocated before // the handler is posted. Even if we're not about to post the handler, a@@ -91,17 +87,15 @@ if (a != channel_operation::destroy_op) { Payload* payload = static_cast<Payload*>(v);- asio::detail::completion_payload_handler<Payload, Handler> handler(- static_cast<Payload&&>(*payload), o->handler_);+ channel_handler<Payload, Handler> handler(+ ASIO_MOVE_CAST(Payload)(*payload), o->handler_); p.h = asio::detail::addressof(handler.handler_); p.reset(); ASIO_HANDLER_INVOCATION_BEGIN(()); if (a == channel_operation::immediate_op) w.immediate(handler, handler.handler_, 0);- else if (a == channel_operation::dispatch_op)- w.dispatch(handler, handler.handler_); else- w.post(handler, handler.handler_);+ w.complete(handler, handler.handler_); ASIO_HANDLER_INVOCATION_END; } else
link/modules/asio-standalone/asio/include/asio/experimental/detail/channel_send_functions.hpp view
@@ -2,7 +2,7 @@ // experimental/detail/channel_send_functions.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -17,9 +17,9 @@ #include "asio/detail/config.hpp" #include "asio/async_result.hpp"-#include "asio/detail/completion_message.hpp" #include "asio/detail/type_traits.hpp" #include "asio/error_code.hpp"+#include "asio/experimental/detail/channel_message.hpp" #include "asio/detail/push_options.hpp" @@ -35,76 +35,48 @@ { public: template <typename... Args2>- enable_if_t<- is_constructible<asio::detail::completion_message<R(Args...)>,- int, Args2...>::value,- bool- > try_send(Args2&&... args)- {- typedef asio::detail::completion_message<R(Args...)> message_type;- Derived* self = static_cast<Derived*>(this);- return self->service_->template try_send<message_type>(- self->impl_, false, static_cast<Args2&&>(args)...);- }-- template <typename... Args2>- enable_if_t<- is_constructible<asio::detail::completion_message<R(Args...)>,- int, Args2...>::value,+ typename enable_if<+ is_constructible<detail::channel_message<R(Args...)>, int, Args2...>::value, bool- > try_send_via_dispatch(Args2&&... args)+ >::type try_send(ASIO_MOVE_ARG(Args2)... args) {- typedef asio::detail::completion_message<R(Args...)> message_type;+ typedef typename detail::channel_message<R(Args...)> message_type; Derived* self = static_cast<Derived*>(this); return self->service_->template try_send<message_type>(- self->impl_, true, static_cast<Args2&&>(args)...);- }-- template <typename... Args2>- enable_if_t<- is_constructible<asio::detail::completion_message<R(Args...)>,- int, Args2...>::value,- std::size_t- > try_send_n(std::size_t count, Args2&&... args)- {- typedef asio::detail::completion_message<R(Args...)> message_type;- Derived* self = static_cast<Derived*>(this);- return self->service_->template try_send_n<message_type>(- self->impl_, count, false, static_cast<Args2&&>(args)...);+ self->impl_, ASIO_MOVE_CAST(Args2)(args)...); } template <typename... Args2>- enable_if_t<- is_constructible<asio::detail::completion_message<R(Args...)>,- int, Args2...>::value,+ typename enable_if<+ is_constructible<detail::channel_message<R(Args...)>, int, Args2...>::value, std::size_t- > try_send_n_via_dispatch(std::size_t count, Args2&&... args)+ >::type try_send_n(std::size_t count, ASIO_MOVE_ARG(Args2)... args) {- typedef asio::detail::completion_message<R(Args...)> message_type;+ typedef typename detail::channel_message<R(Args...)> message_type; Derived* self = static_cast<Derived*>(this); return self->service_->template try_send_n<message_type>(- self->impl_, count, true, static_cast<Args2&&>(args)...);+ self->impl_, count, ASIO_MOVE_CAST(Args2)(args)...); } template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code)) CompletionToken ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(Executor)> auto async_send(Args... args,- CompletionToken&& token+ ASIO_MOVE_ARG(CompletionToken) token ASIO_DEFAULT_COMPLETION_TOKEN(Executor)) -> decltype( async_initiate<CompletionToken, void (asio::error_code)>(- declval<typename conditional_t<false, CompletionToken,- Derived>::initiate_async_send>(), token,- declval<typename conditional_t<false, CompletionToken,- Derived>::payload_type>()))+ declval<typename conditional<false, CompletionToken,+ Derived>::type::initiate_async_send>(), token,+ declval<typename conditional<false, CompletionToken,+ Derived>::type::payload_type>())) { typedef typename Derived::payload_type payload_type;- typedef asio::detail::completion_message<R(Args...)> message_type;+ typedef typename detail::channel_message<R(Args...)> message_type; Derived* self = static_cast<Derived*>(this); return async_initiate<CompletionToken, void (asio::error_code)>( typename Derived::initiate_async_send(self), token,- payload_type(message_type(0, static_cast<Args&&>(args)...)));+ payload_type(message_type(0, ASIO_MOVE_CAST(Args)(args)...))); } }; @@ -118,76 +90,48 @@ using channel_send_functions<Derived, Executor, Signatures...>::async_send; template <typename... Args2>- enable_if_t<- is_constructible<asio::detail::completion_message<R(Args...)>,- int, Args2...>::value,- bool- > try_send(Args2&&... args)- {- typedef asio::detail::completion_message<R(Args...)> message_type;- Derived* self = static_cast<Derived*>(this);- return self->service_->template try_send<message_type>(- self->impl_, false, static_cast<Args2&&>(args)...);- }-- template <typename... Args2>- enable_if_t<- is_constructible<asio::detail::completion_message<R(Args...)>,- int, Args2...>::value,+ typename enable_if<+ is_constructible<detail::channel_message<R(Args...)>, int, Args2...>::value, bool- > try_send_via_dispatch(Args2&&... args)+ >::type try_send(ASIO_MOVE_ARG(Args2)... args) {- typedef asio::detail::completion_message<R(Args...)> message_type;+ typedef typename detail::channel_message<R(Args...)> message_type; Derived* self = static_cast<Derived*>(this); return self->service_->template try_send<message_type>(- self->impl_, true, static_cast<Args2&&>(args)...);- }-- template <typename... Args2>- enable_if_t<- is_constructible<asio::detail::completion_message<R(Args...)>,- int, Args2...>::value,- std::size_t- > try_send_n(std::size_t count, Args2&&... args)- {- typedef asio::detail::completion_message<R(Args...)> message_type;- Derived* self = static_cast<Derived*>(this);- return self->service_->template try_send_n<message_type>(- self->impl_, count, false, static_cast<Args2&&>(args)...);+ self->impl_, ASIO_MOVE_CAST(Args2)(args)...); } template <typename... Args2>- enable_if_t<- is_constructible<asio::detail::completion_message<R(Args...)>,- int, Args2...>::value,+ typename enable_if<+ is_constructible<detail::channel_message<R(Args...)>, int, Args2...>::value, std::size_t- > try_send_n_via_dispatch(std::size_t count, Args2&&... args)+ >::type try_send_n(std::size_t count, ASIO_MOVE_ARG(Args2)... args) {- typedef asio::detail::completion_message<R(Args...)> message_type;+ typedef typename detail::channel_message<R(Args...)> message_type; Derived* self = static_cast<Derived*>(this); return self->service_->template try_send_n<message_type>(- self->impl_, count, true, static_cast<Args2&&>(args)...);+ self->impl_, count, ASIO_MOVE_CAST(Args2)(args)...); } template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code)) CompletionToken ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(Executor)> auto async_send(Args... args,- CompletionToken&& token+ ASIO_MOVE_ARG(CompletionToken) token ASIO_DEFAULT_COMPLETION_TOKEN(Executor)) -> decltype( async_initiate<CompletionToken, void (asio::error_code)>(- declval<typename conditional_t<false, CompletionToken,- Derived>::initiate_async_send>(), token,- declval<typename conditional_t<false, CompletionToken,- Derived>::payload_type>()))+ declval<typename conditional<false, CompletionToken,+ Derived>::type::initiate_async_send>(), token,+ declval<typename conditional<false, CompletionToken,+ Derived>::type::payload_type>())) { typedef typename Derived::payload_type payload_type;- typedef asio::detail::completion_message<R(Args...)> message_type;+ typedef typename detail::channel_message<R(Args...)> message_type; Derived* self = static_cast<Derived*>(this); return async_initiate<CompletionToken, void (asio::error_code)>( typename Derived::initiate_async_send(self), token,- payload_type(message_type(0, static_cast<Args&&>(args)...)));+ payload_type(message_type(0, ASIO_MOVE_CAST(Args)(args)...))); } };
link/modules/asio-standalone/asio/include/asio/experimental/detail/channel_send_op.hpp view
@@ -2,7 +2,7 @@ // experimental/detail/channel_send_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -21,6 +21,7 @@ #include "asio/error.hpp" #include "asio/experimental/channel_error.hpp" #include "asio/experimental/detail/channel_operation.hpp"+#include "asio/experimental/detail/channel_payload.hpp" #include "asio/detail/push_options.hpp" @@ -34,7 +35,7 @@ public: Payload get_payload() {- return static_cast<Payload&&>(payload_);+ return ASIO_MOVE_CAST(Payload)(payload_); } void immediate()@@ -42,9 +43,9 @@ func_(this, immediate_op, 0); } - void post()+ void complete() {- func_(this, post_op, 0);+ func_(this, complete_op, 0); } void cancel()@@ -58,9 +59,9 @@ } protected:- channel_send(func_type func, Payload&& payload)+ channel_send(func_type func, ASIO_MOVE_ARG(Payload) payload) : channel_operation(func),- payload_(static_cast<Payload&&>(payload))+ payload_(ASIO_MOVE_CAST(Payload)(payload)) { } @@ -74,11 +75,11 @@ public: ASIO_DEFINE_HANDLER_PTR(channel_send_op); - channel_send_op(Payload&& payload,+ channel_send_op(ASIO_MOVE_ARG(Payload) payload, Handler& handler, const IoExecutor& io_ex) : channel_send<Payload>(&channel_send_op::do_action,- static_cast<Payload&&>(payload)),- handler_(static_cast<Handler&&>(handler)),+ ASIO_MOVE_CAST(Payload)(payload)),+ handler_(ASIO_MOVE_CAST(Handler)(handler)), work_(handler_, io_ex) { }@@ -94,8 +95,8 @@ // Take ownership of the operation's outstanding work. channel_operation::handler_work<Handler, IoExecutor> w(- static_cast<channel_operation::handler_work<Handler, IoExecutor>&&>(- o->work_));+ ASIO_MOVE_CAST2(channel_operation::handler_work<+ Handler, IoExecutor>)(o->work_)); asio::error_code ec; switch (a)@@ -128,7 +129,7 @@ if (a == channel_operation::immediate_op) w.immediate(handler, handler.handler_, 0); else- w.post(handler, handler.handler_);+ w.complete(handler, handler.handler_); ASIO_HANDLER_INVOCATION_END; } }
link/modules/asio-standalone/asio/include/asio/experimental/detail/channel_service.hpp view
@@ -2,7 +2,7 @@ // experimental/detail/channel_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -18,12 +18,10 @@ #include "asio/detail/config.hpp" #include "asio/associated_cancellation_slot.hpp" #include "asio/cancellation_type.hpp"-#include "asio/detail/completion_message.hpp"-#include "asio/detail/completion_payload.hpp"-#include "asio/detail/completion_payload_handler.hpp" #include "asio/detail/mutex.hpp" #include "asio/detail/op_queue.hpp" #include "asio/execution_context.hpp"+#include "asio/experimental/detail/channel_message.hpp" #include "asio/experimental/detail/channel_receive_op.hpp" #include "asio/experimental/detail/channel_send_op.hpp" #include "asio/experimental/detail/has_signature.hpp"@@ -37,7 +35,7 @@ template <typename Mutex> class channel_service : public asio::detail::execution_context_service_base<- channel_service<Mutex>>+ channel_service<Mutex> > { public: // Possible states for a channel end.@@ -85,7 +83,7 @@ struct implementation_type; // Constructor.- channel_service(asio::execution_context& ctx);+ channel_service(execution_context& ctx); // Destroy all user-defined handler objects owned by the service. void shutdown();@@ -110,10 +108,10 @@ // Get the capacity of the channel. std::size_t capacity(- const base_implementation_type& impl) const noexcept;+ const base_implementation_type& impl) const ASIO_NOEXCEPT; // Determine whether the channel is open.- bool is_open(const base_implementation_type& impl) const noexcept;+ bool is_open(const base_implementation_type& impl) const ASIO_NOEXCEPT; // Reset the channel to its initial state. template <typename Traits, typename... Signatures>@@ -133,29 +131,29 @@ void* cancellation_key); // Determine whether a value can be read from the channel without blocking.- bool ready(const base_implementation_type& impl) const noexcept;+ bool ready(const base_implementation_type& impl) const ASIO_NOEXCEPT; // Synchronously send a new value into the channel. template <typename Message, typename Traits, typename... Signatures, typename... Args> bool try_send(implementation_type<Traits, Signatures...>& impl,- bool via_dispatch, Args&&... args);+ ASIO_MOVE_ARG(Args)... args); // Synchronously send a number of new values into the channel. template <typename Message, typename Traits, typename... Signatures, typename... Args> std::size_t try_send_n(implementation_type<Traits, Signatures...>& impl,- std::size_t count, bool via_dispatch, Args&&... args);+ std::size_t count, ASIO_MOVE_ARG(Args)... args); // Asynchronously send a new value into the channel. template <typename Traits, typename... Signatures, typename Handler, typename IoExecutor> void async_send(implementation_type<Traits, Signatures...>& impl,- typename implementation_type<Traits,- Signatures...>::payload_type&& payload,+ ASIO_MOVE_ARG2(typename implementation_type<+ Traits, Signatures...>::payload_type) payload, Handler& handler, const IoExecutor& io_ex) {- associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -164,14 +162,14 @@ Handler, IoExecutor> op; typename op::ptr p = { asio::detail::addressof(handler), op::ptr::allocate(handler), 0 };- p.p = new (p.v) op(static_cast<typename implementation_type<- Traits, Signatures...>::payload_type&&>(payload), handler, io_ex);+ p.p = new (p.v) op(ASIO_MOVE_CAST2(typename implementation_type<+ Traits, Signatures...>::payload_type)(payload), handler, io_ex); // Optionally register for per-operation cancellation. if (slot.is_connected()) { p.p->cancellation_key_ =- &slot.template emplace<op_cancellation<Traits, Signatures...>>(+ &slot.template emplace<op_cancellation<Traits, Signatures...> >( this, &impl); } @@ -185,7 +183,7 @@ // Synchronously receive a value from the channel. template <typename Traits, typename... Signatures, typename Handler> bool try_receive(implementation_type<Traits, Signatures...>& impl,- Handler&& handler);+ ASIO_MOVE_ARG(Handler) handler); // Asynchronously receive a value from the channel. template <typename Traits, typename... Signatures,@@ -193,7 +191,7 @@ void async_receive(implementation_type<Traits, Signatures...>& impl, Handler& handler, const IoExecutor& io_ex) {- associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -208,7 +206,7 @@ if (slot.is_connected()) { p.p->cancellation_key_ =- &slot.template emplace<op_cancellation<Traits, Signatures...>>(+ &slot.template emplace<op_cancellation<Traits, Signatures...> >( this, &impl); } @@ -222,19 +220,19 @@ private: // Helper function object to handle a closed notification. template <typename Payload, typename Signature>- struct post_receive+ struct complete_receive {- explicit post_receive(channel_receive<Payload>* op)+ explicit complete_receive(channel_receive<Payload>* op) : op_(op) { } template <typename... Args>- void operator()(Args&&... args)+ void operator()(ASIO_MOVE_ARG(Args)... args) {- op_->post(- asio::detail::completion_message<Signature>(0,- static_cast<Args&&>(args)...));+ op_->complete(+ channel_message<Signature>(0,+ ASIO_MOVE_CAST(Args)(args)...)); } channel_receive<Payload>* op_;@@ -299,46 +297,46 @@ typedef typename Traits::template rebind<Signatures...>::other traits_type; // Type of an element stored in the buffer.- typedef conditional_t<+ typedef typename conditional< has_signature< typename traits_type::receive_cancelled_signature, Signatures... >::value,- conditional_t<+ typename conditional< has_signature< typename traits_type::receive_closed_signature, Signatures... >::value,- asio::detail::completion_payload<Signatures...>,- asio::detail::completion_payload<+ channel_payload<Signatures...>,+ channel_payload< Signatures..., typename traits_type::receive_closed_signature >- >,- conditional_t<+ >::type,+ typename conditional< has_signature< typename traits_type::receive_closed_signature, Signatures..., typename traits_type::receive_cancelled_signature >::value,- asio::detail::completion_payload<+ channel_payload< Signatures..., typename traits_type::receive_cancelled_signature >,- asio::detail::completion_payload<+ channel_payload< Signatures..., typename traits_type::receive_cancelled_signature, typename traits_type::receive_closed_signature >- >- > payload_type;+ >::type+ >::type payload_type; // Move from another buffer. void buffer_move_from(implementation_type& other) {- buffer_ = static_cast<- typename traits_type::template container<payload_type>::type&&>(- other.buffer_);+ buffer_ = ASIO_MOVE_CAST(+ typename traits_type::template container<+ payload_type>::type)(other.buffer_); other.buffer_clear(); } @@ -351,7 +349,7 @@ // Push a new value to the back of the buffer. void buffer_push(payload_type payload) {- buffer_.push_back(static_cast<payload_type&&>(payload));+ buffer_.push_back(ASIO_MOVE_CAST(payload_type)(payload)); } // Push new values to the back of the buffer.@@ -366,7 +364,7 @@ // Get the element at the front of the buffer. payload_type buffer_front() {- return static_cast<payload_type&&>(buffer_.front());+ return ASIO_MOVE_CAST(payload_type)(buffer_.front()); } // Pop a value from the front of the buffer.@@ -396,39 +394,39 @@ typedef typename Traits::template rebind<R()>::other traits_type; // Type of an element stored in the buffer.- typedef conditional_t<+ typedef typename conditional< has_signature< typename traits_type::receive_cancelled_signature, R() >::value,- conditional_t<+ typename conditional< has_signature< typename traits_type::receive_closed_signature, R() >::value,- asio::detail::completion_payload<R()>,- asio::detail::completion_payload<+ channel_payload<R()>,+ channel_payload< R(), typename traits_type::receive_closed_signature >- >,- conditional_t<+ >::type,+ typename conditional< has_signature< typename traits_type::receive_closed_signature, R(), typename traits_type::receive_cancelled_signature >::value,- asio::detail::completion_payload<+ channel_payload< R(), typename traits_type::receive_cancelled_signature >,- asio::detail::completion_payload<+ channel_payload< R(), typename traits_type::receive_cancelled_signature, typename traits_type::receive_closed_signature >- >- > payload_type;+ >::type+ >::type payload_type; // Construct with empty buffer. implementation_type()@@ -467,7 +465,7 @@ // Get the element at the front of the buffer. payload_type buffer_front() {- return payload_type(asio::detail::completion_message<R()>(0));+ return payload_type(channel_message<R()>(0)); } // Pop a value from the front of the buffer.@@ -499,39 +497,39 @@ traits_type; // Type of an element stored in the buffer.- typedef conditional_t<+ typedef typename conditional< has_signature< typename traits_type::receive_cancelled_signature, R(asio::error_code) >::value,- conditional_t<+ typename conditional< has_signature< typename traits_type::receive_closed_signature, R(asio::error_code) >::value,- asio::detail::completion_payload<R(asio::error_code)>,- asio::detail::completion_payload<+ channel_payload<R(asio::error_code)>,+ channel_payload< R(asio::error_code), typename traits_type::receive_closed_signature >- >,- conditional_t<+ >::type,+ typename conditional< has_signature< typename traits_type::receive_closed_signature, R(asio::error_code), typename traits_type::receive_cancelled_signature >::value,- asio::detail::completion_payload<+ channel_payload< R(asio::error_code), typename traits_type::receive_cancelled_signature >,- asio::detail::completion_payload<+ channel_payload< R(asio::error_code), typename traits_type::receive_cancelled_signature, typename traits_type::receive_closed_signature >- >- > payload_type;+ >::type+ >::type payload_type; // Construct with empty buffer. implementation_type()@@ -543,13 +541,13 @@ // Move from another buffer. void buffer_move_from(implementation_type& other) {- size_ = other.size_;+ size_ = other.buffer_; other.size_ = 0; first_ = other.first_;- other.first_.count_ = 0;- rest_ = static_cast<- typename traits_type::template container<buffered_value>::type&&>(- other.rest_);+ other.first.count_ = 0;+ rest_ = ASIO_MOVE_CAST(+ typename traits_type::template container<+ buffered_value>::type)(other.rest_); other.buffer_clear(); } @@ -630,7 +628,7 @@ void buffer_clear() { size_ = 0;- first_.count_ = 0;+ first_.count_ == 0; rest_.clear(); }
link/modules/asio-standalone/asio/include/asio/experimental/detail/coro_promise_allocator.hpp view
@@ -13,7 +13,6 @@ #define ASIO_EXPERIMENTAL_DETAIL_CORO_PROMISE_ALLOCATOR_HPP #include "asio/detail/config.hpp"-#include <limits> #include "asio/experimental/coro_traits.hpp" namespace asio {@@ -65,6 +64,7 @@ return std::numeric_limits<std::size_t>::max(); } + template <typename T, typename First, typename... Args> constexpr std::size_t variadic_first(std::size_t pos = 0u) {@@ -94,14 +94,14 @@ allocator_type get_allocator() const {return alloc_;} template <typename... Args>- void* operator new(std::size_t size, Args & ... args)+ void* operator new(const std::size_t size, Args & ... args) { return allocate_coroutine(size, get_variadic<variadic_first<std::allocator_arg_t, std::decay_t<Args>...>() + 1u>(args...)); } - void operator delete(void* raw, std::size_t size)+ void operator delete(void* raw, const std::size_t size) { deallocate_coroutine<allocator_type>(raw, size); }
link/modules/asio-standalone/asio/include/asio/experimental/detail/has_signature.hpp view
@@ -2,7 +2,7 @@ // experimental/detail/has_signature.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/experimental/detail/impl/channel_service.hpp view
@@ -2,7 +2,7 @@ // experimental/detail/impl/channel_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -22,8 +22,7 @@ namespace detail { template <typename Mutex>-inline channel_service<Mutex>::channel_service(- asio::execution_context& ctx)+inline channel_service<Mutex>::channel_service(execution_context& ctx) : asio::detail::execution_context_service_base<channel_service>(ctx), mutex_(), impl_list_(0)@@ -156,7 +155,7 @@ template <typename Mutex> inline std::size_t channel_service<Mutex>::capacity( const channel_service<Mutex>::base_implementation_type& impl)- const noexcept+ const ASIO_NOEXCEPT { typename Mutex::scoped_lock lock(impl.mutex_); @@ -166,7 +165,7 @@ template <typename Mutex> inline bool channel_service<Mutex>::is_open( const channel_service<Mutex>::base_implementation_type& impl)- const noexcept+ const ASIO_NOEXCEPT { typename Mutex::scoped_lock lock(impl.mutex_); @@ -205,7 +204,7 @@ { impl.waiters_.pop(); traits_type::invoke_receive_closed(- post_receive<payload_type,+ complete_receive<payload_type, typename traits_type::receive_closed_signature>( static_cast<channel_receive<payload_type>*>(op))); }@@ -239,7 +238,7 @@ { impl.waiters_.pop(); traits_type::invoke_receive_cancelled(- post_receive<payload_type,+ complete_receive<payload_type, typename traits_type::receive_cancelled_signature>( static_cast<channel_receive<payload_type>*>(op))); }@@ -278,7 +277,7 @@ { impl.waiters_.pop(); traits_type::invoke_receive_cancelled(- post_receive<payload_type,+ complete_receive<payload_type, typename traits_type::receive_cancelled_signature>( static_cast<channel_receive<payload_type>*>(op))); }@@ -303,7 +302,7 @@ template <typename Mutex> inline bool channel_service<Mutex>::ready( const channel_service<Mutex>::base_implementation_type& impl)- const noexcept+ const ASIO_NOEXCEPT { typename Mutex::scoped_lock lock(impl.mutex_); @@ -315,7 +314,7 @@ typename... Signatures, typename... Args> bool channel_service<Mutex>::try_send( channel_service<Mutex>::implementation_type<Traits, Signatures...>& impl,- bool via_dispatch, Args&&... args)+ ASIO_MOVE_ARG(Args)... args) { typedef typename implementation_type<Traits, Signatures...>::payload_type payload_type;@@ -330,7 +329,7 @@ } case buffer: {- impl.buffer_push(Message(0, static_cast<Args&&>(args)...));+ impl.buffer_push(Message(0, ASIO_MOVE_CAST(Args)(args)...)); impl.receive_state_ = buffer; if (impl.buffer_size() == impl.max_buffer_size_) impl.send_state_ = block;@@ -338,17 +337,13 @@ } case waiter: {- payload_type payload(Message(0, static_cast<Args&&>(args)...));+ payload_type payload(Message(0, ASIO_MOVE_CAST(Args)(args)...)); channel_receive<payload_type>* receive_op = static_cast<channel_receive<payload_type>*>(impl.waiters_.front()); impl.waiters_.pop();+ receive_op->complete(ASIO_MOVE_CAST(payload_type)(payload)); if (impl.waiters_.empty()) impl.send_state_ = impl.max_buffer_size_ ? buffer : block;- lock.unlock();- if (via_dispatch)- receive_op->dispatch(static_cast<payload_type&&>(payload));- else- receive_op->post(static_cast<payload_type&&>(payload)); return true; } case closed:@@ -364,7 +359,7 @@ typename... Signatures, typename... Args> std::size_t channel_service<Mutex>::try_send_n( channel_service<Mutex>::implementation_type<Traits, Signatures...>& impl,- std::size_t count, bool via_dispatch, Args&&... args)+ std::size_t count, ASIO_MOVE_ARG(Args)... args) { typedef typename implementation_type<Traits, Signatures...>::payload_type payload_type;@@ -386,7 +381,7 @@ return 0; } - payload_type payload(Message(0, static_cast<Args&&>(args)...));+ payload_type payload(Message(0, ASIO_MOVE_CAST(Args)(args)...)); for (std::size_t i = 0; i < count; ++i) {@@ -399,7 +394,7 @@ case buffer: { i += impl.buffer_push_n(count - i,- static_cast<payload_type&&>(payload));+ ASIO_MOVE_CAST(payload_type)(payload)); impl.receive_state_ = buffer; if (impl.buffer_size() == impl.max_buffer_size_) impl.send_state_ = block;@@ -410,13 +405,9 @@ channel_receive<payload_type>* receive_op = static_cast<channel_receive<payload_type>*>(impl.waiters_.front()); impl.waiters_.pop();+ receive_op->complete(payload); if (impl.waiters_.empty()) impl.send_state_ = impl.max_buffer_size_ ? buffer : block;- lock.unlock();- if (via_dispatch)- receive_op->dispatch(payload);- else- receive_op->post(payload); break; } case closed:@@ -465,9 +456,9 @@ channel_receive<payload_type>* receive_op = static_cast<channel_receive<payload_type>*>(impl.waiters_.front()); impl.waiters_.pop();+ receive_op->complete(send_op->get_payload()); if (impl.waiters_.empty()) impl.send_state_ = impl.max_buffer_size_ ? buffer : block;- receive_op->post(send_op->get_payload()); send_op->immediate(); break; }@@ -484,7 +475,7 @@ template <typename Traits, typename... Signatures, typename Handler> bool channel_service<Mutex>::try_receive( channel_service<Mutex>::implementation_type<Traits, Signatures...>& impl,- Handler&& handler)+ ASIO_MOVE_ARG(Handler) handler) { typedef typename implementation_type<Traits, Signatures...>::payload_type payload_type;@@ -506,7 +497,7 @@ impl.buffer_pop(); impl.buffer_push(send_op->get_payload()); impl.waiters_.pop();- send_op->post();+ send_op->complete(); } else {@@ -517,9 +508,8 @@ } lock.unlock(); asio::detail::non_const_lvalue<Handler> handler2(handler);- asio::detail::completion_payload_handler<- payload_type, decay_t<Handler>>(- static_cast<payload_type&&>(payload), handler2.value)();+ channel_handler<payload_type, typename decay<Handler>::type>(+ ASIO_MOVE_CAST(payload_type)(payload), handler2.value)(); return true; } case waiter:@@ -528,14 +518,13 @@ static_cast<channel_send<payload_type>*>(impl.waiters_.front()); payload_type payload = send_op->get_payload(); impl.waiters_.pop();+ send_op->complete(); if (impl.waiters_.front() == 0) impl.receive_state_ = (impl.send_state_ == closed) ? closed : block;- send_op->post(); lock.unlock(); asio::detail::non_const_lvalue<Handler> handler2(handler);- asio::detail::completion_payload_handler<- payload_type, decay_t<Handler>>(- static_cast<payload_type&&>(payload), handler2.value)();+ channel_handler<payload_type, typename decay<Handler>::type>(+ ASIO_MOVE_CAST(payload_type)(payload), handler2.value)(); return true; } case closed:@@ -572,14 +561,14 @@ case buffer: { payload_type payload(- static_cast<payload_type&&>(impl.buffer_front()));+ ASIO_MOVE_CAST(payload_type)(impl.buffer_front())); if (channel_send<payload_type>* send_op = static_cast<channel_send<payload_type>*>(impl.waiters_.front())) { impl.buffer_pop(); impl.buffer_push(send_op->get_payload()); impl.waiters_.pop();- send_op->post();+ send_op->complete(); } else {@@ -588,7 +577,7 @@ impl.receive_state_ = (impl.send_state_ == closed) ? closed : block; impl.send_state_ = (impl.send_state_ == closed) ? closed : buffer; }- receive_op->immediate(static_cast<payload_type&&>(payload));+ receive_op->immediate(ASIO_MOVE_CAST(payload_type)(payload)); break; } case waiter:@@ -597,17 +586,17 @@ static_cast<channel_send<payload_type>*>(impl.waiters_.front()); payload_type payload = send_op->get_payload(); impl.waiters_.pop();+ send_op->complete(); if (impl.waiters_.front() == 0) impl.receive_state_ = (impl.send_state_ == closed) ? closed : block;- send_op->post();- receive_op->immediate(static_cast<payload_type&&>(payload));+ receive_op->immediate(ASIO_MOVE_CAST(payload_type)(payload)); break; } case closed: default: { traits_type::invoke_receive_closed(- post_receive<payload_type,+ complete_receive<payload_type, typename traits_type::receive_closed_signature>(receive_op)); break; }
link/modules/asio-standalone/asio/include/asio/experimental/detail/partial_promise.hpp view
@@ -54,12 +54,12 @@ struct partial_promise_base { template <typename Executor, typename Token, typename... Args>- void* operator new(std::size_t size, Executor&, Token& tk, Args&...)+ void* operator new(const std::size_t size, Executor&, Token& tk, Args&...) { return allocate_coroutine<Allocator>(size, get_associated_allocator(tk)); } - void operator delete(void* raw, std::size_t size)+ void operator delete(void* raw, const std::size_t size) { deallocate_coroutine<Allocator>(raw, size); }@@ -110,7 +110,9 @@ } }; -} // namespace detail+++}; // namespace detail } // namespace experimental } // namespace asio
link/modules/asio-standalone/asio/include/asio/experimental/impl/as_single.hpp view
@@ -2,7 +2,7 @@ // experimental/impl/as_single.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -16,12 +16,16 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"+ #include <tuple>+ #include "asio/associator.hpp" #include "asio/async_result.hpp"+#include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_cont_helpers.hpp"-#include "asio/detail/initiation_base.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/type_traits.hpp"+#include "asio/detail/variadic_templates.hpp" #include "asio/detail/push_options.hpp" @@ -38,32 +42,33 @@ template <typename CompletionToken> as_single_handler(as_single_t<CompletionToken> e)- : handler_(static_cast<CompletionToken&&>(e.token_))+ : handler_(ASIO_MOVE_CAST(CompletionToken)(e.token_)) { } template <typename RedirectedHandler>- as_single_handler(RedirectedHandler&& h)- : handler_(static_cast<RedirectedHandler&&>(h))+ as_single_handler(ASIO_MOVE_ARG(RedirectedHandler) h)+ : handler_(ASIO_MOVE_CAST(RedirectedHandler)(h)) { } void operator()() {- static_cast<Handler&&>(handler_)();+ ASIO_MOVE_OR_LVALUE(Handler)(handler_)(); } template <typename Arg>- void operator()(Arg&& arg)+ void operator()(ASIO_MOVE_ARG(Arg) arg) {- static_cast<Handler&&>(handler_)(static_cast<Arg&&>(arg));+ ASIO_MOVE_OR_LVALUE(Handler)(handler_)(+ ASIO_MOVE_CAST(Arg)(arg)); } template <typename... Args>- void operator()(Args&&... args)+ void operator()(ASIO_MOVE_ARG(Args)... args) {- static_cast<Handler&&>(handler_)(- std::make_tuple(static_cast<Args&&>(args)...));+ ASIO_MOVE_OR_LVALUE(Handler)(handler_)(+ std::make_tuple(ASIO_MOVE_CAST(Args)(args)...)); } //private:@@ -71,6 +76,32 @@ }; template <typename Handler>+inline asio_handler_allocate_is_deprecated+asio_handler_allocate(std::size_t size,+ as_single_handler<Handler>* this_handler)+{+#if defined(ASIO_NO_DEPRECATED)+ asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+ return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+ return asio_handler_alloc_helpers::allocate(+ size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler>+inline asio_handler_deallocate_is_deprecated+asio_handler_deallocate(void* pointer, std::size_t size,+ as_single_handler<Handler>* this_handler)+{+ asio_handler_alloc_helpers::deallocate(+ pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler> inline bool asio_handler_is_continuation( as_single_handler<Handler>* this_handler) {@@ -78,6 +109,30 @@ this_handler->handler_); } +template <typename Function, typename Handler>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(Function& function,+ as_single_handler<Handler>* this_handler)+{+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Function, typename Handler>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(const Function& function,+ as_single_handler<Handler>* this_handler)+{+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}+ template <typename Signature> struct as_single_signature {@@ -99,7 +154,7 @@ template <typename R, typename... Args> struct as_single_signature<R(Args...)> {- typedef R type(std::tuple<decay_t<Args>...>);+ typedef R type(std::tuple<typename decay<Args>::type...>); }; } // namespace detail@@ -110,45 +165,44 @@ template <typename CompletionToken, typename Signature> struct async_result<experimental::as_single_t<CompletionToken>, Signature> {+ typedef typename async_result<CompletionToken,+ typename experimental::detail::as_single_signature<Signature>::type>+ ::return_type return_type;+ template <typename Initiation>- struct init_wrapper : detail::initiation_base<Initiation>+ struct init_wrapper {- using detail::initiation_base<Initiation>::initiation_base;-- template <typename Handler, typename... Args>- void operator()(Handler&& handler, Args&&... args) &&+ init_wrapper(Initiation init)+ : initiation_(ASIO_MOVE_CAST(Initiation)(init)) {- static_cast<Initiation&&>(*this)(- experimental::detail::as_single_handler<decay_t<Handler>>(- static_cast<Handler&&>(handler)),- static_cast<Args&&>(args)...); } template <typename Handler, typename... Args>- void operator()(Handler&& handler, Args&&... args) const &+ void operator()(+ ASIO_MOVE_ARG(Handler) handler,+ ASIO_MOVE_ARG(Args)... args) {- static_cast<const Initiation&>(*this)(- experimental::detail::as_single_handler<decay_t<Handler>>(- static_cast<Handler&&>(handler)),- static_cast<Args&&>(args)...);+ ASIO_MOVE_CAST(Initiation)(initiation_)(+ experimental::detail::as_single_handler<+ typename decay<Handler>::type>(+ ASIO_MOVE_CAST(Handler)(handler)),+ ASIO_MOVE_CAST(Args)(args)...); }++ Initiation initiation_; }; template <typename Initiation, typename RawCompletionToken, typename... Args>- static auto initiate(Initiation&& initiation,- RawCompletionToken&& token, Args&&... args)- -> decltype(- async_initiate<CompletionToken,- typename experimental::detail::as_single_signature<Signature>::type>(- init_wrapper<decay_t<Initiation>>(- static_cast<Initiation&&>(initiation)),- token.token_, static_cast<Args&&>(args)...))+ static return_type initiate(+ ASIO_MOVE_ARG(Initiation) initiation,+ ASIO_MOVE_ARG(RawCompletionToken) token,+ ASIO_MOVE_ARG(Args)... args) { return async_initiate<CompletionToken, typename experimental::detail::as_single_signature<Signature>::type>(- init_wrapper<decay_t<Initiation>>(- static_cast<Initiation&&>(initiation)),- token.token_, static_cast<Args&&>(args)...);+ init_wrapper<typename decay<Initiation>::type>(+ ASIO_MOVE_CAST(Initiation)(initiation)),+ token.token_, ASIO_MOVE_CAST(Args)(args)...); } }; @@ -158,15 +212,19 @@ experimental::detail::as_single_handler<Handler>, DefaultCandidate> : Associator<Handler, DefaultCandidate> {- static typename Associator<Handler, DefaultCandidate>::type get(- const experimental::detail::as_single_handler<Handler>& h) noexcept+ static typename Associator<Handler, DefaultCandidate>::type+ get(const experimental::detail::as_single_handler<Handler>& h)+ ASIO_NOEXCEPT { return Associator<Handler, DefaultCandidate>::get(h.handler_); } - static auto get(const experimental::detail::as_single_handler<Handler>& h,- const DefaultCandidate& c) noexcept- -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))+ static ASIO_AUTO_RETURN_TYPE_PREFIX2(+ typename Associator<Handler, DefaultCandidate>::type)+ get(const experimental::detail::as_single_handler<Handler>& h,+ const DefaultCandidate& c) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ Associator<Handler, DefaultCandidate>::get(h.handler_, c))) { return Associator<Handler, DefaultCandidate>::get(h.handler_, c); }
link/modules/asio-standalone/asio/include/asio/experimental/impl/channel_error.ipp view
@@ -2,7 +2,7 @@ // experimental/impl/channel_error.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -28,7 +28,7 @@ class channel_category : public asio::error_category { public:- const char* name() const noexcept+ const char* name() const ASIO_ERROR_CATEGORY_NOEXCEPT { return "asio.channel"; }
+ link/modules/asio-standalone/asio/include/asio/experimental/impl/co_composed.hpp view
@@ -0,0 +1,1175 @@+//+// experimental/impl/co_composed.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_IMPL_EXPERIMENTAL_CO_COMPOSED_HPP+#define ASIO_IMPL_EXPERIMENTAL_CO_COMPOSED_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include <new>+#include <tuple>+#include <variant>+#include "asio/associated_cancellation_slot.hpp"+#include "asio/associator.hpp"+#include "asio/async_result.hpp"+#include "asio/cancellation_state.hpp"+#include "asio/detail/composed_work.hpp"+#include "asio/detail/recycling_allocator.hpp"+#include "asio/detail/throw_error.hpp"+#include "asio/detail/type_traits.hpp"+#include "asio/error.hpp"++#if defined(ASIO_HAS_STD_COROUTINE)+# include <coroutine>+#else // defined(ASIO_HAS_STD_COROUTINE)+# include <experimental/coroutine>+#endif // defined(ASIO_HAS_STD_COROUTINE)++#if defined(ASIO_ENABLE_HANDLER_TRACKING)+# if defined(ASIO_HAS_SOURCE_LOCATION)+# include "asio/detail/source_location.hpp"+# endif // defined(ASIO_HAS_SOURCE_LOCATION)+#endif // defined(ASIO_ENABLE_HANDLER_TRACKING)++#include "asio/detail/push_options.hpp"++namespace asio {+namespace experimental {+namespace detail {++#if defined(ASIO_HAS_STD_COROUTINE)+using std::coroutine_handle;+using std::suspend_always;+using std::suspend_never;+#else // defined(ASIO_HAS_STD_COROUTINE)+using std::experimental::coroutine_handle;+using std::experimental::suspend_always;+using std::experimental::suspend_never;+#endif // defined(ASIO_HAS_STD_COROUTINE)++using asio::detail::composed_io_executors;+using asio::detail::composed_work;+using asio::detail::composed_work_guard;+using asio::detail::get_composed_io_executor;+using asio::detail::make_composed_io_executors;+using asio::detail::recycling_allocator;+using asio::detail::throw_error;++template <typename Executors, typename Handler, typename Return>+class co_composed_state;++template <typename Executors, typename Handler, typename Return>+class co_composed_handler_base;++template <typename Executors, typename Handler, typename Return>+class co_composed_promise;++template <completion_signature... Signatures>+class co_composed_returns+{+};++struct co_composed_on_suspend+{+ void (*fn_)(void*) = nullptr;+ void* arg_ = nullptr;+};++template <typename... T>+struct co_composed_completion : std::tuple<T&&...>+{+ template <typename... U>+ co_composed_completion(U&&... u) noexcept+ : std::tuple<T&&...>(std::forward<U>(u)...)+ {+ }+};++template <typename Executors, typename Handler,+ typename Return, typename Signature>+class co_composed_state_return_overload;++template <typename Executors, typename Handler,+ typename Return, typename R, typename... Args>+class co_composed_state_return_overload<+ Executors, Handler, Return, R(Args...)>+{+public:+ using derived_type = co_composed_state<Executors, Handler, Return>;+ using promise_type = co_composed_promise<Executors, Handler, Return>;+ using return_type = std::tuple<Args...>;++ void on_cancellation_complete_with(Args... args)+ {+ derived_type& state = *static_cast<derived_type*>(this);+ state.return_value_ = std::make_tuple(std::move(args)...);+ state.cancellation_on_suspend_fn(+ [](void* p)+ {+ auto& promise = *static_cast<promise_type*>(p);++ co_composed_handler_base<Executors, Handler,+ Return> composed_handler(promise);++ Handler handler(std::move(promise.state().handler_));+ return_type result(+ std::move(std::get<return_type>(promise.state().return_value_)));++ co_composed_handler_base<Executors, Handler,+ Return>(std::move(composed_handler));++ std::apply(std::move(handler), std::move(result));+ });+ }+};++template <typename Executors, typename Handler, typename Return>+class co_composed_state_return;++template <typename Executors, typename Handler, typename... Signatures>+class co_composed_state_return<+ Executors, Handler, co_composed_returns<Signatures...>>+ : public co_composed_state_return_overload<Executors,+ Handler, co_composed_returns<Signatures...>, Signatures>...+{+public:+ using co_composed_state_return_overload<Executors,+ Handler, co_composed_returns<Signatures...>,+ Signatures>::on_cancellation_complete_with...;++private:+ template <typename, typename, typename, typename>+ friend class co_composed_promise_return_overload;+ template <typename, typename, typename, typename>+ friend class co_composed_state_return_overload;++ std::variant<std::monostate,+ typename co_composed_state_return_overload<+ Executors, Handler, co_composed_returns<Signatures...>,+ Signatures>::return_type...> return_value_;+};++template <typename Executors, typename Handler,+ typename Return, typename... Signatures>+struct co_composed_state_default_cancellation_on_suspend_impl;++template <typename Executors, typename Handler, typename Return>+struct co_composed_state_default_cancellation_on_suspend_impl<+ Executors, Handler, Return>+{+ static constexpr void (*fn())(void*)+ {+ return nullptr;+ }+};++template <typename Executors, typename Handler, typename Return,+ typename R, typename... Args, typename... Signatures>+struct co_composed_state_default_cancellation_on_suspend_impl<+ Executors, Handler, Return, R(Args...), Signatures...>+{+ static constexpr void (*fn())(void*)+ {+ return co_composed_state_default_cancellation_on_suspend_impl<+ Executors, Handler, Return, Signatures...>::fn();+ }+};++template <typename Executors, typename Handler, typename Return,+ typename R, typename... Args, typename... Signatures>+struct co_composed_state_default_cancellation_on_suspend_impl<Executors,+ Handler, Return, R(asio::error_code, Args...), Signatures...>+{+ using promise_type = co_composed_promise<Executors, Handler, Return>;+ using return_type = std::tuple<asio::error_code, Args...>;++ static constexpr void (*fn())(void*)+ {+ if constexpr ((is_constructible<Args>::value && ...))+ {+ return [](void* p)+ {+ auto& promise = *static_cast<promise_type*>(p);++ co_composed_handler_base<Executors, Handler,+ Return> composed_handler(promise);++ Handler handler(std::move(promise.state().handler_));++ co_composed_handler_base<Executors, Handler,+ Return>(std::move(composed_handler));++ std::move(handler)(+ asio::error_code(asio::error::operation_aborted),+ Args{}...);+ };+ }+ else+ {+ return co_composed_state_default_cancellation_on_suspend_impl<+ Executors, Handler, Return, Signatures...>::fn();+ }+ }+};++template <typename Executors, typename Handler, typename Return,+ typename R, typename... Args, typename... Signatures>+struct co_composed_state_default_cancellation_on_suspend_impl<Executors,+ Handler, Return, R(std::exception_ptr, Args...), Signatures...>+{+ using promise_type = co_composed_promise<Executors, Handler, Return>;+ using return_type = std::tuple<std::exception_ptr, Args...>;++ static constexpr void (*fn())(void*)+ {+ if constexpr ((is_constructible<Args>::value && ...))+ {+ return [](void* p)+ {+ auto& promise = *static_cast<promise_type*>(p);++ co_composed_handler_base<Executors, Handler,+ Return> composed_handler(promise);++ Handler handler(std::move(promise.state().handler_));++ co_composed_handler_base<Executors, Handler,+ Return>(std::move(composed_handler));++ std::move(handler)(+ std::make_exception_ptr(+ asio::system_error(+ asio::error::operation_aborted, "co_await")),+ Args{}...);+ };+ }+ else+ {+ return co_composed_state_default_cancellation_on_suspend_impl<+ Executors, Handler, Return, Signatures...>::fn();+ }+ }+};++template <typename Executors, typename Handler, typename Return>+struct co_composed_state_default_cancellation_on_suspend;++template <typename Executors, typename Handler, typename... Signatures>+struct co_composed_state_default_cancellation_on_suspend<+ Executors, Handler, co_composed_returns<Signatures...>>+ : co_composed_state_default_cancellation_on_suspend_impl<Executors,+ Handler, co_composed_returns<Signatures...>, Signatures...>+{+};++template <typename Executors, typename Handler, typename Return>+class co_composed_state_cancellation+{+public:+ using cancellation_slot_type = cancellation_slot;++ cancellation_slot_type get_cancellation_slot() const noexcept+ {+ return cancellation_state_.slot();+ }++ cancellation_state get_cancellation_state() const noexcept+ {+ return cancellation_state_;+ }++ void reset_cancellation_state()+ {+ cancellation_state_ = cancellation_state(+ (get_associated_cancellation_slot)(+ static_cast<co_composed_state<Executors, Handler, Return>*>(+ this)->handler()));+ }++ template <typename Filter>+ void reset_cancellation_state(Filter filter)+ {+ cancellation_state_ = cancellation_state(+ (get_associated_cancellation_slot)(+ static_cast<co_composed_state<Executors, Handler, Return>*>(+ this)->handler()), filter, filter);+ }++ template <typename InFilter, typename OutFilter>+ void reset_cancellation_state(InFilter&& in_filter, OutFilter&& out_filter)+ {+ cancellation_state_ = cancellation_state(+ (get_associated_cancellation_slot)(+ static_cast<co_composed_state<Executors, Handler, Return>*>(+ this)->handler()),+ std::forward<InFilter>(in_filter),+ std::forward<OutFilter>(out_filter));+ }++ cancellation_type_t cancelled() const noexcept+ {+ return cancellation_state_.cancelled();+ }++ void clear_cancellation_slot() noexcept+ {+ cancellation_state_.slot().clear();+ }++ [[nodiscard]] bool throw_if_cancelled() const noexcept+ {+ return throw_if_cancelled_;+ }++ void throw_if_cancelled(bool b) noexcept+ {+ throw_if_cancelled_ = b;+ }++ [[nodiscard]] bool complete_if_cancelled() const noexcept+ {+ return complete_if_cancelled_;+ }++ void complete_if_cancelled(bool b) noexcept+ {+ complete_if_cancelled_ = b;+ }++private:+ template <typename, typename, typename>+ friend class co_composed_promise;+ template <typename, typename, typename, typename>+ friend class co_composed_state_return_overload;++ void cancellation_on_suspend_fn(void (*fn)(void*))+ {+ cancellation_on_suspend_fn_ = fn;+ }++ void check_for_cancellation_on_transform()+ {+ if (throw_if_cancelled_ && !!cancelled())+ throw_error(asio::error::operation_aborted, "co_await");+ }++ bool check_for_cancellation_on_suspend(+ co_composed_promise<Executors, Handler, Return>& promise) noexcept+ {+ if (complete_if_cancelled_ && !!cancelled() && cancellation_on_suspend_fn_)+ {+ promise.state().work_.reset();+ promise.state().on_suspend_->fn_ = cancellation_on_suspend_fn_;+ promise.state().on_suspend_->arg_ = &promise;+ return false;+ }+ return true;+ }++ cancellation_state cancellation_state_;+ void (*cancellation_on_suspend_fn_)(void*) =+ co_composed_state_default_cancellation_on_suspend<+ Executors, Handler, Return>::fn();+ bool throw_if_cancelled_ = false;+ bool complete_if_cancelled_ = true;+};++template <typename Executors, typename Handler, typename Return>+ requires is_same<+ typename associated_cancellation_slot<+ Handler, cancellation_slot+ >::asio_associated_cancellation_slot_is_unspecialised,+ void>::value+class co_composed_state_cancellation<Executors, Handler, Return>+{+public:+ void reset_cancellation_state()+ {+ }++ template <typename Filter>+ void reset_cancellation_state(Filter)+ {+ }++ template <typename InFilter, typename OutFilter>+ void reset_cancellation_state(InFilter&&, OutFilter&&)+ {+ }++ cancellation_type_t cancelled() const noexcept+ {+ return cancellation_type::none;+ }++ void clear_cancellation_slot() noexcept+ {+ }++ [[nodiscard]] bool throw_if_cancelled() const noexcept+ {+ return false;+ }++ void throw_if_cancelled(bool) noexcept+ {+ }++ [[nodiscard]] bool complete_if_cancelled() const noexcept+ {+ return false;+ }++ void complete_if_cancelled(bool) noexcept+ {+ }++private:+ template <typename, typename, typename>+ friend class co_composed_promise;+ template <typename, typename, typename, typename>+ friend class co_composed_state_return_overload;++ void cancellation_on_suspend_fn(void (*)(void*))+ {+ }++ void check_for_cancellation_on_transform() noexcept+ {+ }++ bool check_for_cancellation_on_suspend(+ co_composed_promise<Executors, Handler, Return>&) noexcept+ {+ return true;+ }+};++template <typename Executors, typename Handler, typename Return>+class co_composed_state+ : public co_composed_state_return<Executors, Handler, Return>,+ public co_composed_state_cancellation<Executors, Handler, Return>+{+public:+ using io_executor_type = typename composed_work_guard<+ typename composed_work<Executors>::head_type>::executor_type;++ template <typename H>+ co_composed_state(composed_io_executors<Executors>&& executors,+ H&& h, co_composed_on_suspend& on_suspend)+ : work_(std::move(executors)),+ handler_(std::forward<H>(h)),+ on_suspend_(&on_suspend)+ {+ this->reset_cancellation_state(enable_terminal_cancellation());+ }++ io_executor_type get_io_executor() const noexcept+ {+ return work_.head_.get_executor();+ }++ template <typename... Args>+ [[nodiscard]] co_composed_completion<Args...> complete(Args&&... args)+ requires requires { declval<Handler>()(std::forward<Args>(args)...); }+ {+ return co_composed_completion<Args...>(std::forward<Args>(args)...);+ }++ const Handler& handler() const noexcept+ {+ return handler_;+ }++private:+ template <typename, typename, typename>+ friend class co_composed_handler_base;+ template <typename, typename, typename>+ friend class co_composed_promise;+ template <typename, typename, typename, typename>+ friend class co_composed_promise_return_overload;+ template <typename, typename, typename>+ friend class co_composed_state_cancellation;+ template <typename, typename, typename, typename>+ friend class co_composed_state_return_overload;+ template <typename, typename, typename, typename...>+ friend struct co_composed_state_default_cancellation_on_suspend_impl;++ composed_work<Executors> work_;+ Handler handler_;+ co_composed_on_suspend* on_suspend_;+};++template <typename Executors, typename Handler, typename Return>+class co_composed_handler_cancellation+{+public:+ using cancellation_slot_type = cancellation_slot;++ cancellation_slot_type get_cancellation_slot() const noexcept+ {+ return static_cast<+ const co_composed_handler_base<Executors, Handler, Return>*>(+ this)->promise().state().get_cancellation_slot();+ }+};++template <typename Executors, typename Handler, typename Return>+ requires is_same<+ typename associated_cancellation_slot<+ Handler, cancellation_slot+ >::asio_associated_cancellation_slot_is_unspecialised,+ void>::value+class co_composed_handler_cancellation<Executors, Handler, Return>+{+};++template <typename Executors, typename Handler, typename Return>+class co_composed_handler_base :+ public co_composed_handler_cancellation<Executors, Handler, Return>+{+public:+ co_composed_handler_base(+ co_composed_promise<Executors, Handler, Return>& p) noexcept+ : p_(&p)+ {+ }++ co_composed_handler_base(co_composed_handler_base&& other) noexcept+ : p_(std::exchange(other.p_, nullptr))+ {+ }++ ~co_composed_handler_base()+ {+ if (p_) [[unlikely]]+ p_->destroy();+ }++ co_composed_promise<Executors, Handler, Return>& promise() const noexcept+ {+ return *p_;+ }++protected:+ void resume(void* result)+ {+ co_composed_on_suspend on_suspend{};+ std::exchange(p_, nullptr)->resume(p_, result, on_suspend);+ if (on_suspend.fn_)+ on_suspend.fn_(on_suspend.arg_);+ }++private:+ co_composed_promise<Executors, Handler, Return>* p_;+};++template <typename Executors, typename Handler,+ typename Return, typename Signature>+class co_composed_handler;++template <typename Executors, typename Handler,+ typename Return, typename R, typename... Args>+class co_composed_handler<Executors, Handler, Return, R(Args...)>+ : public co_composed_handler_base<Executors, Handler, Return>+{+public:+ using co_composed_handler_base<Executors,+ Handler, Return>::co_composed_handler_base;++ using result_type = std::tuple<typename decay<Args>::type...>;++ template <typename... T>+ void operator()(T&&... args)+ {+ result_type result(std::forward<T>(args)...);+ this->resume(&result);+ }++ static auto on_resume(void* result)+ {+ auto& args = *static_cast<result_type*>(result);+ if constexpr (sizeof...(Args) == 0)+ return;+ else if constexpr (sizeof...(Args) == 1)+ return std::move(std::get<0>(args));+ else+ return std::move(args);+ }+};++template <typename Executors, typename Handler,+ typename Return, typename R, typename... Args>+class co_composed_handler<Executors, Handler,+ Return, R(asio::error_code, Args...)>+ : public co_composed_handler_base<Executors, Handler, Return>+{+public:+ using co_composed_handler_base<Executors,+ Handler, Return>::co_composed_handler_base;++ using args_type = std::tuple<typename decay<Args>::type...>;+ using result_type = std::tuple<asio::error_code, args_type>;++ template <typename... T>+ void operator()(const asio::error_code& ec, T&&... args)+ {+ result_type result(ec, args_type(std::forward<T>(args)...));+ this->resume(&result);+ }++ static auto on_resume(void* result)+ {+ auto& [ec, args] = *static_cast<result_type*>(result);+ throw_error(ec);+ if constexpr (sizeof...(Args) == 0)+ return;+ else if constexpr (sizeof...(Args) == 1)+ return std::move(std::get<0>(args));+ else+ return std::move(args);+ }+};++template <typename Executors, typename Handler,+ typename Return, typename R, typename... Args>+class co_composed_handler<Executors, Handler,+ Return, R(std::exception_ptr, Args...)>+ : public co_composed_handler_base<Executors, Handler, Return>+{+public:+ using co_composed_handler_base<Executors,+ Handler, Return>::co_composed_handler_base;++ using args_type = std::tuple<typename decay<Args>::type...>;+ using result_type = std::tuple<std::exception_ptr, args_type>;++ template <typename... T>+ void operator()(std::exception_ptr ex, T&&... args)+ {+ result_type result(std::move(ex), args_type(std::forward<T>(args)...));+ this->resume(&result);+ }++ static auto on_resume(void* result)+ {+ auto& [ex, args] = *static_cast<result_type*>(result);+ if (ex)+ std::rethrow_exception(ex);+ if constexpr (sizeof...(Args) == 0)+ return;+ else if constexpr (sizeof...(Args) == 1)+ return std::move(std::get<0>(args));+ else+ return std::move(args);+ }+};++template <typename Executors, typename Handler, typename Return>+class co_composed_promise_return;++template <typename Executors, typename Handler>+class co_composed_promise_return<Executors, Handler, co_composed_returns<>>+{+public:+ auto final_suspend() noexcept+ {+ return suspend_never();+ }++ void return_void() noexcept+ {+ }+};++template <typename Executors, typename Handler,+ typename Return, typename Signature>+class co_composed_promise_return_overload;++template <typename Executors, typename Handler,+ typename Return, typename R, typename... Args>+class co_composed_promise_return_overload<+ Executors, Handler, Return, R(Args...)>+{+public:+ using derived_type = co_composed_promise<Executors, Handler, Return>;+ using return_type = std::tuple<Args...>;++ void return_value(std::tuple<Args...>&& value)+ {+ derived_type& promise = *static_cast<derived_type*>(this);+ promise.state().return_value_ = std::move(value);+ promise.state().work_.reset();+ promise.state().on_suspend_->arg_ = this;+ promise.state().on_suspend_->fn_ =+ [](void* p)+ {+ auto& promise = *static_cast<derived_type*>(p);++ co_composed_handler_base<Executors, Handler,+ Return> composed_handler(promise);++ Handler handler(std::move(promise.state().handler_));+ return_type result(+ std::move(std::get<return_type>(promise.state().return_value_)));++ co_composed_handler_base<Executors, Handler,+ Return>(std::move(composed_handler));++ std::apply(std::move(handler), std::move(result));+ };+ }+};++template <typename Executors, typename Handler, typename... Signatures>+class co_composed_promise_return<Executors,+ Handler, co_composed_returns<Signatures...>>+ : public co_composed_promise_return_overload<Executors,+ Handler, co_composed_returns<Signatures...>, Signatures>...+{+public:+ auto final_suspend() noexcept+ {+ return suspend_always();+ }++ using co_composed_promise_return_overload<Executors, Handler,+ co_composed_returns<Signatures...>, Signatures>::return_value...;++private:+ template <typename, typename, typename, typename>+ friend class co_composed_promise_return_overload;+};++template <typename Executors, typename Handler, typename Return>+class co_composed_promise+ : public co_composed_promise_return<Executors, Handler, Return>+{+public:+ template <typename... Args>+ void* operator new(std::size_t size,+ co_composed_state<Executors, Handler, Return>& state, Args&&...)+ {+ block_allocator_type allocator(+ (get_associated_allocator)(state.handler_,+ recycling_allocator<void>()));++ block* base_ptr = std::allocator_traits<block_allocator_type>::allocate(+ allocator, blocks(sizeof(allocator_type)) + blocks(size));++ new (static_cast<void*>(base_ptr)) allocator_type(std::move(allocator));++ return base_ptr + blocks(sizeof(allocator_type));+ }++ template <typename C, typename... Args>+ void* operator new(std::size_t size, C&&,+ co_composed_state<Executors, Handler, Return>& state, Args&&...)+ {+ return co_composed_promise::operator new(size, state);+ }++ void operator delete(void* ptr, std::size_t size)+ {+ block* base_ptr = static_cast<block*>(ptr) - blocks(sizeof(allocator_type));++ allocator_type* allocator_ptr = std::launder(+ static_cast<allocator_type*>(static_cast<void*>(base_ptr)));++ block_allocator_type block_allocator(std::move(*allocator_ptr));+ allocator_ptr->~allocator_type();++ std::allocator_traits<block_allocator_type>::deallocate(block_allocator,+ base_ptr, blocks(sizeof(allocator_type)) + blocks(size));+ }++ template <typename... Args>+ co_composed_promise(+ co_composed_state<Executors, Handler, Return>& state, Args&&...)+ : state_(state)+ {+ }++ template <typename C, typename... Args>+ co_composed_promise(C&&,+ co_composed_state<Executors, Handler, Return>& state, Args&&...)+ : state_(state)+ {+ }++ void destroy() noexcept+ {+ coroutine_handle<co_composed_promise>::from_promise(*this).destroy();+ }++ void resume(co_composed_promise*& owner, void* result,+ co_composed_on_suspend& on_suspend)+ {+ state_.on_suspend_ = &on_suspend;+ state_.clear_cancellation_slot();+ owner_ = &owner;+ result_ = result;+ coroutine_handle<co_composed_promise>::from_promise(*this).resume();+ }++ co_composed_state<Executors, Handler, Return>& state() noexcept+ {+ return state_;+ }++ void get_return_object() noexcept+ {+ }++ auto initial_suspend() noexcept+ {+ return suspend_never();+ }++ void unhandled_exception()+ {+ if (owner_)+ *owner_ = this;+ throw;+ }++ template <async_operation Op>+ auto await_transform(Op&& op+#if defined(ASIO_ENABLE_HANDLER_TRACKING)+# if defined(ASIO_HAS_SOURCE_LOCATION)+ , asio::detail::source_location location+ = asio::detail::source_location::current()+# endif // defined(ASIO_HAS_SOURCE_LOCATION)+#endif // defined(ASIO_ENABLE_HANDLER_TRACKING)+ )+ {+ class [[nodiscard]] awaitable+ {+ public:+ awaitable(Op&& op, co_composed_promise& promise+#if defined(ASIO_ENABLE_HANDLER_TRACKING)+# if defined(ASIO_HAS_SOURCE_LOCATION)+ , const asio::detail::source_location& location+# endif // defined(ASIO_HAS_SOURCE_LOCATION)+#endif // defined(ASIO_ENABLE_HANDLER_TRACKING)+ )+ : op_(std::forward<Op>(op)),+ promise_(promise)+#if defined(ASIO_ENABLE_HANDLER_TRACKING)+# if defined(ASIO_HAS_SOURCE_LOCATION)+ , location_(location)+# endif // defined(ASIO_HAS_SOURCE_LOCATION)+#endif // defined(ASIO_ENABLE_HANDLER_TRACKING)+ {+ }++ constexpr bool await_ready() const noexcept+ {+ return false;+ }++ void await_suspend(coroutine_handle<co_composed_promise>)+ {+ if (promise_.state_.check_for_cancellation_on_suspend(promise_))+ {+ promise_.state_.on_suspend_->arg_ = this;+ promise_.state_.on_suspend_->fn_ =+ [](void* p)+ {+#if defined(ASIO_ENABLE_HANDLER_TRACKING)+# if defined(ASIO_HAS_SOURCE_LOCATION)+ ASIO_HANDLER_LOCATION((+ static_cast<awaitable*>(p)->location_.file_name(),+ static_cast<awaitable*>(p)->location_.line(),+ static_cast<awaitable*>(p)->location_.function_name()));+# endif // defined(ASIO_HAS_SOURCE_LOCATION)+#endif // defined(ASIO_ENABLE_HANDLER_TRACKING)+ std::forward<Op>(static_cast<awaitable*>(p)->op_)(+ co_composed_handler<Executors, Handler,+ Return, completion_signature_of_t<Op>>(+ static_cast<awaitable*>(p)->promise_));+ };+ }+ }++ auto await_resume()+ {+ return co_composed_handler<Executors, Handler, Return,+ completion_signature_of_t<Op>>::on_resume(promise_.result_);+ }++ private:+ Op&& op_;+ co_composed_promise& promise_;+#if defined(ASIO_ENABLE_HANDLER_TRACKING)+# if defined(ASIO_HAS_SOURCE_LOCATION)+ asio::detail::source_location location_;+# endif // defined(ASIO_HAS_SOURCE_LOCATION)+#endif // defined(ASIO_ENABLE_HANDLER_TRACKING)+ };++ state_.check_for_cancellation_on_transform();+ return awaitable{std::forward<Op>(op), *this+#if defined(ASIO_ENABLE_HANDLER_TRACKING)+# if defined(ASIO_HAS_SOURCE_LOCATION)+ , location+# endif // defined(ASIO_HAS_SOURCE_LOCATION)+#endif // defined(ASIO_ENABLE_HANDLER_TRACKING)+ };+ }++ template <typename... Args>+ auto yield_value(co_composed_completion<Args...>&& result)+ {+ class [[nodiscard]] awaitable+ {+ public:+ awaitable(co_composed_completion<Args...>&& result,+ co_composed_promise& promise)+ : result_(std::move(result)),+ promise_(promise)+ {+ }++ constexpr bool await_ready() const noexcept+ {+ return false;+ }++ void await_suspend(coroutine_handle<co_composed_promise>)+ {+ promise_.state_.work_.reset();+ promise_.state_.on_suspend_->arg_ = this;+ promise_.state_.on_suspend_->fn_ =+ [](void* p)+ {+ awaitable& a = *static_cast<awaitable*>(p);++ co_composed_handler_base<Executors, Handler,+ Return> composed_handler(a.promise_);++ Handler handler(std::move(a.promise_.state_.handler_));+ std::tuple<typename decay<Args>::type...> result(+ std::move(static_cast<std::tuple<Args&&...>>(a.result_)));++ co_composed_handler_base<Executors, Handler,+ Return>(std::move(composed_handler));++ std::apply(std::move(handler), std::move(result));+ };+ }++ void await_resume() noexcept+ {+ }++ private:+ co_composed_completion<Args...> result_;+ co_composed_promise& promise_;+ };++ return awaitable{std::move(result), *this};+ }++private:+ using allocator_type =+ associated_allocator_t<Handler, recycling_allocator<void>>;++ union block+ {+ std::max_align_t max_align;+ alignas(allocator_type) char pad[alignof(allocator_type)];+ };++ using block_allocator_type =+ typename std::allocator_traits<allocator_type>+ ::template rebind_alloc<block>;++ static constexpr std::size_t blocks(std::size_t size)+ {+ return (size + sizeof(block) - 1) / sizeof(block);+ }++ co_composed_state<Executors, Handler, Return>& state_;+ co_composed_promise** owner_ = nullptr;+ void* result_ = nullptr;+};++template <typename Implementation, typename Executors, typename... Signatures>+class initiate_co_composed+{+public:+ using executor_type = typename composed_io_executors<Executors>::head_type;++ template <typename I>+ initiate_co_composed(I&& impl, composed_io_executors<Executors>&& executors)+ : implementation_(std::forward<I>(impl)),+ executors_(std::move(executors))+ {+ }++ executor_type get_executor() const noexcept+ {+ return executors_.head_;+ }++ template <typename Handler, typename... InitArgs>+ void operator()(Handler&& handler, InitArgs&&... init_args) const &+ {+ using handler_type = typename decay<Handler>::type;+ using returns_type = co_composed_returns<Signatures...>;+ co_composed_on_suspend on_suspend{};+ implementation_(+ co_composed_state<Executors, handler_type, returns_type>(+ executors_, std::forward<Handler>(handler), on_suspend),+ std::forward<InitArgs>(init_args)...);+ if (on_suspend.fn_)+ on_suspend.fn_(on_suspend.arg_);+ }++ template <typename Handler, typename... InitArgs>+ void operator()(Handler&& handler, InitArgs&&... init_args) &&+ {+ using handler_type = typename decay<Handler>::type;+ using returns_type = co_composed_returns<Signatures...>;+ co_composed_on_suspend on_suspend{};+ std::move(implementation_)(+ co_composed_state<Executors, handler_type, returns_type>(+ std::move(executors_), std::forward<Handler>(handler), on_suspend),+ std::forward<InitArgs>(init_args)...);+ if (on_suspend.fn_)+ on_suspend.fn_(on_suspend.arg_);+ }++private:+ Implementation implementation_;+ composed_io_executors<Executors> executors_;+};++template <typename... Signatures, typename Implementation, typename Executors>+inline initiate_co_composed<Implementation, Executors, Signatures...>+make_initiate_co_composed(Implementation&& implementation,+ composed_io_executors<Executors>&& executors)+{+ return initiate_co_composed<+ typename decay<Implementation>::type, Executors, Signatures...>(+ std::forward<Implementation>(implementation), std::move(executors));+}++} // namespace detail++template <completion_signature... Signatures,+ typename Implementation, typename... IoObjectsOrExecutors>+inline auto co_composed(Implementation&& implementation,+ IoObjectsOrExecutors&&... io_objects_or_executors)+{+ return detail::make_initiate_co_composed<Signatures...>(+ std::forward<Implementation>(implementation),+ detail::make_composed_io_executors(+ detail::get_composed_io_executor(+ std::forward<IoObjectsOrExecutors>(+ io_objects_or_executors))...));+}++} // namespace experimental++#if !defined(GENERATING_DOCUMENTATION)++template <template <typename, typename> class Associator,+ typename Executors, typename Handler, typename Return,+ typename Signature, typename DefaultCandidate>+struct associator<Associator,+ experimental::detail::co_composed_handler<+ Executors, Handler, Return, Signature>,+ DefaultCandidate>+ : Associator<Handler, DefaultCandidate>+{+ static typename Associator<Handler, DefaultCandidate>::type+ get(const experimental::detail::co_composed_handler<+ Executors, Handler, Return, Signature>& h) ASIO_NOEXCEPT+ {+ return Associator<Handler, DefaultCandidate>::get(+ h.promise().state().handler());+ }++ static ASIO_AUTO_RETURN_TYPE_PREFIX2(+ typename Associator<Handler, DefaultCandidate>::type)+ get(const experimental::detail::co_composed_handler<+ Executors, Handler, Return, Signature>& h,+ const DefaultCandidate& c) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ Associator<Handler, DefaultCandidate>::get(+ h.promise().state().handler(), c)))+ {+ return Associator<Handler, DefaultCandidate>::get(+ h.promise().state().handler(), c);+ }+};++#endif // !defined(GENERATING_DOCUMENTATION)++} // namespace asio++#if !defined(GENERATING_DOCUMENTATION)+# if defined(ASIO_HAS_STD_COROUTINE)+namespace std {+# else // defined(ASIO_HAS_STD_COROUTINE)+namespace std { namespace experimental {+# endif // defined(ASIO_HAS_STD_COROUTINE)++template <typename C, typename Executors,+ typename Handler, typename Return, typename... Args>+struct coroutine_traits<void, C&,+ asio::experimental::detail::co_composed_state<+ Executors, Handler, Return>,+ Args...>+{+ using promise_type =+ asio::experimental::detail::co_composed_promise<+ Executors, Handler, Return>;+};++template <typename C, typename Executors,+ typename Handler, typename Return, typename... Args>+struct coroutine_traits<void, C&&,+ asio::experimental::detail::co_composed_state<+ Executors, Handler, Return>,+ Args...>+{+ using promise_type =+ asio::experimental::detail::co_composed_promise<+ Executors, Handler, Return>;+};++template <typename Executors, typename Handler,+ typename Return, typename... Args>+struct coroutine_traits<void,+ asio::experimental::detail::co_composed_state<+ Executors, Handler, Return>,+ Args...>+{+ using promise_type =+ asio::experimental::detail::co_composed_promise<+ Executors, Handler, Return>;+};++# if defined(ASIO_HAS_STD_COROUTINE)+} // namespace std+# else // defined(ASIO_HAS_STD_COROUTINE)+}} // namespace std::experimental+# endif // defined(ASIO_HAS_STD_COROUTINE)+#endif // !defined(GENERATING_DOCUMENTATION)++#include "asio/detail/pop_options.hpp"++#endif // ASIO_IMPL_EXPERIMENTAL_CO_COMPOSED_HPP
link/modules/asio-standalone/asio/include/asio/experimental/impl/coro.hpp view
@@ -45,18 +45,18 @@ } template <typename Filter>- void reset_cancellation_state(Filter&& filter)+ void reset_cancellation_state(ASIO_MOVE_ARG(Filter) filter) {- state = cancellation_state(slot, static_cast<Filter&&>(filter));+ state = cancellation_state(slot, ASIO_MOVE_CAST(Filter)(filter)); } template <typename InFilter, typename OutFilter>- void reset_cancellation_state(InFilter&& in_filter,- OutFilter&& out_filter)+ void reset_cancellation_state(ASIO_MOVE_ARG(InFilter) in_filter,+ ASIO_MOVE_ARG(OutFilter) out_filter) { state = cancellation_state(slot,- static_cast<InFilter&&>(in_filter),- static_cast<OutFilter&&>(out_filter));+ ASIO_MOVE_CAST(InFilter)(in_filter),+ ASIO_MOVE_CAST(OutFilter)(out_filter)); } bool throw_if_cancelled() const@@ -600,7 +600,7 @@ cancellation_slot_type get_cancellation_slot() const noexcept {- return cancel ? cancel->state.slot() : cancellation_slot_type{};+ return cancel ? cancel->slot : cancellation_slot_type{}; } using allocator_type =@@ -767,11 +767,11 @@ auto await_resume() { return src_->reset_cancellation_state(- static_cast<Filter&&>(filter_));+ ASIO_MOVE_CAST(Filter)(filter_)); } }; - return result{cancel, static_cast<Filter&&>(reset.filter)};+ return result{cancel, ASIO_MOVE_CAST(Filter)(reset.filter)}; } // This await transformation resets the associated cancellation state.@@ -798,14 +798,14 @@ auto await_resume() { return src_->reset_cancellation_state(- static_cast<InFilter&&>(in_filter_),- static_cast<OutFilter&&>(out_filter_));+ ASIO_MOVE_CAST(InFilter)(in_filter_),+ ASIO_MOVE_CAST(OutFilter)(out_filter_)); } }; return result{cancel,- static_cast<InFilter&&>(reset.in_filter),- static_cast<OutFilter&&>(reset.out_filter)};+ ASIO_MOVE_CAST(InFilter)(reset.in_filter),+ ASIO_MOVE_CAST(OutFilter)(reset.out_filter)}; } // This await transformation determines whether cancellation is propagated as@@ -894,7 +894,7 @@ template <typename Op> auto await_transform(Op&& op,- constraint_t<is_async_operation<Op>::value> = 0)+ typename constraint<is_async_operation<Op>::value>::type = 0) { if ((cancel->state.cancelled() != cancellation_type::none) && cancel->throw_if_cancelled_)@@ -902,7 +902,7 @@ asio::detail::throw_error( asio::error::operation_aborted, "coro-cancelled"); }- using signature = completion_signature_of_t<Op>;+ using signature = typename completion_signature_of<Op>::type; using result_type = detail::coro_completion_handler_type_t<signature>; using handler_type = typename detail::coro_completion_handler_type<signature>::template@@ -1069,17 +1069,17 @@ std::true_type /* error is noexcept */, std::true_type /* result is void */) //noexcept {- return [this, the_coro = coro_,+ return [this, coro = coro_, h = std::forward<WaitHandler>(handler), exec = std::move(exec)]() mutable {- assert(the_coro);+ assert(coro); - auto ch = detail::coroutine_handle<promise_type>::from_promise(*the_coro);+ auto ch = detail::coroutine_handle<promise_type>::from_promise(*coro); assert(ch && !ch.done()); - the_coro->awaited_from = post_coroutine(std::move(exec), std::move(h));- the_coro->reset_error();+ coro->awaited_from = post_coroutine(std::move(exec), std::move(h));+ coro->reset_error(); ch.resume(); }; }@@ -1090,18 +1090,18 @@ std::true_type /* error is noexcept */, std::false_type /* result is void */) //noexcept {- return [the_coro = coro_,+ return [coro = coro_, h = std::forward<WaitHandler>(handler), exec = std::move(exec)]() mutable {- assert(the_coro);+ assert(coro); - auto ch = detail::coroutine_handle<promise_type>::from_promise(*the_coro);+ auto ch = detail::coroutine_handle<promise_type>::from_promise(*coro); assert(ch && !ch.done()); - the_coro->awaited_from = detail::post_coroutine(- exec, std::move(h), the_coro->result_).handle;- the_coro->reset_error();+ coro->awaited_from = detail::post_coroutine(+ exec, std::move(h), coro->result_).handle;+ coro->reset_error(); ch.resume(); }; }@@ -1111,16 +1111,16 @@ std::false_type /* error is noexcept */, std::true_type /* result is void */) {- return [the_coro = coro_,+ return [coro = coro_, h = std::forward<WaitHandler>(handler), exec = std::move(exec)]() mutable {- if (!the_coro)+ if (!coro) return asio::post(exec, asio::append(std::move(h), detail::coro_error<error_type>::invalid())); - auto ch = detail::coroutine_handle<promise_type>::from_promise(*the_coro);+ auto ch = detail::coroutine_handle<promise_type>::from_promise(*coro); if (!ch) return asio::post(exec, asio::append(std::move(h),@@ -1131,9 +1131,9 @@ detail::coro_error<error_type>::done())); else {- the_coro->awaited_from = detail::post_coroutine(- exec, std::move(h), the_coro->error_).handle;- the_coro->reset_error();+ coro->awaited_from = detail::post_coroutine(+ exec, std::move(h), coro->error_).handle;+ coro->reset_error(); ch.resume(); } };@@ -1144,17 +1144,17 @@ std::false_type /* error is noexcept */, std::false_type /* result is void */) {- return [the_coro = coro_,+ return [coro = coro_, h = std::forward<WaitHandler>(handler), exec = std::move(exec)]() mutable {- if (!the_coro)+ if (!coro) return asio::post(exec, asio::append(std::move(h), detail::coro_error<error_type>::invalid(), result_type{})); auto ch =- detail::coroutine_handle<promise_type>::from_promise(*the_coro);+ detail::coroutine_handle<promise_type>::from_promise(*coro); if (!ch) return asio::post(exec, asio::append(std::move(h),@@ -1165,9 +1165,9 @@ detail::coro_error<error_type>::done(), result_type{})); else {- the_coro->awaited_from = detail::post_coroutine(- exec, std::move(h), the_coro->error_, the_coro->result_).handle;- the_coro->reset_error();+ coro->awaited_from = detail::post_coroutine(+ exec, std::move(h), coro->error_, coro->result_).handle;+ coro->reset_error(); ch.resume(); } };@@ -1203,9 +1203,9 @@ [h = handle(exec, std::forward<WaitHandler>(handler), std::integral_constant<bool, is_noexcept>{}, std::is_void<result_type>{}),- in = std::forward<Input>(input), the_coro = coro_]() mutable+ in = std::forward<Input>(input), coro = coro_]() mutable {- the_coro->input_ = std::move(in);+ coro->input_ = std::move(in); std::move(h)(); }); }
link/modules/asio-standalone/asio/include/asio/experimental/impl/parallel_group.hpp view
@@ -2,7 +2,7 @@ // experimental/impl/parallel_group.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -78,18 +78,18 @@ bool has_value_; }; -// Proxy completion handler for the group of parallel operations. Unpacks and+// Proxy completion handler for the group of parallel operatations. Unpacks and // concatenates the individual operations' results, and invokes the user's // completion handler. template <typename Handler, typename... Ops> struct parallel_group_completion_handler {- typedef decay_t<- prefer_result_t<- associated_executor_t<Handler>,+ typedef typename decay<+ typename prefer_result<+ typename associated_executor<Handler>::type, execution::outstanding_work_t::tracked_t- >- > executor_type;+ >::type+ >::type executor_type; parallel_group_completion_handler(Handler&& h) : handler_(std::move(h)),@@ -136,7 +136,7 @@ std::tuple< parallel_group_op_result< typename parallel_op_signature_as_tuple<- completion_signature_of_t<Ops>+ typename completion_signature_of<Ops>::type >::type >... > args_{};@@ -189,7 +189,7 @@ typedef asio::cancellation_slot cancellation_slot_type; parallel_group_op_handler(- std::shared_ptr<parallel_group_state<Condition, Handler, Ops...>> state)+ std::shared_ptr<parallel_group_state<Condition, Handler, Ops...> > state) : state_(std::move(state)) { }@@ -230,7 +230,7 @@ asio::dispatch(std::move(state_->handler_)); } - std::shared_ptr<parallel_group_state<Condition, Handler, Ops...>> state_;+ std::shared_ptr<parallel_group_state<Condition, Handler, Ops...> > state_; }; // Handler for an individual operation within the parallel group that has an@@ -245,7 +245,7 @@ typedef Executor executor_type; parallel_group_op_handler_with_executor(- std::shared_ptr<parallel_group_state<Condition, Handler, Ops...>> state,+ std::shared_ptr<parallel_group_state<Condition, Handler, Ops...> > state, executor_type ex) : parallel_group_op_handler<I, Condition, Handler, Ops...>(std::move(state)) {@@ -269,7 +269,7 @@ { cancel_proxy( std::shared_ptr<parallel_group_state<- Condition, Handler, Ops...>> state,+ Condition, Handler, Ops...> > state, executor_type ex) : state_(std::move(state)), executor_(std::move(ex))@@ -286,7 +286,7 @@ } } - std::weak_ptr<parallel_group_state<Condition, Handler, Ops...>> state_;+ std::weak_ptr<parallel_group_state<Condition, Handler, Ops...> > state_; asio::cancellation_signal signal_; executor_type executor_; };@@ -301,9 +301,9 @@ template <typename Condition, typename Handler, typename... Ops> static void launch(Op& op, const std::shared_ptr<parallel_group_state<- Condition, Handler, Ops...>>& state)+ Condition, Handler, Ops...> >& state) {- typedef associated_executor_t<Op> ex_type;+ typedef typename associated_executor<Op>::type ex_type; ex_type ex = asio::get_associated_executor(op); std::move(op)( parallel_group_op_handler_with_executor<ex_type, I,@@ -314,18 +314,18 @@ // Specialised launcher for operations that specify no executor. template <std::size_t I, typename Op> struct parallel_group_op_launcher<I, Op,- enable_if_t<+ typename enable_if< is_same< typename associated_executor< Op>::asio_associated_executor_is_unspecialised, void >::value- >>+ >::type> { template <typename Condition, typename Handler, typename... Ops> static void launch(Op& op, const std::shared_ptr<parallel_group_state<- Condition, Handler, Ops...>>& state)+ Condition, Handler, Ops...> >& state) { std::move(op)( parallel_group_op_handler<I, Condition, Handler, Ops...>(state));@@ -336,7 +336,7 @@ struct parallel_group_cancellation_handler { parallel_group_cancellation_handler(- std::shared_ptr<parallel_group_state<Condition, Handler, Ops...>> state)+ std::shared_ptr<parallel_group_state<Condition, Handler, Ops...> > state) : state_(std::move(state)) { }@@ -353,7 +353,7 @@ state->cancellation_signals_[i].emit(cancel_type); } - std::weak_ptr<parallel_group_state<Condition, Handler, Ops...>> state_;+ std::weak_ptr<parallel_group_state<Condition, Handler, Ops...> > state_; }; template <typename Condition, typename Handler,@@ -363,7 +363,7 @@ { // Get the user's completion handler's cancellation slot, so that we can allow // cancellation of the entire group.- associated_cancellation_slot_t<Handler> slot+ typename associated_cancellation_slot<Handler>::type slot = asio::get_associated_cancellation_slot(handler); // Create the shared state for the operation.@@ -390,24 +390,24 @@ if (slot.is_connected()) slot.template emplace< parallel_group_cancellation_handler<- Condition, Handler, Ops...>>(state);+ Condition, Handler, Ops...> >(state); } -// Proxy completion handler for the ranged group of parallel operations.+// Proxy completion handler for the ranged group of parallel operatations. // Unpacks and recombines the individual operations' results, and invokes the // user's completion handler. template <typename Handler, typename Op, typename Allocator> struct ranged_parallel_group_completion_handler {- typedef decay_t<- prefer_result_t<- associated_executor_t<Handler>,+ typedef typename decay<+ typename prefer_result<+ typename associated_executor<Handler>::type, execution::outstanding_work_t::tracked_t- >- > executor_type;+ >::type+ >::type executor_type; typedef typename parallel_op_signature_as_tuple<- completion_signature_of_t<Op>+ typename completion_signature_of<Op>::type >::type op_tuple_type; typedef parallel_group_op_result<op_tuple_type> op_result_type;@@ -445,7 +445,7 @@ { typedef typename parallel_op_signature_as_tuple< typename ranged_parallel_group_signature<- completion_signature_of_t<Op>,+ typename completion_signature_of<Op>::type, Allocator >::raw_type >::type vectors_type;@@ -473,8 +473,7 @@ (void)pushback_fold; } - std::move(handler_)(std::move(completion_order_),- std::move(std::get<I>(vectors))...);+ std::move(handler_)(completion_order_, std::move(std::get<I>(vectors))...); } Handler handler_;@@ -544,7 +543,7 @@ ranged_parallel_group_op_handler( std::shared_ptr<ranged_parallel_group_state<- Condition, Handler, Op, Allocator>> state,+ Condition, Handler, Op, Allocator> > state, std::size_t idx) : state_(std::move(state)), idx_(idx)@@ -588,7 +587,7 @@ } std::shared_ptr<ranged_parallel_group_state<- Condition, Handler, Op, Allocator>> state_;+ Condition, Handler, Op, Allocator> > state_; std::size_t idx_; }; @@ -606,7 +605,7 @@ ranged_parallel_group_op_handler_with_executor( std::shared_ptr<ranged_parallel_group_state<- Condition, Handler, Op, Allocator>> state,+ Condition, Handler, Op, Allocator> > state, executor_type ex, std::size_t idx) : ranged_parallel_group_op_handler<Condition, Handler, Op, Allocator>( std::move(state), idx)@@ -631,7 +630,7 @@ { cancel_proxy( std::shared_ptr<ranged_parallel_group_state<- Condition, Handler, Op, Allocator>> state,+ Condition, Handler, Op, Allocator> > state, executor_type ex) : state_(std::move(state)), executor_(std::move(ex))@@ -649,7 +648,7 @@ } std::weak_ptr<ranged_parallel_group_state<- Condition, Handler, Op, Allocator>> state_;+ Condition, Handler, Op, Allocator> > state_; asio::cancellation_signal signal_; executor_type executor_; };@@ -662,7 +661,7 @@ { ranged_parallel_group_cancellation_handler( std::shared_ptr<ranged_parallel_group_state<- Condition, Handler, Op, Allocator>> state)+ Condition, Handler, Op, Allocator> > state) : state_(std::move(state)) { }@@ -680,7 +679,7 @@ } std::weak_ptr<ranged_parallel_group_state<- Condition, Handler, Op, Allocator>> state_;+ Condition, Handler, Op, Allocator> > state_; }; template <typename Condition, typename Handler,@@ -690,11 +689,12 @@ { // Get the user's completion handler's cancellation slot, so that we can allow // cancellation of the entire group.- associated_cancellation_slot_t<Handler> slot- = asio::get_associated_cancellation_slot(handler);+ typename associated_cancellation_slot<Handler>::type slot+ = asio::get_associated_cancellation_slot(handler); // The type of the asynchronous operation.- typedef decay_t<decltype(*declval<typename Range::iterator>())> op_type;+ typedef typename std::decay<decltype(+ *std::declval<typename Range::iterator>())>::type op_type; // Create the shared state for the operation. typedef ranged_parallel_group_state<Condition,@@ -706,10 +706,9 @@ std::move(handler), range.size(), allocator); std::size_t idx = 0;- std::size_t range_size = range.size(); for (auto&& op : std::forward<Range>(range)) {- typedef associated_executor_t<op_type> ex_type;+ typedef typename associated_executor<op_type>::type ex_type; ex_type ex = asio::get_associated_executor(op); std::move(op)( ranged_parallel_group_op_handler_with_executor<@@ -719,7 +718,7 @@ // Check if any of the operations has already requested cancellation, and if // so, emit a signal for each operation in the group.- if ((state->cancellations_requested_ -= range_size) > 0)+ if ((state->cancellations_requested_ -= range.size()) > 0) for (auto& signal : state->cancellation_signals_) signal.emit(state->cancel_type_); @@ -727,7 +726,7 @@ if (slot.is_connected()) slot.template emplace< ranged_parallel_group_cancellation_handler<- Condition, Handler, op_type, Allocator>>(state);+ Condition, Handler, op_type, Allocator> >(state); } } // namespace detail@@ -740,18 +739,20 @@ DefaultCandidate> : Associator<Handler, DefaultCandidate> {- static typename Associator<Handler, DefaultCandidate>::type get(- const experimental::detail::parallel_group_completion_handler<- Handler, Ops...>& h) noexcept+ static typename Associator<Handler, DefaultCandidate>::type+ get(const experimental::detail::parallel_group_completion_handler<+ Handler, Ops...>& h) ASIO_NOEXCEPT { return Associator<Handler, DefaultCandidate>::get(h.handler_); } - static auto get(- const experimental::detail::parallel_group_completion_handler<+ static ASIO_AUTO_RETURN_TYPE_PREFIX2(+ typename Associator<Handler, DefaultCandidate>::type)+ get(const experimental::detail::parallel_group_completion_handler< Handler, Ops...>& h,- const DefaultCandidate& c) noexcept- -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))+ const DefaultCandidate& c) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ Associator<Handler, DefaultCandidate>::get(h.handler_, c))) { return Associator<Handler, DefaultCandidate>::get(h.handler_, c); }@@ -765,18 +766,20 @@ DefaultCandidate> : Associator<Handler, DefaultCandidate> {- static typename Associator<Handler, DefaultCandidate>::type get(- const experimental::detail::ranged_parallel_group_completion_handler<- Handler, Op, Allocator>& h) noexcept+ static typename Associator<Handler, DefaultCandidate>::type+ get(const experimental::detail::ranged_parallel_group_completion_handler<+ Handler, Op, Allocator>& h) ASIO_NOEXCEPT { return Associator<Handler, DefaultCandidate>::get(h.handler_); } - static auto get(- const experimental::detail::ranged_parallel_group_completion_handler<+ static ASIO_AUTO_RETURN_TYPE_PREFIX2(+ typename Associator<Handler, DefaultCandidate>::type)+ get(const experimental::detail::ranged_parallel_group_completion_handler< Handler, Op, Allocator>& h,- const DefaultCandidate& c) noexcept- -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))+ const DefaultCandidate& c) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ Associator<Handler, DefaultCandidate>::get(h.handler_, c))) { return Associator<Handler, DefaultCandidate>::get(h.handler_, c); }
link/modules/asio-standalone/asio/include/asio/experimental/impl/promise.hpp view
@@ -18,8 +18,6 @@ #include "asio/detail/config.hpp" #include "asio/cancellation_signal.hpp" #include "asio/detail/utility.hpp"-#include "asio/error.hpp"-#include "asio/system_error.hpp" #include <tuple> #include "asio/detail/push_options.hpp"@@ -58,7 +56,8 @@ reinterpret_cast<result_type*>(&result)->~result_type(); } - aligned_storage_t<sizeof(result_type), alignof(result_type)> result;+ typename aligned_storage<sizeof(result_type),+ alignof(result_type)>::type result; std::atomic<bool> done{false}; cancellation_signal cancel; Allocator allocator;@@ -187,7 +186,7 @@ template<typename Signature = void(), typename Executor = asio::any_io_executor,- typename Allocator = std::allocator<void>>+ typename Allocator = any_io_executor> struct promise_handler; template<typename... Ts, typename Executor, typename Allocator>
link/modules/asio-standalone/asio/include/asio/experimental/impl/use_promise.hpp view
@@ -44,11 +44,11 @@ template <typename Initiation, typename... InitArgs> static auto initiate(Initiation initiation, experimental::use_promise_t<Allocator> up, InitArgs... args)- -> experimental::promise<void(decay_t<Args>...),+ -> experimental::promise<void(typename decay<Args>::type...), asio::associated_executor_t<Initiation>, Allocator> { using handler_type = experimental::detail::promise_handler<- void(decay_t<Args>...),+ void(typename decay<Args>::type...), asio::associated_executor_t<Initiation>, Allocator>; handler_type ht{up.get_allocator(), get_associated_executor(initiation)};
link/modules/asio-standalone/asio/include/asio/experimental/parallel_group.hpp view
@@ -2,7 +2,7 @@ // experimental/parallel_group.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -17,10 +17,8 @@ #include "asio/detail/config.hpp" #include <vector>-#include "asio/async_result.hpp" #include "asio/detail/array.hpp" #include "asio/detail/memory.hpp"-#include "asio/detail/type_traits.hpp" #include "asio/detail/utility.hpp" #include "asio/experimental/cancellation_condition.hpp" @@ -38,7 +36,7 @@ template <typename R, typename... Args> struct parallel_op_signature_as_tuple<R(Args...)> {- typedef std::tuple<decay_t<Args>...> type;+ typedef std::tuple<typename decay<Args>::type...> type; }; // Helper trait for concatenating completion signatures.@@ -164,7 +162,7 @@ /// The completion signature for the group of operations. typedef typename detail::parallel_group_signature<sizeof...(Ops),- completion_signature_of_t<Ops>...>::type signature;+ typename completion_signature_of<Ops>::type...>::type signature; /// Initiate an asynchronous wait for the group of operations. /**@@ -190,12 +188,13 @@ */ template <typename CancellationCondition, ASIO_COMPLETION_TOKEN_FOR(signature) CompletionToken>- auto async_wait(CancellationCondition cancellation_condition,+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(CompletionToken, signature)+ async_wait(CancellationCondition cancellation_condition, CompletionToken&& token)- -> decltype(+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( asio::async_initiate<CompletionToken, signature>(- declval<initiate_async_wait>(), token,- std::move(cancellation_condition), std::move(ops_)))+ declval<initiate_async_wait>(), token,+ std::move(cancellation_condition), std::move(ops_)))) { return asio::async_initiate<CompletionToken, signature>( initiate_async_wait(), token,@@ -207,36 +206,6 @@ /** * For example: * @code asio::experimental::make_parallel_group(- * in.async_read_some(asio::buffer(data)),- * timer.async_wait()- * ).async_wait(- * asio::experimental::wait_for_all(),- * [](- * std::array<std::size_t, 2> completion_order,- * std::error_code ec1, std::size_t n1,- * std::error_code ec2- * )- * {- * switch (completion_order[0])- * {- * case 0:- * {- * std::cout << "descriptor finished: " << ec1 << ", " << n1 << "\n";- * }- * break;- * case 1:- * {- * std::cout << "timer finished: " << ec2 << "\n";- * }- * break;- * }- * }- * );- * @endcode- *- * If preferred, the asynchronous operations may be explicitly packaged as- * function objects:- * @code asio::experimental::make_parallel_group( * [&](auto token) * { * return in.async_read_some(asio::buffer(data), token);@@ -283,7 +252,7 @@ * See the documentation for asio::experimental::make_parallel_group for * a usage example. */-template <typename Range, typename Allocator = std::allocator<void>>+template <typename Range, typename Allocator = std::allocator<void> > class ranged_parallel_group { private:@@ -312,8 +281,9 @@ /// The completion signature for the group of operations. typedef typename detail::ranged_parallel_group_signature<- completion_signature_of_t<- decay_t<decltype(*std::declval<typename Range::iterator>())>>,+ typename completion_signature_of<+ typename std::decay<+ decltype(*std::declval<typename Range::iterator>())>::type>::type, Allocator>::type signature; /// Initiate an asynchronous wait for the group of operations.@@ -341,13 +311,14 @@ */ template <typename CancellationCondition, ASIO_COMPLETION_TOKEN_FOR(signature) CompletionToken>- auto async_wait(CancellationCondition cancellation_condition,+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(CompletionToken, signature)+ async_wait(CancellationCondition cancellation_condition, CompletionToken&& token)- -> decltype(+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( asio::async_initiate<CompletionToken, signature>(- declval<initiate_async_wait>(), token,- std::move(cancellation_condition),- std::move(range_), allocator_))+ declval<initiate_async_wait>(), token,+ std::move(cancellation_condition),+ std::move(range_), allocator_))) { return asio::async_initiate<CompletionToken, signature>( initiate_async_wait(), token,@@ -362,13 +333,29 @@ * * For example: * @code- * using op_type =- * decltype(socket1.async_read_some(asio::buffer(data1)));+ * using op_type = decltype(+ * socket1.async_read_some(+ * asio::buffer(data1),+ * asio::deferred+ * )+ * ); * * std::vector<op_type> ops;- * ops.push_back(socket1.async_read_some(asio::buffer(data1)));- * ops.push_back(socket2.async_read_some(asio::buffer(data2))); *+ * ops.push_back(+ * socket1.async_read_some(+ * asio::buffer(data1),+ * asio::deferred+ * )+ * );+ *+ * ops.push_back(+ * socket2.async_read_some(+ * asio::buffer(data2),+ * asio::deferred+ * )+ * );+ * * asio::experimental::make_parallel_group(ops).async_wait( * asio::experimental::wait_for_all(), * [](@@ -388,13 +375,15 @@ * @endcode */ template <typename Range>-ASIO_NODISCARD inline ranged_parallel_group<decay_t<Range>>+ASIO_NODISCARD inline+ranged_parallel_group<typename std::decay<Range>::type> make_parallel_group(Range&& range,- constraint_t<- is_async_operation_range<decay_t<Range>>::value- > = 0)+ typename constraint<+ is_async_operation_range<typename std::decay<Range>::type>::value+ >::type = 0) {- return ranged_parallel_group<decay_t<Range>>(std::forward<Range>(range));+ return ranged_parallel_group<typename std::decay<Range>::type>(+ std::forward<Range>(range)); } /// Create a group of operations that may be launched in parallel.@@ -405,13 +394,29 @@ * * For example: * @code- * using op_type =- * decltype(socket1.async_read_some(asio::buffer(data1)));+ * using op_type = decltype(+ * socket1.async_read_some(+ * asio::buffer(data1),+ * asio::deferred+ * )+ * ); * * std::vector<op_type> ops;- * ops.push_back(socket1.async_read_some(asio::buffer(data1)));- * ops.push_back(socket2.async_read_some(asio::buffer(data2))); *+ * ops.push_back(+ * socket1.async_read_some(+ * asio::buffer(data1),+ * asio::deferred+ * )+ * );+ *+ * ops.push_back(+ * socket2.async_read_some(+ * asio::buffer(data2),+ * asio::deferred+ * )+ * );+ * * asio::experimental::make_parallel_group( * std::allocator_arg_t, * my_allocator,@@ -435,13 +440,14 @@ * @endcode */ template <typename Allocator, typename Range>-ASIO_NODISCARD inline ranged_parallel_group<decay_t<Range>, Allocator>+ASIO_NODISCARD inline+ranged_parallel_group<typename std::decay<Range>::type, Allocator> make_parallel_group(allocator_arg_t, const Allocator& allocator, Range&& range,- constraint_t<- is_async_operation_range<decay_t<Range>>::value- > = 0)+ typename constraint<+ is_async_operation_range<typename std::decay<Range>::type>::value+ >::type = 0) {- return ranged_parallel_group<decay_t<Range>, Allocator>(+ return ranged_parallel_group<typename std::decay<Range>::type, Allocator>( std::forward<Range>(range), allocator); }
+ link/modules/asio-standalone/asio/include/asio/experimental/prepend.hpp view
@@ -0,0 +1,36 @@+//+// experimental/prepend.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_EXPERIMENTAL_PREPEND_HPP+#define ASIO_EXPERIMENTAL_PREPEND_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/prepend.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {+namespace experimental {++#if !defined(ASIO_NO_DEPRECATED)+using asio::prepend_t;+using asio::prepend;+#endif // !defined(ASIO_NO_DEPRECATED)++} // namespace experimental+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_EXPERIMENTAL_PREPEND_HPP
link/modules/asio-standalone/asio/include/asio/experimental/promise.hpp view
@@ -84,9 +84,8 @@ * awaitable<void> read_write_some(asio::ip::tcp::socket & sock, * asio::mutable_buffer read_buf, asio::const_buffer to_write) * {- * auto p = asio::async_read(read_buf,- * asio::experimental::use_promise);- * co_await asio::async_write_some(to_write);+ * auto p = asio::async_read(read_buf, asio::use_awaitable);+ * co_await asio::async_write_some(to_write, asio::deferred); * co_await p; * } * @endcode@@ -139,6 +138,7 @@ * It is safe to destruct a promise of a promise that didn't complete. */ ~promise() { cancel(); }+ private: #if !defined(GENERATING_DOCUMENTATION)
link/modules/asio-standalone/asio/include/asio/experimental/use_coro.hpp view
@@ -47,9 +47,8 @@ * the asynchronous operation completes, and the result of the operation is * returned. *- * Note that this token is not the most efficient (use the default completion- * token @c asio::deferred for that) but does provide type erasure, as it- * will always return a @c coro.+ * Note that this token is not the most efficient (use @c asio::deferred+ * for that) but does provide type erasure, as it will always return a @c coro. */ template <typename Allocator = std::allocator<void>> struct use_coro_t@@ -60,7 +59,7 @@ typedef Allocator allocator_type; /// Default constructor.- constexpr use_coro_t(+ ASIO_CONSTEXPR use_coro_t( allocator_type allocator = allocator_type{} #if defined(ASIO_ENABLE_HANDLER_TRACKING) # if defined(ASIO_HAS_SOURCE_LOCATION)@@ -84,6 +83,7 @@ { } + /// Specify an alternate allocator. template <typename OtherAllocator> use_coro_t<OtherAllocator> rebind(const OtherAllocator& allocator) const@@ -98,7 +98,7 @@ } /// Constructor used to specify file name, line, and function name.- constexpr use_coro_t(const char* file_name,+ ASIO_CONSTEXPR use_coro_t(const char* file_name, int line, const char* function_name, allocator_type allocator = allocator_type{}) : #if defined(ASIO_ENABLE_HANDLER_TRACKING)@@ -126,13 +126,13 @@ /// Construct the adapted executor from the inner executor type. template <typename InnerExecutor1> executor_with_default(const InnerExecutor1& ex,- constraint_t<- conditional_t<+ typename constraint<+ conditional< !is_same<InnerExecutor1, executor_with_default>::value, is_convertible<InnerExecutor1, InnerExecutor>, false_type- >::value- > = 0) noexcept+ >::type::value+ >::type = 0) ASIO_NOEXCEPT : InnerExecutor(ex) { }@@ -140,21 +140,25 @@ /// Type alias to adapt an I/O object to use @c use_coro_t as its /// default completion token type.+#if defined(ASIO_HAS_ALIAS_TEMPLATES) \+ || defined(GENERATING_DOCUMENTATION) template <typename T> using as_default_on_t = typename T::template rebind_executor<- executor_with_default<typename T::executor_type>>::other;+ executor_with_default<typename T::executor_type> >::other;+#endif // defined(ASIO_HAS_ALIAS_TEMPLATES)+ // || defined(GENERATING_DOCUMENTATION) /// Function helper to adapt an I/O object to use @c use_coro_t as its /// default completion token type. template <typename T>- static typename decay_t<T>::template rebind_executor<- executor_with_default<typename decay_t<T>::executor_type>+ static typename decay<T>::type::template rebind_executor<+ executor_with_default<typename decay<T>::type::executor_type> >::other- as_default_on(T&& object)+ as_default_on(ASIO_MOVE_ARG(T) object) {- return typename decay_t<T>::template rebind_executor<- executor_with_default<typename decay_t<T>::executor_type>- >::other(static_cast<T&&>(object));+ return typename decay<T>::type::template rebind_executor<+ executor_with_default<typename decay<T>::type::executor_type>+ >::other(ASIO_MOVE_CAST(T)(object)); } #if defined(ASIO_ENABLE_HANDLER_TRACKING)@@ -173,9 +177,11 @@ * See the documentation for asio::use_coro_t for a usage example. */ #if defined(GENERATING_DOCUMENTATION)-ASIO_INLINE_VARIABLE constexpr use_coro_t<> use_coro;-#else-ASIO_INLINE_VARIABLE constexpr use_coro_t<> use_coro(0, 0, 0);+constexpr use_coro_t<> use_coro;+#elif defined(ASIO_HAS_CONSTEXPR)+constexpr use_coro_t<> use_coro(0, 0, 0);+#elif defined(ASIO_MSVC)+__declspec(selectany) use_coro_t<> use_coro(0, 0, 0); #endif } // namespace experimental
link/modules/asio-standalone/asio/include/asio/experimental/use_promise.hpp view
@@ -33,7 +33,7 @@ typedef Allocator allocator_type; /// Construct using default-constructed allocator.- constexpr use_promise_t()+ ASIO_CONSTEXPR use_promise_t() { } @@ -44,7 +44,7 @@ } /// Obtain allocator.- allocator_type get_allocator() const noexcept+ allocator_type get_allocator() const ASIO_NOEXCEPT { return allocator_; }@@ -58,7 +58,7 @@ typedef use_promise_t<Allocator> default_completion_token_type; /// Construct the adapted executor from the inner executor type.- executor_with_default(const InnerExecutor& ex) noexcept+ executor_with_default(const InnerExecutor& ex) ASIO_NOEXCEPT : InnerExecutor(ex) { }@@ -67,9 +67,9 @@ /// that to construct the adapted executor. template <typename OtherExecutor> executor_with_default(const OtherExecutor& ex,- constraint_t<+ typename constraint< is_convertible<OtherExecutor, InnerExecutor>::value- > = 0) noexcept+ >::type = 0) ASIO_NOEXCEPT : InnerExecutor(ex) { }@@ -78,14 +78,14 @@ /// Function helper to adapt an I/O object to use @c use_promise_t as its /// default completion token type. template <typename T>- static typename decay_t<T>::template rebind_executor<- executor_with_default<typename decay_t<T>::executor_type>+ static typename decay<T>::type::template rebind_executor<+ executor_with_default<typename decay<T>::type::executor_type> >::other- as_default_on(T&& object)+ as_default_on(ASIO_MOVE_ARG(T) object) {- return typename decay_t<T>::template rebind_executor<- executor_with_default<typename decay_t<T>::executor_type>- >::other(static_cast<T&&>(object));+ return typename decay<T>::type::template rebind_executor<+ executor_with_default<typename decay<T>::type::executor_type>+ >::other(ASIO_MOVE_CAST(T)(object)); } /// Specify an alternate allocator.@@ -99,7 +99,7 @@ Allocator allocator_; }; -ASIO_INLINE_VARIABLE constexpr use_promise_t<> use_promise;+constexpr use_promise_t<> use_promise; } // namespace experimental } // namespace asio
link/modules/asio-standalone/asio/include/asio/file_base.hpp view
@@ -2,7 +2,7 @@ // file_base.hpp // ~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/generic/basic_endpoint.hpp view
@@ -2,7 +2,7 @@ // generic/basic_endpoint.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -54,7 +54,7 @@ #endif /// Default constructor.- basic_endpoint() noexcept+ basic_endpoint() ASIO_NOEXCEPT { } @@ -78,11 +78,13 @@ { } +#if defined(ASIO_HAS_MOVE) /// Move constructor. basic_endpoint(basic_endpoint&& other) : impl_(other.impl_) { }+#endif // defined(ASIO_HAS_MOVE) /// Assign from another endpoint. basic_endpoint& operator=(const basic_endpoint& other)@@ -91,12 +93,14 @@ return *this; } +#if defined(ASIO_HAS_MOVE) /// Move-assign from another endpoint. basic_endpoint& operator=(basic_endpoint&& other) { impl_ = other.impl_; return *this; }+#endif // defined(ASIO_HAS_MOVE) /// The protocol associated with the endpoint. protocol_type protocol() const
link/modules/asio-standalone/asio/include/asio/generic/datagram_protocol.hpp view
@@ -2,7 +2,7 @@ // generic/datagram_protocol.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -73,19 +73,19 @@ } /// Obtain an identifier for the type of the protocol.- int type() const noexcept+ int type() const ASIO_NOEXCEPT { return ASIO_OS_DEF(SOCK_DGRAM); } /// Obtain an identifier for the protocol.- int protocol() const noexcept+ int protocol() const ASIO_NOEXCEPT { return protocol_; } /// Obtain an identifier for the protocol family.- int family() const noexcept+ int family() const ASIO_NOEXCEPT { return family_; }
link/modules/asio-standalone/asio/include/asio/generic/detail/endpoint.hpp view
@@ -2,7 +2,7 @@ // generic/detail/endpoint.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/generic/detail/impl/endpoint.ipp view
@@ -2,7 +2,7 @@ // generic/detail/impl/endpoint.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/generic/raw_protocol.hpp view
@@ -2,7 +2,7 @@ // generic/raw_protocol.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -73,19 +73,19 @@ } /// Obtain an identifier for the type of the protocol.- int type() const noexcept+ int type() const ASIO_NOEXCEPT { return ASIO_OS_DEF(SOCK_RAW); } /// Obtain an identifier for the protocol.- int protocol() const noexcept+ int protocol() const ASIO_NOEXCEPT { return protocol_; } /// Obtain an identifier for the protocol family.- int family() const noexcept+ int family() const ASIO_NOEXCEPT { return family_; }
link/modules/asio-standalone/asio/include/asio/generic/seq_packet_protocol.hpp view
@@ -2,7 +2,7 @@ // generic/seq_packet_protocol.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -72,19 +72,19 @@ } /// Obtain an identifier for the type of the protocol.- int type() const noexcept+ int type() const ASIO_NOEXCEPT { return ASIO_OS_DEF(SOCK_SEQPACKET); } /// Obtain an identifier for the protocol.- int protocol() const noexcept+ int protocol() const ASIO_NOEXCEPT { return protocol_; } /// Obtain an identifier for the protocol family.- int family() const noexcept+ int family() const ASIO_NOEXCEPT { return family_; }
link/modules/asio-standalone/asio/include/asio/generic/stream_protocol.hpp view
@@ -2,7 +2,7 @@ // generic/stream_protocol.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -74,19 +74,19 @@ } /// Obtain an identifier for the type of the protocol.- int type() const noexcept+ int type() const ASIO_NOEXCEPT { return ASIO_OS_DEF(SOCK_STREAM); } /// Obtain an identifier for the protocol.- int protocol() const noexcept+ int protocol() const ASIO_NOEXCEPT { return protocol_; } /// Obtain an identifier for the protocol family.- int family() const noexcept+ int family() const ASIO_NOEXCEPT { return family_; }
+ link/modules/asio-standalone/asio/include/asio/handler_alloc_hook.hpp view
@@ -0,0 +1,104 @@+//+// handler_alloc_hook.hpp+// ~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_HANDLER_ALLOC_HOOK_HPP+#define ASIO_HANDLER_ALLOC_HOOK_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include <cstddef>++#include "asio/detail/push_options.hpp"++namespace asio {++#if defined(ASIO_NO_DEPRECATED)++// Places in asio that would have previously called the allocate or deallocate+// hooks to manage memory, now call them only to check whether the result types+// are these types. If the result is not the correct type, it indicates that+// the user code still has the old hooks in place, and if so we want to trigger+// a compile error.+enum asio_handler_allocate_is_no_longer_used {};+enum asio_handler_deallocate_is_no_longer_used {};++typedef asio_handler_allocate_is_no_longer_used+ asio_handler_allocate_is_deprecated;+typedef asio_handler_deallocate_is_no_longer_used+ asio_handler_deallocate_is_deprecated;++#else // defined(ASIO_NO_DEPRECATED)++typedef void* asio_handler_allocate_is_deprecated;+typedef void asio_handler_deallocate_is_deprecated;++#endif // defined(ASIO_NO_DEPRECATED)++/// (Deprecated: Use the associated_allocator trait.) Default allocation+/// function for handlers.+/**+ * Asynchronous operations may need to allocate temporary objects. Since+ * asynchronous operations have a handler function object, these temporary+ * objects can be said to be associated with the handler.+ *+ * Implement asio_handler_allocate and asio_handler_deallocate for your own+ * handlers to provide custom allocation for these temporary objects.+ *+ * The default implementation of these allocation hooks uses <tt>::operator+ * new</tt> and <tt>::operator delete</tt>.+ *+ * @note All temporary objects associated with a handler will be deallocated+ * before the upcall to the handler is performed. This allows the same memory to+ * be reused for a subsequent asynchronous operation initiated by the handler.+ *+ * @par Example+ * @code+ * class my_handler;+ *+ * void* asio_handler_allocate(std::size_t size, my_handler* context)+ * {+ * return ::operator new(size);+ * }+ *+ * void asio_handler_deallocate(void* pointer, std::size_t size,+ * my_handler* context)+ * {+ * ::operator delete(pointer);+ * }+ * @endcode+ */+ASIO_DECL asio_handler_allocate_is_deprecated+asio_handler_allocate(std::size_t size, ...);++/// Default deallocation function for handlers.+/**+ * Implement asio_handler_allocate and asio_handler_deallocate for your own+ * handlers to provide custom allocation for the associated temporary objects.+ *+ * The default implementation of these allocation hooks uses <tt>::operator+ * new</tt> and <tt>::operator delete</tt>.+ *+ * @sa asio_handler_allocate.+ */+ASIO_DECL asio_handler_deallocate_is_deprecated+asio_handler_deallocate(void* pointer, std::size_t size, ...);++} // namespace asio++#include "asio/detail/pop_options.hpp"++#if defined(ASIO_HEADER_ONLY)+# include "asio/impl/handler_alloc_hook.ipp"+#endif // defined(ASIO_HEADER_ONLY)++#endif // ASIO_HANDLER_ALLOC_HOOK_HPP
link/modules/asio-standalone/asio/include/asio/handler_continuation_hook.hpp view
@@ -2,7 +2,7 @@ // handler_continuation_hook.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ link/modules/asio-standalone/asio/include/asio/handler_invoke_hook.hpp view
@@ -0,0 +1,111 @@+//+// handler_invoke_hook.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_HANDLER_INVOKE_HOOK_HPP+#define ASIO_HANDLER_INVOKE_HOOK_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {++/** @defgroup asio_handler_invoke asio::asio_handler_invoke+ *+ * @brief (Deprecated: Use the associated_executor trait.) Default invoke+ * function for handlers.+ *+ * Completion handlers for asynchronous operations are invoked by the+ * io_context associated with the corresponding object (e.g. a socket or+ * deadline_timer). Certain guarantees are made on when the handler may be+ * invoked, in particular that a handler can only be invoked from a thread that+ * is currently calling @c run() on the corresponding io_context object.+ * Handlers may subsequently be invoked through other objects (such as+ * io_context::strand objects) that provide additional guarantees.+ *+ * When asynchronous operations are composed from other asynchronous+ * operations, all intermediate handlers should be invoked using the same+ * method as the final handler. This is required to ensure that user-defined+ * objects are not accessed in a way that may violate the guarantees. This+ * hooking function ensures that the invoked method used for the final handler+ * is accessible at each intermediate step.+ *+ * Implement asio_handler_invoke for your own handlers to specify a custom+ * invocation strategy.+ *+ * This default implementation invokes the function object like so:+ * @code function(); @endcode+ * If necessary, the default implementation makes a copy of the function object+ * so that the non-const operator() can be used.+ *+ * @par Example+ * @code+ * class my_handler;+ *+ * template <typename Function>+ * void asio_handler_invoke(Function function, my_handler* context)+ * {+ * context->strand_.dispatch(function);+ * }+ * @endcode+ */+/*@{*/++#if defined(ASIO_NO_DEPRECATED)++// Places in asio that would have previously called the invocation hook to+// execute a handler, now call it only to check whether the result type is this+// type. If the result is not this type, it indicates that the user code still+// has the old hooks in place, and if so we want to trigger a compile error.+enum asio_handler_invoke_is_no_longer_used {};++typedef asio_handler_invoke_is_no_longer_used+ asio_handler_invoke_is_deprecated;++#else // defined(ASIO_NO_DEPRECATED)++typedef void asio_handler_invoke_is_deprecated;++#endif // defined(ASIO_NO_DEPRECATED)++/// Default handler invocation hook used for non-const function objects.+template <typename Function>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(Function& function, ...)+{+ function();+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++/// Default handler invocation hook used for const function objects.+template <typename Function>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(const Function& function, ...)+{+ Function tmp(function);+ tmp();+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++/*@}*/++} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_HANDLER_INVOKE_HOOK_HPP
link/modules/asio-standalone/asio/include/asio/high_resolution_timer.hpp view
@@ -2,7 +2,7 @@ // high_resolution_timer.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -16,6 +16,9 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"++#if defined(ASIO_HAS_CHRONO) || defined(GENERATING_DOCUMENTATION)+ #include "asio/basic_waitable_timer.hpp" #include "asio/detail/chrono.hpp" @@ -35,5 +38,7 @@ high_resolution_timer; } // namespace asio++#endif // defined(ASIO_HAS_CHRONO) || defined(GENERATING_DOCUMENTATION) #endif // ASIO_HIGH_RESOLUTION_TIMER_HPP
− link/modules/asio-standalone/asio/include/asio/immediate.hpp
@@ -1,142 +0,0 @@-//-// immediate.hpp-// ~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef ASIO_IMMEDIATE_HPP-#define ASIO_IMMEDIATE_HPP--#if defined(_MSC_VER) && (_MSC_VER >= 1200)-# pragma once-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)--#include "asio/detail/config.hpp"-#include "asio/associated_immediate_executor.hpp"-#include "asio/async_result.hpp"-#include "asio/dispatch.hpp"--#include "asio/detail/push_options.hpp"--namespace asio {-namespace detail {--template <typename Executor>-class initiate_immediate-{-public:- typedef Executor executor_type;-- explicit initiate_immediate(const Executor& ex)- : ex_(ex)- {- }-- executor_type get_executor() const noexcept- {- return ex_;- }-- template <typename CompletionHandler>- void operator()(CompletionHandler&& handler) const- {- typename associated_immediate_executor<- CompletionHandler, executor_type>::type ex =- (get_associated_immediate_executor)(handler, ex_);- (dispatch)(ex, static_cast<CompletionHandler&&>(handler));- }--private:- Executor ex_;-};--} // namespace detail--/// Launch a trivial asynchronous operation that completes immediately.-/**- * The async_immediate function is intended for use by composed operations,- * which can delegate to this operation in order to implement the correct- * semantics for immediate completion.- *- * @param ex The asynchronous operation's I/O executor.- *- * @param token The completion token.- *- * The completion handler is immediately submitted for execution by calling- * asio::dispatch() on the handler's associated immediate executor.- *- * If the completion handler does not have a customised associated immediate- * executor, then the handler is submitted as if by calling asio::post()- * on the supplied I/O executor.- *- * @par Completion Signature- * @code void() @endcode- */-template <typename Executor,- ASIO_COMPLETION_TOKEN_FOR(void()) NullaryToken- = default_completion_token_t<Executor>>-inline auto async_immediate(const Executor& ex,- NullaryToken&& token = default_completion_token_t<Executor>(),- constraint_t<- (execution::is_executor<Executor>::value- && can_require<Executor, execution::blocking_t::never_t>::value)- || is_executor<Executor>::value- > = 0)- -> decltype(- async_initiate<NullaryToken, void()>(- declval<detail::initiate_immediate<Executor>>(), token))-{- return async_initiate<NullaryToken, void()>(- detail::initiate_immediate<Executor>(ex), token);-}--/// Launch a trivial asynchronous operation that completes immediately.-/**- * The async_immediate function is intended for use by composed operations,- * which can delegate to this operation in order to implement the correct- * semantics for immediate completion.- *- * @param ex The execution context used to obtain the asynchronous operation's- * I/O executor.- *- * @param token The completion token.- *- * The completion handler is immediately submitted for execution by calling- * asio::dispatch() on the handler's associated immediate executor.- *- * If the completion handler does not have a customised associated immediate- * executor, then the handler is submitted as if by calling asio::post()- * on the I/O executor obtained from the supplied execution context.- *- * @par Completion Signature- * @code void() @endcode- */-template <typename ExecutionContext,- ASIO_COMPLETION_TOKEN_FOR(void()) NullaryToken- = default_completion_token_t<typename ExecutionContext::executor_type>>-inline auto async_immediate(ExecutionContext& ctx,- NullaryToken&& token = default_completion_token_t<- typename ExecutionContext::executor_type>(),- constraint_t<- is_convertible<ExecutionContext&, execution_context&>::value- > = 0)- -> decltype(- async_initiate<NullaryToken, void()>(- declval<detail::initiate_immediate<- typename ExecutionContext::executor_type>>(), token))-{- return async_initiate<NullaryToken, void()>(- detail::initiate_immediate<- typename ExecutionContext::executor_type>(- ctx.get_executor()), token);-}--} // namespace asio--#include "asio/detail/pop_options.hpp"--#endif // ASIO_IMMEDIATE_HPP
link/modules/asio-standalone/asio/include/asio/impl/any_completion_executor.ipp view
@@ -2,7 +2,7 @@ // impl/any_completion_executor.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -25,53 +25,57 @@ namespace asio { -any_completion_executor::any_completion_executor() noexcept+any_completion_executor::any_completion_executor() ASIO_NOEXCEPT : base_type() { } -any_completion_executor::any_completion_executor(nullptr_t) noexcept+any_completion_executor::any_completion_executor(nullptr_t) ASIO_NOEXCEPT : base_type(nullptr_t()) { } any_completion_executor::any_completion_executor(- const any_completion_executor& e) noexcept+ const any_completion_executor& e) ASIO_NOEXCEPT : base_type(static_cast<const base_type&>(e)) { } any_completion_executor::any_completion_executor(std::nothrow_t,- const any_completion_executor& e) noexcept+ const any_completion_executor& e) ASIO_NOEXCEPT : base_type(static_cast<const base_type&>(e)) { } +#if defined(ASIO_HAS_MOVE) any_completion_executor::any_completion_executor(- any_completion_executor&& e) noexcept+ any_completion_executor&& e) ASIO_NOEXCEPT : base_type(static_cast<base_type&&>(e)) { } any_completion_executor::any_completion_executor(std::nothrow_t,- any_completion_executor&& e) noexcept+ any_completion_executor&& e) ASIO_NOEXCEPT : base_type(static_cast<base_type&&>(e)) { }+#endif // defined(ASIO_HAS_MOVE) any_completion_executor& any_completion_executor::operator=(- const any_completion_executor& e) noexcept+ const any_completion_executor& e) ASIO_NOEXCEPT { base_type::operator=(static_cast<const base_type&>(e)); return *this; } +#if defined(ASIO_HAS_MOVE) any_completion_executor& any_completion_executor::operator=(- any_completion_executor&& e) noexcept+ any_completion_executor&& e) ASIO_NOEXCEPT { base_type::operator=(static_cast<base_type&&>(e)); return *this; }+#endif // defined(ASIO_HAS_MOVE) any_completion_executor& any_completion_executor::operator=(nullptr_t) {@@ -84,7 +88,7 @@ } void any_completion_executor::swap(- any_completion_executor& other) noexcept+ any_completion_executor& other) ASIO_NOEXCEPT { static_cast<base_type&>(*this).swap(static_cast<base_type&>(other)); }
link/modules/asio-standalone/asio/include/asio/impl/any_io_executor.ipp view
@@ -2,7 +2,7 @@ // impl/any_io_executor.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -25,48 +25,55 @@ namespace asio { -any_io_executor::any_io_executor() noexcept+any_io_executor::any_io_executor() ASIO_NOEXCEPT : base_type() { } -any_io_executor::any_io_executor(nullptr_t) noexcept+any_io_executor::any_io_executor(nullptr_t) ASIO_NOEXCEPT : base_type(nullptr_t()) { } -any_io_executor::any_io_executor(const any_io_executor& e) noexcept+any_io_executor::any_io_executor(const any_io_executor& e) ASIO_NOEXCEPT : base_type(static_cast<const base_type&>(e)) { } any_io_executor::any_io_executor(std::nothrow_t,- const any_io_executor& e) noexcept+ const any_io_executor& e) ASIO_NOEXCEPT : base_type(static_cast<const base_type&>(e)) { } -any_io_executor::any_io_executor(any_io_executor&& e) noexcept+#if defined(ASIO_HAS_MOVE)+any_io_executor::any_io_executor(any_io_executor&& e) ASIO_NOEXCEPT : base_type(static_cast<base_type&&>(e)) { } -any_io_executor::any_io_executor(std::nothrow_t, any_io_executor&& e) noexcept+any_io_executor::any_io_executor(std::nothrow_t,+ any_io_executor&& e) ASIO_NOEXCEPT : base_type(static_cast<base_type&&>(e)) { }+#endif // defined(ASIO_HAS_MOVE) -any_io_executor& any_io_executor::operator=(const any_io_executor& e) noexcept+any_io_executor& any_io_executor::operator=(+ const any_io_executor& e) ASIO_NOEXCEPT { base_type::operator=(static_cast<const base_type&>(e)); return *this; } -any_io_executor& any_io_executor::operator=(any_io_executor&& e) noexcept+#if defined(ASIO_HAS_MOVE)+any_io_executor& any_io_executor::operator=(+ any_io_executor&& e) ASIO_NOEXCEPT { base_type::operator=(static_cast<base_type&&>(e)); return *this; }+#endif // defined(ASIO_HAS_MOVE) any_io_executor& any_io_executor::operator=(nullptr_t) {@@ -78,7 +85,7 @@ { } -void any_io_executor::swap(any_io_executor& other) noexcept+void any_io_executor::swap(any_io_executor& other) ASIO_NOEXCEPT { static_cast<base_type&>(*this).swap(static_cast<base_type&>(other)); }
link/modules/asio-standalone/asio/include/asio/impl/append.hpp view
@@ -2,7 +2,7 @@ // impl/append.hpp // ~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -16,12 +16,15 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"+ #include "asio/associator.hpp" #include "asio/async_result.hpp"+#include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_cont_helpers.hpp"-#include "asio/detail/initiation_base.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/type_traits.hpp" #include "asio/detail/utility.hpp"+#include "asio/detail/variadic_templates.hpp" #include "asio/detail/push_options.hpp" @@ -36,26 +39,26 @@ typedef void result_type; template <typename H>- append_handler(H&& handler, std::tuple<Values...> values)- : handler_(static_cast<H&&>(handler)),- values_(static_cast<std::tuple<Values...>&&>(values))+ append_handler(ASIO_MOVE_ARG(H) handler, std::tuple<Values...> values)+ : handler_(ASIO_MOVE_CAST(H)(handler)),+ values_(ASIO_MOVE_CAST(std::tuple<Values...>)(values)) { } template <typename... Args>- void operator()(Args&&... args)+ void operator()(ASIO_MOVE_ARG(Args)... args) { this->invoke( index_sequence_for<Values...>{},- static_cast<Args&&>(args)...);+ ASIO_MOVE_CAST(Args)(args)...); } template <std::size_t... I, typename... Args>- void invoke(index_sequence<I...>, Args&&... args)+ void invoke(index_sequence<I...>, ASIO_MOVE_ARG(Args)... args) {- static_cast<Handler&&>(handler_)(- static_cast<Args&&>(args)...,- static_cast<Values&&>(std::get<I>(values_))...);+ ASIO_MOVE_OR_LVALUE(Handler)(handler_)(+ ASIO_MOVE_CAST(Args)(args)...,+ ASIO_MOVE_CAST(Values)(std::get<I>(values_))...); } //private:@@ -64,6 +67,32 @@ }; template <typename Handler>+inline asio_handler_allocate_is_deprecated+asio_handler_allocate(std::size_t size,+ append_handler<Handler>* this_handler)+{+#if defined(ASIO_NO_DEPRECATED)+ asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+ return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+ return asio_handler_alloc_helpers::allocate(+ size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler>+inline asio_handler_deallocate_is_deprecated+asio_handler_deallocate(void* pointer, std::size_t size,+ append_handler<Handler>* this_handler)+{+ asio_handler_alloc_helpers::deallocate(+ pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler> inline bool asio_handler_is_continuation( append_handler<Handler>* this_handler) {@@ -71,13 +100,37 @@ this_handler->handler_); } +template <typename Function, typename Handler>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(Function& function,+ append_handler<Handler>* this_handler)+{+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Function, typename Handler>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(const Function& function,+ append_handler<Handler>* this_handler)+{+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}+ template <typename Signature, typename... Values> struct append_signature; template <typename R, typename... Args, typename... Values> struct append_signature<R(Args...), Values...> {- typedef R type(decay_t<Args>..., Values...);+ typedef R type(typename decay<Args>::type..., Values...); }; } // namespace detail@@ -85,7 +138,8 @@ #if !defined(GENERATING_DOCUMENTATION) template <typename CompletionToken, typename... Values, typename Signature>-struct async_result<append_t<CompletionToken, Values...>, Signature>+struct async_result<+ append_t<CompletionToken, Values...>, Signature> : async_result<CompletionToken, typename detail::append_signature< Signature, Values...>::type>@@ -94,49 +148,48 @@ Signature, Values...>::type signature; template <typename Initiation>- struct init_wrapper : detail::initiation_base<Initiation>+ struct init_wrapper {- using detail::initiation_base<Initiation>::initiation_base;-- template <typename Handler, typename... Args>- void operator()(Handler&& handler,- std::tuple<Values...> values, Args&&... args) &&+ init_wrapper(Initiation init)+ : initiation_(ASIO_MOVE_CAST(Initiation)(init)) {- static_cast<Initiation&&>(*this)(- detail::append_handler<decay_t<Handler>, Values...>(- static_cast<Handler&&>(handler),- static_cast<std::tuple<Values...>&&>(values)),- static_cast<Args&&>(args)...); } template <typename Handler, typename... Args>- void operator()(Handler&& handler,- std::tuple<Values...> values, Args&&... args) const &+ void operator()(+ ASIO_MOVE_ARG(Handler) handler,+ std::tuple<Values...> values,+ ASIO_MOVE_ARG(Args)... args) {- static_cast<const Initiation&>(*this)(- detail::append_handler<decay_t<Handler>, Values...>(- static_cast<Handler&&>(handler),- static_cast<std::tuple<Values...>&&>(values)),- static_cast<Args&&>(args)...);+ ASIO_MOVE_CAST(Initiation)(initiation_)(+ detail::append_handler<+ typename decay<Handler>::type, Values...>(+ ASIO_MOVE_CAST(Handler)(handler),+ ASIO_MOVE_CAST(std::tuple<Values...>)(values)),+ ASIO_MOVE_CAST(Args)(args)...); }++ Initiation initiation_; }; template <typename Initiation, typename RawCompletionToken, typename... Args>- static auto initiate(Initiation&& initiation,- RawCompletionToken&& token, Args&&... args)- -> decltype(- async_initiate<CompletionToken, signature>(- declval<init_wrapper<decay_t<Initiation>>>(),- token.token_,- static_cast<std::tuple<Values...>&&>(token.values_),- static_cast<Args&&>(args)...))+ static ASIO_INITFN_DEDUCED_RESULT_TYPE(CompletionToken, signature,+ (async_initiate<CompletionToken, signature>(+ declval<init_wrapper<typename decay<Initiation>::type> >(),+ declval<CompletionToken&>(),+ declval<std::tuple<Values...> >(),+ declval<ASIO_MOVE_ARG(Args)>()...)))+ initiate(+ ASIO_MOVE_ARG(Initiation) initiation,+ ASIO_MOVE_ARG(RawCompletionToken) token,+ ASIO_MOVE_ARG(Args)... args) { return async_initiate<CompletionToken, signature>(- init_wrapper<decay_t<Initiation>>(- static_cast<Initiation&&>(initiation)),+ init_wrapper<typename decay<Initiation>::type>(+ ASIO_MOVE_CAST(Initiation)(initiation)), token.token_,- static_cast<std::tuple<Values...>&&>(token.values_),- static_cast<Args&&>(args)...);+ ASIO_MOVE_CAST(std::tuple<Values...>)(token.values_),+ ASIO_MOVE_CAST(Args)(args)...); } }; @@ -146,15 +199,18 @@ detail::append_handler<Handler, Values...>, DefaultCandidate> : Associator<Handler, DefaultCandidate> {- static typename Associator<Handler, DefaultCandidate>::type get(- const detail::append_handler<Handler, Values...>& h) noexcept+ static typename Associator<Handler, DefaultCandidate>::type+ get(const detail::append_handler<Handler, Values...>& h) ASIO_NOEXCEPT { return Associator<Handler, DefaultCandidate>::get(h.handler_); } - static auto get(const detail::append_handler<Handler, Values...>& h,- const DefaultCandidate& c) noexcept- -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))+ static ASIO_AUTO_RETURN_TYPE_PREFIX2(+ typename Associator<Handler, DefaultCandidate>::type)+ get(const detail::append_handler<Handler, Values...>& h,+ const DefaultCandidate& c) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ Associator<Handler, DefaultCandidate>::get(h.handler_, c))) { return Associator<Handler, DefaultCandidate>::get(h.handler_, c); }
link/modules/asio-standalone/asio/include/asio/impl/as_tuple.hpp view
@@ -2,7 +2,7 @@ // impl/as_tuple.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -16,13 +16,16 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"+ #include <tuple>-#include "asio/associated_executor.hpp"+ #include "asio/associator.hpp" #include "asio/async_result.hpp"+#include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_cont_helpers.hpp"-#include "asio/detail/initiation_base.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/type_traits.hpp"+#include "asio/detail/variadic_templates.hpp" #include "asio/detail/push_options.hpp" @@ -38,21 +41,21 @@ template <typename CompletionToken> as_tuple_handler(as_tuple_t<CompletionToken> e)- : handler_(static_cast<CompletionToken&&>(e.token_))+ : handler_(ASIO_MOVE_CAST(CompletionToken)(e.token_)) { } template <typename RedirectedHandler>- as_tuple_handler(RedirectedHandler&& h)- : handler_(static_cast<RedirectedHandler&&>(h))+ as_tuple_handler(ASIO_MOVE_ARG(RedirectedHandler) h)+ : handler_(ASIO_MOVE_CAST(RedirectedHandler)(h)) { } template <typename... Args>- void operator()(Args&&... args)+ void operator()(ASIO_MOVE_ARG(Args)... args) {- static_cast<Handler&&>(handler_)(- std::make_tuple(static_cast<Args&&>(args)...));+ ASIO_MOVE_OR_LVALUE(Handler)(handler_)(+ std::make_tuple(ASIO_MOVE_CAST(Args)(args)...)); } //private:@@ -60,6 +63,32 @@ }; template <typename Handler>+inline asio_handler_allocate_is_deprecated+asio_handler_allocate(std::size_t size,+ as_tuple_handler<Handler>* this_handler)+{+#if defined(ASIO_NO_DEPRECATED)+ asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+ return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+ return asio_handler_alloc_helpers::allocate(+ size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler>+inline asio_handler_deallocate_is_deprecated+asio_handler_deallocate(void* pointer, std::size_t size,+ as_tuple_handler<Handler>* this_handler)+{+ asio_handler_alloc_helpers::deallocate(+ pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler> inline bool asio_handler_is_continuation( as_tuple_handler<Handler>* this_handler) {@@ -67,48 +96,75 @@ this_handler->handler_); } +template <typename Function, typename Handler>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(Function& function,+ as_tuple_handler<Handler>* this_handler)+{+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Function, typename Handler>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(const Function& function,+ as_tuple_handler<Handler>* this_handler)+{+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}+ template <typename Signature> struct as_tuple_signature; template <typename R, typename... Args> struct as_tuple_signature<R(Args...)> {- typedef R type(std::tuple<decay_t<Args>...>);+ typedef R type(std::tuple<typename decay<Args>::type...>); }; +#if defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)+ template <typename R, typename... Args> struct as_tuple_signature<R(Args...) &> {- typedef R type(std::tuple<decay_t<Args>...>) &;+ typedef R type(std::tuple<typename decay<Args>::type...>) &; }; template <typename R, typename... Args> struct as_tuple_signature<R(Args...) &&> {- typedef R type(std::tuple<decay_t<Args>...>) &&;+ typedef R type(std::tuple<typename decay<Args>::type...>) &&; }; -#if defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)+# if defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE) template <typename R, typename... Args> struct as_tuple_signature<R(Args...) noexcept> {- typedef R type(std::tuple<decay_t<Args>...>) noexcept;+ typedef R type(std::tuple<typename decay<Args>::type...>) noexcept; }; template <typename R, typename... Args> struct as_tuple_signature<R(Args...) & noexcept> {- typedef R type(std::tuple<decay_t<Args>...>) & noexcept;+ typedef R type(std::tuple<typename decay<Args>::type...>) & noexcept; }; template <typename R, typename... Args> struct as_tuple_signature<R(Args...) && noexcept> {- typedef R type(std::tuple<decay_t<Args>...>) && noexcept;+ typedef R type(std::tuple<typename decay<Args>::type...>) && noexcept; }; -#endif // defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)+# endif // defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)+#endif // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS) } // namespace detail @@ -120,50 +176,53 @@ typename detail::as_tuple_signature<Signatures>::type...> { template <typename Initiation>- struct init_wrapper : detail::initiation_base<Initiation>+ struct init_wrapper {- using detail::initiation_base<Initiation>::initiation_base;-- template <typename Handler, typename... Args>- void operator()(Handler&& handler, Args&&... args) &&+ init_wrapper(Initiation init)+ : initiation_(ASIO_MOVE_CAST(Initiation)(init)) {- static_cast<Initiation&&>(*this)(- detail::as_tuple_handler<decay_t<Handler>>(- static_cast<Handler&&>(handler)),- static_cast<Args&&>(args)...); } template <typename Handler, typename... Args>- void operator()(Handler&& handler, Args&&... args) const &+ void operator()(+ ASIO_MOVE_ARG(Handler) handler,+ ASIO_MOVE_ARG(Args)... args) {- static_cast<const Initiation&>(*this)(- detail::as_tuple_handler<decay_t<Handler>>(- static_cast<Handler&&>(handler)),- static_cast<Args&&>(args)...);+ ASIO_MOVE_CAST(Initiation)(initiation_)(+ detail::as_tuple_handler<+ typename decay<Handler>::type>(+ ASIO_MOVE_CAST(Handler)(handler)),+ ASIO_MOVE_CAST(Args)(args)...); }++ Initiation initiation_; }; template <typename Initiation, typename RawCompletionToken, typename... Args>- static auto initiate(Initiation&& initiation,- RawCompletionToken&& token, Args&&... args)- -> decltype(+ static ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(CompletionToken,+ typename detail::as_tuple_signature<Signatures>::type...)+ initiate(+ ASIO_MOVE_ARG(Initiation) initiation,+ ASIO_MOVE_ARG(RawCompletionToken) token,+ ASIO_MOVE_ARG(Args)... args)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<- conditional_t<- is_const<remove_reference_t<RawCompletionToken>>::value,- const CompletionToken, CompletionToken>,+ typename conditional<+ is_const<typename remove_reference<RawCompletionToken>::type>::value,+ const CompletionToken, CompletionToken>::type, typename detail::as_tuple_signature<Signatures>::type...>(- init_wrapper<decay_t<Initiation>>(- static_cast<Initiation&&>(initiation)),- token.token_, static_cast<Args&&>(args)...))+ init_wrapper<typename decay<Initiation>::type>(+ ASIO_MOVE_CAST(Initiation)(initiation)),+ token.token_, ASIO_MOVE_CAST(Args)(args)...))) { return async_initiate<- conditional_t<- is_const<remove_reference_t<RawCompletionToken>>::value,- const CompletionToken, CompletionToken>,+ typename conditional<+ is_const<typename remove_reference<RawCompletionToken>::type>::value,+ const CompletionToken, CompletionToken>::type, typename detail::as_tuple_signature<Signatures>::type...>(- init_wrapper<decay_t<Initiation>>(- static_cast<Initiation&&>(initiation)),- token.token_, static_cast<Args&&>(args)...);+ init_wrapper<typename decay<Initiation>::type>(+ ASIO_MOVE_CAST(Initiation)(initiation)),+ token.token_, ASIO_MOVE_CAST(Args)(args)...); } }; @@ -177,50 +236,53 @@ typename detail::as_tuple_signature<Signature>::type> { template <typename Initiation>- struct init_wrapper : detail::initiation_base<Initiation>+ struct init_wrapper {- using detail::initiation_base<Initiation>::initiation_base;-- template <typename Handler, typename... Args>- void operator()(Handler&& handler, Args&&... args) &&+ init_wrapper(Initiation init)+ : initiation_(ASIO_MOVE_CAST(Initiation)(init)) {- static_cast<Initiation&&>(*this)(- detail::as_tuple_handler<decay_t<Handler>>(- static_cast<Handler&&>(handler)),- static_cast<Args&&>(args)...); } template <typename Handler, typename... Args>- void operator()(Handler&& handler, Args&&... args) const &+ void operator()(+ ASIO_MOVE_ARG(Handler) handler,+ ASIO_MOVE_ARG(Args)... args) {- static_cast<const Initiation&>(*this)(- detail::as_tuple_handler<decay_t<Handler>>(- static_cast<Handler&&>(handler)),- static_cast<Args&&>(args)...);+ ASIO_MOVE_CAST(Initiation)(initiation_)(+ detail::as_tuple_handler<+ typename decay<Handler>::type>(+ ASIO_MOVE_CAST(Handler)(handler)),+ ASIO_MOVE_CAST(Args)(args)...); }++ Initiation initiation_; }; template <typename Initiation, typename RawCompletionToken, typename... Args>- static auto initiate(Initiation&& initiation,- RawCompletionToken&& token, Args&&... args)- -> decltype(+ static ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(CompletionToken,+ typename detail::as_tuple_signature<Signatures>::type...)+ initiate(+ ASIO_MOVE_ARG(Initiation) initiation,+ ASIO_MOVE_ARG(RawCompletionToken) token,+ ASIO_MOVE_ARG(Args)... args)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<- conditional_t<- is_const<remove_reference_t<RawCompletionToken>>::value,- const CompletionToken, CompletionToken>,+ typename conditional<+ is_const<typename remove_reference<RawCompletionToken>::type>::value,+ const CompletionToken, CompletionToken>::type, typename detail::as_tuple_signature<Signature>::type>(- init_wrapper<decay_t<Initiation>>(- static_cast<Initiation&&>(initiation)),- token.token_, static_cast<Args&&>(args)...))+ init_wrapper<typename decay<Initiation>::type>(+ ASIO_MOVE_CAST(Initiation)(initiation)),+ token.token_, ASIO_MOVE_CAST(Args)(args)...))) { return async_initiate<- conditional_t<- is_const<remove_reference_t<RawCompletionToken>>::value,- const CompletionToken, CompletionToken>,+ typename conditional<+ is_const<typename remove_reference<RawCompletionToken>::type>::value,+ const CompletionToken, CompletionToken>::type, typename detail::as_tuple_signature<Signature>::type>(- init_wrapper<decay_t<Initiation>>(- static_cast<Initiation&&>(initiation)),- token.token_, static_cast<Args&&>(args)...);+ init_wrapper<typename decay<Initiation>::type>(+ ASIO_MOVE_CAST(Initiation)(initiation)),+ token.token_, ASIO_MOVE_CAST(Args)(args)...); } }; @@ -232,38 +294,20 @@ detail::as_tuple_handler<Handler>, DefaultCandidate> : Associator<Handler, DefaultCandidate> {- static typename Associator<Handler, DefaultCandidate>::type get(- const detail::as_tuple_handler<Handler>& h) noexcept+ static typename Associator<Handler, DefaultCandidate>::type+ get(const detail::as_tuple_handler<Handler>& h) ASIO_NOEXCEPT { return Associator<Handler, DefaultCandidate>::get(h.handler_); } - static auto get(const detail::as_tuple_handler<Handler>& h,- const DefaultCandidate& c) noexcept- -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))+ static ASIO_AUTO_RETURN_TYPE_PREFIX2(+ typename Associator<Handler, DefaultCandidate>::type)+ get(const detail::as_tuple_handler<Handler>& h,+ const DefaultCandidate& c) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ Associator<Handler, DefaultCandidate>::get(h.handler_, c))) { return Associator<Handler, DefaultCandidate>::get(h.handler_, c);- }-};--template <typename... Signatures>-struct async_result<partial_as_tuple, Signatures...>-{- template <typename Initiation, typename RawCompletionToken, typename... Args>- static auto initiate(Initiation&& initiation,- RawCompletionToken&&, Args&&... args)- -> decltype(- async_initiate<Signatures...>(- static_cast<Initiation&&>(initiation),- as_tuple_t<- default_completion_token_t<associated_executor_t<Initiation>>>{},- static_cast<Args&&>(args)...))- {- return async_initiate<Signatures...>(- static_cast<Initiation&&>(initiation),- as_tuple_t<- default_completion_token_t<associated_executor_t<Initiation>>>{},- static_cast<Args&&>(args)...); } };
link/modules/asio-standalone/asio/include/asio/impl/awaitable.hpp view
@@ -2,7 +2,7 @@ // impl/awaitable.hpp // ~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -21,12 +21,10 @@ #include <tuple> #include "asio/cancellation_signal.hpp" #include "asio/cancellation_state.hpp"-#include "asio/detail/memory.hpp" #include "asio/detail/thread_context.hpp" #include "asio/detail/thread_info_base.hpp" #include "asio/detail/throw_error.hpp" #include "asio/detail/type_traits.hpp"-#include "asio/disposition.hpp" #include "asio/error.hpp" #include "asio/post.hpp" #include "asio/system_error.hpp"@@ -43,7 +41,8 @@ namespace asio { namespace detail { -template <typename, typename, typename> class awaitable_async_op_handler;+struct awaitable_thread_has_context_switched {};+template <typename, typename> class awaitable_async_op_handler; template <typename, typename, typename> class awaitable_async_op; // An awaitable_thread represents a thread-of-execution that is composed of one@@ -82,17 +81,8 @@ // | | // +-----------------+ -class awaitable_launch_context-{-public:- ASIO_DECL void launch(void (*pump_fn)(void*), void* arg);- ASIO_DECL bool is_launching();-};--struct awaitable_thread_is_launching {};- template <typename Executor>-class awaitable_frame_base : public awaitable_launch_context+class awaitable_frame_base { public: #if !defined(ASIO_DISABLE_AWAITABLE_FRAME_RECYCLING)@@ -145,15 +135,19 @@ return result{this}; } - template <typename Disposition>- void set_disposition(Disposition&& d) noexcept+ void set_except(std::exception_ptr e) noexcept {- pending_exception_ = (to_exception_ptr)(static_cast<Disposition&&>(d));+ pending_exception_ = e; } + void set_error(const asio::error_code& ec)+ {+ this->set_except(std::make_exception_ptr(asio::system_error(ec)));+ }+ void unhandled_exception() {- set_disposition(std::current_exception());+ set_except(std::current_exception()); } void rethrow_exception()@@ -181,7 +175,7 @@ template <typename Op> auto await_transform(Op&& op,- constraint_t<is_async_operation<Op>::value> = 0+ typename constraint<is_async_operation<Op>::value>::type = 0 #if defined(ASIO_ENABLE_HANDLER_TRACKING) # if defined(ASIO_HAS_SOURCE_LOCATION) , detail::source_location location = detail::source_location::current()@@ -193,8 +187,8 @@ if (!!attached_thread_->get_cancellation_state().cancelled()) throw_error(asio::error::operation_aborted, "co_await"); - return awaitable_async_op<- completion_signature_of_t<Op>, decay_t<Op>, Executor>{+ return awaitable_async_op<typename completion_signature_of<Op>::type,+ typename decay<Op>::type, Executor>{ std::forward<Op>(op), this #if defined(ASIO_ENABLE_HANDLER_TRACKING) # if defined(ASIO_HAS_SOURCE_LOCATION)@@ -303,11 +297,11 @@ auto await_resume() { return this_->attached_thread_->reset_cancellation_state(- static_cast<Filter&&>(filter_));+ ASIO_MOVE_CAST(Filter)(filter_)); } }; - return result{this, static_cast<Filter&&>(reset.filter)};+ return result{this, ASIO_MOVE_CAST(Filter)(reset.filter)}; } // This await transformation resets the associated cancellation state.@@ -334,14 +328,14 @@ auto await_resume() { return this_->attached_thread_->reset_cancellation_state(- static_cast<InFilter&&>(in_filter_),- static_cast<OutFilter&&>(out_filter_));+ ASIO_MOVE_CAST(InFilter)(in_filter_),+ ASIO_MOVE_CAST(OutFilter)(out_filter_)); } }; return result{this,- static_cast<InFilter&&>(reset.in_filter),- static_cast<OutFilter&&>(reset.out_filter)};+ ASIO_MOVE_CAST(InFilter)(reset.in_filter),+ ASIO_MOVE_CAST(OutFilter)(reset.out_filter)}; } // This await transformation determines whether cancellation is propagated as@@ -405,12 +399,12 @@ // race condition. template <typename Function> auto await_transform(Function f,- enable_if_t<+ typename enable_if< is_convertible<- result_of_t<Function(awaitable_frame_base*)>,+ typename result_of<Function(awaitable_frame_base*)>::type, awaitable_thread<Executor>* >::value- >* = nullptr)+ >::type* = nullptr) { struct result {@@ -440,8 +434,8 @@ return result{std::move(f), this}; } - // Determine whether the awaitable thread is launching.- auto await_transform(detail::awaitable_thread_is_launching) noexcept+ // Access the awaitable thread's has_context_switched_ flag.+ auto await_transform(detail::awaitable_thread_has_context_switched) noexcept { struct result {@@ -456,9 +450,9 @@ { } - bool await_resume() const noexcept+ bool& await_resume() const noexcept {- return this_->is_launching();+ return this_->attached_thread_->entry_point()->has_context_switched_; } }; @@ -472,6 +466,7 @@ awaitable_thread<Executor>* detach_thread() noexcept {+ attached_thread_->entry_point()->has_context_switched_ = true; return std::exchange(attached_thread_, nullptr); } @@ -543,14 +538,14 @@ ~awaitable_frame() { if (has_result_)- std::launder(static_cast<T*>(static_cast<void*>(result_)))->~T();+ static_cast<T*>(static_cast<void*>(result_))->~T(); } awaitable<T, Executor> get_return_object() noexcept { this->coro_ = coroutine_handle<awaitable_frame>::from_promise(*this); return awaitable<T, Executor>(this);- }+ }; template <typename U> void return_value(U&& u)@@ -569,8 +564,7 @@ { this->caller_ = nullptr; this->rethrow_exception();- return std::move(*std::launder(- static_cast<T*>(static_cast<void*>(result_))));+ return std::move(*static_cast<T*>(static_cast<void*>(result_))); } private:@@ -587,7 +581,7 @@ { this->coro_ = coroutine_handle<awaitable_frame>::from_promise(*this); return awaitable<void, Executor>(this);- }+ }; void return_void() {@@ -610,6 +604,7 @@ awaitable_frame() : top_of_stack_(0), has_executor_(false),+ has_context_switched_(false), throw_if_cancelled_(true) { }@@ -624,7 +619,7 @@ { this->coro_ = coroutine_handle<awaitable_frame>::from_promise(*this); return awaitable<awaitable_thread_entry_point, Executor>(this);- }+ }; void return_void() {@@ -638,8 +633,7 @@ private: template <typename> friend class awaitable_frame_base;- template <typename, typename, typename>- friend class awaitable_async_op_handler;+ template <typename, typename> friend class awaitable_async_op_handler; template <typename, typename> friend class awaitable_handler_base; template <typename> friend class awaitable_thread; @@ -655,6 +649,7 @@ asio::cancellation_slot parent_cancellation_slot_; asio::cancellation_state cancellation_state_; bool has_executor_;+ bool has_context_switched_; bool throw_if_cancelled_; }; @@ -723,21 +718,21 @@ } template <typename Filter>- void reset_cancellation_state(Filter&& filter)+ void reset_cancellation_state(ASIO_MOVE_ARG(Filter) filter) { bottom_of_stack_.frame_->cancellation_state_ = cancellation_state(bottom_of_stack_.frame_->parent_cancellation_slot_,- static_cast<Filter&&>(filter));+ ASIO_MOVE_CAST(Filter)(filter)); } template <typename InFilter, typename OutFilter>- void reset_cancellation_state(InFilter&& in_filter,- OutFilter&& out_filter)+ void reset_cancellation_state(ASIO_MOVE_ARG(InFilter) in_filter,+ ASIO_MOVE_ARG(OutFilter) out_filter) { bottom_of_stack_.frame_->cancellation_state_ = cancellation_state(bottom_of_stack_.frame_->parent_cancellation_slot_,- static_cast<InFilter&&>(in_filter),- static_cast<OutFilter&&>(out_filter));+ ASIO_MOVE_CAST(InFilter)(in_filter),+ ASIO_MOVE_CAST(OutFilter)(out_filter)); } bool throw_if_cancelled() const@@ -759,7 +754,7 @@ void launch() { bottom_of_stack_.frame_->top_of_stack_->attach_thread(this);- bottom_of_stack_.frame_->launch(&awaitable_thread::do_pump, this);+ pump(); } protected:@@ -781,15 +776,10 @@ } } - static void do_pump(void* self)- {- static_cast<awaitable_thread*>(self)->pump();- }- awaitable<awaitable_thread_entry_point, Executor> bottom_of_stack_; }; -template <typename Signature, typename Executor, typename = void>+template <typename Signature, typename Executor> class awaitable_async_op_handler; template <typename R, typename Executor>@@ -817,9 +807,74 @@ } }; +template <typename R, typename Executor>+class awaitable_async_op_handler<R(asio::error_code), Executor>+ : public awaitable_thread<Executor>+{+public:+ typedef asio::error_code* result_type;++ awaitable_async_op_handler(+ awaitable_thread<Executor>* h, result_type& result)+ : awaitable_thread<Executor>(std::move(*h)),+ result_(result)+ {+ }++ void operator()(asio::error_code ec)+ {+ result_ = &ec;+ this->entry_point()->top_of_stack_->attach_thread(this);+ this->entry_point()->top_of_stack_->clear_cancellation_slot();+ this->pump();+ }++ static void resume(result_type& result)+ {+ throw_error(*result);+ }++private:+ result_type& result_;+};++template <typename R, typename Executor>+class awaitable_async_op_handler<R(std::exception_ptr), Executor>+ : public awaitable_thread<Executor>+{+public:+ typedef std::exception_ptr* result_type;++ awaitable_async_op_handler(+ awaitable_thread<Executor>* h, result_type& result)+ : awaitable_thread<Executor>(std::move(*h)),+ result_(result)+ {+ }++ void operator()(std::exception_ptr ex)+ {+ result_ = &ex;+ this->entry_point()->top_of_stack_->attach_thread(this);+ this->entry_point()->top_of_stack_->clear_cancellation_slot();+ this->pump();+ }++ static void resume(result_type& result)+ {+ if (*result)+ {+ std::exception_ptr ex = std::exchange(*result, nullptr);+ std::rethrow_exception(ex);+ }+ }++private:+ result_type& result_;+};+ template <typename R, typename T, typename Executor>-class awaitable_async_op_handler<R(T), Executor,- enable_if_t<!is_disposition<T>::value>>+class awaitable_async_op_handler<R(T), Executor> : public awaitable_thread<Executor> { public:@@ -834,7 +889,7 @@ void operator()(T result) {- result_ = detail::addressof(result);+ result_ = &result; this->entry_point()->top_of_stack_->attach_thread(this); this->entry_point()->top_of_stack_->clear_cancellation_slot(); this->pump();@@ -849,13 +904,16 @@ result_type& result_; }; -template <typename R, typename Disposition, typename Executor>-class awaitable_async_op_handler<R(Disposition), Executor,- enable_if_t<is_disposition<Disposition>::value>>+template <typename R, typename T, typename Executor>+class awaitable_async_op_handler<R(asio::error_code, T), Executor> : public awaitable_thread<Executor> { public:- typedef Disposition* result_type;+ struct result_type+ {+ asio::error_code* ec_;+ T* value_;+ }; awaitable_async_op_handler( awaitable_thread<Executor>* h, result_type& result)@@ -864,36 +922,33 @@ { } - void operator()(Disposition d)+ void operator()(asio::error_code ec, T value) {- result_ = detail::addressof(d);+ result_.ec_ = &ec;+ result_.value_ = &value; this->entry_point()->top_of_stack_->attach_thread(this); this->entry_point()->top_of_stack_->clear_cancellation_slot(); this->pump(); } - static void resume(result_type& result)+ static T resume(result_type& result) {- if (*result != no_error)- {- Disposition d = std::exchange(*result, Disposition());- asio::throw_exception(static_cast<Disposition&&>(d));- }+ throw_error(*result.ec_);+ return std::move(*result.value_); } private: result_type& result_; }; -template <typename R, typename Disposition, typename T, typename Executor>-class awaitable_async_op_handler<R(Disposition, T), Executor,- enable_if_t<is_disposition<Disposition>::value>>+template <typename R, typename T, typename Executor>+class awaitable_async_op_handler<R(std::exception_ptr, T), Executor> : public awaitable_thread<Executor> { public: struct result_type {- Disposition* disposition_;+ std::exception_ptr* ex_; T* value_; }; @@ -904,10 +959,10 @@ { } - void operator()(Disposition d, T value)+ void operator()(std::exception_ptr ex, T value) {- result_.disposition_ = detail::addressof(d);- result_.value_ = detail::addressof(value);+ result_.ex_ = &ex;+ result_.value_ = &value; this->entry_point()->top_of_stack_->attach_thread(this); this->entry_point()->top_of_stack_->clear_cancellation_slot(); this->pump();@@ -915,10 +970,10 @@ static T resume(result_type& result) {- if (*result.disposition_ != no_error)+ if (*result.ex_) {- Disposition d = std::exchange(*result.disposition_, Disposition());- asio::throw_exception(static_cast<Disposition&&>(d));+ std::exception_ptr ex = std::exchange(*result.ex_, nullptr);+ std::rethrow_exception(ex); } return std::move(*result.value_); }@@ -927,13 +982,12 @@ result_type& result_; }; -template <typename R, typename T, typename... Ts, typename Executor>-class awaitable_async_op_handler<R(T, Ts...), Executor,- enable_if_t<!is_disposition<T>::value>>+template <typename R, typename... Ts, typename Executor>+class awaitable_async_op_handler<R(Ts...), Executor> : public awaitable_thread<Executor> { public:- typedef std::tuple<T, Ts...>* result_type;+ typedef std::tuple<Ts...>* result_type; awaitable_async_op_handler( awaitable_thread<Executor>* h, result_type& result)@@ -945,14 +999,14 @@ template <typename... Args> void operator()(Args&&... args) {- std::tuple<T, Ts...> result(std::forward<Args>(args)...);- result_ = detail::addressof(result);+ std::tuple<Ts...> result(std::forward<Args>(args)...);+ result_ = &result; this->entry_point()->top_of_stack_->attach_thread(this); this->entry_point()->top_of_stack_->clear_cancellation_slot(); this->pump(); } - static std::tuple<T, Ts...> resume(result_type& result)+ static std::tuple<Ts...> resume(result_type& result) { return std::move(*result); }@@ -961,15 +1015,14 @@ result_type& result_; }; -template <typename R, typename Disposition, typename... Ts, typename Executor>-class awaitable_async_op_handler<R(Disposition, Ts...), Executor,- enable_if_t<is_disposition<Disposition>::value>>+template <typename R, typename... Ts, typename Executor>+class awaitable_async_op_handler<R(asio::error_code, Ts...), Executor> : public awaitable_thread<Executor> { public: struct result_type {- Disposition* disposition_;+ asio::error_code* ec_; std::tuple<Ts...>* value_; }; @@ -981,11 +1034,11 @@ } template <typename... Args>- void operator()(Disposition d, Args&&... args)+ void operator()(asio::error_code ec, Args&&... args) {- result_.disposition_ = detail::addressof(d);+ result_.ec_ = &ec; std::tuple<Ts...> value(std::forward<Args>(args)...);- result_.value_ = detail::addressof(value);+ result_.value_ = &value; this->entry_point()->top_of_stack_->attach_thread(this); this->entry_point()->top_of_stack_->clear_cancellation_slot(); this->pump();@@ -993,10 +1046,49 @@ static std::tuple<Ts...> resume(result_type& result) {- if (*result.disposition_ != no_error)+ throw_error(*result.ec_);+ return std::move(*result.value_);+ }++private:+ result_type& result_;+};++template <typename R, typename... Ts, typename Executor>+class awaitable_async_op_handler<R(std::exception_ptr, Ts...), Executor>+ : public awaitable_thread<Executor>+{+public:+ struct result_type+ {+ std::exception_ptr* ex_;+ std::tuple<Ts...>* value_;+ };++ awaitable_async_op_handler(+ awaitable_thread<Executor>* h, result_type& result)+ : awaitable_thread<Executor>(std::move(*h)),+ result_(result)+ {+ }++ template <typename... Args>+ void operator()(std::exception_ptr ex, Args&&... args)+ {+ result_.ex_ = &ex;+ std::tuple<Ts...> value(std::forward<Args>(args)...);+ result_.value_ = &value;+ this->entry_point()->top_of_stack_->attach_thread(this);+ this->entry_point()->top_of_stack_->clear_cancellation_slot();+ this->pump();+ }++ static std::tuple<Ts...> resume(result_type& result)+ {+ if (*result.ex_) {- Disposition d = std::exchange(*result.disposition_, Disposition());- asio::throw_exception(static_cast<Disposition&&>(d));+ std::exception_ptr ex = std::exchange(*result.ex_, nullptr);+ std::rethrow_exception(ex); } return std::move(*result.value_); }
− link/modules/asio-standalone/asio/include/asio/impl/awaitable.ipp
@@ -1,48 +0,0 @@-//-// impl/awaitable.ipp-// ~~~~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef ASIO_IMPL_AWAITABLE_IPP-#define ASIO_IMPL_AWAITABLE_IPP--#if defined(_MSC_VER) && (_MSC_VER >= 1200)-# pragma once-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)--#include "asio/detail/config.hpp"--#if defined(ASIO_HAS_CO_AWAIT)--#include "asio/awaitable.hpp"-#include "asio/detail/call_stack.hpp"--#include "asio/detail/push_options.hpp"--namespace asio {-namespace detail {--void awaitable_launch_context::launch(void (*pump_fn)(void*), void* arg)-{- call_stack<awaitable_launch_context>::context ctx(this);- pump_fn(arg);-}--bool awaitable_launch_context::is_launching()-{- return !!call_stack<awaitable_launch_context>::contains(this);-}--} // namespace detail-} // namespace asio--#include "asio/detail/pop_options.hpp"--#endif // defined(ASIO_HAS_CO_AWAIT)--#endif // ASIO_IMPL_AWAITABLE_IPP
link/modules/asio-standalone/asio/include/asio/impl/buffered_read_stream.hpp view
@@ -2,7 +2,7 @@ // impl/buffered_read_stream.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -16,7 +16,9 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/associator.hpp"+#include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_cont_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_type_requirements.hpp" #include "asio/detail/non_const_lvalue.hpp" #include "asio/detail/type_traits.hpp"@@ -64,10 +66,11 @@ std::size_t previous_size, ReadHandler& handler) : storage_(storage), previous_size_(previous_size),- handler_(static_cast<ReadHandler&&>(handler))+ handler_(ASIO_MOVE_CAST(ReadHandler)(handler)) { } +#if defined(ASIO_HAS_MOVE) buffered_fill_handler(const buffered_fill_handler& other) : storage_(other.storage_), previous_size_(other.previous_size_),@@ -78,15 +81,16 @@ buffered_fill_handler(buffered_fill_handler&& other) : storage_(other.storage_), previous_size_(other.previous_size_),- handler_(static_cast<ReadHandler&&>(other.handler_))+ handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_)) { }+#endif // defined(ASIO_HAS_MOVE) void operator()(const asio::error_code& ec, const std::size_t bytes_transferred) { storage_.resize(previous_size_ + bytes_transferred);- static_cast<ReadHandler&&>(handler_)(ec, bytes_transferred);+ ASIO_MOVE_OR_LVALUE(ReadHandler)(handler_)(ec, bytes_transferred); } //private:@@ -96,6 +100,32 @@ }; template <typename ReadHandler>+ inline asio_handler_allocate_is_deprecated+ asio_handler_allocate(std::size_t size,+ buffered_fill_handler<ReadHandler>* this_handler)+ {+#if defined(ASIO_NO_DEPRECATED)+ asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+ return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+ return asio_handler_alloc_helpers::allocate(+ size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename ReadHandler>+ inline asio_handler_deallocate_is_deprecated+ asio_handler_deallocate(void* pointer, std::size_t size,+ buffered_fill_handler<ReadHandler>* this_handler)+ {+ asio_handler_alloc_helpers::deallocate(+ pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename ReadHandler> inline bool asio_handler_is_continuation( buffered_fill_handler<ReadHandler>* this_handler) {@@ -103,26 +133,50 @@ this_handler->handler_); } + template <typename Function, typename ReadHandler>+ inline asio_handler_invoke_is_deprecated+ asio_handler_invoke(Function& function,+ buffered_fill_handler<ReadHandler>* this_handler)+ {+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename Function, typename ReadHandler>+ inline asio_handler_invoke_is_deprecated+ asio_handler_invoke(const Function& function,+ buffered_fill_handler<ReadHandler>* this_handler)+ {+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }+ template <typename Stream> class initiate_async_buffered_fill { public:- typedef typename remove_reference_t<- Stream>::lowest_layer_type::executor_type executor_type;+ typedef typename remove_reference<+ Stream>::type::lowest_layer_type::executor_type executor_type; explicit initiate_async_buffered_fill(- remove_reference_t<Stream>& next_layer)+ typename remove_reference<Stream>::type& next_layer) : next_layer_(next_layer) { } - executor_type get_executor() const noexcept+ executor_type get_executor() const ASIO_NOEXCEPT { return next_layer_.lowest_layer().get_executor(); } template <typename ReadHandler>- void operator()(ReadHandler&& handler,+ void operator()(ASIO_MOVE_ARG(ReadHandler) handler, buffered_stream_storage* storage) const { // If you get an error on the following line it means that your handler@@ -136,12 +190,12 @@ buffer( storage->data() + previous_size, storage->size() - previous_size),- buffered_fill_handler<decay_t<ReadHandler>>(+ buffered_fill_handler<typename decay<ReadHandler>::type>( *storage, previous_size, handler2.value)); } private:- remove_reference_t<Stream>& next_layer_;+ typename remove_reference<Stream>::type& next_layer_; }; } // namespace detail @@ -154,15 +208,18 @@ DefaultCandidate> : Associator<ReadHandler, DefaultCandidate> {- static typename Associator<ReadHandler, DefaultCandidate>::type get(- const detail::buffered_fill_handler<ReadHandler>& h) noexcept+ static typename Associator<ReadHandler, DefaultCandidate>::type+ get(const detail::buffered_fill_handler<ReadHandler>& h) ASIO_NOEXCEPT { return Associator<ReadHandler, DefaultCandidate>::get(h.handler_); } - static auto get(const detail::buffered_fill_handler<ReadHandler>& h,- const DefaultCandidate& c) noexcept- -> decltype(Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c))+ static ASIO_AUTO_RETURN_TYPE_PREFIX2(+ typename Associator<ReadHandler, DefaultCandidate>::type)+ get(const detail::buffered_fill_handler<ReadHandler>& h,+ const DefaultCandidate& c) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c))) { return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c); }@@ -174,12 +231,15 @@ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, std::size_t)) ReadHandler>-inline auto buffered_read_stream<Stream>::async_fill(ReadHandler&& handler)- -> decltype(+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadHandler,+ void (asio::error_code, std::size_t))+buffered_read_stream<Stream>::async_fill(+ ASIO_MOVE_ARG(ReadHandler) handler)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<ReadHandler, void (asio::error_code, std::size_t)>(- declval<detail::initiate_async_buffered_fill<Stream>>(),- handler, declval<detail::buffered_stream_storage*>()))+ declval<detail::initiate_async_buffered_fill<Stream> >(),+ handler, declval<detail::buffered_stream_storage*>()))) { return async_initiate<ReadHandler, void (asio::error_code, std::size_t)>(@@ -229,37 +289,39 @@ const MutableBufferSequence& buffers, ReadHandler& handler) : storage_(storage), buffers_(buffers),- handler_(static_cast<ReadHandler&&>(handler))+ handler_(ASIO_MOVE_CAST(ReadHandler)(handler)) { } - buffered_read_some_handler(const buffered_read_some_handler& other)- : storage_(other.storage_),- buffers_(other.buffers_),- handler_(other.handler_)- {- }+#if defined(ASIO_HAS_MOVE)+ buffered_read_some_handler(const buffered_read_some_handler& other)+ : storage_(other.storage_),+ buffers_(other.buffers_),+ handler_(other.handler_)+ {+ } - buffered_read_some_handler(buffered_read_some_handler&& other)- : storage_(other.storage_),- buffers_(other.buffers_),- handler_(static_cast<ReadHandler&&>(other.handler_))- {- }+ buffered_read_some_handler(buffered_read_some_handler&& other)+ : storage_(other.storage_),+ buffers_(other.buffers_),+ handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_))+ {+ }+#endif // defined(ASIO_HAS_MOVE) void operator()(const asio::error_code& ec, std::size_t) { if (ec || storage_.empty()) { const std::size_t length = 0;- static_cast<ReadHandler&&>(handler_)(ec, length);+ ASIO_MOVE_OR_LVALUE(ReadHandler)(handler_)(ec, length); } else { const std::size_t bytes_copied = asio::buffer_copy( buffers_, storage_.data(), storage_.size()); storage_.consume(bytes_copied);- static_cast<ReadHandler&&>(handler_)(ec, bytes_copied);+ ASIO_MOVE_OR_LVALUE(ReadHandler)(handler_)(ec, bytes_copied); } } @@ -270,6 +332,34 @@ }; template <typename MutableBufferSequence, typename ReadHandler>+ inline asio_handler_allocate_is_deprecated+ asio_handler_allocate(std::size_t size,+ buffered_read_some_handler<+ MutableBufferSequence, ReadHandler>* this_handler)+ {+#if defined(ASIO_NO_DEPRECATED)+ asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+ return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+ return asio_handler_alloc_helpers::allocate(+ size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename MutableBufferSequence, typename ReadHandler>+ inline asio_handler_deallocate_is_deprecated+ asio_handler_deallocate(void* pointer, std::size_t size,+ buffered_read_some_handler<+ MutableBufferSequence, ReadHandler>* this_handler)+ {+ asio_handler_alloc_helpers::deallocate(+ pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename MutableBufferSequence, typename ReadHandler> inline bool asio_handler_is_continuation( buffered_read_some_handler< MutableBufferSequence, ReadHandler>* this_handler)@@ -278,26 +368,54 @@ this_handler->handler_); } + template <typename Function, typename MutableBufferSequence,+ typename ReadHandler>+ inline asio_handler_invoke_is_deprecated+ asio_handler_invoke(Function& function,+ buffered_read_some_handler<+ MutableBufferSequence, ReadHandler>* this_handler)+ {+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename Function, typename MutableBufferSequence,+ typename ReadHandler>+ inline asio_handler_invoke_is_deprecated+ asio_handler_invoke(const Function& function,+ buffered_read_some_handler<+ MutableBufferSequence, ReadHandler>* this_handler)+ {+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }+ template <typename Stream> class initiate_async_buffered_read_some { public:- typedef typename remove_reference_t<- Stream>::lowest_layer_type::executor_type executor_type;+ typedef typename remove_reference<+ Stream>::type::lowest_layer_type::executor_type executor_type; explicit initiate_async_buffered_read_some(- remove_reference_t<Stream>& next_layer)+ typename remove_reference<Stream>::type& next_layer) : next_layer_(next_layer) { } - executor_type get_executor() const noexcept+ executor_type get_executor() const ASIO_NOEXCEPT { return next_layer_.lowest_layer().get_executor(); } template <typename ReadHandler, typename MutableBufferSequence>- void operator()(ReadHandler&& handler,+ void operator()(ASIO_MOVE_ARG(ReadHandler) handler, buffered_stream_storage* storage, const MutableBufferSequence& buffers) const {@@ -309,23 +427,23 @@ non_const_lvalue<ReadHandler> handler2(handler); if (buffer_size(buffers) == 0 || !storage->empty()) {- next_layer_.async_read_some(mutable_buffer(0, 0),+ next_layer_.async_read_some(ASIO_MUTABLE_BUFFER(0, 0), buffered_read_some_handler<MutableBufferSequence,- decay_t<ReadHandler>>(+ typename decay<ReadHandler>::type>( *storage, buffers, handler2.value)); } else { initiate_async_buffered_fill<Stream>(this->next_layer_)( buffered_read_some_handler<MutableBufferSequence,- decay_t<ReadHandler>>(+ typename decay<ReadHandler>::type>( *storage, buffers, handler2.value), storage); } } private:- remove_reference_t<Stream>& next_layer_;+ typename remove_reference<Stream>::type& next_layer_; }; } // namespace detail @@ -339,18 +457,20 @@ DefaultCandidate> : Associator<ReadHandler, DefaultCandidate> {- static typename Associator<ReadHandler, DefaultCandidate>::type get(- const detail::buffered_read_some_handler<- MutableBufferSequence, ReadHandler>& h) noexcept+ static typename Associator<ReadHandler, DefaultCandidate>::type+ get(const detail::buffered_read_some_handler<+ MutableBufferSequence, ReadHandler>& h) ASIO_NOEXCEPT { return Associator<ReadHandler, DefaultCandidate>::get(h.handler_); } - static auto get(- const detail::buffered_read_some_handler<+ static ASIO_AUTO_RETURN_TYPE_PREFIX2(+ typename Associator<ReadHandler, DefaultCandidate>::type)+ get(const detail::buffered_read_some_handler< MutableBufferSequence, ReadHandler>& h,- const DefaultCandidate& c) noexcept- -> decltype(Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c))+ const DefaultCandidate& c) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c))) { return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c); }@@ -362,13 +482,16 @@ template <typename MutableBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, std::size_t)) ReadHandler>-inline auto buffered_read_stream<Stream>::async_read_some(- const MutableBufferSequence& buffers, ReadHandler&& handler)- -> decltype(+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadHandler,+ void (asio::error_code, std::size_t))+buffered_read_stream<Stream>::async_read_some(+ const MutableBufferSequence& buffers,+ ASIO_MOVE_ARG(ReadHandler) handler)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<ReadHandler, void (asio::error_code, std::size_t)>(- declval<detail::initiate_async_buffered_read_some<Stream>>(),- handler, declval<detail::buffered_stream_storage*>(), buffers))+ declval<detail::initiate_async_buffered_read_some<Stream> >(),+ handler, declval<detail::buffered_stream_storage*>(), buffers))) { return async_initiate<ReadHandler, void (asio::error_code, std::size_t)>(
link/modules/asio-standalone/asio/include/asio/impl/buffered_write_stream.hpp view
@@ -2,7 +2,7 @@ // impl/buffered_write_stream.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -16,7 +16,9 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/associator.hpp"+#include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_cont_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_type_requirements.hpp" #include "asio/detail/non_const_lvalue.hpp" @@ -52,10 +54,11 @@ buffered_flush_handler(detail::buffered_stream_storage& storage, WriteHandler& handler) : storage_(storage),- handler_(static_cast<WriteHandler&&>(handler))+ handler_(ASIO_MOVE_CAST(WriteHandler)(handler)) { } +#if defined(ASIO_HAS_MOVE) buffered_flush_handler(const buffered_flush_handler& other) : storage_(other.storage_), handler_(other.handler_)@@ -64,15 +67,16 @@ buffered_flush_handler(buffered_flush_handler&& other) : storage_(other.storage_),- handler_(static_cast<WriteHandler&&>(other.handler_))+ handler_(ASIO_MOVE_CAST(WriteHandler)(other.handler_)) { }+#endif // defined(ASIO_HAS_MOVE) void operator()(const asio::error_code& ec, const std::size_t bytes_written) { storage_.consume(bytes_written);- static_cast<WriteHandler&&>(handler_)(ec, bytes_written);+ ASIO_MOVE_OR_LVALUE(WriteHandler)(handler_)(ec, bytes_written); } //private:@@ -81,6 +85,32 @@ }; template <typename WriteHandler>+ inline asio_handler_allocate_is_deprecated+ asio_handler_allocate(std::size_t size,+ buffered_flush_handler<WriteHandler>* this_handler)+ {+#if defined(ASIO_NO_DEPRECATED)+ asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+ return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+ return asio_handler_alloc_helpers::allocate(+ size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename WriteHandler>+ inline asio_handler_deallocate_is_deprecated+ asio_handler_deallocate(void* pointer, std::size_t size,+ buffered_flush_handler<WriteHandler>* this_handler)+ {+ asio_handler_alloc_helpers::deallocate(+ pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename WriteHandler> inline bool asio_handler_is_continuation( buffered_flush_handler<WriteHandler>* this_handler) {@@ -88,26 +118,50 @@ this_handler->handler_); } + template <typename Function, typename WriteHandler>+ inline asio_handler_invoke_is_deprecated+ asio_handler_invoke(Function& function,+ buffered_flush_handler<WriteHandler>* this_handler)+ {+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename Function, typename WriteHandler>+ inline asio_handler_invoke_is_deprecated+ asio_handler_invoke(const Function& function,+ buffered_flush_handler<WriteHandler>* this_handler)+ {+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }+ template <typename Stream> class initiate_async_buffered_flush { public:- typedef typename remove_reference_t<- Stream>::lowest_layer_type::executor_type executor_type;+ typedef typename remove_reference<+ Stream>::type::lowest_layer_type::executor_type executor_type; explicit initiate_async_buffered_flush(- remove_reference_t<Stream>& next_layer)+ typename remove_reference<Stream>::type& next_layer) : next_layer_(next_layer) { } - executor_type get_executor() const noexcept+ executor_type get_executor() const ASIO_NOEXCEPT { return next_layer_.lowest_layer().get_executor(); } template <typename WriteHandler>- void operator()(WriteHandler&& handler,+ void operator()(ASIO_MOVE_ARG(WriteHandler) handler, buffered_stream_storage* storage) const { // If you get an error on the following line it means that your handler@@ -116,12 +170,12 @@ non_const_lvalue<WriteHandler> handler2(handler); async_write(next_layer_, buffer(storage->data(), storage->size()),- buffered_flush_handler<decay_t<WriteHandler>>(+ buffered_flush_handler<typename decay<WriteHandler>::type>( *storage, handler2.value)); } private:- remove_reference_t<Stream>& next_layer_;+ typename remove_reference<Stream>::type& next_layer_; }; } // namespace detail @@ -134,15 +188,18 @@ DefaultCandidate> : Associator<WriteHandler, DefaultCandidate> {- static typename Associator<WriteHandler, DefaultCandidate>::type get(- const detail::buffered_flush_handler<WriteHandler>& h) noexcept+ static typename Associator<WriteHandler, DefaultCandidate>::type+ get(const detail::buffered_flush_handler<WriteHandler>& h) ASIO_NOEXCEPT { return Associator<WriteHandler, DefaultCandidate>::get(h.handler_); } - static auto get(const detail::buffered_flush_handler<WriteHandler>& h,- const DefaultCandidate& c) noexcept- -> decltype(Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c))+ static ASIO_AUTO_RETURN_TYPE_PREFIX2(+ typename Associator<WriteHandler, DefaultCandidate>::type)+ get(const detail::buffered_flush_handler<WriteHandler>& h,+ const DefaultCandidate& c) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c))) { return Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c); }@@ -154,12 +211,15 @@ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, std::size_t)) WriteHandler>-inline auto buffered_write_stream<Stream>::async_flush(WriteHandler&& handler)- -> decltype(+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteHandler,+ void (asio::error_code, std::size_t))+buffered_write_stream<Stream>::async_flush(+ ASIO_MOVE_ARG(WriteHandler) handler)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<WriteHandler, void (asio::error_code, std::size_t)>(- declval<detail::initiate_async_buffered_flush<Stream>>(),- handler, declval<detail::buffered_stream_storage*>()))+ declval<detail::initiate_async_buffered_flush<Stream> >(),+ handler, declval<detail::buffered_stream_storage*>()))) { return async_initiate<WriteHandler, void (asio::error_code, std::size_t)>(@@ -209,30 +269,32 @@ const ConstBufferSequence& buffers, WriteHandler& handler) : storage_(storage), buffers_(buffers),- handler_(static_cast<WriteHandler&&>(handler))+ handler_(ASIO_MOVE_CAST(WriteHandler)(handler)) { } - buffered_write_some_handler(const buffered_write_some_handler& other)- : storage_(other.storage_),- buffers_(other.buffers_),- handler_(other.handler_)- {- }+#if defined(ASIO_HAS_MOVE)+ buffered_write_some_handler(const buffered_write_some_handler& other)+ : storage_(other.storage_),+ buffers_(other.buffers_),+ handler_(other.handler_)+ {+ } - buffered_write_some_handler(buffered_write_some_handler&& other)- : storage_(other.storage_),- buffers_(other.buffers_),- handler_(static_cast<WriteHandler&&>(other.handler_))- {- }+ buffered_write_some_handler(buffered_write_some_handler&& other)+ : storage_(other.storage_),+ buffers_(other.buffers_),+ handler_(ASIO_MOVE_CAST(WriteHandler)(other.handler_))+ {+ }+#endif // defined(ASIO_HAS_MOVE) void operator()(const asio::error_code& ec, std::size_t) { if (ec) { const std::size_t length = 0;- static_cast<WriteHandler&&>(handler_)(ec, length);+ ASIO_MOVE_OR_LVALUE(WriteHandler)(handler_)(ec, length); } else {@@ -245,7 +307,7 @@ storage_.resize(orig_size + length); const std::size_t bytes_copied = asio::buffer_copy( storage_.data() + orig_size, buffers_, length);- static_cast<WriteHandler&&>(handler_)(ec, bytes_copied);+ ASIO_MOVE_OR_LVALUE(WriteHandler)(handler_)(ec, bytes_copied); } } @@ -256,6 +318,34 @@ }; template <typename ConstBufferSequence, typename WriteHandler>+ inline asio_handler_allocate_is_deprecated+ asio_handler_allocate(std::size_t size,+ buffered_write_some_handler<+ ConstBufferSequence, WriteHandler>* this_handler)+ {+#if defined(ASIO_NO_DEPRECATED)+ asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+ return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+ return asio_handler_alloc_helpers::allocate(+ size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename ConstBufferSequence, typename WriteHandler>+ inline asio_handler_deallocate_is_deprecated+ asio_handler_deallocate(void* pointer, std::size_t size,+ buffered_write_some_handler<+ ConstBufferSequence, WriteHandler>* this_handler)+ {+ asio_handler_alloc_helpers::deallocate(+ pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename ConstBufferSequence, typename WriteHandler> inline bool asio_handler_is_continuation( buffered_write_some_handler< ConstBufferSequence, WriteHandler>* this_handler)@@ -264,26 +354,54 @@ this_handler->handler_); } + template <typename Function, typename ConstBufferSequence,+ typename WriteHandler>+ inline asio_handler_invoke_is_deprecated+ asio_handler_invoke(Function& function,+ buffered_write_some_handler<+ ConstBufferSequence, WriteHandler>* this_handler)+ {+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename Function, typename ConstBufferSequence,+ typename WriteHandler>+ inline asio_handler_invoke_is_deprecated+ asio_handler_invoke(const Function& function,+ buffered_write_some_handler<+ ConstBufferSequence, WriteHandler>* this_handler)+ {+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }+ template <typename Stream> class initiate_async_buffered_write_some { public:- typedef typename remove_reference_t<- Stream>::lowest_layer_type::executor_type executor_type;+ typedef typename remove_reference<+ Stream>::type::lowest_layer_type::executor_type executor_type; explicit initiate_async_buffered_write_some(- remove_reference_t<Stream>& next_layer)+ typename remove_reference<Stream>::type& next_layer) : next_layer_(next_layer) { } - executor_type get_executor() const noexcept+ executor_type get_executor() const ASIO_NOEXCEPT { return next_layer_.lowest_layer().get_executor(); } template <typename WriteHandler, typename ConstBufferSequence>- void operator()(WriteHandler&& handler,+ void operator()(ASIO_MOVE_ARG(WriteHandler) handler, buffered_stream_storage* storage, const ConstBufferSequence& buffers) const {@@ -295,23 +413,23 @@ non_const_lvalue<WriteHandler> handler2(handler); if (buffer_size(buffers) == 0 || storage->size() < storage->capacity()) {- next_layer_.async_write_some(const_buffer(0, 0),+ next_layer_.async_write_some(ASIO_CONST_BUFFER(0, 0), buffered_write_some_handler<ConstBufferSequence,- decay_t<WriteHandler>>(+ typename decay<WriteHandler>::type>( *storage, buffers, handler2.value)); } else { initiate_async_buffered_flush<Stream>(this->next_layer_)( buffered_write_some_handler<ConstBufferSequence,- decay_t<WriteHandler>>(+ typename decay<WriteHandler>::type>( *storage, buffers, handler2.value), storage); } } private:- remove_reference_t<Stream>& next_layer_;+ typename remove_reference<Stream>::type& next_layer_; }; } // namespace detail @@ -325,18 +443,20 @@ DefaultCandidate> : Associator<WriteHandler, DefaultCandidate> {- static typename Associator<WriteHandler, DefaultCandidate>::type get(- const detail::buffered_write_some_handler<- ConstBufferSequence, WriteHandler>& h) noexcept+ static typename Associator<WriteHandler, DefaultCandidate>::type+ get(const detail::buffered_write_some_handler<+ ConstBufferSequence, WriteHandler>& h) ASIO_NOEXCEPT { return Associator<WriteHandler, DefaultCandidate>::get(h.handler_); } - static auto get(- const detail::buffered_write_some_handler<+ static ASIO_AUTO_RETURN_TYPE_PREFIX2(+ typename Associator<WriteHandler, DefaultCandidate>::type)+ get(const detail::buffered_write_some_handler< ConstBufferSequence, WriteHandler>& h,- const DefaultCandidate& c) noexcept- -> decltype(Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c))+ const DefaultCandidate& c) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c))) { return Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c); }@@ -348,13 +468,16 @@ template <typename ConstBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, std::size_t)) WriteHandler>-inline auto buffered_write_stream<Stream>::async_write_some(- const ConstBufferSequence& buffers, WriteHandler&& handler)- -> decltype(+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteHandler,+ void (asio::error_code, std::size_t))+buffered_write_stream<Stream>::async_write_some(+ const ConstBufferSequence& buffers,+ ASIO_MOVE_ARG(WriteHandler) handler)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<WriteHandler, void (asio::error_code, std::size_t)>(- declval<detail::initiate_async_buffered_write_some<Stream>>(),- handler, declval<detail::buffered_stream_storage*>(), buffers))+ declval<detail::initiate_async_buffered_write_some<Stream> >(),+ handler, declval<detail::buffered_stream_storage*>(), buffers))) { return async_initiate<WriteHandler, void (asio::error_code, std::size_t)>(
− link/modules/asio-standalone/asio/include/asio/impl/cancel_after.hpp
@@ -1,268 +0,0 @@-//-// impl/cancel_after.hpp-// ~~~~~~~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef ASIO_IMPL_CANCEL_AFTER_HPP-#define ASIO_IMPL_CANCEL_AFTER_HPP--#if defined(_MSC_VER) && (_MSC_VER >= 1200)-# pragma once-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)--#include "asio/detail/config.hpp"-#include "asio/associated_executor.hpp"-#include "asio/async_result.hpp"-#include "asio/detail/initiation_base.hpp"-#include "asio/detail/timed_cancel_op.hpp"--#include "asio/detail/push_options.hpp"--namespace asio {-namespace detail {--template <typename Initiation, typename Clock,- typename WaitTraits, typename... Signatures>-struct initiate_cancel_after : initiation_base<Initiation>-{- using initiation_base<Initiation>::initiation_base;-- template <typename Handler, typename Rep, typename Period, typename... Args>- void operator()(Handler&& handler,- const chrono::duration<Rep, Period>& timeout,- cancellation_type_t cancel_type, Args&&... args) &&- {- using op = detail::timed_cancel_op<decay_t<Handler>,- basic_waitable_timer<Clock, WaitTraits>, Signatures...>;-- non_const_lvalue<Handler> handler2(handler);- typename op::ptr p = { asio::detail::addressof(handler2.value),- op::ptr::allocate(handler2.value), 0 };- p.p = new (p.v) op(handler2.value,- basic_waitable_timer<Clock, WaitTraits,- typename Initiation::executor_type>(this->get_executor(), timeout),- cancel_type);-- op* o = p.p;- p.v = p.p = 0;- o->start(static_cast<Initiation&&>(*this), static_cast<Args&&>(args)...);- }-- template <typename Handler, typename Rep, typename Period, typename... Args>- void operator()(Handler&& handler,- const chrono::duration<Rep, Period>& timeout,- cancellation_type_t cancel_type, Args&&... args) const &- {- using op = detail::timed_cancel_op<decay_t<Handler>,- basic_waitable_timer<Clock, WaitTraits>, Signatures...>;-- non_const_lvalue<Handler> handler2(handler);- typename op::ptr p = { asio::detail::addressof(handler2.value),- op::ptr::allocate(handler2.value), 0 };- p.p = new (p.v) op(handler2.value,- basic_waitable_timer<Clock, WaitTraits,- typename Initiation::executor_type>(this->get_executor(), timeout),- cancel_type);-- op* o = p.p;- p.v = p.p = 0;- o->start(static_cast<const Initiation&>(*this),- static_cast<Args&&>(args)...);- }-};--template <typename Initiation, typename Clock,- typename WaitTraits, typename Executor, typename... Signatures>-struct initiate_cancel_after_timer : initiation_base<Initiation>-{- using initiation_base<Initiation>::initiation_base;-- template <typename Handler, typename Rep, typename Period, typename... Args>- void operator()(Handler&& handler,- basic_waitable_timer<Clock, WaitTraits, Executor>* timer,- const chrono::duration<Rep, Period>& timeout,- cancellation_type_t cancel_type, Args&&... args) &&- {- using op = detail::timed_cancel_op<decay_t<Handler>,- basic_waitable_timer<Clock, WaitTraits, Executor>&, Signatures...>;-- non_const_lvalue<Handler> handler2(handler);- typename op::ptr p = { asio::detail::addressof(handler2.value),- op::ptr::allocate(handler2.value), 0 };- timer->expires_after(timeout);- p.p = new (p.v) op(handler2.value, *timer, cancel_type);-- op* o = p.p;- p.v = p.p = 0;- o->start(static_cast<Initiation&&>(*this), static_cast<Args&&>(args)...);- }-- template <typename Handler, typename Rep, typename Period, typename... Args>- void operator()(Handler&& handler,- basic_waitable_timer<Clock, WaitTraits, Executor>* timer,- const chrono::duration<Rep, Period>& timeout,- cancellation_type_t cancel_type, Args&&... args) const &- {- using op = detail::timed_cancel_op<decay_t<Handler>,- basic_waitable_timer<Clock, WaitTraits, Executor>&, Signatures...>;-- non_const_lvalue<Handler> handler2(handler);- typename op::ptr p = { asio::detail::addressof(handler2.value),- op::ptr::allocate(handler2.value), 0 };- timer->expires_after(timeout);- p.p = new (p.v) op(handler2.value, *timer, cancel_type);-- op* o = p.p;- p.v = p.p = 0;- o->start(static_cast<const Initiation&>(*this),- static_cast<Args&&>(args)...);- }-};--} // namespace detail--#if !defined(GENERATING_DOCUMENTATION)--template <typename CompletionToken, typename Clock,- typename WaitTraits, typename... Signatures>-struct async_result<- cancel_after_t<CompletionToken, Clock, WaitTraits>, Signatures...>- : async_result<CompletionToken, Signatures...>-{- template <typename Initiation, typename RawCompletionToken, typename... Args>- static auto initiate(Initiation&& initiation,- RawCompletionToken&& token, Args&&... args)- -> decltype(- async_initiate<- conditional_t<- is_const<remove_reference_t<RawCompletionToken>>::value,- const CompletionToken, CompletionToken>,- Signatures...>(- declval<detail::initiate_cancel_after<- decay_t<Initiation>, Clock, WaitTraits, Signatures...>>(),- token.token_, token.timeout_, token.cancel_type_,- static_cast<Args&&>(args)...))- {- return async_initiate<- conditional_t<- is_const<remove_reference_t<RawCompletionToken>>::value,- const CompletionToken, CompletionToken>,- Signatures...>(- detail::initiate_cancel_after<- decay_t<Initiation>, Clock, WaitTraits, Signatures...>(- static_cast<Initiation&&>(initiation)),- token.token_, token.timeout_, token.cancel_type_,- static_cast<Args&&>(args)...);- }-};--template <typename CompletionToken, typename Clock,- typename WaitTraits, typename Executor, typename... Signatures>-struct async_result<- cancel_after_timer<CompletionToken, Clock, WaitTraits, Executor>,- Signatures...>- : async_result<CompletionToken, Signatures...>-{- template <typename Initiation, typename RawCompletionToken, typename... Args>- static auto initiate(Initiation&& initiation,- RawCompletionToken&& token, Args&&... args)- -> decltype(- async_initiate<- conditional_t<- is_const<remove_reference_t<RawCompletionToken>>::value,- const CompletionToken, CompletionToken>,- Signatures...>(- declval<detail::initiate_cancel_after_timer<- decay_t<Initiation>, Clock, WaitTraits, Executor, Signatures...>>(),- token.token_, &token.timer_, token.timeout_,- token.cancel_type_, static_cast<Args&&>(args)...))- {- return async_initiate<- conditional_t<- is_const<remove_reference_t<RawCompletionToken>>::value,- const CompletionToken, CompletionToken>,- Signatures...>(- detail::initiate_cancel_after_timer<- decay_t<Initiation>, Clock, WaitTraits, Executor, Signatures...>(- static_cast<Initiation&&>(initiation)),- token.token_, &token.timer_, token.timeout_,- token.cancel_type_, static_cast<Args&&>(args)...);- }-};--template <typename Clock, typename WaitTraits, typename... Signatures>-struct async_result<partial_cancel_after<Clock, WaitTraits>, Signatures...>-{- template <typename Initiation, typename RawCompletionToken, typename... Args>- static auto initiate(Initiation&& initiation,- RawCompletionToken&& token, Args&&... args)- -> decltype(- async_initiate<- const cancel_after_t<- default_completion_token_t<associated_executor_t<Initiation>>,- Clock, WaitTraits>&,- Signatures...>(- static_cast<Initiation&&>(initiation),- cancel_after_t<- default_completion_token_t<associated_executor_t<Initiation>>,- Clock, WaitTraits>(- default_completion_token_t<associated_executor_t<Initiation>>{},- token.timeout_, token.cancel_type_),- static_cast<Args&&>(args)...))- {- return async_initiate<- const cancel_after_t<- default_completion_token_t<associated_executor_t<Initiation>>,- Clock, WaitTraits>&,- Signatures...>(- static_cast<Initiation&&>(initiation),- cancel_after_t<- default_completion_token_t<associated_executor_t<Initiation>>,- Clock, WaitTraits>(- default_completion_token_t<associated_executor_t<Initiation>>{},- token.timeout_, token.cancel_type_),- static_cast<Args&&>(args)...);- }-};--template <typename Clock, typename WaitTraits,- typename Executor, typename... Signatures>-struct async_result<- partial_cancel_after_timer<Clock, WaitTraits, Executor>, Signatures...>-{- template <typename Initiation, typename RawCompletionToken, typename... Args>- static auto initiate(Initiation&& initiation,- RawCompletionToken&& token, Args&&... args)- -> decltype(- async_initiate<Signatures...>(- static_cast<Initiation&&>(initiation),- cancel_after_timer<- default_completion_token_t<associated_executor_t<Initiation>>,- Clock, WaitTraits, Executor>(- default_completion_token_t<associated_executor_t<Initiation>>{},- token.timer_, token.timeout_, token.cancel_type_),- static_cast<Args&&>(args)...))- {- return async_initiate<Signatures...>(- static_cast<Initiation&&>(initiation),- cancel_after_timer<- default_completion_token_t<associated_executor_t<Initiation>>,- Clock, WaitTraits, Executor>(- default_completion_token_t<associated_executor_t<Initiation>>{},- token.timer_, token.timeout_, token.cancel_type_),- static_cast<Args&&>(args)...);- }-};--#endif // !defined(GENERATING_DOCUMENTATION)--} // namespace asio--#include "asio/detail/pop_options.hpp"--#endif // ASIO_IMPL_CANCEL_AFTER_HPP
− link/modules/asio-standalone/asio/include/asio/impl/cancel_at.hpp
@@ -1,268 +0,0 @@-//-// impl/cancel_at.hpp-// ~~~~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef ASIO_IMPL_CANCEL_AT_HPP-#define ASIO_IMPL_CANCEL_AT_HPP--#if defined(_MSC_VER) && (_MSC_VER >= 1200)-# pragma once-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)--#include "asio/detail/config.hpp"-#include "asio/associated_executor.hpp"-#include "asio/async_result.hpp"-#include "asio/detail/initiation_base.hpp"-#include "asio/detail/timed_cancel_op.hpp"--#include "asio/detail/push_options.hpp"--namespace asio {-namespace detail {--template <typename Initiation, typename Clock,- typename WaitTraits, typename... Signatures>-struct initiate_cancel_at : initiation_base<Initiation>-{- using initiation_base<Initiation>::initiation_base;-- template <typename Handler, typename Duration, typename... Args>- void operator()(Handler&& handler,- const chrono::time_point<Clock, Duration>& expiry,- cancellation_type_t cancel_type, Args&&... args) &&- {- using op = detail::timed_cancel_op<decay_t<Handler>,- basic_waitable_timer<Clock, WaitTraits>, Signatures...>;-- non_const_lvalue<Handler> handler2(handler);- typename op::ptr p = { asio::detail::addressof(handler2.value),- op::ptr::allocate(handler2.value), 0 };- p.p = new (p.v) op(handler2.value,- basic_waitable_timer<Clock, WaitTraits,- typename Initiation::executor_type>(this->get_executor(), expiry),- cancel_type);-- op* o = p.p;- p.v = p.p = 0;- o->start(static_cast<Initiation&&>(*this), static_cast<Args&&>(args)...);- }-- template <typename Handler, typename Duration, typename... Args>- void operator()(Handler&& handler,- const chrono::time_point<Clock, Duration>& expiry,- cancellation_type_t cancel_type, Args&&... args) const &- {- using op = detail::timed_cancel_op<decay_t<Handler>,- basic_waitable_timer<Clock, WaitTraits>, Signatures...>;-- non_const_lvalue<Handler> handler2(handler);- typename op::ptr p = { asio::detail::addressof(handler2.value),- op::ptr::allocate(handler2.value), 0 };- p.p = new (p.v) op(handler2.value,- basic_waitable_timer<Clock, WaitTraits,- typename Initiation::executor_type>(this->get_executor(), expiry),- cancel_type);-- op* o = p.p;- p.v = p.p = 0;- o->start(static_cast<const Initiation&>(*this),- static_cast<Args&&>(args)...);- }-};--template <typename Initiation, typename Clock,- typename WaitTraits, typename Executor, typename... Signatures>-struct initiate_cancel_at_timer : initiation_base<Initiation>-{- using initiation_base<Initiation>::initiation_base;-- template <typename Handler, typename Duration, typename... Args>- void operator()(Handler&& handler,- basic_waitable_timer<Clock, WaitTraits, Executor>* timer,- const chrono::time_point<Clock, Duration>& expiry,- cancellation_type_t cancel_type, Args&&... args) &&- {- using op = detail::timed_cancel_op<decay_t<Handler>,- basic_waitable_timer<Clock, WaitTraits, Executor>&, Signatures...>;-- non_const_lvalue<Handler> handler2(handler);- typename op::ptr p = { asio::detail::addressof(handler2.value),- op::ptr::allocate(handler2.value), 0 };- timer->expires_at(expiry);- p.p = new (p.v) op(handler2.value, *timer, cancel_type);-- op* o = p.p;- p.v = p.p = 0;- o->start(static_cast<Initiation&&>(*this), static_cast<Args&&>(args)...);- }-- template <typename Handler, typename Duration, typename... Args>- void operator()(Handler&& handler,- basic_waitable_timer<Clock, WaitTraits, Executor>* timer,- const chrono::time_point<Clock, Duration>& expiry,- cancellation_type_t cancel_type, Args&&... args) const &- {- using op = detail::timed_cancel_op<decay_t<Handler>,- basic_waitable_timer<Clock, WaitTraits, Executor>&, Signatures...>;-- non_const_lvalue<Handler> handler2(handler);- typename op::ptr p = { asio::detail::addressof(handler2.value),- op::ptr::allocate(handler2.value), 0 };- timer->expires_at(expiry);- p.p = new (p.v) op(handler2.value, *timer, cancel_type);-- op* o = p.p;- p.v = p.p = 0;- o->start(static_cast<const Initiation&>(*this),- static_cast<Args&&>(args)...);- }-};--} // namespace detail--#if !defined(GENERATING_DOCUMENTATION)--template <typename CompletionToken, typename Clock,- typename WaitTraits, typename... Signatures>-struct async_result<- cancel_at_t<CompletionToken, Clock, WaitTraits>, Signatures...>- : async_result<CompletionToken, Signatures...>-{- template <typename Initiation, typename RawCompletionToken, typename... Args>- static auto initiate(Initiation&& initiation,- RawCompletionToken&& token, Args&&... args)- -> decltype(- async_initiate<- conditional_t<- is_const<remove_reference_t<RawCompletionToken>>::value,- const CompletionToken, CompletionToken>,- Signatures...>(- declval<detail::initiate_cancel_at<- decay_t<Initiation>, Clock, WaitTraits, Signatures...>>(),- token.token_, token.expiry_, token.cancel_type_,- static_cast<Args&&>(args)...))- {- return async_initiate<- conditional_t<- is_const<remove_reference_t<RawCompletionToken>>::value,- const CompletionToken, CompletionToken>,- Signatures...>(- detail::initiate_cancel_at<- decay_t<Initiation>, Clock, WaitTraits, Signatures...>(- static_cast<Initiation&&>(initiation)),- token.token_, token.expiry_, token.cancel_type_,- static_cast<Args&&>(args)...);- }-};--template <typename CompletionToken, typename Clock,- typename WaitTraits, typename Executor, typename... Signatures>-struct async_result<- cancel_at_timer<CompletionToken, Clock, WaitTraits, Executor>,- Signatures...>- : async_result<CompletionToken, Signatures...>-{- template <typename Initiation, typename RawCompletionToken, typename... Args>- static auto initiate(Initiation&& initiation,- RawCompletionToken&& token, Args&&... args)- -> decltype(- async_initiate<- conditional_t<- is_const<remove_reference_t<RawCompletionToken>>::value,- const CompletionToken, CompletionToken>,- Signatures...>(- declval<detail::initiate_cancel_at_timer<- decay_t<Initiation>, Clock, WaitTraits, Executor, Signatures...>>(),- token.token_, &token.timer_, token.expiry_, token.cancel_type_,- static_cast<Args&&>(args)...))- {- return async_initiate<- conditional_t<- is_const<remove_reference_t<RawCompletionToken>>::value,- const CompletionToken, CompletionToken>,- Signatures...>(- detail::initiate_cancel_at_timer<- decay_t<Initiation>, Clock, WaitTraits, Executor, Signatures...>(- static_cast<Initiation&&>(initiation)),- token.token_, &token.timer_, token.expiry_, token.cancel_type_,- static_cast<Args&&>(args)...);- }-};--template <typename Clock, typename WaitTraits, typename... Signatures>-struct async_result<partial_cancel_at<Clock, WaitTraits>, Signatures...>-{- template <typename Initiation, typename RawCompletionToken, typename... Args>- static auto initiate(Initiation&& initiation,- RawCompletionToken&& token, Args&&... args)- -> decltype(- async_initiate<- const cancel_at_t<- default_completion_token_t<associated_executor_t<Initiation>>,- Clock, WaitTraits>&,- Signatures...>(- static_cast<Initiation&&>(initiation),- cancel_at_t<- default_completion_token_t<associated_executor_t<Initiation>>,- Clock, WaitTraits>(- default_completion_token_t<associated_executor_t<Initiation>>{},- token.expiry_, token.cancel_type_),- static_cast<Args&&>(args)...))- {- return async_initiate<- const cancel_at_t<- default_completion_token_t<associated_executor_t<Initiation>>,- Clock, WaitTraits>&,- Signatures...>(- static_cast<Initiation&&>(initiation),- cancel_at_t<- default_completion_token_t<associated_executor_t<Initiation>>,- Clock, WaitTraits>(- default_completion_token_t<associated_executor_t<Initiation>>{},- token.expiry_, token.cancel_type_),- static_cast<Args&&>(args)...);- }-};--template <typename Clock, typename WaitTraits,- typename Executor, typename... Signatures>-struct async_result<- partial_cancel_at_timer<Clock, WaitTraits, Executor>, Signatures...>-{- template <typename Initiation, typename RawCompletionToken, typename... Args>- static auto initiate(Initiation&& initiation,- RawCompletionToken&& token, Args&&... args)- -> decltype(- async_initiate<Signatures...>(- static_cast<Initiation&&>(initiation),- cancel_at_timer<- default_completion_token_t<associated_executor_t<Initiation>>,- Clock, WaitTraits, Executor>(- default_completion_token_t<associated_executor_t<Initiation>>{},- token.timer_, token.expiry_, token.cancel_type_),- static_cast<Args&&>(args)...))- {- return async_initiate<Signatures...>(- static_cast<Initiation&&>(initiation),- cancel_at_timer<- default_completion_token_t<associated_executor_t<Initiation>>,- Clock, WaitTraits, Executor>(- default_completion_token_t<associated_executor_t<Initiation>>{},- token.timer_, token.expiry_, token.cancel_type_),- static_cast<Args&&>(args)...);- }-};--#endif // !defined(GENERATING_DOCUMENTATION)--} // namespace asio--#include "asio/detail/pop_options.hpp"--#endif // ASIO_IMPL_CANCEL_AT_HPP
link/modules/asio-standalone/asio/include/asio/impl/cancellation_signal.ipp view
@@ -2,7 +2,7 @@ // impl/cancellation_signal.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/impl/co_spawn.hpp view
@@ -2,7 +2,7 @@ // impl/co_spawn.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -18,8 +18,6 @@ #include "asio/detail/config.hpp" #include "asio/associated_cancellation_slot.hpp" #include "asio/awaitable.hpp"-#include "asio/detail/memory.hpp"-#include "asio/detail/recycling_allocator.hpp" #include "asio/dispatch.hpp" #include "asio/execution/outstanding_work.hpp" #include "asio/post.hpp"@@ -35,18 +33,18 @@ class co_spawn_work_guard { public:- typedef decay_t<- prefer_result_t<Executor,+ typedef typename decay<+ typename prefer_result<Executor, execution::outstanding_work_t::tracked_t- >- > executor_type;+ >::type+ >::type executor_type; co_spawn_work_guard(const Executor& ex) : executor_(asio::prefer(ex, execution::outstanding_work.tracked)) { } - executor_type get_executor() const noexcept+ executor_type get_executor() const ASIO_NOEXCEPT { return executor_; }@@ -59,9 +57,9 @@ template <typename Executor> struct co_spawn_work_guard<Executor,- enable_if_t<+ typename enable_if< !execution::is_executor<Executor>::value- >> : executor_work_guard<Executor>+ >::type> : executor_work_guard<Executor> { co_spawn_work_guard(const Executor& ex) : executor_work_guard<Executor>(ex)@@ -71,100 +69,49 @@ #endif // !defined(ASIO_NO_TS_EXECUTORS) -template <typename Handler, typename Executor,- typename Function, typename = void>-struct co_spawn_state-{- template <typename H, typename F>- co_spawn_state(H&& h, const Executor& ex, F&& f)- : handler(std::forward<H>(h)),- spawn_work(ex),- handler_work(asio::get_associated_executor(handler, ex)),- function(std::forward<F>(f))- {- }-- Handler handler;- co_spawn_work_guard<Executor> spawn_work;- co_spawn_work_guard<associated_executor_t<Handler, Executor>> handler_work;- Function function;-};--template <typename Handler, typename Executor, typename Function>-struct co_spawn_state<Handler, Executor, Function,- enable_if_t<- is_same<- typename associated_executor<Handler,- Executor>::asio_associated_executor_is_unspecialised,- void- >::value- >>-{- template <typename H, typename F>- co_spawn_state(H&& h, const Executor& ex, F&& f)- : handler(std::forward<H>(h)),- handler_work(ex),- function(std::forward<F>(f))- {- }-- Handler handler;- co_spawn_work_guard<Executor> handler_work;- Function function;-};--struct co_spawn_dispatch-{- template <typename CompletionToken>- auto operator()(CompletionToken&& token) const- -> decltype(asio::dispatch(std::forward<CompletionToken>(token)))- {- return asio::dispatch(std::forward<CompletionToken>(token));- }-};--struct co_spawn_post+template <typename Executor>+inline co_spawn_work_guard<Executor>+make_co_spawn_work_guard(const Executor& ex) {- template <typename CompletionToken>- auto operator()(CompletionToken&& token) const- -> decltype(asio::post(std::forward<CompletionToken>(token)))- {- return asio::post(std::forward<CompletionToken>(token));- }-};+ return co_spawn_work_guard<Executor>(ex);+} -template <typename T, typename Handler, typename Executor, typename Function>+template <typename T, typename Executor, typename F, typename Handler> awaitable<awaitable_thread_entry_point, Executor> co_spawn_entry_point(- awaitable<T, Executor>*, co_spawn_state<Handler, Executor, Function> s)+ awaitable<T, Executor>*, Executor ex, F f, Handler handler) {- (void) co_await co_spawn_dispatch{};+ auto spawn_work = make_co_spawn_work_guard(ex);+ auto handler_work = make_co_spawn_work_guard(+ asio::get_associated_executor(handler, ex)); + (void) co_await (dispatch)(+ use_awaitable_t<Executor>{__FILE__, __LINE__, "co_spawn_entry_point"});++ (co_await awaitable_thread_has_context_switched{}) = false; std::exception_ptr e = nullptr; bool done = false;-#if !defined(ASIO_NO_EXCEPTIONS) try-#endif // !defined(ASIO_NO_EXCEPTIONS) {- T t = co_await s.function();+ T t = co_await f(); done = true; - bool is_launching = (co_await awaitable_thread_is_launching{});- if (is_launching)+ bool switched = (co_await awaitable_thread_has_context_switched{});+ if (!switched) {- co_await this_coro::throw_if_cancelled(false);- (void) co_await co_spawn_post();+ (void) co_await (post)(+ use_awaitable_t<Executor>{__FILE__,+ __LINE__, "co_spawn_entry_point"}); } - (dispatch)(s.handler_work.get_executor(),- [handler = std::move(s.handler), t = std::move(t)]() mutable+ (dispatch)(handler_work.get_executor(),+ [handler = std::move(handler), t = std::move(t)]() mutable { std::move(handler)(std::exception_ptr(), std::move(t)); }); co_return; }-#if !defined(ASIO_NO_EXCEPTIONS) catch (...) { if (done)@@ -172,51 +119,52 @@ e = std::current_exception(); }-#endif // !defined(ASIO_NO_EXCEPTIONS) - bool is_launching = (co_await awaitable_thread_is_launching{});- if (is_launching)+ bool switched = (co_await awaitable_thread_has_context_switched{});+ if (!switched) {- co_await this_coro::throw_if_cancelled(false);- (void) co_await co_spawn_post();+ (void) co_await (post)(+ use_awaitable_t<Executor>{__FILE__, __LINE__, "co_spawn_entry_point"}); } - (dispatch)(s.handler_work.get_executor(),- [handler = std::move(s.handler), e]() mutable+ (dispatch)(handler_work.get_executor(),+ [handler = std::move(handler), e]() mutable { std::move(handler)(e, T()); }); } -template <typename Handler, typename Executor, typename Function>+template <typename Executor, typename F, typename Handler> awaitable<awaitable_thread_entry_point, Executor> co_spawn_entry_point(- awaitable<void, Executor>*, co_spawn_state<Handler, Executor, Function> s)+ awaitable<void, Executor>*, Executor ex, F f, Handler handler) {- (void) co_await co_spawn_dispatch{};+ auto spawn_work = make_co_spawn_work_guard(ex);+ auto handler_work = make_co_spawn_work_guard(+ asio::get_associated_executor(handler, ex)); + (void) co_await (dispatch)(+ use_awaitable_t<Executor>{__FILE__, __LINE__, "co_spawn_entry_point"});++ (co_await awaitable_thread_has_context_switched{}) = false; std::exception_ptr e = nullptr;-#if !defined(ASIO_NO_EXCEPTIONS) try-#endif // !defined(ASIO_NO_EXCEPTIONS) {- co_await s.function();+ co_await f(); }-#if !defined(ASIO_NO_EXCEPTIONS) catch (...) { e = std::current_exception(); }-#endif // !defined(ASIO_NO_EXCEPTIONS) - bool is_launching = (co_await awaitable_thread_is_launching{});- if (is_launching)+ bool switched = (co_await awaitable_thread_has_context_switched{});+ if (!switched) {- co_await this_coro::throw_if_cancelled(false);- (void) co_await co_spawn_post();+ (void) co_await (post)(+ use_awaitable_t<Executor>{__FILE__, __LINE__, "co_spawn_entry_point"}); } - (dispatch)(s.handler_work.get_executor(),- [handler = std::move(s.handler), e]() mutable+ (dispatch)(handler_work.get_executor(),+ [handler = std::move(handler), e]() mutable { std::move(handler)(e); });@@ -245,38 +193,36 @@ { public: co_spawn_cancellation_handler(const Handler&, const Executor& ex)- : signal_(detail::allocate_shared<cancellation_signal>(- detail::recycling_allocator<cancellation_signal,- detail::thread_info_base::cancellation_signal_tag>())),- ex_(ex)+ : ex_(ex) { } cancellation_slot slot() {- return signal_->slot();+ return signal_.slot(); } void operator()(cancellation_type_t type) {- shared_ptr<cancellation_signal> sig = signal_;+ cancellation_signal* sig = &signal_; asio::dispatch(ex_, [sig, type]{ sig->emit(type); }); } private:- shared_ptr<cancellation_signal> signal_;+ cancellation_signal signal_; Executor ex_; }; + template <typename Handler, typename Executor> class co_spawn_cancellation_handler<Handler, Executor,- enable_if_t<+ typename enable_if< is_same< typename associated_executor<Handler, Executor>::asio_associated_executor_is_unspecialised, void >::value- >>+ >::type> { public: co_spawn_cancellation_handler(const Handler&, const Executor&)@@ -309,7 +255,7 @@ { } - executor_type get_executor() const noexcept+ executor_type get_executor() const ASIO_NOEXCEPT { return ex_; }@@ -317,9 +263,8 @@ template <typename Handler, typename F> void operator()(Handler&& handler, F&& f) const {- typedef result_of_t<F()> awaitable_type;- typedef decay_t<Handler> handler_type;- typedef decay_t<F> function_type;+ typedef typename result_of<F()>::type awaitable_type;+ typedef typename decay<Handler>::type handler_type; typedef co_spawn_cancellation_handler< handler_type, Executor> cancel_handler_type; @@ -336,8 +281,7 @@ cancellation_state cancel_state(proxy_slot); auto a = (co_spawn_entry_point)(static_cast<awaitable_type*>(nullptr),- co_spawn_state<handler_type, Executor, function_type>(- std::forward<Handler>(handler), ex_, std::forward<F>(f)));+ ex_, std::forward<F>(f), std::forward<Handler>(handler)); awaitable_handler<executor_type, void>(std::move(a), ex_, proxy_slot, cancel_state).launch(); }@@ -355,10 +299,10 @@ CompletionToken, void(std::exception_ptr, T)) co_spawn(const Executor& ex, awaitable<T, AwaitableExecutor> a, CompletionToken&& token,- constraint_t<+ typename constraint< (is_executor<Executor>::value || execution::is_executor<Executor>::value) && is_convertible<Executor, AwaitableExecutor>::value- >)+ >::type) { return async_initiate<CompletionToken, void(std::exception_ptr, T)>( detail::initiate_co_spawn<AwaitableExecutor>(AwaitableExecutor(ex)),@@ -372,10 +316,10 @@ CompletionToken, void(std::exception_ptr)) co_spawn(const Executor& ex, awaitable<void, AwaitableExecutor> a, CompletionToken&& token,- constraint_t<+ typename constraint< (is_executor<Executor>::value || execution::is_executor<Executor>::value) && is_convertible<Executor, AwaitableExecutor>::value- >)+ >::type) { return async_initiate<CompletionToken, void(std::exception_ptr)>( detail::initiate_co_spawn<AwaitableExecutor>(AwaitableExecutor(ex)),@@ -390,11 +334,11 @@ CompletionToken, void(std::exception_ptr, T)) co_spawn(ExecutionContext& ctx, awaitable<T, AwaitableExecutor> a, CompletionToken&& token,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value && is_convertible<typename ExecutionContext::executor_type, AwaitableExecutor>::value- >)+ >::type) { return (co_spawn)(ctx.get_executor(), std::move(a), std::forward<CompletionToken>(token));@@ -407,11 +351,11 @@ CompletionToken, void(std::exception_ptr)) co_spawn(ExecutionContext& ctx, awaitable<void, AwaitableExecutor> a, CompletionToken&& token,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value && is_convertible<typename ExecutionContext::executor_type, AwaitableExecutor>::value- >)+ >::type) { return (co_spawn)(ctx.get_executor(), std::move(a), std::forward<CompletionToken>(token));@@ -419,30 +363,30 @@ template <typename Executor, typename F, ASIO_COMPLETION_TOKEN_FOR(typename detail::awaitable_signature<- result_of_t<F()>>::type) CompletionToken>+ typename result_of<F()>::type>::type) CompletionToken> inline ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken,- typename detail::awaitable_signature<result_of_t<F()>>::type)+ typename detail::awaitable_signature<typename result_of<F()>::type>::type) co_spawn(const Executor& ex, F&& f, CompletionToken&& token,- constraint_t<+ typename constraint< is_executor<Executor>::value || execution::is_executor<Executor>::value- >)+ >::type) { return async_initiate<CompletionToken,- typename detail::awaitable_signature<result_of_t<F()>>::type>(+ typename detail::awaitable_signature<typename result_of<F()>::type>::type>( detail::initiate_co_spawn<- typename result_of_t<F()>::executor_type>(ex),+ typename result_of<F()>::type::executor_type>(ex), token, std::forward<F>(f)); } template <typename ExecutionContext, typename F, ASIO_COMPLETION_TOKEN_FOR(typename detail::awaitable_signature<- result_of_t<F()>>::type) CompletionToken>+ typename result_of<F()>::type>::type) CompletionToken> inline ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken,- typename detail::awaitable_signature<result_of_t<F()>>::type)+ typename detail::awaitable_signature<typename result_of<F()>::type>::type) co_spawn(ExecutionContext& ctx, F&& f, CompletionToken&& token,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- >)+ >::type) { return (co_spawn)(ctx.get_executor(), std::forward<F>(f), std::forward<CompletionToken>(token));
− link/modules/asio-standalone/asio/include/asio/impl/config.hpp
@@ -1,102 +0,0 @@-//-// impl/config.hpp-// ~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef ASIO_IMPL_CONFIG_HPP-#define ASIO_IMPL_CONFIG_HPP--#if defined(_MSC_VER) && (_MSC_VER >= 1200)-# pragma once-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)--#include "asio/detail/config.hpp"-#include <cerrno>-#include <cstdlib>-#include <limits>-#include <stdexcept>--#include "asio/detail/push_options.hpp"--namespace asio {-namespace detail {--template <typename T>-T config_get(const config_service& service, const char* section,- const char* key_name, T default_value, false_type /*is_bool*/)-{- if (is_unsigned<T>::value)- {- char buf[std::numeric_limits<unsigned long long>::digits10- + 1 /* sign */ + 1 /* partial digit */ + 1 /* NUL */];- if (const char* str = service.get_value(- section, key_name, buf, sizeof(buf)))- {- char* end = nullptr;- errno = 0;- unsigned long long result = std::strtoull(str, &end, 0);- if (errno == ERANGE- || result > static_cast<unsigned long long>(- (std::numeric_limits<T>::max)()))- detail::throw_exception(std::out_of_range("config out of range"));- return static_cast<T>(result);- }- }- else- {- char buf[std::numeric_limits<unsigned long long>::digits10- + 1 /* sign */ + 1 /* partial digit */ + 1 /* NUL */];- if (const char* str = service.get_value(- section, key_name, buf, sizeof(buf)))- {- char* end = nullptr;- errno = 0;- long long result = std::strtoll(str, &end, 0);- if (errno == ERANGE || result < (std::numeric_limits<T>::min)()- || result > (std::numeric_limits<T>::max)())- detail::throw_exception(std::out_of_range("config out of range"));- return static_cast<T>(result);- }- }- return default_value;-}--template <typename T>-T config_get(const config_service& service, const char* section,- const char* key_name, T default_value, true_type /*is_bool*/)-{- char buf[std::numeric_limits<unsigned long long>::digits10- + 1 /* sign */ + 1 /* partial digit */ + 1 /* NUL */];- if (const char* str = service.get_value(- section, key_name, buf, sizeof(buf)))- {- char* end = nullptr;- errno = 0;- unsigned long long result = std::strtoll(str, &end, 0);- if (errno == ERANGE || (result != 0 && result != 1))- detail::throw_exception(std::out_of_range("config out of range"));- return static_cast<T>(result != 0);- }- return default_value;-}--} // namespace detail--template <typename T>-constraint_t<is_integral<T>::value, T>-config::get(const char* section, const char* key_name, T default_value) const-{- return detail::config_get(service_, section,- key_name, default_value, is_same<T, bool>());-}--} // namespace asio--#include "asio/detail/pop_options.hpp"--#endif // ASIO_IMPL_CONFIG_HPP
− link/modules/asio-standalone/asio/include/asio/impl/config.ipp
@@ -1,345 +0,0 @@-//-// impl/config.ipp-// ~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef ASIO_IMPL_CONFIG_IPP-#define ASIO_IMPL_CONFIG_IPP--#if defined(_MSC_VER) && (_MSC_VER >= 1200)-# pragma once-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)--#include "asio/config.hpp"-#include "asio/detail/concurrency_hint.hpp"-#include <cctype>-#include <cstdio>-#include <cstring>-#include <cstdlib>-#include <vector>-#include <utility>--#include "asio/detail/push_options.hpp"--namespace asio {--config_service::config_service(execution_context& ctx)- : detail::execution_context_service_base<config_service>(ctx)-{-}--void config_service::shutdown()-{-}--const char* config_service::get_value(const char* /*section*/,- const char* /*key_name*/, char* /*value*/, std::size_t /*value_len*/) const-{- return nullptr;-}--namespace detail {--class config_from_concurrency_hint_service : public config_service-{-public:- explicit config_from_concurrency_hint_service(- execution_context& ctx, int concurrency_hint)- : config_service(ctx),- concurrency_hint_(concurrency_hint)- {- }-- const char* get_value(const char* section, const char* key_name,- char* value, std::size_t value_len) const override- {- if (std::strcmp(section, "scheduler") == 0)- {- if (std::strcmp(key_name, "concurrency_hint") == 0)- {- if (ASIO_CONCURRENCY_HINT_IS_SPECIAL(concurrency_hint_))- {- return- !ASIO_CONCURRENCY_HINT_IS_LOCKING(- SCHEDULER, concurrency_hint_) ||- !ASIO_CONCURRENCY_HINT_IS_LOCKING(- REACTOR_IO, concurrency_hint_) ? "1" : "-1";- }- else- {- std::snprintf(value, value_len, "%d", concurrency_hint_);- return value;- }- }- else if (std::strcmp(key_name, "locking") == 0)- {- return ASIO_CONCURRENCY_HINT_IS_LOCKING(- SCHEDULER, concurrency_hint_) ? "1" : "0";- }- }- else if (std::strcmp(section, "reactor") == 0)- {- if (std::strcmp(key_name, "io_locking") == 0)- {- return ASIO_CONCURRENCY_HINT_IS_LOCKING(- REACTOR_IO, concurrency_hint_) ? "1" : "0";- }- else if (std::strcmp(key_name, "registration_locking") == 0)- {- return ASIO_CONCURRENCY_HINT_IS_LOCKING(- REACTOR_REGISTRATION, concurrency_hint_) ? "1" : "0";- }- }- return nullptr;- }--private:- int concurrency_hint_;-};--} // namespace detail--config_from_concurrency_hint::config_from_concurrency_hint()- : concurrency_hint_(ASIO_CONCURRENCY_HINT_DEFAULT)-{-}--void config_from_concurrency_hint::make(execution_context& ctx) const-{- (void)make_service<detail::config_from_concurrency_hint_service>(ctx,- concurrency_hint_ == 1- ? ASIO_CONCURRENCY_HINT_1 : concurrency_hint_);-}--namespace detail {--class config_from_string_service : public config_service-{-public:- config_from_string_service(execution_context& ctx,- std::string s, std::string prefix)- : config_service(ctx),- string_(static_cast<std::string&&>(s)),- prefix_(static_cast<std::string&&>(prefix))- {- enum- {- expecting_key_name,- key_name,- expecting_equals,- expecting_value,- value,- expecting_eol- } state = expecting_key_name;- std::pair<const char*, const char*> entry{};-- for (char& c : string_)- {- switch (state)- {- case expecting_key_name:- switch (c)- {- case ' ': case '\t': case '\n':- break;- case '#':- state = expecting_eol;- break;- default:- entry.first = &c;- state = key_name;- break;- }- break;- case key_name:- switch (c)- {- case ' ': case '\t':- c = 0;- state = expecting_equals;- break;- case '=':- c = 0;- state = expecting_value;- break;- case '\n':- entry.first = nullptr;- state = expecting_key_name;- break;- case '#':- entry.first = nullptr;- state = expecting_eol;- break;- default:- break;- }- break;- case expecting_equals:- switch (c)- {- case ' ': case '\t':- break;- case '=':- state = expecting_value;- break;- case '\n':- entry.first = nullptr;- state = expecting_key_name;- break;- default:- entry.first = nullptr;- state = expecting_eol;- break;- }- break;- case expecting_value:- switch (c)- {- case ' ': case '\t':- break;- case '\n':- entry.first = nullptr;- state = expecting_key_name;- break;- case '#':- entry.first = nullptr;- state = expecting_eol;- break;- default:- entry.second = &c;- state = value;- break;- }- break;- case value:- switch (c)- {- case '\n':- c = 0;- entries_.push_back(entry);- entry.first = entry.second = nullptr;- state = expecting_key_name;- break;- case '#':- c = 0;- entries_.push_back(entry);- entry.first = entry.second = nullptr;- state = expecting_eol;- break;- default:- break;- }- break;- case expecting_eol:- switch (c)- {- case '\n':- state = expecting_key_name;- break;- default:- break;- }- break;- }- }- if (entry.first && entry.second)- entries_.push_back(entry);- }-- const char* get_value(const char* section, const char* key_name,- char* /*value*/, std::size_t /*value_len*/) const override- {- std::string entry_key;- entry_key.reserve(prefix_.length() + 1- + std::strlen(section) + 1- + std::strlen(key_name) + 1);- entry_key.append(prefix_);- if (!entry_key.empty())- entry_key.append(".");- entry_key.append(section);- entry_key.append(".");- entry_key.append(key_name);- for (const std::pair<const char*, const char*>& entry : entries_)- if (entry_key == entry.first)- return entry.second;- return nullptr;- }--private:- std::string string_;- std::string prefix_;- std::vector<std::pair<const char*, const char*>> entries_;-};--} // namespace detail--void config_from_string::make(execution_context& ctx) const-{- (void)make_service<detail::config_from_string_service>(ctx, string_, prefix_);-}--namespace detail {--#if defined(ASIO_MSVC)-# pragma warning (push)-# pragma warning (disable:4996) // suppress unsafe warning for std::getenv-#endif // defined(ASIO_MSVC)--class config_from_env_service : public config_service-{-public:- explicit config_from_env_service(- execution_context& ctx, std::string prefix)- : config_service(ctx),- prefix_(static_cast<std::string&&>(prefix))- {- }-- const char* get_value(const char* section, const char* key_name,- char* /*value*/, std::size_t /*value_len*/) const override- {- std::string env_var;- env_var.reserve(prefix_.length() + 1- + std::strlen(section) + 1- + std::strlen(key_name) + 1);- env_var.append(prefix_);- if (!env_var.empty())- env_var.append("_");- env_var.append(section);- env_var.append("_");- env_var.append(key_name);- for (char& c : env_var)- c = static_cast<char>(std::toupper(static_cast<unsigned char>(c)));- return std::getenv(env_var.c_str());- }--private:- std::string prefix_;-};--#if defined(ASIO_MSVC)-# pragma warning (pop)-#endif // defined(ASIO_MSVC)--} // namespace detail--config_from_env::config_from_env()- : prefix_("asio")-{-}--void config_from_env::make(execution_context& ctx) const-{- (void)make_service<detail::config_from_env_service>(ctx, prefix_);-}--} // namespace asio--#include "asio/detail/pop_options.hpp"--#endif // ASIO_IMPL_CONFIG_IPP
link/modules/asio-standalone/asio/include/asio/impl/connect.hpp view
@@ -2,7 +2,7 @@ // impl/connect.hpp // ~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -19,7 +19,9 @@ #include "asio/associator.hpp" #include "asio/detail/base_from_cancellation_state.hpp" #include "asio/detail/bind_handler.hpp"+#include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_cont_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_tracking.hpp" #include "asio/detail/handler_type_requirements.hpp" #include "asio/detail/non_const_lvalue.hpp"@@ -34,6 +36,15 @@ namespace detail {+ struct default_connect_condition+ {+ template <typename Endpoint>+ bool operator()(const asio::error_code&, const Endpoint&)+ {+ return true;+ }+ };+ template <typename Protocol, typename Iterator> inline typename Protocol::endpoint deref_connect_result( Iterator iter, asio::error_code& ec)@@ -41,15 +52,38 @@ return ec ? typename Protocol::endpoint() : *iter; } + template <typename T, typename Iterator>+ struct legacy_connect_condition_helper : T+ {+ typedef char (*fallback_func_type)(...);+ operator fallback_func_type() const;+ };++ template <typename R, typename Arg1, typename Arg2, typename Iterator>+ struct legacy_connect_condition_helper<R (*)(Arg1, Arg2), Iterator>+ {+ R operator()(Arg1, Arg2) const;+ char operator()(...) const;+ };++ template <typename T, typename Iterator>+ struct is_legacy_connect_condition+ {+ static char asio_connect_condition_check(char);+ static char (&asio_connect_condition_check(Iterator))[2];++ static const bool value =+ sizeof(asio_connect_condition_check(+ (declval<legacy_connect_condition_helper<T, Iterator> >())(+ declval<const asio::error_code>(),+ declval<const Iterator>()))) != 1;+ };+ template <typename ConnectCondition, typename Iterator> inline Iterator call_connect_condition(ConnectCondition& connect_condition, const asio::error_code& ec, Iterator next, Iterator end,- constraint_t<- is_same<- result_of_t<ConnectCondition(asio::error_code, Iterator)>,- Iterator- >::value- > = 0)+ typename enable_if<is_legacy_connect_condition<+ ConnectCondition, Iterator>::value>::type* = 0) { if (next != end) return connect_condition(ec, next);@@ -59,27 +93,21 @@ template <typename ConnectCondition, typename Iterator> inline Iterator call_connect_condition(ConnectCondition& connect_condition, const asio::error_code& ec, Iterator next, Iterator end,- constraint_t<- is_same<- result_of_t<ConnectCondition(asio::error_code,- decltype(*declval<Iterator>()))>,- bool- >::value- > = 0)+ typename enable_if<!is_legacy_connect_condition<+ ConnectCondition, Iterator>::value>::type* = 0) { for (;next != end; ++next) if (connect_condition(ec, *next)) return next; return end; }-} // namespace detail+} template <typename Protocol, typename Executor, typename EndpointSequence> typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s, const EndpointSequence& endpoints,- constraint_t<- is_endpoint_sequence<EndpointSequence>::value- >)+ typename constraint<is_endpoint_sequence<+ EndpointSequence>::value>::type) { asio::error_code ec; typename Protocol::endpoint result = connect(s, endpoints, ec);@@ -90,16 +118,35 @@ template <typename Protocol, typename Executor, typename EndpointSequence> typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s, const EndpointSequence& endpoints, asio::error_code& ec,- constraint_t<- is_endpoint_sequence<EndpointSequence>::value- >)+ typename constraint<is_endpoint_sequence<+ EndpointSequence>::value>::type) { return detail::deref_connect_result<Protocol>( connect(s, endpoints.begin(), endpoints.end(), detail::default_connect_condition(), ec), ec); } +#if !defined(ASIO_NO_DEPRECATED) template <typename Protocol, typename Executor, typename Iterator>+Iterator connect(basic_socket<Protocol, Executor>& s, Iterator begin,+ typename constraint<!is_endpoint_sequence<Iterator>::value>::type)+{+ asio::error_code ec;+ Iterator result = connect(s, begin, ec);+ asio::detail::throw_error(ec, "connect");+ return result;+}++template <typename Protocol, typename Executor, typename Iterator>+inline Iterator connect(basic_socket<Protocol, Executor>& s,+ Iterator begin, asio::error_code& ec,+ typename constraint<!is_endpoint_sequence<Iterator>::value>::type)+{+ return connect(s, begin, Iterator(), detail::default_connect_condition(), ec);+}+#endif // !defined(ASIO_NO_DEPRECATED)++template <typename Protocol, typename Executor, typename Iterator> Iterator connect(basic_socket<Protocol, Executor>& s, Iterator begin, Iterator end) {@@ -120,13 +167,8 @@ typename EndpointSequence, typename ConnectCondition> typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s, const EndpointSequence& endpoints, ConnectCondition connect_condition,- constraint_t<- is_endpoint_sequence<EndpointSequence>::value- >,- constraint_t<- is_connect_condition<ConnectCondition,- decltype(declval<const EndpointSequence&>().begin())>::value- >)+ typename constraint<is_endpoint_sequence<+ EndpointSequence>::value>::type) { asio::error_code ec; typename Protocol::endpoint result = connect(@@ -140,26 +182,42 @@ typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s, const EndpointSequence& endpoints, ConnectCondition connect_condition, asio::error_code& ec,- constraint_t<- is_endpoint_sequence<EndpointSequence>::value- >,- constraint_t<- is_connect_condition<ConnectCondition,- decltype(declval<const EndpointSequence&>().begin())>::value- >)+ typename constraint<is_endpoint_sequence<+ EndpointSequence>::value>::type) { return detail::deref_connect_result<Protocol>( connect(s, endpoints.begin(), endpoints.end(), connect_condition, ec), ec); } +#if !defined(ASIO_NO_DEPRECATED) template <typename Protocol, typename Executor, typename Iterator, typename ConnectCondition>+Iterator connect(basic_socket<Protocol, Executor>& s,+ Iterator begin, ConnectCondition connect_condition,+ typename constraint<!is_endpoint_sequence<Iterator>::value>::type)+{+ asio::error_code ec;+ Iterator result = connect(s, begin, connect_condition, ec);+ asio::detail::throw_error(ec, "connect");+ return result;+}++template <typename Protocol, typename Executor,+ typename Iterator, typename ConnectCondition>+inline Iterator connect(basic_socket<Protocol, Executor>& s,+ Iterator begin, ConnectCondition connect_condition,+ asio::error_code& ec,+ typename constraint<!is_endpoint_sequence<Iterator>::value>::type)+{+ return connect(s, begin, Iterator(), connect_condition, ec);+}+#endif // !defined(ASIO_NO_DEPRECATED)++template <typename Protocol, typename Executor,+ typename Iterator, typename ConnectCondition> Iterator connect(basic_socket<Protocol, Executor>& s, Iterator begin,- Iterator end, ConnectCondition connect_condition,- constraint_t<- is_connect_condition<ConnectCondition, Iterator>::value- >)+ Iterator end, ConnectCondition connect_condition) { asio::error_code ec; Iterator result = connect(s, begin, end, connect_condition, ec);@@ -171,10 +229,7 @@ typename Iterator, typename ConnectCondition> Iterator connect(basic_socket<Protocol, Executor>& s, Iterator begin, Iterator end, ConnectCondition connect_condition,- asio::error_code& ec,- constraint_t<- is_connect_condition<ConnectCondition, Iterator>::value- >)+ asio::error_code& ec) { ec = asio::error_code(); @@ -256,10 +311,11 @@ endpoints_(endpoints), index_(0), start_(0),- handler_(static_cast<RangeConnectHandler&&>(handler))+ handler_(ASIO_MOVE_CAST(RangeConnectHandler)(handler)) { } +#if defined(ASIO_HAS_MOVE) range_connect_op(const range_connect_op& other) : base_from_cancellation_state<RangeConnectHandler>(other), base_from_connect_condition<ConnectCondition>(other),@@ -273,16 +329,17 @@ range_connect_op(range_connect_op&& other) : base_from_cancellation_state<RangeConnectHandler>(- static_cast<base_from_cancellation_state<RangeConnectHandler>&&>(- other)),+ ASIO_MOVE_CAST(base_from_cancellation_state<+ RangeConnectHandler>)(other)), base_from_connect_condition<ConnectCondition>(other), socket_(other.socket_), endpoints_(other.endpoints_), index_(other.index_), start_(other.start_),- handler_(static_cast<RangeConnectHandler&&>(other.handler_))+ handler_(ASIO_MOVE_CAST(RangeConnectHandler)(other.handler_)) { }+#endif // defined(ASIO_HAS_MOVE) void operator()(asio::error_code ec, int start = 0) {@@ -312,7 +369,7 @@ socket_.close(ec); ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_connect")); socket_.async_connect(*iter,- static_cast<range_connect_op&&>(*this));+ ASIO_MOVE_CAST(range_connect_op)(*this)); return; } @@ -322,7 +379,7 @@ ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_connect")); asio::post(socket_.get_executor(), detail::bind_handler(- static_cast<range_connect_op&&>(*this), ec));+ ASIO_MOVE_CAST(range_connect_op)(*this), ec)); return; } @@ -350,7 +407,7 @@ ++index_; } - static_cast<RangeConnectHandler&&>(handler_)(+ ASIO_MOVE_OR_LVALUE(RangeConnectHandler)(handler_)( static_cast<const asio::error_code&>(ec), static_cast<const typename Protocol::endpoint&>( ec || iter == end ? typename Protocol::endpoint() : *iter));@@ -366,6 +423,36 @@ template <typename Protocol, typename Executor, typename EndpointSequence, typename ConnectCondition, typename RangeConnectHandler>+ inline asio_handler_allocate_is_deprecated+ asio_handler_allocate(std::size_t size,+ range_connect_op<Protocol, Executor, EndpointSequence,+ ConnectCondition, RangeConnectHandler>* this_handler)+ {+#if defined(ASIO_NO_DEPRECATED)+ asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+ return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+ return asio_handler_alloc_helpers::allocate(+ size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename Protocol, typename Executor, typename EndpointSequence,+ typename ConnectCondition, typename RangeConnectHandler>+ inline asio_handler_deallocate_is_deprecated+ asio_handler_deallocate(void* pointer, std::size_t size,+ range_connect_op<Protocol, Executor, EndpointSequence,+ ConnectCondition, RangeConnectHandler>* this_handler)+ {+ asio_handler_alloc_helpers::deallocate(+ pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename Protocol, typename Executor, typename EndpointSequence,+ typename ConnectCondition, typename RangeConnectHandler> inline bool asio_handler_is_continuation( range_connect_op<Protocol, Executor, EndpointSequence, ConnectCondition, RangeConnectHandler>* this_handler)@@ -374,6 +461,36 @@ this_handler->handler_); } + template <typename Function, typename Executor, typename Protocol,+ typename EndpointSequence, typename ConnectCondition,+ typename RangeConnectHandler>+ inline asio_handler_invoke_is_deprecated+ asio_handler_invoke(Function& function,+ range_connect_op<Protocol, Executor, EndpointSequence,+ ConnectCondition, RangeConnectHandler>* this_handler)+ {+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename Function, typename Executor, typename Protocol,+ typename EndpointSequence, typename ConnectCondition,+ typename RangeConnectHandler>+ inline asio_handler_invoke_is_deprecated+ asio_handler_invoke(const Function& function,+ range_connect_op<Protocol, Executor, EndpointSequence,+ ConnectCondition, RangeConnectHandler>* this_handler)+ {+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }+ template <typename Protocol, typename Executor> class initiate_async_range_connect {@@ -385,14 +502,14 @@ { } - executor_type get_executor() const noexcept+ executor_type get_executor() const ASIO_NOEXCEPT { return socket_.get_executor(); } template <typename RangeConnectHandler, typename EndpointSequence, typename ConnectCondition>- void operator()(RangeConnectHandler&& handler,+ void operator()(ASIO_MOVE_ARG(RangeConnectHandler) handler, const EndpointSequence& endpoints, const ConnectCondition& connect_condition) const {@@ -404,7 +521,7 @@ non_const_lvalue<RangeConnectHandler> handler2(handler); range_connect_op<Protocol, Executor, EndpointSequence, ConnectCondition,- decay_t<RangeConnectHandler>>(socket_, endpoints,+ typename decay<RangeConnectHandler>::type>(socket_, endpoints, connect_condition, handler2.value)(asio::error_code(), 1); } @@ -430,10 +547,11 @@ iter_(begin), end_(end), start_(0),- handler_(static_cast<IteratorConnectHandler&&>(handler))+ handler_(ASIO_MOVE_CAST(IteratorConnectHandler)(handler)) { } +#if defined(ASIO_HAS_MOVE) iterator_connect_op(const iterator_connect_op& other) : base_from_cancellation_state<IteratorConnectHandler>(other), base_from_connect_condition<ConnectCondition>(other),@@ -447,16 +565,17 @@ iterator_connect_op(iterator_connect_op&& other) : base_from_cancellation_state<IteratorConnectHandler>(- static_cast<base_from_cancellation_state<IteratorConnectHandler>&&>(- other)),+ ASIO_MOVE_CAST(base_from_cancellation_state<+ IteratorConnectHandler>)(other)), base_from_connect_condition<ConnectCondition>(other), socket_(other.socket_), iter_(other.iter_), end_(other.end_), start_(other.start_),- handler_(static_cast<IteratorConnectHandler&&>(other.handler_))+ handler_(ASIO_MOVE_CAST(IteratorConnectHandler)(other.handler_)) { }+#endif // defined(ASIO_HAS_MOVE) void operator()(asio::error_code ec, int start = 0) {@@ -472,7 +591,7 @@ socket_.close(ec); ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_connect")); socket_.async_connect(*iter_,- static_cast<iterator_connect_op&&>(*this));+ ASIO_MOVE_CAST(iterator_connect_op)(*this)); return; } @@ -482,7 +601,7 @@ ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_connect")); asio::post(socket_.get_executor(), detail::bind_handler(- static_cast<iterator_connect_op&&>(*this), ec));+ ASIO_MOVE_CAST(iterator_connect_op)(*this), ec)); return; } @@ -509,7 +628,7 @@ ++iter_; } - static_cast<IteratorConnectHandler&&>(handler_)(+ ASIO_MOVE_OR_LVALUE(IteratorConnectHandler)(handler_)( static_cast<const asio::error_code&>(ec), static_cast<const Iterator&>(iter_)); }@@ -525,6 +644,36 @@ template <typename Protocol, typename Executor, typename Iterator, typename ConnectCondition, typename IteratorConnectHandler>+ inline asio_handler_allocate_is_deprecated+ asio_handler_allocate(std::size_t size,+ iterator_connect_op<Protocol, Executor, Iterator,+ ConnectCondition, IteratorConnectHandler>* this_handler)+ {+#if defined(ASIO_NO_DEPRECATED)+ asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+ return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+ return asio_handler_alloc_helpers::allocate(+ size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename Protocol, typename Executor, typename Iterator,+ typename ConnectCondition, typename IteratorConnectHandler>+ inline asio_handler_deallocate_is_deprecated+ asio_handler_deallocate(void* pointer, std::size_t size,+ iterator_connect_op<Protocol, Executor, Iterator,+ ConnectCondition, IteratorConnectHandler>* this_handler)+ {+ asio_handler_alloc_helpers::deallocate(+ pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename Protocol, typename Executor, typename Iterator,+ typename ConnectCondition, typename IteratorConnectHandler> inline bool asio_handler_is_continuation( iterator_connect_op<Protocol, Executor, Iterator, ConnectCondition, IteratorConnectHandler>* this_handler)@@ -533,6 +682,36 @@ this_handler->handler_); } + template <typename Function, typename Executor, typename Protocol,+ typename Iterator, typename ConnectCondition,+ typename IteratorConnectHandler>+ inline asio_handler_invoke_is_deprecated+ asio_handler_invoke(Function& function,+ iterator_connect_op<Protocol, Executor, Iterator,+ ConnectCondition, IteratorConnectHandler>* this_handler)+ {+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename Function, typename Executor, typename Protocol,+ typename Iterator, typename ConnectCondition,+ typename IteratorConnectHandler>+ inline asio_handler_invoke_is_deprecated+ asio_handler_invoke(const Function& function,+ iterator_connect_op<Protocol, Executor, Iterator,+ ConnectCondition, IteratorConnectHandler>* this_handler)+ {+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }+ template <typename Protocol, typename Executor> class initiate_async_iterator_connect {@@ -545,14 +724,14 @@ { } - executor_type get_executor() const noexcept+ executor_type get_executor() const ASIO_NOEXCEPT { return socket_.get_executor(); } template <typename IteratorConnectHandler, typename Iterator, typename ConnectCondition>- void operator()(IteratorConnectHandler&& handler,+ void operator()(ASIO_MOVE_ARG(IteratorConnectHandler) handler, Iterator begin, Iterator end, const ConnectCondition& connect_condition) const {@@ -564,7 +743,7 @@ non_const_lvalue<IteratorConnectHandler> handler2(handler); iterator_connect_op<Protocol, Executor, Iterator, ConnectCondition,- decay_t<IteratorConnectHandler>>(socket_, begin, end,+ typename decay<IteratorConnectHandler>::type>(socket_, begin, end, connect_condition, handler2.value)(asio::error_code(), 1); } @@ -585,20 +764,21 @@ DefaultCandidate> : Associator<RangeConnectHandler, DefaultCandidate> {- static typename Associator<RangeConnectHandler, DefaultCandidate>::type get(- const detail::range_connect_op<Protocol, Executor, EndpointSequence,- ConnectCondition, RangeConnectHandler>& h) noexcept+ static typename Associator<RangeConnectHandler, DefaultCandidate>::type+ get(const detail::range_connect_op<Protocol, Executor, EndpointSequence,+ ConnectCondition, RangeConnectHandler>& h) ASIO_NOEXCEPT { return Associator<RangeConnectHandler, DefaultCandidate>::get(h.handler_); } - static auto get(- const detail::range_connect_op<Protocol, Executor,+ static ASIO_AUTO_RETURN_TYPE_PREFIX2(+ typename Associator<RangeConnectHandler, DefaultCandidate>::type)+ get(const detail::range_connect_op<Protocol, Executor, EndpointSequence, ConnectCondition, RangeConnectHandler>& h,- const DefaultCandidate& c) noexcept- -> decltype(+ const DefaultCandidate& c) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX(( Associator<RangeConnectHandler, DefaultCandidate>::get(- h.handler_, c))+ h.handler_, c))) { return Associator<RangeConnectHandler, DefaultCandidate>::get( h.handler_, c);@@ -617,19 +797,20 @@ { static typename Associator<IteratorConnectHandler, DefaultCandidate>::type get(const detail::iterator_connect_op<Protocol, Executor, Iterator,- ConnectCondition, IteratorConnectHandler>& h) noexcept+ ConnectCondition, IteratorConnectHandler>& h) ASIO_NOEXCEPT { return Associator<IteratorConnectHandler, DefaultCandidate>::get( h.handler_); } - static auto get(- const detail::iterator_connect_op<Protocol, Executor,+ static ASIO_AUTO_RETURN_TYPE_PREFIX2(+ typename Associator<IteratorConnectHandler, DefaultCandidate>::type)+ get(const detail::iterator_connect_op<Protocol, Executor, Iterator, ConnectCondition, IteratorConnectHandler>& h,- const DefaultCandidate& c) noexcept- -> decltype(+ const DefaultCandidate& c) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX(( Associator<IteratorConnectHandler, DefaultCandidate>::get(- h.handler_, c))+ h.handler_, c))) { return Associator<IteratorConnectHandler, DefaultCandidate>::get( h.handler_, c);@@ -637,6 +818,139 @@ }; #endif // !defined(GENERATING_DOCUMENTATION)++template <typename Protocol, typename Executor, typename EndpointSequence,+ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+ typename Protocol::endpoint)) RangeConnectToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(RangeConnectToken,+ void (asio::error_code, typename Protocol::endpoint))+async_connect(basic_socket<Protocol, Executor>& s,+ const EndpointSequence& endpoints,+ ASIO_MOVE_ARG(RangeConnectToken) token,+ typename constraint<is_endpoint_sequence<+ EndpointSequence>::value>::type)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_initiate<RangeConnectToken,+ void (asio::error_code, typename Protocol::endpoint)>(+ declval<detail::initiate_async_range_connect<Protocol, Executor> >(),+ token, endpoints, declval<detail::default_connect_condition>())))+{+ return async_initiate<RangeConnectToken,+ void (asio::error_code, typename Protocol::endpoint)>(+ detail::initiate_async_range_connect<Protocol, Executor>(s),+ token, endpoints, detail::default_connect_condition());+}++#if !defined(ASIO_NO_DEPRECATED)+template <typename Protocol, typename Executor, typename Iterator,+ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+ Iterator)) IteratorConnectToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(IteratorConnectToken,+ void (asio::error_code, Iterator))+async_connect(basic_socket<Protocol, Executor>& s, Iterator begin,+ ASIO_MOVE_ARG(IteratorConnectToken) token,+ typename constraint<!is_endpoint_sequence<Iterator>::value>::type)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_initiate<IteratorConnectToken,+ void (asio::error_code, Iterator)>(+ declval<detail::initiate_async_iterator_connect<Protocol, Executor> >(),+ token, begin, Iterator(),+ declval<detail::default_connect_condition>())))+{+ return async_initiate<IteratorConnectToken,+ void (asio::error_code, Iterator)>(+ detail::initiate_async_iterator_connect<Protocol, Executor>(s),+ token, begin, Iterator(),+ detail::default_connect_condition());+}+#endif // !defined(ASIO_NO_DEPRECATED)++template <typename Protocol, typename Executor, typename Iterator,+ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+ Iterator)) IteratorConnectToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(IteratorConnectToken,+ void (asio::error_code, Iterator))+async_connect(basic_socket<Protocol, Executor>& s, Iterator begin, Iterator end,+ ASIO_MOVE_ARG(IteratorConnectToken) token)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_initiate<IteratorConnectToken,+ void (asio::error_code, Iterator)>(+ declval<detail::initiate_async_iterator_connect<Protocol, Executor> >(),+ token, begin, end, declval<detail::default_connect_condition>())))+{+ return async_initiate<IteratorConnectToken,+ void (asio::error_code, Iterator)>(+ detail::initiate_async_iterator_connect<Protocol, Executor>(s),+ token, begin, end, detail::default_connect_condition());+}++template <typename Protocol, typename Executor,+ typename EndpointSequence, typename ConnectCondition,+ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+ typename Protocol::endpoint)) RangeConnectToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(RangeConnectToken,+ void (asio::error_code, typename Protocol::endpoint))+async_connect(basic_socket<Protocol, Executor>& s,+ const EndpointSequence& endpoints, ConnectCondition connect_condition,+ ASIO_MOVE_ARG(RangeConnectToken) token,+ typename constraint<is_endpoint_sequence<+ EndpointSequence>::value>::type)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_initiate<RangeConnectToken,+ void (asio::error_code, typename Protocol::endpoint)>(+ declval<detail::initiate_async_range_connect<Protocol, Executor> >(),+ token, endpoints, connect_condition)))+{+ return async_initiate<RangeConnectToken,+ void (asio::error_code, typename Protocol::endpoint)>(+ detail::initiate_async_range_connect<Protocol, Executor>(s),+ token, endpoints, connect_condition);+}++#if !defined(ASIO_NO_DEPRECATED)+template <typename Protocol, typename Executor,+ typename Iterator, typename ConnectCondition,+ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+ Iterator)) IteratorConnectToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(IteratorConnectToken,+ void (asio::error_code, Iterator))+async_connect(basic_socket<Protocol, Executor>& s, Iterator begin,+ ConnectCondition connect_condition,+ ASIO_MOVE_ARG(IteratorConnectToken) token,+ typename constraint<!is_endpoint_sequence<Iterator>::value>::type)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_initiate<IteratorConnectToken,+ void (asio::error_code, Iterator)>(+ declval<detail::initiate_async_iterator_connect<Protocol, Executor> >(),+ token, begin, Iterator(), connect_condition)))+{+ return async_initiate<IteratorConnectToken,+ void (asio::error_code, Iterator)>(+ detail::initiate_async_iterator_connect<Protocol, Executor>(s),+ token, begin, Iterator(), connect_condition);+}+#endif // !defined(ASIO_NO_DEPRECATED)++template <typename Protocol, typename Executor,+ typename Iterator, typename ConnectCondition,+ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+ Iterator)) IteratorConnectToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(IteratorConnectToken,+ void (asio::error_code, Iterator))+async_connect(basic_socket<Protocol, Executor>& s, Iterator begin,+ Iterator end, ConnectCondition connect_condition,+ ASIO_MOVE_ARG(IteratorConnectToken) token)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_initiate<IteratorConnectToken,+ void (asio::error_code, Iterator)>(+ declval<detail::initiate_async_iterator_connect<Protocol, Executor> >(),+ token, begin, end, connect_condition)))+{+ return async_initiate<IteratorConnectToken,+ void (asio::error_code, Iterator)>(+ detail::initiate_async_iterator_connect<Protocol, Executor>(s),+ token, begin, end, connect_condition);+} } // namespace asio
link/modules/asio-standalone/asio/include/asio/impl/connect_pipe.hpp view
@@ -2,7 +2,7 @@ // impl/connect_pipe.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/impl/connect_pipe.ipp view
@@ -2,7 +2,7 @@ // impl/connect_pipe.ipp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2021 Klemens D. Morgenstern // (klemens dot morgenstern at gmx dot net) //@@ -62,9 +62,8 @@ _snwprintf( #endif // defined(ASIO_HAS_SECURE_RTL) pipe_name, 128,- // Include address of static to discriminate asio instances in DLLs.- L"\\\\.\\pipe\\asio-A0812896-741A-484D-AF23-BE51BF620E22-%u-%p-%ld-%ld",- static_cast<unsigned int>(::GetCurrentProcessId()), &counter1, n1, n2);+ L"\\\\.\\pipe\\asio-A0812896-741A-484D-AF23-BE51BF620E22-%u-%ld-%ld",+ static_cast<unsigned int>(::GetCurrentProcessId()), n1, n2); p[0] = ::CreateNamedPipeW(pipe_name, PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED,
link/modules/asio-standalone/asio/include/asio/impl/consign.hpp view
@@ -2,7 +2,7 @@ // impl/consign.hpp // ~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -16,12 +16,15 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"+ #include "asio/associator.hpp" #include "asio/async_result.hpp"+#include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_cont_helpers.hpp"-#include "asio/detail/initiation_base.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/type_traits.hpp" #include "asio/detail/utility.hpp"+#include "asio/detail/variadic_templates.hpp" #include "asio/detail/push_options.hpp" @@ -36,16 +39,17 @@ typedef void result_type; template <typename H>- consign_handler(H&& handler, std::tuple<Values...> values)- : handler_(static_cast<H&&>(handler)),- values_(static_cast<std::tuple<Values...>&&>(values))+ consign_handler(ASIO_MOVE_ARG(H) handler, std::tuple<Values...> values)+ : handler_(ASIO_MOVE_CAST(H)(handler)),+ values_(ASIO_MOVE_CAST(std::tuple<Values...>)(values)) { } template <typename... Args>- void operator()(Args&&... args)+ void operator()(ASIO_MOVE_ARG(Args)... args) {- static_cast<Handler&&>(handler_)(static_cast<Args&&>(args)...);+ ASIO_MOVE_OR_LVALUE(Handler)(handler_)(+ ASIO_MOVE_CAST(Args)(args)...); } //private:@@ -54,6 +58,32 @@ }; template <typename Handler>+inline asio_handler_allocate_is_deprecated+asio_handler_allocate(std::size_t size,+ consign_handler<Handler>* this_handler)+{+#if defined(ASIO_NO_DEPRECATED)+ asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+ return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+ return asio_handler_alloc_helpers::allocate(+ size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler>+inline asio_handler_deallocate_is_deprecated+asio_handler_deallocate(void* pointer, std::size_t size,+ consign_handler<Handler>* this_handler)+{+ asio_handler_alloc_helpers::deallocate(+ pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler> inline bool asio_handler_is_continuation( consign_handler<Handler>* this_handler) {@@ -61,57 +91,82 @@ this_handler->handler_); } +template <typename Function, typename Handler>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(Function& function,+ consign_handler<Handler>* this_handler)+{+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Function, typename Handler>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(const Function& function,+ consign_handler<Handler>* this_handler)+{+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}+ } // namespace detail #if !defined(GENERATING_DOCUMENTATION) template <typename CompletionToken, typename... Values, typename... Signatures>-struct async_result<consign_t<CompletionToken, Values...>, Signatures...>+struct async_result<+ consign_t<CompletionToken, Values...>, Signatures...> : async_result<CompletionToken, Signatures...> { template <typename Initiation>- struct init_wrapper : detail::initiation_base<Initiation>+ struct init_wrapper {- using detail::initiation_base<Initiation>::initiation_base;-- template <typename Handler, typename... Args>- void operator()(Handler&& handler,- std::tuple<Values...> values, Args&&... args) &&+ init_wrapper(Initiation init)+ : initiation_(ASIO_MOVE_CAST(Initiation)(init)) {- static_cast<Initiation&&>(*this)(- detail::consign_handler<decay_t<Handler>, Values...>(- static_cast<Handler&&>(handler),- static_cast<std::tuple<Values...>&&>(values)),- static_cast<Args&&>(args)...); } template <typename Handler, typename... Args>- void operator()(Handler&& handler,- std::tuple<Values...> values, Args&&... args) const &+ void operator()(+ ASIO_MOVE_ARG(Handler) handler,+ std::tuple<Values...> values,+ ASIO_MOVE_ARG(Args)... args) {- static_cast<const Initiation&>(*this)(- detail::consign_handler<decay_t<Handler>, Values...>(- static_cast<Handler&&>(handler),- static_cast<std::tuple<Values...>&&>(values)),- static_cast<Args&&>(args)...);+ ASIO_MOVE_CAST(Initiation)(initiation_)(+ detail::consign_handler<+ typename decay<Handler>::type, Values...>(+ ASIO_MOVE_CAST(Handler)(handler),+ ASIO_MOVE_CAST(std::tuple<Values...>)(values)),+ ASIO_MOVE_CAST(Args)(args)...); }++ Initiation initiation_; }; template <typename Initiation, typename RawCompletionToken, typename... Args>- static auto initiate(Initiation&& initiation,- RawCompletionToken&& token, Args&&... args)- -> decltype(- async_initiate<CompletionToken, Signatures...>(- init_wrapper<decay_t<Initiation>>(- static_cast<Initiation&&>(initiation)),- token.token_, static_cast<std::tuple<Values...>&&>(token.values_),- static_cast<Args&&>(args)...))+ static ASIO_INITFN_DEDUCED_RESULT_TYPE(CompletionToken, Signatures...,+ (async_initiate<CompletionToken, Signatures...>(+ declval<init_wrapper<typename decay<Initiation>::type> >(),+ declval<CompletionToken&>(),+ declval<std::tuple<Values...> >(),+ declval<ASIO_MOVE_ARG(Args)>()...)))+ initiate(+ ASIO_MOVE_ARG(Initiation) initiation,+ ASIO_MOVE_ARG(RawCompletionToken) token,+ ASIO_MOVE_ARG(Args)... args) { return async_initiate<CompletionToken, Signatures...>(- init_wrapper<decay_t<Initiation>>(- static_cast<Initiation&&>(initiation)),- token.token_, static_cast<std::tuple<Values...>&&>(token.values_),- static_cast<Args&&>(args)...);+ init_wrapper<typename decay<Initiation>::type>(+ ASIO_MOVE_CAST(Initiation)(initiation)),+ token.token_,+ ASIO_MOVE_CAST(std::tuple<Values...>)(token.values_),+ ASIO_MOVE_CAST(Args)(args)...); } }; @@ -121,15 +176,18 @@ detail::consign_handler<Handler, Values...>, DefaultCandidate> : Associator<Handler, DefaultCandidate> {- static typename Associator<Handler, DefaultCandidate>::type get(- const detail::consign_handler<Handler, Values...>& h) noexcept+ static typename Associator<Handler, DefaultCandidate>::type+ get(const detail::consign_handler<Handler, Values...>& h) ASIO_NOEXCEPT { return Associator<Handler, DefaultCandidate>::get(h.handler_); } - static auto get(const detail::consign_handler<Handler, Values...>& h,- const DefaultCandidate& c) noexcept- -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))+ static ASIO_AUTO_RETURN_TYPE_PREFIX2(+ typename Associator<Handler, DefaultCandidate>::type)+ get(const detail::consign_handler<Handler, Values...>& h,+ const DefaultCandidate& c) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ Associator<Handler, DefaultCandidate>::get(h.handler_, c))) { return Associator<Handler, DefaultCandidate>::get(h.handler_, c); }
link/modules/asio-standalone/asio/include/asio/impl/deferred.hpp view
@@ -2,7 +2,7 @@ // impl/deferred.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -27,13 +27,15 @@ public: template <typename Initiation, typename... InitArgs> static deferred_async_operation<Signature, Initiation, InitArgs...>- initiate(Initiation&& initiation, deferred_t, InitArgs&&... args)+ initiate(ASIO_MOVE_ARG(Initiation) initiation,+ deferred_t, ASIO_MOVE_ARG(InitArgs)... args) {- return deferred_async_operation<Signature, Initiation, InitArgs...>(- deferred_init_tag{},- static_cast<Initiation&&>(initiation),- static_cast<InitArgs&&>(args)...);- }+ return deferred_async_operation<+ Signature, Initiation, InitArgs...>(+ deferred_init_tag{},+ ASIO_MOVE_CAST(Initiation)(initiation),+ ASIO_MOVE_CAST(InitArgs)(args)...);+ } }; template <typename... Signatures>@@ -43,14 +45,15 @@ template <typename Initiation, typename... InitArgs> static deferred_async_operation< deferred_signatures<Signatures...>, Initiation, InitArgs...>- initiate(Initiation&& initiation, deferred_t, InitArgs&&... args)+ initiate(ASIO_MOVE_ARG(Initiation) initiation,+ deferred_t, ASIO_MOVE_ARG(InitArgs)... args) { return deferred_async_operation< deferred_signatures<Signatures...>, Initiation, InitArgs...>( deferred_init_tag{},- static_cast<Initiation&&>(initiation),- static_cast<InitArgs&&>(args)...);- }+ ASIO_MOVE_CAST(Initiation)(initiation),+ ASIO_MOVE_CAST(InitArgs)(args)...);+ } }; template <typename Function, typename Signature>@@ -58,8 +61,9 @@ { public: template <typename Initiation, typename... InitArgs>- static auto initiate(Initiation&& initiation,- deferred_function<Function> token, InitArgs&&... init_args)+ static auto initiate(ASIO_MOVE_ARG(Initiation) initiation,+ deferred_function<Function> token,+ ASIO_MOVE_ARG(InitArgs)... init_args) -> decltype( deferred_sequence< deferred_async_operation<@@ -68,9 +72,9 @@ deferred_async_operation< Signature, Initiation, InitArgs...>( deferred_init_tag{},- static_cast<Initiation&&>(initiation),- static_cast<InitArgs&&>(init_args)...),- static_cast<Function&&>(token.function_)))+ ASIO_MOVE_CAST(Initiation)(initiation),+ ASIO_MOVE_CAST(InitArgs)(init_args)...),+ ASIO_MOVE_CAST(Function)(token.function_))) { return deferred_sequence< deferred_async_operation<@@ -79,9 +83,9 @@ deferred_async_operation< Signature, Initiation, InitArgs...>( deferred_init_tag{},- static_cast<Initiation&&>(initiation),- static_cast<InitArgs&&>(init_args)...),- static_cast<Function&&>(token.function_));+ ASIO_MOVE_CAST(Initiation)(initiation),+ ASIO_MOVE_CAST(InitArgs)(init_args)...),+ ASIO_MOVE_CAST(Function)(token.function_)); } }; @@ -90,8 +94,9 @@ { public: template <typename Initiation, typename... InitArgs>- static auto initiate(Initiation&& initiation,- deferred_function<Function> token, InitArgs&&... init_args)+ static auto initiate(ASIO_MOVE_ARG(Initiation) initiation,+ deferred_function<Function> token,+ ASIO_MOVE_ARG(InitArgs)... init_args) -> decltype( deferred_sequence< deferred_async_operation<@@ -100,9 +105,9 @@ deferred_async_operation< deferred_signatures<Signatures...>, Initiation, InitArgs...>( deferred_init_tag{},- static_cast<Initiation&&>(initiation),- static_cast<InitArgs&&>(init_args)...),- static_cast<Function&&>(token.function_)))+ ASIO_MOVE_CAST(Initiation)(initiation),+ ASIO_MOVE_CAST(InitArgs)(init_args)...),+ ASIO_MOVE_CAST(Function)(token.function_))) { return deferred_sequence< deferred_async_operation<@@ -111,9 +116,9 @@ deferred_async_operation< deferred_signatures<Signatures...>, Initiation, InitArgs...>( deferred_init_tag{},- static_cast<Initiation&&>(initiation),- static_cast<InitArgs&&>(init_args)...),- static_cast<Function&&>(token.function_));+ ASIO_MOVE_CAST(Initiation)(initiation),+ ASIO_MOVE_CAST(InitArgs)(init_args)...),+ ASIO_MOVE_CAST(Function)(token.function_)); } }; @@ -124,15 +129,19 @@ DefaultCandidate> : Associator<Handler, DefaultCandidate> {- static typename Associator<Handler, DefaultCandidate>::type get(- const detail::deferred_sequence_handler<Handler, Tail>& h) noexcept+ static typename Associator<Handler, DefaultCandidate>::type+ get(const detail::deferred_sequence_handler<Handler, Tail>& h)+ ASIO_NOEXCEPT { return Associator<Handler, DefaultCandidate>::get(h.handler_); } - static auto get(const detail::deferred_sequence_handler<Handler, Tail>& h,- const DefaultCandidate& c) noexcept- -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))+ static ASIO_AUTO_RETURN_TYPE_PREFIX2(+ typename Associator<Handler, DefaultCandidate>::type)+ get(const detail::deferred_sequence_handler<Handler, Tail>& h,+ const DefaultCandidate& c) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ Associator<Handler, DefaultCandidate>::get(h.handler_, c))) { return Associator<Handler, DefaultCandidate>::get(h.handler_, c); }
link/modules/asio-standalone/asio/include/asio/impl/detached.hpp view
@@ -2,7 +2,7 @@ // impl/detached.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -17,6 +17,7 @@ #include "asio/detail/config.hpp" #include "asio/async_result.hpp"+#include "asio/detail/variadic_templates.hpp" #include "asio/detail/push_options.hpp" @@ -33,18 +34,37 @@ { } +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+ template <typename... Args> void operator()(Args...) { }++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++ void operator()()+ {+ }++#define ASIO_PRIVATE_DETACHED_DEF(n) \+ template <ASIO_VARIADIC_TPARAMS(n)> \+ void operator()(ASIO_VARIADIC_TARGS(n)) \+ { \+ } \+ /**/+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_DETACHED_DEF)+#undef ASIO_PRIVATE_DETACHED_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) }; } // namespace detail #if !defined(GENERATING_DOCUMENTATION) -template <typename... Signatures>-struct async_result<detached_t, Signatures...>+template <typename Signature>+struct async_result<detached_t, Signature> { typedef asio::detail::detached_handler completion_handler_type; @@ -58,14 +78,47 @@ { } +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+ template <typename Initiation, typename RawCompletionToken, typename... Args>- static return_type initiate(Initiation&& initiation,- RawCompletionToken&&, Args&&... args)+ static return_type initiate(+ ASIO_MOVE_ARG(Initiation) initiation,+ ASIO_MOVE_ARG(RawCompletionToken),+ ASIO_MOVE_ARG(Args)... args) {- static_cast<Initiation&&>(initiation)(+ ASIO_MOVE_CAST(Initiation)(initiation)( detail::detached_handler(detached_t()),- static_cast<Args&&>(args)...);+ ASIO_MOVE_CAST(Args)(args)...); }++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++ template <typename Initiation, typename RawCompletionToken>+ static return_type initiate(+ ASIO_MOVE_ARG(Initiation) initiation,+ ASIO_MOVE_ARG(RawCompletionToken))+ {+ ASIO_MOVE_CAST(Initiation)(initiation)(+ detail::detached_handler(detached_t()));+ }++#define ASIO_PRIVATE_INITIATE_DEF(n) \+ template <typename Initiation, typename RawCompletionToken, \+ ASIO_VARIADIC_TPARAMS(n)> \+ static return_type initiate( \+ ASIO_MOVE_ARG(Initiation) initiation, \+ ASIO_MOVE_ARG(RawCompletionToken), \+ ASIO_VARIADIC_MOVE_PARAMS(n)) \+ { \+ ASIO_MOVE_CAST(Initiation)(initiation)( \+ detail::detached_handler(detached_t()), \+ ASIO_VARIADIC_MOVE_ARGS(n)); \+ } \+ /**/+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_INITIATE_DEF)+#undef ASIO_PRIVATE_INITIATE_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) }; #endif // !defined(GENERATING_DOCUMENTATION)
link/modules/asio-standalone/asio/include/asio/impl/error.ipp view
@@ -2,7 +2,7 @@ // impl/error.ipp // ~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -31,7 +31,7 @@ class netdb_category : public asio::error_category { public:- const char* name() const noexcept+ const char* name() const ASIO_ERROR_CATEGORY_NOEXCEPT { return "asio.netdb"; }@@ -63,7 +63,7 @@ class addrinfo_category : public asio::error_category { public:- const char* name() const noexcept+ const char* name() const ASIO_ERROR_CATEGORY_NOEXCEPT { return "asio.addrinfo"; }@@ -93,7 +93,7 @@ class misc_category : public asio::error_category { public:- const char* name() const noexcept+ const char* name() const ASIO_ERROR_CATEGORY_NOEXCEPT { return "asio.misc"; }
link/modules/asio-standalone/asio/include/asio/impl/error_code.ipp view
@@ -2,7 +2,7 @@ // impl/error_code.ipp // ~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -37,7 +37,7 @@ class system_category : public error_category { public:- const char* name() const noexcept+ const char* name() const ASIO_ERROR_CATEGORY_NOEXCEPT { return "asio.system"; }@@ -108,7 +108,7 @@ #if defined(ASIO_HAS_STD_ERROR_CODE) std::error_condition default_error_condition(- int ev) const noexcept+ int ev) const ASIO_ERROR_CATEGORY_NOEXCEPT { switch (ev) {@@ -182,7 +182,6 @@ return std::errc::operation_would_block; default: return std::make_error_condition(ev, *this);- } } #endif // defined(ASIO_HAS_STD_ERROR_CODE)
link/modules/asio-standalone/asio/include/asio/impl/execution_context.hpp view
@@ -2,7 +2,7 @@ // impl/execution_context.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -15,83 +15,14 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <cstring> #include "asio/detail/handler_type_requirements.hpp"-#include "asio/detail/memory.hpp"+#include "asio/detail/scoped_ptr.hpp" #include "asio/detail/service_registry.hpp"-#include "asio/detail/throw_exception.hpp" #include "asio/detail/push_options.hpp" namespace asio { -template <typename Allocator>-execution_context::execution_context(allocator_arg_t, const Allocator& a)- : execution_context(detail::allocate_object<allocator_impl<Allocator>>(a, a))-{-}--template <typename Allocator>-execution_context::execution_context(allocator_arg_t, const Allocator& a,- const service_maker& initial_services)- : execution_context(detail::allocate_object<allocator_impl<Allocator>>(a, a),- initial_services)-{-}--inline execution_context::auto_allocator_ptr::~auto_allocator_ptr()-{- ptr_->destroy();-}--template <typename Allocator>-void execution_context::allocator_impl<Allocator>::destroy()-{- detail::deallocate_object(allocator_, this);-}--template <typename Allocator>-void* execution_context::allocator_impl<Allocator>::allocate(- std::size_t size, std::size_t align)-{- typename std::allocator_traits<Allocator>::template- rebind_alloc<unsigned char> alloc(allocator_);-- std::size_t space = size + align - 1;- unsigned char* base = std::allocator_traits<decltype(alloc)>::allocate(- alloc, space + sizeof(std::ptrdiff_t));-- void* p = base;- if (detail::align(align, size, p, space))- {- std::ptrdiff_t off = static_cast<unsigned char*>(p) - base;- std::memcpy(static_cast<unsigned char*>(p) + size, &off, sizeof(off));- return p;- }-- std::bad_alloc ex;- asio::detail::throw_exception(ex);- return 0;-}--template <typename Allocator>-void execution_context::allocator_impl<Allocator>::deallocate(- void* ptr, std::size_t size, std::size_t align)-{- if (ptr)- {- typename std::allocator_traits<Allocator>::template- rebind_alloc<unsigned char> alloc(allocator_);-- std::ptrdiff_t off;- std::memcpy(&off, static_cast<unsigned char*>(ptr) + size, sizeof(off));- unsigned char* base = static_cast<unsigned char*>(ptr) - off;-- std::allocator_traits<decltype(alloc)>::deallocate(- alloc, base, size + align - 1 + sizeof(std::ptrdiff_t));- }-}- #if !defined(GENERATING_DOCUMENTATION) template <typename Service>@@ -103,15 +34,48 @@ return e.service_registry_->template use_service<Service>(); } +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+ template <typename Service, typename... Args>-Service& make_service(execution_context& e, Args&&... args)+Service& make_service(execution_context& e, ASIO_MOVE_ARG(Args)... args) {- // Check that Service meets the necessary type requirements.- (void)static_cast<execution_context::service*>(static_cast<Service*>(0));+ detail::scoped_ptr<Service> svc(+ new Service(e, ASIO_MOVE_CAST(Args)(args)...));+ e.service_registry_->template add_service<Service>(svc.get());+ Service& result = *svc;+ svc.release();+ return result;+} - return e.service_registry_->template make_service<Service>(- static_cast<Args&&>(args)...);+#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename Service>+Service& make_service(execution_context& e)+{+ detail::scoped_ptr<Service> svc(new Service(e));+ e.service_registry_->template add_service<Service>(svc.get());+ Service& result = *svc;+ svc.release();+ return result; }++#define ASIO_PRIVATE_MAKE_SERVICE_DEF(n) \+ template <typename Service, ASIO_VARIADIC_TPARAMS(n)> \+ Service& make_service(execution_context& e, \+ ASIO_VARIADIC_MOVE_PARAMS(n)) \+ { \+ detail::scoped_ptr<Service> svc( \+ new Service(e, ASIO_VARIADIC_MOVE_ARGS(n))); \+ e.service_registry_->template add_service<Service>(svc.get()); \+ Service& result = *svc; \+ svc.release(); \+ return result; \+ } \+ /**/+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_MAKE_SERVICE_DEF)+#undef ASIO_PRIVATE_MAKE_SERVICE_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) template <typename Service> inline void add_service(execution_context& e, Service* svc)
link/modules/asio-standalone/asio/include/asio/impl/execution_context.ipp view
@@ -2,7 +2,7 @@ // impl/execution_context.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -24,44 +24,15 @@ namespace asio { execution_context::execution_context()- : execution_context(- detail::allocate_object<allocator_impl<std::allocator<void>>>(- std::allocator<void>(), std::allocator<void>()))-{-}--execution_context::execution_context(allocator_impl_base* alloc)- : allocator_{alloc},- service_registry_(- detail::allocate_object<detail::service_registry>(- allocator<void>(*this), *this))-{-}--execution_context::execution_context(- const execution_context::service_maker& initial_services)- : execution_context(- detail::allocate_object<allocator_impl<std::allocator<void>>>(- std::allocator<void>(), std::allocator<void>()),- initial_services)+ : service_registry_(new asio::detail::service_registry(*this)) { } -execution_context::execution_context(allocator_impl_base* alloc,- const execution_context::service_maker& initial_services)- : allocator_{alloc},- service_registry_(- detail::allocate_object<detail::service_registry>(- allocator<void>(*this), *this))-{- initial_services.make(*this);-}- execution_context::~execution_context() { shutdown(); destroy();- detail::deallocate_object(allocator<void>(*this), service_registry_);+ delete service_registry_; } void execution_context::shutdown()@@ -80,14 +51,9 @@ service_registry_->notify_fork(event); } -execution_context::allocator_impl_base::~allocator_impl_base()-{-}- execution_context::service::service(execution_context& owner) : owner_(owner),- next_(0),- destroy_(0)+ next_(0) { } @@ -96,10 +62,6 @@ } void execution_context::service::notify_fork(execution_context::fork_event)-{-}--execution_context::service_maker::~service_maker() { }
link/modules/asio-standalone/asio/include/asio/impl/executor.hpp view
@@ -2,7 +2,7 @@ // impl/executor.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -19,7 +19,6 @@ #if !defined(ASIO_NO_TS_EXECUTORS) -#include <new> #include "asio/detail/atomic_count.hpp" #include "asio/detail/global.hpp" #include "asio/detail/memory.hpp"@@ -48,12 +47,7 @@ return p; } - static impl_base* create(std::nothrow_t, const Executor& e) noexcept- {- return new (std::nothrow) impl(e, std::allocator<void>());- }-- impl(const Executor& e, const Allocator& a) noexcept+ impl(const Executor& e, const Allocator& a) ASIO_NOEXCEPT : impl_base(false), ref_count_(1), executor_(e),@@ -61,13 +55,13 @@ { } - impl_base* clone() const noexcept+ impl_base* clone() const ASIO_NOEXCEPT { detail::ref_count_up(ref_count_); return const_cast<impl_base*>(static_cast<const impl_base*>(this)); } - void destroy() noexcept+ void destroy() ASIO_NOEXCEPT { if (detail::ref_count_down(ref_count_)) {@@ -78,52 +72,52 @@ } } - void on_work_started() noexcept+ void on_work_started() ASIO_NOEXCEPT { executor_.on_work_started(); } - void on_work_finished() noexcept+ void on_work_finished() ASIO_NOEXCEPT { executor_.on_work_finished(); } - execution_context& context() noexcept+ execution_context& context() ASIO_NOEXCEPT { return executor_.context(); } - void dispatch(function&& f)+ void dispatch(ASIO_MOVE_ARG(function) f) {- executor_.dispatch(static_cast<function&&>(f), allocator_);+ executor_.dispatch(ASIO_MOVE_CAST(function)(f), allocator_); } - void post(function&& f)+ void post(ASIO_MOVE_ARG(function) f) {- executor_.post(static_cast<function&&>(f), allocator_);+ executor_.post(ASIO_MOVE_CAST(function)(f), allocator_); } - void defer(function&& f)+ void defer(ASIO_MOVE_ARG(function) f) {- executor_.defer(static_cast<function&&>(f), allocator_);+ executor_.defer(ASIO_MOVE_CAST(function)(f), allocator_); } - type_id_result_type target_type() const noexcept+ type_id_result_type target_type() const ASIO_NOEXCEPT { return type_id<Executor>(); } - void* target() noexcept+ void* target() ASIO_NOEXCEPT { return &executor_; } - const void* target() const noexcept+ const void* target() const ASIO_NOEXCEPT { return &executor_; } - bool equals(const impl_base* e) const noexcept+ bool equals(const impl_base* e) const ASIO_NOEXCEPT { if (this == e) return true;@@ -170,12 +164,7 @@ static impl_base* create(const system_executor&, const Allocator& = Allocator()) {- return &detail::global<impl<system_executor, std::allocator<void>> >();- }-- static impl_base* create(std::nothrow_t, const system_executor&) noexcept- {- return &detail::global<impl<system_executor, std::allocator<void>> >();+ return &detail::global<impl<system_executor, std::allocator<void> > >(); } impl()@@ -183,64 +172,64 @@ { } - impl_base* clone() const noexcept+ impl_base* clone() const ASIO_NOEXCEPT { return const_cast<impl_base*>(static_cast<const impl_base*>(this)); } - void destroy() noexcept+ void destroy() ASIO_NOEXCEPT { } - void on_work_started() noexcept+ void on_work_started() ASIO_NOEXCEPT { executor_.on_work_started(); } - void on_work_finished() noexcept+ void on_work_finished() ASIO_NOEXCEPT { executor_.on_work_finished(); } - execution_context& context() noexcept+ execution_context& context() ASIO_NOEXCEPT { return executor_.context(); } - void dispatch(function&& f)+ void dispatch(ASIO_MOVE_ARG(function) f) {- executor_.dispatch(static_cast<function&&>(f),+ executor_.dispatch(ASIO_MOVE_CAST(function)(f), std::allocator<void>()); } - void post(function&& f)+ void post(ASIO_MOVE_ARG(function) f) {- executor_.post(static_cast<function&&>(f),+ executor_.post(ASIO_MOVE_CAST(function)(f), std::allocator<void>()); } - void defer(function&& f)+ void defer(ASIO_MOVE_ARG(function) f) {- executor_.defer(static_cast<function&&>(f),+ executor_.defer(ASIO_MOVE_CAST(function)(f), std::allocator<void>()); } - type_id_result_type target_type() const noexcept+ type_id_result_type target_type() const ASIO_NOEXCEPT { return type_id<system_executor>(); } - void* target() noexcept+ void* target() ASIO_NOEXCEPT { return &executor_; } - const void* target() const noexcept+ const void* target() const ASIO_NOEXCEPT { return &executor_; } - bool equals(const impl_base* e) const noexcept+ bool equals(const impl_base* e) const ASIO_NOEXCEPT { return this == e; }@@ -251,13 +240,7 @@ template <typename Executor> executor::executor(Executor e)- : impl_(impl<Executor, std::allocator<void>>::create(e))-{-}--template <typename Executor>-executor::executor(std::nothrow_t, Executor e) noexcept- : impl_(impl<Executor, std::allocator<void>>::create(std::nothrow, e))+ : impl_(impl<Executor, std::allocator<void> >::create(e)) { } @@ -268,39 +251,39 @@ } template <typename Function, typename Allocator>-void executor::dispatch(Function&& f,+void executor::dispatch(ASIO_MOVE_ARG(Function) f, const Allocator& a) const { impl_base* i = get_impl(); if (i->fast_dispatch_)- system_executor().dispatch(static_cast<Function&&>(f), a);+ system_executor().dispatch(ASIO_MOVE_CAST(Function)(f), a); else- i->dispatch(function(static_cast<Function&&>(f), a));+ i->dispatch(function(ASIO_MOVE_CAST(Function)(f), a)); } template <typename Function, typename Allocator>-void executor::post(Function&& f,+void executor::post(ASIO_MOVE_ARG(Function) f, const Allocator& a) const {- get_impl()->post(function(static_cast<Function&&>(f), a));+ get_impl()->post(function(ASIO_MOVE_CAST(Function)(f), a)); } template <typename Function, typename Allocator>-void executor::defer(Function&& f,+void executor::defer(ASIO_MOVE_ARG(Function) f, const Allocator& a) const {- get_impl()->defer(function(static_cast<Function&&>(f), a));+ get_impl()->defer(function(ASIO_MOVE_CAST(Function)(f), a)); } template <typename Executor>-Executor* executor::target() noexcept+Executor* executor::target() ASIO_NOEXCEPT { return impl_ && impl_->target_type() == type_id<Executor>() ? static_cast<Executor*>(impl_->target()) : 0; } template <typename Executor>-const Executor* executor::target() const noexcept+const Executor* executor::target() const ASIO_NOEXCEPT { return impl_ && impl_->target_type() == type_id<Executor>() ? static_cast<Executor*>(impl_->target()) : 0;
link/modules/asio-standalone/asio/include/asio/impl/executor.ipp view
@@ -2,7 +2,7 @@ // impl/executor.ipp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -25,11 +25,11 @@ namespace asio { -bad_executor::bad_executor() noexcept+bad_executor::bad_executor() ASIO_NOEXCEPT { } -const char* bad_executor::what() const noexcept+const char* bad_executor::what() const ASIO_NOEXCEPT_OR_NOTHROW { return "bad executor"; }
+ link/modules/asio-standalone/asio/include/asio/impl/handler_alloc_hook.ipp view
@@ -0,0 +1,62 @@+//+// impl/handler_alloc_hook.ipp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_IMPL_HANDLER_ALLOC_HOOK_IPP+#define ASIO_IMPL_HANDLER_ALLOC_HOOK_IPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/detail/memory.hpp"+#include "asio/detail/thread_context.hpp"+#include "asio/detail/thread_info_base.hpp"+#include "asio/handler_alloc_hook.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {++asio_handler_allocate_is_deprecated+asio_handler_allocate(std::size_t size, ...)+{+#if defined(ASIO_NO_DEPRECATED)+ (void)size;+ return asio_handler_allocate_is_no_longer_used();+#elif !defined(ASIO_DISABLE_SMALL_BLOCK_RECYCLING)+ return detail::thread_info_base::allocate(+ detail::thread_context::top_of_thread_call_stack(), size);+#else // !defined(ASIO_DISABLE_SMALL_BLOCK_RECYCLING)+ return aligned_new(ASIO_DEFAULT_ALIGN, size);+#endif // !defined(ASIO_DISABLE_SMALL_BLOCK_RECYCLING)+}++asio_handler_deallocate_is_deprecated+asio_handler_deallocate(void* pointer, std::size_t size, ...)+{+#if defined(ASIO_NO_DEPRECATED)+ (void)pointer;+ (void)size;+ return asio_handler_deallocate_is_no_longer_used();+#elif !defined(ASIO_DISABLE_SMALL_BLOCK_RECYCLING)+ detail::thread_info_base::deallocate(+ detail::thread_context::top_of_thread_call_stack(), pointer, size);+#else // !defined(ASIO_DISABLE_SMALL_BLOCK_RECYCLING)+ (void)size;+ aligned_delete(pointer);+#endif // !defined(ASIO_DISABLE_SMALL_BLOCK_RECYCLING)+}++} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_IMPL_HANDLER_ALLOC_HOOK_IPP
link/modules/asio-standalone/asio/include/asio/impl/io_context.hpp view
@@ -2,7 +2,7 @@ // impl/io_context.hpp // ~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -15,7 +15,6 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include "asio/config.hpp" #include "asio/detail/completion_handler.hpp" #include "asio/detail/executor_op.hpp" #include "asio/detail/fenced_block.hpp"@@ -29,30 +28,6 @@ namespace asio { -template <typename Allocator>-io_context::io_context(allocator_arg_t, const Allocator& a)- : execution_context(std::allocator_arg, a, config_from_concurrency_hint()),- impl_(asio::make_service<impl_type>(*this, false))-{-}--template <typename Allocator>-io_context::io_context(allocator_arg_t,- const Allocator& a, int concurrency_hint)- : execution_context(std::allocator_arg, a,- config_from_concurrency_hint(concurrency_hint)),- impl_(asio::make_service<impl_type>(*this, false))-{-}--template <typename Allocator>-io_context::io_context(allocator_arg_t, const Allocator& a,- const execution_context::service_maker& initial_services)- : execution_context(std::allocator_arg, a, initial_services),- impl_(asio::make_service<impl_type>(*this, false))-{-}- #if !defined(GENERATING_DOCUMENTATION) template <typename Service>@@ -75,11 +50,13 @@ #endif // !defined(GENERATING_DOCUMENTATION) inline io_context::executor_type-io_context::get_executor() noexcept+io_context::get_executor() ASIO_NOEXCEPT { return executor_type(*this); } +#if defined(ASIO_HAS_CHRONO)+ template <typename Rep, typename Period> std::size_t io_context::run_for( const chrono::duration<Rep, Period>& rel_time)@@ -131,8 +108,104 @@ return 0; } +#endif // defined(ASIO_HAS_CHRONO)+ #if !defined(ASIO_NO_DEPRECATED) +inline void io_context::reset()+{+ restart();+}++struct io_context::initiate_dispatch+{+ template <typename LegacyCompletionHandler>+ void operator()(ASIO_MOVE_ARG(LegacyCompletionHandler) handler,+ io_context* self) const+ {+ // If you get an error on the following line it means that your handler does+ // not meet the documented type requirements for a LegacyCompletionHandler.+ ASIO_LEGACY_COMPLETION_HANDLER_CHECK(+ LegacyCompletionHandler, handler) type_check;++ detail::non_const_lvalue<LegacyCompletionHandler> handler2(handler);+ if (self->impl_.can_dispatch())+ {+ detail::fenced_block b(detail::fenced_block::full);+ asio_handler_invoke_helpers::invoke(+ handler2.value, handler2.value);+ }+ else+ {+ // Allocate and construct an operation to wrap the handler.+ typedef detail::completion_handler<+ typename decay<LegacyCompletionHandler>::type, executor_type> op;+ typename op::ptr p = { detail::addressof(handler2.value),+ op::ptr::allocate(handler2.value), 0 };+ p.p = new (p.v) op(handler2.value, self->get_executor());++ ASIO_HANDLER_CREATION((*self, *p.p,+ "io_context", self, 0, "dispatch"));++ self->impl_.do_dispatch(p.p);+ p.v = p.p = 0;+ }+ }+};++template <typename LegacyCompletionHandler>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(LegacyCompletionHandler, void ())+io_context::dispatch(ASIO_MOVE_ARG(LegacyCompletionHandler) handler)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_initiate<LegacyCompletionHandler, void ()>(+ declval<initiate_dispatch>(), handler, this)))+{+ return async_initiate<LegacyCompletionHandler, void ()>(+ initiate_dispatch(), handler, this);+}++struct io_context::initiate_post+{+ template <typename LegacyCompletionHandler>+ void operator()(ASIO_MOVE_ARG(LegacyCompletionHandler) handler,+ io_context* self) const+ {+ // If you get an error on the following line it means that your handler does+ // not meet the documented type requirements for a LegacyCompletionHandler.+ ASIO_LEGACY_COMPLETION_HANDLER_CHECK(+ LegacyCompletionHandler, handler) type_check;++ detail::non_const_lvalue<LegacyCompletionHandler> handler2(handler);++ bool is_continuation =+ asio_handler_cont_helpers::is_continuation(handler2.value);++ // Allocate and construct an operation to wrap the handler.+ typedef detail::completion_handler<+ typename decay<LegacyCompletionHandler>::type, executor_type> op;+ typename op::ptr p = { detail::addressof(handler2.value),+ op::ptr::allocate(handler2.value), 0 };+ p.p = new (p.v) op(handler2.value, self->get_executor());++ ASIO_HANDLER_CREATION((*self, *p.p,+ "io_context", self, 0, "post"));++ self->impl_.post_immediate_completion(p.p, is_continuation);+ p.v = p.p = 0;+ }+};++template <typename LegacyCompletionHandler>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(LegacyCompletionHandler, void ())+io_context::post(ASIO_MOVE_ARG(LegacyCompletionHandler) handler)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_initiate<LegacyCompletionHandler, void ()>(+ declval<initiate_post>(), handler, this)))+{+ return async_initiate<LegacyCompletionHandler, void ()>(+ initiate_post(), handler, this);+}+ template <typename Handler> #if defined(GENERATING_DOCUMENTATION) unspecified@@ -149,7 +222,7 @@ template <typename Allocator, uintptr_t Bits> io_context::basic_executor_type<Allocator, Bits>& io_context::basic_executor_type<Allocator, Bits>::operator=(- const basic_executor_type& other) noexcept+ const basic_executor_type& other) ASIO_NOEXCEPT { if (this != &other) {@@ -167,10 +240,11 @@ return *this; } +#if defined(ASIO_HAS_MOVE) template <typename Allocator, uintptr_t Bits> io_context::basic_executor_type<Allocator, Bits>& io_context::basic_executor_type<Allocator, Bits>::operator=(- basic_executor_type&& other) noexcept+ basic_executor_type&& other) ASIO_NOEXCEPT { if (this != &other) {@@ -186,10 +260,11 @@ } return *this; }+#endif // defined(ASIO_HAS_MOVE) template <typename Allocator, uintptr_t Bits> inline bool io_context::basic_executor_type<Allocator,- Bits>::running_in_this_thread() const noexcept+ Bits>::running_in_this_thread() const ASIO_NOEXCEPT { return context_ptr()->impl_.can_dispatch(); }@@ -197,32 +272,36 @@ template <typename Allocator, uintptr_t Bits> template <typename Function> void io_context::basic_executor_type<Allocator, Bits>::execute(- Function&& f) const+ ASIO_MOVE_ARG(Function) f) const {- typedef decay_t<Function> function_type;+ typedef typename decay<Function>::type function_type; // Invoke immediately if the blocking.possibly property is enabled and we are // already inside the thread pool. if ((bits() & blocking_never) == 0 && context_ptr()->impl_.can_dispatch()) { // Make a local, non-const copy of the function.- function_type tmp(static_cast<Function&&>(f));+ function_type tmp(ASIO_MOVE_CAST(Function)(f)); -#if !defined(ASIO_NO_EXCEPTIONS)+#if defined(ASIO_HAS_STD_EXCEPTION_PTR) \+ && !defined(ASIO_NO_EXCEPTIONS) try {-#endif // !defined(ASIO_NO_EXCEPTIONS)+#endif // defined(ASIO_HAS_STD_EXCEPTION_PTR)+ // && !defined(ASIO_NO_EXCEPTIONS) detail::fenced_block b(detail::fenced_block::full);- static_cast<function_type&&>(tmp)();+ asio_handler_invoke_helpers::invoke(tmp, tmp); return;-#if !defined(ASIO_NO_EXCEPTIONS)+#if defined(ASIO_HAS_STD_EXCEPTION_PTR) \+ && !defined(ASIO_NO_EXCEPTIONS) } catch (...) { context_ptr()->impl_.capture_current_exception(); return; }-#endif // !defined(ASIO_NO_EXCEPTIONS)+#endif // defined(ASIO_HAS_STD_EXCEPTION_PTR)+ // && !defined(ASIO_NO_EXCEPTIONS) } // Allocate and construct an operation to wrap the function.@@ -230,7 +309,7 @@ typename op::ptr p = { detail::addressof(static_cast<const Allocator&>(*this)), op::ptr::allocate(static_cast<const Allocator&>(*this)), 0 };- p.p = new (p.v) op(static_cast<Function&&>(f),+ p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(f), static_cast<const Allocator&>(*this)); ASIO_HANDLER_CREATION((*context_ptr(), *p.p,@@ -244,21 +323,21 @@ #if !defined(ASIO_NO_TS_EXECUTORS) template <typename Allocator, uintptr_t Bits> inline io_context& io_context::basic_executor_type<- Allocator, Bits>::context() const noexcept+ Allocator, Bits>::context() const ASIO_NOEXCEPT { return *context_ptr(); } template <typename Allocator, uintptr_t Bits> inline void io_context::basic_executor_type<Allocator,- Bits>::on_work_started() const noexcept+ Bits>::on_work_started() const ASIO_NOEXCEPT { context_ptr()->impl_.work_started(); } template <typename Allocator, uintptr_t Bits> inline void io_context::basic_executor_type<Allocator,- Bits>::on_work_finished() const noexcept+ Bits>::on_work_finished() const ASIO_NOEXCEPT { context_ptr()->impl_.work_finished(); }@@ -266,18 +345,18 @@ template <typename Allocator, uintptr_t Bits> template <typename Function, typename OtherAllocator> void io_context::basic_executor_type<Allocator, Bits>::dispatch(- Function&& f, const OtherAllocator& a) const+ ASIO_MOVE_ARG(Function) f, const OtherAllocator& a) const {- typedef decay_t<Function> function_type;+ typedef typename decay<Function>::type function_type; // Invoke immediately if we are already inside the thread pool. if (context_ptr()->impl_.can_dispatch()) { // Make a local, non-const copy of the function.- function_type tmp(static_cast<Function&&>(f));+ function_type tmp(ASIO_MOVE_CAST(Function)(f)); detail::fenced_block b(detail::fenced_block::full);- static_cast<function_type&&>(tmp)();+ asio_handler_invoke_helpers::invoke(tmp, tmp); return; } @@ -285,7 +364,7 @@ typedef detail::executor_op<function_type, OtherAllocator, detail::operation> op; typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 };- p.p = new (p.v) op(static_cast<Function&&>(f), a);+ p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(f), a); ASIO_HANDLER_CREATION((*context_ptr(), *p.p, "io_context", context_ptr(), 0, "dispatch"));@@ -297,13 +376,15 @@ template <typename Allocator, uintptr_t Bits> template <typename Function, typename OtherAllocator> void io_context::basic_executor_type<Allocator, Bits>::post(- Function&& f, const OtherAllocator& a) const+ ASIO_MOVE_ARG(Function) f, const OtherAllocator& a) const {+ typedef typename decay<Function>::type function_type;+ // Allocate and construct an operation to wrap the function.- typedef detail::executor_op<decay_t<Function>,+ typedef detail::executor_op<function_type, OtherAllocator, detail::operation> op; typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 };- p.p = new (p.v) op(static_cast<Function&&>(f), a);+ p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(f), a); ASIO_HANDLER_CREATION((*context_ptr(), *p.p, "io_context", context_ptr(), 0, "post"));@@ -315,13 +396,15 @@ template <typename Allocator, uintptr_t Bits> template <typename Function, typename OtherAllocator> void io_context::basic_executor_type<Allocator, Bits>::defer(- Function&& f, const OtherAllocator& a) const+ ASIO_MOVE_ARG(Function) f, const OtherAllocator& a) const {+ typedef typename decay<Function>::type function_type;+ // Allocate and construct an operation to wrap the function.- typedef detail::executor_op<decay_t<Function>,+ typedef detail::executor_op<function_type, OtherAllocator, detail::operation> op; typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 };- p.p = new (p.v) op(static_cast<Function&&>(f), a);+ p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(f), a); ASIO_HANDLER_CREATION((*context_ptr(), *p.p, "io_context", context_ptr(), 0, "defer"));@@ -330,6 +413,30 @@ p.v = p.p = 0; } #endif // !defined(ASIO_NO_TS_EXECUTORS)++#if !defined(ASIO_NO_DEPRECATED)+inline io_context::work::work(asio::io_context& io_context)+ : io_context_impl_(io_context.impl_)+{+ io_context_impl_.work_started();+}++inline io_context::work::work(const work& other)+ : io_context_impl_(other.io_context_impl_)+{+ io_context_impl_.work_started();+}++inline io_context::work::~work()+{+ io_context_impl_.work_finished();+}++inline asio::io_context& io_context::work::get_io_context()+{+ return static_cast<asio::io_context&>(io_context_impl_.context());+}+#endif // !defined(ASIO_NO_DEPRECATED) inline asio::io_context& io_context::service::get_io_context() {
link/modules/asio-standalone/asio/include/asio/impl/io_context.ipp view
@@ -2,7 +2,7 @@ // impl/io_context.ipp // ~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -16,10 +16,10 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"-#include "asio/config.hpp" #include "asio/io_context.hpp" #include "asio/detail/concurrency_hint.hpp" #include "asio/detail/limits.hpp"+#include "asio/detail/scoped_ptr.hpp" #include "asio/detail/service_registry.hpp" #include "asio/detail/throw_error.hpp" @@ -34,21 +34,22 @@ namespace asio { io_context::io_context()- : execution_context(config_from_concurrency_hint()),- impl_(asio::make_service<impl_type>(*this, false))+ : impl_(add_impl(new impl_type(*this,+ ASIO_CONCURRENCY_HINT_DEFAULT, false))) { } io_context::io_context(int concurrency_hint)- : execution_context(config_from_concurrency_hint(concurrency_hint)),- impl_(asio::make_service<impl_type>(*this, false))+ : impl_(add_impl(new impl_type(*this, concurrency_hint == 1+ ? ASIO_CONCURRENCY_HINT_1 : concurrency_hint, false))) { } -io_context::io_context(const execution_context::service_maker& initial_services)- : execution_context(initial_services),- impl_(asio::make_service<impl_type>(*this, false))+io_context::impl_type& io_context::add_impl(io_context::impl_type* impl) {+ asio::detail::scoped_ptr<impl_type> scoped_impl(impl);+ asio::add_service<impl_type>(*this, scoped_impl.get());+ return *scoped_impl.release(); } io_context::~io_context()@@ -64,6 +65,13 @@ return s; } +#if !defined(ASIO_NO_DEPRECATED)+io_context::count_type io_context::run(asio::error_code& ec)+{+ return impl_.run(ec);+}+#endif // !defined(ASIO_NO_DEPRECATED)+ io_context::count_type io_context::run_one() { asio::error_code ec;@@ -72,6 +80,13 @@ return s; } +#if !defined(ASIO_NO_DEPRECATED)+io_context::count_type io_context::run_one(asio::error_code& ec)+{+ return impl_.run_one(ec);+}+#endif // !defined(ASIO_NO_DEPRECATED)+ io_context::count_type io_context::poll() { asio::error_code ec;@@ -80,6 +95,13 @@ return s; } +#if !defined(ASIO_NO_DEPRECATED)+io_context::count_type io_context::poll(asio::error_code& ec)+{+ return impl_.poll(ec);+}+#endif // !defined(ASIO_NO_DEPRECATED)+ io_context::count_type io_context::poll_one() { asio::error_code ec;@@ -88,6 +110,13 @@ return s; } +#if !defined(ASIO_NO_DEPRECATED)+io_context::count_type io_context::poll_one(asio::error_code& ec)+{+ return impl_.poll_one(ec);+}+#endif // !defined(ASIO_NO_DEPRECATED)+ void io_context::stop() { impl_.stop();@@ -114,11 +143,31 @@ void io_context::service::shutdown() {+#if !defined(ASIO_NO_DEPRECATED)+ shutdown_service();+#endif // !defined(ASIO_NO_DEPRECATED) } -void io_context::service::notify_fork(io_context::fork_event)+#if !defined(ASIO_NO_DEPRECATED)+void io_context::service::shutdown_service() { }+#endif // !defined(ASIO_NO_DEPRECATED)++void io_context::service::notify_fork(io_context::fork_event ev)+{+#if !defined(ASIO_NO_DEPRECATED)+ fork_service(ev);+#else // !defined(ASIO_NO_DEPRECATED)+ (void)ev;+#endif // !defined(ASIO_NO_DEPRECATED)+}++#if !defined(ASIO_NO_DEPRECATED)+void io_context::service::fork_service(io_context::fork_event)+{+}+#endif // !defined(ASIO_NO_DEPRECATED) } // namespace asio
link/modules/asio-standalone/asio/include/asio/impl/multiple_exceptions.ipp view
@@ -2,7 +2,7 @@ // impl/multiple_exceptions.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -22,13 +22,15 @@ namespace asio { +#if defined(ASIO_HAS_STD_EXCEPTION_PTR)+ multiple_exceptions::multiple_exceptions(- std::exception_ptr first) noexcept- : first_(static_cast<std::exception_ptr&&>(first))+ std::exception_ptr first) ASIO_NOEXCEPT+ : first_(ASIO_MOVE_CAST(std::exception_ptr)(first)) { } -const char* multiple_exceptions::what() const noexcept+const char* multiple_exceptions::what() const ASIO_NOEXCEPT_OR_NOTHROW { return "multiple exceptions"; }@@ -37,6 +39,8 @@ { return first_; }++#endif // defined(ASIO_HAS_STD_EXCEPTION_PTR) } // namespace asio
link/modules/asio-standalone/asio/include/asio/impl/prepend.hpp view
@@ -2,7 +2,7 @@ // impl/prepend.hpp // ~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -16,12 +16,15 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"+ #include "asio/associator.hpp" #include "asio/async_result.hpp"+#include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_cont_helpers.hpp"-#include "asio/detail/initiation_base.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/type_traits.hpp" #include "asio/detail/utility.hpp"+#include "asio/detail/variadic_templates.hpp" #include "asio/detail/push_options.hpp" @@ -36,26 +39,26 @@ typedef void result_type; template <typename H>- prepend_handler(H&& handler, std::tuple<Values...> values)- : handler_(static_cast<H&&>(handler)),- values_(static_cast<std::tuple<Values...>&&>(values))+ prepend_handler(ASIO_MOVE_ARG(H) handler, std::tuple<Values...> values)+ : handler_(ASIO_MOVE_CAST(H)(handler)),+ values_(ASIO_MOVE_CAST(std::tuple<Values...>)(values)) { } template <typename... Args>- void operator()(Args&&... args)+ void operator()(ASIO_MOVE_ARG(Args)... args) { this->invoke( index_sequence_for<Values...>{},- static_cast<Args&&>(args)...);+ ASIO_MOVE_CAST(Args)(args)...); } template <std::size_t... I, typename... Args>- void invoke(index_sequence<I...>, Args&&... args)+ void invoke(index_sequence<I...>, ASIO_MOVE_ARG(Args)... args) {- static_cast<Handler&&>(handler_)(- static_cast<Values&&>(std::get<I>(values_))...,- static_cast<Args&&>(args)...);+ ASIO_MOVE_OR_LVALUE(Handler)(handler_)(+ ASIO_MOVE_CAST(Values)(std::get<I>(values_))...,+ ASIO_MOVE_CAST(Args)(args)...); } //private:@@ -64,6 +67,32 @@ }; template <typename Handler>+inline asio_handler_allocate_is_deprecated+asio_handler_allocate(std::size_t size,+ prepend_handler<Handler>* this_handler)+{+#if defined(ASIO_NO_DEPRECATED)+ asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+ return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+ return asio_handler_alloc_helpers::allocate(+ size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler>+inline asio_handler_deallocate_is_deprecated+asio_handler_deallocate(void* pointer, std::size_t size,+ prepend_handler<Handler>* this_handler)+{+ asio_handler_alloc_helpers::deallocate(+ pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler> inline bool asio_handler_is_continuation( prepend_handler<Handler>* this_handler) {@@ -71,13 +100,37 @@ this_handler->handler_); } +template <typename Function, typename Handler>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(Function& function,+ prepend_handler<Handler>* this_handler)+{+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Function, typename Handler>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(const Function& function,+ prepend_handler<Handler>* this_handler)+{+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}+ template <typename Signature, typename... Values> struct prepend_signature; template <typename R, typename... Args, typename... Values> struct prepend_signature<R(Args...), Values...> {- typedef R type(Values..., decay_t<Args>...);+ typedef R type(Values..., typename decay<Args>::type...); }; } // namespace detail@@ -95,49 +148,48 @@ Signature, Values...>::type signature; template <typename Initiation>- struct init_wrapper : detail::initiation_base<Initiation>+ struct init_wrapper {- using detail::initiation_base<Initiation>::initiation_base;-- template <typename Handler, typename... Args>- void operator()(Handler&& handler,- std::tuple<Values...> values, Args&&... args) &&+ init_wrapper(Initiation init)+ : initiation_(ASIO_MOVE_CAST(Initiation)(init)) {- static_cast<Initiation&&>(*this)(- detail::prepend_handler<decay_t<Handler>, Values...>(- static_cast<Handler&&>(handler),- static_cast<std::tuple<Values...>&&>(values)),- static_cast<Args&&>(args)...); } template <typename Handler, typename... Args>- void operator()(Handler&& handler,- std::tuple<Values...> values, Args&&... args) const &+ void operator()(+ ASIO_MOVE_ARG(Handler) handler,+ std::tuple<Values...> values,+ ASIO_MOVE_ARG(Args)... args) {- static_cast<const Initiation&>(*this)(- detail::prepend_handler<decay_t<Handler>, Values...>(- static_cast<Handler&&>(handler),- static_cast<std::tuple<Values...>&&>(values)),- static_cast<Args&&>(args)...);+ ASIO_MOVE_CAST(Initiation)(initiation_)(+ detail::prepend_handler<+ typename decay<Handler>::type, Values...>(+ ASIO_MOVE_CAST(Handler)(handler),+ ASIO_MOVE_CAST(std::tuple<Values...>)(values)),+ ASIO_MOVE_CAST(Args)(args)...); }++ Initiation initiation_; }; template <typename Initiation, typename RawCompletionToken, typename... Args>- static auto initiate(Initiation&& initiation,- RawCompletionToken&& token, Args&&... args)- -> decltype(- async_initiate<CompletionToken, signature>(- declval<init_wrapper<decay_t<Initiation>>>(),- token.token_,- static_cast<std::tuple<Values...>&&>(token.values_),- static_cast<Args&&>(args)...))+ static ASIO_INITFN_DEDUCED_RESULT_TYPE(CompletionToken, signature,+ (async_initiate<CompletionToken, signature>(+ declval<init_wrapper<typename decay<Initiation>::type> >(),+ declval<CompletionToken&>(),+ declval<std::tuple<Values...> >(),+ declval<ASIO_MOVE_ARG(Args)>()...)))+ initiate(+ ASIO_MOVE_ARG(Initiation) initiation,+ ASIO_MOVE_ARG(RawCompletionToken) token,+ ASIO_MOVE_ARG(Args)... args) { return async_initiate<CompletionToken, signature>(- init_wrapper<decay_t<Initiation>>(- static_cast<Initiation&&>(initiation)),+ init_wrapper<typename decay<Initiation>::type>(+ ASIO_MOVE_CAST(Initiation)(initiation)), token.token_,- static_cast<std::tuple<Values...>&&>(token.values_),- static_cast<Args&&>(args)...);+ ASIO_MOVE_CAST(std::tuple<Values...>)(token.values_),+ ASIO_MOVE_CAST(Args)(args)...); } }; @@ -147,15 +199,18 @@ detail::prepend_handler<Handler, Values...>, DefaultCandidate> : Associator<Handler, DefaultCandidate> {- static typename Associator<Handler, DefaultCandidate>::type get(- const detail::prepend_handler<Handler, Values...>& h) noexcept+ static typename Associator<Handler, DefaultCandidate>::type+ get(const detail::prepend_handler<Handler, Values...>& h) ASIO_NOEXCEPT { return Associator<Handler, DefaultCandidate>::get(h.handler_); } - static auto get(const detail::prepend_handler<Handler, Values...>& h,- const DefaultCandidate& c) noexcept- -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))+ static ASIO_AUTO_RETURN_TYPE_PREFIX2(+ typename Associator<Handler, DefaultCandidate>::type)+ get(const detail::prepend_handler<Handler, Values...>& h,+ const DefaultCandidate& c) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ Associator<Handler, DefaultCandidate>::get(h.handler_, c))) { return Associator<Handler, DefaultCandidate>::get(h.handler_, c); }
link/modules/asio-standalone/asio/include/asio/impl/read.hpp view
@@ -2,7 +2,7 @@ // impl/read.hpp // ~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -24,7 +24,9 @@ #include "asio/detail/bind_handler.hpp" #include "asio/detail/consuming_buffers.hpp" #include "asio/detail/dependent_type.hpp"+#include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_cont_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_tracking.hpp" #include "asio/detail/handler_type_requirements.hpp" #include "asio/detail/non_const_lvalue.hpp"@@ -62,23 +64,20 @@ typename CompletionCondition> std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers, CompletionCondition completion_condition, asio::error_code& ec,- constraint_t<+ typename constraint< is_mutable_buffer_sequence<MutableBufferSequence>::value- >,- constraint_t<- is_completion_condition<CompletionCondition>::value- >)+ >::type) { return detail::read_buffer_seq(s, buffers, asio::buffer_sequence_begin(buffers),- static_cast<CompletionCondition&&>(completion_condition), ec);+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec); } template <typename SyncReadStream, typename MutableBufferSequence> inline std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers,- constraint_t<+ typename constraint< is_mutable_buffer_sequence<MutableBufferSequence>::value- >)+ >::type) { asio::error_code ec; std::size_t bytes_transferred = read(s, buffers, transfer_all(), ec);@@ -89,9 +88,9 @@ template <typename SyncReadStream, typename MutableBufferSequence> inline std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers, asio::error_code& ec,- constraint_t<+ typename constraint< is_mutable_buffer_sequence<MutableBufferSequence>::value- >)+ >::type) { return read(s, buffers, transfer_all(), ec); }@@ -100,16 +99,13 @@ typename CompletionCondition> inline std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers, CompletionCondition completion_condition,- constraint_t<+ typename constraint< is_mutable_buffer_sequence<MutableBufferSequence>::value- >,- constraint_t<- is_completion_condition<CompletionCondition>::value- >)+ >::type) { asio::error_code ec; std::size_t bytes_transferred = read(s, buffers,- static_cast<CompletionCondition&&>(completion_condition), ec);+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec); asio::detail::throw_error(ec, "read"); return bytes_transferred; }@@ -119,20 +115,17 @@ template <typename SyncReadStream, typename DynamicBuffer_v1, typename CompletionCondition> std::size_t read(SyncReadStream& s,- DynamicBuffer_v1&& buffers,+ ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, CompletionCondition completion_condition, asio::error_code& ec,- constraint_t<- is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value- >,- constraint_t<- !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value- >,- constraint_t<- is_completion_condition<CompletionCondition>::value- >)+ typename constraint<+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+ >::type,+ typename constraint<+ !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+ >::type) {- decay_t<DynamicBuffer_v1> b(- static_cast<DynamicBuffer_v1&&>(buffers));+ typename decay<DynamicBuffer_v1>::type b(+ ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers)); ec = asio::error_code(); std::size_t total_transferred = 0;@@ -157,55 +150,52 @@ template <typename SyncReadStream, typename DynamicBuffer_v1> inline std::size_t read(SyncReadStream& s,- DynamicBuffer_v1&& buffers,- constraint_t<- is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value- >,- constraint_t<- !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value- >)+ ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+ typename constraint<+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+ >::type,+ typename constraint<+ !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+ >::type) { asio::error_code ec; std::size_t bytes_transferred = read(s,- static_cast<DynamicBuffer_v1&&>(buffers), transfer_all(), ec);+ ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), transfer_all(), ec); asio::detail::throw_error(ec, "read"); return bytes_transferred; } template <typename SyncReadStream, typename DynamicBuffer_v1> inline std::size_t read(SyncReadStream& s,- DynamicBuffer_v1&& buffers,+ ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, asio::error_code& ec,- constraint_t<- is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value- >,- constraint_t<- !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value- >)+ typename constraint<+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+ >::type,+ typename constraint<+ !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+ >::type) {- return read(s, static_cast<DynamicBuffer_v1&&>(buffers),+ return read(s, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), transfer_all(), ec); } template <typename SyncReadStream, typename DynamicBuffer_v1, typename CompletionCondition> inline std::size_t read(SyncReadStream& s,- DynamicBuffer_v1&& buffers,+ ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, CompletionCondition completion_condition,- constraint_t<- is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value- >,- constraint_t<- !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value- >,- constraint_t<- is_completion_condition<CompletionCondition>::value- >)+ typename constraint<+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+ >::type,+ typename constraint<+ !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+ >::type) { asio::error_code ec; std::size_t bytes_transferred = read(s,- static_cast<DynamicBuffer_v1&&>(buffers),- static_cast<CompletionCondition&&>(completion_condition), ec);+ ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec); asio::detail::throw_error(ec, "read"); return bytes_transferred; }@@ -217,13 +207,10 @@ typename CompletionCondition> inline std::size_t read(SyncReadStream& s, asio::basic_streambuf<Allocator>& b,- CompletionCondition completion_condition, asio::error_code& ec,- constraint_t<- is_completion_condition<CompletionCondition>::value- >)+ CompletionCondition completion_condition, asio::error_code& ec) { return read(s, basic_streambuf_ref<Allocator>(b),- static_cast<CompletionCondition&&>(completion_condition), ec);+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec); } template <typename SyncReadStream, typename Allocator>@@ -245,13 +232,10 @@ typename CompletionCondition> inline std::size_t read(SyncReadStream& s, asio::basic_streambuf<Allocator>& b,- CompletionCondition completion_condition,- constraint_t<- is_completion_condition<CompletionCondition>::value- >)+ CompletionCondition completion_condition) { return read(s, basic_streambuf_ref<Allocator>(b),- static_cast<CompletionCondition&&>(completion_condition));+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition)); } #endif // !defined(ASIO_NO_IOSTREAM)@@ -262,12 +246,9 @@ typename CompletionCondition> std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers, CompletionCondition completion_condition, asio::error_code& ec,- constraint_t<+ typename constraint< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- >,- constraint_t<- is_completion_condition<CompletionCondition>::value- >)+ >::type) { DynamicBuffer_v2& b = buffers; @@ -297,13 +278,13 @@ template <typename SyncReadStream, typename DynamicBuffer_v2> inline std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers,- constraint_t<+ typename constraint< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- >)+ >::type) { asio::error_code ec; std::size_t bytes_transferred = read(s,- static_cast<DynamicBuffer_v2&&>(buffers), transfer_all(), ec);+ ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), transfer_all(), ec); asio::detail::throw_error(ec, "read"); return bytes_transferred; }@@ -311,11 +292,11 @@ template <typename SyncReadStream, typename DynamicBuffer_v2> inline std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers, asio::error_code& ec,- constraint_t<+ typename constraint< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- >)+ >::type) {- return read(s, static_cast<DynamicBuffer_v2&&>(buffers),+ return read(s, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), transfer_all(), ec); } @@ -323,17 +304,14 @@ typename CompletionCondition> inline std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers, CompletionCondition completion_condition,- constraint_t<+ typename constraint< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- >,- constraint_t<- is_completion_condition<CompletionCondition>::value- >)+ >::type) { asio::error_code ec; std::size_t bytes_transferred = read(s,- static_cast<DynamicBuffer_v2&&>(buffers),- static_cast<CompletionCondition&&>(completion_condition), ec);+ ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec); asio::detail::throw_error(ec, "read"); return bytes_transferred; }@@ -356,10 +334,11 @@ stream_(stream), buffers_(buffers), start_(0),- handler_(static_cast<ReadHandler&&>(handler))+ handler_(ASIO_MOVE_CAST(ReadHandler)(handler)) { } +#if defined(ASIO_HAS_MOVE) read_op(const read_op& other) : base_from_cancellation_state<ReadHandler>(other), base_from_completion_cond<CompletionCondition>(other),@@ -372,15 +351,18 @@ read_op(read_op&& other) : base_from_cancellation_state<ReadHandler>(- static_cast<base_from_cancellation_state<ReadHandler>&&>(other)),+ ASIO_MOVE_CAST(base_from_cancellation_state<+ ReadHandler>)(other)), base_from_completion_cond<CompletionCondition>(- static_cast<base_from_completion_cond<CompletionCondition>&&>(other)),+ ASIO_MOVE_CAST(base_from_completion_cond<+ CompletionCondition>)(other)), stream_(other.stream_),- buffers_(static_cast<buffers_type&&>(other.buffers_)),+ buffers_(ASIO_MOVE_CAST(buffers_type)(other.buffers_)), start_(other.start_),- handler_(static_cast<ReadHandler&&>(other.handler_))+ handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_)) { }+#endif // defined(ASIO_HAS_MOVE) void operator()(asio::error_code ec, std::size_t bytes_transferred, int start = 0)@@ -395,7 +377,7 @@ { ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_read")); stream_.async_read_some(buffers_.prepare(max_size),- static_cast<read_op&&>(*this));+ ASIO_MOVE_CAST(read_op)(*this)); } return; default: buffers_.consume(bytes_transferred);@@ -411,7 +393,7 @@ } } - static_cast<ReadHandler&&>(handler_)(+ ASIO_MOVE_OR_LVALUE(ReadHandler)(handler_)( static_cast<const asio::error_code&>(ec), static_cast<const std::size_t&>(buffers_.total_consumed())); }@@ -430,6 +412,38 @@ template <typename AsyncReadStream, typename MutableBufferSequence, typename MutableBufferIterator, typename CompletionCondition, typename ReadHandler>+ inline asio_handler_allocate_is_deprecated+ asio_handler_allocate(std::size_t size,+ read_op<AsyncReadStream, MutableBufferSequence, MutableBufferIterator,+ CompletionCondition, ReadHandler>* this_handler)+ {+#if defined(ASIO_NO_DEPRECATED)+ asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+ return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+ return asio_handler_alloc_helpers::allocate(+ size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename AsyncReadStream, typename MutableBufferSequence,+ typename MutableBufferIterator, typename CompletionCondition,+ typename ReadHandler>+ inline asio_handler_deallocate_is_deprecated+ asio_handler_deallocate(void* pointer, std::size_t size,+ read_op<AsyncReadStream, MutableBufferSequence, MutableBufferIterator,+ CompletionCondition, ReadHandler>* this_handler)+ {+ asio_handler_alloc_helpers::deallocate(+ pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename AsyncReadStream, typename MutableBufferSequence,+ typename MutableBufferIterator, typename CompletionCondition,+ typename ReadHandler> inline bool asio_handler_is_continuation( read_op<AsyncReadStream, MutableBufferSequence, MutableBufferIterator, CompletionCondition, ReadHandler>* this_handler)@@ -439,6 +453,36 @@ this_handler->handler_); } + template <typename Function, typename AsyncReadStream,+ typename MutableBufferSequence, typename MutableBufferIterator,+ typename CompletionCondition, typename ReadHandler>+ inline asio_handler_invoke_is_deprecated+ asio_handler_invoke(Function& function,+ read_op<AsyncReadStream, MutableBufferSequence, MutableBufferIterator,+ CompletionCondition, ReadHandler>* this_handler)+ {+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename Function, typename AsyncReadStream,+ typename MutableBufferSequence, typename MutableBufferIterator,+ typename CompletionCondition, typename ReadHandler>+ inline asio_handler_invoke_is_deprecated+ asio_handler_invoke(const Function& function,+ read_op<AsyncReadStream, MutableBufferSequence, MutableBufferIterator,+ CompletionCondition, ReadHandler>* this_handler)+ {+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }+ template <typename AsyncReadStream, typename MutableBufferSequence, typename MutableBufferIterator, typename CompletionCondition, typename ReadHandler>@@ -463,16 +507,16 @@ { } - executor_type get_executor() const noexcept+ executor_type get_executor() const ASIO_NOEXCEPT { return stream_.get_executor(); } template <typename ReadHandler, typename MutableBufferSequence, typename CompletionCondition>- void operator()(ReadHandler&& handler,+ void operator()(ASIO_MOVE_ARG(ReadHandler) handler, const MutableBufferSequence& buffers,- CompletionCondition&& completion_cond) const+ ASIO_MOVE_ARG(CompletionCondition) completion_cond) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a ReadHandler.@@ -502,18 +546,21 @@ DefaultCandidate> : Associator<ReadHandler, DefaultCandidate> {- static typename Associator<ReadHandler, DefaultCandidate>::type get(- const detail::read_op<AsyncReadStream, MutableBufferSequence,- MutableBufferIterator, CompletionCondition, ReadHandler>& h) noexcept+ static typename Associator<ReadHandler, DefaultCandidate>::type+ get(const detail::read_op<AsyncReadStream, MutableBufferSequence,+ MutableBufferIterator, CompletionCondition, ReadHandler>& h)+ ASIO_NOEXCEPT { return Associator<ReadHandler, DefaultCandidate>::get(h.handler_); } - static auto get(- const detail::read_op<AsyncReadStream, MutableBufferSequence,+ static ASIO_AUTO_RETURN_TYPE_PREFIX2(+ typename Associator<ReadHandler, DefaultCandidate>::type)+ get(const detail::read_op<AsyncReadStream, MutableBufferSequence, MutableBufferIterator, CompletionCondition, ReadHandler>& h,- const DefaultCandidate& c) noexcept- -> decltype(Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c))+ const DefaultCandidate& c) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c))) { return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c); }@@ -521,6 +568,54 @@ #endif // !defined(GENERATING_DOCUMENTATION) +template <typename AsyncReadStream,+ typename MutableBufferSequence, typename CompletionCondition,+ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+ std::size_t)) ReadToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+async_read(AsyncReadStream& s, const MutableBufferSequence& buffers,+ CompletionCondition completion_condition,+ ASIO_MOVE_ARG(ReadToken) token,+ typename constraint<+ is_mutable_buffer_sequence<MutableBufferSequence>::value+ >::type)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_initiate<ReadToken,+ void (asio::error_code, std::size_t)>(+ declval<detail::initiate_async_read<AsyncReadStream> >(),+ token, buffers,+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition))))+{+ return async_initiate<ReadToken,+ void (asio::error_code, std::size_t)>(+ detail::initiate_async_read<AsyncReadStream>(s),+ token, buffers,+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition));+}++template <typename AsyncReadStream, typename MutableBufferSequence,+ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+ std::size_t)) ReadToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+async_read(AsyncReadStream& s, const MutableBufferSequence& buffers,+ ASIO_MOVE_ARG(ReadToken) token,+ typename constraint<+ is_mutable_buffer_sequence<MutableBufferSequence>::value+ >::type)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_initiate<ReadToken,+ void (asio::error_code, std::size_t)>(+ declval<detail::initiate_async_read<AsyncReadStream> >(),+ token, buffers, transfer_all())))+{+ return async_initiate<ReadToken,+ void (asio::error_code, std::size_t)>(+ detail::initiate_async_read<AsyncReadStream>(s),+ token, buffers, transfer_all());+}+ #if !defined(ASIO_NO_DYNAMIC_BUFFER_V1) namespace detail@@ -534,19 +629,20 @@ public: template <typename BufferSequence> read_dynbuf_v1_op(AsyncReadStream& stream,- BufferSequence&& buffers,+ ASIO_MOVE_ARG(BufferSequence) buffers, CompletionCondition& completion_condition, ReadHandler& handler) : base_from_cancellation_state<ReadHandler>( handler, enable_partial_cancellation()), base_from_completion_cond<CompletionCondition>(completion_condition), stream_(stream),- buffers_(static_cast<BufferSequence&&>(buffers)),+ buffers_(ASIO_MOVE_CAST(BufferSequence)(buffers)), start_(0), total_transferred_(0),- handler_(static_cast<ReadHandler&&>(handler))+ handler_(ASIO_MOVE_CAST(ReadHandler)(handler)) { } +#if defined(ASIO_HAS_MOVE) read_dynbuf_v1_op(const read_dynbuf_v1_op& other) : base_from_cancellation_state<ReadHandler>(other), base_from_completion_cond<CompletionCondition>(other),@@ -560,16 +656,19 @@ read_dynbuf_v1_op(read_dynbuf_v1_op&& other) : base_from_cancellation_state<ReadHandler>(- static_cast<base_from_cancellation_state<ReadHandler>&&>(other)),+ ASIO_MOVE_CAST(base_from_cancellation_state<+ ReadHandler>)(other)), base_from_completion_cond<CompletionCondition>(- static_cast<base_from_completion_cond<CompletionCondition>&&>(other)),+ ASIO_MOVE_CAST(base_from_completion_cond<+ CompletionCondition>)(other)), stream_(other.stream_),- buffers_(static_cast<DynamicBuffer_v1&&>(other.buffers_)),+ buffers_(ASIO_MOVE_CAST(DynamicBuffer_v1)(other.buffers_)), start_(other.start_), total_transferred_(other.total_transferred_),- handler_(static_cast<ReadHandler&&>(other.handler_))+ handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_)) { }+#endif // defined(ASIO_HAS_MOVE) void operator()(asio::error_code ec, std::size_t bytes_transferred, int start = 0)@@ -589,7 +688,7 @@ { ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_read")); stream_.async_read_some(buffers_.prepare(bytes_available),- static_cast<read_dynbuf_v1_op&&>(*this));+ ASIO_MOVE_CAST(read_dynbuf_v1_op)(*this)); } return; default: total_transferred_ += bytes_transferred;@@ -609,7 +708,7 @@ } } - static_cast<ReadHandler&&>(handler_)(+ ASIO_MOVE_OR_LVALUE(ReadHandler)(handler_)( static_cast<const asio::error_code&>(ec), static_cast<const std::size_t&>(total_transferred_)); }@@ -625,6 +724,36 @@ template <typename AsyncReadStream, typename DynamicBuffer_v1, typename CompletionCondition, typename ReadHandler>+ inline asio_handler_allocate_is_deprecated+ asio_handler_allocate(std::size_t size,+ read_dynbuf_v1_op<AsyncReadStream, DynamicBuffer_v1,+ CompletionCondition, ReadHandler>* this_handler)+ {+#if defined(ASIO_NO_DEPRECATED)+ asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+ return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+ return asio_handler_alloc_helpers::allocate(+ size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename AsyncReadStream, typename DynamicBuffer_v1,+ typename CompletionCondition, typename ReadHandler>+ inline asio_handler_deallocate_is_deprecated+ asio_handler_deallocate(void* pointer, std::size_t size,+ read_dynbuf_v1_op<AsyncReadStream, DynamicBuffer_v1,+ CompletionCondition, ReadHandler>* this_handler)+ {+ asio_handler_alloc_helpers::deallocate(+ pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename AsyncReadStream, typename DynamicBuffer_v1,+ typename CompletionCondition, typename ReadHandler> inline bool asio_handler_is_continuation( read_dynbuf_v1_op<AsyncReadStream, DynamicBuffer_v1, CompletionCondition, ReadHandler>* this_handler)@@ -634,6 +763,36 @@ this_handler->handler_); } + template <typename Function, typename AsyncReadStream,+ typename DynamicBuffer_v1, typename CompletionCondition,+ typename ReadHandler>+ inline asio_handler_invoke_is_deprecated+ asio_handler_invoke(Function& function,+ read_dynbuf_v1_op<AsyncReadStream, DynamicBuffer_v1,+ CompletionCondition, ReadHandler>* this_handler)+ {+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename Function, typename AsyncReadStream,+ typename DynamicBuffer_v1, typename CompletionCondition,+ typename ReadHandler>+ inline asio_handler_invoke_is_deprecated+ asio_handler_invoke(const Function& function,+ read_dynbuf_v1_op<AsyncReadStream, DynamicBuffer_v1,+ CompletionCondition, ReadHandler>* this_handler)+ {+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }+ template <typename AsyncReadStream> class initiate_async_read_dynbuf_v1 {@@ -645,16 +804,16 @@ { } - executor_type get_executor() const noexcept+ executor_type get_executor() const ASIO_NOEXCEPT { return stream_.get_executor(); } template <typename ReadHandler, typename DynamicBuffer_v1, typename CompletionCondition>- void operator()(ReadHandler&& handler,- DynamicBuffer_v1&& buffers,- CompletionCondition&& completion_cond) const+ void operator()(ASIO_MOVE_ARG(ReadHandler) handler,+ ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+ ASIO_MOVE_ARG(CompletionCondition) completion_cond) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a ReadHandler.@@ -662,9 +821,9 @@ non_const_lvalue<ReadHandler> handler2(handler); non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);- read_dynbuf_v1_op<AsyncReadStream, decay_t<DynamicBuffer_v1>,- CompletionCondition, decay_t<ReadHandler>>(- stream_, static_cast<DynamicBuffer_v1&&>(buffers),+ read_dynbuf_v1_op<AsyncReadStream, typename decay<DynamicBuffer_v1>::type,+ CompletionCondition, typename decay<ReadHandler>::type>(+ stream_, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), completion_cond2.value, handler2.value)( asio::error_code(), 0, 1); }@@ -686,18 +845,20 @@ DefaultCandidate> : Associator<ReadHandler, DefaultCandidate> {- static typename Associator<ReadHandler, DefaultCandidate>::type get(- const detail::read_dynbuf_v1_op<AsyncReadStream, DynamicBuffer_v1,- CompletionCondition, ReadHandler>& h) noexcept+ static typename Associator<ReadHandler, DefaultCandidate>::type+ get(const detail::read_dynbuf_v1_op<AsyncReadStream, DynamicBuffer_v1,+ CompletionCondition, ReadHandler>& h) ASIO_NOEXCEPT { return Associator<ReadHandler, DefaultCandidate>::get(h.handler_); } - static auto get(- const detail::read_dynbuf_v1_op<AsyncReadStream,+ static ASIO_AUTO_RETURN_TYPE_PREFIX2(+ typename Associator<ReadHandler, DefaultCandidate>::type)+ get(const detail::read_dynbuf_v1_op<AsyncReadStream, DynamicBuffer_v1, CompletionCondition, ReadHandler>& h,- const DefaultCandidate& c) noexcept- -> decltype(Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c))+ const DefaultCandidate& c) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c))) { return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c); }@@ -705,6 +866,103 @@ #endif // !defined(GENERATING_DOCUMENTATION) +template <typename AsyncReadStream, typename DynamicBuffer_v1,+ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+ std::size_t)) ReadToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+async_read(AsyncReadStream& s,+ ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+ ASIO_MOVE_ARG(ReadToken) token,+ typename constraint<+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+ >::type,+ typename constraint<+ !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+ >::type)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_initiate<ReadToken,+ void (asio::error_code, std::size_t)>(+ declval<detail::initiate_async_read_dynbuf_v1<AsyncReadStream> >(),+ token, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+ transfer_all())))+{+ return async_initiate<ReadToken,+ void (asio::error_code, std::size_t)>(+ detail::initiate_async_read_dynbuf_v1<AsyncReadStream>(s),+ token, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+ transfer_all());+}++template <typename AsyncReadStream,+ typename DynamicBuffer_v1, typename CompletionCondition,+ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+ std::size_t)) ReadToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+async_read(AsyncReadStream& s,+ ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+ CompletionCondition completion_condition,+ ASIO_MOVE_ARG(ReadToken) token,+ typename constraint<+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+ >::type,+ typename constraint<+ !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+ >::type)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_initiate<ReadToken,+ void (asio::error_code, std::size_t)>(+ declval<detail::initiate_async_read_dynbuf_v1<AsyncReadStream> >(),+ token, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition))))+{+ return async_initiate<ReadToken,+ void (asio::error_code, std::size_t)>(+ detail::initiate_async_read_dynbuf_v1<AsyncReadStream>(s),+ token, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition));+}++#if !defined(ASIO_NO_EXTENSIONS)+#if !defined(ASIO_NO_IOSTREAM)++template <typename AsyncReadStream, typename Allocator,+ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+ std::size_t)) ReadToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+async_read(AsyncReadStream& s, basic_streambuf<Allocator>& b,+ ASIO_MOVE_ARG(ReadToken) token)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_read(s, basic_streambuf_ref<Allocator>(b),+ ASIO_MOVE_CAST(ReadToken)(token))))+{+ return async_read(s, basic_streambuf_ref<Allocator>(b),+ ASIO_MOVE_CAST(ReadToken)(token));+}++template <typename AsyncReadStream,+ typename Allocator, typename CompletionCondition,+ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+ std::size_t)) ReadToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+async_read(AsyncReadStream& s, basic_streambuf<Allocator>& b,+ CompletionCondition completion_condition,+ ASIO_MOVE_ARG(ReadToken) token)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_read(s, basic_streambuf_ref<Allocator>(b),+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition),+ ASIO_MOVE_CAST(ReadToken)(token))))+{+ return async_read(s, basic_streambuf_ref<Allocator>(b),+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition),+ ASIO_MOVE_CAST(ReadToken)(token));+}++#endif // !defined(ASIO_NO_IOSTREAM)+#endif // !defined(ASIO_NO_EXTENSIONS) #endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1) namespace detail@@ -718,20 +976,21 @@ public: template <typename BufferSequence> read_dynbuf_v2_op(AsyncReadStream& stream,- BufferSequence&& buffers,+ ASIO_MOVE_ARG(BufferSequence) buffers, CompletionCondition& completion_condition, ReadHandler& handler) : base_from_cancellation_state<ReadHandler>( handler, enable_partial_cancellation()), base_from_completion_cond<CompletionCondition>(completion_condition), stream_(stream),- buffers_(static_cast<BufferSequence&&>(buffers)),+ buffers_(ASIO_MOVE_CAST(BufferSequence)(buffers)), start_(0), total_transferred_(0), bytes_available_(0),- handler_(static_cast<ReadHandler&&>(handler))+ handler_(ASIO_MOVE_CAST(ReadHandler)(handler)) { } +#if defined(ASIO_HAS_MOVE) read_dynbuf_v2_op(const read_dynbuf_v2_op& other) : base_from_cancellation_state<ReadHandler>(other), base_from_completion_cond<CompletionCondition>(other),@@ -746,17 +1005,20 @@ read_dynbuf_v2_op(read_dynbuf_v2_op&& other) : base_from_cancellation_state<ReadHandler>(- static_cast<base_from_cancellation_state<ReadHandler>&&>(other)),+ ASIO_MOVE_CAST(base_from_cancellation_state<+ ReadHandler>)(other)), base_from_completion_cond<CompletionCondition>(- static_cast<base_from_completion_cond<CompletionCondition>&&>(other)),+ ASIO_MOVE_CAST(base_from_completion_cond<+ CompletionCondition>)(other)), stream_(other.stream_),- buffers_(static_cast<DynamicBuffer_v2&&>(other.buffers_)),+ buffers_(ASIO_MOVE_CAST(DynamicBuffer_v2)(other.buffers_)), start_(other.start_), total_transferred_(other.total_transferred_), bytes_available_(other.bytes_available_),- handler_(static_cast<ReadHandler&&>(other.handler_))+ handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_)) { }+#endif // defined(ASIO_HAS_MOVE) void operator()(asio::error_code ec, std::size_t bytes_transferred, int start = 0)@@ -778,7 +1040,7 @@ { ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_read")); stream_.async_read_some(buffers_.data(pos, bytes_available_),- static_cast<read_dynbuf_v2_op&&>(*this));+ ASIO_MOVE_CAST(read_dynbuf_v2_op)(*this)); } return; default: total_transferred_ += bytes_transferred;@@ -798,7 +1060,7 @@ } } - static_cast<ReadHandler&&>(handler_)(+ ASIO_MOVE_OR_LVALUE(ReadHandler)(handler_)( static_cast<const asio::error_code&>(ec), static_cast<const std::size_t&>(total_transferred_)); }@@ -815,6 +1077,36 @@ template <typename AsyncReadStream, typename DynamicBuffer_v2, typename CompletionCondition, typename ReadHandler>+ inline asio_handler_allocate_is_deprecated+ asio_handler_allocate(std::size_t size,+ read_dynbuf_v2_op<AsyncReadStream, DynamicBuffer_v2,+ CompletionCondition, ReadHandler>* this_handler)+ {+#if defined(ASIO_NO_DEPRECATED)+ asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+ return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+ return asio_handler_alloc_helpers::allocate(+ size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename AsyncReadStream, typename DynamicBuffer_v2,+ typename CompletionCondition, typename ReadHandler>+ inline asio_handler_deallocate_is_deprecated+ asio_handler_deallocate(void* pointer, std::size_t size,+ read_dynbuf_v2_op<AsyncReadStream, DynamicBuffer_v2,+ CompletionCondition, ReadHandler>* this_handler)+ {+ asio_handler_alloc_helpers::deallocate(+ pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename AsyncReadStream, typename DynamicBuffer_v2,+ typename CompletionCondition, typename ReadHandler> inline bool asio_handler_is_continuation( read_dynbuf_v2_op<AsyncReadStream, DynamicBuffer_v2, CompletionCondition, ReadHandler>* this_handler)@@ -824,6 +1116,36 @@ this_handler->handler_); } + template <typename Function, typename AsyncReadStream,+ typename DynamicBuffer_v2, typename CompletionCondition,+ typename ReadHandler>+ inline asio_handler_invoke_is_deprecated+ asio_handler_invoke(Function& function,+ read_dynbuf_v2_op<AsyncReadStream, DynamicBuffer_v2,+ CompletionCondition, ReadHandler>* this_handler)+ {+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename Function, typename AsyncReadStream,+ typename DynamicBuffer_v2, typename CompletionCondition,+ typename ReadHandler>+ inline asio_handler_invoke_is_deprecated+ asio_handler_invoke(const Function& function,+ read_dynbuf_v2_op<AsyncReadStream, DynamicBuffer_v2,+ CompletionCondition, ReadHandler>* this_handler)+ {+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }+ template <typename AsyncReadStream> class initiate_async_read_dynbuf_v2 {@@ -835,16 +1157,16 @@ { } - executor_type get_executor() const noexcept+ executor_type get_executor() const ASIO_NOEXCEPT { return stream_.get_executor(); } template <typename ReadHandler, typename DynamicBuffer_v2, typename CompletionCondition>- void operator()(ReadHandler&& handler,- DynamicBuffer_v2&& buffers,- CompletionCondition&& completion_cond) const+ void operator()(ASIO_MOVE_ARG(ReadHandler) handler,+ ASIO_MOVE_ARG(DynamicBuffer_v2) buffers,+ ASIO_MOVE_ARG(CompletionCondition) completion_cond) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a ReadHandler.@@ -852,9 +1174,9 @@ non_const_lvalue<ReadHandler> handler2(handler); non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);- read_dynbuf_v2_op<AsyncReadStream, decay_t<DynamicBuffer_v2>,- CompletionCondition, decay_t<ReadHandler>>(- stream_, static_cast<DynamicBuffer_v2&&>(buffers),+ read_dynbuf_v2_op<AsyncReadStream, typename decay<DynamicBuffer_v2>::type,+ CompletionCondition, typename decay<ReadHandler>::type>(+ stream_, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), completion_cond2.value, handler2.value)( asio::error_code(), 0, 1); }@@ -876,24 +1198,76 @@ DefaultCandidate> : Associator<ReadHandler, DefaultCandidate> {- static typename Associator<ReadHandler, DefaultCandidate>::type get(- const detail::read_dynbuf_v2_op<AsyncReadStream, DynamicBuffer_v2,- CompletionCondition, ReadHandler>& h) noexcept+ static typename Associator<ReadHandler, DefaultCandidate>::type+ get(const detail::read_dynbuf_v2_op<AsyncReadStream, DynamicBuffer_v2,+ CompletionCondition, ReadHandler>& h) ASIO_NOEXCEPT { return Associator<ReadHandler, DefaultCandidate>::get(h.handler_); } - static auto get(- const detail::read_dynbuf_v2_op<AsyncReadStream,+ static ASIO_AUTO_RETURN_TYPE_PREFIX2(+ typename Associator<ReadHandler, DefaultCandidate>::type)+ get(const detail::read_dynbuf_v2_op<AsyncReadStream, DynamicBuffer_v2, CompletionCondition, ReadHandler>& h,- const DefaultCandidate& c) noexcept- -> decltype(Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c))+ const DefaultCandidate& c) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c))) { return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c); } }; #endif // !defined(GENERATING_DOCUMENTATION)++template <typename AsyncReadStream, typename DynamicBuffer_v2,+ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+ std::size_t)) ReadToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+async_read(AsyncReadStream& s, DynamicBuffer_v2 buffers,+ ASIO_MOVE_ARG(ReadToken) token,+ typename constraint<+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value+ >::type)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_initiate<ReadToken,+ void (asio::error_code, std::size_t)>(+ declval<detail::initiate_async_read_dynbuf_v2<AsyncReadStream> >(),+ token, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+ transfer_all())))+{+ return async_initiate<ReadToken,+ void (asio::error_code, std::size_t)>(+ detail::initiate_async_read_dynbuf_v2<AsyncReadStream>(s),+ token, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+ transfer_all());+}++template <typename AsyncReadStream,+ typename DynamicBuffer_v2, typename CompletionCondition,+ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+ std::size_t)) ReadToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+async_read(AsyncReadStream& s, DynamicBuffer_v2 buffers,+ CompletionCondition completion_condition,+ ASIO_MOVE_ARG(ReadToken) token,+ typename constraint<+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value+ >::type)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_initiate<ReadToken,+ void (asio::error_code, std::size_t)>(+ declval<detail::initiate_async_read_dynbuf_v2<AsyncReadStream> >(),+ token, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition))))+{+ return async_initiate<ReadToken,+ void (asio::error_code, std::size_t)>(+ detail::initiate_async_read_dynbuf_v2<AsyncReadStream>(s),+ token, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition));+} } // namespace asio
link/modules/asio-standalone/asio/include/asio/impl/read_at.hpp view
@@ -2,7 +2,7 @@ // impl/read_at.hpp // ~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -24,7 +24,9 @@ #include "asio/detail/bind_handler.hpp" #include "asio/detail/consuming_buffers.hpp" #include "asio/detail/dependent_type.hpp"+#include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_cont_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_tracking.hpp" #include "asio/detail/handler_type_requirements.hpp" #include "asio/detail/non_const_lvalue.hpp"@@ -66,14 +68,11 @@ typename CompletionCondition> std::size_t read_at(SyncRandomAccessReadDevice& d, uint64_t offset, const MutableBufferSequence& buffers,- CompletionCondition completion_condition, asio::error_code& ec,- constraint_t<- is_completion_condition<CompletionCondition>::value- >)+ CompletionCondition completion_condition, asio::error_code& ec) { return detail::read_at_buffer_sequence(d, offset, buffers, asio::buffer_sequence_begin(buffers),- static_cast<CompletionCondition&&>(completion_condition), ec);+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec); } template <typename SyncRandomAccessReadDevice, typename MutableBufferSequence>@@ -99,14 +98,11 @@ typename CompletionCondition> inline std::size_t read_at(SyncRandomAccessReadDevice& d, uint64_t offset, const MutableBufferSequence& buffers,- CompletionCondition completion_condition,- constraint_t<- is_completion_condition<CompletionCondition>::value- >)+ CompletionCondition completion_condition) { asio::error_code ec; std::size_t bytes_transferred = read_at(d, offset, buffers,- static_cast<CompletionCondition&&>(completion_condition), ec);+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec); asio::detail::throw_error(ec, "read_at"); return bytes_transferred; }@@ -118,10 +114,7 @@ typename CompletionCondition> std::size_t read_at(SyncRandomAccessReadDevice& d, uint64_t offset, asio::basic_streambuf<Allocator>& b,- CompletionCondition completion_condition, asio::error_code& ec,- constraint_t<- is_completion_condition<CompletionCondition>::value- >)+ CompletionCondition completion_condition, asio::error_code& ec) { ec = asio::error_code(); std::size_t total_transferred = 0;@@ -164,14 +157,11 @@ typename CompletionCondition> inline std::size_t read_at(SyncRandomAccessReadDevice& d, uint64_t offset, asio::basic_streambuf<Allocator>& b,- CompletionCondition completion_condition,- constraint_t<- is_completion_condition<CompletionCondition>::value- >)+ CompletionCondition completion_condition) { asio::error_code ec; std::size_t bytes_transferred = read_at(d, offset, b,- static_cast<CompletionCondition&&>(completion_condition), ec);+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec); asio::detail::throw_error(ec, "read_at"); return bytes_transferred; }@@ -199,10 +189,11 @@ offset_(offset), buffers_(buffers), start_(0),- handler_(static_cast<ReadHandler&&>(handler))+ handler_(ASIO_MOVE_CAST(ReadHandler)(handler)) { } +#if defined(ASIO_HAS_MOVE) read_at_op(const read_at_op& other) : base_from_cancellation_state<ReadHandler>(other), base_from_completion_cond<CompletionCondition>(other),@@ -216,16 +207,19 @@ read_at_op(read_at_op&& other) : base_from_cancellation_state<ReadHandler>(- static_cast<base_from_cancellation_state<ReadHandler>&&>(other)),+ ASIO_MOVE_CAST(base_from_cancellation_state<+ ReadHandler>)(other)), base_from_completion_cond<CompletionCondition>(- static_cast<base_from_completion_cond<CompletionCondition>&&>(other)),+ ASIO_MOVE_CAST(base_from_completion_cond<+ CompletionCondition>)(other)), device_(other.device_), offset_(other.offset_),- buffers_(static_cast<buffers_type&&>(other.buffers_)),+ buffers_(ASIO_MOVE_CAST(buffers_type)(other.buffers_)), start_(other.start_),- handler_(static_cast<ReadHandler&&>(other.handler_))+ handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_)) { }+#endif // defined(ASIO_HAS_MOVE) void operator()(asio::error_code ec, std::size_t bytes_transferred, int start = 0)@@ -241,7 +235,7 @@ ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_read_at")); device_.async_read_some_at( offset_ + buffers_.total_consumed(), buffers_.prepare(max_size),- static_cast<read_at_op&&>(*this));+ ASIO_MOVE_CAST(read_at_op)(*this)); } return; default: buffers_.consume(bytes_transferred);@@ -257,7 +251,7 @@ } } - static_cast<ReadHandler&&>(handler_)(+ ASIO_MOVE_OR_LVALUE(ReadHandler)(handler_)( static_cast<const asio::error_code&>(ec), static_cast<const std::size_t&>(buffers_.total_consumed())); }@@ -277,6 +271,38 @@ template <typename AsyncRandomAccessReadDevice, typename MutableBufferSequence, typename MutableBufferIterator, typename CompletionCondition, typename ReadHandler>+ inline asio_handler_allocate_is_deprecated+ asio_handler_allocate(std::size_t size,+ read_at_op<AsyncRandomAccessReadDevice, MutableBufferSequence,+ MutableBufferIterator, CompletionCondition, ReadHandler>* this_handler)+ {+#if defined(ASIO_NO_DEPRECATED)+ asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+ return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+ return asio_handler_alloc_helpers::allocate(+ size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename AsyncRandomAccessReadDevice,+ typename MutableBufferSequence, typename MutableBufferIterator,+ typename CompletionCondition, typename ReadHandler>+ inline asio_handler_deallocate_is_deprecated+ asio_handler_deallocate(void* pointer, std::size_t size,+ read_at_op<AsyncRandomAccessReadDevice, MutableBufferSequence,+ MutableBufferIterator, CompletionCondition, ReadHandler>* this_handler)+ {+ asio_handler_alloc_helpers::deallocate(+ pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename AsyncRandomAccessReadDevice,+ typename MutableBufferSequence, typename MutableBufferIterator,+ typename CompletionCondition, typename ReadHandler> inline bool asio_handler_is_continuation( read_at_op<AsyncRandomAccessReadDevice, MutableBufferSequence, MutableBufferIterator, CompletionCondition, ReadHandler>* this_handler)@@ -286,6 +312,36 @@ this_handler->handler_); } + template <typename Function, typename AsyncRandomAccessReadDevice,+ typename MutableBufferSequence, typename MutableBufferIterator,+ typename CompletionCondition, typename ReadHandler>+ inline asio_handler_invoke_is_deprecated+ asio_handler_invoke(Function& function,+ read_at_op<AsyncRandomAccessReadDevice, MutableBufferSequence,+ MutableBufferIterator, CompletionCondition, ReadHandler>* this_handler)+ {+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename Function, typename AsyncRandomAccessReadDevice,+ typename MutableBufferSequence, typename MutableBufferIterator,+ typename CompletionCondition, typename ReadHandler>+ inline asio_handler_invoke_is_deprecated+ asio_handler_invoke(const Function& function,+ read_at_op<AsyncRandomAccessReadDevice, MutableBufferSequence,+ MutableBufferIterator, CompletionCondition, ReadHandler>* this_handler)+ {+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }+ template <typename AsyncRandomAccessReadDevice, typename MutableBufferSequence, typename MutableBufferIterator, typename CompletionCondition, typename ReadHandler>@@ -311,16 +367,16 @@ { } - executor_type get_executor() const noexcept+ executor_type get_executor() const ASIO_NOEXCEPT { return device_.get_executor(); } template <typename ReadHandler, typename MutableBufferSequence, typename CompletionCondition>- void operator()(ReadHandler&& handler,+ void operator()(ASIO_MOVE_ARG(ReadHandler) handler, uint64_t offset, const MutableBufferSequence& buffers,- CompletionCondition&& completion_cond) const+ ASIO_MOVE_ARG(CompletionCondition) completion_cond) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a ReadHandler.@@ -350,20 +406,22 @@ DefaultCandidate> : Associator<ReadHandler, DefaultCandidate> {- static typename Associator<ReadHandler, DefaultCandidate>::type get(- const detail::read_at_op<AsyncRandomAccessReadDevice,+ static typename Associator<ReadHandler, DefaultCandidate>::type+ get(const detail::read_at_op<AsyncRandomAccessReadDevice, MutableBufferSequence, MutableBufferIterator,- CompletionCondition, ReadHandler>& h) noexcept+ CompletionCondition, ReadHandler>& h) ASIO_NOEXCEPT { return Associator<ReadHandler, DefaultCandidate>::get(h.handler_); } - static auto get(- const detail::read_at_op<AsyncRandomAccessReadDevice,+ static ASIO_AUTO_RETURN_TYPE_PREFIX2(+ typename Associator<ReadHandler, DefaultCandidate>::type)+ get(const detail::read_at_op<AsyncRandomAccessReadDevice, MutableBufferSequence, MutableBufferIterator, CompletionCondition, ReadHandler>& h,- const DefaultCandidate& c) noexcept- -> decltype(Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c))+ const DefaultCandidate& c) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c))) { return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c); }@@ -371,6 +429,50 @@ #endif // !defined(GENERATING_DOCUMENTATION) +template <typename AsyncRandomAccessReadDevice,+ typename MutableBufferSequence, typename CompletionCondition,+ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+ std::size_t)) ReadToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+async_read_at(AsyncRandomAccessReadDevice& d,+ uint64_t offset, const MutableBufferSequence& buffers,+ CompletionCondition completion_condition,+ ASIO_MOVE_ARG(ReadToken) token)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_initiate<ReadToken,+ void (asio::error_code, std::size_t)>(+ declval<detail::initiate_async_read_at<AsyncRandomAccessReadDevice> >(),+ token, offset, buffers,+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition))))+{+ return async_initiate<ReadToken,+ void (asio::error_code, std::size_t)>(+ detail::initiate_async_read_at<AsyncRandomAccessReadDevice>(d),+ token, offset, buffers,+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition));+}++template <typename AsyncRandomAccessReadDevice, typename MutableBufferSequence,+ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+ std::size_t)) ReadToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+async_read_at(AsyncRandomAccessReadDevice& d,+ uint64_t offset, const MutableBufferSequence& buffers,+ ASIO_MOVE_ARG(ReadToken) token)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_initiate<ReadToken,+ void (asio::error_code, std::size_t)>(+ declval<detail::initiate_async_read_at<AsyncRandomAccessReadDevice> >(),+ token, offset, buffers, transfer_all())))+{+ return async_initiate<ReadToken,+ void (asio::error_code, std::size_t)>(+ detail::initiate_async_read_at<AsyncRandomAccessReadDevice>(d),+ token, offset, buffers, transfer_all());+}+ #if !defined(ASIO_NO_EXTENSIONS) #if !defined(ASIO_NO_IOSTREAM) @@ -394,10 +496,11 @@ streambuf_(streambuf), start_(0), total_transferred_(0),- handler_(static_cast<ReadHandler&&>(handler))+ handler_(ASIO_MOVE_CAST(ReadHandler)(handler)) { } +#if defined(ASIO_HAS_MOVE) read_at_streambuf_op(const read_at_streambuf_op& other) : base_from_cancellation_state<ReadHandler>(other), base_from_completion_cond<CompletionCondition>(other),@@ -412,17 +515,20 @@ read_at_streambuf_op(read_at_streambuf_op&& other) : base_from_cancellation_state<ReadHandler>(- static_cast<base_from_cancellation_state<ReadHandler>&&>(other)),+ ASIO_MOVE_CAST(base_from_cancellation_state<+ ReadHandler>)(other)), base_from_completion_cond<CompletionCondition>(- static_cast<base_from_completion_cond<CompletionCondition>&&>(other)),+ ASIO_MOVE_CAST(base_from_completion_cond<+ CompletionCondition>)(other)), device_(other.device_), offset_(other.offset_), streambuf_(other.streambuf_), start_(other.start_), total_transferred_(other.total_transferred_),- handler_(static_cast<ReadHandler&&>(other.handler_))+ handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_)) { }+#endif // defined(ASIO_HAS_MOVE) void operator()(asio::error_code ec, std::size_t bytes_transferred, int start = 0)@@ -439,7 +545,7 @@ ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_read_at")); device_.async_read_some_at(offset_ + total_transferred_, streambuf_.prepare(bytes_available),- static_cast<read_at_streambuf_op&&>(*this));+ ASIO_MOVE_CAST(read_at_streambuf_op)(*this)); } return; default: total_transferred_ += bytes_transferred;@@ -455,7 +561,7 @@ } } - static_cast<ReadHandler&&>(handler_)(+ ASIO_MOVE_OR_LVALUE(ReadHandler)(handler_)( static_cast<const asio::error_code&>(ec), static_cast<const std::size_t&>(total_transferred_)); }@@ -472,6 +578,36 @@ template <typename AsyncRandomAccessReadDevice, typename Allocator, typename CompletionCondition, typename ReadHandler>+ inline asio_handler_allocate_is_deprecated+ asio_handler_allocate(std::size_t size,+ read_at_streambuf_op<AsyncRandomAccessReadDevice, Allocator,+ CompletionCondition, ReadHandler>* this_handler)+ {+#if defined(ASIO_NO_DEPRECATED)+ asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+ return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+ return asio_handler_alloc_helpers::allocate(+ size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename AsyncRandomAccessReadDevice, typename Allocator,+ typename CompletionCondition, typename ReadHandler>+ inline asio_handler_deallocate_is_deprecated+ asio_handler_deallocate(void* pointer, std::size_t size,+ read_at_streambuf_op<AsyncRandomAccessReadDevice, Allocator,+ CompletionCondition, ReadHandler>* this_handler)+ {+ asio_handler_alloc_helpers::deallocate(+ pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename AsyncRandomAccessReadDevice, typename Allocator,+ typename CompletionCondition, typename ReadHandler> inline bool asio_handler_is_continuation( read_at_streambuf_op<AsyncRandomAccessReadDevice, Allocator, CompletionCondition, ReadHandler>* this_handler)@@ -481,6 +617,34 @@ this_handler->handler_); } + template <typename Function, typename AsyncRandomAccessReadDevice,+ typename Allocator, typename CompletionCondition, typename ReadHandler>+ inline asio_handler_invoke_is_deprecated+ asio_handler_invoke(Function& function,+ read_at_streambuf_op<AsyncRandomAccessReadDevice, Allocator,+ CompletionCondition, ReadHandler>* this_handler)+ {+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename Function, typename AsyncRandomAccessReadDevice,+ typename Allocator, typename CompletionCondition, typename ReadHandler>+ inline asio_handler_invoke_is_deprecated+ asio_handler_invoke(const Function& function,+ read_at_streambuf_op<AsyncRandomAccessReadDevice, Allocator,+ CompletionCondition, ReadHandler>* this_handler)+ {+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }+ template <typename AsyncRandomAccessReadDevice> class initiate_async_read_at_streambuf {@@ -493,16 +657,16 @@ { } - executor_type get_executor() const noexcept+ executor_type get_executor() const ASIO_NOEXCEPT { return device_.get_executor(); } template <typename ReadHandler, typename Allocator, typename CompletionCondition>- void operator()(ReadHandler&& handler,+ void operator()(ASIO_MOVE_ARG(ReadHandler) handler, uint64_t offset, basic_streambuf<Allocator>* b,- CompletionCondition&& completion_cond) const+ ASIO_MOVE_ARG(CompletionCondition) completion_cond) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a ReadHandler.@@ -511,7 +675,7 @@ non_const_lvalue<ReadHandler> handler2(handler); non_const_lvalue<CompletionCondition> completion_cond2(completion_cond); read_at_streambuf_op<AsyncRandomAccessReadDevice, Allocator,- CompletionCondition, decay_t<ReadHandler>>(+ CompletionCondition, typename decay<ReadHandler>::type>( device_, offset, *b, completion_cond2.value, handler2.value)( asio::error_code(), 0, 1); }@@ -533,24 +697,72 @@ DefaultCandidate> : Associator<ReadHandler, DefaultCandidate> {- static typename Associator<ReadHandler, DefaultCandidate>::type get(- const detail::read_at_streambuf_op<AsyncRandomAccessReadDevice,- Executor, CompletionCondition, ReadHandler>& h) noexcept+ static typename Associator<ReadHandler, DefaultCandidate>::type+ get(const detail::read_at_streambuf_op<AsyncRandomAccessReadDevice,+ Executor, CompletionCondition, ReadHandler>& h) ASIO_NOEXCEPT { return Associator<ReadHandler, DefaultCandidate>::get(h.handler_); } - static auto get(- const detail::read_at_streambuf_op<AsyncRandomAccessReadDevice,+ static ASIO_AUTO_RETURN_TYPE_PREFIX2(+ typename Associator<ReadHandler, DefaultCandidate>::type)+ get(const detail::read_at_streambuf_op<AsyncRandomAccessReadDevice, Executor, CompletionCondition, ReadHandler>& h,- const DefaultCandidate& c) noexcept- -> decltype(Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c))+ const DefaultCandidate& c) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c))) { return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c); } }; #endif // !defined(GENERATING_DOCUMENTATION)++template <typename AsyncRandomAccessReadDevice,+ typename Allocator, typename CompletionCondition,+ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+ std::size_t)) ReadToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+async_read_at(AsyncRandomAccessReadDevice& d,+ uint64_t offset, asio::basic_streambuf<Allocator>& b,+ CompletionCondition completion_condition,+ ASIO_MOVE_ARG(ReadToken) token)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_initiate<ReadToken,+ void (asio::error_code, std::size_t)>(+ declval<detail::initiate_async_read_at_streambuf<+ AsyncRandomAccessReadDevice> >(),+ token, offset, &b,+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition))))+{+ return async_initiate<ReadToken,+ void (asio::error_code, std::size_t)>(+ detail::initiate_async_read_at_streambuf<AsyncRandomAccessReadDevice>(d),+ token, offset, &b,+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition));+}++template <typename AsyncRandomAccessReadDevice, typename Allocator,+ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+ std::size_t)) ReadToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+async_read_at(AsyncRandomAccessReadDevice& d,+ uint64_t offset, asio::basic_streambuf<Allocator>& b,+ ASIO_MOVE_ARG(ReadToken) token)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_initiate<ReadToken,+ void (asio::error_code, std::size_t)>(+ declval<detail::initiate_async_read_at_streambuf<+ AsyncRandomAccessReadDevice> >(),+ token, offset, &b, transfer_all())))+{+ return async_initiate<ReadToken,+ void (asio::error_code, std::size_t)>(+ detail::initiate_async_read_at_streambuf<AsyncRandomAccessReadDevice>(d),+ token, offset, &b, transfer_all());+} #endif // !defined(ASIO_NO_IOSTREAM) #endif // !defined(ASIO_NO_EXTENSIONS)
link/modules/asio-standalone/asio/include/asio/impl/read_until.hpp view
@@ -2,2662 +2,3449 @@ // impl/read_until.hpp // ~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef ASIO_IMPL_READ_UNTIL_HPP-#define ASIO_IMPL_READ_UNTIL_HPP--#if defined(_MSC_VER) && (_MSC_VER >= 1200)-# pragma once-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)--#include <algorithm>-#include <string>-#include <vector>-#include <utility>-#include "asio/associator.hpp"-#include "asio/buffer.hpp"-#include "asio/buffers_iterator.hpp"-#include "asio/detail/base_from_cancellation_state.hpp"-#include "asio/detail/bind_handler.hpp"-#include "asio/detail/handler_cont_helpers.hpp"-#include "asio/detail/handler_tracking.hpp"-#include "asio/detail/handler_type_requirements.hpp"-#include "asio/detail/limits.hpp"-#include "asio/detail/non_const_lvalue.hpp"-#include "asio/detail/throw_error.hpp"--#include "asio/detail/push_options.hpp"--namespace asio {--namespace detail-{- // Algorithm that finds a subsequence of equal values in a sequence. Returns- // (iterator,true) if a full match was found, in which case the iterator- // points to the beginning of the match. Returns (iterator,false) if a- // partial match was found at the end of the first sequence, in which case- // the iterator points to the beginning of the partial match. Returns- // (last1,false) if no full or partial match was found.- template <typename Iterator1, typename Iterator2>- std::pair<Iterator1, bool> partial_search(- Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2)- {- for (Iterator1 iter1 = first1; iter1 != last1; ++iter1)- {- Iterator1 test_iter1 = iter1;- Iterator2 test_iter2 = first2;- for (;; ++test_iter1, ++test_iter2)- {- if (test_iter2 == last2)- return std::make_pair(iter1, true);- if (test_iter1 == last1)- {- if (test_iter2 != first2)- return std::make_pair(iter1, false);- else- break;- }- if (*test_iter1 != *test_iter2)- break;- }- }- return std::make_pair(last1, false);- }--#if !defined(ASIO_NO_EXTENSIONS)-#if defined(ASIO_HAS_BOOST_REGEX)- struct regex_match_flags- {- template <typename T>- operator T() const- {- return T::match_default | T::match_partial;- }- };-#endif // !defined(ASIO_NO_EXTENSIONS)-#endif // defined(ASIO_HAS_BOOST_REGEX)-} // namespace detail--#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)--template <typename SyncReadStream, typename DynamicBuffer_v1>-inline std::size_t read_until(SyncReadStream& s,- DynamicBuffer_v1&& buffers, char delim,- constraint_t<- is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value- >,- constraint_t<- !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value- >)-{- asio::error_code ec;- std::size_t bytes_transferred = read_until(s,- static_cast<DynamicBuffer_v1&&>(buffers), delim, ec);- asio::detail::throw_error(ec, "read_until");- return bytes_transferred;-}--template <typename SyncReadStream, typename DynamicBuffer_v1>-std::size_t read_until(SyncReadStream& s,- DynamicBuffer_v1&& buffers,- char delim, asio::error_code& ec,- constraint_t<- is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value- >,- constraint_t<- !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value- >)-{- decay_t<DynamicBuffer_v1> b(- static_cast<DynamicBuffer_v1&&>(buffers));-- std::size_t search_position = 0;- for (;;)- {- // Determine the range of the data to be searched.- typedef typename DynamicBuffer_v1::const_buffers_type buffers_type;- typedef buffers_iterator<buffers_type> iterator;- buffers_type data_buffers = b.data();- iterator begin = iterator::begin(data_buffers);- iterator start_pos = begin + search_position;- iterator end = iterator::end(data_buffers);-- // Look for a match.- iterator iter = std::find(start_pos, end, delim);- if (iter != end)- {- // Found a match. We're done.- ec = asio::error_code();- return iter - begin + 1;- }- else- {- // No match. Next search can start with the new data.- search_position = end - begin;- }-- // Check if buffer is full.- if (b.size() == b.max_size())- {- ec = error::not_found;- return 0;- }-- // Need more data.- std::size_t bytes_to_read = std::min<std::size_t>(- std::max<std::size_t>(512, b.capacity() - b.size()),- std::min<std::size_t>(65536, b.max_size() - b.size()));- b.commit(s.read_some(b.prepare(bytes_to_read), ec));- if (ec)- return 0;- }-}--template <typename SyncReadStream, typename DynamicBuffer_v1>-inline std::size_t read_until(SyncReadStream& s,- DynamicBuffer_v1&& buffers,- ASIO_STRING_VIEW_PARAM delim,- constraint_t<- is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value- >,- constraint_t<- !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value- >)-{- asio::error_code ec;- std::size_t bytes_transferred = read_until(s,- static_cast<DynamicBuffer_v1&&>(buffers), delim, ec);- asio::detail::throw_error(ec, "read_until");- return bytes_transferred;-}--template <typename SyncReadStream, typename DynamicBuffer_v1>-std::size_t read_until(SyncReadStream& s,- DynamicBuffer_v1&& buffers,- ASIO_STRING_VIEW_PARAM delim, asio::error_code& ec,- constraint_t<- is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value- >,- constraint_t<- !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value- >)-{- decay_t<DynamicBuffer_v1> b(- static_cast<DynamicBuffer_v1&&>(buffers));-- std::size_t search_position = 0;- for (;;)- {- // Determine the range of the data to be searched.- typedef typename DynamicBuffer_v1::const_buffers_type buffers_type;- typedef buffers_iterator<buffers_type> iterator;- buffers_type data_buffers = b.data();- iterator begin = iterator::begin(data_buffers);- iterator start_pos = begin + search_position;- iterator end = iterator::end(data_buffers);-- // Look for a match.- std::pair<iterator, bool> result = detail::partial_search(- start_pos, end, delim.begin(), delim.end());- if (result.first != end)- {- if (result.second)- {- // Full match. We're done.- ec = asio::error_code();- return result.first - begin + delim.length();- }- else- {- // Partial match. Next search needs to start from beginning of match.- search_position = result.first - begin;- }- }- else- {- // No match. Next search can start with the new data.- search_position = end - begin;- }-- // Check if buffer is full.- if (b.size() == b.max_size())- {- ec = error::not_found;- return 0;- }-- // Need more data.- std::size_t bytes_to_read = std::min<std::size_t>(- std::max<std::size_t>(512, b.capacity() - b.size()),- std::min<std::size_t>(65536, b.max_size() - b.size()));- b.commit(s.read_some(b.prepare(bytes_to_read), ec));- if (ec)- return 0;- }-}--#if !defined(ASIO_NO_EXTENSIONS)-#if defined(ASIO_HAS_BOOST_REGEX)--template <typename SyncReadStream, typename DynamicBuffer_v1, typename Traits>-inline std::size_t read_until(SyncReadStream& s, DynamicBuffer_v1&& buffers,- const boost::basic_regex<char, Traits>& expr,- constraint_t<- is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value- >,- constraint_t<- !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value- >)-{- asio::error_code ec;- std::size_t bytes_transferred = read_until(s,- static_cast<DynamicBuffer_v1&&>(buffers), expr, ec);- asio::detail::throw_error(ec, "read_until");- return bytes_transferred;-}--template <typename SyncReadStream, typename DynamicBuffer_v1, typename Traits>-std::size_t read_until(SyncReadStream& s, DynamicBuffer_v1&& buffers,- const boost::basic_regex<char, Traits>& expr, asio::error_code& ec,- constraint_t<- is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value- >,- constraint_t<- !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value- >)-{- decay_t<DynamicBuffer_v1> b(- static_cast<DynamicBuffer_v1&&>(buffers));-- std::size_t search_position = 0;- for (;;)- {- // Determine the range of the data to be searched.- typedef typename DynamicBuffer_v1::const_buffers_type buffers_type;- typedef buffers_iterator<buffers_type> iterator;- buffers_type data_buffers = b.data();- iterator begin = iterator::begin(data_buffers);- iterator start_pos = begin + search_position;- iterator end = iterator::end(data_buffers);-- // Look for a match.- boost::match_results<iterator,- typename std::vector<boost::sub_match<iterator>>::allocator_type>- match_results;- if (regex_search(start_pos, end, match_results,- expr, detail::regex_match_flags()))- {- if (match_results[0].matched)- {- // Full match. We're done.- ec = asio::error_code();- return match_results[0].second - begin;- }- else- {- // Partial match. Next search needs to start from beginning of match.- search_position = match_results[0].first - begin;- }- }- else- {- // No match. Next search can start with the new data.- search_position = end - begin;- }-- // Check if buffer is full.- if (b.size() == b.max_size())- {- ec = error::not_found;- return 0;- }-- // Need more data.- std::size_t bytes_to_read = std::min<std::size_t>(- std::max<std::size_t>(512, b.capacity() - b.size()),- std::min<std::size_t>(65536, b.max_size() - b.size()));- b.commit(s.read_some(b.prepare(bytes_to_read), ec));- if (ec)- return 0;- }-}--#endif // defined(ASIO_HAS_BOOST_REGEX)--template <typename SyncReadStream,- typename DynamicBuffer_v1, typename MatchCondition>-inline std::size_t read_until(SyncReadStream& s,- DynamicBuffer_v1&& buffers,- MatchCondition match_condition,- constraint_t<- is_match_condition<MatchCondition>::value- >,- constraint_t<- is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value- >,- constraint_t<- !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value- >)-{- asio::error_code ec;- std::size_t bytes_transferred = read_until(s,- static_cast<DynamicBuffer_v1&&>(buffers),- match_condition, ec);- asio::detail::throw_error(ec, "read_until");- return bytes_transferred;-}--template <typename SyncReadStream,- typename DynamicBuffer_v1, typename MatchCondition>-std::size_t read_until(SyncReadStream& s,- DynamicBuffer_v1&& buffers,- MatchCondition match_condition, asio::error_code& ec,- constraint_t<- is_match_condition<MatchCondition>::value- >,- constraint_t<- is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value- >,- constraint_t<- !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value- >)-{- decay_t<DynamicBuffer_v1> b(- static_cast<DynamicBuffer_v1&&>(buffers));-- std::size_t search_position = 0;- for (;;)- {- // Determine the range of the data to be searched.- typedef typename DynamicBuffer_v1::const_buffers_type buffers_type;- typedef buffers_iterator<buffers_type> iterator;- buffers_type data_buffers = b.data();- iterator begin = iterator::begin(data_buffers);- iterator start_pos = begin + search_position;- iterator end = iterator::end(data_buffers);-- // Look for a match.- std::pair<iterator, bool> result = match_condition(start_pos, end);- if (result.second)- {- // Full match. We're done.- ec = asio::error_code();- return result.first - begin;- }- else if (result.first != end)- {- // Partial match. Next search needs to start from beginning of match.- search_position = result.first - begin;- }- else- {- // No match. Next search can start with the new data.- search_position = end - begin;- }-- // Check if buffer is full.- if (b.size() == b.max_size())- {- ec = error::not_found;- return 0;- }-- // Need more data.- std::size_t bytes_to_read = std::min<std::size_t>(- std::max<std::size_t>(512, b.capacity() - b.size()),- std::min<std::size_t>(65536, b.max_size() - b.size()));- b.commit(s.read_some(b.prepare(bytes_to_read), ec));- if (ec)- return 0;- }-}--#if !defined(ASIO_NO_IOSTREAM)--template <typename SyncReadStream, typename Allocator>-inline std::size_t read_until(SyncReadStream& s,- asio::basic_streambuf<Allocator>& b, char delim)-{- return read_until(s, basic_streambuf_ref<Allocator>(b), delim);-}--template <typename SyncReadStream, typename Allocator>-inline std::size_t read_until(SyncReadStream& s,- asio::basic_streambuf<Allocator>& b, char delim,- asio::error_code& ec)-{- return read_until(s, basic_streambuf_ref<Allocator>(b), delim, ec);-}--template <typename SyncReadStream, typename Allocator>-inline std::size_t read_until(SyncReadStream& s,- asio::basic_streambuf<Allocator>& b,- ASIO_STRING_VIEW_PARAM delim)-{- return read_until(s, basic_streambuf_ref<Allocator>(b), delim);-}--template <typename SyncReadStream, typename Allocator>-inline std::size_t read_until(SyncReadStream& s,- asio::basic_streambuf<Allocator>& b,- ASIO_STRING_VIEW_PARAM delim, asio::error_code& ec)-{- return read_until(s, basic_streambuf_ref<Allocator>(b), delim, ec);-}--#if defined(ASIO_HAS_BOOST_REGEX)--template <typename SyncReadStream, typename Allocator, typename Traits>-inline std::size_t read_until(SyncReadStream& s,- asio::basic_streambuf<Allocator>& b,- const boost::basic_regex<char, Traits>& expr)-{- return read_until(s, basic_streambuf_ref<Allocator>(b), expr);-}--template <typename SyncReadStream, typename Allocator, typename Traits>-inline std::size_t read_until(SyncReadStream& s,- asio::basic_streambuf<Allocator>& b,- const boost::basic_regex<char, Traits>& expr,- asio::error_code& ec)-{- return read_until(s, basic_streambuf_ref<Allocator>(b), expr, ec);-}--#endif // defined(ASIO_HAS_BOOST_REGEX)--template <typename SyncReadStream, typename Allocator, typename MatchCondition>-inline std::size_t read_until(SyncReadStream& s,- asio::basic_streambuf<Allocator>& b, MatchCondition match_condition,- constraint_t<is_match_condition<MatchCondition>::value>)-{- return read_until(s, basic_streambuf_ref<Allocator>(b), match_condition);-}--template <typename SyncReadStream, typename Allocator, typename MatchCondition>-inline std::size_t read_until(SyncReadStream& s,- asio::basic_streambuf<Allocator>& b,- MatchCondition match_condition, asio::error_code& ec,- constraint_t<is_match_condition<MatchCondition>::value>)-{- return read_until(s, basic_streambuf_ref<Allocator>(b), match_condition, ec);-}--#endif // !defined(ASIO_NO_IOSTREAM)-#endif // !defined(ASIO_NO_EXTENSIONS)-#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)--template <typename SyncReadStream, typename DynamicBuffer_v2>-inline std::size_t read_until(SyncReadStream& s,- DynamicBuffer_v2 buffers, char delim,- constraint_t<- is_dynamic_buffer_v2<DynamicBuffer_v2>::value- >)-{- asio::error_code ec;- std::size_t bytes_transferred = read_until(s,- static_cast<DynamicBuffer_v2&&>(buffers), delim, ec);- asio::detail::throw_error(ec, "read_until");- return bytes_transferred;-}--template <typename SyncReadStream, typename DynamicBuffer_v2>-std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers,- char delim, asio::error_code& ec,- constraint_t<- is_dynamic_buffer_v2<DynamicBuffer_v2>::value- >)-{- DynamicBuffer_v2& b = buffers;-- std::size_t search_position = 0;- for (;;)- {- // Determine the range of the data to be searched.- typedef typename DynamicBuffer_v2::const_buffers_type buffers_type;- typedef buffers_iterator<buffers_type> iterator;- buffers_type data_buffers =- const_cast<const DynamicBuffer_v2&>(b).data(0, b.size());- iterator begin = iterator::begin(data_buffers);- iterator start_pos = begin + search_position;- iterator end = iterator::end(data_buffers);-- // Look for a match.- iterator iter = std::find(start_pos, end, delim);- if (iter != end)- {- // Found a match. We're done.- ec = asio::error_code();- return iter - begin + 1;- }- else- {- // No match. Next search can start with the new data.- search_position = end - begin;- }-- // Check if buffer is full.- if (b.size() == b.max_size())- {- ec = error::not_found;- return 0;- }-- // Need more data.- std::size_t bytes_to_read = std::min<std::size_t>(- std::max<std::size_t>(512, b.capacity() - b.size()),- std::min<std::size_t>(65536, b.max_size() - b.size()));- std::size_t pos = b.size();- b.grow(bytes_to_read);- std::size_t bytes_transferred = s.read_some(b.data(pos, bytes_to_read), ec);- b.shrink(bytes_to_read - bytes_transferred);- if (ec)- return 0;- }-}--template <typename SyncReadStream, typename DynamicBuffer_v2>-inline std::size_t read_until(SyncReadStream& s,- DynamicBuffer_v2 buffers, ASIO_STRING_VIEW_PARAM delim,- constraint_t<- is_dynamic_buffer_v2<DynamicBuffer_v2>::value- >)-{- asio::error_code ec;- std::size_t bytes_transferred = read_until(s,- static_cast<DynamicBuffer_v2&&>(buffers), delim, ec);- asio::detail::throw_error(ec, "read_until");- return bytes_transferred;-}--template <typename SyncReadStream, typename DynamicBuffer_v2>-std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers,- ASIO_STRING_VIEW_PARAM delim, asio::error_code& ec,- constraint_t<- is_dynamic_buffer_v2<DynamicBuffer_v2>::value- >)-{- DynamicBuffer_v2& b = buffers;-- std::size_t search_position = 0;- for (;;)- {- // Determine the range of the data to be searched.- typedef typename DynamicBuffer_v2::const_buffers_type buffers_type;- typedef buffers_iterator<buffers_type> iterator;- buffers_type data_buffers =- const_cast<const DynamicBuffer_v2&>(b).data(0, b.size());- iterator begin = iterator::begin(data_buffers);- iterator start_pos = begin + search_position;- iterator end = iterator::end(data_buffers);-- // Look for a match.- std::pair<iterator, bool> result = detail::partial_search(- start_pos, end, delim.begin(), delim.end());- if (result.first != end)- {- if (result.second)- {- // Full match. We're done.- ec = asio::error_code();- return result.first - begin + delim.length();- }- else- {- // Partial match. Next search needs to start from beginning of match.- search_position = result.first - begin;- }- }- else- {- // No match. Next search can start with the new data.- search_position = end - begin;- }-- // Check if buffer is full.- if (b.size() == b.max_size())- {- ec = error::not_found;- return 0;- }-- // Need more data.- std::size_t bytes_to_read = std::min<std::size_t>(- std::max<std::size_t>(512, b.capacity() - b.size()),- std::min<std::size_t>(65536, b.max_size() - b.size()));- std::size_t pos = b.size();- b.grow(bytes_to_read);- std::size_t bytes_transferred = s.read_some(b.data(pos, bytes_to_read), ec);- b.shrink(bytes_to_read - bytes_transferred);- if (ec)- return 0;- }-}--#if !defined(ASIO_NO_EXTENSIONS)-#if defined(ASIO_HAS_BOOST_REGEX)--template <typename SyncReadStream, typename DynamicBuffer_v2, typename Traits>-inline std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers,- const boost::basic_regex<char, Traits>& expr,- constraint_t<- is_dynamic_buffer_v2<DynamicBuffer_v2>::value- >)-{- asio::error_code ec;- std::size_t bytes_transferred = read_until(s,- static_cast<DynamicBuffer_v2&&>(buffers), expr, ec);- asio::detail::throw_error(ec, "read_until");- return bytes_transferred;-}--template <typename SyncReadStream, typename DynamicBuffer_v2, typename Traits>-std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers,- const boost::basic_regex<char, Traits>& expr, asio::error_code& ec,- constraint_t<- is_dynamic_buffer_v2<DynamicBuffer_v2>::value- >)-{- DynamicBuffer_v2& b = buffers;-- std::size_t search_position = 0;- for (;;)- {- // Determine the range of the data to be searched.- typedef typename DynamicBuffer_v2::const_buffers_type buffers_type;- typedef buffers_iterator<buffers_type> iterator;- buffers_type data_buffers =- const_cast<const DynamicBuffer_v2&>(b).data(0, b.size());- iterator begin = iterator::begin(data_buffers);- iterator start_pos = begin + search_position;- iterator end = iterator::end(data_buffers);-- // Look for a match.- boost::match_results<iterator,- typename std::vector<boost::sub_match<iterator>>::allocator_type>- match_results;- if (regex_search(start_pos, end, match_results,- expr, detail::regex_match_flags()))- {- if (match_results[0].matched)- {- // Full match. We're done.- ec = asio::error_code();- return match_results[0].second - begin;- }- else- {- // Partial match. Next search needs to start from beginning of match.- search_position = match_results[0].first - begin;- }- }- else- {- // No match. Next search can start with the new data.- search_position = end - begin;- }-- // Check if buffer is full.- if (b.size() == b.max_size())- {- ec = error::not_found;- return 0;- }-- // Need more data.- std::size_t bytes_to_read = std::min<std::size_t>(- std::max<std::size_t>(512, b.capacity() - b.size()),- std::min<std::size_t>(65536, b.max_size() - b.size()));- std::size_t pos = b.size();- b.grow(bytes_to_read);- std::size_t bytes_transferred = s.read_some(b.data(pos, bytes_to_read), ec);- b.shrink(bytes_to_read - bytes_transferred);- if (ec)- return 0;- }-}--#endif // defined(ASIO_HAS_BOOST_REGEX)--template <typename SyncReadStream,- typename DynamicBuffer_v2, typename MatchCondition>-inline std::size_t read_until(SyncReadStream& s,- DynamicBuffer_v2 buffers, MatchCondition match_condition,- constraint_t<- is_match_condition<MatchCondition>::value- >,- constraint_t<- is_dynamic_buffer_v2<DynamicBuffer_v2>::value- >)-{- asio::error_code ec;- std::size_t bytes_transferred = read_until(s,- static_cast<DynamicBuffer_v2&&>(buffers),- match_condition, ec);- asio::detail::throw_error(ec, "read_until");- return bytes_transferred;-}--template <typename SyncReadStream,- typename DynamicBuffer_v2, typename MatchCondition>-std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers,- MatchCondition match_condition, asio::error_code& ec,- constraint_t<- is_match_condition<MatchCondition>::value- >,- constraint_t<- is_dynamic_buffer_v2<DynamicBuffer_v2>::value- >)-{- DynamicBuffer_v2& b = buffers;-- std::size_t search_position = 0;- for (;;)- {- // Determine the range of the data to be searched.- typedef typename DynamicBuffer_v2::const_buffers_type buffers_type;- typedef buffers_iterator<buffers_type> iterator;- buffers_type data_buffers =- const_cast<const DynamicBuffer_v2&>(b).data(0, b.size());- iterator begin = iterator::begin(data_buffers);- iterator start_pos = begin + search_position;- iterator end = iterator::end(data_buffers);-- // Look for a match.- std::pair<iterator, bool> result = match_condition(start_pos, end);- if (result.second)- {- // Full match. We're done.- ec = asio::error_code();- return result.first - begin;- }- else if (result.first != end)- {- // Partial match. Next search needs to start from beginning of match.- search_position = result.first - begin;- }- else- {- // No match. Next search can start with the new data.- search_position = end - begin;- }-- // Check if buffer is full.- if (b.size() == b.max_size())- {- ec = error::not_found;- return 0;- }-- // Need more data.- std::size_t bytes_to_read = std::min<std::size_t>(- std::max<std::size_t>(512, b.capacity() - b.size()),- std::min<std::size_t>(65536, b.max_size() - b.size()));- std::size_t pos = b.size();- b.grow(bytes_to_read);- std::size_t bytes_transferred = s.read_some(b.data(pos, bytes_to_read), ec);- b.shrink(bytes_to_read - bytes_transferred);- if (ec)- return 0;- }-}--#endif // !defined(ASIO_NO_EXTENSIONS)--#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)--namespace detail-{- template <typename AsyncReadStream,- typename DynamicBuffer_v1, typename ReadHandler>- class read_until_delim_op_v1- : public base_from_cancellation_state<ReadHandler>- {- public:- template <typename BufferSequence>- read_until_delim_op_v1(AsyncReadStream& stream,- BufferSequence&& buffers,- char delim, ReadHandler& handler)- : base_from_cancellation_state<ReadHandler>(- handler, enable_partial_cancellation()),- stream_(stream),- buffers_(static_cast<BufferSequence&&>(buffers)),- delim_(delim),- start_(0),- search_position_(0),- handler_(static_cast<ReadHandler&&>(handler))- {- }-- read_until_delim_op_v1(const read_until_delim_op_v1& other)- : base_from_cancellation_state<ReadHandler>(other),- stream_(other.stream_),- buffers_(other.buffers_),- delim_(other.delim_),- start_(other.start_),- search_position_(other.search_position_),- handler_(other.handler_)- {- }-- read_until_delim_op_v1(read_until_delim_op_v1&& other)- : base_from_cancellation_state<ReadHandler>(- static_cast<base_from_cancellation_state<ReadHandler>&&>(other)),- stream_(other.stream_),- buffers_(static_cast<DynamicBuffer_v1&&>(other.buffers_)),- delim_(other.delim_),- start_(other.start_),- search_position_(other.search_position_),- handler_(static_cast<ReadHandler&&>(other.handler_))- {- }-- void operator()(asio::error_code ec,- std::size_t bytes_transferred, int start = 0)- {- const std::size_t not_found = (std::numeric_limits<std::size_t>::max)();- std::size_t bytes_to_read;- switch (start_ = start)- {- case 1:- for (;;)- {- {- // Determine the range of the data to be searched.- typedef typename DynamicBuffer_v1::const_buffers_type- buffers_type;- typedef buffers_iterator<buffers_type> iterator;- buffers_type data_buffers = buffers_.data();- iterator begin = iterator::begin(data_buffers);- iterator start_pos = begin + search_position_;- iterator end = iterator::end(data_buffers);-- // Look for a match.- iterator iter = std::find(start_pos, end, delim_);- if (iter != end)- {- // Found a match. We're done.- search_position_ = iter - begin + 1;- bytes_to_read = 0;- }-- // No match yet. Check if buffer is full.- else if (buffers_.size() == buffers_.max_size())- {- search_position_ = not_found;- bytes_to_read = 0;- }-- // Need to read some more data.- else- {- // Next search can start with the new data.- search_position_ = end - begin;- bytes_to_read = std::min<std::size_t>(- std::max<std::size_t>(512,- buffers_.capacity() - buffers_.size()),- std::min<std::size_t>(65536,- buffers_.max_size() - buffers_.size()));- }- }-- // Check if we're done.- if (!start && bytes_to_read == 0)- break;-- // Start a new asynchronous read operation to obtain more data.- {- ASIO_HANDLER_LOCATION((- __FILE__, __LINE__, "async_read_until"));- stream_.async_read_some(buffers_.prepare(bytes_to_read),- static_cast<read_until_delim_op_v1&&>(*this));- }- return; default:- buffers_.commit(bytes_transferred);- if (ec || bytes_transferred == 0)- break;- if (this->cancelled() != cancellation_type::none)- {- ec = error::operation_aborted;- break;- }- }-- const asio::error_code result_ec =- (search_position_ == not_found)- ? error::not_found : ec;-- const std::size_t result_n =- (ec || search_position_ == not_found)- ? 0 : search_position_;-- static_cast<ReadHandler&&>(handler_)(result_ec, result_n);- }- }-- //private:- AsyncReadStream& stream_;- DynamicBuffer_v1 buffers_;- char delim_;- int start_;- std::size_t search_position_;- ReadHandler handler_;- };-- template <typename AsyncReadStream,- typename DynamicBuffer_v1, typename ReadHandler>- inline bool asio_handler_is_continuation(- read_until_delim_op_v1<AsyncReadStream,- DynamicBuffer_v1, ReadHandler>* this_handler)- {- return this_handler->start_ == 0 ? true- : asio_handler_cont_helpers::is_continuation(- this_handler->handler_);- }-- template <typename AsyncReadStream>- class initiate_async_read_until_delim_v1- {- public:- typedef typename AsyncReadStream::executor_type executor_type;-- explicit initiate_async_read_until_delim_v1(AsyncReadStream& stream)- : stream_(stream)- {- }-- executor_type get_executor() const noexcept- {- return stream_.get_executor();- }-- template <typename ReadHandler, typename DynamicBuffer_v1>- void operator()(ReadHandler&& handler,- DynamicBuffer_v1&& buffers,- char delim) const- {- // If you get an error on the following line it means that your handler- // does not meet the documented type requirements for a ReadHandler.- ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;-- non_const_lvalue<ReadHandler> handler2(handler);- read_until_delim_op_v1<AsyncReadStream,- decay_t<DynamicBuffer_v1>,- decay_t<ReadHandler>>(- stream_, static_cast<DynamicBuffer_v1&&>(buffers),- delim, handler2.value)(asio::error_code(), 0, 1);- }-- private:- AsyncReadStream& stream_;- };-} // namespace detail--#if !defined(GENERATING_DOCUMENTATION)--template <template <typename, typename> class Associator,- typename AsyncReadStream, typename DynamicBuffer_v1,- typename ReadHandler, typename DefaultCandidate>-struct associator<Associator,- detail::read_until_delim_op_v1<AsyncReadStream,- DynamicBuffer_v1, ReadHandler>,- DefaultCandidate>- : Associator<ReadHandler, DefaultCandidate>-{- static typename Associator<ReadHandler, DefaultCandidate>::type get(- const detail::read_until_delim_op_v1<AsyncReadStream,- DynamicBuffer_v1, ReadHandler>& h) noexcept- {- return Associator<ReadHandler, DefaultCandidate>::get(h.handler_);- }-- static auto get(- const detail::read_until_delim_op_v1<AsyncReadStream,- DynamicBuffer_v1, ReadHandler>& h,- const DefaultCandidate& c) noexcept- -> decltype(Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c))- {- return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c);- }-};--#endif // !defined(GENERATING_DOCUMENTATION)--namespace detail-{- template <typename AsyncReadStream,- typename DynamicBuffer_v1, typename ReadHandler>- class read_until_delim_string_op_v1- : public base_from_cancellation_state<ReadHandler>- {- public:- template <typename BufferSequence>- read_until_delim_string_op_v1(AsyncReadStream& stream,- BufferSequence&& buffers,- const std::string& delim, ReadHandler& handler)- : base_from_cancellation_state<ReadHandler>(- handler, enable_partial_cancellation()),- stream_(stream),- buffers_(static_cast<BufferSequence&&>(buffers)),- delim_(delim),- start_(0),- search_position_(0),- handler_(static_cast<ReadHandler&&>(handler))- {- }-- read_until_delim_string_op_v1(const read_until_delim_string_op_v1& other)- : base_from_cancellation_state<ReadHandler>(other),- stream_(other.stream_),- buffers_(other.buffers_),- delim_(other.delim_),- start_(other.start_),- search_position_(other.search_position_),- handler_(other.handler_)- {- }-- read_until_delim_string_op_v1(read_until_delim_string_op_v1&& other)- : base_from_cancellation_state<ReadHandler>(- static_cast<base_from_cancellation_state<ReadHandler>&&>(other)),- stream_(other.stream_),- buffers_(static_cast<DynamicBuffer_v1&&>(other.buffers_)),- delim_(static_cast<std::string&&>(other.delim_)),- start_(other.start_),- search_position_(other.search_position_),- handler_(static_cast<ReadHandler&&>(other.handler_))- {- }-- void operator()(asio::error_code ec,- std::size_t bytes_transferred, int start = 0)- {- const std::size_t not_found = (std::numeric_limits<std::size_t>::max)();- std::size_t bytes_to_read;- switch (start_ = start)- {- case 1:- for (;;)- {- {- // Determine the range of the data to be searched.- typedef typename DynamicBuffer_v1::const_buffers_type- buffers_type;- typedef buffers_iterator<buffers_type> iterator;- buffers_type data_buffers = buffers_.data();- iterator begin = iterator::begin(data_buffers);- iterator start_pos = begin + search_position_;- iterator end = iterator::end(data_buffers);-- // Look for a match.- std::pair<iterator, bool> result = detail::partial_search(- start_pos, end, delim_.begin(), delim_.end());- if (result.first != end && result.second)- {- // Full match. We're done.- search_position_ = result.first - begin + delim_.length();- bytes_to_read = 0;- }-- // No match yet. Check if buffer is full.- else if (buffers_.size() == buffers_.max_size())- {- search_position_ = not_found;- bytes_to_read = 0;- }-- // Need to read some more data.- else- {- if (result.first != end)- {- // Partial match. Next search needs to start from beginning of- // match.- search_position_ = result.first - begin;- }- else- {- // Next search can start with the new data.- search_position_ = end - begin;- }-- bytes_to_read = std::min<std::size_t>(- std::max<std::size_t>(512,- buffers_.capacity() - buffers_.size()),- std::min<std::size_t>(65536,- buffers_.max_size() - buffers_.size()));- }- }-- // Check if we're done.- if (!start && bytes_to_read == 0)- break;-- // Start a new asynchronous read operation to obtain more data.- {- ASIO_HANDLER_LOCATION((- __FILE__, __LINE__, "async_read_until"));- stream_.async_read_some(buffers_.prepare(bytes_to_read),- static_cast<read_until_delim_string_op_v1&&>(*this));- }- return; default:- buffers_.commit(bytes_transferred);- if (ec || bytes_transferred == 0)- break;- if (this->cancelled() != cancellation_type::none)- {- ec = error::operation_aborted;- break;- }- }-- const asio::error_code result_ec =- (search_position_ == not_found)- ? error::not_found : ec;-- const std::size_t result_n =- (ec || search_position_ == not_found)- ? 0 : search_position_;-- static_cast<ReadHandler&&>(handler_)(result_ec, result_n);- }- }-- //private:- AsyncReadStream& stream_;- DynamicBuffer_v1 buffers_;- std::string delim_;- int start_;- std::size_t search_position_;- ReadHandler handler_;- };-- template <typename AsyncReadStream,- typename DynamicBuffer_v1, typename ReadHandler>- inline bool asio_handler_is_continuation(- read_until_delim_string_op_v1<AsyncReadStream,- DynamicBuffer_v1, ReadHandler>* this_handler)- {- return this_handler->start_ == 0 ? true- : asio_handler_cont_helpers::is_continuation(- this_handler->handler_);- }-- template <typename AsyncReadStream>- class initiate_async_read_until_delim_string_v1- {- public:- typedef typename AsyncReadStream::executor_type executor_type;-- explicit initiate_async_read_until_delim_string_v1(AsyncReadStream& stream)- : stream_(stream)- {- }-- executor_type get_executor() const noexcept- {- return stream_.get_executor();- }-- template <typename ReadHandler, typename DynamicBuffer_v1>- void operator()(ReadHandler&& handler,- DynamicBuffer_v1&& buffers,- const std::string& delim) const- {- // If you get an error on the following line it means that your handler- // does not meet the documented type requirements for a ReadHandler.- ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;-- non_const_lvalue<ReadHandler> handler2(handler);- read_until_delim_string_op_v1<AsyncReadStream,- decay_t<DynamicBuffer_v1>,- decay_t<ReadHandler>>(- stream_, static_cast<DynamicBuffer_v1&&>(buffers),- delim, handler2.value)(asio::error_code(), 0, 1);- }-- private:- AsyncReadStream& stream_;- };-} // namespace detail--#if !defined(GENERATING_DOCUMENTATION)--template <template <typename, typename> class Associator,- typename AsyncReadStream, typename DynamicBuffer_v1,- typename ReadHandler, typename DefaultCandidate>-struct associator<Associator,- detail::read_until_delim_string_op_v1<AsyncReadStream,- DynamicBuffer_v1, ReadHandler>,- DefaultCandidate>- : Associator<ReadHandler, DefaultCandidate>-{- static typename Associator<ReadHandler, DefaultCandidate>::type get(- const detail::read_until_delim_string_op_v1<- AsyncReadStream, DynamicBuffer_v1, ReadHandler>& h) noexcept- {- return Associator<ReadHandler, DefaultCandidate>::get(h.handler_);- }-- static auto get(- const detail::read_until_delim_string_op_v1<- AsyncReadStream, DynamicBuffer_v1, ReadHandler>& h,- const DefaultCandidate& c) noexcept- -> decltype(Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c))- {- return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c);- }-};--#endif // !defined(GENERATING_DOCUMENTATION)--#if !defined(ASIO_NO_EXTENSIONS)-#if defined(ASIO_HAS_BOOST_REGEX)--namespace detail-{- template <typename AsyncReadStream, typename DynamicBuffer_v1,- typename RegEx, typename ReadHandler>- class read_until_expr_op_v1- : public base_from_cancellation_state<ReadHandler>- {- public:- template <typename BufferSequence, typename Traits>- read_until_expr_op_v1(AsyncReadStream& stream, BufferSequence&& buffers,- const boost::basic_regex<char, Traits>& expr, ReadHandler& handler)- : base_from_cancellation_state<ReadHandler>(- handler, enable_partial_cancellation()),- stream_(stream),- buffers_(static_cast<BufferSequence&&>(buffers)),- expr_(expr),- start_(0),- search_position_(0),- handler_(static_cast<ReadHandler&&>(handler))- {- }-- read_until_expr_op_v1(const read_until_expr_op_v1& other)- : base_from_cancellation_state<ReadHandler>(other),- stream_(other.stream_),- buffers_(other.buffers_),- expr_(other.expr_),- start_(other.start_),- search_position_(other.search_position_),- handler_(other.handler_)- {- }-- read_until_expr_op_v1(read_until_expr_op_v1&& other)- : base_from_cancellation_state<ReadHandler>(- static_cast<base_from_cancellation_state<ReadHandler>&&>(other)),- stream_(other.stream_),- buffers_(static_cast<DynamicBuffer_v1&&>(other.buffers_)),- expr_(other.expr_),- start_(other.start_),- search_position_(other.search_position_),- handler_(static_cast<ReadHandler&&>(other.handler_))- {- }-- void operator()(asio::error_code ec,- std::size_t bytes_transferred, int start = 0)- {- const std::size_t not_found = (std::numeric_limits<std::size_t>::max)();- std::size_t bytes_to_read;- switch (start_ = start)- {- case 1:- for (;;)- {- {- // Determine the range of the data to be searched.- typedef typename DynamicBuffer_v1::const_buffers_type- buffers_type;- typedef buffers_iterator<buffers_type> iterator;- buffers_type data_buffers = buffers_.data();- iterator begin = iterator::begin(data_buffers);- iterator start_pos = begin + search_position_;- iterator end = iterator::end(data_buffers);-- // Look for a match.- boost::match_results<iterator,- typename std::vector<boost::sub_match<iterator>>::allocator_type>- match_results;- bool match = regex_search(start_pos, end,- match_results, expr_, regex_match_flags());- if (match && match_results[0].matched)- {- // Full match. We're done.- search_position_ = match_results[0].second - begin;- bytes_to_read = 0;- }-- // No match yet. Check if buffer is full.- else if (buffers_.size() == buffers_.max_size())- {- search_position_ = not_found;- bytes_to_read = 0;- }-- // Need to read some more data.- else- {- if (match)- {- // Partial match. Next search needs to start from beginning of- // match.- search_position_ = match_results[0].first - begin;- }- else- {- // Next search can start with the new data.- search_position_ = end - begin;- }-- bytes_to_read = std::min<std::size_t>(- std::max<std::size_t>(512,- buffers_.capacity() - buffers_.size()),- std::min<std::size_t>(65536,- buffers_.max_size() - buffers_.size()));- }- }-- // Check if we're done.- if (!start && bytes_to_read == 0)- break;-- // Start a new asynchronous read operation to obtain more data.- {- ASIO_HANDLER_LOCATION((- __FILE__, __LINE__, "async_read_until"));- stream_.async_read_some(buffers_.prepare(bytes_to_read),- static_cast<read_until_expr_op_v1&&>(*this));- }- return; default:- buffers_.commit(bytes_transferred);- if (ec || bytes_transferred == 0)- break;- if (this->cancelled() != cancellation_type::none)- {- ec = error::operation_aborted;- break;- }- }-- const asio::error_code result_ec =- (search_position_ == not_found)- ? error::not_found : ec;-- const std::size_t result_n =- (ec || search_position_ == not_found)- ? 0 : search_position_;-- static_cast<ReadHandler&&>(handler_)(result_ec, result_n);- }- }-- //private:- AsyncReadStream& stream_;- DynamicBuffer_v1 buffers_;- RegEx expr_;- int start_;- std::size_t search_position_;- ReadHandler handler_;- };-- template <typename AsyncReadStream, typename DynamicBuffer_v1,- typename RegEx, typename ReadHandler>- inline bool asio_handler_is_continuation(- read_until_expr_op_v1<AsyncReadStream,- DynamicBuffer_v1, RegEx, ReadHandler>* this_handler)- {- return this_handler->start_ == 0 ? true- : asio_handler_cont_helpers::is_continuation(- this_handler->handler_);- }-- template <typename AsyncReadStream>- class initiate_async_read_until_expr_v1- {- public:- typedef typename AsyncReadStream::executor_type executor_type;-- explicit initiate_async_read_until_expr_v1(AsyncReadStream& stream)- : stream_(stream)- {- }-- executor_type get_executor() const noexcept- {- return stream_.get_executor();- }-- template <typename ReadHandler, typename DynamicBuffer_v1, typename RegEx>- void operator()(ReadHandler&& handler,- DynamicBuffer_v1&& buffers, const RegEx& expr) const- {- // If you get an error on the following line it means that your handler- // does not meet the documented type requirements for a ReadHandler.- ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;-- non_const_lvalue<ReadHandler> handler2(handler);- read_until_expr_op_v1<AsyncReadStream,- decay_t<DynamicBuffer_v1>,- RegEx, decay_t<ReadHandler>>(- stream_, static_cast<DynamicBuffer_v1&&>(buffers),- expr, handler2.value)(asio::error_code(), 0, 1);- }-- private:- AsyncReadStream& stream_;- };-} // namespace detail--#if !defined(GENERATING_DOCUMENTATION)--template <template <typename, typename> class Associator,- typename AsyncReadStream, typename DynamicBuffer_v1,- typename RegEx, typename ReadHandler, typename DefaultCandidate>-struct associator<Associator,- detail::read_until_expr_op_v1<AsyncReadStream,- DynamicBuffer_v1, RegEx, ReadHandler>,- DefaultCandidate>- : Associator<ReadHandler, DefaultCandidate>-{- static typename Associator<ReadHandler, DefaultCandidate>::type get(- const detail::read_until_expr_op_v1<AsyncReadStream,- DynamicBuffer_v1, RegEx, ReadHandler>& h) noexcept- {- return Associator<ReadHandler, DefaultCandidate>::get(h.handler_);- }-- static auto get(- const detail::read_until_expr_op_v1<AsyncReadStream,- DynamicBuffer_v1, RegEx, ReadHandler>& h,- const DefaultCandidate& c) noexcept- -> decltype(Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c))- {- return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c);- }-};--#endif // !defined(GENERATING_DOCUMENTATION)--#endif // defined(ASIO_HAS_BOOST_REGEX)--namespace detail-{- template <typename AsyncReadStream, typename DynamicBuffer_v1,- typename MatchCondition, typename ReadHandler>- class read_until_match_op_v1- : public base_from_cancellation_state<ReadHandler>- {- public:- template <typename BufferSequence>- read_until_match_op_v1(AsyncReadStream& stream,- BufferSequence&& buffers,- MatchCondition match_condition, ReadHandler& handler)- : base_from_cancellation_state<ReadHandler>(- handler, enable_partial_cancellation()),- stream_(stream),- buffers_(static_cast<BufferSequence&&>(buffers)),- match_condition_(match_condition),- start_(0),- search_position_(0),- handler_(static_cast<ReadHandler&&>(handler))- {- }-- read_until_match_op_v1(const read_until_match_op_v1& other)- : base_from_cancellation_state<ReadHandler>(other),- stream_(other.stream_),- buffers_(other.buffers_),- match_condition_(other.match_condition_),- start_(other.start_),- search_position_(other.search_position_),- handler_(other.handler_)- {- }-- read_until_match_op_v1(read_until_match_op_v1&& other)- : base_from_cancellation_state<ReadHandler>(- static_cast<base_from_cancellation_state<ReadHandler>&&>(other)),- stream_(other.stream_),- buffers_(static_cast<DynamicBuffer_v1&&>(other.buffers_)),- match_condition_(other.match_condition_),- start_(other.start_),- search_position_(other.search_position_),- handler_(static_cast<ReadHandler&&>(other.handler_))- {- }-- void operator()(asio::error_code ec,- std::size_t bytes_transferred, int start = 0)- {- const std::size_t not_found = (std::numeric_limits<std::size_t>::max)();- std::size_t bytes_to_read;- switch (start_ = start)- {- case 1:- for (;;)- {- {- // Determine the range of the data to be searched.- typedef typename DynamicBuffer_v1::const_buffers_type- buffers_type;- typedef buffers_iterator<buffers_type> iterator;- buffers_type data_buffers = buffers_.data();- iterator begin = iterator::begin(data_buffers);- iterator start_pos = begin + search_position_;- iterator end = iterator::end(data_buffers);-- // Look for a match.- std::pair<iterator, bool> result = match_condition_(start_pos, end);- if (result.second)- {- // Full match. We're done.- search_position_ = result.first - begin;- bytes_to_read = 0;- }-- // No match yet. Check if buffer is full.- else if (buffers_.size() == buffers_.max_size())- {- search_position_ = not_found;- bytes_to_read = 0;- }-- // Need to read some more data.- else- {- if (result.first != end)- {- // Partial match. Next search needs to start from beginning of- // match.- search_position_ = result.first - begin;- }- else- {- // Next search can start with the new data.- search_position_ = end - begin;- }-- bytes_to_read = std::min<std::size_t>(- std::max<std::size_t>(512,- buffers_.capacity() - buffers_.size()),- std::min<std::size_t>(65536,- buffers_.max_size() - buffers_.size()));- }- }-- // Check if we're done.- if (!start && bytes_to_read == 0)- break;-- // Start a new asynchronous read operation to obtain more data.- {- ASIO_HANDLER_LOCATION((- __FILE__, __LINE__, "async_read_until"));- stream_.async_read_some(buffers_.prepare(bytes_to_read),- static_cast<read_until_match_op_v1&&>(*this));- }- return; default:- buffers_.commit(bytes_transferred);- if (ec || bytes_transferred == 0)- break;- if (this->cancelled() != cancellation_type::none)- {- ec = error::operation_aborted;- break;- }- }-- const asio::error_code result_ec =- (search_position_ == not_found)- ? error::not_found : ec;-- const std::size_t result_n =- (ec || search_position_ == not_found)- ? 0 : search_position_;-- static_cast<ReadHandler&&>(handler_)(result_ec, result_n);- }- }-- //private:- AsyncReadStream& stream_;- DynamicBuffer_v1 buffers_;- MatchCondition match_condition_;- int start_;- std::size_t search_position_;- ReadHandler handler_;- };-- template <typename AsyncReadStream, typename DynamicBuffer_v1,- typename MatchCondition, typename ReadHandler>- inline bool asio_handler_is_continuation(- read_until_match_op_v1<AsyncReadStream, DynamicBuffer_v1,- MatchCondition, ReadHandler>* this_handler)- {- return this_handler->start_ == 0 ? true- : asio_handler_cont_helpers::is_continuation(- this_handler->handler_);- }-- template <typename AsyncReadStream>- class initiate_async_read_until_match_v1- {- public:- typedef typename AsyncReadStream::executor_type executor_type;-- explicit initiate_async_read_until_match_v1(AsyncReadStream& stream)- : stream_(stream)- {- }-- executor_type get_executor() const noexcept- {- return stream_.get_executor();- }-- template <typename ReadHandler,- typename DynamicBuffer_v1, typename MatchCondition>- void operator()(ReadHandler&& handler,- DynamicBuffer_v1&& buffers,- MatchCondition match_condition) const- {- // If you get an error on the following line it means that your handler- // does not meet the documented type requirements for a ReadHandler.- ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;-- non_const_lvalue<ReadHandler> handler2(handler);- read_until_match_op_v1<AsyncReadStream,- decay_t<DynamicBuffer_v1>,- MatchCondition, decay_t<ReadHandler>>(- stream_, static_cast<DynamicBuffer_v1&&>(buffers),- match_condition, handler2.value)(asio::error_code(), 0, 1);- }-- private:- AsyncReadStream& stream_;- };-} // namespace detail--#if !defined(GENERATING_DOCUMENTATION)--template <template <typename, typename> class Associator,- typename AsyncReadStream, typename DynamicBuffer_v1,- typename MatchCondition, typename ReadHandler, typename DefaultCandidate>-struct associator<Associator,- detail::read_until_match_op_v1<AsyncReadStream,- DynamicBuffer_v1, MatchCondition, ReadHandler>,- DefaultCandidate>- : Associator<ReadHandler, DefaultCandidate>-{- static typename Associator<ReadHandler, DefaultCandidate>::type get(- const detail::read_until_match_op_v1<AsyncReadStream,- DynamicBuffer_v1, MatchCondition, ReadHandler>& h) noexcept- {- return Associator<ReadHandler, DefaultCandidate>::get(h.handler_);- }-- static auto get(- const detail::read_until_match_op_v1<AsyncReadStream,- DynamicBuffer_v1, MatchCondition, ReadHandler>& h,- const DefaultCandidate& c) noexcept- -> decltype(Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c))- {- return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c);- }-};--#endif // !defined(GENERATING_DOCUMENTATION)--#endif // !defined(ASIO_NO_EXTENSIONS)-#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)--namespace detail-{- template <typename AsyncReadStream,- typename DynamicBuffer_v2, typename ReadHandler>- class read_until_delim_op_v2- : public base_from_cancellation_state<ReadHandler>- {- public:- template <typename BufferSequence>- read_until_delim_op_v2(AsyncReadStream& stream,- BufferSequence&& buffers,- char delim, ReadHandler& handler)- : base_from_cancellation_state<ReadHandler>(- handler, enable_partial_cancellation()),- stream_(stream),- buffers_(static_cast<BufferSequence&&>(buffers)),- delim_(delim),- start_(0),- search_position_(0),- bytes_to_read_(0),- handler_(static_cast<ReadHandler&&>(handler))- {- }-- read_until_delim_op_v2(const read_until_delim_op_v2& other)- : base_from_cancellation_state<ReadHandler>(other),- stream_(other.stream_),- buffers_(other.buffers_),- delim_(other.delim_),- start_(other.start_),- search_position_(other.search_position_),- bytes_to_read_(other.bytes_to_read_),- handler_(other.handler_)- {- }-- read_until_delim_op_v2(read_until_delim_op_v2&& other)- : base_from_cancellation_state<ReadHandler>(- static_cast<base_from_cancellation_state<ReadHandler>&&>(other)),- stream_(other.stream_),- buffers_(static_cast<DynamicBuffer_v2&&>(other.buffers_)),- delim_(other.delim_),- start_(other.start_),- search_position_(other.search_position_),- bytes_to_read_(other.bytes_to_read_),- handler_(static_cast<ReadHandler&&>(other.handler_))- {- }-- void operator()(asio::error_code ec,- std::size_t bytes_transferred, int start = 0)- {- const std::size_t not_found = (std::numeric_limits<std::size_t>::max)();- std::size_t pos;- switch (start_ = start)- {- case 1:- for (;;)- {- {- // Determine the range of the data to be searched.- typedef typename DynamicBuffer_v2::const_buffers_type- buffers_type;- typedef buffers_iterator<buffers_type> iterator;- buffers_type data_buffers =- const_cast<const DynamicBuffer_v2&>(buffers_).data(- 0, buffers_.size());- iterator begin = iterator::begin(data_buffers);- iterator start_pos = begin + search_position_;- iterator end = iterator::end(data_buffers);-- // Look for a match.- iterator iter = std::find(start_pos, end, delim_);- if (iter != end)- {- // Found a match. We're done.- search_position_ = iter - begin + 1;- bytes_to_read_ = 0;- }-- // No match yet. Check if buffer is full.- else if (buffers_.size() == buffers_.max_size())- {- search_position_ = not_found;- bytes_to_read_ = 0;- }-- // Need to read some more data.- else- {- // Next search can start with the new data.- search_position_ = end - begin;- bytes_to_read_ = std::min<std::size_t>(- std::max<std::size_t>(512,- buffers_.capacity() - buffers_.size()),- std::min<std::size_t>(65536,- buffers_.max_size() - buffers_.size()));- }- }-- // Check if we're done.- if (!start && bytes_to_read_ == 0)- break;-- // Start a new asynchronous read operation to obtain more data.- pos = buffers_.size();- buffers_.grow(bytes_to_read_);- {- ASIO_HANDLER_LOCATION((- __FILE__, __LINE__, "async_read_until"));- stream_.async_read_some(buffers_.data(pos, bytes_to_read_),- static_cast<read_until_delim_op_v2&&>(*this));- }- return; default:- buffers_.shrink(bytes_to_read_ - bytes_transferred);- if (ec || bytes_transferred == 0)- break;- if (this->cancelled() != cancellation_type::none)- {- ec = error::operation_aborted;- break;- }- }-- const asio::error_code result_ec =- (search_position_ == not_found)- ? error::not_found : ec;-- const std::size_t result_n =- (ec || search_position_ == not_found)- ? 0 : search_position_;-- static_cast<ReadHandler&&>(handler_)(result_ec, result_n);- }- }-- //private:- AsyncReadStream& stream_;- DynamicBuffer_v2 buffers_;- char delim_;- int start_;- std::size_t search_position_;- std::size_t bytes_to_read_;- ReadHandler handler_;- };-- template <typename AsyncReadStream,- typename DynamicBuffer_v2, typename ReadHandler>- inline bool asio_handler_is_continuation(- read_until_delim_op_v2<AsyncReadStream,- DynamicBuffer_v2, ReadHandler>* this_handler)- {- return this_handler->start_ == 0 ? true- : asio_handler_cont_helpers::is_continuation(- this_handler->handler_);- }-- template <typename AsyncReadStream>- class initiate_async_read_until_delim_v2- {- public:- typedef typename AsyncReadStream::executor_type executor_type;-- explicit initiate_async_read_until_delim_v2(AsyncReadStream& stream)- : stream_(stream)- {- }-- executor_type get_executor() const noexcept- {- return stream_.get_executor();- }-- template <typename ReadHandler, typename DynamicBuffer_v2>- void operator()(ReadHandler&& handler,- DynamicBuffer_v2&& buffers, char delim) const- {- // If you get an error on the following line it means that your handler- // does not meet the documented type requirements for a ReadHandler.- ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;-- non_const_lvalue<ReadHandler> handler2(handler);- read_until_delim_op_v2<AsyncReadStream,- decay_t<DynamicBuffer_v2>,- decay_t<ReadHandler>>(- stream_, static_cast<DynamicBuffer_v2&&>(buffers),- delim, handler2.value)(asio::error_code(), 0, 1);- }-- private:- AsyncReadStream& stream_;- };-} // namespace detail--#if !defined(GENERATING_DOCUMENTATION)--template <template <typename, typename> class Associator,- typename AsyncReadStream, typename DynamicBuffer_v2,- typename ReadHandler, typename DefaultCandidate>-struct associator<Associator,- detail::read_until_delim_op_v2<AsyncReadStream,- DynamicBuffer_v2, ReadHandler>,- DefaultCandidate>- : Associator<ReadHandler, DefaultCandidate>-{- static typename Associator<ReadHandler, DefaultCandidate>::type get(- const detail::read_until_delim_op_v2<AsyncReadStream,- DynamicBuffer_v2, ReadHandler>& h) noexcept- {- return Associator<ReadHandler, DefaultCandidate>::get(h.handler_);- }-- static auto get(- const detail::read_until_delim_op_v2<AsyncReadStream,- DynamicBuffer_v2, ReadHandler>& h,- const DefaultCandidate& c) noexcept- -> decltype(Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c))- {- return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c);- }-};--#endif // !defined(GENERATING_DOCUMENTATION)--namespace detail-{- template <typename AsyncReadStream,- typename DynamicBuffer_v2, typename ReadHandler>- class read_until_delim_string_op_v2- : public base_from_cancellation_state<ReadHandler>- {- public:- template <typename BufferSequence>- read_until_delim_string_op_v2(AsyncReadStream& stream,- BufferSequence&& buffers,- const std::string& delim, ReadHandler& handler)- : base_from_cancellation_state<ReadHandler>(- handler, enable_partial_cancellation()),- stream_(stream),- buffers_(static_cast<BufferSequence&&>(buffers)),- delim_(delim),- start_(0),- search_position_(0),- bytes_to_read_(0),- handler_(static_cast<ReadHandler&&>(handler))- {- }-- read_until_delim_string_op_v2(const read_until_delim_string_op_v2& other)- : base_from_cancellation_state<ReadHandler>(other),- stream_(other.stream_),- buffers_(other.buffers_),- delim_(other.delim_),- start_(other.start_),- search_position_(other.search_position_),- bytes_to_read_(other.bytes_to_read_),- handler_(other.handler_)- {- }-- read_until_delim_string_op_v2(read_until_delim_string_op_v2&& other)- : base_from_cancellation_state<ReadHandler>(- static_cast<base_from_cancellation_state<ReadHandler>&&>(other)),- stream_(other.stream_),- buffers_(static_cast<DynamicBuffer_v2&&>(other.buffers_)),- delim_(static_cast<std::string&&>(other.delim_)),- start_(other.start_),- search_position_(other.search_position_),- bytes_to_read_(other.bytes_to_read_),- handler_(static_cast<ReadHandler&&>(other.handler_))- {- }-- void operator()(asio::error_code ec,- std::size_t bytes_transferred, int start = 0)- {- const std::size_t not_found = (std::numeric_limits<std::size_t>::max)();- std::size_t pos;- switch (start_ = start)- {- case 1:- for (;;)- {- {- // Determine the range of the data to be searched.- typedef typename DynamicBuffer_v2::const_buffers_type- buffers_type;- typedef buffers_iterator<buffers_type> iterator;- buffers_type data_buffers =- const_cast<const DynamicBuffer_v2&>(buffers_).data(- 0, buffers_.size());- iterator begin = iterator::begin(data_buffers);- iterator start_pos = begin + search_position_;- iterator end = iterator::end(data_buffers);-- // Look for a match.- std::pair<iterator, bool> result = detail::partial_search(- start_pos, end, delim_.begin(), delim_.end());- if (result.first != end && result.second)- {- // Full match. We're done.- search_position_ = result.first - begin + delim_.length();- bytes_to_read_ = 0;- }-- // No match yet. Check if buffer is full.- else if (buffers_.size() == buffers_.max_size())- {- search_position_ = not_found;- bytes_to_read_ = 0;- }-- // Need to read some more data.- else- {- if (result.first != end)- {- // Partial match. Next search needs to start from beginning of- // match.- search_position_ = result.first - begin;- }- else- {- // Next search can start with the new data.- search_position_ = end - begin;- }-- bytes_to_read_ = std::min<std::size_t>(- std::max<std::size_t>(512,- buffers_.capacity() - buffers_.size()),- std::min<std::size_t>(65536,- buffers_.max_size() - buffers_.size()));- }- }-- // Check if we're done.- if (!start && bytes_to_read_ == 0)- break;-- // Start a new asynchronous read operation to obtain more data.- pos = buffers_.size();- buffers_.grow(bytes_to_read_);- {- ASIO_HANDLER_LOCATION((- __FILE__, __LINE__, "async_read_until"));- stream_.async_read_some(buffers_.data(pos, bytes_to_read_),- static_cast<read_until_delim_string_op_v2&&>(*this));- }- return; default:- buffers_.shrink(bytes_to_read_ - bytes_transferred);- if (ec || bytes_transferred == 0)- break;- if (this->cancelled() != cancellation_type::none)- {- ec = error::operation_aborted;- break;- }- }-- const asio::error_code result_ec =- (search_position_ == not_found)- ? error::not_found : ec;-- const std::size_t result_n =- (ec || search_position_ == not_found)- ? 0 : search_position_;-- static_cast<ReadHandler&&>(handler_)(result_ec, result_n);- }- }-- //private:- AsyncReadStream& stream_;- DynamicBuffer_v2 buffers_;- std::string delim_;- int start_;- std::size_t search_position_;- std::size_t bytes_to_read_;- ReadHandler handler_;- };-- template <typename AsyncReadStream,- typename DynamicBuffer_v2, typename ReadHandler>- inline bool asio_handler_is_continuation(- read_until_delim_string_op_v2<AsyncReadStream,- DynamicBuffer_v2, ReadHandler>* this_handler)- {- return this_handler->start_ == 0 ? true- : asio_handler_cont_helpers::is_continuation(- this_handler->handler_);- }-- template <typename AsyncReadStream>- class initiate_async_read_until_delim_string_v2- {- public:- typedef typename AsyncReadStream::executor_type executor_type;-- explicit initiate_async_read_until_delim_string_v2(AsyncReadStream& stream)- : stream_(stream)- {- }-- executor_type get_executor() const noexcept- {- return stream_.get_executor();- }-- template <typename ReadHandler, typename DynamicBuffer_v2>- void operator()(ReadHandler&& handler,- DynamicBuffer_v2&& buffers,- const std::string& delim) const- {- // If you get an error on the following line it means that your handler- // does not meet the documented type requirements for a ReadHandler.- ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;-- non_const_lvalue<ReadHandler> handler2(handler);- read_until_delim_string_op_v2<AsyncReadStream,- decay_t<DynamicBuffer_v2>,- decay_t<ReadHandler>>(- stream_, static_cast<DynamicBuffer_v2&&>(buffers),- delim, handler2.value)(asio::error_code(), 0, 1);- }-- private:- AsyncReadStream& stream_;- };-} // namespace detail--#if !defined(GENERATING_DOCUMENTATION)--template <template <typename, typename> class Associator,- typename AsyncReadStream, typename DynamicBuffer_v2,- typename ReadHandler, typename DefaultCandidate>-struct associator<Associator,- detail::read_until_delim_string_op_v2<AsyncReadStream,- DynamicBuffer_v2, ReadHandler>,- DefaultCandidate>- : Associator<ReadHandler, DefaultCandidate>-{- static typename Associator<ReadHandler, DefaultCandidate>::type get(- const detail::read_until_delim_string_op_v2<- AsyncReadStream, DynamicBuffer_v2, ReadHandler>& h) noexcept- {- return Associator<ReadHandler, DefaultCandidate>::get(h.handler_);- }-- static auto get(- const detail::read_until_delim_string_op_v2<- AsyncReadStream, DynamicBuffer_v2, ReadHandler>& h,- const DefaultCandidate& c) noexcept- -> decltype(Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c))- {- return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c);- }-};--#endif // !defined(GENERATING_DOCUMENTATION)--#if !defined(ASIO_NO_EXTENSIONS)-#if defined(ASIO_HAS_BOOST_REGEX)--namespace detail-{- template <typename AsyncReadStream, typename DynamicBuffer_v2,- typename RegEx, typename ReadHandler>- class read_until_expr_op_v2- : public base_from_cancellation_state<ReadHandler>- {- public:- template <typename BufferSequence, typename Traits>- read_until_expr_op_v2(AsyncReadStream& stream, BufferSequence&& buffers,- const boost::basic_regex<char, Traits>& expr, ReadHandler& handler)- : base_from_cancellation_state<ReadHandler>(- handler, enable_partial_cancellation()),- stream_(stream),- buffers_(static_cast<BufferSequence&&>(buffers)),- expr_(expr),- start_(0),- search_position_(0),- bytes_to_read_(0),- handler_(static_cast<ReadHandler&&>(handler))- {- }-- read_until_expr_op_v2(const read_until_expr_op_v2& other)- : base_from_cancellation_state<ReadHandler>(other),- stream_(other.stream_),- buffers_(other.buffers_),- expr_(other.expr_),- start_(other.start_),- search_position_(other.search_position_),- bytes_to_read_(other.bytes_to_read_),- handler_(other.handler_)- {- }-- read_until_expr_op_v2(read_until_expr_op_v2&& other)- : base_from_cancellation_state<ReadHandler>(- static_cast<base_from_cancellation_state<ReadHandler>&&>(other)),- stream_(other.stream_),- buffers_(static_cast<DynamicBuffer_v2&&>(other.buffers_)),- expr_(other.expr_),- start_(other.start_),- search_position_(other.search_position_),- bytes_to_read_(other.bytes_to_read_),- handler_(static_cast<ReadHandler&&>(other.handler_))- {- }-- void operator()(asio::error_code ec,- std::size_t bytes_transferred, int start = 0)- {- const std::size_t not_found = (std::numeric_limits<std::size_t>::max)();- std::size_t pos;- switch (start_ = start)- {- case 1:- for (;;)- {- {- // Determine the range of the data to be searched.- typedef typename DynamicBuffer_v2::const_buffers_type- buffers_type;- typedef buffers_iterator<buffers_type> iterator;- buffers_type data_buffers =- const_cast<const DynamicBuffer_v2&>(buffers_).data(- 0, buffers_.size());- iterator begin = iterator::begin(data_buffers);- iterator start_pos = begin + search_position_;- iterator end = iterator::end(data_buffers);-- // Look for a match.- boost::match_results<iterator,- typename std::vector<boost::sub_match<iterator>>::allocator_type>- match_results;- bool match = regex_search(start_pos, end,- match_results, expr_, regex_match_flags());- if (match && match_results[0].matched)- {- // Full match. We're done.- search_position_ = match_results[0].second - begin;- bytes_to_read_ = 0;- }-- // No match yet. Check if buffer is full.- else if (buffers_.size() == buffers_.max_size())- {- search_position_ = not_found;- bytes_to_read_ = 0;- }-- // Need to read some more data.- else- {- if (match)- {- // Partial match. Next search needs to start from beginning of- // match.- search_position_ = match_results[0].first - begin;- }- else- {- // Next search can start with the new data.- search_position_ = end - begin;- }-- bytes_to_read_ = std::min<std::size_t>(- std::max<std::size_t>(512,- buffers_.capacity() - buffers_.size()),- std::min<std::size_t>(65536,- buffers_.max_size() - buffers_.size()));- }- }-- // Check if we're done.- if (!start && bytes_to_read_ == 0)- break;-- // Start a new asynchronous read operation to obtain more data.- pos = buffers_.size();- buffers_.grow(bytes_to_read_);- {- ASIO_HANDLER_LOCATION((- __FILE__, __LINE__, "async_read_until"));- stream_.async_read_some(buffers_.data(pos, bytes_to_read_),- static_cast<read_until_expr_op_v2&&>(*this));- }- return; default:- buffers_.shrink(bytes_to_read_ - bytes_transferred);- if (ec || bytes_transferred == 0)- break;- if (this->cancelled() != cancellation_type::none)- {- ec = error::operation_aborted;- break;- }- }-- const asio::error_code result_ec =- (search_position_ == not_found)- ? error::not_found : ec;-- const std::size_t result_n =- (ec || search_position_ == not_found)- ? 0 : search_position_;-- static_cast<ReadHandler&&>(handler_)(result_ec, result_n);- }- }-- //private:- AsyncReadStream& stream_;- DynamicBuffer_v2 buffers_;- RegEx expr_;- int start_;- std::size_t search_position_;- std::size_t bytes_to_read_;- ReadHandler handler_;- };-- template <typename AsyncReadStream, typename DynamicBuffer_v2,- typename RegEx, typename ReadHandler>- inline bool asio_handler_is_continuation(- read_until_expr_op_v2<AsyncReadStream,- DynamicBuffer_v2, RegEx, ReadHandler>* this_handler)- {- return this_handler->start_ == 0 ? true- : asio_handler_cont_helpers::is_continuation(- this_handler->handler_);- }-- template <typename AsyncReadStream>- class initiate_async_read_until_expr_v2- {- public:- typedef typename AsyncReadStream::executor_type executor_type;-- explicit initiate_async_read_until_expr_v2(AsyncReadStream& stream)- : stream_(stream)- {- }-- executor_type get_executor() const noexcept- {- return stream_.get_executor();- }-- template <typename ReadHandler, typename DynamicBuffer_v2, typename RegEx>- void operator()(ReadHandler&& handler,- DynamicBuffer_v2&& buffers,- const RegEx& expr) const- {- // If you get an error on the following line it means that your handler- // does not meet the documented type requirements for a ReadHandler.- ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;-- non_const_lvalue<ReadHandler> handler2(handler);- read_until_expr_op_v2<AsyncReadStream,- decay_t<DynamicBuffer_v2>,- RegEx, decay_t<ReadHandler>>(- stream_, static_cast<DynamicBuffer_v2&&>(buffers),- expr, handler2.value)(asio::error_code(), 0, 1);- }-- private:- AsyncReadStream& stream_;- };-} // namespace detail--#if !defined(GENERATING_DOCUMENTATION)--template <template <typename, typename> class Associator,- typename AsyncReadStream, typename DynamicBuffer_v2,- typename RegEx, typename ReadHandler, typename DefaultCandidate>-struct associator<Associator,- detail::read_until_expr_op_v2<AsyncReadStream,- DynamicBuffer_v2, RegEx, ReadHandler>,- DefaultCandidate>- : Associator<ReadHandler, DefaultCandidate>-{- static typename Associator<ReadHandler, DefaultCandidate>::type get(- const detail::read_until_expr_op_v2<AsyncReadStream,- DynamicBuffer_v2, RegEx, ReadHandler>& h) noexcept- {- return Associator<ReadHandler, DefaultCandidate>::get(h.handler_);- }-- static auto get(- const detail::read_until_expr_op_v2<AsyncReadStream,- DynamicBuffer_v2, RegEx, ReadHandler>& h,- const DefaultCandidate& c) noexcept- -> decltype(Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c))- {- return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c);- }-};--#endif // !defined(GENERATING_DOCUMENTATION)--#endif // defined(ASIO_HAS_BOOST_REGEX)--namespace detail-{- template <typename AsyncReadStream, typename DynamicBuffer_v2,- typename MatchCondition, typename ReadHandler>- class read_until_match_op_v2- : public base_from_cancellation_state<ReadHandler>- {- public:- template <typename BufferSequence>- read_until_match_op_v2(AsyncReadStream& stream,- BufferSequence&& buffers,- MatchCondition match_condition, ReadHandler& handler)- : base_from_cancellation_state<ReadHandler>(- handler, enable_partial_cancellation()),- stream_(stream),- buffers_(static_cast<BufferSequence&&>(buffers)),- match_condition_(match_condition),- start_(0),- search_position_(0),- bytes_to_read_(0),- handler_(static_cast<ReadHandler&&>(handler))- {- }-- read_until_match_op_v2(const read_until_match_op_v2& other)- : base_from_cancellation_state<ReadHandler>(other),- stream_(other.stream_),- buffers_(other.buffers_),- match_condition_(other.match_condition_),- start_(other.start_),- search_position_(other.search_position_),- bytes_to_read_(other.bytes_to_read_),- handler_(other.handler_)- {- }-- read_until_match_op_v2(read_until_match_op_v2&& other)- : base_from_cancellation_state<ReadHandler>(- static_cast<base_from_cancellation_state<ReadHandler>&&>(other)),- stream_(other.stream_),- buffers_(static_cast<DynamicBuffer_v2&&>(other.buffers_)),- match_condition_(other.match_condition_),- start_(other.start_),- search_position_(other.search_position_),- bytes_to_read_(other.bytes_to_read_),- handler_(static_cast<ReadHandler&&>(other.handler_))- {- }-- void operator()(asio::error_code ec,- std::size_t bytes_transferred, int start = 0)- {- const std::size_t not_found = (std::numeric_limits<std::size_t>::max)();- std::size_t pos;- switch (start_ = start)- {- case 1:- for (;;)- {- {- // Determine the range of the data to be searched.- typedef typename DynamicBuffer_v2::const_buffers_type- buffers_type;- typedef buffers_iterator<buffers_type> iterator;- buffers_type data_buffers =- const_cast<const DynamicBuffer_v2&>(buffers_).data(- 0, buffers_.size());- iterator begin = iterator::begin(data_buffers);- iterator start_pos = begin + search_position_;- iterator end = iterator::end(data_buffers);-- // Look for a match.- std::pair<iterator, bool> result = match_condition_(start_pos, end);- if (result.second)- {- // Full match. We're done.- search_position_ = result.first - begin;- bytes_to_read_ = 0;- }-- // No match yet. Check if buffer is full.- else if (buffers_.size() == buffers_.max_size())- {- search_position_ = not_found;- bytes_to_read_ = 0;- }-- // Need to read some more data.- else- {- if (result.first != end)- {- // Partial match. Next search needs to start from beginning of- // match.- search_position_ = result.first - begin;- }- else- {- // Next search can start with the new data.- search_position_ = end - begin;- }-- bytes_to_read_ = std::min<std::size_t>(- std::max<std::size_t>(512,- buffers_.capacity() - buffers_.size()),- std::min<std::size_t>(65536,- buffers_.max_size() - buffers_.size()));- }- }-- // Check if we're done.- if (!start && bytes_to_read_ == 0)- break;-- // Start a new asynchronous read operation to obtain more data.- pos = buffers_.size();- buffers_.grow(bytes_to_read_);- {- ASIO_HANDLER_LOCATION((- __FILE__, __LINE__, "async_read_until"));- stream_.async_read_some(buffers_.data(pos, bytes_to_read_),- static_cast<read_until_match_op_v2&&>(*this));- }- return; default:- buffers_.shrink(bytes_to_read_ - bytes_transferred);- if (ec || bytes_transferred == 0)- break;- if (this->cancelled() != cancellation_type::none)- {- ec = error::operation_aborted;- break;- }- }-- const asio::error_code result_ec =- (search_position_ == not_found)- ? error::not_found : ec;-- const std::size_t result_n =- (ec || search_position_ == not_found)- ? 0 : search_position_;-- static_cast<ReadHandler&&>(handler_)(result_ec, result_n);- }- }-- //private:- AsyncReadStream& stream_;- DynamicBuffer_v2 buffers_;- MatchCondition match_condition_;- int start_;- std::size_t search_position_;- std::size_t bytes_to_read_;- ReadHandler handler_;- };-- template <typename AsyncReadStream, typename DynamicBuffer_v2,- typename MatchCondition, typename ReadHandler>- inline bool asio_handler_is_continuation(- read_until_match_op_v2<AsyncReadStream, DynamicBuffer_v2,- MatchCondition, ReadHandler>* this_handler)- {- return this_handler->start_ == 0 ? true- : asio_handler_cont_helpers::is_continuation(- this_handler->handler_);- }-- template <typename AsyncReadStream>- class initiate_async_read_until_match_v2- {- public:- typedef typename AsyncReadStream::executor_type executor_type;-- explicit initiate_async_read_until_match_v2(AsyncReadStream& stream)- : stream_(stream)- {- }-- executor_type get_executor() const noexcept- {- return stream_.get_executor();- }-- template <typename ReadHandler,- typename DynamicBuffer_v2, typename MatchCondition>- void operator()(ReadHandler&& handler,- DynamicBuffer_v2&& buffers,- MatchCondition match_condition) const- {- // If you get an error on the following line it means that your handler- // does not meet the documented type requirements for a ReadHandler.- ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;-- non_const_lvalue<ReadHandler> handler2(handler);- read_until_match_op_v2<AsyncReadStream, decay_t<DynamicBuffer_v2>,- MatchCondition, decay_t<ReadHandler>>(- stream_, static_cast<DynamicBuffer_v2&&>(buffers),- match_condition, handler2.value)(asio::error_code(), 0, 1);- }-- private:- AsyncReadStream& stream_;- };-} // namespace detail--#if !defined(GENERATING_DOCUMENTATION)--template <template <typename, typename> class Associator,- typename AsyncReadStream, typename DynamicBuffer_v2,- typename MatchCondition, typename ReadHandler, typename DefaultCandidate>-struct associator<Associator,- detail::read_until_match_op_v2<AsyncReadStream,- DynamicBuffer_v2, MatchCondition, ReadHandler>,- DefaultCandidate>- : Associator<ReadHandler, DefaultCandidate>-{- static typename Associator<ReadHandler, DefaultCandidate>::type get(- const detail::read_until_match_op_v2<AsyncReadStream,- DynamicBuffer_v2, MatchCondition, ReadHandler>& h) noexcept- {- return Associator<ReadHandler, DefaultCandidate>::get(h.handler_);- }-- static auto get(- const detail::read_until_match_op_v2<AsyncReadStream,- DynamicBuffer_v2, MatchCondition, ReadHandler>& h,- const DefaultCandidate& c) noexcept- -> decltype(Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c))- {- return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c);- }-};--#endif // !defined(GENERATING_DOCUMENTATION)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_IMPL_READ_UNTIL_HPP+#define ASIO_IMPL_READ_UNTIL_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include <algorithm>+#include <string>+#include <vector>+#include <utility>+#include "asio/associator.hpp"+#include "asio/buffer.hpp"+#include "asio/buffers_iterator.hpp"+#include "asio/detail/base_from_cancellation_state.hpp"+#include "asio/detail/bind_handler.hpp"+#include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_cont_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp"+#include "asio/detail/handler_tracking.hpp"+#include "asio/detail/handler_type_requirements.hpp"+#include "asio/detail/limits.hpp"+#include "asio/detail/non_const_lvalue.hpp"+#include "asio/detail/throw_error.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {++namespace detail+{+ // Algorithm that finds a subsequence of equal values in a sequence. Returns+ // (iterator,true) if a full match was found, in which case the iterator+ // points to the beginning of the match. Returns (iterator,false) if a+ // partial match was found at the end of the first sequence, in which case+ // the iterator points to the beginning of the partial match. Returns+ // (last1,false) if no full or partial match was found.+ template <typename Iterator1, typename Iterator2>+ std::pair<Iterator1, bool> partial_search(+ Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2)+ {+ for (Iterator1 iter1 = first1; iter1 != last1; ++iter1)+ {+ Iterator1 test_iter1 = iter1;+ Iterator2 test_iter2 = first2;+ for (;; ++test_iter1, ++test_iter2)+ {+ if (test_iter2 == last2)+ return std::make_pair(iter1, true);+ if (test_iter1 == last1)+ {+ if (test_iter2 != first2)+ return std::make_pair(iter1, false);+ else+ break;+ }+ if (*test_iter1 != *test_iter2)+ break;+ }+ }+ return std::make_pair(last1, false);+ }+} // namespace detail++#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)++template <typename SyncReadStream, typename DynamicBuffer_v1>+inline std::size_t read_until(SyncReadStream& s,+ ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, char delim,+ typename constraint<+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+ >::type,+ typename constraint<+ !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+ >::type)+{+ asio::error_code ec;+ std::size_t bytes_transferred = read_until(s,+ ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), delim, ec);+ asio::detail::throw_error(ec, "read_until");+ return bytes_transferred;+}++template <typename SyncReadStream, typename DynamicBuffer_v1>+std::size_t read_until(SyncReadStream& s,+ ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+ char delim, asio::error_code& ec,+ typename constraint<+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+ >::type,+ typename constraint<+ !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+ >::type)+{+ typename decay<DynamicBuffer_v1>::type b(+ ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers));++ std::size_t search_position = 0;+ for (;;)+ {+ // Determine the range of the data to be searched.+ typedef typename DynamicBuffer_v1::const_buffers_type buffers_type;+ typedef buffers_iterator<buffers_type> iterator;+ buffers_type data_buffers = b.data();+ iterator begin = iterator::begin(data_buffers);+ iterator start_pos = begin + search_position;+ iterator end = iterator::end(data_buffers);++ // Look for a match.+ iterator iter = std::find(start_pos, end, delim);+ if (iter != end)+ {+ // Found a match. We're done.+ ec = asio::error_code();+ return iter - begin + 1;+ }+ else+ {+ // No match. Next search can start with the new data.+ search_position = end - begin;+ }++ // Check if buffer is full.+ if (b.size() == b.max_size())+ {+ ec = error::not_found;+ return 0;+ }++ // Need more data.+ std::size_t bytes_to_read = std::min<std::size_t>(+ std::max<std::size_t>(512, b.capacity() - b.size()),+ std::min<std::size_t>(65536, b.max_size() - b.size()));+ b.commit(s.read_some(b.prepare(bytes_to_read), ec));+ if (ec)+ return 0;+ }+}++template <typename SyncReadStream, typename DynamicBuffer_v1>+inline std::size_t read_until(SyncReadStream& s,+ ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+ ASIO_STRING_VIEW_PARAM delim,+ typename constraint<+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+ >::type,+ typename constraint<+ !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+ >::type)+{+ asio::error_code ec;+ std::size_t bytes_transferred = read_until(s,+ ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), delim, ec);+ asio::detail::throw_error(ec, "read_until");+ return bytes_transferred;+}++template <typename SyncReadStream, typename DynamicBuffer_v1>+std::size_t read_until(SyncReadStream& s,+ ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+ ASIO_STRING_VIEW_PARAM delim, asio::error_code& ec,+ typename constraint<+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+ >::type,+ typename constraint<+ !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+ >::type)+{+ typename decay<DynamicBuffer_v1>::type b(+ ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers));++ std::size_t search_position = 0;+ for (;;)+ {+ // Determine the range of the data to be searched.+ typedef typename DynamicBuffer_v1::const_buffers_type buffers_type;+ typedef buffers_iterator<buffers_type> iterator;+ buffers_type data_buffers = b.data();+ iterator begin = iterator::begin(data_buffers);+ iterator start_pos = begin + search_position;+ iterator end = iterator::end(data_buffers);++ // Look for a match.+ std::pair<iterator, bool> result = detail::partial_search(+ start_pos, end, delim.begin(), delim.end());+ if (result.first != end)+ {+ if (result.second)+ {+ // Full match. We're done.+ ec = asio::error_code();+ return result.first - begin + delim.length();+ }+ else+ {+ // Partial match. Next search needs to start from beginning of match.+ search_position = result.first - begin;+ }+ }+ else+ {+ // No match. Next search can start with the new data.+ search_position = end - begin;+ }++ // Check if buffer is full.+ if (b.size() == b.max_size())+ {+ ec = error::not_found;+ return 0;+ }++ // Need more data.+ std::size_t bytes_to_read = std::min<std::size_t>(+ std::max<std::size_t>(512, b.capacity() - b.size()),+ std::min<std::size_t>(65536, b.max_size() - b.size()));+ b.commit(s.read_some(b.prepare(bytes_to_read), ec));+ if (ec)+ return 0;+ }+}++#if !defined(ASIO_NO_EXTENSIONS)+#if defined(ASIO_HAS_BOOST_REGEX)++template <typename SyncReadStream, typename DynamicBuffer_v1>+inline std::size_t read_until(SyncReadStream& s,+ ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+ const boost::regex& expr,+ typename constraint<+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+ >::type,+ typename constraint<+ !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+ >::type)+{+ asio::error_code ec;+ std::size_t bytes_transferred = read_until(s,+ ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), expr, ec);+ asio::detail::throw_error(ec, "read_until");+ return bytes_transferred;+}++template <typename SyncReadStream, typename DynamicBuffer_v1>+std::size_t read_until(SyncReadStream& s,+ ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+ const boost::regex& expr, asio::error_code& ec,+ typename constraint<+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+ >::type,+ typename constraint<+ !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+ >::type)+{+ typename decay<DynamicBuffer_v1>::type b(+ ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers));++ std::size_t search_position = 0;+ for (;;)+ {+ // Determine the range of the data to be searched.+ typedef typename DynamicBuffer_v1::const_buffers_type buffers_type;+ typedef buffers_iterator<buffers_type> iterator;+ buffers_type data_buffers = b.data();+ iterator begin = iterator::begin(data_buffers);+ iterator start_pos = begin + search_position;+ iterator end = iterator::end(data_buffers);++ // Look for a match.+ boost::match_results<iterator,+ typename std::vector<boost::sub_match<iterator> >::allocator_type>+ match_results;+ if (regex_search(start_pos, end, match_results, expr,+ boost::match_default | boost::match_partial))+ {+ if (match_results[0].matched)+ {+ // Full match. We're done.+ ec = asio::error_code();+ return match_results[0].second - begin;+ }+ else+ {+ // Partial match. Next search needs to start from beginning of match.+ search_position = match_results[0].first - begin;+ }+ }+ else+ {+ // No match. Next search can start with the new data.+ search_position = end - begin;+ }++ // Check if buffer is full.+ if (b.size() == b.max_size())+ {+ ec = error::not_found;+ return 0;+ }++ // Need more data.+ std::size_t bytes_to_read = std::min<std::size_t>(+ std::max<std::size_t>(512, b.capacity() - b.size()),+ std::min<std::size_t>(65536, b.max_size() - b.size()));+ b.commit(s.read_some(b.prepare(bytes_to_read), ec));+ if (ec)+ return 0;+ }+}++#endif // defined(ASIO_HAS_BOOST_REGEX)++template <typename SyncReadStream,+ typename DynamicBuffer_v1, typename MatchCondition>+inline std::size_t read_until(SyncReadStream& s,+ ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+ MatchCondition match_condition,+ typename constraint<+ is_match_condition<MatchCondition>::value+ >::type,+ typename constraint<+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+ >::type,+ typename constraint<+ !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+ >::type)+{+ asio::error_code ec;+ std::size_t bytes_transferred = read_until(s,+ ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+ match_condition, ec);+ asio::detail::throw_error(ec, "read_until");+ return bytes_transferred;+}++template <typename SyncReadStream,+ typename DynamicBuffer_v1, typename MatchCondition>+std::size_t read_until(SyncReadStream& s,+ ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+ MatchCondition match_condition, asio::error_code& ec,+ typename constraint<+ is_match_condition<MatchCondition>::value+ >::type,+ typename constraint<+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+ >::type,+ typename constraint<+ !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+ >::type)+{+ typename decay<DynamicBuffer_v1>::type b(+ ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers));++ std::size_t search_position = 0;+ for (;;)+ {+ // Determine the range of the data to be searched.+ typedef typename DynamicBuffer_v1::const_buffers_type buffers_type;+ typedef buffers_iterator<buffers_type> iterator;+ buffers_type data_buffers = b.data();+ iterator begin = iterator::begin(data_buffers);+ iterator start_pos = begin + search_position;+ iterator end = iterator::end(data_buffers);++ // Look for a match.+ std::pair<iterator, bool> result = match_condition(start_pos, end);+ if (result.second)+ {+ // Full match. We're done.+ ec = asio::error_code();+ return result.first - begin;+ }+ else if (result.first != end)+ {+ // Partial match. Next search needs to start from beginning of match.+ search_position = result.first - begin;+ }+ else+ {+ // No match. Next search can start with the new data.+ search_position = end - begin;+ }++ // Check if buffer is full.+ if (b.size() == b.max_size())+ {+ ec = error::not_found;+ return 0;+ }++ // Need more data.+ std::size_t bytes_to_read = std::min<std::size_t>(+ std::max<std::size_t>(512, b.capacity() - b.size()),+ std::min<std::size_t>(65536, b.max_size() - b.size()));+ b.commit(s.read_some(b.prepare(bytes_to_read), ec));+ if (ec)+ return 0;+ }+}++#if !defined(ASIO_NO_IOSTREAM)++template <typename SyncReadStream, typename Allocator>+inline std::size_t read_until(SyncReadStream& s,+ asio::basic_streambuf<Allocator>& b, char delim)+{+ return read_until(s, basic_streambuf_ref<Allocator>(b), delim);+}++template <typename SyncReadStream, typename Allocator>+inline std::size_t read_until(SyncReadStream& s,+ asio::basic_streambuf<Allocator>& b, char delim,+ asio::error_code& ec)+{+ return read_until(s, basic_streambuf_ref<Allocator>(b), delim, ec);+}++template <typename SyncReadStream, typename Allocator>+inline std::size_t read_until(SyncReadStream& s,+ asio::basic_streambuf<Allocator>& b,+ ASIO_STRING_VIEW_PARAM delim)+{+ return read_until(s, basic_streambuf_ref<Allocator>(b), delim);+}++template <typename SyncReadStream, typename Allocator>+inline std::size_t read_until(SyncReadStream& s,+ asio::basic_streambuf<Allocator>& b,+ ASIO_STRING_VIEW_PARAM delim, asio::error_code& ec)+{+ return read_until(s, basic_streambuf_ref<Allocator>(b), delim, ec);+}++#if defined(ASIO_HAS_BOOST_REGEX)++template <typename SyncReadStream, typename Allocator>+inline std::size_t read_until(SyncReadStream& s,+ asio::basic_streambuf<Allocator>& b, const boost::regex& expr)+{+ return read_until(s, basic_streambuf_ref<Allocator>(b), expr);+}++template <typename SyncReadStream, typename Allocator>+inline std::size_t read_until(SyncReadStream& s,+ asio::basic_streambuf<Allocator>& b, const boost::regex& expr,+ asio::error_code& ec)+{+ return read_until(s, basic_streambuf_ref<Allocator>(b), expr, ec);+}++#endif // defined(ASIO_HAS_BOOST_REGEX)++template <typename SyncReadStream, typename Allocator, typename MatchCondition>+inline std::size_t read_until(SyncReadStream& s,+ asio::basic_streambuf<Allocator>& b, MatchCondition match_condition,+ typename constraint<is_match_condition<MatchCondition>::value>::type)+{+ return read_until(s, basic_streambuf_ref<Allocator>(b), match_condition);+}++template <typename SyncReadStream, typename Allocator, typename MatchCondition>+inline std::size_t read_until(SyncReadStream& s,+ asio::basic_streambuf<Allocator>& b,+ MatchCondition match_condition, asio::error_code& ec,+ typename constraint<is_match_condition<MatchCondition>::value>::type)+{+ return read_until(s, basic_streambuf_ref<Allocator>(b), match_condition, ec);+}++#endif // !defined(ASIO_NO_IOSTREAM)+#endif // !defined(ASIO_NO_EXTENSIONS)+#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)++template <typename SyncReadStream, typename DynamicBuffer_v2>+inline std::size_t read_until(SyncReadStream& s,+ DynamicBuffer_v2 buffers, char delim,+ typename constraint<+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value+ >::type)+{+ asio::error_code ec;+ std::size_t bytes_transferred = read_until(s,+ ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), delim, ec);+ asio::detail::throw_error(ec, "read_until");+ return bytes_transferred;+}++template <typename SyncReadStream, typename DynamicBuffer_v2>+std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers,+ char delim, asio::error_code& ec,+ typename constraint<+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value+ >::type)+{+ DynamicBuffer_v2& b = buffers;++ std::size_t search_position = 0;+ for (;;)+ {+ // Determine the range of the data to be searched.+ typedef typename DynamicBuffer_v2::const_buffers_type buffers_type;+ typedef buffers_iterator<buffers_type> iterator;+ buffers_type data_buffers =+ const_cast<const DynamicBuffer_v2&>(b).data(0, b.size());+ iterator begin = iterator::begin(data_buffers);+ iterator start_pos = begin + search_position;+ iterator end = iterator::end(data_buffers);++ // Look for a match.+ iterator iter = std::find(start_pos, end, delim);+ if (iter != end)+ {+ // Found a match. We're done.+ ec = asio::error_code();+ return iter - begin + 1;+ }+ else+ {+ // No match. Next search can start with the new data.+ search_position = end - begin;+ }++ // Check if buffer is full.+ if (b.size() == b.max_size())+ {+ ec = error::not_found;+ return 0;+ }++ // Need more data.+ std::size_t bytes_to_read = std::min<std::size_t>(+ std::max<std::size_t>(512, b.capacity() - b.size()),+ std::min<std::size_t>(65536, b.max_size() - b.size()));+ std::size_t pos = b.size();+ b.grow(bytes_to_read);+ std::size_t bytes_transferred = s.read_some(b.data(pos, bytes_to_read), ec);+ b.shrink(bytes_to_read - bytes_transferred);+ if (ec)+ return 0;+ }+}++template <typename SyncReadStream, typename DynamicBuffer_v2>+inline std::size_t read_until(SyncReadStream& s,+ DynamicBuffer_v2 buffers, ASIO_STRING_VIEW_PARAM delim,+ typename constraint<+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value+ >::type)+{+ asio::error_code ec;+ std::size_t bytes_transferred = read_until(s,+ ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), delim, ec);+ asio::detail::throw_error(ec, "read_until");+ return bytes_transferred;+}++template <typename SyncReadStream, typename DynamicBuffer_v2>+std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers,+ ASIO_STRING_VIEW_PARAM delim, asio::error_code& ec,+ typename constraint<+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value+ >::type)+{+ DynamicBuffer_v2& b = buffers;++ std::size_t search_position = 0;+ for (;;)+ {+ // Determine the range of the data to be searched.+ typedef typename DynamicBuffer_v2::const_buffers_type buffers_type;+ typedef buffers_iterator<buffers_type> iterator;+ buffers_type data_buffers =+ const_cast<const DynamicBuffer_v2&>(b).data(0, b.size());+ iterator begin = iterator::begin(data_buffers);+ iterator start_pos = begin + search_position;+ iterator end = iterator::end(data_buffers);++ // Look for a match.+ std::pair<iterator, bool> result = detail::partial_search(+ start_pos, end, delim.begin(), delim.end());+ if (result.first != end)+ {+ if (result.second)+ {+ // Full match. We're done.+ ec = asio::error_code();+ return result.first - begin + delim.length();+ }+ else+ {+ // Partial match. Next search needs to start from beginning of match.+ search_position = result.first - begin;+ }+ }+ else+ {+ // No match. Next search can start with the new data.+ search_position = end - begin;+ }++ // Check if buffer is full.+ if (b.size() == b.max_size())+ {+ ec = error::not_found;+ return 0;+ }++ // Need more data.+ std::size_t bytes_to_read = std::min<std::size_t>(+ std::max<std::size_t>(512, b.capacity() - b.size()),+ std::min<std::size_t>(65536, b.max_size() - b.size()));+ std::size_t pos = b.size();+ b.grow(bytes_to_read);+ std::size_t bytes_transferred = s.read_some(b.data(pos, bytes_to_read), ec);+ b.shrink(bytes_to_read - bytes_transferred);+ if (ec)+ return 0;+ }+}++#if !defined(ASIO_NO_EXTENSIONS)+#if defined(ASIO_HAS_BOOST_REGEX)++template <typename SyncReadStream, typename DynamicBuffer_v2>+inline std::size_t read_until(SyncReadStream& s,+ DynamicBuffer_v2 buffers, const boost::regex& expr,+ typename constraint<+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value+ >::type)+{+ asio::error_code ec;+ std::size_t bytes_transferred = read_until(s,+ ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), expr, ec);+ asio::detail::throw_error(ec, "read_until");+ return bytes_transferred;+}++template <typename SyncReadStream, typename DynamicBuffer_v2>+std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers,+ const boost::regex& expr, asio::error_code& ec,+ typename constraint<+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value+ >::type)+{+ DynamicBuffer_v2& b = buffers;++ std::size_t search_position = 0;+ for (;;)+ {+ // Determine the range of the data to be searched.+ typedef typename DynamicBuffer_v2::const_buffers_type buffers_type;+ typedef buffers_iterator<buffers_type> iterator;+ buffers_type data_buffers =+ const_cast<const DynamicBuffer_v2&>(b).data(0, b.size());+ iterator begin = iterator::begin(data_buffers);+ iterator start_pos = begin + search_position;+ iterator end = iterator::end(data_buffers);++ // Look for a match.+ boost::match_results<iterator,+ typename std::vector<boost::sub_match<iterator> >::allocator_type>+ match_results;+ if (regex_search(start_pos, end, match_results, expr,+ boost::match_default | boost::match_partial))+ {+ if (match_results[0].matched)+ {+ // Full match. We're done.+ ec = asio::error_code();+ return match_results[0].second - begin;+ }+ else+ {+ // Partial match. Next search needs to start from beginning of match.+ search_position = match_results[0].first - begin;+ }+ }+ else+ {+ // No match. Next search can start with the new data.+ search_position = end - begin;+ }++ // Check if buffer is full.+ if (b.size() == b.max_size())+ {+ ec = error::not_found;+ return 0;+ }++ // Need more data.+ std::size_t bytes_to_read = std::min<std::size_t>(+ std::max<std::size_t>(512, b.capacity() - b.size()),+ std::min<std::size_t>(65536, b.max_size() - b.size()));+ std::size_t pos = b.size();+ b.grow(bytes_to_read);+ std::size_t bytes_transferred = s.read_some(b.data(pos, bytes_to_read), ec);+ b.shrink(bytes_to_read - bytes_transferred);+ if (ec)+ return 0;+ }+}++#endif // defined(ASIO_HAS_BOOST_REGEX)++template <typename SyncReadStream,+ typename DynamicBuffer_v2, typename MatchCondition>+inline std::size_t read_until(SyncReadStream& s,+ DynamicBuffer_v2 buffers, MatchCondition match_condition,+ typename constraint<+ is_match_condition<MatchCondition>::value+ >::type,+ typename constraint<+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value+ >::type)+{+ asio::error_code ec;+ std::size_t bytes_transferred = read_until(s,+ ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+ match_condition, ec);+ asio::detail::throw_error(ec, "read_until");+ return bytes_transferred;+}++template <typename SyncReadStream,+ typename DynamicBuffer_v2, typename MatchCondition>+std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers,+ MatchCondition match_condition, asio::error_code& ec,+ typename constraint<+ is_match_condition<MatchCondition>::value+ >::type,+ typename constraint<+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value+ >::type)+{+ DynamicBuffer_v2& b = buffers;++ std::size_t search_position = 0;+ for (;;)+ {+ // Determine the range of the data to be searched.+ typedef typename DynamicBuffer_v2::const_buffers_type buffers_type;+ typedef buffers_iterator<buffers_type> iterator;+ buffers_type data_buffers =+ const_cast<const DynamicBuffer_v2&>(b).data(0, b.size());+ iterator begin = iterator::begin(data_buffers);+ iterator start_pos = begin + search_position;+ iterator end = iterator::end(data_buffers);++ // Look for a match.+ std::pair<iterator, bool> result = match_condition(start_pos, end);+ if (result.second)+ {+ // Full match. We're done.+ ec = asio::error_code();+ return result.first - begin;+ }+ else if (result.first != end)+ {+ // Partial match. Next search needs to start from beginning of match.+ search_position = result.first - begin;+ }+ else+ {+ // No match. Next search can start with the new data.+ search_position = end - begin;+ }++ // Check if buffer is full.+ if (b.size() == b.max_size())+ {+ ec = error::not_found;+ return 0;+ }++ // Need more data.+ std::size_t bytes_to_read = std::min<std::size_t>(+ std::max<std::size_t>(512, b.capacity() - b.size()),+ std::min<std::size_t>(65536, b.max_size() - b.size()));+ std::size_t pos = b.size();+ b.grow(bytes_to_read);+ std::size_t bytes_transferred = s.read_some(b.data(pos, bytes_to_read), ec);+ b.shrink(bytes_to_read - bytes_transferred);+ if (ec)+ return 0;+ }+}++#endif // !defined(ASIO_NO_EXTENSIONS)++#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)++namespace detail+{+ template <typename AsyncReadStream,+ typename DynamicBuffer_v1, typename ReadHandler>+ class read_until_delim_op_v1+ : public base_from_cancellation_state<ReadHandler>+ {+ public:+ template <typename BufferSequence>+ read_until_delim_op_v1(AsyncReadStream& stream,+ ASIO_MOVE_ARG(BufferSequence) buffers,+ char delim, ReadHandler& handler)+ : base_from_cancellation_state<ReadHandler>(+ handler, enable_partial_cancellation()),+ stream_(stream),+ buffers_(ASIO_MOVE_CAST(BufferSequence)(buffers)),+ delim_(delim),+ start_(0),+ search_position_(0),+ handler_(ASIO_MOVE_CAST(ReadHandler)(handler))+ {+ }++#if defined(ASIO_HAS_MOVE)+ read_until_delim_op_v1(const read_until_delim_op_v1& other)+ : base_from_cancellation_state<ReadHandler>(other),+ stream_(other.stream_),+ buffers_(other.buffers_),+ delim_(other.delim_),+ start_(other.start_),+ search_position_(other.search_position_),+ handler_(other.handler_)+ {+ }++ read_until_delim_op_v1(read_until_delim_op_v1&& other)+ : base_from_cancellation_state<ReadHandler>(+ ASIO_MOVE_CAST(base_from_cancellation_state<+ ReadHandler>)(other)),+ stream_(other.stream_),+ buffers_(ASIO_MOVE_CAST(DynamicBuffer_v1)(other.buffers_)),+ delim_(other.delim_),+ start_(other.start_),+ search_position_(other.search_position_),+ handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_))+ {+ }+#endif // defined(ASIO_HAS_MOVE)++ void operator()(asio::error_code ec,+ std::size_t bytes_transferred, int start = 0)+ {+ const std::size_t not_found = (std::numeric_limits<std::size_t>::max)();+ std::size_t bytes_to_read;+ switch (start_ = start)+ {+ case 1:+ for (;;)+ {+ {+ // Determine the range of the data to be searched.+ typedef typename DynamicBuffer_v1::const_buffers_type+ buffers_type;+ typedef buffers_iterator<buffers_type> iterator;+ buffers_type data_buffers = buffers_.data();+ iterator begin = iterator::begin(data_buffers);+ iterator start_pos = begin + search_position_;+ iterator end = iterator::end(data_buffers);++ // Look for a match.+ iterator iter = std::find(start_pos, end, delim_);+ if (iter != end)+ {+ // Found a match. We're done.+ search_position_ = iter - begin + 1;+ bytes_to_read = 0;+ }++ // No match yet. Check if buffer is full.+ else if (buffers_.size() == buffers_.max_size())+ {+ search_position_ = not_found;+ bytes_to_read = 0;+ }++ // Need to read some more data.+ else+ {+ // Next search can start with the new data.+ search_position_ = end - begin;+ bytes_to_read = std::min<std::size_t>(+ std::max<std::size_t>(512,+ buffers_.capacity() - buffers_.size()),+ std::min<std::size_t>(65536,+ buffers_.max_size() - buffers_.size()));+ }+ }++ // Check if we're done.+ if (!start && bytes_to_read == 0)+ break;++ // Start a new asynchronous read operation to obtain more data.+ {+ ASIO_HANDLER_LOCATION((+ __FILE__, __LINE__, "async_read_until"));+ stream_.async_read_some(buffers_.prepare(bytes_to_read),+ ASIO_MOVE_CAST(read_until_delim_op_v1)(*this));+ }+ return; default:+ buffers_.commit(bytes_transferred);+ if (ec || bytes_transferred == 0)+ break;+ if (this->cancelled() != cancellation_type::none)+ {+ ec = error::operation_aborted;+ break;+ }+ }++ const asio::error_code result_ec =+ (search_position_ == not_found)+ ? error::not_found : ec;++ const std::size_t result_n =+ (ec || search_position_ == not_found)+ ? 0 : search_position_;++ ASIO_MOVE_OR_LVALUE(ReadHandler)(handler_)(result_ec, result_n);+ }+ }++ //private:+ AsyncReadStream& stream_;+ DynamicBuffer_v1 buffers_;+ char delim_;+ int start_;+ std::size_t search_position_;+ ReadHandler handler_;+ };++ template <typename AsyncReadStream,+ typename DynamicBuffer_v1, typename ReadHandler>+ inline asio_handler_allocate_is_deprecated+ asio_handler_allocate(std::size_t size,+ read_until_delim_op_v1<AsyncReadStream,+ DynamicBuffer_v1, ReadHandler>* this_handler)+ {+#if defined(ASIO_NO_DEPRECATED)+ asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+ return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+ return asio_handler_alloc_helpers::allocate(+ size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename AsyncReadStream,+ typename DynamicBuffer_v1, typename ReadHandler>+ inline asio_handler_deallocate_is_deprecated+ asio_handler_deallocate(void* pointer, std::size_t size,+ read_until_delim_op_v1<AsyncReadStream,+ DynamicBuffer_v1, ReadHandler>* this_handler)+ {+ asio_handler_alloc_helpers::deallocate(+ pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename AsyncReadStream,+ typename DynamicBuffer_v1, typename ReadHandler>+ inline bool asio_handler_is_continuation(+ read_until_delim_op_v1<AsyncReadStream,+ DynamicBuffer_v1, ReadHandler>* this_handler)+ {+ return this_handler->start_ == 0 ? true+ : asio_handler_cont_helpers::is_continuation(+ this_handler->handler_);+ }++ template <typename Function, typename AsyncReadStream,+ typename DynamicBuffer_v1, typename ReadHandler>+ inline asio_handler_invoke_is_deprecated+ asio_handler_invoke(Function& function,+ read_until_delim_op_v1<AsyncReadStream,+ DynamicBuffer_v1, ReadHandler>* this_handler)+ {+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename Function, typename AsyncReadStream,+ typename DynamicBuffer_v1, typename ReadHandler>+ inline asio_handler_invoke_is_deprecated+ asio_handler_invoke(const Function& function,+ read_until_delim_op_v1<AsyncReadStream,+ DynamicBuffer_v1, ReadHandler>* this_handler)+ {+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename AsyncReadStream>+ class initiate_async_read_until_delim_v1+ {+ public:+ typedef typename AsyncReadStream::executor_type executor_type;++ explicit initiate_async_read_until_delim_v1(AsyncReadStream& stream)+ : stream_(stream)+ {+ }++ executor_type get_executor() const ASIO_NOEXCEPT+ {+ return stream_.get_executor();+ }++ template <typename ReadHandler, typename DynamicBuffer_v1>+ void operator()(ASIO_MOVE_ARG(ReadHandler) handler,+ ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+ char delim) const+ {+ // If you get an error on the following line it means that your handler+ // does not meet the documented type requirements for a ReadHandler.+ ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;++ non_const_lvalue<ReadHandler> handler2(handler);+ read_until_delim_op_v1<AsyncReadStream,+ typename decay<DynamicBuffer_v1>::type,+ typename decay<ReadHandler>::type>(+ stream_, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+ delim, handler2.value)(asio::error_code(), 0, 1);+ }++ private:+ AsyncReadStream& stream_;+ };+} // namespace detail++#if !defined(GENERATING_DOCUMENTATION)++template <template <typename, typename> class Associator,+ typename AsyncReadStream, typename DynamicBuffer_v1,+ typename ReadHandler, typename DefaultCandidate>+struct associator<Associator,+ detail::read_until_delim_op_v1<AsyncReadStream,+ DynamicBuffer_v1, ReadHandler>,+ DefaultCandidate>+ : Associator<ReadHandler, DefaultCandidate>+{+ static typename Associator<ReadHandler, DefaultCandidate>::type+ get(const detail::read_until_delim_op_v1<AsyncReadStream,+ DynamicBuffer_v1, ReadHandler>& h) ASIO_NOEXCEPT+ {+ return Associator<ReadHandler, DefaultCandidate>::get(h.handler_);+ }++ static ASIO_AUTO_RETURN_TYPE_PREFIX2(+ typename Associator<ReadHandler, DefaultCandidate>::type)+ get(const detail::read_until_delim_op_v1<AsyncReadStream,+ DynamicBuffer_v1, ReadHandler>& h,+ const DefaultCandidate& c) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c)))+ {+ return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c);+ }+};++#endif // !defined(GENERATING_DOCUMENTATION)++template <typename AsyncReadStream, typename DynamicBuffer_v1,+ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+ std::size_t)) ReadToken>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+async_read_until(AsyncReadStream& s,+ ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+ char delim, ASIO_MOVE_ARG(ReadToken) token,+ typename constraint<+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+ >::type,+ typename constraint<+ !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+ >::type)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_initiate<ReadToken,+ void (asio::error_code, std::size_t)>(+ declval<detail::initiate_async_read_until_delim_v1<AsyncReadStream> >(),+ token, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), delim)))+{+ return async_initiate<ReadToken,+ void (asio::error_code, std::size_t)>(+ detail::initiate_async_read_until_delim_v1<AsyncReadStream>(s),+ token, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), delim);+}++namespace detail+{+ template <typename AsyncReadStream,+ typename DynamicBuffer_v1, typename ReadHandler>+ class read_until_delim_string_op_v1+ : public base_from_cancellation_state<ReadHandler>+ {+ public:+ template <typename BufferSequence>+ read_until_delim_string_op_v1(AsyncReadStream& stream,+ ASIO_MOVE_ARG(BufferSequence) buffers,+ const std::string& delim, ReadHandler& handler)+ : base_from_cancellation_state<ReadHandler>(+ handler, enable_partial_cancellation()),+ stream_(stream),+ buffers_(ASIO_MOVE_CAST(BufferSequence)(buffers)),+ delim_(delim),+ start_(0),+ search_position_(0),+ handler_(ASIO_MOVE_CAST(ReadHandler)(handler))+ {+ }++#if defined(ASIO_HAS_MOVE)+ read_until_delim_string_op_v1(const read_until_delim_string_op_v1& other)+ : base_from_cancellation_state<ReadHandler>(other),+ stream_(other.stream_),+ buffers_(other.buffers_),+ delim_(other.delim_),+ start_(other.start_),+ search_position_(other.search_position_),+ handler_(other.handler_)+ {+ }++ read_until_delim_string_op_v1(read_until_delim_string_op_v1&& other)+ : base_from_cancellation_state<ReadHandler>(+ ASIO_MOVE_CAST(base_from_cancellation_state<+ ReadHandler>)(other)),+ stream_(other.stream_),+ buffers_(ASIO_MOVE_CAST(DynamicBuffer_v1)(other.buffers_)),+ delim_(ASIO_MOVE_CAST(std::string)(other.delim_)),+ start_(other.start_),+ search_position_(other.search_position_),+ handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_))+ {+ }+#endif // defined(ASIO_HAS_MOVE)++ void operator()(asio::error_code ec,+ std::size_t bytes_transferred, int start = 0)+ {+ const std::size_t not_found = (std::numeric_limits<std::size_t>::max)();+ std::size_t bytes_to_read;+ switch (start_ = start)+ {+ case 1:+ for (;;)+ {+ {+ // Determine the range of the data to be searched.+ typedef typename DynamicBuffer_v1::const_buffers_type+ buffers_type;+ typedef buffers_iterator<buffers_type> iterator;+ buffers_type data_buffers = buffers_.data();+ iterator begin = iterator::begin(data_buffers);+ iterator start_pos = begin + search_position_;+ iterator end = iterator::end(data_buffers);++ // Look for a match.+ std::pair<iterator, bool> result = detail::partial_search(+ start_pos, end, delim_.begin(), delim_.end());+ if (result.first != end && result.second)+ {+ // Full match. We're done.+ search_position_ = result.first - begin + delim_.length();+ bytes_to_read = 0;+ }++ // No match yet. Check if buffer is full.+ else if (buffers_.size() == buffers_.max_size())+ {+ search_position_ = not_found;+ bytes_to_read = 0;+ }++ // Need to read some more data.+ else+ {+ if (result.first != end)+ {+ // Partial match. Next search needs to start from beginning of+ // match.+ search_position_ = result.first - begin;+ }+ else+ {+ // Next search can start with the new data.+ search_position_ = end - begin;+ }++ bytes_to_read = std::min<std::size_t>(+ std::max<std::size_t>(512,+ buffers_.capacity() - buffers_.size()),+ std::min<std::size_t>(65536,+ buffers_.max_size() - buffers_.size()));+ }+ }++ // Check if we're done.+ if (!start && bytes_to_read == 0)+ break;++ // Start a new asynchronous read operation to obtain more data.+ {+ ASIO_HANDLER_LOCATION((+ __FILE__, __LINE__, "async_read_until"));+ stream_.async_read_some(buffers_.prepare(bytes_to_read),+ ASIO_MOVE_CAST(read_until_delim_string_op_v1)(*this));+ }+ return; default:+ buffers_.commit(bytes_transferred);+ if (ec || bytes_transferred == 0)+ break;+ if (this->cancelled() != cancellation_type::none)+ {+ ec = error::operation_aborted;+ break;+ }+ }++ const asio::error_code result_ec =+ (search_position_ == not_found)+ ? error::not_found : ec;++ const std::size_t result_n =+ (ec || search_position_ == not_found)+ ? 0 : search_position_;++ ASIO_MOVE_OR_LVALUE(ReadHandler)(handler_)(result_ec, result_n);+ }+ }++ //private:+ AsyncReadStream& stream_;+ DynamicBuffer_v1 buffers_;+ std::string delim_;+ int start_;+ std::size_t search_position_;+ ReadHandler handler_;+ };++ template <typename AsyncReadStream,+ typename DynamicBuffer_v1, typename ReadHandler>+ inline asio_handler_allocate_is_deprecated+ asio_handler_allocate(std::size_t size,+ read_until_delim_string_op_v1<AsyncReadStream,+ DynamicBuffer_v1, ReadHandler>* this_handler)+ {+#if defined(ASIO_NO_DEPRECATED)+ asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+ return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+ return asio_handler_alloc_helpers::allocate(+ size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename AsyncReadStream,+ typename DynamicBuffer_v1, typename ReadHandler>+ inline asio_handler_deallocate_is_deprecated+ asio_handler_deallocate(void* pointer, std::size_t size,+ read_until_delim_string_op_v1<AsyncReadStream,+ DynamicBuffer_v1, ReadHandler>* this_handler)+ {+ asio_handler_alloc_helpers::deallocate(+ pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename AsyncReadStream,+ typename DynamicBuffer_v1, typename ReadHandler>+ inline bool asio_handler_is_continuation(+ read_until_delim_string_op_v1<AsyncReadStream,+ DynamicBuffer_v1, ReadHandler>* this_handler)+ {+ return this_handler->start_ == 0 ? true+ : asio_handler_cont_helpers::is_continuation(+ this_handler->handler_);+ }++ template <typename Function, typename AsyncReadStream,+ typename DynamicBuffer_v1, typename ReadHandler>+ inline asio_handler_invoke_is_deprecated+ asio_handler_invoke(Function& function,+ read_until_delim_string_op_v1<AsyncReadStream,+ DynamicBuffer_v1, ReadHandler>* this_handler)+ {+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename Function, typename AsyncReadStream,+ typename DynamicBuffer_v1, typename ReadHandler>+ inline asio_handler_invoke_is_deprecated+ asio_handler_invoke(const Function& function,+ read_until_delim_string_op_v1<AsyncReadStream,+ DynamicBuffer_v1, ReadHandler>* this_handler)+ {+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename AsyncReadStream>+ class initiate_async_read_until_delim_string_v1+ {+ public:+ typedef typename AsyncReadStream::executor_type executor_type;++ explicit initiate_async_read_until_delim_string_v1(AsyncReadStream& stream)+ : stream_(stream)+ {+ }++ executor_type get_executor() const ASIO_NOEXCEPT+ {+ return stream_.get_executor();+ }++ template <typename ReadHandler, typename DynamicBuffer_v1>+ void operator()(ASIO_MOVE_ARG(ReadHandler) handler,+ ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+ const std::string& delim) const+ {+ // If you get an error on the following line it means that your handler+ // does not meet the documented type requirements for a ReadHandler.+ ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;++ non_const_lvalue<ReadHandler> handler2(handler);+ read_until_delim_string_op_v1<AsyncReadStream,+ typename decay<DynamicBuffer_v1>::type,+ typename decay<ReadHandler>::type>(+ stream_, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+ delim, handler2.value)(asio::error_code(), 0, 1);+ }++ private:+ AsyncReadStream& stream_;+ };+} // namespace detail++#if !defined(GENERATING_DOCUMENTATION)++template <template <typename, typename> class Associator,+ typename AsyncReadStream, typename DynamicBuffer_v1,+ typename ReadHandler, typename DefaultCandidate>+struct associator<Associator,+ detail::read_until_delim_string_op_v1<AsyncReadStream,+ DynamicBuffer_v1, ReadHandler>,+ DefaultCandidate>+ : Associator<ReadHandler, DefaultCandidate>+{+ static typename Associator<ReadHandler, DefaultCandidate>::type+ get(const detail::read_until_delim_string_op_v1<AsyncReadStream,+ DynamicBuffer_v1, ReadHandler>& h) ASIO_NOEXCEPT+ {+ return Associator<ReadHandler, DefaultCandidate>::get(h.handler_);+ }++ static ASIO_AUTO_RETURN_TYPE_PREFIX2(+ typename Associator<ReadHandler, DefaultCandidate>::type)+ get(const detail::read_until_delim_string_op_v1<AsyncReadStream,+ DynamicBuffer_v1, ReadHandler>& h,+ const DefaultCandidate& c) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c)))+ {+ return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c);+ }+};++#endif // !defined(GENERATING_DOCUMENTATION)++template <typename AsyncReadStream, typename DynamicBuffer_v1,+ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+ std::size_t)) ReadToken>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+async_read_until(AsyncReadStream& s,+ ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+ ASIO_STRING_VIEW_PARAM delim,+ ASIO_MOVE_ARG(ReadToken) token,+ typename constraint<+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+ >::type,+ typename constraint<+ !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+ >::type)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_initiate<ReadToken,+ void (asio::error_code, std::size_t)>(+ declval<detail::initiate_async_read_until_delim_string_v1<+ AsyncReadStream> >(),+ token, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+ static_cast<std::string>(delim))))+{+ return async_initiate<ReadToken,+ void (asio::error_code, std::size_t)>(+ detail::initiate_async_read_until_delim_string_v1<AsyncReadStream>(s),+ token, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+ static_cast<std::string>(delim));+}++#if !defined(ASIO_NO_EXTENSIONS)+#if defined(ASIO_HAS_BOOST_REGEX)++namespace detail+{+ template <typename AsyncReadStream, typename DynamicBuffer_v1,+ typename RegEx, typename ReadHandler>+ class read_until_expr_op_v1+ : public base_from_cancellation_state<ReadHandler>+ {+ public:+ template <typename BufferSequence>+ read_until_expr_op_v1(AsyncReadStream& stream,+ ASIO_MOVE_ARG(BufferSequence) buffers,+ const boost::regex& expr, ReadHandler& handler)+ : base_from_cancellation_state<ReadHandler>(+ handler, enable_partial_cancellation()),+ stream_(stream),+ buffers_(ASIO_MOVE_CAST(BufferSequence)(buffers)),+ expr_(expr),+ start_(0),+ search_position_(0),+ handler_(ASIO_MOVE_CAST(ReadHandler)(handler))+ {+ }++#if defined(ASIO_HAS_MOVE)+ read_until_expr_op_v1(const read_until_expr_op_v1& other)+ : base_from_cancellation_state<ReadHandler>(other),+ stream_(other.stream_),+ buffers_(other.buffers_),+ expr_(other.expr_),+ start_(other.start_),+ search_position_(other.search_position_),+ handler_(other.handler_)+ {+ }++ read_until_expr_op_v1(read_until_expr_op_v1&& other)+ : base_from_cancellation_state<ReadHandler>(+ ASIO_MOVE_CAST(base_from_cancellation_state<+ ReadHandler>)(other)),+ stream_(other.stream_),+ buffers_(ASIO_MOVE_CAST(DynamicBuffer_v1)(other.buffers_)),+ expr_(other.expr_),+ start_(other.start_),+ search_position_(other.search_position_),+ handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_))+ {+ }+#endif // defined(ASIO_HAS_MOVE)++ void operator()(asio::error_code ec,+ std::size_t bytes_transferred, int start = 0)+ {+ const std::size_t not_found = (std::numeric_limits<std::size_t>::max)();+ std::size_t bytes_to_read;+ switch (start_ = start)+ {+ case 1:+ for (;;)+ {+ {+ // Determine the range of the data to be searched.+ typedef typename DynamicBuffer_v1::const_buffers_type+ buffers_type;+ typedef buffers_iterator<buffers_type> iterator;+ buffers_type data_buffers = buffers_.data();+ iterator begin = iterator::begin(data_buffers);+ iterator start_pos = begin + search_position_;+ iterator end = iterator::end(data_buffers);++ // Look for a match.+ boost::match_results<iterator,+ typename std::vector<boost::sub_match<iterator> >::allocator_type>+ match_results;+ bool match = regex_search(start_pos, end, match_results, expr_,+ boost::match_default | boost::match_partial);+ if (match && match_results[0].matched)+ {+ // Full match. We're done.+ search_position_ = match_results[0].second - begin;+ bytes_to_read = 0;+ }++ // No match yet. Check if buffer is full.+ else if (buffers_.size() == buffers_.max_size())+ {+ search_position_ = not_found;+ bytes_to_read = 0;+ }++ // Need to read some more data.+ else+ {+ if (match)+ {+ // Partial match. Next search needs to start from beginning of+ // match.+ search_position_ = match_results[0].first - begin;+ }+ else+ {+ // Next search can start with the new data.+ search_position_ = end - begin;+ }++ bytes_to_read = std::min<std::size_t>(+ std::max<std::size_t>(512,+ buffers_.capacity() - buffers_.size()),+ std::min<std::size_t>(65536,+ buffers_.max_size() - buffers_.size()));+ }+ }++ // Check if we're done.+ if (!start && bytes_to_read == 0)+ break;++ // Start a new asynchronous read operation to obtain more data.+ {+ ASIO_HANDLER_LOCATION((+ __FILE__, __LINE__, "async_read_until"));+ stream_.async_read_some(buffers_.prepare(bytes_to_read),+ ASIO_MOVE_CAST(read_until_expr_op_v1)(*this));+ }+ return; default:+ buffers_.commit(bytes_transferred);+ if (ec || bytes_transferred == 0)+ break;+ if (this->cancelled() != cancellation_type::none)+ {+ ec = error::operation_aborted;+ break;+ }+ }++ const asio::error_code result_ec =+ (search_position_ == not_found)+ ? error::not_found : ec;++ const std::size_t result_n =+ (ec || search_position_ == not_found)+ ? 0 : search_position_;++ ASIO_MOVE_OR_LVALUE(ReadHandler)(handler_)(result_ec, result_n);+ }+ }++ //private:+ AsyncReadStream& stream_;+ DynamicBuffer_v1 buffers_;+ RegEx expr_;+ int start_;+ std::size_t search_position_;+ ReadHandler handler_;+ };++ template <typename AsyncReadStream, typename DynamicBuffer_v1,+ typename RegEx, typename ReadHandler>+ inline asio_handler_allocate_is_deprecated+ asio_handler_allocate(std::size_t size,+ read_until_expr_op_v1<AsyncReadStream,+ DynamicBuffer_v1, RegEx, ReadHandler>* this_handler)+ {+#if defined(ASIO_NO_DEPRECATED)+ asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+ return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+ return asio_handler_alloc_helpers::allocate(+ size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename AsyncReadStream, typename DynamicBuffer_v1,+ typename RegEx, typename ReadHandler>+ inline asio_handler_deallocate_is_deprecated+ asio_handler_deallocate(void* pointer, std::size_t size,+ read_until_expr_op_v1<AsyncReadStream,+ DynamicBuffer_v1, RegEx, ReadHandler>* this_handler)+ {+ asio_handler_alloc_helpers::deallocate(+ pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename AsyncReadStream, typename DynamicBuffer_v1,+ typename RegEx, typename ReadHandler>+ inline bool asio_handler_is_continuation(+ read_until_expr_op_v1<AsyncReadStream,+ DynamicBuffer_v1, RegEx, ReadHandler>* this_handler)+ {+ return this_handler->start_ == 0 ? true+ : asio_handler_cont_helpers::is_continuation(+ this_handler->handler_);+ }++ template <typename Function, typename AsyncReadStream,+ typename DynamicBuffer_v1, typename RegEx, typename ReadHandler>+ inline asio_handler_invoke_is_deprecated+ asio_handler_invoke(Function& function,+ read_until_expr_op_v1<AsyncReadStream,+ DynamicBuffer_v1, RegEx, ReadHandler>* this_handler)+ {+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename Function, typename AsyncReadStream,+ typename DynamicBuffer_v1, typename RegEx, typename ReadHandler>+ inline asio_handler_invoke_is_deprecated+ asio_handler_invoke(const Function& function,+ read_until_expr_op_v1<AsyncReadStream,+ DynamicBuffer_v1, RegEx, ReadHandler>* this_handler)+ {+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename AsyncReadStream>+ class initiate_async_read_until_expr_v1+ {+ public:+ typedef typename AsyncReadStream::executor_type executor_type;++ explicit initiate_async_read_until_expr_v1(AsyncReadStream& stream)+ : stream_(stream)+ {+ }++ executor_type get_executor() const ASIO_NOEXCEPT+ {+ return stream_.get_executor();+ }++ template <typename ReadHandler, typename DynamicBuffer_v1, typename RegEx>+ void operator()(ASIO_MOVE_ARG(ReadHandler) handler,+ ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, const RegEx& expr) const+ {+ // If you get an error on the following line it means that your handler+ // does not meet the documented type requirements for a ReadHandler.+ ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;++ non_const_lvalue<ReadHandler> handler2(handler);+ read_until_expr_op_v1<AsyncReadStream,+ typename decay<DynamicBuffer_v1>::type,+ RegEx, typename decay<ReadHandler>::type>(+ stream_, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+ expr, handler2.value)(asio::error_code(), 0, 1);+ }++ private:+ AsyncReadStream& stream_;+ };+} // namespace detail++#if !defined(GENERATING_DOCUMENTATION)++template <template <typename, typename> class Associator,+ typename AsyncReadStream, typename DynamicBuffer_v1,+ typename RegEx, typename ReadHandler, typename DefaultCandidate>+struct associator<Associator,+ detail::read_until_expr_op_v1<AsyncReadStream,+ DynamicBuffer_v1, RegEx, ReadHandler>,+ DefaultCandidate>+ : Associator<ReadHandler, DefaultCandidate>+{+ static typename Associator<ReadHandler, DefaultCandidate>::type+ get(const detail::read_until_expr_op_v1<AsyncReadStream,+ DynamicBuffer_v1, RegEx, ReadHandler>& h) ASIO_NOEXCEPT+ {+ return Associator<ReadHandler, DefaultCandidate>::get(h.handler_);+ }++ static ASIO_AUTO_RETURN_TYPE_PREFIX2(+ typename Associator<ReadHandler, DefaultCandidate>::type)+ get(const detail::read_until_expr_op_v1<AsyncReadStream,+ DynamicBuffer_v1, RegEx, ReadHandler>& h,+ const DefaultCandidate& c) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c)))+ {+ return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c);+ }+};++#endif // !defined(GENERATING_DOCUMENTATION)++template <typename AsyncReadStream, typename DynamicBuffer_v1,+ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+ std::size_t)) ReadToken>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+async_read_until(AsyncReadStream& s,+ ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+ const boost::regex& expr,+ ASIO_MOVE_ARG(ReadToken) token,+ typename constraint<+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+ >::type,+ typename constraint<+ !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+ >::type)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_initiate<ReadToken,+ void (asio::error_code, std::size_t)>(+ declval<detail::initiate_async_read_until_expr_v1<AsyncReadStream> >(),+ token, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), expr)))+{+ return async_initiate<ReadToken,+ void (asio::error_code, std::size_t)>(+ detail::initiate_async_read_until_expr_v1<AsyncReadStream>(s),+ token, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), expr);+}++#endif // defined(ASIO_HAS_BOOST_REGEX)++namespace detail+{+ template <typename AsyncReadStream, typename DynamicBuffer_v1,+ typename MatchCondition, typename ReadHandler>+ class read_until_match_op_v1+ : public base_from_cancellation_state<ReadHandler>+ {+ public:+ template <typename BufferSequence>+ read_until_match_op_v1(AsyncReadStream& stream,+ ASIO_MOVE_ARG(BufferSequence) buffers,+ MatchCondition match_condition, ReadHandler& handler)+ : base_from_cancellation_state<ReadHandler>(+ handler, enable_partial_cancellation()),+ stream_(stream),+ buffers_(ASIO_MOVE_CAST(BufferSequence)(buffers)),+ match_condition_(match_condition),+ start_(0),+ search_position_(0),+ handler_(ASIO_MOVE_CAST(ReadHandler)(handler))+ {+ }++#if defined(ASIO_HAS_MOVE)+ read_until_match_op_v1(const read_until_match_op_v1& other)+ : base_from_cancellation_state<ReadHandler>(other),+ stream_(other.stream_),+ buffers_(other.buffers_),+ match_condition_(other.match_condition_),+ start_(other.start_),+ search_position_(other.search_position_),+ handler_(other.handler_)+ {+ }++ read_until_match_op_v1(read_until_match_op_v1&& other)+ : base_from_cancellation_state<ReadHandler>(+ ASIO_MOVE_CAST(base_from_cancellation_state<+ ReadHandler>)(other)),+ stream_(other.stream_),+ buffers_(ASIO_MOVE_CAST(DynamicBuffer_v1)(other.buffers_)),+ match_condition_(other.match_condition_),+ start_(other.start_),+ search_position_(other.search_position_),+ handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_))+ {+ }+#endif // defined(ASIO_HAS_MOVE)++ void operator()(asio::error_code ec,+ std::size_t bytes_transferred, int start = 0)+ {+ const std::size_t not_found = (std::numeric_limits<std::size_t>::max)();+ std::size_t bytes_to_read;+ switch (start_ = start)+ {+ case 1:+ for (;;)+ {+ {+ // Determine the range of the data to be searched.+ typedef typename DynamicBuffer_v1::const_buffers_type+ buffers_type;+ typedef buffers_iterator<buffers_type> iterator;+ buffers_type data_buffers = buffers_.data();+ iterator begin = iterator::begin(data_buffers);+ iterator start_pos = begin + search_position_;+ iterator end = iterator::end(data_buffers);++ // Look for a match.+ std::pair<iterator, bool> result = match_condition_(start_pos, end);+ if (result.second)+ {+ // Full match. We're done.+ search_position_ = result.first - begin;+ bytes_to_read = 0;+ }++ // No match yet. Check if buffer is full.+ else if (buffers_.size() == buffers_.max_size())+ {+ search_position_ = not_found;+ bytes_to_read = 0;+ }++ // Need to read some more data.+ else+ {+ if (result.first != end)+ {+ // Partial match. Next search needs to start from beginning of+ // match.+ search_position_ = result.first - begin;+ }+ else+ {+ // Next search can start with the new data.+ search_position_ = end - begin;+ }++ bytes_to_read = std::min<std::size_t>(+ std::max<std::size_t>(512,+ buffers_.capacity() - buffers_.size()),+ std::min<std::size_t>(65536,+ buffers_.max_size() - buffers_.size()));+ }+ }++ // Check if we're done.+ if (!start && bytes_to_read == 0)+ break;++ // Start a new asynchronous read operation to obtain more data.+ {+ ASIO_HANDLER_LOCATION((+ __FILE__, __LINE__, "async_read_until"));+ stream_.async_read_some(buffers_.prepare(bytes_to_read),+ ASIO_MOVE_CAST(read_until_match_op_v1)(*this));+ }+ return; default:+ buffers_.commit(bytes_transferred);+ if (ec || bytes_transferred == 0)+ break;+ if (this->cancelled() != cancellation_type::none)+ {+ ec = error::operation_aborted;+ break;+ }+ }++ const asio::error_code result_ec =+ (search_position_ == not_found)+ ? error::not_found : ec;++ const std::size_t result_n =+ (ec || search_position_ == not_found)+ ? 0 : search_position_;++ ASIO_MOVE_OR_LVALUE(ReadHandler)(handler_)(result_ec, result_n);+ }+ }++ //private:+ AsyncReadStream& stream_;+ DynamicBuffer_v1 buffers_;+ MatchCondition match_condition_;+ int start_;+ std::size_t search_position_;+ ReadHandler handler_;+ };++ template <typename AsyncReadStream, typename DynamicBuffer_v1,+ typename MatchCondition, typename ReadHandler>+ inline asio_handler_allocate_is_deprecated+ asio_handler_allocate(std::size_t size,+ read_until_match_op_v1<AsyncReadStream, DynamicBuffer_v1,+ MatchCondition, ReadHandler>* this_handler)+ {+#if defined(ASIO_NO_DEPRECATED)+ asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+ return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+ return asio_handler_alloc_helpers::allocate(+ size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename AsyncReadStream, typename DynamicBuffer_v1,+ typename MatchCondition, typename ReadHandler>+ inline asio_handler_deallocate_is_deprecated+ asio_handler_deallocate(void* pointer, std::size_t size,+ read_until_match_op_v1<AsyncReadStream, DynamicBuffer_v1,+ MatchCondition, ReadHandler>* this_handler)+ {+ asio_handler_alloc_helpers::deallocate(+ pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename AsyncReadStream, typename DynamicBuffer_v1,+ typename MatchCondition, typename ReadHandler>+ inline bool asio_handler_is_continuation(+ read_until_match_op_v1<AsyncReadStream, DynamicBuffer_v1,+ MatchCondition, ReadHandler>* this_handler)+ {+ return this_handler->start_ == 0 ? true+ : asio_handler_cont_helpers::is_continuation(+ this_handler->handler_);+ }++ template <typename Function, typename AsyncReadStream,+ typename DynamicBuffer_v1, typename MatchCondition,+ typename ReadHandler>+ inline asio_handler_invoke_is_deprecated+ asio_handler_invoke(Function& function,+ read_until_match_op_v1<AsyncReadStream, DynamicBuffer_v1,+ MatchCondition, ReadHandler>* this_handler)+ {+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename Function, typename AsyncReadStream,+ typename DynamicBuffer_v1, typename MatchCondition,+ typename ReadHandler>+ inline asio_handler_invoke_is_deprecated+ asio_handler_invoke(const Function& function,+ read_until_match_op_v1<AsyncReadStream, DynamicBuffer_v1,+ MatchCondition, ReadHandler>* this_handler)+ {+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename AsyncReadStream>+ class initiate_async_read_until_match_v1+ {+ public:+ typedef typename AsyncReadStream::executor_type executor_type;++ explicit initiate_async_read_until_match_v1(AsyncReadStream& stream)+ : stream_(stream)+ {+ }++ executor_type get_executor() const ASIO_NOEXCEPT+ {+ return stream_.get_executor();+ }++ template <typename ReadHandler,+ typename DynamicBuffer_v1, typename MatchCondition>+ void operator()(ASIO_MOVE_ARG(ReadHandler) handler,+ ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+ MatchCondition match_condition) const+ {+ // If you get an error on the following line it means that your handler+ // does not meet the documented type requirements for a ReadHandler.+ ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;++ non_const_lvalue<ReadHandler> handler2(handler);+ read_until_match_op_v1<AsyncReadStream,+ typename decay<DynamicBuffer_v1>::type,+ MatchCondition, typename decay<ReadHandler>::type>(+ stream_, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+ match_condition, handler2.value)(asio::error_code(), 0, 1);+ }++ private:+ AsyncReadStream& stream_;+ };+} // namespace detail++#if !defined(GENERATING_DOCUMENTATION)++template <template <typename, typename> class Associator,+ typename AsyncReadStream, typename DynamicBuffer_v1,+ typename MatchCondition, typename ReadHandler, typename DefaultCandidate>+struct associator<Associator,+ detail::read_until_match_op_v1<AsyncReadStream,+ DynamicBuffer_v1, MatchCondition, ReadHandler>,+ DefaultCandidate>+ : Associator<ReadHandler, DefaultCandidate>+{+ static typename Associator<ReadHandler, DefaultCandidate>::type+ get(const detail::read_until_match_op_v1<AsyncReadStream,+ DynamicBuffer_v1, MatchCondition, ReadHandler>& h) ASIO_NOEXCEPT+ {+ return Associator<ReadHandler, DefaultCandidate>::get(h.handler_);+ }++ static ASIO_AUTO_RETURN_TYPE_PREFIX2(+ typename Associator<ReadHandler, DefaultCandidate>::type)+ get(const detail::read_until_match_op_v1<AsyncReadStream,+ DynamicBuffer_v1, MatchCondition, ReadHandler>& h,+ const DefaultCandidate& c) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c)))+ {+ return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c);+ }+};++#endif // !defined(GENERATING_DOCUMENTATION)++template <typename AsyncReadStream,+ typename DynamicBuffer_v1, typename MatchCondition,+ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+ std::size_t)) ReadToken>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+async_read_until(AsyncReadStream& s,+ ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+ MatchCondition match_condition, ASIO_MOVE_ARG(ReadToken) token,+ typename constraint<+ is_match_condition<MatchCondition>::value+ >::type,+ typename constraint<+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+ >::type,+ typename constraint<+ !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+ >::type)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_initiate<ReadToken,+ void (asio::error_code, std::size_t)>(+ declval<detail::initiate_async_read_until_match_v1<AsyncReadStream> >(),+ token, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+ match_condition)))+{+ return async_initiate<ReadToken,+ void (asio::error_code, std::size_t)>(+ detail::initiate_async_read_until_match_v1<AsyncReadStream>(s),+ token, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+ match_condition);+}++#if !defined(ASIO_NO_IOSTREAM)++template <typename AsyncReadStream, typename Allocator,+ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+ std::size_t)) ReadToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+async_read_until(AsyncReadStream& s,+ asio::basic_streambuf<Allocator>& b,+ char delim, ASIO_MOVE_ARG(ReadToken) token)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_read_until(s, basic_streambuf_ref<Allocator>(b),+ delim, ASIO_MOVE_CAST(ReadToken)(token))))+{+ return async_read_until(s, basic_streambuf_ref<Allocator>(b),+ delim, ASIO_MOVE_CAST(ReadToken)(token));+}++template <typename AsyncReadStream, typename Allocator,+ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+ std::size_t)) ReadToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+async_read_until(AsyncReadStream& s,+ asio::basic_streambuf<Allocator>& b,+ ASIO_STRING_VIEW_PARAM delim,+ ASIO_MOVE_ARG(ReadToken) token)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_read_until(s, basic_streambuf_ref<Allocator>(b),+ delim, ASIO_MOVE_CAST(ReadToken)(token))))+{+ return async_read_until(s, basic_streambuf_ref<Allocator>(b),+ delim, ASIO_MOVE_CAST(ReadToken)(token));+}++#if defined(ASIO_HAS_BOOST_REGEX)++template <typename AsyncReadStream, typename Allocator,+ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+ std::size_t)) ReadToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+async_read_until(AsyncReadStream& s,+ asio::basic_streambuf<Allocator>& b, const boost::regex& expr,+ ASIO_MOVE_ARG(ReadToken) token)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_read_until(s, basic_streambuf_ref<Allocator>(b),+ expr, ASIO_MOVE_CAST(ReadToken)(token))))+{+ return async_read_until(s, basic_streambuf_ref<Allocator>(b),+ expr, ASIO_MOVE_CAST(ReadToken)(token));+}++#endif // defined(ASIO_HAS_BOOST_REGEX)++template <typename AsyncReadStream, typename Allocator, typename MatchCondition,+ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+ std::size_t)) ReadToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+async_read_until(AsyncReadStream& s,+ asio::basic_streambuf<Allocator>& b,+ MatchCondition match_condition, ASIO_MOVE_ARG(ReadToken) token,+ typename constraint<is_match_condition<MatchCondition>::value>::type)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_read_until(s, basic_streambuf_ref<Allocator>(b),+ match_condition, ASIO_MOVE_CAST(ReadToken)(token))))+{+ return async_read_until(s, basic_streambuf_ref<Allocator>(b),+ match_condition, ASIO_MOVE_CAST(ReadToken)(token));+}++#endif // !defined(ASIO_NO_IOSTREAM)+#endif // !defined(ASIO_NO_EXTENSIONS)+#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)++namespace detail+{+ template <typename AsyncReadStream,+ typename DynamicBuffer_v2, typename ReadHandler>+ class read_until_delim_op_v2+ : public base_from_cancellation_state<ReadHandler>+ {+ public:+ template <typename BufferSequence>+ read_until_delim_op_v2(AsyncReadStream& stream,+ ASIO_MOVE_ARG(BufferSequence) buffers,+ char delim, ReadHandler& handler)+ : base_from_cancellation_state<ReadHandler>(+ handler, enable_partial_cancellation()),+ stream_(stream),+ buffers_(ASIO_MOVE_CAST(BufferSequence)(buffers)),+ delim_(delim),+ start_(0),+ search_position_(0),+ bytes_to_read_(0),+ handler_(ASIO_MOVE_CAST(ReadHandler)(handler))+ {+ }++#if defined(ASIO_HAS_MOVE)+ read_until_delim_op_v2(const read_until_delim_op_v2& other)+ : base_from_cancellation_state<ReadHandler>(other),+ stream_(other.stream_),+ buffers_(other.buffers_),+ delim_(other.delim_),+ start_(other.start_),+ search_position_(other.search_position_),+ bytes_to_read_(other.bytes_to_read_),+ handler_(other.handler_)+ {+ }++ read_until_delim_op_v2(read_until_delim_op_v2&& other)+ : base_from_cancellation_state<ReadHandler>(+ ASIO_MOVE_CAST(base_from_cancellation_state<+ ReadHandler>)(other)),+ stream_(other.stream_),+ buffers_(ASIO_MOVE_CAST(DynamicBuffer_v2)(other.buffers_)),+ delim_(other.delim_),+ start_(other.start_),+ search_position_(other.search_position_),+ bytes_to_read_(other.bytes_to_read_),+ handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_))+ {+ }+#endif // defined(ASIO_HAS_MOVE)++ void operator()(asio::error_code ec,+ std::size_t bytes_transferred, int start = 0)+ {+ const std::size_t not_found = (std::numeric_limits<std::size_t>::max)();+ std::size_t pos;+ switch (start_ = start)+ {+ case 1:+ for (;;)+ {+ {+ // Determine the range of the data to be searched.+ typedef typename DynamicBuffer_v2::const_buffers_type+ buffers_type;+ typedef buffers_iterator<buffers_type> iterator;+ buffers_type data_buffers =+ const_cast<const DynamicBuffer_v2&>(buffers_).data(+ 0, buffers_.size());+ iterator begin = iterator::begin(data_buffers);+ iterator start_pos = begin + search_position_;+ iterator end = iterator::end(data_buffers);++ // Look for a match.+ iterator iter = std::find(start_pos, end, delim_);+ if (iter != end)+ {+ // Found a match. We're done.+ search_position_ = iter - begin + 1;+ bytes_to_read_ = 0;+ }++ // No match yet. Check if buffer is full.+ else if (buffers_.size() == buffers_.max_size())+ {+ search_position_ = not_found;+ bytes_to_read_ = 0;+ }++ // Need to read some more data.+ else+ {+ // Next search can start with the new data.+ search_position_ = end - begin;+ bytes_to_read_ = std::min<std::size_t>(+ std::max<std::size_t>(512,+ buffers_.capacity() - buffers_.size()),+ std::min<std::size_t>(65536,+ buffers_.max_size() - buffers_.size()));+ }+ }++ // Check if we're done.+ if (!start && bytes_to_read_ == 0)+ break;++ // Start a new asynchronous read operation to obtain more data.+ pos = buffers_.size();+ buffers_.grow(bytes_to_read_);+ {+ ASIO_HANDLER_LOCATION((+ __FILE__, __LINE__, "async_read_until"));+ stream_.async_read_some(buffers_.data(pos, bytes_to_read_),+ ASIO_MOVE_CAST(read_until_delim_op_v2)(*this));+ }+ return; default:+ buffers_.shrink(bytes_to_read_ - bytes_transferred);+ if (ec || bytes_transferred == 0)+ break;+ if (this->cancelled() != cancellation_type::none)+ {+ ec = error::operation_aborted;+ break;+ }+ }++ const asio::error_code result_ec =+ (search_position_ == not_found)+ ? error::not_found : ec;++ const std::size_t result_n =+ (ec || search_position_ == not_found)+ ? 0 : search_position_;++ ASIO_MOVE_OR_LVALUE(ReadHandler)(handler_)(result_ec, result_n);+ }+ }++ //private:+ AsyncReadStream& stream_;+ DynamicBuffer_v2 buffers_;+ char delim_;+ int start_;+ std::size_t search_position_;+ std::size_t bytes_to_read_;+ ReadHandler handler_;+ };++ template <typename AsyncReadStream,+ typename DynamicBuffer_v2, typename ReadHandler>+ inline asio_handler_allocate_is_deprecated+ asio_handler_allocate(std::size_t size,+ read_until_delim_op_v2<AsyncReadStream,+ DynamicBuffer_v2, ReadHandler>* this_handler)+ {+#if defined(ASIO_NO_DEPRECATED)+ asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+ return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+ return asio_handler_alloc_helpers::allocate(+ size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename AsyncReadStream,+ typename DynamicBuffer_v2, typename ReadHandler>+ inline asio_handler_deallocate_is_deprecated+ asio_handler_deallocate(void* pointer, std::size_t size,+ read_until_delim_op_v2<AsyncReadStream,+ DynamicBuffer_v2, ReadHandler>* this_handler)+ {+ asio_handler_alloc_helpers::deallocate(+ pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename AsyncReadStream,+ typename DynamicBuffer_v2, typename ReadHandler>+ inline bool asio_handler_is_continuation(+ read_until_delim_op_v2<AsyncReadStream,+ DynamicBuffer_v2, ReadHandler>* this_handler)+ {+ return this_handler->start_ == 0 ? true+ : asio_handler_cont_helpers::is_continuation(+ this_handler->handler_);+ }++ template <typename Function, typename AsyncReadStream,+ typename DynamicBuffer_v2, typename ReadHandler>+ inline asio_handler_invoke_is_deprecated+ asio_handler_invoke(Function& function,+ read_until_delim_op_v2<AsyncReadStream,+ DynamicBuffer_v2, ReadHandler>* this_handler)+ {+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename Function, typename AsyncReadStream,+ typename DynamicBuffer_v2, typename ReadHandler>+ inline asio_handler_invoke_is_deprecated+ asio_handler_invoke(const Function& function,+ read_until_delim_op_v2<AsyncReadStream,+ DynamicBuffer_v2, ReadHandler>* this_handler)+ {+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename AsyncReadStream>+ class initiate_async_read_until_delim_v2+ {+ public:+ typedef typename AsyncReadStream::executor_type executor_type;++ explicit initiate_async_read_until_delim_v2(AsyncReadStream& stream)+ : stream_(stream)+ {+ }++ executor_type get_executor() const ASIO_NOEXCEPT+ {+ return stream_.get_executor();+ }++ template <typename ReadHandler, typename DynamicBuffer_v2>+ void operator()(ASIO_MOVE_ARG(ReadHandler) handler,+ ASIO_MOVE_ARG(DynamicBuffer_v2) buffers, char delim) const+ {+ // If you get an error on the following line it means that your handler+ // does not meet the documented type requirements for a ReadHandler.+ ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;++ non_const_lvalue<ReadHandler> handler2(handler);+ read_until_delim_op_v2<AsyncReadStream,+ typename decay<DynamicBuffer_v2>::type,+ typename decay<ReadHandler>::type>(+ stream_, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+ delim, handler2.value)(asio::error_code(), 0, 1);+ }++ private:+ AsyncReadStream& stream_;+ };+} // namespace detail++#if !defined(GENERATING_DOCUMENTATION)++template <template <typename, typename> class Associator,+ typename AsyncReadStream, typename DynamicBuffer_v2,+ typename ReadHandler, typename DefaultCandidate>+struct associator<Associator,+ detail::read_until_delim_op_v2<AsyncReadStream,+ DynamicBuffer_v2, ReadHandler>,+ DefaultCandidate>+ : Associator<ReadHandler, DefaultCandidate>+{+ static typename Associator<ReadHandler, DefaultCandidate>::type+ get(const detail::read_until_delim_op_v2<AsyncReadStream,+ DynamicBuffer_v2, ReadHandler>& h) ASIO_NOEXCEPT+ {+ return Associator<ReadHandler, DefaultCandidate>::get(h.handler_);+ }++ static ASIO_AUTO_RETURN_TYPE_PREFIX2(+ typename Associator<ReadHandler, DefaultCandidate>::type)+ get(const detail::read_until_delim_op_v2<AsyncReadStream,+ DynamicBuffer_v2, ReadHandler>& h,+ const DefaultCandidate& c) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c)))+ {+ return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c);+ }+};++#endif // !defined(GENERATING_DOCUMENTATION)++template <typename AsyncReadStream, typename DynamicBuffer_v2,+ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+ std::size_t)) ReadToken>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers,+ char delim, ASIO_MOVE_ARG(ReadToken) token,+ typename constraint<+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value+ >::type)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_initiate<ReadToken,+ void (asio::error_code, std::size_t)>(+ declval<detail::initiate_async_read_until_delim_v2<AsyncReadStream> >(),+ token, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), delim)))+{+ return async_initiate<ReadToken,+ void (asio::error_code, std::size_t)>(+ detail::initiate_async_read_until_delim_v2<AsyncReadStream>(s),+ token, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), delim);+}++namespace detail+{+ template <typename AsyncReadStream,+ typename DynamicBuffer_v2, typename ReadHandler>+ class read_until_delim_string_op_v2+ : public base_from_cancellation_state<ReadHandler>+ {+ public:+ template <typename BufferSequence>+ read_until_delim_string_op_v2(AsyncReadStream& stream,+ ASIO_MOVE_ARG(BufferSequence) buffers,+ const std::string& delim, ReadHandler& handler)+ : base_from_cancellation_state<ReadHandler>(+ handler, enable_partial_cancellation()),+ stream_(stream),+ buffers_(ASIO_MOVE_CAST(BufferSequence)(buffers)),+ delim_(delim),+ start_(0),+ search_position_(0),+ bytes_to_read_(0),+ handler_(ASIO_MOVE_CAST(ReadHandler)(handler))+ {+ }++#if defined(ASIO_HAS_MOVE)+ read_until_delim_string_op_v2(const read_until_delim_string_op_v2& other)+ : base_from_cancellation_state<ReadHandler>(other),+ stream_(other.stream_),+ buffers_(other.buffers_),+ delim_(other.delim_),+ start_(other.start_),+ search_position_(other.search_position_),+ bytes_to_read_(other.bytes_to_read_),+ handler_(other.handler_)+ {+ }++ read_until_delim_string_op_v2(read_until_delim_string_op_v2&& other)+ : base_from_cancellation_state<ReadHandler>(+ ASIO_MOVE_CAST(base_from_cancellation_state<+ ReadHandler>)(other)),+ stream_(other.stream_),+ buffers_(ASIO_MOVE_CAST(DynamicBuffer_v2)(other.buffers_)),+ delim_(ASIO_MOVE_CAST(std::string)(other.delim_)),+ start_(other.start_),+ search_position_(other.search_position_),+ bytes_to_read_(other.bytes_to_read_),+ handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_))+ {+ }+#endif // defined(ASIO_HAS_MOVE)++ void operator()(asio::error_code ec,+ std::size_t bytes_transferred, int start = 0)+ {+ const std::size_t not_found = (std::numeric_limits<std::size_t>::max)();+ std::size_t pos;+ switch (start_ = start)+ {+ case 1:+ for (;;)+ {+ {+ // Determine the range of the data to be searched.+ typedef typename DynamicBuffer_v2::const_buffers_type+ buffers_type;+ typedef buffers_iterator<buffers_type> iterator;+ buffers_type data_buffers =+ const_cast<const DynamicBuffer_v2&>(buffers_).data(+ 0, buffers_.size());+ iterator begin = iterator::begin(data_buffers);+ iterator start_pos = begin + search_position_;+ iterator end = iterator::end(data_buffers);++ // Look for a match.+ std::pair<iterator, bool> result = detail::partial_search(+ start_pos, end, delim_.begin(), delim_.end());+ if (result.first != end && result.second)+ {+ // Full match. We're done.+ search_position_ = result.first - begin + delim_.length();+ bytes_to_read_ = 0;+ }++ // No match yet. Check if buffer is full.+ else if (buffers_.size() == buffers_.max_size())+ {+ search_position_ = not_found;+ bytes_to_read_ = 0;+ }++ // Need to read some more data.+ else+ {+ if (result.first != end)+ {+ // Partial match. Next search needs to start from beginning of+ // match.+ search_position_ = result.first - begin;+ }+ else+ {+ // Next search can start with the new data.+ search_position_ = end - begin;+ }++ bytes_to_read_ = std::min<std::size_t>(+ std::max<std::size_t>(512,+ buffers_.capacity() - buffers_.size()),+ std::min<std::size_t>(65536,+ buffers_.max_size() - buffers_.size()));+ }+ }++ // Check if we're done.+ if (!start && bytes_to_read_ == 0)+ break;++ // Start a new asynchronous read operation to obtain more data.+ pos = buffers_.size();+ buffers_.grow(bytes_to_read_);+ {+ ASIO_HANDLER_LOCATION((+ __FILE__, __LINE__, "async_read_until"));+ stream_.async_read_some(buffers_.data(pos, bytes_to_read_),+ ASIO_MOVE_CAST(read_until_delim_string_op_v2)(*this));+ }+ return; default:+ buffers_.shrink(bytes_to_read_ - bytes_transferred);+ if (ec || bytes_transferred == 0)+ break;+ if (this->cancelled() != cancellation_type::none)+ {+ ec = error::operation_aborted;+ break;+ }+ }++ const asio::error_code result_ec =+ (search_position_ == not_found)+ ? error::not_found : ec;++ const std::size_t result_n =+ (ec || search_position_ == not_found)+ ? 0 : search_position_;++ ASIO_MOVE_OR_LVALUE(ReadHandler)(handler_)(result_ec, result_n);+ }+ }++ //private:+ AsyncReadStream& stream_;+ DynamicBuffer_v2 buffers_;+ std::string delim_;+ int start_;+ std::size_t search_position_;+ std::size_t bytes_to_read_;+ ReadHandler handler_;+ };++ template <typename AsyncReadStream,+ typename DynamicBuffer_v2, typename ReadHandler>+ inline asio_handler_allocate_is_deprecated+ asio_handler_allocate(std::size_t size,+ read_until_delim_string_op_v2<AsyncReadStream,+ DynamicBuffer_v2, ReadHandler>* this_handler)+ {+#if defined(ASIO_NO_DEPRECATED)+ asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+ return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+ return asio_handler_alloc_helpers::allocate(+ size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename AsyncReadStream,+ typename DynamicBuffer_v2, typename ReadHandler>+ inline asio_handler_deallocate_is_deprecated+ asio_handler_deallocate(void* pointer, std::size_t size,+ read_until_delim_string_op_v2<AsyncReadStream,+ DynamicBuffer_v2, ReadHandler>* this_handler)+ {+ asio_handler_alloc_helpers::deallocate(+ pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename AsyncReadStream,+ typename DynamicBuffer_v2, typename ReadHandler>+ inline bool asio_handler_is_continuation(+ read_until_delim_string_op_v2<AsyncReadStream,+ DynamicBuffer_v2, ReadHandler>* this_handler)+ {+ return this_handler->start_ == 0 ? true+ : asio_handler_cont_helpers::is_continuation(+ this_handler->handler_);+ }++ template <typename Function, typename AsyncReadStream,+ typename DynamicBuffer_v2, typename ReadHandler>+ inline asio_handler_invoke_is_deprecated+ asio_handler_invoke(Function& function,+ read_until_delim_string_op_v2<AsyncReadStream,+ DynamicBuffer_v2, ReadHandler>* this_handler)+ {+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename Function, typename AsyncReadStream,+ typename DynamicBuffer_v2, typename ReadHandler>+ inline asio_handler_invoke_is_deprecated+ asio_handler_invoke(const Function& function,+ read_until_delim_string_op_v2<AsyncReadStream,+ DynamicBuffer_v2, ReadHandler>* this_handler)+ {+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename AsyncReadStream>+ class initiate_async_read_until_delim_string_v2+ {+ public:+ typedef typename AsyncReadStream::executor_type executor_type;++ explicit initiate_async_read_until_delim_string_v2(AsyncReadStream& stream)+ : stream_(stream)+ {+ }++ executor_type get_executor() const ASIO_NOEXCEPT+ {+ return stream_.get_executor();+ }++ template <typename ReadHandler, typename DynamicBuffer_v2>+ void operator()(ASIO_MOVE_ARG(ReadHandler) handler,+ ASIO_MOVE_ARG(DynamicBuffer_v2) buffers,+ const std::string& delim) const+ {+ // If you get an error on the following line it means that your handler+ // does not meet the documented type requirements for a ReadHandler.+ ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;++ non_const_lvalue<ReadHandler> handler2(handler);+ read_until_delim_string_op_v2<AsyncReadStream,+ typename decay<DynamicBuffer_v2>::type,+ typename decay<ReadHandler>::type>(+ stream_, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+ delim, handler2.value)(asio::error_code(), 0, 1);+ }++ private:+ AsyncReadStream& stream_;+ };+} // namespace detail++#if !defined(GENERATING_DOCUMENTATION)++template <template <typename, typename> class Associator,+ typename AsyncReadStream, typename DynamicBuffer_v2,+ typename ReadHandler, typename DefaultCandidate>+struct associator<Associator,+ detail::read_until_delim_string_op_v2<AsyncReadStream,+ DynamicBuffer_v2, ReadHandler>,+ DefaultCandidate>+ : Associator<ReadHandler, DefaultCandidate>+{+ static typename Associator<ReadHandler, DefaultCandidate>::type+ get(const detail::read_until_delim_string_op_v2<AsyncReadStream,+ DynamicBuffer_v2, ReadHandler>& h) ASIO_NOEXCEPT+ {+ return Associator<ReadHandler, DefaultCandidate>::get(h.handler_);+ }++ static ASIO_AUTO_RETURN_TYPE_PREFIX2(+ typename Associator<ReadHandler, DefaultCandidate>::type)+ get(const detail::read_until_delim_string_op_v2<AsyncReadStream,+ DynamicBuffer_v2, ReadHandler>& h,+ const DefaultCandidate& c) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c)))+ {+ return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c);+ }+};++#endif // !defined(GENERATING_DOCUMENTATION)++template <typename AsyncReadStream,+ typename DynamicBuffer_v2,+ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+ std::size_t)) ReadToken>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+async_read_until(AsyncReadStream& s,+ DynamicBuffer_v2 buffers, ASIO_STRING_VIEW_PARAM delim,+ ASIO_MOVE_ARG(ReadToken) token,+ typename constraint<+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value+ >::type)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_initiate<ReadToken,+ void (asio::error_code, std::size_t)>(+ declval<detail::initiate_async_read_until_delim_string_v2<+ AsyncReadStream> >(),+ token, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+ static_cast<std::string>(delim))))+{+ return async_initiate<ReadToken,+ void (asio::error_code, std::size_t)>(+ detail::initiate_async_read_until_delim_string_v2<AsyncReadStream>(s),+ token, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+ static_cast<std::string>(delim));+}++#if !defined(ASIO_NO_EXTENSIONS)+#if defined(ASIO_HAS_BOOST_REGEX)++namespace detail+{+ template <typename AsyncReadStream, typename DynamicBuffer_v2,+ typename RegEx, typename ReadHandler>+ class read_until_expr_op_v2+ : public base_from_cancellation_state<ReadHandler>+ {+ public:+ template <typename BufferSequence>+ read_until_expr_op_v2(AsyncReadStream& stream,+ ASIO_MOVE_ARG(BufferSequence) buffers,+ const boost::regex& expr, ReadHandler& handler)+ : base_from_cancellation_state<ReadHandler>(+ handler, enable_partial_cancellation()),+ stream_(stream),+ buffers_(ASIO_MOVE_CAST(BufferSequence)(buffers)),+ expr_(expr),+ start_(0),+ search_position_(0),+ bytes_to_read_(0),+ handler_(ASIO_MOVE_CAST(ReadHandler)(handler))+ {+ }++#if defined(ASIO_HAS_MOVE)+ read_until_expr_op_v2(const read_until_expr_op_v2& other)+ : base_from_cancellation_state<ReadHandler>(other),+ stream_(other.stream_),+ buffers_(other.buffers_),+ expr_(other.expr_),+ start_(other.start_),+ search_position_(other.search_position_),+ bytes_to_read_(other.bytes_to_read_),+ handler_(other.handler_)+ {+ }++ read_until_expr_op_v2(read_until_expr_op_v2&& other)+ : base_from_cancellation_state<ReadHandler>(+ ASIO_MOVE_CAST(base_from_cancellation_state<+ ReadHandler>)(other)),+ stream_(other.stream_),+ buffers_(ASIO_MOVE_CAST(DynamicBuffer_v2)(other.buffers_)),+ expr_(other.expr_),+ start_(other.start_),+ search_position_(other.search_position_),+ bytes_to_read_(other.bytes_to_read_),+ handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_))+ {+ }+#endif // defined(ASIO_HAS_MOVE)++ void operator()(asio::error_code ec,+ std::size_t bytes_transferred, int start = 0)+ {+ const std::size_t not_found = (std::numeric_limits<std::size_t>::max)();+ std::size_t pos;+ switch (start_ = start)+ {+ case 1:+ for (;;)+ {+ {+ // Determine the range of the data to be searched.+ typedef typename DynamicBuffer_v2::const_buffers_type+ buffers_type;+ typedef buffers_iterator<buffers_type> iterator;+ buffers_type data_buffers =+ const_cast<const DynamicBuffer_v2&>(buffers_).data(+ 0, buffers_.size());+ iterator begin = iterator::begin(data_buffers);+ iterator start_pos = begin + search_position_;+ iterator end = iterator::end(data_buffers);++ // Look for a match.+ boost::match_results<iterator,+ typename std::vector<boost::sub_match<iterator> >::allocator_type>+ match_results;+ bool match = regex_search(start_pos, end, match_results, expr_,+ boost::match_default | boost::match_partial);+ if (match && match_results[0].matched)+ {+ // Full match. We're done.+ search_position_ = match_results[0].second - begin;+ bytes_to_read_ = 0;+ }++ // No match yet. Check if buffer is full.+ else if (buffers_.size() == buffers_.max_size())+ {+ search_position_ = not_found;+ bytes_to_read_ = 0;+ }++ // Need to read some more data.+ else+ {+ if (match)+ {+ // Partial match. Next search needs to start from beginning of+ // match.+ search_position_ = match_results[0].first - begin;+ }+ else+ {+ // Next search can start with the new data.+ search_position_ = end - begin;+ }++ bytes_to_read_ = std::min<std::size_t>(+ std::max<std::size_t>(512,+ buffers_.capacity() - buffers_.size()),+ std::min<std::size_t>(65536,+ buffers_.max_size() - buffers_.size()));+ }+ }++ // Check if we're done.+ if (!start && bytes_to_read_ == 0)+ break;++ // Start a new asynchronous read operation to obtain more data.+ pos = buffers_.size();+ buffers_.grow(bytes_to_read_);+ {+ ASIO_HANDLER_LOCATION((+ __FILE__, __LINE__, "async_read_until"));+ stream_.async_read_some(buffers_.data(pos, bytes_to_read_),+ ASIO_MOVE_CAST(read_until_expr_op_v2)(*this));+ }+ return; default:+ buffers_.shrink(bytes_to_read_ - bytes_transferred);+ if (ec || bytes_transferred == 0)+ break;+ if (this->cancelled() != cancellation_type::none)+ {+ ec = error::operation_aborted;+ break;+ }+ }++ const asio::error_code result_ec =+ (search_position_ == not_found)+ ? error::not_found : ec;++ const std::size_t result_n =+ (ec || search_position_ == not_found)+ ? 0 : search_position_;++ ASIO_MOVE_OR_LVALUE(ReadHandler)(handler_)(result_ec, result_n);+ }+ }++ //private:+ AsyncReadStream& stream_;+ DynamicBuffer_v2 buffers_;+ RegEx expr_;+ int start_;+ std::size_t search_position_;+ std::size_t bytes_to_read_;+ ReadHandler handler_;+ };++ template <typename AsyncReadStream, typename DynamicBuffer_v2,+ typename RegEx, typename ReadHandler>+ inline asio_handler_allocate_is_deprecated+ asio_handler_allocate(std::size_t size,+ read_until_expr_op_v2<AsyncReadStream,+ DynamicBuffer_v2, RegEx, ReadHandler>* this_handler)+ {+#if defined(ASIO_NO_DEPRECATED)+ asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+ return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+ return asio_handler_alloc_helpers::allocate(+ size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename AsyncReadStream, typename DynamicBuffer_v2,+ typename RegEx, typename ReadHandler>+ inline asio_handler_deallocate_is_deprecated+ asio_handler_deallocate(void* pointer, std::size_t size,+ read_until_expr_op_v2<AsyncReadStream,+ DynamicBuffer_v2, RegEx, ReadHandler>* this_handler)+ {+ asio_handler_alloc_helpers::deallocate(+ pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename AsyncReadStream, typename DynamicBuffer_v2,+ typename RegEx, typename ReadHandler>+ inline bool asio_handler_is_continuation(+ read_until_expr_op_v2<AsyncReadStream,+ DynamicBuffer_v2, RegEx, ReadHandler>* this_handler)+ {+ return this_handler->start_ == 0 ? true+ : asio_handler_cont_helpers::is_continuation(+ this_handler->handler_);+ }++ template <typename Function, typename AsyncReadStream,+ typename DynamicBuffer_v2, typename RegEx, typename ReadHandler>+ inline asio_handler_invoke_is_deprecated+ asio_handler_invoke(Function& function,+ read_until_expr_op_v2<AsyncReadStream,+ DynamicBuffer_v2, RegEx, ReadHandler>* this_handler)+ {+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename Function, typename AsyncReadStream,+ typename DynamicBuffer_v2, typename RegEx, typename ReadHandler>+ inline asio_handler_invoke_is_deprecated+ asio_handler_invoke(const Function& function,+ read_until_expr_op_v2<AsyncReadStream,+ DynamicBuffer_v2, RegEx, ReadHandler>* this_handler)+ {+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename AsyncReadStream>+ class initiate_async_read_until_expr_v2+ {+ public:+ typedef typename AsyncReadStream::executor_type executor_type;++ explicit initiate_async_read_until_expr_v2(AsyncReadStream& stream)+ : stream_(stream)+ {+ }++ executor_type get_executor() const ASIO_NOEXCEPT+ {+ return stream_.get_executor();+ }++ template <typename ReadHandler, typename DynamicBuffer_v2, typename RegEx>+ void operator()(ASIO_MOVE_ARG(ReadHandler) handler,+ ASIO_MOVE_ARG(DynamicBuffer_v2) buffers,+ const RegEx& expr) const+ {+ // If you get an error on the following line it means that your handler+ // does not meet the documented type requirements for a ReadHandler.+ ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;++ non_const_lvalue<ReadHandler> handler2(handler);+ read_until_expr_op_v2<AsyncReadStream,+ typename decay<DynamicBuffer_v2>::type,+ RegEx, typename decay<ReadHandler>::type>(+ stream_, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+ expr, handler2.value)(asio::error_code(), 0, 1);+ }++ private:+ AsyncReadStream& stream_;+ };+} // namespace detail++#if !defined(GENERATING_DOCUMENTATION)++template <template <typename, typename> class Associator,+ typename AsyncReadStream, typename DynamicBuffer_v2,+ typename RegEx, typename ReadHandler, typename DefaultCandidate>+struct associator<Associator,+ detail::read_until_expr_op_v2<AsyncReadStream,+ DynamicBuffer_v2, RegEx, ReadHandler>,+ DefaultCandidate>+ : Associator<ReadHandler, DefaultCandidate>+{+ static typename Associator<ReadHandler, DefaultCandidate>::type+ get(const detail::read_until_expr_op_v2<AsyncReadStream,+ DynamicBuffer_v2, RegEx, ReadHandler>& h) ASIO_NOEXCEPT+ {+ return Associator<ReadHandler, DefaultCandidate>::get(h.handler_);+ }++ static ASIO_AUTO_RETURN_TYPE_PREFIX2(+ typename Associator<ReadHandler, DefaultCandidate>::type)+ get(const detail::read_until_expr_op_v2<AsyncReadStream,+ DynamicBuffer_v2, RegEx, ReadHandler>& h,+ const DefaultCandidate& c) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c)))+ {+ return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c);+ }+};++#endif // !defined(GENERATING_DOCUMENTATION)++template <typename AsyncReadStream, typename DynamicBuffer_v2,+ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+ std::size_t)) ReadToken>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers,+ const boost::regex& expr, ASIO_MOVE_ARG(ReadToken) token,+ typename constraint<+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value+ >::type)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_initiate<ReadToken,+ void (asio::error_code, std::size_t)>(+ declval<detail::initiate_async_read_until_expr_v2<AsyncReadStream> >(),+ token, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), expr)))+{+ return async_initiate<ReadToken,+ void (asio::error_code, std::size_t)>(+ detail::initiate_async_read_until_expr_v2<AsyncReadStream>(s),+ token, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), expr);+}++#endif // defined(ASIO_HAS_BOOST_REGEX)++namespace detail+{+ template <typename AsyncReadStream, typename DynamicBuffer_v2,+ typename MatchCondition, typename ReadHandler>+ class read_until_match_op_v2+ : public base_from_cancellation_state<ReadHandler>+ {+ public:+ template <typename BufferSequence>+ read_until_match_op_v2(AsyncReadStream& stream,+ ASIO_MOVE_ARG(BufferSequence) buffers,+ MatchCondition match_condition, ReadHandler& handler)+ : base_from_cancellation_state<ReadHandler>(+ handler, enable_partial_cancellation()),+ stream_(stream),+ buffers_(ASIO_MOVE_CAST(BufferSequence)(buffers)),+ match_condition_(match_condition),+ start_(0),+ search_position_(0),+ bytes_to_read_(0),+ handler_(ASIO_MOVE_CAST(ReadHandler)(handler))+ {+ }++#if defined(ASIO_HAS_MOVE)+ read_until_match_op_v2(const read_until_match_op_v2& other)+ : base_from_cancellation_state<ReadHandler>(other),+ stream_(other.stream_),+ buffers_(other.buffers_),+ match_condition_(other.match_condition_),+ start_(other.start_),+ search_position_(other.search_position_),+ bytes_to_read_(other.bytes_to_read_),+ handler_(other.handler_)+ {+ }++ read_until_match_op_v2(read_until_match_op_v2&& other)+ : base_from_cancellation_state<ReadHandler>(+ ASIO_MOVE_CAST(base_from_cancellation_state<+ ReadHandler>)(other)),+ stream_(other.stream_),+ buffers_(ASIO_MOVE_CAST(DynamicBuffer_v2)(other.buffers_)),+ match_condition_(other.match_condition_),+ start_(other.start_),+ search_position_(other.search_position_),+ bytes_to_read_(other.bytes_to_read_),+ handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_))+ {+ }+#endif // defined(ASIO_HAS_MOVE)++ void operator()(asio::error_code ec,+ std::size_t bytes_transferred, int start = 0)+ {+ const std::size_t not_found = (std::numeric_limits<std::size_t>::max)();+ std::size_t pos;+ switch (start_ = start)+ {+ case 1:+ for (;;)+ {+ {+ // Determine the range of the data to be searched.+ typedef typename DynamicBuffer_v2::const_buffers_type+ buffers_type;+ typedef buffers_iterator<buffers_type> iterator;+ buffers_type data_buffers =+ const_cast<const DynamicBuffer_v2&>(buffers_).data(+ 0, buffers_.size());+ iterator begin = iterator::begin(data_buffers);+ iterator start_pos = begin + search_position_;+ iterator end = iterator::end(data_buffers);++ // Look for a match.+ std::pair<iterator, bool> result = match_condition_(start_pos, end);+ if (result.second)+ {+ // Full match. We're done.+ search_position_ = result.first - begin;+ bytes_to_read_ = 0;+ }++ // No match yet. Check if buffer is full.+ else if (buffers_.size() == buffers_.max_size())+ {+ search_position_ = not_found;+ bytes_to_read_ = 0;+ }++ // Need to read some more data.+ else+ {+ if (result.first != end)+ {+ // Partial match. Next search needs to start from beginning of+ // match.+ search_position_ = result.first - begin;+ }+ else+ {+ // Next search can start with the new data.+ search_position_ = end - begin;+ }++ bytes_to_read_ = std::min<std::size_t>(+ std::max<std::size_t>(512,+ buffers_.capacity() - buffers_.size()),+ std::min<std::size_t>(65536,+ buffers_.max_size() - buffers_.size()));+ }+ }++ // Check if we're done.+ if (!start && bytes_to_read_ == 0)+ break;++ // Start a new asynchronous read operation to obtain more data.+ pos = buffers_.size();+ buffers_.grow(bytes_to_read_);+ {+ ASIO_HANDLER_LOCATION((+ __FILE__, __LINE__, "async_read_until"));+ stream_.async_read_some(buffers_.data(pos, bytes_to_read_),+ ASIO_MOVE_CAST(read_until_match_op_v2)(*this));+ }+ return; default:+ buffers_.shrink(bytes_to_read_ - bytes_transferred);+ if (ec || bytes_transferred == 0)+ break;+ if (this->cancelled() != cancellation_type::none)+ {+ ec = error::operation_aborted;+ break;+ }+ }++ const asio::error_code result_ec =+ (search_position_ == not_found)+ ? error::not_found : ec;++ const std::size_t result_n =+ (ec || search_position_ == not_found)+ ? 0 : search_position_;++ ASIO_MOVE_OR_LVALUE(ReadHandler)(handler_)(result_ec, result_n);+ }+ }++ //private:+ AsyncReadStream& stream_;+ DynamicBuffer_v2 buffers_;+ MatchCondition match_condition_;+ int start_;+ std::size_t search_position_;+ std::size_t bytes_to_read_;+ ReadHandler handler_;+ };++ template <typename AsyncReadStream, typename DynamicBuffer_v2,+ typename MatchCondition, typename ReadHandler>+ inline asio_handler_allocate_is_deprecated+ asio_handler_allocate(std::size_t size,+ read_until_match_op_v2<AsyncReadStream, DynamicBuffer_v2,+ MatchCondition, ReadHandler>* this_handler)+ {+#if defined(ASIO_NO_DEPRECATED)+ asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+ return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+ return asio_handler_alloc_helpers::allocate(+ size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename AsyncReadStream, typename DynamicBuffer_v2,+ typename MatchCondition, typename ReadHandler>+ inline asio_handler_deallocate_is_deprecated+ asio_handler_deallocate(void* pointer, std::size_t size,+ read_until_match_op_v2<AsyncReadStream, DynamicBuffer_v2,+ MatchCondition, ReadHandler>* this_handler)+ {+ asio_handler_alloc_helpers::deallocate(+ pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename AsyncReadStream, typename DynamicBuffer_v2,+ typename MatchCondition, typename ReadHandler>+ inline bool asio_handler_is_continuation(+ read_until_match_op_v2<AsyncReadStream, DynamicBuffer_v2,+ MatchCondition, ReadHandler>* this_handler)+ {+ return this_handler->start_ == 0 ? true+ : asio_handler_cont_helpers::is_continuation(+ this_handler->handler_);+ }++ template <typename Function, typename AsyncReadStream,+ typename DynamicBuffer_v2, typename MatchCondition,+ typename ReadHandler>+ inline asio_handler_invoke_is_deprecated+ asio_handler_invoke(Function& function,+ read_until_match_op_v2<AsyncReadStream, DynamicBuffer_v2,+ MatchCondition, ReadHandler>* this_handler)+ {+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename Function, typename AsyncReadStream,+ typename DynamicBuffer_v2, typename MatchCondition,+ typename ReadHandler>+ inline asio_handler_invoke_is_deprecated+ asio_handler_invoke(const Function& function,+ read_until_match_op_v2<AsyncReadStream, DynamicBuffer_v2,+ MatchCondition, ReadHandler>* this_handler)+ {+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename AsyncReadStream>+ class initiate_async_read_until_match_v2+ {+ public:+ typedef typename AsyncReadStream::executor_type executor_type;++ explicit initiate_async_read_until_match_v2(AsyncReadStream& stream)+ : stream_(stream)+ {+ }++ executor_type get_executor() const ASIO_NOEXCEPT+ {+ return stream_.get_executor();+ }++ template <typename ReadHandler,+ typename DynamicBuffer_v2, typename MatchCondition>+ void operator()(ASIO_MOVE_ARG(ReadHandler) handler,+ ASIO_MOVE_ARG(DynamicBuffer_v2) buffers,+ MatchCondition match_condition) const+ {+ // If you get an error on the following line it means that your handler+ // does not meet the documented type requirements for a ReadHandler.+ ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;++ non_const_lvalue<ReadHandler> handler2(handler);+ read_until_match_op_v2<AsyncReadStream,+ typename decay<DynamicBuffer_v2>::type,+ MatchCondition, typename decay<ReadHandler>::type>(+ stream_, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+ match_condition, handler2.value)(asio::error_code(), 0, 1);+ }++ private:+ AsyncReadStream& stream_;+ };+} // namespace detail++#if !defined(GENERATING_DOCUMENTATION)++template <template <typename, typename> class Associator,+ typename AsyncReadStream, typename DynamicBuffer_v2,+ typename MatchCondition, typename ReadHandler, typename DefaultCandidate>+struct associator<Associator,+ detail::read_until_match_op_v2<AsyncReadStream,+ DynamicBuffer_v2, MatchCondition, ReadHandler>,+ DefaultCandidate>+ : Associator<ReadHandler, DefaultCandidate>+{+ static typename Associator<ReadHandler, DefaultCandidate>::type+ get(const detail::read_until_match_op_v2<AsyncReadStream,+ DynamicBuffer_v2, MatchCondition, ReadHandler>& h) ASIO_NOEXCEPT+ {+ return Associator<ReadHandler, DefaultCandidate>::get(h.handler_);+ }++ static ASIO_AUTO_RETURN_TYPE_PREFIX2(+ typename Associator<ReadHandler, DefaultCandidate>::type)+ get(const detail::read_until_match_op_v2<AsyncReadStream,+ DynamicBuffer_v2, MatchCondition, ReadHandler>& h,+ const DefaultCandidate& c) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c)))+ {+ return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c);+ }+};++#endif // !defined(GENERATING_DOCUMENTATION)++template <typename AsyncReadStream,+ typename DynamicBuffer_v2, typename MatchCondition,+ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+ std::size_t)) ReadToken>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers,+ MatchCondition match_condition, ASIO_MOVE_ARG(ReadToken) token,+ typename constraint<+ is_match_condition<MatchCondition>::value+ >::type,+ typename constraint<+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value+ >::type)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_initiate<ReadToken,+ void (asio::error_code, std::size_t)>(+ declval<detail::initiate_async_read_until_match_v2<AsyncReadStream> >(),+ token, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+ match_condition)))+{+ return async_initiate<ReadToken,+ void (asio::error_code, std::size_t)>(+ detail::initiate_async_read_until_match_v2<AsyncReadStream>(s),+ token, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+ match_condition);+} #endif // !defined(ASIO_NO_EXTENSIONS)
link/modules/asio-standalone/asio/include/asio/impl/redirect_error.hpp view
@@ -2,7 +2,7 @@ // impl/redirect_error.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -16,12 +16,13 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"-#include "asio/associated_executor.hpp" #include "asio/associator.hpp" #include "asio/async_result.hpp"+#include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_cont_helpers.hpp"-#include "asio/detail/initiation_base.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/type_traits.hpp"+#include "asio/detail/variadic_templates.hpp" #include "asio/system_error.hpp" #include "asio/detail/push_options.hpp"@@ -39,47 +40,121 @@ template <typename CompletionToken> redirect_error_handler(redirect_error_t<CompletionToken> e) : ec_(e.ec_),- handler_(static_cast<CompletionToken&&>(e.token_))+ handler_(ASIO_MOVE_CAST(CompletionToken)(e.token_)) { } template <typename RedirectedHandler> redirect_error_handler(asio::error_code& ec,- RedirectedHandler&& h)+ ASIO_MOVE_ARG(RedirectedHandler) h) : ec_(ec),- handler_(static_cast<RedirectedHandler&&>(h))+ handler_(ASIO_MOVE_CAST(RedirectedHandler)(h)) { } void operator()() {- static_cast<Handler&&>(handler_)();+ ASIO_MOVE_OR_LVALUE(Handler)(handler_)(); } +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+ template <typename Arg, typename... Args>- enable_if_t<- !is_same<decay_t<Arg>, asio::error_code>::value- >- operator()(Arg&& arg, Args&&... args)+ typename enable_if<+ !is_same<typename decay<Arg>::type, asio::error_code>::value+ >::type+ operator()(ASIO_MOVE_ARG(Arg) arg, ASIO_MOVE_ARG(Args)... args) {- static_cast<Handler&&>(handler_)(- static_cast<Arg&&>(arg),- static_cast<Args&&>(args)...);+ ASIO_MOVE_OR_LVALUE(Handler)(handler_)(+ ASIO_MOVE_CAST(Arg)(arg),+ ASIO_MOVE_CAST(Args)(args)...); } template <typename... Args>- void operator()(const asio::error_code& ec, Args&&... args)+ void operator()(const asio::error_code& ec,+ ASIO_MOVE_ARG(Args)... args) { ec_ = ec;- static_cast<Handler&&>(handler_)(static_cast<Args&&>(args)...);+ ASIO_MOVE_OR_LVALUE(Handler)(handler_)(+ ASIO_MOVE_CAST(Args)(args)...); } +#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++ template <typename Arg>+ typename enable_if<+ !is_same<typename decay<Arg>::type, asio::error_code>::value+ >::type+ operator()(ASIO_MOVE_ARG(Arg) arg)+ {+ ASIO_MOVE_OR_LVALUE(Handler)(handler_)(+ ASIO_MOVE_CAST(Arg)(arg));+ }++ void operator()(const asio::error_code& ec)+ {+ ec_ = ec;+ ASIO_MOVE_OR_LVALUE(Handler)(handler_)();+ }++#define ASIO_PRIVATE_REDIRECT_ERROR_DEF(n) \+ template <typename Arg, ASIO_VARIADIC_TPARAMS(n)> \+ typename enable_if< \+ !is_same<typename decay<Arg>::type, asio::error_code>::value \+ >::type \+ operator()(ASIO_MOVE_ARG(Arg) arg, ASIO_VARIADIC_MOVE_PARAMS(n)) \+ { \+ ASIO_MOVE_OR_LVALUE(Handler)(handler_)( \+ ASIO_MOVE_CAST(Arg)(arg), \+ ASIO_VARIADIC_MOVE_ARGS(n)); \+ } \+ \+ template <ASIO_VARIADIC_TPARAMS(n)> \+ void operator()(const asio::error_code& ec, \+ ASIO_VARIADIC_MOVE_PARAMS(n)) \+ { \+ ec_ = ec; \+ ASIO_MOVE_OR_LVALUE(Handler)(handler_)( \+ ASIO_VARIADIC_MOVE_ARGS(n)); \+ } \+ /**/+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_REDIRECT_ERROR_DEF)+#undef ASIO_PRIVATE_REDIRECT_ERROR_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+ //private: asio::error_code& ec_; Handler handler_; }; template <typename Handler>+inline asio_handler_allocate_is_deprecated+asio_handler_allocate(std::size_t size,+ redirect_error_handler<Handler>* this_handler)+{+#if defined(ASIO_NO_DEPRECATED)+ asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+ return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+ return asio_handler_alloc_helpers::allocate(+ size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler>+inline asio_handler_deallocate_is_deprecated+asio_handler_deallocate(void* pointer, std::size_t size,+ redirect_error_handler<Handler>* this_handler)+{+ asio_handler_alloc_helpers::deallocate(+ pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler> inline bool asio_handler_is_continuation( redirect_error_handler<Handler>* this_handler) {@@ -87,12 +162,38 @@ this_handler->handler_); } +template <typename Function, typename Handler>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(Function& function,+ redirect_error_handler<Handler>* this_handler)+{+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Function, typename Handler>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(const Function& function,+ redirect_error_handler<Handler>* this_handler)+{+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}+ template <typename Signature> struct redirect_error_signature { typedef Signature type; }; +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+ template <typename R, typename... Args> struct redirect_error_signature<R(asio::error_code, Args...)> {@@ -105,6 +206,8 @@ typedef R type(Args...); }; +# if defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)+ template <typename R, typename... Args> struct redirect_error_signature<R(asio::error_code, Args...) &> {@@ -129,7 +232,7 @@ typedef R type(Args...) &&; }; -#if defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)+# if defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE) template <typename R, typename... Args> struct redirect_error_signature<@@ -173,8 +276,197 @@ typedef R type(Args...) && noexcept; }; -#endif // defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)+# endif // defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)+# endif // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)+#else // defined(ASIO_HAS_VARIADIC_TEMPLATES) +template <typename R>+struct redirect_error_signature<R(asio::error_code)>+{+ typedef R type();+};++template <typename R>+struct redirect_error_signature<R(const asio::error_code&)>+{+ typedef R type();+};++#define ASIO_PRIVATE_REDIRECT_ERROR_DEF(n) \+ template <typename R, ASIO_VARIADIC_TPARAMS(n)> \+ struct redirect_error_signature< \+ R(asio::error_code, ASIO_VARIADIC_TARGS(n))> \+ { \+ typedef R type(ASIO_VARIADIC_TARGS(n)); \+ }; \+ \+ template <typename R, ASIO_VARIADIC_TPARAMS(n)> \+ struct redirect_error_signature< \+ R(const asio::error_code&, ASIO_VARIADIC_TARGS(n))> \+ { \+ typedef R type(ASIO_VARIADIC_TARGS(n)); \+ }; \+ /**/+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_REDIRECT_ERROR_DEF)+#undef ASIO_PRIVATE_REDIRECT_ERROR_DEF++# if defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)++template <typename R>+struct redirect_error_signature<R(asio::error_code) &>+{+ typedef R type() &;+};++template <typename R>+struct redirect_error_signature<R(const asio::error_code&) &>+{+ typedef R type() &;+};++template <typename R>+struct redirect_error_signature<R(asio::error_code) &&>+{+ typedef R type() &&;+};++template <typename R>+struct redirect_error_signature<R(const asio::error_code&) &&>+{+ typedef R type() &&;+};++#define ASIO_PRIVATE_REDIRECT_ERROR_DEF(n) \+ template <typename R, ASIO_VARIADIC_TPARAMS(n)> \+ struct redirect_error_signature< \+ R(asio::error_code, ASIO_VARIADIC_TARGS(n)) &> \+ { \+ typedef R type(ASIO_VARIADIC_TARGS(n)) &; \+ }; \+ \+ template <typename R, ASIO_VARIADIC_TPARAMS(n)> \+ struct redirect_error_signature< \+ R(const asio::error_code&, ASIO_VARIADIC_TARGS(n)) &> \+ { \+ typedef R type(ASIO_VARIADIC_TARGS(n)) &; \+ }; \+ \+ template <typename R, ASIO_VARIADIC_TPARAMS(n)> \+ struct redirect_error_signature< \+ R(asio::error_code, ASIO_VARIADIC_TARGS(n)) &&> \+ { \+ typedef R type(ASIO_VARIADIC_TARGS(n)) &&; \+ }; \+ \+ template <typename R, ASIO_VARIADIC_TPARAMS(n)> \+ struct redirect_error_signature< \+ R(const asio::error_code&, ASIO_VARIADIC_TARGS(n)) &&> \+ { \+ typedef R type(ASIO_VARIADIC_TARGS(n)) &&; \+ }; \+ /**/+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_REDIRECT_ERROR_DEF)+#undef ASIO_PRIVATE_REDIRECT_ERROR_DEF++# if defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)++template <typename R>+struct redirect_error_signature<+ R(asio::error_code) noexcept>+{+ typedef R type() noexcept;+};++template <typename R>+struct redirect_error_signature<+ R(const asio::error_code&) noexcept>+{+ typedef R type() noexcept;+};++template <typename R>+struct redirect_error_signature<+ R(asio::error_code) & noexcept>+{+ typedef R type() & noexcept;+};++template <typename R>+struct redirect_error_signature<+ R(const asio::error_code&) & noexcept>+{+ typedef R type() & noexcept;+};++template <typename R>+struct redirect_error_signature<+ R(asio::error_code) && noexcept>+{+ typedef R type() && noexcept;+};++template <typename R>+struct redirect_error_signature<+ R(const asio::error_code&) && noexcept>+{+ typedef R type() && noexcept;+};++#define ASIO_PRIVATE_REDIRECT_ERROR_DEF(n) \+ template <typename R, ASIO_VARIADIC_TPARAMS(n)> \+ struct redirect_error_signature< \+ R(asio::error_code, ASIO_VARIADIC_TARGS(n)) noexcept> \+ { \+ typedef R type(ASIO_VARIADIC_TARGS(n)) noexcept; \+ }; \+ \+ template <typename R, ASIO_VARIADIC_TPARAMS(n)> \+ struct redirect_error_signature< \+ R(const asio::error_code&, \+ ASIO_VARIADIC_TARGS(n)) noexcept> \+ { \+ typedef R type(ASIO_VARIADIC_TARGS(n)) noexcept; \+ }; \+ \+ template <typename R, ASIO_VARIADIC_TPARAMS(n)> \+ struct redirect_error_signature< \+ R(asio::error_code, \+ ASIO_VARIADIC_TARGS(n)) & noexcept> \+ { \+ typedef R type(ASIO_VARIADIC_TARGS(n)) & noexcept; \+ }; \+ \+ template <typename R, ASIO_VARIADIC_TPARAMS(n)> \+ struct redirect_error_signature< \+ R(const asio::error_code&, \+ ASIO_VARIADIC_TARGS(n)) & noexcept> \+ { \+ typedef R type(ASIO_VARIADIC_TARGS(n)) & noexcept; \+ }; \+ \+ template <typename R, ASIO_VARIADIC_TPARAMS(n)> \+ struct redirect_error_signature< \+ R(asio::error_code, \+ ASIO_VARIADIC_TARGS(n)) && noexcept> \+ { \+ typedef R type(ASIO_VARIADIC_TARGS(n)) && noexcept; \+ }; \+ \+ template <typename R, ASIO_VARIADIC_TPARAMS(n)> \+ struct redirect_error_signature< \+ R(const asio::error_code&, \+ ASIO_VARIADIC_TARGS(n)) && noexcept> \+ { \+ typedef R type(ASIO_VARIADIC_TARGS(n)) && noexcept; \+ }; \+ /**/+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_REDIRECT_ERROR_DEF)+#undef ASIO_PRIVATE_REDIRECT_ERROR_DEF++# endif // defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)+# endif // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)+#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+ } // namespace detail #if !defined(GENERATING_DOCUMENTATION)@@ -184,53 +476,130 @@ : async_result<CompletionToken, typename detail::redirect_error_signature<Signature>::type> {- template <typename Initiation>- struct init_wrapper : detail::initiation_base<Initiation>++ struct init_wrapper {- using detail::initiation_base<Initiation>::initiation_base;+ explicit init_wrapper(asio::error_code& ec)+ : ec_(ec)+ {+ } - template <typename Handler, typename... Args>- void operator()(Handler&& handler,- asio::error_code* ec, Args&&... args) &&+#if defined(ASIO_HAS_VARIADIC_TEMPLATES)++ template <typename Handler, typename Initiation, typename... Args>+ void operator()(+ ASIO_MOVE_ARG(Handler) handler,+ ASIO_MOVE_ARG(Initiation) initiation,+ ASIO_MOVE_ARG(Args)... args) const {- static_cast<Initiation&&>(*this)(- detail::redirect_error_handler<decay_t<Handler>>(- *ec, static_cast<Handler&&>(handler)),- static_cast<Args&&>(args)...);+ ASIO_MOVE_CAST(Initiation)(initiation)(+ detail::redirect_error_handler<+ typename decay<Handler>::type>(+ ec_, ASIO_MOVE_CAST(Handler)(handler)),+ ASIO_MOVE_CAST(Args)(args)...); } - template <typename Handler, typename... Args>- void operator()(Handler&& handler,- asio::error_code* ec, Args&&... args) const &+#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++ template <typename Handler, typename Initiation>+ void operator()(+ ASIO_MOVE_ARG(Handler) handler,+ ASIO_MOVE_ARG(Initiation) initiation) const {- static_cast<const Initiation&>(*this)(- detail::redirect_error_handler<decay_t<Handler>>(- *ec, static_cast<Handler&&>(handler)),- static_cast<Args&&>(args)...);+ ASIO_MOVE_CAST(Initiation)(initiation)(+ detail::redirect_error_handler<+ typename decay<Handler>::type>(+ ec_, ASIO_MOVE_CAST(Handler)(handler))); }++#define ASIO_PRIVATE_INIT_WRAPPER_DEF(n) \+ template <typename Handler, typename Initiation, \+ ASIO_VARIADIC_TPARAMS(n)> \+ void operator()( \+ ASIO_MOVE_ARG(Handler) handler, \+ ASIO_MOVE_ARG(Initiation) initiation, \+ ASIO_VARIADIC_MOVE_PARAMS(n)) const \+ { \+ ASIO_MOVE_CAST(Initiation)(initiation)( \+ detail::redirect_error_handler< \+ typename decay<Handler>::type>( \+ ec_, ASIO_MOVE_CAST(Handler)(handler)), \+ ASIO_VARIADIC_MOVE_ARGS(n)); \+ } \+ /**/+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_INIT_WRAPPER_DEF)+#undef ASIO_PRIVATE_INIT_WRAPPER_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++ asio::error_code& ec_; }; +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+ template <typename Initiation, typename RawCompletionToken, typename... Args>- static auto initiate(Initiation&& initiation,- RawCompletionToken&& token, Args&&... args)- -> decltype(- async_initiate<- conditional_t<- is_const<remove_reference_t<RawCompletionToken>>::value,- const CompletionToken, CompletionToken>,+ static ASIO_INITFN_DEDUCED_RESULT_TYPE(CompletionToken,+ typename detail::redirect_error_signature<Signature>::type,+ (async_initiate<CompletionToken, typename detail::redirect_error_signature<Signature>::type>(- declval<init_wrapper<decay_t<Initiation>>>(),- token.token_, &token.ec_, static_cast<Args&&>(args)...))+ declval<init_wrapper>(), declval<CompletionToken&>(),+ declval<Initiation>(), declval<ASIO_MOVE_ARG(Args)>()...)))+ initiate(+ ASIO_MOVE_ARG(Initiation) initiation,+ ASIO_MOVE_ARG(RawCompletionToken) token,+ ASIO_MOVE_ARG(Args)... args) {- return async_initiate<- conditional_t<- is_const<remove_reference_t<RawCompletionToken>>::value,- const CompletionToken, CompletionToken>,+ return async_initiate<CompletionToken, typename detail::redirect_error_signature<Signature>::type>(- init_wrapper<decay_t<Initiation>>(- static_cast<Initiation&&>(initiation)),- token.token_, &token.ec_, static_cast<Args&&>(args)...);+ init_wrapper(token.ec_), token.token_,+ ASIO_MOVE_CAST(Initiation)(initiation),+ ASIO_MOVE_CAST(Args)(args)...); }++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++ template <typename Initiation, typename RawCompletionToken>+ static ASIO_INITFN_DEDUCED_RESULT_TYPE(CompletionToken,+ typename detail::redirect_error_signature<Signature>::type,+ (async_initiate<CompletionToken,+ typename detail::redirect_error_signature<Signature>::type>(+ declval<init_wrapper>(), declval<CompletionToken&>(),+ declval<Initiation>())))+ initiate(+ ASIO_MOVE_ARG(Initiation) initiation,+ ASIO_MOVE_ARG(RawCompletionToken) token)+ {+ return async_initiate<CompletionToken,+ typename detail::redirect_error_signature<Signature>::type>(+ init_wrapper(token.ec_), token.token_,+ ASIO_MOVE_CAST(Initiation)(initiation));+ }++#define ASIO_PRIVATE_INITIATE_DEF(n) \+ template <typename Initiation, typename RawCompletionToken, \+ ASIO_VARIADIC_TPARAMS(n)> \+ static ASIO_INITFN_DEDUCED_RESULT_TYPE(CompletionToken, \+ typename detail::redirect_error_signature<Signature>::type, \+ (async_initiate<CompletionToken, \+ typename detail::redirect_error_signature<Signature>::type>( \+ declval<init_wrapper>(), declval<CompletionToken&>(), \+ declval<Initiation>(), ASIO_VARIADIC_DECLVAL(n)))) \+ initiate( \+ ASIO_MOVE_ARG(Initiation) initiation, \+ ASIO_MOVE_ARG(RawCompletionToken) token, \+ ASIO_VARIADIC_MOVE_PARAMS(n)) \+ { \+ return async_initiate<CompletionToken, \+ typename detail::redirect_error_signature<Signature>::type>( \+ init_wrapper(token.ec_), token.token_, \+ ASIO_MOVE_CAST(Initiation)(initiation), \+ ASIO_VARIADIC_MOVE_ARGS(n)); \+ } \+ /**/+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_INITIATE_DEF)+#undef ASIO_PRIVATE_INITIATE_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) }; template <template <typename, typename> class Associator,@@ -239,42 +608,20 @@ detail::redirect_error_handler<Handler>, DefaultCandidate> : Associator<Handler, DefaultCandidate> {- static typename Associator<Handler, DefaultCandidate>::type get(- const detail::redirect_error_handler<Handler>& h) noexcept+ static typename Associator<Handler, DefaultCandidate>::type+ get(const detail::redirect_error_handler<Handler>& h) ASIO_NOEXCEPT { return Associator<Handler, DefaultCandidate>::get(h.handler_); } - static auto get(const detail::redirect_error_handler<Handler>& h,- const DefaultCandidate& c) noexcept- -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))+ static ASIO_AUTO_RETURN_TYPE_PREFIX2(+ typename Associator<Handler, DefaultCandidate>::type)+ get(const detail::redirect_error_handler<Handler>& h,+ const DefaultCandidate& c) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ Associator<Handler, DefaultCandidate>::get(h.handler_, c))) { return Associator<Handler, DefaultCandidate>::get(h.handler_, c);- }-};--template <typename... Signatures>-struct async_result<partial_redirect_error, Signatures...>-{- template <typename Initiation, typename RawCompletionToken, typename... Args>- static auto initiate(Initiation&& initiation,- RawCompletionToken&& token, Args&&... args)- -> decltype(- async_initiate<Signatures...>(- static_cast<Initiation&&>(initiation),- redirect_error_t<- default_completion_token_t<associated_executor_t<Initiation>>>(- default_completion_token_t<associated_executor_t<Initiation>>{},- token.ec_),- static_cast<Args&&>(args)...))- {- return async_initiate<Signatures...>(- static_cast<Initiation&&>(initiation),- redirect_error_t<- default_completion_token_t<associated_executor_t<Initiation>>>(- default_completion_token_t<associated_executor_t<Initiation>>{},- token.ec_),- static_cast<Args&&>(args)...); } };
link/modules/asio-standalone/asio/include/asio/impl/serial_port_base.hpp view
@@ -2,7 +2,7 @@ // impl/serial_port_base.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying
link/modules/asio-standalone/asio/include/asio/impl/serial_port_base.ipp view
@@ -2,7 +2,7 @@ // impl/serial_port_base.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying
link/modules/asio-standalone/asio/include/asio/impl/spawn.hpp view
@@ -2,7 +2,7 @@ // impl/spawn.hpp // ~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -16,7 +16,6 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"-#include <tuple> #include "asio/associated_allocator.hpp" #include "asio/associated_cancellation_slot.hpp" #include "asio/associated_executor.hpp"@@ -24,15 +23,20 @@ #include "asio/bind_executor.hpp" #include "asio/detail/atomic_count.hpp" #include "asio/detail/bind_handler.hpp"+#include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_cont_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/noncopyable.hpp" #include "asio/detail/type_traits.hpp" #include "asio/detail/utility.hpp"-#include "asio/disposition.hpp"-#include "asio/error.hpp"+#include "asio/detail/variadic_templates.hpp" #include "asio/system_error.hpp" +#if defined(ASIO_HAS_STD_TUPLE)+# include <tuple>+#endif // defined(ASIO_HAS_STD_TUPLE)+ #if defined(ASIO_HAS_BOOST_CONTEXT_FIBER) # include <boost/context/fiber.hpp> #endif // defined(ASIO_HAS_BOOST_CONTEXT_FIBER)@@ -50,6 +54,137 @@ } #endif // !defined(ASIO_NO_EXCEPTIONS) +#if defined(ASIO_HAS_BOOST_COROUTINE)++// Spawned thread implementation using Boost.Coroutine.+class spawned_coroutine_thread : public spawned_thread_base+{+public:+#if defined(BOOST_COROUTINES_UNIDIRECT) || defined(BOOST_COROUTINES_V2)+ typedef boost::coroutines::pull_coroutine<void> callee_type;+ typedef boost::coroutines::push_coroutine<void> caller_type;+#else+ typedef boost::coroutines::coroutine<void()> callee_type;+ typedef boost::coroutines::coroutine<void()> caller_type;+#endif++ spawned_coroutine_thread(caller_type& caller)+ : caller_(caller),+ on_suspend_fn_(0),+ on_suspend_arg_(0)+ {+ }++ template <typename F>+ static spawned_thread_base* spawn(ASIO_MOVE_ARG(F) f,+ const boost::coroutines::attributes& attributes,+ cancellation_slot parent_cancel_slot = cancellation_slot(),+ cancellation_state cancel_state = cancellation_state())+ {+ spawned_coroutine_thread* spawned_thread = 0;+ callee_type callee(entry_point<typename decay<F>::type>(+ ASIO_MOVE_CAST(F)(f), &spawned_thread), attributes);+ spawned_thread->callee_.swap(callee);+ spawned_thread->parent_cancellation_slot_ = parent_cancel_slot;+ spawned_thread->cancellation_state_ = cancel_state;+ return spawned_thread;+ }++ template <typename F>+ static spawned_thread_base* spawn(ASIO_MOVE_ARG(F) f,+ cancellation_slot parent_cancel_slot = cancellation_slot(),+ cancellation_state cancel_state = cancellation_state())+ {+ return spawn(ASIO_MOVE_CAST(F)(f), boost::coroutines::attributes(),+ parent_cancel_slot, cancel_state);+ }++ void resume()+ {+ callee_();+ if (on_suspend_fn_)+ {+ void (*fn)(void*) = on_suspend_fn_;+ void* arg = on_suspend_arg_;+ on_suspend_fn_ = 0;+ fn(arg);+ }+ }++ void suspend_with(void (*fn)(void*), void* arg)+ {+ if (throw_if_cancelled_)+ if (!!cancellation_state_.cancelled())+ throw_error(asio::error::operation_aborted, "yield");+ has_context_switched_ = true;+ on_suspend_fn_ = fn;+ on_suspend_arg_ = arg;+ caller_();+ }++ void destroy()+ {+ callee_type callee;+ callee.swap(callee_);+ if (terminal_)+ callee();+ }++private:+ template <typename Function>+ class entry_point+ {+ public:+ template <typename F>+ entry_point(ASIO_MOVE_ARG(F) f,+ spawned_coroutine_thread** spawned_thread_out)+ : function_(ASIO_MOVE_CAST(F)(f)),+ spawned_thread_out_(spawned_thread_out)+ {+ }++ void operator()(caller_type& caller)+ {+ Function function(ASIO_MOVE_CAST(Function)(function_));+ spawned_coroutine_thread spawned_thread(caller);+ *spawned_thread_out_ = &spawned_thread;+ spawned_thread_out_ = 0;+ spawned_thread.suspend();+#if !defined(ASIO_NO_EXCEPTIONS)+ try+#endif // !defined(ASIO_NO_EXCEPTIONS)+ {+ function(&spawned_thread);+ spawned_thread.terminal_ = true;+ spawned_thread.suspend();+ }+#if !defined(ASIO_NO_EXCEPTIONS)+ catch (const boost::coroutines::detail::forced_unwind&)+ {+ throw;+ }+ catch (...)+ {+ exception_ptr ex = current_exception();+ spawned_thread.terminal_ = true;+ spawned_thread.suspend_with(spawned_thread_rethrow, &ex);+ }+#endif // !defined(ASIO_NO_EXCEPTIONS)+ }++ private:+ Function function_;+ spawned_coroutine_thread** spawned_thread_out_;+ };++ caller_type& caller_;+ callee_type callee_;+ void (*on_suspend_fn_)(void*);+ void* on_suspend_arg_;+};++#endif // defined(ASIO_HAS_BOOST_COROUTINE)+ #if defined(ASIO_HAS_BOOST_CONTEXT_FIBER) // Spawned thread implementation using Boost.Context's fiber.@@ -58,8 +193,8 @@ public: typedef boost::context::fiber fiber_type; - spawned_fiber_thread(fiber_type&& caller)- : caller_(static_cast<fiber_type&&>(caller)),+ spawned_fiber_thread(ASIO_MOVE_ARG(fiber_type) caller)+ : caller_(ASIO_MOVE_CAST(fiber_type)(caller)), on_suspend_fn_(0), on_suspend_arg_(0) {@@ -67,35 +202,35 @@ template <typename StackAllocator, typename F> static spawned_thread_base* spawn(allocator_arg_t,- StackAllocator&& stack_allocator,- F&& f,+ ASIO_MOVE_ARG(StackAllocator) stack_allocator,+ ASIO_MOVE_ARG(F) f, cancellation_slot parent_cancel_slot = cancellation_slot(), cancellation_state cancel_state = cancellation_state()) { spawned_fiber_thread* spawned_thread = 0; fiber_type callee(allocator_arg_t(),- static_cast<StackAllocator&&>(stack_allocator),- entry_point<decay_t<F>>(- static_cast<F&&>(f), &spawned_thread));- callee = fiber_type(static_cast<fiber_type&&>(callee)).resume();- spawned_thread->callee_ = static_cast<fiber_type&&>(callee);+ ASIO_MOVE_CAST(StackAllocator)(stack_allocator),+ entry_point<typename decay<F>::type>(+ ASIO_MOVE_CAST(F)(f), &spawned_thread));+ callee = fiber_type(ASIO_MOVE_CAST(fiber_type)(callee)).resume();+ spawned_thread->callee_ = ASIO_MOVE_CAST(fiber_type)(callee); spawned_thread->parent_cancellation_slot_ = parent_cancel_slot; spawned_thread->cancellation_state_ = cancel_state; return spawned_thread; } template <typename F>- static spawned_thread_base* spawn(F&& f,+ static spawned_thread_base* spawn(ASIO_MOVE_ARG(F) f, cancellation_slot parent_cancel_slot = cancellation_slot(), cancellation_state cancel_state = cancellation_state()) { return spawn(allocator_arg_t(), boost::context::fixedsize_stack(),- static_cast<F&&>(f), parent_cancel_slot, cancel_state);+ ASIO_MOVE_CAST(F)(f), parent_cancel_slot, cancel_state); } void resume() {- callee_ = fiber_type(static_cast<fiber_type&&>(callee_)).resume();+ callee_ = fiber_type(ASIO_MOVE_CAST(fiber_type)(callee_)).resume(); if (on_suspend_fn_) { void (*fn)(void*) = on_suspend_fn_;@@ -113,14 +248,14 @@ has_context_switched_ = true; on_suspend_fn_ = fn; on_suspend_arg_ = arg;- caller_ = fiber_type(static_cast<fiber_type&&>(caller_)).resume();+ caller_ = fiber_type(ASIO_MOVE_CAST(fiber_type)(caller_)).resume(); } void destroy() {- fiber_type callee = static_cast<fiber_type&&>(callee_);+ fiber_type callee = ASIO_MOVE_CAST(fiber_type)(callee_); if (terminal_)- fiber_type(static_cast<fiber_type&&>(callee)).resume();+ fiber_type(ASIO_MOVE_CAST(fiber_type)(callee)).resume(); } private:@@ -129,18 +264,18 @@ { public: template <typename F>- entry_point(F&& f,+ entry_point(ASIO_MOVE_ARG(F) f, spawned_fiber_thread** spawned_thread_out)- : function_(static_cast<F&&>(f)),+ : function_(ASIO_MOVE_CAST(F)(f)), spawned_thread_out_(spawned_thread_out) { } - fiber_type operator()(fiber_type&& caller)+ fiber_type operator()(ASIO_MOVE_ARG(fiber_type) caller) {- Function function(static_cast<Function&&>(function_));+ Function function(ASIO_MOVE_CAST(Function)(function_)); spawned_fiber_thread spawned_thread(- static_cast<fiber_type&&>(caller));+ ASIO_MOVE_CAST(fiber_type)(caller)); *spawned_thread_out_ = &spawned_thread; spawned_thread_out_ = 0; spawned_thread.suspend();@@ -164,7 +299,7 @@ spawned_thread.suspend_with(spawned_thread_rethrow, &ex); } #endif // !defined(ASIO_NO_EXCEPTIONS)- return static_cast<fiber_type&&>(spawned_thread.caller_);+ return ASIO_MOVE_CAST(fiber_type)(spawned_thread.caller_); } private:@@ -182,6 +317,8 @@ #if defined(ASIO_HAS_BOOST_CONTEXT_FIBER) typedef spawned_fiber_thread default_spawned_thread_type;+#elif defined(ASIO_HAS_BOOST_COROUTINE)+typedef spawned_coroutine_thread default_spawned_thread_type; #else # error No spawn() implementation available #endif@@ -193,14 +330,32 @@ explicit spawned_thread_resumer(spawned_thread_base* spawned_thread) : spawned_thread_(spawned_thread) {+#if !defined(ASIO_HAS_MOVE)+ spawned_thread->detach();+ spawned_thread->attach(&spawned_thread_);+#endif // !defined(ASIO_HAS_MOVE) } - spawned_thread_resumer(spawned_thread_resumer&& other) noexcept+#if defined(ASIO_HAS_MOVE)++ spawned_thread_resumer(spawned_thread_resumer&& other) ASIO_NOEXCEPT : spawned_thread_(other.spawned_thread_) { other.spawned_thread_ = 0; } +#else // defined(ASIO_HAS_MOVE)++ spawned_thread_resumer(+ const spawned_thread_resumer& other) ASIO_NOEXCEPT+ : spawned_thread_(other.spawned_thread_)+ {+ spawned_thread_->detach();+ spawned_thread_->attach(&spawned_thread_);+ }++#endif // defined(ASIO_HAS_MOVE)+ ~spawned_thread_resumer() { if (spawned_thread_)@@ -209,7 +364,9 @@ void operator()() {+#if defined(ASIO_HAS_MOVE) spawned_thread_->attach(&spawned_thread_);+#endif // defined(ASIO_HAS_MOVE) spawned_thread_->resume(); } @@ -225,14 +382,31 @@ : spawned_thread_(spawned_thread) { spawned_thread->detach();+#if !defined(ASIO_HAS_MOVE)+ spawned_thread->attach(&spawned_thread_);+#endif // !defined(ASIO_HAS_MOVE) } - spawned_thread_destroyer(spawned_thread_destroyer&& other) noexcept+#if defined(ASIO_HAS_MOVE)++ spawned_thread_destroyer(spawned_thread_destroyer&& other) ASIO_NOEXCEPT : spawned_thread_(other.spawned_thread_) { other.spawned_thread_ = 0; } +#else // defined(ASIO_HAS_MOVE)++ spawned_thread_destroyer(+ const spawned_thread_destroyer& other) ASIO_NOEXCEPT+ : spawned_thread_(other.spawned_thread_)+ {+ spawned_thread_->detach();+ spawned_thread_->attach(&spawned_thread_);+ }++#endif // defined(ASIO_HAS_MOVE)+ ~spawned_thread_destroyer() { if (spawned_thread_)@@ -265,9 +439,14 @@ spawned_thread_(yield.spawned_thread_) { spawned_thread_->detach();+#if !defined(ASIO_HAS_MOVE)+ spawned_thread_->attach(&spawned_thread_);+#endif // !defined(ASIO_HAS_MOVE) } - spawn_handler_base(spawn_handler_base&& other) noexcept+#if defined(ASIO_HAS_MOVE)++ spawn_handler_base(spawn_handler_base&& other) ASIO_NOEXCEPT : yield_(other.yield_), spawned_thread_(other.spawned_thread_) @@ -275,18 +454,30 @@ other.spawned_thread_ = 0; } +#else // defined(ASIO_HAS_MOVE)++ spawn_handler_base(const spawn_handler_base& other) ASIO_NOEXCEPT+ : yield_(other.yield_),+ spawned_thread_(other.spawned_thread_)+ {+ spawned_thread_->detach();+ spawned_thread_->attach(&spawned_thread_);+ }++#endif // defined(ASIO_HAS_MOVE)+ ~spawn_handler_base() { if (spawned_thread_) (post)(yield_.executor_, spawned_thread_destroyer(spawned_thread_)); } - executor_type get_executor() const noexcept+ executor_type get_executor() const ASIO_NOEXCEPT { return yield_.executor_; } - cancellation_slot_type get_cancellation_slot() const noexcept+ cancellation_slot_type get_cancellation_slot() const ASIO_NOEXCEPT { return spawned_thread_->get_cancellation_slot(); }@@ -304,7 +495,7 @@ }; // Completion handlers for when basic_yield_context is used as a token.-template <typename Executor, typename Signature, typename = void>+template <typename Executor, typename Signature> class spawn_handler; template <typename Executor, typename R>@@ -367,14 +558,13 @@ result_type& result_; }; -template <typename Executor, typename R, typename Disposition>-class spawn_handler<Executor, R(Disposition),- enable_if_t<is_disposition<Disposition>::value>- > : public spawn_handler_base<Executor>+template <typename Executor, typename R>+class spawn_handler<Executor, R(exception_ptr)>+ : public spawn_handler_base<Executor> { public: typedef void return_type;- typedef Disposition* result_type;+ typedef exception_ptr* result_type; spawn_handler(const basic_yield_context<Executor>& yield, result_type& result) : spawn_handler_base<Executor>(yield),@@ -382,16 +572,16 @@ { } - void operator()(Disposition d)+ void operator()(exception_ptr ex) {- result_ = detail::addressof(d);+ result_ = &ex; this->resume(); } static return_type on_resume(result_type& result) {- if (*result != no_error)- asio::throw_exception(static_cast<Disposition&&>(*result));+ if (result)+ rethrow_exception(*result); } private:@@ -399,9 +589,8 @@ }; template <typename Executor, typename R, typename T>-class spawn_handler<Executor, R(T),- enable_if_t<!is_disposition<T>::value>- > : public spawn_handler_base<Executor>+class spawn_handler<Executor, R(T)>+ : public spawn_handler_base<Executor> { public: typedef T return_type;@@ -415,13 +604,13 @@ void operator()(T value) {- result_ = detail::addressof(value);+ result_ = &value; this->resume(); } static return_type on_resume(result_type& result) {- return static_cast<return_type&&>(*result);+ return ASIO_MOVE_CAST(return_type)(*result); } private:@@ -456,7 +645,7 @@ } else result_.ec_ = &ec;- result_.value_ = detail::addressof(value);+ result_.value_ = &value; this->resume(); } @@ -464,24 +653,23 @@ { if (result.ec_) throw_error(*result.ec_);- return static_cast<return_type&&>(*result.value_);+ return ASIO_MOVE_CAST(return_type)(*result.value_); } private: result_type& result_; }; -template <typename Executor, typename R, typename Disposition, typename T>-class spawn_handler<Executor, R(Disposition, T),- enable_if_t<is_disposition<Disposition>::value>- > : public spawn_handler_base<Executor>+template <typename Executor, typename R, typename T>+class spawn_handler<Executor, R(exception_ptr, T)>+ : public spawn_handler_base<Executor> { public: typedef T return_type; struct result_type {- Disposition* disposition_;+ exception_ptr ex_; return_type* value_; }; @@ -491,34 +679,33 @@ { } - void operator()(Disposition d, T value)+ void operator()(exception_ptr ex, T value) {- result_.disposition_ = detail::addressof(d);- result_.value_ = detail::addressof(value);+ result_.ex_ = &ex;+ result_.value_ = &value; this->resume(); } static return_type on_resume(result_type& result) {- if (*result.disposition_ != no_error)- {- asio::throw_exception(- static_cast<Disposition&&>(*result.disposition_));- }- return static_cast<return_type&&>(*result.value_);+ if (result.ex_)+ rethrow_exception(*result.ex_);+ return ASIO_MOVE_CAST(return_type)(*result.value_); } private: result_type& result_; }; -template <typename Executor, typename R, typename T, typename... Ts>-class spawn_handler<Executor, R(T, Ts...),- enable_if_t<!is_disposition<T>::value>- > : public spawn_handler_base<Executor>+#if defined(ASIO_HAS_VARIADIC_TEMPLATES) \+ && defined(ASIO_HAS_STD_TUPLE)++template <typename Executor, typename R, typename... Ts>+class spawn_handler<Executor, R(Ts...)>+ : public spawn_handler_base<Executor> { public:- typedef std::tuple<T, Ts...> return_type;+ typedef std::tuple<Ts...> return_type; typedef return_type* result_type; @@ -529,16 +716,16 @@ } template <typename... Args>- void operator()(Args&&... args)+ void operator()(ASIO_MOVE_ARG(Args)... args) {- return_type value(static_cast<Args&&>(args)...);- result_ = detail::addressof(value);+ return_type value(ASIO_MOVE_CAST(Args)(args)...);+ result_ = &value; this->resume(); } static return_type on_resume(result_type& result) {- return static_cast<return_type&&>(*result);+ return ASIO_MOVE_CAST(return_type)(*result); } private:@@ -566,9 +753,9 @@ template <typename... Args> void operator()(asio::error_code ec,- Args&&... args)+ ASIO_MOVE_ARG(Args)... args) {- return_type value(static_cast<Args&&>(args)...);+ return_type value(ASIO_MOVE_CAST(Args)(args)...); if (this->yield_.ec_) { *this->yield_.ec_ = ec;@@ -576,7 +763,7 @@ } else result_.ec_ = &ec;- result_.value_ = detail::addressof(value);+ result_.value_ = &value; this->resume(); } @@ -584,24 +771,23 @@ { if (result.ec_) throw_error(*result.ec_);- return static_cast<return_type&&>(*result.value_);+ return ASIO_MOVE_CAST(return_type)(*result.value_); } private: result_type& result_; }; -template <typename Executor, typename R, typename Disposition, typename... Ts>-class spawn_handler<Executor, R(Disposition, Ts...),- enable_if_t<is_disposition<Disposition>::value>- > : public spawn_handler_base<Executor>+template <typename Executor, typename R, typename... Ts>+class spawn_handler<Executor, R(exception_ptr, Ts...)>+ : public spawn_handler_base<Executor> { public: typedef std::tuple<Ts...> return_type; struct result_type {- Disposition* disposition_;+ exception_ptr ex_; return_type* value_; }; @@ -612,28 +798,28 @@ } template <typename... Args>- void operator()(Disposition d, Args&&... args)+ void operator()(exception_ptr ex, ASIO_MOVE_ARG(Args)... args) {- return_type value(static_cast<Args&&>(args)...);- result_.disposition_ = detail::addressof(d);- result_.value_ = detail::addressof(value);+ return_type value(ASIO_MOVE_CAST(Args)(args)...);+ result_.ex_ = &ex;+ result_.value_ = &value; this->resume(); } static return_type on_resume(result_type& result) {- if (*result.disposition_ != no_error)- {- asio::throw_exception(- static_cast<Disposition&&>(*result.disposition_));- }- return static_cast<return_type&&>(*result.value_);+ if (result.ex_)+ rethrow_exception(*result.ex_);+ return ASIO_MOVE_CAST(return_type)(*result.value_); } private: result_type& result_; }; +#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+ // && defined(ASIO_HAS_STD_TUPLE)+ template <typename Executor, typename Signature> inline bool asio_handler_is_continuation(spawn_handler<Executor, Signature>*) {@@ -642,8 +828,6 @@ } // namespace detail -#if !defined(GENERATING_DOCUMENTATION)- template <typename Executor, typename Signature> class async_result<basic_yield_context<Executor>, Signature> {@@ -651,12 +835,13 @@ typedef typename detail::spawn_handler<Executor, Signature> handler_type; typedef typename handler_type::return_type return_type; -#if defined(ASIO_HAS_VARIADIC_LAMBDA_CAPTURES)+#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+# if defined(ASIO_HAS_VARIADIC_LAMBDA_CAPTURES) template <typename Initiation, typename... InitArgs>- static return_type initiate(Initiation&& init,+ static return_type initiate(ASIO_MOVE_ARG(Initiation) init, const basic_yield_context<Executor>& yield,- InitArgs&&... init_args)+ ASIO_MOVE_ARG(InitArgs)... init_args) { typename handler_type::result_type result = typename handler_type::result_type();@@ -664,30 +849,30 @@ yield.spawned_thread_->suspend_with( [&]() {- static_cast<Initiation&&>(init)(+ ASIO_MOVE_CAST(Initiation)(init)( handler_type(yield, result),- static_cast<InitArgs&&>(init_args)...);+ ASIO_MOVE_CAST(InitArgs)(init_args)...); }); return handler_type::on_resume(result); } -#else // defined(ASIO_HAS_VARIADIC_LAMBDA_CAPTURES)+# else // defined(ASIO_HAS_VARIADIC_LAMBDA_CAPTURES) template <typename Initiation, typename... InitArgs> struct suspend_with_helper { typename handler_type::result_type& result_;- Initiation&& init_;+ ASIO_MOVE_ARG(Initiation) init_; const basic_yield_context<Executor>& yield_;- std::tuple<InitArgs&&...> init_args_;+ std::tuple<ASIO_MOVE_ARG(InitArgs)...> init_args_; template <std::size_t... I> void do_invoke(detail::index_sequence<I...>) {- static_cast<Initiation&&>(init_)(+ ASIO_MOVE_CAST(Initiation)(init_)( handler_type(yield_, result_),- static_cast<InitArgs&&>(std::get<I>(init_args_))...);+ ASIO_MOVE_CAST(InitArgs)(std::get<I>(init_args_))...); } void operator()()@@ -697,27 +882,123 @@ }; template <typename Initiation, typename... InitArgs>- static return_type initiate(Initiation&& init,+ static return_type initiate(ASIO_MOVE_ARG(Initiation) init, const basic_yield_context<Executor>& yield,- InitArgs&&... init_args)+ ASIO_MOVE_ARG(InitArgs)... init_args) { typename handler_type::result_type result = typename handler_type::result_type(); yield.spawned_thread_->suspend_with( suspend_with_helper<Initiation, InitArgs...>{- result, static_cast<Initiation&&>(init), yield,- std::tuple<InitArgs&&...>(- static_cast<InitArgs&&>(init_args)...)});+ result, ASIO_MOVE_CAST(Initiation)(init), yield,+ std::tuple<ASIO_MOVE_ARG(InitArgs)...>(+ ASIO_MOVE_CAST(InitArgs)(init_args)...)}); return handler_type::on_resume(result); } -#endif // defined(ASIO_HAS_VARIADIC_LAMBDA_CAPTURES)-};+# endif // defined(ASIO_HAS_VARIADIC_LAMBDA_CAPTURES)+#else // defined(ASIO_HAS_VARIADIC_TEMPLATES) -#endif // !defined(GENERATING_DOCUMENTATION)+ template <typename Initiation>+ static return_type initiate(Initiation init,+ const basic_yield_context<Executor>& yield)+ {+ typename handler_type::result_type result+ = typename handler_type::result_type(); + struct on_suspend+ {+ Initiation& init_;+ const basic_yield_context<Executor>& yield_;+ typename handler_type::result_type& result_;++ void do_call()+ {+ ASIO_MOVE_CAST(Initiation)(init_)(+ handler_type(yield_, result_));+ }++ static void call(void* arg)+ {+ static_cast<on_suspend*>(arg)->do_call();+ }+ } o = { init, yield, result };++ yield.spawned_thread_->suspend_with(&on_suspend::call, &o);++ return handler_type::on_resume(result);+ }++#define ASIO_PRIVATE_ON_SUSPEND_MEMBERS(n) \+ ASIO_PRIVATE_ON_SUSPEND_MEMBERS_##n+#define ASIO_PRIVATE_ON_SUSPEND_MEMBERS_1 \+ T1& x1;+#define ASIO_PRIVATE_ON_SUSPEND_MEMBERS_2 \+ T1& x1; T2& x2;+#define ASIO_PRIVATE_ON_SUSPEND_MEMBERS_3 \+ T1& x1; T2& x2; T3& x3;+#define ASIO_PRIVATE_ON_SUSPEND_MEMBERS_4 \+ T1& x1; T2& x2; T3& x3; T4& x4;+#define ASIO_PRIVATE_ON_SUSPEND_MEMBERS_5 \+ T1& x1; T2& x2; T3& x3; T4& x4; T5& x5;+#define ASIO_PRIVATE_ON_SUSPEND_MEMBERS_6 \+ T1& x1; T2& x2; T3& x3; T4& x4; T5& x5; T6& x6;+#define ASIO_PRIVATE_ON_SUSPEND_MEMBERS_7 \+ T1& x1; T2& x2; T3& x3; T4& x4; T5& x5; T6& x6; T7& x7;+#define ASIO_PRIVATE_ON_SUSPEND_MEMBERS_8 \+ T1& x1; T2& x2; T3& x3; T4& x4; T5& x5; T6& x6; T7& x7; T8& x8;++#define ASIO_PRIVATE_INITIATE_DEF(n) \+ template <typename Initiation, ASIO_VARIADIC_TPARAMS(n)> \+ static return_type initiate(Initiation init, \+ const basic_yield_context<Executor>& yield, \+ ASIO_VARIADIC_BYVAL_PARAMS(n)) \+ { \+ typename handler_type::result_type result \+ = typename handler_type::result_type(); \+ \+ struct on_suspend \+ { \+ Initiation& init; \+ const basic_yield_context<Executor>& yield; \+ typename handler_type::result_type& result; \+ ASIO_PRIVATE_ON_SUSPEND_MEMBERS(n) \+ \+ void do_call() \+ { \+ ASIO_MOVE_CAST(Initiation)(init)( \+ handler_type(yield, result), \+ ASIO_VARIADIC_MOVE_ARGS(n)); \+ } \+ \+ static void call(void* arg) \+ { \+ static_cast<on_suspend*>(arg)->do_call(); \+ } \+ } o = { init, yield, result, ASIO_VARIADIC_BYVAL_ARGS(n) }; \+ \+ yield.spawned_thread_->suspend_with(&on_suspend::call, &o); \+ \+ return handler_type::on_resume(result); \+ } \+ /**/+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_INITIATE_DEF)+#undef ASIO_PRIVATE_INITIATE_DEF+#undef ASIO_PRIVATE_ON_SUSPEND_MEMBERS+#undef ASIO_PRIVATE_ON_SUSPEND_MEMBERS_1+#undef ASIO_PRIVATE_ON_SUSPEND_MEMBERS_2+#undef ASIO_PRIVATE_ON_SUSPEND_MEMBERS_3+#undef ASIO_PRIVATE_ON_SUSPEND_MEMBERS_4+#undef ASIO_PRIVATE_ON_SUSPEND_MEMBERS_5+#undef ASIO_PRIVATE_ON_SUSPEND_MEMBERS_6+#undef ASIO_PRIVATE_ON_SUSPEND_MEMBERS_7+#undef ASIO_PRIVATE_ON_SUSPEND_MEMBERS_8++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+};+ namespace detail { template <typename Executor, typename Function, typename Handler>@@ -726,10 +1007,10 @@ public: template <typename F, typename H> spawn_entry_point(const Executor& ex,- F&& f, H&& h)+ ASIO_MOVE_ARG(F) f, ASIO_MOVE_ARG(H) h) : executor_(ex),- function_(static_cast<F&&>(f)),- handler_(static_cast<H&&>(h)),+ function_(ASIO_MOVE_CAST(F)(f)),+ handler_(ASIO_MOVE_CAST(H)(h)), work_(handler_, executor_) { }@@ -738,7 +1019,8 @@ { const basic_yield_context<Executor> yield(spawned_thread, executor_); this->call(yield,- void_type<result_of_t<Function(basic_yield_context<Executor>)>>());+ void_type<typename result_of<Function(+ basic_yield_context<Executor>)>::type>()); } private:@@ -762,6 +1044,12 @@ throw; } # endif // defined(ASIO_HAS_BOOST_CONTEXT_FIBER)+# if defined(ASIO_HAS_BOOST_COROUTINE)+ catch (const boost::coroutines::detail::forced_unwind&)+ {+ throw;+ }+# endif // defined(ASIO_HAS_BOOST_COROUTINE) catch (...) { exception_ptr ex = current_exception();@@ -783,9 +1071,8 @@ T result(function_(yield)); if (!yield.spawned_thread_->has_context_switched()) (post)(yield);- detail::move_binder2<Handler, exception_ptr, T>- handler(0, static_cast<Handler&&>(handler_),- exception_ptr(), static_cast<T&&>(result));+ detail::binder2<Handler, exception_ptr, T>+ handler(handler_, exception_ptr(), ASIO_MOVE_CAST(T)(result)); work_.complete(handler, handler.handler_); } #if !defined(ASIO_NO_EXCEPTIONS)@@ -795,13 +1082,18 @@ throw; } # endif // defined(ASIO_HAS_BOOST_CONTEXT_FIBER)+# if defined(ASIO_HAS_BOOST_COROUTINE)+ catch (const boost::coroutines::detail::forced_unwind&)+ {+ throw;+ }+# endif // defined(ASIO_HAS_BOOST_COROUTINE) catch (...) { exception_ptr ex = current_exception(); if (!yield.spawned_thread_->has_context_switched()) (post)(yield);- detail::move_binder2<Handler, exception_ptr, T>- handler(0, static_cast<Handler&&>(handler_), ex, T());+ detail::binder2<Handler, exception_ptr, T> handler(handler_, ex, T()); work_.complete(handler, handler.handler_); } #endif // !defined(ASIO_NO_EXCEPTIONS)@@ -849,15 +1141,16 @@ Executor ex_; }; + template <typename Handler, typename Executor> class spawn_cancellation_handler<Handler, Executor,- enable_if_t<+ typename enable_if< is_same< typename associated_executor<Handler, Executor>::asio_associated_executor_is_unspecialised, void >::value- >>+ >::type> { public: spawn_cancellation_handler(const Handler&, const Executor&)@@ -889,21 +1182,21 @@ { } - executor_type get_executor() const noexcept+ executor_type get_executor() const ASIO_NOEXCEPT { return executor_; } template <typename Handler, typename F>- void operator()(Handler&& handler,- F&& f) const+ void operator()(ASIO_MOVE_ARG(Handler) handler,+ ASIO_MOVE_ARG(F) f) const {- typedef decay_t<Handler> handler_type;- typedef decay_t<F> function_type;+ typedef typename decay<Handler>::type handler_type;+ typedef typename decay<F>::type function_type; typedef spawn_cancellation_handler< handler_type, Executor> cancel_handler_type; - associated_cancellation_slot_t<handler_type> slot+ typename associated_cancellation_slot<handler_type>::type slot = asio::get_associated_cancellation_slot(handler); cancel_handler_type* cancel_handler = slot.is_connected()@@ -921,24 +1214,24 @@ spawned_thread_resumer( default_spawned_thread_type::spawn( spawn_entry_point<Executor, function_type, handler_type>(- executor_, static_cast<F&&>(f),- static_cast<Handler&&>(handler)),+ executor_, ASIO_MOVE_CAST(F)(f),+ ASIO_MOVE_CAST(Handler)(handler)), proxy_slot, cancel_state))); } #if defined(ASIO_HAS_BOOST_CONTEXT_FIBER) template <typename Handler, typename StackAllocator, typename F>- void operator()(Handler&& handler, allocator_arg_t,- StackAllocator&& stack_allocator,- F&& f) const+ void operator()(ASIO_MOVE_ARG(Handler) handler, allocator_arg_t,+ ASIO_MOVE_ARG(StackAllocator) stack_allocator,+ ASIO_MOVE_ARG(F) f) const {- typedef decay_t<Handler> handler_type;- typedef decay_t<F> function_type;+ typedef typename decay<Handler>::type handler_type;+ typedef typename decay<F>::type function_type; typedef spawn_cancellation_handler< handler_type, Executor> cancel_handler_type; - associated_cancellation_slot_t<handler_type> slot+ typename associated_cancellation_slot<handler_type>::type slot = asio::get_associated_cancellation_slot(handler); cancel_handler_type* cancel_handler = slot.is_connected()@@ -955,10 +1248,10 @@ (dispatch)(executor_, spawned_thread_resumer( spawned_fiber_thread::spawn(allocator_arg_t(),- static_cast<StackAllocator&&>(stack_allocator),+ ASIO_MOVE_CAST(StackAllocator)(stack_allocator), spawn_entry_point<Executor, function_type, handler_type>(- executor_, static_cast<F&&>(f),- static_cast<Handler&&>(handler)),+ executor_, ASIO_MOVE_CAST(F)(f),+ ASIO_MOVE_CAST(Handler)(handler)), proxy_slot, cancel_state))); } @@ -972,141 +1265,349 @@ template <typename Executor, typename F, ASIO_COMPLETION_TOKEN_FOR(typename detail::spawn_signature<- result_of_t<F(basic_yield_context<Executor>)>>::type) CompletionToken>-inline auto spawn(const Executor& ex, F&& function, CompletionToken&& token,- constraint_t<+ typename result_of<F(basic_yield_context<Executor>)>::type>::type)+ CompletionToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(CompletionToken,+ typename detail::spawn_signature<+ typename result_of<F(basic_yield_context<Executor>)>::type>::type)+spawn(const Executor& ex, ASIO_MOVE_ARG(F) function,+ ASIO_MOVE_ARG(CompletionToken) token,+#if defined(ASIO_HAS_BOOST_COROUTINE)+ typename constraint<+ !is_same<+ typename decay<CompletionToken>::type,+ boost::coroutines::attributes+ >::value+ >::type,+#endif // defined(ASIO_HAS_BOOST_COROUTINE)+ typename constraint< is_executor<Executor>::value || execution::is_executor<Executor>::value- >)- -> decltype(+ >::type)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<CompletionToken, typename detail::spawn_signature<- result_of_t<F(basic_yield_context<Executor>)>>::type>(- declval<detail::initiate_spawn<Executor>>(),- token, static_cast<F&&>(function)))+ typename result_of<F(basic_yield_context<Executor>)>::type>::type>(+ declval<detail::initiate_spawn<Executor> >(),+ token, ASIO_MOVE_CAST(F)(function)))) { return async_initiate<CompletionToken, typename detail::spawn_signature<- result_of_t<F(basic_yield_context<Executor>)>>::type>(+ typename result_of<F(basic_yield_context<Executor>)>::type>::type>( detail::initiate_spawn<Executor>(ex),- token, static_cast<F&&>(function));+ token, ASIO_MOVE_CAST(F)(function)); } template <typename ExecutionContext, typename F, ASIO_COMPLETION_TOKEN_FOR(typename detail::spawn_signature<- result_of_t<F(basic_yield_context<- typename ExecutionContext::executor_type>)>>::type) CompletionToken>-inline auto spawn(ExecutionContext& ctx, F&& function, CompletionToken&& token,- constraint_t<+ typename result_of<F(basic_yield_context<+ typename ExecutionContext::executor_type>)>::type>::type)+ CompletionToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(CompletionToken,+ typename detail::spawn_signature<+ typename result_of<F(basic_yield_context<+ typename ExecutionContext::executor_type>)>::type>::type)+spawn(ExecutionContext& ctx, ASIO_MOVE_ARG(F) function,+ ASIO_MOVE_ARG(CompletionToken) token,+#if defined(ASIO_HAS_BOOST_COROUTINE)+ typename constraint<+ !is_same<+ typename decay<CompletionToken>::type,+ boost::coroutines::attributes+ >::value+ >::type,+#endif // defined(ASIO_HAS_BOOST_COROUTINE)+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- >)- -> decltype(+ >::type)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<CompletionToken, typename detail::spawn_signature<- result_of_t<F(basic_yield_context<- typename ExecutionContext::executor_type>)>>::type>(+ typename result_of<F(basic_yield_context<+ typename ExecutionContext::executor_type>)>::type>::type>( declval<detail::initiate_spawn<- typename ExecutionContext::executor_type>>(),- token, static_cast<F&&>(function)))+ typename ExecutionContext::executor_type> >(),+ token, ASIO_MOVE_CAST(F)(function)))) {- return (spawn)(ctx.get_executor(), static_cast<F&&>(function),- static_cast<CompletionToken&&>(token));+ return (spawn)(ctx.get_executor(), ASIO_MOVE_CAST(F)(function),+ ASIO_MOVE_CAST(CompletionToken)(token)); } template <typename Executor, typename F, ASIO_COMPLETION_TOKEN_FOR(typename detail::spawn_signature<- result_of_t<F(basic_yield_context<Executor>)>>::type)+ typename result_of<F(basic_yield_context<Executor>)>::type>::type) CompletionToken>-inline auto spawn(const basic_yield_context<Executor>& ctx,- F&& function, CompletionToken&& token,- constraint_t<+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(CompletionToken,+ typename detail::spawn_signature<+ typename result_of<F(basic_yield_context<Executor>)>::type>::type)+spawn(const basic_yield_context<Executor>& ctx,+ ASIO_MOVE_ARG(F) function,+ ASIO_MOVE_ARG(CompletionToken) token,+#if defined(ASIO_HAS_BOOST_COROUTINE)+ typename constraint<+ !is_same<+ typename decay<CompletionToken>::type,+ boost::coroutines::attributes+ >::value+ >::type,+#endif // defined(ASIO_HAS_BOOST_COROUTINE)+ typename constraint< is_executor<Executor>::value || execution::is_executor<Executor>::value- >)- -> decltype(+ >::type)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<CompletionToken, typename detail::spawn_signature<- result_of_t<F(basic_yield_context<Executor>)>>::type>(- declval<detail::initiate_spawn<Executor>>(),- token, static_cast<F&&>(function)))+ typename result_of<F(basic_yield_context<Executor>)>::type>::type>(+ declval<detail::initiate_spawn<Executor> >(),+ token, ASIO_MOVE_CAST(F)(function)))) {- return (spawn)(ctx.get_executor(), static_cast<F&&>(function),- static_cast<CompletionToken&&>(token));+ return (spawn)(ctx.get_executor(), ASIO_MOVE_CAST(F)(function),+ ASIO_MOVE_CAST(CompletionToken)(token)); } #if defined(ASIO_HAS_BOOST_CONTEXT_FIBER) template <typename Executor, typename StackAllocator, typename F, ASIO_COMPLETION_TOKEN_FOR(typename detail::spawn_signature<- result_of_t<F(basic_yield_context<Executor>)>>::type)+ typename result_of<F(basic_yield_context<Executor>)>::type>::type) CompletionToken>-inline auto spawn(const Executor& ex, allocator_arg_t,- StackAllocator&& stack_allocator, F&& function, CompletionToken&& token,- constraint_t<+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(CompletionToken,+ typename detail::spawn_signature<+ typename result_of<F(basic_yield_context<Executor>)>::type>::type)+spawn(const Executor& ex, allocator_arg_t,+ ASIO_MOVE_ARG(StackAllocator) stack_allocator,+ ASIO_MOVE_ARG(F) function,+ ASIO_MOVE_ARG(CompletionToken) token,+ typename constraint< is_executor<Executor>::value || execution::is_executor<Executor>::value- >)- -> decltype(+ >::type)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<CompletionToken, typename detail::spawn_signature<- result_of_t<F(basic_yield_context<Executor>)>>::type>(- declval<detail::initiate_spawn<Executor>>(),+ typename result_of<F(basic_yield_context<Executor>)>::type>::type>(+ declval<detail::initiate_spawn<Executor> >(), token, allocator_arg_t(),- static_cast<StackAllocator&&>(stack_allocator),- static_cast<F&&>(function)))+ ASIO_MOVE_CAST(StackAllocator)(stack_allocator),+ ASIO_MOVE_CAST(F)(function)))) { return async_initiate<CompletionToken, typename detail::spawn_signature<- result_of_t<F(basic_yield_context<Executor>)>>::type>(+ typename result_of<F(basic_yield_context<Executor>)>::type>::type>( detail::initiate_spawn<Executor>(ex), token, allocator_arg_t(),- static_cast<StackAllocator&&>(stack_allocator),- static_cast<F&&>(function));+ ASIO_MOVE_CAST(StackAllocator)(stack_allocator),+ ASIO_MOVE_CAST(F)(function)); } template <typename ExecutionContext, typename StackAllocator, typename F, ASIO_COMPLETION_TOKEN_FOR(typename detail::spawn_signature<- result_of_t<F(basic_yield_context<- typename ExecutionContext::executor_type>)>>::type) CompletionToken>-inline auto spawn(ExecutionContext& ctx, allocator_arg_t,- StackAllocator&& stack_allocator, F&& function, CompletionToken&& token,- constraint_t<+ typename result_of<F(basic_yield_context<+ typename ExecutionContext::executor_type>)>::type>::type)+ CompletionToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(CompletionToken,+ typename detail::spawn_signature<+ typename result_of<F(basic_yield_context<+ typename ExecutionContext::executor_type>)>::type>::type)+spawn(ExecutionContext& ctx, allocator_arg_t,+ ASIO_MOVE_ARG(StackAllocator) stack_allocator,+ ASIO_MOVE_ARG(F) function,+ ASIO_MOVE_ARG(CompletionToken) token,+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- >)- -> decltype(+ >::type)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<CompletionToken, typename detail::spawn_signature<- result_of_t<F(basic_yield_context<- typename ExecutionContext::executor_type>)>>::type>(+ typename result_of<F(basic_yield_context<+ typename ExecutionContext::executor_type>)>::type>::type>( declval<detail::initiate_spawn<- typename ExecutionContext::executor_type>>(),+ typename ExecutionContext::executor_type> >(), token, allocator_arg_t(),- static_cast<StackAllocator&&>(stack_allocator),- static_cast<F&&>(function)))+ ASIO_MOVE_CAST(StackAllocator)(stack_allocator),+ ASIO_MOVE_CAST(F)(function)))) { return (spawn)(ctx.get_executor(), allocator_arg_t(),- static_cast<StackAllocator&&>(stack_allocator),- static_cast<F&&>(function), static_cast<CompletionToken&&>(token));+ ASIO_MOVE_CAST(StackAllocator)(stack_allocator),+ ASIO_MOVE_CAST(F)(function),+ ASIO_MOVE_CAST(CompletionToken)(token)); } template <typename Executor, typename StackAllocator, typename F, ASIO_COMPLETION_TOKEN_FOR(typename detail::spawn_signature<- result_of_t<F(basic_yield_context<Executor>)>>::type) CompletionToken>-inline auto spawn(const basic_yield_context<Executor>& ctx, allocator_arg_t,- StackAllocator&& stack_allocator, F&& function, CompletionToken&& token,- constraint_t<+ typename result_of<F(basic_yield_context<Executor>)>::type>::type)+ CompletionToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(CompletionToken,+ typename detail::spawn_signature<+ typename result_of<F(basic_yield_context<Executor>)>::type>::type)+spawn(const basic_yield_context<Executor>& ctx, allocator_arg_t,+ ASIO_MOVE_ARG(StackAllocator) stack_allocator,+ ASIO_MOVE_ARG(F) function,+ ASIO_MOVE_ARG(CompletionToken) token,+ typename constraint< is_executor<Executor>::value || execution::is_executor<Executor>::value- >)- -> decltype(+ >::type)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<CompletionToken, typename detail::spawn_signature<- result_of_t<F(basic_yield_context<Executor>)>>::type>(- declval<detail::initiate_spawn<Executor>>(), token,- allocator_arg_t(), static_cast<StackAllocator&&>(stack_allocator),- static_cast<F&&>(function)))+ typename result_of<F(basic_yield_context<Executor>)>::type>::type>(+ declval<detail::initiate_spawn<Executor> >(),+ token, allocator_arg_t(),+ ASIO_MOVE_CAST(StackAllocator)(stack_allocator),+ ASIO_MOVE_CAST(F)(function)))) { return (spawn)(ctx.get_executor(), allocator_arg_t(),- static_cast<StackAllocator&&>(stack_allocator),- static_cast<F&&>(function), static_cast<CompletionToken&&>(token));+ ASIO_MOVE_CAST(StackAllocator)(stack_allocator),+ ASIO_MOVE_CAST(F)(function),+ ASIO_MOVE_CAST(CompletionToken)(token)); } #endif // defined(ASIO_HAS_BOOST_CONTEXT_FIBER)++#if defined(ASIO_HAS_BOOST_COROUTINE)++namespace detail {++template <typename Executor, typename Function, typename Handler>+class old_spawn_entry_point+{+public:+ template <typename F, typename H>+ old_spawn_entry_point(const Executor& ex,+ ASIO_MOVE_ARG(F) f, ASIO_MOVE_ARG(H) h)+ : executor_(ex),+ function_(ASIO_MOVE_CAST(F)(f)),+ handler_(ASIO_MOVE_CAST(H)(h))+ {+ }++ void operator()(spawned_thread_base* spawned_thread)+ {+ const basic_yield_context<Executor> yield(spawned_thread, executor_);+ this->call(yield,+ void_type<typename result_of<Function(+ basic_yield_context<Executor>)>::type>());+ }++private:+ void call(const basic_yield_context<Executor>& yield, void_type<void>)+ {+ function_(yield);+ ASIO_MOVE_OR_LVALUE(Handler)(handler_)();+ }++ template <typename T>+ void call(const basic_yield_context<Executor>& yield, void_type<T>)+ {+ ASIO_MOVE_OR_LVALUE(Handler)(handler_)(function_(yield));+ }++ Executor executor_;+ Function function_;+ Handler handler_;+};++inline void default_spawn_handler() {}++} // namespace detail++template <typename Function>+inline void spawn(ASIO_MOVE_ARG(Function) function,+ const boost::coroutines::attributes& attributes)+{+ typedef typename decay<Function>::type function_type;++ typename associated_executor<function_type>::type ex(+ (get_associated_executor)(function));++ asio::spawn(ex, ASIO_MOVE_CAST(Function)(function), attributes);+}++template <typename Handler, typename Function>+void spawn(ASIO_MOVE_ARG(Handler) handler,+ ASIO_MOVE_ARG(Function) function,+ const boost::coroutines::attributes& attributes,+ typename constraint<+ !is_executor<typename decay<Handler>::type>::value &&+ !execution::is_executor<typename decay<Handler>::type>::value &&+ !is_convertible<Handler&, execution_context&>::value>::type)+{+ typedef typename decay<Handler>::type handler_type;+ typedef typename decay<Function>::type function_type;+ typedef typename associated_executor<handler_type>::type executor_type;++ executor_type ex((get_associated_executor)(handler));++ (dispatch)(ex,+ detail::spawned_thread_resumer(+ detail::spawned_coroutine_thread::spawn(+ detail::old_spawn_entry_point<executor_type,+ function_type, void (*)()>(+ ex, ASIO_MOVE_CAST(Function)(function),+ &detail::default_spawn_handler), attributes)));+}++template <typename Executor, typename Function>+void spawn(basic_yield_context<Executor> ctx,+ ASIO_MOVE_ARG(Function) function,+ const boost::coroutines::attributes& attributes)+{+ typedef typename decay<Function>::type function_type;++ (dispatch)(ctx.get_executor(),+ detail::spawned_thread_resumer(+ detail::spawned_coroutine_thread::spawn(+ detail::old_spawn_entry_point<Executor,+ function_type, void (*)()>(ctx.get_executor(),+ ASIO_MOVE_CAST(Function)(function),+ &detail::default_spawn_handler), attributes)));+}++template <typename Function, typename Executor>+inline void spawn(const Executor& ex,+ ASIO_MOVE_ARG(Function) function,+ const boost::coroutines::attributes& attributes,+ typename constraint<+ is_executor<Executor>::value || execution::is_executor<Executor>::value+ >::type)+{+ asio::spawn(asio::strand<Executor>(ex),+ ASIO_MOVE_CAST(Function)(function), attributes);+}++template <typename Function, typename Executor>+inline void spawn(const strand<Executor>& ex,+ ASIO_MOVE_ARG(Function) function,+ const boost::coroutines::attributes& attributes)+{+ asio::spawn(asio::bind_executor(+ ex, &detail::default_spawn_handler),+ ASIO_MOVE_CAST(Function)(function), attributes);+}++#if !defined(ASIO_NO_TS_EXECUTORS)++template <typename Function>+inline void spawn(const asio::io_context::strand& s,+ ASIO_MOVE_ARG(Function) function,+ const boost::coroutines::attributes& attributes)+{+ asio::spawn(asio::bind_executor(+ s, &detail::default_spawn_handler),+ ASIO_MOVE_CAST(Function)(function), attributes);+}++#endif // !defined(ASIO_NO_TS_EXECUTORS)++template <typename Function, typename ExecutionContext>+inline void spawn(ExecutionContext& ctx,+ ASIO_MOVE_ARG(Function) function,+ const boost::coroutines::attributes& attributes,+ typename constraint<is_convertible<+ ExecutionContext&, execution_context&>::value>::type)+{+ asio::spawn(ctx.get_executor(),+ ASIO_MOVE_CAST(Function)(function), attributes);+}++#endif // defined(ASIO_HAS_BOOST_COROUTINE) } // namespace asio
link/modules/asio-standalone/asio/include/asio/impl/src.hpp view
@@ -2,7 +2,7 @@ // impl/src.hpp // ~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -21,14 +21,13 @@ #include "asio/impl/any_completion_executor.ipp" #include "asio/impl/any_io_executor.ipp"-#include "asio/impl/awaitable.ipp" #include "asio/impl/cancellation_signal.ipp"-#include "asio/impl/config.ipp" #include "asio/impl/connect_pipe.ipp" #include "asio/impl/error.ipp" #include "asio/impl/error_code.ipp" #include "asio/impl/execution_context.ipp" #include "asio/impl/executor.ipp"+#include "asio/impl/handler_alloc_hook.ipp" #include "asio/impl/io_context.ipp" #include "asio/impl/multiple_exceptions.ipp" #include "asio/impl/serial_port_base.ipp"@@ -55,7 +54,6 @@ #include "asio/detail/impl/reactive_descriptor_service.ipp" #include "asio/detail/impl/reactive_socket_service_base.ipp" #include "asio/detail/impl/resolver_service_base.ipp"-#include "asio/detail/impl/resolver_thread_pool.ipp" #include "asio/detail/impl/scheduler.ipp" #include "asio/detail/impl/select_reactor.ipp" #include "asio/detail/impl/service_registry.ipp"@@ -66,6 +64,7 @@ #include "asio/detail/impl/strand_service.ipp" #include "asio/detail/impl/thread_context.ipp" #include "asio/detail/impl/throw_error.ipp"+#include "asio/detail/impl/timer_queue_ptime.ipp" #include "asio/detail/impl/timer_queue_set.ipp" #include "asio/detail/impl/win_iocp_file_service.ipp" #include "asio/detail/impl/win_iocp_handle_service.ipp"@@ -82,6 +81,7 @@ #include "asio/detail/impl/winrt_timer_scheduler.ipp" #include "asio/detail/impl/winsock_init.ipp" #include "asio/execution/impl/bad_executor.ipp"+#include "asio/execution/impl/receiver_invocation_error.ipp" #include "asio/experimental/impl/channel_error.ipp" #include "asio/generic/detail/impl/endpoint.ipp" #include "asio/ip/impl/address.ipp"
link/modules/asio-standalone/asio/include/asio/impl/system_context.hpp view
@@ -2,7 +2,7 @@ // impl/system_context.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -22,7 +22,7 @@ namespace asio { inline system_context::executor_type-system_context::get_executor() noexcept+system_context::get_executor() ASIO_NOEXCEPT { return system_executor(); }
link/modules/asio-standalone/asio/include/asio/impl/system_context.ipp view
@@ -2,7 +2,7 @@ // impl/system_context.ipp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -45,8 +45,7 @@ }; system_context::system_context()- : scheduler_(add_scheduler(new detail::scheduler(*this, false))),- threads_(std::allocator<void>())+ : scheduler_(add_scheduler(new detail::scheduler(*this, 0, false))) { scheduler_.work_started(); @@ -68,7 +67,7 @@ scheduler_.stop(); } -bool system_context::stopped() const noexcept+bool system_context::stopped() const ASIO_NOEXCEPT { return scheduler_.stopped(); }
link/modules/asio-standalone/asio/include/asio/impl/system_executor.hpp view
@@ -2,7 +2,7 @@ // impl/system_executor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -27,7 +27,7 @@ template <typename Blocking, typename Relationship, typename Allocator> inline system_context& basic_system_executor<Blocking, Relationship, Allocator>::query(- execution::context_t) noexcept+ execution::context_t) ASIO_NOEXCEPT { return detail::global<system_context>(); }@@ -35,7 +35,7 @@ template <typename Blocking, typename Relationship, typename Allocator> inline std::size_t basic_system_executor<Blocking, Relationship, Allocator>::query(- execution::occupancy_t) const noexcept+ execution::occupancy_t) const ASIO_NOEXCEPT { return detail::global<system_context>().num_threads_; }@@ -44,7 +44,7 @@ template <typename Function> inline void basic_system_executor<Blocking, Relationship, Allocator>::do_execute(- Function&& f, execution::blocking_t::possibly_t) const+ ASIO_MOVE_ARG(Function) f, execution::blocking_t::possibly_t) const { // Obtain a non-const instance of the function. detail::non_const_lvalue<Function> f2(f);@@ -54,7 +54,7 @@ { #endif// !defined(ASIO_NO_EXCEPTIONS) detail::fenced_block b(detail::fenced_block::full);- static_cast<decay_t<Function>&&>(f2.value)();+ asio_handler_invoke_helpers::invoke(f2.value, f2.value); #if !defined(ASIO_NO_EXCEPTIONS) } catch (...)@@ -68,7 +68,7 @@ template <typename Function> inline void basic_system_executor<Blocking, Relationship, Allocator>::do_execute(- Function&& f, execution::blocking_t::always_t) const+ ASIO_MOVE_ARG(Function) f, execution::blocking_t::always_t) const { // Obtain a non-const instance of the function. detail::non_const_lvalue<Function> f2(f);@@ -78,7 +78,7 @@ { #endif// !defined(ASIO_NO_EXCEPTIONS) detail::fenced_block b(detail::fenced_block::full);- static_cast<decay_t<Function>&&>(f2.value)();+ asio_handler_invoke_helpers::invoke(f2.value, f2.value); #if !defined(ASIO_NO_EXCEPTIONS) } catch (...)@@ -91,15 +91,16 @@ template <typename Blocking, typename Relationship, typename Allocator> template <typename Function> void basic_system_executor<Blocking, Relationship, Allocator>::do_execute(- Function&& f, execution::blocking_t::never_t) const+ ASIO_MOVE_ARG(Function) f, execution::blocking_t::never_t) const { system_context& ctx = detail::global<system_context>(); // Allocate and construct an operation to wrap the function.- typedef detail::executor_op<decay_t<Function>, Allocator> op;+ typedef typename decay<Function>::type function_type;+ typedef detail::executor_op<function_type, Allocator> op; typename op::ptr p = { detail::addressof(allocator_), op::ptr::allocate(allocator_), 0 };- p.p = new (p.v) op(static_cast<Function&&>(f), allocator_);+ p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(f), allocator_); if (is_same<Relationship, execution::relationship_t::continuation_t>::value) {@@ -120,7 +121,7 @@ #if !defined(ASIO_NO_TS_EXECUTORS) template <typename Blocking, typename Relationship, typename Allocator> inline system_context& basic_system_executor<- Blocking, Relationship, Allocator>::context() const noexcept+ Blocking, Relationship, Allocator>::context() const ASIO_NOEXCEPT { return detail::global<system_context>(); }@@ -128,22 +129,25 @@ template <typename Blocking, typename Relationship, typename Allocator> template <typename Function, typename OtherAllocator> void basic_system_executor<Blocking, Relationship, Allocator>::dispatch(- Function&& f, const OtherAllocator&) const+ ASIO_MOVE_ARG(Function) f, const OtherAllocator&) const {- decay_t<Function>(static_cast<Function&&>(f))();+ typename decay<Function>::type tmp(ASIO_MOVE_CAST(Function)(f));+ asio_handler_invoke_helpers::invoke(tmp, tmp); } template <typename Blocking, typename Relationship, typename Allocator> template <typename Function, typename OtherAllocator> void basic_system_executor<Blocking, Relationship, Allocator>::post(- Function&& f, const OtherAllocator& a) const+ ASIO_MOVE_ARG(Function) f, const OtherAllocator& a) const {+ typedef typename decay<Function>::type function_type;+ system_context& ctx = detail::global<system_context>(); // Allocate and construct an operation to wrap the function.- typedef detail::executor_op<decay_t<Function>, OtherAllocator> op;+ typedef detail::executor_op<function_type, OtherAllocator> op; typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 };- p.p = new (p.v) op(static_cast<Function&&>(f), a);+ p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(f), a); ASIO_HANDLER_CREATION((ctx, *p.p, "system_executor", &this->context(), 0, "post"));@@ -155,14 +159,16 @@ template <typename Blocking, typename Relationship, typename Allocator> template <typename Function, typename OtherAllocator> void basic_system_executor<Blocking, Relationship, Allocator>::defer(- Function&& f, const OtherAllocator& a) const+ ASIO_MOVE_ARG(Function) f, const OtherAllocator& a) const {+ typedef typename decay<Function>::type function_type;+ system_context& ctx = detail::global<system_context>(); // Allocate and construct an operation to wrap the function.- typedef detail::executor_op<decay_t<Function>, OtherAllocator> op;+ typedef detail::executor_op<function_type, OtherAllocator> op; typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 };- p.p = new (p.v) op(static_cast<Function&&>(f), a);+ p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(f), a); ASIO_HANDLER_CREATION((ctx, *p.p, "system_executor", &this->context(), 0, "defer"));
link/modules/asio-standalone/asio/include/asio/impl/thread_pool.hpp view
@@ -2,7 +2,7 @@ // impl/thread_pool.hpp // ~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -15,8 +15,8 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include "asio/config.hpp" #include "asio/detail/blocking_executor_op.hpp"+#include "asio/detail/bulk_executor_op.hpp" #include "asio/detail/executor_op.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/non_const_lvalue.hpp"@@ -27,63 +27,28 @@ namespace asio { -#if !defined(ASIO_NO_TS_EXECUTORS)--template <typename Allocator>-thread_pool::thread_pool(allocator_arg_t, const Allocator& a)- : execution_context(std::allocator_arg, a),- scheduler_(asio::make_service<detail::scheduler>(*this, false)),- threads_(allocator<void>(*this)),- num_threads_(default_thread_pool_size()),- joinable_(true)-{- start();-}--#endif // !defined(ASIO_NO_TS_EXECUTORS)--template <typename Allocator>-thread_pool::thread_pool(allocator_arg_t,- const Allocator& a, std::size_t num_threads)- : execution_context(std::allocator_arg, a,- config_from_concurrency_hint(num_threads == 1 ? 1 : 0)),- scheduler_(asio::make_service<detail::scheduler>(*this, false)),- threads_(allocator<void>(*this)),- num_threads_(clamp_thread_pool_size(num_threads)),- joinable_(true)-{- start();-}--template <typename Allocator>-thread_pool::thread_pool(allocator_arg_t,- const Allocator& a, std::size_t num_threads,- const execution_context::service_maker& initial_services)- : execution_context(std::allocator_arg, a, initial_services),- scheduler_(asio::make_service<detail::scheduler>(*this, false)),- threads_(allocator<void>(*this)),- num_threads_(clamp_thread_pool_size(num_threads)),- joinable_(true)+inline thread_pool::executor_type+thread_pool::get_executor() ASIO_NOEXCEPT {- start();+ return executor_type(*this); } inline thread_pool::executor_type-thread_pool::get_executor() noexcept+thread_pool::executor() ASIO_NOEXCEPT { return executor_type(*this); } -inline thread_pool::executor_type-thread_pool::executor() noexcept+inline thread_pool::scheduler_type+thread_pool::scheduler() ASIO_NOEXCEPT {- return executor_type(*this);+ return scheduler_type(*this); } template <typename Allocator, unsigned int Bits> thread_pool::basic_executor_type<Allocator, Bits>& thread_pool::basic_executor_type<Allocator, Bits>::operator=(- const basic_executor_type& other) noexcept+ const basic_executor_type& other) ASIO_NOEXCEPT { if (this != &other) {@@ -102,10 +67,11 @@ return *this; } +#if defined(ASIO_HAS_MOVE) template <typename Allocator, unsigned int Bits> thread_pool::basic_executor_type<Allocator, Bits>& thread_pool::basic_executor_type<Allocator, Bits>::operator=(- basic_executor_type&& other) noexcept+ basic_executor_type&& other) ASIO_NOEXCEPT { if (this != &other) {@@ -122,10 +88,11 @@ } return *this; }+#endif // defined(ASIO_HAS_MOVE) template <typename Allocator, unsigned int Bits> inline bool thread_pool::basic_executor_type<Allocator,- Bits>::running_in_this_thread() const noexcept+ Bits>::running_in_this_thread() const ASIO_NOEXCEPT { return pool_->scheduler_.can_dispatch(); }@@ -133,39 +100,43 @@ template <typename Allocator, unsigned int Bits> template <typename Function> void thread_pool::basic_executor_type<Allocator,- Bits>::do_execute(Function&& f, false_type) const+ Bits>::do_execute(ASIO_MOVE_ARG(Function) f, false_type) const {- typedef decay_t<Function> function_type;+ typedef typename decay<Function>::type function_type; // Invoke immediately if the blocking.possibly property is enabled and we are // already inside the thread pool. if ((bits_ & blocking_never) == 0 && pool_->scheduler_.can_dispatch()) { // Make a local, non-const copy of the function.- function_type tmp(static_cast<Function&&>(f));+ function_type tmp(ASIO_MOVE_CAST(Function)(f)); -#if !defined(ASIO_NO_EXCEPTIONS)+#if defined(ASIO_HAS_STD_EXCEPTION_PTR) \+ && !defined(ASIO_NO_EXCEPTIONS) try {-#endif // !defined(ASIO_NO_EXCEPTIONS)+#endif // defined(ASIO_HAS_STD_EXCEPTION_PTR)+ // && !defined(ASIO_NO_EXCEPTIONS) detail::fenced_block b(detail::fenced_block::full);- static_cast<function_type&&>(tmp)();+ asio_handler_invoke_helpers::invoke(tmp, tmp); return;-#if !defined(ASIO_NO_EXCEPTIONS)+#if defined(ASIO_HAS_STD_EXCEPTION_PTR) \+ && !defined(ASIO_NO_EXCEPTIONS) } catch (...) { pool_->scheduler_.capture_current_exception(); return; }-#endif // !defined(ASIO_NO_EXCEPTIONS)+#endif // defined(ASIO_HAS_STD_EXCEPTION_PTR)+ // && !defined(ASIO_NO_EXCEPTIONS) } // Allocate and construct an operation to wrap the function. typedef detail::executor_op<function_type, Allocator> op; typename op::ptr p = { detail::addressof(allocator_), op::ptr::allocate(allocator_), 0 };- p.p = new (p.v) op(static_cast<Function&&>(f), allocator_);+ p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(f), allocator_); if ((bits_ & relationship_continuation) != 0) {@@ -186,7 +157,7 @@ template <typename Allocator, unsigned int Bits> template <typename Function> void thread_pool::basic_executor_type<Allocator,- Bits>::do_execute(Function&& f, true_type) const+ Bits>::do_execute(ASIO_MOVE_ARG(Function) f, true_type) const { // Obtain a non-const instance of the function. detail::non_const_lvalue<Function> f2(f);@@ -199,7 +170,7 @@ { #endif // !defined(ASIO_NO_EXCEPTIONS) detail::fenced_block b(detail::fenced_block::full);- static_cast<decay_t<Function>&&>(f2.value)();+ asio_handler_invoke_helpers::invoke(f2.value, f2.value); return; #if !defined(ASIO_NO_EXCEPTIONS) }@@ -211,7 +182,7 @@ } // Construct an operation to wrap the function.- typedef decay_t<Function> function_type;+ typedef typename decay<Function>::type function_type; detail::blocking_executor_op<function_type> op(f2.value); ASIO_HANDLER_CREATION((*pool_, op,@@ -221,24 +192,88 @@ op.wait(); } +template <typename Allocator, unsigned int Bits>+template <typename Function>+void thread_pool::basic_executor_type<Allocator, Bits>::do_bulk_execute(+ ASIO_MOVE_ARG(Function) f, std::size_t n, false_type) const+{+ typedef typename decay<Function>::type function_type;+ typedef detail::bulk_executor_op<function_type, Allocator> op;++ // Allocate and construct operations to wrap the function.+ detail::op_queue<detail::scheduler_operation> ops;+ for (std::size_t i = 0; i < n; ++i)+ {+ typename op::ptr p = { detail::addressof(allocator_),+ op::ptr::allocate(allocator_), 0 };+ p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(f), allocator_, i);+ ops.push(p.p);++ if ((bits_ & relationship_continuation) != 0)+ {+ ASIO_HANDLER_CREATION((*pool_, *p.p,+ "thread_pool", pool_, 0, "bulk_execute(blk=never,rel=cont)"));+ }+ else+ {+ ASIO_HANDLER_CREATION((*pool_, *p.p,+ "thread_pool", pool_, 0, "bulk)execute(blk=never,rel=fork)"));+ }++ p.v = p.p = 0;+ }++ pool_->scheduler_.post_immediate_completions(n,+ ops, (bits_ & relationship_continuation) != 0);+}++template <typename Function>+struct thread_pool_always_blocking_function_adapter+{+ typename decay<Function>::type* f;+ std::size_t n;++ void operator()()+ {+ for (std::size_t i = 0; i < n; ++i)+ {+ (*f)(i);+ }+ }+};++template <typename Allocator, unsigned int Bits>+template <typename Function>+void thread_pool::basic_executor_type<Allocator, Bits>::do_bulk_execute(+ ASIO_MOVE_ARG(Function) f, std::size_t n, true_type) const+{+ // Obtain a non-const instance of the function.+ detail::non_const_lvalue<Function> f2(f);++ thread_pool_always_blocking_function_adapter<Function>+ adapter = { detail::addressof(f2.value), n };++ this->do_execute(adapter, true_type());+}+ #if !defined(ASIO_NO_TS_EXECUTORS) template <typename Allocator, unsigned int Bits> inline thread_pool& thread_pool::basic_executor_type<- Allocator, Bits>::context() const noexcept+ Allocator, Bits>::context() const ASIO_NOEXCEPT { return *pool_; } template <typename Allocator, unsigned int Bits> inline void thread_pool::basic_executor_type<Allocator,- Bits>::on_work_started() const noexcept+ Bits>::on_work_started() const ASIO_NOEXCEPT { pool_->scheduler_.work_started(); } template <typename Allocator, unsigned int Bits> inline void thread_pool::basic_executor_type<Allocator,- Bits>::on_work_finished() const noexcept+ Bits>::on_work_finished() const ASIO_NOEXCEPT { pool_->scheduler_.work_finished(); }@@ -246,25 +281,25 @@ template <typename Allocator, unsigned int Bits> template <typename Function, typename OtherAllocator> void thread_pool::basic_executor_type<Allocator, Bits>::dispatch(- Function&& f, const OtherAllocator& a) const+ ASIO_MOVE_ARG(Function) f, const OtherAllocator& a) const {- typedef decay_t<Function> function_type;+ typedef typename decay<Function>::type function_type; // Invoke immediately if we are already inside the thread pool. if (pool_->scheduler_.can_dispatch()) { // Make a local, non-const copy of the function.- function_type tmp(static_cast<Function&&>(f));+ function_type tmp(ASIO_MOVE_CAST(Function)(f)); detail::fenced_block b(detail::fenced_block::full);- static_cast<function_type&&>(tmp)();+ asio_handler_invoke_helpers::invoke(tmp, tmp); return; } // Allocate and construct an operation to wrap the function. typedef detail::executor_op<function_type, OtherAllocator> op; typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 };- p.p = new (p.v) op(static_cast<Function&&>(f), a);+ p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(f), a); ASIO_HANDLER_CREATION((*pool_, *p.p, "thread_pool", pool_, 0, "dispatch"));@@ -276,14 +311,14 @@ template <typename Allocator, unsigned int Bits> template <typename Function, typename OtherAllocator> void thread_pool::basic_executor_type<Allocator, Bits>::post(- Function&& f, const OtherAllocator& a) const+ ASIO_MOVE_ARG(Function) f, const OtherAllocator& a) const {- typedef decay_t<Function> function_type;+ typedef typename decay<Function>::type function_type; // Allocate and construct an operation to wrap the function. typedef detail::executor_op<function_type, OtherAllocator> op; typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 };- p.p = new (p.v) op(static_cast<Function&&>(f), a);+ p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(f), a); ASIO_HANDLER_CREATION((*pool_, *p.p, "thread_pool", pool_, 0, "post"));@@ -295,14 +330,14 @@ template <typename Allocator, unsigned int Bits> template <typename Function, typename OtherAllocator> void thread_pool::basic_executor_type<Allocator, Bits>::defer(- Function&& f, const OtherAllocator& a) const+ ASIO_MOVE_ARG(Function) f, const OtherAllocator& a) const {- typedef decay_t<Function> function_type;+ typedef typename decay<Function>::type function_type; // Allocate and construct an operation to wrap the function. typedef detail::executor_op<function_type, OtherAllocator> op; typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 };- p.p = new (p.v) op(static_cast<Function&&>(f), a);+ p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(f), a); ASIO_HANDLER_CREATION((*pool_, *p.p, "thread_pool", pool_, 0, "defer"));
link/modules/asio-standalone/asio/include/asio/impl/thread_pool.ipp view
@@ -2,7 +2,7 @@ // impl/thread_pool.ipp // ~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -47,26 +47,31 @@ }; #if !defined(ASIO_NO_TS_EXECUTORS)+namespace detail { -long thread_pool::default_thread_pool_size()+inline long default_thread_pool_size() {- std::size_t num_threads = detail::thread::hardware_concurrency() * 2;+ std::size_t num_threads = thread::hardware_concurrency() * 2; num_threads = num_threads == 0 ? 2 : num_threads; return static_cast<long>(num_threads); } +} // namespace detail+ thread_pool::thread_pool()- : scheduler_(asio::make_service<detail::scheduler>(*this, false)),- threads_(allocator<void>(*this)),- num_threads_(default_thread_pool_size()),- joinable_(true)+ : scheduler_(add_scheduler(new detail::scheduler(*this, 0, false))),+ num_threads_(detail::default_thread_pool_size()) {- start();-}+ scheduler_.work_started(); + thread_function f = { &scheduler_ };+ threads_.create_threads(f, static_cast<std::size_t>(num_threads_));+} #endif // !defined(ASIO_NO_TS_EXECUTORS) -long thread_pool::clamp_thread_pool_size(std::size_t n)+namespace detail {++inline long clamp_thread_pool_size(std::size_t n) { if (n > 0x7FFFFFFF) {@@ -76,25 +81,17 @@ return static_cast<long>(n & 0x7FFFFFFF); } +} // namespace detail+ thread_pool::thread_pool(std::size_t num_threads)- : execution_context(config_from_concurrency_hint(num_threads == 1 ? 1 : 0)),- scheduler_(asio::make_service<detail::scheduler>(*this, false)),- threads_(allocator<void>(*this)),- num_threads_(clamp_thread_pool_size(num_threads)),- joinable_(true)+ : scheduler_(add_scheduler(new detail::scheduler(+ *this, num_threads == 1 ? 1 : 0, false))),+ num_threads_(detail::clamp_thread_pool_size(num_threads)) {- start();-}+ scheduler_.work_started(); -thread_pool::thread_pool(std::size_t num_threads,- const execution_context::service_maker& initial_services)- : execution_context(initial_services),- scheduler_(asio::make_service<detail::scheduler>(*this, false)),- threads_(allocator<void>(*this)),- num_threads_(clamp_thread_pool_size(num_threads)),- joinable_(true)-{- start();+ thread_function f = { &scheduler_ };+ threads_.create_threads(f, static_cast<std::size_t>(num_threads_)); } thread_pool::~thread_pool()@@ -104,13 +101,6 @@ shutdown(); } -void thread_pool::start()-{- scheduler_.work_started();- thread_function f = { &scheduler_ };- threads_.create_threads(f, static_cast<std::size_t>(num_threads_));-}- void thread_pool::stop() { scheduler_.stop();@@ -125,17 +115,24 @@ void thread_pool::join() {- if (joinable_)- {- joinable_ = false;+ if (num_threads_) scheduler_.work_finished();++ if (!threads_.empty()) threads_.join();- } } +detail::scheduler& thread_pool::add_scheduler(detail::scheduler* s)+{+ detail::scoped_ptr<detail::scheduler> scoped_impl(s);+ asio::add_service<detail::scheduler>(*this, scoped_impl.get());+ return *scoped_impl.release();+}+ void thread_pool::wait() {- join();+ scheduler_.work_finished();+ threads_.join(); } } // namespace asio
link/modules/asio-standalone/asio/include/asio/impl/use_awaitable.hpp view
@@ -2,7 +2,7 @@ // impl/use_awaitable.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -18,7 +18,6 @@ #include "asio/detail/config.hpp" #include "asio/async_result.hpp" #include "asio/cancellation_signal.hpp"-#include "asio/disposition.hpp" #include "asio/detail/push_options.hpp" @@ -74,27 +73,77 @@ } }; +template <typename Executor>+class awaitable_handler<Executor, asio::error_code>+ : public awaitable_handler_base<Executor, void>+{+public:+ using awaitable_handler_base<Executor, void>::awaitable_handler_base;++ void operator()(const asio::error_code& ec)+ {+ this->frame()->attach_thread(this);+ if (ec)+ this->frame()->set_error(ec);+ else+ this->frame()->return_void();+ this->frame()->clear_cancellation_slot();+ this->frame()->pop_frame();+ this->pump();+ }+};++template <typename Executor>+class awaitable_handler<Executor, std::exception_ptr>+ : public awaitable_handler_base<Executor, void>+{+public:+ using awaitable_handler_base<Executor, void>::awaitable_handler_base;++ void operator()(std::exception_ptr ex)+ {+ this->frame()->attach_thread(this);+ if (ex)+ this->frame()->set_except(ex);+ else+ this->frame()->return_void();+ this->frame()->clear_cancellation_slot();+ this->frame()->pop_frame();+ this->pump();+ }+};+ template <typename Executor, typename T> class awaitable_handler<Executor, T>- : public awaitable_handler_base<Executor,- conditional_t<is_disposition<T>::value, void, T>>+ : public awaitable_handler_base<Executor, T> { public:- using awaitable_handler_base<Executor,- conditional_t<is_disposition<T>::value, void, T>>- ::awaitable_handler_base;+ using awaitable_handler_base<Executor, T>::awaitable_handler_base; template <typename Arg> void operator()(Arg&& arg) { this->frame()->attach_thread(this);- if constexpr (is_disposition<T>::value)- {- if (arg == no_error)- this->frame()->return_void();- else- this->frame()->set_disposition(arg);- }+ this->frame()->return_value(std::forward<Arg>(arg));+ this->frame()->clear_cancellation_slot();+ this->frame()->pop_frame();+ this->pump();+ }+};++template <typename Executor, typename T>+class awaitable_handler<Executor, asio::error_code, T>+ : public awaitable_handler_base<Executor, T>+{+public:+ using awaitable_handler_base<Executor, T>::awaitable_handler_base;++ template <typename Arg>+ void operator()(const asio::error_code& ec, Arg&& arg)+ {+ this->frame()->attach_thread(this);+ if (ec)+ this->frame()->set_error(ec); else this->frame()->return_value(std::forward<Arg>(arg)); this->frame()->clear_cancellation_slot();@@ -103,66 +152,84 @@ } }; -template <typename Executor, typename T0, typename T1>-class awaitable_handler<Executor, T0, T1>- : public awaitable_handler_base<Executor,- conditional_t<is_disposition<T0>::value, T1, std::tuple<T0, T1>>>+template <typename Executor, typename T>+class awaitable_handler<Executor, std::exception_ptr, T>+ : public awaitable_handler_base<Executor, T> { public:+ using awaitable_handler_base<Executor, T>::awaitable_handler_base;++ template <typename Arg>+ void operator()(std::exception_ptr ex, Arg&& arg)+ {+ this->frame()->attach_thread(this);+ if (ex)+ this->frame()->set_except(ex);+ else+ this->frame()->return_value(std::forward<Arg>(arg));+ this->frame()->clear_cancellation_slot();+ this->frame()->pop_frame();+ this->pump();+ }+};++template <typename Executor, typename... Ts>+class awaitable_handler+ : public awaitable_handler_base<Executor, std::tuple<Ts...>>+{+public: using awaitable_handler_base<Executor,- conditional_t<is_disposition<T0>::value, T1, std::tuple<T0, T1>>>- ::awaitable_handler_base;+ std::tuple<Ts...>>::awaitable_handler_base; - template <typename Arg0, typename Arg1>- void operator()(Arg0&& arg0, Arg1&& arg1)+ template <typename... Args>+ void operator()(Args&&... args) { this->frame()->attach_thread(this);- if constexpr (is_disposition<T0>::value)- {- if (arg0 == no_error)- this->frame()->return_value(std::forward<Arg1>(arg1));- else- this->frame()->set_disposition(std::forward<Arg0>(arg0));- }+ this->frame()->return_values(std::forward<Args>(args)...);+ this->frame()->clear_cancellation_slot();+ this->frame()->pop_frame();+ this->pump();+ }+};++template <typename Executor, typename... Ts>+class awaitable_handler<Executor, asio::error_code, Ts...>+ : public awaitable_handler_base<Executor, std::tuple<Ts...>>+{+public:+ using awaitable_handler_base<Executor,+ std::tuple<Ts...>>::awaitable_handler_base;++ template <typename... Args>+ void operator()(const asio::error_code& ec, Args&&... args)+ {+ this->frame()->attach_thread(this);+ if (ec)+ this->frame()->set_error(ec); else- {- this->frame()->return_values(std::forward<Arg0>(arg0),- std::forward<Arg1>(arg1));- }+ this->frame()->return_values(std::forward<Args>(args)...); this->frame()->clear_cancellation_slot(); this->frame()->pop_frame(); this->pump(); } }; -template <typename Executor, typename T0, typename... Ts>-class awaitable_handler<Executor, T0, Ts...>- : public awaitable_handler_base<Executor,- conditional_t<is_disposition<T0>::value,- std::tuple<Ts...>, std::tuple<T0, Ts...>>>+template <typename Executor, typename... Ts>+class awaitable_handler<Executor, std::exception_ptr, Ts...>+ : public awaitable_handler_base<Executor, std::tuple<Ts...>> { public: using awaitable_handler_base<Executor,- conditional_t<is_disposition<T0>::value,- std::tuple<Ts...>, std::tuple<T0, Ts...>>>- ::awaitable_handler_base;+ std::tuple<Ts...>>::awaitable_handler_base; - template <typename Arg0, typename... Args>- void operator()(Arg0&& arg0, Args&&... args)+ template <typename... Args>+ void operator()(std::exception_ptr ex, Args&&... args) { this->frame()->attach_thread(this);- if constexpr (is_disposition<T0>::value)- {- if (arg0 == no_error)- this->frame()->return_values(std::forward<Args>(args)...);- else- this->frame()->set_disposition(std::forward<Arg0>(arg0));- }+ if (ex)+ this->frame()->set_except(ex); else- {- this->frame()->return_values(std::forward<Arg0>(arg0),- std::forward<Args>(args)...);- }+ this->frame()->return_values(std::forward<Args>(args)...); this->frame()->clear_cancellation_slot(); this->frame()->pop_frame(); this->pump();@@ -191,7 +258,7 @@ { public: typedef typename detail::awaitable_handler<- Executor, decay_t<Args>...> handler_type;+ Executor, typename decay<Args>::type...> handler_type; typedef typename handler_type::awaitable_type return_type; template <typename Initiation, typename... InitArgs>@@ -219,9 +286,9 @@ }; for (;;) {} // Never reached.-#if defined(_MSC_VER) && !defined(__clang__)+#if defined(_MSC_VER) co_return dummy_return<typename return_type::value_type>();-#endif // defined(_MSC_VER) && !defined(__clang__)+#endif // defined(_MSC_VER) } };
link/modules/asio-standalone/asio/include/asio/impl/use_future.hpp view
@@ -2,7 +2,7 @@ // impl/use_future.hpp // ~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -19,9 +19,8 @@ #include <tuple> #include "asio/async_result.hpp" #include "asio/detail/memory.hpp"-#include "asio/detail/type_traits.hpp" #include "asio/dispatch.hpp"-#include "asio/disposition.hpp"+#include "asio/error_code.hpp" #include "asio/execution.hpp" #include "asio/packaged_task.hpp" #include "asio/system_error.hpp"@@ -32,15 +31,17 @@ namespace asio { namespace detail { +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+ template <typename T, typename F, typename... Args> inline void promise_invoke_and_set(std::promise<T>& p,- F& f, Args&&... args)+ F& f, ASIO_MOVE_ARG(Args)... args) { #if !defined(ASIO_NO_EXCEPTIONS) try #endif // !defined(ASIO_NO_EXCEPTIONS) {- p.set_value(f(static_cast<Args&&>(args)...));+ p.set_value(f(ASIO_MOVE_CAST(Args)(args)...)); } #if !defined(ASIO_NO_EXCEPTIONS) catch (...)@@ -52,13 +53,13 @@ template <typename F, typename... Args> inline void promise_invoke_and_set(std::promise<void>& p,- F& f, Args&&... args)+ F& f, ASIO_MOVE_ARG(Args)... args) { #if !defined(ASIO_NO_EXCEPTIONS) try #endif // !defined(ASIO_NO_EXCEPTIONS) {- f(static_cast<Args&&>(args)...);+ f(ASIO_MOVE_CAST(Args)(args)...); p.set_value(); } #if !defined(ASIO_NO_EXCEPTIONS)@@ -69,15 +70,112 @@ #endif // !defined(ASIO_NO_EXCEPTIONS) } +#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename T, typename F>+inline void promise_invoke_and_set(std::promise<T>& p, F& f)+{+#if !defined(ASIO_NO_EXCEPTIONS)+ try+#endif // !defined(ASIO_NO_EXCEPTIONS)+ {+ p.set_value(f());+ }+#if !defined(ASIO_NO_EXCEPTIONS)+ catch (...)+ {+ p.set_exception(std::current_exception());+ }+#endif // !defined(ASIO_NO_EXCEPTIONS)+}++template <typename F, typename Args>+inline void promise_invoke_and_set(std::promise<void>& p, F& f)+{+#if !defined(ASIO_NO_EXCEPTIONS)+ try+#endif // !defined(ASIO_NO_EXCEPTIONS)+ {+ f();+ p.set_value();+#if !defined(ASIO_NO_EXCEPTIONS)+ }+ catch (...)+ {+ p.set_exception(std::current_exception());+ }+#endif // !defined(ASIO_NO_EXCEPTIONS)+}++#if defined(ASIO_NO_EXCEPTIONS)++#define ASIO_PRIVATE_PROMISE_INVOKE_DEF(n) \+ template <typename T, typename F, ASIO_VARIADIC_TPARAMS(n)> \+ inline void promise_invoke_and_set(std::promise<T>& p, \+ F& f, ASIO_VARIADIC_MOVE_PARAMS(n)) \+ { \+ p.set_value(f(ASIO_VARIADIC_MOVE_ARGS(n))); \+ } \+ \+ template <typename F, ASIO_VARIADIC_TPARAMS(n)> \+ inline void promise_invoke_and_set(std::promise<void>& p, \+ F& f, ASIO_VARIADIC_MOVE_PARAMS(n)) \+ { \+ f(ASIO_VARIADIC_MOVE_ARGS(n)); \+ p.set_value(); \+ } \+ /**/+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_PROMISE_INVOKE_DEF)+#undef ASIO_PRIVATE_PROMISE_INVOKE_DEF++#else // defined(ASIO_NO_EXCEPTIONS)++#define ASIO_PRIVATE_PROMISE_INVOKE_DEF(n) \+ template <typename T, typename F, ASIO_VARIADIC_TPARAMS(n)> \+ inline void promise_invoke_and_set(std::promise<T>& p, \+ F& f, ASIO_VARIADIC_MOVE_PARAMS(n)) \+ { \+ try \+ { \+ p.set_value(f(ASIO_VARIADIC_MOVE_ARGS(n))); \+ } \+ catch (...) \+ { \+ p.set_exception(std::current_exception()); \+ } \+ } \+ \+ template <typename F, ASIO_VARIADIC_TPARAMS(n)> \+ inline void promise_invoke_and_set(std::promise<void>& p, \+ F& f, ASIO_VARIADIC_MOVE_PARAMS(n)) \+ { \+ try \+ { \+ f(ASIO_VARIADIC_MOVE_ARGS(n)); \+ p.set_value(); \+ } \+ catch (...) \+ { \+ p.set_exception(std::current_exception()); \+ } \+ } \+ /**/+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_PROMISE_INVOKE_DEF)+#undef ASIO_PRIVATE_PROMISE_INVOKE_DEF++#endif // defined(ASIO_NO_EXCEPTIONS)++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+ // A function object adapter to invoke a nullary function object and capture // any exception thrown into a promise. template <typename T, typename F> class promise_invoker { public:- promise_invoker(const shared_ptr<std::promise<T>>& p,- F&& f)- : p_(p), f_(static_cast<F&&>(f))+ promise_invoker(const shared_ptr<std::promise<T> >& p,+ ASIO_MOVE_ARG(F) f)+ : p_(p), f_(ASIO_MOVE_CAST(F)(f)) { } @@ -98,27 +196,27 @@ } private:- shared_ptr<std::promise<T>> p_;- decay_t<F> f_;+ shared_ptr<std::promise<T> > p_;+ typename decay<F>::type f_; }; -// An executor that adapts the system_executor to capture any exception thrown+// An executor that adapts the system_executor to capture any exeption thrown // by a submitted function object and save it into a promise. template <typename T, typename Blocking = execution::blocking_t::possibly_t> class promise_executor { public:- explicit promise_executor(const shared_ptr<std::promise<T>>& p)+ explicit promise_executor(const shared_ptr<std::promise<T> >& p) : p_(p) { } - execution_context& query(execution::context_t) const noexcept+ execution_context& query(execution::context_t) const ASIO_NOEXCEPT { return asio::query(system_executor(), execution::context); } - static constexpr Blocking query(execution::blocking_t)+ static ASIO_CONSTEXPR Blocking query(execution::blocking_t) { return Blocking(); }@@ -136,56 +234,62 @@ } template <typename F>- void execute(F&& f) const+ void execute(ASIO_MOVE_ARG(F) f) const {+#if defined(ASIO_NO_DEPRECATED) asio::require(system_executor(), Blocking()).execute(- promise_invoker<T, F>(p_, static_cast<F&&>(f)));+ promise_invoker<T, F>(p_, ASIO_MOVE_CAST(F)(f)));+#else // defined(ASIO_NO_DEPRECATED)+ execution::execute(+ asio::require(system_executor(), Blocking()),+ promise_invoker<T, F>(p_, ASIO_MOVE_CAST(F)(f)));+#endif // defined(ASIO_NO_DEPRECATED) } #if !defined(ASIO_NO_TS_EXECUTORS)- execution_context& context() const noexcept+ execution_context& context() const ASIO_NOEXCEPT { return system_executor().context(); } - void on_work_started() const noexcept {}- void on_work_finished() const noexcept {}+ void on_work_started() const ASIO_NOEXCEPT {}+ void on_work_finished() const ASIO_NOEXCEPT {} template <typename F, typename A>- void dispatch(F&& f, const A&) const+ void dispatch(ASIO_MOVE_ARG(F) f, const A&) const {- promise_invoker<T, F>(p_, static_cast<F&&>(f))();+ promise_invoker<T, F>(p_, ASIO_MOVE_CAST(F)(f))(); } template <typename F, typename A>- void post(F&& f, const A& a) const+ void post(ASIO_MOVE_ARG(F) f, const A& a) const { system_executor().post(- promise_invoker<T, F>(p_, static_cast<F&&>(f)), a);+ promise_invoker<T, F>(p_, ASIO_MOVE_CAST(F)(f)), a); } template <typename F, typename A>- void defer(F&& f, const A& a) const+ void defer(ASIO_MOVE_ARG(F) f, const A& a) const { system_executor().defer(- promise_invoker<T, F>(p_, static_cast<F&&>(f)), a);+ promise_invoker<T, F>(p_, ASIO_MOVE_CAST(F)(f)), a); } #endif // !defined(ASIO_NO_TS_EXECUTORS) friend bool operator==(const promise_executor& a,- const promise_executor& b) noexcept+ const promise_executor& b) ASIO_NOEXCEPT { return a.p_ == b.p_; } friend bool operator!=(const promise_executor& a,- const promise_executor& b) noexcept+ const promise_executor& b) ASIO_NOEXCEPT { return a.p_ != b.p_; } private:- shared_ptr<std::promise<T>> p_;+ shared_ptr<std::promise<T> > p_; }; // The base class for all completion handlers that create promises.@@ -195,7 +299,7 @@ public: typedef promise_executor<T> executor_type; - executor_type get_executor() const noexcept+ executor_type get_executor() const ASIO_NOEXCEPT { return executor_type(p_); }@@ -215,7 +319,7 @@ p_ = std::allocate_shared<std::promise<T>>(b, std::allocator_arg, b); } - shared_ptr<std::promise<T>> p_;+ shared_ptr<std::promise<T> > p_; }; // For completion signature void().@@ -229,18 +333,18 @@ } }; -// For completion signature void(disposition auto).-template <typename Disposition>-class promise_handler_d_0+// For completion signature void(error_code).+class promise_handler_ec_0 : public promise_creator<void> { public:- void operator()(Disposition d)+ void operator()(const asio::error_code& ec) {- if (d != no_error)+ if (ec) { this->p_->set_exception(- (to_exception_ptr)(static_cast<Disposition&&>(d)));+ std::make_exception_ptr(+ asio::system_error(ec))); } else {@@ -249,6 +353,24 @@ } }; +// For completion signature void(exception_ptr).+class promise_handler_ex_0+ : public promise_creator<void>+{+public:+ void operator()(const std::exception_ptr& ex)+ {+ if (ex)+ {+ this->p_->set_exception(ex);+ }+ else+ {+ this->p_->set_value();+ }+ }+};+ // For completion signature void(T). template <typename T> class promise_handler_1@@ -256,102 +378,249 @@ { public: template <typename Arg>- void operator()(Arg&& arg)+ void operator()(ASIO_MOVE_ARG(Arg) arg) {- this->p_->set_value(static_cast<Arg&&>(arg));+ this->p_->set_value(ASIO_MOVE_CAST(Arg)(arg)); } }; -// For completion signature void(disposition auto, T).-template <typename Disposition, typename T>-class promise_handler_d_1+// For completion signature void(error_code, T).+template <typename T>+class promise_handler_ec_1 : public promise_creator<T> { public: template <typename Arg>- void operator()(Disposition d, Arg&& arg)+ void operator()(const asio::error_code& ec,+ ASIO_MOVE_ARG(Arg) arg) {- if (d != no_error)+ if (ec) { this->p_->set_exception(- (to_exception_ptr)(static_cast<Disposition&&>(d)));+ std::make_exception_ptr(+ asio::system_error(ec))); } else- this->p_->set_value(static_cast<Arg&&>(arg));+ this->p_->set_value(ASIO_MOVE_CAST(Arg)(arg)); } }; +// For completion signature void(exception_ptr, T).+template <typename T>+class promise_handler_ex_1+ : public promise_creator<T>+{+public:+ template <typename Arg>+ void operator()(const std::exception_ptr& ex,+ ASIO_MOVE_ARG(Arg) arg)+ {+ if (ex)+ this->p_->set_exception(ex);+ else+ this->p_->set_value(ASIO_MOVE_CAST(Arg)(arg));+ }+};+ // For completion signature void(T1, ..., Tn); template <typename T> class promise_handler_n : public promise_creator<T> { public:+#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+ template <typename... Args>- void operator()(Args&&... args)+ void operator()(ASIO_MOVE_ARG(Args)... args) { this->p_->set_value( std::forward_as_tuple(- static_cast<Args&&>(args)...));+ ASIO_MOVE_CAST(Args)(args)...)); }++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++#define ASIO_PRIVATE_CALL_OP_DEF(n) \+ template <ASIO_VARIADIC_TPARAMS(n)> \+ void operator()(ASIO_VARIADIC_MOVE_PARAMS(n)) \+ {\+ this->p_->set_value( \+ std::forward_as_tuple( \+ ASIO_VARIADIC_MOVE_ARGS(n))); \+ } \+ /**/+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_CALL_OP_DEF)+#undef ASIO_PRIVATE_CALL_OP_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) }; // For completion signature void(error_code, T1, ..., Tn);-template <typename Disposition, typename T>-class promise_handler_d_n+template <typename T>+class promise_handler_ec_n : public promise_creator<T> { public:+#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+ template <typename... Args>- void operator()(Disposition d, Args&&... args)+ void operator()(const asio::error_code& ec,+ ASIO_MOVE_ARG(Args)... args) {- if (d != no_error)+ if (ec) { this->p_->set_exception(- (to_exception_ptr)(static_cast<Disposition&&>(d)));+ std::make_exception_ptr(+ asio::system_error(ec))); } else { this->p_->set_value( std::forward_as_tuple(- static_cast<Args&&>(args)...));+ ASIO_MOVE_CAST(Args)(args)...)); } }++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++#define ASIO_PRIVATE_CALL_OP_DEF(n) \+ template <ASIO_VARIADIC_TPARAMS(n)> \+ void operator()(const asio::error_code& ec, \+ ASIO_VARIADIC_MOVE_PARAMS(n)) \+ {\+ if (ec) \+ { \+ this->p_->set_exception( \+ std::make_exception_ptr( \+ asio::system_error(ec))); \+ } \+ else \+ { \+ this->p_->set_value( \+ std::forward_as_tuple( \+ ASIO_VARIADIC_MOVE_ARGS(n))); \+ } \+ } \+ /**/+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_CALL_OP_DEF)+#undef ASIO_PRIVATE_CALL_OP_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) }; +// For completion signature void(exception_ptr, T1, ..., Tn);+template <typename T>+class promise_handler_ex_n+ : public promise_creator<T>+{+public:+#if defined(ASIO_HAS_VARIADIC_TEMPLATES)++ template <typename... Args>+ void operator()(const std::exception_ptr& ex,+ ASIO_MOVE_ARG(Args)... args)+ {+ if (ex)+ this->p_->set_exception(ex);+ else+ {+ this->p_->set_value(+ std::forward_as_tuple(+ ASIO_MOVE_CAST(Args)(args)...));+ }+ }++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++#define ASIO_PRIVATE_CALL_OP_DEF(n) \+ template <ASIO_VARIADIC_TPARAMS(n)> \+ void operator()(const std::exception_ptr& ex, \+ ASIO_VARIADIC_MOVE_PARAMS(n)) \+ {\+ if (ex) \+ this->p_->set_exception(ex); \+ else \+ { \+ this->p_->set_value( \+ std::forward_as_tuple( \+ ASIO_VARIADIC_MOVE_ARGS(n))); \+ } \+ } \+ /**/+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_CALL_OP_DEF)+#undef ASIO_PRIVATE_CALL_OP_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+};+ // Helper template to choose the appropriate concrete promise handler // implementation based on the supplied completion signature.-template <typename, typename = void> class promise_handler_selector;+template <typename> class promise_handler_selector; template <> class promise_handler_selector<void()> : public promise_handler_0 {}; +template <>+class promise_handler_selector<void(asio::error_code)>+ : public promise_handler_ec_0 {};++template <>+class promise_handler_selector<void(std::exception_ptr)>+ : public promise_handler_ex_0 {};+ template <typename Arg>-class promise_handler_selector<void(Arg),- enable_if_t<is_disposition<Arg>::value>>- : public promise_handler_d_0<Arg> {};+class promise_handler_selector<void(Arg)>+ : public promise_handler_1<Arg> {}; template <typename Arg>-class promise_handler_selector<void(Arg),- enable_if_t<!is_disposition<Arg>::value>>- : public promise_handler_1<Arg> {};+class promise_handler_selector<void(asio::error_code, Arg)>+ : public promise_handler_ec_1<Arg> {}; -template <typename Arg0, typename Arg1>-class promise_handler_selector<void(Arg0, Arg1),- enable_if_t<is_disposition<Arg0>::value>>- : public promise_handler_d_1<Arg0, Arg1> {};+template <typename Arg>+class promise_handler_selector<void(std::exception_ptr, Arg)>+ : public promise_handler_ex_1<Arg> {}; -template <typename Arg0, typename... ArgN>-class promise_handler_selector<void(Arg0, ArgN...),- enable_if_t<!is_disposition<Arg0>::value>>- : public promise_handler_n<std::tuple<Arg0, ArgN...>> {};+#if defined(ASIO_HAS_VARIADIC_TEMPLATES) -template <typename Arg0, typename... ArgN>-class promise_handler_selector<void(Arg0, ArgN...),- enable_if_t<is_disposition<Arg0>::value>>- : public promise_handler_d_n<Arg0, std::tuple<ArgN...>> {};+template <typename... Arg>+class promise_handler_selector<void(Arg...)>+ : public promise_handler_n<std::tuple<Arg...> > {}; +template <typename... Arg>+class promise_handler_selector<void(asio::error_code, Arg...)>+ : public promise_handler_ec_n<std::tuple<Arg...> > {};++template <typename... Arg>+class promise_handler_selector<void(std::exception_ptr, Arg...)>+ : public promise_handler_ex_n<std::tuple<Arg...> > {};++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++#define ASIO_PRIVATE_PROMISE_SELECTOR_DEF(n) \+ template <typename Arg, ASIO_VARIADIC_TPARAMS(n)> \+ class promise_handler_selector< \+ void(Arg, ASIO_VARIADIC_TARGS(n))> \+ : public promise_handler_n< \+ std::tuple<Arg, ASIO_VARIADIC_TARGS(n)> > {}; \+ \+ template <typename Arg, ASIO_VARIADIC_TPARAMS(n)> \+ class promise_handler_selector< \+ void(asio::error_code, Arg, ASIO_VARIADIC_TARGS(n))> \+ : public promise_handler_ec_n< \+ std::tuple<Arg, ASIO_VARIADIC_TARGS(n)> > {}; \+ \+ template <typename Arg, ASIO_VARIADIC_TPARAMS(n)> \+ class promise_handler_selector< \+ void(std::exception_ptr, Arg, ASIO_VARIADIC_TARGS(n))> \+ : public promise_handler_ex_n< \+ std::tuple<Arg, ASIO_VARIADIC_TARGS(n)> > {}; \+ /**/+ ASIO_VARIADIC_GENERATE_5(ASIO_PRIVATE_PROMISE_SELECTOR_DEF)+#undef ASIO_PRIVATE_PROMISE_SELECTOR_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+ // Completion handlers produced from the use_future completion token, when not // using use_future::operator(). template <typename Signature, typename Allocator>@@ -368,7 +637,7 @@ this->create_promise(allocator_); } - allocator_type get_allocator() const noexcept+ allocator_type get_allocator() const ASIO_NOEXCEPT { return allocator_; }@@ -381,7 +650,7 @@ struct promise_function_wrapper { explicit promise_function_wrapper(Function& f)- : function_(static_cast<Function&&>(f))+ : function_(ASIO_MOVE_CAST(Function)(f)) { } @@ -398,6 +667,28 @@ Function function_; }; +#if !defined(ASIO_NO_DEPRECATED)++template <typename Function, typename Signature, typename Allocator>+inline void asio_handler_invoke(Function& f,+ promise_handler<Signature, Allocator>* h)+{+ typename promise_handler<Signature, Allocator>::executor_type+ ex(h->get_executor());+ asio::dispatch(ex, promise_function_wrapper<Function>(f));+}++template <typename Function, typename Signature, typename Allocator>+inline void asio_handler_invoke(const Function& f,+ promise_handler<Signature, Allocator>* h)+{+ typename promise_handler<Signature, Allocator>::executor_type+ ex(h->get_executor());+ asio::dispatch(ex, promise_function_wrapper<Function>(f));+}++#endif // !defined(ASIO_NO_DEPRECATED)+ // Helper base class for async_result specialisation. template <typename Signature, typename Allocator> class promise_async_result@@ -413,7 +704,7 @@ return_type get() {- return static_cast<return_type&&>(future_);+ return ASIO_MOVE_CAST(return_type)(future_); } private:@@ -426,7 +717,7 @@ { public: packaged_token(Function f, const Allocator& a)- : function_(static_cast<Function&&>(f)),+ : function_(ASIO_MOVE_CAST(Function)(f)), allocator_(a) { }@@ -447,29 +738,75 @@ typedef void result_type; packaged_handler(packaged_token<Function, Allocator> t)- : function_(static_cast<Function&&>(t.function_)),+ : function_(ASIO_MOVE_CAST(Function)(t.function_)), allocator_(t.allocator_) { this->create_promise(allocator_); } - allocator_type get_allocator() const noexcept+ allocator_type get_allocator() const ASIO_NOEXCEPT { return allocator_; } +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+ template <typename... Args>- void operator()(Args&&... args)+ void operator()(ASIO_MOVE_ARG(Args)... args) { (promise_invoke_and_set)(*this->p_,- function_, static_cast<Args&&>(args)...);+ function_, ASIO_MOVE_CAST(Args)(args)...); } +#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++ void operator()()+ {+ (promise_invoke_and_set)(*this->p_, function_);+ }++#define ASIO_PRIVATE_CALL_OP_DEF(n) \+ template <ASIO_VARIADIC_TPARAMS(n)> \+ void operator()(ASIO_VARIADIC_MOVE_PARAMS(n)) \+ {\+ (promise_invoke_and_set)(*this->p_, \+ function_, ASIO_VARIADIC_MOVE_ARGS(n)); \+ } \+ /**/+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_CALL_OP_DEF)+#undef ASIO_PRIVATE_CALL_OP_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+ private: Function function_; Allocator allocator_; }; +#if !defined(ASIO_NO_DEPRECATED)++template <typename Function,+ typename Function1, typename Allocator, typename Result>+inline void asio_handler_invoke(Function& f,+ packaged_handler<Function1, Allocator, Result>* h)+{+ typename packaged_handler<Function1, Allocator, Result>::executor_type+ ex(h->get_executor());+ asio::dispatch(ex, promise_function_wrapper<Function>(f));+}++template <typename Function,+ typename Function1, typename Allocator, typename Result>+inline void asio_handler_invoke(const Function& f,+ packaged_handler<Function1, Allocator, Result>* h)+{+ typename packaged_handler<Function1, Allocator, Result>::executor_type+ ex(h->get_executor());+ asio::dispatch(ex, promise_function_wrapper<Function>(f));+}++#endif // !defined(ASIO_NO_DEPRECATED)+ // Helper base class for async_result specialisation. template <typename Function, typename Allocator, typename Result> class packaged_async_result@@ -485,7 +822,7 @@ return_type get() {- return static_cast<return_type&&>(future_);+ return ASIO_MOVE_CAST(return_type)(future_); } private:@@ -495,26 +832,28 @@ } // namespace detail template <typename Allocator> template <typename Function>-inline detail::packaged_token<decay_t<Function>, Allocator>-use_future_t<Allocator>::operator()(Function&& f) const+inline detail::packaged_token<typename decay<Function>::type, Allocator>+use_future_t<Allocator>::operator()(ASIO_MOVE_ARG(Function) f) const {- return detail::packaged_token<decay_t<Function>, Allocator>(- static_cast<Function&&>(f), allocator_);+ return detail::packaged_token<typename decay<Function>::type, Allocator>(+ ASIO_MOVE_CAST(Function)(f), allocator_); } #if !defined(GENERATING_DOCUMENTATION) +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+ template <typename Allocator, typename Result, typename... Args> class async_result<use_future_t<Allocator>, Result(Args...)> : public detail::promise_async_result<- void(decay_t<Args>...), Allocator>+ void(typename decay<Args>::type...), Allocator> { public: explicit async_result(- typename detail::promise_async_result<void(decay_t<Args>...),+ typename detail::promise_async_result<void(typename decay<Args>::type...), Allocator>::completion_handler_type& h) : detail::promise_async_result<- void(decay_t<Args>...), Allocator>(h)+ void(typename decay<Args>::type...), Allocator>(h) { } };@@ -523,28 +862,100 @@ typename Result, typename... Args> class async_result<detail::packaged_token<Function, Allocator>, Result(Args...)> : public detail::packaged_async_result<Function, Allocator,- result_of_t<Function(Args...)>>+ typename result_of<Function(Args...)>::type> { public: explicit async_result( typename detail::packaged_async_result<Function, Allocator,- result_of_t<Function(Args...)>>::completion_handler_type& h)+ typename result_of<Function(Args...)>::type>::completion_handler_type& h) : detail::packaged_async_result<Function, Allocator,- result_of_t<Function(Args...)>>(h)+ typename result_of<Function(Args...)>::type>(h) { } }; +#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename Allocator, typename Result>+class async_result<use_future_t<Allocator>, Result()>+ : public detail::promise_async_result<void(), Allocator>+{+public:+ explicit async_result(+ typename detail::promise_async_result<+ void(), Allocator>::completion_handler_type& h)+ : detail::promise_async_result<void(), Allocator>(h)+ {+ }+};++template <typename Function, typename Allocator, typename Result>+class async_result<detail::packaged_token<Function, Allocator>, Result()>+ : public detail::packaged_async_result<Function, Allocator,+ typename result_of<Function()>::type>+{+public:+ explicit async_result(+ typename detail::packaged_async_result<Function, Allocator,+ typename result_of<Function()>::type>::completion_handler_type& h)+ : detail::packaged_async_result<Function, Allocator,+ typename result_of<Function()>::type>(h)+ {+ }+};++#define ASIO_PRIVATE_ASYNC_RESULT_DEF(n) \+ template <typename Allocator, \+ typename Result, ASIO_VARIADIC_TPARAMS(n)> \+ class async_result<use_future_t<Allocator>, \+ Result(ASIO_VARIADIC_TARGS(n))> \+ : public detail::promise_async_result< \+ void(ASIO_VARIADIC_DECAY(n)), Allocator> \+ { \+ public: \+ explicit async_result( \+ typename detail::promise_async_result< \+ void(ASIO_VARIADIC_DECAY(n)), \+ Allocator>::completion_handler_type& h) \+ : detail::promise_async_result< \+ void(ASIO_VARIADIC_DECAY(n)), Allocator>(h) \+ { \+ } \+ }; \+ \+ template <typename Function, typename Allocator, \+ typename Result, ASIO_VARIADIC_TPARAMS(n)> \+ class async_result<detail::packaged_token<Function, Allocator>, \+ Result(ASIO_VARIADIC_TARGS(n))> \+ : public detail::packaged_async_result<Function, Allocator, \+ typename result_of<Function(ASIO_VARIADIC_TARGS(n))>::type> \+ { \+ public: \+ explicit async_result( \+ typename detail::packaged_async_result<Function, Allocator, \+ typename result_of<Function(ASIO_VARIADIC_TARGS(n))>::type \+ >::completion_handler_type& h) \+ : detail::packaged_async_result<Function, Allocator, \+ typename result_of<Function(ASIO_VARIADIC_TARGS(n))>::type>(h) \+ { \+ } \+ }; \+ /**/+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_ASYNC_RESULT_DEF)+#undef ASIO_PRIVATE_ASYNC_RESULT_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+ namespace traits { #if !defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT) template <typename T, typename Blocking> struct equality_comparable<- asio::detail::promise_executor<T, Blocking>>+ asio::detail::promise_executor<T, Blocking> > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); }; #endif // !defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)@@ -555,8 +966,8 @@ struct execute_member< asio::detail::promise_executor<T, Blocking>, Function> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = false;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); typedef void result_type; }; @@ -576,11 +987,11 @@ >::type > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef Blocking result_type; - static constexpr result_type value() noexcept+ static ASIO_CONSTEXPR result_type value() ASIO_NOEXCEPT { return Blocking(); }@@ -596,8 +1007,8 @@ execution::context_t > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef asio::system_context& result_type; }; @@ -611,8 +1022,8 @@ execution::blocking_t::possibly_t > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef asio::detail::promise_executor<T, execution::blocking_t::possibly_t> result_type; };@@ -623,8 +1034,8 @@ execution::blocking_t::never_t > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef asio::detail::promise_executor<T, execution::blocking_t::never_t> result_type; };
link/modules/asio-standalone/asio/include/asio/impl/write.hpp view
@@ -2,7 +2,7 @@ // impl/write.hpp // ~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -23,7 +23,9 @@ #include "asio/detail/bind_handler.hpp" #include "asio/detail/consuming_buffers.hpp" #include "asio/detail/dependent_type.hpp"+#include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_cont_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_tracking.hpp" #include "asio/detail/handler_type_requirements.hpp" #include "asio/detail/non_const_lvalue.hpp"@@ -60,23 +62,20 @@ typename CompletionCondition> inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers, CompletionCondition completion_condition, asio::error_code& ec,- constraint_t<+ typename constraint< is_const_buffer_sequence<ConstBufferSequence>::value- >,- constraint_t<- is_completion_condition<CompletionCondition>::value- >)+ >::type) { return detail::write(s, buffers, asio::buffer_sequence_begin(buffers),- static_cast<CompletionCondition&&>(completion_condition), ec);+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec); } template <typename SyncWriteStream, typename ConstBufferSequence> inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers,- constraint_t<+ typename constraint< is_const_buffer_sequence<ConstBufferSequence>::value- >)+ >::type) { asio::error_code ec; std::size_t bytes_transferred = write(s, buffers, transfer_all(), ec);@@ -87,9 +86,9 @@ template <typename SyncWriteStream, typename ConstBufferSequence> inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers, asio::error_code& ec,- constraint_t<+ typename constraint< is_const_buffer_sequence<ConstBufferSequence>::value- >)+ >::type) { return write(s, buffers, transfer_all(), ec); }@@ -98,16 +97,13 @@ typename CompletionCondition> inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers, CompletionCondition completion_condition,- constraint_t<+ typename constraint< is_const_buffer_sequence<ConstBufferSequence>::value- >,- constraint_t<- is_completion_condition<CompletionCondition>::value- >)+ >::type) { asio::error_code ec; std::size_t bytes_transferred = write(s, buffers,- static_cast<CompletionCondition&&>(completion_condition), ec);+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec); asio::detail::throw_error(ec, "write"); return bytes_transferred; }@@ -117,40 +113,37 @@ template <typename SyncWriteStream, typename DynamicBuffer_v1, typename CompletionCondition> std::size_t write(SyncWriteStream& s,- DynamicBuffer_v1&& buffers,+ ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, CompletionCondition completion_condition, asio::error_code& ec,- constraint_t<- is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value- >,- constraint_t<- !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value- >,- constraint_t<- is_completion_condition<CompletionCondition>::value- >)+ typename constraint<+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+ >::type,+ typename constraint<+ !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+ >::type) {- decay_t<DynamicBuffer_v1> b(- static_cast<DynamicBuffer_v1&&>(buffers));+ typename decay<DynamicBuffer_v1>::type b(+ ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers)); std::size_t bytes_transferred = write(s, b.data(),- static_cast<CompletionCondition&&>(completion_condition), ec);+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec); b.consume(bytes_transferred); return bytes_transferred; } template <typename SyncWriteStream, typename DynamicBuffer_v1> inline std::size_t write(SyncWriteStream& s,- DynamicBuffer_v1&& buffers,- constraint_t<- is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value- >,- constraint_t<- !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value- >)+ ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+ typename constraint<+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+ >::type,+ typename constraint<+ !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+ >::type) { asio::error_code ec; std::size_t bytes_transferred = write(s,- static_cast<DynamicBuffer_v1&&>(buffers),+ ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), transfer_all(), ec); asio::detail::throw_error(ec, "write"); return bytes_transferred;@@ -158,38 +151,35 @@ template <typename SyncWriteStream, typename DynamicBuffer_v1> inline std::size_t write(SyncWriteStream& s,- DynamicBuffer_v1&& buffers,+ ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, asio::error_code& ec,- constraint_t<- is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value- >,- constraint_t<- !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value- >)+ typename constraint<+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+ >::type,+ typename constraint<+ !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+ >::type) {- return write(s, static_cast<DynamicBuffer_v1&&>(buffers),+ return write(s, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), transfer_all(), ec); } template <typename SyncWriteStream, typename DynamicBuffer_v1, typename CompletionCondition> inline std::size_t write(SyncWriteStream& s,- DynamicBuffer_v1&& buffers,+ ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, CompletionCondition completion_condition,- constraint_t<- is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value- >,- constraint_t<- !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value- >,- constraint_t<- is_completion_condition<CompletionCondition>::value- >)+ typename constraint<+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+ >::type,+ typename constraint<+ !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+ >::type) { asio::error_code ec; std::size_t bytes_transferred = write(s,- static_cast<DynamicBuffer_v1&&>(buffers),- static_cast<CompletionCondition&&>(completion_condition), ec);+ ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec); asio::detail::throw_error(ec, "write"); return bytes_transferred; }@@ -201,13 +191,10 @@ typename CompletionCondition> inline std::size_t write(SyncWriteStream& s, asio::basic_streambuf<Allocator>& b,- CompletionCondition completion_condition, asio::error_code& ec,- constraint_t<- is_completion_condition<CompletionCondition>::value- >)+ CompletionCondition completion_condition, asio::error_code& ec) { return write(s, basic_streambuf_ref<Allocator>(b),- static_cast<CompletionCondition&&>(completion_condition), ec);+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec); } template <typename SyncWriteStream, typename Allocator>@@ -229,13 +216,10 @@ typename CompletionCondition> inline std::size_t write(SyncWriteStream& s, asio::basic_streambuf<Allocator>& b,- CompletionCondition completion_condition,- constraint_t<- is_completion_condition<CompletionCondition>::value- >)+ CompletionCondition completion_condition) { return write(s, basic_streambuf_ref<Allocator>(b),- static_cast<CompletionCondition&&>(completion_condition));+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition)); } #endif // !defined(ASIO_NO_IOSTREAM)@@ -246,28 +230,25 @@ typename CompletionCondition> std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers, CompletionCondition completion_condition, asio::error_code& ec,- constraint_t<+ typename constraint< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- >,- constraint_t<- is_completion_condition<CompletionCondition>::value- >)+ >::type) { std::size_t bytes_transferred = write(s, buffers.data(0, buffers.size()),- static_cast<CompletionCondition&&>(completion_condition), ec);+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec); buffers.consume(bytes_transferred); return bytes_transferred; } template <typename SyncWriteStream, typename DynamicBuffer_v2> inline std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers,- constraint_t<+ typename constraint< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- >)+ >::type) { asio::error_code ec; std::size_t bytes_transferred = write(s,- static_cast<DynamicBuffer_v2&&>(buffers),+ ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), transfer_all(), ec); asio::detail::throw_error(ec, "write"); return bytes_transferred;@@ -276,11 +257,11 @@ template <typename SyncWriteStream, typename DynamicBuffer_v2> inline std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers, asio::error_code& ec,- constraint_t<+ typename constraint< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- >)+ >::type) {- return write(s, static_cast<DynamicBuffer_v2&&>(buffers),+ return write(s, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), transfer_all(), ec); } @@ -288,17 +269,14 @@ typename CompletionCondition> inline std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers, CompletionCondition completion_condition,- constraint_t<+ typename constraint< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- >,- constraint_t<- is_completion_condition<CompletionCondition>::value- >)+ >::type) { asio::error_code ec; std::size_t bytes_transferred = write(s,- static_cast<DynamicBuffer_v2&&>(buffers),- static_cast<CompletionCondition&&>(completion_condition), ec);+ ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec); asio::detail::throw_error(ec, "write"); return bytes_transferred; }@@ -321,10 +299,11 @@ stream_(stream), buffers_(buffers), start_(0),- handler_(static_cast<WriteHandler&&>(handler))+ handler_(ASIO_MOVE_CAST(WriteHandler)(handler)) { } +#if defined(ASIO_HAS_MOVE) write_op(const write_op& other) : base_from_cancellation_state<WriteHandler>(other), base_from_completion_cond<CompletionCondition>(other),@@ -337,15 +316,18 @@ write_op(write_op&& other) : base_from_cancellation_state<WriteHandler>(- static_cast<base_from_cancellation_state<WriteHandler>&&>(other)),+ ASIO_MOVE_CAST(base_from_cancellation_state<+ WriteHandler>)(other)), base_from_completion_cond<CompletionCondition>(- static_cast<base_from_completion_cond<CompletionCondition>&&>(other)),+ ASIO_MOVE_CAST(base_from_completion_cond<+ CompletionCondition>)(other)), stream_(other.stream_),- buffers_(static_cast<buffers_type&&>(other.buffers_)),+ buffers_(ASIO_MOVE_CAST(buffers_type)(other.buffers_)), start_(other.start_),- handler_(static_cast<WriteHandler&&>(other.handler_))+ handler_(ASIO_MOVE_CAST(WriteHandler)(other.handler_)) { }+#endif // defined(ASIO_HAS_MOVE) void operator()(asio::error_code ec, std::size_t bytes_transferred, int start = 0)@@ -360,7 +342,7 @@ { ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_write")); stream_.async_write_some(buffers_.prepare(max_size),- static_cast<write_op&&>(*this));+ ASIO_MOVE_CAST(write_op)(*this)); } return; default: buffers_.consume(bytes_transferred);@@ -376,7 +358,7 @@ } } - static_cast<WriteHandler&&>(handler_)(+ ASIO_MOVE_OR_LVALUE(WriteHandler)(handler_)( static_cast<const asio::error_code&>(ec), static_cast<const std::size_t&>(buffers_.total_consumed())); }@@ -395,6 +377,38 @@ template <typename AsyncWriteStream, typename ConstBufferSequence, typename ConstBufferIterator, typename CompletionCondition, typename WriteHandler>+ inline asio_handler_allocate_is_deprecated+ asio_handler_allocate(std::size_t size,+ write_op<AsyncWriteStream, ConstBufferSequence, ConstBufferIterator,+ CompletionCondition, WriteHandler>* this_handler)+ {+#if defined(ASIO_NO_DEPRECATED)+ asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+ return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+ return asio_handler_alloc_helpers::allocate(+ size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename AsyncWriteStream, typename ConstBufferSequence,+ typename ConstBufferIterator, typename CompletionCondition,+ typename WriteHandler>+ inline asio_handler_deallocate_is_deprecated+ asio_handler_deallocate(void* pointer, std::size_t size,+ write_op<AsyncWriteStream, ConstBufferSequence, ConstBufferIterator,+ CompletionCondition, WriteHandler>* this_handler)+ {+ asio_handler_alloc_helpers::deallocate(+ pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename AsyncWriteStream, typename ConstBufferSequence,+ typename ConstBufferIterator, typename CompletionCondition,+ typename WriteHandler> inline bool asio_handler_is_continuation( write_op<AsyncWriteStream, ConstBufferSequence, ConstBufferIterator, CompletionCondition, WriteHandler>* this_handler)@@ -404,6 +418,36 @@ this_handler->handler_); } + template <typename Function, typename AsyncWriteStream,+ typename ConstBufferSequence, typename ConstBufferIterator,+ typename CompletionCondition, typename WriteHandler>+ inline asio_handler_invoke_is_deprecated+ asio_handler_invoke(Function& function,+ write_op<AsyncWriteStream, ConstBufferSequence, ConstBufferIterator,+ CompletionCondition, WriteHandler>* this_handler)+ {+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename Function, typename AsyncWriteStream,+ typename ConstBufferSequence, typename ConstBufferIterator,+ typename CompletionCondition, typename WriteHandler>+ inline asio_handler_invoke_is_deprecated+ asio_handler_invoke(const Function& function,+ write_op<AsyncWriteStream, ConstBufferSequence, ConstBufferIterator,+ CompletionCondition, WriteHandler>* this_handler)+ {+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }+ template <typename AsyncWriteStream, typename ConstBufferSequence, typename ConstBufferIterator, typename CompletionCondition, typename WriteHandler>@@ -428,16 +472,16 @@ { } - executor_type get_executor() const noexcept+ executor_type get_executor() const ASIO_NOEXCEPT { return stream_.get_executor(); } template <typename WriteHandler, typename ConstBufferSequence, typename CompletionCondition>- void operator()(WriteHandler&& handler,+ void operator()(ASIO_MOVE_ARG(WriteHandler) handler, const ConstBufferSequence& buffers,- CompletionCondition&& completion_cond) const+ ASIO_MOVE_ARG(CompletionCondition) completion_cond) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a WriteHandler.@@ -467,18 +511,21 @@ DefaultCandidate> : Associator<WriteHandler, DefaultCandidate> {- static typename Associator<WriteHandler, DefaultCandidate>::type get(- const detail::write_op<AsyncWriteStream, ConstBufferSequence,- ConstBufferIterator, CompletionCondition, WriteHandler>& h) noexcept+ static typename Associator<WriteHandler, DefaultCandidate>::type+ get(const detail::write_op<AsyncWriteStream, ConstBufferSequence,+ ConstBufferIterator, CompletionCondition, WriteHandler>& h)+ ASIO_NOEXCEPT { return Associator<WriteHandler, DefaultCandidate>::get(h.handler_); } - static auto get(- const detail::write_op<AsyncWriteStream, ConstBufferSequence,+ static ASIO_AUTO_RETURN_TYPE_PREFIX2(+ typename Associator<WriteHandler, DefaultCandidate>::type)+ get(const detail::write_op<AsyncWriteStream, ConstBufferSequence, ConstBufferIterator, CompletionCondition, WriteHandler>& h,- const DefaultCandidate& c) noexcept- -> decltype(Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c))+ const DefaultCandidate& c) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c))) { return Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c); }@@ -486,6 +533,54 @@ #endif // !defined(GENERATING_DOCUMENTATION) +template <typename AsyncWriteStream,+ typename ConstBufferSequence, typename CompletionCondition,+ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+ std::size_t)) WriteToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+ void (asio::error_code, std::size_t))+async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers,+ CompletionCondition completion_condition,+ ASIO_MOVE_ARG(WriteToken) token,+ typename constraint<+ is_const_buffer_sequence<ConstBufferSequence>::value+ >::type)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_initiate<WriteToken,+ void (asio::error_code, std::size_t)>(+ declval<detail::initiate_async_write<AsyncWriteStream> >(),+ token, buffers,+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition))))+{+ return async_initiate<WriteToken,+ void (asio::error_code, std::size_t)>(+ detail::initiate_async_write<AsyncWriteStream>(s),+ token, buffers,+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition));+}++template <typename AsyncWriteStream, typename ConstBufferSequence,+ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+ std::size_t)) WriteToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+ void (asio::error_code, std::size_t))+async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers,+ ASIO_MOVE_ARG(WriteToken) token,+ typename constraint<+ is_const_buffer_sequence<ConstBufferSequence>::value+ >::type)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_initiate<WriteToken,+ void (asio::error_code, std::size_t)>(+ declval<detail::initiate_async_write<AsyncWriteStream> >(),+ token, buffers, transfer_all())))+{+ return async_initiate<WriteToken,+ void (asio::error_code, std::size_t)>(+ detail::initiate_async_write<AsyncWriteStream>(s),+ token, buffers, transfer_all());+}+ #if !defined(ASIO_NO_DYNAMIC_BUFFER_V1) namespace detail@@ -497,16 +592,17 @@ public: template <typename BufferSequence> write_dynbuf_v1_op(AsyncWriteStream& stream,- BufferSequence&& buffers,+ ASIO_MOVE_ARG(BufferSequence) buffers, CompletionCondition& completion_condition, WriteHandler& handler) : stream_(stream),- buffers_(static_cast<BufferSequence&&>(buffers)),+ buffers_(ASIO_MOVE_CAST(BufferSequence)(buffers)), completion_condition_(- static_cast<CompletionCondition&&>(completion_condition)),- handler_(static_cast<WriteHandler&&>(handler))+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition)),+ handler_(ASIO_MOVE_CAST(WriteHandler)(handler)) { } +#if defined(ASIO_HAS_MOVE) write_dynbuf_v1_op(const write_dynbuf_v1_op& other) : stream_(other.stream_), buffers_(other.buffers_),@@ -517,13 +613,14 @@ write_dynbuf_v1_op(write_dynbuf_v1_op&& other) : stream_(other.stream_),- buffers_(static_cast<DynamicBuffer_v1&&>(other.buffers_)),+ buffers_(ASIO_MOVE_CAST(DynamicBuffer_v1)(other.buffers_)), completion_condition_(- static_cast<CompletionCondition&&>(+ ASIO_MOVE_CAST(CompletionCondition)( other.completion_condition_)),- handler_(static_cast<WriteHandler&&>(other.handler_))+ handler_(ASIO_MOVE_CAST(WriteHandler)(other.handler_)) { }+#endif // defined(ASIO_HAS_MOVE) void operator()(const asio::error_code& ec, std::size_t bytes_transferred, int start = 0)@@ -532,11 +629,11 @@ { case 1: async_write(stream_, buffers_.data(),- static_cast<CompletionCondition&&>(completion_condition_),- static_cast<write_dynbuf_v1_op&&>(*this));+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition_),+ ASIO_MOVE_CAST(write_dynbuf_v1_op)(*this)); return; default: buffers_.consume(bytes_transferred);- static_cast<WriteHandler&&>(handler_)(ec,+ ASIO_MOVE_OR_LVALUE(WriteHandler)(handler_)(ec, static_cast<const std::size_t&>(bytes_transferred)); } }@@ -550,6 +647,36 @@ template <typename AsyncWriteStream, typename DynamicBuffer_v1, typename CompletionCondition, typename WriteHandler>+ inline asio_handler_allocate_is_deprecated+ asio_handler_allocate(std::size_t size,+ write_dynbuf_v1_op<AsyncWriteStream, DynamicBuffer_v1,+ CompletionCondition, WriteHandler>* this_handler)+ {+#if defined(ASIO_NO_DEPRECATED)+ asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+ return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+ return asio_handler_alloc_helpers::allocate(+ size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename AsyncWriteStream, typename DynamicBuffer_v1,+ typename CompletionCondition, typename WriteHandler>+ inline asio_handler_deallocate_is_deprecated+ asio_handler_deallocate(void* pointer, std::size_t size,+ write_dynbuf_v1_op<AsyncWriteStream, DynamicBuffer_v1,+ CompletionCondition, WriteHandler>* this_handler)+ {+ asio_handler_alloc_helpers::deallocate(+ pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename AsyncWriteStream, typename DynamicBuffer_v1,+ typename CompletionCondition, typename WriteHandler> inline bool asio_handler_is_continuation( write_dynbuf_v1_op<AsyncWriteStream, DynamicBuffer_v1, CompletionCondition, WriteHandler>* this_handler)@@ -558,6 +685,36 @@ this_handler->handler_); } + template <typename Function, typename AsyncWriteStream,+ typename DynamicBuffer_v1, typename CompletionCondition,+ typename WriteHandler>+ inline asio_handler_invoke_is_deprecated+ asio_handler_invoke(Function& function,+ write_dynbuf_v1_op<AsyncWriteStream, DynamicBuffer_v1,+ CompletionCondition, WriteHandler>* this_handler)+ {+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename Function, typename AsyncWriteStream,+ typename DynamicBuffer_v1, typename CompletionCondition,+ typename WriteHandler>+ inline asio_handler_invoke_is_deprecated+ asio_handler_invoke(const Function& function,+ write_dynbuf_v1_op<AsyncWriteStream, DynamicBuffer_v1,+ CompletionCondition, WriteHandler>* this_handler)+ {+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }+ template <typename AsyncWriteStream> class initiate_async_write_dynbuf_v1 {@@ -569,16 +726,16 @@ { } - executor_type get_executor() const noexcept+ executor_type get_executor() const ASIO_NOEXCEPT { return stream_.get_executor(); } template <typename WriteHandler, typename DynamicBuffer_v1, typename CompletionCondition>- void operator()(WriteHandler&& handler,- DynamicBuffer_v1&& buffers,- CompletionCondition&& completion_cond) const+ void operator()(ASIO_MOVE_ARG(WriteHandler) handler,+ ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+ ASIO_MOVE_ARG(CompletionCondition) completion_cond) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a WriteHandler.@@ -587,9 +744,9 @@ non_const_lvalue<WriteHandler> handler2(handler); non_const_lvalue<CompletionCondition> completion_cond2(completion_cond); write_dynbuf_v1_op<AsyncWriteStream,- decay_t<DynamicBuffer_v1>,- CompletionCondition, decay_t<WriteHandler>>(- stream_, static_cast<DynamicBuffer_v1&&>(buffers),+ typename decay<DynamicBuffer_v1>::type,+ CompletionCondition, typename decay<WriteHandler>::type>(+ stream_, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), completion_cond2.value, handler2.value)( asio::error_code(), 0, 1); }@@ -611,18 +768,20 @@ DefaultCandidate> : Associator<WriteHandler, DefaultCandidate> {- static typename Associator<WriteHandler, DefaultCandidate>::type get(- const detail::write_dynbuf_v1_op<AsyncWriteStream, DynamicBuffer_v1,- CompletionCondition, WriteHandler>& h) noexcept+ static typename Associator<WriteHandler, DefaultCandidate>::type+ get(const detail::write_dynbuf_v1_op<AsyncWriteStream, DynamicBuffer_v1,+ CompletionCondition, WriteHandler>& h) ASIO_NOEXCEPT { return Associator<WriteHandler, DefaultCandidate>::get(h.handler_); } - static auto get(- const detail::write_dynbuf_v1_op<AsyncWriteStream,+ static ASIO_AUTO_RETURN_TYPE_PREFIX2(+ typename Associator<WriteHandler, DefaultCandidate>::type)+ get(const detail::write_dynbuf_v1_op<AsyncWriteStream, DynamicBuffer_v1, CompletionCondition, WriteHandler>& h,- const DefaultCandidate& c) noexcept- -> decltype(Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c))+ const DefaultCandidate& c) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c))) { return Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c); }@@ -630,6 +789,105 @@ #endif // !defined(GENERATING_DOCUMENTATION) +template <typename AsyncWriteStream, typename DynamicBuffer_v1,+ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+ std::size_t)) WriteToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+ void (asio::error_code, std::size_t))+async_write(AsyncWriteStream& s,+ ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+ ASIO_MOVE_ARG(WriteToken) token,+ typename constraint<+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+ >::type,+ typename constraint<+ !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+ >::type)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_initiate<WriteToken,+ void (asio::error_code, std::size_t)>(+ declval<detail::initiate_async_write_dynbuf_v1<AsyncWriteStream> >(),+ token, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+ transfer_all())))+{+ return async_initiate<WriteToken,+ void (asio::error_code, std::size_t)>(+ detail::initiate_async_write_dynbuf_v1<AsyncWriteStream>(s),+ token, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+ transfer_all());+}++template <typename AsyncWriteStream,+ typename DynamicBuffer_v1, typename CompletionCondition,+ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+ std::size_t)) WriteToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+ void (asio::error_code, std::size_t))+async_write(AsyncWriteStream& s,+ ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+ CompletionCondition completion_condition,+ ASIO_MOVE_ARG(WriteToken) token,+ typename constraint<+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+ >::type,+ typename constraint<+ !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+ >::type)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_initiate<WriteToken,+ void (asio::error_code, std::size_t)>(+ declval<detail::initiate_async_write_dynbuf_v1<AsyncWriteStream> >(),+ token, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition))))+{+ return async_initiate<WriteToken,+ void (asio::error_code, std::size_t)>(+ detail::initiate_async_write_dynbuf_v1<AsyncWriteStream>(s),+ token, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition));+}++#if !defined(ASIO_NO_EXTENSIONS)+#if !defined(ASIO_NO_IOSTREAM)++template <typename AsyncWriteStream, typename Allocator,+ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+ std::size_t)) WriteToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+ void (asio::error_code, std::size_t))+async_write(AsyncWriteStream& s,+ asio::basic_streambuf<Allocator>& b,+ ASIO_MOVE_ARG(WriteToken) token)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_write(s, basic_streambuf_ref<Allocator>(b),+ ASIO_MOVE_CAST(WriteToken)(token))))+{+ return async_write(s, basic_streambuf_ref<Allocator>(b),+ ASIO_MOVE_CAST(WriteToken)(token));+}++template <typename AsyncWriteStream,+ typename Allocator, typename CompletionCondition,+ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+ std::size_t)) WriteToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+ void (asio::error_code, std::size_t))+async_write(AsyncWriteStream& s,+ asio::basic_streambuf<Allocator>& b,+ CompletionCondition completion_condition,+ ASIO_MOVE_ARG(WriteToken) token)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_write(s, basic_streambuf_ref<Allocator>(b),+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition),+ ASIO_MOVE_CAST(WriteToken)(token))))+{+ return async_write(s, basic_streambuf_ref<Allocator>(b),+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition),+ ASIO_MOVE_CAST(WriteToken)(token));+}++#endif // !defined(ASIO_NO_IOSTREAM)+#endif // !defined(ASIO_NO_EXTENSIONS) #endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1) namespace detail@@ -641,16 +899,17 @@ public: template <typename BufferSequence> write_dynbuf_v2_op(AsyncWriteStream& stream,- BufferSequence&& buffers,+ ASIO_MOVE_ARG(BufferSequence) buffers, CompletionCondition& completion_condition, WriteHandler& handler) : stream_(stream),- buffers_(static_cast<BufferSequence&&>(buffers)),+ buffers_(ASIO_MOVE_CAST(BufferSequence)(buffers)), completion_condition_(- static_cast<CompletionCondition&&>(completion_condition)),- handler_(static_cast<WriteHandler&&>(handler))+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition)),+ handler_(ASIO_MOVE_CAST(WriteHandler)(handler)) { } +#if defined(ASIO_HAS_MOVE) write_dynbuf_v2_op(const write_dynbuf_v2_op& other) : stream_(other.stream_), buffers_(other.buffers_),@@ -661,13 +920,14 @@ write_dynbuf_v2_op(write_dynbuf_v2_op&& other) : stream_(other.stream_),- buffers_(static_cast<DynamicBuffer_v2&&>(other.buffers_)),+ buffers_(ASIO_MOVE_CAST(DynamicBuffer_v2)(other.buffers_)), completion_condition_(- static_cast<CompletionCondition&&>(+ ASIO_MOVE_CAST(CompletionCondition)( other.completion_condition_)),- handler_(static_cast<WriteHandler&&>(other.handler_))+ handler_(ASIO_MOVE_CAST(WriteHandler)(other.handler_)) { }+#endif // defined(ASIO_HAS_MOVE) void operator()(const asio::error_code& ec, std::size_t bytes_transferred, int start = 0)@@ -676,11 +936,11 @@ { case 1: async_write(stream_, buffers_.data(0, buffers_.size()),- static_cast<CompletionCondition&&>(completion_condition_),- static_cast<write_dynbuf_v2_op&&>(*this));+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition_),+ ASIO_MOVE_CAST(write_dynbuf_v2_op)(*this)); return; default: buffers_.consume(bytes_transferred);- static_cast<WriteHandler&&>(handler_)(ec,+ ASIO_MOVE_OR_LVALUE(WriteHandler)(handler_)(ec, static_cast<const std::size_t&>(bytes_transferred)); } }@@ -694,6 +954,36 @@ template <typename AsyncWriteStream, typename DynamicBuffer_v2, typename CompletionCondition, typename WriteHandler>+ inline asio_handler_allocate_is_deprecated+ asio_handler_allocate(std::size_t size,+ write_dynbuf_v2_op<AsyncWriteStream, DynamicBuffer_v2,+ CompletionCondition, WriteHandler>* this_handler)+ {+#if defined(ASIO_NO_DEPRECATED)+ asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+ return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+ return asio_handler_alloc_helpers::allocate(+ size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename AsyncWriteStream, typename DynamicBuffer_v2,+ typename CompletionCondition, typename WriteHandler>+ inline asio_handler_deallocate_is_deprecated+ asio_handler_deallocate(void* pointer, std::size_t size,+ write_dynbuf_v2_op<AsyncWriteStream, DynamicBuffer_v2,+ CompletionCondition, WriteHandler>* this_handler)+ {+ asio_handler_alloc_helpers::deallocate(+ pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename AsyncWriteStream, typename DynamicBuffer_v2,+ typename CompletionCondition, typename WriteHandler> inline bool asio_handler_is_continuation( write_dynbuf_v2_op<AsyncWriteStream, DynamicBuffer_v2, CompletionCondition, WriteHandler>* this_handler)@@ -702,6 +992,36 @@ this_handler->handler_); } + template <typename Function, typename AsyncWriteStream,+ typename DynamicBuffer_v2, typename CompletionCondition,+ typename WriteHandler>+ inline asio_handler_invoke_is_deprecated+ asio_handler_invoke(Function& function,+ write_dynbuf_v2_op<AsyncWriteStream, DynamicBuffer_v2,+ CompletionCondition, WriteHandler>* this_handler)+ {+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename Function, typename AsyncWriteStream,+ typename DynamicBuffer_v2, typename CompletionCondition,+ typename WriteHandler>+ inline asio_handler_invoke_is_deprecated+ asio_handler_invoke(const Function& function,+ write_dynbuf_v2_op<AsyncWriteStream, DynamicBuffer_v2,+ CompletionCondition, WriteHandler>* this_handler)+ {+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }+ template <typename AsyncWriteStream> class initiate_async_write_dynbuf_v2 {@@ -713,16 +1033,16 @@ { } - executor_type get_executor() const noexcept+ executor_type get_executor() const ASIO_NOEXCEPT { return stream_.get_executor(); } template <typename WriteHandler, typename DynamicBuffer_v2, typename CompletionCondition>- void operator()(WriteHandler&& handler,- DynamicBuffer_v2&& buffers,- CompletionCondition&& completion_cond) const+ void operator()(ASIO_MOVE_ARG(WriteHandler) handler,+ ASIO_MOVE_ARG(DynamicBuffer_v2) buffers,+ ASIO_MOVE_ARG(CompletionCondition) completion_cond) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a WriteHandler.@@ -730,11 +1050,12 @@ non_const_lvalue<WriteHandler> handler2(handler); non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);- write_dynbuf_v2_op<AsyncWriteStream, decay_t<DynamicBuffer_v2>,- CompletionCondition, decay_t<WriteHandler>>(- stream_, static_cast<DynamicBuffer_v2&&>(buffers),- completion_cond2.value, handler2.value)(- asio::error_code(), 0, 1);+ write_dynbuf_v2_op<AsyncWriteStream,+ typename decay<DynamicBuffer_v2>::type,+ CompletionCondition, typename decay<WriteHandler>::type>(+ stream_, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+ completion_cond2.value, handler2.value)(+ asio::error_code(), 0, 1); } private:@@ -754,24 +1075,76 @@ DefaultCandidate> : Associator<WriteHandler, DefaultCandidate> {- static typename Associator<WriteHandler, DefaultCandidate>::type get(- const detail::write_dynbuf_v2_op<AsyncWriteStream, DynamicBuffer_v2,- CompletionCondition, WriteHandler>& h) noexcept+ static typename Associator<WriteHandler, DefaultCandidate>::type+ get(const detail::write_dynbuf_v2_op<AsyncWriteStream, DynamicBuffer_v2,+ CompletionCondition, WriteHandler>& h) ASIO_NOEXCEPT { return Associator<WriteHandler, DefaultCandidate>::get(h.handler_); } - static auto get(- const detail::write_dynbuf_v2_op<AsyncWriteStream,+ static ASIO_AUTO_RETURN_TYPE_PREFIX2(+ typename Associator<WriteHandler, DefaultCandidate>::type)+ get(const detail::write_dynbuf_v2_op<AsyncWriteStream, DynamicBuffer_v2, CompletionCondition, WriteHandler>& h,- const DefaultCandidate& c) noexcept- -> decltype(Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c))+ const DefaultCandidate& c) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c))) { return Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c); } }; #endif // !defined(GENERATING_DOCUMENTATION)++template <typename AsyncWriteStream, typename DynamicBuffer_v2,+ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+ std::size_t)) WriteToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+ void (asio::error_code, std::size_t))+async_write(AsyncWriteStream& s, DynamicBuffer_v2 buffers,+ ASIO_MOVE_ARG(WriteToken) token,+ typename constraint<+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value+ >::type)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_initiate<WriteToken,+ void (asio::error_code, std::size_t)>(+ declval<detail::initiate_async_write_dynbuf_v2<AsyncWriteStream> >(),+ token, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+ transfer_all())))+{+ return async_initiate<WriteToken,+ void (asio::error_code, std::size_t)>(+ detail::initiate_async_write_dynbuf_v2<AsyncWriteStream>(s),+ token, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+ transfer_all());+}++template <typename AsyncWriteStream,+ typename DynamicBuffer_v2, typename CompletionCondition,+ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+ std::size_t)) WriteToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+ void (asio::error_code, std::size_t))+async_write(AsyncWriteStream& s, DynamicBuffer_v2 buffers,+ CompletionCondition completion_condition,+ ASIO_MOVE_ARG(WriteToken) token,+ typename constraint<+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value+ >::type)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_initiate<WriteToken,+ void (asio::error_code, std::size_t)>(+ declval<detail::initiate_async_write_dynbuf_v2<AsyncWriteStream> >(),+ token, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition))))+{+ return async_initiate<WriteToken,+ void (asio::error_code, std::size_t)>(+ detail::initiate_async_write_dynbuf_v2<AsyncWriteStream>(s),+ token, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition));+} } // namespace asio
link/modules/asio-standalone/asio/include/asio/impl/write_at.hpp view
@@ -2,7 +2,7 @@ // impl/write_at.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -23,7 +23,9 @@ #include "asio/detail/bind_handler.hpp" #include "asio/detail/consuming_buffers.hpp" #include "asio/detail/dependent_type.hpp"+#include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_cont_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_tracking.hpp" #include "asio/detail/handler_type_requirements.hpp" #include "asio/detail/non_const_lvalue.hpp"@@ -64,14 +66,11 @@ typename CompletionCondition> std::size_t write_at(SyncRandomAccessWriteDevice& d, uint64_t offset, const ConstBufferSequence& buffers,- CompletionCondition completion_condition, asio::error_code& ec,- constraint_t<- is_completion_condition<CompletionCondition>::value- >)+ CompletionCondition completion_condition, asio::error_code& ec) { return detail::write_at_buffer_sequence(d, offset, buffers, asio::buffer_sequence_begin(buffers),- static_cast<CompletionCondition&&>(completion_condition), ec);+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec); } template <typename SyncRandomAccessWriteDevice, typename ConstBufferSequence>@@ -97,14 +96,11 @@ typename CompletionCondition> inline std::size_t write_at(SyncRandomAccessWriteDevice& d, uint64_t offset, const ConstBufferSequence& buffers,- CompletionCondition completion_condition,- constraint_t<- is_completion_condition<CompletionCondition>::value- >)+ CompletionCondition completion_condition) { asio::error_code ec; std::size_t bytes_transferred = write_at(d, offset, buffers,- static_cast<CompletionCondition&&>(completion_condition), ec);+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec); asio::detail::throw_error(ec, "write_at"); return bytes_transferred; }@@ -116,13 +112,10 @@ typename CompletionCondition> std::size_t write_at(SyncRandomAccessWriteDevice& d, uint64_t offset, asio::basic_streambuf<Allocator>& b,- CompletionCondition completion_condition, asio::error_code& ec,- constraint_t<- is_completion_condition<CompletionCondition>::value- >)+ CompletionCondition completion_condition, asio::error_code& ec) { std::size_t bytes_transferred = write_at(d, offset, b.data(),- static_cast<CompletionCondition&&>(completion_condition), ec);+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec); b.consume(bytes_transferred); return bytes_transferred; }@@ -149,14 +142,11 @@ typename CompletionCondition> inline std::size_t write_at(SyncRandomAccessWriteDevice& d, uint64_t offset, asio::basic_streambuf<Allocator>& b,- CompletionCondition completion_condition,- constraint_t<- is_completion_condition<CompletionCondition>::value- >)+ CompletionCondition completion_condition) { asio::error_code ec; std::size_t bytes_transferred = write_at(d, offset, b,- static_cast<CompletionCondition&&>(completion_condition), ec);+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec); asio::detail::throw_error(ec, "write_at"); return bytes_transferred; }@@ -184,10 +174,11 @@ offset_(offset), buffers_(buffers), start_(0),- handler_(static_cast<WriteHandler&&>(handler))+ handler_(ASIO_MOVE_CAST(WriteHandler)(handler)) { } +#if defined(ASIO_HAS_MOVE) write_at_op(const write_at_op& other) : base_from_cancellation_state<WriteHandler>(other), base_from_completion_cond<CompletionCondition>(other),@@ -201,16 +192,19 @@ write_at_op(write_at_op&& other) : base_from_cancellation_state<WriteHandler>(- static_cast<base_from_cancellation_state<WriteHandler>&&>(other)),+ ASIO_MOVE_CAST(base_from_cancellation_state<+ WriteHandler>)(other)), base_from_completion_cond<CompletionCondition>(- static_cast<base_from_completion_cond<CompletionCondition>&&>(other)),+ ASIO_MOVE_CAST(base_from_completion_cond<+ CompletionCondition>)(other)), device_(other.device_), offset_(other.offset_),- buffers_(static_cast<buffers_type&&>(other.buffers_)),+ buffers_(ASIO_MOVE_CAST(buffers_type)(other.buffers_)), start_(other.start_),- handler_(static_cast<WriteHandler&&>(other.handler_))+ handler_(ASIO_MOVE_CAST(WriteHandler)(other.handler_)) { }+#endif // defined(ASIO_HAS_MOVE) void operator()(asio::error_code ec, std::size_t bytes_transferred, int start = 0)@@ -226,7 +220,7 @@ ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_write_at")); device_.async_write_some_at( offset_ + buffers_.total_consumed(), buffers_.prepare(max_size),- static_cast<write_at_op&&>(*this));+ ASIO_MOVE_CAST(write_at_op)(*this)); } return; default: buffers_.consume(bytes_transferred);@@ -242,7 +236,7 @@ } } - static_cast<WriteHandler&&>(handler_)(+ ASIO_MOVE_OR_LVALUE(WriteHandler)(handler_)( static_cast<const asio::error_code&>(ec), static_cast<const std::size_t&>(buffers_.total_consumed())); }@@ -262,6 +256,38 @@ template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence, typename ConstBufferIterator, typename CompletionCondition, typename WriteHandler>+ inline asio_handler_allocate_is_deprecated+ asio_handler_allocate(std::size_t size,+ write_at_op<AsyncRandomAccessWriteDevice, ConstBufferSequence,+ ConstBufferIterator, CompletionCondition, WriteHandler>* this_handler)+ {+#if defined(ASIO_NO_DEPRECATED)+ asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+ return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+ return asio_handler_alloc_helpers::allocate(+ size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename AsyncRandomAccessWriteDevice,+ typename ConstBufferSequence, typename ConstBufferIterator,+ typename CompletionCondition, typename WriteHandler>+ inline asio_handler_deallocate_is_deprecated+ asio_handler_deallocate(void* pointer, std::size_t size,+ write_at_op<AsyncRandomAccessWriteDevice, ConstBufferSequence,+ ConstBufferIterator, CompletionCondition, WriteHandler>* this_handler)+ {+ asio_handler_alloc_helpers::deallocate(+ pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename AsyncRandomAccessWriteDevice,+ typename ConstBufferSequence, typename ConstBufferIterator,+ typename CompletionCondition, typename WriteHandler> inline bool asio_handler_is_continuation( write_at_op<AsyncRandomAccessWriteDevice, ConstBufferSequence, ConstBufferIterator, CompletionCondition, WriteHandler>* this_handler)@@ -271,6 +297,36 @@ this_handler->handler_); } + template <typename Function, typename AsyncRandomAccessWriteDevice,+ typename ConstBufferSequence, typename ConstBufferIterator,+ typename CompletionCondition, typename WriteHandler>+ inline asio_handler_invoke_is_deprecated+ asio_handler_invoke(Function& function,+ write_at_op<AsyncRandomAccessWriteDevice, ConstBufferSequence,+ ConstBufferIterator, CompletionCondition, WriteHandler>* this_handler)+ {+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename Function, typename AsyncRandomAccessWriteDevice,+ typename ConstBufferSequence, typename ConstBufferIterator,+ typename CompletionCondition, typename WriteHandler>+ inline asio_handler_invoke_is_deprecated+ asio_handler_invoke(const Function& function,+ write_at_op<AsyncRandomAccessWriteDevice, ConstBufferSequence,+ ConstBufferIterator, CompletionCondition, WriteHandler>* this_handler)+ {+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }+ template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence, typename ConstBufferIterator, typename CompletionCondition, typename WriteHandler>@@ -296,16 +352,16 @@ { } - executor_type get_executor() const noexcept+ executor_type get_executor() const ASIO_NOEXCEPT { return device_.get_executor(); } template <typename WriteHandler, typename ConstBufferSequence, typename CompletionCondition>- void operator()(WriteHandler&& handler,+ void operator()(ASIO_MOVE_ARG(WriteHandler) handler, uint64_t offset, const ConstBufferSequence& buffers,- CompletionCondition&& completion_cond) const+ ASIO_MOVE_ARG(CompletionCondition) completion_cond) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a WriteHandler.@@ -335,20 +391,22 @@ DefaultCandidate> : Associator<WriteHandler, DefaultCandidate> {- static typename Associator<WriteHandler, DefaultCandidate>::type get(- const detail::write_at_op<AsyncRandomAccessWriteDevice,+ static typename Associator<WriteHandler, DefaultCandidate>::type+ get(const detail::write_at_op<AsyncRandomAccessWriteDevice, ConstBufferSequence, ConstBufferIterator,- CompletionCondition, WriteHandler>& h) noexcept+ CompletionCondition, WriteHandler>& h) ASIO_NOEXCEPT { return Associator<WriteHandler, DefaultCandidate>::get(h.handler_); } - static auto get(- const detail::write_at_op<AsyncRandomAccessWriteDevice,+ static ASIO_AUTO_RETURN_TYPE_PREFIX2(+ typename Associator<WriteHandler, DefaultCandidate>::type)+ get(const detail::write_at_op<AsyncRandomAccessWriteDevice, ConstBufferSequence, ConstBufferIterator, CompletionCondition, WriteHandler>& h,- const DefaultCandidate& c) noexcept- -> decltype(Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c))+ const DefaultCandidate& c) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c))) { return Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c); }@@ -356,6 +414,52 @@ #endif // !defined(GENERATING_DOCUMENTATION) +template <typename AsyncRandomAccessWriteDevice,+ typename ConstBufferSequence, typename CompletionCondition,+ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+ std::size_t)) WriteToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+ void (asio::error_code, std::size_t))+async_write_at(AsyncRandomAccessWriteDevice& d,+ uint64_t offset, const ConstBufferSequence& buffers,+ CompletionCondition completion_condition,+ ASIO_MOVE_ARG(WriteToken) token)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_initiate<WriteToken,+ void (asio::error_code, std::size_t)>(+ declval<detail::initiate_async_write_at<+ AsyncRandomAccessWriteDevice> >(),+ token, offset, buffers,+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition))))+{+ return async_initiate<WriteToken,+ void (asio::error_code, std::size_t)>(+ detail::initiate_async_write_at<AsyncRandomAccessWriteDevice>(d),+ token, offset, buffers,+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition));+}++template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence,+ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+ std::size_t)) WriteToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+ void (asio::error_code, std::size_t))+async_write_at(AsyncRandomAccessWriteDevice& d,+ uint64_t offset, const ConstBufferSequence& buffers,+ ASIO_MOVE_ARG(WriteToken) token)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_initiate<WriteToken,+ void (asio::error_code, std::size_t)>(+ declval<detail::initiate_async_write_at<+ AsyncRandomAccessWriteDevice> >(),+ token, offset, buffers, transfer_all())))+{+ return async_initiate<WriteToken,+ void (asio::error_code, std::size_t)>(+ detail::initiate_async_write_at<AsyncRandomAccessWriteDevice>(d),+ token, offset, buffers, transfer_all());+}+ #if !defined(ASIO_NO_EXTENSIONS) #if !defined(ASIO_NO_IOSTREAM) @@ -369,10 +473,11 @@ asio::basic_streambuf<Allocator>& streambuf, WriteHandler& handler) : streambuf_(streambuf),- handler_(static_cast<WriteHandler&&>(handler))+ handler_(ASIO_MOVE_CAST(WriteHandler)(handler)) { } +#if defined(ASIO_HAS_MOVE) write_at_streambuf_op(const write_at_streambuf_op& other) : streambuf_(other.streambuf_), handler_(other.handler_)@@ -381,15 +486,16 @@ write_at_streambuf_op(write_at_streambuf_op&& other) : streambuf_(other.streambuf_),- handler_(static_cast<WriteHandler&&>(other.handler_))+ handler_(ASIO_MOVE_CAST(WriteHandler)(other.handler_)) { }+#endif // defined(ASIO_HAS_MOVE) void operator()(const asio::error_code& ec, const std::size_t bytes_transferred) { streambuf_.consume(bytes_transferred);- static_cast<WriteHandler&&>(handler_)(ec, bytes_transferred);+ ASIO_MOVE_OR_LVALUE(WriteHandler)(handler_)(ec, bytes_transferred); } //private:@@ -398,6 +504,32 @@ }; template <typename Allocator, typename WriteHandler>+ inline asio_handler_allocate_is_deprecated+ asio_handler_allocate(std::size_t size,+ write_at_streambuf_op<Allocator, WriteHandler>* this_handler)+ {+#if defined(ASIO_NO_DEPRECATED)+ asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+ return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+ return asio_handler_alloc_helpers::allocate(+ size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename Allocator, typename WriteHandler>+ inline asio_handler_deallocate_is_deprecated+ asio_handler_deallocate(void* pointer, std::size_t size,+ write_at_streambuf_op<Allocator, WriteHandler>* this_handler)+ {+ asio_handler_alloc_helpers::deallocate(+ pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename Allocator, typename WriteHandler> inline bool asio_handler_is_continuation( write_at_streambuf_op<Allocator, WriteHandler>* this_handler) {@@ -405,6 +537,30 @@ this_handler->handler_); } + template <typename Function, typename Allocator, typename WriteHandler>+ inline asio_handler_invoke_is_deprecated+ asio_handler_invoke(Function& function,+ write_at_streambuf_op<Allocator, WriteHandler>* this_handler)+ {+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }++ template <typename Function, typename Allocator, typename WriteHandler>+ inline asio_handler_invoke_is_deprecated+ asio_handler_invoke(const Function& function,+ write_at_streambuf_op<Allocator, WriteHandler>* this_handler)+ {+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+ }+ template <typename AsyncRandomAccessWriteDevice> class initiate_async_write_at_streambuf {@@ -417,16 +573,16 @@ { } - executor_type get_executor() const noexcept+ executor_type get_executor() const ASIO_NOEXCEPT { return device_.get_executor(); } template <typename WriteHandler, typename Allocator, typename CompletionCondition>- void operator()(WriteHandler&& handler,+ void operator()(ASIO_MOVE_ARG(WriteHandler) handler, uint64_t offset, basic_streambuf<Allocator>* b,- CompletionCondition&& completion_condition) const+ ASIO_MOVE_ARG(CompletionCondition) completion_condition) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a WriteHandler.@@ -434,8 +590,8 @@ non_const_lvalue<WriteHandler> handler2(handler); async_write_at(device_, offset, b->data(),- static_cast<CompletionCondition&&>(completion_condition),- write_at_streambuf_op<Allocator, decay_t<WriteHandler>>(+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition),+ write_at_streambuf_op<Allocator, typename decay<WriteHandler>::type>( *b, handler2.value)); } @@ -453,22 +609,73 @@ DefaultCandidate> : Associator<WriteHandler, DefaultCandidate> {- static typename Associator<WriteHandler, DefaultCandidate>::type get(- const detail::write_at_streambuf_op<Executor, WriteHandler>& h) noexcept+ static typename Associator<WriteHandler, DefaultCandidate>::type+ get(const detail::write_at_streambuf_op<Executor, WriteHandler>& h)+ ASIO_NOEXCEPT { return Associator<WriteHandler, DefaultCandidate>::get(h.handler_); } - static auto get(- const detail::write_at_streambuf_op<Executor, WriteHandler>& h,- const DefaultCandidate& c) noexcept- -> decltype(Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c))+ static ASIO_AUTO_RETURN_TYPE_PREFIX2(+ typename Associator<WriteHandler, DefaultCandidate>::type)+ get(const detail::write_at_streambuf_op<Executor, WriteHandler>& h,+ const DefaultCandidate& c) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c))) { return Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c); } }; #endif // !defined(GENERATING_DOCUMENTATION)++template <typename AsyncRandomAccessWriteDevice,+ typename Allocator, typename CompletionCondition,+ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+ std::size_t)) WriteToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+ void (asio::error_code, std::size_t))+async_write_at(AsyncRandomAccessWriteDevice& d,+ uint64_t offset, asio::basic_streambuf<Allocator>& b,+ CompletionCondition completion_condition,+ ASIO_MOVE_ARG(WriteToken) token)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_initiate<WriteToken,+ void (asio::error_code, std::size_t)>(+ declval<detail::initiate_async_write_at_streambuf<+ AsyncRandomAccessWriteDevice> >(),+ token, offset, &b,+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition))))+{+ return async_initiate<WriteToken,+ void (asio::error_code, std::size_t)>(+ detail::initiate_async_write_at_streambuf<+ AsyncRandomAccessWriteDevice>(d),+ token, offset, &b,+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition));+}++template <typename AsyncRandomAccessWriteDevice, typename Allocator,+ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+ std::size_t)) WriteToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+ void (asio::error_code, std::size_t))+async_write_at(AsyncRandomAccessWriteDevice& d,+ uint64_t offset, asio::basic_streambuf<Allocator>& b,+ ASIO_MOVE_ARG(WriteToken) token)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_initiate<WriteToken,+ void (asio::error_code, std::size_t)>(+ declval<detail::initiate_async_write_at_streambuf<+ AsyncRandomAccessWriteDevice> >(),+ token, offset, &b, transfer_all())))+{+ return async_initiate<WriteToken,+ void (asio::error_code, std::size_t)>(+ detail::initiate_async_write_at_streambuf<+ AsyncRandomAccessWriteDevice>(d),+ token, offset, &b, transfer_all());+} #endif // !defined(ASIO_NO_IOSTREAM) #endif // !defined(ASIO_NO_EXTENSIONS)
link/modules/asio-standalone/asio/include/asio/io_context.hpp view
@@ -2,7 +2,7 @@ // io_context.hpp // ~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -20,7 +20,6 @@ #include <stdexcept> #include <typeinfo> #include "asio/async_result.hpp"-#include "asio/detail/chrono.hpp" #include "asio/detail/concurrency_hint.hpp" #include "asio/detail/cstdint.hpp" #include "asio/detail/wrapped_handler.hpp"@@ -28,6 +27,10 @@ #include "asio/execution.hpp" #include "asio/execution_context.hpp" +#if defined(ASIO_HAS_CHRONO)+# include "asio/detail/chrono.hpp"+#endif // defined(ASIO_HAS_CHRONO)+ #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) # include "asio/detail/winsock_init.hpp" #elif defined(__sun) || defined(__QNX__) || defined(__hpux) || defined(_AIX) \@@ -55,10 +58,10 @@ struct io_context_bits {- static constexpr uintptr_t blocking_never = 1;- static constexpr uintptr_t relationship_continuation = 2;- static constexpr uintptr_t outstanding_work_tracked = 4;- static constexpr uintptr_t runtime_bits = 3;+ ASIO_STATIC_CONSTEXPR(uintptr_t, blocking_never = 1);+ ASIO_STATIC_CONSTEXPR(uintptr_t, relationship_continuation = 2);+ ASIO_STATIC_CONSTEXPR(uintptr_t, outstanding_work_tracked = 4);+ ASIO_STATIC_CONSTEXPR(uintptr_t, runtime_bits = 3); }; } // namespace detail @@ -197,6 +200,11 @@ friend class detail::win_iocp_overlapped_ptr; #endif +#if !defined(ASIO_NO_DEPRECATED)+ struct initiate_dispatch;+ struct initiate_post;+#endif // !defined(ASIO_NO_DEPRECATED)+ public: template <typename Allocator, uintptr_t Bits> class basic_executor_type;@@ -207,6 +215,11 @@ /// Executor used to submit functions to an io_context. typedef basic_executor_type<std::allocator<void>, 0> executor_type; +#if !defined(ASIO_NO_DEPRECATED)+ class work;+ friend class work;+#endif // !defined(ASIO_NO_DEPRECATED)+ class service; #if !defined(ASIO_NO_EXTENSIONS) \@@ -223,15 +236,6 @@ /// Constructor. /**- * @param a An allocator that will be used for allocating objects that are- * associated with the context, such as services and internal state for I/O- * objects.- */- template <typename Allocator>- io_context(allocator_arg_t, const Allocator& a);-- /// Constructor.- /** * Construct with a hint about the required level of concurrency. * * @param concurrency_hint A suggestion to the implementation on how many@@ -239,47 +243,6 @@ */ ASIO_DECL explicit io_context(int concurrency_hint); - /// Constructor.- /**- * Construct with a hint about the required level of concurrency.- *- * @param a An allocator that will be used for allocating objects that are- * associated with the context, such as services and internal state for I/O- * objects.- *- * @param concurrency_hint A suggestion to the implementation on how many- * threads it should allow to run simultaneously.- */- template <typename Allocator>- io_context(allocator_arg_t, const Allocator& a, int concurrency_hint);-- /// Constructor.- /**- * Construct with a service maker, to create an initial set of services that- * will be installed into the execution context at construction time.- *- * @param initial_services Used to create the initial services. The @c make- * function will be called once at the end of execution_context construction.- */- ASIO_DECL explicit io_context(- const execution_context::service_maker& initial_services);-- /// Constructor.- /**- * Construct with a service maker, to create an initial set of services that- * will be installed into the execution context at construction time.- *- * @param a An allocator that will be used for allocating objects that are- * associated with the context, such as services and internal state for I/O- * objects.- *- * @param initial_services Used to create the initial services. The @c make- * function will be called once at the end of execution_context construction.- */- template <typename Allocator>- io_context(allocator_arg_t, const Allocator& a,- const service_maker& initial_services);- /// Destructor. /** * On destruction, the io_context performs the following sequence of@@ -315,7 +278,7 @@ ASIO_DECL ~io_context(); /// Obtains the executor associated with the io_context.- executor_type get_executor() noexcept;+ executor_type get_executor() ASIO_NOEXCEPT; /// Run the io_context object's event processing loop. /**@@ -337,13 +300,46 @@ * @note Calling the run() function from a thread that is currently calling * one of run(), run_one(), run_for(), run_until(), poll() or poll_one() on * the same io_context object may introduce the potential for deadlock. It is- * the caller's responsibility to avoid this.+ * the caller's reponsibility to avoid this. * * The poll() function may also be used to dispatch ready handlers, but * without blocking. */ ASIO_DECL count_type run(); +#if !defined(ASIO_NO_DEPRECATED)+ /// (Deprecated: Use non-error_code overload.) Run the io_context object's+ /// event processing loop.+ /**+ * The run() function blocks until all work has finished and there are no+ * more handlers to be dispatched, or until the io_context has been stopped.+ *+ * Multiple threads may call the run() function to set up a pool of threads+ * from which the io_context may execute handlers. All threads that are+ * waiting in the pool are equivalent and the io_context may choose any one+ * of them to invoke a handler.+ *+ * A normal exit from the run() function implies that the io_context object+ * is stopped (the stopped() function returns @c true). Subsequent calls to+ * run(), run_one(), poll() or poll_one() will return immediately unless there+ * is a prior call to restart().+ *+ * @param ec Set to indicate what error occurred, if any.+ *+ * @return The number of handlers that were executed.+ *+ * @note Calling the run() function from a thread that is currently calling+ * one of run(), run_one(), run_for(), run_until(), poll() or poll_one() on+ * the same io_context object may introduce the potential for deadlock. It is+ * the caller's reponsibility to avoid this.+ *+ * The poll() function may also be used to dispatch ready handlers, but+ * without blocking.+ */+ ASIO_DECL count_type run(asio::error_code& ec);+#endif // !defined(ASIO_NO_DEPRECATED)++#if defined(ASIO_HAS_CHRONO) || defined(GENERATING_DOCUMENTATION) /// Run the io_context object's event processing loop for a specified /// duration. /**@@ -370,6 +366,7 @@ */ template <typename Clock, typename Duration> std::size_t run_until(const chrono::time_point<Clock, Duration>& abs_time);+#endif // defined(ASIO_HAS_CHRONO) || defined(GENERATING_DOCUMENTATION) /// Run the io_context object's event processing loop to execute at most one /// handler.@@ -386,10 +383,34 @@ * @note Calling the run_one() function from a thread that is currently * calling one of run(), run_one(), run_for(), run_until(), poll() or * poll_one() on the same io_context object may introduce the potential for- * deadlock. It is the caller's responsibility to avoid this.+ * deadlock. It is the caller's reponsibility to avoid this. */ ASIO_DECL count_type run_one(); +#if !defined(ASIO_NO_DEPRECATED)+ /// (Deprecated: Use non-error_code overload.) Run the io_context object's+ /// event processing loop to execute at most one handler.+ /**+ * The run_one() function blocks until one handler has been dispatched, or+ * until the io_context has been stopped.+ *+ * @return The number of handlers that were executed. A zero return value+ * implies that the io_context object is stopped (the stopped() function+ * returns @c true). Subsequent calls to run(), run_one(), poll() or+ * poll_one() will return immediately unless there is a prior call to+ * restart().+ *+ * @return The number of handlers that were executed.+ *+ * @note Calling the run_one() function from a thread that is currently+ * calling one of run(), run_one(), run_for(), run_until(), poll() or+ * poll_one() on the same io_context object may introduce the potential for+ * deadlock. It is the caller's reponsibility to avoid this.+ */+ ASIO_DECL count_type run_one(asio::error_code& ec);+#endif // !defined(ASIO_NO_DEPRECATED)++#if defined(ASIO_HAS_CHRONO) || defined(GENERATING_DOCUMENTATION) /// Run the io_context object's event processing loop for a specified duration /// to execute at most one handler. /**@@ -418,6 +439,7 @@ template <typename Clock, typename Duration> std::size_t run_one_until( const chrono::time_point<Clock, Duration>& abs_time);+#endif // defined(ASIO_HAS_CHRONO) || defined(GENERATING_DOCUMENTATION) /// Run the io_context object's event processing loop to execute ready /// handlers.@@ -429,6 +451,20 @@ */ ASIO_DECL count_type poll(); +#if !defined(ASIO_NO_DEPRECATED)+ /// (Deprecated: Use non-error_code overload.) Run the io_context object's+ /// event processing loop to execute ready handlers.+ /**+ * The poll() function runs handlers that are ready to run, without blocking,+ * until the io_context has been stopped or there are no more ready handlers.+ *+ * @param ec Set to indicate what error occurred, if any.+ *+ * @return The number of handlers that were executed.+ */+ ASIO_DECL count_type poll(asio::error_code& ec);+#endif // !defined(ASIO_NO_DEPRECATED)+ /// Run the io_context object's event processing loop to execute one ready /// handler. /**@@ -439,6 +475,20 @@ */ ASIO_DECL count_type poll_one(); +#if !defined(ASIO_NO_DEPRECATED)+ /// (Deprecated: Use non-error_code overload.) Run the io_context object's+ /// event processing loop to execute one ready handler.+ /**+ * The poll_one() function runs at most one handler that is ready to run,+ * without blocking.+ *+ * @param ec Set to indicate what error occurred, if any.+ *+ * @return The number of handlers that were executed.+ */+ ASIO_DECL count_type poll_one(asio::error_code& ec);+#endif // !defined(ASIO_NO_DEPRECATED)+ /// Stop the io_context object's event processing loop. /** * This function does not block, but instead simply signals the io_context to@@ -474,6 +524,79 @@ ASIO_DECL void restart(); #if !defined(ASIO_NO_DEPRECATED)+ /// (Deprecated: Use restart().) Reset the io_context in preparation for a+ /// subsequent run() invocation.+ /**+ * This function must be called prior to any second or later set of+ * invocations of the run(), run_one(), poll() or poll_one() functions when a+ * previous invocation of these functions returned due to the io_context+ * being stopped or running out of work. After a call to restart(), the+ * io_context object's stopped() function will return @c false.+ *+ * This function must not be called while there are any unfinished calls to+ * the run(), run_one(), poll() or poll_one() functions.+ */+ void reset();++ /// (Deprecated: Use asio::dispatch().) Request the io_context to+ /// invoke the given handler.+ /**+ * This function is used to ask the io_context to execute the given handler.+ *+ * The io_context guarantees that the handler will only be called in a thread+ * in which the run(), run_one(), poll() or poll_one() member functions is+ * currently being invoked. The handler may be executed inside this function+ * if the guarantee can be met.+ *+ * @param handler The handler to be called. The io_context will make+ * a copy of the handler object as required. The function signature of the+ * handler must be: @code void handler(); @endcode+ *+ * @note This function throws an exception only if:+ *+ * @li the handler's @c asio_handler_allocate function; or+ *+ * @li the handler's copy constructor+ *+ * throws an exception.+ */+ template <typename LegacyCompletionHandler>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(LegacyCompletionHandler, void ())+ dispatch(ASIO_MOVE_ARG(LegacyCompletionHandler) handler)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_initiate<LegacyCompletionHandler, void ()>(+ declval<initiate_dispatch>(), handler, this)));++ /// (Deprecated: Use asio::post().) Request the io_context to invoke+ /// the given handler and return immediately.+ /**+ * This function is used to ask the io_context to execute the given handler,+ * but without allowing the io_context to call the handler from inside this+ * function.+ *+ * The io_context guarantees that the handler will only be called in a thread+ * in which the run(), run_one(), poll() or poll_one() member functions is+ * currently being invoked.+ *+ * @param handler The handler to be called. The io_context will make+ * a copy of the handler object as required. The function signature of the+ * handler must be: @code void handler(); @endcode+ *+ * @note This function throws an exception only if:+ *+ * @li the handler's @c asio_handler_allocate function; or+ *+ * @li the handler's copy constructor+ *+ * throws an exception.+ */+ template <typename LegacyCompletionHandler>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(LegacyCompletionHandler, void ())+ post(ASIO_MOVE_ARG(LegacyCompletionHandler) handler)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_initiate<LegacyCompletionHandler, void ()>(+ declval<initiate_post>(), handler, this)));+ /// (Deprecated: Use asio::bind_executor().) Create a new handler that /// automatically dispatches the wrapped handler on the io_context. /**@@ -494,8 +617,7 @@ * then the return value is a function object with the signature * @code void g(A1 a1, ... An an); @endcode * that, when invoked, executes code equivalent to:- * @code asio::dispatch(io_context,- * boost::bind(f, a1, ... an)); @endcode+ * @code io_context.dispatch(boost::bind(f, a1, ... an)); @endcode */ template <typename Handler> #if defined(GENERATING_DOCUMENTATION)@@ -507,9 +629,12 @@ #endif // !defined(ASIO_NO_DEPRECATED) private:- io_context(const io_context&) = delete;- io_context& operator=(const io_context&) = delete;+ io_context(const io_context&) ASIO_DELETED;+ io_context& operator=(const io_context&) ASIO_DELETED; + // Helper function to add the implementation.+ ASIO_DECL impl_type& add_impl(impl_type* impl);+ // Backwards compatible overload for use with services derived from // io_context::service. template <typename Service>@@ -526,6 +651,10 @@ impl_type& impl_; }; +namespace detail {++} // namespace detail+ /// Executor implementation type used to submit functions to an io_context. template <typename Allocator, uintptr_t Bits> class io_context::basic_executor_type :@@ -533,7 +662,8 @@ { public: /// Copy constructor.- basic_executor_type(const basic_executor_type& other) noexcept+ basic_executor_type(+ const basic_executor_type& other) ASIO_NOEXCEPT : Allocator(static_cast<const Allocator&>(other)), target_(other.target_) {@@ -542,17 +672,19 @@ context_ptr()->impl_.work_started(); } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move constructor.- basic_executor_type(basic_executor_type&& other) noexcept- : Allocator(static_cast<Allocator&&>(other)),+ basic_executor_type(basic_executor_type&& other) ASIO_NOEXCEPT+ : Allocator(ASIO_MOVE_CAST(Allocator)(other)), target_(other.target_) { if (Bits & outstanding_work_tracked) other.target_ = 0; }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Destructor.- ~basic_executor_type() noexcept+ ~basic_executor_type() ASIO_NOEXCEPT { if (Bits & outstanding_work_tracked) if (context_ptr())@@ -560,10 +692,14 @@ } /// Assignment operator.- basic_executor_type& operator=(const basic_executor_type& other) noexcept;+ basic_executor_type& operator=(+ const basic_executor_type& other) ASIO_NOEXCEPT; +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move assignment operator.- basic_executor_type& operator=(basic_executor_type&& other) noexcept;+ basic_executor_type& operator=(+ basic_executor_type&& other) ASIO_NOEXCEPT;+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) #if !defined(GENERATING_DOCUMENTATION) private:@@ -581,7 +717,8 @@ * auto ex2 = asio::require(ex1, * asio::execution::blocking.possibly); @endcode */- constexpr basic_executor_type require(execution::blocking_t::possibly_t) const+ ASIO_CONSTEXPR basic_executor_type require(+ execution::blocking_t::possibly_t) const { return basic_executor_type(context_ptr(), *this, bits() & ~blocking_never);@@ -597,7 +734,8 @@ * auto ex2 = asio::require(ex1, * asio::execution::blocking.never); @endcode */- constexpr basic_executor_type require(execution::blocking_t::never_t) const+ ASIO_CONSTEXPR basic_executor_type require(+ execution::blocking_t::never_t) const { return basic_executor_type(context_ptr(), *this, bits() | blocking_never);@@ -613,7 +751,8 @@ * auto ex2 = asio::require(ex1, * asio::execution::relationship.fork); @endcode */- constexpr basic_executor_type require(execution::relationship_t::fork_t) const+ ASIO_CONSTEXPR basic_executor_type require(+ execution::relationship_t::fork_t) const { return basic_executor_type(context_ptr(), *this, bits() & ~relationship_continuation);@@ -629,7 +768,7 @@ * auto ex2 = asio::require(ex1, * asio::execution::relationship.continuation); @endcode */- constexpr basic_executor_type require(+ ASIO_CONSTEXPR basic_executor_type require( execution::relationship_t::continuation_t) const { return basic_executor_type(context_ptr(),@@ -646,7 +785,7 @@ * auto ex2 = asio::require(ex1, * asio::execution::outstanding_work.tracked); @endcode */- constexpr basic_executor_type<Allocator,+ ASIO_CONSTEXPR basic_executor_type<Allocator, ASIO_UNSPECIFIED(Bits | outstanding_work_tracked)> require(execution::outstanding_work_t::tracked_t) const {@@ -664,7 +803,7 @@ * auto ex2 = asio::require(ex1, * asio::execution::outstanding_work.untracked); @endcode */- constexpr basic_executor_type<Allocator,+ ASIO_CONSTEXPR basic_executor_type<Allocator, ASIO_UNSPECIFIED(Bits & ~outstanding_work_tracked)> require(execution::outstanding_work_t::untracked_t) const {@@ -683,7 +822,7 @@ * asio::execution::allocator(my_allocator)); @endcode */ template <typename OtherAllocator>- constexpr basic_executor_type<OtherAllocator, Bits>+ ASIO_CONSTEXPR basic_executor_type<OtherAllocator, Bits> require(execution::allocator_t<OtherAllocator> a) const { return basic_executor_type<OtherAllocator, Bits>(@@ -700,7 +839,7 @@ * auto ex2 = asio::require(ex1, * asio::execution::allocator); @endcode */- constexpr basic_executor_type<std::allocator<void>, Bits>+ ASIO_CONSTEXPR basic_executor_type<std::allocator<void>, Bits> require(execution::allocator_t<void>) const { return basic_executor_type<std::allocator<void>, Bits>(@@ -725,7 +864,8 @@ * == asio::execution::mapping.thread) * ... @endcode */- static constexpr execution::mapping_t query(execution::mapping_t) noexcept+ static ASIO_CONSTEXPR execution::mapping_t query(+ execution::mapping_t) ASIO_NOEXCEPT { return execution::mapping.thread; }@@ -740,7 +880,7 @@ * asio::io_context& ctx = asio::query( * ex, asio::execution::context); @endcode */- io_context& query(execution::context_t) const noexcept+ io_context& query(execution::context_t) const ASIO_NOEXCEPT { return *context_ptr(); }@@ -756,7 +896,8 @@ * == asio::execution::blocking.always) * ... @endcode */- constexpr execution::blocking_t query(execution::blocking_t) const noexcept+ ASIO_CONSTEXPR execution::blocking_t query(+ execution::blocking_t) const ASIO_NOEXCEPT { return (bits() & blocking_never) ? execution::blocking_t(execution::blocking.never)@@ -774,8 +915,8 @@ * == asio::execution::relationship.continuation) * ... @endcode */- constexpr execution::relationship_t query(- execution::relationship_t) const noexcept+ ASIO_CONSTEXPR execution::relationship_t query(+ execution::relationship_t) const ASIO_NOEXCEPT { return (bits() & relationship_continuation) ? execution::relationship_t(execution::relationship.continuation)@@ -793,8 +934,8 @@ * == asio::execution::outstanding_work.tracked) * ... @endcode */- static constexpr execution::outstanding_work_t query(- execution::outstanding_work_t) noexcept+ static ASIO_CONSTEXPR execution::outstanding_work_t query(+ execution::outstanding_work_t) ASIO_NOEXCEPT { return (Bits & outstanding_work_tracked) ? execution::outstanding_work_t(execution::outstanding_work.tracked)@@ -812,8 +953,8 @@ * asio::execution::allocator); @endcode */ template <typename OtherAllocator>- constexpr Allocator query(- execution::allocator_t<OtherAllocator>) const noexcept+ ASIO_CONSTEXPR Allocator query(+ execution::allocator_t<OtherAllocator>) const ASIO_NOEXCEPT { return static_cast<const Allocator&>(*this); }@@ -828,7 +969,8 @@ * auto alloc = asio::query(ex, * asio::execution::allocator); @endcode */- constexpr Allocator query(execution::allocator_t<void>) const noexcept+ ASIO_CONSTEXPR Allocator query(+ execution::allocator_t<void>) const ASIO_NOEXCEPT { return static_cast<const Allocator&>(*this); }@@ -839,14 +981,14 @@ * @return @c true if the current thread is running the io_context. Otherwise * returns @c false. */- bool running_in_this_thread() const noexcept;+ bool running_in_this_thread() const ASIO_NOEXCEPT; /// Compare two executors for equality. /** * Two executors are equal if they refer to the same underlying io_context. */ friend bool operator==(const basic_executor_type& a,- const basic_executor_type& b) noexcept+ const basic_executor_type& b) ASIO_NOEXCEPT { return a.target_ == b.target_ && static_cast<const Allocator&>(a) == static_cast<const Allocator&>(b);@@ -857,7 +999,7 @@ * Two executors are equal if they refer to the same underlying io_context. */ friend bool operator!=(const basic_executor_type& a,- const basic_executor_type& b) noexcept+ const basic_executor_type& b) ASIO_NOEXCEPT { return a.target_ != b.target_ || static_cast<const Allocator&>(a) != static_cast<const Allocator&>(b);@@ -865,12 +1007,12 @@ /// Execution function. template <typename Function>- void execute(Function&& f) const;+ void execute(ASIO_MOVE_ARG(Function) f) const; #if !defined(ASIO_NO_TS_EXECUTORS) public: /// Obtain the underlying execution context.- io_context& context() const noexcept;+ io_context& context() const ASIO_NOEXCEPT; /// Inform the io_context that it has some outstanding work to do. /**@@ -878,7 +1020,7 @@ * This ensures that the io_context's run() and run_one() functions do not * exit while the work is underway. */- void on_work_started() const noexcept;+ void on_work_started() const ASIO_NOEXCEPT; /// Inform the io_context that some work is no longer outstanding. /**@@ -886,7 +1028,7 @@ * finished. Once the count of unfinished work reaches zero, the io_context * is stopped and the run() and run_one() functions may exit. */- void on_work_finished() const noexcept;+ void on_work_finished() const ASIO_NOEXCEPT; /// Request the io_context to invoke the given function object. /**@@ -903,7 +1045,8 @@ * internal storage needed for function invocation. */ template <typename Function, typename OtherAllocator>- void dispatch(Function&& f, const OtherAllocator& a) const;+ void dispatch(ASIO_MOVE_ARG(Function) f,+ const OtherAllocator& a) const; /// Request the io_context to invoke the given function object. /**@@ -919,7 +1062,8 @@ * internal storage needed for function invocation. */ template <typename Function, typename OtherAllocator>- void post(Function&& f, const OtherAllocator& a) const;+ void post(ASIO_MOVE_ARG(Function) f,+ const OtherAllocator& a) const; /// Request the io_context to invoke the given function object. /**@@ -939,7 +1083,8 @@ * internal storage needed for function invocation. */ template <typename Function, typename OtherAllocator>- void defer(Function&& f, const OtherAllocator& a) const;+ void defer(ASIO_MOVE_ARG(Function) f,+ const OtherAllocator& a) const; #endif // !defined(ASIO_NO_TS_EXECUTORS) private:@@ -947,7 +1092,7 @@ template <typename, uintptr_t> friend class basic_executor_type; // Constructor used by io_context::get_executor().- explicit basic_executor_type(io_context& i) noexcept+ explicit basic_executor_type(io_context& i) ASIO_NOEXCEPT : Allocator(), target_(reinterpret_cast<uintptr_t>(&i)) {@@ -957,7 +1102,7 @@ // Constructor used by require(). basic_executor_type(io_context* i,- const Allocator& a, uintptr_t bits) noexcept+ const Allocator& a, uintptr_t bits) ASIO_NOEXCEPT : Allocator(a), target_(reinterpret_cast<uintptr_t>(i) | bits) {@@ -966,12 +1111,12 @@ context_ptr()->impl_.work_started(); } - io_context* context_ptr() const noexcept+ io_context* context_ptr() const ASIO_NOEXCEPT { return reinterpret_cast<io_context*>(target_ & ~runtime_bits); } - uintptr_t bits() const noexcept+ uintptr_t bits() const ASIO_NOEXCEPT { return target_ & runtime_bits; }@@ -980,6 +1125,57 @@ uintptr_t target_; }; +#if !defined(ASIO_NO_DEPRECATED)+/// (Deprecated: Use executor_work_guard.) Class to inform the io_context when+/// it has work to do.+/**+ * The work class is used to inform the io_context when work starts and+ * finishes. This ensures that the io_context object's run() function will not+ * exit while work is underway, and that it does exit when there is no+ * unfinished work remaining.+ *+ * The work class is copy-constructible so that it may be used as a data member+ * in a handler class. It is not assignable.+ */+class io_context::work+{+public:+ /// Constructor notifies the io_context that work is starting.+ /**+ * The constructor is used to inform the io_context that some work has begun.+ * This ensures that the io_context object's run() function will not exit+ * while the work is underway.+ */+ explicit work(asio::io_context& io_context);++ /// Copy constructor notifies the io_context that work is starting.+ /**+ * The constructor is used to inform the io_context that some work has begun.+ * This ensures that the io_context object's run() function will not exit+ * while the work is underway.+ */+ work(const work& other);++ /// Destructor notifies the io_context that the work is complete.+ /**+ * The destructor is used to inform the io_context that some work has+ * finished. Once the count of unfinished work reaches zero, the io_context+ * object's run() function is permitted to exit.+ */+ ~work();++ /// Get the io_context associated with the work.+ asio::io_context& get_io_context();++private:+ // Prevent assignment.+ void operator=(const work& other);++ // The io_context implementation.+ detail::io_context_impl& io_context_impl_;+};+#endif // !defined(ASIO_NO_DEPRECATED)+ /// Base class for all io_context services. class io_context::service : public execution_context::service@@ -992,6 +1188,12 @@ /// Destroy all user-defined handler objects owned by the service. ASIO_DECL virtual void shutdown(); +#if !defined(ASIO_NO_DEPRECATED)+ /// (Deprecated: Use shutdown().) Destroy all user-defined handler objects+ /// owned by the service.+ ASIO_DECL virtual void shutdown_service();+#endif // !defined(ASIO_NO_DEPRECATED)+ /// Handle notification of a fork-related event to perform any necessary /// housekeeping. /**@@ -1001,6 +1203,17 @@ ASIO_DECL virtual void notify_fork( execution_context::fork_event event); +#if !defined(ASIO_NO_DEPRECATED)+ /// (Deprecated: Use notify_fork().) Handle notification of a fork-related+ /// event to perform any necessary housekeeping.+ /**+ * This function is not a pure virtual so that services only have to+ * implement it if necessary. The default implementation does nothing.+ */+ ASIO_DECL virtual void fork_service(+ execution_context::fork_event event);+#endif // !defined(ASIO_NO_DEPRECATED)+ protected: /// Constructor. /**@@ -1045,8 +1258,8 @@ asio::io_context::basic_executor_type<Allocator, Bits> > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); }; #endif // !defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)@@ -1059,8 +1272,8 @@ Function > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = false;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); typedef void result_type; }; @@ -1074,8 +1287,8 @@ asio::execution::blocking_t::possibly_t > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = false;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); typedef asio::io_context::basic_executor_type< Allocator, Bits> result_type; };@@ -1086,8 +1299,8 @@ asio::execution::blocking_t::never_t > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = false;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); typedef asio::io_context::basic_executor_type< Allocator, Bits> result_type; };@@ -1098,8 +1311,8 @@ asio::execution::relationship_t::fork_t > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = false;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); typedef asio::io_context::basic_executor_type< Allocator, Bits> result_type; };@@ -1110,8 +1323,8 @@ asio::execution::relationship_t::continuation_t > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = false;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); typedef asio::io_context::basic_executor_type< Allocator, Bits> result_type; };@@ -1122,8 +1335,8 @@ asio::execution::outstanding_work_t::tracked_t > : asio::detail::io_context_bits {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = false;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); typedef asio::io_context::basic_executor_type< Allocator, Bits | outstanding_work_tracked> result_type; };@@ -1134,8 +1347,8 @@ asio::execution::outstanding_work_t::untracked_t > : asio::detail::io_context_bits {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = false;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); typedef asio::io_context::basic_executor_type< Allocator, Bits & ~outstanding_work_tracked> result_type; };@@ -1146,8 +1359,8 @@ asio::execution::allocator_t<void> > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = false;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); typedef asio::io_context::basic_executor_type< std::allocator<void>, Bits> result_type; };@@ -1159,8 +1372,8 @@ asio::execution::allocator_t<OtherAllocator> > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = false;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); typedef asio::io_context::basic_executor_type< OtherAllocator, Bits> result_type; };@@ -1181,11 +1394,11 @@ >::type > : asio::detail::io_context_bits {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef asio::execution::outstanding_work_t result_type; - static constexpr result_type value() noexcept+ static ASIO_CONSTEXPR result_type value() ASIO_NOEXCEPT { return (Bits & outstanding_work_tracked) ? execution::outstanding_work_t(execution::outstanding_work.tracked)@@ -1205,11 +1418,11 @@ >::type > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef asio::execution::mapping_t::thread_t result_type; - static constexpr result_type value() noexcept+ static ASIO_CONSTEXPR result_type value() ASIO_NOEXCEPT { return result_type(); }@@ -1231,8 +1444,8 @@ >::type > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef asio::execution::blocking_t result_type; }; @@ -1248,8 +1461,8 @@ >::type > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef asio::execution::relationship_t result_type; }; @@ -1259,8 +1472,8 @@ asio::execution::context_t > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef asio::io_context& result_type; }; @@ -1270,8 +1483,8 @@ asio::execution::allocator_t<void> > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef Allocator result_type; }; @@ -1281,8 +1494,8 @@ asio::execution::allocator_t<OtherAllocator> > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef Allocator result_type; };
link/modules/asio-standalone/asio/include/asio/io_context_strand.hpp view
@@ -2,7 +2,7 @@ // io_context_strand.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -54,18 +54,19 @@ * if any of the following conditions are true: * * @li @c s.post(a) happens-before @c s.post(b)- *+ * * @li @c s.post(a) happens-before @c s.dispatch(b), where the latter is * performed outside the strand- *+ * * @li @c s.dispatch(a) happens-before @c s.post(b), where the former is * performed outside the strand- *+ * * @li @c s.dispatch(a) happens-before @c s.dispatch(b), where both are * performed outside the strand- *- * then @c a() happens-before @c b()- *+ * + * then @c asio_handler_invoke(a1, &a1) happens-before+ * @c asio_handler_invoke(b1, &b1).+ * * Note that in the following case: * @code async_op_1(..., s.wrap(a)); * async_op_2(..., s.wrap(b)); @endcode@@ -87,6 +88,12 @@ */ class io_context::strand {+private:+#if !defined(ASIO_NO_DEPRECATED)+ struct initiate_dispatch;+ struct initiate_post;+#endif // !defined(ASIO_NO_DEPRECATED)+ public: /// Constructor. /**@@ -102,17 +109,6 @@ service_.construct(impl_); } - /// Copy constructor.- /**- * Creates a copy such that both strand objects share the same underlying- * state.- */- strand(const strand& other) noexcept- : service_(other.service_),- impl_(other.impl_)- {- }- /// Destructor. /** * Destroys a strand.@@ -125,7 +121,7 @@ } /// Obtain the underlying execution context.- asio::io_context& context() const noexcept+ asio::io_context& context() const ASIO_NOEXCEPT { return service_.get_io_context(); }@@ -134,7 +130,7 @@ /** * The strand delegates this call to its underlying io_context. */- void on_work_started() const noexcept+ void on_work_started() const ASIO_NOEXCEPT { context().get_executor().on_work_started(); }@@ -143,7 +139,7 @@ /** * The strand delegates this call to its underlying io_context. */- void on_work_finished() const noexcept+ void on_work_finished() const ASIO_NOEXCEPT { context().get_executor().on_work_finished(); }@@ -164,13 +160,46 @@ * internal storage needed for function invocation. */ template <typename Function, typename Allocator>- void dispatch(Function&& f, const Allocator& a) const+ void dispatch(ASIO_MOVE_ARG(Function) f, const Allocator& a) const {- decay_t<Function> tmp(static_cast<Function&&>(f));+ typename decay<Function>::type tmp(ASIO_MOVE_CAST(Function)(f)); service_.dispatch(impl_, tmp); (void)a; } +#if !defined(ASIO_NO_DEPRECATED)+ /// (Deprecated: Use asio::dispatch().) Request the strand to invoke+ /// the given handler.+ /**+ * This function is used to ask the strand to execute the given handler.+ *+ * The strand object guarantees that handlers posted or dispatched through+ * the strand will not be executed concurrently. The handler may be executed+ * inside this function if the guarantee can be met. If this function is+ * called from within a handler that was posted or dispatched through the same+ * strand, then the new handler will be executed immediately.+ *+ * The strand's guarantee is in addition to the guarantee provided by the+ * underlying io_context. The io_context guarantees that the handler will only+ * be called in a thread in which the io_context's run member function is+ * currently being invoked.+ *+ * @param handler The handler to be called. The strand will make a copy of the+ * handler object as required. The function signature of the handler must be:+ * @code void handler(); @endcode+ */+ template <typename LegacyCompletionHandler>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(LegacyCompletionHandler, void ())+ dispatch(ASIO_MOVE_ARG(LegacyCompletionHandler) handler)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_initiate<LegacyCompletionHandler, void ()>(+ declval<initiate_dispatch>(), handler, this)))+ {+ return async_initiate<LegacyCompletionHandler, void ()>(+ initiate_dispatch(), handler, this);+ }+#endif // !defined(ASIO_NO_DEPRECATED)+ /// Request the strand to invoke the given function object. /** * This function is used to ask the executor to execute the given function@@ -185,13 +214,42 @@ * internal storage needed for function invocation. */ template <typename Function, typename Allocator>- void post(Function&& f, const Allocator& a) const+ void post(ASIO_MOVE_ARG(Function) f, const Allocator& a) const {- decay_t<Function> tmp(static_cast<Function&&>(f));+ typename decay<Function>::type tmp(ASIO_MOVE_CAST(Function)(f)); service_.post(impl_, tmp); (void)a; } +#if !defined(ASIO_NO_DEPRECATED)+ /// (Deprecated: Use asio::post().) Request the strand to invoke the+ /// given handler and return immediately.+ /**+ * This function is used to ask the strand to execute the given handler, but+ * without allowing the strand to call the handler from inside this function.+ *+ * The strand object guarantees that handlers posted or dispatched through+ * the strand will not be executed concurrently. The strand's guarantee is in+ * addition to the guarantee provided by the underlying io_context. The+ * io_context guarantees that the handler will only be called in a thread in+ * which the io_context's run member function is currently being invoked.+ *+ * @param handler The handler to be called. The strand will make a copy of the+ * handler object as required. The function signature of the handler must be:+ * @code void handler(); @endcode+ */+ template <typename LegacyCompletionHandler>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(LegacyCompletionHandler, void ())+ post(ASIO_MOVE_ARG(LegacyCompletionHandler) handler)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_initiate<LegacyCompletionHandler, void ()>(+ declval<initiate_post>(), handler, this)))+ {+ return async_initiate<LegacyCompletionHandler, void ()>(+ initiate_post(), handler, this);+ }+#endif // !defined(ASIO_NO_DEPRECATED)+ /// Request the strand to invoke the given function object. /** * This function is used to ask the executor to execute the given function@@ -206,9 +264,9 @@ * internal storage needed for function invocation. */ template <typename Function, typename Allocator>- void defer(Function&& f, const Allocator& a) const+ void defer(ASIO_MOVE_ARG(Function) f, const Allocator& a) const {- decay_t<Function> tmp(static_cast<Function&&>(f));+ typename decay<Function>::type tmp(ASIO_MOVE_CAST(Function)(f)); service_.post(impl_, tmp); (void)a; }@@ -233,7 +291,7 @@ * then the return value is a function object with the signature * @code void g(A1 a1, ... An an); @endcode * that, when invoked, executes code equivalent to:- * @code asio::dispatch(strand, boost::bind(f, a1, ... an)); @endcode+ * @code strand.dispatch(boost::bind(f, a1, ... an)); @endcode */ template <typename Handler> #if defined(GENERATING_DOCUMENTATION)@@ -254,7 +312,7 @@ * submitted to the strand using post(), dispatch() or wrap(). Otherwise * returns @c false. */- bool running_in_this_thread() const noexcept+ bool running_in_this_thread() const ASIO_NOEXCEPT { return service_.running_in_this_thread(impl_); }@@ -264,7 +322,7 @@ * Two strands are equal if they refer to the same ordered, non-concurrent * state. */- friend bool operator==(const strand& a, const strand& b) noexcept+ friend bool operator==(const strand& a, const strand& b) ASIO_NOEXCEPT { return a.impl_ == b.impl_; }@@ -274,12 +332,48 @@ * Two strands are equal if they refer to the same ordered, non-concurrent * state. */- friend bool operator!=(const strand& a, const strand& b) noexcept+ friend bool operator!=(const strand& a, const strand& b) ASIO_NOEXCEPT { return a.impl_ != b.impl_; } private:+#if !defined(ASIO_NO_DEPRECATED)+ struct initiate_dispatch+ {+ template <typename LegacyCompletionHandler>+ void operator()(ASIO_MOVE_ARG(LegacyCompletionHandler) handler,+ strand* self) const+ {+ // If you get an error on the following line it means that your+ // handler does not meet the documented type requirements for a+ // LegacyCompletionHandler.+ ASIO_LEGACY_COMPLETION_HANDLER_CHECK(+ LegacyCompletionHandler, handler) type_check;++ detail::non_const_lvalue<LegacyCompletionHandler> handler2(handler);+ self->service_.dispatch(self->impl_, handler2.value);+ }+ };++ struct initiate_post+ {+ template <typename LegacyCompletionHandler>+ void operator()(ASIO_MOVE_ARG(LegacyCompletionHandler) handler,+ strand* self) const+ {+ // If you get an error on the following line it means that your+ // handler does not meet the documented type requirements for a+ // LegacyCompletionHandler.+ ASIO_LEGACY_COMPLETION_HANDLER_CHECK(+ LegacyCompletionHandler, handler) type_check;++ detail::non_const_lvalue<LegacyCompletionHandler> handler2(handler);+ self->service_.post(self->impl_, handler2.value);+ }+ };+#endif // !defined(ASIO_NO_DEPRECATED)+ asio::detail::strand_service& service_; mutable asio::detail::strand_service::implementation_type impl_; };
+ link/modules/asio-standalone/asio/include/asio/io_service.hpp view
@@ -0,0 +1,33 @@+//+// io_service.hpp+// ~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_IO_SERVICE_HPP+#define ASIO_IO_SERVICE_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/io_context.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {++#if !defined(ASIO_NO_DEPRECATED)+/// Typedef for backwards compatibility.+typedef io_context io_service;+#endif // !defined(ASIO_NO_DEPRECATED)++} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_IO_SERVICE_HPP
+ link/modules/asio-standalone/asio/include/asio/io_service_strand.hpp view
@@ -0,0 +1,20 @@+//+// io_service_strand.hpp+// ~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_IO_SERVICE_STRAND_HPP+#define ASIO_IO_SERVICE_STRAND_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/io_context_strand.hpp"++#endif // ASIO_IO_SERVICE_STRAND_HPP
link/modules/asio-standalone/asio/include/asio/ip/address.hpp view
@@ -2,7 +2,7 @@ // ip/address.hpp // ~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -16,7 +16,6 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"-#include <functional> #include <string> #include "asio/detail/throw_exception.hpp" #include "asio/detail/string_view.hpp"@@ -26,6 +25,10 @@ #include "asio/ip/address_v6.hpp" #include "asio/ip/bad_address_cast.hpp" +#if defined(ASIO_HAS_STD_HASH)+# include <functional>+#endif // defined(ASIO_HAS_STD_HASH)+ #if !defined(ASIO_NO_IOSTREAM) # include <iosfwd> #endif // !defined(ASIO_NO_IOSTREAM)@@ -48,44 +51,48 @@ { public: /// Default constructor.- ASIO_DECL address() noexcept;+ ASIO_DECL address() ASIO_NOEXCEPT; /// Construct an address from an IPv4 address. ASIO_DECL address(- const asio::ip::address_v4& ipv4_address) noexcept;+ const asio::ip::address_v4& ipv4_address) ASIO_NOEXCEPT; /// Construct an address from an IPv6 address. ASIO_DECL address(- const asio::ip::address_v6& ipv6_address) noexcept;+ const asio::ip::address_v6& ipv6_address) ASIO_NOEXCEPT; /// Copy constructor.- ASIO_DECL address(const address& other) noexcept;+ ASIO_DECL address(const address& other) ASIO_NOEXCEPT; +#if defined(ASIO_HAS_MOVE) /// Move constructor.- ASIO_DECL address(address&& other) noexcept;+ ASIO_DECL address(address&& other) ASIO_NOEXCEPT;+#endif // defined(ASIO_HAS_MOVE) /// Assign from another address.- ASIO_DECL address& operator=(const address& other) noexcept;+ ASIO_DECL address& operator=(const address& other) ASIO_NOEXCEPT; +#if defined(ASIO_HAS_MOVE) /// Move-assign from another address.- ASIO_DECL address& operator=(address&& other) noexcept;+ ASIO_DECL address& operator=(address&& other) ASIO_NOEXCEPT;+#endif // defined(ASIO_HAS_MOVE) /// Assign from an IPv4 address. ASIO_DECL address& operator=(- const asio::ip::address_v4& ipv4_address) noexcept;+ const asio::ip::address_v4& ipv4_address) ASIO_NOEXCEPT; /// Assign from an IPv6 address. ASIO_DECL address& operator=(- const asio::ip::address_v6& ipv6_address) noexcept;+ const asio::ip::address_v6& ipv6_address) ASIO_NOEXCEPT; /// Get whether the address is an IP version 4 address.- bool is_v4() const noexcept+ bool is_v4() const ASIO_NOEXCEPT { return type_ == ipv4; } /// Get whether the address is an IP version 6 address.- bool is_v6() const noexcept+ bool is_v6() const ASIO_NOEXCEPT { return type_ == ipv6; }@@ -99,47 +106,73 @@ /// Get the address as a string. ASIO_DECL std::string to_string() const; +#if !defined(ASIO_NO_DEPRECATED)+ /// (Deprecated: Use other overload.) Get the address as a string.+ ASIO_DECL std::string to_string(asio::error_code& ec) const;++ /// (Deprecated: Use make_address().) Create an address from an IPv4 address+ /// string in dotted decimal form, or from an IPv6 address in hexadecimal+ /// notation.+ static address from_string(const char* str);++ /// (Deprecated: Use make_address().) Create an address from an IPv4 address+ /// string in dotted decimal form, or from an IPv6 address in hexadecimal+ /// notation.+ static address from_string(const char* str, asio::error_code& ec);++ /// (Deprecated: Use make_address().) Create an address from an IPv4 address+ /// string in dotted decimal form, or from an IPv6 address in hexadecimal+ /// notation.+ static address from_string(const std::string& str);++ /// (Deprecated: Use make_address().) Create an address from an IPv4 address+ /// string in dotted decimal form, or from an IPv6 address in hexadecimal+ /// notation.+ static address from_string(+ const std::string& str, asio::error_code& ec);+#endif // !defined(ASIO_NO_DEPRECATED)+ /// Determine whether the address is a loopback address.- ASIO_DECL bool is_loopback() const noexcept;+ ASIO_DECL bool is_loopback() const ASIO_NOEXCEPT; /// Determine whether the address is unspecified.- ASIO_DECL bool is_unspecified() const noexcept;+ ASIO_DECL bool is_unspecified() const ASIO_NOEXCEPT; /// Determine whether the address is a multicast address.- ASIO_DECL bool is_multicast() const noexcept;+ ASIO_DECL bool is_multicast() const ASIO_NOEXCEPT; /// Compare two addresses for equality. ASIO_DECL friend bool operator==(const address& a1,- const address& a2) noexcept;+ const address& a2) ASIO_NOEXCEPT; /// Compare two addresses for inequality. friend bool operator!=(const address& a1,- const address& a2) noexcept+ const address& a2) ASIO_NOEXCEPT { return !(a1 == a2); } /// Compare addresses for ordering. ASIO_DECL friend bool operator<(const address& a1,- const address& a2) noexcept;+ const address& a2) ASIO_NOEXCEPT; /// Compare addresses for ordering. friend bool operator>(const address& a1,- const address& a2) noexcept+ const address& a2) ASIO_NOEXCEPT { return a2 < a1; } /// Compare addresses for ordering. friend bool operator<=(const address& a1,- const address& a2) noexcept+ const address& a2) ASIO_NOEXCEPT { return !(a2 < a1); } /// Compare addresses for ordering. friend bool operator>=(const address& a1,- const address& a2) noexcept+ const address& a2) ASIO_NOEXCEPT { return !(a1 < a2); }@@ -168,7 +201,7 @@ * @relates address */ ASIO_DECL address make_address(const char* str,- asio::error_code& ec) noexcept;+ asio::error_code& ec) ASIO_NOEXCEPT; /// Create an address from an IPv4 address string in dotted decimal form, /// or from an IPv6 address in hexadecimal notation.@@ -183,7 +216,7 @@ * @relates address */ ASIO_DECL address make_address(const std::string& str,- asio::error_code& ec) noexcept;+ asio::error_code& ec) ASIO_NOEXCEPT; #if defined(ASIO_HAS_STRING_VIEW) \ || defined(GENERATING_DOCUMENTATION)@@ -201,7 +234,7 @@ * @relates address */ ASIO_DECL address make_address(string_view str,- asio::error_code& ec) noexcept;+ asio::error_code& ec) ASIO_NOEXCEPT; #endif // defined(ASIO_HAS_STRING_VIEW) // || defined(GENERATING_DOCUMENTATION)@@ -229,13 +262,14 @@ } // namespace ip } // namespace asio +#if defined(ASIO_HAS_STD_HASH) namespace std { template <> struct hash<asio::ip::address> { std::size_t operator()(const asio::ip::address& addr)- const noexcept+ const ASIO_NOEXCEPT { return addr.is_v4() ? std::hash<asio::ip::address_v4>()(addr.to_v4())@@ -244,6 +278,7 @@ }; } // namespace std+#endif // defined(ASIO_HAS_STD_HASH) #include "asio/detail/pop_options.hpp"
link/modules/asio-standalone/asio/include/asio/ip/address_v4.hpp view
@@ -2,7 +2,7 @@ // ip/address_v4.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -16,7 +16,6 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"-#include <functional> #include <string> #include "asio/detail/array.hpp" #include "asio/detail/cstdint.hpp"@@ -25,6 +24,10 @@ #include "asio/detail/winsock_init.hpp" #include "asio/error_code.hpp" +#if defined(ASIO_HAS_STD_HASH)+# include <functional>+#endif // defined(ASIO_HAS_STD_HASH)+ #if !defined(ASIO_NO_IOSTREAM) # include <iosfwd> #endif // !defined(ASIO_NO_IOSTREAM)@@ -66,7 +69,7 @@ * @li <tt>to_bytes()</tt> yields <tt>{0, 0, 0, 0}</tt>; and * @li <tt>to_uint() == 0</tt>. */- address_v4() noexcept+ address_v4() ASIO_NOEXCEPT { addr_.s_addr = 0; }@@ -89,40 +92,74 @@ ASIO_DECL explicit address_v4(uint_type addr); /// Copy constructor.- address_v4(const address_v4& other) noexcept+ address_v4(const address_v4& other) ASIO_NOEXCEPT : addr_(other.addr_) { } +#if defined(ASIO_HAS_MOVE) /// Move constructor.- address_v4(address_v4&& other) noexcept+ address_v4(address_v4&& other) ASIO_NOEXCEPT : addr_(other.addr_) { }+#endif // defined(ASIO_HAS_MOVE) /// Assign from another address.- address_v4& operator=(const address_v4& other) noexcept+ address_v4& operator=(const address_v4& other) ASIO_NOEXCEPT { addr_ = other.addr_; return *this; } +#if defined(ASIO_HAS_MOVE) /// Move-assign from another address.- address_v4& operator=(address_v4&& other) noexcept+ address_v4& operator=(address_v4&& other) ASIO_NOEXCEPT { addr_ = other.addr_; return *this; }+#endif // defined(ASIO_HAS_MOVE) /// Get the address in bytes, in network byte order.- ASIO_DECL bytes_type to_bytes() const noexcept;+ ASIO_DECL bytes_type to_bytes() const ASIO_NOEXCEPT; /// Get the address as an unsigned integer in host byte order.- ASIO_DECL uint_type to_uint() const noexcept;+ ASIO_DECL uint_type to_uint() const ASIO_NOEXCEPT; +#if !defined(ASIO_NO_DEPRECATED)+ /// (Deprecated: Use to_uint().) Get the address as an unsigned long in host+ /// byte order.+ ASIO_DECL unsigned long to_ulong() const;+#endif // !defined(ASIO_NO_DEPRECATED)+ /// Get the address as a string in dotted decimal format. ASIO_DECL std::string to_string() const; +#if !defined(ASIO_NO_DEPRECATED)+ /// (Deprecated: Use other overload.) Get the address as a string in dotted+ /// decimal format.+ ASIO_DECL std::string to_string(asio::error_code& ec) const;++ /// (Deprecated: Use make_address_v4().) Create an address from an IP address+ /// string in dotted decimal form.+ static address_v4 from_string(const char* str);++ /// (Deprecated: Use make_address_v4().) Create an address from an IP address+ /// string in dotted decimal form.+ static address_v4 from_string(+ const char* str, asio::error_code& ec);++ /// (Deprecated: Use make_address_v4().) Create an address from an IP address+ /// string in dotted decimal form.+ static address_v4 from_string(const std::string& str);++ /// (Deprecated: Use make_address_v4().) Create an address from an IP address+ /// string in dotted decimal form.+ static address_v4 from_string(+ const std::string& str, asio::error_code& ec);+#endif // !defined(ASIO_NO_DEPRECATED)+ /// Determine whether the address is a loopback address. /** * This function tests whether the address is in the address block@@ -131,7 +168,7 @@ * * @returns <tt>(to_uint() & 0xFF000000) == 0x7F000000</tt>. */- ASIO_DECL bool is_loopback() const noexcept;+ ASIO_DECL bool is_loopback() const ASIO_NOEXCEPT; /// Determine whether the address is unspecified. /**@@ -140,8 +177,22 @@ * * @returns <tt>to_uint() == 0</tt>. */- ASIO_DECL bool is_unspecified() const noexcept;+ ASIO_DECL bool is_unspecified() const ASIO_NOEXCEPT; +#if !defined(ASIO_NO_DEPRECATED)+ /// (Deprecated: Use network_v4 class.) Determine whether the address is a+ /// class A address.+ ASIO_DECL bool is_class_a() const;++ /// (Deprecated: Use network_v4 class.) Determine whether the address is a+ /// class B address.+ ASIO_DECL bool is_class_b() const;++ /// (Deprecated: Use network_v4 class.) Determine whether the address is a+ /// class C address.+ ASIO_DECL bool is_class_c() const;+#endif // !defined(ASIO_NO_DEPRECATED)+ /// Determine whether the address is a multicast address. /** * This function tests whether the address is in the multicast address block@@ -150,18 +201,18 @@ * * @returns <tt>(to_uint() & 0xF0000000) == 0xE0000000</tt>. */- ASIO_DECL bool is_multicast() const noexcept;+ ASIO_DECL bool is_multicast() const ASIO_NOEXCEPT; /// Compare two addresses for equality. friend bool operator==(const address_v4& a1,- const address_v4& a2) noexcept+ const address_v4& a2) ASIO_NOEXCEPT { return a1.addr_.s_addr == a2.addr_.s_addr; } /// Compare two addresses for inequality. friend bool operator!=(const address_v4& a1,- const address_v4& a2) noexcept+ const address_v4& a2) ASIO_NOEXCEPT { return a1.addr_.s_addr != a2.addr_.s_addr; }@@ -173,7 +224,7 @@ * @returns <tt>a1.to_uint() < a2.to_uint()</tt>. */ friend bool operator<(const address_v4& a1,- const address_v4& a2) noexcept+ const address_v4& a2) ASIO_NOEXCEPT { return a1.to_uint() < a2.to_uint(); }@@ -185,7 +236,7 @@ * @returns <tt>a1.to_uint() > a2.to_uint()</tt>. */ friend bool operator>(const address_v4& a1,- const address_v4& a2) noexcept+ const address_v4& a2) ASIO_NOEXCEPT { return a1.to_uint() > a2.to_uint(); }@@ -197,7 +248,7 @@ * @returns <tt>a1.to_uint() <= a2.to_uint()</tt>. */ friend bool operator<=(const address_v4& a1,- const address_v4& a2) noexcept+ const address_v4& a2) ASIO_NOEXCEPT { return a1.to_uint() <= a2.to_uint(); }@@ -209,7 +260,7 @@ * @returns <tt>a1.to_uint() >= a2.to_uint()</tt>. */ friend bool operator>=(const address_v4& a1,- const address_v4& a2) noexcept+ const address_v4& a2) ASIO_NOEXCEPT { return a1.to_uint() >= a2.to_uint(); }@@ -221,7 +272,7 @@ * * @returns A default-constructed @c address_v4 object. */- static address_v4 any() noexcept+ static address_v4 any() ASIO_NOEXCEPT { return address_v4(); }@@ -233,7 +284,7 @@ * * @returns <tt>address_v4(0x7F000001)</tt>. */- static address_v4 loopback() noexcept+ static address_v4 loopback() ASIO_NOEXCEPT { return address_v4(0x7F000001); }@@ -245,11 +296,23 @@ * * @returns <tt>address_v4(0xFFFFFFFF)</tt>. */- static address_v4 broadcast() noexcept+ static address_v4 broadcast() ASIO_NOEXCEPT { return address_v4(0xFFFFFFFF); } +#if !defined(ASIO_NO_DEPRECATED)+ /// (Deprecated: Use network_v4 class.) Obtain an address object that+ /// represents the broadcast address that corresponds to the specified+ /// address and netmask.+ ASIO_DECL static address_v4 broadcast(+ const address_v4& addr, const address_v4& mask);++ /// (Deprecated: Use network_v4 class.) Obtain the netmask that corresponds+ /// to the address, based on its address class.+ ASIO_DECL static address_v4 netmask(const address_v4& addr);+#endif // !defined(ASIO_NO_DEPRECATED)+ private: // The underlying IPv4 address. asio::detail::in4_addr_type addr_;@@ -284,7 +347,7 @@ * @relates address_v4 */ ASIO_DECL address_v4 make_address_v4(const char* str,- asio::error_code& ec) noexcept;+ asio::error_code& ec) ASIO_NOEXCEPT; /// Create an IPv4 address from an IP address string in dotted decimal form. /**@@ -297,7 +360,7 @@ * @relates address_v4 */ ASIO_DECL address_v4 make_address_v4(const std::string& str,- asio::error_code& ec) noexcept;+ asio::error_code& ec) ASIO_NOEXCEPT; #if defined(ASIO_HAS_STRING_VIEW) \ || defined(GENERATING_DOCUMENTATION)@@ -313,7 +376,7 @@ * @relates address_v4 */ ASIO_DECL address_v4 make_address_v4(string_view str,- asio::error_code& ec) noexcept;+ asio::error_code& ec) ASIO_NOEXCEPT; #endif // defined(ASIO_HAS_STRING_VIEW) // || defined(GENERATING_DOCUMENTATION)@@ -341,19 +404,21 @@ } // namespace ip } // namespace asio +#if defined(ASIO_HAS_STD_HASH) namespace std { template <> struct hash<asio::ip::address_v4> { std::size_t operator()(const asio::ip::address_v4& addr)- const noexcept+ const ASIO_NOEXCEPT { return std::hash<unsigned int>()(addr.to_uint()); } }; } // namespace std+#endif // defined(ASIO_HAS_STD_HASH) #include "asio/detail/pop_options.hpp"
link/modules/asio-standalone/asio/include/asio/ip/address_v4_iterator.hpp view
@@ -2,7 +2,7 @@ // ip/address_v4_iterator.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -53,59 +53,65 @@ typedef std::input_iterator_tag iterator_category; /// Construct an iterator that points to the specified address.- basic_address_iterator(const address_v4& addr) noexcept+ basic_address_iterator(const address_v4& addr) ASIO_NOEXCEPT : address_(addr) { } /// Copy constructor.- basic_address_iterator(const basic_address_iterator& other) noexcept+ basic_address_iterator(+ const basic_address_iterator& other) ASIO_NOEXCEPT : address_(other.address_) { } +#if defined(ASIO_HAS_MOVE) /// Move constructor.- basic_address_iterator(basic_address_iterator&& other) noexcept- : address_(static_cast<address_v4&&>(other.address_))+ basic_address_iterator(basic_address_iterator&& other) ASIO_NOEXCEPT+ : address_(ASIO_MOVE_CAST(address_v4)(other.address_)) { }+#endif // defined(ASIO_HAS_MOVE) /// Assignment operator. basic_address_iterator& operator=(- const basic_address_iterator& other) noexcept+ const basic_address_iterator& other) ASIO_NOEXCEPT { address_ = other.address_; return *this; } +#if defined(ASIO_HAS_MOVE) /// Move assignment operator.- basic_address_iterator& operator=(basic_address_iterator&& other) noexcept+ basic_address_iterator& operator=(+ basic_address_iterator&& other) ASIO_NOEXCEPT {- address_ = static_cast<address_v4&&>(other.address_);+ address_ = ASIO_MOVE_CAST(address_v4)(other.address_); return *this; }+#endif // defined(ASIO_HAS_MOVE) /// Dereference the iterator.- const address_v4& operator*() const noexcept+ const address_v4& operator*() const ASIO_NOEXCEPT { return address_; } /// Dereference the iterator.- const address_v4* operator->() const noexcept+ const address_v4* operator->() const ASIO_NOEXCEPT { return &address_; } /// Pre-increment operator.- basic_address_iterator& operator++() noexcept+ basic_address_iterator& operator++() ASIO_NOEXCEPT { address_ = address_v4((address_.to_uint() + 1) & 0xFFFFFFFF); return *this; } /// Post-increment operator.- basic_address_iterator operator++(int) noexcept+ basic_address_iterator operator++(int) ASIO_NOEXCEPT { basic_address_iterator tmp(*this); ++*this;@@ -113,7 +119,7 @@ } /// Pre-decrement operator.- basic_address_iterator& operator--() noexcept+ basic_address_iterator& operator--() ASIO_NOEXCEPT { address_ = address_v4((address_.to_uint() - 1) & 0xFFFFFFFF); return *this;
link/modules/asio-standalone/asio/include/asio/ip/address_v4_range.hpp view
@@ -2,7 +2,7 @@ // ip/address_v4_range.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -38,7 +38,7 @@ typedef basic_address_iterator<address_v4> iterator; /// Construct an empty range.- basic_address_range() noexcept+ basic_address_range() ASIO_NOEXCEPT : begin_(address_v4()), end_(address_v4()) {@@ -46,68 +46,74 @@ /// Construct an range that represents the given range of addresses. explicit basic_address_range(const iterator& first,- const iterator& last) noexcept+ const iterator& last) ASIO_NOEXCEPT : begin_(first), end_(last) { } /// Copy constructor.- basic_address_range(const basic_address_range& other) noexcept+ basic_address_range(const basic_address_range& other) ASIO_NOEXCEPT : begin_(other.begin_), end_(other.end_) { } +#if defined(ASIO_HAS_MOVE) /// Move constructor.- basic_address_range(basic_address_range&& other) noexcept- : begin_(static_cast<iterator&&>(other.begin_)),- end_(static_cast<iterator&&>(other.end_))+ basic_address_range(basic_address_range&& other) ASIO_NOEXCEPT+ : begin_(ASIO_MOVE_CAST(iterator)(other.begin_)),+ end_(ASIO_MOVE_CAST(iterator)(other.end_)) { }+#endif // defined(ASIO_HAS_MOVE) /// Assignment operator.- basic_address_range& operator=(const basic_address_range& other) noexcept+ basic_address_range& operator=(+ const basic_address_range& other) ASIO_NOEXCEPT { begin_ = other.begin_; end_ = other.end_; return *this; } +#if defined(ASIO_HAS_MOVE) /// Move assignment operator.- basic_address_range& operator=(basic_address_range&& other) noexcept+ basic_address_range& operator=(+ basic_address_range&& other) ASIO_NOEXCEPT {- begin_ = static_cast<iterator&&>(other.begin_);- end_ = static_cast<iterator&&>(other.end_);+ begin_ = ASIO_MOVE_CAST(iterator)(other.begin_);+ end_ = ASIO_MOVE_CAST(iterator)(other.end_); return *this; }+#endif // defined(ASIO_HAS_MOVE) /// Obtain an iterator that points to the start of the range.- iterator begin() const noexcept+ iterator begin() const ASIO_NOEXCEPT { return begin_; } /// Obtain an iterator that points to the end of the range.- iterator end() const noexcept+ iterator end() const ASIO_NOEXCEPT { return end_; } /// Determine whether the range is empty.- bool empty() const noexcept+ bool empty() const ASIO_NOEXCEPT { return size() == 0; } /// Return the size of the range.- std::size_t size() const noexcept+ std::size_t size() const ASIO_NOEXCEPT { return end_->to_uint() - begin_->to_uint(); } /// Find an address in the range.- iterator find(const address_v4& addr) const noexcept+ iterator find(const address_v4& addr) const ASIO_NOEXCEPT { return addr >= *begin_ && addr < *end_ ? iterator(addr) : end_; }
link/modules/asio-standalone/asio/include/asio/ip/address_v6.hpp view
@@ -2,7 +2,7 @@ // ip/address_v6.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -16,7 +16,6 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"-#include <functional> #include <string> #include "asio/detail/array.hpp" #include "asio/detail/cstdint.hpp"@@ -26,6 +25,10 @@ #include "asio/error_code.hpp" #include "asio/ip/address_v4.hpp" +#if defined(ASIO_HAS_STD_HASH)+# include <functional>+#endif // defined(ASIO_HAS_STD_HASH)+ #if !defined(ASIO_NO_IOSTREAM) # include <iosfwd> #endif // !defined(ASIO_NO_IOSTREAM)@@ -69,7 +72,7 @@ * @li <tt>to_bytes()</tt> yields <tt>{0, 0, ..., 0}</tt>; and * @li <tt>scope_id() == 0</tt>. */- ASIO_DECL address_v6() noexcept;+ ASIO_DECL address_v6() ASIO_NOEXCEPT; /// Construct an address from raw bytes and scope ID. /**@@ -85,23 +88,27 @@ scope_id_type scope_id = 0); /// Copy constructor.- ASIO_DECL address_v6(const address_v6& other) noexcept;+ ASIO_DECL address_v6(const address_v6& other) ASIO_NOEXCEPT; +#if defined(ASIO_HAS_MOVE) /// Move constructor.- ASIO_DECL address_v6(address_v6&& other) noexcept;+ ASIO_DECL address_v6(address_v6&& other) ASIO_NOEXCEPT;+#endif // defined(ASIO_HAS_MOVE) /// Assign from another address. ASIO_DECL address_v6& operator=(- const address_v6& other) noexcept;+ const address_v6& other) ASIO_NOEXCEPT; +#if defined(ASIO_HAS_MOVE) /// Move-assign from another address.- ASIO_DECL address_v6& operator=(address_v6&& other) noexcept;+ ASIO_DECL address_v6& operator=(address_v6&& other) ASIO_NOEXCEPT;+#endif // defined(ASIO_HAS_MOVE) /// The scope ID of the address. /** * Returns the scope ID associated with the IPv6 address. */- scope_id_type scope_id() const noexcept+ scope_id_type scope_id() const ASIO_NOEXCEPT { return scope_id_; }@@ -112,90 +119,123 @@ * * @param id The new scope ID. */- void scope_id(scope_id_type id) noexcept+ void scope_id(scope_id_type id) ASIO_NOEXCEPT { scope_id_ = id; } /// Get the address in bytes, in network byte order.- ASIO_DECL bytes_type to_bytes() const noexcept;+ ASIO_DECL bytes_type to_bytes() const ASIO_NOEXCEPT; /// Get the address as a string. ASIO_DECL std::string to_string() const; +#if !defined(ASIO_NO_DEPRECATED)+ /// (Deprecated: Use other overload.) Get the address as a string.+ ASIO_DECL std::string to_string(asio::error_code& ec) const;++ /// (Deprecated: Use make_address_v6().) Create an IPv6 address from an IP+ /// address string.+ static address_v6 from_string(const char* str);++ /// (Deprecated: Use make_address_v6().) Create an IPv6 address from an IP+ /// address string.+ static address_v6 from_string(+ const char* str, asio::error_code& ec);++ /// (Deprecated: Use make_address_v6().) Create an IPv6 address from an IP+ /// address string.+ static address_v6 from_string(const std::string& str);++ /// (Deprecated: Use make_address_v6().) Create an IPv6 address from an IP+ /// address string.+ static address_v6 from_string(+ const std::string& str, asio::error_code& ec);++ /// (Deprecated: Use make_address_v4().) Converts an IPv4-mapped or+ /// IPv4-compatible address to an IPv4 address.+ ASIO_DECL address_v4 to_v4() const;+#endif // !defined(ASIO_NO_DEPRECATED)+ /// Determine whether the address is a loopback address. /** * This function tests whether the address is the loopback address * <tt>::1</tt>. */- ASIO_DECL bool is_loopback() const noexcept;+ ASIO_DECL bool is_loopback() const ASIO_NOEXCEPT; /// Determine whether the address is unspecified. /** * This function tests whether the address is the loopback address * <tt>::</tt>. */- ASIO_DECL bool is_unspecified() const noexcept;+ ASIO_DECL bool is_unspecified() const ASIO_NOEXCEPT; /// Determine whether the address is link local.- ASIO_DECL bool is_link_local() const noexcept;+ ASIO_DECL bool is_link_local() const ASIO_NOEXCEPT; /// Determine whether the address is site local.- ASIO_DECL bool is_site_local() const noexcept;+ ASIO_DECL bool is_site_local() const ASIO_NOEXCEPT; /// Determine whether the address is a mapped IPv4 address.- ASIO_DECL bool is_v4_mapped() const noexcept;+ ASIO_DECL bool is_v4_mapped() const ASIO_NOEXCEPT; +#if !defined(ASIO_NO_DEPRECATED)+ /// (Deprecated: No replacement.) Determine whether the address is an+ /// IPv4-compatible address.+ ASIO_DECL bool is_v4_compatible() const;+#endif // !defined(ASIO_NO_DEPRECATED)+ /// Determine whether the address is a multicast address.- ASIO_DECL bool is_multicast() const noexcept;+ ASIO_DECL bool is_multicast() const ASIO_NOEXCEPT; /// Determine whether the address is a global multicast address.- ASIO_DECL bool is_multicast_global() const noexcept;+ ASIO_DECL bool is_multicast_global() const ASIO_NOEXCEPT; /// Determine whether the address is a link-local multicast address.- ASIO_DECL bool is_multicast_link_local() const noexcept;+ ASIO_DECL bool is_multicast_link_local() const ASIO_NOEXCEPT; /// Determine whether the address is a node-local multicast address.- ASIO_DECL bool is_multicast_node_local() const noexcept;+ ASIO_DECL bool is_multicast_node_local() const ASIO_NOEXCEPT; /// Determine whether the address is a org-local multicast address.- ASIO_DECL bool is_multicast_org_local() const noexcept;+ ASIO_DECL bool is_multicast_org_local() const ASIO_NOEXCEPT; /// Determine whether the address is a site-local multicast address.- ASIO_DECL bool is_multicast_site_local() const noexcept;+ ASIO_DECL bool is_multicast_site_local() const ASIO_NOEXCEPT; /// Compare two addresses for equality. ASIO_DECL friend bool operator==(const address_v6& a1,- const address_v6& a2) noexcept;+ const address_v6& a2) ASIO_NOEXCEPT; /// Compare two addresses for inequality. friend bool operator!=(const address_v6& a1,- const address_v6& a2) noexcept+ const address_v6& a2) ASIO_NOEXCEPT { return !(a1 == a2); } /// Compare addresses for ordering. ASIO_DECL friend bool operator<(const address_v6& a1,- const address_v6& a2) noexcept;+ const address_v6& a2) ASIO_NOEXCEPT; /// Compare addresses for ordering. friend bool operator>(const address_v6& a1,- const address_v6& a2) noexcept+ const address_v6& a2) ASIO_NOEXCEPT { return a2 < a1; } /// Compare addresses for ordering. friend bool operator<=(const address_v6& a1,- const address_v6& a2) noexcept+ const address_v6& a2) ASIO_NOEXCEPT { return !(a2 < a1); } /// Compare addresses for ordering. friend bool operator>=(const address_v6& a1,- const address_v6& a2) noexcept+ const address_v6& a2) ASIO_NOEXCEPT { return !(a1 < a2); }@@ -207,7 +247,7 @@ * * @returns A default-constructed @c address_v6 object. */- static address_v6 any() noexcept+ static address_v6 any() ASIO_NOEXCEPT { return address_v6(); }@@ -217,8 +257,16 @@ * This function returns an address that represents the well-known loopback * address <tt>::1</tt>. */- ASIO_DECL static address_v6 loopback() noexcept;+ ASIO_DECL static address_v6 loopback() ASIO_NOEXCEPT; +#if !defined(ASIO_NO_DEPRECATED)+ /// (Deprecated: Use make_address_v6().) Create an IPv4-mapped IPv6 address.+ ASIO_DECL static address_v6 v4_mapped(const address_v4& addr);++ /// (Deprecated: No replacement.) Create an IPv4-compatible IPv6 address.+ ASIO_DECL static address_v6 v4_compatible(const address_v4& addr);+#endif // !defined(ASIO_NO_DEPRECATED)+ private: friend class basic_address_iterator<address_v6>; @@ -250,7 +298,7 @@ * @relates address_v6 */ ASIO_DECL address_v6 make_address_v6(const char* str,- asio::error_code& ec) noexcept;+ asio::error_code& ec) ASIO_NOEXCEPT; /// Createan IPv6 address from an IP address string. /**@@ -263,7 +311,7 @@ * @relates address_v6 */ ASIO_DECL address_v6 make_address_v6(const std::string& str,- asio::error_code& ec) noexcept;+ asio::error_code& ec) ASIO_NOEXCEPT; #if defined(ASIO_HAS_STRING_VIEW) \ || defined(GENERATING_DOCUMENTATION)@@ -279,7 +327,7 @@ * @relates address_v6 */ ASIO_DECL address_v6 make_address_v6(string_view str,- asio::error_code& ec) noexcept;+ asio::error_code& ec) ASIO_NOEXCEPT; #endif // defined(ASIO_HAS_STRING_VIEW) // || defined(GENERATING_DOCUMENTATION)@@ -325,13 +373,14 @@ } // namespace ip } // namespace asio +#if defined(ASIO_HAS_STD_HASH) namespace std { template <> struct hash<asio::ip::address_v6> { std::size_t operator()(const asio::ip::address_v6& addr)- const noexcept+ const ASIO_NOEXCEPT { const asio::ip::address_v6::bytes_type bytes = addr.to_bytes(); std::size_t result = static_cast<std::size_t>(addr.scope_id());@@ -355,6 +404,7 @@ }; } // namespace std+#endif // defined(ASIO_HAS_STD_HASH) #include "asio/detail/pop_options.hpp"
link/modules/asio-standalone/asio/include/asio/ip/address_v6_iterator.hpp view
@@ -2,7 +2,7 @@ // ip/address_v6_iterator.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Oliver Kowalke (oliver dot kowalke at gmail dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying@@ -54,53 +54,58 @@ typedef std::input_iterator_tag iterator_category; /// Construct an iterator that points to the specified address.- basic_address_iterator(const address_v6& addr) noexcept+ basic_address_iterator(const address_v6& addr) ASIO_NOEXCEPT : address_(addr) { } /// Copy constructor. basic_address_iterator(- const basic_address_iterator& other) noexcept+ const basic_address_iterator& other) ASIO_NOEXCEPT : address_(other.address_) { } +#if defined(ASIO_HAS_MOVE) /// Move constructor.- basic_address_iterator(basic_address_iterator&& other) noexcept- : address_(static_cast<address_v6&&>(other.address_))+ basic_address_iterator(basic_address_iterator&& other) ASIO_NOEXCEPT+ : address_(ASIO_MOVE_CAST(address_v6)(other.address_)) { }+#endif // defined(ASIO_HAS_MOVE) /// Assignment operator. basic_address_iterator& operator=(- const basic_address_iterator& other) noexcept+ const basic_address_iterator& other) ASIO_NOEXCEPT { address_ = other.address_; return *this; } +#if defined(ASIO_HAS_MOVE) /// Move assignment operator.- basic_address_iterator& operator=(basic_address_iterator&& other) noexcept+ basic_address_iterator& operator=(+ basic_address_iterator&& other) ASIO_NOEXCEPT {- address_ = static_cast<address_v6&&>(other.address_);+ address_ = ASIO_MOVE_CAST(address_v6)(other.address_); return *this; }+#endif // defined(ASIO_HAS_MOVE) /// Dereference the iterator.- const address_v6& operator*() const noexcept+ const address_v6& operator*() const ASIO_NOEXCEPT { return address_; } /// Dereference the iterator.- const address_v6* operator->() const noexcept+ const address_v6* operator->() const ASIO_NOEXCEPT { return &address_; } /// Pre-increment operator.- basic_address_iterator& operator++() noexcept+ basic_address_iterator& operator++() ASIO_NOEXCEPT { for (int i = 15; i >= 0; --i) {@@ -117,7 +122,7 @@ } /// Post-increment operator.- basic_address_iterator operator++(int) noexcept+ basic_address_iterator operator++(int) ASIO_NOEXCEPT { basic_address_iterator tmp(*this); ++*this;@@ -125,7 +130,7 @@ } /// Pre-decrement operator.- basic_address_iterator& operator--() noexcept+ basic_address_iterator& operator--() ASIO_NOEXCEPT { for (int i = 15; i >= 0; --i) {
link/modules/asio-standalone/asio/include/asio/ip/address_v6_range.hpp view
@@ -2,7 +2,7 @@ // ip/address_v6_range.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Oliver Kowalke (oliver dot kowalke at gmail dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying@@ -39,7 +39,7 @@ typedef basic_address_iterator<address_v6> iterator; /// Construct an empty range.- basic_address_range() noexcept+ basic_address_range() ASIO_NOEXCEPT : begin_(address_v6()), end_(address_v6()) {@@ -47,63 +47,68 @@ /// Construct an range that represents the given range of addresses. explicit basic_address_range(const iterator& first,- const iterator& last) noexcept+ const iterator& last) ASIO_NOEXCEPT : begin_(first), end_(last) { } /// Copy constructor.- basic_address_range(const basic_address_range& other) noexcept+ basic_address_range(const basic_address_range& other) ASIO_NOEXCEPT : begin_(other.begin_), end_(other.end_) { } +#if defined(ASIO_HAS_MOVE) /// Move constructor.- basic_address_range(basic_address_range&& other) noexcept- : begin_(static_cast<iterator&&>(other.begin_)),- end_(static_cast<iterator&&>(other.end_))+ basic_address_range(basic_address_range&& other) ASIO_NOEXCEPT+ : begin_(ASIO_MOVE_CAST(iterator)(other.begin_)),+ end_(ASIO_MOVE_CAST(iterator)(other.end_)) { }+#endif // defined(ASIO_HAS_MOVE) /// Assignment operator. basic_address_range& operator=(- const basic_address_range& other) noexcept+ const basic_address_range& other) ASIO_NOEXCEPT { begin_ = other.begin_; end_ = other.end_; return *this; } +#if defined(ASIO_HAS_MOVE) /// Move assignment operator.- basic_address_range& operator=(basic_address_range&& other) noexcept+ basic_address_range& operator=(+ basic_address_range&& other) ASIO_NOEXCEPT {- begin_ = static_cast<iterator&&>(other.begin_);- end_ = static_cast<iterator&&>(other.end_);+ begin_ = ASIO_MOVE_CAST(iterator)(other.begin_);+ end_ = ASIO_MOVE_CAST(iterator)(other.end_); return *this; }+#endif // defined(ASIO_HAS_MOVE) /// Obtain an iterator that points to the start of the range.- iterator begin() const noexcept+ iterator begin() const ASIO_NOEXCEPT { return begin_; } /// Obtain an iterator that points to the end of the range.- iterator end() const noexcept+ iterator end() const ASIO_NOEXCEPT { return end_; } /// Determine whether the range is empty.- bool empty() const noexcept+ bool empty() const ASIO_NOEXCEPT { return begin_ == end_; } /// Find an address in the range.- iterator find(const address_v6& addr) const noexcept+ iterator find(const address_v6& addr) const ASIO_NOEXCEPT { return addr >= *begin_ && addr < *end_ ? iterator(addr) : end_; }
link/modules/asio-standalone/asio/include/asio/ip/bad_address_cast.hpp view
@@ -2,7 +2,7 @@ // ip/bad_address_cast.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -35,21 +35,11 @@ /// Default constructor. bad_address_cast() {} - /// Copy constructor.- bad_address_cast(const bad_address_cast& other) noexcept-#if defined(ASIO_MSVC) && defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS- : std::exception(static_cast<const std::exception&>(other))-#else- : std::bad_cast(static_cast<const std::bad_cast&>(other))-#endif- {- }- /// Destructor.- virtual ~bad_address_cast() noexcept {}+ virtual ~bad_address_cast() ASIO_NOEXCEPT_OR_NOTHROW {} /// Get the message associated with the exception.- virtual const char* what() const noexcept+ virtual const char* what() const ASIO_NOEXCEPT_OR_NOTHROW { return "bad address cast"; }
link/modules/asio-standalone/asio/include/asio/ip/basic_endpoint.hpp view
@@ -2,7 +2,7 @@ // ip/basic_endpoint.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -16,11 +16,14 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"-#include <functional> #include "asio/detail/cstdint.hpp" #include "asio/ip/address.hpp" #include "asio/ip/detail/endpoint.hpp" +#if defined(ASIO_HAS_STD_HASH)+# include <functional>+#endif // defined(ASIO_HAS_STD_HASH)+ #if !defined(ASIO_NO_IOSTREAM) # include <iosfwd> #endif // !defined(ASIO_NO_IOSTREAM)@@ -61,7 +64,7 @@ #endif /// Default constructor.- basic_endpoint() noexcept+ basic_endpoint() ASIO_NOEXCEPT : impl_() { }@@ -83,7 +86,7 @@ * @endcode */ basic_endpoint(const InternetProtocol& internet_protocol,- port_type port_num) noexcept+ port_type port_num) ASIO_NOEXCEPT : impl_(internet_protocol.family(), port_num) { }@@ -92,39 +95,43 @@ /// constructor may be used for accepting connections on a specific interface /// or for making a connection to a remote endpoint. basic_endpoint(const asio::ip::address& addr,- port_type port_num) noexcept+ port_type port_num) ASIO_NOEXCEPT : impl_(addr, port_num) { } /// Copy constructor.- basic_endpoint(const basic_endpoint& other) noexcept+ basic_endpoint(const basic_endpoint& other) ASIO_NOEXCEPT : impl_(other.impl_) { } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move constructor.- basic_endpoint(basic_endpoint&& other) noexcept+ basic_endpoint(basic_endpoint&& other) ASIO_NOEXCEPT : impl_(other.impl_) { }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Assign from another endpoint.- basic_endpoint& operator=(const basic_endpoint& other) noexcept+ basic_endpoint& operator=(const basic_endpoint& other) ASIO_NOEXCEPT { impl_ = other.impl_; return *this; } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move-assign from another endpoint.- basic_endpoint& operator=(basic_endpoint&& other) noexcept+ basic_endpoint& operator=(basic_endpoint&& other) ASIO_NOEXCEPT { impl_ = other.impl_; return *this; }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// The protocol associated with the endpoint.- protocol_type protocol() const noexcept+ protocol_type protocol() const ASIO_NOEXCEPT { if (impl_.is_v4()) return InternetProtocol::v4();@@ -132,19 +139,19 @@ } /// Get the underlying endpoint in the native type.- data_type* data() noexcept+ data_type* data() ASIO_NOEXCEPT { return impl_.data(); } /// Get the underlying endpoint in the native type.- const data_type* data() const noexcept+ const data_type* data() const ASIO_NOEXCEPT { return impl_.data(); } /// Get the underlying size of the endpoint in the native type.- std::size_t size() const noexcept+ std::size_t size() const ASIO_NOEXCEPT { return impl_.size(); }@@ -156,75 +163,75 @@ } /// Get the capacity of the endpoint in the native type.- std::size_t capacity() const noexcept+ std::size_t capacity() const ASIO_NOEXCEPT { return impl_.capacity(); } /// Get the port associated with the endpoint. The port number is always in /// the host's byte order.- port_type port() const noexcept+ port_type port() const ASIO_NOEXCEPT { return impl_.port(); } /// Set the port associated with the endpoint. The port number is always in /// the host's byte order.- void port(port_type port_num) noexcept+ void port(port_type port_num) ASIO_NOEXCEPT { impl_.port(port_num); } /// Get the IP address associated with the endpoint.- asio::ip::address address() const noexcept+ asio::ip::address address() const ASIO_NOEXCEPT { return impl_.address(); } /// Set the IP address associated with the endpoint.- void address(const asio::ip::address& addr) noexcept+ void address(const asio::ip::address& addr) ASIO_NOEXCEPT { impl_.address(addr); } /// Compare two endpoints for equality. friend bool operator==(const basic_endpoint<InternetProtocol>& e1,- const basic_endpoint<InternetProtocol>& e2) noexcept+ const basic_endpoint<InternetProtocol>& e2) ASIO_NOEXCEPT { return e1.impl_ == e2.impl_; } /// Compare two endpoints for inequality. friend bool operator!=(const basic_endpoint<InternetProtocol>& e1,- const basic_endpoint<InternetProtocol>& e2) noexcept+ const basic_endpoint<InternetProtocol>& e2) ASIO_NOEXCEPT { return !(e1 == e2); } /// Compare endpoints for ordering. friend bool operator<(const basic_endpoint<InternetProtocol>& e1,- const basic_endpoint<InternetProtocol>& e2) noexcept+ const basic_endpoint<InternetProtocol>& e2) ASIO_NOEXCEPT { return e1.impl_ < e2.impl_; } /// Compare endpoints for ordering. friend bool operator>(const basic_endpoint<InternetProtocol>& e1,- const basic_endpoint<InternetProtocol>& e2) noexcept+ const basic_endpoint<InternetProtocol>& e2) ASIO_NOEXCEPT { return e2.impl_ < e1.impl_; } /// Compare endpoints for ordering. friend bool operator<=(const basic_endpoint<InternetProtocol>& e1,- const basic_endpoint<InternetProtocol>& e2) noexcept+ const basic_endpoint<InternetProtocol>& e2) ASIO_NOEXCEPT { return !(e2 < e1); } /// Compare endpoints for ordering. friend bool operator>=(const basic_endpoint<InternetProtocol>& e1,- const basic_endpoint<InternetProtocol>& e2) noexcept+ const basic_endpoint<InternetProtocol>& e2) ASIO_NOEXCEPT { return !(e1 < e2); }@@ -258,14 +265,15 @@ } // namespace ip } // namespace asio +#if defined(ASIO_HAS_STD_HASH) namespace std { template <typename InternetProtocol>-struct hash<asio::ip::basic_endpoint<InternetProtocol>>+struct hash<asio::ip::basic_endpoint<InternetProtocol> > { std::size_t operator()( const asio::ip::basic_endpoint<InternetProtocol>& ep)- const noexcept+ const ASIO_NOEXCEPT { std::size_t hash1 = std::hash<asio::ip::address>()(ep.address()); std::size_t hash2 = std::hash<unsigned short>()(ep.port());@@ -274,6 +282,7 @@ }; } // namespace std+#endif // defined(ASIO_HAS_STD_HASH) #include "asio/detail/pop_options.hpp"
link/modules/asio-standalone/asio/include/asio/ip/basic_resolver.hpp view
@@ -2,7 +2,7 @@ // ip/basic_resolver.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -17,7 +17,6 @@ #include "asio/detail/config.hpp" #include <string>-#include <utility> #include "asio/any_io_executor.hpp" #include "asio/async_result.hpp" #include "asio/detail/handler_type_requirements.hpp"@@ -37,6 +36,10 @@ # include "asio/detail/resolver_service.hpp" #endif +#if defined(ASIO_HAS_MOVE)+# include <utility>+#endif // defined(ASIO_HAS_MOVE)+ #include "asio/detail/push_options.hpp" namespace asio {@@ -85,6 +88,14 @@ /// The endpoint type. typedef typename InternetProtocol::endpoint endpoint_type; +#if !defined(ASIO_NO_DEPRECATED)+ /// (Deprecated.) The query type.+ typedef basic_resolver_query<InternetProtocol> query;++ /// (Deprecated.) The iterator type.+ typedef basic_resolver_iterator<InternetProtocol> iterator;+#endif // !defined(ASIO_NO_DEPRECATED)+ /// The results type. typedef basic_resolver_results<InternetProtocol> results_type; @@ -111,13 +122,14 @@ */ template <typename ExecutionContext> explicit basic_resolver(ExecutionContext& context,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- > = 0)+ >::type = 0) : impl_(0, 0, context) { } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move-construct a basic_resolver from another. /** * This constructor moves a resolver from one object to another.@@ -149,9 +161,9 @@ */ template <typename Executor1> basic_resolver(basic_resolver<InternetProtocol, Executor1>&& other,- constraint_t<+ typename constraint< is_convertible<Executor1, Executor>::value- > = 0)+ >::type = 0) : impl_(std::move(other.impl_)) { }@@ -187,15 +199,16 @@ * constructed using the @c basic_resolver(const executor_type&) constructor. */ template <typename Executor1>- constraint_t<+ typename constraint< is_convertible<Executor1, Executor>::value, basic_resolver&- > operator=(basic_resolver<InternetProtocol, Executor1>&& other)+ >::type operator=(basic_resolver<InternetProtocol, Executor1>&& other) { basic_resolver tmp(std::move(other)); impl_ = std::move(tmp.impl_); return *this; }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Destroys the resolver. /**@@ -208,7 +221,7 @@ } /// Get the executor associated with the object.- executor_type get_executor() noexcept+ executor_type get_executor() ASIO_NOEXCEPT { return impl_.get_executor(); }@@ -224,8 +237,50 @@ return impl_.get_service().cancel(impl_.get_implementation()); } +#if !defined(ASIO_NO_DEPRECATED)+ /// (Deprecated: Use overload with separate host and service parameters.) /// Perform forward resolution of a query to a list of entries. /**+ * This function is used to resolve a query into a list of endpoint entries.+ *+ * @param q A query object that determines what endpoints will be returned.+ *+ * @returns A range object representing the list of endpoint entries. A+ * successful call to this function is guaranteed to return a non-empty+ * range.+ *+ * @throws asio::system_error Thrown on failure.+ */+ results_type resolve(const query& q)+ {+ asio::error_code ec;+ results_type r = impl_.get_service().resolve(+ impl_.get_implementation(), q, ec);+ asio::detail::throw_error(ec, "resolve");+ return r;+ }++ /// (Deprecated: Use overload with separate host and service parameters.)+ /// Perform forward resolution of a query to a list of entries.+ /**+ * This function is used to resolve a query into a list of endpoint entries.+ *+ * @param q A query object that determines what endpoints will be returned.+ *+ * @param ec Set to indicate what error occurred, if any.+ *+ * @returns A range object representing the list of endpoint entries. An+ * empty range is returned if an error occurs. A successful call to this+ * function is guaranteed to return a non-empty range.+ */+ results_type resolve(const query& q, asio::error_code& ec)+ {+ return impl_.get_service().resolve(impl_.get_implementation(), q, ec);+ }+#endif // !defined(ASIO_NO_DEPRECATED)++ /// Perform forward resolution of a query to a list of entries.+ /** * This function is used to resolve host and service names into a list of * endpoint entries. *@@ -590,8 +645,58 @@ return impl_.get_service().resolve(impl_.get_implementation(), q, ec); } +#if !defined(ASIO_NO_DEPRECATED)+ /// (Deprecated: Use overload with separate host and service parameters.) /// Asynchronously perform forward resolution of a query to a list of entries. /**+ * This function is used to asynchronously resolve a query into a list of+ * endpoint entries. It is an initiating function for an @ref+ * asynchronous_operation, and always returns immediately.+ *+ * @param q A query object that determines what endpoints will be returned.+ *+ * @param token The @ref completion_token that will be used to produce a+ * completion handler, which will be called when the resolve completes.+ * Potential completion tokens include @ref use_future, @ref use_awaitable,+ * @ref yield_context, or a function object with the correct completion+ * signature. The function signature of the completion handler must be:+ * @code void handler(+ * const asio::error_code& error, // Result of operation.+ * resolver::results_type results // Resolved endpoints as a range.+ * ); @endcode+ * Regardless of whether the asynchronous operation completes immediately or+ * not, the completion handler will not be invoked from within this function.+ * On immediate completion, invocation of the handler will be performed in a+ * manner equivalent to using asio::post().+ *+ * A successful resolve operation is guaranteed to pass a non-empty range to+ * the handler.+ *+ * @par Completion Signature+ * @code void(asio::error_code, results_type) @endcode+ */+ template <+ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+ results_type)) ResolveToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ResolveToken,+ void (asio::error_code, results_type))+ async_resolve(const query& q,+ ASIO_MOVE_ARG(ResolveToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ asio::async_initiate<ResolveToken,+ void (asio::error_code, results_type)>(+ declval<initiate_async_resolve>(), token, q)))+ {+ return asio::async_initiate<ResolveToken,+ void (asio::error_code, results_type)>(+ initiate_async_resolve(this), token, q);+ }+#endif // !defined(ASIO_NO_DEPRECATED)++ /// Asynchronously perform forward resolution of a query to a list of entries.+ /** * This function is used to resolve host and service names into a list of * endpoint entries. *@@ -618,7 +723,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * A successful resolve operation is guaranteed to pass a non-empty range to * the handler.@@ -639,18 +744,22 @@ */ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- results_type)) ResolveToken = default_completion_token_t<executor_type>>- auto async_resolve(ASIO_STRING_VIEW_PARAM host,+ results_type)) ResolveToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ResolveToken,+ void (asio::error_code, results_type))+ async_resolve(ASIO_STRING_VIEW_PARAM host, ASIO_STRING_VIEW_PARAM service,- ResolveToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ ASIO_MOVE_ARG(ResolveToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( asio::async_initiate<ResolveToken, void (asio::error_code, results_type)>( declval<initiate_async_resolve>(), token,- declval<basic_resolver_query<protocol_type>&>()))+ declval<basic_resolver_query<protocol_type>&>()))) { return async_resolve(host, service, resolver_base::flags(),- static_cast<ResolveToken&&>(token));+ ASIO_MOVE_CAST(ResolveToken)(token)); } /// Asynchronously perform forward resolution of a query to a list of entries.@@ -687,7 +796,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * A successful resolve operation is guaranteed to pass a non-empty range to * the handler.@@ -708,15 +817,20 @@ */ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- results_type)) ResolveToken = default_completion_token_t<executor_type>>- auto async_resolve(ASIO_STRING_VIEW_PARAM host,- ASIO_STRING_VIEW_PARAM service, resolver_base::flags resolve_flags,- ResolveToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ results_type)) ResolveToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ResolveToken,+ void (asio::error_code, results_type))+ async_resolve(ASIO_STRING_VIEW_PARAM host,+ ASIO_STRING_VIEW_PARAM service,+ resolver_base::flags resolve_flags,+ ASIO_MOVE_ARG(ResolveToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( asio::async_initiate<ResolveToken, void (asio::error_code, results_type)>( declval<initiate_async_resolve>(), token,- declval<basic_resolver_query<protocol_type>&>()))+ declval<basic_resolver_query<protocol_type>&>()))) { basic_resolver_query<protocol_type> q(static_cast<std::string>(host), static_cast<std::string>(service), resolve_flags);@@ -758,7 +872,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * A successful resolve operation is guaranteed to pass a non-empty range to * the handler.@@ -779,18 +893,22 @@ */ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- results_type)) ResolveToken = default_completion_token_t<executor_type>>- auto async_resolve(const protocol_type& protocol,+ results_type)) ResolveToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ResolveToken,+ void (asio::error_code, results_type))+ async_resolve(const protocol_type& protocol, ASIO_STRING_VIEW_PARAM host, ASIO_STRING_VIEW_PARAM service,- ResolveToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ ASIO_MOVE_ARG(ResolveToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( asio::async_initiate<ResolveToken, void (asio::error_code, results_type)>( declval<initiate_async_resolve>(), token,- declval<basic_resolver_query<protocol_type>&>()))+ declval<basic_resolver_query<protocol_type>&>()))) { return async_resolve(protocol, host, service, resolver_base::flags(),- static_cast<ResolveToken&&>(token));+ ASIO_MOVE_CAST(ResolveToken)(token)); } /// Asynchronously perform forward resolution of a query to a list of entries.@@ -830,7 +948,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * A successful resolve operation is guaranteed to pass a non-empty range to * the handler.@@ -851,16 +969,20 @@ */ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- results_type)) ResolveToken = default_completion_token_t<executor_type>>- auto async_resolve(const protocol_type& protocol,+ results_type)) ResolveToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ResolveToken,+ void (asio::error_code, results_type))+ async_resolve(const protocol_type& protocol, ASIO_STRING_VIEW_PARAM host, ASIO_STRING_VIEW_PARAM service, resolver_base::flags resolve_flags,- ResolveToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ ASIO_MOVE_ARG(ResolveToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( asio::async_initiate<ResolveToken, void (asio::error_code, results_type)>( declval<initiate_async_resolve>(), token,- declval<basic_resolver_query<protocol_type>&>()))+ declval<basic_resolver_query<protocol_type>&>()))) { basic_resolver_query<protocol_type> q( protocol, static_cast<std::string>(host),@@ -935,7 +1057,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * A successful resolve operation is guaranteed to pass a non-empty range to * the handler.@@ -945,13 +1067,17 @@ */ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- results_type)) ResolveToken = default_completion_token_t<executor_type>>- auto async_resolve(const endpoint_type& e,- ResolveToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ results_type)) ResolveToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ResolveToken,+ void (asio::error_code, results_type))+ async_resolve(const endpoint_type& e,+ ASIO_MOVE_ARG(ResolveToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( asio::async_initiate<ResolveToken, void (asio::error_code, results_type)>(- declval<initiate_async_resolve>(), token, e))+ declval<initiate_async_resolve>(), token, e))) { return asio::async_initiate<ResolveToken, void (asio::error_code, results_type)>(@@ -960,8 +1086,8 @@ private: // Disallow copying and assignment.- basic_resolver(const basic_resolver&) = delete;- basic_resolver& operator=(const basic_resolver&) = delete;+ basic_resolver(const basic_resolver&) ASIO_DELETED;+ basic_resolver& operator=(const basic_resolver&) ASIO_DELETED; class initiate_async_resolve {@@ -973,13 +1099,13 @@ { } - executor_type get_executor() const noexcept+ executor_type get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template <typename ResolveHandler, typename Query>- void operator()(ResolveHandler&& handler,+ void operator()(ASIO_MOVE_ARG(ResolveHandler) handler, const Query& q) const { // If you get an error on the following line it means that your handler
link/modules/asio-standalone/asio/include/asio/ip/basic_resolver_entry.hpp view
@@ -2,7 +2,7 @@ // ip/basic_resolver_entry.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/ip/basic_resolver_iterator.hpp view
@@ -2,7 +2,7 @@ // ip/basic_resolver_iterator.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -79,13 +79,15 @@ { } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move constructor. basic_resolver_iterator(basic_resolver_iterator&& other)- : values_(static_cast<values_ptr_type&&>(other.values_)),+ : values_(ASIO_MOVE_CAST(values_ptr_type)(other.values_)), index_(other.index_) { other.index_ = 0; }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Assignment operator. basic_resolver_iterator& operator=(const basic_resolver_iterator& other)@@ -95,18 +97,20 @@ return *this; } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move-assignment operator. basic_resolver_iterator& operator=(basic_resolver_iterator&& other) { if (this != &other) {- values_ = static_cast<values_ptr_type&&>(other.values_);+ values_ = ASIO_MOVE_CAST(values_ptr_type)(other.values_); index_ = other.index_; other.index_ = 0; } return *this; }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Dereference an iterator. const basic_resolver_entry<InternetProtocol>& operator*() const@@ -174,7 +178,7 @@ return (*values_)[index_]; } - typedef std::vector<basic_resolver_entry<InternetProtocol>> values_type;+ typedef std::vector<basic_resolver_entry<InternetProtocol> > values_type; typedef asio::detail::shared_ptr<values_type> values_ptr_type; values_ptr_type values_; std::size_t index_;
link/modules/asio-standalone/asio/include/asio/ip/basic_resolver_query.hpp view
@@ -2,7 +2,7 @@ // ip/basic_resolver_query.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -210,22 +210,6 @@ hints_.ai_canonname = 0; hints_.ai_addr = 0; hints_.ai_next = 0;- }-- /// Copy construct a @c basic_resolver_query from another.- basic_resolver_query(const basic_resolver_query& other)- : hints_(other.hints_),- host_name_(other.host_name_),- service_name_(other.service_name_)- {- }-- /// Move construct a @c basic_resolver_query from another.- basic_resolver_query(basic_resolver_query&& other)- : hints_(other.hints_),- host_name_(static_cast<std::string&&>(other.host_name_)),- service_name_(static_cast<std::string&&>(other.service_name_))- { } /// Get the hints associated with the query.
link/modules/asio-standalone/asio/include/asio/ip/basic_resolver_results.hpp view
@@ -2,7 +2,7 @@ // ip/basic_resolver_results.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -48,7 +48,11 @@ */ template <typename InternetProtocol> class basic_resolver_results+#if !defined(ASIO_NO_DEPRECATED)+ : public basic_resolver_iterator<InternetProtocol>+#else // !defined(ASIO_NO_DEPRECATED) : private basic_resolver_iterator<InternetProtocol>+#endif // !defined(ASIO_NO_DEPRECATED) { public: /// The protocol type associated with the results.@@ -89,12 +93,14 @@ { } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move constructor. basic_resolver_results(basic_resolver_results&& other) : basic_resolver_iterator<InternetProtocol>(- static_cast<basic_resolver_results&&>(other))+ ASIO_MOVE_CAST(basic_resolver_results)(other)) { }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Assignment operator. basic_resolver_results& operator=(const basic_resolver_results& other)@@ -103,13 +109,15 @@ return *this; } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move-assignment operator. basic_resolver_results& operator=(basic_resolver_results&& other) { basic_resolver_iterator<InternetProtocol>::operator=(- static_cast<basic_resolver_results&&>(other));+ ASIO_MOVE_CAST(basic_resolver_results)(other)); return *this; }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) #if !defined(GENERATING_DOCUMENTATION) // Create results from an addrinfo list returned by getaddrinfo.@@ -222,19 +230,19 @@ #endif // !defined(GENERATING_DOCUMENTATION) /// Get the number of entries in the results range.- size_type size() const noexcept+ size_type size() const ASIO_NOEXCEPT { return this->values_ ? this->values_->size() : 0; } /// Get the maximum number of entries permitted in a results range.- size_type max_size() const noexcept+ size_type max_size() const ASIO_NOEXCEPT { return this->values_ ? this->values_->max_size() : values_type().max_size(); } /// Determine whether the results range is empty.- bool empty() const noexcept+ bool empty() const ASIO_NOEXCEPT { return this->values_ ? this->values_->empty() : true; }@@ -244,7 +252,7 @@ { basic_resolver_results tmp(*this); tmp.index_ = 0;- return static_cast<basic_resolver_results&&>(tmp);+ return ASIO_MOVE_CAST(basic_resolver_results)(tmp); } /// Obtain an end iterator for the results range.@@ -266,7 +274,7 @@ } /// Swap the results range with another.- void swap(basic_resolver_results& that) noexcept+ void swap(basic_resolver_results& that) ASIO_NOEXCEPT { if (this != &that) {@@ -292,7 +300,7 @@ } private:- typedef std::vector<basic_resolver_entry<InternetProtocol>> values_type;+ typedef std::vector<basic_resolver_entry<InternetProtocol> > values_type; }; } // namespace ip
link/modules/asio-standalone/asio/include/asio/ip/detail/endpoint.hpp view
@@ -2,7 +2,7 @@ // ip/detail/endpoint.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -28,48 +28,48 @@ namespace ip { namespace detail { -// Helper class for implementing an IP endpoint.+// Helper class for implementating an IP endpoint. class endpoint { public: // Default constructor.- ASIO_DECL endpoint() noexcept;+ ASIO_DECL endpoint() ASIO_NOEXCEPT; // Construct an endpoint using a family and port number. ASIO_DECL endpoint(int family,- unsigned short port_num) noexcept;+ unsigned short port_num) ASIO_NOEXCEPT; // Construct an endpoint using an address and port number. ASIO_DECL endpoint(const asio::ip::address& addr,- unsigned short port_num) noexcept;+ unsigned short port_num) ASIO_NOEXCEPT; // Copy constructor.- endpoint(const endpoint& other) noexcept+ endpoint(const endpoint& other) ASIO_NOEXCEPT : data_(other.data_) { } // Assign from another endpoint.- endpoint& operator=(const endpoint& other) noexcept+ endpoint& operator=(const endpoint& other) ASIO_NOEXCEPT { data_ = other.data_; return *this; } // Get the underlying endpoint in the native type.- asio::detail::socket_addr_type* data() noexcept+ asio::detail::socket_addr_type* data() ASIO_NOEXCEPT {- return &data_.base[0];+ return &data_.base; } // Get the underlying endpoint in the native type.- const asio::detail::socket_addr_type* data() const noexcept+ const asio::detail::socket_addr_type* data() const ASIO_NOEXCEPT {- return &data_.base[0];+ return &data_.base; } // Get the underlying size of the endpoint in the native type.- std::size_t size() const noexcept+ std::size_t size() const ASIO_NOEXCEPT { if (is_v4()) return sizeof(asio::detail::sockaddr_in4_type);@@ -81,36 +81,36 @@ ASIO_DECL void resize(std::size_t new_size); // Get the capacity of the endpoint in the native type.- std::size_t capacity() const noexcept+ std::size_t capacity() const ASIO_NOEXCEPT { return sizeof(data_); } // Get the port associated with the endpoint.- ASIO_DECL unsigned short port() const noexcept;+ ASIO_DECL unsigned short port() const ASIO_NOEXCEPT; // Set the port associated with the endpoint.- ASIO_DECL void port(unsigned short port_num) noexcept;+ ASIO_DECL void port(unsigned short port_num) ASIO_NOEXCEPT; // Get the IP address associated with the endpoint.- ASIO_DECL asio::ip::address address() const noexcept;+ ASIO_DECL asio::ip::address address() const ASIO_NOEXCEPT; // Set the IP address associated with the endpoint. ASIO_DECL void address(- const asio::ip::address& addr) noexcept;+ const asio::ip::address& addr) ASIO_NOEXCEPT; // Compare two endpoints for equality. ASIO_DECL friend bool operator==(const endpoint& e1,- const endpoint& e2) noexcept;+ const endpoint& e2) ASIO_NOEXCEPT; // Compare endpoints for ordering. ASIO_DECL friend bool operator<(const endpoint& e1,- const endpoint& e2) noexcept;+ const endpoint& e2) ASIO_NOEXCEPT; // Determine whether the endpoint is IPv4.- bool is_v4() const noexcept+ bool is_v4() const ASIO_NOEXCEPT {- return data_.base[0].sa_family == ASIO_OS_DEF(AF_INET);+ return data_.base.sa_family == ASIO_OS_DEF(AF_INET); } #if !defined(ASIO_NO_IOSTREAM)@@ -122,11 +122,7 @@ // The underlying IP socket address. union data_union {-#if defined(_FORTIFY_SOURCE)- asio::detail::socket_addr_type base[8];-#else // defined(_FORTIFY_SOURCE)- asio::detail::socket_addr_type base[1];-#endif // defined(_FORTIFY_SOURCE)+ asio::detail::socket_addr_type base; asio::detail::sockaddr_in4_type v4; asio::detail::sockaddr_in6_type v6; } data_;
link/modules/asio-standalone/asio/include/asio/ip/detail/impl/endpoint.ipp view
@@ -2,7 +2,7 @@ // ip/detail/impl/endpoint.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -31,7 +31,7 @@ namespace ip { namespace detail { -endpoint::endpoint() noexcept+endpoint::endpoint() ASIO_NOEXCEPT : data_() { data_.v4.sin_family = ASIO_OS_DEF(AF_INET);@@ -39,7 +39,7 @@ data_.v4.sin_addr.s_addr = ASIO_OS_DEF(INADDR_ANY); } -endpoint::endpoint(int family, unsigned short port_num) noexcept+endpoint::endpoint(int family, unsigned short port_num) ASIO_NOEXCEPT : data_() { using namespace std; // For memcpy.@@ -69,7 +69,7 @@ } endpoint::endpoint(const asio::ip::address& addr,- unsigned short port_num) noexcept+ unsigned short port_num) ASIO_NOEXCEPT : data_() { using namespace std; // For memcpy.@@ -106,7 +106,7 @@ } } -unsigned short endpoint::port() const noexcept+unsigned short endpoint::port() const ASIO_NOEXCEPT { if (is_v4()) {@@ -120,7 +120,7 @@ } } -void endpoint::port(unsigned short port_num) noexcept+void endpoint::port(unsigned short port_num) ASIO_NOEXCEPT { if (is_v4()) {@@ -134,7 +134,7 @@ } } -asio::ip::address endpoint::address() const noexcept+asio::ip::address endpoint::address() const ASIO_NOEXCEPT { using namespace std; // For memcpy. if (is_v4())@@ -146,23 +146,27 @@ else { asio::ip::address_v6::bytes_type bytes;+#if defined(ASIO_HAS_STD_ARRAY) memcpy(bytes.data(), data_.v6.sin6_addr.s6_addr, 16);+#else // defined(ASIO_HAS_STD_ARRAY)+ memcpy(bytes.elems, data_.v6.sin6_addr.s6_addr, 16);+#endif // defined(ASIO_HAS_STD_ARRAY) return asio::ip::address_v6(bytes, data_.v6.sin6_scope_id); } } -void endpoint::address(const asio::ip::address& addr) noexcept+void endpoint::address(const asio::ip::address& addr) ASIO_NOEXCEPT { endpoint tmp_endpoint(addr, port()); data_ = tmp_endpoint.data_; } -bool operator==(const endpoint& e1, const endpoint& e2) noexcept+bool operator==(const endpoint& e1, const endpoint& e2) ASIO_NOEXCEPT { return e1.address() == e2.address() && e1.port() == e2.port(); } -bool operator<(const endpoint& e1, const endpoint& e2) noexcept+bool operator<(const endpoint& e1, const endpoint& e2) ASIO_NOEXCEPT { if (e1.address() < e2.address()) return true;
link/modules/asio-standalone/asio/include/asio/ip/detail/socket_option.hpp view
@@ -2,7 +2,7 @@ // detail/socket_option.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -39,7 +39,7 @@ #if defined(__sun) || defined(__osf__) typedef unsigned char ipv4_value_type; typedef unsigned char ipv6_value_type;-#elif defined(_AIX) || defined(__hpux) || defined(__QNXNTO__)+#elif defined(_AIX) || defined(__hpux) || defined(__QNXNTO__) typedef unsigned char ipv4_value_type; typedef unsigned int ipv6_value_type; #else
link/modules/asio-standalone/asio/include/asio/ip/host_name.hpp view
@@ -2,7 +2,7 @@ // ip/host_name.hpp // ~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/ip/icmp.hpp view
@@ -2,7 +2,7 @@ // ip/icmp.hpp // ~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -46,33 +46,33 @@ typedef basic_endpoint<icmp> endpoint; /// Construct to represent the IPv4 ICMP protocol.- static icmp v4() noexcept+ static icmp v4() ASIO_NOEXCEPT { return icmp(ASIO_OS_DEF(IPPROTO_ICMP), ASIO_OS_DEF(AF_INET)); } /// Construct to represent the IPv6 ICMP protocol.- static icmp v6() noexcept+ static icmp v6() ASIO_NOEXCEPT { return icmp(ASIO_OS_DEF(IPPROTO_ICMPV6), ASIO_OS_DEF(AF_INET6)); } /// Obtain an identifier for the type of the protocol.- int type() const noexcept+ int type() const ASIO_NOEXCEPT { return ASIO_OS_DEF(SOCK_RAW); } /// Obtain an identifier for the protocol.- int protocol() const noexcept+ int protocol() const ASIO_NOEXCEPT { return protocol_; } /// Obtain an identifier for the protocol family.- int family() const noexcept+ int family() const ASIO_NOEXCEPT { return family_; }@@ -97,7 +97,7 @@ private: // Construct with a specific family.- explicit icmp(int protocol_id, int protocol_family) noexcept+ explicit icmp(int protocol_id, int protocol_family) ASIO_NOEXCEPT : protocol_(protocol_id), family_(protocol_family) {
link/modules/asio-standalone/asio/include/asio/ip/impl/address.hpp view
@@ -2,7 +2,7 @@ // ip/impl/address.hpp // ~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -17,10 +17,38 @@ #if !defined(ASIO_NO_IOSTREAM) +#include "asio/detail/throw_error.hpp"+ #include "asio/detail/push_options.hpp" namespace asio { namespace ip {++#if !defined(ASIO_NO_DEPRECATED)++inline address address::from_string(const char* str)+{+ return asio::ip::make_address(str);+}++inline address address::from_string(+ const char* str, asio::error_code& ec)+{+ return asio::ip::make_address(str, ec);+}++inline address address::from_string(const std::string& str)+{+ return asio::ip::make_address(str);+}++inline address address::from_string(+ const std::string& str, asio::error_code& ec)+{+ return asio::ip::make_address(str, ec);+}++#endif // !defined(ASIO_NO_DEPRECATED) template <typename Elem, typename Traits> std::basic_ostream<Elem, Traits>& operator<<(
link/modules/asio-standalone/asio/include/asio/ip/impl/address.ipp view
@@ -2,7 +2,7 @@ // ip/impl/address.ipp // ~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -29,7 +29,7 @@ namespace asio { namespace ip { -address::address() noexcept+address::address() ASIO_NOEXCEPT : type_(ipv4), ipv4_address_(), ipv6_address_()@@ -37,7 +37,7 @@ } address::address(- const asio::ip::address_v4& ipv4_address) noexcept+ const asio::ip::address_v4& ipv4_address) ASIO_NOEXCEPT : type_(ipv4), ipv4_address_(ipv4_address), ipv6_address_()@@ -45,28 +45,30 @@ } address::address(- const asio::ip::address_v6& ipv6_address) noexcept+ const asio::ip::address_v6& ipv6_address) ASIO_NOEXCEPT : type_(ipv6), ipv4_address_(), ipv6_address_(ipv6_address) { } -address::address(const address& other) noexcept+address::address(const address& other) ASIO_NOEXCEPT : type_(other.type_), ipv4_address_(other.ipv4_address_), ipv6_address_(other.ipv6_address_) { } -address::address(address&& other) noexcept+#if defined(ASIO_HAS_MOVE)+address::address(address&& other) ASIO_NOEXCEPT : type_(other.type_), ipv4_address_(other.ipv4_address_), ipv6_address_(other.ipv6_address_) { }+#endif // defined(ASIO_HAS_MOVE) -address& address::operator=(const address& other) noexcept+address& address::operator=(const address& other) ASIO_NOEXCEPT { type_ = other.type_; ipv4_address_ = other.ipv4_address_;@@ -74,16 +76,18 @@ return *this; } -address& address::operator=(address&& other) noexcept+#if defined(ASIO_HAS_MOVE)+address& address::operator=(address&& other) ASIO_NOEXCEPT { type_ = other.type_; ipv4_address_ = other.ipv4_address_; ipv6_address_ = other.ipv6_address_; return *this; }+#endif // defined(ASIO_HAS_MOVE) address& address::operator=(- const asio::ip::address_v4& ipv4_address) noexcept+ const asio::ip::address_v4& ipv4_address) ASIO_NOEXCEPT { type_ = ipv4; ipv4_address_ = ipv4_address;@@ -92,7 +96,7 @@ } address& address::operator=(- const asio::ip::address_v6& ipv6_address) noexcept+ const asio::ip::address_v6& ipv6_address) ASIO_NOEXCEPT { type_ = ipv6; ipv4_address_ = asio::ip::address_v4();@@ -109,7 +113,7 @@ } address make_address(const char* str,- asio::error_code& ec) noexcept+ asio::error_code& ec) ASIO_NOEXCEPT { asio::ip::address_v6 ipv6_address = asio::ip::make_address_v6(str, ec);@@ -130,7 +134,7 @@ } address make_address(const std::string& str,- asio::error_code& ec) noexcept+ asio::error_code& ec) ASIO_NOEXCEPT { return make_address(str.c_str(), ec); }@@ -143,7 +147,7 @@ } address make_address(string_view str,- asio::error_code& ec) noexcept+ asio::error_code& ec) ASIO_NOEXCEPT { return make_address(static_cast<std::string>(str), ec); }@@ -177,28 +181,37 @@ return ipv4_address_.to_string(); } -bool address::is_loopback() const noexcept+#if !defined(ASIO_NO_DEPRECATED)+std::string address::to_string(asio::error_code& ec) const {+ if (type_ == ipv6)+ return ipv6_address_.to_string(ec);+ return ipv4_address_.to_string(ec);+}+#endif // !defined(ASIO_NO_DEPRECATED)++bool address::is_loopback() const ASIO_NOEXCEPT+{ return (type_ == ipv4) ? ipv4_address_.is_loopback() : ipv6_address_.is_loopback(); } -bool address::is_unspecified() const noexcept+bool address::is_unspecified() const ASIO_NOEXCEPT { return (type_ == ipv4) ? ipv4_address_.is_unspecified() : ipv6_address_.is_unspecified(); } -bool address::is_multicast() const noexcept+bool address::is_multicast() const ASIO_NOEXCEPT { return (type_ == ipv4) ? ipv4_address_.is_multicast() : ipv6_address_.is_multicast(); } -bool operator==(const address& a1, const address& a2) noexcept+bool operator==(const address& a1, const address& a2) ASIO_NOEXCEPT { if (a1.type_ != a2.type_) return false;@@ -207,7 +220,7 @@ return a1.ipv4_address_ == a2.ipv4_address_; } -bool operator<(const address& a1, const address& a2) noexcept+bool operator<(const address& a1, const address& a2) ASIO_NOEXCEPT { if (a1.type_ < a2.type_) return true;
link/modules/asio-standalone/asio/include/asio/ip/impl/address_v4.hpp view
@@ -2,7 +2,7 @@ // ip/impl/address_v4.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -17,10 +17,38 @@ #if !defined(ASIO_NO_IOSTREAM) +#include "asio/detail/throw_error.hpp"+ #include "asio/detail/push_options.hpp" namespace asio { namespace ip {++#if !defined(ASIO_NO_DEPRECATED)++inline address_v4 address_v4::from_string(const char* str)+{+ return asio::ip::make_address_v4(str);+}++inline address_v4 address_v4::from_string(+ const char* str, asio::error_code& ec)+{+ return asio::ip::make_address_v4(str, ec);+}++inline address_v4 address_v4::from_string(const std::string& str)+{+ return asio::ip::make_address_v4(str);+}++inline address_v4 address_v4::from_string(+ const std::string& str, asio::error_code& ec)+{+ return asio::ip::make_address_v4(str, ec);+}++#endif // !defined(ASIO_NO_DEPRECATED) template <typename Elem, typename Traits> std::basic_ostream<Elem, Traits>& operator<<(
link/modules/asio-standalone/asio/include/asio/ip/impl/address_v4.ipp view
@@ -2,7 +2,7 @@ // ip/impl/address_v4.ipp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -57,19 +57,30 @@ static_cast<asio::detail::u_long_type>(addr)); } -address_v4::bytes_type address_v4::to_bytes() const noexcept+address_v4::bytes_type address_v4::to_bytes() const ASIO_NOEXCEPT { using namespace std; // For memcpy. bytes_type bytes;+#if defined(ASIO_HAS_STD_ARRAY) memcpy(bytes.data(), &addr_.s_addr, 4);+#else // defined(ASIO_HAS_STD_ARRAY)+ memcpy(bytes.elems, &addr_.s_addr, 4);+#endif // defined(ASIO_HAS_STD_ARRAY) return bytes; } -address_v4::uint_type address_v4::to_uint() const noexcept+address_v4::uint_type address_v4::to_uint() const ASIO_NOEXCEPT { return asio::detail::socket_ops::network_to_host_long(addr_.s_addr); } +#if !defined(ASIO_NO_DEPRECATED)+unsigned long address_v4::to_ulong() const+{+ return asio::detail::socket_ops::network_to_host_long(addr_.s_addr);+}+#endif // !defined(ASIO_NO_DEPRECATED)+ std::string address_v4::to_string() const { asio::error_code ec;@@ -83,21 +94,70 @@ return addr; } -bool address_v4::is_loopback() const noexcept+#if !defined(ASIO_NO_DEPRECATED)+std::string address_v4::to_string(asio::error_code& ec) const {+ char addr_str[asio::detail::max_addr_v4_str_len];+ const char* addr =+ asio::detail::socket_ops::inet_ntop(+ ASIO_OS_DEF(AF_INET), &addr_, addr_str,+ asio::detail::max_addr_v4_str_len, 0, ec);+ if (addr == 0)+ return std::string();+ return addr;+}+#endif // !defined(ASIO_NO_DEPRECATED)++bool address_v4::is_loopback() const ASIO_NOEXCEPT+{ return (to_uint() & 0xFF000000) == 0x7F000000; } -bool address_v4::is_unspecified() const noexcept+bool address_v4::is_unspecified() const ASIO_NOEXCEPT { return to_uint() == 0; } -bool address_v4::is_multicast() const noexcept+#if !defined(ASIO_NO_DEPRECATED)+bool address_v4::is_class_a() const {+ return (to_uint() & 0x80000000) == 0;+}++bool address_v4::is_class_b() const+{+ return (to_uint() & 0xC0000000) == 0x80000000;+}++bool address_v4::is_class_c() const+{+ return (to_uint() & 0xE0000000) == 0xC0000000;+}+#endif // !defined(ASIO_NO_DEPRECATED)++bool address_v4::is_multicast() const ASIO_NOEXCEPT+{ return (to_uint() & 0xF0000000) == 0xE0000000; } +#if !defined(ASIO_NO_DEPRECATED)+address_v4 address_v4::broadcast(const address_v4& addr, const address_v4& mask)+{+ return address_v4(addr.to_uint() | (mask.to_uint() ^ 0xFFFFFFFF));+}++address_v4 address_v4::netmask(const address_v4& addr)+{+ if (addr.is_class_a())+ return address_v4(0xFF000000);+ if (addr.is_class_b())+ return address_v4(0xFFFF0000);+ if (addr.is_class_c())+ return address_v4(0xFFFFFF00);+ return address_v4(0xFFFFFFFF);+}+#endif // !defined(ASIO_NO_DEPRECATED)+ address_v4 make_address_v4(const char* str) { asio::error_code ec;@@ -107,7 +167,7 @@ } address_v4 make_address_v4(const char* str,- asio::error_code& ec) noexcept+ asio::error_code& ec) ASIO_NOEXCEPT { address_v4::bytes_type bytes; if (asio::detail::socket_ops::inet_pton(@@ -122,7 +182,7 @@ } address_v4 make_address_v4(const std::string& str,- asio::error_code& ec) noexcept+ asio::error_code& ec) ASIO_NOEXCEPT { return make_address_v4(str.c_str(), ec); }@@ -135,7 +195,7 @@ } address_v4 make_address_v4(string_view str,- asio::error_code& ec) noexcept+ asio::error_code& ec) ASIO_NOEXCEPT { return make_address_v4(static_cast<std::string>(str), ec); }
link/modules/asio-standalone/asio/include/asio/ip/impl/address_v6.hpp view
@@ -2,7 +2,7 @@ // ip/impl/address_v6.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -17,10 +17,38 @@ #if !defined(ASIO_NO_IOSTREAM) +#include "asio/detail/throw_error.hpp"+ #include "asio/detail/push_options.hpp" namespace asio { namespace ip {++#if !defined(ASIO_NO_DEPRECATED)++inline address_v6 address_v6::from_string(const char* str)+{+ return asio::ip::make_address_v6(str);+}++inline address_v6 address_v6::from_string(+ const char* str, asio::error_code& ec)+{+ return asio::ip::make_address_v6(str, ec);+}++inline address_v6 address_v6::from_string(const std::string& str)+{+ return asio::ip::make_address_v6(str);+}++inline address_v6 address_v6::from_string(+ const std::string& str, asio::error_code& ec)+{+ return asio::ip::make_address_v6(str, ec);+}++#endif // !defined(ASIO_NO_DEPRECATED) template <typename Elem, typename Traits> std::basic_ostream<Elem, Traits>& operator<<(
link/modules/asio-standalone/asio/include/asio/ip/impl/address_v6.ipp view
@@ -2,7 +2,7 @@ // ip/impl/address_v6.ipp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -31,7 +31,7 @@ namespace asio { namespace ip { -address_v6::address_v6() noexcept+address_v6::address_v6() ASIO_NOEXCEPT : addr_(), scope_id_(0) {@@ -56,37 +56,45 @@ memcpy(addr_.s6_addr, bytes.data(), 16); } -address_v6::address_v6(const address_v6& other) noexcept+address_v6::address_v6(const address_v6& other) ASIO_NOEXCEPT : addr_(other.addr_), scope_id_(other.scope_id_) { } -address_v6::address_v6(address_v6&& other) noexcept+#if defined(ASIO_HAS_MOVE)+address_v6::address_v6(address_v6&& other) ASIO_NOEXCEPT : addr_(other.addr_), scope_id_(other.scope_id_) { }+#endif // defined(ASIO_HAS_MOVE) -address_v6& address_v6::operator=(const address_v6& other) noexcept+address_v6& address_v6::operator=(const address_v6& other) ASIO_NOEXCEPT { addr_ = other.addr_; scope_id_ = other.scope_id_; return *this; } -address_v6& address_v6::operator=(address_v6&& other) noexcept+#if defined(ASIO_HAS_MOVE)+address_v6& address_v6::operator=(address_v6&& other) ASIO_NOEXCEPT { addr_ = other.addr_; scope_id_ = other.scope_id_; return *this; }+#endif // defined(ASIO_HAS_MOVE) -address_v6::bytes_type address_v6::to_bytes() const noexcept+address_v6::bytes_type address_v6::to_bytes() const ASIO_NOEXCEPT { using namespace std; // For memcpy. bytes_type bytes;+#if defined(ASIO_HAS_STD_ARRAY) memcpy(bytes.data(), addr_.s6_addr, 16);+#else // defined(ASIO_HAS_STD_ARRAY)+ memcpy(bytes.elems, addr_.s6_addr, 16);+#endif // defined(ASIO_HAS_STD_ARRAY) return bytes; } @@ -103,8 +111,35 @@ return addr; } -bool address_v6::is_loopback() const noexcept+#if !defined(ASIO_NO_DEPRECATED)+std::string address_v6::to_string(asio::error_code& ec) const {+ char addr_str[asio::detail::max_addr_v6_str_len];+ const char* addr =+ asio::detail::socket_ops::inet_ntop(+ ASIO_OS_DEF(AF_INET6), &addr_, addr_str,+ asio::detail::max_addr_v6_str_len, scope_id_, ec);+ if (addr == 0)+ return std::string();+ return addr;+}++address_v4 address_v6::to_v4() const+{+ if (!is_v4_mapped() && !is_v4_compatible())+ {+ bad_address_cast ex;+ asio::detail::throw_exception(ex);+ }++ address_v4::bytes_type v4_bytes = { { addr_.s6_addr[12],+ addr_.s6_addr[13], addr_.s6_addr[14], addr_.s6_addr[15] } };+ return address_v4(v4_bytes);+}+#endif // !defined(ASIO_NO_DEPRECATED)++bool address_v6::is_loopback() const ASIO_NOEXCEPT+{ return ((addr_.s6_addr[0] == 0) && (addr_.s6_addr[1] == 0) && (addr_.s6_addr[2] == 0) && (addr_.s6_addr[3] == 0) && (addr_.s6_addr[4] == 0) && (addr_.s6_addr[5] == 0)@@ -115,7 +150,7 @@ && (addr_.s6_addr[14] == 0) && (addr_.s6_addr[15] == 1)); } -bool address_v6::is_unspecified() const noexcept+bool address_v6::is_unspecified() const ASIO_NOEXCEPT { return ((addr_.s6_addr[0] == 0) && (addr_.s6_addr[1] == 0) && (addr_.s6_addr[2] == 0) && (addr_.s6_addr[3] == 0)@@ -127,17 +162,17 @@ && (addr_.s6_addr[14] == 0) && (addr_.s6_addr[15] == 0)); } -bool address_v6::is_link_local() const noexcept+bool address_v6::is_link_local() const ASIO_NOEXCEPT { return ((addr_.s6_addr[0] == 0xfe) && ((addr_.s6_addr[1] & 0xc0) == 0x80)); } -bool address_v6::is_site_local() const noexcept+bool address_v6::is_site_local() const ASIO_NOEXCEPT { return ((addr_.s6_addr[0] == 0xfe) && ((addr_.s6_addr[1] & 0xc0) == 0xc0)); } -bool address_v6::is_v4_mapped() const noexcept+bool address_v6::is_v4_mapped() const ASIO_NOEXCEPT { return ((addr_.s6_addr[0] == 0) && (addr_.s6_addr[1] == 0) && (addr_.s6_addr[2] == 0) && (addr_.s6_addr[3] == 0)@@ -147,37 +182,53 @@ && (addr_.s6_addr[10] == 0xff) && (addr_.s6_addr[11] == 0xff)); } -bool address_v6::is_multicast() const noexcept+#if !defined(ASIO_NO_DEPRECATED)+bool address_v6::is_v4_compatible() const {+ return ((addr_.s6_addr[0] == 0) && (addr_.s6_addr[1] == 0)+ && (addr_.s6_addr[2] == 0) && (addr_.s6_addr[3] == 0)+ && (addr_.s6_addr[4] == 0) && (addr_.s6_addr[5] == 0)+ && (addr_.s6_addr[6] == 0) && (addr_.s6_addr[7] == 0)+ && (addr_.s6_addr[8] == 0) && (addr_.s6_addr[9] == 0)+ && (addr_.s6_addr[10] == 0) && (addr_.s6_addr[11] == 0)+ && !((addr_.s6_addr[12] == 0)+ && (addr_.s6_addr[13] == 0)+ && (addr_.s6_addr[14] == 0)+ && ((addr_.s6_addr[15] == 0) || (addr_.s6_addr[15] == 1))));+}+#endif // !defined(ASIO_NO_DEPRECATED)++bool address_v6::is_multicast() const ASIO_NOEXCEPT+{ return (addr_.s6_addr[0] == 0xff); } -bool address_v6::is_multicast_global() const noexcept+bool address_v6::is_multicast_global() const ASIO_NOEXCEPT { return ((addr_.s6_addr[0] == 0xff) && ((addr_.s6_addr[1] & 0x0f) == 0x0e)); } -bool address_v6::is_multicast_link_local() const noexcept+bool address_v6::is_multicast_link_local() const ASIO_NOEXCEPT { return ((addr_.s6_addr[0] == 0xff) && ((addr_.s6_addr[1] & 0x0f) == 0x02)); } -bool address_v6::is_multicast_node_local() const noexcept+bool address_v6::is_multicast_node_local() const ASIO_NOEXCEPT { return ((addr_.s6_addr[0] == 0xff) && ((addr_.s6_addr[1] & 0x0f) == 0x01)); } -bool address_v6::is_multicast_org_local() const noexcept+bool address_v6::is_multicast_org_local() const ASIO_NOEXCEPT { return ((addr_.s6_addr[0] == 0xff) && ((addr_.s6_addr[1] & 0x0f) == 0x08)); } -bool address_v6::is_multicast_site_local() const noexcept+bool address_v6::is_multicast_site_local() const ASIO_NOEXCEPT { return ((addr_.s6_addr[0] == 0xff) && ((addr_.s6_addr[1] & 0x0f) == 0x05)); } -bool operator==(const address_v6& a1, const address_v6& a2) noexcept+bool operator==(const address_v6& a1, const address_v6& a2) ASIO_NOEXCEPT { using namespace std; // For memcmp. return memcmp(&a1.addr_, &a2.addr_,@@ -185,7 +236,7 @@ && a1.scope_id_ == a2.scope_id_; } -bool operator<(const address_v6& a1, const address_v6& a2) noexcept+bool operator<(const address_v6& a1, const address_v6& a2) ASIO_NOEXCEPT { using namespace std; // For memcmp. int memcmp_result = memcmp(&a1.addr_, &a2.addr_,@@ -197,13 +248,31 @@ return a1.scope_id_ < a2.scope_id_; } -address_v6 address_v6::loopback() noexcept+address_v6 address_v6::loopback() ASIO_NOEXCEPT { address_v6 tmp; tmp.addr_.s6_addr[15] = 1; return tmp; } +#if !defined(ASIO_NO_DEPRECATED)+address_v6 address_v6::v4_mapped(const address_v4& addr)+{+ address_v4::bytes_type v4_bytes = addr.to_bytes();+ bytes_type v6_bytes = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF,+ v4_bytes[0], v4_bytes[1], v4_bytes[2], v4_bytes[3] } };+ return address_v6(v6_bytes);+}++address_v6 address_v6::v4_compatible(const address_v4& addr)+{+ address_v4::bytes_type v4_bytes = addr.to_bytes();+ bytes_type v6_bytes = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,+ v4_bytes[0], v4_bytes[1], v4_bytes[2], v4_bytes[3] } };+ return address_v6(v6_bytes);+}+#endif // !defined(ASIO_NO_DEPRECATED)+ address_v6 make_address_v6(const char* str) { asio::error_code ec;@@ -213,14 +282,14 @@ } address_v6 make_address_v6(const char* str,- asio::error_code& ec) noexcept+ asio::error_code& ec) ASIO_NOEXCEPT { address_v6::bytes_type bytes; unsigned long scope_id = 0; if (asio::detail::socket_ops::inet_pton( ASIO_OS_DEF(AF_INET6), str, &bytes[0], &scope_id, ec) <= 0) return address_v6();- return address_v6(bytes, static_cast<scope_id_type>(scope_id));+ return address_v6(bytes, scope_id); } address_v6 make_address_v6(const std::string& str)@@ -229,7 +298,7 @@ } address_v6 make_address_v6(const std::string& str,- asio::error_code& ec) noexcept+ asio::error_code& ec) ASIO_NOEXCEPT { return make_address_v6(str.c_str(), ec); }@@ -242,7 +311,7 @@ } address_v6 make_address_v6(string_view str,- asio::error_code& ec) noexcept+ asio::error_code& ec) ASIO_NOEXCEPT { return make_address_v6(static_cast<std::string>(str), ec); }
link/modules/asio-standalone/asio/include/asio/ip/impl/basic_endpoint.hpp view
@@ -2,7 +2,7 @@ // ip/impl/basic_endpoint.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/ip/impl/host_name.ipp view
@@ -2,7 +2,7 @@ // ip/impl/host_name.ipp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/ip/impl/network_v4.hpp view
@@ -2,7 +2,7 @@ // ip/impl/network_v4.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2014 Oliver Kowalke (oliver dot kowalke at gmail dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying
link/modules/asio-standalone/asio/include/asio/ip/impl/network_v4.ipp view
@@ -2,7 +2,7 @@ // ip/impl/network_v4.ipp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2014 Oliver Kowalke (oliver dot kowalke at gmail dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying@@ -91,7 +91,7 @@ } } -address_v4 network_v4::netmask() const noexcept+address_v4 network_v4::netmask() const ASIO_NOEXCEPT { uint32_t nmbits = 0xffffffff; if (prefix_length_ == 0)@@ -101,7 +101,7 @@ return address_v4(nmbits); } -address_v4_range network_v4::hosts() const noexcept+address_v4_range network_v4::hosts() const ASIO_NOEXCEPT { return is_host() ? address_v4_range(address_, address_v4(address_.to_uint() + 1))
link/modules/asio-standalone/asio/include/asio/ip/impl/network_v6.hpp view
@@ -2,7 +2,7 @@ // ip/impl/network_v6.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/ip/impl/network_v6.ipp view
@@ -2,7 +2,7 @@ // ip/impl/network_v6.ipp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2014 Oliver Kowalke (oliver dot kowalke at gmail dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying@@ -42,7 +42,7 @@ } } -ASIO_DECL address_v6 network_v6::network() const noexcept+ASIO_DECL address_v6 network_v6::network() const ASIO_NOEXCEPT { address_v6::bytes_type bytes(address_.to_bytes()); for (std::size_t i = 0; i < 16; ++i)@@ -55,7 +55,7 @@ return address_v6(bytes, address_.scope_id()); } -address_v6_range network_v6::hosts() const noexcept+address_v6_range network_v6::hosts() const ASIO_NOEXCEPT { address_v6::bytes_type begin_bytes(address_.to_bytes()); address_v6::bytes_type end_bytes(address_.to_bytes());
link/modules/asio-standalone/asio/include/asio/ip/multicast.hpp view
@@ -2,7 +2,7 @@ // ip/multicast.hpp // ~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/ip/network_v4.hpp view
@@ -2,7 +2,7 @@ // ip/network_v4.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2014 Oliver Kowalke (oliver dot kowalke at gmail dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying@@ -40,7 +40,7 @@ { public: /// Default constructor.- network_v4() noexcept+ network_v4() ASIO_NOEXCEPT : address_(), prefix_length_(0) {@@ -55,74 +55,78 @@ const address_v4& mask); /// Copy constructor.- network_v4(const network_v4& other) noexcept+ network_v4(const network_v4& other) ASIO_NOEXCEPT : address_(other.address_), prefix_length_(other.prefix_length_) { } +#if defined(ASIO_HAS_MOVE) /// Move constructor.- network_v4(network_v4&& other) noexcept- : address_(static_cast<address_v4&&>(other.address_)),+ network_v4(network_v4&& other) ASIO_NOEXCEPT+ : address_(ASIO_MOVE_CAST(address_v4)(other.address_)), prefix_length_(other.prefix_length_) { }+#endif // defined(ASIO_HAS_MOVE) /// Assign from another network.- network_v4& operator=(const network_v4& other) noexcept+ network_v4& operator=(const network_v4& other) ASIO_NOEXCEPT { address_ = other.address_; prefix_length_ = other.prefix_length_; return *this; } +#if defined(ASIO_HAS_MOVE) /// Move-assign from another network.- network_v4& operator=(network_v4&& other) noexcept+ network_v4& operator=(network_v4&& other) ASIO_NOEXCEPT {- address_ = static_cast<address_v4&&>(other.address_);+ address_ = ASIO_MOVE_CAST(address_v4)(other.address_); prefix_length_ = other.prefix_length_; return *this; }+#endif // defined(ASIO_HAS_MOVE) /// Obtain the address object specified when the network object was created.- address_v4 address() const noexcept+ address_v4 address() const ASIO_NOEXCEPT { return address_; } /// Obtain the prefix length that was specified when the network object was /// created.- unsigned short prefix_length() const noexcept+ unsigned short prefix_length() const ASIO_NOEXCEPT { return prefix_length_; } /// Obtain the netmask that was specified when the network object was created.- ASIO_DECL address_v4 netmask() const noexcept;+ ASIO_DECL address_v4 netmask() const ASIO_NOEXCEPT; /// Obtain an address object that represents the network address.- address_v4 network() const noexcept+ address_v4 network() const ASIO_NOEXCEPT { return address_v4(address_.to_uint() & netmask().to_uint()); } /// Obtain an address object that represents the network's broadcast address.- address_v4 broadcast() const noexcept+ address_v4 broadcast() const ASIO_NOEXCEPT { return address_v4(network().to_uint() | (netmask().to_uint() ^ 0xFFFFFFFF)); } /// Obtain an address range corresponding to the hosts in the network.- ASIO_DECL address_v4_range hosts() const noexcept;+ ASIO_DECL address_v4_range hosts() const ASIO_NOEXCEPT; /// Obtain the true network address, omitting any host bits.- network_v4 canonical() const noexcept+ network_v4 canonical() const ASIO_NOEXCEPT { return network_v4(network(), prefix_length()); } /// Test if network is a valid host address.- bool is_host() const noexcept+ bool is_host() const ASIO_NOEXCEPT { return prefix_length_ == 32; }
link/modules/asio-standalone/asio/include/asio/ip/network_v6.hpp view
@@ -2,7 +2,7 @@ // ip/network_v6.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2014 Oliver Kowalke (oliver dot kowalke at gmail dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying@@ -40,7 +40,7 @@ { public: /// Default constructor.- network_v6() noexcept+ network_v6() ASIO_NOEXCEPT : address_(), prefix_length_(0) {@@ -51,62 +51,66 @@ unsigned short prefix_len); /// Copy constructor.- network_v6(const network_v6& other) noexcept+ network_v6(const network_v6& other) ASIO_NOEXCEPT : address_(other.address_), prefix_length_(other.prefix_length_) { } +#if defined(ASIO_HAS_MOVE) /// Move constructor.- network_v6(network_v6&& other) noexcept- : address_(static_cast<address_v6&&>(other.address_)),+ network_v6(network_v6&& other) ASIO_NOEXCEPT+ : address_(ASIO_MOVE_CAST(address_v6)(other.address_)), prefix_length_(other.prefix_length_) { }+#endif // defined(ASIO_HAS_MOVE) /// Assign from another network.- network_v6& operator=(const network_v6& other) noexcept+ network_v6& operator=(const network_v6& other) ASIO_NOEXCEPT { address_ = other.address_; prefix_length_ = other.prefix_length_; return *this; } +#if defined(ASIO_HAS_MOVE) /// Move-assign from another network.- network_v6& operator=(network_v6&& other) noexcept+ network_v6& operator=(network_v6&& other) ASIO_NOEXCEPT {- address_ = static_cast<address_v6&&>(other.address_);+ address_ = ASIO_MOVE_CAST(address_v6)(other.address_); prefix_length_ = other.prefix_length_; return *this; }+#endif // defined(ASIO_HAS_MOVE) /// Obtain the address object specified when the network object was created.- address_v6 address() const noexcept+ address_v6 address() const ASIO_NOEXCEPT { return address_; } /// Obtain the prefix length that was specified when the network object was /// created.- unsigned short prefix_length() const noexcept+ unsigned short prefix_length() const ASIO_NOEXCEPT { return prefix_length_; } /// Obtain an address object that represents the network address.- ASIO_DECL address_v6 network() const noexcept;+ ASIO_DECL address_v6 network() const ASIO_NOEXCEPT; /// Obtain an address range corresponding to the hosts in the network.- ASIO_DECL address_v6_range hosts() const noexcept;+ ASIO_DECL address_v6_range hosts() const ASIO_NOEXCEPT; /// Obtain the true network address, omitting any host bits.- network_v6 canonical() const noexcept+ network_v6 canonical() const ASIO_NOEXCEPT { return network_v6(network(), prefix_length()); } /// Test if network is a valid host address.- bool is_host() const noexcept+ bool is_host() const ASIO_NOEXCEPT { return prefix_length_ == 128; }
link/modules/asio-standalone/asio/include/asio/ip/resolver_base.hpp view
@@ -2,7 +2,7 @@ // ip/resolver_base.hpp // ~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/ip/resolver_query_base.hpp view
@@ -2,7 +2,7 @@ // ip/resolver_query_base.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/ip/tcp.hpp view
@@ -2,7 +2,7 @@ // ip/tcp.hpp // ~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -49,31 +49,31 @@ typedef basic_endpoint<tcp> endpoint; /// Construct to represent the IPv4 TCP protocol.- static tcp v4() noexcept+ static tcp v4() ASIO_NOEXCEPT { return tcp(ASIO_OS_DEF(AF_INET)); } /// Construct to represent the IPv6 TCP protocol.- static tcp v6() noexcept+ static tcp v6() ASIO_NOEXCEPT { return tcp(ASIO_OS_DEF(AF_INET6)); } /// Obtain an identifier for the type of the protocol.- int type() const noexcept+ int type() const ASIO_NOEXCEPT { return ASIO_OS_DEF(SOCK_STREAM); } /// Obtain an identifier for the protocol.- int protocol() const noexcept+ int protocol() const ASIO_NOEXCEPT { return ASIO_OS_DEF(IPPROTO_TCP); } /// Obtain an identifier for the protocol family.- int family() const noexcept+ int family() const ASIO_NOEXCEPT { return family_; }@@ -139,7 +139,7 @@ private: // Construct with a specific family.- explicit tcp(int protocol_family) noexcept+ explicit tcp(int protocol_family) ASIO_NOEXCEPT : family_(protocol_family) { }
link/modules/asio-standalone/asio/include/asio/ip/udp.hpp view
@@ -2,7 +2,7 @@ // ip/udp.hpp // ~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -46,31 +46,31 @@ typedef basic_endpoint<udp> endpoint; /// Construct to represent the IPv4 UDP protocol.- static udp v4() noexcept+ static udp v4() ASIO_NOEXCEPT { return udp(ASIO_OS_DEF(AF_INET)); } /// Construct to represent the IPv6 UDP protocol.- static udp v6() noexcept+ static udp v6() ASIO_NOEXCEPT { return udp(ASIO_OS_DEF(AF_INET6)); } /// Obtain an identifier for the type of the protocol.- int type() const noexcept+ int type() const ASIO_NOEXCEPT { return ASIO_OS_DEF(SOCK_DGRAM); } /// Obtain an identifier for the protocol.- int protocol() const noexcept+ int protocol() const ASIO_NOEXCEPT { return ASIO_OS_DEF(IPPROTO_UDP); } /// Obtain an identifier for the protocol family.- int family() const noexcept+ int family() const ASIO_NOEXCEPT { return family_; }@@ -95,7 +95,7 @@ private: // Construct with a specific family.- explicit udp(int protocol_family) noexcept+ explicit udp(int protocol_family) ASIO_NOEXCEPT : family_(protocol_family) { }
link/modules/asio-standalone/asio/include/asio/ip/unicast.hpp view
@@ -2,7 +2,7 @@ // ip/unicast.hpp // ~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/ip/v6_only.hpp view
@@ -2,7 +2,7 @@ // ip/v6_only.hpp // ~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/is_applicable_property.hpp view
@@ -2,7 +2,7 @@ // is_applicable_property.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -30,11 +30,11 @@ template <typename T, typename Property> struct is_applicable_property_trait<T, Property,- void_t<- enable_if_t<+ typename void_type<+ typename enable_if< !!Property::template is_applicable_property_v<T>- >- >> : true_type+ >::type+ >::type> : true_type { }; @@ -51,7 +51,7 @@ #if defined(ASIO_HAS_VARIABLE_TEMPLATES) template <typename T, typename Property>-constexpr const bool is_applicable_property_v+ASIO_CONSTEXPR const bool is_applicable_property_v = is_applicable_property<T, Property>::value; #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)
link/modules/asio-standalone/asio/include/asio/is_contiguous_iterator.hpp view
@@ -2,7 +2,7 @@ // is_contiguous_iterator.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -29,7 +29,7 @@ struct is_contiguous_iterator : #if defined(ASIO_HAS_STD_CONCEPTS) \ || defined(GENERATING_DOCUMENTATION)- integral_constant<bool, std::contiguous_iterator<T>>+ integral_constant<bool, std::contiguous_iterator<T> > #else // defined(ASIO_HAS_STD_CONCEPTS) // || defined(GENERATING_DOCUMENTATION) is_pointer<T>
link/modules/asio-standalone/asio/include/asio/is_executor.hpp view
@@ -2,7 +2,7 @@ // is_executor.hpp // ~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/is_read_buffered.hpp view
@@ -2,7 +2,7 @@ // is_read_buffered.hpp // ~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/is_write_buffered.hpp view
@@ -2,7 +2,7 @@ // is_write_buffered.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/local/basic_endpoint.hpp view
@@ -2,7 +2,7 @@ // local/basic_endpoint.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Derived from a public domain implementation written by Daniel Casimiro. // // Distributed under the Boost Software License, Version 1.0. (See accompanying@@ -60,7 +60,7 @@ #endif /// Default constructor.- basic_endpoint() noexcept+ basic_endpoint() ASIO_NOEXCEPT { } @@ -85,51 +85,55 @@ #endif // defined(ASIO_HAS_STRING_VIEW) /// Copy constructor.- basic_endpoint(const basic_endpoint& other) noexcept+ basic_endpoint(const basic_endpoint& other) : impl_(other.impl_) { } +#if defined(ASIO_HAS_MOVE) /// Move constructor.- basic_endpoint(basic_endpoint&& other) noexcept+ basic_endpoint(basic_endpoint&& other) : impl_(other.impl_) { }+#endif // defined(ASIO_HAS_MOVE) /// Assign from another endpoint.- basic_endpoint& operator=(const basic_endpoint& other) noexcept+ basic_endpoint& operator=(const basic_endpoint& other) { impl_ = other.impl_; return *this; } +#if defined(ASIO_HAS_MOVE) /// Move-assign from another endpoint.- basic_endpoint& operator=(basic_endpoint&& other) noexcept+ basic_endpoint& operator=(basic_endpoint&& other) { impl_ = other.impl_; return *this; }+#endif // defined(ASIO_HAS_MOVE) /// The protocol associated with the endpoint.- protocol_type protocol() const noexcept+ protocol_type protocol() const { return protocol_type(); } /// Get the underlying endpoint in the native type.- data_type* data() noexcept+ data_type* data() { return impl_.data(); } /// Get the underlying endpoint in the native type.- const data_type* data() const noexcept+ const data_type* data() const { return impl_.data(); } /// Get the underlying size of the endpoint in the native type.- std::size_t size() const noexcept+ std::size_t size() const { return impl_.size(); }@@ -141,7 +145,7 @@ } /// Get the capacity of the endpoint in the native type.- std::size_t capacity() const noexcept+ std::size_t capacity() const { return impl_.capacity(); }@@ -166,42 +170,42 @@ /// Compare two endpoints for equality. friend bool operator==(const basic_endpoint<Protocol>& e1,- const basic_endpoint<Protocol>& e2) noexcept+ const basic_endpoint<Protocol>& e2) { return e1.impl_ == e2.impl_; } /// Compare two endpoints for inequality. friend bool operator!=(const basic_endpoint<Protocol>& e1,- const basic_endpoint<Protocol>& e2) noexcept+ const basic_endpoint<Protocol>& e2) { return !(e1.impl_ == e2.impl_); } /// Compare endpoints for ordering. friend bool operator<(const basic_endpoint<Protocol>& e1,- const basic_endpoint<Protocol>& e2) noexcept+ const basic_endpoint<Protocol>& e2) { return e1.impl_ < e2.impl_; } /// Compare endpoints for ordering. friend bool operator>(const basic_endpoint<Protocol>& e1,- const basic_endpoint<Protocol>& e2) noexcept+ const basic_endpoint<Protocol>& e2) { return e2.impl_ < e1.impl_; } /// Compare endpoints for ordering. friend bool operator<=(const basic_endpoint<Protocol>& e1,- const basic_endpoint<Protocol>& e2) noexcept+ const basic_endpoint<Protocol>& e2) { return !(e2 < e1); } /// Compare endpoints for ordering. friend bool operator>=(const basic_endpoint<Protocol>& e1,- const basic_endpoint<Protocol>& e2) noexcept+ const basic_endpoint<Protocol>& e2) { return !(e1 < e2); }
link/modules/asio-standalone/asio/include/asio/local/connect_pair.hpp view
@@ -2,7 +2,7 @@ // local/connect_pair.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/local/datagram_protocol.hpp view
@@ -2,7 +2,7 @@ // local/datagram_protocol.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -45,19 +45,19 @@ { public: /// Obtain an identifier for the type of the protocol.- int type() const noexcept+ int type() const ASIO_NOEXCEPT { return SOCK_DGRAM; } /// Obtain an identifier for the protocol.- int protocol() const noexcept+ int protocol() const ASIO_NOEXCEPT { return 0; } /// Obtain an identifier for the protocol family.- int family() const noexcept+ int family() const ASIO_NOEXCEPT { return AF_UNIX; }
link/modules/asio-standalone/asio/include/asio/local/detail/endpoint.hpp view
@@ -2,7 +2,7 @@ // local/detail/endpoint.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Derived from a public domain implementation written by Daniel Casimiro. // // Distributed under the Boost Software License, Version 1.0. (See accompanying@@ -36,7 +36,7 @@ { public: // Default constructor.- ASIO_DECL endpoint() noexcept;+ ASIO_DECL endpoint(); // Construct an endpoint using the specified path name. ASIO_DECL endpoint(const char* path_name);@@ -50,14 +50,14 @@ #endif // defined(ASIO_HAS_STRING_VIEW) // Copy constructor.- endpoint(const endpoint& other) noexcept+ endpoint(const endpoint& other) : data_(other.data_), path_length_(other.path_length_) { } // Assign from another endpoint.- endpoint& operator=(const endpoint& other) noexcept+ endpoint& operator=(const endpoint& other) { data_ = other.data_; path_length_ = other.path_length_;@@ -65,19 +65,19 @@ } // Get the underlying endpoint in the native type.- asio::detail::socket_addr_type* data() noexcept+ asio::detail::socket_addr_type* data() { return &data_.base; } // Get the underlying endpoint in the native type.- const asio::detail::socket_addr_type* data() const noexcept+ const asio::detail::socket_addr_type* data() const { return &data_.base; } // Get the underlying size of the endpoint in the native type.- std::size_t size() const noexcept+ std::size_t size() const { return path_length_ + offsetof(asio::detail::sockaddr_un_type, sun_path);@@ -87,7 +87,7 @@ ASIO_DECL void resize(std::size_t size); // Get the capacity of the endpoint in the native type.- std::size_t capacity() const noexcept+ std::size_t capacity() const { return sizeof(asio::detail::sockaddr_un_type); }@@ -103,11 +103,11 @@ // Compare two endpoints for equality. ASIO_DECL friend bool operator==(- const endpoint& e1, const endpoint& e2) noexcept;+ const endpoint& e1, const endpoint& e2); // Compare endpoints for ordering. ASIO_DECL friend bool operator<(- const endpoint& e1, const endpoint& e2) noexcept;+ const endpoint& e1, const endpoint& e2); private: // The underlying UNIX socket address.
link/modules/asio-standalone/asio/include/asio/local/detail/impl/endpoint.ipp view
@@ -2,7 +2,7 @@ // local/detail/impl/endpoint.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Derived from a public domain implementation written by Daniel Casimiro. // // Distributed under the Boost Software License, Version 1.0. (See accompanying@@ -32,7 +32,7 @@ namespace local { namespace detail { -endpoint::endpoint() noexcept+endpoint::endpoint() { init("", 0); }@@ -93,12 +93,12 @@ init(p.data(), p.length()); } -bool operator==(const endpoint& e1, const endpoint& e2) noexcept+bool operator==(const endpoint& e1, const endpoint& e2) { return e1.path() == e2.path(); } -bool operator<(const endpoint& e1, const endpoint& e2) noexcept+bool operator<(const endpoint& e1, const endpoint& e2) { return e1.path() < e2.path(); }
link/modules/asio-standalone/asio/include/asio/local/seq_packet_protocol.hpp view
@@ -2,7 +2,7 @@ // local/seq_packet_protocol.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -46,19 +46,19 @@ { public: /// Obtain an identifier for the type of the protocol.- int type() const noexcept+ int type() const ASIO_NOEXCEPT { return SOCK_SEQPACKET; } /// Obtain an identifier for the protocol.- int protocol() const noexcept+ int protocol() const ASIO_NOEXCEPT { return 0; } /// Obtain an identifier for the protocol family.- int family() const noexcept+ int family() const ASIO_NOEXCEPT { return AF_UNIX; }
link/modules/asio-standalone/asio/include/asio/local/stream_protocol.hpp view
@@ -2,7 +2,7 @@ // local/stream_protocol.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -47,19 +47,19 @@ { public: /// Obtain an identifier for the type of the protocol.- int type() const noexcept+ int type() const ASIO_NOEXCEPT { return SOCK_STREAM; } /// Obtain an identifier for the protocol.- int protocol() const noexcept+ int protocol() const ASIO_NOEXCEPT { return 0; } /// Obtain an identifier for the protocol family.- int family() const noexcept+ int family() const ASIO_NOEXCEPT { return AF_UNIX; }
link/modules/asio-standalone/asio/include/asio/multiple_exceptions.hpp view
@@ -2,7 +2,7 @@ // multiple_exceptions.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -21,6 +21,9 @@ namespace asio { +#if defined(ASIO_HAS_STD_EXCEPTION_PTR) \+ || defined(GENERATING_DOCUMENTATION)+ /// Exception thrown when there are multiple pending exceptions to rethrow. class multiple_exceptions : public std::exception@@ -28,11 +31,11 @@ public: /// Constructor. ASIO_DECL multiple_exceptions(- std::exception_ptr first) noexcept;+ std::exception_ptr first) ASIO_NOEXCEPT; /// Obtain message associated with exception. ASIO_DECL virtual const char* what() const- noexcept;+ ASIO_NOEXCEPT_OR_NOTHROW; /// Obtain a pointer to the first exception. ASIO_DECL std::exception_ptr first_exception() const;@@ -40,6 +43,9 @@ private: std::exception_ptr first_; };++#endif // defined(ASIO_HAS_STD_EXCEPTION_PTR)+ // || defined(GENERATING_DOCUMENTATION) } // namespace asio
link/modules/asio-standalone/asio/include/asio/packaged_task.hpp view
@@ -2,7 +2,7 @@ // packaged_task.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -23,11 +23,15 @@ #include "asio/async_result.hpp" #include "asio/detail/type_traits.hpp"+#include "asio/detail/variadic_templates.hpp" #include "asio/detail/push_options.hpp" namespace asio { +#if defined(ASIO_HAS_VARIADIC_TEMPLATES) \+ || defined(GENERATING_DOCUMENTATION)+ /// Partial specialisation of @c async_result for @c std::packaged_task. template <typename Result, typename... Args, typename Signature> class async_result<std::packaged_task<Result(Args...)>, Signature>@@ -55,6 +59,62 @@ private: return_type future_; };++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)+ // || defined(GENERATING_DOCUMENTATION)++template <typename Result, typename Signature>+struct async_result<std::packaged_task<Result()>, Signature>+{+ typedef std::packaged_task<Result()> completion_handler_type;+ typedef std::future<Result> return_type;++ explicit async_result(completion_handler_type& h)+ : future_(h.get_future())+ {+ }++ return_type get()+ {+ return std::move(future_);+ }++private:+ return_type future_;+};++#define ASIO_PRIVATE_ASYNC_RESULT_DEF(n) \+ template <typename Result, \+ ASIO_VARIADIC_TPARAMS(n), typename Signature> \+ class async_result< \+ std::packaged_task<Result(ASIO_VARIADIC_TARGS(n))>, Signature> \+ { \+ public: \+ typedef std::packaged_task< \+ Result(ASIO_VARIADIC_TARGS(n))> \+ completion_handler_type; \+ \+ typedef std::future<Result> return_type; \+ \+ explicit async_result(completion_handler_type& h) \+ : future_(h.get_future()) \+ { \+ } \+ \+ return_type get() \+ { \+ return std::move(future_); \+ } \+ \+ private: \+ return_type future_; \+ }; \+ /**/+ ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_ASYNC_RESULT_DEF)+#undef ASIO_PRIVATE_ASYNC_RESULT_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+ // || defined(GENERATING_DOCUMENTATION) } // namespace asio
link/modules/asio-standalone/asio/include/asio/placeholders.hpp view
@@ -2,7 +2,7 @@ // placeholders.hpp // ~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -16,8 +16,11 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"-#include "asio/detail/functional.hpp" +#if defined(ASIO_HAS_BOOST_BIND)+# include <boost/bind/arg.hpp>+#endif // defined(ASIO_HAS_BOOST_BIND)+ #include "asio/detail/push_options.hpp" namespace asio {@@ -25,52 +28,119 @@ #if defined(GENERATING_DOCUMENTATION) -/// An argument placeholder, for use with std::bind() or boost::bind(), that-/// corresponds to the error argument of a handler for any of the asynchronous-/// functions.+/// An argument placeholder, for use with boost::bind(), that corresponds to+/// the error argument of a handler for any of the asynchronous functions. unspecified error; -/// An argument placeholder, for use with std::bind() or boost::bind(), that-/// corresponds to the bytes_transferred argument of a handler for asynchronous-/// functions such as asio::basic_stream_socket::async_write_some or+/// An argument placeholder, for use with boost::bind(), that corresponds to+/// the bytes_transferred argument of a handler for asynchronous functions such+/// as asio::basic_stream_socket::async_write_some or /// asio::async_write. unspecified bytes_transferred; -/// An argument placeholder, for use with std::bind() or boost::bind(), that-/// corresponds to the iterator argument of a handler for asynchronous functions-/// such as asio::async_connect.+/// An argument placeholder, for use with boost::bind(), that corresponds to+/// the iterator argument of a handler for asynchronous functions such as+/// asio::async_connect. unspecified iterator; -/// An argument placeholder, for use with std::bind() or boost::bind(), that-/// corresponds to the results argument of a handler for asynchronous functions-/// such as asio::basic_resolver::async_resolve.+/// An argument placeholder, for use with boost::bind(), that corresponds to+/// the results argument of a handler for asynchronous functions such as+/// asio::basic_resolver::async_resolve. unspecified results; -/// An argument placeholder, for use with std::bind() or boost::bind(), that-/// corresponds to the results argument of a handler for asynchronous functions-/// such as asio::async_connect.+/// An argument placeholder, for use with boost::bind(), that corresponds to+/// the results argument of a handler for asynchronous functions such as+/// asio::async_connect. unspecified endpoint; -/// An argument placeholder, for use with std::bind() or boost::bind(), that-/// corresponds to the signal_number argument of a handler for asynchronous-/// functions such as asio::signal_set::async_wait.+/// An argument placeholder, for use with boost::bind(), that corresponds to+/// the signal_number argument of a handler for asynchronous functions such as+/// asio::signal_set::async_wait. unspecified signal_number; -#else+#elif defined(ASIO_HAS_BOOST_BIND)+# if defined(__BORLANDC__) || defined(__GNUC__) -static ASIO_INLINE_VARIABLE constexpr auto& error- = std::placeholders::_1;-static ASIO_INLINE_VARIABLE constexpr auto& bytes_transferred- = std::placeholders::_2;-static ASIO_INLINE_VARIABLE constexpr auto& iterator- = std::placeholders::_2;-static ASIO_INLINE_VARIABLE constexpr auto& results- = std::placeholders::_2;-static ASIO_INLINE_VARIABLE constexpr auto& endpoint- = std::placeholders::_2;-static ASIO_INLINE_VARIABLE constexpr auto& signal_number- = std::placeholders::_2;+inline boost::arg<1> error()+{+ return boost::arg<1>();+} +inline boost::arg<2> bytes_transferred()+{+ return boost::arg<2>();+}++inline boost::arg<2> iterator()+{+ return boost::arg<2>();+}++inline boost::arg<2> results()+{+ return boost::arg<2>();+}++inline boost::arg<2> endpoint()+{+ return boost::arg<2>();+}++inline boost::arg<2> signal_number()+{+ return boost::arg<2>();+}++# else++namespace detail+{+ template <int Number>+ struct placeholder+ {+ static boost::arg<Number>& get()+ {+ static boost::arg<Number> result;+ return result;+ }+ };+}++# if defined(ASIO_MSVC) && (ASIO_MSVC < 1400)++static boost::arg<1>& error+ = asio::placeholders::detail::placeholder<1>::get();+static boost::arg<2>& bytes_transferred+ = asio::placeholders::detail::placeholder<2>::get();+static boost::arg<2>& iterator+ = asio::placeholders::detail::placeholder<2>::get();+static boost::arg<2>& results+ = asio::placeholders::detail::placeholder<2>::get();+static boost::arg<2>& endpoint+ = asio::placeholders::detail::placeholder<2>::get();+static boost::arg<2>& signal_number+ = asio::placeholders::detail::placeholder<2>::get();++# else++namespace+{+ boost::arg<1>& error+ = asio::placeholders::detail::placeholder<1>::get();+ boost::arg<2>& bytes_transferred+ = asio::placeholders::detail::placeholder<2>::get();+ boost::arg<2>& iterator+ = asio::placeholders::detail::placeholder<2>::get();+ boost::arg<2>& results+ = asio::placeholders::detail::placeholder<2>::get();+ boost::arg<2>& endpoint+ = asio::placeholders::detail::placeholder<2>::get();+ boost::arg<2>& signal_number+ = asio::placeholders::detail::placeholder<2>::get();+} // namespace++# endif+# endif #endif } // namespace placeholders
link/modules/asio-standalone/asio/include/asio/posix/basic_descriptor.hpp view
@@ -2,7 +2,7 @@ // posix/basic_descriptor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -20,7 +20,6 @@ #if defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR) \ || defined(GENERATING_DOCUMENTATION) -#include <utility> #include "asio/any_io_executor.hpp" #include "asio/async_result.hpp" #include "asio/detail/handler_type_requirements.hpp"@@ -37,6 +36,10 @@ # include "asio/detail/reactive_descriptor_service.hpp" #endif // defined(ASIO_HAS_IO_URING_AS_DEFAULT) +#if defined(ASIO_HAS_MOVE)+# include <utility>+#endif // defined(ASIO_HAS_MOVE)+ #include "asio/detail/push_options.hpp" namespace asio {@@ -107,10 +110,10 @@ */ template <typename ExecutionContext> explicit basic_descriptor(ExecutionContext& context,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- > = defaulted_constraint())+ >::type = defaulted_constraint()) : impl_(0, 0, context) { }@@ -154,9 +157,9 @@ template <typename ExecutionContext> basic_descriptor(ExecutionContext& context, const native_handle_type& native_descriptor,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- > = 0)+ >::type = 0) : impl_(0, 0, context) { asio::error_code ec;@@ -165,6 +168,7 @@ asio::detail::throw_error(ec, "assign"); } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move-construct a descriptor from another. /** * This constructor moves a descriptor from one object to another.@@ -176,7 +180,7 @@ * constructed using the @c basic_descriptor(const executor_type&) * constructor. */- basic_descriptor(basic_descriptor&& other) noexcept+ basic_descriptor(basic_descriptor&& other) ASIO_NOEXCEPT : impl_(std::move(other.impl_)) { }@@ -216,10 +220,10 @@ */ template <typename Executor1> basic_descriptor(basic_descriptor<Executor1>&& other,- constraint_t<+ typename constraint< is_convertible<Executor1, Executor>::value, defaulted_constraint- > = defaulted_constraint())+ >::type = defaulted_constraint()) : impl_(std::move(other.impl_)) { }@@ -236,18 +240,19 @@ * constructor. */ template <typename Executor1>- constraint_t<+ typename constraint< is_convertible<Executor1, Executor>::value, basic_descriptor&- > operator=(basic_descriptor<Executor1> && other)+ >::type operator=(basic_descriptor<Executor1> && other) { basic_descriptor tmp(std::move(other)); impl_ = std::move(tmp.impl_); return *this; }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Get the executor associated with the object.- const executor_type& get_executor() noexcept+ const executor_type& get_executor() ASIO_NOEXCEPT { return impl_.get_executor(); }@@ -660,7 +665,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code) @endcode@@ -696,12 +701,15 @@ */ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code))- WaitToken = default_completion_token_t<executor_type>>- auto async_wait(wait_type w,- WaitToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ WaitToken ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WaitToken,+ void (asio::error_code))+ async_wait(wait_type w,+ ASIO_MOVE_ARG(WaitToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<WaitToken, void (asio::error_code)>(- declval<initiate_async_wait>(), token, w))+ declval<initiate_async_wait>(), token, w))) { return async_initiate<WaitToken, void (asio::error_code)>( initiate_async_wait(this), token, w);@@ -726,8 +734,8 @@ private: // Disallow copying and assignment.- basic_descriptor(const basic_descriptor&) = delete;- basic_descriptor& operator=(const basic_descriptor&) = delete;+ basic_descriptor(const basic_descriptor&) ASIO_DELETED;+ basic_descriptor& operator=(const basic_descriptor&) ASIO_DELETED; class initiate_async_wait {@@ -739,13 +747,13 @@ { } - const executor_type& get_executor() const noexcept+ const executor_type& get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template <typename WaitHandler>- void operator()(WaitHandler&& handler, wait_type w) const+ void operator()(ASIO_MOVE_ARG(WaitHandler) handler, wait_type w) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a WaitHandler.
link/modules/asio-standalone/asio/include/asio/posix/basic_stream_descriptor.hpp view
@@ -2,7 +2,7 @@ // posix/basic_stream_descriptor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -95,10 +95,10 @@ */ template <typename ExecutionContext> explicit basic_stream_descriptor(ExecutionContext& context,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- > = defaulted_constraint())+ >::type = defaulted_constraint()) : basic_descriptor<Executor>(context) { }@@ -138,13 +138,14 @@ template <typename ExecutionContext> basic_stream_descriptor(ExecutionContext& context, const native_handle_type& native_descriptor,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- > = 0)+ >::type = 0) : basic_descriptor<Executor>(context, native_descriptor) { } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move-construct a stream descriptor from another. /** * This constructor moves a stream descriptor from one object to another.@@ -156,7 +157,7 @@ * constructed using the @c basic_stream_descriptor(const executor_type&) * constructor. */- basic_stream_descriptor(basic_stream_descriptor&& other) noexcept+ basic_stream_descriptor(basic_stream_descriptor&& other) ASIO_NOEXCEPT : basic_descriptor<Executor>(std::move(other)) { }@@ -193,10 +194,10 @@ */ template <typename Executor1> basic_stream_descriptor(basic_stream_descriptor<Executor1>&& other,- constraint_t<+ typename constraint< is_convertible<Executor1, Executor>::value, defaulted_constraint- > = defaulted_constraint())+ >::type = defaulted_constraint()) : basic_descriptor<Executor>(std::move(other)) { }@@ -214,14 +215,15 @@ * constructor. */ template <typename Executor1>- constraint_t<+ typename constraint< is_convertible<Executor1, Executor>::value, basic_stream_descriptor&- > operator=(basic_stream_descriptor<Executor1> && other)+ >::type operator=(basic_stream_descriptor<Executor1> && other) { basic_descriptor<Executor>::operator=(std::move(other)); return *this; }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Write some data to the descriptor. /**@@ -307,7 +309,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -337,13 +339,17 @@ */ template <typename ConstBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) WriteToken = default_completion_token_t<executor_type>>- auto async_write_some(const ConstBufferSequence& buffers,- WriteToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ std::size_t)) WriteToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+ void (asio::error_code, std::size_t))+ async_write_some(const ConstBufferSequence& buffers,+ ASIO_MOVE_ARG(WriteToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<WriteToken, void (asio::error_code, std::size_t)>(- initiate_async_write_some(this), token, buffers))+ initiate_async_write_some(this), token, buffers))) { return async_initiate<WriteToken, void (asio::error_code, std::size_t)>(@@ -436,7 +442,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -467,13 +473,17 @@ */ template <typename MutableBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) ReadToken = default_completion_token_t<executor_type>>- auto async_read_some(const MutableBufferSequence& buffers,- ReadToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ std::size_t)) ReadToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+ async_read_some(const MutableBufferSequence& buffers,+ ASIO_MOVE_ARG(ReadToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<ReadToken, void (asio::error_code, std::size_t)>(- declval<initiate_async_read_some>(), token, buffers))+ declval<initiate_async_read_some>(), token, buffers))) { return async_initiate<ReadToken, void (asio::error_code, std::size_t)>(@@ -491,13 +501,13 @@ { } - const executor_type& get_executor() const noexcept+ const executor_type& get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template <typename WriteHandler, typename ConstBufferSequence>- void operator()(WriteHandler&& handler,+ void operator()(ASIO_MOVE_ARG(WriteHandler) handler, const ConstBufferSequence& buffers) const { // If you get an error on the following line it means that your handler@@ -524,13 +534,13 @@ { } - const executor_type& get_executor() const noexcept+ const executor_type& get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template <typename ReadHandler, typename MutableBufferSequence>- void operator()(ReadHandler&& handler,+ void operator()(ASIO_MOVE_ARG(ReadHandler) handler, const MutableBufferSequence& buffers) const { // If you get an error on the following line it means that your handler
link/modules/asio-standalone/asio/include/asio/posix/descriptor.hpp view
@@ -2,7 +2,7 @@ // posix/descriptor.hpp // ~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/posix/descriptor_base.hpp view
@@ -2,7 +2,7 @@ // posix/descriptor_base.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/posix/stream_descriptor.hpp view
@@ -2,7 +2,7 @@ // posix/stream_descriptor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/post.hpp view
@@ -2,7 +2,7 @@ // post.hpp // ~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -77,10 +77,11 @@ * @code void() @endcode */ template <ASIO_COMPLETION_TOKEN_FOR(void()) NullaryToken>-inline auto post(NullaryToken&& token)- -> decltype(+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(NullaryToken, void()) post(+ ASIO_MOVE_ARG(NullaryToken) token)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<NullaryToken, void()>(- declval<detail::initiate_post>(), token))+ declval<detail::initiate_post>(), token))) { return async_initiate<NullaryToken, void()>( detail::initiate_post(), token);@@ -157,17 +158,19 @@ */ template <typename Executor, ASIO_COMPLETION_TOKEN_FOR(void()) NullaryToken- = default_completion_token_t<Executor>>-inline auto post(const Executor& ex,- NullaryToken&& token = default_completion_token_t<Executor>(),- constraint_t<+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(Executor)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(NullaryToken, void()) post(+ const Executor& ex,+ ASIO_MOVE_ARG(NullaryToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(Executor),+ typename constraint< (execution::is_executor<Executor>::value && can_require<Executor, execution::blocking_t::never_t>::value) || is_executor<Executor>::value- > = 0)- -> decltype(+ >::type = 0)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<NullaryToken, void()>(- declval<detail::initiate_post_with_executor<Executor>>(), token))+ declval<detail::initiate_post_with_executor<Executor> >(), token))) { return async_initiate<NullaryToken, void()>( detail::initiate_post_with_executor<Executor>(ex), token);@@ -188,17 +191,19 @@ */ template <typename ExecutionContext, ASIO_COMPLETION_TOKEN_FOR(void()) NullaryToken- = default_completion_token_t<typename ExecutionContext::executor_type>>-inline auto post(ExecutionContext& ctx,- NullaryToken&& token = default_completion_token_t<- typename ExecutionContext::executor_type>(),- constraint_t<- is_convertible<ExecutionContext&, execution_context&>::value- > = 0)- -> decltype(+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+ typename ExecutionContext::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(NullaryToken, void()) post(+ ExecutionContext& ctx,+ ASIO_MOVE_ARG(NullaryToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(+ typename ExecutionContext::executor_type),+ typename constraint<is_convertible<+ ExecutionContext&, execution_context&>::value>::type = 0)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<NullaryToken, void()>(- declval<detail::initiate_post_with_executor<- typename ExecutionContext::executor_type>>(), token))+ declval<detail::initiate_post_with_executor<+ typename ExecutionContext::executor_type> >(), token))) { return async_initiate<NullaryToken, void()>( detail::initiate_post_with_executor<
link/modules/asio-standalone/asio/include/asio/prefer.hpp view
@@ -2,7 +2,7 @@ // prefer.hpp // ~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -118,10 +118,10 @@ namespace asio_prefer_fn { -using asio::conditional_t;-using asio::decay_t;+using asio::conditional;+using asio::decay; using asio::declval;-using asio::enable_if_t;+using asio::enable_if; using asio::is_applicable_property; using asio::traits::prefer_free; using asio::traits::prefer_member;@@ -149,187 +149,195 @@ typename = void, typename = void, typename = void> struct call_traits {- static constexpr overload_type overload = ill_formed;- static constexpr bool is_noexcept = false;+ ASIO_STATIC_CONSTEXPR(overload_type, overload = ill_formed);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); typedef void result_type; }; template <typename Impl, typename T, typename Property> struct call_traits<Impl, T, void(Property),- enable_if_t<+ typename enable_if< is_applicable_property<- decay_t<T>,- decay_t<Property>+ typename decay<T>::type,+ typename decay<Property>::type >::value- >,- enable_if_t<- decay_t<Property>::is_preferable- >,- enable_if_t<+ >::type,+ typename enable_if<+ decay<Property>::type::is_preferable+ >::type,+ typename enable_if< static_require<T, Property>::is_valid- >>+ >::type> {- static constexpr overload_type overload = identity;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(overload_type, overload = identity);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); - typedef T&& result_type;+#if defined(ASIO_HAS_MOVE)+ typedef ASIO_MOVE_ARG(T) result_type;+#else // defined(ASIO_HAS_MOVE)+ typedef ASIO_MOVE_ARG(typename decay<T>::type) result_type;+#endif // defined(ASIO_HAS_MOVE) }; template <typename Impl, typename T, typename Property> struct call_traits<Impl, T, void(Property),- enable_if_t<+ typename enable_if< is_applicable_property<- decay_t<T>,- decay_t<Property>+ typename decay<T>::type,+ typename decay<Property>::type >::value- >,- enable_if_t<- decay_t<Property>::is_preferable- >,- enable_if_t<+ >::type,+ typename enable_if<+ decay<Property>::type::is_preferable+ >::type,+ typename enable_if< !static_require<T, Property>::is_valid- >,- enable_if_t<+ >::type,+ typename enable_if< require_member<typename Impl::template proxy<T>::type, Property>::is_valid- >> :+ >::type> : require_member<typename Impl::template proxy<T>::type, Property> {- static constexpr overload_type overload = call_require_member;+ ASIO_STATIC_CONSTEXPR(overload_type, overload = call_require_member); }; template <typename Impl, typename T, typename Property> struct call_traits<Impl, T, void(Property),- enable_if_t<+ typename enable_if< is_applicable_property<- decay_t<T>,- decay_t<Property>+ typename decay<T>::type,+ typename decay<Property>::type >::value- >,- enable_if_t<- decay_t<Property>::is_preferable- >,- enable_if_t<+ >::type,+ typename enable_if<+ decay<Property>::type::is_preferable+ >::type,+ typename enable_if< !static_require<T, Property>::is_valid- >,- enable_if_t<+ >::type,+ typename enable_if< !require_member<typename Impl::template proxy<T>::type, Property>::is_valid- >,- enable_if_t<+ >::type,+ typename enable_if< require_free<T, Property>::is_valid- >> :+ >::type> : require_free<T, Property> {- static constexpr overload_type overload = call_require_free;+ ASIO_STATIC_CONSTEXPR(overload_type, overload = call_require_free); }; template <typename Impl, typename T, typename Property> struct call_traits<Impl, T, void(Property),- enable_if_t<+ typename enable_if< is_applicable_property<- decay_t<T>,- decay_t<Property>+ typename decay<T>::type,+ typename decay<Property>::type >::value- >,- enable_if_t<- decay_t<Property>::is_preferable- >,- enable_if_t<+ >::type,+ typename enable_if<+ decay<Property>::type::is_preferable+ >::type,+ typename enable_if< !static_require<T, Property>::is_valid- >,- enable_if_t<+ >::type,+ typename enable_if< !require_member<typename Impl::template proxy<T>::type, Property>::is_valid- >,- enable_if_t<+ >::type,+ typename enable_if< !require_free<T, Property>::is_valid- >,- enable_if_t<+ >::type,+ typename enable_if< prefer_member<typename Impl::template proxy<T>::type, Property>::is_valid- >> :+ >::type> : prefer_member<typename Impl::template proxy<T>::type, Property> {- static constexpr overload_type overload = call_prefer_member;+ ASIO_STATIC_CONSTEXPR(overload_type, overload = call_prefer_member); }; template <typename Impl, typename T, typename Property> struct call_traits<Impl, T, void(Property),- enable_if_t<+ typename enable_if< is_applicable_property<- decay_t<T>,- decay_t<Property>+ typename decay<T>::type,+ typename decay<Property>::type >::value- >,- enable_if_t<- decay_t<Property>::is_preferable- >,- enable_if_t<+ >::type,+ typename enable_if<+ decay<Property>::type::is_preferable+ >::type,+ typename enable_if< !static_require<T, Property>::is_valid- >,- enable_if_t<+ >::type,+ typename enable_if< !require_member<typename Impl::template proxy<T>::type, Property>::is_valid- >,- enable_if_t<+ >::type,+ typename enable_if< !require_free<T, Property>::is_valid- >,- enable_if_t<+ >::type,+ typename enable_if< !prefer_member<typename Impl::template proxy<T>::type, Property>::is_valid- >,- enable_if_t<+ >::type,+ typename enable_if< prefer_free<T, Property>::is_valid- >> :+ >::type> : prefer_free<T, Property> {- static constexpr overload_type overload = call_prefer_free;+ ASIO_STATIC_CONSTEXPR(overload_type, overload = call_prefer_free); }; template <typename Impl, typename T, typename Property> struct call_traits<Impl, T, void(Property),- enable_if_t<+ typename enable_if< is_applicable_property<- decay_t<T>,- decay_t<Property>+ typename decay<T>::type,+ typename decay<Property>::type >::value- >,- enable_if_t<- decay_t<Property>::is_preferable- >,- enable_if_t<+ >::type,+ typename enable_if<+ decay<Property>::type::is_preferable+ >::type,+ typename enable_if< !static_require<T, Property>::is_valid- >,- enable_if_t<+ >::type,+ typename enable_if< !require_member<typename Impl::template proxy<T>::type, Property>::is_valid- >,- enable_if_t<+ >::type,+ typename enable_if< !require_free<T, Property>::is_valid- >,- enable_if_t<+ >::type,+ typename enable_if< !prefer_member<typename Impl::template proxy<T>::type, Property>::is_valid- >,- enable_if_t<+ >::type,+ typename enable_if< !prefer_free<T, Property>::is_valid- >>+ >::type> {- static constexpr overload_type overload = identity;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(overload_type, overload = identity);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); - typedef T&& result_type;+#if defined(ASIO_HAS_MOVE)+ typedef ASIO_MOVE_ARG(T) result_type;+#else // defined(ASIO_HAS_MOVE)+ typedef ASIO_MOVE_ARG(typename decay<T>::type) result_type;+#endif // defined(ASIO_HAS_MOVE) }; template <typename Impl, typename T, typename P0, typename P1> struct call_traits<Impl, T, void(P0, P1),- enable_if_t<+ typename enable_if< call_traits<Impl, T, void(P0)>::overload != ill_formed- >,- enable_if_t<+ >::type,+ typename enable_if< call_traits< Impl, typename call_traits<Impl, T, void(P0)>::result_type, void(P1) >::overload != ill_formed- >>+ >::type> {- static constexpr overload_type overload = two_props;+ ASIO_STATIC_CONSTEXPR(overload_type, overload = two_props); - static constexpr bool is_noexcept =+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = ( call_traits<Impl, T, void(P0)>::is_noexcept &&@@ -338,51 +346,51 @@ typename call_traits<Impl, T, void(P0)>::result_type, void(P1) >::is_noexcept- );+ )); - typedef decay_t<+ typedef typename decay< typename call_traits< Impl, typename call_traits<Impl, T, void(P0)>::result_type, void(P1) >::result_type- > result_type;+ >::type result_type; }; template <typename Impl, typename T, typename P0,- typename P1, typename... PN>-struct call_traits<Impl, T, void(P0, P1, PN...),- enable_if_t<+ typename P1, typename ASIO_ELLIPSIS PN>+struct call_traits<Impl, T, void(P0, P1, PN ASIO_ELLIPSIS),+ typename enable_if< call_traits<Impl, T, void(P0)>::overload != ill_formed- >,- enable_if_t<+ >::type,+ typename enable_if< call_traits< Impl, typename call_traits<Impl, T, void(P0)>::result_type,- void(P1, PN...)+ void(P1, PN ASIO_ELLIPSIS) >::overload != ill_formed- >>+ >::type> {- static constexpr overload_type overload = n_props;+ ASIO_STATIC_CONSTEXPR(overload_type, overload = n_props); - static constexpr bool is_noexcept =+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = ( call_traits<Impl, T, void(P0)>::is_noexcept && call_traits< Impl, typename call_traits<Impl, T, void(P0)>::result_type,- void(P1, PN...)+ void(P1, PN ASIO_ELLIPSIS) >::is_noexcept- );+ )); - typedef decay_t<+ typedef typename decay< typename call_traits< Impl, typename call_traits<Impl, T, void(P0)>::result_type,- void(P1, PN...)+ void(P1, PN ASIO_ELLIPSIS) >::result_type- > result_type;+ >::type result_type; }; struct impl@@ -395,25 +403,29 @@ struct type { template <typename P>- auto require(P&& p)+ auto require(ASIO_MOVE_ARG(P) p) noexcept( noexcept(- declval<conditional_t<true, T, P>>().require(static_cast<P&&>(p))+ declval<typename conditional<true, T, P>::type>().require(+ ASIO_MOVE_CAST(P)(p)) ) ) -> decltype(- declval<conditional_t<true, T, P>>().require(static_cast<P&&>(p))+ declval<typename conditional<true, T, P>::type>().require(+ ASIO_MOVE_CAST(P)(p)) ); template <typename P>- auto prefer(P&& p)+ auto prefer(ASIO_MOVE_ARG(P) p) noexcept( noexcept(- declval<conditional_t<true, T, P>>().prefer(static_cast<P&&>(p))+ declval<typename conditional<true, T, P>::type>().prefer(+ ASIO_MOVE_CAST(P)(p)) ) ) -> decltype(- declval<conditional_t<true, T, P>>().prefer(static_cast<P&&>(p))+ declval<typename conditional<true, T, P>::type>().prefer(+ ASIO_MOVE_CAST(P)(p)) ); }; #else // defined(ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)@@ -424,85 +436,122 @@ }; template <typename T, typename Property>- ASIO_NODISCARD constexpr enable_if_t<+ ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if< call_traits<impl, T, void(Property)>::overload == identity, typename call_traits<impl, T, void(Property)>::result_type- >- operator()(T&& t, Property&&) const- noexcept(call_traits<impl, T, void(Property)>::is_noexcept)+ >::type+ operator()(+ ASIO_MOVE_ARG(T) t,+ ASIO_MOVE_ARG(Property)) const+ ASIO_NOEXCEPT_IF((+ call_traits<impl, T, void(Property)>::is_noexcept)) {- return static_cast<T&&>(t);+ return ASIO_MOVE_CAST(T)(t); } template <typename T, typename Property>- ASIO_NODISCARD constexpr enable_if_t<+ ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if< call_traits<impl, T, void(Property)>::overload == call_require_member, typename call_traits<impl, T, void(Property)>::result_type- >- operator()(T&& t, Property&& p) const- noexcept(call_traits<impl, T, void(Property)>::is_noexcept)+ >::type+ operator()(+ ASIO_MOVE_ARG(T) t,+ ASIO_MOVE_ARG(Property) p) const+ ASIO_NOEXCEPT_IF((+ call_traits<impl, T, void(Property)>::is_noexcept)) {- return static_cast<T&&>(t).require(static_cast<Property&&>(p));+ return ASIO_MOVE_CAST(T)(t).require(+ ASIO_MOVE_CAST(Property)(p)); } template <typename T, typename Property>- ASIO_NODISCARD constexpr enable_if_t<+ ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if< call_traits<impl, T, void(Property)>::overload == call_require_free, typename call_traits<impl, T, void(Property)>::result_type- >- operator()(T&& t, Property&& p) const- noexcept(call_traits<impl, T, void(Property)>::is_noexcept)+ >::type+ operator()(+ ASIO_MOVE_ARG(T) t,+ ASIO_MOVE_ARG(Property) p) const+ ASIO_NOEXCEPT_IF((+ call_traits<impl, T, void(Property)>::is_noexcept)) {- return require(static_cast<T&&>(t), static_cast<Property&&>(p));+ return require(+ ASIO_MOVE_CAST(T)(t),+ ASIO_MOVE_CAST(Property)(p)); } template <typename T, typename Property>- ASIO_NODISCARD constexpr enable_if_t<+ ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if< call_traits<impl, T, void(Property)>::overload == call_prefer_member, typename call_traits<impl, T, void(Property)>::result_type- >- operator()(T&& t, Property&& p) const- noexcept(call_traits<impl, T, void(Property)>::is_noexcept)+ >::type+ operator()(+ ASIO_MOVE_ARG(T) t,+ ASIO_MOVE_ARG(Property) p) const+ ASIO_NOEXCEPT_IF((+ call_traits<impl, T, void(Property)>::is_noexcept)) {- return static_cast<T&&>(t).prefer(static_cast<Property&&>(p));+ return ASIO_MOVE_CAST(T)(t).prefer(+ ASIO_MOVE_CAST(Property)(p)); } template <typename T, typename Property>- ASIO_NODISCARD constexpr enable_if_t<+ ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if< call_traits<impl, T, void(Property)>::overload == call_prefer_free, typename call_traits<impl, T, void(Property)>::result_type- >- operator()(T&& t, Property&& p) const- noexcept(call_traits<impl, T, void(Property)>::is_noexcept)+ >::type+ operator()(+ ASIO_MOVE_ARG(T) t,+ ASIO_MOVE_ARG(Property) p) const+ ASIO_NOEXCEPT_IF((+ call_traits<impl, T, void(Property)>::is_noexcept)) {- return prefer(static_cast<T&&>(t), static_cast<Property&&>(p));+ return prefer(+ ASIO_MOVE_CAST(T)(t),+ ASIO_MOVE_CAST(Property)(p)); } template <typename T, typename P0, typename P1>- ASIO_NODISCARD constexpr enable_if_t<+ ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if< call_traits<impl, T, void(P0, P1)>::overload == two_props, typename call_traits<impl, T, void(P0, P1)>::result_type- >- operator()(T&& t, P0&& p0, P1&& p1) const- noexcept(call_traits<impl, T, void(P0, P1)>::is_noexcept)+ >::type+ operator()(+ ASIO_MOVE_ARG(T) t,+ ASIO_MOVE_ARG(P0) p0,+ ASIO_MOVE_ARG(P1) p1) const+ ASIO_NOEXCEPT_IF((+ call_traits<impl, T, void(P0, P1)>::is_noexcept)) { return (*this)(- (*this)(static_cast<T&&>(t), static_cast<P0&&>(p0)),- static_cast<P1&&>(p1));+ (*this)(+ ASIO_MOVE_CAST(T)(t),+ ASIO_MOVE_CAST(P0)(p0)),+ ASIO_MOVE_CAST(P1)(p1)); } template <typename T, typename P0, typename P1,- typename... PN>- ASIO_NODISCARD constexpr enable_if_t<- call_traits<impl, T, void(P0, P1, PN...)>::overload == n_props,- typename call_traits<impl, T, void(P0, P1, PN...)>::result_type- >- operator()(T&& t, P0&& p0, P1&& p1, PN&&... pn) const- noexcept(call_traits<impl, T, void(P0, P1, PN...)>::is_noexcept)+ typename ASIO_ELLIPSIS PN>+ ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if<+ call_traits<impl, T,+ void(P0, P1, PN ASIO_ELLIPSIS)>::overload == n_props,+ typename call_traits<impl, T,+ void(P0, P1, PN ASIO_ELLIPSIS)>::result_type+ >::type+ operator()(+ ASIO_MOVE_ARG(T) t,+ ASIO_MOVE_ARG(P0) p0,+ ASIO_MOVE_ARG(P1) p1,+ ASIO_MOVE_ARG(PN) ASIO_ELLIPSIS pn) const+ ASIO_NOEXCEPT_IF((+ call_traits<impl, T, void(P0, P1, PN ASIO_ELLIPSIS)>::is_noexcept)) { return (*this)(- (*this)(static_cast<T&&>(t), static_cast<P0&&>(p0)),- static_cast<P1&&>(p1), static_cast<PN&&>(pn)...);+ (*this)(+ ASIO_MOVE_CAST(T)(t),+ ASIO_MOVE_CAST(P0)(p0)),+ ASIO_MOVE_CAST(P1)(p1),+ ASIO_MOVE_CAST(PN)(pn) ASIO_ELLIPSIS); } }; @@ -519,13 +568,15 @@ namespace asio { namespace { -static constexpr const asio_prefer_fn::impl&+static ASIO_CONSTEXPR const asio_prefer_fn::impl& prefer = asio_prefer_fn::static_instance<>::instance; } // namespace typedef asio_prefer_fn::impl prefer_t; +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+ template <typename T, typename... Properties> struct can_prefer : integral_constant<bool,@@ -535,14 +586,54 @@ { }; +#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename T, typename P0 = void,+ typename P1 = void, typename P2 = void>+struct can_prefer :+ integral_constant<bool,+ asio_prefer_fn::call_traits<+ prefer_t, T, void(P0, P1, P2)>::overload+ != asio_prefer_fn::ill_formed>+{+};++template <typename T, typename P0, typename P1>+struct can_prefer<T, P0, P1> :+ integral_constant<bool,+ asio_prefer_fn::call_traits<+ prefer_t, T, void(P0, P1)>::overload+ != asio_prefer_fn::ill_formed>+{+};++template <typename T, typename P0>+struct can_prefer<T, P0> :+ integral_constant<bool,+ asio_prefer_fn::call_traits<+ prefer_t, T, void(P0)>::overload+ != asio_prefer_fn::ill_formed>+{+};++template <typename T>+struct can_prefer<T> :+ false_type+{+};++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+ #if defined(ASIO_HAS_VARIABLE_TEMPLATES) -template <typename T, typename... Properties>+template <typename T, typename ASIO_ELLIPSIS Properties> constexpr bool can_prefer_v- = can_prefer<T, Properties...>::value;+ = can_prefer<T, Properties ASIO_ELLIPSIS>::value; #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+ template <typename T, typename... Properties> struct is_nothrow_prefer : integral_constant<bool,@@ -551,13 +642,51 @@ { }; +#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename T, typename P0 = void,+ typename P1 = void, typename P2 = void>+struct is_nothrow_prefer :+ integral_constant<bool,+ asio_prefer_fn::call_traits<+ prefer_t, T, void(P0, P1, P2)>::is_noexcept>+{+};++template <typename T, typename P0, typename P1>+struct is_nothrow_prefer<T, P0, P1> :+ integral_constant<bool,+ asio_prefer_fn::call_traits<+ prefer_t, T, void(P0, P1)>::is_noexcept>+{+};++template <typename T, typename P0>+struct is_nothrow_prefer<T, P0> :+ integral_constant<bool,+ asio_prefer_fn::call_traits<+ prefer_t, T, void(P0)>::is_noexcept>+{+};++template <typename T>+struct is_nothrow_prefer<T> :+ false_type+{+};++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+ #if defined(ASIO_HAS_VARIABLE_TEMPLATES) -template <typename T, typename... Properties>-constexpr bool is_nothrow_prefer_v = is_nothrow_prefer<T, Properties...>::value;+template <typename T, typename ASIO_ELLIPSIS Properties>+constexpr bool is_nothrow_prefer_v+ = is_nothrow_prefer<T, Properties ASIO_ELLIPSIS>::value; #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+ template <typename T, typename... Properties> struct prefer_result {@@ -565,8 +694,36 @@ prefer_t, T, void(Properties...)>::result_type type; }; -template <typename T, typename... Properties>-using prefer_result_t = typename prefer_result<T, Properties...>::type;+#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename T, typename P0 = void,+ typename P1 = void, typename P2 = void>+struct prefer_result+{+ typedef typename asio_prefer_fn::call_traits<+ prefer_t, T, void(P0, P1, P2)>::result_type type;+};++template <typename T, typename P0, typename P1>+struct prefer_result<T, P0, P1>+{+ typedef typename asio_prefer_fn::call_traits<+ prefer_t, T, void(P0, P1)>::result_type type;+};++template <typename T, typename P0>+struct prefer_result<T, P0>+{+ typedef typename asio_prefer_fn::call_traits<+ prefer_t, T, void(P0)>::result_type type;+};++template <typename T>+struct prefer_result<T>+{+};++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) } // namespace asio
link/modules/asio-standalone/asio/include/asio/prepend.hpp view
@@ -2,7 +2,7 @@ // prepend.hpp // ~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -16,6 +16,11 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"++#if (defined(ASIO_HAS_STD_TUPLE) \+ && defined(ASIO_HAS_VARIADIC_TEMPLATES)) \+ || defined(GENERATING_DOCUMENTATION)+ #include <tuple> #include "asio/detail/type_traits.hpp" @@ -32,9 +37,11 @@ public: /// Constructor. template <typename T, typename... V>- constexpr explicit prepend_t(T&& completion_token, V&&... values)- : token_(static_cast<T&&>(completion_token)),- values_(static_cast<V&&>(values)...)+ ASIO_CONSTEXPR explicit prepend_t(+ ASIO_MOVE_ARG(T) completion_token,+ ASIO_MOVE_ARG(V)... values)+ : token_(ASIO_MOVE_CAST(T)(completion_token)),+ values_(ASIO_MOVE_CAST(V)(values)...) { } @@ -47,14 +54,15 @@ /// arguments should be passed additional values before the results of the /// operation. template <typename CompletionToken, typename... Values>-ASIO_NODISCARD inline constexpr-prepend_t<decay_t<CompletionToken>, decay_t<Values>...>-prepend(CompletionToken&& completion_token,- Values&&... values)+ASIO_NODISCARD inline ASIO_CONSTEXPR prepend_t<+ typename decay<CompletionToken>::type, typename decay<Values>::type...>+prepend(ASIO_MOVE_ARG(CompletionToken) completion_token,+ ASIO_MOVE_ARG(Values)... values) {- return prepend_t<decay_t<CompletionToken>, decay_t<Values>...>(- static_cast<CompletionToken&&>(completion_token),- static_cast<Values&&>(values)...);+ return prepend_t<+ typename decay<CompletionToken>::type, typename decay<Values>::type...>(+ ASIO_MOVE_CAST(CompletionToken)(completion_token),+ ASIO_MOVE_CAST(Values)(values)...); } } // namespace asio@@ -62,5 +70,9 @@ #include "asio/detail/pop_options.hpp" #include "asio/impl/prepend.hpp"++#endif // (defined(ASIO_HAS_STD_TUPLE)+ // && defined(ASIO_HAS_VARIADIC_TEMPLATES))+ // || defined(GENERATING_DOCUMENTATION) #endif // ASIO_PREPEND_HPP
link/modules/asio-standalone/asio/include/asio/query.hpp view
@@ -2,7 +2,7 @@ // query.hpp // ~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -100,10 +100,10 @@ namespace asio_query_fn { -using asio::conditional_t;-using asio::decay_t;+using asio::conditional;+using asio::decay; using asio::declval;-using asio::enable_if_t;+using asio::enable_if; using asio::is_applicable_property; using asio::traits::query_free; using asio::traits::query_member;@@ -123,66 +123,66 @@ typename = void, typename = void, typename = void, typename = void> struct call_traits {- static constexpr overload_type overload = ill_formed;- static constexpr bool is_noexcept = false;+ ASIO_STATIC_CONSTEXPR(overload_type, overload = ill_formed);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); typedef void result_type; }; template <typename Impl, typename T, typename Property> struct call_traits<Impl, T, void(Property),- enable_if_t<+ typename enable_if< is_applicable_property<- decay_t<T>,- decay_t<Property>+ typename decay<T>::type,+ typename decay<Property>::type >::value- >,- enable_if_t<+ >::type,+ typename enable_if< static_query<T, Property>::is_valid- >> :+ >::type> : static_query<T, Property> {- static constexpr overload_type overload = static_value;+ ASIO_STATIC_CONSTEXPR(overload_type, overload = static_value); }; template <typename Impl, typename T, typename Property> struct call_traits<Impl, T, void(Property),- enable_if_t<+ typename enable_if< is_applicable_property<- decay_t<T>,- decay_t<Property>+ typename decay<T>::type,+ typename decay<Property>::type >::value- >,- enable_if_t<+ >::type,+ typename enable_if< !static_query<T, Property>::is_valid- >,- enable_if_t<+ >::type,+ typename enable_if< query_member<typename Impl::template proxy<T>::type, Property>::is_valid- >> :+ >::type> : query_member<typename Impl::template proxy<T>::type, Property> {- static constexpr overload_type overload = call_member;+ ASIO_STATIC_CONSTEXPR(overload_type, overload = call_member); }; template <typename Impl, typename T, typename Property> struct call_traits<Impl, T, void(Property),- enable_if_t<+ typename enable_if< is_applicable_property<- decay_t<T>,- decay_t<Property>+ typename decay<T>::type,+ typename decay<Property>::type >::value- >,- enable_if_t<+ >::type,+ typename enable_if< !static_query<T, Property>::is_valid- >,- enable_if_t<+ >::type,+ typename enable_if< !query_member<typename Impl::template proxy<T>::type, Property>::is_valid- >,- enable_if_t<+ >::type,+ typename enable_if< query_free<T, Property>::is_valid- >> :+ >::type> : query_free<T, Property> {- static constexpr overload_type overload = call_free;+ ASIO_STATIC_CONSTEXPR(overload_type, overload = call_free); }; struct impl@@ -194,14 +194,16 @@ struct type { template <typename P>- auto query(P&& p)+ auto query(ASIO_MOVE_ARG(P) p) noexcept( noexcept(- declval<conditional_t<true, T, P>>().query(static_cast<P&&>(p))+ declval<typename conditional<true, T, P>::type>().query(+ ASIO_MOVE_CAST(P)(p)) ) ) -> decltype(- declval<conditional_t<true, T, P>>().query(static_cast<P&&>(p))+ declval<typename conditional<true, T, P>::type>().query(+ ASIO_MOVE_CAST(P)(p)) ); }; #else // defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)@@ -210,36 +212,48 @@ }; template <typename T, typename Property>- ASIO_NODISCARD constexpr enable_if_t<+ ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if< call_traits<impl, T, void(Property)>::overload == static_value, typename call_traits<impl, T, void(Property)>::result_type- >- operator()(T&&, Property&&) const- noexcept(call_traits<impl, T, void(Property)>::is_noexcept)+ >::type+ operator()(+ ASIO_MOVE_ARG(T),+ ASIO_MOVE_ARG(Property)) const+ ASIO_NOEXCEPT_IF((+ call_traits<impl, T, void(Property)>::is_noexcept)) {- return static_query<decay_t<T>, decay_t<Property>>::value();+ return static_query<+ typename decay<T>::type,+ typename decay<Property>::type+ >::value(); } template <typename T, typename Property>- ASIO_NODISCARD constexpr enable_if_t<+ ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if< call_traits<impl, T, void(Property)>::overload == call_member, typename call_traits<impl, T, void(Property)>::result_type- >- operator()(T&& t, Property&& p) const- noexcept(call_traits<impl, T, void(Property)>::is_noexcept)+ >::type+ operator()(+ ASIO_MOVE_ARG(T) t,+ ASIO_MOVE_ARG(Property) p) const+ ASIO_NOEXCEPT_IF((+ call_traits<impl, T, void(Property)>::is_noexcept)) {- return static_cast<T&&>(t).query(static_cast<Property&&>(p));+ return ASIO_MOVE_CAST(T)(t).query(ASIO_MOVE_CAST(Property)(p)); } template <typename T, typename Property>- ASIO_NODISCARD constexpr enable_if_t<+ ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if< call_traits<impl, T, void(Property)>::overload == call_free, typename call_traits<impl, T, void(Property)>::result_type- >- operator()(T&& t, Property&& p) const- noexcept(call_traits<impl, T, void(Property)>::is_noexcept)+ >::type+ operator()(+ ASIO_MOVE_ARG(T) t,+ ASIO_MOVE_ARG(Property) p) const+ ASIO_NOEXCEPT_IF((+ call_traits<impl, T, void(Property)>::is_noexcept)) {- return query(static_cast<T&&>(t), static_cast<Property&&>(p));+ return query(ASIO_MOVE_CAST(T)(t), ASIO_MOVE_CAST(Property)(p)); } }; @@ -256,7 +270,7 @@ namespace asio { namespace { -static constexpr const asio_query_fn::impl&+static ASIO_CONSTEXPR const asio_query_fn::impl& query = asio_query_fn::static_instance<>::instance; } // namespace@@ -274,7 +288,8 @@ #if defined(ASIO_HAS_VARIABLE_TEMPLATES) template <typename T, typename Property>-constexpr bool can_query_v = can_query<T, Property>::value;+constexpr bool can_query_v+ = can_query<T, Property>::value; #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) @@ -288,7 +303,8 @@ #if defined(ASIO_HAS_VARIABLE_TEMPLATES) template <typename T, typename Property>-constexpr bool is_nothrow_query_v = is_nothrow_query<T, Property>::value;+constexpr bool is_nothrow_query_v+ = is_nothrow_query<T, Property>::value; #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) @@ -298,9 +314,6 @@ typedef typename asio_query_fn::call_traits< query_t, T, void(Property)>::result_type type; };--template <typename T, typename Property>-using query_result_t = typename query_result<T, Property>::type; } // namespace asio
link/modules/asio-standalone/asio/include/asio/random_access_file.hpp view
@@ -2,7 +2,7 @@ // random_access_file.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/read.hpp view
@@ -2,7 +2,7 @@ // read.hpp // ~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -85,9 +85,9 @@ */ template <typename SyncReadStream, typename MutableBufferSequence> std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers,- constraint_t<+ typename constraint< is_mutable_buffer_sequence<MutableBufferSequence>::value- > = 0);+ >::type = 0); /// Attempt to read a certain amount of data from a stream before returning. /**@@ -128,9 +128,9 @@ template <typename SyncReadStream, typename MutableBufferSequence> std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers, asio::error_code& ec,- constraint_t<+ typename constraint< is_mutable_buffer_sequence<MutableBufferSequence>::value- > = 0);+ >::type = 0); /// Attempt to read a certain amount of data from a stream before returning. /**@@ -182,12 +182,9 @@ typename CompletionCondition> std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers, CompletionCondition completion_condition,- constraint_t<+ typename constraint< is_mutable_buffer_sequence<MutableBufferSequence>::value- > = 0,- constraint_t<- is_completion_condition<CompletionCondition>::value- > = 0);+ >::type = 0); /// Attempt to read a certain amount of data from a stream before returning. /**@@ -232,12 +229,9 @@ typename CompletionCondition> std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers, CompletionCondition completion_condition, asio::error_code& ec,- constraint_t<+ typename constraint< is_mutable_buffer_sequence<MutableBufferSequence>::value- > = 0,- constraint_t<- is_completion_condition<CompletionCondition>::value- > = 0);+ >::type = 0); #if !defined(ASIO_NO_DYNAMIC_BUFFER_V1) @@ -270,13 +264,13 @@ */ template <typename SyncReadStream, typename DynamicBuffer_v1> std::size_t read(SyncReadStream& s,- DynamicBuffer_v1&& buffers,- constraint_t<- is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value- > = 0,- constraint_t<- !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value- > = 0);+ ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+ typename constraint<+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+ >::type = 0,+ typename constraint<+ !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+ >::type = 0); /// Attempt to read a certain amount of data from a stream before returning. /**@@ -306,14 +300,14 @@ */ template <typename SyncReadStream, typename DynamicBuffer_v1> std::size_t read(SyncReadStream& s,- DynamicBuffer_v1&& buffers,+ ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, asio::error_code& ec,- constraint_t<- is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value- > = 0,- constraint_t<- !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value- > = 0);+ typename constraint<+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+ >::type = 0,+ typename constraint<+ !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+ >::type = 0); /// Attempt to read a certain amount of data from a stream before returning. /**@@ -354,17 +348,14 @@ template <typename SyncReadStream, typename DynamicBuffer_v1, typename CompletionCondition> std::size_t read(SyncReadStream& s,- DynamicBuffer_v1&& buffers,+ ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, CompletionCondition completion_condition,- constraint_t<- is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value- > = 0,- constraint_t<- !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value- > = 0,- constraint_t<- is_completion_condition<CompletionCondition>::value- > = 0);+ typename constraint<+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+ >::type = 0,+ typename constraint<+ !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+ >::type = 0); /// Attempt to read a certain amount of data from a stream before returning. /**@@ -406,17 +397,14 @@ template <typename SyncReadStream, typename DynamicBuffer_v1, typename CompletionCondition> std::size_t read(SyncReadStream& s,- DynamicBuffer_v1&& buffers,+ ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, CompletionCondition completion_condition, asio::error_code& ec,- constraint_t<- is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value- > = 0,- constraint_t<- !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value- > = 0,- constraint_t<- is_completion_condition<CompletionCondition>::value- > = 0);+ typename constraint<+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+ >::type = 0,+ typename constraint<+ !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+ >::type = 0); #if !defined(ASIO_NO_EXTENSIONS) #if !defined(ASIO_NO_IOSTREAM)@@ -518,10 +506,7 @@ template <typename SyncReadStream, typename Allocator, typename CompletionCondition> std::size_t read(SyncReadStream& s, basic_streambuf<Allocator>& b,- CompletionCondition completion_condition,- constraint_t<- is_completion_condition<CompletionCondition>::value- > = 0);+ CompletionCondition completion_condition); /// Attempt to read a certain amount of data from a stream before returning. /**@@ -562,10 +547,7 @@ template <typename SyncReadStream, typename Allocator, typename CompletionCondition> std::size_t read(SyncReadStream& s, basic_streambuf<Allocator>& b,- CompletionCondition completion_condition, asio::error_code& ec,- constraint_t<- is_completion_condition<CompletionCondition>::value- > = 0);+ CompletionCondition completion_condition, asio::error_code& ec); #endif // !defined(ASIO_NO_IOSTREAM) #endif // !defined(ASIO_NO_EXTENSIONS)@@ -600,9 +582,9 @@ */ template <typename SyncReadStream, typename DynamicBuffer_v2> std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers,- constraint_t<+ typename constraint< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- > = 0);+ >::type = 0); /// Attempt to read a certain amount of data from a stream before returning. /**@@ -633,9 +615,9 @@ template <typename SyncReadStream, typename DynamicBuffer_v2> std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers, asio::error_code& ec,- constraint_t<+ typename constraint< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- > = 0);+ >::type = 0); /// Attempt to read a certain amount of data from a stream before returning. /**@@ -677,12 +659,9 @@ typename CompletionCondition> std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers, CompletionCondition completion_condition,- constraint_t<+ typename constraint< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- > = 0,- constraint_t<- is_completion_condition<CompletionCondition>::value- > = 0);+ >::type = 0); /// Attempt to read a certain amount of data from a stream before returning. /**@@ -725,12 +704,9 @@ typename CompletionCondition> std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers, CompletionCondition completion_condition, asio::error_code& ec,- constraint_t<+ typename constraint< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- > = 0,- constraint_t<- is_completion_condition<CompletionCondition>::value- > = 0);+ >::type = 0); /*@}*/ /**@@ -786,7 +762,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -819,28 +795,23 @@ */ template <typename AsyncReadStream, typename MutableBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) ReadToken = default_completion_token_t<- typename AsyncReadStream::executor_type>>-inline auto async_read(AsyncReadStream& s, const MutableBufferSequence& buffers,- ReadToken&& token = default_completion_token_t<- typename AsyncReadStream::executor_type>(),- constraint_t<+ std::size_t)) ReadToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+ typename AsyncReadStream::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+async_read(AsyncReadStream& s, const MutableBufferSequence& buffers,+ ASIO_MOVE_ARG(ReadToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(+ typename AsyncReadStream::executor_type),+ typename constraint< is_mutable_buffer_sequence<MutableBufferSequence>::value- > = 0,- constraint_t<- !is_completion_condition<ReadToken>::value- > = 0)- -> decltype(+ >::type = 0)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<ReadToken, void (asio::error_code, std::size_t)>(- declval<detail::initiate_async_read<AsyncReadStream>>(),- token, buffers, transfer_all()))-{- return async_initiate<ReadToken,- void (asio::error_code, std::size_t)>(- detail::initiate_async_read<AsyncReadStream>(s),- token, buffers, transfer_all());-}+ declval<detail::initiate_async_read<AsyncReadStream> >(),+ token, buffers, transfer_all()))); /// Start an asynchronous operation to read a certain amount of data from a /// stream.@@ -895,7 +866,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -924,30 +895,25 @@ template <typename AsyncReadStream, typename MutableBufferSequence, typename CompletionCondition, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) ReadToken = default_completion_token_t<- typename AsyncReadStream::executor_type>>-inline auto async_read(AsyncReadStream& s, const MutableBufferSequence& buffers,+ std::size_t)) ReadToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+ typename AsyncReadStream::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+async_read(AsyncReadStream& s, const MutableBufferSequence& buffers, CompletionCondition completion_condition,- ReadToken&& token = default_completion_token_t<- typename AsyncReadStream::executor_type>(),- constraint_t<+ ASIO_MOVE_ARG(ReadToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(+ typename AsyncReadStream::executor_type),+ typename constraint< is_mutable_buffer_sequence<MutableBufferSequence>::value- > = 0,- constraint_t<- is_completion_condition<CompletionCondition>::value- > = 0)- -> decltype(+ >::type = 0)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<ReadToken, void (asio::error_code, std::size_t)>(- declval<detail::initiate_async_read<AsyncReadStream>>(),+ declval<detail::initiate_async_read<AsyncReadStream> >(), token, buffers,- static_cast<CompletionCondition&&>(completion_condition)))-{- return async_initiate<ReadToken,- void (asio::error_code, std::size_t)>(- detail::initiate_async_read<AsyncReadStream>(s), token, buffers,- static_cast<CompletionCondition&&>(completion_condition));-}+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition)))); #if !defined(ASIO_NO_DYNAMIC_BUFFER_V1) @@ -995,7 +961,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -1019,31 +985,28 @@ */ template <typename AsyncReadStream, typename DynamicBuffer_v1, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) ReadToken = default_completion_token_t<- typename AsyncReadStream::executor_type>>-inline auto async_read(AsyncReadStream& s, DynamicBuffer_v1&& buffers,- ReadToken&& token = default_completion_token_t<- typename AsyncReadStream::executor_type>(),- constraint_t<- is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value- > = 0,- constraint_t<- !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value- > = 0,- constraint_t<- !is_completion_condition<ReadToken>::value- > = 0)- -> decltype(+ std::size_t)) ReadToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+ typename AsyncReadStream::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+async_read(AsyncReadStream& s,+ ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+ ASIO_MOVE_ARG(ReadToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(+ typename AsyncReadStream::executor_type),+ typename constraint<+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+ >::type = 0,+ typename constraint<+ !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+ >::type = 0)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<ReadToken, void (asio::error_code, std::size_t)>(- declval<detail::initiate_async_read_dynbuf_v1<AsyncReadStream>>(),- token, static_cast<DynamicBuffer_v1&&>(buffers), transfer_all()))-{- return async_initiate<ReadToken,- void (asio::error_code, std::size_t)>(- detail::initiate_async_read_dynbuf_v1<AsyncReadStream>(s),- token, static_cast<DynamicBuffer_v1&&>(buffers), transfer_all());-}+ declval<detail::initiate_async_read_dynbuf_v1<AsyncReadStream> >(),+ token, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+ transfer_all()))); /// Start an asynchronous operation to read a certain amount of data from a /// stream.@@ -1103,7 +1066,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -1122,34 +1085,29 @@ template <typename AsyncReadStream, typename DynamicBuffer_v1, typename CompletionCondition, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) ReadToken = default_completion_token_t<- typename AsyncReadStream::executor_type>>-inline auto async_read(AsyncReadStream& s, DynamicBuffer_v1&& buffers,+ std::size_t)) ReadToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+ typename AsyncReadStream::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+async_read(AsyncReadStream& s,+ ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, CompletionCondition completion_condition,- ReadToken&& token = default_completion_token_t<- typename AsyncReadStream::executor_type>(),- constraint_t<- is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value- > = 0,- constraint_t<- !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value- > = 0,- constraint_t<- is_completion_condition<CompletionCondition>::value- > = 0)- -> decltype(+ ASIO_MOVE_ARG(ReadToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(+ typename AsyncReadStream::executor_type),+ typename constraint<+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+ >::type = 0,+ typename constraint<+ !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+ >::type = 0)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<ReadToken, void (asio::error_code, std::size_t)>(- declval<detail::initiate_async_read_dynbuf_v1<AsyncReadStream>>(),- token, static_cast<DynamicBuffer_v1&&>(buffers),- static_cast<CompletionCondition&&>(completion_condition)))-{- return async_initiate<ReadToken,- void (asio::error_code, std::size_t)>(- detail::initiate_async_read_dynbuf_v1<AsyncReadStream>(s),- token, static_cast<DynamicBuffer_v1&&>(buffers),- static_cast<CompletionCondition&&>(completion_condition));-}+ declval<detail::initiate_async_read_dynbuf_v1<AsyncReadStream> >(),+ token, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition)))); #if !defined(ASIO_NO_EXTENSIONS) #if !defined(ASIO_NO_IOSTREAM)@@ -1196,7 +1154,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -1220,25 +1178,18 @@ */ template <typename AsyncReadStream, typename Allocator, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) ReadToken = default_completion_token_t<- typename AsyncReadStream::executor_type>>-inline auto async_read(AsyncReadStream& s, basic_streambuf<Allocator>& b,- ReadToken&& token = default_completion_token_t<- typename AsyncReadStream::executor_type>(),- constraint_t<- !is_completion_condition<ReadToken>::value- > = 0)- -> decltype(- async_initiate<ReadToken,- void (asio::error_code, std::size_t)>(- declval<detail::initiate_async_read_dynbuf_v1<AsyncReadStream>>(),- token, basic_streambuf_ref<Allocator>(b), transfer_all()))-{- return async_initiate<ReadToken,- void (asio::error_code, std::size_t)>(- detail::initiate_async_read_dynbuf_v1<AsyncReadStream>(s),- token, basic_streambuf_ref<Allocator>(b), transfer_all());-}+ std::size_t)) ReadToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+ typename AsyncReadStream::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+async_read(AsyncReadStream& s, basic_streambuf<Allocator>& b,+ ASIO_MOVE_ARG(ReadToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(+ typename AsyncReadStream::executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_read(s, basic_streambuf_ref<Allocator>(b),+ ASIO_MOVE_CAST(ReadToken)(token)))); /// Start an asynchronous operation to read a certain amount of data from a /// stream.@@ -1296,7 +1247,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -1315,28 +1266,20 @@ template <typename AsyncReadStream, typename Allocator, typename CompletionCondition, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) ReadToken = default_completion_token_t<- typename AsyncReadStream::executor_type>>-inline auto async_read(AsyncReadStream& s, basic_streambuf<Allocator>& b,+ std::size_t)) ReadToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+ typename AsyncReadStream::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+async_read(AsyncReadStream& s, basic_streambuf<Allocator>& b, CompletionCondition completion_condition,- ReadToken&& token = default_completion_token_t<- typename AsyncReadStream::executor_type>(),- constraint_t<- is_completion_condition<CompletionCondition>::value- > = 0)- -> decltype(- async_initiate<ReadToken,- void (asio::error_code, std::size_t)>(- declval<detail::initiate_async_read_dynbuf_v1<AsyncReadStream>>(),- token, basic_streambuf_ref<Allocator>(b),- static_cast<CompletionCondition&&>(completion_condition)))-{- return async_initiate<ReadToken,- void (asio::error_code, std::size_t)>(- detail::initiate_async_read_dynbuf_v1<AsyncReadStream>(s),- token, basic_streambuf_ref<Allocator>(b),- static_cast<CompletionCondition&&>(completion_condition));-}+ ASIO_MOVE_ARG(ReadToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(+ typename AsyncReadStream::executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_read(s, basic_streambuf_ref<Allocator>(b),+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition),+ ASIO_MOVE_CAST(ReadToken)(token)))); #endif // !defined(ASIO_NO_IOSTREAM) #endif // !defined(ASIO_NO_EXTENSIONS)@@ -1386,7 +1329,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -1410,28 +1353,24 @@ */ template <typename AsyncReadStream, typename DynamicBuffer_v2, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) ReadToken = default_completion_token_t<- typename AsyncReadStream::executor_type>>-inline auto async_read(AsyncReadStream& s, DynamicBuffer_v2 buffers,- ReadToken&& token = default_completion_token_t<- typename AsyncReadStream::executor_type>(),- constraint_t<+ std::size_t)) ReadToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+ typename AsyncReadStream::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+async_read(AsyncReadStream& s, DynamicBuffer_v2 buffers,+ ASIO_MOVE_ARG(ReadToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(+ typename AsyncReadStream::executor_type),+ typename constraint< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- > = 0,- constraint_t<- !is_completion_condition<ReadToken>::value- > = 0)- -> decltype(+ >::type = 0)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<ReadToken, void (asio::error_code, std::size_t)>(- declval<detail::initiate_async_read_dynbuf_v2<AsyncReadStream>>(),- token, static_cast<DynamicBuffer_v2&&>(buffers), transfer_all()))-{- return async_initiate<ReadToken,- void (asio::error_code, std::size_t)>(- detail::initiate_async_read_dynbuf_v2<AsyncReadStream>(s),- token, static_cast<DynamicBuffer_v2&&>(buffers), transfer_all());-}+ declval<detail::initiate_async_read_dynbuf_v2<AsyncReadStream> >(),+ token, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+ transfer_all()))); /// Start an asynchronous operation to read a certain amount of data from a /// stream.@@ -1491,7 +1430,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -1510,31 +1449,25 @@ template <typename AsyncReadStream, typename DynamicBuffer_v2, typename CompletionCondition, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) ReadToken = default_completion_token_t<- typename AsyncReadStream::executor_type>>-inline auto async_read(AsyncReadStream& s, DynamicBuffer_v2 buffers,+ std::size_t)) ReadToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+ typename AsyncReadStream::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+async_read(AsyncReadStream& s, DynamicBuffer_v2 buffers, CompletionCondition completion_condition,- ReadToken&& token = default_completion_token_t<- typename AsyncReadStream::executor_type>(),- constraint_t<+ ASIO_MOVE_ARG(ReadToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(+ typename AsyncReadStream::executor_type),+ typename constraint< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- > = 0,- constraint_t<- is_completion_condition<CompletionCondition>::value- > = 0)- -> decltype(+ >::type = 0)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<ReadToken, void (asio::error_code, std::size_t)>(- declval<detail::initiate_async_read_dynbuf_v2<AsyncReadStream>>(),- token, static_cast<DynamicBuffer_v2&&>(buffers),- static_cast<CompletionCondition&&>(completion_condition)))-{- return async_initiate<ReadToken,- void (asio::error_code, std::size_t)>(- detail::initiate_async_read_dynbuf_v2<AsyncReadStream>(s),- token, static_cast<DynamicBuffer_v2&&>(buffers),- static_cast<CompletionCondition&&>(completion_condition));-}+ declval<detail::initiate_async_read_dynbuf_v2<AsyncReadStream> >(),+ token, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition)))); /*@}*/
link/modules/asio-standalone/asio/include/asio/read_at.hpp view
@@ -2,7 +2,7 @@ // read_at.hpp // ~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -190,10 +190,7 @@ typename CompletionCondition> std::size_t read_at(SyncRandomAccessReadDevice& d, uint64_t offset, const MutableBufferSequence& buffers,- CompletionCondition completion_condition,- constraint_t<- is_completion_condition<CompletionCondition>::value- > = 0);+ CompletionCondition completion_condition); /// Attempt to read a certain amount of data at the specified offset before /// returning.@@ -242,10 +239,7 @@ typename CompletionCondition> std::size_t read_at(SyncRandomAccessReadDevice& d, uint64_t offset, const MutableBufferSequence& buffers,- CompletionCondition completion_condition, asio::error_code& ec,- constraint_t<- is_completion_condition<CompletionCondition>::value- > = 0);+ CompletionCondition completion_condition, asio::error_code& ec); #if !defined(ASIO_NO_EXTENSIONS) #if !defined(ASIO_NO_IOSTREAM)@@ -356,10 +350,7 @@ typename CompletionCondition> std::size_t read_at(SyncRandomAccessReadDevice& d, uint64_t offset, basic_streambuf<Allocator>& b,- CompletionCondition completion_condition,- constraint_t<- is_completion_condition<CompletionCondition>::value- > = 0);+ CompletionCondition completion_condition); /// Attempt to read a certain amount of data at the specified offset before /// returning.@@ -403,10 +394,7 @@ typename CompletionCondition> std::size_t read_at(SyncRandomAccessReadDevice& d, uint64_t offset, basic_streambuf<Allocator>& b,- CompletionCondition completion_condition, asio::error_code& ec,- constraint_t<- is_completion_condition<CompletionCondition>::value- > = 0);+ CompletionCondition completion_condition, asio::error_code& ec); #endif // !defined(ASIO_NO_IOSTREAM) #endif // !defined(ASIO_NO_EXTENSIONS)@@ -465,7 +453,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -498,26 +486,21 @@ */ template <typename AsyncRandomAccessReadDevice, typename MutableBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) ReadToken = default_completion_token_t<- typename AsyncRandomAccessReadDevice::executor_type>>-inline auto async_read_at(AsyncRandomAccessReadDevice& d,- uint64_t offset, const MutableBufferSequence& buffers,- ReadToken&& token = default_completion_token_t<- typename AsyncRandomAccessReadDevice::executor_type>(),- constraint_t<- !is_completion_condition<ReadToken>::value- > = 0)- -> decltype(+ std::size_t)) ReadToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+ typename AsyncRandomAccessReadDevice::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+async_read_at(AsyncRandomAccessReadDevice& d, uint64_t offset,+ const MutableBufferSequence& buffers,+ ASIO_MOVE_ARG(ReadToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(+ typename AsyncRandomAccessReadDevice::executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<ReadToken, void (asio::error_code, std::size_t)>(- declval<detail::initiate_async_read_at<AsyncRandomAccessReadDevice>>(),- token, offset, buffers, transfer_all()))-{- return async_initiate<ReadToken,- void (asio::error_code, std::size_t)>(- detail::initiate_async_read_at<AsyncRandomAccessReadDevice>(d),- token, offset, buffers, transfer_all());-}+ declval<detail::initiate_async_read_at<AsyncRandomAccessReadDevice> >(),+ token, offset, buffers, transfer_all()))); /// Start an asynchronous operation to read a certain amount of data at the /// specified offset.@@ -575,7 +558,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -604,29 +587,23 @@ template <typename AsyncRandomAccessReadDevice, typename MutableBufferSequence, typename CompletionCondition, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) ReadToken = default_completion_token_t<- typename AsyncRandomAccessReadDevice::executor_type>>-inline auto async_read_at(AsyncRandomAccessReadDevice& d,+ std::size_t)) ReadToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+ typename AsyncRandomAccessReadDevice::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+async_read_at(AsyncRandomAccessReadDevice& d, uint64_t offset, const MutableBufferSequence& buffers, CompletionCondition completion_condition,- ReadToken&& token = default_completion_token_t<- typename AsyncRandomAccessReadDevice::executor_type>(),- constraint_t<- is_completion_condition<CompletionCondition>::value- > = 0)- -> decltype(+ ASIO_MOVE_ARG(ReadToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(+ typename AsyncRandomAccessReadDevice::executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<ReadToken, void (asio::error_code, std::size_t)>(- declval<detail::initiate_async_read_at<AsyncRandomAccessReadDevice>>(),+ declval<detail::initiate_async_read_at<AsyncRandomAccessReadDevice> >(), token, offset, buffers,- static_cast<CompletionCondition&&>(completion_condition)))-{- return async_initiate<ReadToken,- void (asio::error_code, std::size_t)>(- detail::initiate_async_read_at<AsyncRandomAccessReadDevice>(d),- token, offset, buffers,- static_cast<CompletionCondition&&>(completion_condition));-}+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition)))); #if !defined(ASIO_NO_EXTENSIONS) #if !defined(ASIO_NO_IOSTREAM)@@ -671,7 +648,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -695,27 +672,22 @@ */ template <typename AsyncRandomAccessReadDevice, typename Allocator, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) ReadToken = default_completion_token_t<- typename AsyncRandomAccessReadDevice::executor_type>>-inline auto async_read_at(AsyncRandomAccessReadDevice& d,+ std::size_t)) ReadToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+ typename AsyncRandomAccessReadDevice::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+async_read_at(AsyncRandomAccessReadDevice& d, uint64_t offset, basic_streambuf<Allocator>& b,- ReadToken&& token = default_completion_token_t<- typename AsyncRandomAccessReadDevice::executor_type>(),- constraint_t<- !is_completion_condition<ReadToken>::value- > = 0)- -> decltype(+ ASIO_MOVE_ARG(ReadToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(+ typename AsyncRandomAccessReadDevice::executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<ReadToken, void (asio::error_code, std::size_t)>( declval<detail::initiate_async_read_at_streambuf<- AsyncRandomAccessReadDevice>>(),- token, offset, &b, transfer_all()))-{- return async_initiate<ReadToken,- void (asio::error_code, std::size_t)>(- detail::initiate_async_read_at_streambuf<AsyncRandomAccessReadDevice>(d),- token, offset, &b, transfer_all());-}+ AsyncRandomAccessReadDevice> >(),+ token, offset, &b, transfer_all()))); /// Start an asynchronous operation to read a certain amount of data at the /// specified offset.@@ -771,7 +743,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -790,29 +762,24 @@ template <typename AsyncRandomAccessReadDevice, typename Allocator, typename CompletionCondition, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) ReadToken = default_completion_token_t<- typename AsyncRandomAccessReadDevice::executor_type>>-inline auto async_read_at(AsyncRandomAccessReadDevice& d, uint64_t offset,- basic_streambuf<Allocator>& b, CompletionCondition completion_condition,- ReadToken&& token = default_completion_token_t<- typename AsyncRandomAccessReadDevice::executor_type>(),- constraint_t<- is_completion_condition<CompletionCondition>::value- > = 0)- -> decltype(+ std::size_t)) ReadToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+ typename AsyncRandomAccessReadDevice::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+async_read_at(AsyncRandomAccessReadDevice& d,+ uint64_t offset, basic_streambuf<Allocator>& b,+ CompletionCondition completion_condition,+ ASIO_MOVE_ARG(ReadToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(+ typename AsyncRandomAccessReadDevice::executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<ReadToken, void (asio::error_code, std::size_t)>( declval<detail::initiate_async_read_at_streambuf<- AsyncRandomAccessReadDevice>>(),+ AsyncRandomAccessReadDevice> >(), token, offset, &b,- static_cast<CompletionCondition&&>(completion_condition)))-{- return async_initiate<ReadToken,- void (asio::error_code, std::size_t)>(- detail::initiate_async_read_at_streambuf<AsyncRandomAccessReadDevice>(d),- token, offset, &b,- static_cast<CompletionCondition&&>(completion_condition));-}+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition)))); #endif // !defined(ASIO_NO_IOSTREAM) #endif // !defined(ASIO_NO_EXTENSIONS)
link/modules/asio-standalone/asio/include/asio/read_until.hpp view
@@ -2,7 +2,7 @@ // read_until.hpp // ~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -73,7 +73,8 @@ #else enum {- value = asio::is_function<remove_pointer_t<T>>::value+ value = asio::is_function<+ typename asio::remove_pointer<T>::type>::value || detail::has_result_type<T>::value }; #endif@@ -146,13 +147,13 @@ */ template <typename SyncReadStream, typename DynamicBuffer_v1> std::size_t read_until(SyncReadStream& s,- DynamicBuffer_v1&& buffers, char delim,- constraint_t<- is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value- > = 0,- constraint_t<- !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value- > = 0);+ ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, char delim,+ typename constraint<+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+ >::type = 0,+ typename constraint<+ !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+ >::type = 0); /// Read data into a dynamic buffer sequence until it contains a specified /// delimiter.@@ -190,14 +191,14 @@ */ template <typename SyncReadStream, typename DynamicBuffer_v1> std::size_t read_until(SyncReadStream& s,- DynamicBuffer_v1&& buffers,+ ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, char delim, asio::error_code& ec,- constraint_t<- is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value- > = 0,- constraint_t<- !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value- > = 0);+ typename constraint<+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+ >::type = 0,+ typename constraint<+ !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+ >::type = 0); /// Read data into a dynamic buffer sequence until it contains a specified /// delimiter.@@ -252,14 +253,14 @@ */ template <typename SyncReadStream, typename DynamicBuffer_v1> std::size_t read_until(SyncReadStream& s,- DynamicBuffer_v1&& buffers,+ ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, ASIO_STRING_VIEW_PARAM delim,- constraint_t<- is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value- > = 0,- constraint_t<- !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value- > = 0);+ typename constraint<+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+ >::type = 0,+ typename constraint<+ !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+ >::type = 0); /// Read data into a dynamic buffer sequence until it contains a specified /// delimiter.@@ -297,15 +298,15 @@ */ template <typename SyncReadStream, typename DynamicBuffer_v1> std::size_t read_until(SyncReadStream& s,- DynamicBuffer_v1&& buffers,+ ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, ASIO_STRING_VIEW_PARAM delim, asio::error_code& ec,- constraint_t<- is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value- > = 0,- constraint_t<- !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value- > = 0);+ typename constraint<+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+ >::type = 0,+ typename constraint<+ !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+ >::type = 0); #if !defined(ASIO_NO_EXTENSIONS) #if defined(ASIO_HAS_BOOST_REGEX) \@@ -365,15 +366,16 @@ * This data may be the start of a new line, to be extracted by a subsequent * @c read_until operation. */-template <typename SyncReadStream, typename DynamicBuffer_v1, typename Traits>-std::size_t read_until(SyncReadStream& s, DynamicBuffer_v1&& buffers,- const boost::basic_regex<char, Traits>& expr,- constraint_t<- is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value- > = 0,- constraint_t<- !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value- > = 0);+template <typename SyncReadStream, typename DynamicBuffer_v1>+std::size_t read_until(SyncReadStream& s,+ ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+ const boost::regex& expr,+ typename constraint<+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+ >::type = 0,+ typename constraint<+ !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+ >::type = 0); /// Read data into a dynamic buffer sequence until some part of the data it /// contains matches a regular expression.@@ -411,15 +413,16 @@ * expression. An application will typically leave that data in the dynamic * buffer sequence for a subsequent read_until operation to examine. */-template <typename SyncReadStream, typename DynamicBuffer_v1, typename Traits>-std::size_t read_until(SyncReadStream& s, DynamicBuffer_v1&& buffers,- const boost::basic_regex<char, Traits>& expr, asio::error_code& ec,- constraint_t<- is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value- > = 0,- constraint_t<- !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value- > = 0);+template <typename SyncReadStream, typename DynamicBuffer_v1>+std::size_t read_until(SyncReadStream& s,+ ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+ const boost::regex& expr, asio::error_code& ec,+ typename constraint<+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+ >::type = 0,+ typename constraint<+ !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+ >::type = 0); #endif // defined(ASIO_HAS_BOOST_REGEX) // || defined(GENERATING_DOCUMENTATION)@@ -480,7 +483,7 @@ * @par Examples * To read data into a dynamic buffer sequence until whitespace is encountered: * @code typedef asio::buffers_iterator<- * asio::const_buffer> iterator;+ * asio::const_buffers_1> iterator; * * std::pair<iterator, bool> * match_whitespace(iterator begin, iterator end)@@ -529,17 +532,17 @@ template <typename SyncReadStream, typename DynamicBuffer_v1, typename MatchCondition> std::size_t read_until(SyncReadStream& s,- DynamicBuffer_v1&& buffers,+ ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, MatchCondition match_condition,- constraint_t<+ typename constraint< is_match_condition<MatchCondition>::value- > = 0,- constraint_t<- is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value- > = 0,- constraint_t<- !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value- > = 0);+ >::type = 0,+ typename constraint<+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+ >::type = 0,+ typename constraint<+ !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+ >::type = 0); /// Read data into a dynamic buffer sequence until a function object indicates a /// match.@@ -597,17 +600,17 @@ template <typename SyncReadStream, typename DynamicBuffer_v1, typename MatchCondition> std::size_t read_until(SyncReadStream& s,- DynamicBuffer_v1&& buffers,+ ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, MatchCondition match_condition, asio::error_code& ec,- constraint_t<+ typename constraint< is_match_condition<MatchCondition>::value- > = 0,- constraint_t<- is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value- > = 0,- constraint_t<- !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value- > = 0);+ >::type = 0,+ typename constraint<+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+ >::type = 0,+ typename constraint<+ !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+ >::type = 0); #if !defined(ASIO_NO_IOSTREAM) @@ -839,10 +842,9 @@ * This data may be the start of a new line, to be extracted by a subsequent * @c read_until operation. */-template <typename SyncReadStream, typename Allocator, typename Traits>+template <typename SyncReadStream, typename Allocator> std::size_t read_until(SyncReadStream& s,- asio::basic_streambuf<Allocator>& b,- const boost::basic_regex<char, Traits>& expr);+ asio::basic_streambuf<Allocator>& b, const boost::regex& expr); /// Read data into a streambuf until some part of the data it contains matches /// a regular expression.@@ -877,10 +879,9 @@ * application will typically leave that data in the streambuf for a subsequent * read_until operation to examine. */-template <typename SyncReadStream, typename Allocator, typename Traits>+template <typename SyncReadStream, typename Allocator> std::size_t read_until(SyncReadStream& s,- asio::basic_streambuf<Allocator>& b,- const boost::basic_regex<char, Traits>& expr,+ asio::basic_streambuf<Allocator>& b, const boost::regex& expr, asio::error_code& ec); #endif // defined(ASIO_HAS_BOOST_REGEX)@@ -989,7 +990,7 @@ template <typename SyncReadStream, typename Allocator, typename MatchCondition> std::size_t read_until(SyncReadStream& s, asio::basic_streambuf<Allocator>& b, MatchCondition match_condition,- constraint_t<is_match_condition<MatchCondition>::value> = 0);+ typename constraint<is_match_condition<MatchCondition>::value>::type = 0); /// Read data into a streambuf until a function object indicates a match. /**@@ -1046,7 +1047,7 @@ std::size_t read_until(SyncReadStream& s, asio::basic_streambuf<Allocator>& b, MatchCondition match_condition, asio::error_code& ec,- constraint_t<is_match_condition<MatchCondition>::value> = 0);+ typename constraint<is_match_condition<MatchCondition>::value>::type = 0); #endif // !defined(ASIO_NO_IOSTREAM) #endif // !defined(ASIO_NO_EXTENSIONS)@@ -1107,9 +1108,9 @@ */ template <typename SyncReadStream, typename DynamicBuffer_v2> std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers, char delim,- constraint_t<+ typename constraint< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- > = 0);+ >::type = 0); /// Read data into a dynamic buffer sequence until it contains a specified /// delimiter.@@ -1148,9 +1149,9 @@ template <typename SyncReadStream, typename DynamicBuffer_v2> std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers, char delim, asio::error_code& ec,- constraint_t<+ typename constraint< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- > = 0);+ >::type = 0); /// Read data into a dynamic buffer sequence until it contains a specified /// delimiter.@@ -1206,9 +1207,9 @@ template <typename SyncReadStream, typename DynamicBuffer_v2> std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers, ASIO_STRING_VIEW_PARAM delim,- constraint_t<+ typename constraint< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- > = 0);+ >::type = 0); /// Read data into a dynamic buffer sequence until it contains a specified /// delimiter.@@ -1247,9 +1248,9 @@ template <typename SyncReadStream, typename DynamicBuffer_v2> std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers, ASIO_STRING_VIEW_PARAM delim, asio::error_code& ec,- constraint_t<+ typename constraint< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- > = 0);+ >::type = 0); #if !defined(ASIO_NO_EXTENSIONS) #if defined(ASIO_HAS_BOOST_REGEX) \@@ -1309,12 +1310,12 @@ * This data may be the start of a new line, to be extracted by a subsequent * @c read_until operation. */-template <typename SyncReadStream, typename DynamicBuffer_v2, typename Traits>+template <typename SyncReadStream, typename DynamicBuffer_v2> std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers,- const boost::basic_regex<char, Traits>& expr,- constraint_t<+ const boost::regex& expr,+ typename constraint< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- > = 0);+ >::type = 0); /// Read data into a dynamic buffer sequence until some part of the data it /// contains matches a regular expression.@@ -1352,12 +1353,12 @@ * expression. An application will typically leave that data in the dynamic * buffer sequence for a subsequent read_until operation to examine. */-template <typename SyncReadStream, typename DynamicBuffer_v2, typename Traits>+template <typename SyncReadStream, typename DynamicBuffer_v2> std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers,- const boost::basic_regex<char, Traits>& expr, asio::error_code& ec,- constraint_t<+ const boost::regex& expr, asio::error_code& ec,+ typename constraint< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- > = 0);+ >::type = 0); #endif // defined(ASIO_HAS_BOOST_REGEX) // || defined(GENERATING_DOCUMENTATION)@@ -1418,7 +1419,7 @@ * @par Examples * To read data into a dynamic buffer sequence until whitespace is encountered: * @code typedef asio::buffers_iterator<- * asio::const_buffer> iterator;+ * asio::const_buffers_1> iterator; * * std::pair<iterator, bool> * match_whitespace(iterator begin, iterator end)@@ -1468,12 +1469,12 @@ typename DynamicBuffer_v2, typename MatchCondition> std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers, MatchCondition match_condition,- constraint_t<+ typename constraint< is_match_condition<MatchCondition>::value- > = 0,- constraint_t<+ >::type = 0,+ typename constraint< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- > = 0);+ >::type = 0); /// Read data into a dynamic buffer sequence until a function object indicates a /// match.@@ -1532,12 +1533,12 @@ typename DynamicBuffer_v2, typename MatchCondition> std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers, MatchCondition match_condition, asio::error_code& ec,- constraint_t<+ typename constraint< is_match_condition<MatchCondition>::value- > = 0,- constraint_t<+ >::type = 0,+ typename constraint< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- > = 0);+ >::type = 0); #endif // !defined(ASIO_NO_EXTENSIONS) @@ -1602,7 +1603,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -1653,29 +1654,27 @@ */ template <typename AsyncReadStream, typename DynamicBuffer_v1, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) ReadToken = default_completion_token_t<- typename AsyncReadStream::executor_type>>-inline auto async_read_until(AsyncReadStream& s,- DynamicBuffer_v1&& buffers, char delim,- ReadToken&& token = default_completion_token_t<- typename AsyncReadStream::executor_type>(),- constraint_t<- is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value- > = 0,- constraint_t<- !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value- > = 0)- -> decltype(+ std::size_t)) ReadToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+ typename AsyncReadStream::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+async_read_until(AsyncReadStream& s,+ ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, char delim,+ ASIO_MOVE_ARG(ReadToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(+ typename AsyncReadStream::executor_type),+ typename constraint<+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+ >::type = 0,+ typename constraint<+ !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+ >::type = 0)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<ReadToken, void (asio::error_code, std::size_t)>(- declval<detail::initiate_async_read_until_delim_v1<AsyncReadStream>>(),- token, static_cast<DynamicBuffer_v1&&>(buffers), delim))-{- return async_initiate<ReadToken,- void (asio::error_code, std::size_t)>(- detail::initiate_async_read_until_delim_v1<AsyncReadStream>(s),- token, static_cast<DynamicBuffer_v1&&>(buffers), delim);-}+ declval<detail::initiate_async_read_until_delim_v1<AsyncReadStream> >(),+ token, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), delim))); /// Start an asynchronous operation to read data into a dynamic buffer sequence /// until it contains a specified delimiter.@@ -1725,7 +1724,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -1776,33 +1775,30 @@ */ template <typename AsyncReadStream, typename DynamicBuffer_v1, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) ReadToken = default_completion_token_t<- typename AsyncReadStream::executor_type>>-inline auto async_read_until(AsyncReadStream& s,- DynamicBuffer_v1&& buffers,+ std::size_t)) ReadToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+ typename AsyncReadStream::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+async_read_until(AsyncReadStream& s,+ ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, ASIO_STRING_VIEW_PARAM delim,- ReadToken&& token = default_completion_token_t<- typename AsyncReadStream::executor_type>(),- constraint_t<- is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value- > = 0,- constraint_t<- !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value- > = 0)- -> decltype(+ ASIO_MOVE_ARG(ReadToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(+ typename AsyncReadStream::executor_type),+ typename constraint<+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+ >::type = 0,+ typename constraint<+ !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+ >::type = 0)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<ReadToken, void (asio::error_code, std::size_t)>( declval<detail::initiate_async_read_until_delim_string_v1<- AsyncReadStream>>(),- token, static_cast<DynamicBuffer_v1&&>(buffers),- static_cast<std::string>(delim)))-{- return async_initiate<ReadToken,- void (asio::error_code, std::size_t)>(- detail::initiate_async_read_until_delim_string_v1<AsyncReadStream>(s),- token, static_cast<DynamicBuffer_v1&&>(buffers),- static_cast<std::string>(delim));-}+ AsyncReadStream> >(),+ token, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+ static_cast<std::string>(delim)))); #if !defined(ASIO_NO_EXTENSIONS) #if defined(ASIO_HAS_BOOST_REGEX) \@@ -1860,7 +1856,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -1910,31 +1906,30 @@ * if they are also supported by the @c AsyncReadStream type's * @c async_read_some operation. */-template <typename AsyncReadStream, typename DynamicBuffer_v1, typename Traits,+template <typename AsyncReadStream, typename DynamicBuffer_v1, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) ReadToken = default_completion_token_t<- typename AsyncReadStream::executor_type>>-inline auto async_read_until(AsyncReadStream& s, DynamicBuffer_v1&& buffers,- const boost::basic_regex<char, Traits>& expr,- ReadToken&& token = default_completion_token_t<- typename AsyncReadStream::executor_type>(),- constraint_t<- is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value- > = 0,- constraint_t<- !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value- > = 0)- -> decltype(+ std::size_t)) ReadToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+ typename AsyncReadStream::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+async_read_until(AsyncReadStream& s,+ ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+ const boost::regex& expr,+ ASIO_MOVE_ARG(ReadToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(+ typename AsyncReadStream::executor_type),+ typename constraint<+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+ >::type = 0,+ typename constraint<+ !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+ >::type = 0)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<ReadToken, void (asio::error_code, std::size_t)>(- declval<detail::initiate_async_read_until_expr_v1<AsyncReadStream>>(),- token, static_cast<DynamicBuffer_v1&&>(buffers), expr))-{- return async_initiate<ReadToken,- void (asio::error_code, std::size_t)>(- detail::initiate_async_read_until_expr_v1<AsyncReadStream>(s),- token, static_cast<DynamicBuffer_v1&&>(buffers), expr);-}+ declval<detail::initiate_async_read_until_expr_v1<AsyncReadStream> >(),+ token, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), expr))); #endif // defined(ASIO_HAS_BOOST_REGEX) // || defined(GENERATING_DOCUMENTATION)@@ -2002,7 +1997,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @note After a successful async_read_until operation, the dynamic buffer * sequence may contain additional data beyond that which matched the function@@ -2021,7 +2016,7 @@ * To asynchronously read data into a @c std::string until whitespace is * encountered: * @code typedef asio::buffers_iterator<- * asio::const_buffer> iterator;+ * asio::const_buffers_1> iterator; * * std::pair<iterator, bool> * match_whitespace(iterator begin, iterator end)@@ -2086,34 +2081,32 @@ template <typename AsyncReadStream, typename DynamicBuffer_v1, typename MatchCondition, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) ReadToken = default_completion_token_t<- typename AsyncReadStream::executor_type>>-inline auto async_read_until(AsyncReadStream& s,- DynamicBuffer_v1&& buffers, MatchCondition match_condition,- ReadToken&& token = default_completion_token_t<- typename AsyncReadStream::executor_type>(),- constraint_t<+ std::size_t)) ReadToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+ typename AsyncReadStream::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+async_read_until(AsyncReadStream& s,+ ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+ MatchCondition match_condition,+ ASIO_MOVE_ARG(ReadToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(+ typename AsyncReadStream::executor_type),+ typename constraint< is_match_condition<MatchCondition>::value- > = 0,- constraint_t<- is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value- > = 0,- constraint_t<- !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value- > = 0)- -> decltype(+ >::type = 0,+ typename constraint<+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+ >::type = 0,+ typename constraint<+ !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+ >::type = 0)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<ReadToken, void (asio::error_code, std::size_t)>(- declval<detail::initiate_async_read_until_match_v1<AsyncReadStream>>(),- token, static_cast<DynamicBuffer_v1&&>(buffers),- match_condition))-{- return async_initiate<ReadToken,- void (asio::error_code, std::size_t)>(- detail::initiate_async_read_until_match_v1<AsyncReadStream>(s),- token, static_cast<DynamicBuffer_v1&&>(buffers),- match_condition);-}+ declval<detail::initiate_async_read_until_match_v1<AsyncReadStream> >(),+ token, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+ match_condition))); #if !defined(ASIO_NO_IOSTREAM) @@ -2164,7 +2157,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -2214,23 +2207,19 @@ */ template <typename AsyncReadStream, typename Allocator, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) ReadToken = default_completion_token_t<- typename AsyncReadStream::executor_type>>-inline auto async_read_until(AsyncReadStream& s,+ std::size_t)) ReadToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+ typename AsyncReadStream::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+async_read_until(AsyncReadStream& s, asio::basic_streambuf<Allocator>& b, char delim,- ReadToken&& token = default_completion_token_t<- typename AsyncReadStream::executor_type>())- -> decltype(- async_initiate<ReadToken,- void (asio::error_code, std::size_t)>(- declval<detail::initiate_async_read_until_delim_v1<AsyncReadStream>>(),- token, basic_streambuf_ref<Allocator>(b), delim))-{- return async_initiate<ReadToken,- void (asio::error_code, std::size_t)>(- detail::initiate_async_read_until_delim_v1<AsyncReadStream>(s),- token, basic_streambuf_ref<Allocator>(b), delim);-}+ ASIO_MOVE_ARG(ReadToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(+ typename AsyncReadStream::executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_read_until(s, basic_streambuf_ref<Allocator>(b),+ delim, ASIO_MOVE_CAST(ReadToken)(token)))); /// Start an asynchronous operation to read data into a streambuf until it /// contains a specified delimiter.@@ -2279,7 +2268,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -2329,27 +2318,20 @@ */ template <typename AsyncReadStream, typename Allocator, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) ReadToken = default_completion_token_t<- typename AsyncReadStream::executor_type>>-inline auto async_read_until(AsyncReadStream& s,+ std::size_t)) ReadToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+ typename AsyncReadStream::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+async_read_until(AsyncReadStream& s, asio::basic_streambuf<Allocator>& b, ASIO_STRING_VIEW_PARAM delim,- ReadToken&& token = default_completion_token_t<- typename AsyncReadStream::executor_type>())- -> decltype(- async_initiate<ReadToken,- void (asio::error_code, std::size_t)>(- declval<detail::initiate_async_read_until_delim_string_v1<- AsyncReadStream>>(),- token, basic_streambuf_ref<Allocator>(b),- static_cast<std::string>(delim)))-{- return async_initiate<ReadToken,- void (asio::error_code, std::size_t)>(- detail::initiate_async_read_until_delim_string_v1<AsyncReadStream>(s),- token, basic_streambuf_ref<Allocator>(b),- static_cast<std::string>(delim));-}+ ASIO_MOVE_ARG(ReadToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(+ typename AsyncReadStream::executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_read_until(s, basic_streambuf_ref<Allocator>(b),+ delim, ASIO_MOVE_CAST(ReadToken)(token)))); #if defined(ASIO_HAS_BOOST_REGEX) \ || defined(GENERATING_DOCUMENTATION)@@ -2403,7 +2385,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -2452,26 +2434,21 @@ * if they are also supported by the @c AsyncReadStream type's * @c async_read_some operation. */-template <typename AsyncReadStream, typename Allocator, typename Traits,+template <typename AsyncReadStream, typename Allocator, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) ReadToken = default_completion_token_t<- typename AsyncReadStream::executor_type>>-inline auto async_read_until(AsyncReadStream& s,- asio::basic_streambuf<Allocator>& b,- const boost::basic_regex<char, Traits>& expr,- ReadToken&& token = default_completion_token_t<- typename AsyncReadStream::executor_type>())- -> decltype(- async_initiate<ReadToken,- void (asio::error_code, std::size_t)>(- declval<detail::initiate_async_read_until_expr_v1<AsyncReadStream>>(),- token, basic_streambuf_ref<Allocator>(b), expr))-{- return async_initiate<ReadToken,- void (asio::error_code, std::size_t)>(- detail::initiate_async_read_until_expr_v1<AsyncReadStream>(s),- token, basic_streambuf_ref<Allocator>(b), expr);-}+ std::size_t)) ReadToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+ typename AsyncReadStream::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+async_read_until(AsyncReadStream& s,+ asio::basic_streambuf<Allocator>& b, const boost::regex& expr,+ ASIO_MOVE_ARG(ReadToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(+ typename AsyncReadStream::executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_read_until(s, basic_streambuf_ref<Allocator>(b),+ expr, ASIO_MOVE_CAST(ReadToken)(token)))); #endif // defined(ASIO_HAS_BOOST_REGEX) // || defined(GENERATING_DOCUMENTATION)@@ -2536,7 +2513,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @note After a successful async_read_until operation, the streambuf may * contain additional data beyond that which matched the function object. An@@ -2618,24 +2595,21 @@ */ template <typename AsyncReadStream, typename Allocator, typename MatchCondition, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) ReadToken = default_completion_token_t<- typename AsyncReadStream::executor_type>>-inline auto async_read_until(AsyncReadStream& s,- asio::basic_streambuf<Allocator>& b, MatchCondition match_condition,- ReadToken&& token = default_completion_token_t<- typename AsyncReadStream::executor_type>(),- constraint_t<is_match_condition<MatchCondition>::value> = 0)- -> decltype(- async_initiate<ReadToken,- void (asio::error_code, std::size_t)>(- declval<detail::initiate_async_read_until_match_v1<AsyncReadStream>>(),- token, basic_streambuf_ref<Allocator>(b), match_condition))-{- return async_initiate<ReadToken,- void (asio::error_code, std::size_t)>(- detail::initiate_async_read_until_match_v1<AsyncReadStream>(s),- token, basic_streambuf_ref<Allocator>(b), match_condition);-}+ std::size_t)) ReadToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+ typename AsyncReadStream::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+async_read_until(AsyncReadStream& s,+ asio::basic_streambuf<Allocator>& b,+ MatchCondition match_condition,+ ASIO_MOVE_ARG(ReadToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(+ typename AsyncReadStream::executor_type),+ typename constraint<is_match_condition<MatchCondition>::value>::type = 0)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_read_until(s, basic_streambuf_ref<Allocator>(b),+ match_condition, ASIO_MOVE_CAST(ReadToken)(token)))); #endif // !defined(ASIO_NO_IOSTREAM) #endif // !defined(ASIO_NO_EXTENSIONS)@@ -2690,7 +2664,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -2741,26 +2715,23 @@ */ template <typename AsyncReadStream, typename DynamicBuffer_v2, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) ReadToken = default_completion_token_t<- typename AsyncReadStream::executor_type>>-inline auto async_read_until(AsyncReadStream& s,- DynamicBuffer_v2 buffers, char delim,- ReadToken&& token = default_completion_token_t<- typename AsyncReadStream::executor_type>(),- constraint_t<+ std::size_t)) ReadToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+ typename AsyncReadStream::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers, char delim,+ ASIO_MOVE_ARG(ReadToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(+ typename AsyncReadStream::executor_type),+ typename constraint< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- > = 0)- -> decltype(+ >::type = 0)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<ReadToken, void (asio::error_code, std::size_t)>(- declval<detail::initiate_async_read_until_delim_v2<AsyncReadStream>>(),- token, static_cast<DynamicBuffer_v2&&>(buffers), delim))-{- return async_initiate<ReadToken,- void (asio::error_code, std::size_t)>(- detail::initiate_async_read_until_delim_v2<AsyncReadStream>(s),- token, static_cast<DynamicBuffer_v2&&>(buffers), delim);-}+ declval<detail::initiate_async_read_until_delim_v2<AsyncReadStream> >(),+ token, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), delim))); /// Start an asynchronous operation to read data into a dynamic buffer sequence /// until it contains a specified delimiter.@@ -2810,7 +2781,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -2861,29 +2832,26 @@ */ template <typename AsyncReadStream, typename DynamicBuffer_v2, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) ReadToken = default_completion_token_t<- typename AsyncReadStream::executor_type>>-inline auto async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers,+ std::size_t)) ReadToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+ typename AsyncReadStream::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers, ASIO_STRING_VIEW_PARAM delim,- ReadToken&& token = default_completion_token_t<- typename AsyncReadStream::executor_type>(),- constraint_t<+ ASIO_MOVE_ARG(ReadToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(+ typename AsyncReadStream::executor_type),+ typename constraint< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- > = 0)- -> decltype(+ >::type = 0)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<ReadToken, void (asio::error_code, std::size_t)>( declval<detail::initiate_async_read_until_delim_string_v2<- AsyncReadStream>>(),- token, static_cast<DynamicBuffer_v2&&>(buffers),- static_cast<std::string>(delim)))-{- return async_initiate<ReadToken,- void (asio::error_code, std::size_t)>(- detail::initiate_async_read_until_delim_string_v2<AsyncReadStream>(s),- token, static_cast<DynamicBuffer_v2&&>(buffers),- static_cast<std::string>(delim));-}+ AsyncReadStream> >(),+ token, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+ static_cast<std::string>(delim)))); #if !defined(ASIO_NO_EXTENSIONS) #if defined(ASIO_HAS_BOOST_REGEX) \@@ -2941,7 +2909,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -2991,28 +2959,26 @@ * if they are also supported by the @c AsyncReadStream type's * @c async_read_some operation. */-template <typename AsyncReadStream, typename DynamicBuffer_v2, typename Traits,+template <typename AsyncReadStream, typename DynamicBuffer_v2, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) ReadToken = default_completion_token_t<- typename AsyncReadStream::executor_type>>-inline auto async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers,- const boost::basic_regex<char, Traits>& expr,- ReadToken&& token = default_completion_token_t<- typename AsyncReadStream::executor_type>(),- constraint_t<+ std::size_t)) ReadToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+ typename AsyncReadStream::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers,+ const boost::regex& expr,+ ASIO_MOVE_ARG(ReadToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(+ typename AsyncReadStream::executor_type),+ typename constraint< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- > = 0)- -> decltype(+ >::type = 0)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<ReadToken, void (asio::error_code, std::size_t)>(- declval<detail::initiate_async_read_until_expr_v2<AsyncReadStream>>(),- token, static_cast<DynamicBuffer_v2&&>(buffers), expr))-{- return async_initiate<ReadToken,- void (asio::error_code, std::size_t)>(- detail::initiate_async_read_until_expr_v2<AsyncReadStream>(s),- token, static_cast<DynamicBuffer_v2&&>(buffers), expr);-}+ declval<detail::initiate_async_read_until_expr_v2<AsyncReadStream> >(),+ token, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), expr))); #endif // defined(ASIO_HAS_BOOST_REGEX) // || defined(GENERATING_DOCUMENTATION)@@ -3080,7 +3046,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @note After a successful async_read_until operation, the dynamic buffer * sequence may contain additional data beyond that which matched the function@@ -3099,7 +3065,7 @@ * To asynchronously read data into a @c std::string until whitespace is * encountered: * @code typedef asio::buffers_iterator<- * asio::const_buffer> iterator;+ * asio::const_buffers_1> iterator; * * std::pair<iterator, bool> * match_whitespace(iterator begin, iterator end)@@ -3164,30 +3130,28 @@ template <typename AsyncReadStream, typename DynamicBuffer_v2, typename MatchCondition, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) ReadToken = default_completion_token_t<- typename AsyncReadStream::executor_type>>-inline auto async_read_until(AsyncReadStream& s,- DynamicBuffer_v2 buffers, MatchCondition match_condition,- ReadToken&& token = default_completion_token_t<- typename AsyncReadStream::executor_type>(),- constraint_t<+ std::size_t)) ReadToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+ typename AsyncReadStream::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers,+ MatchCondition match_condition,+ ASIO_MOVE_ARG(ReadToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(+ typename AsyncReadStream::executor_type),+ typename constraint< is_match_condition<MatchCondition>::value- > = 0,- constraint_t<+ >::type = 0,+ typename constraint< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- > = 0)- -> decltype(+ >::type = 0)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<ReadToken, void (asio::error_code, std::size_t)>(- declval<detail::initiate_async_read_until_match_v2<AsyncReadStream>>(),- token, static_cast<DynamicBuffer_v2&&>(buffers), match_condition))-{- return async_initiate<ReadToken,- void (asio::error_code, std::size_t)>(- detail::initiate_async_read_until_match_v2<AsyncReadStream>(s),- token, static_cast<DynamicBuffer_v2&&>(buffers),- match_condition);-}+ declval<detail::initiate_async_read_until_match_v2<AsyncReadStream> >(),+ token, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+ match_condition))); #endif // !defined(ASIO_NO_EXTENSIONS)
link/modules/asio-standalone/asio/include/asio/readable_pipe.hpp view
@@ -2,7 +2,7 @@ // readable_pipe.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/recycling_allocator.hpp view
@@ -2,7 +2,7 @@ // recycling_allocator.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -44,27 +44,27 @@ }; /// Default constructor.- constexpr recycling_allocator() noexcept+ ASIO_CONSTEXPR recycling_allocator() ASIO_NOEXCEPT { } /// Converting constructor. template <typename U>- constexpr recycling_allocator(- const recycling_allocator<U>&) noexcept+ ASIO_CONSTEXPR recycling_allocator(+ const recycling_allocator<U>&) ASIO_NOEXCEPT { } /// Equality operator. Always returns true.- constexpr bool operator==(- const recycling_allocator&) const noexcept+ ASIO_CONSTEXPR bool operator==(+ const recycling_allocator&) const ASIO_NOEXCEPT { return true; } /// Inequality operator. Always returns false.- constexpr bool operator!=(- const recycling_allocator&) const noexcept+ ASIO_CONSTEXPR bool operator!=(+ const recycling_allocator&) const ASIO_NOEXCEPT { return false; }@@ -105,27 +105,27 @@ }; /// Default constructor.- constexpr recycling_allocator() noexcept+ ASIO_CONSTEXPR recycling_allocator() ASIO_NOEXCEPT { } /// Converting constructor. template <typename U>- constexpr recycling_allocator(- const recycling_allocator<U>&) noexcept+ ASIO_CONSTEXPR recycling_allocator(+ const recycling_allocator<U>&) ASIO_NOEXCEPT { } /// Equality operator. Always returns true.- constexpr bool operator==(- const recycling_allocator&) const noexcept+ ASIO_CONSTEXPR bool operator==(+ const recycling_allocator&) const ASIO_NOEXCEPT { return true; } /// Inequality operator. Always returns false.- constexpr bool operator!=(- const recycling_allocator&) const noexcept+ ASIO_CONSTEXPR bool operator!=(+ const recycling_allocator&) const ASIO_NOEXCEPT { return false; }
link/modules/asio-standalone/asio/include/asio/redirect_error.hpp view
@@ -2,7 +2,7 @@ // redirect_error.hpp // ~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -33,10 +33,11 @@ class redirect_error_t { public:- /// Constructor.+ /// Constructor. template <typename T>- redirect_error_t(T&& completion_token, asio::error_code& ec)- : token_(static_cast<T&&>(completion_token)),+ redirect_error_t(ASIO_MOVE_ARG(T) completion_token,+ asio::error_code& ec)+ : token_(ASIO_MOVE_CAST(T)(completion_token)), ec_(ec) { }@@ -46,53 +47,14 @@ asio::error_code& ec_; }; -/// A function object type that adapts a @ref completion_token to capture-/// error_code values to a variable.-/**- * May also be used directly as a completion token, in which case it adapts the- * asynchronous operation's default completion token (or asio::deferred- * if no default is available).- */-class partial_redirect_error-{-public:- /// Constructor that specifies the variable used to capture error_code values.- explicit partial_redirect_error(asio::error_code& ec)- : ec_(ec)- {- }-- /// Adapt a @ref completion_token to specify that the completion handler- /// should capture error_code values to a variable.- template <typename CompletionToken>- ASIO_NODISCARD inline- constexpr redirect_error_t<decay_t<CompletionToken>>- operator()(CompletionToken&& completion_token) const- {- return redirect_error_t<decay_t<CompletionToken>>(- static_cast<CompletionToken&&>(completion_token), ec_);- }--//private:- asio::error_code& ec_;-};--/// Create a partial completion token adapter that captures error_code values-/// to a variable.-ASIO_NODISCARD inline partial_redirect_error-redirect_error(asio::error_code& ec)-{- return partial_redirect_error(ec);-}- /// Adapt a @ref completion_token to capture error_code values to a variable. template <typename CompletionToken>-ASIO_NODISCARD inline redirect_error_t<decay_t<CompletionToken>>-redirect_error(CompletionToken&& completion_token,+inline redirect_error_t<typename decay<CompletionToken>::type> redirect_error(+ ASIO_MOVE_ARG(CompletionToken) completion_token, asio::error_code& ec) {- return redirect_error_t<decay_t<CompletionToken>>(- static_cast<CompletionToken&&>(completion_token), ec);+ return redirect_error_t<typename decay<CompletionToken>::type>(+ ASIO_MOVE_CAST(CompletionToken)(completion_token), ec); } } // namespace asio
link/modules/asio-standalone/asio/include/asio/registered_buffer.hpp view
@@ -2,7 +2,7 @@ // registered_buffer.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -37,28 +37,28 @@ typedef int native_handle_type; /// Default constructor creates an invalid registered buffer identifier.- registered_buffer_id() noexcept+ registered_buffer_id() ASIO_NOEXCEPT : scope_(0), index_(-1) { } /// Get the native buffer identifier type.- native_handle_type native_handle() const noexcept+ native_handle_type native_handle() const ASIO_NOEXCEPT { return index_; } /// Compare two IDs for equality. friend bool operator==(const registered_buffer_id& lhs,- const registered_buffer_id& rhs) noexcept+ const registered_buffer_id& rhs) ASIO_NOEXCEPT { return lhs.scope_ == rhs.scope_ && lhs.index_ == rhs.index_; } /// Compare two IDs for equality. friend bool operator!=(const registered_buffer_id& lhs,- const registered_buffer_id& rhs) noexcept+ const registered_buffer_id& rhs) ASIO_NOEXCEPT { return lhs.scope_ != rhs.scope_ || lhs.index_ != rhs.index_; }@@ -67,7 +67,7 @@ friend class detail::buffer_registration_base; // Hidden constructor used by buffer registration.- registered_buffer_id(const void* scope, int index) noexcept+ registered_buffer_id(const void* scope, int index) ASIO_NOEXCEPT : scope_(scope), index_(index) {@@ -78,21 +78,27 @@ }; /// Holds a registered buffer over modifiable data.-/**+/** * Satisfies the @c MutableBufferSequence type requirements. */ class mutable_registered_buffer { public:+#if !defined(ASIO_HAS_DECLTYPE) \+ && !defined(GENERATING_DOCUMENTATION)+ typedef mutable_buffer value_type;+#endif // !defined(ASIO_HAS_DECLTYPE)+ // && !defined(GENERATING_DOCUMENTATION)+ /// Default constructor creates an invalid registered buffer.- mutable_registered_buffer() noexcept+ mutable_registered_buffer() ASIO_NOEXCEPT : buffer_(), id_() { } /// Get the underlying mutable buffer.- const mutable_buffer& buffer() const noexcept+ const mutable_buffer& buffer() const ASIO_NOEXCEPT { return buffer_; }@@ -101,7 +107,7 @@ /** * @returns <tt>buffer().data()</tt>. */- void* data() const noexcept+ void* data() const ASIO_NOEXCEPT { return buffer_.data(); }@@ -110,19 +116,19 @@ /** * @returns <tt>buffer().size()</tt>. */- std::size_t size() const noexcept+ std::size_t size() const ASIO_NOEXCEPT { return buffer_.size(); } /// Get the registered buffer identifier.- const registered_buffer_id& id() const noexcept+ const registered_buffer_id& id() const ASIO_NOEXCEPT { return id_; } /// Move the start of the buffer by the specified number of bytes.- mutable_registered_buffer& operator+=(std::size_t n) noexcept+ mutable_registered_buffer& operator+=(std::size_t n) ASIO_NOEXCEPT { buffer_ += n; return *this;@@ -133,7 +139,7 @@ // Hidden constructor used by buffer registration and operators. mutable_registered_buffer(const mutable_buffer& b,- const registered_buffer_id& i) noexcept+ const registered_buffer_id& i) ASIO_NOEXCEPT : buffer_(b), id_(i) {@@ -141,7 +147,7 @@ #if !defined(GENERATING_DOCUMENTATION) friend mutable_registered_buffer buffer(- const mutable_registered_buffer& b, std::size_t n) noexcept;+ const mutable_registered_buffer& b, std::size_t n) ASIO_NOEXCEPT; #endif // !defined(GENERATING_DOCUMENTATION) mutable_buffer buffer_;@@ -149,14 +155,20 @@ }; /// Holds a registered buffer over non-modifiable data.-/**+/** * Satisfies the @c ConstBufferSequence type requirements. */ class const_registered_buffer { public:+#if !defined(ASIO_HAS_DECLTYPE) \+ && !defined(GENERATING_DOCUMENTATION)+ typedef const_buffer value_type;+#endif // !defined(ASIO_HAS_DECLTYPE)+ // && !defined(GENERATING_DOCUMENTATION)+ /// Default constructor creates an invalid registered buffer.- const_registered_buffer() noexcept+ const_registered_buffer() ASIO_NOEXCEPT : buffer_(), id_() {@@ -164,14 +176,14 @@ /// Construct a non-modifiable buffer from a modifiable one. const_registered_buffer(- const mutable_registered_buffer& b) noexcept+ const mutable_registered_buffer& b) ASIO_NOEXCEPT : buffer_(b.buffer()), id_(b.id()) { } /// Get the underlying constant buffer.- const const_buffer& buffer() const noexcept+ const const_buffer& buffer() const ASIO_NOEXCEPT { return buffer_; }@@ -180,7 +192,7 @@ /** * @returns <tt>buffer().data()</tt>. */- const void* data() const noexcept+ const void* data() const ASIO_NOEXCEPT { return buffer_.data(); }@@ -189,19 +201,19 @@ /** * @returns <tt>buffer().size()</tt>. */- std::size_t size() const noexcept+ std::size_t size() const ASIO_NOEXCEPT { return buffer_.size(); } /// Get the registered buffer identifier.- const registered_buffer_id& id() const noexcept+ const registered_buffer_id& id() const ASIO_NOEXCEPT { return id_; } /// Move the start of the buffer by the specified number of bytes.- const_registered_buffer& operator+=(std::size_t n) noexcept+ const_registered_buffer& operator+=(std::size_t n) ASIO_NOEXCEPT { buffer_ += n; return *this;@@ -210,7 +222,7 @@ private: // Hidden constructor used by operators. const_registered_buffer(const const_buffer& b,- const registered_buffer_id& i) noexcept+ const registered_buffer_id& i) ASIO_NOEXCEPT : buffer_(b), id_(i) {@@ -218,7 +230,7 @@ #if !defined(GENERATING_DOCUMENTATION) friend const_registered_buffer buffer(- const const_registered_buffer& b, std::size_t n) noexcept;+ const const_registered_buffer& b, std::size_t n) ASIO_NOEXCEPT; #endif // !defined(GENERATING_DOCUMENTATION) const_buffer buffer_;@@ -229,14 +241,14 @@ /// Get an iterator to the first element in a buffer sequence. inline const mutable_buffer* buffer_sequence_begin(- const mutable_registered_buffer& b) noexcept+ const mutable_registered_buffer& b) ASIO_NOEXCEPT { return &b.buffer(); } /// Get an iterator to the first element in a buffer sequence. inline const const_buffer* buffer_sequence_begin(- const const_registered_buffer& b) noexcept+ const const_registered_buffer& b) ASIO_NOEXCEPT { return &b.buffer(); }@@ -246,14 +258,14 @@ /// Get an iterator to one past the end element in a buffer sequence. inline const mutable_buffer* buffer_sequence_end(- const mutable_registered_buffer& b) noexcept+ const mutable_registered_buffer& b) ASIO_NOEXCEPT { return &b.buffer() + 1; } /// Get an iterator to one past the end element in a buffer sequence. inline const const_buffer* buffer_sequence_end(- const const_registered_buffer& b) noexcept+ const const_registered_buffer& b) ASIO_NOEXCEPT { return &b.buffer() + 1; }@@ -263,28 +275,28 @@ /// Obtain a buffer representing the entire registered buffer. inline mutable_registered_buffer buffer(- const mutable_registered_buffer& b) noexcept+ const mutable_registered_buffer& b) ASIO_NOEXCEPT { return b; } /// Obtain a buffer representing the entire registered buffer. inline const_registered_buffer buffer(- const const_registered_buffer& b) noexcept+ const const_registered_buffer& b) ASIO_NOEXCEPT { return b; } /// Obtain a buffer representing part of a registered buffer. inline mutable_registered_buffer buffer(- const mutable_registered_buffer& b, std::size_t n) noexcept+ const mutable_registered_buffer& b, std::size_t n) ASIO_NOEXCEPT { return mutable_registered_buffer(buffer(b.buffer_, n), b.id_); } /// Obtain a buffer representing part of a registered buffer. inline const_registered_buffer buffer(- const const_registered_buffer& b, std::size_t n) noexcept+ const const_registered_buffer& b, std::size_t n) ASIO_NOEXCEPT { return const_registered_buffer(buffer(b.buffer_, n), b.id_); }@@ -297,7 +309,7 @@ * @relates mutable_registered_buffer */ inline mutable_registered_buffer operator+(- const mutable_registered_buffer& b, std::size_t n) noexcept+ const mutable_registered_buffer& b, std::size_t n) ASIO_NOEXCEPT { mutable_registered_buffer tmp(b); tmp += n;@@ -309,7 +321,7 @@ * @relates mutable_registered_buffer */ inline mutable_registered_buffer operator+(std::size_t n,- const mutable_registered_buffer& b) noexcept+ const mutable_registered_buffer& b) ASIO_NOEXCEPT { return b + n; }@@ -320,7 +332,7 @@ * @relates const_registered_buffer */ inline const_registered_buffer operator+(const const_registered_buffer& b,- std::size_t n) noexcept+ std::size_t n) ASIO_NOEXCEPT { const_registered_buffer tmp(b); tmp += n;@@ -332,7 +344,7 @@ * @relates const_registered_buffer */ inline const_registered_buffer operator+(std::size_t n,- const const_registered_buffer& b) noexcept+ const const_registered_buffer& b) ASIO_NOEXCEPT { return b + n; }
link/modules/asio-standalone/asio/include/asio/require.hpp view
@@ -2,7 +2,7 @@ // require.hpp // ~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -107,10 +107,10 @@ namespace asio_require_fn { -using asio::conditional_t;-using asio::decay_t;+using asio::conditional;+using asio::decay; using asio::declval;-using asio::enable_if_t;+using asio::enable_if; using asio::is_applicable_property; using asio::traits::require_free; using asio::traits::require_member;@@ -132,95 +132,99 @@ typename = void, typename = void, typename = void, typename = void> struct call_traits {- static constexpr overload_type overload = ill_formed;- static constexpr bool is_noexcept = false;+ ASIO_STATIC_CONSTEXPR(overload_type, overload = ill_formed);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); typedef void result_type; }; template <typename Impl, typename T, typename Property> struct call_traits<Impl, T, void(Property),- enable_if_t<+ typename enable_if< is_applicable_property<- decay_t<T>,- decay_t<Property>+ typename decay<T>::type,+ typename decay<Property>::type >::value- >,- enable_if_t<- decay_t<Property>::is_requirable- >,- enable_if_t<+ >::type,+ typename enable_if<+ decay<Property>::type::is_requirable+ >::type,+ typename enable_if< static_require<T, Property>::is_valid- >>+ >::type> {- static constexpr overload_type overload = identity;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(overload_type, overload = identity);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); - typedef T&& result_type;+#if defined(ASIO_HAS_MOVE)+ typedef ASIO_MOVE_ARG(T) result_type;+#else // defined(ASIO_HAS_MOVE)+ typedef ASIO_MOVE_ARG(typename decay<T>::type) result_type;+#endif // defined(ASIO_HAS_MOVE) }; template <typename Impl, typename T, typename Property> struct call_traits<Impl, T, void(Property),- enable_if_t<+ typename enable_if< is_applicable_property<- decay_t<T>,- decay_t<Property>+ typename decay<T>::type,+ typename decay<Property>::type >::value- >,- enable_if_t<- decay_t<Property>::is_requirable- >,- enable_if_t<+ >::type,+ typename enable_if<+ decay<Property>::type::is_requirable+ >::type,+ typename enable_if< !static_require<T, Property>::is_valid- >,- enable_if_t<+ >::type,+ typename enable_if< require_member<typename Impl::template proxy<T>::type, Property>::is_valid- >> :+ >::type> : require_member<typename Impl::template proxy<T>::type, Property> {- static constexpr overload_type overload = call_member;+ ASIO_STATIC_CONSTEXPR(overload_type, overload = call_member); }; template <typename Impl, typename T, typename Property> struct call_traits<Impl, T, void(Property),- enable_if_t<+ typename enable_if< is_applicable_property<- decay_t<T>,- decay_t<Property>+ typename decay<T>::type,+ typename decay<Property>::type >::value- >,- enable_if_t<- decay_t<Property>::is_requirable- >,- enable_if_t<+ >::type,+ typename enable_if<+ decay<Property>::type::is_requirable+ >::type,+ typename enable_if< !static_require<T, Property>::is_valid- >,- enable_if_t<+ >::type,+ typename enable_if< !require_member<typename Impl::template proxy<T>::type, Property>::is_valid- >,- enable_if_t<+ >::type,+ typename enable_if< require_free<T, Property>::is_valid- >> :+ >::type> : require_free<T, Property> {- static constexpr overload_type overload = call_free;+ ASIO_STATIC_CONSTEXPR(overload_type, overload = call_free); }; template <typename Impl, typename T, typename P0, typename P1> struct call_traits<Impl, T, void(P0, P1),- enable_if_t<+ typename enable_if< call_traits<Impl, T, void(P0)>::overload != ill_formed- >,- enable_if_t<+ >::type,+ typename enable_if< call_traits< Impl, typename call_traits<Impl, T, void(P0)>::result_type, void(P1) >::overload != ill_formed- >>+ >::type> {- static constexpr overload_type overload = two_props;+ ASIO_STATIC_CONSTEXPR(overload_type, overload = two_props); - static constexpr bool is_noexcept =+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = ( call_traits<Impl, T, void(P0)>::is_noexcept &&@@ -229,51 +233,51 @@ typename call_traits<Impl, T, void(P0)>::result_type, void(P1) >::is_noexcept- );+ )); - typedef decay_t<+ typedef typename decay< typename call_traits< Impl, typename call_traits<Impl, T, void(P0)>::result_type, void(P1) >::result_type- > result_type;+ >::type result_type; }; template <typename Impl, typename T, typename P0,- typename P1, typename... PN>-struct call_traits<Impl, T, void(P0, P1, PN...),- enable_if_t<+ typename P1, typename ASIO_ELLIPSIS PN>+struct call_traits<Impl, T, void(P0, P1, PN ASIO_ELLIPSIS),+ typename enable_if< call_traits<Impl, T, void(P0)>::overload != ill_formed- >,- enable_if_t<+ >::type,+ typename enable_if< call_traits< Impl, typename call_traits<Impl, T, void(P0)>::result_type,- void(P1, PN...)+ void(P1, PN ASIO_ELLIPSIS) >::overload != ill_formed- >>+ >::type> {- static constexpr overload_type overload = n_props;+ ASIO_STATIC_CONSTEXPR(overload_type, overload = n_props); - static constexpr bool is_noexcept =+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = ( call_traits<Impl, T, void(P0)>::is_noexcept && call_traits< Impl, typename call_traits<Impl, T, void(P0)>::result_type,- void(P1, PN...)+ void(P1, PN ASIO_ELLIPSIS) >::is_noexcept- );+ )); - typedef decay_t<+ typedef typename decay< typename call_traits< Impl, typename call_traits<Impl, T, void(P0)>::result_type,- void(P1, PN...)+ void(P1, PN ASIO_ELLIPSIS) >::result_type- > result_type;+ >::type result_type; }; struct impl@@ -285,14 +289,16 @@ struct type { template <typename P>- auto require(P&& p)+ auto require(ASIO_MOVE_ARG(P) p) noexcept( noexcept(- declval<conditional_t<true, T, P>>().require(static_cast<P&&>(p))+ declval<typename conditional<true, T, P>::type>().require(+ ASIO_MOVE_CAST(P)(p)) ) ) -> decltype(- declval<conditional_t<true, T, P>>().require(static_cast<P&&>(p))+ declval<typename conditional<true, T, P>::type>().require(+ ASIO_MOVE_CAST(P)(p)) ); }; #else // defined(ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)@@ -301,63 +307,91 @@ }; template <typename T, typename Property>- ASIO_NODISCARD constexpr enable_if_t<+ ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if< call_traits<impl, T, void(Property)>::overload == identity, typename call_traits<impl, T, void(Property)>::result_type- >- operator()(T&& t, Property&&) const- noexcept(call_traits<impl, T, void(Property)>::is_noexcept)+ >::type+ operator()(+ ASIO_MOVE_ARG(T) t,+ ASIO_MOVE_ARG(Property)) const+ ASIO_NOEXCEPT_IF((+ call_traits<impl, T, void(Property)>::is_noexcept)) {- return static_cast<T&&>(t);+ return ASIO_MOVE_CAST(T)(t); } template <typename T, typename Property>- ASIO_NODISCARD constexpr enable_if_t<+ ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if< call_traits<impl, T, void(Property)>::overload == call_member, typename call_traits<impl, T, void(Property)>::result_type- >- operator()(T&& t, Property&& p) const- noexcept(call_traits<impl, T, void(Property)>::is_noexcept)+ >::type+ operator()(+ ASIO_MOVE_ARG(T) t,+ ASIO_MOVE_ARG(Property) p) const+ ASIO_NOEXCEPT_IF((+ call_traits<impl, T, void(Property)>::is_noexcept)) {- return static_cast<T&&>(t).require(static_cast<Property&&>(p));+ return ASIO_MOVE_CAST(T)(t).require(+ ASIO_MOVE_CAST(Property)(p)); } template <typename T, typename Property>- ASIO_NODISCARD constexpr enable_if_t<+ ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if< call_traits<impl, T, void(Property)>::overload == call_free, typename call_traits<impl, T, void(Property)>::result_type- >- operator()(T&& t, Property&& p) const- noexcept(call_traits<impl, T, void(Property)>::is_noexcept)+ >::type+ operator()(+ ASIO_MOVE_ARG(T) t,+ ASIO_MOVE_ARG(Property) p) const+ ASIO_NOEXCEPT_IF((+ call_traits<impl, T, void(Property)>::is_noexcept)) {- return require(static_cast<T&&>(t), static_cast<Property&&>(p));+ return require(+ ASIO_MOVE_CAST(T)(t),+ ASIO_MOVE_CAST(Property)(p)); } template <typename T, typename P0, typename P1>- ASIO_NODISCARD constexpr enable_if_t<+ ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if< call_traits<impl, T, void(P0, P1)>::overload == two_props, typename call_traits<impl, T, void(P0, P1)>::result_type- >- operator()(T&& t, P0&& p0, P1&& p1) const- noexcept(call_traits<impl, T, void(P0, P1)>::is_noexcept)+ >::type+ operator()(+ ASIO_MOVE_ARG(T) t,+ ASIO_MOVE_ARG(P0) p0,+ ASIO_MOVE_ARG(P1) p1) const+ ASIO_NOEXCEPT_IF((+ call_traits<impl, T, void(P0, P1)>::is_noexcept)) { return (*this)(- (*this)(static_cast<T&&>(t), static_cast<P0&&>(p0)),- static_cast<P1&&>(p1));+ (*this)(+ ASIO_MOVE_CAST(T)(t),+ ASIO_MOVE_CAST(P0)(p0)),+ ASIO_MOVE_CAST(P1)(p1)); } template <typename T, typename P0, typename P1,- typename... PN>- ASIO_NODISCARD constexpr enable_if_t<- call_traits<impl, T, void(P0, P1, PN...)>::overload == n_props,- typename call_traits<impl, T, void(P0, P1, PN...)>::result_type- >- operator()(T&& t, P0&& p0, P1&& p1, PN&&... pn) const- noexcept(call_traits<impl, T, void(P0, P1, PN...)>::is_noexcept)+ typename ASIO_ELLIPSIS PN>+ ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if<+ call_traits<impl, T,+ void(P0, P1, PN ASIO_ELLIPSIS)>::overload == n_props,+ typename call_traits<impl, T,+ void(P0, P1, PN ASIO_ELLIPSIS)>::result_type+ >::type+ operator()(+ ASIO_MOVE_ARG(T) t,+ ASIO_MOVE_ARG(P0) p0,+ ASIO_MOVE_ARG(P1) p1,+ ASIO_MOVE_ARG(PN) ASIO_ELLIPSIS pn) const+ ASIO_NOEXCEPT_IF((+ call_traits<impl, T, void(P0, P1, PN ASIO_ELLIPSIS)>::is_noexcept)) { return (*this)(- (*this)(static_cast<T&&>(t), static_cast<P0&&>(p0)),- static_cast<P1&&>(p1), static_cast<PN&&>(pn)...);+ (*this)(+ ASIO_MOVE_CAST(T)(t),+ ASIO_MOVE_CAST(P0)(p0)),+ ASIO_MOVE_CAST(P1)(p1),+ ASIO_MOVE_CAST(PN)(pn) ASIO_ELLIPSIS); } }; @@ -374,13 +408,15 @@ namespace asio { namespace { -static constexpr const asio_require_fn::impl&+static ASIO_CONSTEXPR const asio_require_fn::impl& require = asio_require_fn::static_instance<>::instance; } // namespace typedef asio_require_fn::impl require_t; +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+ template <typename T, typename... Properties> struct can_require : integral_constant<bool,@@ -390,14 +426,51 @@ { }; +#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename T, typename P0 = void,+ typename P1 = void, typename P2 = void>+struct can_require :+ integral_constant<bool,+ asio_require_fn::call_traits<require_t, T, void(P0, P1, P2)>::overload+ != asio_require_fn::ill_formed>+{+};++template <typename T, typename P0, typename P1>+struct can_require<T, P0, P1> :+ integral_constant<bool,+ asio_require_fn::call_traits<require_t, T, void(P0, P1)>::overload+ != asio_require_fn::ill_formed>+{+};++template <typename T, typename P0>+struct can_require<T, P0> :+ integral_constant<bool,+ asio_require_fn::call_traits<require_t, T, void(P0)>::overload+ != asio_require_fn::ill_formed>+{+};++template <typename T>+struct can_require<T> :+ false_type+{+};++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+ #if defined(ASIO_HAS_VARIABLE_TEMPLATES) -template <typename T, typename... Properties>+template <typename T, typename ASIO_ELLIPSIS Properties> constexpr bool can_require_v- = can_require<T, Properties...>::value;+ = can_require<T, Properties ASIO_ELLIPSIS>::value; #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+ template <typename T, typename... Properties> struct is_nothrow_require : integral_constant<bool,@@ -406,14 +479,51 @@ { }; +#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename T, typename P0 = void,+ typename P1 = void, typename P2 = void>+struct is_nothrow_require :+ integral_constant<bool,+ asio_require_fn::call_traits<+ require_t, T, void(P0, P1, P2)>::is_noexcept>+{+};++template <typename T, typename P0, typename P1>+struct is_nothrow_require<T, P0, P1> :+ integral_constant<bool,+ asio_require_fn::call_traits<+ require_t, T, void(P0, P1)>::is_noexcept>+{+};++template <typename T, typename P0>+struct is_nothrow_require<T, P0> :+ integral_constant<bool,+ asio_require_fn::call_traits<+ require_t, T, void(P0)>::is_noexcept>+{+};++template <typename T>+struct is_nothrow_require<T> :+ false_type+{+};++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+ #if defined(ASIO_HAS_VARIABLE_TEMPLATES) -template <typename T, typename... Properties>+template <typename T, typename ASIO_ELLIPSIS Properties> constexpr bool is_nothrow_require_v- = is_nothrow_require<T, Properties...>::value;+ = is_nothrow_require<T, Properties ASIO_ELLIPSIS>::value; #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+ template <typename T, typename... Properties> struct require_result {@@ -421,8 +531,36 @@ require_t, T, void(Properties...)>::result_type type; }; -template <typename T, typename... Properties>-using require_result_t = typename require_result<T, Properties...>::type;+#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename T, typename P0 = void,+ typename P1 = void, typename P2 = void>+struct require_result+{+ typedef typename asio_require_fn::call_traits<+ require_t, T, void(P0, P1, P2)>::result_type type;+};++template <typename T, typename P0, typename P1>+struct require_result<T, P0, P1>+{+ typedef typename asio_require_fn::call_traits<+ require_t, T, void(P0, P1)>::result_type type;+};++template <typename T, typename P0>+struct require_result<T, P0>+{+ typedef typename asio_require_fn::call_traits<+ require_t, T, void(P0)>::result_type type;+};++template <typename T>+struct require_result<T>+{+};++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) } // namespace asio
link/modules/asio-standalone/asio/include/asio/require_concept.hpp view
@@ -2,7 +2,7 @@ // require_concept.hpp // ~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -107,10 +107,10 @@ namespace asio_require_concept_fn { -using asio::conditional_t;-using asio::decay_t;+using asio::conditional;+using asio::decay; using asio::declval;-using asio::enable_if_t;+using asio::enable_if; using asio::is_applicable_property; using asio::traits::require_concept_free; using asio::traits::require_concept_member;@@ -130,85 +130,85 @@ typename = void, typename = void, typename = void, typename = void> struct call_traits {- static constexpr overload_type overload = ill_formed;- static constexpr bool is_noexcept = false;+ ASIO_STATIC_CONSTEXPR(overload_type, overload = ill_formed);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); typedef void result_type; }; template <typename Impl, typename T, typename Property> struct call_traits<Impl, T, void(Property),- enable_if_t<+ typename enable_if< is_applicable_property<- decay_t<T>,- decay_t<Property>+ typename decay<T>::type,+ typename decay<Property>::type >::value- >,- enable_if_t<- decay_t<Property>::is_requirable_concept- >,- enable_if_t<+ >::type,+ typename enable_if<+ decay<Property>::type::is_requirable_concept+ >::type,+ typename enable_if< static_require_concept<T, Property>::is_valid- >>+ >::type> {- static constexpr overload_type overload = identity;- static constexpr bool is_noexcept = true;- typedef T&& result_type;+ ASIO_STATIC_CONSTEXPR(overload_type, overload = identity);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ typedef ASIO_MOVE_ARG(T) result_type; }; template <typename Impl, typename T, typename Property> struct call_traits<Impl, T, void(Property),- enable_if_t<+ typename enable_if< is_applicable_property<- decay_t<T>,- decay_t<Property>+ typename decay<T>::type,+ typename decay<Property>::type >::value- >,- enable_if_t<- decay_t<Property>::is_requirable_concept- >,- enable_if_t<+ >::type,+ typename enable_if<+ decay<Property>::type::is_requirable_concept+ >::type,+ typename enable_if< !static_require_concept<T, Property>::is_valid- >,- enable_if_t<+ >::type,+ typename enable_if< require_concept_member< typename Impl::template proxy<T>::type, Property >::is_valid- >> :+ >::type> : require_concept_member< typename Impl::template proxy<T>::type, Property > {- static constexpr overload_type overload = call_member;+ ASIO_STATIC_CONSTEXPR(overload_type, overload = call_member); }; template <typename Impl, typename T, typename Property> struct call_traits<Impl, T, void(Property),- enable_if_t<+ typename enable_if< is_applicable_property<- decay_t<T>,- decay_t<Property>+ typename decay<T>::type,+ typename decay<Property>::type >::value- >,- enable_if_t<- decay_t<Property>::is_requirable_concept- >,- enable_if_t<+ >::type,+ typename enable_if<+ decay<Property>::type::is_requirable_concept+ >::type,+ typename enable_if< !static_require_concept<T, Property>::is_valid- >,- enable_if_t<+ >::type,+ typename enable_if< !require_concept_member< typename Impl::template proxy<T>::type, Property >::is_valid- >,- enable_if_t<+ >::type,+ typename enable_if< require_concept_free<T, Property>::is_valid- >> :+ >::type> : require_concept_free<T, Property> {- static constexpr overload_type overload = call_free;+ ASIO_STATIC_CONSTEXPR(overload_type, overload = call_free); }; struct impl@@ -220,16 +220,16 @@ struct type { template <typename P>- auto require_concept(P&& p)+ auto require_concept(ASIO_MOVE_ARG(P) p) noexcept( noexcept(- declval<conditional_t<true, T, P>>().require_concept(- static_cast<P&&>(p))+ declval<typename conditional<true, T, P>::type>().require_concept(+ ASIO_MOVE_CAST(P)(p)) ) ) -> decltype(- declval<conditional_t<true, T, P>>().require_concept(- static_cast<P&&>(p))+ declval<typename conditional<true, T, P>::type>().require_concept(+ ASIO_MOVE_CAST(P)(p)) ); }; #else // defined(ASIO_HAS_DEDUCED_REQUIRE_CONCEPT_MEMBER_TRAIT)@@ -238,36 +238,48 @@ }; template <typename T, typename Property>- ASIO_NODISCARD constexpr enable_if_t<+ ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if< call_traits<impl, T, void(Property)>::overload == identity, typename call_traits<impl, T, void(Property)>::result_type- >- operator()(T&& t, Property&&) const- noexcept(call_traits<impl, T, void(Property)>::is_noexcept)+ >::type+ operator()(+ ASIO_MOVE_ARG(T) t,+ ASIO_MOVE_ARG(Property)) const+ ASIO_NOEXCEPT_IF((+ call_traits<impl, T, void(Property)>::is_noexcept)) {- return static_cast<T&&>(t);+ return ASIO_MOVE_CAST(T)(t); } template <typename T, typename Property>- ASIO_NODISCARD constexpr enable_if_t<+ ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if< call_traits<impl, T, void(Property)>::overload == call_member, typename call_traits<impl, T, void(Property)>::result_type- >- operator()(T&& t, Property&& p) const- noexcept(call_traits<impl, T, void(Property)>::is_noexcept)+ >::type+ operator()(+ ASIO_MOVE_ARG(T) t,+ ASIO_MOVE_ARG(Property) p) const+ ASIO_NOEXCEPT_IF((+ call_traits<impl, T, void(Property)>::is_noexcept)) {- return static_cast<T&&>(t).require_concept(static_cast<Property&&>(p));+ return ASIO_MOVE_CAST(T)(t).require_concept(+ ASIO_MOVE_CAST(Property)(p)); } template <typename T, typename Property>- ASIO_NODISCARD constexpr enable_if_t<+ ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if< call_traits<impl, T, void(Property)>::overload == call_free, typename call_traits<impl, T, void(Property)>::result_type- >- operator()(T&& t, Property&& p) const- noexcept(call_traits<impl, T, void(Property)>::is_noexcept)+ >::type+ operator()(+ ASIO_MOVE_ARG(T) t,+ ASIO_MOVE_ARG(Property) p) const+ ASIO_NOEXCEPT_IF((+ call_traits<impl, T, void(Property)>::is_noexcept)) {- return require_concept(static_cast<T&&>(t), static_cast<Property&&>(p));+ return require_concept(+ ASIO_MOVE_CAST(T)(t),+ ASIO_MOVE_CAST(Property)(p)); } }; @@ -284,7 +296,7 @@ namespace asio { namespace { -static constexpr const asio_require_concept_fn::impl&+static ASIO_CONSTEXPR const asio_require_concept_fn::impl& require_concept = asio_require_concept_fn::static_instance<>::instance; } // namespace@@ -303,7 +315,8 @@ #if defined(ASIO_HAS_VARIABLE_TEMPLATES) template <typename T, typename Property>-constexpr bool can_require_concept_v = can_require_concept<T, Property>::value;+constexpr bool can_require_concept_v+ = can_require_concept<T, Property>::value; #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) @@ -329,10 +342,6 @@ typedef typename asio_require_concept_fn::call_traits< require_concept_t, T, void(Property)>::result_type type; };--template <typename T, typename Property>-using require_concept_result_t =- typename require_concept_result<T, Property>::type; } // namespace asio
link/modules/asio-standalone/asio/include/asio/serial_port.hpp view
@@ -2,7 +2,7 @@ // serial_port.hpp // ~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying
link/modules/asio-standalone/asio/include/asio/serial_port_base.hpp view
@@ -2,7 +2,7 @@ // serial_port_base.hpp // ~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying
link/modules/asio-standalone/asio/include/asio/signal_set.hpp view
@@ -2,7 +2,7 @@ // signal_set.hpp // ~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/signal_set_base.hpp view
@@ -2,7 +2,7 @@ // signal_set_base.hpp // ~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -56,9 +56,7 @@ /// Portability typedef. typedef flags flags_t;--#else // defined(GENERATING_DOCUMENTATION)-+#elif defined(ASIO_HAS_ENUM_CLASS) enum class flags : int { none = 0,@@ -69,8 +67,21 @@ }; typedef flags flags_t;+#else // defined(ASIO_HAS_ENUM_CLASS)+ struct flags+ {+ enum flags_t+ {+ none = 0,+ restart = ASIO_OS_DEF(SA_RESTART),+ no_child_stop = ASIO_OS_DEF(SA_NOCLDSTOP),+ no_child_wait = ASIO_OS_DEF(SA_NOCLDWAIT),+ dont_care = -1+ };+ }; -#endif // defined(GENERATING_DOCUMENTATION)+ typedef flags::flags_t flags_t;+#endif // defined(ASIO_HAS_ENUM_CLASS) protected: /// Protected destructor to prevent deletion through this type.@@ -83,7 +94,7 @@ /** * @relates signal_set_base::flags */-inline constexpr bool operator!(signal_set_base::flags_t x)+inline ASIO_CONSTEXPR bool operator!(signal_set_base::flags_t x) { return static_cast<int>(x) == 0; }@@ -92,7 +103,7 @@ /** * @relates signal_set_base::flags */-inline constexpr signal_set_base::flags_t operator&(+inline ASIO_CONSTEXPR signal_set_base::flags_t operator&( signal_set_base::flags_t x, signal_set_base::flags_t y) { return static_cast<signal_set_base::flags_t>(@@ -103,7 +114,7 @@ /** * @relates signal_set_base::flags */-inline constexpr signal_set_base::flags_t operator|(+inline ASIO_CONSTEXPR signal_set_base::flags_t operator|( signal_set_base::flags_t x, signal_set_base::flags_t y) { return static_cast<signal_set_base::flags_t>(@@ -114,7 +125,7 @@ /** * @relates signal_set_base::flags */-inline constexpr signal_set_base::flags_t operator^(+inline ASIO_CONSTEXPR signal_set_base::flags_t operator^( signal_set_base::flags_t x, signal_set_base::flags_t y) { return static_cast<signal_set_base::flags_t>(@@ -125,7 +136,7 @@ /** * @relates signal_set_base::flags */-inline constexpr signal_set_base::flags_t operator~(+inline ASIO_CONSTEXPR signal_set_base::flags_t operator~( signal_set_base::flags_t x) { return static_cast<signal_set_base::flags_t>(~static_cast<int>(x));
link/modules/asio-standalone/asio/include/asio/socket_base.hpp view
@@ -2,7 +2,7 @@ // socket_base.hpp // ~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -533,6 +533,17 @@ ASIO_STATIC_CONSTANT(int, max_listen_connections = ASIO_OS_DEF(SOMAXCONN)); #endif++#if !defined(ASIO_NO_DEPRECATED)+ /// (Deprecated: Use max_listen_connections.) The maximum length of the queue+ /// of pending incoming connections.+#if defined(GENERATING_DOCUMENTATION)+ static const int max_connections = implementation_defined;+#else+ ASIO_STATIC_CONSTANT(int, max_connections+ = ASIO_OS_DEF(SOMAXCONN));+#endif+#endif // !defined(ASIO_NO_DEPRECATED) protected: /// Protected destructor to prevent deletion through this type.
link/modules/asio-standalone/asio/include/asio/spawn.hpp view
@@ -2,7 +2,7 @@ // spawn.hpp // ~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -26,6 +26,10 @@ #include "asio/is_executor.hpp" #include "asio/strand.hpp" +#if defined(ASIO_HAS_BOOST_COROUTINE)+# include <boost/coroutine/all.hpp>+#endif // defined(ASIO_HAS_BOOST_COROUTINE)+ #include "asio/detail/push_options.hpp" namespace asio {@@ -72,12 +76,12 @@ suspend_with(&spawned_thread_base::call<F>, &f); } - cancellation_slot get_cancellation_slot() const noexcept+ cancellation_slot get_cancellation_slot() const ASIO_NOEXCEPT { return cancellation_state_.slot(); } - cancellation_state get_cancellation_state() const noexcept+ cancellation_state get_cancellation_state() const ASIO_NOEXCEPT { return cancellation_state_; }@@ -101,22 +105,22 @@ parent_cancellation_slot_, in_filter, out_filter); } - cancellation_type_t cancelled() const noexcept+ cancellation_type_t cancelled() const ASIO_NOEXCEPT { return cancellation_state_.cancelled(); } - bool has_context_switched() const noexcept+ bool has_context_switched() const ASIO_NOEXCEPT { return has_context_switched_; } - bool throw_if_cancelled() const noexcept+ bool throw_if_cancelled() const ASIO_NOEXCEPT { return throw_if_cancelled_; } - void throw_if_cancelled(bool value) noexcept+ void throw_if_cancelled(bool value) ASIO_NOEXCEPT { throw_if_cancelled_ = value; }@@ -131,8 +135,8 @@ private: // Disallow copying and assignment.- spawned_thread_base(const spawned_thread_base&) = delete;- spawned_thread_base& operator=(const spawned_thread_base&) = delete;+ spawned_thread_base(const spawned_thread_base&) ASIO_DELETED;+ spawned_thread_base& operator=(const spawned_thread_base&) ASIO_DELETED; template <typename F> static void call(void* f)@@ -141,6 +145,7 @@ } }; + template <typename T> struct spawn_signature {@@ -193,9 +198,9 @@ */ template <typename OtherExecutor> basic_yield_context(const basic_yield_context<OtherExecutor>& other,- constraint_t<+ typename constraint< is_convertible<OtherExecutor, Executor>::value- > = 0)+ >::type = 0) : spawned_thread_(other.spawned_thread_), executor_(other.executor_), ec_(other.ec_)@@ -203,19 +208,19 @@ } /// Get the executor associated with the yield context.- executor_type get_executor() const noexcept+ executor_type get_executor() const ASIO_NOEXCEPT { return executor_; } /// Get the cancellation slot associated with the coroutine.- cancellation_slot_type get_cancellation_slot() const noexcept+ cancellation_slot_type get_cancellation_slot() const ASIO_NOEXCEPT { return spawned_thread_->get_cancellation_slot(); } /// Get the cancellation state associated with the coroutine.- cancellation_state get_cancellation_state() const noexcept+ cancellation_state get_cancellation_state() const ASIO_NOEXCEPT { return spawned_thread_->get_cancellation_state(); }@@ -241,10 +246,10 @@ * cancellation state object. */ template <typename Filter>- void reset_cancellation_state(Filter&& filter) const+ void reset_cancellation_state(ASIO_MOVE_ARG(Filter) filter) const { spawned_thread_->reset_cancellation_state(- static_cast<Filter&&>(filter));+ ASIO_MOVE_CAST(Filter)(filter)); } /// Reset the cancellation state associated with the coroutine.@@ -257,30 +262,30 @@ * cancellation state object. */ template <typename InFilter, typename OutFilter>- void reset_cancellation_state(InFilter&& in_filter,- OutFilter&& out_filter) const+ void reset_cancellation_state(ASIO_MOVE_ARG(InFilter) in_filter,+ ASIO_MOVE_ARG(OutFilter) out_filter) const { spawned_thread_->reset_cancellation_state(- static_cast<InFilter&&>(in_filter),- static_cast<OutFilter&&>(out_filter));+ ASIO_MOVE_CAST(InFilter)(in_filter),+ ASIO_MOVE_CAST(OutFilter)(out_filter)); } /// Determine whether the current coroutine has been cancelled.- cancellation_type_t cancelled() const noexcept+ cancellation_type_t cancelled() const ASIO_NOEXCEPT { return spawned_thread_->cancelled(); } /// Determine whether the coroutine throws if trying to suspend when it has /// been cancelled.- bool throw_if_cancelled() const noexcept+ bool throw_if_cancelled() const ASIO_NOEXCEPT { return spawned_thread_->throw_if_cancelled(); } /// Set whether the coroutine throws if trying to suspend when it has been /// cancelled.- void throw_if_cancelled(bool value) const noexcept+ void throw_if_cancelled(bool value) const ASIO_NOEXCEPT { spawned_thread_->throw_if_cancelled(value); }@@ -397,19 +402,31 @@ */ template <typename Executor, typename F, ASIO_COMPLETION_TOKEN_FOR(typename detail::spawn_signature<- result_of_t<F(basic_yield_context<Executor>)>>::type)- CompletionToken = default_completion_token_t<Executor>>-auto spawn(const Executor& ex, F&& function,- CompletionToken&& token = default_completion_token_t<Executor>(),- constraint_t<+ typename result_of<F(basic_yield_context<Executor>)>::type>::type)+ CompletionToken ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(Executor)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(CompletionToken,+ typename detail::spawn_signature<+ typename result_of<F(basic_yield_context<Executor>)>::type>::type)+spawn(const Executor& ex, ASIO_MOVE_ARG(F) function,+ ASIO_MOVE_ARG(CompletionToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(Executor),+#if defined(ASIO_HAS_BOOST_COROUTINE)+ typename constraint<+ !is_same<+ typename decay<CompletionToken>::type,+ boost::coroutines::attributes+ >::value+ >::type = 0,+#endif // defined(ASIO_HAS_BOOST_COROUTINE)+ typename constraint< is_executor<Executor>::value || execution::is_executor<Executor>::value- > = 0)- -> decltype(+ >::type = 0)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<CompletionToken, typename detail::spawn_signature<- result_of_t<F(basic_yield_context<Executor>)>>::type>(- declval<detail::initiate_spawn<Executor>>(),- token, static_cast<F&&>(function)));+ typename result_of<F(basic_yield_context<Executor>)>::type>::type>(+ declval<detail::initiate_spawn<Executor> >(),+ token, ASIO_MOVE_CAST(F)(function)))); /// Start a new stackful coroutine that executes on a given execution context. /**@@ -442,24 +459,37 @@ */ template <typename ExecutionContext, typename F, ASIO_COMPLETION_TOKEN_FOR(typename detail::spawn_signature<- result_of_t<F(basic_yield_context<- typename ExecutionContext::executor_type>)>>::type)- CompletionToken = default_completion_token_t<- typename ExecutionContext::executor_type>>-auto spawn(ExecutionContext& ctx, F&& function,- CompletionToken&& token- = default_completion_token_t<typename ExecutionContext::executor_type>(),- constraint_t<+ typename result_of<F(basic_yield_context<+ typename ExecutionContext::executor_type>)>::type>::type)+ CompletionToken ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+ typename ExecutionContext::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(CompletionToken,+ typename detail::spawn_signature<+ typename result_of<F(basic_yield_context<+ typename ExecutionContext::executor_type>)>::type>::type)+spawn(ExecutionContext& ctx, ASIO_MOVE_ARG(F) function,+ ASIO_MOVE_ARG(CompletionToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(+ typename ExecutionContext::executor_type),+#if defined(ASIO_HAS_BOOST_COROUTINE)+ typename constraint<+ !is_same<+ typename decay<CompletionToken>::type,+ boost::coroutines::attributes+ >::value+ >::type = 0,+#endif // defined(ASIO_HAS_BOOST_COROUTINE)+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- > = 0)- -> decltype(+ >::type = 0)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<CompletionToken, typename detail::spawn_signature<- result_of_t<F(basic_yield_context<- typename ExecutionContext::executor_type>)>>::type>(+ typename result_of<F(basic_yield_context<+ typename ExecutionContext::executor_type>)>::type>::type>( declval<detail::initiate_spawn<- typename ExecutionContext::executor_type>>(),- token, static_cast<F&&>(function)));+ typename ExecutionContext::executor_type> >(),+ token, ASIO_MOVE_CAST(F)(function)))); /// Start a new stackful coroutine, inheriting the executor of another. /**@@ -494,19 +524,32 @@ */ template <typename Executor, typename F, ASIO_COMPLETION_TOKEN_FOR(typename detail::spawn_signature<- result_of_t<F(basic_yield_context<Executor>)>>::type)- CompletionToken = default_completion_token_t<Executor>>-auto spawn(const basic_yield_context<Executor>& ctx, F&& function,- CompletionToken&& token = default_completion_token_t<Executor>(),- constraint_t<+ typename result_of<F(basic_yield_context<Executor>)>::type>::type)+ CompletionToken ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(Executor)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(CompletionToken,+ typename detail::spawn_signature<+ typename result_of<F(basic_yield_context<Executor>)>::type>::type)+spawn(const basic_yield_context<Executor>& ctx,+ ASIO_MOVE_ARG(F) function,+ ASIO_MOVE_ARG(CompletionToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(Executor),+#if defined(ASIO_HAS_BOOST_COROUTINE)+ typename constraint<+ !is_same<+ typename decay<CompletionToken>::type,+ boost::coroutines::attributes+ >::value+ >::type = 0,+#endif // defined(ASIO_HAS_BOOST_COROUTINE)+ typename constraint< is_executor<Executor>::value || execution::is_executor<Executor>::value- > = 0)- -> decltype(+ >::type = 0)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<CompletionToken, typename detail::spawn_signature<- result_of_t<F(basic_yield_context<Executor>)>>::type>(- declval<detail::initiate_spawn<Executor>>(),- token, static_cast<F&&>(function)));+ typename result_of<F(basic_yield_context<Executor>)>::type>::type>(+ declval<detail::initiate_spawn<Executor> >(),+ token, ASIO_MOVE_CAST(F)(function)))); #if defined(ASIO_HAS_BOOST_CONTEXT_FIBER) \ || defined(GENERATING_DOCUMENTATION)@@ -546,22 +589,27 @@ */ template <typename Executor, typename StackAllocator, typename F, ASIO_COMPLETION_TOKEN_FOR(typename detail::spawn_signature<- result_of_t<F(basic_yield_context<Executor>)>>::type)- CompletionToken = default_completion_token_t<Executor>>-auto spawn(const Executor& ex, allocator_arg_t,- StackAllocator&& stack_allocator, F&& function,- CompletionToken&& token = default_completion_token_t<Executor>(),- constraint_t<+ typename result_of<F(basic_yield_context<Executor>)>::type>::type)+ CompletionToken ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(Executor)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(CompletionToken,+ typename detail::spawn_signature<+ typename result_of<F(basic_yield_context<Executor>)>::type>::type)+spawn(const Executor& ex, allocator_arg_t,+ ASIO_MOVE_ARG(StackAllocator) stack_allocator,+ ASIO_MOVE_ARG(F) function,+ ASIO_MOVE_ARG(CompletionToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(Executor),+ typename constraint< is_executor<Executor>::value || execution::is_executor<Executor>::value- > = 0)- -> decltype(+ >::type = 0)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<CompletionToken, typename detail::spawn_signature<- result_of_t<F(basic_yield_context<Executor>)>>::type>(- declval<detail::initiate_spawn<Executor>>(),+ typename result_of<F(basic_yield_context<Executor>)>::type>::type>(+ declval<detail::initiate_spawn<Executor> >(), token, allocator_arg_t(),- static_cast<StackAllocator&&>(stack_allocator),- static_cast<F&&>(function)));+ ASIO_MOVE_CAST(StackAllocator)(stack_allocator),+ ASIO_MOVE_CAST(F)(function)))); /// Start a new stackful coroutine that executes on a given execution context. /**@@ -598,27 +646,33 @@ */ template <typename ExecutionContext, typename StackAllocator, typename F, ASIO_COMPLETION_TOKEN_FOR(typename detail::spawn_signature<- result_of_t<F(basic_yield_context<- typename ExecutionContext::executor_type>)>>::type)- CompletionToken = default_completion_token_t<- typename ExecutionContext::executor_type>>-auto spawn(ExecutionContext& ctx, allocator_arg_t,- StackAllocator&& stack_allocator, F&& function,- CompletionToken&& token- = default_completion_token_t<typename ExecutionContext::executor_type>(),- constraint_t<+ typename result_of<F(basic_yield_context<+ typename ExecutionContext::executor_type>)>::type>::type)+ CompletionToken ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+ typename ExecutionContext::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(CompletionToken,+ typename detail::spawn_signature<+ typename result_of<F(basic_yield_context<+ typename ExecutionContext::executor_type>)>::type>::type)+spawn(ExecutionContext& ctx, allocator_arg_t,+ ASIO_MOVE_ARG(StackAllocator) stack_allocator,+ ASIO_MOVE_ARG(F) function,+ ASIO_MOVE_ARG(CompletionToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(+ typename ExecutionContext::executor_type),+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- > = 0)- -> decltype(+ >::type = 0)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<CompletionToken, typename detail::spawn_signature<- result_of_t<F(basic_yield_context<- typename ExecutionContext::executor_type>)>>::type>(+ typename result_of<F(basic_yield_context<+ typename ExecutionContext::executor_type>)>::type>::type>( declval<detail::initiate_spawn<- typename ExecutionContext::executor_type>>(),+ typename ExecutionContext::executor_type> >(), token, allocator_arg_t(),- static_cast<StackAllocator&&>(stack_allocator),- static_cast<F&&>(function)));+ ASIO_MOVE_CAST(StackAllocator)(stack_allocator),+ ASIO_MOVE_CAST(F)(function)))); /// Start a new stackful coroutine, inheriting the executor of another. /**@@ -659,24 +713,186 @@ */ template <typename Executor, typename StackAllocator, typename F, ASIO_COMPLETION_TOKEN_FOR(typename detail::spawn_signature<- result_of_t<F(basic_yield_context<Executor>)>>::type)- CompletionToken = default_completion_token_t<Executor>>-auto spawn(const basic_yield_context<Executor>& ctx, allocator_arg_t,- StackAllocator&& stack_allocator, F&& function,- CompletionToken&& token = default_completion_token_t<Executor>(),- constraint_t<- is_executor<Executor>::value || execution::is_executor<Executor>::value- > = 0)- -> decltype(- async_initiate<CompletionToken,- typename detail::spawn_signature<- result_of_t<F(basic_yield_context<Executor>)>>::type>(- declval<detail::initiate_spawn<Executor>>(),- token, allocator_arg_t(),- static_cast<StackAllocator&&>(stack_allocator),- static_cast<F&&>(function)));+ typename result_of<F(basic_yield_context<Executor>)>::type>::type)+ CompletionToken ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(Executor)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(CompletionToken,+ typename detail::spawn_signature<+ typename result_of<F(basic_yield_context<Executor>)>::type>::type)+spawn(const basic_yield_context<Executor>& ctx, allocator_arg_t,+ ASIO_MOVE_ARG(StackAllocator) stack_allocator,+ ASIO_MOVE_ARG(F) function,+ ASIO_MOVE_ARG(CompletionToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(Executor),+ typename constraint<+ is_executor<Executor>::value || execution::is_executor<Executor>::value+ >::type = 0)+ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_initiate<CompletionToken,+ typename detail::spawn_signature<+ typename result_of<F(basic_yield_context<Executor>)>::type>::type>(+ declval<detail::initiate_spawn<Executor> >(),+ token, allocator_arg_t(),+ ASIO_MOVE_CAST(StackAllocator)(stack_allocator),+ ASIO_MOVE_CAST(F)(function)))); #endif // defined(ASIO_HAS_BOOST_CONTEXT_FIBER)+ // || defined(GENERATING_DOCUMENTATION)++#if defined(ASIO_HAS_BOOST_COROUTINE) \+ || defined(GENERATING_DOCUMENTATION)++/// (Deprecated: Use overloads with a completion token.) Start a new stackful+/// coroutine, calling the specified handler when it completes.+/**+ * This function is used to launch a new coroutine.+ *+ * @param function The coroutine function. The function must have the signature:+ * @code void function(basic_yield_context<Executor> yield); @endcode+ * where Executor is the associated executor type of @c Function.+ *+ * @param attributes Boost.Coroutine attributes used to customise the coroutine.+ */+template <typename Function>+void spawn(ASIO_MOVE_ARG(Function) function,+ const boost::coroutines::attributes& attributes+ = boost::coroutines::attributes());++/// (Deprecated: Use overloads with a completion token.) Start a new stackful+/// coroutine, calling the specified handler when it completes.+/**+ * This function is used to launch a new coroutine.+ *+ * @param handler A handler to be called when the coroutine exits. More+ * importantly, the handler provides an execution context (via the the handler+ * invocation hook) for the coroutine. The handler must have the signature:+ * @code void handler(); @endcode+ *+ * @param function The coroutine function. The function must have the signature:+ * @code void function(basic_yield_context<Executor> yield); @endcode+ * where Executor is the associated executor type of @c Handler.+ *+ * @param attributes Boost.Coroutine attributes used to customise the coroutine.+ */+template <typename Handler, typename Function>+void spawn(ASIO_MOVE_ARG(Handler) handler,+ ASIO_MOVE_ARG(Function) function,+ const boost::coroutines::attributes& attributes+ = boost::coroutines::attributes(),+ typename constraint<+ !is_executor<typename decay<Handler>::type>::value &&+ !execution::is_executor<typename decay<Handler>::type>::value &&+ !is_convertible<Handler&, execution_context&>::value>::type = 0);++/// (Deprecated: Use overloads with a completion token.) Start a new stackful+/// coroutine, inheriting the execution context of another.+/**+ * This function is used to launch a new coroutine.+ *+ * @param ctx Identifies the current coroutine as a parent of the new+ * coroutine. This specifies that the new coroutine should inherit the+ * execution context of the parent. For example, if the parent coroutine is+ * executing in a particular strand, then the new coroutine will execute in the+ * same strand.+ *+ * @param function The coroutine function. The function must have the signature:+ * @code void function(basic_yield_context<Executor> yield); @endcode+ *+ * @param attributes Boost.Coroutine attributes used to customise the coroutine.+ */+template <typename Executor, typename Function>+void spawn(basic_yield_context<Executor> ctx,+ ASIO_MOVE_ARG(Function) function,+ const boost::coroutines::attributes& attributes+ = boost::coroutines::attributes());++/// (Deprecated: Use overloads with a completion token.) Start a new stackful+/// coroutine that executes on a given executor.+/**+ * This function is used to launch a new coroutine.+ *+ * @param ex Identifies the executor that will run the coroutine. The new+ * coroutine is automatically given its own explicit strand within this+ * executor.+ *+ * @param function The coroutine function. The function must have the signature:+ * @code void function(yield_context yield); @endcode+ *+ * @param attributes Boost.Coroutine attributes used to customise the coroutine.+ */+template <typename Function, typename Executor>+void spawn(const Executor& ex,+ ASIO_MOVE_ARG(Function) function,+ const boost::coroutines::attributes& attributes+ = boost::coroutines::attributes(),+ typename constraint<+ is_executor<Executor>::value || execution::is_executor<Executor>::value+ >::type = 0);++/// (Deprecated: Use overloads with a completion token.) Start a new stackful+/// coroutine that executes on a given strand.+/**+ * This function is used to launch a new coroutine.+ *+ * @param ex Identifies the strand that will run the coroutine.+ *+ * @param function The coroutine function. The function must have the signature:+ * @code void function(yield_context yield); @endcode+ *+ * @param attributes Boost.Coroutine attributes used to customise the coroutine.+ */+template <typename Function, typename Executor>+void spawn(const strand<Executor>& ex,+ ASIO_MOVE_ARG(Function) function,+ const boost::coroutines::attributes& attributes+ = boost::coroutines::attributes());++#if !defined(ASIO_NO_TS_EXECUTORS)++/// (Deprecated: Use overloads with a completion token.) Start a new stackful+/// coroutine that executes in the context of a strand.+/**+ * This function is used to launch a new coroutine.+ *+ * @param s Identifies a strand. By starting multiple coroutines on the same+ * strand, the implementation ensures that none of those coroutines can execute+ * simultaneously.+ *+ * @param function The coroutine function. The function must have the signature:+ * @code void function(yield_context yield); @endcode+ *+ * @param attributes Boost.Coroutine attributes used to customise the coroutine.+ */+template <typename Function>+void spawn(const asio::io_context::strand& s,+ ASIO_MOVE_ARG(Function) function,+ const boost::coroutines::attributes& attributes+ = boost::coroutines::attributes());++#endif // !defined(ASIO_NO_TS_EXECUTORS)++/// (Deprecated: Use overloads with a completion token.) Start a new stackful+/// coroutine that executes on a given execution context.+/**+ * This function is used to launch a new coroutine.+ *+ * @param ctx Identifies the execution context that will run the coroutine. The+ * new coroutine is implicitly given its own strand within this execution+ * context.+ *+ * @param function The coroutine function. The function must have the signature:+ * @code void function(yield_context yield); @endcode+ *+ * @param attributes Boost.Coroutine attributes used to customise the coroutine.+ */+template <typename Function, typename ExecutionContext>+void spawn(ExecutionContext& ctx,+ ASIO_MOVE_ARG(Function) function,+ const boost::coroutines::attributes& attributes+ = boost::coroutines::attributes(),+ typename constraint<is_convertible<+ ExecutionContext&, execution_context&>::value>::type = 0);++#endif // defined(ASIO_HAS_BOOST_COROUTINE) // || defined(GENERATING_DOCUMENTATION) /*@}*/
link/modules/asio-standalone/asio/include/asio/ssl.hpp view
@@ -2,7 +2,7 @@ // ssl.hpp // ~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -18,6 +18,7 @@ #include "asio/ssl/context.hpp" #include "asio/ssl/context_base.hpp" #include "asio/ssl/error.hpp"+#include "asio/ssl/rfc2818_verification.hpp" #include "asio/ssl/host_name_verification.hpp" #include "asio/ssl/stream.hpp" #include "asio/ssl/stream_base.hpp"
link/modules/asio-standalone/asio/include/asio/ssl/context.hpp view
@@ -2,7 +2,7 @@ // ssl/context.hpp // ~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -46,6 +46,7 @@ /// Construct to take ownership of a native handle. ASIO_DECL explicit context(native_handle_type native_handle); +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move-construct a context from another. /** * This constructor moves an SSL context from one object to another.@@ -71,6 +72,7 @@ * @li As a target for move-assignment. */ ASIO_DECL context& operator=(context&& other);+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Destructor. ASIO_DECL ~context();
link/modules/asio-standalone/asio/include/asio/ssl/context_base.hpp view
@@ -2,7 +2,7 @@ // ssl/context_base.hpp // ~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/ssl/detail/buffered_handshake_op.hpp view
@@ -2,7 +2,7 @@ // ssl/detail/buffered_handshake_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -29,7 +29,7 @@ class buffered_handshake_op { public:- static constexpr const char* tracking_name()+ static ASIO_CONSTEXPR const char* tracking_name() { return "ssl::stream<>::async_buffered_handshake"; }@@ -56,7 +56,7 @@ const asio::error_code& ec, const std::size_t& bytes_transferred) const {- static_cast<Handler&&>(handler)(ec, bytes_transferred);+ ASIO_MOVE_OR_LVALUE(Handler)(handler)(ec, bytes_transferred); } private:
link/modules/asio-standalone/asio/include/asio/ssl/detail/engine.hpp view
@@ -2,7 +2,7 @@ // ssl/detail/engine.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -61,14 +61,18 @@ // Construct a new engine for an existing native SSL implementation. ASIO_DECL explicit engine(SSL* ssl_impl); +#if defined(ASIO_HAS_MOVE) // Move construct from another engine.- ASIO_DECL engine(engine&& other) noexcept;+ ASIO_DECL engine(engine&& other) ASIO_NOEXCEPT;+#endif // defined(ASIO_HAS_MOVE) // Destructor. ASIO_DECL ~engine(); +#if defined(ASIO_HAS_MOVE) // Move assign from another engine.- ASIO_DECL engine& operator=(engine&& other) noexcept;+ ASIO_DECL engine& operator=(engine&& other) ASIO_NOEXCEPT;+#endif // defined(ASIO_HAS_MOVE) // Get the underlying implementation in the native type. ASIO_DECL SSL* native_handle();
link/modules/asio-standalone/asio/include/asio/ssl/detail/handshake_op.hpp view
@@ -2,7 +2,7 @@ // ssl/detail/handshake_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -28,7 +28,7 @@ class handshake_op { public:- static constexpr const char* tracking_name()+ static ASIO_CONSTEXPR const char* tracking_name() { return "ssl::stream<>::async_handshake"; }@@ -51,7 +51,7 @@ const asio::error_code& ec, const std::size_t&) const {- static_cast<Handler&&>(handler)(ec);+ ASIO_MOVE_OR_LVALUE(Handler)(handler)(ec); } private:
link/modules/asio-standalone/asio/include/asio/ssl/detail/impl/engine.ipp view
@@ -2,7 +2,7 @@ // ssl/detail/impl/engine.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -73,13 +73,15 @@ ::SSL_set_bio(ssl_, int_bio, int_bio); } -engine::engine(engine&& other) noexcept+#if defined(ASIO_HAS_MOVE)+engine::engine(engine&& other) ASIO_NOEXCEPT : ssl_(other.ssl_), ext_bio_(other.ext_bio_) { other.ssl_ = 0; other.ext_bio_ = 0; }+#endif // defined(ASIO_HAS_MOVE) engine::~engine() {@@ -96,16 +98,11 @@ ::SSL_free(ssl_); } -engine& engine::operator=(engine&& other) noexcept+#if defined(ASIO_HAS_MOVE)+engine& engine::operator=(engine&& other) ASIO_NOEXCEPT { if (this != &other) {- if (ext_bio_)- ::BIO_free(ext_bio_);-- if (ssl_)- ::SSL_free(ssl_);- ssl_ = other.ssl_; ext_bio_ = other.ext_bio_; other.ssl_ = 0;@@ -113,6 +110,7 @@ } return *this; }+#endif // defined(ASIO_HAS_MOVE) SSL* engine::native_handle() {
link/modules/asio-standalone/asio/include/asio/ssl/detail/impl/openssl_init.ipp view
@@ -3,7 +3,7 @@ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com-// Copyright (c) 2005-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2005-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -37,7 +37,7 @@ { #if (OPENSSL_VERSION_NUMBER < 0x10100000L) ::SSL_library_init();- ::SSL_load_error_strings();+ ::SSL_load_error_strings(); ::OpenSSL_add_all_algorithms(); mutexes_.resize(::CRYPTO_num_locks());@@ -123,7 +123,7 @@ #endif // (OPENSSL_VERSION_NUMBER < 0x10000000L) #if (OPENSSL_VERSION_NUMBER < 0x10100000L)- static void openssl_locking_func(int mode, int n,+ static void openssl_locking_func(int mode, int n, const char* /*file*/, int /*line*/) { if (mode & CRYPTO_LOCK)@@ -134,7 +134,7 @@ // Mutexes to be used in locking callbacks. std::vector<asio::detail::shared_ptr<- asio::detail::mutex>> mutexes_;+ asio::detail::mutex> > mutexes_; #endif // (OPENSSL_VERSION_NUMBER < 0x10100000L) #if !defined(SSL_OP_NO_COMPRESSION) \
link/modules/asio-standalone/asio/include/asio/ssl/detail/io.hpp view
@@ -2,7 +2,7 @@ // ssl/detail/io.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -107,10 +107,11 @@ start_(0), want_(engine::want_nothing), bytes_transferred_(0),- handler_(static_cast<Handler&&>(handler))+ handler_(ASIO_MOVE_CAST(Handler)(handler)) { } +#if defined(ASIO_HAS_MOVE) io_op(const io_op& other) : asio::detail::base_from_cancellation_state<Handler>(other), next_layer_(other.next_layer_),@@ -126,18 +127,20 @@ io_op(io_op&& other) : asio::detail::base_from_cancellation_state<Handler>(- static_cast<- asio::detail::base_from_cancellation_state<Handler>&&>(other)),+ ASIO_MOVE_CAST(+ asio::detail::base_from_cancellation_state<Handler>)(+ other)), next_layer_(other.next_layer_), core_(other.core_),- op_(static_cast<Operation&&>(other.op_)),+ op_(ASIO_MOVE_CAST(Operation)(other.op_)), start_(other.start_), want_(other.want_), ec_(other.ec_), bytes_transferred_(other.bytes_transferred_),- handler_(static_cast<Handler&&>(other.handler_))+ handler_(ASIO_MOVE_CAST(Handler)(other.handler_)) { }+#endif // defined(ASIO_HAS_MOVE) void operator()(asio::error_code ec, std::size_t bytes_transferred = ~std::size_t(0), int start = 0)@@ -174,7 +177,7 @@ // Start reading some data from the underlying transport. next_layer_.async_read_some( asio::buffer(core_.input_buffer_),- static_cast<io_op&&>(*this));+ ASIO_MOVE_CAST(io_op)(*this)); } else {@@ -182,7 +185,7 @@ __FILE__, __LINE__, Operation::tracking_name())); // Wait until the current read operation completes.- core_.pending_read_.async_wait(static_cast<io_op&&>(*this));+ core_.pending_read_.async_wait(ASIO_MOVE_CAST(io_op)(*this)); } // Yield control until asynchronous operation completes. Control@@ -207,7 +210,7 @@ // Start writing all the data to the underlying transport. asio::async_write(next_layer_, core_.engine_.get_output(core_.output_buffer_),- static_cast<io_op&&>(*this));+ ASIO_MOVE_CAST(io_op)(*this)); } else {@@ -215,7 +218,7 @@ __FILE__, __LINE__, Operation::tracking_name())); // Wait until the current write operation completes.- core_.pending_write_.async_wait(static_cast<io_op&&>(*this));+ core_.pending_write_.async_wait(ASIO_MOVE_CAST(io_op)(*this)); } // Yield control until asynchronous operation completes. Control@@ -236,7 +239,7 @@ next_layer_.async_read_some( asio::buffer(core_.input_buffer_, 0),- static_cast<io_op&&>(*this));+ ASIO_MOVE_CAST(io_op)(*this)); // Yield control until asynchronous operation completes. Control // resumes at the "default:" label below.@@ -328,6 +331,32 @@ }; template <typename Stream, typename Operation, typename Handler>+inline asio_handler_allocate_is_deprecated+asio_handler_allocate(std::size_t size,+ io_op<Stream, Operation, Handler>* this_handler)+{+#if defined(ASIO_NO_DEPRECATED)+ asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+ return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+ return asio_handler_alloc_helpers::allocate(+ size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Stream, typename Operation, typename Handler>+inline asio_handler_deallocate_is_deprecated+asio_handler_deallocate(void* pointer, std::size_t size,+ io_op<Stream, Operation, Handler>* this_handler)+{+ asio_handler_alloc_helpers::deallocate(+ pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Stream, typename Operation, typename Handler> inline bool asio_handler_is_continuation( io_op<Stream, Operation, Handler>* this_handler) {@@ -335,6 +364,32 @@ : asio_handler_cont_helpers::is_continuation(this_handler->handler_); } +template <typename Function, typename Stream,+ typename Operation, typename Handler>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(Function& function,+ io_op<Stream, Operation, Handler>* this_handler)+{+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Function, typename Stream,+ typename Operation, typename Handler>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(const Function& function,+ io_op<Stream, Operation, Handler>* this_handler)+{+ asio_handler_invoke_helpers::invoke(+ function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+ return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}+ template <typename Stream, typename Operation, typename Handler> inline void async_io(Stream& next_layer, stream_core& core, const Operation& op, Handler& handler)@@ -355,15 +410,19 @@ DefaultCandidate> : Associator<Handler, DefaultCandidate> {- static typename Associator<Handler, DefaultCandidate>::type get(- const ssl::detail::io_op<Stream, Operation, Handler>& h) noexcept+ static typename Associator<Handler, DefaultCandidate>::type+ get(const ssl::detail::io_op<Stream, Operation, Handler>& h)+ ASIO_NOEXCEPT { return Associator<Handler, DefaultCandidate>::get(h.handler_); } - static auto get(const ssl::detail::io_op<Stream, Operation, Handler>& h,- const DefaultCandidate& c) noexcept- -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))+ static ASIO_AUTO_RETURN_TYPE_PREFIX2(+ typename Associator<Handler, DefaultCandidate>::type)+ get(const ssl::detail::io_op<Stream, Operation, Handler>& h,+ const DefaultCandidate& c) ASIO_NOEXCEPT+ ASIO_AUTO_RETURN_TYPE_SUFFIX((+ Associator<Handler, DefaultCandidate>::get(h.handler_, c))) { return Associator<Handler, DefaultCandidate>::get(h.handler_, c); }
link/modules/asio-standalone/asio/include/asio/ssl/detail/openssl_init.hpp view
@@ -2,7 +2,7 @@ // ssl/detail/openssl_init.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/ssl/detail/openssl_types.hpp view
@@ -2,7 +2,7 @@ // ssl/detail/openssl_types.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/ssl/detail/password_callback.hpp view
@@ -2,7 +2,7 @@ // ssl/detail/password_callback.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/ssl/detail/read_op.hpp view
@@ -2,7 +2,7 @@ // ssl/detail/read_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -30,7 +30,7 @@ class read_op { public:- static constexpr const char* tracking_name()+ static ASIO_CONSTEXPR const char* tracking_name() { return "ssl::stream<>::async_read_some"; }@@ -56,7 +56,7 @@ const asio::error_code& ec, const std::size_t& bytes_transferred) const {- static_cast<Handler&&>(handler)(ec, bytes_transferred);+ ASIO_MOVE_OR_LVALUE(Handler)(handler)(ec, bytes_transferred); } private:
link/modules/asio-standalone/asio/include/asio/ssl/detail/shutdown_op.hpp view
@@ -2,7 +2,7 @@ // ssl/detail/shutdown_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -28,7 +28,7 @@ class shutdown_op { public:- static constexpr const char* tracking_name()+ static ASIO_CONSTEXPR const char* tracking_name() { return "ssl::stream<>::async_shutdown"; }@@ -51,11 +51,11 @@ // The engine only generates an eof when the shutdown notification has // been received from the peer. This indicates that the shutdown has // completed successfully, and thus need not be passed on to the handler.- static_cast<Handler&&>(handler)(asio::error_code());+ ASIO_MOVE_OR_LVALUE(Handler)(handler)(asio::error_code()); } else {- static_cast<Handler&&>(handler)(ec);+ ASIO_MOVE_OR_LVALUE(Handler)(handler)(ec); } } };
link/modules/asio-standalone/asio/include/asio/ssl/detail/stream_core.hpp view
@@ -2,7 +2,7 @@ // ssl/detail/stream_core.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -17,9 +17,13 @@ #include "asio/detail/config.hpp" +#if defined(ASIO_HAS_BOOST_DATE_TIME)+# include "asio/deadline_timer.hpp"+#else // defined(ASIO_HAS_BOOST_DATE_TIME)+# include "asio/steady_timer.hpp"+#endif // defined(ASIO_HAS_BOOST_DATE_TIME) #include "asio/ssl/detail/engine.hpp" #include "asio/buffer.hpp"-#include "asio/steady_timer.hpp" #include "asio/detail/push_options.hpp" @@ -61,20 +65,30 @@ pending_write_.expires_at(neg_infin()); } +#if defined(ASIO_HAS_MOVE) stream_core(stream_core&& other)- : engine_(static_cast<engine&&>(other.engine_)),+ : engine_(ASIO_MOVE_CAST(engine)(other.engine_)),+#if defined(ASIO_HAS_BOOST_DATE_TIME) pending_read_(- static_cast<asio::steady_timer&&>(+ ASIO_MOVE_CAST(asio::deadline_timer)( other.pending_read_)), pending_write_(- static_cast<asio::steady_timer&&>(+ ASIO_MOVE_CAST(asio::deadline_timer)( other.pending_write_)),+#else // defined(ASIO_HAS_BOOST_DATE_TIME)+ pending_read_(+ ASIO_MOVE_CAST(asio::steady_timer)(+ other.pending_read_)),+ pending_write_(+ ASIO_MOVE_CAST(asio::steady_timer)(+ other.pending_write_)),+#endif // defined(ASIO_HAS_BOOST_DATE_TIME) output_buffer_space_(- static_cast<std::vector<unsigned char>&&>(+ ASIO_MOVE_CAST(std::vector<unsigned char>)( other.output_buffer_space_)), output_buffer_(other.output_buffer_), input_buffer_space_(- static_cast<std::vector<unsigned char>&&>(+ ASIO_MOVE_CAST(std::vector<unsigned char>)( other.input_buffer_space_)), input_buffer_(other.input_buffer_), input_(other.input_)@@ -83,28 +97,39 @@ other.input_buffer_ = asio::mutable_buffer(0, 0); other.input_ = asio::const_buffer(0, 0); }+#endif // defined(ASIO_HAS_MOVE) ~stream_core() { } +#if defined(ASIO_HAS_MOVE) stream_core& operator=(stream_core&& other) { if (this != &other) {- engine_ = static_cast<engine&&>(other.engine_);+ engine_ = ASIO_MOVE_CAST(engine)(other.engine_);+#if defined(ASIO_HAS_BOOST_DATE_TIME) pending_read_ =- static_cast<asio::steady_timer&&>(+ ASIO_MOVE_CAST(asio::deadline_timer)( other.pending_read_); pending_write_ =- static_cast<asio::steady_timer&&>(+ ASIO_MOVE_CAST(asio::deadline_timer)( other.pending_write_);+#else // defined(ASIO_HAS_BOOST_DATE_TIME)+ pending_read_ =+ ASIO_MOVE_CAST(asio::steady_timer)(+ other.pending_read_);+ pending_write_ =+ ASIO_MOVE_CAST(asio::steady_timer)(+ other.pending_write_);+#endif // defined(ASIO_HAS_BOOST_DATE_TIME) output_buffer_space_ =- static_cast<std::vector<unsigned char>&&>(+ ASIO_MOVE_CAST(std::vector<unsigned char>)( other.output_buffer_space_); output_buffer_ = other.output_buffer_; input_buffer_space_ =- static_cast<std::vector<unsigned char>&&>(+ ASIO_MOVE_CAST(std::vector<unsigned char>)( other.input_buffer_space_); input_buffer_ = other.input_buffer_; input_ = other.input_;@@ -114,11 +139,38 @@ } return *this; }+#endif // defined(ASIO_HAS_MOVE) // The SSL engine. engine engine_; +#if defined(ASIO_HAS_BOOST_DATE_TIME) // Timer used for storing queued read operations.+ asio::deadline_timer pending_read_;++ // Timer used for storing queued write operations.+ asio::deadline_timer pending_write_;++ // Helper function for obtaining a time value that always fires.+ static asio::deadline_timer::time_type neg_infin()+ {+ return boost::posix_time::neg_infin;+ }++ // Helper function for obtaining a time value that never fires.+ static asio::deadline_timer::time_type pos_infin()+ {+ return boost::posix_time::pos_infin;+ }++ // Helper function to get a timer's expiry time.+ static asio::deadline_timer::time_type expiry(+ const asio::deadline_timer& timer)+ {+ return timer.expires_at();+ }+#else // defined(ASIO_HAS_BOOST_DATE_TIME)+ // Timer used for storing queued read operations. asio::steady_timer pending_read_; // Timer used for storing queued write operations.@@ -142,6 +194,7 @@ { return timer.expiry(); }+#endif // defined(ASIO_HAS_BOOST_DATE_TIME) // Buffer space used to prepare output intended for the transport. std::vector<unsigned char> output_buffer_space_;
link/modules/asio-standalone/asio/include/asio/ssl/detail/verify_callback.hpp view
@@ -1,8 +1,8 @@ // // ssl/detail/verify_callback.hpp-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/ssl/detail/write_op.hpp view
@@ -2,7 +2,7 @@ // ssl/detail/write_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -30,7 +30,7 @@ class write_op { public:- static constexpr const char* tracking_name()+ static ASIO_CONSTEXPR const char* tracking_name() { return "ssl::stream<>::async_write_some"; }@@ -60,7 +60,7 @@ const asio::error_code& ec, const std::size_t& bytes_transferred) const {- static_cast<Handler&&>(handler)(ec, bytes_transferred);+ ASIO_MOVE_OR_LVALUE(Handler)(handler)(ec, bytes_transferred); } private:
link/modules/asio-standalone/asio/include/asio/ssl/error.hpp view
@@ -2,7 +2,7 @@ // ssl/error.hpp // ~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -77,6 +77,7 @@ } // namespace ssl } // namespace asio +#if defined(ASIO_HAS_STD_SYSTEM_ERROR) namespace std { template<> struct is_error_code_enum<asio::error::ssl_errors>@@ -90,6 +91,7 @@ }; } // namespace std+#endif // defined(ASIO_HAS_STD_SYSTEM_ERROR) namespace asio { namespace error {
link/modules/asio-standalone/asio/include/asio/ssl/host_name_verification.hpp view
@@ -2,7 +2,7 @@ // ssl/host_name_verification.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/ssl/impl/context.hpp view
@@ -3,7 +3,7 @@ // ~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com-// Copyright (c) 2005-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2005-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/ssl/impl/context.ipp view
@@ -3,7 +3,7 @@ // ~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com-// Copyright (c) 2005-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2005-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -269,9 +269,8 @@ #endif // defined(SSL_TXT_TLSV1_2) // TLS v1.3.-#if ((OPENSSL_VERSION_NUMBER >= 0x10101000L) \- && !defined(LIBRESSL_VERSION_NUMBER)) \- || defined(ASIO_USE_WOLFSSL)+#if (OPENSSL_VERSION_NUMBER >= 0x10101000L) \+ && !defined(LIBRESSL_VERSION_NUMBER) case context::tlsv13: handle_ = ::SSL_CTX_new(::TLS_method()); if (handle_)@@ -296,18 +295,16 @@ SSL_CTX_set_max_proto_version(handle_, TLS1_3_VERSION); } break;-#else // ((OPENSSL_VERSION_NUMBER >= 0x10101000L)- // && !defined(LIBRESSL_VERSION_NUMBER))- // || defined(ASIO_USE_WOLFSSL)+#else // (OPENSSL_VERSION_NUMBER >= 0x10101000L)+ // && !defined(LIBRESSL_VERSION_NUMBER) case context::tlsv13: case context::tlsv13_client: case context::tlsv13_server: asio::detail::throw_error( asio::error::invalid_argument, "context"); break;-#endif // ((OPENSSL_VERSION_NUMBER >= 0x10101000L)- // && !defined(LIBRESSL_VERSION_NUMBER))- // || defined(ASIO_USE_WOLFSSL)+#endif // (OPENSSL_VERSION_NUMBER >= 0x10101000L)+ // && !defined(LIBRESSL_VERSION_NUMBER) // Any supported SSL/TLS version. case context::sslv23:@@ -379,6 +376,7 @@ } } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) context::context(context&& other) { handle_ = other.handle_;@@ -387,11 +385,12 @@ context& context::operator=(context&& other) {- context tmp(static_cast<context&&>(*this));+ context tmp(ASIO_MOVE_CAST(context)(*this)); handle_ = other.handle_; other.handle_ = 0; return *this; }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) context::~context() {@@ -797,7 +796,7 @@ ASIO_SYNC_OP_VOID_RETURN(ec); } }-+ result = ::ERR_peek_last_error(); if ((ERR_GET_LIB(result) == ERR_LIB_PEM) && (ERR_GET_REASON(result) == PEM_R_NO_START_LINE))
link/modules/asio-standalone/asio/include/asio/ssl/impl/error.ipp view
@@ -2,7 +2,7 @@ // ssl/impl/error.ipp // ~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -28,7 +28,7 @@ class ssl_category : public asio::error_category { public:- const char* name() const noexcept+ const char* name() const ASIO_ERROR_CATEGORY_NOEXCEPT { return "asio.ssl"; }@@ -88,7 +88,7 @@ class stream_category : public asio::error_category { public:- const char* name() const noexcept+ const char* name() const ASIO_ERROR_CATEGORY_NOEXCEPT { return "asio.ssl.stream"; }
link/modules/asio-standalone/asio/include/asio/ssl/impl/host_name_verification.ipp view
@@ -2,7 +2,7 @@ // ssl/impl/host_name_verification.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ link/modules/asio-standalone/asio/include/asio/ssl/impl/rfc2818_verification.ipp view
@@ -0,0 +1,164 @@+//+// ssl/impl/rfc2818_verification.ipp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_SSL_IMPL_RFC2818_VERIFICATION_IPP+#define ASIO_SSL_IMPL_RFC2818_VERIFICATION_IPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"++#if !defined(ASIO_NO_DEPRECATED)++#include <cctype>+#include <cstring>+#include "asio/ip/address.hpp"+#include "asio/ssl/rfc2818_verification.hpp"+#include "asio/ssl/detail/openssl_types.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {+namespace ssl {++bool rfc2818_verification::operator()(+ bool preverified, verify_context& ctx) const+{+ using namespace std; // For memcmp.++ // Don't bother looking at certificates that have failed pre-verification.+ if (!preverified)+ return false;++ // We're only interested in checking the certificate at the end of the chain.+ int depth = X509_STORE_CTX_get_error_depth(ctx.native_handle());+ if (depth > 0)+ return true;++ // Try converting the host name to an address. If it is an address then we+ // need to look for an IP address in the certificate rather than a host name.+ asio::error_code ec;+ ip::address address = ip::make_address(host_, ec);+ bool is_address = !ec;++ X509* cert = X509_STORE_CTX_get_current_cert(ctx.native_handle());++ // Go through the alternate names in the certificate looking for matching DNS+ // or IP address entries.+ GENERAL_NAMES* gens = static_cast<GENERAL_NAMES*>(+ X509_get_ext_d2i(cert, NID_subject_alt_name, 0, 0));+ for (int i = 0; i < sk_GENERAL_NAME_num(gens); ++i)+ {+ GENERAL_NAME* gen = sk_GENERAL_NAME_value(gens, i);+ if (gen->type == GEN_DNS && !is_address)+ {+ ASN1_IA5STRING* domain = gen->d.dNSName;+ if (domain->type == V_ASN1_IA5STRING && domain->data && domain->length)+ {+ const char* pattern = reinterpret_cast<const char*>(domain->data);+ std::size_t pattern_length = domain->length;+ if (match_pattern(pattern, pattern_length, host_.c_str()))+ {+ GENERAL_NAMES_free(gens);+ return true;+ }+ }+ }+ else if (gen->type == GEN_IPADD && is_address)+ {+ ASN1_OCTET_STRING* ip_address = gen->d.iPAddress;+ if (ip_address->type == V_ASN1_OCTET_STRING && ip_address->data)+ {+ if (address.is_v4() && ip_address->length == 4)+ {+ ip::address_v4::bytes_type bytes = address.to_v4().to_bytes();+ if (memcmp(bytes.data(), ip_address->data, 4) == 0)+ {+ GENERAL_NAMES_free(gens);+ return true;+ }+ }+ else if (address.is_v6() && ip_address->length == 16)+ {+ ip::address_v6::bytes_type bytes = address.to_v6().to_bytes();+ if (memcmp(bytes.data(), ip_address->data, 16) == 0)+ {+ GENERAL_NAMES_free(gens);+ return true;+ }+ }+ }+ }+ }+ GENERAL_NAMES_free(gens);++ // No match in the alternate names, so try the common names. We should only+ // use the "most specific" common name, which is the last one in the list.+ X509_NAME* name = X509_get_subject_name(cert);+ int i = -1;+ ASN1_STRING* common_name = 0;+ while ((i = X509_NAME_get_index_by_NID(name, NID_commonName, i)) >= 0)+ {+ X509_NAME_ENTRY* name_entry = X509_NAME_get_entry(name, i);+ common_name = X509_NAME_ENTRY_get_data(name_entry);+ }+ if (common_name && common_name->data && common_name->length)+ {+ const char* pattern = reinterpret_cast<const char*>(common_name->data);+ std::size_t pattern_length = common_name->length;+ if (match_pattern(pattern, pattern_length, host_.c_str()))+ return true;+ }++ return false;+}++bool rfc2818_verification::match_pattern(const char* pattern,+ std::size_t pattern_length, const char* host)+{+ using namespace std; // For tolower.++ const char* p = pattern;+ const char* p_end = p + pattern_length;+ const char* h = host;++ while (p != p_end && *h)+ {+ if (*p == '*')+ {+ ++p;+ while (*h && *h != '.')+ if (match_pattern(p, p_end - p, h++))+ return true;+ }+ else if (tolower(*p) == tolower(*h))+ {+ ++p;+ ++h;+ }+ else+ {+ return false;+ }+ }++ return p == p_end && !*h;+}++} // namespace ssl+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // !defined(ASIO_NO_DEPRECATED)++#endif // ASIO_SSL_IMPL_RFC2818_VERIFICATION_IPP
link/modules/asio-standalone/asio/include/asio/ssl/impl/src.hpp view
@@ -2,7 +2,7 @@ // impl/ssl/src.hpp // ~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -24,5 +24,6 @@ #include "asio/ssl/detail/impl/engine.ipp" #include "asio/ssl/detail/impl/openssl_init.ipp" #include "asio/ssl/impl/host_name_verification.ipp"+#include "asio/ssl/impl/rfc2818_verification.ipp" #endif // ASIO_SSL_IMPL_SRC_HPP
+ link/modules/asio-standalone/asio/include/asio/ssl/rfc2818_verification.hpp view
@@ -0,0 +1,98 @@+//+// ssl/rfc2818_verification.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_SSL_RFC2818_VERIFICATION_HPP+#define ASIO_SSL_RFC2818_VERIFICATION_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"++#if !defined(ASIO_NO_DEPRECATED)++#include <string>+#include "asio/ssl/detail/openssl_types.hpp"+#include "asio/ssl/verify_context.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {+namespace ssl {++/// (Deprecated. Use ssl::host_name_verification.) Verifies a certificate+/// against a hostname according to the rules described in RFC 2818.+/**+ * @par Example+ * The following example shows how to synchronously open a secure connection to+ * a given host name:+ * @code+ * using asio::ip::tcp;+ * namespace ssl = asio::ssl;+ * typedef ssl::stream<tcp::socket> ssl_socket;+ *+ * // Create a context that uses the default paths for finding CA certificates.+ * ssl::context ctx(ssl::context::sslv23);+ * ctx.set_default_verify_paths();+ *+ * // Open a socket and connect it to the remote host.+ * asio::io_context io_context;+ * ssl_socket sock(io_context, ctx);+ * tcp::resolver resolver(io_context);+ * tcp::resolver::query query("host.name", "https");+ * asio::connect(sock.lowest_layer(), resolver.resolve(query));+ * sock.lowest_layer().set_option(tcp::no_delay(true));+ *+ * // Perform SSL handshake and verify the remote host's certificate.+ * sock.set_verify_mode(ssl::verify_peer);+ * sock.set_verify_callback(ssl::rfc2818_verification("host.name"));+ * sock.handshake(ssl_socket::client);+ *+ * // ... read and write as normal ...+ * @endcode+ */+class rfc2818_verification+{+public:+ /// The type of the function object's result.+ typedef bool result_type;++ /// Constructor.+ explicit rfc2818_verification(const std::string& host)+ : host_(host)+ {+ }++ /// Perform certificate verification.+ ASIO_DECL bool operator()(bool preverified, verify_context& ctx) const;++private:+ // Helper function to check a host name against a pattern.+ ASIO_DECL static bool match_pattern(const char* pattern,+ std::size_t pattern_length, const char* host);++ // Helper function to check a host name against an IPv4 address+ // The host name to be checked.+ std::string host_;+};++} // namespace ssl+} // namespace asio++#include "asio/detail/pop_options.hpp"++#if defined(ASIO_HEADER_ONLY)+# include "asio/ssl/impl/rfc2818_verification.ipp"+#endif // defined(ASIO_HEADER_ONLY)++#endif // !defined(ASIO_NO_DEPRECATED)++#endif // ASIO_SSL_RFC2818_VERIFICATION_HPP
link/modules/asio-standalone/asio/include/asio/ssl/stream.hpp view
@@ -2,7 +2,7 @@ // ssl/stream.hpp // ~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -18,7 +18,6 @@ #include "asio/detail/config.hpp" #include "asio/async_result.hpp"-#include "asio/buffer.hpp" #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/handler_type_requirements.hpp" #include "asio/detail/non_const_lvalue.hpp"@@ -55,7 +54,7 @@ * @code * asio::io_context my_context; * asio::ssl::context ctx(asio::ssl::context::sslv23);- * asio::ssl::stream<asio::ip::tcp::socket> sock(my_context, ctx);+ * asio::ssl::stream<asio:ip::tcp::socket> sock(my_context, ctx); * @endcode * * @par Concepts:@@ -84,7 +83,7 @@ }; /// The type of the next layer.- typedef remove_reference_t<Stream> next_layer_type;+ typedef typename remove_reference<Stream>::type next_layer_type; /// The type of the lowest layer. typedef typename next_layer_type::lowest_layer_type lowest_layer_type;@@ -92,6 +91,7 @@ /// The type of the executor associated with the object. typedef typename lowest_layer_type::executor_type executor_type; +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Construct a stream. /** * This constructor creates a stream and initialises the underlying stream@@ -103,7 +103,7 @@ */ template <typename Arg> stream(Arg&& arg, context& ctx)- : next_layer_(static_cast<Arg&&>(arg)),+ : next_layer_(ASIO_MOVE_CAST(Arg)(arg)), core_(ctx.native_handle(), next_layer_.lowest_layer().get_executor()) { }@@ -120,11 +120,27 @@ */ template <typename Arg> stream(Arg&& arg, native_handle_type handle)- : next_layer_(static_cast<Arg&&>(arg)),+ : next_layer_(ASIO_MOVE_CAST(Arg)(arg)), core_(handle, next_layer_.lowest_layer().get_executor()) { }+#else // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)+ template <typename Arg>+ stream(Arg& arg, context& ctx)+ : next_layer_(arg),+ core_(ctx.native_handle(), next_layer_.lowest_layer().get_executor())+ {+ } + template <typename Arg>+ stream(Arg& arg, native_handle_type handle)+ : next_layer_(arg),+ core_(handle, next_layer_.lowest_layer().get_executor())+ {+ }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)++#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move-construct a stream from another. /** * @param other The other stream object from which the move will occur. Must@@ -133,8 +149,8 @@ * operation is destruction, or use as the target of a move assignment. */ stream(stream&& other)- : next_layer_(static_cast<Stream&&>(other.next_layer_)),- core_(static_cast<detail::stream_core&&>(other.core_))+ : next_layer_(ASIO_MOVE_CAST(Stream)(other.next_layer_)),+ core_(ASIO_MOVE_CAST(detail::stream_core)(other.core_)) { } @@ -149,11 +165,12 @@ { if (this != &other) {- next_layer_ = static_cast<Stream&&>(other.next_layer_);- core_ = static_cast<detail::stream_core&&>(other.core_);+ next_layer_ = ASIO_MOVE_CAST(Stream)(other.next_layer_);+ core_ = ASIO_MOVE_CAST(detail::stream_core)(other.core_); } return *this; }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Destructor. /**@@ -171,7 +188,7 @@ * * @return A copy of the executor that stream will use to dispatch handlers. */- executor_type get_executor() noexcept+ executor_type get_executor() ASIO_NOEXCEPT { return next_layer_.lowest_layer().get_executor(); }@@ -187,7 +204,7 @@ * suitable for passing to functions such as @c SSL_get_verify_result and * @c SSL_get_peer_certificate: * @code- * asio::ssl::stream<asio::ip::tcp::socket> sock(io_ctx, ctx);+ * asio::ssl::stream<asio:ip::tcp::socket> sock(my_context, ctx); * * // ... establish connection and perform handshake ... *@@ -481,7 +498,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code) @endcode@@ -499,13 +516,17 @@ */ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code))- HandshakeToken = default_completion_token_t<executor_type>>- auto async_handshake(handshake_type type,- HandshakeToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ HandshakeToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(HandshakeToken,+ void (asio::error_code))+ async_handshake(handshake_type type,+ ASIO_MOVE_ARG(HandshakeToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<HandshakeToken, void (asio::error_code)>(- declval<initiate_async_handshake>(), token, type))+ declval<initiate_async_handshake>(), token, type))) { return async_initiate<HandshakeToken, void (asio::error_code)>(@@ -538,7 +559,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -557,17 +578,16 @@ template <typename ConstBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, std::size_t)) BufferedHandshakeToken- = default_completion_token_t<executor_type>>- auto async_handshake(handshake_type type, const ConstBufferSequence& buffers,- BufferedHandshakeToken&& token- = default_completion_token_t<executor_type>(),- constraint_t<- is_const_buffer_sequence<ConstBufferSequence>::value- > = 0)- -> decltype(+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(BufferedHandshakeToken,+ void (asio::error_code, std::size_t))+ async_handshake(handshake_type type, const ConstBufferSequence& buffers,+ ASIO_MOVE_ARG(BufferedHandshakeToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<BufferedHandshakeToken, void (asio::error_code, std::size_t)>(- declval<initiate_async_buffered_handshake>(), token, type, buffers))+ declval<initiate_async_buffered_handshake>(), token, type, buffers))) { return async_initiate<BufferedHandshakeToken, void (asio::error_code, std::size_t)>(@@ -618,7 +638,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code) @endcode@@ -637,13 +657,16 @@ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code)) ShutdownToken- = default_completion_token_t<executor_type>>- auto async_shutdown(- ShutdownToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ShutdownToken,+ void (asio::error_code))+ async_shutdown(+ ASIO_MOVE_ARG(ShutdownToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<ShutdownToken, void (asio::error_code)>(- declval<initiate_async_shutdown>(), token))+ declval<initiate_async_shutdown>(), token))) { return async_initiate<ShutdownToken, void (asio::error_code)>(@@ -722,7 +745,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -745,13 +768,17 @@ */ template <typename ConstBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) WriteToken = default_completion_token_t<executor_type>>- auto async_write_some(const ConstBufferSequence& buffers,- WriteToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ std::size_t)) WriteToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+ void (asio::error_code, std::size_t))+ async_write_some(const ConstBufferSequence& buffers,+ ASIO_MOVE_ARG(WriteToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<WriteToken, void (asio::error_code, std::size_t)>(- declval<initiate_async_write_some>(), token, buffers))+ declval<initiate_async_write_some>(), token, buffers))) { return async_initiate<WriteToken, void (asio::error_code, std::size_t)>(@@ -830,7 +857,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -853,13 +880,17 @@ */ template <typename MutableBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) ReadToken = default_completion_token_t<executor_type>>- auto async_read_some(const MutableBufferSequence& buffers,- ReadToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ std::size_t)) ReadToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+ async_read_some(const MutableBufferSequence& buffers,+ ASIO_MOVE_ARG(ReadToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<ReadToken, void (asio::error_code, std::size_t)>(- declval<initiate_async_read_some>(), token, buffers))+ declval<initiate_async_read_some>(), token, buffers))) { return async_initiate<ReadToken, void (asio::error_code, std::size_t)>(@@ -877,13 +908,13 @@ { } - executor_type get_executor() const noexcept+ executor_type get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template <typename HandshakeHandler>- void operator()(HandshakeHandler&& handler,+ void operator()(ASIO_MOVE_ARG(HandshakeHandler) handler, handshake_type type) const { // If you get an error on the following line it means that your handler@@ -909,13 +940,13 @@ { } - executor_type get_executor() const noexcept+ executor_type get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template <typename BufferedHandshakeHandler, typename ConstBufferSequence>- void operator()(BufferedHandshakeHandler&& handler,+ void operator()(ASIO_MOVE_ARG(BufferedHandshakeHandler) handler, handshake_type type, const ConstBufferSequence& buffers) const { // If you get an error on the following line it means that your@@ -945,13 +976,13 @@ { } - executor_type get_executor() const noexcept+ executor_type get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template <typename ShutdownHandler>- void operator()(ShutdownHandler&& handler) const+ void operator()(ASIO_MOVE_ARG(ShutdownHandler) handler) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a ShutdownHandler.@@ -976,13 +1007,13 @@ { } - executor_type get_executor() const noexcept+ executor_type get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template <typename WriteHandler, typename ConstBufferSequence>- void operator()(WriteHandler&& handler,+ void operator()(ASIO_MOVE_ARG(WriteHandler) handler, const ConstBufferSequence& buffers) const { // If you get an error on the following line it means that your handler@@ -1008,13 +1039,13 @@ { } - executor_type get_executor() const noexcept+ executor_type get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template <typename ReadHandler, typename MutableBufferSequence>- void operator()(ReadHandler&& handler,+ void operator()(ASIO_MOVE_ARG(ReadHandler) handler, const MutableBufferSequence& buffers) const { // If you get an error on the following line it means that your handler
link/modules/asio-standalone/asio/include/asio/ssl/stream_base.hpp view
@@ -2,7 +2,7 @@ // ssl/stream_base.hpp // ~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/ssl/verify_context.hpp view
@@ -2,7 +2,7 @@ // ssl/verify_context.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/ssl/verify_mode.hpp view
@@ -2,7 +2,7 @@ // ssl/verify_mode.hpp // ~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/static_thread_pool.hpp view
@@ -2,7 +2,7 @@ // static_thread_pool.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/steady_timer.hpp view
@@ -2,7 +2,7 @@ // steady_timer.hpp // ~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -16,6 +16,9 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"++#if defined(ASIO_HAS_CHRONO) || defined(GENERATING_DOCUMENTATION)+ #include "asio/basic_waitable_timer.hpp" #include "asio/detail/chrono.hpp" @@ -33,5 +36,7 @@ typedef basic_waitable_timer<chrono::steady_clock> steady_timer; } // namespace asio++#endif // defined(ASIO_HAS_CHRONO) || defined(GENERATING_DOCUMENTATION) #endif // ASIO_STEADY_TIMER_HPP
link/modules/asio-standalone/asio/include/asio/strand.hpp view
@@ -2,7 +2,7 @@ // strand.hpp // ~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -48,20 +48,20 @@ /// Construct a strand for the specified executor. template <typename Executor1> explicit strand(const Executor1& e,- constraint_t<- conditional_t<+ typename constraint<+ conditional< !is_same<Executor1, strand>::value, is_convertible<Executor1, Executor>, false_type- >::value- > = 0)+ >::type::value+ >::type = 0) : executor_(e), impl_(strand::create_implementation(executor_)) { } /// Copy constructor.- strand(const strand& other) noexcept+ strand(const strand& other) ASIO_NOEXCEPT : executor_(other.executor_), impl_(other.impl_) {@@ -74,14 +74,14 @@ */ template <class OtherExecutor> strand(- const strand<OtherExecutor>& other) noexcept+ const strand<OtherExecutor>& other) ASIO_NOEXCEPT : executor_(other.executor_), impl_(other.impl_) { } /// Assignment operator.- strand& operator=(const strand& other) noexcept+ strand& operator=(const strand& other) ASIO_NOEXCEPT { executor_ = other.executor_; impl_ = other.impl_;@@ -95,17 +95,18 @@ */ template <class OtherExecutor> strand& operator=(- const strand<OtherExecutor>& other) noexcept+ const strand<OtherExecutor>& other) ASIO_NOEXCEPT { executor_ = other.executor_; impl_ = other.impl_; return *this; } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move constructor.- strand(strand&& other) noexcept- : executor_(static_cast<Executor&&>(other.executor_)),- impl_(static_cast<implementation_type&&>(other.impl_))+ strand(strand&& other) ASIO_NOEXCEPT+ : executor_(ASIO_MOVE_CAST(Executor)(other.executor_)),+ impl_(ASIO_MOVE_CAST(implementation_type)(other.impl_)) { } @@ -115,17 +116,17 @@ * to @c Executor. */ template <class OtherExecutor>- strand(strand<OtherExecutor>&& other) noexcept- : executor_(static_cast<OtherExecutor&&>(other.executor_)),- impl_(static_cast<implementation_type&&>(other.impl_))+ strand(strand<OtherExecutor>&& other) ASIO_NOEXCEPT+ : executor_(ASIO_MOVE_CAST(OtherExecutor)(other.executor_)),+ impl_(ASIO_MOVE_CAST(implementation_type)(other.impl_)) { } /// Move assignment operator.- strand& operator=(strand&& other) noexcept+ strand& operator=(strand&& other) ASIO_NOEXCEPT {- executor_ = static_cast<Executor&&>(other.executor_);- impl_ = static_cast<implementation_type&&>(other.impl_);+ executor_ = ASIO_MOVE_CAST(Executor)(other.executor_);+ impl_ = ASIO_MOVE_CAST(implementation_type)(other.impl_); return *this; } @@ -135,20 +136,21 @@ * convertible to @c Executor. */ template <class OtherExecutor>- strand& operator=(strand<OtherExecutor>&& other) noexcept+ strand& operator=(strand<OtherExecutor>&& other) ASIO_NOEXCEPT {- executor_ = static_cast<OtherExecutor&&>(other.executor_);- impl_ = static_cast<implementation_type&&>(other.impl_);+ executor_ = ASIO_MOVE_CAST(OtherExecutor)(other.executor_);+ impl_ = ASIO_MOVE_CAST(implementation_type)(other.impl_); return *this; }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Destructor.- ~strand() noexcept+ ~strand() ASIO_NOEXCEPT { } /// Obtain the underlying executor.- inner_executor_type get_inner_executor() const noexcept+ inner_executor_type get_inner_executor() const ASIO_NOEXCEPT { return executor_; }@@ -165,15 +167,16 @@ * ... @endcode */ template <typename Property>- constraint_t<+ typename constraint< can_query<const Executor&, Property>::value,- conditional_t<+ typename conditional< is_convertible<Property, execution::blocking_t>::value, execution::blocking_t,- query_result_t<const Executor&, Property>- >- > query(const Property& p) const- noexcept(is_nothrow_query<const Executor&, Property>::value)+ typename query_result<const Executor&, Property>::type+ >::type+ >::type query(const Property& p) const+ ASIO_NOEXCEPT_IF((+ is_nothrow_query<const Executor&, Property>::value)) { return this->query_helper( is_convertible<Property, execution::blocking_t>(), p);@@ -190,15 +193,19 @@ * asio::execution::blocking.never); @endcode */ template <typename Property>- constraint_t<+ typename constraint< can_require<const Executor&, Property>::value && !is_convertible<Property, execution::blocking_t::always_t>::value,- strand<decay_t<require_result_t<const Executor&, Property>>>- > require(const Property& p) const- noexcept(is_nothrow_require<const Executor&, Property>::value)+ strand<typename decay<+ typename require_result<const Executor&, Property>::type+ >::type>+ >::type require(const Property& p) const+ ASIO_NOEXCEPT_IF((+ is_nothrow_require<const Executor&, Property>::value)) {- return strand<decay_t<require_result_t<const Executor&, Property>>>(- asio::require(executor_, p), impl_);+ return strand<typename decay<+ typename require_result<const Executor&, Property>::type+ >::type>(asio::require(executor_, p), impl_); } /// Forward a preference to the underlying executor.@@ -212,20 +219,24 @@ * asio::execution::blocking.never); @endcode */ template <typename Property>- constraint_t<+ typename constraint< can_prefer<const Executor&, Property>::value && !is_convertible<Property, execution::blocking_t::always_t>::value,- strand<decay_t<prefer_result_t<const Executor&, Property>>>- > prefer(const Property& p) const- noexcept(is_nothrow_prefer<const Executor&, Property>::value)+ strand<typename decay<+ typename prefer_result<const Executor&, Property>::type+ >::type>+ >::type prefer(const Property& p) const+ ASIO_NOEXCEPT_IF((+ is_nothrow_prefer<const Executor&, Property>::value)) {- return strand<decay_t<prefer_result_t<const Executor&, Property>>>(- asio::prefer(executor_, p), impl_);+ return strand<typename decay<+ typename prefer_result<const Executor&, Property>::type+ >::type>(asio::prefer(executor_, p), impl_); } #if !defined(ASIO_NO_TS_EXECUTORS) /// Obtain the underlying execution context.- execution_context& context() const noexcept+ execution_context& context() const ASIO_NOEXCEPT { return executor_.context(); }@@ -234,7 +245,7 @@ /** * The strand delegates this call to its underlying executor. */- void on_work_started() const noexcept+ void on_work_started() const ASIO_NOEXCEPT { executor_.on_work_started(); }@@ -243,7 +254,7 @@ /** * The strand delegates this call to its underlying executor. */- void on_work_finished() const noexcept+ void on_work_finished() const ASIO_NOEXCEPT { executor_.on_work_finished(); }@@ -260,13 +271,20 @@ * function object must be: @code void function(); @endcode */ template <typename Function>- constraint_t<+ typename constraint<+#if defined(ASIO_NO_DEPRECATED) \+ || defined(GENERATING_DOCUMENTATION) traits::execute_member<const Executor&, Function>::is_valid,+#else // defined(ASIO_NO_DEPRECATED)+ // || defined(GENERATING_DOCUMENTATION)+ execution::can_execute<const Executor&, Function>::value,+#endif // defined(ASIO_NO_DEPRECATED)+ // || defined(GENERATING_DOCUMENTATION) void- > execute(Function&& f) const+ >::type execute(ASIO_MOVE_ARG(Function) f) const { detail::strand_executor_service::execute(impl_,- executor_, static_cast<Function&&>(f));+ executor_, ASIO_MOVE_CAST(Function)(f)); } #if !defined(ASIO_NO_TS_EXECUTORS)@@ -286,10 +304,10 @@ * internal storage needed for function invocation. */ template <typename Function, typename Allocator>- void dispatch(Function&& f, const Allocator& a) const+ void dispatch(ASIO_MOVE_ARG(Function) f, const Allocator& a) const { detail::strand_executor_service::dispatch(impl_,- executor_, static_cast<Function&&>(f), a);+ executor_, ASIO_MOVE_CAST(Function)(f), a); } /// Request the strand to invoke the given function object.@@ -306,10 +324,10 @@ * internal storage needed for function invocation. */ template <typename Function, typename Allocator>- void post(Function&& f, const Allocator& a) const+ void post(ASIO_MOVE_ARG(Function) f, const Allocator& a) const { detail::strand_executor_service::post(impl_,- executor_, static_cast<Function&&>(f), a);+ executor_, ASIO_MOVE_CAST(Function)(f), a); } /// Request the strand to invoke the given function object.@@ -326,10 +344,10 @@ * internal storage needed for function invocation. */ template <typename Function, typename Allocator>- void defer(Function&& f, const Allocator& a) const+ void defer(ASIO_MOVE_ARG(Function) f, const Allocator& a) const { detail::strand_executor_service::defer(impl_,- executor_, static_cast<Function&&>(f), a);+ executor_, ASIO_MOVE_CAST(Function)(f), a); } #endif // !defined(ASIO_NO_TS_EXECUTORS) @@ -339,7 +357,7 @@ * submitted to the strand using post(), dispatch() or defer(). Otherwise * returns @c false. */- bool running_in_this_thread() const noexcept+ bool running_in_this_thread() const ASIO_NOEXCEPT { return detail::strand_executor_service::running_in_this_thread(impl_); }@@ -349,7 +367,7 @@ * Two strands are equal if they refer to the same ordered, non-concurrent * state. */- friend bool operator==(const strand& a, const strand& b) noexcept+ friend bool operator==(const strand& a, const strand& b) ASIO_NOEXCEPT { return a.impl_ == b.impl_; }@@ -359,7 +377,7 @@ * Two strands are equal if they refer to the same ordered, non-concurrent * state. */- friend bool operator!=(const strand& a, const strand& b) noexcept+ friend bool operator!=(const strand& a, const strand& b) ASIO_NOEXCEPT { return a.impl_ != b.impl_; }@@ -372,9 +390,9 @@ template <typename InnerExecutor> static implementation_type create_implementation(const InnerExecutor& ex,- constraint_t<+ typename constraint< can_query<InnerExecutor, execution::context_t>::value- > = 0)+ >::type = 0) { return use_service<detail::strand_executor_service>( asio::query(ex, execution::context)).create_implementation();@@ -382,9 +400,9 @@ template <typename InnerExecutor> static implementation_type create_implementation(const InnerExecutor& ex,- constraint_t<+ typename constraint< !can_query<InnerExecutor, execution::context_t>::value- > = 0)+ >::type = 0) { return use_service<detail::strand_executor_service>( ex.context()).create_implementation();@@ -397,7 +415,7 @@ } template <typename Property>- query_result_t<const Executor&, Property> query_helper(+ typename query_result<const Executor&, Property>::type query_helper( false_type, const Property& property) const { return asio::query(executor_, property);@@ -430,9 +448,9 @@ */ template <typename Executor> inline strand<Executor> make_strand(const Executor& ex,- constraint_t<+ typename constraint< is_executor<Executor>::value || execution::is_executor<Executor>::value- > = 0)+ >::type = 0) { return strand<Executor>(ex); }@@ -447,9 +465,9 @@ template <typename ExecutionContext> inline strand<typename ExecutionContext::executor_type> make_strand(ExecutionContext& ctx,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- > = 0)+ >::type = 0) { return strand<typename ExecutionContext::executor_type>(ctx.get_executor()); }@@ -463,10 +481,10 @@ #if !defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT) template <typename Executor>-struct equality_comparable<strand<Executor>>+struct equality_comparable<strand<Executor> > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); }; #endif // !defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)@@ -475,12 +493,16 @@ template <typename Executor, typename Function> struct execute_member<strand<Executor>, Function,- enable_if_t<+ typename enable_if<+#if defined(ASIO_NO_DEPRECATED) traits::execute_member<const Executor&, Function>::is_valid- >>+#else // defined(ASIO_NO_DEPRECATED)+ execution::can_execute<const Executor&, Function>::value+#endif // defined(ASIO_NO_DEPRECATED)+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = false;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); typedef void result_type; }; @@ -490,16 +512,17 @@ template <typename Executor, typename Property> struct query_member<strand<Executor>, Property,- enable_if_t<+ typename enable_if< can_query<const Executor&, Property>::value- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept =- is_nothrow_query<Executor, Property>::value;- typedef conditional_t<+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+ (is_nothrow_query<Executor, Property>::value));+ typedef typename conditional< is_convertible<Property, execution::blocking_t>::value,- execution::blocking_t, query_result_t<Executor, Property>> result_type;+ execution::blocking_t, typename query_result<Executor, Property>::type+ >::type result_type; }; #endif // !defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)@@ -508,15 +531,17 @@ template <typename Executor, typename Property> struct require_member<strand<Executor>, Property,- enable_if_t<+ typename enable_if< can_require<const Executor&, Property>::value && !is_convertible<Property, execution::blocking_t::always_t>::value- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept =- is_nothrow_require<Executor, Property>::value;- typedef strand<decay_t<require_result_t<Executor, Property>>> result_type;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+ (is_nothrow_require<Executor, Property>::value));+ typedef strand<typename decay<+ typename require_result<Executor, Property>::type+ >::type> result_type; }; #endif // !defined(ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)@@ -525,15 +550,17 @@ template <typename Executor, typename Property> struct prefer_member<strand<Executor>, Property,- enable_if_t<+ typename enable_if< can_prefer<const Executor&, Property>::value && !is_convertible<Property, execution::blocking_t::always_t>::value- >>+ >::type> {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept =- is_nothrow_prefer<Executor, Property>::value;- typedef strand<decay_t<prefer_result_t<Executor, Property>>> result_type;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+ (is_nothrow_prefer<Executor, Property>::value));+ typedef strand<typename decay<+ typename prefer_result<Executor, Property>::type+ >::type> result_type; }; #endif // !defined(ASIO_HAS_DEDUCED_PREFER_MEMBER_TRAIT)
link/modules/asio-standalone/asio/include/asio/stream_file.hpp view
@@ -2,7 +2,7 @@ // stream_file.hpp // ~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/streambuf.hpp view
@@ -2,7 +2,7 @@ // streambuf.hpp // ~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/system_context.hpp view
@@ -2,7 +2,7 @@ // system_context.hpp // ~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -43,13 +43,13 @@ ASIO_DECL ~system_context(); /// Obtain an executor for the context.- executor_type get_executor() noexcept;+ executor_type get_executor() ASIO_NOEXCEPT; /// Signal all threads in the system thread pool to stop. ASIO_DECL void stop(); /// Determine whether the system thread pool has been stopped.- ASIO_DECL bool stopped() const noexcept;+ ASIO_DECL bool stopped() const ASIO_NOEXCEPT; /// Join all threads in the system thread pool. ASIO_DECL void join();@@ -72,7 +72,7 @@ detail::scheduler& scheduler_; // The threads in the system thread pool.- detail::thread_group<std::allocator<void>> threads_;+ detail::thread_group threads_; // The number of threads in the pool. std::size_t num_threads_;
link/modules/asio-standalone/asio/include/asio/system_error.hpp view
@@ -2,7 +2,7 @@ // system_error.hpp // ~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -16,13 +16,113 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"-#include <system_error> +#if defined(ASIO_HAS_STD_SYSTEM_ERROR)+# include <system_error>+#else // defined(ASIO_HAS_STD_SYSTEM_ERROR)+# include <cerrno>+# include <exception>+# include <string>+# include "asio/error_code.hpp"+# include "asio/detail/scoped_ptr.hpp"+#endif // defined(ASIO_HAS_STD_SYSTEM_ERROR)+ #include "asio/detail/push_options.hpp" namespace asio { +#if defined(ASIO_HAS_STD_SYSTEM_ERROR)+ typedef std::system_error system_error;++#else // defined(ASIO_HAS_STD_SYSTEM_ERROR)++/// The system_error class is used to represent system conditions that+/// prevent the library from operating correctly.+class system_error+ : public std::exception+{+public:+ /// Construct with an error code.+ system_error(const error_code& ec)+ : code_(ec),+ context_()+ {+ }++ /// Construct with an error code and context.+ system_error(const error_code& ec, const std::string& context)+ : code_(ec),+ context_(context)+ {+ }++ /// Copy constructor.+ system_error(const system_error& other)+ : std::exception(other),+ code_(other.code_),+ context_(other.context_),+ what_()+ {+ }++ /// Destructor.+ virtual ~system_error() throw ()+ {+ }++ /// Assignment operator.+ system_error& operator=(const system_error& e)+ {+ context_ = e.context_;+ code_ = e.code_;+ what_.reset();+ return *this;+ }++ /// Get a string representation of the exception.+ virtual const char* what() const throw ()+ {+#if !defined(ASIO_NO_EXCEPTIONS)+ try+#endif // !defined(ASIO_NO_EXCEPTIONS)+ {+ if (!what_.get())+ {+ std::string tmp(context_);+ if (tmp.length())+ tmp += ": ";+ tmp += code_.message();+ what_.reset(new std::string(tmp));+ }+ return what_->c_str();+ }+#if !defined(ASIO_NO_EXCEPTIONS)+ catch (std::exception&)+ {+ return "system_error";+ }+#endif // !defined(ASIO_NO_EXCEPTIONS)+ }++ /// Get the error code associated with the exception.+ error_code code() const+ {+ return code_;+ }++private:+ // The code associated with the error.+ error_code code_;++ // The context associated with the error.+ std::string context_;++ // The string representation of the error.+ mutable asio::detail::scoped_ptr<std::string> what_;+};++#endif // defined(ASIO_HAS_STD_SYSTEM_ERROR) } // namespace asio
link/modules/asio-standalone/asio/include/asio/system_executor.hpp view
@@ -2,7 +2,7 @@ // system_executor.hpp // ~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -39,7 +39,7 @@ { public: /// Default constructor.- basic_system_executor() noexcept+ basic_system_executor() ASIO_NOEXCEPT : allocator_(Allocator()) { }@@ -168,11 +168,11 @@ * auto ex2 = asio::require(ex1, * asio::execution::allocator); @endcode */- basic_system_executor<Blocking, Relationship, std::allocator<void>>+ basic_system_executor<Blocking, Relationship, std::allocator<void> > require(execution::allocator_t<void>) const { return basic_system_executor<Blocking,- Relationship, std::allocator<void>>();+ Relationship, std::allocator<void> >(); } #if !defined(GENERATING_DOCUMENTATION)@@ -195,8 +195,8 @@ * == asio::execution::mapping.thread) * ... @endcode */- static constexpr execution::mapping_t query(- execution::mapping_t) noexcept+ static ASIO_CONSTEXPR execution::mapping_t query(+ execution::mapping_t) ASIO_NOEXCEPT { return execution::mapping.thread; }@@ -211,7 +211,7 @@ * asio::system_context& pool = asio::query( * ex, asio::execution::context); @endcode */- static system_context& query(execution::context_t) noexcept;+ static system_context& query(execution::context_t) ASIO_NOEXCEPT; /// Query the current value of the @c blocking property. /**@@ -224,8 +224,8 @@ * == asio::execution::blocking.always) * ... @endcode */- static constexpr execution::blocking_t query(- execution::blocking_t) noexcept+ static ASIO_CONSTEXPR execution::blocking_t query(+ execution::blocking_t) ASIO_NOEXCEPT { return Blocking(); }@@ -241,8 +241,8 @@ * == asio::execution::relationship.continuation) * ... @endcode */- static constexpr execution::relationship_t query(- execution::relationship_t) noexcept+ static ASIO_CONSTEXPR execution::relationship_t query(+ execution::relationship_t) ASIO_NOEXCEPT { return Relationship(); }@@ -258,8 +258,8 @@ * asio::execution::allocator); @endcode */ template <typename OtherAllocator>- constexpr Allocator query(- execution::allocator_t<OtherAllocator>) const noexcept+ ASIO_CONSTEXPR Allocator query(+ execution::allocator_t<OtherAllocator>) const ASIO_NOEXCEPT { return allocator_; }@@ -274,8 +274,8 @@ * auto alloc = asio::query(ex, * asio::execution::allocator); @endcode */- constexpr Allocator query(- execution::allocator_t<void>) const noexcept+ ASIO_CONSTEXPR Allocator query(+ execution::allocator_t<void>) const ASIO_NOEXCEPT { return allocator_; }@@ -291,7 +291,7 @@ * std::size_t occupancy = asio::query( * ex, asio::execution::occupancy); @endcode */- std::size_t query(execution::occupancy_t) const noexcept;+ std::size_t query(execution::occupancy_t) const ASIO_NOEXCEPT; public: /// Compare two executors for equality.@@ -299,7 +299,7 @@ * Two executors are equal if they refer to the same underlying io_context. */ friend bool operator==(const basic_system_executor&,- const basic_system_executor&) noexcept+ const basic_system_executor&) ASIO_NOEXCEPT { return true; }@@ -309,28 +309,28 @@ * Two executors are equal if they refer to the same underlying io_context. */ friend bool operator!=(const basic_system_executor&,- const basic_system_executor&) noexcept+ const basic_system_executor&) ASIO_NOEXCEPT { return false; } /// Execution function. template <typename Function>- void execute(Function&& f) const+ void execute(ASIO_MOVE_ARG(Function) f) const {- this->do_execute(static_cast<Function&&>(f), Blocking());+ this->do_execute(ASIO_MOVE_CAST(Function)(f), Blocking()); } #if !defined(ASIO_NO_TS_EXECUTORS) public: /// Obtain the underlying execution context.- system_context& context() const noexcept;+ system_context& context() const ASIO_NOEXCEPT; /// Inform the executor that it has some outstanding work to do. /** * For the system executor, this is a no-op. */- void on_work_started() const noexcept+ void on_work_started() const ASIO_NOEXCEPT { } @@ -338,7 +338,7 @@ /** * For the system executor, this is a no-op. */- void on_work_finished() const noexcept+ void on_work_finished() const ASIO_NOEXCEPT { } @@ -355,7 +355,7 @@ * internal storage needed for function invocation. */ template <typename Function, typename OtherAllocator>- void dispatch(Function&& f, const OtherAllocator& a) const;+ void dispatch(ASIO_MOVE_ARG(Function) f, const OtherAllocator& a) const; /// Request the system executor to invoke the given function object. /**@@ -371,7 +371,7 @@ * internal storage needed for function invocation. */ template <typename Function, typename OtherAllocator>- void post(Function&& f, const OtherAllocator& a) const;+ void post(ASIO_MOVE_ARG(Function) f, const OtherAllocator& a) const; /// Request the system executor to invoke the given function object. /**@@ -387,7 +387,7 @@ * internal storage needed for function invocation. */ template <typename Function, typename OtherAllocator>- void defer(Function&& f, const OtherAllocator& a) const;+ void defer(ASIO_MOVE_ARG(Function) f, const OtherAllocator& a) const; #endif // !defined(ASIO_NO_TS_EXECUTORS) private:@@ -401,17 +401,17 @@ /// Execution helper implementation for the possibly blocking property. template <typename Function>- void do_execute(Function&& f,+ void do_execute(ASIO_MOVE_ARG(Function) f, execution::blocking_t::possibly_t) const; /// Execution helper implementation for the always blocking property. template <typename Function>- void do_execute(Function&& f,+ void do_execute(ASIO_MOVE_ARG(Function) f, execution::blocking_t::always_t) const; /// Execution helper implementation for the never blocking property. template <typename Function>- void do_execute(Function&& f,+ void do_execute(ASIO_MOVE_ARG(Function) f, execution::blocking_t::never_t) const; // The allocator used for execution functions.@@ -428,7 +428,7 @@ * immediately. */ typedef basic_system_executor<execution::blocking_t::possibly_t,- execution::relationship_t::fork_t, std::allocator<void>>+ execution::relationship_t::fork_t, std::allocator<void> > system_executor; #if !defined(GENERATING_DOCUMENTATION)@@ -442,8 +442,8 @@ asio::basic_system_executor<Blocking, Relationship, Allocator> > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); }; #endif // !defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)@@ -457,8 +457,8 @@ Function > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = false;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); typedef void result_type; }; @@ -472,8 +472,8 @@ asio::execution::blocking_t::possibly_t > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = false;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); typedef asio::basic_system_executor< asio::execution::blocking_t::possibly_t, Relationship, Allocator> result_type;@@ -485,8 +485,8 @@ asio::execution::blocking_t::always_t > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = false;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); typedef asio::basic_system_executor< asio::execution::blocking_t::always_t, Relationship, Allocator> result_type;@@ -498,8 +498,8 @@ asio::execution::blocking_t::never_t > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = false;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); typedef asio::basic_system_executor< asio::execution::blocking_t::never_t, Relationship, Allocator> result_type;@@ -511,8 +511,8 @@ asio::execution::relationship_t::fork_t > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = false;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); typedef asio::basic_system_executor<Blocking, asio::execution::relationship_t::fork_t, Allocator> result_type;@@ -524,8 +524,8 @@ asio::execution::relationship_t::continuation_t > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = false;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); typedef asio::basic_system_executor<Blocking, asio::execution::relationship_t::continuation_t, Allocator> result_type;@@ -537,10 +537,10 @@ asio::execution::allocator_t<void> > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = false;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); typedef asio::basic_system_executor<Blocking,- Relationship, std::allocator<void>> result_type;+ Relationship, std::allocator<void> > result_type; }; template <typename Blocking, typename Relationship,@@ -550,8 +550,8 @@ asio::execution::allocator_t<OtherAllocator> > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = false;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); typedef asio::basic_system_executor<Blocking, Relationship, OtherAllocator> result_type; };@@ -573,11 +573,11 @@ >::type > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef asio::execution::mapping_t::thread_t result_type; - static constexpr result_type value() noexcept+ static ASIO_CONSTEXPR result_type value() ASIO_NOEXCEPT { return result_type(); }@@ -600,8 +600,8 @@ >::type > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef asio::execution::blocking_t result_type; }; @@ -618,8 +618,8 @@ >::type > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef asio::execution::relationship_t result_type; }; @@ -629,8 +629,8 @@ asio::execution::context_t > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef asio::system_context& result_type; }; @@ -640,8 +640,8 @@ asio::execution::allocator_t<void> > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef Allocator result_type; }; @@ -651,8 +651,8 @@ asio::execution::allocator_t<Allocator> > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef Allocator result_type; };
link/modules/asio-standalone/asio/include/asio/system_timer.hpp view
@@ -2,7 +2,7 @@ // system_timer.hpp // ~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -16,6 +16,9 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"++#if defined(ASIO_HAS_CHRONO) || defined(GENERATING_DOCUMENTATION)+ #include "asio/basic_waitable_timer.hpp" #include "asio/detail/chrono.hpp" @@ -33,5 +36,7 @@ typedef basic_waitable_timer<chrono::system_clock> system_timer; } // namespace asio++#endif // defined(ASIO_HAS_CHRONO) || defined(GENERATING_DOCUMENTATION) #endif // ASIO_SYSTEM_TIMER_HPP
link/modules/asio-standalone/asio/include/asio/this_coro.hpp view
@@ -2,7 +2,7 @@ // this_coro.hpp // ~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -26,18 +26,22 @@ /// Awaitable type that returns the executor of the current coroutine. struct executor_t {- constexpr executor_t()+ ASIO_CONSTEXPR executor_t() { } }; /// Awaitable object that returns the executor of the current coroutine.-ASIO_INLINE_VARIABLE constexpr executor_t executor;+#if defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)+constexpr executor_t executor;+#elif defined(ASIO_MSVC)+__declspec(selectany) executor_t executor;+#endif /// Awaitable type that returns the cancellation state of the current coroutine. struct cancellation_state_t {- constexpr cancellation_state_t()+ ASIO_CONSTEXPR cancellation_state_t() { } };@@ -57,7 +61,11 @@ * // ... * } @endcode */-ASIO_INLINE_VARIABLE constexpr cancellation_state_t cancellation_state;+#if defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)+constexpr cancellation_state_t cancellation_state;+#elif defined(ASIO_MSVC)+__declspec(selectany) cancellation_state_t cancellation_state;+#endif #if defined(GENERATING_DOCUMENTATION) @@ -80,7 +88,7 @@ * @note The cancellation state is shared by all coroutines in the same "thread * of execution" that was created using asio::co_spawn. */-ASIO_NODISCARD constexpr unspecified+ASIO_NODISCARD ASIO_CONSTEXPR unspecified reset_cancellation_state(); /// Returns an awaitable object that may be used to reset the cancellation state@@ -105,8 +113,8 @@ * of execution" that was created using asio::co_spawn. */ template <typename Filter>-ASIO_NODISCARD constexpr unspecified-reset_cancellation_state(Filter&& filter);+ASIO_NODISCARD ASIO_CONSTEXPR unspecified+reset_cancellation_state(ASIO_MOVE_ARG(Filter) filter); /// Returns an awaitable object that may be used to reset the cancellation state /// of the current coroutine.@@ -132,10 +140,10 @@ * of execution" that was created using asio::co_spawn. */ template <typename InFilter, typename OutFilter>-ASIO_NODISCARD constexpr unspecified+ASIO_NODISCARD ASIO_CONSTEXPR unspecified reset_cancellation_state(- InFilter&& in_filter,- OutFilter&& out_filter);+ ASIO_MOVE_ARG(InFilter) in_filter,+ ASIO_MOVE_ARG(OutFilter) out_filter); /// Returns an awaitable object that may be used to determine whether the /// coroutine throws if trying to suspend when it has been cancelled.@@ -149,7 +157,7 @@ * // ... * } @endcode */-ASIO_NODISCARD constexpr unspecified+ASIO_NODISCARD ASIO_CONSTEXPR unspecified throw_if_cancelled(); /// Returns an awaitable object that may be used to specify whether the@@ -163,19 +171,19 @@ * // ... * } @endcode */-ASIO_NODISCARD constexpr unspecified+ASIO_NODISCARD ASIO_CONSTEXPR unspecified throw_if_cancelled(bool value); #else // defined(GENERATING_DOCUMENTATION) struct reset_cancellation_state_0_t {- constexpr reset_cancellation_state_0_t()+ ASIO_CONSTEXPR reset_cancellation_state_0_t() { } }; -ASIO_NODISCARD inline constexpr reset_cancellation_state_0_t+ASIO_NODISCARD inline ASIO_CONSTEXPR reset_cancellation_state_0_t reset_cancellation_state() { return reset_cancellation_state_0_t();@@ -185,9 +193,9 @@ struct reset_cancellation_state_1_t { template <typename F>- explicit constexpr reset_cancellation_state_1_t(- F&& filt)- : filter(static_cast<F&&>(filt))+ explicit ASIO_CONSTEXPR reset_cancellation_state_1_t(+ ASIO_MOVE_ARG(F) filt)+ : filter(ASIO_MOVE_CAST(F)(filt)) { } @@ -195,22 +203,22 @@ }; template <typename Filter>-ASIO_NODISCARD inline constexpr reset_cancellation_state_1_t<- decay_t<Filter>>-reset_cancellation_state(Filter&& filter)+ASIO_NODISCARD inline ASIO_CONSTEXPR reset_cancellation_state_1_t<+ typename decay<Filter>::type>+reset_cancellation_state(ASIO_MOVE_ARG(Filter) filter) {- return reset_cancellation_state_1_t<decay_t<Filter>>(- static_cast<Filter&&>(filter));+ return reset_cancellation_state_1_t<typename decay<Filter>::type>(+ ASIO_MOVE_CAST(Filter)(filter)); } template <typename InFilter, typename OutFilter> struct reset_cancellation_state_2_t { template <typename F1, typename F2>- constexpr reset_cancellation_state_2_t(- F1&& in_filt, F2&& out_filt)- : in_filter(static_cast<F1&&>(in_filt)),- out_filter(static_cast<F2&&>(out_filt))+ ASIO_CONSTEXPR reset_cancellation_state_2_t(+ ASIO_MOVE_ARG(F1) in_filt, ASIO_MOVE_ARG(F2) out_filt)+ : in_filter(ASIO_MOVE_CAST(F1)(in_filt)),+ out_filter(ASIO_MOVE_CAST(F2)(out_filt)) { } @@ -219,23 +227,28 @@ }; template <typename InFilter, typename OutFilter>-ASIO_NODISCARD inline constexpr-reset_cancellation_state_2_t<decay_t<InFilter>, decay_t<OutFilter>>-reset_cancellation_state(InFilter&& in_filter, OutFilter&& out_filter)+ASIO_NODISCARD inline ASIO_CONSTEXPR reset_cancellation_state_2_t<+ typename decay<InFilter>::type,+ typename decay<OutFilter>::type>+reset_cancellation_state(+ ASIO_MOVE_ARG(InFilter) in_filter,+ ASIO_MOVE_ARG(OutFilter) out_filter) {- return reset_cancellation_state_2_t<decay_t<InFilter>, decay_t<OutFilter>>(- static_cast<InFilter&&>(in_filter),- static_cast<OutFilter&&>(out_filter));+ return reset_cancellation_state_2_t<+ typename decay<InFilter>::type,+ typename decay<OutFilter>::type>(+ ASIO_MOVE_CAST(InFilter)(in_filter),+ ASIO_MOVE_CAST(OutFilter)(out_filter)); } struct throw_if_cancelled_0_t {- constexpr throw_if_cancelled_0_t()+ ASIO_CONSTEXPR throw_if_cancelled_0_t() { } }; -ASIO_NODISCARD inline constexpr throw_if_cancelled_0_t+ASIO_NODISCARD inline ASIO_CONSTEXPR throw_if_cancelled_0_t throw_if_cancelled() { return throw_if_cancelled_0_t();@@ -243,7 +256,7 @@ struct throw_if_cancelled_1_t {- explicit constexpr throw_if_cancelled_1_t(bool val)+ explicit ASIO_CONSTEXPR throw_if_cancelled_1_t(bool val) : value(val) { }@@ -251,7 +264,7 @@ bool value; }; -ASIO_NODISCARD inline constexpr throw_if_cancelled_1_t+ASIO_NODISCARD inline ASIO_CONSTEXPR throw_if_cancelled_1_t throw_if_cancelled(bool value) { return throw_if_cancelled_1_t(value);
link/modules/asio-standalone/asio/include/asio/thread.hpp view
@@ -2,7 +2,7 @@ // thread.hpp // ~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/thread_pool.hpp view
@@ -2,7 +2,7 @@ // thread_pool.hpp // ~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -28,11 +28,11 @@ namespace detail { struct thread_pool_bits {- static constexpr unsigned int blocking_never = 1;- static constexpr unsigned int blocking_always = 2;- static constexpr unsigned int blocking_mask = 3;- static constexpr unsigned int relationship_continuation = 4;- static constexpr unsigned int outstanding_work_tracked = 8;+ ASIO_STATIC_CONSTEXPR(unsigned int, blocking_never = 1);+ ASIO_STATIC_CONSTEXPR(unsigned int, blocking_always = 2);+ ASIO_STATIC_CONSTEXPR(unsigned int, blocking_mask = 3);+ ASIO_STATIC_CONSTEXPR(unsigned int, relationship_continuation = 4);+ ASIO_STATIC_CONSTEXPR(unsigned int, outstanding_work_tracked = 8); }; } // namespace detail @@ -41,17 +41,6 @@ * The thread pool class is an execution context where functions are permitted * to run on one of a fixed number of threads. *- * @par Thread Safety- * @e Distinct @e objects: Safe.@n- * @e Shared @e objects: Safe, with the specific exceptions of the join()- * wait() and notify_fork() functions. The join() and wait() functions must not- * be called at the same time as other calls to join() or wait() on the same- * pool. The notify_fork() function should not be called while any thread_pool- * function, or any function on an I/O object that is associated with the- * thread_pool, is being called in another thread. (In effect, this means that- * notify_fork() is safe only on a thread pool that has no internal or attached- * threads at the time.)- * * @par Submitting tasks to the pool * * To submit functions to the thread pool, use the @ref asio::dispatch,@@ -95,67 +84,16 @@ /// Executor used to submit functions to a thread pool. typedef basic_executor_type<std::allocator<void>, 0> executor_type; + /// Scheduler used to schedule receivers on a thread pool.+ typedef basic_executor_type<std::allocator<void>, 0> scheduler_type;+ #if !defined(ASIO_NO_TS_EXECUTORS) /// Constructs a pool with an automatically determined number of threads. ASIO_DECL thread_pool();-- /// Constructs a pool with an automatically determined number of threads.- /**- * @param a An allocator that will be used for allocating objects that are- * associated with the execution context, such as services and internal state- * for I/O objects.- */- template <typename Allocator>- thread_pool(allocator_arg_t, const Allocator& a); #endif // !defined(ASIO_NO_TS_EXECUTORS) /// Constructs a pool with a specified number of threads.- /**- * @param num_threads The number of threads required.- */- ASIO_DECL explicit thread_pool(std::size_t num_threads);-- /// Constructs a pool with a specified number of threads.- /**- * @param num_threads The number of threads required.- *- * @param a An allocator that will be used for allocating objects that are- * associated with the execution context, such as services and internal state- * for I/O objects.- */- template <typename Allocator>- thread_pool(allocator_arg_t, const Allocator& a, std::size_t num_threads);-- /// Constructs a pool with a specified number of threads.- /**- * Construct with a service maker, to create an initial set of services that- * will be installed into the execution context at construction time.- *- * @param num_threads The number of threads required.- *- * @param initial_services Used to create the initial services. The @c make- * function will be called once at the end of execution_context construction.- */- ASIO_DECL thread_pool(std::size_t num_threads,- const execution_context::service_maker& initial_services);-- /// Constructs a pool with a specified number of threads.- /**- * Construct with a service maker, to create an initial set of services that- * will be installed into the execution context at construction time.- *- * @param a An allocator that will be used for allocating objects that are- * associated with the execution context, such as services and internal state- * for I/O objects.- *- * @param num_threads The number of threads required.- *- * @param initial_services Used to create the initial services. The @c make- * function will be called once at the end of execution_context construction.- */- template <typename Allocator>- thread_pool(allocator_arg_t, const Allocator& a, std::size_t num_threads,- const execution_context::service_maker& initial_services);+ ASIO_DECL thread_pool(std::size_t num_threads); /// Destructor. /**@@ -164,11 +102,14 @@ ASIO_DECL ~thread_pool(); /// Obtains the executor associated with the pool.- executor_type get_executor() noexcept;+ executor_type get_executor() ASIO_NOEXCEPT; /// Obtains the executor associated with the pool.- executor_type executor() noexcept;+ executor_type executor() ASIO_NOEXCEPT; + /// Obtains the scheduler associated with the pool.+ scheduler_type scheduler() ASIO_NOEXCEPT;+ /// Stops the threads. /** * This function stops the threads as soon as possible. As a result of calling@@ -197,39 +138,26 @@ * This function blocks until the threads in the pool have completed. If @c * stop() is not called prior to @c wait(), the @c wait() call will wait * until the pool has no more outstanding work.- *- * @note @c wait() is synonymous with @c join(). */ ASIO_DECL void wait(); private:- thread_pool(const thread_pool&) = delete;- thread_pool& operator=(const thread_pool&) = delete;+ thread_pool(const thread_pool&) ASIO_DELETED;+ thread_pool& operator=(const thread_pool&) ASIO_DELETED; struct thread_function; -#if !defined(ASIO_NO_TS_EXECUTORS)- // Helper function to calculate the default number of threads in the pool.- ASIO_DECL static long default_thread_pool_size();-#endif // !defined(ASIO_NO_TS_EXECUTORS)-- // Helper function to ensure the thread pool size is not out of range.- ASIO_DECL static long clamp_thread_pool_size(std::size_t n);-- // Helper function to start all threads in the pool.- ASIO_DECL void start();+ // Helper function to create the underlying scheduler.+ ASIO_DECL detail::scheduler& add_scheduler(detail::scheduler* s); // The underlying scheduler. detail::scheduler& scheduler_; // The threads in the pool.- detail::thread_group<allocator<void>> threads_;+ detail::thread_group threads_; // The current number of threads in the pool. detail::atomic_count num_threads_;-- // Whether a join call will have any effect.- bool joinable_; }; /// Executor implementation type used to submit functions to a thread pool.@@ -237,8 +165,34 @@ class thread_pool::basic_executor_type : detail::thread_pool_bits { public:+#if !defined(ASIO_NO_DEPRECATED)+ /// (Deprecated.) The sender type, when this type is used as a scheduler.+ typedef basic_executor_type sender_type;+#endif // !defined(ASIO_NO_DEPRECATED)++ /// The bulk execution shape type.+ typedef std::size_t shape_type;++ /// The bulk execution index type.+ typedef std::size_t index_type;++#if defined(ASIO_HAS_DEDUCED_EXECUTION_IS_TYPED_SENDER_TRAIT) \+ && defined(ASIO_HAS_STD_EXCEPTION_PTR)+ template <+ template <typename...> class Tuple,+ template <typename...> class Variant>+ using value_types = Variant<Tuple<>>;++ template <template <typename...> class Variant>+ using error_types = Variant<std::exception_ptr>;++ ASIO_STATIC_CONSTEXPR(bool, sends_done = true);+#endif // defined(ASIO_HAS_DEDUCED_EXECUTION_IS_TYPED_SENDER_TRAIT)+ // && defined(ASIO_HAS_STD_EXCEPTION_PTR)+ /// Copy constructor.- basic_executor_type(const basic_executor_type& other) noexcept+ basic_executor_type(+ const basic_executor_type& other) ASIO_NOEXCEPT : pool_(other.pool_), allocator_(other.allocator_), bits_(other.bits_)@@ -248,18 +202,20 @@ pool_->scheduler_.work_started(); } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move constructor.- basic_executor_type(basic_executor_type&& other) noexcept+ basic_executor_type(basic_executor_type&& other) ASIO_NOEXCEPT : pool_(other.pool_),- allocator_(static_cast<Allocator&&>(other.allocator_)),+ allocator_(ASIO_MOVE_CAST(Allocator)(other.allocator_)), bits_(other.bits_) { if (Bits & outstanding_work_tracked) other.pool_ = 0; }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Destructor.- ~basic_executor_type() noexcept+ ~basic_executor_type() ASIO_NOEXCEPT { if (Bits & outstanding_work_tracked) if (pool_)@@ -267,10 +223,14 @@ } /// Assignment operator.- basic_executor_type& operator=(const basic_executor_type& other) noexcept;+ basic_executor_type& operator=(+ const basic_executor_type& other) ASIO_NOEXCEPT; +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move assignment operator.- basic_executor_type& operator=(basic_executor_type&& other) noexcept;+ basic_executor_type& operator=(+ basic_executor_type&& other) ASIO_NOEXCEPT;+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) #if !defined(GENERATING_DOCUMENTATION) private:@@ -288,7 +248,7 @@ * auto ex2 = asio::require(ex1, * asio::execution::blocking.possibly); @endcode */- constexpr basic_executor_type<Allocator,+ ASIO_CONSTEXPR basic_executor_type<Allocator, ASIO_UNSPECIFIED(Bits & ~blocking_mask)> require(execution::blocking_t::possibly_t) const {@@ -306,7 +266,7 @@ * auto ex2 = asio::require(ex1, * asio::execution::blocking.always); @endcode */- constexpr basic_executor_type<Allocator,+ ASIO_CONSTEXPR basic_executor_type<Allocator, ASIO_UNSPECIFIED((Bits & ~blocking_mask) | blocking_always)> require(execution::blocking_t::always_t) const {@@ -325,7 +285,7 @@ * auto ex2 = asio::require(ex1, * asio::execution::blocking.never); @endcode */- constexpr basic_executor_type<Allocator,+ ASIO_CONSTEXPR basic_executor_type<Allocator, ASIO_UNSPECIFIED(Bits & ~blocking_mask)> require(execution::blocking_t::never_t) const {@@ -343,7 +303,8 @@ * auto ex2 = asio::require(ex1, * asio::execution::relationship.fork); @endcode */- constexpr basic_executor_type require(execution::relationship_t::fork_t) const+ ASIO_CONSTEXPR basic_executor_type require(+ execution::relationship_t::fork_t) const { return basic_executor_type(pool_, allocator_, bits_ & ~relationship_continuation);@@ -359,7 +320,7 @@ * auto ex2 = asio::require(ex1, * asio::execution::relationship.continuation); @endcode */- constexpr basic_executor_type require(+ ASIO_CONSTEXPR basic_executor_type require( execution::relationship_t::continuation_t) const { return basic_executor_type(pool_,@@ -376,7 +337,7 @@ * auto ex2 = asio::require(ex1, * asio::execution::outstanding_work.tracked); @endcode */- constexpr basic_executor_type<Allocator,+ ASIO_CONSTEXPR basic_executor_type<Allocator, ASIO_UNSPECIFIED(Bits | outstanding_work_tracked)> require(execution::outstanding_work_t::tracked_t) const {@@ -394,7 +355,7 @@ * auto ex2 = asio::require(ex1, * asio::execution::outstanding_work.untracked); @endcode */- constexpr basic_executor_type<Allocator,+ ASIO_CONSTEXPR basic_executor_type<Allocator, ASIO_UNSPECIFIED(Bits & ~outstanding_work_tracked)> require(execution::outstanding_work_t::untracked_t) const {@@ -413,7 +374,7 @@ * asio::execution::allocator(my_allocator)); @endcode */ template <typename OtherAllocator>- constexpr basic_executor_type<OtherAllocator, Bits>+ ASIO_CONSTEXPR basic_executor_type<OtherAllocator, Bits> require(execution::allocator_t<OtherAllocator> a) const { return basic_executor_type<OtherAllocator, Bits>(@@ -430,7 +391,7 @@ * auto ex2 = asio::require(ex1, * asio::execution::allocator); @endcode */- constexpr basic_executor_type<std::allocator<void>, Bits>+ ASIO_CONSTEXPR basic_executor_type<std::allocator<void>, Bits> require(execution::allocator_t<void>) const { return basic_executor_type<std::allocator<void>, Bits>(@@ -444,6 +405,25 @@ friend struct asio::execution::detail::outstanding_work_t<0>; #endif // !defined(GENERATING_DOCUMENTATION) +#if !defined(ASIO_NO_DEPRECATED)+ /// (Deprecated.) Query the current value of the @c bulk_guarantee property.+ /**+ * Do not call this function directly. It is intended for use with the+ * asio::query customisation point.+ *+ * For example:+ * @code auto ex = my_thread_pool.executor();+ * if (asio::query(ex, asio::execution::bulk_guarantee)+ * == asio::execution::bulk_guarantee.parallel)+ * ... @endcode+ */+ static ASIO_CONSTEXPR execution::bulk_guarantee_t query(+ execution::bulk_guarantee_t) ASIO_NOEXCEPT+ {+ return execution::bulk_guarantee.parallel;+ }+#endif // !defined(ASIO_NO_DEPRECATED)+ /// Query the current value of the @c mapping property. /** * Do not call this function directly. It is intended for use with the@@ -455,7 +435,8 @@ * == asio::execution::mapping.thread) * ... @endcode */- static constexpr execution::mapping_t query(execution::mapping_t) noexcept+ static ASIO_CONSTEXPR execution::mapping_t query(+ execution::mapping_t) ASIO_NOEXCEPT { return execution::mapping.thread; }@@ -470,7 +451,7 @@ * asio::thread_pool& pool = asio::query( * ex, asio::execution::context); @endcode */- thread_pool& query(execution::context_t) const noexcept+ thread_pool& query(execution::context_t) const ASIO_NOEXCEPT { return *pool_; }@@ -486,7 +467,8 @@ * == asio::execution::blocking.always) * ... @endcode */- constexpr execution::blocking_t query(execution::blocking_t) const noexcept+ ASIO_CONSTEXPR execution::blocking_t query(+ execution::blocking_t) const ASIO_NOEXCEPT { return (bits_ & blocking_never) ? execution::blocking_t(execution::blocking.never)@@ -506,8 +488,8 @@ * == asio::execution::relationship.continuation) * ... @endcode */- constexpr execution::relationship_t query(- execution::relationship_t) const noexcept+ ASIO_CONSTEXPR execution::relationship_t query(+ execution::relationship_t) const ASIO_NOEXCEPT { return (bits_ & relationship_continuation) ? execution::relationship_t(execution::relationship.continuation)@@ -525,8 +507,8 @@ * == asio::execution::outstanding_work.tracked) * ... @endcode */- static constexpr execution::outstanding_work_t query(- execution::outstanding_work_t) noexcept+ static ASIO_CONSTEXPR execution::outstanding_work_t query(+ execution::outstanding_work_t) ASIO_NOEXCEPT { return (Bits & outstanding_work_tracked) ? execution::outstanding_work_t(execution::outstanding_work.tracked)@@ -544,8 +526,8 @@ * asio::execution::allocator); @endcode */ template <typename OtherAllocator>- constexpr Allocator query(- execution::allocator_t<OtherAllocator>) const noexcept+ ASIO_CONSTEXPR Allocator query(+ execution::allocator_t<OtherAllocator>) const ASIO_NOEXCEPT { return allocator_; }@@ -560,7 +542,8 @@ * auto alloc = asio::query(ex, * asio::execution::allocator); @endcode */- constexpr Allocator query(execution::allocator_t<void>) const noexcept+ ASIO_CONSTEXPR Allocator query(+ execution::allocator_t<void>) const ASIO_NOEXCEPT { return allocator_; }@@ -575,7 +558,7 @@ * std::size_t occupancy = asio::query( * ex, asio::execution::occupancy); @endcode */- std::size_t query(execution::occupancy_t) const noexcept+ std::size_t query(execution::occupancy_t) const ASIO_NOEXCEPT { return static_cast<std::size_t>(pool_->num_threads_); }@@ -586,14 +569,14 @@ * @return @c true if the current thread is running the thread pool. Otherwise * returns @c false. */- bool running_in_this_thread() const noexcept;+ bool running_in_this_thread() const ASIO_NOEXCEPT; /// Compare two executors for equality. /** * Two executors are equal if they refer to the same underlying thread pool. */ friend bool operator==(const basic_executor_type& a,- const basic_executor_type& b) noexcept+ const basic_executor_type& b) ASIO_NOEXCEPT { return a.pool_ == b.pool_ && a.allocator_ == b.allocator_@@ -605,7 +588,7 @@ * Two executors are equal if they refer to the same underlying thread pool. */ friend bool operator!=(const basic_executor_type& a,- const basic_executor_type& b) noexcept+ const basic_executor_type& b) ASIO_NOEXCEPT { return a.pool_ != b.pool_ || a.allocator_ != b.allocator_@@ -614,16 +597,58 @@ /// Execution function. template <typename Function>- void execute(Function&& f) const+ void execute(ASIO_MOVE_ARG(Function) f) const {- this->do_execute(static_cast<Function&&>(f),+ this->do_execute(ASIO_MOVE_CAST(Function)(f), integral_constant<bool, (Bits & blocking_always) != 0>()); } public:+#if !defined(ASIO_NO_DEPRECATED)+ /// (Deprecated.) Bulk execution function.+ template <typename Function>+ void bulk_execute(ASIO_MOVE_ARG(Function) f, std::size_t n) const+ {+ this->do_bulk_execute(ASIO_MOVE_CAST(Function)(f), n,+ integral_constant<bool, (Bits & blocking_always) != 0>());+ }++ /// (Deprecated.) Schedule function.+ /**+ * Do not call this function directly. It is intended for use with the+ * execution::schedule customisation point.+ *+ * @return An object that satisfies the sender concept.+ */+ sender_type schedule() const ASIO_NOEXCEPT+ {+ return *this;+ }++ /// (Deprecated.) Connect function.+ /**+ * Do not call this function directly. It is intended for use with the+ * execution::connect customisation point.+ *+ * @return An object of an unspecified type that satisfies the @c+ * operation_state concept.+ */+ template <ASIO_EXECUTION_RECEIVER_OF_0 Receiver>+#if defined(GENERATING_DOCUMENTATION)+ unspecified+#else // defined(GENERATING_DOCUMENTATION)+ execution::detail::as_operation<basic_executor_type, Receiver>+#endif // defined(GENERATING_DOCUMENTATION)+ connect(ASIO_MOVE_ARG(Receiver) r) const+ {+ return execution::detail::as_operation<basic_executor_type, Receiver>(+ *this, ASIO_MOVE_CAST(Receiver)(r));+ }+#endif // !defined(ASIO_NO_DEPRECATED)+ #if !defined(ASIO_NO_TS_EXECUTORS) /// Obtain the underlying execution context.- thread_pool& context() const noexcept;+ thread_pool& context() const ASIO_NOEXCEPT; /// Inform the thread pool that it has some outstanding work to do. /**@@ -631,7 +656,7 @@ * This ensures that the thread pool's join() function will not return while * the work is underway. */- void on_work_started() const noexcept;+ void on_work_started() const ASIO_NOEXCEPT; /// Inform the thread pool that some work is no longer outstanding. /**@@ -639,7 +664,7 @@ * finished. Once the count of unfinished work reaches zero, the thread * pool's join() function is permitted to exit. */- void on_work_finished() const noexcept;+ void on_work_finished() const ASIO_NOEXCEPT; /// Request the thread pool to invoke the given function object. /**@@ -656,7 +681,8 @@ * internal storage needed for function invocation. */ template <typename Function, typename OtherAllocator>- void dispatch(Function&& f, const OtherAllocator& a) const;+ void dispatch(ASIO_MOVE_ARG(Function) f,+ const OtherAllocator& a) const; /// Request the thread pool to invoke the given function object. /**@@ -672,7 +698,8 @@ * internal storage needed for function invocation. */ template <typename Function, typename OtherAllocator>- void post(Function&& f, const OtherAllocator& a) const;+ void post(ASIO_MOVE_ARG(Function) f,+ const OtherAllocator& a) const; /// Request the thread pool to invoke the given function object. /**@@ -692,7 +719,8 @@ * internal storage needed for function invocation. */ template <typename Function, typename OtherAllocator>- void defer(Function&& f, const OtherAllocator& a) const;+ void defer(ASIO_MOVE_ARG(Function) f,+ const OtherAllocator& a) const; #endif // !defined(ASIO_NO_TS_EXECUTORS) private:@@ -700,7 +728,7 @@ template <typename, unsigned int> friend class basic_executor_type; // Constructor used by thread_pool::get_executor().- explicit basic_executor_type(thread_pool& p) noexcept+ explicit basic_executor_type(thread_pool& p) ASIO_NOEXCEPT : pool_(&p), allocator_(), bits_(0)@@ -711,7 +739,7 @@ // Constructor used by require(). basic_executor_type(thread_pool* p,- const Allocator& a, unsigned int bits) noexcept+ const Allocator& a, unsigned int bits) ASIO_NOEXCEPT : pool_(p), allocator_(a), bits_(bits)@@ -723,12 +751,22 @@ /// Execution helper implementation for possibly and never blocking. template <typename Function>- void do_execute(Function&& f, false_type) const;+ void do_execute(ASIO_MOVE_ARG(Function) f, false_type) const; /// Execution helper implementation for always blocking. template <typename Function>- void do_execute(Function&& f, true_type) const;+ void do_execute(ASIO_MOVE_ARG(Function) f, true_type) const; + /// Bulk execution helper implementation for possibly and never blocking.+ template <typename Function>+ void do_bulk_execute(ASIO_MOVE_ARG(Function) f,+ std::size_t n, false_type) const;++ /// Bulk execution helper implementation for always blocking.+ template <typename Function>+ void do_bulk_execute(ASIO_MOVE_ARG(Function) f,+ std::size_t n, true_type) const;+ // The underlying thread pool. thread_pool* pool_; @@ -750,8 +788,8 @@ asio::thread_pool::basic_executor_type<Allocator, Bits> > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); }; #endif // !defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)@@ -764,13 +802,53 @@ Function > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = false;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); typedef void result_type; }; #endif // !defined(ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT) +#if !defined(ASIO_HAS_DEDUCED_SCHEDULE_MEMBER_TRAIT)++#if !defined(ASIO_NO_DEPRECATED)++template <typename Allocator, unsigned int Bits>+struct schedule_member<+ const asio::thread_pool::basic_executor_type<Allocator, Bits>+ >+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ typedef asio::thread_pool::basic_executor_type<+ Allocator, Bits> result_type;+};++#endif // !defined(ASIO_NO_DEPRECATED)++#endif // !defined(ASIO_HAS_DEDUCED_SCHEDULE_MEMBER_TRAIT)++#if !defined(ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT)++#if !defined(ASIO_NO_DEPRECATED)++template <typename Allocator, unsigned int Bits, typename Receiver>+struct connect_member<+ const asio::thread_pool::basic_executor_type<Allocator, Bits>,+ Receiver+ >+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ typedef asio::execution::detail::as_operation<+ asio::thread_pool::basic_executor_type<Allocator, Bits>,+ Receiver> result_type;+};++#endif // !defined(ASIO_NO_DEPRECATED)++#endif // !defined(ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT)+ #if !defined(ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT) template <typename Allocator, unsigned int Bits>@@ -779,8 +857,8 @@ asio::execution::blocking_t::possibly_t > : asio::detail::thread_pool_bits {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef asio::thread_pool::basic_executor_type< Allocator, Bits & ~blocking_mask> result_type; };@@ -791,8 +869,8 @@ asio::execution::blocking_t::always_t > : asio::detail::thread_pool_bits {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = false;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); typedef asio::thread_pool::basic_executor_type<Allocator, (Bits & ~blocking_mask) | blocking_always> result_type; };@@ -803,8 +881,8 @@ asio::execution::blocking_t::never_t > : asio::detail::thread_pool_bits {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = false;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); typedef asio::thread_pool::basic_executor_type< Allocator, Bits & ~blocking_mask> result_type; };@@ -815,8 +893,8 @@ asio::execution::relationship_t::fork_t > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = false;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); typedef asio::thread_pool::basic_executor_type< Allocator, Bits> result_type; };@@ -827,8 +905,8 @@ asio::execution::relationship_t::continuation_t > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = false;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); typedef asio::thread_pool::basic_executor_type< Allocator, Bits> result_type; };@@ -839,8 +917,8 @@ asio::execution::outstanding_work_t::tracked_t > : asio::detail::thread_pool_bits {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = false;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); typedef asio::thread_pool::basic_executor_type< Allocator, Bits | outstanding_work_tracked> result_type; };@@ -851,8 +929,8 @@ asio::execution::outstanding_work_t::untracked_t > : asio::detail::thread_pool_bits {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = false;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); typedef asio::thread_pool::basic_executor_type< Allocator, Bits & ~outstanding_work_tracked> result_type; };@@ -863,8 +941,8 @@ asio::execution::allocator_t<void> > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = false;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); typedef asio::thread_pool::basic_executor_type< std::allocator<void>, Bits> result_type; };@@ -876,8 +954,8 @@ asio::execution::allocator_t<OtherAllocator> > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = false;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); typedef asio::thread_pool::basic_executor_type< OtherAllocator, Bits> result_type; };@@ -886,6 +964,8 @@ #if !defined(ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT) +#if !defined(ASIO_NO_DEPRECATED)+ template <typename Allocator, unsigned int Bits, typename Property> struct query_static_constexpr_member< asio::thread_pool::basic_executor_type<Allocator, Bits>,@@ -893,16 +973,40 @@ typename asio::enable_if< asio::is_convertible< Property,+ asio::execution::bulk_guarantee_t+ >::value+ >::type+ >+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ typedef asio::execution::bulk_guarantee_t::parallel_t result_type;++ static ASIO_CONSTEXPR result_type value() ASIO_NOEXCEPT+ {+ return result_type();+ }+};++#endif // !defined(ASIO_NO_DEPRECATED)++template <typename Allocator, unsigned int Bits, typename Property>+struct query_static_constexpr_member<+ asio::thread_pool::basic_executor_type<Allocator, Bits>,+ Property,+ typename asio::enable_if<+ asio::is_convertible<+ Property, asio::execution::outstanding_work_t >::value >::type > : asio::detail::thread_pool_bits {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef asio::execution::outstanding_work_t result_type; - static constexpr result_type value() noexcept+ static ASIO_CONSTEXPR result_type value() ASIO_NOEXCEPT { return (Bits & outstanding_work_tracked) ? execution::outstanding_work_t(execution::outstanding_work.tracked)@@ -922,11 +1026,11 @@ >::type > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef asio::execution::mapping_t::thread_t result_type; - static constexpr result_type value() noexcept+ static ASIO_CONSTEXPR result_type value() ASIO_NOEXCEPT { return result_type(); }@@ -948,8 +1052,8 @@ >::type > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef asio::execution::blocking_t result_type; }; @@ -965,8 +1069,8 @@ >::type > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef asio::execution::relationship_t result_type; }; @@ -976,8 +1080,8 @@ asio::execution::occupancy_t > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef std::size_t result_type; }; @@ -987,8 +1091,8 @@ asio::execution::context_t > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef asio::thread_pool& result_type; }; @@ -998,8 +1102,8 @@ asio::execution::allocator_t<void> > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef Allocator result_type; }; @@ -1009,8 +1113,8 @@ asio::execution::allocator_t<OtherAllocator> > {- static constexpr bool is_valid = true;- static constexpr bool is_noexcept = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); typedef Allocator result_type; };
link/modules/asio-standalone/asio/include/asio/time_traits.hpp view
@@ -2,7 +2,7 @@ // time_traits.hpp // ~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -17,8 +17,6 @@ #include "asio/detail/socket_types.hpp" // Must come before posix_time. -#if !defined(ASIO_NO_DEPRECATED)- #if defined(ASIO_HAS_BOOST_DATE_TIME) \ || defined(GENERATING_DOCUMENTATION) @@ -28,11 +26,11 @@ namespace asio { -/// (Deprecated) Time traits suitable for use with the deadline timer.+/// Time traits suitable for use with the deadline timer. template <typename Time> struct time_traits; -/// (Deprecated) Time traits specialised for posix_time.+/// Time traits specialised for posix_time. template <> struct time_traits<boost::posix_time::ptime> {@@ -84,7 +82,5 @@ #endif // defined(ASIO_HAS_BOOST_DATE_TIME) // || defined(GENERATING_DOCUMENTATION)--#endif // !defined(ASIO_NO_DEPRECATED) #endif // ASIO_TIME_TRAITS_HPP
+ link/modules/asio-standalone/asio/include/asio/traits/bulk_execute_free.hpp view
@@ -0,0 +1,114 @@+//+// traits/bulk_execute_free.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_TRAITS_BULK_EXECUTE_FREE_HPP+#define ASIO_TRAITS_BULK_EXECUTE_FREE_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/detail/type_traits.hpp"++#if defined(ASIO_HAS_DECLTYPE) \+ && defined(ASIO_HAS_NOEXCEPT) \+ && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+# define ASIO_HAS_DEDUCED_BULK_EXECUTE_FREE_TRAIT 1+#endif // defined(ASIO_HAS_DECLTYPE)+ // && defined(ASIO_HAS_NOEXCEPT)+ // && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)++#include "asio/detail/push_options.hpp"++namespace asio {+namespace traits {++template <typename T, typename F, typename N, typename = void>+struct bulk_execute_free_default;++template <typename T, typename F, typename N, typename = void>+struct bulk_execute_free;++} // namespace traits+namespace detail {++struct no_bulk_execute_free+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+};++#if defined(ASIO_HAS_DEDUCED_BULK_EXECUTE_FREE_TRAIT)++template <typename T, typename F, typename N, typename = void>+struct bulk_execute_free_trait : no_bulk_execute_free+{+};++template <typename T, typename F, typename N>+struct bulk_execute_free_trait<T, F, N,+ typename void_type<+ decltype(bulk_execute(declval<T>(), declval<F>(), declval<N>()))+ >::type>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);++ using result_type = decltype(+ bulk_execute(declval<T>(), declval<F>(), declval<N>()));++ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = noexcept(+ bulk_execute(declval<T>(), declval<F>(), declval<N>())));+};++#else // defined(ASIO_HAS_DEDUCED_BULK_EXECUTE_FREE_TRAIT)++template <typename T, typename F, typename N, typename = void>+struct bulk_execute_free_trait :+ conditional<+ is_same<T, typename remove_reference<T>::type>::value+ && is_same<F, typename decay<F>::type>::value+ && is_same<N, typename decay<N>::type>::value,+ typename conditional<+ is_same<T, typename add_const<T>::type>::value,+ no_bulk_execute_free,+ traits::bulk_execute_free<typename add_const<T>::type, F, N>+ >::type,+ traits::bulk_execute_free<+ typename remove_reference<T>::type,+ typename decay<F>::type,+ typename decay<N>::type>+ >::type+{+};++#endif // defined(ASIO_HAS_DEDUCED_BULK_EXECUTE_FREE_TRAIT)++} // namespace detail+namespace traits {++template <typename T, typename F, typename N, typename>+struct bulk_execute_free_default :+ detail::bulk_execute_free_trait<T, F, N>+{+};++template <typename T, typename F, typename N, typename>+struct bulk_execute_free :+ bulk_execute_free_default<T, F, N>+{+};++} // namespace traits+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_TRAITS_BULK_EXECUTE_FREE_HPP
+ link/modules/asio-standalone/asio/include/asio/traits/bulk_execute_member.hpp view
@@ -0,0 +1,114 @@+//+// traits/bulk_execute_member.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_TRAITS_BULK_EXECUTE_MEMBER_HPP+#define ASIO_TRAITS_BULK_EXECUTE_MEMBER_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/detail/type_traits.hpp"++#if defined(ASIO_HAS_DECLTYPE) \+ && defined(ASIO_HAS_NOEXCEPT) \+ && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+# define ASIO_HAS_DEDUCED_BULK_EXECUTE_MEMBER_TRAIT 1+#endif // defined(ASIO_HAS_DECLTYPE)+ // && defined(ASIO_HAS_NOEXCEPT)+ // && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)++#include "asio/detail/push_options.hpp"++namespace asio {+namespace traits {++template <typename T, typename F, typename N, typename = void>+struct bulk_execute_member_default;++template <typename T, typename F, typename N, typename = void>+struct bulk_execute_member;++} // namespace traits+namespace detail {++struct no_bulk_execute_member+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+};++#if defined(ASIO_HAS_DEDUCED_BULK_EXECUTE_MEMBER_TRAIT)++template <typename T, typename F, typename N, typename = void>+struct bulk_execute_member_trait : no_bulk_execute_member+{+};++template <typename T, typename F, typename N>+struct bulk_execute_member_trait<T, F, N,+ typename void_type<+ decltype(declval<T>().bulk_execute(declval<F>(), declval<N>()))+ >::type>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);++ using result_type = decltype(+ declval<T>().bulk_execute(declval<F>(), declval<N>()));++ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = noexcept(+ declval<T>().bulk_execute(declval<F>(), declval<N>())));+};++#else // defined(ASIO_HAS_DEDUCED_BULK_EXECUTE_MEMBER_TRAIT)++template <typename T, typename F, typename N, typename = void>+struct bulk_execute_member_trait :+ conditional<+ is_same<T, typename remove_reference<T>::type>::value+ && is_same<F, typename decay<F>::type>::value+ && is_same<N, typename decay<N>::type>::value,+ typename conditional<+ is_same<T, typename add_const<T>::type>::value,+ no_bulk_execute_member,+ traits::bulk_execute_member<typename add_const<T>::type, F, N>+ >::type,+ traits::bulk_execute_member<+ typename remove_reference<T>::type,+ typename decay<F>::type,+ typename decay<N>::type>+ >::type+{+};++#endif // defined(ASIO_HAS_DEDUCED_BULK_EXECUTE_MEMBER_TRAIT)++} // namespace detail+namespace traits {++template <typename T, typename F, typename N, typename>+struct bulk_execute_member_default :+ detail::bulk_execute_member_trait<T, F, N>+{+};++template <typename T, typename F, typename N, typename>+struct bulk_execute_member :+ bulk_execute_member_default<T, F, N>+{+};++} // namespace traits+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_TRAITS_BULK_EXECUTE_MEMBER_HPP
+ link/modules/asio-standalone/asio/include/asio/traits/connect_free.hpp view
@@ -0,0 +1,112 @@+//+// traits/connect_free.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_TRAITS_CONNECT_FREE_HPP+#define ASIO_TRAITS_CONNECT_FREE_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/detail/type_traits.hpp"++#if defined(ASIO_HAS_DECLTYPE) \+ && defined(ASIO_HAS_NOEXCEPT) \+ && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+# define ASIO_HAS_DEDUCED_CONNECT_FREE_TRAIT 1+#endif // defined(ASIO_HAS_DECLTYPE)+ // && defined(ASIO_HAS_NOEXCEPT)+ // && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)++#include "asio/detail/push_options.hpp"++namespace asio {+namespace traits {++template <typename S, typename R, typename = void>+struct connect_free_default;++template <typename S, typename R, typename = void>+struct connect_free;++} // namespace traits+namespace detail {++struct no_connect_free+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+};++#if defined(ASIO_HAS_DEDUCED_CONNECT_FREE_TRAIT)++template <typename S, typename R, typename = void>+struct connect_free_trait : no_connect_free+{+};++template <typename S, typename R>+struct connect_free_trait<S, R,+ typename void_type<+ decltype(connect(declval<S>(), declval<R>()))+ >::type>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);++ using result_type = decltype(+ connect(declval<S>(), declval<R>()));++ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = noexcept(+ connect(declval<S>(), declval<R>())));+};++#else // defined(ASIO_HAS_DEDUCED_CONNECT_FREE_TRAIT)++template <typename S, typename R, typename = void>+struct connect_free_trait :+ conditional<+ is_same<S, typename remove_reference<S>::type>::value+ && is_same<R, typename decay<R>::type>::value,+ typename conditional<+ is_same<S, typename add_const<S>::type>::value,+ no_connect_free,+ traits::connect_free<typename add_const<S>::type, R>+ >::type,+ traits::connect_free<+ typename remove_reference<S>::type,+ typename decay<R>::type>+ >::type+{+};++#endif // defined(ASIO_HAS_DEDUCED_CONNECT_FREE_TRAIT)++} // namespace detail+namespace traits {++template <typename S, typename R, typename>+struct connect_free_default :+ detail::connect_free_trait<S, R>+{+};++template <typename S, typename R, typename>+struct connect_free :+ connect_free_default<S, R>+{+};++} // namespace traits+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_TRAITS_CONNECT_FREE_HPP
+ link/modules/asio-standalone/asio/include/asio/traits/connect_member.hpp view
@@ -0,0 +1,112 @@+//+// traits/connect_member.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_TRAITS_CONNECT_MEMBER_HPP+#define ASIO_TRAITS_CONNECT_MEMBER_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/detail/type_traits.hpp"++#if defined(ASIO_HAS_DECLTYPE) \+ && defined(ASIO_HAS_NOEXCEPT) \+ && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+# define ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT 1+#endif // defined(ASIO_HAS_DECLTYPE)+ // && defined(ASIO_HAS_NOEXCEPT)+ // && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)++#include "asio/detail/push_options.hpp"++namespace asio {+namespace traits {++template <typename S, typename R, typename = void>+struct connect_member_default;++template <typename S, typename R, typename = void>+struct connect_member;++} // namespace traits+namespace detail {++struct no_connect_member+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+};++#if defined(ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT)++template <typename S, typename R, typename = void>+struct connect_member_trait : no_connect_member+{+};++template <typename S, typename R>+struct connect_member_trait<S, R,+ typename void_type<+ decltype(declval<S>().connect(declval<R>()))+ >::type>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);++ using result_type = decltype(+ declval<S>().connect(declval<R>()));++ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = noexcept(+ declval<S>().connect(declval<R>())));+};++#else // defined(ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT)++template <typename S, typename R, typename = void>+struct connect_member_trait :+ conditional<+ is_same<S, typename remove_reference<S>::type>::value+ && is_same<R, typename decay<R>::type>::value,+ typename conditional<+ is_same<S, typename add_const<S>::type>::value,+ no_connect_member,+ traits::connect_member<typename add_const<S>::type, R>+ >::type,+ traits::connect_member<+ typename remove_reference<S>::type,+ typename decay<R>::type>+ >::type+{+};++#endif // defined(ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT)++} // namespace detail+namespace traits {++template <typename S, typename R, typename>+struct connect_member_default :+ detail::connect_member_trait<S, R>+{+};++template <typename S, typename R, typename>+struct connect_member :+ connect_member_default<S, R>+{+};++} // namespace traits+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_TRAITS_CONNECT_MEMBER_HPP
link/modules/asio-standalone/asio/include/asio/traits/equality_comparable.hpp view
@@ -2,7 +2,7 @@ // traits/equality_comparable.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -18,9 +18,13 @@ #include "asio/detail/config.hpp" #include "asio/detail/type_traits.hpp" -#if defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#if defined(ASIO_HAS_DECLTYPE) \+ && defined(ASIO_HAS_NOEXCEPT) \+ && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) # define ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT 1-#endif // defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#endif // defined(ASIO_HAS_DECLTYPE)+ // && defined(ASIO_HAS_NOEXCEPT)+ // && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) namespace asio { namespace traits {@@ -36,8 +40,8 @@ struct no_equality_comparable {- static constexpr bool is_valid = false;- static constexpr bool is_noexcept = false;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); }; #if defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)@@ -49,7 +53,7 @@ template <typename T> struct equality_comparable_trait<T,- void_t<+ typename void_type< decltype( static_cast<void>( static_cast<bool>(declval<const T>() == declval<const T>())@@ -58,24 +62,24 @@ static_cast<bool>(declval<const T>() != declval<const T>()) ) )- >>+ >::type> {- static constexpr bool is_valid = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true); - static constexpr bool is_noexcept =+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = noexcept(declval<const T>() == declval<const T>())- && noexcept(declval<const T>() != declval<const T>());+ && noexcept(declval<const T>() != declval<const T>())); }; #else // defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT) template <typename T, typename = void> struct equality_comparable_trait :- conditional_t<- is_same<T, decay_t<T>>::value,+ conditional<+ is_same<T, typename decay<T>::type>::value, no_equality_comparable,- traits::equality_comparable<decay_t<T>>- >+ traits::equality_comparable<typename decay<T>::type>+ >::type { };
+ link/modules/asio-standalone/asio/include/asio/traits/execute_free.hpp view
@@ -0,0 +1,108 @@+//+// traits/execute_free.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_TRAITS_EXECUTE_FREE_HPP+#define ASIO_TRAITS_EXECUTE_FREE_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/detail/type_traits.hpp"++#if defined(ASIO_HAS_DECLTYPE) \+ && defined(ASIO_HAS_NOEXCEPT) \+ && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+# define ASIO_HAS_DEDUCED_EXECUTE_FREE_TRAIT 1+#endif // defined(ASIO_HAS_DECLTYPE)+ // && defined(ASIO_HAS_NOEXCEPT)+ // && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)++#include "asio/detail/push_options.hpp"++namespace asio {+namespace traits {++template <typename T, typename F, typename = void>+struct execute_free_default;++template <typename T, typename F, typename = void>+struct execute_free;++} // namespace traits+namespace detail {++struct no_execute_free+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+};++#if defined(ASIO_HAS_DEDUCED_EXECUTE_FREE_TRAIT)++template <typename T, typename F, typename = void>+struct execute_free_trait : no_execute_free+{+};++template <typename T, typename F>+struct execute_free_trait<T, F,+ typename void_type<+ decltype(execute(declval<T>(), declval<F>()))+ >::type>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);++ using result_type = decltype(+ execute(declval<T>(), declval<F>()));++ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = noexcept(+ execute(declval<T>(), declval<F>())));+};++#else // defined(ASIO_HAS_DEDUCED_EXECUTE_FREE_TRAIT)++template <typename T, typename F, typename = void>+struct execute_free_trait :+ conditional<+ is_same<T, typename decay<T>::type>::value+ && is_same<F, typename decay<F>::type>::value,+ no_execute_free,+ traits::execute_free<+ typename decay<T>::type,+ typename decay<F>::type>+ >::type+{+};++#endif // defined(ASIO_HAS_DEDUCED_EXECUTE_FREE_TRAIT)++} // namespace detail+namespace traits {++template <typename T, typename F, typename>+struct execute_free_default :+ detail::execute_free_trait<T, F>+{+};++template <typename T, typename F, typename>+struct execute_free :+ execute_free_default<T, F>+{+};++} // namespace traits+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_TRAITS_EXECUTE_FREE_HPP
link/modules/asio-standalone/asio/include/asio/traits/execute_member.hpp view
@@ -2,7 +2,7 @@ // traits/execute_member.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -18,9 +18,13 @@ #include "asio/detail/config.hpp" #include "asio/detail/type_traits.hpp" -#if defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#if defined(ASIO_HAS_DECLTYPE) \+ && defined(ASIO_HAS_NOEXCEPT) \+ && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) # define ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT 1-#endif // defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#endif // defined(ASIO_HAS_DECLTYPE)+ // && defined(ASIO_HAS_NOEXCEPT)+ // && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) #include "asio/detail/push_options.hpp" @@ -38,8 +42,8 @@ struct no_execute_member {- static constexpr bool is_valid = false;- static constexpr bool is_noexcept = false;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); }; #if defined(ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)@@ -51,31 +55,31 @@ template <typename T, typename F> struct execute_member_trait<T, F,- void_t<+ typename void_type< decltype(declval<T>().execute(declval<F>()))- >>+ >::type> {- static constexpr bool is_valid = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true); using result_type = decltype( declval<T>().execute(declval<F>())); - static constexpr bool is_noexcept =- noexcept(declval<T>().execute(declval<F>()));+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = noexcept(+ declval<T>().execute(declval<F>()))); }; #else // defined(ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT) template <typename T, typename F, typename = void> struct execute_member_trait :- conditional_t<- is_same<T, decay_t<T>>::value- && is_same<F, decay_t<F>>::value,+ conditional<+ is_same<T, typename decay<T>::type>::value+ && is_same<F, typename decay<F>::type>::value, no_execute_member, traits::execute_member<- decay_t<T>,- decay_t<F>>- >+ typename decay<T>::type,+ typename decay<F>::type>+ >::type { };
link/modules/asio-standalone/asio/include/asio/traits/prefer_free.hpp view
@@ -2,7 +2,7 @@ // traits/prefer_free.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -18,9 +18,13 @@ #include "asio/detail/config.hpp" #include "asio/detail/type_traits.hpp" -#if defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#if defined(ASIO_HAS_DECLTYPE) \+ && defined(ASIO_HAS_NOEXCEPT) \+ && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) # define ASIO_HAS_DEDUCED_PREFER_FREE_TRAIT 1-#endif // defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#endif // defined(ASIO_HAS_DECLTYPE)+ // && defined(ASIO_HAS_NOEXCEPT)+ // && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) #include "asio/detail/push_options.hpp" @@ -38,8 +42,8 @@ struct no_prefer_free {- static constexpr bool is_valid = false;- static constexpr bool is_noexcept = false;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); }; #if defined(ASIO_HAS_DEDUCED_PREFER_FREE_TRAIT)@@ -51,31 +55,31 @@ template <typename T, typename Property> struct prefer_free_trait<T, Property,- void_t<+ typename void_type< decltype(prefer(declval<T>(), declval<Property>()))- >>+ >::type> {- static constexpr bool is_valid = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true); using result_type = decltype( prefer(declval<T>(), declval<Property>())); - static constexpr bool is_noexcept =- noexcept(prefer(declval<T>(), declval<Property>()));+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = noexcept(+ prefer(declval<T>(), declval<Property>()))); }; #else // defined(ASIO_HAS_DEDUCED_PREFER_FREE_TRAIT) template <typename T, typename Property, typename = void> struct prefer_free_trait :- conditional_t<- is_same<T, decay_t<T>>::value- && is_same<Property, decay_t<Property>>::value,+ conditional<+ is_same<T, typename decay<T>::type>::value+ && is_same<Property, typename decay<Property>::type>::value, no_prefer_free, traits::prefer_free<- decay_t<T>,- decay_t<Property>>- >+ typename decay<T>::type,+ typename decay<Property>::type>+ >::type { };
link/modules/asio-standalone/asio/include/asio/traits/prefer_member.hpp view
@@ -2,7 +2,7 @@ // traits/prefer_member.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -18,9 +18,13 @@ #include "asio/detail/config.hpp" #include "asio/detail/type_traits.hpp" -#if defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#if defined(ASIO_HAS_DECLTYPE) \+ && defined(ASIO_HAS_NOEXCEPT) \+ && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) # define ASIO_HAS_DEDUCED_PREFER_MEMBER_TRAIT 1-#endif // defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#endif // defined(ASIO_HAS_DECLTYPE)+ // && defined(ASIO_HAS_NOEXCEPT)+ // && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) #include "asio/detail/push_options.hpp" @@ -38,8 +42,8 @@ struct no_prefer_member {- static constexpr bool is_valid = false;- static constexpr bool is_noexcept = false;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); }; #if defined(ASIO_HAS_DEDUCED_PREFER_MEMBER_TRAIT)@@ -51,31 +55,31 @@ template <typename T, typename Property> struct prefer_member_trait<T, Property,- void_t<+ typename void_type< decltype(declval<T>().prefer(declval<Property>()))- >>+ >::type> {- static constexpr bool is_valid = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true); using result_type = decltype( declval<T>().prefer(declval<Property>())); - static constexpr bool is_noexcept =- noexcept(declval<T>().prefer(declval<Property>()));+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = noexcept(+ declval<T>().prefer(declval<Property>()))); }; #else // defined(ASIO_HAS_DEDUCED_PREFER_MEMBER_TRAIT) template <typename T, typename Property, typename = void> struct prefer_member_trait :- conditional_t<- is_same<T, decay_t<T>>::value- && is_same<Property, decay_t<Property>>::value,+ conditional<+ is_same<T, typename decay<T>::type>::value+ && is_same<Property, typename decay<Property>::type>::value, no_prefer_member, traits::prefer_member<- decay_t<T>,- decay_t<Property>>- >+ typename decay<T>::type,+ typename decay<Property>::type>+ >::type { };
link/modules/asio-standalone/asio/include/asio/traits/query_free.hpp view
@@ -2,7 +2,7 @@ // traits/query_free.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -18,9 +18,13 @@ #include "asio/detail/config.hpp" #include "asio/detail/type_traits.hpp" -#if defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#if defined(ASIO_HAS_DECLTYPE) \+ && defined(ASIO_HAS_NOEXCEPT) \+ && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) # define ASIO_HAS_DEDUCED_QUERY_FREE_TRAIT 1-#endif // defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#endif // defined(ASIO_HAS_DECLTYPE)+ // && defined(ASIO_HAS_NOEXCEPT)+ // && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) #include "asio/detail/push_options.hpp" @@ -38,8 +42,8 @@ struct no_query_free {- static constexpr bool is_valid = false;- static constexpr bool is_noexcept = false;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); }; #if defined(ASIO_HAS_DEDUCED_QUERY_FREE_TRAIT)@@ -51,31 +55,31 @@ template <typename T, typename Property> struct query_free_trait<T, Property,- void_t<+ typename void_type< decltype(query(declval<T>(), declval<Property>()))- >>+ >::type> {- static constexpr bool is_valid = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true); using result_type = decltype( query(declval<T>(), declval<Property>())); - static constexpr bool is_noexcept =- noexcept(query(declval<T>(), declval<Property>()));+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = noexcept(+ query(declval<T>(), declval<Property>()))); }; #else // defined(ASIO_HAS_DEDUCED_QUERY_FREE_TRAIT) template <typename T, typename Property, typename = void> struct query_free_trait :- conditional_t<- is_same<T, decay_t<T>>::value- && is_same<Property, decay_t<Property>>::value,+ conditional<+ is_same<T, typename decay<T>::type>::value+ && is_same<Property, typename decay<Property>::type>::value, no_query_free, traits::query_free<- decay_t<T>,- decay_t<Property>>- >+ typename decay<T>::type,+ typename decay<Property>::type>+ >::type { };
link/modules/asio-standalone/asio/include/asio/traits/query_member.hpp view
@@ -2,7 +2,7 @@ // traits/query_member.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -18,9 +18,13 @@ #include "asio/detail/config.hpp" #include "asio/detail/type_traits.hpp" -#if defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#if defined(ASIO_HAS_DECLTYPE) \+ && defined(ASIO_HAS_NOEXCEPT) \+ && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) # define ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT 1-#endif // defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#endif // defined(ASIO_HAS_DECLTYPE)+ // && defined(ASIO_HAS_NOEXCEPT)+ // && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) #include "asio/detail/push_options.hpp" @@ -38,8 +42,8 @@ struct no_query_member {- static constexpr bool is_valid = false;- static constexpr bool is_noexcept = false;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); }; #if defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)@@ -51,31 +55,31 @@ template <typename T, typename Property> struct query_member_trait<T, Property,- void_t<+ typename void_type< decltype(declval<T>().query(declval<Property>()))- >>+ >::type> {- static constexpr bool is_valid = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true); using result_type = decltype( declval<T>().query(declval<Property>())); - static constexpr bool is_noexcept =- noexcept(declval<T>().query(declval<Property>()));+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = noexcept(+ declval<T>().query(declval<Property>()))); }; #else // defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT) template <typename T, typename Property, typename = void> struct query_member_trait :- conditional_t<- is_same<T, decay_t<T>>::value- && is_same<Property, decay_t<Property>>::value,+ conditional<+ is_same<T, typename decay<T>::type>::value+ && is_same<Property, typename decay<Property>::type>::value, no_query_member, traits::query_member<- decay_t<T>,- decay_t<Property>>- >+ typename decay<T>::type,+ typename decay<Property>::type>+ >::type { };
link/modules/asio-standalone/asio/include/asio/traits/query_static_constexpr_member.hpp view
@@ -2,7 +2,7 @@ // traits/query_static_constexpr_member.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -18,10 +18,16 @@ #include "asio/detail/config.hpp" #include "asio/detail/type_traits.hpp" -#if defined(ASIO_HAS_CONSTANT_EXPRESSION_SFINAE) \+#if defined(ASIO_HAS_DECLTYPE) \+ && defined(ASIO_HAS_NOEXCEPT) \+ && defined(ASIO_HAS_CONSTEXPR) \+ && defined(ASIO_HAS_CONSTANT_EXPRESSION_SFINAE) \ && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) # define ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT 1-#endif // defined(ASIO_HAS_CONSTANT_EXPRESSION_SFINAE)+#endif // defined(ASIO_HAS_DECLTYPE)+ // && defined(ASIO_HAS_NOEXCEPT)+ // && defined(ASIO_HAS_CONSTEXPR)+ // && defined(ASIO_HAS_CONSTANT_EXPRESSION_SFINAE) // && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) #include "asio/detail/push_options.hpp"@@ -40,19 +46,19 @@ struct no_query_static_constexpr_member {- static constexpr bool is_valid = false;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = false); }; template <typename T, typename Property, typename = void> struct query_static_constexpr_member_trait :- conditional_t<- is_same<T, decay_t<T>>::value- && is_same<Property, decay_t<Property>>::value,+ conditional<+ is_same<T, typename decay<T>::type>::value+ && is_same<Property, typename decay<Property>::type>::value, no_query_static_constexpr_member, traits::query_static_constexpr_member<- decay_t<T>,- decay_t<Property>>- >+ typename decay<T>::type,+ typename decay<Property>::type>+ >::type { }; @@ -60,17 +66,18 @@ template <typename T, typename Property> struct query_static_constexpr_member_trait<T, Property,- enable_if_t<+ typename enable_if< (static_cast<void>(T::query(Property{})), true)- >>+ >::type> {- static constexpr bool is_valid = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true); using result_type = decltype(T::query(Property{})); - static constexpr bool is_noexcept = noexcept(T::query(Property{}));+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+ noexcept(T::query(Property{}))); - static constexpr result_type value() noexcept(is_noexcept)+ static ASIO_CONSTEXPR result_type value() noexcept(is_noexcept) { return T::query(Property{}); }
link/modules/asio-standalone/asio/include/asio/traits/require_concept_free.hpp view
@@ -2,7 +2,7 @@ // traits/require_concept_free.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -18,9 +18,13 @@ #include "asio/detail/config.hpp" #include "asio/detail/type_traits.hpp" -#if defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#if defined(ASIO_HAS_DECLTYPE) \+ && defined(ASIO_HAS_NOEXCEPT) \+ && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) # define ASIO_HAS_DEDUCED_REQUIRE_CONCEPT_FREE_TRAIT 1-#endif // defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#endif // defined(ASIO_HAS_DECLTYPE)+ // && defined(ASIO_HAS_NOEXCEPT)+ // && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) #include "asio/detail/push_options.hpp" @@ -38,8 +42,8 @@ struct no_require_concept_free {- static constexpr bool is_valid = false;- static constexpr bool is_noexcept = false;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); }; #if defined(ASIO_HAS_DEDUCED_REQUIRE_CONCEPT_FREE_TRAIT)@@ -51,31 +55,31 @@ template <typename T, typename Property> struct require_concept_free_trait<T, Property,- void_t<+ typename void_type< decltype(require_concept(declval<T>(), declval<Property>()))- >>+ >::type> {- static constexpr bool is_valid = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true); using result_type = decltype( require_concept(declval<T>(), declval<Property>())); - static constexpr bool is_noexcept =- noexcept(require_concept(declval<T>(), declval<Property>()));+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = noexcept(+ require_concept(declval<T>(), declval<Property>()))); }; #else // defined(ASIO_HAS_DEDUCED_REQUIRE_CONCEPT_FREE_TRAIT) template <typename T, typename Property, typename = void> struct require_concept_free_trait :- conditional_t<- is_same<T, decay_t<T>>::value- && is_same<Property, decay_t<Property>>::value,+ conditional<+ is_same<T, typename decay<T>::type>::value+ && is_same<Property, typename decay<Property>::type>::value, no_require_concept_free, traits::require_concept_free<- decay_t<T>,- decay_t<Property>>- >+ typename decay<T>::type,+ typename decay<Property>::type>+ >::type { };
link/modules/asio-standalone/asio/include/asio/traits/require_concept_member.hpp view
@@ -2,7 +2,7 @@ // traits/require_concept_member.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -18,9 +18,13 @@ #include "asio/detail/config.hpp" #include "asio/detail/type_traits.hpp" -#if defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#if defined(ASIO_HAS_DECLTYPE) \+ && defined(ASIO_HAS_NOEXCEPT) \+ && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) # define ASIO_HAS_DEDUCED_REQUIRE_CONCEPT_MEMBER_TRAIT 1-#endif // defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#endif // defined(ASIO_HAS_DECLTYPE)+ // && defined(ASIO_HAS_NOEXCEPT)+ // && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) #include "asio/detail/push_options.hpp" @@ -38,8 +42,8 @@ struct no_require_concept_member {- static constexpr bool is_valid = false;- static constexpr bool is_noexcept = false;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); }; #if defined(ASIO_HAS_DEDUCED_REQUIRE_CONCEPT_MEMBER_TRAIT)@@ -51,31 +55,31 @@ template <typename T, typename Property> struct require_concept_member_trait<T, Property,- void_t<+ typename void_type< decltype(declval<T>().require_concept(declval<Property>()))- >>+ >::type> {- static constexpr bool is_valid = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true); using result_type = decltype( declval<T>().require_concept(declval<Property>())); - static constexpr bool is_noexcept =- noexcept(declval<T>().require_concept(declval<Property>()));+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = noexcept(+ declval<T>().require_concept(declval<Property>()))); }; #else // defined(ASIO_HAS_DEDUCED_REQUIRE_CONCEPT_MEMBER_TRAIT) template <typename T, typename Property, typename = void> struct require_concept_member_trait :- conditional_t<- is_same<T, decay_t<T>>::value- && is_same<Property, decay_t<Property>>::value,+ conditional<+ is_same<T, typename decay<T>::type>::value+ && is_same<Property, typename decay<Property>::type>::value, no_require_concept_member, traits::require_concept_member<- decay_t<T>,- decay_t<Property>>- >+ typename decay<T>::type,+ typename decay<Property>::type>+ >::type { };
link/modules/asio-standalone/asio/include/asio/traits/require_free.hpp view
@@ -2,7 +2,7 @@ // traits/require_free.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -18,9 +18,13 @@ #include "asio/detail/config.hpp" #include "asio/detail/type_traits.hpp" -#if defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#if defined(ASIO_HAS_DECLTYPE) \+ && defined(ASIO_HAS_NOEXCEPT) \+ && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) # define ASIO_HAS_DEDUCED_REQUIRE_FREE_TRAIT 1-#endif // defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#endif // defined(ASIO_HAS_DECLTYPE)+ // && defined(ASIO_HAS_NOEXCEPT)+ // && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) #include "asio/detail/push_options.hpp" @@ -38,8 +42,8 @@ struct no_require_free {- static constexpr bool is_valid = false;- static constexpr bool is_noexcept = false;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); }; #if defined(ASIO_HAS_DEDUCED_REQUIRE_FREE_TRAIT)@@ -51,31 +55,31 @@ template <typename T, typename Property> struct require_free_trait<T, Property,- void_t<+ typename void_type< decltype(require(declval<T>(), declval<Property>()))- >>+ >::type> {- static constexpr bool is_valid = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true); using result_type = decltype( require(declval<T>(), declval<Property>())); - static constexpr bool is_noexcept =- noexcept(require(declval<T>(), declval<Property>()));+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = noexcept(+ require(declval<T>(), declval<Property>()))); }; #else // defined(ASIO_HAS_DEDUCED_REQUIRE_FREE_TRAIT) template <typename T, typename Property, typename = void> struct require_free_trait :- conditional_t<- is_same<T, decay_t<T>>::value- && is_same<Property, decay_t<Property>>::value,+ conditional<+ is_same<T, typename decay<T>::type>::value+ && is_same<Property, typename decay<Property>::type>::value, no_require_free, traits::require_free<- decay_t<T>,- decay_t<Property>>- >+ typename decay<T>::type,+ typename decay<Property>::type>+ >::type { };
link/modules/asio-standalone/asio/include/asio/traits/require_member.hpp view
@@ -2,7 +2,7 @@ // traits/require_member.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -18,9 +18,13 @@ #include "asio/detail/config.hpp" #include "asio/detail/type_traits.hpp" -#if defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#if defined(ASIO_HAS_DECLTYPE) \+ && defined(ASIO_HAS_NOEXCEPT) \+ && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) # define ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT 1-#endif // defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#endif // defined(ASIO_HAS_DECLTYPE)+ // && defined(ASIO_HAS_NOEXCEPT)+ // && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) #include "asio/detail/push_options.hpp" @@ -38,8 +42,8 @@ struct no_require_member {- static constexpr bool is_valid = false;- static constexpr bool is_noexcept = false;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); }; #if defined(ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)@@ -51,31 +55,31 @@ template <typename T, typename Property> struct require_member_trait<T, Property,- void_t<+ typename void_type< decltype(declval<T>().require(declval<Property>()))- >>+ >::type> {- static constexpr bool is_valid = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true); using result_type = decltype( declval<T>().require(declval<Property>())); - static constexpr bool is_noexcept =- noexcept(declval<T>().require(declval<Property>()));+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = noexcept(+ declval<T>().require(declval<Property>()))); }; #else // defined(ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT) template <typename T, typename Property, typename = void> struct require_member_trait :- conditional_t<- is_same<T, decay_t<T>>::value- && is_same<Property, decay_t<Property>>::value,+ conditional<+ is_same<T, typename decay<T>::type>::value+ && is_same<Property, typename decay<Property>::type>::value, no_require_member, traits::require_member<- decay_t<T>,- decay_t<Property>>- >+ typename decay<T>::type,+ typename decay<Property>::type>+ >::type { };
+ link/modules/asio-standalone/asio/include/asio/traits/schedule_free.hpp view
@@ -0,0 +1,108 @@+//+// traits/schedule_free.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_TRAITS_SCHEDULE_FREE_HPP+#define ASIO_TRAITS_SCHEDULE_FREE_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/detail/type_traits.hpp"++#if defined(ASIO_HAS_DECLTYPE) \+ && defined(ASIO_HAS_NOEXCEPT) \+ && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+# define ASIO_HAS_DEDUCED_SCHEDULE_FREE_TRAIT 1+#endif // defined(ASIO_HAS_DECLTYPE)+ // && defined(ASIO_HAS_NOEXCEPT)+ // && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)++#include "asio/detail/push_options.hpp"++namespace asio {+namespace traits {++template <typename T, typename = void>+struct schedule_free_default;++template <typename T, typename = void>+struct schedule_free;++} // namespace traits+namespace detail {++struct no_schedule_free+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+};++#if defined(ASIO_HAS_DEDUCED_SCHEDULE_FREE_TRAIT)++template <typename T, typename = void>+struct schedule_free_trait : no_schedule_free+{+};++template <typename T>+struct schedule_free_trait<T,+ typename void_type<+ decltype(schedule(declval<T>()))+ >::type>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);++ using result_type = decltype(schedule(declval<T>()));++ ASIO_STATIC_CONSTEXPR(bool,+ is_noexcept = noexcept(schedule(declval<T>())));+};++#else // defined(ASIO_HAS_DEDUCED_SCHEDULE_FREE_TRAIT)++template <typename T, typename = void>+struct schedule_free_trait :+ conditional<+ is_same<T, typename remove_reference<T>::type>::value,+ typename conditional<+ is_same<T, typename add_const<T>::type>::value,+ no_schedule_free,+ traits::schedule_free<typename add_const<T>::type>+ >::type,+ traits::schedule_free<typename remove_reference<T>::type>+ >::type+{+};++#endif // defined(ASIO_HAS_DEDUCED_SCHEDULE_FREE_TRAIT)++} // namespace detail+namespace traits {++template <typename T, typename>+struct schedule_free_default :+ detail::schedule_free_trait<T>+{+};++template <typename T, typename>+struct schedule_free :+ schedule_free_default<T>+{+};++} // namespace traits+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_TRAITS_SCHEDULE_FREE_HPP
+ link/modules/asio-standalone/asio/include/asio/traits/schedule_member.hpp view
@@ -0,0 +1,108 @@+//+// traits/schedule_member.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_TRAITS_SCHEDULE_MEMBER_HPP+#define ASIO_TRAITS_SCHEDULE_MEMBER_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/detail/type_traits.hpp"++#if defined(ASIO_HAS_DECLTYPE) \+ && defined(ASIO_HAS_NOEXCEPT) \+ && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+# define ASIO_HAS_DEDUCED_SCHEDULE_MEMBER_TRAIT 1+#endif // defined(ASIO_HAS_DECLTYPE)+ // && defined(ASIO_HAS_NOEXCEPT)+ // && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)++#include "asio/detail/push_options.hpp"++namespace asio {+namespace traits {++template <typename T, typename = void>+struct schedule_member_default;++template <typename T, typename = void>+struct schedule_member;++} // namespace traits+namespace detail {++struct no_schedule_member+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+};++#if defined(ASIO_HAS_DEDUCED_SCHEDULE_MEMBER_TRAIT)++template <typename T, typename = void>+struct schedule_member_trait : no_schedule_member+{+};++template <typename T>+struct schedule_member_trait<T,+ typename void_type<+ decltype(declval<T>().schedule())+ >::type>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);++ using result_type = decltype(declval<T>().schedule());++ ASIO_STATIC_CONSTEXPR(bool,+ is_noexcept = noexcept(declval<T>().schedule()));+};++#else // defined(ASIO_HAS_DEDUCED_SCHEDULE_MEMBER_TRAIT)++template <typename T, typename = void>+struct schedule_member_trait :+ conditional<+ is_same<T, typename remove_reference<T>::type>::value,+ typename conditional<+ is_same<T, typename add_const<T>::type>::value,+ no_schedule_member,+ traits::schedule_member<typename add_const<T>::type>+ >::type,+ traits::schedule_member<typename remove_reference<T>::type>+ >::type+{+};++#endif // defined(ASIO_HAS_DEDUCED_SCHEDULE_MEMBER_TRAIT)++} // namespace detail+namespace traits {++template <typename T, typename>+struct schedule_member_default :+ detail::schedule_member_trait<T>+{+};++template <typename T, typename>+struct schedule_member :+ schedule_member_default<T>+{+};++} // namespace traits+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_TRAITS_SCHEDULE_MEMBER_HPP
+ link/modules/asio-standalone/asio/include/asio/traits/set_done_free.hpp view
@@ -0,0 +1,108 @@+//+// traits/set_done_free.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_TRAITS_SET_DONE_FREE_HPP+#define ASIO_TRAITS_SET_DONE_FREE_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/detail/type_traits.hpp"++#if defined(ASIO_HAS_DECLTYPE) \+ && defined(ASIO_HAS_NOEXCEPT) \+ && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+# define ASIO_HAS_DEDUCED_SET_DONE_FREE_TRAIT 1+#endif // defined(ASIO_HAS_DECLTYPE)+ // && defined(ASIO_HAS_NOEXCEPT)+ // && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)++#include "asio/detail/push_options.hpp"++namespace asio {+namespace traits {++template <typename T, typename = void>+struct set_done_free_default;++template <typename T, typename = void>+struct set_done_free;++} // namespace traits+namespace detail {++struct no_set_done_free+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+};++#if defined(ASIO_HAS_DEDUCED_SET_DONE_FREE_TRAIT)++template <typename T, typename = void>+struct set_done_free_trait : no_set_done_free+{+};++template <typename T>+struct set_done_free_trait<T,+ typename void_type<+ decltype(set_done(declval<T>()))+ >::type>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);++ using result_type = decltype(set_done(declval<T>()));++ ASIO_STATIC_CONSTEXPR(bool,+ is_noexcept = noexcept(set_done(declval<T>())));+};++#else // defined(ASIO_HAS_DEDUCED_SET_DONE_FREE_TRAIT)++template <typename T, typename = void>+struct set_done_free_trait :+ conditional<+ is_same<T, typename remove_reference<T>::type>::value,+ typename conditional<+ is_same<T, typename add_const<T>::type>::value,+ no_set_done_free,+ traits::set_done_free<typename add_const<T>::type>+ >::type,+ traits::set_done_free<typename remove_reference<T>::type>+ >::type+{+};++#endif // defined(ASIO_HAS_DEDUCED_SET_DONE_FREE_TRAIT)++} // namespace detail+namespace traits {++template <typename T, typename>+struct set_done_free_default :+ detail::set_done_free_trait<T>+{+};++template <typename T, typename>+struct set_done_free :+ set_done_free_default<T>+{+};++} // namespace traits+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_TRAITS_SET_DONE_FREE_HPP
+ link/modules/asio-standalone/asio/include/asio/traits/set_done_member.hpp view
@@ -0,0 +1,108 @@+//+// traits/set_done_member.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_TRAITS_SET_DONE_MEMBER_HPP+#define ASIO_TRAITS_SET_DONE_MEMBER_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/detail/type_traits.hpp"++#if defined(ASIO_HAS_DECLTYPE) \+ && defined(ASIO_HAS_NOEXCEPT) \+ && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+# define ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT 1+#endif // defined(ASIO_HAS_DECLTYPE)+ // && defined(ASIO_HAS_NOEXCEPT)+ // && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)++#include "asio/detail/push_options.hpp"++namespace asio {+namespace traits {++template <typename T, typename = void>+struct set_done_member_default;++template <typename T, typename = void>+struct set_done_member;++} // namespace traits+namespace detail {++struct no_set_done_member+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+};++#if defined(ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)++template <typename T, typename = void>+struct set_done_member_trait : no_set_done_member+{+};++template <typename T>+struct set_done_member_trait<T,+ typename void_type<+ decltype(declval<T>().set_done())+ >::type>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);++ using result_type = decltype(declval<T>().set_done());++ ASIO_STATIC_CONSTEXPR(bool,+ is_noexcept = noexcept(declval<T>().set_done()));+};++#else // defined(ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)++template <typename T, typename = void>+struct set_done_member_trait :+ conditional<+ is_same<T, typename remove_reference<T>::type>::value,+ typename conditional<+ is_same<T, typename add_const<T>::type>::value,+ no_set_done_member,+ traits::set_done_member<typename add_const<T>::type>+ >::type,+ traits::set_done_member<typename remove_reference<T>::type>+ >::type+{+};++#endif // defined(ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)++} // namespace detail+namespace traits {++template <typename T, typename>+struct set_done_member_default :+ detail::set_done_member_trait<T>+{+};++template <typename T, typename>+struct set_done_member :+ set_done_member_default<T>+{+};++} // namespace traits+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_TRAITS_SET_DONE_MEMBER_HPP
+ link/modules/asio-standalone/asio/include/asio/traits/set_error_free.hpp view
@@ -0,0 +1,112 @@+//+// traits/set_error_free.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_TRAITS_SET_ERROR_FREE_HPP+#define ASIO_TRAITS_SET_ERROR_FREE_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/detail/type_traits.hpp"++#if defined(ASIO_HAS_DECLTYPE) \+ && defined(ASIO_HAS_NOEXCEPT) \+ && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+# define ASIO_HAS_DEDUCED_SET_ERROR_FREE_TRAIT 1+#endif // defined(ASIO_HAS_DECLTYPE)+ // && defined(ASIO_HAS_NOEXCEPT)+ // && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)++#include "asio/detail/push_options.hpp"++namespace asio {+namespace traits {++template <typename T, typename E, typename = void>+struct set_error_free_default;++template <typename T, typename E, typename = void>+struct set_error_free;++} // namespace traits+namespace detail {++struct no_set_error_free+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+};++#if defined(ASIO_HAS_DEDUCED_SET_ERROR_FREE_TRAIT)++template <typename T, typename E, typename = void>+struct set_error_free_trait : no_set_error_free+{+};++template <typename T, typename E>+struct set_error_free_trait<T, E,+ typename void_type<+ decltype(set_error(declval<T>(), declval<E>()))+ >::type>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);++ using result_type = decltype(+ set_error(declval<T>(), declval<E>()));++ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = noexcept(+ set_error(declval<T>(), declval<E>())));+};++#else // defined(ASIO_HAS_DEDUCED_SET_ERROR_FREE_TRAIT)++template <typename T, typename E, typename = void>+struct set_error_free_trait :+ conditional<+ is_same<T, typename remove_reference<T>::type>::value+ && is_same<E, typename decay<E>::type>::value,+ typename conditional<+ is_same<T, typename add_const<T>::type>::value,+ no_set_error_free,+ traits::set_error_free<typename add_const<T>::type, E>+ >::type,+ traits::set_error_free<+ typename remove_reference<T>::type,+ typename decay<E>::type>+ >::type+{+};++#endif // defined(ASIO_HAS_DEDUCED_SET_ERROR_FREE_TRAIT)++} // namespace detail+namespace traits {++template <typename T, typename E, typename>+struct set_error_free_default :+ detail::set_error_free_trait<T, E>+{+};++template <typename T, typename E, typename>+struct set_error_free :+ set_error_free_default<T, E>+{+};++} // namespace traits+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_TRAITS_SET_ERROR_FREE_HPP
+ link/modules/asio-standalone/asio/include/asio/traits/set_error_member.hpp view
@@ -0,0 +1,112 @@+//+// traits/set_error_member.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_TRAITS_SET_ERROR_MEMBER_HPP+#define ASIO_TRAITS_SET_ERROR_MEMBER_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/detail/type_traits.hpp"++#if defined(ASIO_HAS_DECLTYPE) \+ && defined(ASIO_HAS_NOEXCEPT) \+ && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+# define ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT 1+#endif // defined(ASIO_HAS_DECLTYPE)+ // && defined(ASIO_HAS_NOEXCEPT)+ // && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)++#include "asio/detail/push_options.hpp"++namespace asio {+namespace traits {++template <typename T, typename E, typename = void>+struct set_error_member_default;++template <typename T, typename E, typename = void>+struct set_error_member;++} // namespace traits+namespace detail {++struct no_set_error_member+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+};++#if defined(ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)++template <typename T, typename E, typename = void>+struct set_error_member_trait : no_set_error_member+{+};++template <typename T, typename E>+struct set_error_member_trait<T, E,+ typename void_type<+ decltype(declval<T>().set_error(declval<E>()))+ >::type>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);++ using result_type = decltype(+ declval<T>().set_error(declval<E>()));++ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = noexcept(+ declval<T>().set_error(declval<E>())));+};++#else // defined(ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)++template <typename T, typename E, typename = void>+struct set_error_member_trait :+ conditional<+ is_same<T, typename remove_reference<T>::type>::value+ && is_same<E, typename decay<E>::type>::value,+ typename conditional<+ is_same<T, typename add_const<T>::type>::value,+ no_set_error_member,+ traits::set_error_member<typename add_const<T>::type, E>+ >::type,+ traits::set_error_member<+ typename remove_reference<T>::type,+ typename decay<E>::type>+ >::type+{+};++#endif // defined(ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)++} // namespace detail+namespace traits {++template <typename T, typename E, typename>+struct set_error_member_default :+ detail::set_error_member_trait<T, E>+{+};++template <typename T, typename E, typename>+struct set_error_member :+ set_error_member_default<T, E>+{+};++} // namespace traits+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_TRAITS_SET_ERROR_MEMBER_HPP
+ link/modules/asio-standalone/asio/include/asio/traits/set_value_free.hpp view
@@ -0,0 +1,234 @@+//+// traits/set_value_free.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_TRAITS_SET_VALUE_FREE_HPP+#define ASIO_TRAITS_SET_VALUE_FREE_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/detail/type_traits.hpp"+#include "asio/detail/variadic_templates.hpp"++#if defined(ASIO_HAS_DECLTYPE) \+ && defined(ASIO_HAS_NOEXCEPT) \+ && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+# define ASIO_HAS_DEDUCED_SET_VALUE_FREE_TRAIT 1+#endif // defined(ASIO_HAS_DECLTYPE)+ // && defined(ASIO_HAS_NOEXCEPT)+ // && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)++#include "asio/detail/push_options.hpp"++namespace asio {+namespace traits {++template <typename T, typename Vs, typename = void>+struct set_value_free_default;++template <typename T, typename Vs, typename = void>+struct set_value_free;++} // namespace traits+namespace detail {++struct no_set_value_free+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+};++#if defined(ASIO_HAS_DEDUCED_SET_VALUE_FREE_TRAIT)++template <typename T, typename Vs, typename = void>+struct set_value_free_trait : no_set_value_free+{+};++#if defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename T, typename... Vs>+struct set_value_free_trait<T, void(Vs...),+ typename void_type<+ decltype(set_value(declval<T>(), declval<Vs>()...))+ >::type>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);++ using result_type = decltype(+ set_value(declval<T>(), declval<Vs>()...));++ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = noexcept(+ set_value(declval<T>(), declval<Vs>()...)));+};++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename T>+struct set_value_free_trait<T, void(),+ typename void_type<+ decltype(set_value(declval<T>()))+ >::type>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);++ using result_type = decltype(set_value(declval<T>()));++ ASIO_STATIC_CONSTEXPR(bool,+ is_noexcept = noexcept(set_value(declval<T>())));+};++#define ASIO_PRIVATE_SET_VALUE_FREE_TRAIT_DEF(n) \+ template <typename T, ASIO_VARIADIC_TPARAMS(n)> \+ struct set_value_free_trait<T, void(ASIO_VARIADIC_TARGS(n)), \+ typename void_type< \+ decltype(set_value(declval<T>(), ASIO_VARIADIC_DECLVAL(n))) \+ >::type> \+ { \+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true); \+ \+ using result_type = decltype( \+ set_value(declval<T>(), ASIO_VARIADIC_DECLVAL(n))); \+ \+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = noexcept( \+ set_value(declval<T>(), ASIO_VARIADIC_DECLVAL(n)))); \+ }; \+ /**/+ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_SET_VALUE_FREE_TRAIT_DEF)+#undef ASIO_PRIVATE_SET_VALUE_FREE_TRAIT_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++#else // defined(ASIO_HAS_DEDUCED_SET_VALUE_FREE_TRAIT)++template <typename T, typename Vs, typename = void>+struct set_value_free_trait;++#if defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename T, typename... Vs>+struct set_value_free_trait<T, void(Vs...)> :+ conditional<+ is_same<T, typename remove_reference<T>::type>::value+ && conjunction<is_same<Vs, typename decay<Vs>::type>...>::value,+ typename conditional<+ is_same<T, typename add_const<T>::type>::value,+ no_set_value_free,+ traits::set_value_free<typename add_const<T>::type, void(Vs...)>+ >::type,+ traits::set_value_free<+ typename remove_reference<T>::type,+ void(typename decay<Vs>::type...)>+ >::type+{+};++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename T>+struct set_value_free_trait<T, void()> :+ conditional<+ is_same<T, typename remove_reference<T>::type>::value,+ typename conditional<+ is_same<T, typename add_const<T>::type>::value,+ no_set_value_free,+ traits::set_value_free<typename add_const<T>::type, void()>+ >::type,+ traits::set_value_free<typename remove_reference<T>::type, void()>+ >::type+{+};++#define ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME(n) \+ ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_##n++#define ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_1 \+ && is_same<T1, typename decay<T1>::type>::value+#define ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_2 \+ ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_1 \+ && is_same<T2, typename decay<T2>::type>::value+#define ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_3 \+ ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_2 \+ && is_same<T3, typename decay<T3>::type>::value+#define ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_4 \+ ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_3 \+ && is_same<T4, typename decay<T4>::type>::value+#define ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_5 \+ ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_4 \+ && is_same<T5, typename decay<T5>::type>::value+#define ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_6 \+ ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_5 \+ && is_same<T6, typename decay<T6>::type>::value+#define ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_7 \+ ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_6 \+ && is_same<T7, typename decay<T7>::type>::value+#define ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_8 \+ ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_7 \+ && is_same<T8, typename decay<T8>::type>::value++#define ASIO_PRIVATE_SET_VALUE_MEMBER_TRAIT_DEF(n) \+ template <typename T, ASIO_VARIADIC_TPARAMS(n)> \+ struct set_value_free_trait<T, void(ASIO_VARIADIC_TARGS(n))> : \+ conditional< \+ is_same<T, typename remove_reference<T>::type>::value \+ ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME(n), \+ typename conditional< \+ is_same<T, typename add_const<T>::type>::value, \+ no_set_value_free, \+ traits::set_value_free< \+ typename add_const<T>::type, \+ void(ASIO_VARIADIC_TARGS(n))> \+ >::type, \+ traits::set_value_free< \+ typename remove_reference<T>::type, \+ void(ASIO_VARIADIC_DECAY(n))> \+ >::type \+ { \+ }; \+ /**/+ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_SET_VALUE_MEMBER_TRAIT_DEF)+#undef ASIO_PRIVATE_SET_VALUE_MEMBER_TRAIT_DEF+#undef ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME+#undef ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_1+#undef ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_2+#undef ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_3+#undef ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_4+#undef ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_5+#undef ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_6+#undef ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_7+#undef ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_8++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++#endif // defined(ASIO_HAS_DEDUCED_SET_VALUE_FREE_TRAIT)++} // namespace detail+namespace traits {++template <typename T, typename Vs, typename>+struct set_value_free_default :+ detail::set_value_free_trait<T, Vs>+{+};++template <typename T, typename Vs, typename>+struct set_value_free :+ set_value_free_default<T, Vs>+{+};++} // namespace traits+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_TRAITS_SET_VALUE_FREE_HPP
+ link/modules/asio-standalone/asio/include/asio/traits/set_value_member.hpp view
@@ -0,0 +1,234 @@+//+// traits/set_value_member.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_TRAITS_SET_VALUE_MEMBER_HPP+#define ASIO_TRAITS_SET_VALUE_MEMBER_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/detail/type_traits.hpp"+#include "asio/detail/variadic_templates.hpp"++#if defined(ASIO_HAS_DECLTYPE) \+ && defined(ASIO_HAS_NOEXCEPT) \+ && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+# define ASIO_HAS_DEDUCED_SET_VALUE_MEMBER_TRAIT 1+#endif // defined(ASIO_HAS_DECLTYPE)+ // && defined(ASIO_HAS_NOEXCEPT)+ // && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)++#include "asio/detail/push_options.hpp"++namespace asio {+namespace traits {++template <typename T, typename Vs, typename = void>+struct set_value_member_default;++template <typename T, typename Vs, typename = void>+struct set_value_member;++} // namespace traits+namespace detail {++struct no_set_value_member+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+};++#if defined(ASIO_HAS_DEDUCED_SET_VALUE_MEMBER_TRAIT)++template <typename T, typename Vs, typename = void>+struct set_value_member_trait : no_set_value_member+{+};++#if defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename T, typename... Vs>+struct set_value_member_trait<T, void(Vs...),+ typename void_type<+ decltype(declval<T>().set_value(declval<Vs>()...))+ >::type>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);++ using result_type = decltype(+ declval<T>().set_value(declval<Vs>()...));++ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = noexcept(+ declval<T>().set_value(declval<Vs>()...)));+};++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename T>+struct set_value_member_trait<T, void(),+ typename void_type<+ decltype(declval<T>().set_value())+ >::type>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);++ using result_type = decltype(declval<T>().set_value());++ ASIO_STATIC_CONSTEXPR(bool,+ is_noexcept = noexcept(declval<T>().set_value()));+};++#define ASIO_PRIVATE_SET_VALUE_MEMBER_TRAIT_DEF(n) \+ template <typename T, ASIO_VARIADIC_TPARAMS(n)> \+ struct set_value_member_trait<T, void(ASIO_VARIADIC_TARGS(n)), \+ typename void_type< \+ decltype(declval<T>().set_value(ASIO_VARIADIC_DECLVAL(n))) \+ >::type> \+ { \+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true); \+ \+ using result_type = decltype( \+ declval<T>().set_value(ASIO_VARIADIC_DECLVAL(n))); \+ \+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = noexcept( \+ declval<T>().set_value(ASIO_VARIADIC_DECLVAL(n)))); \+ }; \+ /**/+ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_SET_VALUE_MEMBER_TRAIT_DEF)+#undef ASIO_PRIVATE_SET_VALUE_MEMBER_TRAIT_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++#else // defined(ASIO_HAS_DEDUCED_SET_VALUE_MEMBER_TRAIT)++template <typename T, typename Vs, typename = void>+struct set_value_member_trait;++#if defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename T, typename... Vs>+struct set_value_member_trait<T, void(Vs...)> :+ conditional<+ is_same<T, typename remove_reference<T>::type>::value+ && conjunction<is_same<Vs, typename decay<Vs>::type>...>::value,+ typename conditional<+ is_same<T, typename add_const<T>::type>::value,+ no_set_value_member,+ traits::set_value_member<typename add_const<T>::type, void(Vs...)>+ >::type,+ traits::set_value_member<+ typename remove_reference<T>::type,+ void(typename decay<Vs>::type...)>+ >::type+{+};++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename T>+struct set_value_member_trait<T, void()> :+ conditional<+ is_same<T, typename remove_reference<T>::type>::value,+ typename conditional<+ is_same<T, typename add_const<T>::type>::value,+ no_set_value_member,+ traits::set_value_member<typename add_const<T>::type, void()>+ >::type,+ traits::set_value_member<typename remove_reference<T>::type, void()>+ >::type+{+};++#define ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME(n) \+ ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_##n++#define ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_1 \+ && is_same<T1, typename decay<T1>::type>::value+#define ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_2 \+ ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_1 \+ && is_same<T2, typename decay<T2>::type>::value+#define ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_3 \+ ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_2 \+ && is_same<T3, typename decay<T3>::type>::value+#define ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_4 \+ ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_3 \+ && is_same<T4, typename decay<T4>::type>::value+#define ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_5 \+ ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_4 \+ && is_same<T5, typename decay<T5>::type>::value+#define ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_6 \+ ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_5 \+ && is_same<T6, typename decay<T6>::type>::value+#define ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_7 \+ ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_6 \+ && is_same<T7, typename decay<T7>::type>::value+#define ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_8 \+ ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_7 \+ && is_same<T8, typename decay<T8>::type>::value++#define ASIO_PRIVATE_SET_VALUE_MEMBER_TRAIT_DEF(n) \+ template <typename T, ASIO_VARIADIC_TPARAMS(n)> \+ struct set_value_member_trait<T, void(ASIO_VARIADIC_TARGS(n))> : \+ conditional< \+ is_same<T, typename remove_reference<T>::type>::value \+ ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME(n), \+ typename conditional< \+ is_same<T, typename add_const<T>::type>::value, \+ no_set_value_member, \+ traits::set_value_member< \+ typename add_const<T>::type, \+ void(ASIO_VARIADIC_TARGS(n))> \+ >::type, \+ traits::set_value_member< \+ typename remove_reference<T>::type, \+ void(ASIO_VARIADIC_DECAY(n))> \+ >::type \+ { \+ }; \+ /**/+ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_SET_VALUE_MEMBER_TRAIT_DEF)+#undef ASIO_PRIVATE_SET_VALUE_MEMBER_TRAIT_DEF+#undef ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME+#undef ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_1+#undef ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_2+#undef ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_3+#undef ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_4+#undef ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_5+#undef ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_6+#undef ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_7+#undef ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_8++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++#endif // defined(ASIO_HAS_DEDUCED_SET_VALUE_MEMBER_TRAIT)++} // namespace detail+namespace traits {++template <typename T, typename Vs, typename>+struct set_value_member_default :+ detail::set_value_member_trait<T, Vs>+{+};++template <typename T, typename Vs, typename>+struct set_value_member :+ set_value_member_default<T, Vs>+{+};++} // namespace traits+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_TRAITS_SET_VALUE_MEMBER_HPP
+ link/modules/asio-standalone/asio/include/asio/traits/start_free.hpp view
@@ -0,0 +1,108 @@+//+// traits/start_free.hpp+// ~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_TRAITS_START_FREE_HPP+#define ASIO_TRAITS_START_FREE_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/detail/type_traits.hpp"++#if defined(ASIO_HAS_DECLTYPE) \+ && defined(ASIO_HAS_NOEXCEPT) \+ && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+# define ASIO_HAS_DEDUCED_START_FREE_TRAIT 1+#endif // defined(ASIO_HAS_DECLTYPE)+ // && defined(ASIO_HAS_NOEXCEPT)+ // && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)++#include "asio/detail/push_options.hpp"++namespace asio {+namespace traits {++template <typename T, typename = void>+struct start_free_default;++template <typename T, typename = void>+struct start_free;++} // namespace traits+namespace detail {++struct no_start_free+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+};++#if defined(ASIO_HAS_DEDUCED_START_FREE_TRAIT)++template <typename T, typename = void>+struct start_free_trait : no_start_free+{+};++template <typename T>+struct start_free_trait<T,+ typename void_type<+ decltype(start(declval<T>()))+ >::type>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);++ using result_type = decltype(start(declval<T>()));++ ASIO_STATIC_CONSTEXPR(bool,+ is_noexcept = noexcept(start(declval<T>())));+};++#else // defined(ASIO_HAS_DEDUCED_START_FREE_TRAIT)++template <typename T, typename = void>+struct start_free_trait :+ conditional<+ is_same<T, typename remove_reference<T>::type>::value,+ typename conditional<+ is_same<T, typename add_const<T>::type>::value,+ no_start_free,+ traits::start_free<typename add_const<T>::type>+ >::type,+ traits::start_free<typename remove_reference<T>::type>+ >::type+{+};++#endif // defined(ASIO_HAS_DEDUCED_START_FREE_TRAIT)++} // namespace detail+namespace traits {++template <typename T, typename>+struct start_free_default :+ detail::start_free_trait<T>+{+};++template <typename T, typename>+struct start_free :+ start_free_default<T>+{+};++} // namespace traits+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_TRAITS_START_FREE_HPP
+ link/modules/asio-standalone/asio/include/asio/traits/start_member.hpp view
@@ -0,0 +1,108 @@+//+// traits/start_member.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_TRAITS_START_MEMBER_HPP+#define ASIO_TRAITS_START_MEMBER_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/detail/type_traits.hpp"++#if defined(ASIO_HAS_DECLTYPE) \+ && defined(ASIO_HAS_NOEXCEPT) \+ && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+# define ASIO_HAS_DEDUCED_START_MEMBER_TRAIT 1+#endif // defined(ASIO_HAS_DECLTYPE)+ // && defined(ASIO_HAS_NOEXCEPT)+ // && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)++#include "asio/detail/push_options.hpp"++namespace asio {+namespace traits {++template <typename T, typename = void>+struct start_member_default;++template <typename T, typename = void>+struct start_member;++} // namespace traits+namespace detail {++struct no_start_member+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+};++#if defined(ASIO_HAS_DEDUCED_START_MEMBER_TRAIT)++template <typename T, typename = void>+struct start_member_trait : no_start_member+{+};++template <typename T>+struct start_member_trait<T,+ typename void_type<+ decltype(declval<T>().start())+ >::type>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);++ using result_type = decltype(declval<T>().start());++ ASIO_STATIC_CONSTEXPR(bool,+ is_noexcept = noexcept(declval<T>().start()));+};++#else // defined(ASIO_HAS_DEDUCED_START_MEMBER_TRAIT)++template <typename T, typename = void>+struct start_member_trait :+ conditional<+ is_same<T, typename remove_reference<T>::type>::value,+ typename conditional<+ is_same<T, typename add_const<T>::type>::value,+ no_start_member,+ traits::start_member<typename add_const<T>::type>+ >::type,+ traits::start_member<typename remove_reference<T>::type>+ >::type+{+};++#endif // defined(ASIO_HAS_DEDUCED_START_MEMBER_TRAIT)++} // namespace detail+namespace traits {++template <typename T, typename>+struct start_member_default :+ detail::start_member_trait<T>+{+};++template <typename T, typename>+struct start_member :+ start_member_default<T>+{+};++} // namespace traits+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_TRAITS_START_MEMBER_HPP
link/modules/asio-standalone/asio/include/asio/traits/static_query.hpp view
@@ -2,7 +2,7 @@ // traits/static_query.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -18,10 +18,16 @@ #include "asio/detail/config.hpp" #include "asio/detail/type_traits.hpp" -#if defined(ASIO_HAS_VARIABLE_TEMPLATES) \+#if defined(ASIO_HAS_DECLTYPE) \+ && defined(ASIO_HAS_NOEXCEPT) \+ && defined(ASIO_HAS_CONSTEXPR) \+ && defined(ASIO_HAS_VARIABLE_TEMPLATES) \ && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) # define ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT 1-#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)+#endif // defined(ASIO_HAS_DECLTYPE)+ // && defined(ASIO_HAS_NOEXCEPT)+ // && defined(ASIO_HAS_CONSTEXPR)+ // && defined(ASIO_HAS_VARIABLE_TEMPLATES) // && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) #include "asio/detail/push_options.hpp"@@ -40,20 +46,20 @@ struct no_static_query {- static constexpr bool is_valid = false;- static constexpr bool is_noexcept = false;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); }; template <typename T, typename Property, typename = void> struct static_query_trait :- conditional_t<- is_same<T, decay_t<T>>::value- && is_same<Property, decay_t<Property>>::value,+ conditional<+ is_same<T, typename decay<T>::type>::value+ && is_same<Property, typename decay<Property>::type>::value, no_static_query, traits::static_query<- decay_t<T>,- decay_t<Property>>- >+ typename decay<T>::type,+ typename decay<Property>::type>+ >::type { }; @@ -61,21 +67,21 @@ template <typename T, typename Property> struct static_query_trait<T, Property,- void_t<- decltype(decay_t<Property>::template static_query_v<T>)- >>+ typename void_type<+ decltype(decay<Property>::type::template static_query_v<T>)+ >::type> {- static constexpr bool is_valid = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true); using result_type = decltype(- decay_t<Property>::template static_query_v<T>);+ decay<Property>::type::template static_query_v<T>); - static constexpr bool is_noexcept =- noexcept(decay_t<Property>::template static_query_v<T>);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+ noexcept(decay<Property>::type::template static_query_v<T>)); - static constexpr result_type value() noexcept(is_noexcept)+ static ASIO_CONSTEXPR result_type value() noexcept(is_noexcept) {- return decay_t<Property>::template static_query_v<T>;+ return decay<Property>::type::template static_query_v<T>; } };
link/modules/asio-standalone/asio/include/asio/traits/static_require.hpp view
@@ -2,7 +2,7 @@ // traits/static_require.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -19,7 +19,11 @@ #include "asio/detail/type_traits.hpp" #include "asio/traits/static_query.hpp" -#define ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT 1+#if defined(ASIO_HAS_DECLTYPE) \+ && defined(ASIO_HAS_NOEXCEPT)+# define ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT 1+#endif // defined(ASIO_HAS_DECLTYPE)+ // && defined(ASIO_HAS_NOEXCEPT) #include "asio/detail/push_options.hpp" @@ -37,31 +41,33 @@ struct no_static_require {- static constexpr bool is_valid = false;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = false); }; template <typename T, typename Property, typename = void> struct static_require_trait :- conditional_t<- is_same<T, decay_t<T>>::value- && is_same<Property, decay_t<Property>>::value,+ conditional<+ is_same<T, typename decay<T>::type>::value+ && is_same<Property, typename decay<Property>::type>::value, no_static_require, traits::static_require<- decay_t<T>,- decay_t<Property>>- >+ typename decay<T>::type,+ typename decay<Property>::type>+ >::type { }; +#if defined(ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT)+ #if defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) template <typename T, typename Property> struct static_require_trait<T, Property,- enable_if_t<- decay_t<Property>::value() == traits::static_query<T, Property>::value()- >>+ typename enable_if<+ decay<Property>::type::value() == traits::static_query<T, Property>::value()+ >::type> {- static constexpr bool is_valid = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true); }; #else // defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)@@ -70,29 +76,31 @@ template <typename T, typename Property> true_type static_require_test(T*, Property*,- enable_if_t<+ typename enable_if< Property::value() == traits::static_query<T, Property>::value()- >* = 0);+ >::type* = 0); template <typename T, typename Property> struct has_static_require {- static constexpr bool value =+ ASIO_STATIC_CONSTEXPR(bool, value = decltype((static_require_test)(- static_cast<T*>(0), static_cast<Property*>(0)))::value;+ static_cast<T*>(0), static_cast<Property*>(0)))::value); }; template <typename T, typename Property> struct static_require_trait<T, Property,- enable_if_t<- has_static_require<decay_t<T>,- decay_t<Property>>::value- >>+ typename enable_if<+ has_static_require<typename decay<T>::type,+ typename decay<Property>::type>::value+ >::type> {- static constexpr bool is_valid = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true); }; #endif // defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)++#endif // defined(ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT) } // namespace detail namespace traits {
link/modules/asio-standalone/asio/include/asio/traits/static_require_concept.hpp view
@@ -2,7 +2,7 @@ // traits/static_require_concept.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -19,7 +19,11 @@ #include "asio/detail/type_traits.hpp" #include "asio/traits/static_query.hpp" -#define ASIO_HAS_DEDUCED_STATIC_REQUIRE_CONCEPT_TRAIT 1+#if defined(ASIO_HAS_DECLTYPE) \+ && defined(ASIO_HAS_NOEXCEPT)+# define ASIO_HAS_DEDUCED_STATIC_REQUIRE_CONCEPT_TRAIT 1+#endif // defined(ASIO_HAS_DECLTYPE)+ // && defined(ASIO_HAS_NOEXCEPT) #include "asio/detail/push_options.hpp" @@ -37,31 +41,33 @@ struct no_static_require_concept {- static constexpr bool is_valid = false;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = false); }; template <typename T, typename Property, typename = void> struct static_require_concept_trait :- conditional_t<- is_same<T, decay_t<T>>::value- && is_same<Property, decay_t<Property>>::value,+ conditional<+ is_same<T, typename decay<T>::type>::value+ && is_same<Property, typename decay<Property>::type>::value, no_static_require_concept, traits::static_require_concept<- decay_t<T>,- decay_t<Property>>- >+ typename decay<T>::type,+ typename decay<Property>::type>+ >::type { }; +#if defined(ASIO_HAS_DEDUCED_STATIC_REQUIRE_CONCEPT_TRAIT)+ #if defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) template <typename T, typename Property> struct static_require_concept_trait<T, Property,- enable_if_t<- decay_t<Property>::value() == traits::static_query<T, Property>::value()- >>+ typename enable_if<+ decay<Property>::type::value() == traits::static_query<T, Property>::value()+ >::type> {- static constexpr bool is_valid = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true); }; #else // defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)@@ -70,29 +76,31 @@ template <typename T, typename Property> true_type static_require_concept_test(T*, Property*,- enable_if_t<+ typename enable_if< Property::value() == traits::static_query<T, Property>::value()- >* = 0);+ >::type* = 0); template <typename T, typename Property> struct has_static_require_concept {- static constexpr bool value =+ ASIO_STATIC_CONSTEXPR(bool, value = decltype((static_require_concept_test)(- static_cast<T*>(0), static_cast<Property*>(0)))::value;+ static_cast<T*>(0), static_cast<Property*>(0)))::value); }; template <typename T, typename Property> struct static_require_concept_trait<T, Property,- enable_if_t<- has_static_require_concept<decay_t<T>,- decay_t<Property>>::value- >>+ typename enable_if<+ has_static_require_concept<typename decay<T>::type,+ typename decay<Property>::type>::value+ >::type> {- static constexpr bool is_valid = true;+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true); }; #endif // defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)++#endif // defined(ASIO_HAS_DEDUCED_STATIC_REQUIRE_CONCEPT_TRAIT) } // namespace detail namespace traits {
+ link/modules/asio-standalone/asio/include/asio/traits/submit_free.hpp view
@@ -0,0 +1,112 @@+//+// traits/submit_free.hpp+// ~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_TRAITS_SUBMIT_FREE_HPP+#define ASIO_TRAITS_SUBMIT_FREE_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/detail/type_traits.hpp"++#if defined(ASIO_HAS_DECLTYPE) \+ && defined(ASIO_HAS_NOEXCEPT) \+ && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+# define ASIO_HAS_DEDUCED_SUBMIT_FREE_TRAIT 1+#endif // defined(ASIO_HAS_DECLTYPE)+ // && defined(ASIO_HAS_NOEXCEPT)+ // && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)++#include "asio/detail/push_options.hpp"++namespace asio {+namespace traits {++template <typename S, typename R, typename = void>+struct submit_free_default;++template <typename S, typename R, typename = void>+struct submit_free;++} // namespace traits+namespace detail {++struct no_submit_free+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+};++#if defined(ASIO_HAS_DEDUCED_SUBMIT_FREE_TRAIT)++template <typename S, typename R, typename = void>+struct submit_free_trait : no_submit_free+{+};++template <typename S, typename R>+struct submit_free_trait<S, R,+ typename void_type<+ decltype(submit(declval<S>(), declval<R>()))+ >::type>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);++ using result_type = decltype(+ submit(declval<S>(), declval<R>()));++ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = noexcept(+ submit(declval<S>(), declval<R>())));+};++#else // defined(ASIO_HAS_DEDUCED_SUBMIT_FREE_TRAIT)++template <typename S, typename R, typename = void>+struct submit_free_trait :+ conditional<+ is_same<S, typename remove_reference<S>::type>::value+ && is_same<R, typename decay<R>::type>::value,+ typename conditional<+ is_same<S, typename add_const<S>::type>::value,+ no_submit_free,+ traits::submit_free<typename add_const<S>::type, R>+ >::type,+ traits::submit_free<+ typename remove_reference<S>::type,+ typename decay<R>::type>+ >::type+{+};++#endif // defined(ASIO_HAS_DEDUCED_SUBMIT_FREE_TRAIT)++} // namespace detail+namespace traits {++template <typename S, typename R, typename>+struct submit_free_default :+ detail::submit_free_trait<S, R>+{+};++template <typename S, typename R, typename>+struct submit_free :+ submit_free_default<S, R>+{+};++} // namespace traits+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_TRAITS_SUBMIT_FREE_HPP
+ link/modules/asio-standalone/asio/include/asio/traits/submit_member.hpp view
@@ -0,0 +1,112 @@+//+// traits/submit_member.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ASIO_TRAITS_SUBMIT_MEMBER_HPP+#define ASIO_TRAITS_SUBMIT_MEMBER_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/detail/type_traits.hpp"++#if defined(ASIO_HAS_DECLTYPE) \+ && defined(ASIO_HAS_NOEXCEPT) \+ && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+# define ASIO_HAS_DEDUCED_SUBMIT_MEMBER_TRAIT 1+#endif // defined(ASIO_HAS_DECLTYPE)+ // && defined(ASIO_HAS_NOEXCEPT)+ // && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)++#include "asio/detail/push_options.hpp"++namespace asio {+namespace traits {++template <typename S, typename R, typename = void>+struct submit_member_default;++template <typename S, typename R, typename = void>+struct submit_member;++} // namespace traits+namespace detail {++struct no_submit_member+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+};++#if defined(ASIO_HAS_DEDUCED_SUBMIT_MEMBER_TRAIT)++template <typename S, typename R, typename = void>+struct submit_member_trait : no_submit_member+{+};++template <typename S, typename R>+struct submit_member_trait<S, R,+ typename void_type<+ decltype(declval<S>().submit(declval<R>()))+ >::type>+{+ ASIO_STATIC_CONSTEXPR(bool, is_valid = true);++ using result_type = decltype(+ declval<S>().submit(declval<R>()));++ ASIO_STATIC_CONSTEXPR(bool, is_noexcept = noexcept(+ declval<S>().submit(declval<R>())));+};++#else // defined(ASIO_HAS_DEDUCED_SUBMIT_MEMBER_TRAIT)++template <typename S, typename R, typename = void>+struct submit_member_trait :+ conditional<+ is_same<S, typename remove_reference<S>::type>::value+ && is_same<R, typename decay<R>::type>::value,+ typename conditional<+ is_same<S, typename add_const<S>::type>::value,+ no_submit_member,+ traits::submit_member<typename add_const<S>::type, R>+ >::type,+ traits::submit_member<+ typename remove_reference<S>::type,+ typename decay<R>::type>+ >::type+{+};++#endif // defined(ASIO_HAS_DEDUCED_SUBMIT_MEMBER_TRAIT)++} // namespace detail+namespace traits {++template <typename S, typename R, typename>+struct submit_member_default :+ detail::submit_member_trait<S, R>+{+};++template <typename S, typename R, typename>+struct submit_member :+ submit_member_default<S, R>+{+};++} // namespace traits+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_TRAITS_SUBMIT_MEMBER_HPP
link/modules/asio-standalone/asio/include/asio/ts/buffer.hpp view
@@ -2,7 +2,7 @@ // ts/buffer.hpp // ~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/ts/executor.hpp view
@@ -2,7 +2,7 @@ // ts/executor.hpp // ~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/ts/internet.hpp view
@@ -2,7 +2,7 @@ // ts/internet.hpp // ~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/ts/io_context.hpp view
@@ -2,7 +2,7 @@ // ts/io_context.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/ts/net.hpp view
@@ -2,7 +2,7 @@ // ts/net.hpp // ~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/ts/netfwd.hpp view
@@ -2,7 +2,7 @@ // ts/netfwd.hpp // ~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -16,8 +16,15 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"-#include "asio/detail/chrono.hpp" +#if defined(ASIO_HAS_CHRONO)+# include "asio/detail/chrono.hpp"+#endif // defined(ASIO_HAS_CHRONO)++#if defined(ASIO_HAS_BOOST_DATE_TIME)+# include "asio/detail/date_time_fwd.hpp"+#endif // defined(ASIO_HAS_BOOST_DATE_TIME)+ #if !defined(ASIO_USE_TS_EXECUTOR_AS_DEFAULT) #include "asio/execution/blocking.hpp" #include "asio/execution/outstanding_work.hpp"@@ -59,9 +66,20 @@ #if !defined(ASIO_EXECUTION_ANY_EXECUTOR_FWD_DECL) #define ASIO_EXECUTION_ANY_EXECUTOR_FWD_DECL +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+ template <typename... SupportableProperties> class any_executor; +#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename = void, typename = void, typename = void,+ typename = void, typename = void, typename = void,+ typename = void, typename = void, typename = void>+class any_executor;++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+ #endif // !defined(ASIO_EXECUTION_ANY_EXECUTOR_FWD_DECL) template <typename U>@@ -84,6 +102,13 @@ template <typename Clock> struct wait_traits; +#if defined(ASIO_HAS_BOOST_DATE_TIME)++template <typename Time>+struct time_traits;++#endif // defined(ASIO_HAS_BOOST_DATE_TIME)+ #if !defined(ASIO_BASIC_WAITABLE_TIMER_FWD_DECL) #define ASIO_BASIC_WAITABLE_TIMER_FWD_DECL @@ -94,6 +119,8 @@ #endif // !defined(ASIO_BASIC_WAITABLE_TIMER_FWD_DECL) +#if defined(ASIO_HAS_CHRONO)+ typedef basic_waitable_timer<chrono::system_clock> system_timer; typedef basic_waitable_timer<chrono::steady_clock> steady_timer;@@ -101,6 +128,8 @@ typedef basic_waitable_timer<chrono::high_resolution_clock> high_resolution_timer; +#endif // defined(ASIO_HAS_CHRONO)+ #if !defined(ASIO_BASIC_SOCKET_FWD_DECL) #define ASIO_BASIC_SOCKET_FWD_DECL @@ -139,8 +168,14 @@ // Forward declaration with defaulted arguments. template <typename Protocol,+#if defined(ASIO_HAS_BOOST_DATE_TIME) \+ || defined(GENERATING_DOCUMENTATION)+ typename Clock = boost::posix_time::ptime,+ typename WaitTraits = time_traits<Clock> >+#else typename Clock = chrono::steady_clock,- typename WaitTraits = wait_traits<Clock>>+ typename WaitTraits = wait_traits<Clock> >+#endif class basic_socket_streambuf; #endif // !defined(ASIO_BASIC_SOCKET_STREAMBUF_FWD_DECL)@@ -150,8 +185,14 @@ // Forward declaration with defaulted arguments. template <typename Protocol,+#if defined(ASIO_HAS_BOOST_DATE_TIME) \+ || defined(GENERATING_DOCUMENTATION)+ typename Clock = boost::posix_time::ptime,+ typename WaitTraits = time_traits<Clock> >+#else typename Clock = chrono::steady_clock,- typename WaitTraits = wait_traits<Clock>>+ typename WaitTraits = wait_traits<Clock> >+#endif class basic_socket_iostream; #endif // !defined(ASIO_BASIC_SOCKET_IOSTREAM_FWD_DECL)
link/modules/asio-standalone/asio/include/asio/ts/socket.hpp view
@@ -2,7 +2,7 @@ // ts/socket.hpp // ~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/ts/timer.hpp view
@@ -2,7 +2,7 @@ // ts/timer.hpp // ~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/unyield.hpp view
@@ -2,7 +2,7 @@ // unyield.hpp // ~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/use_awaitable.hpp view
@@ -2,7 +2,7 @@ // use_awaitable.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -53,7 +53,7 @@ struct use_awaitable_t { /// Default constructor.- constexpr use_awaitable_t(+ ASIO_CONSTEXPR use_awaitable_t( #if defined(ASIO_ENABLE_HANDLER_TRACKING) # if defined(ASIO_HAS_SOURCE_LOCATION) detail::source_location location = detail::source_location::current()@@ -75,7 +75,7 @@ } /// Constructor used to specify file name, line, and function name.- constexpr use_awaitable_t(const char* file_name,+ ASIO_CONSTEXPR use_awaitable_t(const char* file_name, int line, const char* function_name) #if defined(ASIO_ENABLE_HANDLER_TRACKING) : file_name_(file_name),@@ -101,13 +101,13 @@ /// Construct the adapted executor from the inner executor type. template <typename InnerExecutor1> executor_with_default(const InnerExecutor1& ex,- constraint_t<- conditional_t<+ typename constraint<+ conditional< !is_same<InnerExecutor1, executor_with_default>::value, is_convertible<InnerExecutor1, InnerExecutor>, false_type- >::value- > = 0) noexcept+ >::type::value+ >::type = 0) ASIO_NOEXCEPT : InnerExecutor(ex) { }@@ -115,21 +115,25 @@ /// Type alias to adapt an I/O object to use @c use_awaitable_t as its /// default completion token type.+#if defined(ASIO_HAS_ALIAS_TEMPLATES) \+ || defined(GENERATING_DOCUMENTATION) template <typename T> using as_default_on_t = typename T::template rebind_executor<- executor_with_default<typename T::executor_type>>::other;+ executor_with_default<typename T::executor_type> >::other;+#endif // defined(ASIO_HAS_ALIAS_TEMPLATES)+ // || defined(GENERATING_DOCUMENTATION) /// Function helper to adapt an I/O object to use @c use_awaitable_t as its /// default completion token type. template <typename T>- static typename decay_t<T>::template rebind_executor<- executor_with_default<typename decay_t<T>::executor_type>+ static typename decay<T>::type::template rebind_executor<+ executor_with_default<typename decay<T>::type::executor_type> >::other- as_default_on(T&& object)+ as_default_on(ASIO_MOVE_ARG(T) object) {- return typename decay_t<T>::template rebind_executor<- executor_with_default<typename decay_t<T>::executor_type>- >::other(static_cast<T&&>(object));+ return typename decay<T>::type::template rebind_executor<+ executor_with_default<typename decay<T>::type::executor_type>+ >::other(ASIO_MOVE_CAST(T)(object)); } #if defined(ASIO_ENABLE_HANDLER_TRACKING)@@ -145,9 +149,11 @@ * See the documentation for asio::use_awaitable_t for a usage example. */ #if defined(GENERATING_DOCUMENTATION)-ASIO_INLINE_VARIABLE constexpr use_awaitable_t<> use_awaitable;-#else-ASIO_INLINE_VARIABLE constexpr use_awaitable_t<> use_awaitable(0, 0, 0);+constexpr use_awaitable_t<> use_awaitable;+#elif defined(ASIO_HAS_CONSTEXPR)+constexpr use_awaitable_t<> use_awaitable(0, 0, 0);+#elif defined(ASIO_MSVC)+__declspec(selectany) use_awaitable_t<> use_awaitable(0, 0, 0); #endif } // namespace asio
link/modules/asio-standalone/asio/include/asio/use_future.hpp view
@@ -2,7 +2,7 @@ // use_future.hpp // ~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -54,7 +54,7 @@ * completes with an error_code indicating failure, it is converted into a * system_error and passed back to the caller via the future. */-template <typename Allocator = std::allocator<void>>+template <typename Allocator = std::allocator<void> > class use_future_t { public:@@ -63,7 +63,7 @@ typedef Allocator allocator_type; /// Construct using default-constructed allocator.- constexpr use_future_t()+ ASIO_CONSTEXPR use_future_t() { } @@ -73,6 +73,15 @@ { } +#if !defined(ASIO_NO_DEPRECATED)+ /// (Deprecated: Use rebind().) Specify an alternate allocator.+ template <typename OtherAllocator>+ use_future_t<OtherAllocator> operator[](const OtherAllocator& allocator) const+ {+ return use_future_t<OtherAllocator>(allocator);+ }+#endif // !defined(ASIO_NO_DEPRECATED)+ /// Specify an alternate allocator. template <typename OtherAllocator> use_future_t<OtherAllocator> rebind(const OtherAllocator& allocator) const@@ -90,7 +99,7 @@ /** * The @c package function is used to adapt a function object as a packaged * task. When this adapter is passed as a completion token to an asynchronous- * operation, the result of the function object is returned via a std::future.+ * operation, the result of the function object is retuned via a std::future. * * @par Example *@@ -107,16 +116,16 @@ #if defined(GENERATING_DOCUMENTATION) unspecified #else // defined(GENERATING_DOCUMENTATION)- detail::packaged_token<decay_t<Function>, Allocator>+ detail::packaged_token<typename decay<Function>::type, Allocator> #endif // defined(GENERATING_DOCUMENTATION)- operator()(Function&& f) const;+ operator()(ASIO_MOVE_ARG(Function) f) const; private: // Helper type to ensure that use_future can be constexpr default-constructed // even when std::allocator<void> can't be. struct std_allocator_void {- constexpr std_allocator_void()+ ASIO_CONSTEXPR std_allocator_void() { } @@ -126,9 +135,9 @@ } }; - conditional_t<+ typename conditional< is_same<std::allocator<void>, Allocator>::value,- std_allocator_void, Allocator> allocator_;+ std_allocator_void, Allocator>::type allocator_; }; /// A @ref completion_token object that causes an asynchronous operation to@@ -136,7 +145,11 @@ /** * See the documentation for asio::use_future_t for a usage example. */-ASIO_INLINE_VARIABLE constexpr use_future_t<> use_future;+#if defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)+constexpr use_future_t<> use_future;+#elif defined(ASIO_MSVC)+__declspec(selectany) use_future_t<> use_future;+#endif } // namespace asio
link/modules/asio-standalone/asio/include/asio/uses_executor.hpp view
@@ -2,7 +2,7 @@ // uses_executor.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -34,7 +34,7 @@ struct executor_arg_t { /// Constructor.- constexpr executor_arg_t() noexcept+ ASIO_CONSTEXPR executor_arg_t() ASIO_NOEXCEPT { } };@@ -45,7 +45,11 @@ * See asio::executor_arg_t and asio::uses_executor * for more information. */-ASIO_INLINE_VARIABLE constexpr executor_arg_t executor_arg;+#if defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)+constexpr executor_arg_t executor_arg;+#elif defined(ASIO_MSVC)+__declspec(selectany) executor_arg_t executor_arg;+#endif /// The uses_executor trait detects whether a type T has an associated executor /// that is convertible from type Executor.
link/modules/asio-standalone/asio/include/asio/version.hpp view
@@ -2,7 +2,7 @@ // version.hpp // ~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -18,6 +18,6 @@ // ASIO_VERSION % 100 is the sub-minor version // ASIO_VERSION / 100 % 1000 is the minor version // ASIO_VERSION / 100000 is the major version-#define ASIO_VERSION 103600 // 1.36.0+#define ASIO_VERSION 102800 // 1.28.0 #endif // ASIO_VERSION_HPP
link/modules/asio-standalone/asio/include/asio/wait_traits.hpp view
@@ -2,7 +2,7 @@ // wait_traits.hpp // ~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/windows/basic_object_handle.hpp view
@@ -2,7 +2,7 @@ // windows/basic_object_handle.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2011 Boris Schaeling (boris@highscore.de) // // Distributed under the Boost Software License, Version 1.0. (See accompanying@@ -21,7 +21,6 @@ #if defined(ASIO_HAS_WINDOWS_OBJECT_HANDLE) \ || defined(GENERATING_DOCUMENTATION) -#include <utility> #include "asio/any_io_executor.hpp" #include "asio/async_result.hpp" #include "asio/detail/io_object_impl.hpp"@@ -30,6 +29,10 @@ #include "asio/error.hpp" #include "asio/execution_context.hpp" +#if defined(ASIO_HAS_MOVE)+# include <utility>+#endif // defined(ASIO_HAS_MOVE)+ #include "asio/detail/push_options.hpp" namespace asio {@@ -96,10 +99,10 @@ */ template <typename ExecutionContext> explicit basic_object_handle(ExecutionContext& context,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- > = defaulted_constraint())+ >::type = defaulted_constraint()) : impl_(0, 0, context) { }@@ -142,9 +145,9 @@ template <typename ExecutionContext> basic_object_handle(ExecutionContext& context, const native_handle_type& native_handle,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- > = 0)+ >::type = 0) : impl_(0, 0, context) { asio::error_code ec;@@ -152,6 +155,7 @@ asio::detail::throw_error(ec, "assign"); } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move-construct an object handle from another. /** * This constructor moves an object handle from one object to another.@@ -202,10 +206,10 @@ */ template<typename Executor1> basic_object_handle(basic_object_handle<Executor1>&& other,- constraint_t<+ typename constraint< is_convertible<Executor1, Executor>::value, defaulted_constraint- > = defaulted_constraint())+ >::type = defaulted_constraint()) : impl_(std::move(other.impl_)) { }@@ -222,17 +226,18 @@ * constructor. */ template<typename Executor1>- constraint_t<+ typename constraint< is_convertible<Executor1, Executor>::value, basic_object_handle&- > operator=(basic_object_handle<Executor1>&& other)+ >::type operator=(basic_object_handle<Executor1>&& other) { impl_ = std::move(other.impl_); return *this; }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Get the executor associated with the object.- const executor_type& get_executor() noexcept+ const executor_type& get_executor() ASIO_NOEXCEPT { return impl_.get_executor(); }@@ -415,19 +420,22 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code) @endcode */ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code))- WaitToken = default_completion_token_t<executor_type>>- auto async_wait(- WaitToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ WaitToken ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WaitToken,+ void (asio::error_code))+ async_wait(+ ASIO_MOVE_ARG(WaitToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<WaitToken, void (asio::error_code)>(- declval<initiate_async_wait>(), token))+ declval<initiate_async_wait>(), token))) { return async_initiate<WaitToken, void (asio::error_code)>( initiate_async_wait(this), token);@@ -435,8 +443,8 @@ private: // Disallow copying and assignment.- basic_object_handle(const basic_object_handle&) = delete;- basic_object_handle& operator=(const basic_object_handle&) = delete;+ basic_object_handle(const basic_object_handle&) ASIO_DELETED;+ basic_object_handle& operator=(const basic_object_handle&) ASIO_DELETED; class initiate_async_wait {@@ -448,13 +456,13 @@ { } - const executor_type& get_executor() const noexcept+ const executor_type& get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template <typename WaitHandler>- void operator()(WaitHandler&& handler) const+ void operator()(ASIO_MOVE_ARG(WaitHandler) handler) const { // If you get an error on the following line it means that your handler // does not meet the documented type requirements for a WaitHandler.
link/modules/asio-standalone/asio/include/asio/windows/basic_overlapped_handle.hpp view
@@ -2,7 +2,7 @@ // windows/basic_overlapped_handle.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -22,7 +22,6 @@ || defined(GENERATING_DOCUMENTATION) #include <cstddef>-#include <utility> #include "asio/any_io_executor.hpp" #include "asio/async_result.hpp" #include "asio/detail/io_object_impl.hpp"@@ -31,6 +30,10 @@ #include "asio/error.hpp" #include "asio/execution_context.hpp" +#if defined(ASIO_HAS_MOVE)+# include <utility>+#endif // defined(ASIO_HAS_MOVE)+ #include "asio/detail/push_options.hpp" namespace asio {@@ -96,10 +99,10 @@ */ template <typename ExecutionContext> explicit basic_overlapped_handle(ExecutionContext& context,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- > = defaulted_constraint())+ >::type = defaulted_constraint()) : impl_(0, 0, context) { }@@ -142,9 +145,9 @@ template <typename ExecutionContext> basic_overlapped_handle(ExecutionContext& context, const native_handle_type& native_handle,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- > = 0)+ >::type = 0) : impl_(0, 0, context) { asio::error_code ec;@@ -152,6 +155,7 @@ asio::detail::throw_error(ec, "assign"); } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move-construct an overlapped handle from another. /** * This constructor moves a handle from one object to another.@@ -203,10 +207,10 @@ */ template<typename Executor1> basic_overlapped_handle(basic_overlapped_handle<Executor1>&& other,- constraint_t<+ typename constraint< is_convertible<Executor1, Executor>::value, defaulted_constraint- > = defaulted_constraint())+ >::type = defaulted_constraint()) : impl_(std::move(other.impl_)) { }@@ -223,17 +227,18 @@ * constructor. */ template<typename Executor1>- constraint_t<+ typename constraint< is_convertible<Executor1, Executor>::value, basic_overlapped_handle&- > operator=(basic_overlapped_handle<Executor1>&& other)+ >::type operator=(basic_overlapped_handle<Executor1>&& other) { impl_ = std::move(other.impl_); return *this; }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Get the executor associated with the object.- const executor_type& get_executor() noexcept+ const executor_type& get_executor() ASIO_NOEXCEPT { return impl_.get_executor(); }@@ -438,9 +443,9 @@ private: // Disallow copying and assignment.- basic_overlapped_handle(const basic_overlapped_handle&) = delete;+ basic_overlapped_handle(const basic_overlapped_handle&) ASIO_DELETED; basic_overlapped_handle& operator=(- const basic_overlapped_handle&) = delete;+ const basic_overlapped_handle&) ASIO_DELETED; }; } // namespace windows
link/modules/asio-standalone/asio/include/asio/windows/basic_random_access_handle.hpp view
@@ -2,7 +2,7 @@ // windows/basic_random_access_handle.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -88,10 +88,10 @@ */ template <typename ExecutionContext> explicit basic_random_access_handle(ExecutionContext& context,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- > = defaulted_constraint())+ >::type = defaulted_constraint()) : basic_overlapped_handle<Executor>(context) { }@@ -131,13 +131,14 @@ template <typename ExecutionContext> basic_random_access_handle(ExecutionContext& context, const native_handle_type& handle,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- > = 0)+ >::type = 0) : basic_overlapped_handle<Executor>(context, handle) { } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move-construct a random-access handle from another. /** * This constructor moves a random-access handle from one object to another.@@ -186,10 +187,10 @@ */ template<typename Executor1> basic_random_access_handle(basic_random_access_handle<Executor1>&& other,- constraint_t<+ typename constraint< is_convertible<Executor1, Executor>::value, defaulted_constraint- > = defaulted_constraint())+ >::type = defaulted_constraint()) : basic_overlapped_handle<Executor>(std::move(other)) { }@@ -208,14 +209,15 @@ * constructor. */ template<typename Executor1>- constraint_t<+ typename constraint< is_convertible<Executor1, Executor>::value, basic_random_access_handle&- > operator=(basic_random_access_handle<Executor1>&& other)+ >::type operator=(basic_random_access_handle<Executor1>&& other) { basic_overlapped_handle<Executor>::operator=(std::move(other)); return *this; }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Write some data to the handle at the specified offset. /**@@ -308,7 +310,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -338,13 +340,18 @@ */ template <typename ConstBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) WriteToken = default_completion_token_t<executor_type>>- auto async_write_some_at(uint64_t offset, const ConstBufferSequence& buffers,- WriteToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ std::size_t)) WriteToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+ void (asio::error_code, std::size_t))+ async_write_some_at(uint64_t offset,+ const ConstBufferSequence& buffers,+ ASIO_MOVE_ARG(WriteToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<WriteToken, void (asio::error_code, std::size_t)>(- declval<initiate_async_write_some_at>(), token, offset, buffers))+ declval<initiate_async_write_some_at>(), token, offset, buffers))) { return async_initiate<WriteToken, void (asio::error_code, std::size_t)>(@@ -444,7 +451,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -475,13 +482,18 @@ */ template <typename MutableBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) ReadToken = default_completion_token_t<executor_type>>- auto async_read_some_at(uint64_t offset, const MutableBufferSequence& buffers,- ReadToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ std::size_t)) ReadToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+ async_read_some_at(uint64_t offset,+ const MutableBufferSequence& buffers,+ ASIO_MOVE_ARG(ReadToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<ReadToken, void (asio::error_code, std::size_t)>(- declval<initiate_async_read_some_at>(), token, offset, buffers))+ declval<initiate_async_read_some_at>(), token, offset, buffers))) { return async_initiate<ReadToken, void (asio::error_code, std::size_t)>(@@ -499,13 +511,13 @@ { } - const executor_type& get_executor() const noexcept+ const executor_type& get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template <typename WriteHandler, typename ConstBufferSequence>- void operator()(WriteHandler&& handler,+ void operator()(ASIO_MOVE_ARG(WriteHandler) handler, uint64_t offset, const ConstBufferSequence& buffers) const { // If you get an error on the following line it means that your handler@@ -532,13 +544,13 @@ { } - const executor_type& get_executor() const noexcept+ const executor_type& get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template <typename ReadHandler, typename MutableBufferSequence>- void operator()(ReadHandler&& handler,+ void operator()(ASIO_MOVE_ARG(ReadHandler) handler, uint64_t offset, const MutableBufferSequence& buffers) const { // If you get an error on the following line it means that your handler
link/modules/asio-standalone/asio/include/asio/windows/basic_stream_handle.hpp view
@@ -2,7 +2,7 @@ // windows/basic_stream_handle.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -91,10 +91,10 @@ */ template <typename ExecutionContext> explicit basic_stream_handle(ExecutionContext& context,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- > = defaulted_constraint())+ >::type = defaulted_constraint()) : basic_overlapped_handle<Executor>(context) { }@@ -133,13 +133,14 @@ template <typename ExecutionContext> basic_stream_handle(ExecutionContext& context, const native_handle_type& handle,- constraint_t<+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- > = 0)+ >::type = 0) : basic_overlapped_handle<Executor>(context, handle) { } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move-construct a stream handle from another. /** * This constructor moves a stream handle from one object to another.@@ -186,10 +187,10 @@ */ template<typename Executor1> basic_stream_handle(basic_stream_handle<Executor1>&& other,- constraint_t<+ typename constraint< is_convertible<Executor1, Executor>::value, defaulted_constraint- > = defaulted_constraint())+ >::type = defaulted_constraint()) : basic_overlapped_handle<Executor>(std::move(other)) { }@@ -206,14 +207,15 @@ * constructor. */ template<typename Executor1>- constraint_t<+ typename constraint< is_convertible<Executor1, Executor>::value, basic_stream_handle&- > operator=(basic_stream_handle<Executor1>&& other)+ >::type operator=(basic_stream_handle<Executor1>&& other) { basic_overlapped_handle<Executor>::operator=(std::move(other)); return *this; }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Write some data to the handle. /**@@ -299,7 +301,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -329,13 +331,17 @@ */ template <typename ConstBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) WriteToken = default_completion_token_t<executor_type>>- auto async_write_some(const ConstBufferSequence& buffers,- WriteToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ std::size_t)) WriteToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+ void (asio::error_code, std::size_t))+ async_write_some(const ConstBufferSequence& buffers,+ ASIO_MOVE_ARG(WriteToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<WriteToken, void (asio::error_code, std::size_t)>(- declval<initiate_async_write_some>(), token, buffers))+ declval<initiate_async_write_some>(), token, buffers))) { return async_initiate<WriteToken, void (asio::error_code, std::size_t)>(@@ -428,7 +434,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -459,13 +465,17 @@ */ template <typename MutableBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) ReadToken = default_completion_token_t<executor_type>>- auto async_read_some(const MutableBufferSequence& buffers,- ReadToken&& token = default_completion_token_t<executor_type>())- -> decltype(+ std::size_t)) ReadToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+ ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+ void (asio::error_code, std::size_t))+ async_read_some(const MutableBufferSequence& buffers,+ ASIO_MOVE_ARG(ReadToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<ReadToken, void (asio::error_code, std::size_t)>(- declval<initiate_async_read_some>(), token, buffers))+ declval<initiate_async_read_some>(), token, buffers))) { return async_initiate<ReadToken, void (asio::error_code, std::size_t)>(@@ -483,13 +493,13 @@ { } - const executor_type& get_executor() const noexcept+ const executor_type& get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template <typename WriteHandler, typename ConstBufferSequence>- void operator()(WriteHandler&& handler,+ void operator()(ASIO_MOVE_ARG(WriteHandler) handler, const ConstBufferSequence& buffers) const { // If you get an error on the following line it means that your handler@@ -516,13 +526,13 @@ { } - const executor_type& get_executor() const noexcept+ const executor_type& get_executor() const ASIO_NOEXCEPT { return self_->get_executor(); } template <typename ReadHandler, typename MutableBufferSequence>- void operator()(ReadHandler&& handler,+ void operator()(ASIO_MOVE_ARG(ReadHandler) handler, const MutableBufferSequence& buffers) const { // If you get an error on the following line it means that your handler
link/modules/asio-standalone/asio/include/asio/windows/object_handle.hpp view
@@ -2,7 +2,7 @@ // windows/object_handle.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2011 Boris Schaeling (boris@highscore.de) // // Distributed under the Boost Software License, Version 1.0. (See accompanying
link/modules/asio-standalone/asio/include/asio/windows/overlapped_handle.hpp view
@@ -2,7 +2,7 @@ // windows/overlapped_handle.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/windows/overlapped_ptr.hpp view
@@ -2,7 +2,7 @@ // windows/overlapped_ptr.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -51,23 +51,23 @@ /// Construct an overlapped_ptr to contain the specified handler. template <typename ExecutionContext, typename Handler> explicit overlapped_ptr(ExecutionContext& context,- Handler&& handler,- constraint_t<+ ASIO_MOVE_ARG(Handler) handler,+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- > = 0)- : impl_(context.get_executor(), static_cast<Handler&&>(handler))+ >::type = 0)+ : impl_(context.get_executor(), ASIO_MOVE_CAST(Handler)(handler)) { } /// Construct an overlapped_ptr to contain the specified handler. template <typename Executor, typename Handler> explicit overlapped_ptr(const Executor& ex,- Handler&& handler,- constraint_t<+ ASIO_MOVE_ARG(Handler) handler,+ typename constraint< execution::is_executor<Executor>::value || is_executor<Executor>::value- > = 0)- : impl_(ex, static_cast<Handler&&>(handler))+ >::type = 0)+ : impl_(ex, ASIO_MOVE_CAST(Handler)(handler)) { } @@ -85,24 +85,24 @@ /// Reset to contain the specified handler, freeing any current OVERLAPPED /// object. template <typename ExecutionContext, typename Handler>- void reset(ExecutionContext& context, Handler&& handler,- constraint_t<+ void reset(ExecutionContext& context, ASIO_MOVE_ARG(Handler) handler,+ typename constraint< is_convertible<ExecutionContext&, execution_context&>::value- > = 0)+ >::type = 0) {- impl_.reset(context.get_executor(), static_cast<Handler&&>(handler));+ impl_.reset(context.get_executor(), ASIO_MOVE_CAST(Handler)(handler)); } /// Reset to contain the specified handler, freeing any current OVERLAPPED /// object. template <typename Executor, typename Handler>- void reset(const Executor& ex, Handler&& handler,- constraint_t<+ void reset(const Executor& ex, ASIO_MOVE_ARG(Handler) handler,+ typename constraint< execution::is_executor<Executor>::value || is_executor<Executor>::value- > = 0)+ >::type = 0) {- impl_.reset(ex, static_cast<Handler&&>(handler));+ impl_.reset(ex, ASIO_MOVE_CAST(Handler)(handler)); } /// Get the contained OVERLAPPED object.
link/modules/asio-standalone/asio/include/asio/windows/random_access_handle.hpp view
@@ -2,7 +2,7 @@ // windows/random_access_handle.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/windows/stream_handle.hpp view
@@ -2,7 +2,7 @@ // windows/stream_handle.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/writable_pipe.hpp view
@@ -2,7 +2,7 @@ // writable_pipe.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/include/asio/write.hpp view
@@ -2,7 +2,7 @@ // write.hpp // ~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -85,9 +85,9 @@ */ template <typename SyncWriteStream, typename ConstBufferSequence> std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers,- constraint_t<+ typename constraint< is_const_buffer_sequence<ConstBufferSequence>::value- > = 0);+ >::type = 0); /// Write all of the supplied data to a stream before returning. /**@@ -128,9 +128,9 @@ template <typename SyncWriteStream, typename ConstBufferSequence> std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers, asio::error_code& ec,- constraint_t<+ typename constraint< is_const_buffer_sequence<ConstBufferSequence>::value- > = 0);+ >::type = 0); /// Write a certain amount of data to a stream before returning. /**@@ -182,12 +182,9 @@ typename CompletionCondition> std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers, CompletionCondition completion_condition,- constraint_t<+ typename constraint< is_const_buffer_sequence<ConstBufferSequence>::value- > = 0,- constraint_t<- is_completion_condition<CompletionCondition>::value- > = 0);+ >::type = 0); /// Write a certain amount of data to a stream before returning. /**@@ -232,12 +229,9 @@ typename CompletionCondition> std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers, CompletionCondition completion_condition, asio::error_code& ec,- constraint_t<+ typename constraint< is_const_buffer_sequence<ConstBufferSequence>::value- > = 0,- constraint_t<- is_completion_condition<CompletionCondition>::value- > = 0);+ >::type = 0); #if !defined(ASIO_NO_DYNAMIC_BUFFER_V1) @@ -270,13 +264,13 @@ */ template <typename SyncWriteStream, typename DynamicBuffer_v1> std::size_t write(SyncWriteStream& s,- DynamicBuffer_v1&& buffers,- constraint_t<- is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value- > = 0,- constraint_t<- !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value- > = 0);+ ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+ typename constraint<+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+ >::type = 0,+ typename constraint<+ !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+ >::type = 0); /// Write all of the supplied data to a stream before returning. /**@@ -307,14 +301,14 @@ */ template <typename SyncWriteStream, typename DynamicBuffer_v1> std::size_t write(SyncWriteStream& s,- DynamicBuffer_v1&& buffers,+ ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, asio::error_code& ec,- constraint_t<- is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value- > = 0,- constraint_t<- !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value- > = 0);+ typename constraint<+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+ >::type = 0,+ typename constraint<+ !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+ >::type = 0); /// Write a certain amount of data to a stream before returning. /**@@ -355,17 +349,14 @@ template <typename SyncWriteStream, typename DynamicBuffer_v1, typename CompletionCondition> std::size_t write(SyncWriteStream& s,- DynamicBuffer_v1&& buffers,+ ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, CompletionCondition completion_condition,- constraint_t<- is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value- > = 0,- constraint_t<- !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value- > = 0,- constraint_t<- is_completion_condition<CompletionCondition>::value- > = 0);+ typename constraint<+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+ >::type = 0,+ typename constraint<+ !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+ >::type = 0); /// Write a certain amount of data to a stream before returning. /**@@ -407,17 +398,14 @@ template <typename SyncWriteStream, typename DynamicBuffer_v1, typename CompletionCondition> std::size_t write(SyncWriteStream& s,- DynamicBuffer_v1&& buffers,+ ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, CompletionCondition completion_condition, asio::error_code& ec,- constraint_t<- is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value- > = 0,- constraint_t<- !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value- > = 0,- constraint_t<- is_completion_condition<CompletionCondition>::value- > = 0);+ typename constraint<+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+ >::type = 0,+ typename constraint<+ !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+ >::type = 0); #if !defined(ASIO_NO_EXTENSIONS) #if !defined(ASIO_NO_IOSTREAM)@@ -519,10 +507,7 @@ template <typename SyncWriteStream, typename Allocator, typename CompletionCondition> std::size_t write(SyncWriteStream& s, basic_streambuf<Allocator>& b,- CompletionCondition completion_condition,- constraint_t<- is_completion_condition<CompletionCondition>::value- > = 0);+ CompletionCondition completion_condition); /// Write a certain amount of data to a stream before returning. /**@@ -563,10 +548,7 @@ template <typename SyncWriteStream, typename Allocator, typename CompletionCondition> std::size_t write(SyncWriteStream& s, basic_streambuf<Allocator>& b,- CompletionCondition completion_condition, asio::error_code& ec,- constraint_t<- is_completion_condition<CompletionCondition>::value- > = 0);+ CompletionCondition completion_condition, asio::error_code& ec); #endif // !defined(ASIO_NO_IOSTREAM) #endif // !defined(ASIO_NO_EXTENSIONS)@@ -601,9 +583,9 @@ */ template <typename SyncWriteStream, typename DynamicBuffer_v2> std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers,- constraint_t<+ typename constraint< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- > = 0);+ >::type = 0); /// Write all of the supplied data to a stream before returning. /**@@ -635,9 +617,9 @@ template <typename SyncWriteStream, typename DynamicBuffer_v2> std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers, asio::error_code& ec,- constraint_t<+ typename constraint< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- > = 0);+ >::type = 0); /// Write a certain amount of data to a stream before returning. /**@@ -679,12 +661,9 @@ typename CompletionCondition> std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers, CompletionCondition completion_condition,- constraint_t<+ typename constraint< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- > = 0,- constraint_t<- is_completion_condition<CompletionCondition>::value- > = 0);+ >::type = 0); /// Write a certain amount of data to a stream before returning. /**@@ -727,12 +706,9 @@ typename CompletionCondition> std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers, CompletionCondition completion_condition, asio::error_code& ec,- constraint_t<+ typename constraint< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- > = 0,- constraint_t<- is_completion_condition<CompletionCondition>::value- > = 0);+ >::type = 0); /*@}*/ /**@@ -786,7 +762,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -814,27 +790,22 @@ template <typename AsyncWriteStream, typename ConstBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, std::size_t)) WriteToken- = default_completion_token_t<typename AsyncWriteStream::executor_type>>-inline auto async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers,- WriteToken&& token- = default_completion_token_t<typename AsyncWriteStream::executor_type>(),- constraint_t<+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+ typename AsyncWriteStream::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+ void (asio::error_code, std::size_t))+async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers,+ ASIO_MOVE_ARG(WriteToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(+ typename AsyncWriteStream::executor_type),+ typename constraint< is_const_buffer_sequence<ConstBufferSequence>::value- > = 0,- constraint_t<- !is_completion_condition<decay_t<WriteToken>>::value- > = 0)- -> decltype(+ >::type = 0)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<WriteToken, void (asio::error_code, std::size_t)>(- declval<detail::initiate_async_write<AsyncWriteStream>>(),- token, buffers, transfer_all()))-{- return async_initiate<WriteToken,- void (asio::error_code, std::size_t)>(- detail::initiate_async_write<AsyncWriteStream>(s),- token, buffers, transfer_all());-}+ declval<detail::initiate_async_write<AsyncWriteStream> >(),+ token, buffers, transfer_all()))); /// Start an asynchronous operation to write a certain amount of data to a /// stream.@@ -893,7 +864,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -922,31 +893,21 @@ template <typename AsyncWriteStream, typename ConstBufferSequence, typename CompletionCondition, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) WriteToken- = default_completion_token_t<typename AsyncWriteStream::executor_type>>-inline auto async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers,+ std::size_t)) WriteToken>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+ void (asio::error_code, std::size_t))+async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers, CompletionCondition completion_condition,- WriteToken&& token- = default_completion_token_t<typename AsyncWriteStream::executor_type>(),- constraint_t<+ ASIO_MOVE_ARG(WriteToken) token,+ typename constraint< is_const_buffer_sequence<ConstBufferSequence>::value- > = 0,- constraint_t<- is_completion_condition<CompletionCondition>::value- > = 0)- -> decltype(+ >::type = 0)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<WriteToken, void (asio::error_code, std::size_t)>(- declval<detail::initiate_async_write<AsyncWriteStream>>(),+ declval<detail::initiate_async_write<AsyncWriteStream> >(), token, buffers,- static_cast<CompletionCondition&&>(completion_condition)))-{- return async_initiate<WriteToken,- void (asio::error_code, std::size_t)>(- detail::initiate_async_write<AsyncWriteStream>(s),- token, buffers,- static_cast<CompletionCondition&&>(completion_condition));-}+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition)))); #if !defined(ASIO_NO_DYNAMIC_BUFFER_V1) @@ -993,7 +954,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -1012,32 +973,27 @@ template <typename AsyncWriteStream, typename DynamicBuffer_v1, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, std::size_t)) WriteToken- = default_completion_token_t<typename AsyncWriteStream::executor_type>>-inline auto async_write(AsyncWriteStream& s, DynamicBuffer_v1&& buffers,- WriteToken&& token- = default_completion_token_t<typename AsyncWriteStream::executor_type>(),- constraint_t<- is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value- > = 0,- constraint_t<- !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value- > = 0,- constraint_t<- !is_completion_condition<decay_t<WriteToken>>::value- > = 0)- -> decltype(+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+ typename AsyncWriteStream::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+ void (asio::error_code, std::size_t))+async_write(AsyncWriteStream& s,+ ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+ ASIO_MOVE_ARG(WriteToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(+ typename AsyncWriteStream::executor_type),+ typename constraint<+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+ >::type = 0,+ typename constraint<+ !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+ >::type = 0)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<WriteToken, void (asio::error_code, std::size_t)>(- declval<detail::initiate_async_write_dynbuf_v1<AsyncWriteStream>>(),- token, static_cast<DynamicBuffer_v1&&>(buffers),- transfer_all()))-{- return async_initiate<WriteToken,- void (asio::error_code, std::size_t)>(- detail::initiate_async_write_dynbuf_v1<AsyncWriteStream>(s),- token, static_cast<DynamicBuffer_v1&&>(buffers),- transfer_all());-}+ declval<detail::initiate_async_write_dynbuf_v1<AsyncWriteStream> >(),+ token, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+ transfer_all()))); /// Start an asynchronous operation to write a certain amount of data to a /// stream.@@ -1096,7 +1052,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -1115,34 +1071,25 @@ template <typename AsyncWriteStream, typename DynamicBuffer_v1, typename CompletionCondition, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) WriteToken- = default_completion_token_t<typename AsyncWriteStream::executor_type>>-inline auto async_write(AsyncWriteStream& s, DynamicBuffer_v1&& buffers,+ std::size_t)) WriteToken>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+ void (asio::error_code, std::size_t))+async_write(AsyncWriteStream& s,+ ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, CompletionCondition completion_condition,- WriteToken&& token- = default_completion_token_t<typename AsyncWriteStream::executor_type>(),- constraint_t<- is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value- > = 0,- constraint_t<- !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value- > = 0,- constraint_t<- is_completion_condition<CompletionCondition>::value- > = 0)- -> decltype(+ ASIO_MOVE_ARG(WriteToken) token,+ typename constraint<+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+ >::type = 0,+ typename constraint<+ !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+ >::type = 0)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<WriteToken, void (asio::error_code, std::size_t)>(- declval<detail::initiate_async_write_dynbuf_v1<AsyncWriteStream>>(),- token, static_cast<DynamicBuffer_v1&&>(buffers),- static_cast<CompletionCondition&&>(completion_condition)))-{- return async_initiate<WriteToken,- void (asio::error_code, std::size_t)>(- detail::initiate_async_write_dynbuf_v1<AsyncWriteStream>(s),- token, static_cast<DynamicBuffer_v1&&>(buffers),- static_cast<CompletionCondition&&>(completion_condition));-}+ declval<detail::initiate_async_write_dynbuf_v1<AsyncWriteStream> >(),+ token, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition)))); #if !defined(ASIO_NO_EXTENSIONS) #if !defined(ASIO_NO_IOSTREAM)@@ -1188,7 +1135,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -1207,24 +1154,17 @@ template <typename AsyncWriteStream, typename Allocator, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, std::size_t)) WriteToken- = default_completion_token_t<typename AsyncWriteStream::executor_type>>-inline auto async_write(AsyncWriteStream& s, basic_streambuf<Allocator>& b,- WriteToken&& token- = default_completion_token_t<typename AsyncWriteStream::executor_type>(),- constraint_t<- !is_completion_condition<decay_t<WriteToken>>::value- > = 0)- -> decltype(- async_initiate<WriteToken,- void (asio::error_code, std::size_t)>(- declval<detail::initiate_async_write_dynbuf_v1<AsyncWriteStream>>(),- token, basic_streambuf_ref<Allocator>(b), transfer_all()))-{- return async_initiate<WriteToken,- void (asio::error_code, std::size_t)>(- detail::initiate_async_write_dynbuf_v1<AsyncWriteStream>(s),- token, basic_streambuf_ref<Allocator>(b), transfer_all());-}+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+ typename AsyncWriteStream::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+ void (asio::error_code, std::size_t))+async_write(AsyncWriteStream& s, basic_streambuf<Allocator>& b,+ ASIO_MOVE_ARG(WriteToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(+ typename AsyncWriteStream::executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_write(s, basic_streambuf_ref<Allocator>(b),+ ASIO_MOVE_CAST(WriteToken)(token)))); /// Start an asynchronous operation to write a certain amount of data to a /// stream.@@ -1281,7 +1221,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -1300,28 +1240,16 @@ template <typename AsyncWriteStream, typename Allocator, typename CompletionCondition, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) WriteToken- = default_completion_token_t<typename AsyncWriteStream::executor_type>>-inline auto async_write(AsyncWriteStream& s, basic_streambuf<Allocator>& b,+ std::size_t)) WriteToken>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+ void (asio::error_code, std::size_t))+async_write(AsyncWriteStream& s, basic_streambuf<Allocator>& b, CompletionCondition completion_condition,- WriteToken&& token- = default_completion_token_t<typename AsyncWriteStream::executor_type>(),- constraint_t<- is_completion_condition<CompletionCondition>::value- > = 0)- -> decltype(- async_initiate<WriteToken,- void (asio::error_code, std::size_t)>(- declval<detail::initiate_async_write_dynbuf_v1<AsyncWriteStream>>(),- token, basic_streambuf_ref<Allocator>(b),- static_cast<CompletionCondition&&>(completion_condition)))-{- return async_initiate<WriteToken,- void (asio::error_code, std::size_t)>(- detail::initiate_async_write_dynbuf_v1<AsyncWriteStream>(s),- token, basic_streambuf_ref<Allocator>(b),- static_cast<CompletionCondition&&>(completion_condition));-}+ ASIO_MOVE_ARG(WriteToken) token)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ async_write(s, basic_streambuf_ref<Allocator>(b),+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition),+ ASIO_MOVE_CAST(WriteToken)(token)))); #endif // !defined(ASIO_NO_IOSTREAM) #endif // !defined(ASIO_NO_EXTENSIONS)@@ -1370,7 +1298,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -1389,29 +1317,23 @@ template <typename AsyncWriteStream, typename DynamicBuffer_v2, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, std::size_t)) WriteToken- = default_completion_token_t<typename AsyncWriteStream::executor_type>>-inline auto async_write(AsyncWriteStream& s, DynamicBuffer_v2 buffers,- WriteToken&& token- = default_completion_token_t<typename AsyncWriteStream::executor_type>(),- constraint_t<+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+ typename AsyncWriteStream::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+ void (asio::error_code, std::size_t))+async_write(AsyncWriteStream& s, DynamicBuffer_v2 buffers,+ ASIO_MOVE_ARG(WriteToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(+ typename AsyncWriteStream::executor_type),+ typename constraint< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- > = 0,- constraint_t<- !is_completion_condition<decay_t<WriteToken>>::value- > = 0)- -> decltype(+ >::type = 0)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<WriteToken, void (asio::error_code, std::size_t)>(- declval<detail::initiate_async_write_dynbuf_v2<AsyncWriteStream>>(),- token, static_cast<DynamicBuffer_v2&&>(buffers),- transfer_all()))-{- return async_initiate<WriteToken,- void (asio::error_code, std::size_t)>(- detail::initiate_async_write_dynbuf_v2<AsyncWriteStream>(s),- token, static_cast<DynamicBuffer_v2&&>(buffers),- transfer_all());-}+ declval<detail::initiate_async_write_dynbuf_v2<AsyncWriteStream> >(),+ token, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+ transfer_all()))); /// Start an asynchronous operation to write a certain amount of data to a /// stream.@@ -1470,7 +1392,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -1489,31 +1411,21 @@ template <typename AsyncWriteStream, typename DynamicBuffer_v2, typename CompletionCondition, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) WriteToken- = default_completion_token_t<typename AsyncWriteStream::executor_type>>-inline auto async_write(AsyncWriteStream& s, DynamicBuffer_v2 buffers,+ std::size_t)) WriteToken>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+ void (asio::error_code, std::size_t))+async_write(AsyncWriteStream& s, DynamicBuffer_v2 buffers, CompletionCondition completion_condition,- WriteToken&& token- = default_completion_token_t<typename AsyncWriteStream::executor_type>(),- constraint_t<+ ASIO_MOVE_ARG(WriteToken) token,+ typename constraint< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- > = 0,- constraint_t<- is_completion_condition<CompletionCondition>::value- > = 0)- -> decltype(+ >::type = 0)+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<WriteToken, void (asio::error_code, std::size_t)>(- declval<detail::initiate_async_write_dynbuf_v2<AsyncWriteStream>>(),- token, static_cast<DynamicBuffer_v2&&>(buffers),- static_cast<CompletionCondition&&>(completion_condition)))-{- return async_initiate<WriteToken,- void (asio::error_code, std::size_t)>(- detail::initiate_async_write_dynbuf_v2<AsyncWriteStream>(s),- token, static_cast<DynamicBuffer_v2&&>(buffers),- static_cast<CompletionCondition&&>(completion_condition));-}+ declval<detail::initiate_async_write_dynbuf_v2<AsyncWriteStream> >(),+ token, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition)))); /*@}*/
link/modules/asio-standalone/asio/include/asio/write_at.hpp view
@@ -2,7 +2,7 @@ // write_at.hpp // ~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -187,10 +187,7 @@ typename CompletionCondition> std::size_t write_at(SyncRandomAccessWriteDevice& d, uint64_t offset, const ConstBufferSequence& buffers,- CompletionCondition completion_condition,- constraint_t<- is_completion_condition<CompletionCondition>::value- > = 0);+ CompletionCondition completion_condition); /// Write a certain amount of data at a specified offset before returning. /**@@ -238,10 +235,7 @@ typename CompletionCondition> std::size_t write_at(SyncRandomAccessWriteDevice& d, uint64_t offset, const ConstBufferSequence& buffers,- CompletionCondition completion_condition, asio::error_code& ec,- constraint_t<- is_completion_condition<CompletionCondition>::value- > = 0);+ CompletionCondition completion_condition, asio::error_code& ec); #if !defined(ASIO_NO_EXTENSIONS) #if !defined(ASIO_NO_IOSTREAM)@@ -354,10 +348,7 @@ template <typename SyncRandomAccessWriteDevice, typename Allocator, typename CompletionCondition> std::size_t write_at(SyncRandomAccessWriteDevice& d, uint64_t offset,- basic_streambuf<Allocator>& b, CompletionCondition completion_condition,- constraint_t<- is_completion_condition<CompletionCondition>::value- > = 0);+ basic_streambuf<Allocator>& b, CompletionCondition completion_condition); /// Write a certain amount of data at a specified offset before returning. /**@@ -400,12 +391,9 @@ */ template <typename SyncRandomAccessWriteDevice, typename Allocator, typename CompletionCondition>-std::size_t write_at(SyncRandomAccessWriteDevice& d,- uint64_t offset, basic_streambuf<Allocator>& b,- CompletionCondition completion_condition, asio::error_code& ec,- constraint_t<- is_completion_condition<CompletionCondition>::value- > = 0);+std::size_t write_at(SyncRandomAccessWriteDevice& d, uint64_t offset,+ basic_streambuf<Allocator>& b, CompletionCondition completion_condition,+ asio::error_code& ec); #endif // !defined(ASIO_NO_IOSTREAM) #endif // !defined(ASIO_NO_EXTENSIONS)@@ -468,7 +456,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -495,27 +483,22 @@ */ template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) WriteToken = default_completion_token_t<- typename AsyncRandomAccessWriteDevice::executor_type>>-inline auto async_write_at(AsyncRandomAccessWriteDevice& d,- uint64_t offset, const ConstBufferSequence& buffers,- WriteToken&& token = default_completion_token_t<- typename AsyncRandomAccessWriteDevice::executor_type>(),- constraint_t<- !is_completion_condition<WriteToken>::value- > = 0)- -> decltype(+ std::size_t)) WriteToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+ typename AsyncRandomAccessWriteDevice::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+ void (asio::error_code, std::size_t))+async_write_at(AsyncRandomAccessWriteDevice& d, uint64_t offset,+ const ConstBufferSequence& buffers,+ ASIO_MOVE_ARG(WriteToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(+ typename AsyncRandomAccessWriteDevice::executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<WriteToken, void (asio::error_code, std::size_t)>( declval<detail::initiate_async_write_at<- AsyncRandomAccessWriteDevice>>(),- token, offset, buffers, transfer_all()))-{- return async_initiate<WriteToken,- void (asio::error_code, std::size_t)>(- detail::initiate_async_write_at<AsyncRandomAccessWriteDevice>(d),- token, offset, buffers, transfer_all());-}+ AsyncRandomAccessWriteDevice> >(),+ token, offset, buffers, transfer_all()))); /// Start an asynchronous operation to write a certain amount of data at the /// specified offset.@@ -579,7 +562,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -608,30 +591,24 @@ template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence, typename CompletionCondition, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) WriteToken = default_completion_token_t<- typename AsyncRandomAccessWriteDevice::executor_type>>-inline auto async_write_at(AsyncRandomAccessWriteDevice& d,+ std::size_t)) WriteToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+ typename AsyncRandomAccessWriteDevice::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+ void (asio::error_code, std::size_t))+async_write_at(AsyncRandomAccessWriteDevice& d, uint64_t offset, const ConstBufferSequence& buffers, CompletionCondition completion_condition,- WriteToken&& token = default_completion_token_t<- typename AsyncRandomAccessWriteDevice::executor_type>(),- constraint_t<- is_completion_condition<CompletionCondition>::value- > = 0)- -> decltype(+ ASIO_MOVE_ARG(WriteToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(+ typename AsyncRandomAccessWriteDevice::executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<WriteToken, void (asio::error_code, std::size_t)>( declval<detail::initiate_async_write_at<- AsyncRandomAccessWriteDevice>>(),+ AsyncRandomAccessWriteDevice> >(), token, offset, buffers,- static_cast<CompletionCondition&&>(completion_condition)))-{- return async_initiate<WriteToken,- void (asio::error_code, std::size_t)>(- detail::initiate_async_write_at<AsyncRandomAccessWriteDevice>(d),- token, offset, buffers,- static_cast<CompletionCondition&&>(completion_condition));-}+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition)))); #if !defined(ASIO_NO_EXTENSIONS) #if !defined(ASIO_NO_IOSTREAM)@@ -682,7 +659,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -700,28 +677,22 @@ */ template <typename AsyncRandomAccessWriteDevice, typename Allocator, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) WriteToken = default_completion_token_t<- typename AsyncRandomAccessWriteDevice::executor_type>>-inline auto async_write_at(AsyncRandomAccessWriteDevice& d,+ std::size_t)) WriteToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+ typename AsyncRandomAccessWriteDevice::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+ void (asio::error_code, std::size_t))+async_write_at(AsyncRandomAccessWriteDevice& d, uint64_t offset, basic_streambuf<Allocator>& b,- WriteToken&& token = default_completion_token_t<- typename AsyncRandomAccessWriteDevice::executor_type>(),- constraint_t<- !is_completion_condition<WriteToken>::value- > = 0)- -> decltype(+ ASIO_MOVE_ARG(WriteToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(+ typename AsyncRandomAccessWriteDevice::executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<WriteToken, void (asio::error_code, std::size_t)>( declval<detail::initiate_async_write_at_streambuf<- AsyncRandomAccessWriteDevice>>(),- token, offset, &b, transfer_all()))-{- return async_initiate<WriteToken,- void (asio::error_code, std::size_t)>(- detail::initiate_async_write_at_streambuf<- AsyncRandomAccessWriteDevice>(d),- token, offset, &b, transfer_all());-}+ AsyncRandomAccessWriteDevice> >(),+ token, offset, &b, transfer_all()))); /// Start an asynchronous operation to write a certain amount of data at the /// specified offset.@@ -783,7 +754,7 @@ * Regardless of whether the asynchronous operation completes immediately or * not, the completion handler will not be invoked from within this function. * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -802,30 +773,23 @@ template <typename AsyncRandomAccessWriteDevice, typename Allocator, typename CompletionCondition, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) WriteToken = default_completion_token_t<- typename AsyncRandomAccessWriteDevice::executor_type>>-inline auto async_write_at(AsyncRandomAccessWriteDevice& d, uint64_t offset,+ std::size_t)) WriteToken+ ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+ typename AsyncRandomAccessWriteDevice::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+ void (asio::error_code, std::size_t))+async_write_at(AsyncRandomAccessWriteDevice& d, uint64_t offset, basic_streambuf<Allocator>& b, CompletionCondition completion_condition,- WriteToken&& token = default_completion_token_t<- typename AsyncRandomAccessWriteDevice::executor_type>(),- constraint_t<- is_completion_condition<CompletionCondition>::value- > = 0)- -> decltype(+ ASIO_MOVE_ARG(WriteToken) token+ ASIO_DEFAULT_COMPLETION_TOKEN(+ typename AsyncRandomAccessWriteDevice::executor_type))+ ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate<WriteToken, void (asio::error_code, std::size_t)>( declval<detail::initiate_async_write_at_streambuf<- AsyncRandomAccessWriteDevice>>(),+ AsyncRandomAccessWriteDevice> >(), token, offset, &b,- static_cast<CompletionCondition&&>(completion_condition)))-{- return async_initiate<WriteToken,- void (asio::error_code, std::size_t)>(- detail::initiate_async_write_at_streambuf<- AsyncRandomAccessWriteDevice>(d),- token, offset, &b,- static_cast<CompletionCondition&&>(completion_condition));-}+ ASIO_MOVE_CAST(CompletionCondition)(completion_condition)))); #endif // !defined(ASIO_NO_IOSTREAM) #endif // !defined(ASIO_NO_EXTENSIONS)
link/modules/asio-standalone/asio/include/asio/yield.hpp view
@@ -2,7 +2,7 @@ // yield.hpp // ~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ link/modules/asio-standalone/asio/src/examples/cpp03/chat/chat_message.hpp view
@@ -0,0 +1,96 @@+//+// chat_message.hpp+// ~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef CHAT_MESSAGE_HPP+#define CHAT_MESSAGE_HPP++#include <cstdio>+#include <cstdlib>+#include <cstring>++class chat_message+{+public:+ enum+ {+ header_length = 4,+ max_body_length = 512+ };++ chat_message()+ : body_length_(0)+ {+ }++ const char* data() const+ {+ return data_;+ }++ char* data()+ {+ return data_;+ }++ size_t length() const+ {+ return header_length + body_length_;+ }++ const char* body() const+ {+ return data_ + header_length;+ }++ char* body()+ {+ return data_ + header_length;+ }++ size_t body_length() const+ {+ return body_length_;+ }++ void body_length(size_t new_length)+ {+ body_length_ = new_length;+ if (body_length_ > max_body_length)+ body_length_ = max_body_length;+ }++ bool decode_header()+ {+ using namespace std; // For strncat and atoi.+ char header[header_length + 1] = "";+ strncat(header, data_, header_length);+ body_length_ = atoi(header);+ if (body_length_ > max_body_length)+ {+ body_length_ = 0;+ return false;+ }+ return true;+ }++ void encode_header()+ {+ using namespace std; // For sprintf and memcpy.+ char header[header_length + 1] = "";+ sprintf(header, "%4d", static_cast<int>(body_length_));+ memcpy(data_, header, header_length);+ }++private:+ char data_[header_length + max_body_length];+ size_t body_length_;+};++#endif // CHAT_MESSAGE_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server/connection.hpp view
@@ -0,0 +1,83 @@+//+// connection.hpp+// ~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef HTTP_CONNECTION_HPP+#define HTTP_CONNECTION_HPP++#include <asio.hpp>+#include <boost/array.hpp>+#include <boost/noncopyable.hpp>+#include <boost/shared_ptr.hpp>+#include <boost/enable_shared_from_this.hpp>+#include "reply.hpp"+#include "request.hpp"+#include "request_handler.hpp"+#include "request_parser.hpp"++namespace http {+namespace server {++class connection_manager;++/// Represents a single connection from a client.+class connection+ : public boost::enable_shared_from_this<connection>,+ private boost::noncopyable+{+public:+ /// Construct a connection with the given io_context.+ explicit connection(asio::io_context& io_context,+ connection_manager& manager, request_handler& handler);++ /// Get the socket associated with the connection.+ asio::ip::tcp::socket& socket();++ /// Start the first asynchronous operation for the connection.+ void start();++ /// Stop all asynchronous operations associated with the connection.+ void stop();++private:+ /// Handle completion of a read operation.+ void handle_read(const asio::error_code& e,+ std::size_t bytes_transferred);++ /// Handle completion of a write operation.+ void handle_write(const asio::error_code& e);++ /// Socket for the connection.+ asio::ip::tcp::socket socket_;++ /// The manager for this connection.+ connection_manager& connection_manager_;++ /// The handler used to process the incoming request.+ request_handler& request_handler_;++ /// Buffer for incoming data.+ boost::array<char, 8192> buffer_;++ /// The incoming request.+ request request_;++ /// The parser for the incoming request.+ request_parser request_parser_;++ /// The reply to be sent back to the client.+ reply reply_;+};++typedef boost::shared_ptr<connection> connection_ptr;++} // namespace server+} // namespace http++#endif // HTTP_CONNECTION_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server/connection_manager.hpp view
@@ -0,0 +1,44 @@+//+// connection_manager.hpp+// ~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef HTTP_CONNECTION_MANAGER_HPP+#define HTTP_CONNECTION_MANAGER_HPP++#include <set>+#include <boost/noncopyable.hpp>+#include "connection.hpp"++namespace http {+namespace server {++/// Manages open connections so that they may be cleanly stopped when the server+/// needs to shut down.+class connection_manager+ : private boost::noncopyable+{+public:+ /// Add the specified connection to the manager and start it.+ void start(connection_ptr c);++ /// Stop the specified connection.+ void stop(connection_ptr c);++ /// Stop all connections.+ void stop_all();++private:+ /// The managed connections.+ std::set<connection_ptr> connections_;+};++} // namespace server+} // namespace http++#endif // HTTP_CONNECTION_MANAGER_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server/header.hpp view
@@ -0,0 +1,28 @@+//+// header.hpp+// ~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef HTTP_HEADER_HPP+#define HTTP_HEADER_HPP++#include <string>++namespace http {+namespace server {++struct header+{+ std::string name;+ std::string value;+};++} // namespace server+} // namespace http++#endif // HTTP_HEADER_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server/mime_types.hpp view
@@ -0,0 +1,27 @@+//+// mime_types.hpp+// ~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef HTTP_MIME_TYPES_HPP+#define HTTP_MIME_TYPES_HPP++#include <string>++namespace http {+namespace server {+namespace mime_types {++/// Convert a file extension into a MIME type.+std::string extension_to_type(const std::string& extension);++} // namespace mime_types+} // namespace server+} // namespace http++#endif // HTTP_MIME_TYPES_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server/reply.hpp view
@@ -0,0 +1,64 @@+//+// reply.hpp+// ~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef HTTP_REPLY_HPP+#define HTTP_REPLY_HPP++#include <string>+#include <vector>+#include <asio.hpp>+#include "header.hpp"++namespace http {+namespace server {++/// A reply to be sent to a client.+struct reply+{+ /// The status of the reply.+ enum status_type+ {+ ok = 200,+ created = 201,+ accepted = 202,+ no_content = 204,+ multiple_choices = 300,+ moved_permanently = 301,+ moved_temporarily = 302,+ not_modified = 304,+ bad_request = 400,+ unauthorized = 401,+ forbidden = 403,+ not_found = 404,+ internal_server_error = 500,+ not_implemented = 501,+ bad_gateway = 502,+ service_unavailable = 503+ } status;++ /// The headers to be included in the reply.+ std::vector<header> headers;++ /// The content to be sent in the reply.+ std::string content;++ /// Convert the reply into a vector of buffers. The buffers do not own the+ /// underlying memory blocks, therefore the reply object must remain valid and+ /// not be changed until the write operation has completed.+ std::vector<asio::const_buffer> to_buffers();++ /// Get a stock reply.+ static reply stock_reply(status_type status);+};++} // namespace server+} // namespace http++#endif // HTTP_REPLY_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server/request.hpp view
@@ -0,0 +1,34 @@+//+// request.hpp+// ~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef HTTP_REQUEST_HPP+#define HTTP_REQUEST_HPP++#include <string>+#include <vector>+#include "header.hpp"++namespace http {+namespace server {++/// A request received from a client.+struct request+{+ std::string method;+ std::string uri;+ int http_version_major;+ int http_version_minor;+ std::vector<header> headers;+};++} // namespace server+} // namespace http++#endif // HTTP_REQUEST_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server/request_handler.hpp view
@@ -0,0 +1,46 @@+//+// request_handler.hpp+// ~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef HTTP_REQUEST_HANDLER_HPP+#define HTTP_REQUEST_HANDLER_HPP++#include <string>+#include <boost/noncopyable.hpp>++namespace http {+namespace server {++struct reply;+struct request;++/// The common handler for all incoming requests.+class request_handler+ : private boost::noncopyable+{+public:+ /// Construct with a directory containing files to be served.+ explicit request_handler(const std::string& doc_root);++ /// Handle a request and produce a reply.+ void handle_request(const request& req, reply& rep);++private:+ /// The directory containing the files to be served.+ std::string doc_root_;++ /// Perform URL-decoding on a string. Returns false if the encoding was+ /// invalid.+ static bool url_decode(const std::string& in, std::string& out);+};++} // namespace server+} // namespace http++#endif // HTTP_REQUEST_HANDLER_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server/request_parser.hpp view
@@ -0,0 +1,95 @@+//+// request_parser.hpp+// ~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef HTTP_REQUEST_PARSER_HPP+#define HTTP_REQUEST_PARSER_HPP++#include <boost/logic/tribool.hpp>+#include <boost/tuple/tuple.hpp>++namespace http {+namespace server {++struct request;++/// Parser for incoming requests.+class request_parser+{+public:+ /// Construct ready to parse the request method.+ request_parser();++ /// Reset to initial parser state.+ void reset();++ /// Parse some data. The tribool return value is true when a complete request+ /// has been parsed, false if the data is invalid, indeterminate when more+ /// data is required. The InputIterator return value indicates how much of the+ /// input has been consumed.+ template <typename InputIterator>+ boost::tuple<boost::tribool, InputIterator> parse(request& req,+ InputIterator begin, InputIterator end)+ {+ while (begin != end)+ {+ boost::tribool result = consume(req, *begin++);+ if (result || !result)+ return boost::make_tuple(result, begin);+ }+ boost::tribool result = boost::indeterminate;+ return boost::make_tuple(result, begin);+ }++private:+ /// Handle the next character of input.+ boost::tribool consume(request& req, char input);++ /// Check if a byte is an HTTP character.+ static bool is_char(int c);++ /// Check if a byte is an HTTP control character.+ static bool is_ctl(int c);++ /// Check if a byte is defined as an HTTP tspecial character.+ static bool is_tspecial(int c);++ /// Check if a byte is a digit.+ static bool is_digit(int c);++ /// The current state of the parser.+ enum state+ {+ method_start,+ method,+ uri,+ http_version_h,+ http_version_t_1,+ http_version_t_2,+ http_version_p,+ http_version_slash,+ http_version_major_start,+ http_version_major,+ http_version_minor_start,+ http_version_minor,+ expecting_newline_1,+ header_line_start,+ header_lws,+ header_name,+ space_before_header_value,+ header_value,+ expecting_newline_2,+ expecting_newline_3+ } state_;+};++} // namespace server+} // namespace http++#endif // HTTP_REQUEST_PARSER_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server/server.hpp view
@@ -0,0 +1,69 @@+//+// server.hpp+// ~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef HTTP_SERVER_HPP+#define HTTP_SERVER_HPP++#include <asio.hpp>+#include <string>+#include <boost/noncopyable.hpp>+#include "connection.hpp"+#include "connection_manager.hpp"+#include "request_handler.hpp"++namespace http {+namespace server {++/// The top-level class of the HTTP server.+class server+ : private boost::noncopyable+{+public:+ /// Construct the server to listen on the specified TCP address and port, and+ /// serve up files from the given directory.+ explicit server(const std::string& address, const std::string& port,+ const std::string& doc_root);++ /// Run the server's io_context loop.+ void run();++private:+ /// Initiate an asynchronous accept operation.+ void start_accept();++ /// Handle completion of an asynchronous accept operation.+ void handle_accept(const asio::error_code& e);++ /// Handle a request to stop the server.+ void handle_stop();++ /// The io_context used to perform asynchronous operations.+ asio::io_context io_context_;++ /// The signal_set is used to register for process termination notifications.+ asio::signal_set signals_;++ /// Acceptor used to listen for incoming connections.+ asio::ip::tcp::acceptor acceptor_;++ /// The connection manager which owns all live connections.+ connection_manager connection_manager_;++ /// The next connection to be accepted.+ connection_ptr new_connection_;++ /// The handler for all incoming requests.+ request_handler request_handler_;+};++} // namespace server+} // namespace http++#endif // HTTP_SERVER_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server2/connection.hpp view
@@ -0,0 +1,75 @@+//+// connection.hpp+// ~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef HTTP_SERVER2_CONNECTION_HPP+#define HTTP_SERVER2_CONNECTION_HPP++#include <asio.hpp>+#include <boost/array.hpp>+#include <boost/noncopyable.hpp>+#include <boost/shared_ptr.hpp>+#include <boost/enable_shared_from_this.hpp>+#include "reply.hpp"+#include "request.hpp"+#include "request_handler.hpp"+#include "request_parser.hpp"++namespace http {+namespace server2 {++/// Represents a single connection from a client.+class connection+ : public boost::enable_shared_from_this<connection>,+ private boost::noncopyable+{+public:+ /// Construct a connection with the given io_context.+ explicit connection(asio::io_context& io_context,+ request_handler& handler);++ /// Get the socket associated with the connection.+ asio::ip::tcp::socket& socket();++ /// Start the first asynchronous operation for the connection.+ void start();++private:+ /// Handle completion of a read operation.+ void handle_read(const asio::error_code& e,+ std::size_t bytes_transferred);++ /// Handle completion of a write operation.+ void handle_write(const asio::error_code& e);++ /// Socket for the connection.+ asio::ip::tcp::socket socket_;++ /// The handler used to process the incoming request.+ request_handler& request_handler_;++ /// Buffer for incoming data.+ boost::array<char, 8192> buffer_;++ /// The incoming request.+ request request_;++ /// The parser for the incoming request.+ request_parser request_parser_;++ /// The reply to be sent back to the client.+ reply reply_;+};++typedef boost::shared_ptr<connection> connection_ptr;++} // namespace server2+} // namespace http++#endif // HTTP_SERVER2_CONNECTION_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server2/header.hpp view
@@ -0,0 +1,28 @@+//+// header.hpp+// ~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef HTTP_SERVER2_HEADER_HPP+#define HTTP_SERVER2_HEADER_HPP++#include <string>++namespace http {+namespace server2 {++struct header+{+ std::string name;+ std::string value;+};++} // namespace server2+} // namespace http++#endif // HTTP_SERVER2_HEADER_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server2/io_context_pool.hpp view
@@ -0,0 +1,58 @@+//+// io_context_pool.hpp+// ~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef HTTP_SERVER2_IO_SERVICE_POOL_HPP+#define HTTP_SERVER2_IO_SERVICE_POOL_HPP++#include <asio.hpp>+#include <list>+#include <vector>+#include <boost/noncopyable.hpp>+#include <boost/shared_ptr.hpp>++namespace http {+namespace server2 {++/// A pool of io_context objects.+class io_context_pool+ : private boost::noncopyable+{+public:+ /// Construct the io_context pool.+ explicit io_context_pool(std::size_t pool_size);++ /// Run all io_context objects in the pool.+ void run();++ /// Stop all io_context objects in the pool.+ void stop();++ /// Get an io_context to use.+ asio::io_context& get_io_context();++private:+ typedef boost::shared_ptr<asio::io_context> io_context_ptr;+ typedef asio::executor_work_guard<+ asio::io_context::executor_type> io_context_work;++ /// The pool of io_contexts.+ std::vector<io_context_ptr> io_contexts_;++ /// The work that keeps the io_contexts running.+ std::list<io_context_work> work_;++ /// The next io_context to use for a connection.+ std::size_t next_io_context_;+};++} // namespace server2+} // namespace http++#endif // HTTP_SERVER2_IO_SERVICE_POOL_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server2/mime_types.hpp view
@@ -0,0 +1,27 @@+//+// mime_types.hpp+// ~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef HTTP_SERVER2_MIME_TYPES_HPP+#define HTTP_SERVER2_MIME_TYPES_HPP++#include <string>++namespace http {+namespace server2 {+namespace mime_types {++/// Convert a file extension into a MIME type.+std::string extension_to_type(const std::string& extension);++} // namespace mime_types+} // namespace server2+} // namespace http++#endif // HTTP_SERVER2_MIME_TYPES_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server2/reply.hpp view
@@ -0,0 +1,64 @@+//+// reply.hpp+// ~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef HTTP_SERVER2_REPLY_HPP+#define HTTP_SERVER2_REPLY_HPP++#include <string>+#include <vector>+#include <asio.hpp>+#include "header.hpp"++namespace http {+namespace server2 {++/// A reply to be sent to a client.+struct reply+{+ /// The status of the reply.+ enum status_type+ {+ ok = 200,+ created = 201,+ accepted = 202,+ no_content = 204,+ multiple_choices = 300,+ moved_permanently = 301,+ moved_temporarily = 302,+ not_modified = 304,+ bad_request = 400,+ unauthorized = 401,+ forbidden = 403,+ not_found = 404,+ internal_server_error = 500,+ not_implemented = 501,+ bad_gateway = 502,+ service_unavailable = 503+ } status;++ /// The headers to be included in the reply.+ std::vector<header> headers;++ /// The content to be sent in the reply.+ std::string content;++ /// Convert the reply into a vector of buffers. The buffers do not own the+ /// underlying memory blocks, therefore the reply object must remain valid and+ /// not be changed until the write operation has completed.+ std::vector<asio::const_buffer> to_buffers();++ /// Get a stock reply.+ static reply stock_reply(status_type status);+};++} // namespace server2+} // namespace http++#endif // HTTP_SERVER2_REPLY_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server2/request.hpp view
@@ -0,0 +1,34 @@+//+// request.hpp+// ~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef HTTP_SERVER2_REQUEST_HPP+#define HTTP_SERVER2_REQUEST_HPP++#include <string>+#include <vector>+#include "header.hpp"++namespace http {+namespace server2 {++/// A request received from a client.+struct request+{+ std::string method;+ std::string uri;+ int http_version_major;+ int http_version_minor;+ std::vector<header> headers;+};++} // namespace server2+} // namespace http++#endif // HTTP_SERVER2_REQUEST_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server2/request_handler.hpp view
@@ -0,0 +1,46 @@+//+// request_handler.hpp+// ~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef HTTP_SERVER2_REQUEST_HANDLER_HPP+#define HTTP_SERVER2_REQUEST_HANDLER_HPP++#include <string>+#include <boost/noncopyable.hpp>++namespace http {+namespace server2 {++struct reply;+struct request;++/// The common handler for all incoming requests.+class request_handler+ : private boost::noncopyable+{+public:+ /// Construct with a directory containing files to be served.+ explicit request_handler(const std::string& doc_root);++ /// Handle a request and produce a reply.+ void handle_request(const request& req, reply& rep);++private:+ /// The directory containing the files to be served.+ std::string doc_root_;++ /// Perform URL-decoding on a string. Returns false if the encoding was+ /// invalid.+ static bool url_decode(const std::string& in, std::string& out);+};++} // namespace server2+} // namespace http++#endif // HTTP_SERVER2_REQUEST_HANDLER_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server2/request_parser.hpp view
@@ -0,0 +1,95 @@+//+// request_parser.hpp+// ~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef HTTP_SERVER2_REQUEST_PARSER_HPP+#define HTTP_SERVER2_REQUEST_PARSER_HPP++#include <boost/logic/tribool.hpp>+#include <boost/tuple/tuple.hpp>++namespace http {+namespace server2 {++struct request;++/// Parser for incoming requests.+class request_parser+{+public:+ /// Construct ready to parse the request method.+ request_parser();++ /// Reset to initial parser state.+ void reset();++ /// Parse some data. The tribool return value is true when a complete request+ /// has been parsed, false if the data is invalid, indeterminate when more+ /// data is required. The InputIterator return value indicates how much of the+ /// input has been consumed.+ template <typename InputIterator>+ boost::tuple<boost::tribool, InputIterator> parse(request& req,+ InputIterator begin, InputIterator end)+ {+ while (begin != end)+ {+ boost::tribool result = consume(req, *begin++);+ if (result || !result)+ return boost::make_tuple(result, begin);+ }+ boost::tribool result = boost::indeterminate;+ return boost::make_tuple(result, begin);+ }++private:+ /// Handle the next character of input.+ boost::tribool consume(request& req, char input);++ /// Check if a byte is an HTTP character.+ static bool is_char(int c);++ /// Check if a byte is an HTTP control character.+ static bool is_ctl(int c);++ /// Check if a byte is defined as an HTTP tspecial character.+ static bool is_tspecial(int c);++ /// Check if a byte is a digit.+ static bool is_digit(int c);++ /// The current state of the parser.+ enum state+ {+ method_start,+ method,+ uri,+ http_version_h,+ http_version_t_1,+ http_version_t_2,+ http_version_p,+ http_version_slash,+ http_version_major_start,+ http_version_major,+ http_version_minor_start,+ http_version_minor,+ expecting_newline_1,+ header_line_start,+ header_lws,+ header_name,+ space_before_header_value,+ header_value,+ expecting_newline_2,+ expecting_newline_3+ } state_;+};++} // namespace server2+} // namespace http++#endif // HTTP_SERVER2_REQUEST_PARSER_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server2/server.hpp view
@@ -0,0 +1,68 @@+//+// server.hpp+// ~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef HTTP_SERVER2_SERVER_HPP+#define HTTP_SERVER2_SERVER_HPP++#include <asio.hpp>+#include <string>+#include <vector>+#include <boost/noncopyable.hpp>+#include <boost/shared_ptr.hpp>+#include "connection.hpp"+#include "io_context_pool.hpp"+#include "request_handler.hpp"++namespace http {+namespace server2 {++/// The top-level class of the HTTP server.+class server+ : private boost::noncopyable+{+public:+ /// Construct the server to listen on the specified TCP address and port, and+ /// serve up files from the given directory.+ explicit server(const std::string& address, const std::string& port,+ const std::string& doc_root, std::size_t io_context_pool_size);++ /// Run the server's io_context loop.+ void run();++private:+ /// Initiate an asynchronous accept operation.+ void start_accept();++ /// Handle completion of an asynchronous accept operation.+ void handle_accept(const asio::error_code& e);++ /// Handle a request to stop the server.+ void handle_stop();++ /// The pool of io_context objects used to perform asynchronous operations.+ io_context_pool io_context_pool_;++ /// The signal_set is used to register for process termination notifications.+ asio::signal_set signals_;++ /// Acceptor used to listen for incoming connections.+ asio::ip::tcp::acceptor acceptor_;++ /// The next connection to be accepted.+ connection_ptr new_connection_;++ /// The handler for all incoming requests.+ request_handler request_handler_;+};++} // namespace server2+} // namespace http++#endif // HTTP_SERVER2_SERVER_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server3/connection.hpp view
@@ -0,0 +1,78 @@+//+// connection.hpp+// ~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef HTTP_SERVER3_CONNECTION_HPP+#define HTTP_SERVER3_CONNECTION_HPP++#include <asio.hpp>+#include <boost/array.hpp>+#include <boost/noncopyable.hpp>+#include <boost/shared_ptr.hpp>+#include <boost/enable_shared_from_this.hpp>+#include "reply.hpp"+#include "request.hpp"+#include "request_handler.hpp"+#include "request_parser.hpp"++namespace http {+namespace server3 {++/// Represents a single connection from a client.+class connection+ : public boost::enable_shared_from_this<connection>,+ private boost::noncopyable+{+public:+ /// Construct a connection with the given io_context.+ explicit connection(asio::io_context& io_context,+ request_handler& handler);++ /// Get the socket associated with the connection.+ asio::ip::tcp::socket& socket();++ /// Start the first asynchronous operation for the connection.+ void start();++private:+ /// Handle completion of a read operation.+ void handle_read(const asio::error_code& e,+ std::size_t bytes_transferred);++ /// Handle completion of a write operation.+ void handle_write(const asio::error_code& e);++ /// Strand to ensure the connection's handlers are not called concurrently.+ asio::strand<asio::io_context::executor_type> strand_;++ /// Socket for the connection.+ asio::ip::tcp::socket socket_;++ /// The handler used to process the incoming request.+ request_handler& request_handler_;++ /// Buffer for incoming data.+ boost::array<char, 8192> buffer_;++ /// The incoming request.+ request request_;++ /// The parser for the incoming request.+ request_parser request_parser_;++ /// The reply to be sent back to the client.+ reply reply_;+};++typedef boost::shared_ptr<connection> connection_ptr;++} // namespace server3+} // namespace http++#endif // HTTP_SERVER3_CONNECTION_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server3/header.hpp view
@@ -0,0 +1,28 @@+//+// header.hpp+// ~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef HTTP_SERVER3_HEADER_HPP+#define HTTP_SERVER3_HEADER_HPP++#include <string>++namespace http {+namespace server3 {++struct header+{+ std::string name;+ std::string value;+};++} // namespace server3+} // namespace http++#endif // HTTP_SERVER3_HEADER_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server3/mime_types.hpp view
@@ -0,0 +1,27 @@+//+// mime_types.hpp+// ~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef HTTP_SERVER3_MIME_TYPES_HPP+#define HTTP_SERVER3_MIME_TYPES_HPP++#include <string>++namespace http {+namespace server3 {+namespace mime_types {++/// Convert a file extension into a MIME type.+std::string extension_to_type(const std::string& extension);++} // namespace mime_types+} // namespace server3+} // namespace http++#endif // HTTP_SERVER3_MIME_TYPES_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server3/reply.hpp view
@@ -0,0 +1,64 @@+//+// reply.hpp+// ~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef HTTP_SERVER3_REPLY_HPP+#define HTTP_SERVER3_REPLY_HPP++#include <string>+#include <vector>+#include <asio.hpp>+#include "header.hpp"++namespace http {+namespace server3 {++/// A reply to be sent to a client.+struct reply+{+ /// The status of the reply.+ enum status_type+ {+ ok = 200,+ created = 201,+ accepted = 202,+ no_content = 204,+ multiple_choices = 300,+ moved_permanently = 301,+ moved_temporarily = 302,+ not_modified = 304,+ bad_request = 400,+ unauthorized = 401,+ forbidden = 403,+ not_found = 404,+ internal_server_error = 500,+ not_implemented = 501,+ bad_gateway = 502,+ service_unavailable = 503+ } status;++ /// The headers to be included in the reply.+ std::vector<header> headers;++ /// The content to be sent in the reply.+ std::string content;++ /// Convert the reply into a vector of buffers. The buffers do not own the+ /// underlying memory blocks, therefore the reply object must remain valid and+ /// not be changed until the write operation has completed.+ std::vector<asio::const_buffer> to_buffers();++ /// Get a stock reply.+ static reply stock_reply(status_type status);+};++} // namespace server3+} // namespace http++#endif // HTTP_SERVER3_REPLY_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server3/request.hpp view
@@ -0,0 +1,34 @@+//+// request.hpp+// ~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef HTTP_SERVER3_REQUEST_HPP+#define HTTP_SERVER3_REQUEST_HPP++#include <string>+#include <vector>+#include "header.hpp"++namespace http {+namespace server3 {++/// A request received from a client.+struct request+{+ std::string method;+ std::string uri;+ int http_version_major;+ int http_version_minor;+ std::vector<header> headers;+};++} // namespace server3+} // namespace http++#endif // HTTP_SERVER3_REQUEST_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server3/request_handler.hpp view
@@ -0,0 +1,46 @@+//+// request_handler.hpp+// ~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef HTTP_SERVER3_REQUEST_HANDLER_HPP+#define HTTP_SERVER3_REQUEST_HANDLER_HPP++#include <string>+#include <boost/noncopyable.hpp>++namespace http {+namespace server3 {++struct reply;+struct request;++/// The common handler for all incoming requests.+class request_handler+ : private boost::noncopyable+{+public:+ /// Construct with a directory containing files to be served.+ explicit request_handler(const std::string& doc_root);++ /// Handle a request and produce a reply.+ void handle_request(const request& req, reply& rep);++private:+ /// The directory containing the files to be served.+ std::string doc_root_;++ /// Perform URL-decoding on a string. Returns false if the encoding was+ /// invalid.+ static bool url_decode(const std::string& in, std::string& out);+};++} // namespace server3+} // namespace http++#endif // HTTP_SERVER3_REQUEST_HANDLER_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server3/request_parser.hpp view
@@ -0,0 +1,95 @@+//+// request_parser.hpp+// ~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef HTTP_SERVER3_REQUEST_PARSER_HPP+#define HTTP_SERVER3_REQUEST_PARSER_HPP++#include <boost/logic/tribool.hpp>+#include <boost/tuple/tuple.hpp>++namespace http {+namespace server3 {++struct request;++/// Parser for incoming requests.+class request_parser+{+public:+ /// Construct ready to parse the request method.+ request_parser();++ /// Reset to initial parser state.+ void reset();++ /// Parse some data. The tribool return value is true when a complete request+ /// has been parsed, false if the data is invalid, indeterminate when more+ /// data is required. The InputIterator return value indicates how much of the+ /// input has been consumed.+ template <typename InputIterator>+ boost::tuple<boost::tribool, InputIterator> parse(request& req,+ InputIterator begin, InputIterator end)+ {+ while (begin != end)+ {+ boost::tribool result = consume(req, *begin++);+ if (result || !result)+ return boost::make_tuple(result, begin);+ }+ boost::tribool result = boost::indeterminate;+ return boost::make_tuple(result, begin);+ }++private:+ /// Handle the next character of input.+ boost::tribool consume(request& req, char input);++ /// Check if a byte is an HTTP character.+ static bool is_char(int c);++ /// Check if a byte is an HTTP control character.+ static bool is_ctl(int c);++ /// Check if a byte is defined as an HTTP tspecial character.+ static bool is_tspecial(int c);++ /// Check if a byte is a digit.+ static bool is_digit(int c);++ /// The current state of the parser.+ enum state+ {+ method_start,+ method,+ uri,+ http_version_h,+ http_version_t_1,+ http_version_t_2,+ http_version_p,+ http_version_slash,+ http_version_major_start,+ http_version_major,+ http_version_minor_start,+ http_version_minor,+ expecting_newline_1,+ header_line_start,+ header_lws,+ header_name,+ space_before_header_value,+ header_value,+ expecting_newline_2,+ expecting_newline_3+ } state_;+};++} // namespace server3+} // namespace http++#endif // HTTP_SERVER3_REQUEST_PARSER_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server3/server.hpp view
@@ -0,0 +1,70 @@+//+// server.hpp+// ~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef HTTP_SERVER3_SERVER_HPP+#define HTTP_SERVER3_SERVER_HPP++#include <asio.hpp>+#include <string>+#include <vector>+#include <boost/noncopyable.hpp>+#include <boost/shared_ptr.hpp>+#include "connection.hpp"+#include "request_handler.hpp"++namespace http {+namespace server3 {++/// The top-level class of the HTTP server.+class server+ : private boost::noncopyable+{+public:+ /// Construct the server to listen on the specified TCP address and port, and+ /// serve up files from the given directory.+ explicit server(const std::string& address, const std::string& port,+ const std::string& doc_root, std::size_t thread_pool_size);++ /// Run the server's io_context loop.+ void run();++private:+ /// Initiate an asynchronous accept operation.+ void start_accept();++ /// Handle completion of an asynchronous accept operation.+ void handle_accept(const asio::error_code& e);++ /// Handle a request to stop the server.+ void handle_stop();++ /// The number of threads that will call io_context::run().+ std::size_t thread_pool_size_;++ /// The io_context used to perform asynchronous operations.+ asio::io_context io_context_;++ /// The signal_set is used to register for process termination notifications.+ asio::signal_set signals_;++ /// Acceptor used to listen for incoming connections.+ asio::ip::tcp::acceptor acceptor_;++ /// The next connection to be accepted.+ connection_ptr new_connection_;++ /// The handler for all incoming requests.+ request_handler request_handler_;+};++} // namespace server3+} // namespace http++#endif // HTTP_SERVER3_SERVER_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server4/file_handler.hpp view
@@ -0,0 +1,44 @@+//+// file_handler.hpp+// ~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef HTTP_SERVER4_FILE_HANDLER_HPP+#define HTTP_SERVER4_FILE_HANDLER_HPP++#include <string>++namespace http {+namespace server4 {++struct reply;+struct request;++/// The common handler for all incoming requests.+class file_handler+{+public:+ /// Construct with a directory containing files to be served.+ explicit file_handler(const std::string& doc_root);++ /// Handle a request and produce a reply.+ void operator()(const request& req, reply& rep);++private:+ /// The directory containing the files to be served.+ std::string doc_root_;++ /// Perform URL-decoding on a string. Returns false if the encoding was+ /// invalid.+ static bool url_decode(const std::string& in, std::string& out);+};++} // namespace server4+} // namespace http++#endif // HTTP_SERVER4_FILE_HANDLER_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server4/header.hpp view
@@ -0,0 +1,28 @@+//+// header.hpp+// ~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef HTTP_SERVER4_HEADER_HPP+#define HTTP_SERVER4_HEADER_HPP++#include <string>++namespace http {+namespace server4 {++struct header+{+ std::string name;+ std::string value;+};++} // namespace server4+} // namespace http++#endif // HTTP_SERVER4_HEADER_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server4/mime_types.hpp view
@@ -0,0 +1,27 @@+//+// mime_types.hpp+// ~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef HTTP_SERVER4_MIME_TYPES_HPP+#define HTTP_SERVER4_MIME_TYPES_HPP++#include <string>++namespace http {+namespace server4 {+namespace mime_types {++/// Convert a file extension into a MIME type.+std::string extension_to_type(const std::string& extension);++} // namespace mime_types+} // namespace server4+} // namespace http++#endif // HTTP_SERVER4_MIME_TYPES_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server4/reply.hpp view
@@ -0,0 +1,64 @@+//+// reply.hpp+// ~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef HTTP_SERVER4_REPLY_HPP+#define HTTP_SERVER4_REPLY_HPP++#include <string>+#include <vector>+#include <asio.hpp>+#include "header.hpp"++namespace http {+namespace server4 {++/// A reply to be sent to a client.+struct reply+{+ /// The status of the reply.+ enum status_type+ {+ ok = 200,+ created = 201,+ accepted = 202,+ no_content = 204,+ multiple_choices = 300,+ moved_permanently = 301,+ moved_temporarily = 302,+ not_modified = 304,+ bad_request = 400,+ unauthorized = 401,+ forbidden = 403,+ not_found = 404,+ internal_server_error = 500,+ not_implemented = 501,+ bad_gateway = 502,+ service_unavailable = 503+ } status;++ /// The headers to be included in the reply.+ std::vector<header> headers;++ /// The content to be sent in the reply.+ std::string content;++ /// Convert the reply into a vector of buffers. The buffers do not own the+ /// underlying memory blocks, therefore the reply object must remain valid and+ /// not be changed until the write operation has completed.+ std::vector<asio::const_buffer> to_buffers();++ /// Get a stock reply.+ static reply stock_reply(status_type status);+};++} // namespace server4+} // namespace http++#endif // HTTP_SERVER4_REPLY_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server4/request.hpp view
@@ -0,0 +1,46 @@+//+// request.hpp+// ~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef HTTP_SERVER4_REQUEST_HPP+#define HTTP_SERVER4_REQUEST_HPP++#include <string>+#include <vector>+#include "header.hpp"++namespace http {+namespace server4 {++/// A request received from a client.+struct request+{+ /// The request method, e.g. "GET", "POST".+ std::string method;++ /// The requested URI, such as a path to a file.+ std::string uri;++ /// Major version number, usually 1.+ int http_version_major;++ /// Minor version number, usually 0 or 1.+ int http_version_minor;++ /// The headers included with the request.+ std::vector<header> headers;++ /// The optional content sent with the request.+ std::string content;+};++} // namespace server4+} // namespace http++#endif // HTTP_SERVER4_REQUEST_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server4/request_parser.hpp view
@@ -0,0 +1,78 @@+//+// request_parser.hpp+// ~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef HTTP_SERVER4_REQUEST_PARSER_HPP+#define HTTP_SERVER4_REQUEST_PARSER_HPP++#include <string>+#include <boost/logic/tribool.hpp>+#include <boost/tuple/tuple.hpp>+#include <asio/coroutine.hpp>++namespace http {+namespace server4 {++struct request;++/// Parser for incoming requests.+class request_parser : asio::coroutine+{+public:+ /// Parse some data. The tribool return value is true when a complete request+ /// has been parsed, false if the data is invalid, indeterminate when more+ /// data is required. The InputIterator return value indicates how much of the+ /// input has been consumed.+ template <typename InputIterator>+ boost::tuple<boost::tribool, InputIterator> parse(request& req,+ InputIterator begin, InputIterator end)+ {+ while (begin != end)+ {+ boost::tribool result = consume(req, *begin++);+ if (result || !result)+ return boost::make_tuple(result, begin);+ }+ boost::tribool result = boost::indeterminate;+ return boost::make_tuple(result, begin);+ }++private:+ /// The name of the content length header.+ static std::string content_length_name_;++ /// Content length as decoded from headers. Defaults to 0.+ std::size_t content_length_;++ /// Handle the next character of input.+ boost::tribool consume(request& req, char input);++ /// Check if a byte is an HTTP character.+ static bool is_char(int c);++ /// Check if a byte is an HTTP control character.+ static bool is_ctl(int c);++ /// Check if a byte is defined as an HTTP tspecial character.+ static bool is_tspecial(int c);++ /// Check if a byte is a digit.+ static bool is_digit(int c);++ /// Check if two characters are equal, without regard to case.+ static bool tolower_compare(char a, char b);++ /// Check whether the two request header names match.+ bool headers_equal(const std::string& a, const std::string& b);+};++} // namespace server4+} // namespace http++#endif // HTTP_SERVER4_REQUEST_PARSER_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server4/server.hpp view
@@ -0,0 +1,73 @@+//+// server.hpp+// ~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef HTTP_SERVER4_SERVER_HPP+#define HTTP_SERVER4_SERVER_HPP++#include <asio.hpp>+#include <string>+#include <boost/array.hpp>+#include <boost/function.hpp>+#include <boost/shared_ptr.hpp>+#include "request_parser.hpp"++namespace http {+namespace server4 {++struct request;+struct reply;++/// The top-level coroutine of the HTTP server.+class server : asio::coroutine+{+public:+ /// Construct the server to listen on the specified TCP address and port, and+ /// serve up files from the given directory.+ explicit server(asio::io_context& io_context,+ const std::string& address, const std::string& port,+ boost::function<void(const request&, reply&)> request_handler);++ /// Perform work associated with the server.+ void operator()(+ asio::error_code ec = asio::error_code(),+ std::size_t length = 0);++private:+ typedef asio::ip::tcp tcp;++ /// The user-supplied handler for all incoming requests.+ boost::function<void(const request&, reply&)> request_handler_;++ /// Acceptor used to listen for incoming connections.+ boost::shared_ptr<tcp::acceptor> acceptor_;++ /// The current connection from a client.+ boost::shared_ptr<tcp::socket> socket_;++ /// Buffer for incoming data.+ boost::shared_ptr<boost::array<char, 8192> > buffer_;++ /// The incoming request.+ boost::shared_ptr<request> request_;++ /// Whether the request is valid or not.+ boost::tribool valid_request_;++ /// The parser for the incoming request.+ request_parser request_parser_;++ /// The reply to be sent back to the client.+ boost::shared_ptr<reply> reply_;+};++} // namespace server4+} // namespace http++#endif // HTTP_SERVER4_SERVER_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/icmp/icmp_header.hpp view
@@ -0,0 +1,94 @@+//+// icmp_header.hpp+// ~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef ICMP_HEADER_HPP+#define ICMP_HEADER_HPP++#include <istream>+#include <ostream>+#include <algorithm>++// ICMP header for both IPv4 and IPv6.+//+// The wire format of an ICMP header is:+// +// 0 8 16 31+// +---------------+---------------+------------------------------+ ---+// | | | | ^+// | type | code | checksum | |+// | | | | |+// +---------------+---------------+------------------------------+ 8 bytes+// | | | |+// | identifier | sequence number | |+// | | | v+// +-------------------------------+------------------------------+ ---++class icmp_header+{+public:+ enum { echo_reply = 0, destination_unreachable = 3, source_quench = 4,+ redirect = 5, echo_request = 8, time_exceeded = 11, parameter_problem = 12,+ timestamp_request = 13, timestamp_reply = 14, info_request = 15,+ info_reply = 16, address_request = 17, address_reply = 18 };++ icmp_header() { std::fill(rep_, rep_ + sizeof(rep_), 0); }++ unsigned char type() const { return rep_[0]; }+ unsigned char code() const { return rep_[1]; }+ unsigned short checksum() const { return decode(2, 3); }+ unsigned short identifier() const { return decode(4, 5); }+ unsigned short sequence_number() const { return decode(6, 7); }++ void type(unsigned char n) { rep_[0] = n; }+ void code(unsigned char n) { rep_[1] = n; }+ void checksum(unsigned short n) { encode(2, 3, n); }+ void identifier(unsigned short n) { encode(4, 5, n); }+ void sequence_number(unsigned short n) { encode(6, 7, n); }++ friend std::istream& operator>>(std::istream& is, icmp_header& header)+ { return is.read(reinterpret_cast<char*>(header.rep_), 8); }++ friend std::ostream& operator<<(std::ostream& os, const icmp_header& header)+ { return os.write(reinterpret_cast<const char*>(header.rep_), 8); }++private:+ unsigned short decode(int a, int b) const+ { return (rep_[a] << 8) + rep_[b]; }++ void encode(int a, int b, unsigned short n)+ {+ rep_[a] = static_cast<unsigned char>(n >> 8);+ rep_[b] = static_cast<unsigned char>(n & 0xFF);+ }++ unsigned char rep_[8];+};++template <typename Iterator>+void compute_checksum(icmp_header& header,+ Iterator body_begin, Iterator body_end)+{+ unsigned int sum = (header.type() << 8) + header.code()+ + header.identifier() + header.sequence_number();++ Iterator body_iter = body_begin;+ while (body_iter != body_end)+ {+ sum += (static_cast<unsigned char>(*body_iter++) << 8);+ if (body_iter != body_end)+ sum += static_cast<unsigned char>(*body_iter++);+ }++ sum = (sum >> 16) + (sum & 0xFFFF);+ sum += (sum >> 16);+ header.checksum(static_cast<unsigned short>(~sum));+}++#endif // ICMP_HEADER_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/icmp/ipv4_header.hpp view
@@ -0,0 +1,102 @@+//+// ipv4_header.hpp+// ~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef IPV4_HEADER_HPP+#define IPV4_HEADER_HPP++#include <algorithm>+#include <asio/ip/address_v4.hpp>++// Packet header for IPv4.+//+// The wire format of an IPv4 header is:+// +// 0 8 16 31+// +-------+-------+---------------+------------------------------+ ---+// | | | | | ^+// |version|header | type of | total length in bytes | |+// | (4) | length| service | | |+// +-------+-------+---------------+-+-+-+------------------------+ |+// | | | | | | |+// | identification |0|D|M| fragment offset | |+// | | |F|F| | |+// +---------------+---------------+-+-+-+------------------------+ |+// | | | | |+// | time to live | protocol | header checksum | 20 bytes+// | | | | |+// +---------------+---------------+------------------------------+ |+// | | |+// | source IPv4 address | |+// | | |+// +--------------------------------------------------------------+ |+// | | |+// | destination IPv4 address | |+// | | v+// +--------------------------------------------------------------+ ---+// | | ^+// | | |+// / options (if any) / 0 - 40+// / / bytes+// | | |+// | | v+// +--------------------------------------------------------------+ ---++class ipv4_header+{+public:+ ipv4_header() { std::fill(rep_, rep_ + sizeof(rep_), 0); }++ unsigned char version() const { return (rep_[0] >> 4) & 0xF; }+ unsigned short header_length() const { return (rep_[0] & 0xF) * 4; }+ unsigned char type_of_service() const { return rep_[1]; }+ unsigned short total_length() const { return decode(2, 3); }+ unsigned short identification() const { return decode(4, 5); }+ bool dont_fragment() const { return (rep_[6] & 0x40) != 0; }+ bool more_fragments() const { return (rep_[6] & 0x20) != 0; }+ unsigned short fragment_offset() const { return decode(6, 7) & 0x1FFF; }+ unsigned int time_to_live() const { return rep_[8]; }+ unsigned char protocol() const { return rep_[9]; }+ unsigned short header_checksum() const { return decode(10, 11); }++ asio::ip::address_v4 source_address() const+ {+ asio::ip::address_v4::bytes_type bytes+ = { { rep_[12], rep_[13], rep_[14], rep_[15] } };+ return asio::ip::address_v4(bytes);+ }++ asio::ip::address_v4 destination_address() const+ {+ asio::ip::address_v4::bytes_type bytes+ = { { rep_[16], rep_[17], rep_[18], rep_[19] } };+ return asio::ip::address_v4(bytes);+ }++ friend std::istream& operator>>(std::istream& is, ipv4_header& header)+ {+ is.read(reinterpret_cast<char*>(header.rep_), 20);+ if (header.version() != 4)+ is.setstate(std::ios::failbit);+ std::streamsize options_length = header.header_length() - 20;+ if (options_length < 0 || options_length > 40)+ is.setstate(std::ios::failbit);+ else+ is.read(reinterpret_cast<char*>(header.rep_) + 20, options_length);+ return is;+ }++private:+ unsigned short decode(int a, int b) const+ { return (rep_[a] << 8) + rep_[b]; }++ unsigned char rep_[60];+};++#endif // IPV4_HEADER_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/porthopper/protocol.hpp view
@@ -0,0 +1,156 @@+//+// protocol.hpp+// ~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef PORTHOPPER_PROTOCOL_HPP+#define PORTHOPPER_PROTOCOL_HPP++#include <boost/array.hpp>+#include <asio.hpp>+#include <cstring>+#include <iomanip>+#include <string>+#include <strstream>++// This request is sent by the client to the server over a TCP connection.+// The client uses it to perform three functions:+// - To request that data start being sent to a given port.+// - To request that data is no longer sent to a given port.+// - To change the target port to another.+class control_request+{+public:+ // Construct an empty request. Used when receiving.+ control_request()+ {+ }++ // Create a request to start sending data to a given port.+ static const control_request start(unsigned short port)+ {+ return control_request(0, port);+ }++ // Create a request to stop sending data to a given port.+ static const control_request stop(unsigned short port)+ {+ return control_request(port, 0);+ }++ // Create a request to change the port that data is sent to.+ static const control_request change(+ unsigned short old_port, unsigned short new_port)+ {+ return control_request(old_port, new_port);+ }++ // Get the old port. Returns 0 for start requests.+ unsigned short old_port() const+ {+ std::istrstream is(data_, encoded_port_size);+ unsigned short port = 0;+ is >> std::setw(encoded_port_size) >> std::hex >> port;+ return port;+ }++ // Get the new port. Returns 0 for stop requests.+ unsigned short new_port() const+ {+ std::istrstream is(data_ + encoded_port_size, encoded_port_size);+ unsigned short port = 0;+ is >> std::setw(encoded_port_size) >> std::hex >> port;+ return port;+ }++ // Obtain buffers for reading from or writing to a socket.+ boost::array<asio::mutable_buffer, 1> to_buffers()+ {+ boost::array<asio::mutable_buffer, 1> buffers+ = { { asio::buffer(data_) } };+ return buffers;+ }++private:+ // Construct with specified old and new ports.+ control_request(unsigned short old_port_number,+ unsigned short new_port_number)+ {+ std::ostrstream os(data_, control_request_size);+ os << std::setw(encoded_port_size) << std::hex << old_port_number;+ os << std::setw(encoded_port_size) << std::hex << new_port_number;+ }++ // The length in bytes of a control_request and its components.+ enum+ {+ encoded_port_size = 4, // 16-bit port in hex.+ control_request_size = encoded_port_size * 2+ };++ // The encoded request data.+ char data_[control_request_size];+};++// This frame is sent from the server to subscribed clients over UDP.+class frame+{+public:+ // The maximum allowable length of the payload.+ enum { payload_size = 32 };++ // Construct an empty frame. Used when receiving.+ frame()+ {+ }++ // Construct a frame with specified frame number and payload.+ frame(unsigned long frame_number, const std::string& payload_data)+ {+ std::ostrstream os(data_, frame_size);+ os << std::setw(encoded_number_size) << std::hex << frame_number;+ os << std::setw(payload_size)+ << std::setfill(' ') << payload_data.substr(0, payload_size);+ }++ // Get the frame number.+ unsigned long number() const+ {+ std::istrstream is(data_, encoded_number_size);+ unsigned long frame_number = 0;+ is >> std::setw(encoded_number_size) >> std::hex >> frame_number;+ return frame_number;+ }++ // Get the payload data.+ const std::string payload() const+ {+ return std::string(data_ + encoded_number_size, payload_size);+ }++ // Obtain buffers for reading from or writing to a socket.+ boost::array<asio::mutable_buffer, 1> to_buffers()+ {+ boost::array<asio::mutable_buffer, 1> buffers+ = { { asio::buffer(data_) } };+ return buffers;+ }++private:+ // The length in bytes of a frame and its components.+ enum+ {+ encoded_number_size = 8, // Frame number in hex.+ frame_size = encoded_number_size + payload_size+ };++ // The encoded frame data.+ char data_[frame_size];+};++#endif // PORTHOPPER_PROTOCOL_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/serialization/connection.hpp view
@@ -0,0 +1,188 @@+//+// connection.hpp+// ~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef SERIALIZATION_CONNECTION_HPP+#define SERIALIZATION_CONNECTION_HPP++#include <asio.hpp>+#include <boost/archive/text_iarchive.hpp>+#include <boost/archive/text_oarchive.hpp>+#include <boost/bind/bind.hpp>+#include <boost/shared_ptr.hpp>+#include <boost/tuple/tuple.hpp>+#include <iomanip>+#include <string>+#include <sstream>+#include <vector>++namespace s11n_example {++/// The connection class provides serialization primitives on top of a socket.+/**+ * Each message sent using this class consists of:+ * @li An 8-byte header containing the length of the serialized data in+ * hexadecimal.+ * @li The serialized data.+ */+class connection+{+public:+ /// Constructor.+ connection(const asio::executor& ex)+ : socket_(ex)+ {+ }++ /// Get the underlying socket. Used for making a connection or for accepting+ /// an incoming connection.+ asio::ip::tcp::socket& socket()+ {+ return socket_;+ }++ /// Asynchronously write a data structure to the socket.+ template <typename T, typename Handler>+ void async_write(const T& t, Handler handler)+ {+ // Serialize the data first so we know how large it is.+ std::ostringstream archive_stream;+ boost::archive::text_oarchive archive(archive_stream);+ archive << t;+ outbound_data_ = archive_stream.str();++ // Format the header.+ std::ostringstream header_stream;+ header_stream << std::setw(header_length)+ << std::hex << outbound_data_.size();+ if (!header_stream || header_stream.str().size() != header_length)+ {+ // Something went wrong, inform the caller.+ asio::error_code error(asio::error::invalid_argument);+ asio::post(socket_.get_executor(), boost::bind(handler, error));+ return;+ }+ outbound_header_ = header_stream.str();++ // Write the serialized data to the socket. We use "gather-write" to send+ // both the header and the data in a single write operation.+ std::vector<asio::const_buffer> buffers;+ buffers.push_back(asio::buffer(outbound_header_));+ buffers.push_back(asio::buffer(outbound_data_));+ asio::async_write(socket_, buffers, handler);+ }++ /// Asynchronously read a data structure from the socket.+ template <typename T, typename Handler>+ void async_read(T& t, Handler handler)+ {+ // Issue a read operation to read exactly the number of bytes in a header.+ void (connection::*f)(+ const asio::error_code&,+ T&, boost::tuple<Handler>)+ = &connection::handle_read_header<T, Handler>;+ asio::async_read(socket_, asio::buffer(inbound_header_),+ boost::bind(f,+ this, asio::placeholders::error, boost::ref(t),+ boost::make_tuple(handler)));+ }++ /// Handle a completed read of a message header. The handler is passed using+ /// a tuple since boost::bind seems to have trouble binding a function object+ /// created using boost::bind as a parameter.+ template <typename T, typename Handler>+ void handle_read_header(const asio::error_code& e,+ T& t, boost::tuple<Handler> handler)+ {+ if (e)+ {+ boost::get<0>(handler)(e);+ }+ else+ {+ // Determine the length of the serialized data.+ std::istringstream is(std::string(inbound_header_, header_length));+ std::size_t inbound_data_size = 0;+ if (!(is >> std::hex >> inbound_data_size))+ {+ // Header doesn't seem to be valid. Inform the caller.+ asio::error_code error(asio::error::invalid_argument);+ boost::get<0>(handler)(error);+ return;+ }++ // Start an asynchronous call to receive the data.+ inbound_data_.resize(inbound_data_size);+ void (connection::*f)(+ const asio::error_code&,+ T&, boost::tuple<Handler>)+ = &connection::handle_read_data<T, Handler>;+ asio::async_read(socket_, asio::buffer(inbound_data_),+ boost::bind(f, this,+ asio::placeholders::error, boost::ref(t), handler));+ }+ }++ /// Handle a completed read of message data.+ template <typename T, typename Handler>+ void handle_read_data(const asio::error_code& e,+ T& t, boost::tuple<Handler> handler)+ {+ if (e)+ {+ boost::get<0>(handler)(e);+ }+ else+ {+ // Extract the data structure from the data just received.+ try+ {+ std::string archive_data(&inbound_data_[0], inbound_data_.size());+ std::istringstream archive_stream(archive_data);+ boost::archive::text_iarchive archive(archive_stream);+ archive >> t;+ }+ catch (std::exception& e)+ {+ // Unable to decode data.+ asio::error_code error(asio::error::invalid_argument);+ boost::get<0>(handler)(error);+ return;+ }++ // Inform caller that data has been received ok.+ boost::get<0>(handler)(e);+ }+ }++private:+ /// The underlying socket.+ asio::ip::tcp::socket socket_;++ /// The size of a fixed length header.+ enum { header_length = 8 };++ /// Holds an outbound header.+ std::string outbound_header_;++ /// Holds the outbound data.+ std::string outbound_data_;++ /// Holds an inbound header.+ char inbound_header_[header_length];++ /// Holds the inbound data.+ std::vector<char> inbound_data_;+};++typedef boost::shared_ptr<connection> connection_ptr;++} // namespace s11n_example++#endif // SERIALIZATION_CONNECTION_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/serialization/stock.hpp view
@@ -0,0 +1,50 @@+//+// stock.hpp+// ~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef SERIALIZATION_STOCK_HPP+#define SERIALIZATION_STOCK_HPP++#include <string>++namespace s11n_example {++/// Structure to hold information about a single stock.+struct stock+{+ std::string code;+ std::string name;+ double open_price;+ double high_price;+ double low_price;+ double last_price;+ double buy_price;+ int buy_quantity;+ double sell_price;+ int sell_quantity;++ template <typename Archive>+ void serialize(Archive& ar, const unsigned int version)+ {+ ar & code;+ ar & name;+ ar & open_price;+ ar & high_price;+ ar & low_price;+ ar & last_price;+ ar & buy_price;+ ar & buy_quantity;+ ar & sell_price;+ ar & sell_quantity;+ }+};++} // namespace s11n_example++#endif // SERIALIZATION_STOCK_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/services/basic_logger.hpp view
@@ -0,0 +1,77 @@+//+// basic_logger.hpp+// ~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef SERVICES_BASIC_LOGGER_HPP+#define SERVICES_BASIC_LOGGER_HPP++#include <asio.hpp>+#include <boost/noncopyable.hpp>+#include <string>++namespace services {++/// Class to provide simple logging functionality. Use the services::logger+/// typedef.+template <typename Service>+class basic_logger+ : private boost::noncopyable+{+public:+ /// The type of the service that will be used to provide timer operations.+ typedef Service service_type;++ /// The native implementation type of the timer.+ typedef typename service_type::impl_type impl_type;++ /// Constructor.+ /**+ * This constructor creates a logger.+ *+ * @param context The execution context used to locate the logger service.+ *+ * @param identifier An identifier for this logger.+ */+ explicit basic_logger(asio::execution_context& context,+ const std::string& identifier)+ : service_(asio::use_service<Service>(context)),+ impl_(service_.null())+ {+ service_.create(impl_, identifier);+ }++ /// Destructor.+ ~basic_logger()+ {+ service_.destroy(impl_);+ }++ /// Set the output file for all logger instances.+ void use_file(const std::string& file)+ {+ service_.use_file(impl_, file);+ }++ /// Log a message.+ void log(const std::string& message)+ {+ service_.log(impl_, message);+ }++private:+ /// The backend service implementation.+ service_type& service_;++ /// The underlying native implementation.+ impl_type impl_;+};++} // namespace services++#endif // SERVICES_BASIC_LOGGER_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/services/logger.hpp view
@@ -0,0 +1,24 @@+//+// logger.hpp+// ~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef SERVICES_LOGGER_HPP+#define SERVICES_LOGGER_HPP++#include "basic_logger.hpp"+#include "logger_service.hpp"++namespace services {++/// Typedef for typical logger usage.+typedef basic_logger<logger_service> logger;++} // namespace services++#endif // SERVICES_LOGGER_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/services/logger_service.hpp view
@@ -0,0 +1,145 @@+//+// logger_service.hpp+// ~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef SERVICES_LOGGER_SERVICE_HPP+#define SERVICES_LOGGER_SERVICE_HPP++#include <asio.hpp>+#include <boost/bind/bind.hpp>+#include <boost/date_time/posix_time/posix_time.hpp>+#include <boost/noncopyable.hpp>+#include <boost/scoped_ptr.hpp>+#include <fstream>+#include <sstream>+#include <string>++namespace services {++/// Service implementation for the logger.+class logger_service+ : public asio::execution_context::service+{+public:+ /// The type used to identify this service in the execution context.+ typedef logger_service key_type;++ /// The backend implementation of a logger.+ struct logger_impl+ {+ explicit logger_impl(const std::string& ident) : identifier(ident) {}+ std::string identifier;+ };++ /// The type for an implementation of the logger.+ typedef logger_impl* impl_type;++ /// Constructor creates a thread to run a private io_context.+ logger_service(asio::execution_context& context)+ : asio::execution_context::service(context),+ work_io_context_(),+ work_(asio::make_work_guard(work_io_context_)),+ work_thread_(new asio::thread(+ boost::bind(&asio::io_context::run, &work_io_context_)))+ {+ }++ /// Destructor shuts down the private io_context.+ ~logger_service()+ {+ /// Indicate that we have finished with the private io_context. Its+ /// io_context::run() function will exit once all other work has completed.+ work_.reset();+ if (work_thread_)+ work_thread_->join();+ }++ /// Destroy all user-defined handler objects owned by the service.+ void shutdown()+ {+ }++ /// Return a null logger implementation.+ impl_type null() const+ {+ return 0;+ }++ /// Create a new logger implementation.+ void create(impl_type& impl, const std::string& identifier)+ {+ impl = new logger_impl(identifier);+ }++ /// Destroy a logger implementation.+ void destroy(impl_type& impl)+ {+ delete impl;+ impl = null();+ }++ /// Set the output file for the logger. The current implementation sets the+ /// output file for all logger instances, and so the impl parameter is not+ /// actually needed. It is retained here to illustrate how service functions+ /// are typically defined.+ void use_file(impl_type& /*impl*/, const std::string& file)+ {+ // Pass the work of opening the file to the background thread.+ asio::post(work_io_context_, boost::bind(+ &logger_service::use_file_impl, this, file));+ }++ /// Log a message.+ void log(impl_type& impl, const std::string& message)+ {+ // Format the text to be logged.+ std::ostringstream os;+ os << impl->identifier << ": " << message;++ // Pass the work of writing to the file to the background thread.+ asio::post(work_io_context_, boost::bind(+ &logger_service::log_impl, this, os.str()));+ }++private:+ /// Helper function used to open the output file from within the private+ /// io_context's thread.+ void use_file_impl(const std::string& file)+ {+ ofstream_.close();+ ofstream_.clear();+ ofstream_.open(file.c_str());+ }++ /// Helper function used to log a message from within the private io_context's+ /// thread.+ void log_impl(const std::string& text)+ {+ ofstream_ << text << std::endl;+ }++ /// Private io_context used for performing logging operations.+ asio::io_context work_io_context_;++ /// Work for the private io_context to perform. If we do not give the+ /// io_context some work to do then the io_context::run() function will exit+ /// immediately.+ asio::executor_work_guard<+ asio::io_context::executor_type> work_;++ /// Thread used for running the work io_context's run loop.+ boost::scoped_ptr<asio::thread> work_thread_;++ /// The file to which log messages will be written.+ std::ofstream ofstream_;+};++} // namespace services++#endif // SERVICES_LOGGER_SERVICE_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/socks4/socks4.hpp view
@@ -0,0 +1,144 @@+//+// socks4.hpp+// ~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+//+// Distributed under the Boost Software License, Version 1.0. (See accompanying+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)+//++#ifndef SOCKS4_HPP+#define SOCKS4_HPP++#include <string>+#include <asio.hpp>+#include <boost/array.hpp>++namespace socks4 {++const unsigned char version = 0x04;++class request+{+public:+ enum command_type+ {+ connect = 0x01,+ bind = 0x02+ };++ request(command_type cmd, const asio::ip::tcp::endpoint& endpoint,+ const std::string& user_id)+ : version_(version),+ command_(cmd),+ user_id_(user_id),+ null_byte_(0)+ {+ // Only IPv4 is supported by the SOCKS 4 protocol.+ if (endpoint.protocol() != asio::ip::tcp::v4())+ {+ throw asio::system_error(+ asio::error::address_family_not_supported);+ }++ // Convert port number to network byte order.+ unsigned short port = endpoint.port();+ port_high_byte_ = (port >> 8) & 0xff;+ port_low_byte_ = port & 0xff;++ // Save IP address in network byte order.+ address_ = endpoint.address().to_v4().to_bytes();+ }++ boost::array<asio::const_buffer, 7> buffers() const+ {+ boost::array<asio::const_buffer, 7> bufs =+ {+ {+ asio::buffer(&version_, 1),+ asio::buffer(&command_, 1),+ asio::buffer(&port_high_byte_, 1),+ asio::buffer(&port_low_byte_, 1),+ asio::buffer(address_),+ asio::buffer(user_id_),+ asio::buffer(&null_byte_, 1)+ }+ };+ return bufs;+ }++private:+ unsigned char version_;+ unsigned char command_;+ unsigned char port_high_byte_;+ unsigned char port_low_byte_;+ asio::ip::address_v4::bytes_type address_;+ std::string user_id_;+ unsigned char null_byte_;+};++class reply+{+public:+ enum status_type+ {+ request_granted = 0x5a,+ request_failed = 0x5b,+ request_failed_no_identd = 0x5c,+ request_failed_bad_user_id = 0x5d+ };++ reply()+ : null_byte_(0),+ status_()+ {+ }++ boost::array<asio::mutable_buffer, 5> buffers()+ {+ boost::array<asio::mutable_buffer, 5> bufs =+ {+ {+ asio::buffer(&null_byte_, 1),+ asio::buffer(&status_, 1),+ asio::buffer(&port_high_byte_, 1),+ asio::buffer(&port_low_byte_, 1),+ asio::buffer(address_)+ }+ };+ return bufs;+ }++ bool success() const+ {+ return null_byte_ == 0 && status_ == request_granted;+ }++ unsigned char status() const+ {+ return status_;+ }++ asio::ip::tcp::endpoint endpoint() const+ {+ unsigned short port = port_high_byte_;+ port = (port << 8) & 0xff00;+ port = port | port_low_byte_;++ asio::ip::address_v4 address(address_);++ return asio::ip::tcp::endpoint(address, port);+ }++private:+ unsigned char null_byte_;+ unsigned char status_;+ unsigned char port_high_byte_;+ unsigned char port_low_byte_;+ asio::ip::address_v4::bytes_type address_;+};++} // namespace socks4++#endif // SOCKS4_HPP
link/modules/asio-standalone/asio/src/examples/cpp11/chat/chat_message.hpp view
@@ -2,7 +2,7 @@ // chat_message.hpp // ~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -79,8 +79,7 @@ void encode_header() { char header[header_length + 1] = "";- std::snprintf(header, header_length + 1,- "%4d", static_cast<int>(body_length_));+ std::sprintf(header, "%4d", static_cast<int>(body_length_)); std::memcpy(data_, header, header_length); }
link/modules/asio-standalone/asio/src/examples/cpp11/handler_tracking/custom_tracking.hpp view
@@ -2,7 +2,7 @@ // custom_tracking.hpp // ~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -187,7 +187,7 @@ // Record a reactor-based operation that is associated with a handler. static void reactor_operation(const tracked_handler& h,- const char* op_name, const std::error_code& ec)+ const char* op_name, const asio::error_code& ec) { std::printf( "Performed operation %s.%s for native_handle = %" PRIuMAX@@ -197,7 +197,7 @@ // Record a reactor-based operation that is associated with a handler. static void reactor_operation(const tracked_handler& h,- const char* op_name, const std::error_code& ec,+ const char* op_name, const asio::error_code& ec, std::size_t bytes_transferred) { std::printf(
link/modules/asio-standalone/asio/src/examples/cpp11/http/server/connection.hpp view
@@ -2,7 +2,7 @@ // connection.hpp // ~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -11,9 +11,9 @@ #ifndef HTTP_CONNECTION_HPP #define HTTP_CONNECTION_HPP -#include <asio.hpp> #include <array> #include <memory>+#include <asio.hpp> #include "reply.hpp" #include "request.hpp" #include "request_handler.hpp"
link/modules/asio-standalone/asio/src/examples/cpp11/http/server/connection_manager.hpp view
@@ -2,7 +2,7 @@ // connection_manager.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/src/examples/cpp11/http/server/header.hpp view
@@ -2,7 +2,7 @@ // header.hpp // ~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/src/examples/cpp11/http/server/mime_types.hpp view
@@ -2,7 +2,7 @@ // mime_types.hpp // ~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/src/examples/cpp11/http/server/reply.hpp view
@@ -2,7 +2,7 @@ // reply.hpp // ~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/src/examples/cpp11/http/server/request.hpp view
@@ -2,7 +2,7 @@ // request.hpp // ~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/src/examples/cpp11/http/server/request_handler.hpp view
@@ -2,7 +2,7 @@ // request_handler.hpp // ~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/src/examples/cpp11/http/server/request_parser.hpp view
@@ -2,7 +2,7 @@ // request_parser.hpp // ~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/src/examples/cpp11/http/server/server.hpp view
@@ -2,7 +2,7 @@ // server.hpp // ~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
− link/modules/asio-standalone/asio/src/examples/cpp11/http/server2/connection.hpp
@@ -1,71 +0,0 @@-//-// connection.hpp-// ~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef HTTP_SERVER2_CONNECTION_HPP-#define HTTP_SERVER2_CONNECTION_HPP--#include <asio.hpp>-#include <array>-#include <memory>-#include "reply.hpp"-#include "request.hpp"-#include "request_handler.hpp"-#include "request_parser.hpp"--namespace http {-namespace server2 {--/// Represents a single connection from a client.-class connection- : public std::enable_shared_from_this<connection>-{-public:- connection(const connection&) = delete;- connection& operator=(const connection&) = delete;-- /// Construct a connection with the given socket.- explicit connection(asio::ip::tcp::socket socket,- request_handler& handler);-- /// Start the first asynchronous operation for the connection.- void start();--private:- /// Perform an asynchronous read operation.- void do_read();-- /// Perform an asynchronous write operation.- void do_write();-- /// Socket for the connection.- asio::ip::tcp::socket socket_;-- /// The handler used to process the incoming request.- request_handler& request_handler_;-- /// Buffer for incoming data.- std::array<char, 8192> buffer_;-- /// The incoming request.- request request_;-- /// The parser for the incoming request.- request_parser request_parser_;-- /// The reply to be sent back to the client.- reply reply_;-};--typedef std::shared_ptr<connection> connection_ptr;--} // namespace server2-} // namespace http--#endif // HTTP_SERVER2_CONNECTION_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/http/server2/header.hpp
@@ -1,28 +0,0 @@-//-// header.hpp-// ~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef HTTP_SERVER2_HEADER_HPP-#define HTTP_SERVER2_HEADER_HPP--#include <string>--namespace http {-namespace server2 {--struct header-{- std::string name;- std::string value;-};--} // namespace server2-} // namespace http--#endif // HTTP_SERVER2_HEADER_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/http/server2/io_context_pool.hpp
@@ -1,59 +0,0 @@-//-// io_context_pool.hpp-// ~~~~~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef HTTP_SERVER2_IO_SERVICE_POOL_HPP-#define HTTP_SERVER2_IO_SERVICE_POOL_HPP--#include <asio.hpp>-#include <list>-#include <memory>-#include <vector>--namespace http {-namespace server2 {--/// A pool of io_context objects.-class io_context_pool-{-public:- /// Construct the io_context pool.- explicit io_context_pool(std::size_t pool_size);-- /// Run all io_context objects in the pool.- void run();-- /// Stop all io_context objects in the pool.- void stop();-- /// Get an io_context to use.- asio::io_context& get_io_context();--private:- io_context_pool(const io_context_pool&) = delete;- io_context_pool& operator=(const io_context_pool&) = delete;-- typedef std::shared_ptr<asio::io_context> io_context_ptr;- typedef asio::executor_work_guard<- asio::io_context::executor_type> io_context_work;-- /// The pool of io_contexts.- std::vector<io_context_ptr> io_contexts_;-- /// The work that keeps the io_contexts running.- std::list<io_context_work> work_;-- /// The next io_context to use for a connection.- std::size_t next_io_context_;-};--} // namespace server2-} // namespace http--#endif // HTTP_SERVER2_IO_SERVICE_POOL_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/http/server2/mime_types.hpp
@@ -1,27 +0,0 @@-//-// mime_types.hpp-// ~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef HTTP_SERVER2_MIME_TYPES_HPP-#define HTTP_SERVER2_MIME_TYPES_HPP--#include <string>--namespace http {-namespace server2 {-namespace mime_types {--/// Convert a file extension into a MIME type.-std::string extension_to_type(const std::string& extension);--} // namespace mime_types-} // namespace server2-} // namespace http--#endif // HTTP_SERVER2_MIME_TYPES_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/http/server2/reply.hpp
@@ -1,64 +0,0 @@-//-// reply.hpp-// ~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef HTTP_SERVER2_REPLY_HPP-#define HTTP_SERVER2_REPLY_HPP--#include <string>-#include <vector>-#include <asio.hpp>-#include "header.hpp"--namespace http {-namespace server2 {--/// A reply to be sent to a client.-struct reply-{- /// The status of the reply.- enum status_type- {- ok = 200,- created = 201,- accepted = 202,- no_content = 204,- multiple_choices = 300,- moved_permanently = 301,- moved_temporarily = 302,- not_modified = 304,- bad_request = 400,- unauthorized = 401,- forbidden = 403,- not_found = 404,- internal_server_error = 500,- not_implemented = 501,- bad_gateway = 502,- service_unavailable = 503- } status;-- /// The headers to be included in the reply.- std::vector<header> headers;-- /// The content to be sent in the reply.- std::string content;-- /// Convert the reply into a vector of buffers. The buffers do not own the- /// underlying memory blocks, therefore the reply object must remain valid and- /// not be changed until the write operation has completed.- std::vector<asio::const_buffer> to_buffers();-- /// Get a stock reply.- static reply stock_reply(status_type status);-};--} // namespace server2-} // namespace http--#endif // HTTP_SERVER2_REPLY_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/http/server2/request.hpp
@@ -1,34 +0,0 @@-//-// request.hpp-// ~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef HTTP_SERVER2_REQUEST_HPP-#define HTTP_SERVER2_REQUEST_HPP--#include <string>-#include <vector>-#include "header.hpp"--namespace http {-namespace server2 {--/// A request received from a client.-struct request-{- std::string method;- std::string uri;- int http_version_major;- int http_version_minor;- std::vector<header> headers;-};--} // namespace server2-} // namespace http--#endif // HTTP_SERVER2_REQUEST_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/http/server2/request_handler.hpp
@@ -1,47 +0,0 @@-//-// request_handler.hpp-// ~~~~~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef HTTP_SERVER2_REQUEST_HANDLER_HPP-#define HTTP_SERVER2_REQUEST_HANDLER_HPP--#include <string>--namespace http {-namespace server2 {--struct reply;-struct request;--/// The common handler for all incoming requests.-class request_handler-{-public:- request_handler(const request_handler&) = delete;- request_handler& operator=(const request_handler&) = delete;-- /// Construct with a directory containing files to be served.- explicit request_handler(const std::string& doc_root);-- /// Handle a request and produce a reply.- void handle_request(const request& req, reply& rep);--private:- /// The directory containing the files to be served.- std::string doc_root_;-- /// Perform URL-decoding on a string. Returns false if the encoding was- /// invalid.- static bool url_decode(const std::string& in, std::string& out);-};--} // namespace server2-} // namespace http--#endif // HTTP_SERVER2_REQUEST_HANDLER_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/http/server2/request_parser.hpp
@@ -1,96 +0,0 @@-//-// request_parser.hpp-// ~~~~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef HTTP_SERVER2_REQUEST_PARSER_HPP-#define HTTP_SERVER2_REQUEST_PARSER_HPP--#include <tuple>--namespace http {-namespace server2 {--struct request;--/// Parser for incoming requests.-class request_parser-{-public:- /// Construct ready to parse the request method.- request_parser();-- /// Reset to initial parser state.- void reset();-- /// Result of parse.- enum result_type { good, bad, indeterminate };-- /// Parse some data. The enum return value is good when a complete request has- /// been parsed, bad if the data is invalid, indeterminate when more data is- /// required. The InputIterator return value indicates how much of the input- /// has been consumed.- template <typename InputIterator>- std::tuple<result_type, InputIterator> parse(request& req,- InputIterator begin, InputIterator end)- {- while (begin != end)- {- result_type result = consume(req, *begin++);- if (result == good || result == bad)- return std::make_tuple(result, begin);- }- return std::make_tuple(indeterminate, begin);- }--private:- /// Handle the next character of input.- result_type consume(request& req, char input);-- /// Check if a byte is an HTTP character.- static bool is_char(int c);-- /// Check if a byte is an HTTP control character.- static bool is_ctl(int c);-- /// Check if a byte is defined as an HTTP tspecial character.- static bool is_tspecial(int c);-- /// Check if a byte is a digit.- static bool is_digit(int c);-- /// The current state of the parser.- enum state- {- method_start,- method,- uri,- http_version_h,- http_version_t_1,- http_version_t_2,- http_version_p,- http_version_slash,- http_version_major_start,- http_version_major,- http_version_minor_start,- http_version_minor,- expecting_newline_1,- header_line_start,- header_lws,- header_name,- space_before_header_value,- header_value,- expecting_newline_2,- expecting_newline_3- } state_;-};--} // namespace server2-} // namespace http--#endif // HTTP_SERVER2_REQUEST_PARSER_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/http/server2/server.hpp
@@ -1,60 +0,0 @@-//-// server.hpp-// ~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef HTTP_SERVER2_SERVER_HPP-#define HTTP_SERVER2_SERVER_HPP--#include <asio.hpp>-#include <string>-#include "io_context_pool.hpp"-#include "request_handler.hpp"--namespace http {-namespace server2 {--/// The top-level class of the HTTP server.-class server-{-public:- server(const server&) = delete;- server& operator=(const server&) = delete;-- /// Construct the server to listen on the specified TCP address and port, and- /// serve up files from the given directory.- explicit server(const std::string& address, const std::string& port,- const std::string& doc_root, std::size_t io_context_pool_size);-- /// Run the server's io_context loop.- void run();--private:- /// Perform an asynchronous accept operation.- void do_accept();-- /// Wait for a request to stop the server.- void do_await_stop();-- /// The pool of io_context objects used to perform asynchronous operations.- io_context_pool io_context_pool_;-- /// The signal_set is used to register for process termination notifications.- asio::signal_set signals_;-- /// Acceptor used to listen for incoming connections.- asio::ip::tcp::acceptor acceptor_;-- /// The handler for all incoming requests.- request_handler request_handler_;-};--} // namespace server2-} // namespace http--#endif // HTTP_SERVER2_SERVER_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/http/server3/connection.hpp
@@ -1,71 +0,0 @@-//-// connection.hpp-// ~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef HTTP_SERVER3_CONNECTION_HPP-#define HTTP_SERVER3_CONNECTION_HPP--#include <asio.hpp>-#include <array>-#include <memory>-#include "reply.hpp"-#include "request.hpp"-#include "request_handler.hpp"-#include "request_parser.hpp"--namespace http {-namespace server3 {--/// Represents a single connection from a client.-class connection- : public std::enable_shared_from_this<connection>-{-public:- connection(const connection&) = delete;- connection& operator=(const connection&) = delete;-- /// Construct a connection with the given socket.- explicit connection(asio::ip::tcp::socket socket,- request_handler& handler);-- /// Start the first asynchronous operation for the connection.- void start();--private:- /// Perform an asynchronous read operation.- void do_read();-- /// Perform an asynchronous write operation.- void do_write();-- /// Socket for the connection.- asio::ip::tcp::socket socket_;-- /// The handler used to process the incoming request.- request_handler& request_handler_;-- /// Buffer for incoming data.- std::array<char, 8192> buffer_;-- /// The incoming request.- request request_;-- /// The parser for the incoming request.- request_parser request_parser_;-- /// The reply to be sent back to the client.- reply reply_;-};--typedef std::shared_ptr<connection> connection_ptr;--} // namespace server3-} // namespace http--#endif // HTTP_SERVER3_CONNECTION_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/http/server3/header.hpp
@@ -1,28 +0,0 @@-//-// header.hpp-// ~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef HTTP_SERVER3_HEADER_HPP-#define HTTP_SERVER3_HEADER_HPP--#include <string>--namespace http {-namespace server3 {--struct header-{- std::string name;- std::string value;-};--} // namespace server3-} // namespace http--#endif // HTTP_SERVER3_HEADER_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/http/server3/mime_types.hpp
@@ -1,27 +0,0 @@-//-// mime_types.hpp-// ~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef HTTP_SERVER3_MIME_TYPES_HPP-#define HTTP_SERVER3_MIME_TYPES_HPP--#include <string>--namespace http {-namespace server3 {-namespace mime_types {--/// Convert a file extension into a MIME type.-std::string extension_to_type(const std::string& extension);--} // namespace mime_types-} // namespace server3-} // namespace http--#endif // HTTP_SERVER3_MIME_TYPES_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/http/server3/reply.hpp
@@ -1,64 +0,0 @@-//-// reply.hpp-// ~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef HTTP_SERVER3_REPLY_HPP-#define HTTP_SERVER3_REPLY_HPP--#include <string>-#include <vector>-#include <asio.hpp>-#include "header.hpp"--namespace http {-namespace server3 {--/// A reply to be sent to a client.-struct reply-{- /// The status of the reply.- enum status_type- {- ok = 200,- created = 201,- accepted = 202,- no_content = 204,- multiple_choices = 300,- moved_permanently = 301,- moved_temporarily = 302,- not_modified = 304,- bad_request = 400,- unauthorized = 401,- forbidden = 403,- not_found = 404,- internal_server_error = 500,- not_implemented = 501,- bad_gateway = 502,- service_unavailable = 503- } status;-- /// The headers to be included in the reply.- std::vector<header> headers;-- /// The content to be sent in the reply.- std::string content;-- /// Convert the reply into a vector of buffers. The buffers do not own the- /// underlying memory blocks, therefore the reply object must remain valid and- /// not be changed until the write operation has completed.- std::vector<asio::const_buffer> to_buffers();-- /// Get a stock reply.- static reply stock_reply(status_type status);-};--} // namespace server3-} // namespace http--#endif // HTTP_SERVER3_REPLY_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/http/server3/request.hpp
@@ -1,34 +0,0 @@-//-// request.hpp-// ~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef HTTP_SERVER3_REQUEST_HPP-#define HTTP_SERVER3_REQUEST_HPP--#include <string>-#include <vector>-#include "header.hpp"--namespace http {-namespace server3 {--/// A request received from a client.-struct request-{- std::string method;- std::string uri;- int http_version_major;- int http_version_minor;- std::vector<header> headers;-};--} // namespace server3-} // namespace http--#endif // HTTP_SERVER3_REQUEST_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/http/server3/request_handler.hpp
@@ -1,47 +0,0 @@-//-// request_handler.hpp-// ~~~~~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef HTTP_SERVER3_REQUEST_HANDLER_HPP-#define HTTP_SERVER3_REQUEST_HANDLER_HPP--#include <string>--namespace http {-namespace server3 {--struct reply;-struct request;--/// The common handler for all incoming requests.-class request_handler-{-public:- request_handler(const request_handler&) = delete;- request_handler& operator=(const request_handler&) = delete;-- /// Construct with a directory containing files to be served.- explicit request_handler(const std::string& doc_root);-- /// Handle a request and produce a reply.- void handle_request(const request& req, reply& rep);--private:- /// The directory containing the files to be served.- std::string doc_root_;-- /// Perform URL-decoding on a string. Returns false if the encoding was- /// invalid.- static bool url_decode(const std::string& in, std::string& out);-};--} // namespace server3-} // namespace http--#endif // HTTP_SERVER3_REQUEST_HANDLER_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/http/server3/request_parser.hpp
@@ -1,96 +0,0 @@-//-// request_parser.hpp-// ~~~~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef HTTP_SERVER3_REQUEST_PARSER_HPP-#define HTTP_SERVER3_REQUEST_PARSER_HPP--#include <tuple>--namespace http {-namespace server3 {--struct request;--/// Parser for incoming requests.-class request_parser-{-public:- /// Construct ready to parse the request method.- request_parser();-- /// Reset to initial parser state.- void reset();-- /// Result of parse.- enum result_type { good, bad, indeterminate };-- /// Parse some data. The enum return value is good when a complete request has- /// been parsed, bad if the data is invalid, indeterminate when more data is- /// required. The InputIterator return value indicates how much of the input- /// has been consumed.- template <typename InputIterator>- std::tuple<result_type, InputIterator> parse(request& req,- InputIterator begin, InputIterator end)- {- while (begin != end)- {- result_type result = consume(req, *begin++);- if (result == good || result == bad)- return std::make_tuple(result, begin);- }- return std::make_tuple(indeterminate, begin);- }--private:- /// Handle the next character of input.- result_type consume(request& req, char input);-- /// Check if a byte is an HTTP character.- static bool is_char(int c);-- /// Check if a byte is an HTTP control character.- static bool is_ctl(int c);-- /// Check if a byte is defined as an HTTP tspecial character.- static bool is_tspecial(int c);-- /// Check if a byte is a digit.- static bool is_digit(int c);-- /// The current state of the parser.- enum state- {- method_start,- method,- uri,- http_version_h,- http_version_t_1,- http_version_t_2,- http_version_p,- http_version_slash,- http_version_major_start,- http_version_major,- http_version_minor_start,- http_version_minor,- expecting_newline_1,- header_line_start,- header_lws,- header_name,- space_before_header_value,- header_value,- expecting_newline_2,- expecting_newline_3- } state_;-};--} // namespace server3-} // namespace http--#endif // HTTP_SERVER3_REQUEST_PARSER_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/http/server3/server.hpp
@@ -1,62 +0,0 @@-//-// server.hpp-// ~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef HTTP_SERVER3_SERVER_HPP-#define HTTP_SERVER3_SERVER_HPP--#include <asio.hpp>-#include <string>-#include "request_handler.hpp"--namespace http {-namespace server3 {--/// The top-level class of the HTTP server.-class server-{-public:- server(const server&) = delete;- server& operator=(const server&) = delete;-- /// Construct the server to listen on the specified TCP address and port, and- /// serve up files from the given directory.- explicit server(const std::string& address, const std::string& port,- const std::string& doc_root, std::size_t thread_pool_size);-- /// Run the server's io_context loop.- void run();--private:- /// Perform an asynchronous accept operation.- void do_accept();-- /// Wait for a request to stop the server.- void do_await_stop();-- /// The number of threads that will call io_context::run().- std::size_t thread_pool_size_;-- /// The io_context used to perform asynchronous operations.- asio::io_context io_context_;-- /// The signal_set is used to register for process termination notifications.- asio::signal_set signals_;-- /// Acceptor used to listen for incoming connections.- asio::ip::tcp::acceptor acceptor_;-- /// The handler for all incoming requests.- request_handler request_handler_;-};--} // namespace server3-} // namespace http--#endif // HTTP_SERVER3_SERVER_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/http/server4/file_handler.hpp
@@ -1,44 +0,0 @@-//-// file_handler.hpp-// ~~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef HTTP_SERVER4_FILE_HANDLER_HPP-#define HTTP_SERVER4_FILE_HANDLER_HPP--#include <string>--namespace http {-namespace server4 {--struct reply;-struct request;--/// The common handler for all incoming requests.-class file_handler-{-public:- /// Construct with a directory containing files to be served.- explicit file_handler(const std::string& doc_root);-- /// Handle a request and produce a reply.- void operator()(const request& req, reply& rep);--private:- /// The directory containing the files to be served.- std::string doc_root_;-- /// Perform URL-decoding on a string. Returns false if the encoding was- /// invalid.- static bool url_decode(const std::string& in, std::string& out);-};--} // namespace server4-} // namespace http--#endif // HTTP_SERVER4_FILE_HANDLER_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/http/server4/header.hpp
@@ -1,28 +0,0 @@-//-// header.hpp-// ~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef HTTP_SERVER4_HEADER_HPP-#define HTTP_SERVER4_HEADER_HPP--#include <string>--namespace http {-namespace server4 {--struct header-{- std::string name;- std::string value;-};--} // namespace server4-} // namespace http--#endif // HTTP_SERVER4_HEADER_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/http/server4/mime_types.hpp
@@ -1,27 +0,0 @@-//-// mime_types.hpp-// ~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef HTTP_SERVER4_MIME_TYPES_HPP-#define HTTP_SERVER4_MIME_TYPES_HPP--#include <string>--namespace http {-namespace server4 {-namespace mime_types {--/// Convert a file extension into a MIME type.-std::string extension_to_type(const std::string& extension);--} // namespace mime_types-} // namespace server4-} // namespace http--#endif // HTTP_SERVER4_MIME_TYPES_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/http/server4/reply.hpp
@@ -1,64 +0,0 @@-//-// reply.hpp-// ~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef HTTP_SERVER4_REPLY_HPP-#define HTTP_SERVER4_REPLY_HPP--#include <string>-#include <vector>-#include <asio.hpp>-#include "header.hpp"--namespace http {-namespace server4 {--/// A reply to be sent to a client.-struct reply-{- /// The status of the reply.- enum status_type- {- ok = 200,- created = 201,- accepted = 202,- no_content = 204,- multiple_choices = 300,- moved_permanently = 301,- moved_temporarily = 302,- not_modified = 304,- bad_request = 400,- unauthorized = 401,- forbidden = 403,- not_found = 404,- internal_server_error = 500,- not_implemented = 501,- bad_gateway = 502,- service_unavailable = 503- } status;-- /// The headers to be included in the reply.- std::vector<header> headers;-- /// The content to be sent in the reply.- std::string content;-- /// Convert the reply into a vector of buffers. The buffers do not own the- /// underlying memory blocks, therefore the reply object must remain valid and- /// not be changed until the write operation has completed.- std::vector<asio::const_buffer> to_buffers();-- /// Get a stock reply.- static reply stock_reply(status_type status);-};--} // namespace server4-} // namespace http--#endif // HTTP_SERVER4_REPLY_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/http/server4/request.hpp
@@ -1,34 +0,0 @@-//-// request.hpp-// ~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef HTTP_SERVER4_REQUEST_HPP-#define HTTP_SERVER4_REQUEST_HPP--#include <string>-#include <vector>-#include "header.hpp"--namespace http {-namespace server4 {--/// A request received from a client.-struct request-{- std::string method;- std::string uri;- int http_version_major;- int http_version_minor;- std::vector<header> headers;-};--} // namespace server4-} // namespace http--#endif // HTTP_SERVER4_REQUEST_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/http/server4/request_handler.hpp
@@ -1,47 +0,0 @@-//-// request_handler.hpp-// ~~~~~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef HTTP_SERVER4_REQUEST_HANDLER_HPP-#define HTTP_SERVER4_REQUEST_HANDLER_HPP--#include <string>--namespace http {-namespace server4 {--struct reply;-struct request;--/// The common handler for all incoming requests.-class request_handler-{-public:- request_handler(const request_handler&) = delete;- request_handler& operator=(const request_handler&) = delete;-- /// Construct with a directory containing files to be served.- explicit request_handler(const std::string& doc_root);-- /// Handle a request and produce a reply.- void handle_request(const request& req, reply& rep);--private:- /// The directory containing the files to be served.- std::string doc_root_;-- /// Perform URL-decoding on a string. Returns false if the encoding was- /// invalid.- static bool url_decode(const std::string& in, std::string& out);-};--} // namespace server4-} // namespace http--#endif // HTTP_SERVER4_REQUEST_HANDLER_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/http/server4/request_parser.hpp
@@ -1,96 +0,0 @@-//-// request_parser.hpp-// ~~~~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef HTTP_SERVER4_REQUEST_PARSER_HPP-#define HTTP_SERVER4_REQUEST_PARSER_HPP--#include <tuple>--namespace http {-namespace server4 {--struct request;--/// Parser for incoming requests.-class request_parser-{-public:- /// Construct ready to parse the request method.- request_parser();-- /// Reset to initial parser state.- void reset();-- /// Result of parse.- enum result_type { good, bad, indeterminate };-- /// Parse some data. The enum return value is good when a complete request has- /// been parsed, bad if the data is invalid, indeterminate when more data is- /// required. The InputIterator return value indicates how much of the input- /// has been consumed.- template <typename InputIterator>- std::tuple<result_type, InputIterator> parse(request& req,- InputIterator begin, InputIterator end)- {- while (begin != end)- {- result_type result = consume(req, *begin++);- if (result == good || result == bad)- return std::make_tuple(result, begin);- }- return std::make_tuple(indeterminate, begin);- }--private:- /// Handle the next character of input.- result_type consume(request& req, char input);-- /// Check if a byte is an HTTP character.- static bool is_char(int c);-- /// Check if a byte is an HTTP control character.- static bool is_ctl(int c);-- /// Check if a byte is defined as an HTTP tspecial character.- static bool is_tspecial(int c);-- /// Check if a byte is a digit.- static bool is_digit(int c);-- /// The current state of the parser.- enum state- {- method_start,- method,- uri,- http_version_h,- http_version_t_1,- http_version_t_2,- http_version_p,- http_version_slash,- http_version_major_start,- http_version_major,- http_version_minor_start,- http_version_minor,- expecting_newline_1,- header_line_start,- header_lws,- header_name,- space_before_header_value,- header_value,- expecting_newline_2,- expecting_newline_3- } state_;-};--} // namespace server4-} // namespace http--#endif // HTTP_SERVER4_REQUEST_PARSER_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/http/server4/server.hpp
@@ -1,73 +0,0 @@-//-// server.hpp-// ~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef HTTP_SERVER4_SERVER_HPP-#define HTTP_SERVER4_SERVER_HPP--#include <asio.hpp>-#include <array>-#include <functional>-#include <memory>-#include <string>-#include "request_parser.hpp"--namespace http {-namespace server4 {--struct request;-struct reply;--/// The top-level coroutine of the HTTP server.-class server : asio::coroutine-{-public:- /// Construct the server to listen on the specified TCP address and port, and- /// serve up files from the given directory.- explicit server(asio::io_context& io_context,- const std::string& address, const std::string& port,- std::function<void(const request&, reply&)> request_handler);-- /// Perform work associated with the server.- void operator()(- std::error_code ec = std::error_code(),- std::size_t length = 0);--private:- typedef asio::ip::tcp tcp;-- /// The user-supplied handler for all incoming requests.- std::function<void(const request&, reply&)> request_handler_;-- /// Acceptor used to listen for incoming connections.- std::shared_ptr<tcp::acceptor> acceptor_;-- /// The current connection from a client.- std::shared_ptr<tcp::socket> socket_;-- /// Buffer for incoming data.- std::shared_ptr<std::array<char, 8192>> buffer_;-- /// The incoming request.- std::shared_ptr<request> request_;-- /// Whether the request is valid or not.- request_parser::result_type parse_result_;-- /// The parser for the incoming request.- request_parser request_parser_;-- /// The reply to be sent back to the client.- std::shared_ptr<reply> reply_;-};--} // namespace server4-} // namespace http--#endif // HTTP_SERVER4_SERVER_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/icmp/icmp_header.hpp
@@ -1,94 +0,0 @@-//-// icmp_header.hpp-// ~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef ICMP_HEADER_HPP-#define ICMP_HEADER_HPP--#include <istream>-#include <ostream>-#include <algorithm>--// ICMP header for both IPv4 and IPv6.-//-// The wire format of an ICMP header is:-//-// 0 8 16 31-// +---------------+---------------+------------------------------+ ----// | | | | ^-// | type | code | checksum | |-// | | | | |-// +---------------+---------------+------------------------------+ 8 bytes-// | | | |-// | identifier | sequence number | |-// | | | v-// +-------------------------------+------------------------------+ -----class icmp_header-{-public:- enum { echo_reply = 0, destination_unreachable = 3, source_quench = 4,- redirect = 5, echo_request = 8, time_exceeded = 11, parameter_problem = 12,- timestamp_request = 13, timestamp_reply = 14, info_request = 15,- info_reply = 16, address_request = 17, address_reply = 18 };-- icmp_header() { std::fill(rep_, rep_ + sizeof(rep_), 0); }-- unsigned char type() const { return rep_[0]; }- unsigned char code() const { return rep_[1]; }- unsigned short checksum() const { return decode(2, 3); }- unsigned short identifier() const { return decode(4, 5); }- unsigned short sequence_number() const { return decode(6, 7); }-- void type(unsigned char n) { rep_[0] = n; }- void code(unsigned char n) { rep_[1] = n; }- void checksum(unsigned short n) { encode(2, 3, n); }- void identifier(unsigned short n) { encode(4, 5, n); }- void sequence_number(unsigned short n) { encode(6, 7, n); }-- friend std::istream& operator>>(std::istream& is, icmp_header& header)- { return is.read(reinterpret_cast<char*>(header.rep_), 8); }-- friend std::ostream& operator<<(std::ostream& os, const icmp_header& header)- { return os.write(reinterpret_cast<const char*>(header.rep_), 8); }--private:- unsigned short decode(int a, int b) const- { return (rep_[a] << 8) + rep_[b]; }-- void encode(int a, int b, unsigned short n)- {- rep_[a] = static_cast<unsigned char>(n >> 8);- rep_[b] = static_cast<unsigned char>(n & 0xFF);- }-- unsigned char rep_[8];-};--template <typename Iterator>-void compute_checksum(icmp_header& header,- Iterator body_begin, Iterator body_end)-{- unsigned int sum = (header.type() << 8) + header.code()- + header.identifier() + header.sequence_number();-- Iterator body_iter = body_begin;- while (body_iter != body_end)- {- sum += (static_cast<unsigned char>(*body_iter++) << 8);- if (body_iter != body_end)- sum += static_cast<unsigned char>(*body_iter++);- }-- sum = (sum >> 16) + (sum & 0xFFFF);- sum += (sum >> 16);- header.checksum(static_cast<unsigned short>(~sum));-}--#endif // ICMP_HEADER_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/icmp/ipv4_header.hpp
@@ -1,102 +0,0 @@-//-// ipv4_header.hpp-// ~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef IPV4_HEADER_HPP-#define IPV4_HEADER_HPP--#include <algorithm>-#include <asio/ip/address_v4.hpp>--// Packet header for IPv4.-//-// The wire format of an IPv4 header is:-//-// 0 8 16 31-// +-------+-------+---------------+------------------------------+ ----// | | | | | ^-// |version|header | type of | total length in bytes | |-// | (4) | length| service | | |-// +-------+-------+---------------+-+-+-+------------------------+ |-// | | | | | | |-// | identification |0|D|M| fragment offset | |-// | | |F|F| | |-// +---------------+---------------+-+-+-+------------------------+ |-// | | | | |-// | time to live | protocol | header checksum | 20 bytes-// | | | | |-// +---------------+---------------+------------------------------+ |-// | | |-// | source IPv4 address | |-// | | |-// +--------------------------------------------------------------+ |-// | | |-// | destination IPv4 address | |-// | | v-// +--------------------------------------------------------------+ ----// | | ^-// | | |-// / options (if any) / 0 - 40-// / / bytes-// | | |-// | | v-// +--------------------------------------------------------------+ -----class ipv4_header-{-public:- ipv4_header() { std::fill(rep_, rep_ + sizeof(rep_), 0); }-- unsigned char version() const { return (rep_[0] >> 4) & 0xF; }- unsigned short header_length() const { return (rep_[0] & 0xF) * 4; }- unsigned char type_of_service() const { return rep_[1]; }- unsigned short total_length() const { return decode(2, 3); }- unsigned short identification() const { return decode(4, 5); }- bool dont_fragment() const { return (rep_[6] & 0x40) != 0; }- bool more_fragments() const { return (rep_[6] & 0x20) != 0; }- unsigned short fragment_offset() const { return decode(6, 7) & 0x1FFF; }- unsigned int time_to_live() const { return rep_[8]; }- unsigned char protocol() const { return rep_[9]; }- unsigned short header_checksum() const { return decode(10, 11); }-- asio::ip::address_v4 source_address() const- {- asio::ip::address_v4::bytes_type bytes- = { { rep_[12], rep_[13], rep_[14], rep_[15] } };- return asio::ip::address_v4(bytes);- }-- asio::ip::address_v4 destination_address() const- {- asio::ip::address_v4::bytes_type bytes- = { { rep_[16], rep_[17], rep_[18], rep_[19] } };- return asio::ip::address_v4(bytes);- }-- friend std::istream& operator>>(std::istream& is, ipv4_header& header)- {- is.read(reinterpret_cast<char*>(header.rep_), 20);- if (header.version() != 4)- is.setstate(std::ios::failbit);- std::streamsize options_length = header.header_length() - 20;- if (options_length < 0 || options_length > 40)- is.setstate(std::ios::failbit);- else- is.read(reinterpret_cast<char*>(header.rep_) + 20, options_length);- return is;- }--private:- unsigned short decode(int a, int b) const- { return (rep_[a] << 8) + rep_[b]; }-- unsigned char rep_[60];-};--#endif // IPV4_HEADER_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/porthopper/protocol.hpp
@@ -1,156 +0,0 @@-//-// protocol.hpp-// ~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef PORTHOPPER_PROTOCOL_HPP-#define PORTHOPPER_PROTOCOL_HPP--#include <asio.hpp>-#include <array>-#include <cstring>-#include <iomanip>-#include <string>-#include <strstream>--// This request is sent by the client to the server over a TCP connection.-// The client uses it to perform three functions:-// - To request that data start being sent to a given port.-// - To request that data is no longer sent to a given port.-// - To change the target port to another.-class control_request-{-public:- // Construct an empty request. Used when receiving.- control_request()- {- }-- // Create a request to start sending data to a given port.- static const control_request start(unsigned short port)- {- return control_request(0, port);- }-- // Create a request to stop sending data to a given port.- static const control_request stop(unsigned short port)- {- return control_request(port, 0);- }-- // Create a request to change the port that data is sent to.- static const control_request change(- unsigned short old_port, unsigned short new_port)- {- return control_request(old_port, new_port);- }-- // Get the old port. Returns 0 for start requests.- unsigned short old_port() const- {- std::istrstream is(data_, encoded_port_size);- unsigned short port = 0;- is >> std::setw(encoded_port_size) >> std::hex >> port;- return port;- }-- // Get the new port. Returns 0 for stop requests.- unsigned short new_port() const- {- std::istrstream is(data_ + encoded_port_size, encoded_port_size);- unsigned short port = 0;- is >> std::setw(encoded_port_size) >> std::hex >> port;- return port;- }-- // Obtain buffers for reading from or writing to a socket.- std::array<asio::mutable_buffer, 1> to_buffers()- {- std::array<asio::mutable_buffer, 1> buffers- = { { asio::buffer(data_) } };- return buffers;- }--private:- // Construct with specified old and new ports.- control_request(unsigned short old_port_number,- unsigned short new_port_number)- {- std::ostrstream os(data_, control_request_size);- os << std::setw(encoded_port_size) << std::hex << old_port_number;- os << std::setw(encoded_port_size) << std::hex << new_port_number;- }-- // The length in bytes of a control_request and its components.- enum- {- encoded_port_size = 4, // 16-bit port in hex.- control_request_size = encoded_port_size * 2- };-- // The encoded request data.- char data_[control_request_size];-};--// This frame is sent from the server to subscribed clients over UDP.-class frame-{-public:- // The maximum allowable length of the payload.- enum { payload_size = 32 };-- // Construct an empty frame. Used when receiving.- frame()- {- }-- // Construct a frame with specified frame number and payload.- frame(unsigned long frame_number, const std::string& payload_data)- {- std::ostrstream os(data_, frame_size);- os << std::setw(encoded_number_size) << std::hex << frame_number;- os << std::setw(payload_size)- << std::setfill(' ') << payload_data.substr(0, payload_size);- }-- // Get the frame number.- unsigned long number() const- {- std::istrstream is(data_, encoded_number_size);- unsigned long frame_number = 0;- is >> std::setw(encoded_number_size) >> std::hex >> frame_number;- return frame_number;- }-- // Get the payload data.- const std::string payload() const- {- return std::string(data_ + encoded_number_size, payload_size);- }-- // Obtain buffers for reading from or writing to a socket.- std::array<asio::mutable_buffer, 1> to_buffers()- {- std::array<asio::mutable_buffer, 1> buffers- = { { asio::buffer(data_) } };- return buffers;- }--private:- // The length in bytes of a frame and its components.- enum- {- encoded_number_size = 8, // Frame number in hex.- frame_size = encoded_number_size + payload_size- };-- // The encoded frame data.- char data_[frame_size];-};--#endif // PORTHOPPER_PROTOCOL_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/serialization/connection.hpp
@@ -1,184 +0,0 @@-//-// connection.hpp-// ~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef SERIALIZATION_CONNECTION_HPP-#define SERIALIZATION_CONNECTION_HPP--#include <asio.hpp>-#include <boost/archive/text_iarchive.hpp>-#include <boost/archive/text_oarchive.hpp>-#include <functional>-#include <iomanip>-#include <memory>-#include <string>-#include <sstream>-#include <tuple>-#include <vector>--namespace s11n_example {--/// The connection class provides serialization primitives on top of a socket.-/**- * Each message sent using this class consists of:- * @li An 8-byte header containing the length of the serialized data in- * hexadecimal.- * @li The serialized data.- */-class connection-{-public:- /// Constructor.- connection(const asio::any_io_executor& ex)- : socket_(ex)- {- }-- /// Get the underlying socket. Used for making a connection or for accepting- /// an incoming connection.- asio::ip::tcp::socket& socket()- {- return socket_;- }-- /// Asynchronously write a data structure to the socket.- template <typename T, typename Handler>- void async_write(const T& t, Handler handler)- {- // Serialize the data first so we know how large it is.- std::ostringstream archive_stream;- boost::archive::text_oarchive archive(archive_stream);- archive << t;- outbound_data_ = archive_stream.str();-- // Format the header.- std::ostringstream header_stream;- header_stream << std::setw(header_length)- << std::hex << outbound_data_.size();- if (!header_stream || header_stream.str().size() != header_length)- {- // Something went wrong, inform the caller.- std::error_code error(asio::error::invalid_argument);- asio::post(socket_.get_executor(), std::bind(handler, error));- return;- }- outbound_header_ = header_stream.str();-- // Write the serialized data to the socket. We use "gather-write" to send- // both the header and the data in a single write operation.- std::vector<asio::const_buffer> buffers;- buffers.push_back(asio::buffer(outbound_header_));- buffers.push_back(asio::buffer(outbound_data_));- asio::async_write(socket_, buffers, handler);- }-- /// Asynchronously read a data structure from the socket.- template <typename T, typename Handler>- void async_read(T& t, Handler handler)- {- // Issue a read operation to read exactly the number of bytes in a header.- void (connection::*f)(const std::error_code&, T&, std::tuple<Handler>)- = &connection::handle_read_header<T, Handler>;- asio::async_read(socket_, asio::buffer(inbound_header_),- std::bind(f,- this, asio::placeholders::error, std::ref(t),- std::make_tuple(handler)));- }-- /// Handle a completed read of a message header.- template <typename T, typename Handler>- void handle_read_header(const std::error_code& e,- T& t, std::tuple<Handler> handler)- {- if (e)- {- std::get<0>(handler)(e);- }- else- {- // Determine the length of the serialized data.- std::istringstream is(std::string(inbound_header_, header_length));- std::size_t inbound_data_size = 0;- if (!(is >> std::hex >> inbound_data_size))- {- // Header doesn't seem to be valid. Inform the caller.- std::error_code error(asio::error::invalid_argument);- std::get<0>(handler)(error);- return;- }-- // Start an asynchronous call to receive the data.- inbound_data_.resize(inbound_data_size);- void (connection::*f)(- const std::error_code&,- T&, std::tuple<Handler>)- = &connection::handle_read_data<T, Handler>;- asio::async_read(socket_, asio::buffer(inbound_data_),- std::bind(f, this,- asio::placeholders::error, std::ref(t), handler));- }- }-- /// Handle a completed read of message data.- template <typename T, typename Handler>- void handle_read_data(const std::error_code& e,- T& t, std::tuple<Handler> handler)- {- if (e)- {- std::get<0>(handler)(e);- }- else- {- // Extract the data structure from the data just received.- try- {- std::string archive_data(&inbound_data_[0], inbound_data_.size());- std::istringstream archive_stream(archive_data);- boost::archive::text_iarchive archive(archive_stream);- archive >> t;- }- catch (std::exception& e)- {- // Unable to decode data.- std::error_code error(asio::error::invalid_argument);- std::get<0>(handler)(error);- return;- }-- // Inform caller that data has been received ok.- std::get<0>(handler)(e);- }- }--private:- /// The underlying socket.- asio::ip::tcp::socket socket_;-- /// The size of a fixed length header.- enum { header_length = 8 };-- /// Holds an outbound header.- std::string outbound_header_;-- /// Holds the outbound data.- std::string outbound_data_;-- /// Holds an inbound header.- char inbound_header_[header_length];-- /// Holds the inbound data.- std::vector<char> inbound_data_;-};--typedef std::shared_ptr<connection> connection_ptr;--} // namespace s11n_example--#endif // SERIALIZATION_CONNECTION_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/serialization/stock.hpp
@@ -1,50 +0,0 @@-//-// stock.hpp-// ~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef SERIALIZATION_STOCK_HPP-#define SERIALIZATION_STOCK_HPP--#include <string>--namespace s11n_example {--/// Structure to hold information about a single stock.-struct stock-{- std::string code;- std::string name;- double open_price;- double high_price;- double low_price;- double last_price;- double buy_price;- int buy_quantity;- double sell_price;- int sell_quantity;-- template <typename Archive>- void serialize(Archive& ar, const unsigned int version)- {- ar & code;- ar & name;- ar & open_price;- ar & high_price;- ar & low_price;- ar & last_price;- ar & buy_price;- ar & buy_quantity;- ar & sell_price;- ar & sell_quantity;- }-};--} // namespace s11n_example--#endif // SERIALIZATION_STOCK_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/services/basic_logger.hpp
@@ -1,78 +0,0 @@-//-// basic_logger.hpp-// ~~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef SERVICES_BASIC_LOGGER_HPP-#define SERVICES_BASIC_LOGGER_HPP--#include <asio.hpp>-#include <string>--namespace services {--/// Class to provide simple logging functionality. Use the services::logger-/// typedef.-template <typename Service>-class basic_logger-{-public:- /// The type of the service that will be used to provide timer operations.- typedef Service service_type;-- /// The native implementation type of the timer.- typedef typename service_type::impl_type impl_type;-- /// Constructor.- /**- * This constructor creates a logger.- *- * @param context The execution context used to locate the logger service.- *- * @param identifier An identifier for this logger.- */- explicit basic_logger(asio::execution_context& context,- const std::string& identifier)- : service_(asio::use_service<Service>(context)),- impl_(service_.null())- {- service_.create(impl_, identifier);- }-- basic_logger(const basic_logger&) = delete;- basic_logger& operator=(basic_logger&) = delete;-- /// Destructor.- ~basic_logger()- {- service_.destroy(impl_);- }-- /// Set the output file for all logger instances.- void use_file(const std::string& file)- {- service_.use_file(impl_, file);- }-- /// Log a message.- void log(const std::string& message)- {- service_.log(impl_, message);- }--private:- /// The backend service implementation.- service_type& service_;-- /// The underlying native implementation.- impl_type impl_;-};--} // namespace services--#endif // SERVICES_BASIC_LOGGER_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/services/logger.hpp
@@ -1,24 +0,0 @@-//-// logger.hpp-// ~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef SERVICES_LOGGER_HPP-#define SERVICES_LOGGER_HPP--#include "basic_logger.hpp"-#include "logger_service.hpp"--namespace services {--/// Typedef for typical logger usage.-typedef basic_logger<logger_service> logger;--} // namespace services--#endif // SERVICES_LOGGER_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/services/logger_service.hpp
@@ -1,145 +0,0 @@-//-// logger_service.hpp-// ~~~~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)-//-// Distributed under the Boost Software License, Version 1.0. (See accompanying-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)-//--#ifndef SERVICES_LOGGER_SERVICE_HPP-#define SERVICES_LOGGER_SERVICE_HPP--#include <asio.hpp>-#include <functional>-#include <fstream>-#include <sstream>-#include <string>-#include <thread>--namespace services {--/// Service implementation for the logger.-class logger_service- : public asio::execution_context::service-{-public:- /// The type used to identify this service in the execution context.- typedef logger_service key_type;-- /// The backend implementation of a logger.- struct logger_impl- {- explicit logger_impl(const std::string& ident) : identifier(ident) {}- std::string identifier;- };-- /// The type for an implementation of the logger.- typedef logger_impl* impl_type;-- /// Constructor creates a thread to run a private io_context.- logger_service(asio::execution_context& context)- : asio::execution_context::service(context),- work_io_context_(),- work_(asio::make_work_guard(work_io_context_)),- work_thread_([this]{ work_io_context_.run(); })- {- }-- logger_service(const logger_service&) = delete;- logger_service& operator=(const logger_service&) = delete;;-- /// Destructor shuts down the private io_context.- ~logger_service()- {- /// Indicate that we have finished with the private io_context. Its- /// io_context::run() function will exit once all other work has completed.- work_.reset();- if (work_thread_.joinable())- work_thread_.join();- }-- /// Destroy all user-defined handler objects owned by the service.- void shutdown()- {- }-- /// Return a null logger implementation.- impl_type null() const- {- return 0;- }-- /// Create a new logger implementation.- void create(impl_type& impl, const std::string& identifier)- {- impl = new logger_impl(identifier);- }-- /// Destroy a logger implementation.- void destroy(impl_type& impl)- {- delete impl;- impl = null();- }-- /// Set the output file for the logger. The current implementation sets the- /// output file for all logger instances, and so the impl parameter is not- /// actually needed. It is retained here to illustrate how service functions- /// are typically defined.- void use_file(impl_type& /*impl*/, const std::string& file)- {- // Pass the work of opening the file to the background thread.- asio::post(work_io_context_,- std::bind(&logger_service::use_file_impl, this, file));- }-- /// Log a message.- void log(impl_type& impl, const std::string& message)- {- // Format the text to be logged.- std::ostringstream os;- os << impl->identifier << ": " << message;-- // Pass the work of writing to the file to the background thread.- asio::post(work_io_context_,- std::bind(&logger_service::log_impl, this, os.str()));- }--private:- /// Helper function used to open the output file from within the private- /// io_context's thread.- void use_file_impl(const std::string& file)- {- ofstream_.close();- ofstream_.clear();- ofstream_.open(file.c_str());- }-- /// Helper function used to log a message from within the private io_context's- /// thread.- void log_impl(const std::string& text)- {- ofstream_ << text << std::endl;- }-- /// Private io_context used for performing logging operations.- asio::io_context work_io_context_;-- /// Work for the private io_context to perform. If we do not give the- /// io_context some work to do then the io_context::run() function will exit- /// immediately.- asio::executor_work_guard<- asio::io_context::executor_type> work_;-- /// Thread used for running the work io_context's run loop.- std::thread work_thread_;-- /// The file to which log messages will be written.- std::ofstream ofstream_;-};--} // namespace services--#endif // SERVICES_LOGGER_SERVICE_HPP
link/modules/asio-standalone/asio/src/examples/cpp11/socks4/socks4.hpp view
@@ -2,7 +2,7 @@ // socks4.hpp // ~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -39,7 +39,7 @@ // Only IPv4 is supported by the SOCKS 4 protocol. if (endpoint.protocol() != asio::ip::tcp::v4()) {- throw std::system_error(+ throw asio::system_error( asio::error::address_family_not_supported); }
link/modules/asio-standalone/asio/src/examples/cpp11/type_erasure/line_reader.hpp view
@@ -2,7 +2,7 @@ // line_reader.hpp // ~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -20,7 +20,7 @@ { private: virtual void async_read_line_impl(std::string prompt,- asio::any_completion_handler<void(std::error_code, std::string)> handler) = 0;+ asio::any_completion_handler<void(asio::error_code, std::string)> handler) = 0; struct initiate_read_line {@@ -37,10 +37,10 @@ template <typename CompletionToken> auto async_read_line(std::string prompt, CompletionToken&& token) -> decltype(- asio::async_initiate<CompletionToken, void(std::error_code, std::string)>(+ asio::async_initiate<CompletionToken, void(asio::error_code, std::string)>( initiate_read_line(), token, this, prompt)) {- return asio::async_initiate<CompletionToken, void(std::error_code, std::string)>(+ return asio::async_initiate<CompletionToken, void(asio::error_code, std::string)>( initiate_read_line(), token, this, prompt); } };
link/modules/asio-standalone/asio/src/examples/cpp11/type_erasure/sleep.hpp view
@@ -2,7 +2,7 @@ // sleep.hpp // ~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/src/examples/cpp11/type_erasure/stdin_line_reader.hpp view
@@ -2,7 +2,7 @@ // stdin_line_reader.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -21,7 +21,7 @@ private: void async_read_line_impl(std::string prompt,- asio::any_completion_handler<void(std::error_code, std::string)> handler) override;+ asio::any_completion_handler<void(asio::error_code, std::string)> handler) override; asio::posix::stream_descriptor stdin_; std::string buffer_;
link/modules/asio-standalone/asio/src/examples/cpp20/type_erasure/line_reader.hpp view
@@ -2,7 +2,7 @@ // line_reader.hpp // ~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/src/examples/cpp20/type_erasure/sleep.hpp view
@@ -2,7 +2,7 @@ // sleep.hpp // ~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/src/examples/cpp20/type_erasure/stdin_line_reader.hpp view
@@ -2,7 +2,7 @@ // stdin_line_reader.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/src/tests/latency/allocator.hpp view
@@ -2,7 +2,7 @@ // allocator.hpp // ~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/src/tests/latency/high_res_clock.hpp view
@@ -2,7 +2,7 @@ // high_res_clock.hpp // ~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/src/tests/performance/handler_allocator.hpp view
@@ -2,7 +2,7 @@ // handler_allocator.cpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -12,12 +12,15 @@ #define HANDLER_ALLOCATOR_HPP #include "asio.hpp"+#include <boost/aligned_storage.hpp>+#include <boost/noncopyable.hpp> // Class to manage the memory to be used for handler-based custom allocation. // It contains a single block of memory which may be returned for allocation // requests. If the memory is in use when an allocation request is made, the // allocator delegates allocation to the global heap. class handler_allocator+ : private boost::noncopyable { public: handler_allocator()@@ -25,15 +28,12 @@ { } - handler_allocator(const handler_allocator&) = delete;- handler_allocator& operator=(const handler_allocator&) = delete;- void* allocate(std::size_t size) {- if (!in_use_ && size < sizeof(storage_))+ if (!in_use_ && size < storage_.size) { in_use_ = true;- return storage_;+ return storage_.address(); } return ::operator new(size);@@ -41,7 +41,7 @@ void deallocate(void* pointer) {- if (pointer == storage_)+ if (pointer == storage_.address()) { in_use_ = false; }@@ -53,7 +53,7 @@ private: // Storage space used for handler-based custom memory allocation.- alignas(std::max_align_t) unsigned char storage_[1024];+ boost::aligned_storage<1024> storage_; // Whether the handler-based custom allocation storage has been used. bool in_use_;
link/modules/asio-standalone/asio/src/tests/unit/archetypes/async_ops.hpp view
@@ -1,8 +1,8 @@ //-// archetypes/async_ops.hpp-// ~~~~~~~~~~~~~~~~~~~~~~~~+// async_ops.hpp+// ~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -11,448 +11,403 @@ #ifndef ARCHETYPES_ASYNC_OPS_HPP #define ARCHETYPES_ASYNC_OPS_HPP -#include <functional>-#include "asio/associated_allocator.hpp"-#include "asio/associated_executor.hpp"-#include "asio/async_result.hpp"-#include "asio/bind_allocator.hpp"-#include "asio/error.hpp"-#include "asio/post.hpp"+#include <asio/associated_allocator.hpp>+#include <asio/associated_executor.hpp>+#include <asio/async_result.hpp>+#include <asio/error.hpp> +#if defined(ASIO_HAS_BOOST_BIND)+# include <boost/bind/bind.hpp>+#else // defined(ASIO_HAS_BOOST_BIND)+# include <functional>+#endif // defined(ASIO_HAS_BOOST_BIND)+ namespace archetypes { +#if defined(ASIO_HAS_BOOST_BIND)+namespace bindns = boost;+#else // defined(ASIO_HAS_BOOST_BIND) namespace bindns = std;+#endif // defined(ASIO_HAS_BOOST_BIND) -struct initiate_op_0+template <typename CompletionToken>+ASIO_INITFN_RESULT_TYPE(CompletionToken, void())+async_op_0(ASIO_MOVE_ARG(CompletionToken) token) {- template <typename Handler>- void operator()(Handler&& handler)- {- typename asio::associated_allocator<Handler>::type a- = asio::get_associated_allocator(handler);+ typedef typename asio::async_completion<CompletionToken,+ void()>::completion_handler_type handler_type; - typename asio::associated_executor<Handler>::type ex- = asio::get_associated_executor(handler);+ asio::async_completion<CompletionToken,+ void()> completion(token); - asio::post(ex,- asio::bind_allocator(a, static_cast<Handler&&>(handler)));- }-};+ typename asio::associated_allocator<handler_type>::type a+ = asio::get_associated_allocator(completion.completion_handler); -template <typename CompletionToken>-auto async_op_0(CompletionToken&& token)- -> decltype(- asio::async_initiate<CompletionToken, void()>(- initiate_op_0(), token))-{- return asio::async_initiate<CompletionToken, void()>(- initiate_op_0(), token);+ typename asio::associated_executor<handler_type>::type ex+ = asio::get_associated_executor(completion.completion_handler);++ ex.post(ASIO_MOVE_CAST(handler_type)(completion.completion_handler), a);++ return completion.result.get(); } -struct initiate_op_ec_0+template <typename CompletionToken>+ASIO_INITFN_RESULT_TYPE(CompletionToken, void(asio::error_code))+async_op_ec_0(bool ok, ASIO_MOVE_ARG(CompletionToken) token) {- template <typename Handler>- void operator()(Handler&& handler, bool ok)- {- typename asio::associated_allocator<Handler>::type a- = asio::get_associated_allocator(handler);+ typedef typename asio::async_completion<CompletionToken,+ void(asio::error_code)>::completion_handler_type handler_type; - typename asio::associated_executor<Handler>::type ex- = asio::get_associated_executor(handler);+ asio::async_completion<CompletionToken,+ void(asio::error_code)> completion(token); - if (ok)- {- asio::post(ex,- asio::bind_allocator(a,- bindns::bind(static_cast<Handler&&>(handler),- asio::error_code())));- }- else- {- asio::post(ex,- asio::bind_allocator(a,- bindns::bind(static_cast<Handler&&>(handler),- asio::error_code(- asio::error::operation_aborted))));- }+ typename asio::associated_allocator<handler_type>::type a+ = asio::get_associated_allocator(completion.completion_handler);++ typename asio::associated_executor<handler_type>::type ex+ = asio::get_associated_executor(completion.completion_handler);++ if (ok)+ {+ ex.post(+ bindns::bind(+ ASIO_MOVE_CAST(handler_type)(completion.completion_handler),+ asio::error_code()), a); }-};+ else+ {+ ex.post(+ bindns::bind(+ ASIO_MOVE_CAST(handler_type)(completion.completion_handler),+ asio::error_code(asio::error::operation_aborted)), a);+ } -template <typename CompletionToken>-auto async_op_ec_0(bool ok, CompletionToken&& token)- -> decltype(- asio::async_initiate<CompletionToken,- void(asio::error_code)>(- initiate_op_ec_0(), token, ok))-{- return asio::async_initiate<CompletionToken,- void(asio::error_code)>(- initiate_op_ec_0(), token, ok);+ return completion.result.get(); } -struct initiate_op_ex_0+template <typename CompletionToken>+ASIO_INITFN_RESULT_TYPE(CompletionToken, void(std::exception_ptr))+async_op_ex_0(bool ok, ASIO_MOVE_ARG(CompletionToken) token) {- template <typename Handler>- void operator()(Handler&& handler, bool ok)- {- typename asio::associated_allocator<Handler>::type a- = asio::get_associated_allocator(handler);+ typedef typename asio::async_completion<CompletionToken,+ void(std::exception_ptr)>::completion_handler_type handler_type; - typename asio::associated_executor<Handler>::type ex- = asio::get_associated_executor(handler);+ asio::async_completion<CompletionToken,+ void(std::exception_ptr)> completion(token); - if (ok)- {- asio::post(ex,- asio::bind_allocator(a,- bindns::bind(static_cast<Handler&&>(handler),- std::exception_ptr())));- }- else- {- asio::post(ex,- asio::bind_allocator(a,- bindns::bind(static_cast<Handler&&>(handler),- std::make_exception_ptr(std::runtime_error("blah")))));- }+ typename asio::associated_allocator<handler_type>::type a+ = asio::get_associated_allocator(completion.completion_handler);++ typename asio::associated_executor<handler_type>::type ex+ = asio::get_associated_executor(completion.completion_handler);++ if (ok)+ {+ ex.post(+ bindns::bind(+ ASIO_MOVE_CAST(handler_type)(completion.completion_handler),+ std::exception_ptr()), a); }-};+ else+ {+ ex.post(+ bindns::bind(+ ASIO_MOVE_CAST(handler_type)(completion.completion_handler),+ std::make_exception_ptr(std::runtime_error("blah"))), a);+ } -template <typename CompletionToken>-auto async_op_ex_0(bool ok, CompletionToken&& token)- -> decltype(- asio::async_initiate<CompletionToken,- void(std::exception_ptr)>(- initiate_op_ex_0(), token, ok))-{- return asio::async_initiate<CompletionToken,- void(std::exception_ptr)>(- initiate_op_ex_0(), token, ok);+ return completion.result.get(); } -struct initiate_op_1+template <typename CompletionToken>+ASIO_INITFN_RESULT_TYPE(CompletionToken, void(int))+async_op_1(ASIO_MOVE_ARG(CompletionToken) token) {- template <typename Handler>- void operator()(Handler&& handler)- {- typename asio::associated_allocator<Handler>::type a- = asio::get_associated_allocator(handler);+ typedef typename asio::async_completion<CompletionToken,+ void(int)>::completion_handler_type handler_type; - typename asio::associated_executor<Handler>::type ex- = asio::get_associated_executor(handler);+ asio::async_completion<CompletionToken,+ void(int)> completion(token); - asio::post(ex,- asio::bind_allocator(a,- bindns::bind(static_cast<Handler&&>(handler), 42)));- }-};+ typename asio::associated_allocator<handler_type>::type a+ = asio::get_associated_allocator(completion.completion_handler); -template <typename CompletionToken>-auto async_op_1(CompletionToken&& token)- -> decltype(- asio::async_initiate<CompletionToken, void(int)>(- initiate_op_1(), token))-{- return asio::async_initiate<CompletionToken, void(int)>(- initiate_op_1(), token);+ typename asio::associated_executor<handler_type>::type ex+ = asio::get_associated_executor(completion.completion_handler);++ ex.post(+ bindns::bind(+ ASIO_MOVE_CAST(handler_type)(completion.completion_handler),+ 42), a);++ return completion.result.get(); } -struct initiate_op_ec_1+template <typename CompletionToken>+ASIO_INITFN_RESULT_TYPE(CompletionToken,+ void(asio::error_code, int))+async_op_ec_1(bool ok, ASIO_MOVE_ARG(CompletionToken) token) {- template <typename Handler>- void operator()(Handler&& handler, bool ok)- {- typename asio::associated_allocator<Handler>::type a- = asio::get_associated_allocator(handler);+ typedef typename asio::async_completion<CompletionToken,+ void(asio::error_code, int)>::completion_handler_type+ handler_type; - typename asio::associated_executor<Handler>::type ex- = asio::get_associated_executor(handler);+ asio::async_completion<CompletionToken,+ void(asio::error_code, int)> completion(token); - if (ok)- {- asio::post(ex,- asio::bind_allocator(a,- bindns::bind(static_cast<Handler&&>(handler),- asio::error_code(), 42)));- }- else- {- asio::post(ex,- asio::bind_allocator(a,- bindns::bind(static_cast<Handler&&>(handler),- asio::error_code(- asio::error::operation_aborted), 0)));- }+ typename asio::associated_allocator<handler_type>::type a+ = asio::get_associated_allocator(completion.completion_handler);++ typename asio::associated_executor<handler_type>::type ex+ = asio::get_associated_executor(completion.completion_handler);++ if (ok)+ {+ ex.post(+ bindns::bind(+ ASIO_MOVE_CAST(handler_type)(completion.completion_handler),+ asio::error_code(), 42), a); }-};+ else+ {+ ex.post(+ bindns::bind(+ ASIO_MOVE_CAST(handler_type)(completion.completion_handler),+ asio::error_code(asio::error::operation_aborted),+ 0), a);+ } -template <typename CompletionToken>-auto async_op_ec_1(bool ok, CompletionToken&& token)- -> decltype(- asio::async_initiate<CompletionToken,- void(asio::error_code, int)>(- initiate_op_ec_1(), token, ok))-{- return asio::async_initiate<CompletionToken,- void(asio::error_code, int)>(- initiate_op_ec_1(), token, ok);+ return completion.result.get(); } -struct initiate_op_ex_1+template <typename CompletionToken>+ASIO_INITFN_RESULT_TYPE(CompletionToken, void(std::exception_ptr, int))+async_op_ex_1(bool ok, ASIO_MOVE_ARG(CompletionToken) token) {- template <typename Handler>- void operator()(Handler&& handler, bool ok)- {- typename asio::associated_allocator<Handler>::type a- = asio::get_associated_allocator(handler);+ typedef typename asio::async_completion<CompletionToken,+ void(std::exception_ptr, int)>::completion_handler_type+ handler_type; - typename asio::associated_executor<Handler>::type ex- = asio::get_associated_executor(handler);+ asio::async_completion<CompletionToken,+ void(std::exception_ptr, int)> completion(token); - if (ok)- {- asio::post(ex,- asio::bind_allocator(a,- bindns::bind(static_cast<Handler&&>(handler),- std::exception_ptr(), 42)));- }- else- {- asio::post(ex,- asio::bind_allocator(a,- bindns::bind(static_cast<Handler&&>(handler),- std::make_exception_ptr(std::runtime_error("blah")), 0)));- }+ typename asio::associated_allocator<handler_type>::type a+ = asio::get_associated_allocator(completion.completion_handler);++ typename asio::associated_executor<handler_type>::type ex+ = asio::get_associated_executor(completion.completion_handler);++ if (ok)+ {+ ex.post(+ bindns::bind(+ ASIO_MOVE_CAST(handler_type)(completion.completion_handler),+ std::exception_ptr(), 42), a); }-};+ else+ {+ ex.post(+ bindns::bind(+ ASIO_MOVE_CAST(handler_type)(completion.completion_handler),+ std::make_exception_ptr(std::runtime_error("blah")), 0), a);+ } -template <typename CompletionToken>-auto async_op_ex_1(bool ok, CompletionToken&& token)- -> decltype(- asio::async_initiate<CompletionToken,- void(std::exception_ptr, int)>(- initiate_op_ex_1(), token, ok))-{- return asio::async_initiate<CompletionToken,- void(std::exception_ptr, int)>(- initiate_op_ex_1(), token, ok);+ return completion.result.get(); } -struct initiate_op_2+template <typename CompletionToken>+ASIO_INITFN_RESULT_TYPE(CompletionToken, void(int, double))+async_op_2(ASIO_MOVE_ARG(CompletionToken) token) {- template <typename Handler>- void operator()(Handler&& handler)- {- typename asio::associated_allocator<Handler>::type a- = asio::get_associated_allocator(handler);+ typedef typename asio::async_completion<CompletionToken,+ void(int, double)>::completion_handler_type handler_type; - typename asio::associated_executor<Handler>::type ex- = asio::get_associated_executor(handler);+ asio::async_completion<CompletionToken,+ void(int, double)> completion(token); - asio::post(ex,- asio::bind_allocator(a,- bindns::bind(static_cast<Handler&&>(handler), 42, 2.0)));- }-};+ typename asio::associated_allocator<handler_type>::type a+ = asio::get_associated_allocator(completion.completion_handler); -template <typename CompletionToken>-auto async_op_2(CompletionToken&& token)- -> decltype(- asio::async_initiate<CompletionToken, void(int, double)>(- initiate_op_2(), token))-{- return asio::async_initiate<CompletionToken, void(int, double)>(- initiate_op_2(), token);+ typename asio::associated_executor<handler_type>::type ex+ = asio::get_associated_executor(completion.completion_handler);++ ex.post(+ bindns::bind(+ ASIO_MOVE_CAST(handler_type)(completion.completion_handler),+ 42, 2.0), a);++ return completion.result.get(); } -struct initiate_op_ec_2+template <typename CompletionToken>+ASIO_INITFN_RESULT_TYPE(CompletionToken,+ void(asio::error_code, int, double))+async_op_ec_2(bool ok, ASIO_MOVE_ARG(CompletionToken) token) {- template <typename Handler>- void operator()(Handler&& handler, bool ok)- {- typename asio::associated_allocator<Handler>::type a- = asio::get_associated_allocator(handler);+ typedef typename asio::async_completion<CompletionToken,+ void(asio::error_code, int, double)>::completion_handler_type+ handler_type; - typename asio::associated_executor<Handler>::type ex- = asio::get_associated_executor(handler);+ asio::async_completion<CompletionToken,+ void(asio::error_code, int, double)> completion(token); - if (ok)- {- asio::post(ex,- asio::bind_allocator(a,- bindns::bind(static_cast<Handler&&>(handler),- asio::error_code(), 42, 2.0)));- }- else- {- asio::post(ex,- asio::bind_allocator(a,- bindns::bind(static_cast<Handler&&>(handler),- asio::error_code(asio::error::operation_aborted),- 0, 0.0)));- }+ typename asio::associated_allocator<handler_type>::type a+ = asio::get_associated_allocator(completion.completion_handler);++ typename asio::associated_executor<handler_type>::type ex+ = asio::get_associated_executor(completion.completion_handler);++ if (ok)+ {+ ex.post(+ bindns::bind(+ ASIO_MOVE_CAST(handler_type)(completion.completion_handler),+ asio::error_code(), 42, 2.0), a); }-};+ else+ {+ ex.post(+ bindns::bind(+ ASIO_MOVE_CAST(handler_type)(completion.completion_handler),+ asio::error_code(asio::error::operation_aborted),+ 0, 0.0), a);+ } -template <typename CompletionToken>-auto async_op_ec_2(bool ok, CompletionToken&& token)- -> decltype(- asio::async_initiate<CompletionToken,- void(asio::error_code, int, double)>(- initiate_op_ec_2(), token, ok))-{- return asio::async_initiate<CompletionToken,- void(asio::error_code, int, double)>(- initiate_op_ec_2(), token, ok);+ return completion.result.get(); } -struct initiate_op_ex_2+template <typename CompletionToken>+ASIO_INITFN_RESULT_TYPE(CompletionToken,+ void(std::exception_ptr, int, double))+async_op_ex_2(bool ok, ASIO_MOVE_ARG(CompletionToken) token) {- template <typename Handler>- void operator()(Handler&& handler, bool ok)- {- typename asio::associated_allocator<Handler>::type a- = asio::get_associated_allocator(handler);+ typedef typename asio::async_completion<CompletionToken,+ void(std::exception_ptr, int, double)>::completion_handler_type+ handler_type; - typename asio::associated_executor<Handler>::type ex- = asio::get_associated_executor(handler);+ asio::async_completion<CompletionToken,+ void(std::exception_ptr, int, double)> completion(token); - if (ok)- {- asio::post(ex,- asio::bind_allocator(a,- bindns::bind(static_cast<Handler&&>(handler),- std::exception_ptr(), 42, 2.0)));- }- else- {- asio::post(ex,- asio::bind_allocator(a,- bindns::bind(static_cast<Handler&&>(handler),- std::make_exception_ptr(std::runtime_error("blah")), 0, 0.0)));- }+ typename asio::associated_allocator<handler_type>::type a+ = asio::get_associated_allocator(completion.completion_handler);++ typename asio::associated_executor<handler_type>::type ex+ = asio::get_associated_executor(completion.completion_handler);++ if (ok)+ {+ ex.post(+ bindns::bind(+ ASIO_MOVE_CAST(handler_type)(completion.completion_handler),+ std::exception_ptr(), 42, 2.0), a); }-};+ else+ {+ ex.post(+ bindns::bind(+ ASIO_MOVE_CAST(handler_type)(completion.completion_handler),+ std::make_exception_ptr(std::runtime_error("blah")), 0, 0.0), a);+ } -template <typename CompletionToken>-auto async_op_ex_2(bool ok, CompletionToken&& token)- -> decltype(- asio::async_initiate<CompletionToken,- void(std::exception_ptr, int, double)>(- initiate_op_ex_2(), token, ok))-{- return asio::async_initiate<CompletionToken,- void(std::exception_ptr, int, double)>(- initiate_op_ex_2(), token, ok);+ return completion.result.get(); } -struct initiate_op_3+template <typename CompletionToken>+ASIO_INITFN_RESULT_TYPE(CompletionToken, void(int, double, char))+async_op_3(ASIO_MOVE_ARG(CompletionToken) token) {- template <typename Handler>- void operator()(Handler&& handler)- {- typename asio::associated_allocator<Handler>::type a- = asio::get_associated_allocator(handler);+ typedef typename asio::async_completion<CompletionToken,+ void(int, double, char)>::completion_handler_type handler_type; - typename asio::associated_executor<Handler>::type ex- = asio::get_associated_executor(handler);+ asio::async_completion<CompletionToken,+ void(int, double, char)> completion(token); - asio::post(ex,- asio::bind_allocator(a,- bindns::bind(static_cast<Handler&&>(handler), 42, 2.0, 'a')));- }-};+ typename asio::associated_allocator<handler_type>::type a+ = asio::get_associated_allocator(completion.completion_handler); -template <typename CompletionToken>-auto async_op_3(CompletionToken&& token)- -> decltype(- asio::async_initiate<CompletionToken, void(int, double, char)>(- initiate_op_3(), token))-{- return asio::async_initiate<CompletionToken, void(int, double, char)>(- initiate_op_3(), token);+ typename asio::associated_executor<handler_type>::type ex+ = asio::get_associated_executor(completion.completion_handler);++ ex.post(+ bindns::bind(+ ASIO_MOVE_CAST(handler_type)(completion.completion_handler),+ 42, 2.0, 'a'), a);++ return completion.result.get(); } -struct initiate_op_ec_3+template <typename CompletionToken>+ASIO_INITFN_RESULT_TYPE(CompletionToken,+ void(asio::error_code, int, double, char))+async_op_ec_3(bool ok, ASIO_MOVE_ARG(CompletionToken) token) {- template <typename Handler>- void operator()(Handler&& handler, bool ok)- {- typename asio::associated_allocator<Handler>::type a- = asio::get_associated_allocator(handler);+ typedef typename asio::async_completion<CompletionToken,+ void(asio::error_code, int, double, char)>::completion_handler_type+ handler_type; - typename asio::associated_executor<Handler>::type ex- = asio::get_associated_executor(handler);+ asio::async_completion<CompletionToken,+ void(asio::error_code, int, double, char)> completion(token); - if (ok)- {- asio::post(ex,- asio::bind_allocator(a,- bindns::bind(static_cast<Handler&&>(handler),- asio::error_code(), 42, 2.0, 'a')));- }- else- {- asio::post(ex,- asio::bind_allocator(a,- bindns::bind(static_cast<Handler&&>(handler),- asio::error_code(asio::error::operation_aborted),- 0, 0.0, 'z')));- }+ typename asio::associated_allocator<handler_type>::type a+ = asio::get_associated_allocator(completion.completion_handler);++ typename asio::associated_executor<handler_type>::type ex+ = asio::get_associated_executor(completion.completion_handler);++ if (ok)+ {+ ex.post(+ bindns::bind(+ ASIO_MOVE_CAST(handler_type)(completion.completion_handler),+ asio::error_code(), 42, 2.0, 'a'), a); }-};+ else+ {+ ex.post(+ bindns::bind(+ ASIO_MOVE_CAST(handler_type)(completion.completion_handler),+ asio::error_code(asio::error::operation_aborted),+ 0, 0.0, 'z'), a);+ } -template <typename CompletionToken>-auto async_op_ec_3(bool ok, CompletionToken&& token)- -> decltype(- asio::async_initiate<CompletionToken,- void(asio::error_code, int, double, char)>(- initiate_op_ec_3(), token, ok))-{- return asio::async_initiate<CompletionToken,- void(asio::error_code, int, double, char)>(- initiate_op_ec_3(), token, ok);+ return completion.result.get(); } -struct initiate_op_ex_3+template <typename CompletionToken>+ASIO_INITFN_RESULT_TYPE(CompletionToken,+ void(std::exception_ptr, int, double, char))+async_op_ex_3(bool ok, ASIO_MOVE_ARG(CompletionToken) token) {- template <typename Handler>- void operator()(Handler&& handler, bool ok)- {- typename asio::associated_allocator<Handler>::type a- = asio::get_associated_allocator(handler);+ typedef typename asio::async_completion<CompletionToken,+ void(std::exception_ptr, int, double, char)>::completion_handler_type+ handler_type; - typename asio::associated_executor<Handler>::type ex- = asio::get_associated_executor(handler);+ asio::async_completion<CompletionToken,+ void(std::exception_ptr, int, double, char)> completion(token); - if (ok)- {- asio::post(ex,- asio::bind_allocator(a,- bindns::bind(static_cast<Handler&&>(handler),- std::exception_ptr(), 42, 2.0, 'a')));- }- else- {- asio::post(ex,- asio::bind_allocator(a,- bindns::bind(static_cast<Handler&&>(handler),- std::make_exception_ptr(std::runtime_error("blah")),- 0, 0.0, 'z')));- }+ typename asio::associated_allocator<handler_type>::type a+ = asio::get_associated_allocator(completion.completion_handler);++ typename asio::associated_executor<handler_type>::type ex+ = asio::get_associated_executor(completion.completion_handler);++ if (ok)+ {+ ex.post(+ bindns::bind(+ ASIO_MOVE_CAST(handler_type)(completion.completion_handler),+ std::exception_ptr(), 42, 2.0, 'a'), a); }-};+ else+ {+ ex.post(+ bindns::bind(+ ASIO_MOVE_CAST(handler_type)(completion.completion_handler),+ std::make_exception_ptr(std::runtime_error("blah")),+ 0, 0.0, 'z'), a);+ } -template <typename CompletionToken>-auto async_op_ex_3(bool ok, CompletionToken&& token)- -> decltype(- asio::async_initiate<CompletionToken,- void(std::exception_ptr, int, double, char)>(- initiate_op_ex_3(), token, ok))-{- return asio::async_initiate<CompletionToken,- void(std::exception_ptr, int, double, char)>(- initiate_op_ex_3(), token, ok);+ return completion.result.get(); } } // namespace archetypes
link/modules/asio-standalone/asio/src/tests/unit/archetypes/async_result.hpp view
@@ -2,7 +2,7 @@ // async_result.hpp // ~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -38,9 +38,11 @@ { } +#if defined(ASIO_HAS_MOVE) concrete_handler(concrete_handler&&) {} private: concrete_handler(const concrete_handler&);+#endif // defined(ASIO_HAS_MOVE) }; template <typename R, typename Arg1, typename Arg2>@@ -65,14 +67,16 @@ { } - immediate_executor_type get_immediate_executor() const noexcept+ immediate_executor_type get_immediate_executor() const ASIO_NOEXCEPT { return immediate_executor_type(); } +#if defined(ASIO_HAS_MOVE) immediate_concrete_handler(immediate_concrete_handler&&) {} private: immediate_concrete_handler(const immediate_concrete_handler&);+#endif // defined(ASIO_HAS_MOVE) }; template <typename Signature>@@ -82,9 +86,11 @@ { } +#if defined(ASIO_HAS_MOVE) lazy_concrete_handler(lazy_concrete_handler&&) {} private: lazy_concrete_handler(const lazy_concrete_handler&);+#endif // defined(ASIO_HAS_MOVE) }; } // namespace archetypes@@ -114,8 +120,8 @@ private: // Disallow copying and assignment.- async_result(const async_result&) = delete;- async_result& operator=(const async_result&) = delete;+ async_result(const async_result&) ASIO_DELETED;+ async_result& operator=(const async_result&) ASIO_DELETED; }; template <typename Signature>@@ -141,8 +147,8 @@ private: // Disallow copying and assignment.- async_result(const async_result&) = delete;- async_result& operator=(const async_result&) = delete;+ async_result(const async_result&) ASIO_DELETED;+ async_result& operator=(const async_result&) ASIO_DELETED; }; } // namespace asio
link/modules/asio-standalone/asio/src/tests/unit/archetypes/gettable_socket_option.hpp view
@@ -2,7 +2,7 @@ // gettable_socket_option.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/src/tests/unit/archetypes/io_control_command.hpp view
@@ -2,7 +2,7 @@ // io_control_command.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/src/tests/unit/archetypes/settable_socket_option.hpp view
@@ -2,7 +2,7 @@ // settable_socket_option.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
link/modules/asio-standalone/asio/src/tests/unit/unit_test.hpp view
@@ -2,7 +2,7 @@ // unit_test.hpp // ~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)@@ -24,7 +24,7 @@ // Prevent use of intrinsic for strcmp. # include <cstring> # undef strcmp-+ // Suppress error about condition always being true. # pragma option -w-ccc
src/hs/Sound/Tidal/Link.hsc view
@@ -26,22 +26,22 @@ type Quantum = CDouble instance Storable AbletonLink where- alignment _ = #{alignment struct abl_link}- sizeOf _ = #{size struct abl_link}+ alignment _ = #{alignment abl_link}+ sizeOf _ = #{size abl_link} peek ptr = do- impl <- #{peek struct abl_link, impl} ptr- pure (AbletonLink impl)- poke ptr (AbletonLink impl) =- #{poke struct abl_link, impl} ptr impl+ impl <- #{peek abl_link,impl} ptr+ return (AbletonLink impl)+ poke ptr (AbletonLink impl) = do+ #{poke abl_link,impl} ptr impl instance Storable SessionState where- alignment _ = #{alignment struct abl_link_session_state}- sizeOf _ = #{size struct abl_link_session_state}+ alignment _ = #{alignment abl_link_session_state}+ sizeOf _ = #{size abl_link_session_state} peek ptr = do- impl <- #{peek struct abl_link_session_state, impl} ptr- pure (SessionState impl)- poke ptr (SessionState impl) =- #{poke struct abl_link_session_state, impl} ptr impl+ impl <- #{peek abl_link_session_state,impl} ptr+ return (SessionState impl)+ poke ptr (SessionState impl) = do+ #{poke abl_link_session_state,impl} ptr impl foreign import ccall "abl_link.h abl_link_create" create :: BPM -> IO AbletonLink
tidal-link.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.4 name: tidal-link-version: 1.2.1+version: 1.2.2 synopsis: Ableton Link integration for Tidal -- description: homepage: http://tidalcycles.org/@@ -46,10 +46,10 @@ -DLINK_PLATFORM_WINDOWS=1 -Wno-multichar elif os(darwin) cxx-options:- -DLINK_PLATFORM_MACOSX=1 -std=c++17 -Wno-multichar -Wno-subobject-linkage+ -DLINK_PLATFORM_MACOSX=1 -std=c++14 -Wno-multichar -Wno-subobject-linkage else cxx-options:- -DLINK_PLATFORM_LINUX=1 -std=c++17 -Wno-multichar -Wno-subobject-linkage+ -DLINK_PLATFORM_LINUX=1 -std=c++14 -Wno-multichar -Wno-subobject-linkage if impl(ghc >= 9.4) build-depends: system-cxx-std-lib