tidal-link 1.2.0 → 1.2.1
raw patch · 909 files changed
+40899/−52420 lines, 909 files
Files
- link/examples/linkaudio/AudioEngine.hpp +34/−19
- link/examples/linkaudio/AudioEngine.ipp +255/−0
- link/examples/linkaudio/AudioPlatform_Asio.hpp +10/−9
- link/examples/linkaudio/AudioPlatform_Asio.ipp +319/−0
- link/examples/linkaudio/AudioPlatform_CoreAudio.hpp +15/−6
- link/examples/linkaudio/AudioPlatform_CoreAudio.ipp +294/−0
- link/examples/linkaudio/AudioPlatform_Dummy.hpp +8/−25
- link/examples/linkaudio/AudioPlatform_Jack.hpp +5/−3
- link/examples/linkaudio/AudioPlatform_Jack.ipp +221/−0
- link/examples/linkaudio/AudioPlatform_Portaudio.hpp +10/−8
- link/examples/linkaudio/AudioPlatform_Portaudio.ipp +168/−0
- link/examples/linkaudio/AudioPlatform_Wasapi.hpp +6/−2
- link/examples/linkaudio/AudioPlatform_Wasapi.ipp +344/−0
- link/examples/linkaudio/LinkAudioRenderer.hpp +418/−0
- link/extensions/abl_link/include/abl_link.h +276/−31
- link/extensions/abl_link/src/abl_link.cpp +391/−39
- link/include/ableton/Link.hpp +16/−12
- link/include/ableton/Link.ipp +38/−16
- link/include/ableton/LinkAudio.hpp +358/−0
- link/include/ableton/LinkAudio.ipp +267/−0
- link/include/ableton/discovery/AsioTypes.hpp +8/−2
- link/include/ableton/discovery/InterfaceScanner.hpp +9/−7
- link/include/ableton/discovery/IpInterface.hpp +8/−12
- link/include/ableton/discovery/NetworkByteStreamSerializable.hpp +62/−10
- link/include/ableton/discovery/Payload.hpp +10/−19
- link/include/ableton/discovery/PeerGateway.hpp +28/−26
- link/include/ableton/discovery/PeerGateways.hpp +35/−19
- link/include/ableton/discovery/Service.hpp +5/−9
- link/include/ableton/discovery/UdpMessenger.hpp +75/−80
- link/include/ableton/discovery/UnicastIpInterface.hpp +99/−0
- link/include/ableton/discovery/test/Interface.hpp +17/−9
- link/include/ableton/discovery/test/PayloadEntries.hpp +1/−4
- link/include/ableton/discovery/test/Socket.hpp +8/−15
- link/include/ableton/discovery/v1/Messages.hpp +13/−9
- link/include/ableton/link/ApiConfig.hpp +46/−0
- link/include/ableton/link/Beats.hpp +4/−16
- link/include/ableton/link/ClientSessionTimelines.hpp +9/−8
- link/include/ableton/link/Controller.hpp +250/−185
- link/include/ableton/link/EndpointV4.hpp +75/−0
- link/include/ableton/link/EndpointV6.hpp +75/−0
- link/include/ableton/link/Gateway.hpp +26/−12
- link/include/ableton/link/Measurement.hpp +75/−51
- link/include/ableton/link/MeasurementEndpointV4.hpp +0/−75
- link/include/ableton/link/MeasurementEndpointV6.hpp +0/−75
- link/include/ableton/link/MeasurementService.hpp +78/−31
- link/include/ableton/link/NodeId.hpp +13/−1
- link/include/ableton/link/NodeState.hpp +9/−11
- link/include/ableton/link/Optional.hpp +0/−97
- link/include/ableton/link/PeerState.hpp +68/−31
- link/include/ableton/link/Peers.hpp +75/−55
- link/include/ableton/link/Phase.hpp +6/−4
- link/include/ableton/link/PingResponder.hpp +30/−40
- link/include/ableton/link/SessionController.hpp +106/−0
- link/include/ableton/link/SessionState.hpp +34/−10
- link/include/ableton/link/Sessions.hpp +33/−28
- link/include/ableton/link/StartStopState.hpp +5/−4
- link/include/ableton/link/Tempo.hpp +3/−6
- link/include/ableton/link/TripleBuffer.hpp +0/−121
- link/include/ableton/link/v1/Messages.hpp +4/−3
- link/include/ableton/link_audio/ApiConfig.hpp +56/−0
- link/include/ableton/link_audio/AudioBuffer.hpp +245/−0
- link/include/ableton/link_audio/BeatTimeMapping.hpp +50/−0
- link/include/ableton/link_audio/Buffer.hpp +67/−0
- link/include/ableton/link_audio/ChannelAnnouncements.hpp +180/−0
- link/include/ableton/link_audio/ChannelId.hpp +63/−0
- link/include/ableton/link_audio/ChannelRequests.hpp +92/−0
- link/include/ableton/link_audio/Channels.hpp +594/−0
- link/include/ableton/link_audio/Controller.hpp +388/−0
- link/include/ableton/link_audio/Encoder.hpp +69/−0
- link/include/ableton/link_audio/Id.hpp +32/−0
- link/include/ableton/link_audio/MainProcessor.hpp +242/−0
- link/include/ableton/link_audio/NetworkMetrics.hpp +82/−0
- link/include/ableton/link_audio/PCMCodec.hpp +116/−0
- link/include/ableton/link_audio/PeerAnnouncement.hpp +78/−0
- link/include/ableton/link_audio/PeerGateways.hpp +154/−0
- link/include/ableton/link_audio/PeerInfo.hpp +75/−0
- link/include/ableton/link_audio/Queue.hpp +217/−0
- link/include/ableton/link_audio/Receivers.hpp +172/−0
- link/include/ableton/link_audio/Resizer.hpp +147/−0
- link/include/ableton/link_audio/SessionController.hpp +125/−0
- link/include/ableton/link_audio/Sink.hpp +144/−0
- link/include/ableton/link_audio/SinkProcessor.hpp +146/−0
- link/include/ableton/link_audio/Source.hpp +67/−0
- link/include/ableton/link_audio/SourceProcessor.hpp +159/−0
- link/include/ableton/link_audio/UdpMessenger.hpp +617/−0
- link/include/ableton/link_audio/v1/Messages.hpp +170/−0
- link/include/ableton/platforms/Config.hpp +16/−11
- 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 +40/−28
- link/include/ableton/platforms/asio/LockFreeCallbackDispatcher.hpp +23/−6
- link/include/ableton/platforms/asio/Socket.hpp +11/−12
- link/include/ableton/platforms/darwin/Clock.hpp +2/−8
- link/include/ableton/platforms/darwin/ThreadFactory.hpp +87/−2
- link/include/ableton/platforms/esp32/Context.hpp +19/−54
- link/include/ableton/platforms/esp32/LockFreeCallbackDispatcher.hpp +17/−3
- link/include/ableton/platforms/esp32/Log.hpp +138/−0
- link/include/ableton/platforms/esp32/ScanIpIfAddrs.hpp +31/−14
- link/include/ableton/platforms/linux/ThreadFactory.hpp +40/−0
- link/include/ableton/platforms/posix/ScanIpIfAddrs.hpp +34/−28
- link/include/ableton/platforms/stl/Random.hpp +1/−4
- link/include/ableton/platforms/windows/Clock.hpp +1/−4
- link/include/ableton/platforms/windows/ScanIpIfAddrs.hpp +55/−43
- link/include/ableton/platforms/windows/ThreadFactory.hpp +39/−2
- link/include/ableton/platforms/windows/Windows.hpp +2/−2
- link/include/ableton/test/serial_io/Context.hpp +6/−17
- link/include/ableton/test/serial_io/Fixture.hpp +3/−12
- link/include/ableton/test/serial_io/Timer.hpp +3/−6
- link/include/ableton/util/FloatIntConversion.hpp +54/−0
- link/include/ableton/util/Injected.hpp +16/−64
- link/include/ableton/util/Locked.hpp +58/−0
- link/include/ableton/util/Log.hpp +9/−36
- link/include/ableton/util/TripleBuffer.hpp +117/−0
- link/include/ableton/util/test/IoService.hpp +3/−12
- link/include/ableton/util/test/Timer.hpp +1/−4
- link/modules/asio-standalone/asio/include/asio.hpp +9/−23
- link/modules/asio-standalone/asio/include/asio/any_completion_executor.hpp +26/−32
- link/modules/asio-standalone/asio/include/asio/any_completion_handler.hpp +121/−61
- link/modules/asio-standalone/asio/include/asio/any_io_executor.hpp +34/−42
- link/modules/asio-standalone/asio/include/asio/append.hpp +10/−23
- link/modules/asio-standalone/asio/include/asio/as_tuple.hpp +52/−39
- link/modules/asio-standalone/asio/include/asio/associated_allocator.hpp +26/−45
- link/modules/asio-standalone/asio/include/asio/associated_cancellation_slot.hpp +26/−43
- link/modules/asio-standalone/asio/include/asio/associated_executor.hpp +28/−46
- link/modules/asio-standalone/asio/include/asio/associated_immediate_executor.hpp +43/−59
- link/modules/asio-standalone/asio/include/asio/associator.hpp +2/−2
- link/modules/asio-standalone/asio/include/asio/async_result.hpp +962/−1665
- link/modules/asio-standalone/asio/include/asio/awaitable.hpp +4/−1
- link/modules/asio-standalone/asio/include/asio/basic_datagram_socket.hpp +77/−111
- link/modules/asio-standalone/asio/include/asio/basic_deadline_timer.hpp +25/−25
- link/modules/asio-standalone/asio/include/asio/basic_file.hpp +132/−25
- link/modules/asio-standalone/asio/include/asio/basic_io_object.hpp +14/−17
- link/modules/asio-standalone/asio/include/asio/basic_random_access_file.hpp +32/−44
- link/modules/asio-standalone/asio/include/asio/basic_raw_socket.hpp +77/−108
- link/modules/asio-standalone/asio/include/asio/basic_readable_pipe.hpp +21/−30
- link/modules/asio-standalone/asio/include/asio/basic_seq_packet_socket.hpp +39/−51
- link/modules/asio-standalone/asio/include/asio/basic_serial_port.hpp +33/−46
- link/modules/asio-standalone/asio/include/asio/basic_signal_set.hpp +25/−23
- link/modules/asio-standalone/asio/include/asio/basic_socket.hpp +36/−47
- link/modules/asio-standalone/asio/include/asio/basic_socket_acceptor.hpp +115/−162
- link/modules/asio-standalone/asio/include/asio/basic_socket_iostream.hpp +5/−146
- link/modules/asio-standalone/asio/include/asio/basic_socket_streambuf.hpp +6/−148
- link/modules/asio-standalone/asio/include/asio/basic_stream_file.hpp +32/−42
- link/modules/asio-standalone/asio/include/asio/basic_stream_socket.hpp +56/−82
- link/modules/asio-standalone/asio/include/asio/basic_streambuf.hpp +15/−17
- link/modules/asio-standalone/asio/include/asio/basic_streambuf_fwd.hpp +3/−3
- link/modules/asio-standalone/asio/include/asio/basic_waitable_timer.hpp +25/−213
- link/modules/asio-standalone/asio/include/asio/basic_writable_pipe.hpp +21/−30
- link/modules/asio-standalone/asio/include/asio/bind_allocator.hpp +172/−302
- link/modules/asio-standalone/asio/include/asio/bind_cancellation_slot.hpp +177/−293
- link/modules/asio-standalone/asio/include/asio/bind_executor.hpp +180/−290
- link/modules/asio-standalone/asio/include/asio/bind_immediate_executor.hpp +173/−286
- link/modules/asio-standalone/asio/include/asio/buffer.hpp +2872/−2900
- link/modules/asio-standalone/asio/include/asio/buffer_registration.hpp +30/−40
- link/modules/asio-standalone/asio/include/asio/buffered_read_stream.hpp +26/−39
- link/modules/asio-standalone/asio/include/asio/buffered_read_stream_fwd.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/buffered_stream.hpp +32/−48
- link/modules/asio-standalone/asio/include/asio/buffered_stream_fwd.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/buffered_write_stream.hpp +26/−39
- link/modules/asio-standalone/asio/include/asio/buffered_write_stream_fwd.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/buffers_iterator.hpp +4/−24
- link/modules/asio-standalone/asio/include/asio/cancel_after.hpp +301/−0
- link/modules/asio-standalone/asio/include/asio/cancel_at.hpp +294/−0
- link/modules/asio-standalone/asio/include/asio/cancellation_signal.hpp +25/−85
- link/modules/asio-standalone/asio/include/asio/cancellation_state.hpp +16/−16
- link/modules/asio-standalone/asio/include/asio/cancellation_type.hpp +8/−25
- link/modules/asio-standalone/asio/include/asio/co_composed.hpp +1319/−0
- link/modules/asio-standalone/asio/include/asio/co_spawn.hpp +17/−17
- link/modules/asio-standalone/asio/include/asio/completion_condition.hpp +50/−1
- link/modules/asio-standalone/asio/include/asio/compose.hpp +21/−424
- link/modules/asio-standalone/asio/include/asio/composed.hpp +413/−0
- link/modules/asio-standalone/asio/include/asio/config.hpp +193/−0
- link/modules/asio-standalone/asio/include/asio/connect.hpp +180/−367
- link/modules/asio-standalone/asio/include/asio/connect_pipe.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/consign.hpp +11/−24
- link/modules/asio-standalone/asio/include/asio/coroutine.hpp +6/−6
- link/modules/asio-standalone/asio/include/asio/deadline_timer.hpp +7/−2
- link/modules/asio-standalone/asio/include/asio/default_completion_token.hpp +89/−0
- link/modules/asio-standalone/asio/include/asio/defer.hpp +22/−26
- link/modules/asio-standalone/asio/include/asio/deferred.hpp +196/−279
- link/modules/asio-standalone/asio/include/asio/detached.hpp +14/−22
- link/modules/asio-standalone/asio/include/asio/detail/array.hpp +2/−10
- link/modules/asio-standalone/asio/include/asio/detail/array_fwd.hpp +2/−4
- link/modules/asio-standalone/asio/include/asio/detail/assert.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/atomic_count.hpp +5/−13
- link/modules/asio-standalone/asio/include/asio/detail/base_from_cancellation_state.hpp +21/−20
- 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 +129/−563
- link/modules/asio-standalone/asio/include/asio/detail/blocking_executor_op.hpp +2/−3
- 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 +3/−147
- 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 +0/−89
- link/modules/asio-standalone/asio/include/asio/detail/call_stack.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/chrono.hpp +2/−23
- 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 +127/−0
- link/modules/asio-standalone/asio/include/asio/detail/completion_payload.hpp +220/−0
- link/modules/asio-standalone/asio/include/asio/detail/completion_payload_handler.hpp +79/−0
- link/modules/asio-standalone/asio/include/asio/detail/composed_work.hpp +21/−97
- 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 +24/−3
- link/modules/asio-standalone/asio/include/asio/detail/config.hpp +1423/−2301
- link/modules/asio-standalone/asio/include/asio/detail/consuming_buffers.hpp +9/−55
- link/modules/asio-standalone/asio/include/asio/detail/cstddef.hpp +1/−5
- link/modules/asio-standalone/asio/include/asio/detail/cstdint.hpp +2/−24
- 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 +31/−21
- 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 +30/−25
- link/modules/asio-standalone/asio/include/asio/detail/event.hpp +3/−5
- link/modules/asio-standalone/asio/include/asio/detail/eventfd_select_interrupter.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/exception.hpp +2/−13
- link/modules/asio-standalone/asio/include/asio/detail/executor_function.hpp +8/−60
- link/modules/asio-standalone/asio/include/asio/detail/executor_op.hpp +5/−6
- 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 +3/−43
- link/modules/asio-standalone/asio/include/asio/detail/functional.hpp +1/−12
- link/modules/asio-standalone/asio/include/asio/detail/future.hpp +9/−10
- link/modules/asio-standalone/asio/include/asio/detail/gcc_arm_fenced_block.hpp +0/−91
- link/modules/asio-standalone/asio/include/asio/detail/gcc_hppa_fenced_block.hpp +0/−68
- link/modules/asio-standalone/asio/include/asio/detail/gcc_sync_fenced_block.hpp +0/−65
- link/modules/asio-standalone/asio/include/asio/detail/gcc_x86_fenced_block.hpp +0/−99
- link/modules/asio-standalone/asio/include/asio/detail/global.hpp +3/−5
- link/modules/asio-standalone/asio/include/asio/detail/handler_alloc_helpers.hpp +19/−184
- 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 +0/−80
- 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 +9/−37
- link/modules/asio-standalone/asio/include/asio/detail/handler_work.hpp +73/−127
- 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 +43/−19
- link/modules/asio-standalone/asio/include/asio/detail/impl/dev_poll_reactor.hpp +25/−19
- 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 +24/−19
- link/modules/asio-standalone/asio/include/asio/detail/impl/epoll_reactor.ipp +29/−15
- 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 +5/−16
- 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 +25/−19
- link/modules/asio-standalone/asio/include/asio/detail/impl/io_uring_service.ipp +45/−36
- 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 +23/−19
- link/modules/asio-standalone/asio/include/asio/detail/impl/kqueue_reactor.ipp +12/−6
- 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 +9/−7
- link/modules/asio-standalone/asio/include/asio/detail/impl/reactive_socket_service_base.ipp +8/−6
- link/modules/asio-standalone/asio/include/asio/detail/impl/resolver_service_base.ipp +8/−87
- link/modules/asio-standalone/asio/include/asio/detail/impl/resolver_thread_pool.ipp +124/−0
- link/modules/asio-standalone/asio/include/asio/detail/impl/scheduler.ipp +54/−33
- link/modules/asio-standalone/asio/include/asio/detail/impl/select_reactor.hpp +25/−19
- link/modules/asio-standalone/asio/include/asio/detail/impl/select_reactor.ipp +7/−18
- link/modules/asio-standalone/asio/include/asio/detail/impl/service_registry.hpp +29/−6
- link/modules/asio-standalone/asio/include/asio/detail/impl/service_registry.ipp +12/−4
- link/modules/asio-standalone/asio/include/asio/detail/impl/signal_set_service.ipp +6/−5
- link/modules/asio-standalone/asio/include/asio/detail/impl/socket_ops.ipp +81/−14
- 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 +47/−68
- link/modules/asio-standalone/asio/include/asio/detail/impl/strand_executor_service.ipp +5/−4
- link/modules/asio-standalone/asio/include/asio/detail/impl/strand_service.hpp +2/−3
- link/modules/asio-standalone/asio/include/asio/detail/impl/strand_service.ipp +6/−3
- 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 +1/−22
- link/modules/asio-standalone/asio/include/asio/detail/impl/timer_queue_ptime.ipp +0/−97
- 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 +32/−9
- 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 +23/−20
- link/modules/asio-standalone/asio/include/asio/detail/impl/win_iocp_io_context.ipp +43/−22
- 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 +43/−42
- 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 +22/−16
- link/modules/asio-standalone/asio/include/asio/detail/impl/winrt_timer_scheduler.ipp +4/−11
- 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 +56/−101
- link/modules/asio-standalone/asio/include/asio/detail/initiate_dispatch.hpp +56/−92
- link/modules/asio-standalone/asio/include/asio/detail/initiate_post.hpp +56/−101
- link/modules/asio-standalone/asio/include/asio/detail/initiation_base.hpp +62/−0
- 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 +6/−10
- 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 +3/−4
- 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 +30/−25
- link/modules/asio-standalone/asio/include/asio/detail/io_uring_socket_accept_op.hpp +7/−12
- link/modules/asio-standalone/asio/include/asio/detail/io_uring_socket_connect_op.hpp +3/−4
- 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 +11/−13
- 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 +3/−4
- link/modules/asio-standalone/asio/include/asio/detail/is_buffer_sequence.hpp +7/−49
- 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 +30/−24
- link/modules/asio-standalone/asio/include/asio/detail/limits.hpp +1/−6
- 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 +0/−62
- link/modules/asio-standalone/asio/include/asio/detail/memory.hpp +41/−54
- link/modules/asio-standalone/asio/include/asio/detail/mutex.hpp +3/−5
- link/modules/asio-standalone/asio/include/asio/detail/non_const_lvalue.hpp +4/−15
- 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 +7/−1
- 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 +7/−1
- link/modules/asio-standalone/asio/include/asio/detail/null_thread.hpp +31/−3
- 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 +39/−83
- 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 +7/−1
- 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 +52/−17
- 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 +29/−25
- link/modules/asio-standalone/asio/include/asio/detail/reactive_null_buffers_op.hpp +4/−5
- link/modules/asio-standalone/asio/include/asio/detail/reactive_socket_accept_op.hpp +11/−16
- link/modules/asio-standalone/asio/include/asio/detail/reactive_socket_connect_op.hpp +4/−5
- link/modules/asio-standalone/asio/include/asio/detail/reactive_socket_recv_op.hpp +4/−5
- link/modules/asio-standalone/asio/include/asio/detail/reactive_socket_recvfrom_op.hpp +4/−5
- link/modules/asio-standalone/asio/include/asio/detail/reactive_socket_recvmsg_op.hpp +4/−5
- link/modules/asio-standalone/asio/include/asio/detail/reactive_socket_send_op.hpp +4/−6
- link/modules/asio-standalone/asio/include/asio/detail/reactive_socket_sendto_op.hpp +4/−5
- link/modules/asio-standalone/asio/include/asio/detail/reactive_socket_service.hpp +15/−17
- link/modules/asio-standalone/asio/include/asio/detail/reactive_socket_service_base.hpp +40/−35
- link/modules/asio-standalone/asio/include/asio/detail/reactive_wait_op.hpp +4/−5
- 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 +11/−2
- link/modules/asio-standalone/asio/include/asio/detail/regex_fwd.hpp +4/−13
- link/modules/asio-standalone/asio/include/asio/detail/resolve_endpoint_op.hpp +4/−5
- 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 +4/−5
- link/modules/asio-standalone/asio/include/asio/detail/resolver_service.hpp +10/−17
- link/modules/asio-standalone/asio/include/asio/detail/resolver_service_base.hpp +4/−37
- link/modules/asio-standalone/asio/include/asio/detail/resolver_thread_pool.hpp +105/−0
- link/modules/asio-standalone/asio/include/asio/detail/scheduler.hpp +20/−18
- 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 +21/−20
- link/modules/asio-standalone/asio/include/asio/detail/service_registry.hpp +20/−11
- 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 +6/−2
- link/modules/asio-standalone/asio/include/asio/detail/solaris_fenced_block.hpp +0/−62
- link/modules/asio-standalone/asio/include/asio/detail/source_location.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/static_mutex.hpp +3/−5
- link/modules/asio-standalone/asio/include/asio/detail/std_event.hpp +1/−6
- link/modules/asio-standalone/asio/include/asio/detail/std_fenced_block.hpp +1/−6
- link/modules/asio-standalone/asio/include/asio/detail/std_global.hpp +1/−6
- link/modules/asio-standalone/asio/include/asio/detail/std_mutex.hpp +7/−6
- link/modules/asio-standalone/asio/include/asio/detail/std_static_mutex.hpp +1/−6
- link/modules/asio-standalone/asio/include/asio/detail/std_thread.hpp +34/−9
- link/modules/asio-standalone/asio/include/asio/detail/strand_executor_service.hpp +14/−15
- link/modules/asio-standalone/asio/include/asio/detail/strand_service.hpp +2/−3
- link/modules/asio-standalone/asio/include/asio/detail/string_view.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/thread.hpp +3/−5
- link/modules/asio-standalone/asio/include/asio/detail/thread_context.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/detail/thread_group.hpp +13/−8
- 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 +361/−0
- link/modules/asio-standalone/asio/include/asio/detail/timer_queue.hpp +21/−17
- 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 +0/−103
- 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 +116/−90
- link/modules/asio-standalone/asio/include/asio/detail/utility.hpp +4/−4
- link/modules/asio-standalone/asio/include/asio/detail/variadic_templates.hpp +0/−294
- 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 +0/−90
- 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 +3/−4
- 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 +3/−4
- 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 +3/−4
- 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 +3/−4
- 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 +7/−12
- link/modules/asio-standalone/asio/include/asio/detail/win_iocp_socket_connect_op.hpp +3/−4
- link/modules/asio-standalone/asio/include/asio/detail/win_iocp_socket_recv_op.hpp +3/−4
- link/modules/asio-standalone/asio/include/asio/detail/win_iocp_socket_recvfrom_op.hpp +3/−4
- link/modules/asio-standalone/asio/include/asio/detail/win_iocp_socket_recvmsg_op.hpp +4/−5
- link/modules/asio-standalone/asio/include/asio/detail/win_iocp_socket_send_op.hpp +3/−4
- link/modules/asio-standalone/asio/include/asio/detail/win_iocp_socket_service.hpp +10/−13
- link/modules/asio-standalone/asio/include/asio/detail/win_iocp_socket_service_base.hpp +9/−10
- 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 +3/−4
- link/modules/asio-standalone/asio/include/asio/detail/win_mutex.hpp +7/−1
- link/modules/asio-standalone/asio/include/asio/detail/win_object_handle_service.hpp +1/−2
- 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 +55/−19
- 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 +73/−26
- link/modules/asio-standalone/asio/include/asio/detail/wince_thread.hpp +72/−25
- 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 +3/−4
- 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 +3/−4
- link/modules/asio-standalone/asio/include/asio/detail/winrt_socket_recv_op.hpp +3/−4
- link/modules/asio-standalone/asio/include/asio/detail/winrt_socket_send_op.hpp +3/−4
- 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 +18/−17
- 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 +20/−34
- link/modules/asio-standalone/asio/include/asio/detail/wrapped_handler.hpp +61/−180
- link/modules/asio-standalone/asio/include/asio/dispatch.hpp +21/−26
- link/modules/asio-standalone/asio/include/asio/disposition.hpp +282/−0
- link/modules/asio-standalone/asio/include/asio/error.hpp +1/−3
- link/modules/asio-standalone/asio/include/asio/error_code.hpp +3/−166
- link/modules/asio-standalone/asio/include/asio/execution.hpp +1/−16
- link/modules/asio-standalone/asio/include/asio/execution/allocator.hpp +35/−113
- link/modules/asio-standalone/asio/include/asio/execution/any_executor.hpp +1918/−2648
- link/modules/asio-standalone/asio/include/asio/execution/bad_executor.hpp +3/−4
- link/modules/asio-standalone/asio/include/asio/execution/blocking.hpp +297/−537
- link/modules/asio-standalone/asio/include/asio/execution/blocking_adaptation.hpp +275/−413
- link/modules/asio-standalone/asio/include/asio/execution/bulk_execute.hpp +0/−402
- link/modules/asio-standalone/asio/include/asio/execution/bulk_guarantee.hpp +0/−1252
- link/modules/asio-standalone/asio/include/asio/execution/connect.hpp +0/−494
- link/modules/asio-standalone/asio/include/asio/execution/context.hpp +21/−74
- link/modules/asio-standalone/asio/include/asio/execution/context_as.hpp +30/−72
- link/modules/asio-standalone/asio/include/asio/execution/detail/as_invocable.hpp +0/−152
- link/modules/asio-standalone/asio/include/asio/execution/detail/as_operation.hpp +0/−109
- link/modules/asio-standalone/asio/include/asio/execution/detail/as_receiver.hpp +0/−128
- link/modules/asio-standalone/asio/include/asio/execution/detail/bulk_sender.hpp +0/−261
- link/modules/asio-standalone/asio/include/asio/execution/detail/submit_receiver.hpp +0/−233
- link/modules/asio-standalone/asio/include/asio/execution/detail/void_receiver.hpp +0/−90
- link/modules/asio-standalone/asio/include/asio/execution/execute.hpp +0/−290
- link/modules/asio-standalone/asio/include/asio/execution/executor.hpp +24/−170
- 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 +0/−36
- link/modules/asio-standalone/asio/include/asio/execution/invocable_archetype.hpp +2/−30
- link/modules/asio-standalone/asio/include/asio/execution/mapping.hpp +241/−399
- link/modules/asio-standalone/asio/include/asio/execution/occupancy.hpp +21/−74
- link/modules/asio-standalone/asio/include/asio/execution/operation_state.hpp +0/−99
- link/modules/asio-standalone/asio/include/asio/execution/outstanding_work.hpp +150/−297
- link/modules/asio-standalone/asio/include/asio/execution/prefer_only.hpp +56/−59
- link/modules/asio-standalone/asio/include/asio/execution/receiver.hpp +0/−285
- link/modules/asio-standalone/asio/include/asio/execution/receiver_invocation_error.hpp +0/−48
- link/modules/asio-standalone/asio/include/asio/execution/relationship.hpp +150/−297
- link/modules/asio-standalone/asio/include/asio/execution/schedule.hpp +0/−292
- link/modules/asio-standalone/asio/include/asio/execution/scheduler.hpp +0/−91
- link/modules/asio-standalone/asio/include/asio/execution/sender.hpp +0/−316
- link/modules/asio-standalone/asio/include/asio/execution/set_done.hpp +0/−255
- link/modules/asio-standalone/asio/include/asio/execution/set_error.hpp +0/−255
- link/modules/asio-standalone/asio/include/asio/execution/set_value.hpp +0/−488
- link/modules/asio-standalone/asio/include/asio/execution/start.hpp +0/−252
- link/modules/asio-standalone/asio/include/asio/execution/submit.hpp +0/−455
- link/modules/asio-standalone/asio/include/asio/execution_context.hpp +203/−28
- link/modules/asio-standalone/asio/include/asio/executor.hpp +59/−43
- link/modules/asio-standalone/asio/include/asio/executor_work_guard.hpp +56/−61
- link/modules/asio-standalone/asio/include/asio/experimental/append.hpp +0/−36
- link/modules/asio-standalone/asio/include/asio/experimental/as_single.hpp +20/−24
- link/modules/asio-standalone/asio/include/asio/experimental/as_tuple.hpp +0/−36
- link/modules/asio-standalone/asio/include/asio/experimental/awaitable_operators.hpp +8/−8
- link/modules/asio-standalone/asio/include/asio/experimental/basic_channel.hpp +58/−35
- link/modules/asio-standalone/asio/include/asio/experimental/basic_concurrent_channel.hpp +58/−35
- link/modules/asio-standalone/asio/include/asio/experimental/cancellation_condition.hpp +20/−36
- link/modules/asio-standalone/asio/include/asio/experimental/channel.hpp +9/−3
- link/modules/asio-standalone/asio/include/asio/experimental/channel_error.hpp +1/−3
- link/modules/asio-standalone/asio/include/asio/experimental/channel_traits.hpp +15/−15
- link/modules/asio-standalone/asio/include/asio/experimental/co_composed.hpp +3/−114
- link/modules/asio-standalone/asio/include/asio/experimental/co_spawn.hpp +2/−2
- link/modules/asio-standalone/asio/include/asio/experimental/concurrent_channel.hpp +9/−3
- link/modules/asio-standalone/asio/include/asio/experimental/deferred.hpp +0/−36
- link/modules/asio-standalone/asio/include/asio/experimental/detail/channel_handler.hpp +0/−80
- link/modules/asio-standalone/asio/include/asio/experimental/detail/channel_message.hpp +0/−129
- link/modules/asio-standalone/asio/include/asio/experimental/detail/channel_operation.hpp +130/−53
- link/modules/asio-standalone/asio/include/asio/experimental/detail/channel_payload.hpp +0/−139
- link/modules/asio-standalone/asio/include/asio/experimental/detail/channel_receive_op.hpp +17/−11
- link/modules/asio-standalone/asio/include/asio/experimental/detail/channel_send_functions.hpp +92/−36
- link/modules/asio-standalone/asio/include/asio/experimental/detail/channel_send_op.hpp +12/−13
- link/modules/asio-standalone/asio/include/asio/experimental/detail/channel_service.hpp +68/−66
- 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 +41/−30
- link/modules/asio-standalone/asio/include/asio/experimental/detail/partial_promise.hpp +3/−5
- link/modules/asio-standalone/asio/include/asio/experimental/impl/as_single.hpp +42/−100
- 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 +0/−1175
- 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 +60/−63
- link/modules/asio-standalone/asio/include/asio/experimental/impl/promise.hpp +4/−3
- 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 +65/−71
- link/modules/asio-standalone/asio/include/asio/experimental/prepend.hpp +0/−36
- link/modules/asio-standalone/asio/include/asio/experimental/promise.hpp +3/−3
- link/modules/asio-standalone/asio/include/asio/experimental/use_coro.hpp +19/−25
- 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 +2/−6
- 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 +0/−104
- link/modules/asio-standalone/asio/include/asio/handler_continuation_hook.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/handler_invoke_hook.hpp +0/−111
- link/modules/asio-standalone/asio/include/asio/high_resolution_timer.hpp +1/−6
- link/modules/asio-standalone/asio/include/asio/immediate.hpp +142/−0
- link/modules/asio-standalone/asio/include/asio/impl/any_completion_executor.ipp +10/−14
- link/modules/asio-standalone/asio/include/asio/impl/any_io_executor.ipp +10/−17
- link/modules/asio-standalone/asio/include/asio/impl/append.hpp +48/−104
- link/modules/asio-standalone/asio/include/asio/impl/as_tuple.hpp +101/−145
- link/modules/asio-standalone/asio/include/asio/impl/awaitable.hpp +97/−189
- link/modules/asio-standalone/asio/include/asio/impl/awaitable.ipp +48/−0
- link/modules/asio-standalone/asio/include/asio/impl/buffered_read_stream.hpp +56/−179
- link/modules/asio-standalone/asio/include/asio/impl/buffered_write_stream.hpp +56/−179
- link/modules/asio-standalone/asio/include/asio/impl/cancel_after.hpp +268/−0
- link/modules/asio-standalone/asio/include/asio/impl/cancel_at.hpp +268/−0
- link/modules/asio-standalone/asio/include/asio/impl/cancellation_signal.ipp +1/−1
- link/modules/asio-standalone/asio/include/asio/impl/co_spawn.hpp +137/−81
- link/modules/asio-standalone/asio/include/asio/impl/config.hpp +102/−0
- link/modules/asio-standalone/asio/include/asio/impl/config.ipp +345/−0
- link/modules/asio-standalone/asio/include/asio/impl/connect.hpp +77/−391
- link/modules/asio-standalone/asio/include/asio/impl/connect_pipe.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/impl/connect_pipe.ipp +4/−3
- link/modules/asio-standalone/asio/include/asio/impl/consign.hpp +43/−101
- link/modules/asio-standalone/asio/include/asio/impl/deferred.hpp +32/−41
- link/modules/asio-standalone/asio/include/asio/impl/detached.hpp +7/−60
- link/modules/asio-standalone/asio/include/asio/impl/error.ipp +4/−4
- link/modules/asio-standalone/asio/include/asio/impl/error_code.ipp +4/−3
- link/modules/asio-standalone/asio/include/asio/impl/execution_context.hpp +76/−40
- link/modules/asio-standalone/asio/include/asio/impl/execution_context.ipp +42/−4
- link/modules/asio-standalone/asio/include/asio/impl/executor.hpp +60/−43
- link/modules/asio-standalone/asio/include/asio/impl/executor.ipp +3/−3
- link/modules/asio-standalone/asio/include/asio/impl/handler_alloc_hook.ipp +0/−62
- link/modules/asio-standalone/asio/include/asio/impl/io_context.hpp +53/−160
- link/modules/asio-standalone/asio/include/asio/impl/io_context.ipp +10/−59
- link/modules/asio-standalone/asio/include/asio/impl/multiple_exceptions.ipp +4/−8
- link/modules/asio-standalone/asio/include/asio/impl/prepend.hpp +47/−102
- link/modules/asio-standalone/asio/include/asio/impl/read.hpp +148/−522
- link/modules/asio-standalone/asio/include/asio/impl/read_at.hpp +54/−266
- link/modules/asio-standalone/asio/include/asio/impl/read_until.hpp +2656/−3443
- link/modules/asio-standalone/asio/include/asio/impl/redirect_error.hpp +81/−428
- 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 +209/−710
- 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 +4/−3
- link/modules/asio-standalone/asio/include/asio/impl/system_executor.hpp +19/−25
- link/modules/asio-standalone/asio/include/asio/impl/thread_pool.hpp +73/−108
- link/modules/asio-standalone/asio/include/asio/impl/thread_pool.ipp +38/−35
- link/modules/asio-standalone/asio/include/asio/impl/use_awaitable.hpp +57/−124
- link/modules/asio-standalone/asio/include/asio/impl/use_future.hpp +107/−518
- link/modules/asio-standalone/asio/include/asio/impl/write.hpp +154/−527
- link/modules/asio-standalone/asio/include/asio/impl/write_at.hpp +52/−259
- link/modules/asio-standalone/asio/include/asio/io_context.hpp +137/−350
- link/modules/asio-standalone/asio/include/asio/io_context_strand.hpp +31/−125
- link/modules/asio-standalone/asio/include/asio/io_service.hpp +0/−33
- link/modules/asio-standalone/asio/include/asio/io_service_strand.hpp +0/−20
- link/modules/asio-standalone/asio/include/asio/ip/address.hpp +26/−61
- link/modules/asio-standalone/asio/include/asio/ip/address_v4.hpp +25/−90
- link/modules/asio-standalone/asio/include/asio/ip/address_v4_iterator.hpp +13/−19
- link/modules/asio-standalone/asio/include/asio/ip/address_v4_range.hpp +16/−22
- link/modules/asio-standalone/asio/include/asio/ip/address_v6.hpp +33/−83
- link/modules/asio-standalone/asio/include/asio/ip/address_v6_iterator.hpp +13/−18
- link/modules/asio-standalone/asio/include/asio/ip/address_v6_range.hpp +15/−20
- link/modules/asio-standalone/asio/include/asio/ip/bad_address_cast.hpp +13/−3
- link/modules/asio-standalone/asio/include/asio/ip/basic_endpoint.hpp +26/−35
- link/modules/asio-standalone/asio/include/asio/ip/basic_resolver.hpp +46/−172
- 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 +4/−8
- link/modules/asio-standalone/asio/include/asio/ip/basic_resolver_query.hpp +17/−1
- link/modules/asio-standalone/asio/include/asio/ip/basic_resolver_results.hpp +9/−17
- link/modules/asio-standalone/asio/include/asio/ip/detail/endpoint.hpp +26/−22
- link/modules/asio-standalone/asio/include/asio/ip/detail/impl/endpoint.ipp +10/−14
- 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 +1/−29
- link/modules/asio-standalone/asio/include/asio/ip/impl/address.ipp +18/−31
- link/modules/asio-standalone/asio/include/asio/ip/impl/address_v4.hpp +1/−29
- link/modules/asio-standalone/asio/include/asio/ip/impl/address_v4.ipp +9/−69
- link/modules/asio-standalone/asio/include/asio/ip/impl/address_v6.hpp +1/−29
- link/modules/asio-standalone/asio/include/asio/ip/impl/address_v6.ipp +25/−94
- 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 +16/−20
- link/modules/asio-standalone/asio/include/asio/ip/network_v6.hpp +14/−18
- 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 +17/−21
- 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 +3/−9
- link/modules/asio-standalone/asio/include/asio/packaged_task.hpp +1/−61
- link/modules/asio-standalone/asio/include/asio/placeholders.hpp +33/−103
- link/modules/asio-standalone/asio/include/asio/posix/basic_descriptor.hpp +22/−30
- link/modules/asio-standalone/asio/include/asio/posix/basic_stream_descriptor.hpp +26/−36
- 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 +21/−26
- link/modules/asio-standalone/asio/include/asio/prefer.hpp +174/−331
- link/modules/asio-standalone/asio/include/asio/prepend.hpp +11/−23
- link/modules/asio-standalone/asio/include/asio/query.hpp +57/−70
- link/modules/asio-standalone/asio/include/asio/random_access_file.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/read.hpp +245/−178
- link/modules/asio-standalone/asio/include/asio/read_at.hpp +93/−60
- link/modules/asio-standalone/asio/include/asio/read_until.hpp +350/−314
- 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 +47/−9
- link/modules/asio-standalone/asio/include/asio/registered_buffer.hpp +37/−49
- link/modules/asio-standalone/asio/include/asio/require.hpp +107/−245
- link/modules/asio-standalone/asio/include/asio/require_concept.hpp +70/−79
- 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 +10/−21
- link/modules/asio-standalone/asio/include/asio/socket_base.hpp +1/−12
- link/modules/asio-standalone/asio/include/asio/spawn.hpp +101/−317
- link/modules/asio-standalone/asio/include/asio/ssl.hpp +1/−2
- link/modules/asio-standalone/asio/include/asio/ssl/context.hpp +1/−3
- 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 +3/−7
- 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 +9/−7
- 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 +16/−75
- 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 +12/−65
- 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 +1/−3
- 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 +12/−11
- 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 +0/−164
- link/modules/asio-standalone/asio/include/asio/ssl/impl/src.hpp +1/−2
- link/modules/asio-standalone/asio/include/asio/ssl/rfc2818_verification.hpp +0/−98
- link/modules/asio-standalone/asio/include/asio/ssl/stream.hpp +56/−87
- 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 +1/−6
- link/modules/asio-standalone/asio/include/asio/strand.hpp +91/−118
- 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 +2/−102
- link/modules/asio-standalone/asio/include/asio/system_executor.hpp +62/−62
- link/modules/asio-standalone/asio/include/asio/system_timer.hpp +1/−6
- link/modules/asio-standalone/asio/include/asio/this_coro.hpp +37/−50
- link/modules/asio-standalone/asio/include/asio/thread.hpp +1/−1
- link/modules/asio-standalone/asio/include/asio/thread_pool.hpp +173/−277
- link/modules/asio-standalone/asio/include/asio/time_traits.hpp +7/−3
- link/modules/asio-standalone/asio/include/asio/traits/bulk_execute_free.hpp +0/−114
- link/modules/asio-standalone/asio/include/asio/traits/bulk_execute_member.hpp +0/−114
- link/modules/asio-standalone/asio/include/asio/traits/connect_free.hpp +0/−112
- link/modules/asio-standalone/asio/include/asio/traits/connect_member.hpp +0/−112
- link/modules/asio-standalone/asio/include/asio/traits/equality_comparable.hpp +14/−18
- link/modules/asio-standalone/asio/include/asio/traits/execute_free.hpp +0/−108
- link/modules/asio-standalone/asio/include/asio/traits/execute_member.hpp +16/−20
- link/modules/asio-standalone/asio/include/asio/traits/prefer_free.hpp +16/−20
- link/modules/asio-standalone/asio/include/asio/traits/prefer_member.hpp +16/−20
- link/modules/asio-standalone/asio/include/asio/traits/query_free.hpp +16/−20
- link/modules/asio-standalone/asio/include/asio/traits/query_member.hpp +16/−20
- link/modules/asio-standalone/asio/include/asio/traits/query_static_constexpr_member.hpp +15/−22
- link/modules/asio-standalone/asio/include/asio/traits/require_concept_free.hpp +16/−20
- link/modules/asio-standalone/asio/include/asio/traits/require_concept_member.hpp +16/−20
- link/modules/asio-standalone/asio/include/asio/traits/require_free.hpp +16/−20
- link/modules/asio-standalone/asio/include/asio/traits/require_member.hpp +16/−20
- link/modules/asio-standalone/asio/include/asio/traits/schedule_free.hpp +0/−108
- link/modules/asio-standalone/asio/include/asio/traits/schedule_member.hpp +0/−108
- link/modules/asio-standalone/asio/include/asio/traits/set_done_free.hpp +0/−108
- link/modules/asio-standalone/asio/include/asio/traits/set_done_member.hpp +0/−108
- link/modules/asio-standalone/asio/include/asio/traits/set_error_free.hpp +0/−112
- link/modules/asio-standalone/asio/include/asio/traits/set_error_member.hpp +0/−112
- link/modules/asio-standalone/asio/include/asio/traits/set_value_free.hpp +0/−234
- link/modules/asio-standalone/asio/include/asio/traits/set_value_member.hpp +0/−234
- link/modules/asio-standalone/asio/include/asio/traits/start_free.hpp +0/−108
- link/modules/asio-standalone/asio/include/asio/traits/start_member.hpp +0/−108
- link/modules/asio-standalone/asio/include/asio/traits/static_query.hpp +20/−26
- link/modules/asio-standalone/asio/include/asio/traits/static_require.hpp +22/−30
- link/modules/asio-standalone/asio/include/asio/traits/static_require_concept.hpp +22/−30
- link/modules/asio-standalone/asio/include/asio/traits/submit_free.hpp +0/−112
- link/modules/asio-standalone/asio/include/asio/traits/submit_member.hpp +0/−112
- 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 +4/−45
- 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 +17/−23
- link/modules/asio-standalone/asio/include/asio/use_future.hpp +10/−23
- link/modules/asio-standalone/asio/include/asio/uses_executor.hpp +3/−7
- 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 +21/−29
- link/modules/asio-standalone/asio/include/asio/windows/basic_overlapped_handle.hpp +13/−18
- link/modules/asio-standalone/asio/include/asio/windows/basic_random_access_handle.hpp +25/−37
- link/modules/asio-standalone/asio/include/asio/windows/basic_stream_handle.hpp +25/−35
- 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 +246/−158
- link/modules/asio-standalone/asio/include/asio/write_at.hpp +96/−60
- link/modules/asio-standalone/asio/include/asio/yield.hpp +1/−1
- link/modules/asio-standalone/asio/src/examples/cpp03/chat/chat_message.hpp +0/−96
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server/connection.hpp +0/−83
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server/connection_manager.hpp +0/−44
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server/header.hpp +0/−28
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server/mime_types.hpp +0/−27
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server/reply.hpp +0/−64
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server/request.hpp +0/−34
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server/request_handler.hpp +0/−46
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server/request_parser.hpp +0/−95
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server/server.hpp +0/−69
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server2/connection.hpp +0/−75
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server2/header.hpp +0/−28
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server2/io_context_pool.hpp +0/−58
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server2/mime_types.hpp +0/−27
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server2/reply.hpp +0/−64
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server2/request.hpp +0/−34
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server2/request_handler.hpp +0/−46
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server2/request_parser.hpp +0/−95
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server2/server.hpp +0/−68
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server3/connection.hpp +0/−78
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server3/header.hpp +0/−28
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server3/mime_types.hpp +0/−27
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server3/reply.hpp +0/−64
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server3/request.hpp +0/−34
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server3/request_handler.hpp +0/−46
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server3/request_parser.hpp +0/−95
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server3/server.hpp +0/−70
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server4/file_handler.hpp +0/−44
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server4/header.hpp +0/−28
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server4/mime_types.hpp +0/−27
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server4/reply.hpp +0/−64
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server4/request.hpp +0/−46
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server4/request_parser.hpp +0/−78
- link/modules/asio-standalone/asio/src/examples/cpp03/http/server4/server.hpp +0/−73
- link/modules/asio-standalone/asio/src/examples/cpp03/icmp/icmp_header.hpp +0/−94
- link/modules/asio-standalone/asio/src/examples/cpp03/icmp/ipv4_header.hpp +0/−102
- link/modules/asio-standalone/asio/src/examples/cpp03/porthopper/protocol.hpp +0/−156
- link/modules/asio-standalone/asio/src/examples/cpp03/serialization/connection.hpp +0/−188
- link/modules/asio-standalone/asio/src/examples/cpp03/serialization/stock.hpp +0/−50
- link/modules/asio-standalone/asio/src/examples/cpp03/services/basic_logger.hpp +0/−77
- link/modules/asio-standalone/asio/src/examples/cpp03/services/logger.hpp +0/−24
- link/modules/asio-standalone/asio/src/examples/cpp03/services/logger_service.hpp +0/−145
- link/modules/asio-standalone/asio/src/examples/cpp03/socks4/socks4.hpp +0/−144
- link/modules/asio-standalone/asio/src/examples/cpp11/chat/chat_message.hpp +3/−2
- 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 +71/−0
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server2/header.hpp +28/−0
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server2/io_context_pool.hpp +59/−0
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server2/mime_types.hpp +27/−0
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server2/reply.hpp +64/−0
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server2/request.hpp +34/−0
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server2/request_handler.hpp +47/−0
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server2/request_parser.hpp +96/−0
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server2/server.hpp +60/−0
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server3/connection.hpp +71/−0
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server3/header.hpp +28/−0
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server3/mime_types.hpp +27/−0
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server3/reply.hpp +64/−0
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server3/request.hpp +34/−0
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server3/request_handler.hpp +47/−0
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server3/request_parser.hpp +96/−0
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server3/server.hpp +62/−0
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server4/file_handler.hpp +44/−0
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server4/header.hpp +28/−0
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server4/mime_types.hpp +27/−0
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server4/reply.hpp +64/−0
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server4/request.hpp +34/−0
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server4/request_handler.hpp +47/−0
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server4/request_parser.hpp +96/−0
- link/modules/asio-standalone/asio/src/examples/cpp11/http/server4/server.hpp +73/−0
- link/modules/asio-standalone/asio/src/examples/cpp11/icmp/icmp_header.hpp +94/−0
- link/modules/asio-standalone/asio/src/examples/cpp11/icmp/ipv4_header.hpp +102/−0
- link/modules/asio-standalone/asio/src/examples/cpp11/porthopper/protocol.hpp +156/−0
- link/modules/asio-standalone/asio/src/examples/cpp11/serialization/connection.hpp +184/−0
- link/modules/asio-standalone/asio/src/examples/cpp11/serialization/stock.hpp +50/−0
- link/modules/asio-standalone/asio/src/examples/cpp11/services/basic_logger.hpp +78/−0
- link/modules/asio-standalone/asio/src/examples/cpp11/services/logger.hpp +24/−0
- link/modules/asio-standalone/asio/src/examples/cpp11/services/logger_service.hpp +145/−0
- 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 +362/−317
- link/modules/asio-standalone/asio/src/tests/unit/archetypes/async_result.hpp +6/−12
- 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 +4/−4
link/examples/linkaudio/AudioEngine.hpp view
@@ -21,15 +21,22 @@ // Make sure to define this before <cmath> is included for Windows #define _USE_MATH_DEFINES-#include <ableton/Link.hpp>+#include <array> #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:@@ -44,38 +51,46 @@ bool isStartStopSyncEnabled() const; void setStartStopSyncEnabled(bool enabled); -private: struct EngineData {- double requestedTempo;- bool requestStart;- bool requestStop;- double quantum;- bool startStopSyncOn;+ double requestedTempo = 0;+ bool requestStart = false;+ bool requestStop = false;+ double quantum = 4;+ bool startStopSyncOn = false; }; - void setBufferSize(std::size_t size);+ 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};+ };+++ void setNumFrames(std::size_t size); void setSampleRate(double sampleRate); EngineData pullEngineData();- 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);+ 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); Link& mLink; double mSampleRate; std::atomic<std::chrono::microseconds> mOutputLatency;- std::vector<double> mBuffer;- EngineData mSharedEngineData;- EngineData mLockfreeEngineData;+ std::array<std::vector<double>, 2> mBuffers;+ EngineDataSignals mEngineDataSignals; std::chrono::microseconds mTimeAtLastClick; bool mIsPlaying;- std::mutex mEngineDataGuard; - friend class AudioPlatform;+ LinkAudioRenderer<Link> mLinkAudioRenderer; }; - } // namespace linkaudio } // namespace ableton++#include "AudioEngine.ipp"
+ link/examples/linkaudio/AudioEngine.ipp view
@@ -0,0 +1,255 @@+/* 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,7 +21,6 @@ #include "AudioEngine.hpp" -#include <ableton/Link.hpp> #include <ableton/link/HostTimeFilter.hpp> #include "asiosys.h" // Should be included before asio.h@@ -67,9 +66,13 @@ 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:@@ -78,12 +81,7 @@ void audioCallback(ASIOTime* timeInfo, long index); - 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);+ AudioEngine<Link> mEngine; private: void createAsioBuffers();@@ -94,10 +92,13 @@ DriverInfo mDriverInfo; ASIOCallbacks mAsioCallbacks;- link::HostTimeFilter<platforms::windows::Clock> mHostTimeFilter;+ link::HostTimeFilter<typename Link::Clock> mHostTimeFilter; - static AudioPlatform* _singleton;+public:+ static AudioPlatform<Link>* _singleton; }; } // namespace linkaudio } // namespace ableton++#include "AudioPlatform_Asio.ipp"
+ link/examples/linkaudio/AudioPlatform_Asio.ipp view
@@ -0,0 +1,319 @@+/* 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,21 +27,28 @@ namespace linkaudio { +template <typename Link> class AudioPlatform { public: AudioPlatform(Link& link); ~AudioPlatform();- AudioEngine mEngine;+ AudioEngine<Link> mEngine; private: static OSStatus audioCallback(void* inRefCon,- AudioUnitRenderActionFlags*,- const AudioTimeStamp* inTimeStamp,- UInt32,- UInt32 inNumberFrames,- AudioBufferList* ioData);+ AudioUnitRenderActionFlags*,+ const AudioTimeStamp* inTimeStamp,+ UInt32,+ UInt32 inNumberFrames,+ AudioBufferList* ioData); + static void streamFormatCallback(void* inRefCon,+ AudioUnit inUnit,+ AudioUnitPropertyID inID,+ AudioUnitScope inScope,+ AudioUnitElement inElement);+ void initialize(); void uninitialize(); void start();@@ -52,3 +59,5 @@ } // namespace linkaudio } // namespace ableton++#include "AudioPlatform_CoreAudio.ipp"
+ link/examples/linkaudio/AudioPlatform_CoreAudio.ipp view
@@ -0,0 +1,294 @@+/* 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,13 +19,14 @@ #pragma once -#include <ableton/Link.hpp>+#include <chrono> namespace ableton { namespace linkaudio { +template <typename Link> class AudioPlatform { class AudioEngine@@ -51,10 +52,7 @@ mLink.commitAppSessionState(sessionState); } - bool isPlaying() const- {- return mLink.captureAppSessionState().isPlaying();- }+ bool isPlaying() const { return mLink.captureAppSessionState().isPlaying(); } double beatTime() const {@@ -69,31 +67,16 @@ 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,7 +21,6 @@ #include "AudioEngine.hpp" #include <ableton/link/HostTimeFilter.hpp>-#include <ableton/platforms/Config.hpp> #include <jack/jack.h> namespace ableton@@ -29,13 +28,14 @@ namespace linkaudio { +template <typename Link> class AudioPlatform { public: AudioPlatform(Link& link); ~AudioPlatform(); - AudioEngine mEngine;+ AudioEngine<Link> mEngine; private: static int audioCallback(jack_nframes_t nframes, void* pvUserData);@@ -48,7 +48,7 @@ void start(); void stop(); - link::HostTimeFilter<link::platform::Clock> mHostTimeFilter;+ link::HostTimeFilter<typename Link::Clock> mHostTimeFilter; double mSampleTime; jack_client_t* mpJackClient; jack_port_t** mpJackPorts;@@ -56,3 +56,5 @@ } // namespace linkaudio } // namespace ableton++#include "AudioPlatform_Jack.ipp"
+ link/examples/linkaudio/AudioPlatform_Jack.ipp view
@@ -0,0 +1,221 @@+/* 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,7 +21,6 @@ #include "AudioEngine.hpp" #include <ableton/link/HostTimeFilter.hpp>-#include <ableton/platforms/Config.hpp> #include <portaudio.h> namespace ableton@@ -29,31 +28,34 @@ namespace linkaudio { +template <typename Link> class AudioPlatform { public: AudioPlatform(Link& link); ~AudioPlatform(); - AudioEngine mEngine;+ AudioEngine<Link> 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<link::platform::Clock> mHostTimeFilter;+ link::HostTimeFilter<typename Link::Clock> mHostTimeFilter; double mSampleTime; PaStream* pStream; }; } // namespace linkaudio } // namespace ableton++#include "AudioPlatform_Portaudio.ipp"
+ link/examples/linkaudio/AudioPlatform_Portaudio.ipp view
@@ -0,0 +1,168 @@+/* 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,8 +38,10 @@ // and then terminate the application. void fatalError(HRESULT result, LPCTSTR context); +template <typename Link> DWORD renderAudioRunloop(LPVOID); +template <typename Link> class AudioPlatform { public:@@ -48,7 +50,7 @@ DWORD audioRunloop(); - AudioEngine mEngine;+ AudioEngine<Link> mEngine; private: UINT32 bufferSize();@@ -56,7 +58,7 @@ void initialize(); void start(); - link::HostTimeFilter<platforms::windows::Clock> mHostTimeFilter;+ link::HostTimeFilter<typename Link::Clock> mHostTimeFilter; double mSampleTime; IMMDevice* mDevice;@@ -70,3 +72,5 @@ } // namespace linkaudio } // namespace ableton++#include "AudioPlatform_Wasapi.ipp"
+ link/examples/linkaudio/AudioPlatform_Wasapi.ipp view
@@ -0,0 +1,344 @@+/* 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 view
@@ -0,0 +1,418 @@+/* 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,6 +18,7 @@ */ #include <stdbool.h>+#include <stddef.h> #include <stdint.h> #ifdef __cplusplus@@ -61,52 +62,52 @@ */ /*! @brief The representation of an abl_link instance*/- typedef struct abl_link+ struct abl_link { void *impl;- } abl_link;+ }; /*! @brief Construct a new abl_link instance with an initial tempo. * Thread-safe: yes * Realtime-safe: no */- abl_link abl_link_create(double bpm);+ struct abl_link abl_link_create(double bpm); /*! @brief Delete an abl_link instance. * Thread-safe: yes * Realtime-safe: no */- void abl_link_destroy(abl_link link);+ void abl_link_destroy(struct abl_link link); /*! @brief Is Link currently enabled? * Thread-safe: yes * Realtime-safe: yes */- bool abl_link_is_enabled(abl_link link);+ bool abl_link_is_enabled(struct abl_link link); /*! @brief Enable/disable Link. * Thread-safe: yes * Realtime-safe: no */- void abl_link_enable(abl_link link, bool enable);+ void abl_link_enable(struct abl_link link, bool enable); /*! @brief: Is start/stop synchronization enabled? * Thread-safe: yes- * Realtime-safe: no+ * Realtime-safe: yes */- bool abl_link_is_start_stop_sync_enabled(abl_link link);+ bool abl_link_is_start_stop_sync_enabled(struct abl_link link); /*! @brief: Enable start/stop synchronization. * Thread-safe: yes- * Realtime-safe: no+ * Realtime-safe: yes */- void abl_link_enable_start_stop_sync(abl_link link, bool enabled);+ void abl_link_enable_start_stop_sync(struct 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(abl_link link);+ uint64_t abl_link_num_peers(struct abl_link link); /*! @brief Register a callback to be notified when the number of * peers in the Link session changes.@@ -115,9 +116,9 @@ * * @discussion The callback is invoked on a Link-managed thread. */- 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);+ void abl_link_set_num_peers_callback(struct abl_link link,+ void (*callback)(uint64_t num_peers, void *context),+ void *context); /*! @brief Register a callback to be notified when the session * tempo changes.@@ -126,9 +127,8 @@ * * @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(- abl_link link, abl_link_tempo_callback callback, void *context);+ struct abl_link link, void (*callback)(double tempo, void *context), 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. */- 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);+ void abl_link_set_start_stop_callback(struct abl_link link,+ void (*callback)(bool is_playing, void *context),+ void *context); /*! brief: Get the current link clock time in microseconds. * Thread-safe: yes * Realtime-safe: yes */- int64_t abl_link_clock_micros(abl_link link);+ int64_t abl_link_clock_micros(struct 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+ typedef struct abl_link_session_state // NOLINT(modernize-use-using) { 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(- abl_link link, abl_link_session_state session_state);+ struct 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(- abl_link link, abl_link_session_state session_state);+ struct abl_link link, abl_link_session_state session_state); /*! @brief Capture the current Link Session State from an application thread.- * Thread-safe: no- * Realtime-safe: yes+ * Thread-safe: yes+ * Realtime-safe: no * * @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(- abl_link link, abl_link_session_state session_state);+ struct 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(- abl_link link, abl_link_session_state session_state);+ struct 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, uint64_t time, double quantum);+ abl_link_session_state session_state, double beat, int64_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, uint64_t time);+ abl_link_session_state session_state, bool is_playing, int64_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 */- uint64_t abl_link_time_for_is_playing(abl_link_session_state session_state);+ int64_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,9 +343,254 @@ void abl_link_set_is_playing_and_request_beat_at_time( abl_link_session_state session_state, bool is_playing,- uint64_t time,+ int64_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,70 +18,135 @@ */ #include <abl_link.h>-#include <ableton/Link.hpp>+#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+ extern "C" {- abl_link abl_link_create(double bpm)+ struct abl_link abl_link_create(double bpm) {- return abl_link{reinterpret_cast<void *>(new ableton::Link(bpm))};+ return {reinterpret_cast<void *>(new ableton::LinkAudio(bpm, std::string{}))}; } - void abl_link_destroy(abl_link link)+ void abl_link_destroy(struct abl_link link) {- delete reinterpret_cast<ableton::Link *>(link.impl);+ delete reinterpret_cast<ableton::LinkAudio *>(link.impl); } - bool abl_link_is_enabled(abl_link link)+ bool abl_link_is_enabled(struct abl_link link) {- return reinterpret_cast<ableton::Link *>(link.impl)->isEnabled();+ return reinterpret_cast<ableton::LinkAudio *>(link.impl)->isEnabled(); } - void abl_link_enable(abl_link link, bool enabled)+ void abl_link_enable(struct abl_link link, bool enabled) {- reinterpret_cast<ableton::Link *>(link.impl)->enable(enabled);+ reinterpret_cast<ableton::LinkAudio *>(link.impl)->enable(enabled); } - bool abl_link_is_start_stop_sync_enabled(abl_link link)+ bool abl_link_is_start_stop_sync_enabled(struct abl_link link) {- return reinterpret_cast<ableton::Link *>(link.impl)->isStartStopSyncEnabled();+ return reinterpret_cast<ableton::LinkAudio *>(link.impl)->isStartStopSyncEnabled(); } - void abl_link_enable_start_stop_sync(abl_link link, bool enabled)+ void abl_link_enable_start_stop_sync(struct abl_link link, bool enabled) {- reinterpret_cast<ableton::Link *>(link.impl)->enableStartStopSync(enabled);+ reinterpret_cast<ableton::LinkAudio *>(link.impl)->enableStartStopSync(enabled); } - uint64_t abl_link_num_peers(abl_link link)+ uint64_t abl_link_num_peers(struct abl_link link) {- return reinterpret_cast<ableton::Link *>(link.impl)->numPeers();+ return reinterpret_cast<ableton::LinkAudio *>(link.impl)->numPeers(); } - void abl_link_set_num_peers_callback(- abl_link link, abl_link_num_peers_callback callback, void *context)+ void abl_link_set_num_peers_callback(struct abl_link link,+ void (*callback)(uint64_t num_peers, void *context),+ void *context) {- reinterpret_cast<ableton::Link *>(link.impl)->setNumPeersCallback(- [callback, context](- std::size_t numPeers) { (*callback)(static_cast<uint64_t>(numPeers), context); });+ reinterpret_cast<ableton::LinkAudio *>(link.impl)->setNumPeersCallback(+ [callback, context](std::size_t numPeers)+ { (*callback)(static_cast<uint64_t>(numPeers), context); }); } void abl_link_set_tempo_callback(- abl_link link, abl_link_tempo_callback callback, void *context)+ struct abl_link link, void (*callback)(double tempo, void *context), void *context) {- reinterpret_cast<ableton::Link *>(link.impl)->setTempoCallback(+ reinterpret_cast<ableton::LinkAudio *>(link.impl)->setTempoCallback( [callback, context](double tempo) { (*callback)(tempo, context); }); } void abl_link_set_start_stop_callback(- abl_link link, abl_link_start_stop_callback callback, void *context)+ struct abl_link link, void (*callback)(bool isPlaying, void *context), void *context) {- reinterpret_cast<ableton::Link *>(link.impl)->setStartStopCallback(+ reinterpret_cast<ableton::LinkAudio *>(link.impl)->setStartStopCallback( [callback, context](bool isPlaying) { (*callback)(isPlaying, context); }); } - int64_t abl_link_clock_micros(abl_link link)+ int64_t abl_link_clock_micros(struct abl_link link) {- return reinterpret_cast<ableton::Link *>(link.impl)->clock().micros().count();+ return reinterpret_cast<ableton::LinkAudio *>(link.impl)->clock().micros().count(); } abl_link_session_state abl_link_create_session_state(void)@@ -96,30 +161,30 @@ } void abl_link_capture_app_session_state(- abl_link link, abl_link_session_state session_state)+ struct abl_link link, abl_link_session_state session_state) { *reinterpret_cast<ableton::Link::SessionState *>(session_state.impl) =- reinterpret_cast<ableton::Link *>(link.impl)->captureAppSessionState();+ reinterpret_cast<ableton::LinkAudio *>(link.impl)->captureAppSessionState(); } void abl_link_commit_app_session_state(- abl_link link, abl_link_session_state session_state)+ struct abl_link link, abl_link_session_state session_state) {- reinterpret_cast<ableton::Link *>(link.impl)->commitAppSessionState(+ reinterpret_cast<ableton::LinkAudio *>(link.impl)->commitAppSessionState( *reinterpret_cast<ableton::Link::SessionState *>(session_state.impl)); } void abl_link_capture_audio_session_state(- abl_link link, abl_link_session_state session_state)+ struct abl_link link, abl_link_session_state session_state) { *reinterpret_cast<ableton::Link::SessionState *>(session_state.impl) =- reinterpret_cast<ableton::Link *>(link.impl)->captureAudioSessionState();+ reinterpret_cast<ableton::LinkAudio *>(link.impl)->captureAudioSessionState(); } void abl_link_commit_audio_session_state(- abl_link link, abl_link_session_state session_state)+ struct abl_link link, abl_link_session_state session_state) {- reinterpret_cast<ableton::Link *>(link.impl)->commitAudioSessionState(+ reinterpret_cast<ableton::LinkAudio *>(link.impl)->commitAudioSessionState( *reinterpret_cast<ableton::Link::SessionState *>(session_state.impl)); } @@ -166,14 +231,14 @@ } void abl_link_force_beat_at_time(- abl_link_session_state session_state, double beat, uint64_t time, double quantum)+ abl_link_session_state session_state, double beat, int64_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, uint64_t time)+ abl_link_session_state session_state, bool is_playing, int64_t time) { reinterpret_cast<ableton::Link::SessionState *>(session_state.impl) ->setIsPlaying(is_playing, std::chrono::microseconds(time));@@ -185,9 +250,9 @@ ->isPlaying(); } - uint64_t abl_link_time_for_is_playing(abl_link_session_state session_state)+ int64_t abl_link_time_for_is_playing(abl_link_session_state session_state) {- return static_cast<uint64_t>(+ return static_cast<int64_t>( reinterpret_cast<ableton::Link::SessionState *>(session_state.impl) ->timeForIsPlaying() .count());@@ -203,12 +268,299 @@ void abl_link_set_is_playing_and_request_beat_at_time( abl_link_session_state session_state, bool is_playing,- uint64_t time,+ int64_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,7 +22,8 @@ #pragma once -#include <ableton/platforms/Config.hpp>+#include <ableton/link/ApiConfig.hpp>+ #include <chrono> #include <mutex> @@ -103,13 +104,13 @@ /*! @brief: Is start/stop synchronization enabled? * Thread-safe: yes- * Realtime-safe: no+ * Realtime-safe: yes */ bool isStartStopSyncEnabled() const; /*! @brief: Enable start/stop synchronization. * Thread-safe: yes- * Realtime-safe: no+ * Realtime-safe: yes */ void enableStartStopSync(bool bEnable); @@ -244,6 +245,9 @@ 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@@ -361,23 +365,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; }; -private:- using Controller = ableton::link::Controller<link::PeerCountCallback,- link::TempoCallback,- link::StartStopStateCallback,- Clock,- link::platform::Random,- link::platform::IoContext>;+protected:+ using Controller = ableton::link::ApiController<Clock>; std::mutex mCallbackMutex; link::PeerCountCallback mPeerCountCallback = [](std::size_t) {};
link/include/ableton/Link.ipp view
@@ -30,11 +30,14 @@ inline typename BasicLink<Clock>::SessionState toSessionState( const link::ClientState& state, const bool isConnected) {- return {{state.timeline, {state.startStopState.isPlaying, state.startStopState.time}},- isConnected};+ return {{state.timeline,+ state.timelineSessionId,+ {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) {@@ -44,7 +47,8 @@ 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}; }@@ -53,16 +57,20 @@ 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); },@@ -163,8 +171,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)@@ -172,6 +180,19 @@ } 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();@@ -217,18 +238,19 @@ { 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 view
@@ -0,0 +1,358 @@+/*! @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 view
@@ -0,0 +1,267 @@+/* 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,8 +32,14 @@ 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 makeAddress(const char* pAddr)+AsioAddrType makeAddressFromBytes(const char* pAddr) { using namespace std; typename AsioAddrType::bytes_type bytes;@@ -42,7 +48,7 @@ } template <typename AsioAddrType>-AsioAddrType makeAddress(const char* pAddr, uint32_t scopeId)+AsioAddrType makeAddressFromBytes(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,12 +73,14 @@ // setup the next scanning mTimer.expires_from_now(mPeriod); using ErrorCode = typename Timer::ErrorCode;- mTimer.async_wait([this](const ErrorCode e) {- if (!e)+ mTimer.async_wait(+ [this](const ErrorCode e) {- scan();- }- });+ if (!e)+ {+ scan();+ }+ }); } private:
link/include/ableton/discovery/IpInterface.hpp view
@@ -29,15 +29,13 @@ inline UdpEndpoint multicastEndpointV4() {- return {IpAddressV4::from_string("224.76.78.75"), 20808};+ return {makeAddress("224.76.78.75"), 20808}; } inline UdpEndpoint multicastEndpointV6(uint64_t scopeId) { // This is a non-permanently-assigned link-local multicast address (RFC4291)- return {- ::LINK_ASIO_NAMESPACE::ip::make_address("ff12::8080%" + std::to_string(scopeId)),- 20808};+ return {makeAddress("ff12::8080%" + std::to_string(scopeId)), 20808}; } // Type tags for dispatching between unicast and multicast packets@@ -72,8 +70,9 @@ } - 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); }@@ -91,10 +90,7 @@ SocketReceiver<MulticastTag, Handler>(std::move(handler))); } - UdpEndpoint endpoint() const- {- return mSendSocket.endpoint();- }+ UdpEndpoint endpoint() const { return mSendSocket.endpoint(); } private: template <typename Tag, typename Handler>@@ -120,8 +116,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,6 +32,8 @@ #include <chrono> #include <cstdint>+#include <iterator>+#include <string> #include <type_traits> #include <utility> #include <vector>@@ -85,7 +87,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);@@ -240,6 +242,25 @@ } }; +// 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) {@@ -274,7 +295,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 matche the size of int64_t.");+ "The size of microseconds::rep must match the size of int64_t."); return toNetworkByteStream(static_cast<int64_t>(micros.count()), std::move(out)); } @@ -291,6 +312,34 @@ } }; +// 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 { @@ -319,9 +368,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;@@ -385,15 +434,17 @@ 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)); } };@@ -438,8 +489,9 @@ 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,10 +200,7 @@ 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)@@ -236,10 +233,7 @@ template <> struct PayloadBuilder<> {- Payload<> operator()()- {- return {};- }+ Payload<> operator()() { return {}; } }; // Parse payloads to values@@ -258,20 +252,17 @@ } 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) {- 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());+ throw range_error("Parsing payload failed"); } 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,10 +57,7 @@ { } - 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>;@@ -69,8 +66,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))@@ -91,10 +88,7 @@ } } - 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)@@ -150,10 +144,13 @@ 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(); }@@ -171,12 +168,14 @@ << mPeerTimeouts.front().second; mPruneTimer.expires_at(t);- mPruneTimer.async_wait([this](const TimerError e) {- if (!e)+ mPruneTimer.async_wait(+ [this](const TimerError e) {- pruneExpiredPeers();- }- });+ if (!e)+ {+ pruneExpiredPeers();+ }+ }); } } @@ -190,8 +189,10 @@ 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;@@ -222,12 +223,13 @@ 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,15 +35,17 @@ { public: using IoType = typename util::Injected<IoContext>::type;- using Gateway = decltype(std::declval<GatewayFactory>()(std::declval<NodeState>(),- std::declval<util::Injected<IoType&>>(),- std::declval<IpAddress>()));+ using FactoryType = typename util::Injected<GatewayFactory>::type;+ using Gateway = std::invoke_result_t<FactoryType,+ NodeState,+ util::Injected<IoType&>,+ const discovery::IpAddress&>; using GatewayMap = std::map<IpAddress, Gateway>; PeerGateways(const std::chrono::seconds rescanPeriod,- NodeState state,- GatewayFactory factory,- util::Injected<IoContext> io)+ NodeState state,+ util::Injected<GatewayFactory> factory,+ util::Injected<IoContext> io) : mIo(std::move(io)) { mpScannerCallback =@@ -67,6 +69,7 @@ void enable(const bool bEnable) { mpScannerCallback->mGateways.clear();+ mpScannerCallback->mFactory->gatewaysChanged(); mpScanner->enable(bEnable); } @@ -91,6 +94,7 @@ { 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();@@ -100,7 +104,7 @@ private: struct Callback {- Callback(NodeState state, GatewayFactory factory, IoType& io)+ Callback(NodeState state, util::Injected<GatewayFactory> factory, IoType& io) : mState(std::move(state)) , mFactory(std::move(factory)) , mIo(io)@@ -114,18 +118,26 @@ // 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)@@ -139,7 +151,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) {@@ -147,10 +159,15 @@ << " reason: " << e.what(); } }++ if (!staleAddrs.empty() || !newAddrs.empty())+ {+ mFactory->gatewaysChanged();+ } } NodeState mState;- GatewayFactory mFactory;+ util::Injected<GatewayFactory> mFactory; IoType& mIo; GatewayMap mGateways; };@@ -166,13 +183,12 @@ std::unique_ptr<PeerGateways<NodeState, GatewayFactory, IoContext>> makePeerGateways( const std::chrono::seconds rescanPeriod, NodeState state,- GatewayFactory factory,+ util::Injected<GatewayFactory> factory, util::Injected<IoContext> io) {- using namespace std; using Gateways = PeerGateways<NodeState, GatewayFactory, IoContext>;- return unique_ptr<Gateways>{- new Gateways{rescanPeriod, std::move(state), std::move(factory), std::move(io)}};+ return std::make_unique<Gateways>(+ rescanPeriod, std::move(state), std::move(factory), std::move(io)); } } // namespace discovery
link/include/ableton/discovery/Service.hpp view
@@ -32,7 +32,9 @@ public: using ServicePeerGateways = PeerGateways<NodeState, GatewayFactory, IoContext>; - Service(NodeState state, GatewayFactory factory, util::Injected<IoContext> io)+ Service(NodeState state,+ util::Injected<GatewayFactory> factory,+ util::Injected<IoContext> io) : mEnabled(false) , mGateways( std::chrono::seconds(5), std::move(state), std::move(factory), std::move(io))@@ -45,10 +47,7 @@ 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.@@ -58,10 +57,7 @@ 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,18 +130,12 @@ } } - 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@@ -157,10 +151,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))@@ -176,8 +170,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)); }; }@@ -186,20 +180,26 @@ { 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,12 +218,14 @@ // 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)+ mTimer.async_wait(+ [this](const TimerError e) {- broadcastState();- }- });+ if (!e)+ {+ broadcastState();+ }+ }); // If we're not delaying, broadcast now if (delay < milliseconds{1})@@ -235,7 +237,8 @@ } if (mInterface->endpoint().address().is_v6()) {- sendPeerState(v1::kAlive,+ sendPeerState(+ v1::kAlive, multicastEndpointV6(mInterface->endpoint().address().to_v6().scope_id())); } }@@ -243,9 +246,16 @@ void sendPeerState(const v1::MessageType messageType, const UdpEndpoint& to) {- sendUdpMessage(- *mInterface, mState.ident(), mTtl, messageType, toPayload(mState), to);- mLastBroadcastTime = mTimer.now();+ 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();+ } } void sendResponse(const UdpEndpoint& to)@@ -261,8 +271,10 @@ } 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); @@ -270,50 +282,33 @@ // Ignore messages from self and other groups if (header.ident != mState.ident() && header.groupId == 0) {- // 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);- }+ debug(mIo->log()) << "Received message type "+ << static_cast<int>(header.messageType) << " from peer "+ << header.ident; - if (!ignoreIpV4Message)+ switch (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;- }+ 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 view
@@ -0,0 +1,99 @@+/* 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,7 +19,11 @@ #pragma once +#include <ableton/discovery/AsioTypes.hpp> #include <ableton/util/Log.hpp>+#include <functional>+#include <utility>+#include <vector> namespace ableton {@@ -38,8 +42,9 @@ { } - 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));@@ -49,11 +54,17 @@ 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));- };+ 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)); };+ }+ template <typename It> void incomingMessage(const UdpEndpoint& from, It messageBegin, It messageEnd) {@@ -61,10 +72,7 @@ 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,10 +122,7 @@ 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,16 +33,13 @@ 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));@@ -52,9 +49,8 @@ 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>@@ -64,10 +60,7 @@ 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,9 +61,12 @@ 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))))); } @@ -97,10 +100,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)};@@ -110,8 +113,9 @@ 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 view
@@ -0,0 +1,46 @@+/* 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,25 +42,13 @@ { } - 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,7 +33,8 @@ 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@@ -42,9 +43,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.@@ -63,9 +64,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.@@ -94,7 +95,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,7 +28,9 @@ #include <ableton/link/SessionState.hpp> #include <ableton/link/Sessions.hpp> #include <ableton/link/StartStopState.hpp>-#include <ableton/link/TripleBuffer.hpp>+#include <ableton/util/TripleBuffer.hpp>++#include <chrono> #include <condition_variable> #include <mutex> @@ -52,22 +54,27 @@ { 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)+inline ClientState initClientState(const SessionState& sessionState, SessionId sessionId) { 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.startStopState, microseconds{0}, microseconds{0}};+ return {clientState.timeline,+ clientState.timelineSessionId,+ clientState.startStopState,+ microseconds{0},+ microseconds{0}}; } // The timespan in which local modifications to the timeline will be@@ -116,50 +123,55 @@ // The main Link controller template <typename PeerCountCallback,- typename TempoCallback,- typename StartStopStateCallback,- typename Clock,- typename Random,- typename IoContext>+ typename TempoCallback,+ typename StartStopStateCallback,+ typename Clock,+ typename Random,+ typename IoContext,+ typename SessionController> 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))+ , mClientState(detail::initClientState(mSessionState, mSessionId)) , 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),- std::ref(mSessionPeerCounter),- SessionTimelineCallback{*this},- SessionStartStopStateCallback{*this})+ SessionMembershipCallback{this},+ SessionTimelineCallback{*this},+ SessionStartStopStateCallback{*this},+ SawAudioEndpointCallback{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),- GatewayFactory{*this},+ , mDiscovery(+ std::make_pair(+ NodeState{+ mNodeId, mSessionId, mSessionState.timeline, mSessionState.startStopState},+ mSessionState.ghostXForm),+ util::injectVal(GatewayFactory{this}), util::injectRef(*mIo))+ , mRtClientStateSetter(*this) { } @@ -169,26 +181,6 @@ 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);@@ -198,51 +190,38 @@ } } - 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) {- if (newClientState.timeline)- {- *newClientState.timeline = clampTempo(*newClientState.timeline);- clientState.timeline = *newClientState.timeline;- }- if (newClientState.startStopState)+ mClientState.update(+ [&](ClientState& clientState) {- // Prevent updating client start stop state with an outdated start stop state- *newClientState.startStopState = detail::selectPreferredStartStopState(- clientState.startStopState, *newClientState.startStopState);- clientState.startStopState = *newClientState.startStopState;- }- });+ 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;+ }+ }); mIo->async([this, newClientState] { handleClientState(newClientState); }); } @@ -267,20 +246,22 @@ { const auto clientState = mClientState.getRt(); - if (timelineGracePeriodOver && clientState.timeline != mRtClientState.timeline)+ if (timelineGracePeriodOver) { mRtClientState.timeline = clientState.timeline;+ mRtClientState.timelineSessionId = clientState.timelineSessionId; } - if (startStopStateGracePeriodOver- && clientState.startStopState != mRtClientState.startStopState)+ if (startStopStateGracePeriodOver) { mRtClientState.startStopState = clientState.startStopState; } } } - return {mRtClientState.timeline, mRtClientState.startStopState};+ return {mRtClientState.timeline,+ mRtClientState.timelineSessionId,+ mRtClientState.startStopState}; } // should only be called from the audio thread@@ -322,7 +303,7 @@ } } -private:+protected: std::chrono::microseconds makeRtTimestamp(const std::chrono::microseconds now) const { return isEnabled() ? now : std::chrono::microseconds(0);@@ -332,11 +313,13 @@ { 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) {@@ -347,10 +330,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)@@ -370,19 +353,26 @@ } // Update the client timeline and start stop state based on the new session timing- 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{})+ mClientState.update(+ [&](ClientState& clientState) {- std::lock_guard<std::mutex> startStopStateLock(mSessionStateGuard);- clientState.startStopState =- detail::mapStartStopStateFromSessionToClient(mSessionState.startStopState,- mSessionState.timeline, mSessionState.ghostXForm);- }- });+ 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);+ }+ }); if (oldTimeline.tempo != newTimeline.tempo) {@@ -396,14 +386,11 @@ debug(mIo->log()) << "Received timeline with tempo: " << timeline.tempo.bpm() << " for session: " << id; updateSessionTiming(mSessions.sawSessionTimeline(std::move(id), std::move(timeline)),- mSessionState.ghostXForm);- updateDiscovery();+ mSessionState.ghostXForm);+ mpSessionController->updateDiscoveryCallback(); } - void resetSessionStartStopState()- {- mSessionState.startStopState = StartStopState{};- }+ void resetSessionStartStopState() { mSessionState.startStopState = StartStopState{}; } void handleStartStopStateFromSession(SessionId sessionId, StartStopState startStopState) {@@ -419,14 +406,16 @@ // Always propagate the session start stop state so even a client that doesn't have // the feature enabled can function as a relay.- updateDiscovery();+ mpSessionController->updateDiscoveryCallback(); 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(); } }@@ -438,8 +427,11 @@ 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);@@ -455,12 +447,15 @@ 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; }@@ -468,7 +463,7 @@ if (mustUpdateDiscovery) {- updateDiscovery();+ mpSessionController->updateDiscoveryCallback(); } invokeStartStopStateCallbackIfChanged();@@ -476,19 +471,21 @@ void handleRtClientState(IncomingClientState clientState) {- mClientState.update([&](ClientState& currentClientState) {- if (clientState.timeline)- {- currentClientState.timeline = *clientState.timeline;- }- if (clientState.startStopState)+ mClientState.update(+ [&](ClientState& currentClientState) {- // Prevent updating client start stop state with an outdated start stop state- *clientState.startStopState = detail::selectPreferredStartStopState(- currentClientState.startStopState, *clientState.startStopState);- currentClientState.startStopState = *clientState.startStopState;- }- });+ 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;+ }+ }); handleClientState(clientState); mHasPendingRtClientStates = false;@@ -507,13 +504,13 @@ } updateSessionTiming(session.timeline, session.measurement.xform);- updateDiscovery();+ mpSessionController->updateDiscoveryCallback(); if (sessionIdChanged) { debug(mIo->log()) << "Joining session " << session.sessionId << " with tempo " << session.timeline.tempo.bpm();- mSessionPeerCounter();+ mpSessionController->sessionMembershipCallback(); } } @@ -528,14 +525,15 @@ // 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);- updateDiscovery();+ mpSessionController->updateDiscoveryCallback(); mSessions.resetSession({mNodeId, newTl, {xform, hostTime}}); mPeers.resetPeers();@@ -555,28 +553,26 @@ { 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]() {- // 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();- });+ [this]+ {+ mController.mIo->async(+ [this]() { mController.mpSessionController->updateRtStatesCallback(); }); }, detail::kRtHandlerFallbackPeriod) { } - void invoke()- {- mCallbackDispatcher.invoke();- }+ void start() { mCallbackDispatcher.start(); } + void stop() { mCallbackDispatcher.stop(); }++ void invoke() { mCallbackDispatcher.invoke(); }+ void push(const IncomingClientState clientState) { if (clientState.timeline)@@ -635,8 +631,8 @@ Controller& mController; // Use separate TripleBuffers for the Timeline and the StartStopState so we read the // latest set value from either optional.- TripleBuffer<std::pair<std::chrono::microseconds, Timeline>> mTimelineBuffer;- TripleBuffer<ClientStartStopState> mStartStopStateBuffer;+ util::TripleBuffer<std::pair<std::chrono::microseconds, Timeline>> mTimelineBuffer;+ util::TripleBuffer<ClientStartStopState> mStartStopStateBuffer; CallbackDispatcher mCallbackDispatcher; }; @@ -650,6 +646,26 @@ 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)@@ -686,12 +702,22 @@ template <typename Peer, typename Handler> void operator()(Peer peer, Handler handler) {- 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) {+ 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)+ { const auto addr = peer.second;- const auto it = std::find_if(- begin, end, [&addr](const ValueType& vt) { return vt.first == addr; });+ const auto it =+ std::find_if(begin, end, [&addr](const auto& vt) { return vt.first == addr; }); if (it != end) { it->second->measurePeer(std::move(peer.first), std::move(handler));@@ -703,27 +729,54 @@ handler(GhostXForm{}); } });- }-- Controller& mController;- };+ } struct JoinSessionCallback { void operator()(Session session) {- mController.joinSession(std::move(session));+ mpController->mpSessionController->joinSessionCallback(std::move(session)); } - Controller& mController;+ Controller* mpController; }; + void shutdown()+ {+ if (mIoStopped)+ {+ return;+ }++ 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();+ }+ using IoType = typename util::Injected<IoContext>::type; using ControllerPeers = Peers<IoType&,- std::reference_wrapper<SessionPeerCounter>,- SessionTimelineCallback,- SessionStartStopStateCallback>;+ SessionMembershipCallback,+ SessionTimelineCallback,+ SessionStartStopStateCallback,+ SawAudioEndpointCallback>; using ControllerGateway = Gateway<typename ControllerPeers::GatewayObserver, Clock, IoType&>;@@ -732,15 +785,24 @@ struct GatewayFactory { GatewayPtr operator()(std::pair<NodeState, GhostXForm> state,- util::Injected<IoType&> io,- const discovery::IpAddress& addr)+ util::Injected<IoType&> io,+ const discovery::IpAddress& addr) {- return GatewayPtr{new ControllerGateway{std::move(io), addr,- util::injectVal(makeGatewayObserver(mController.mPeers, addr)),- std::move(state.first), std::move(state.second), mController.mClock}};+ return GatewayPtr{new ControllerGateway{+ std::move(io),+ addr,+ util::injectVal(makeGatewayObserver(mpController->mPeers, addr)),+ std::move(state.first),+ std::move(state.second),+ mpController->mClock}}; } - Controller& mController;+ void gatewaysChanged()+ {+ mpController->mpSessionController->gatewaysChangedCallback();+ }++ Controller* mpController; }; struct UdpSendExceptionHandler@@ -749,9 +811,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;@@ -772,6 +834,8 @@ mutable RtClientState mRtClientState; std::atomic<bool> mHasPendingRtClientStates; + SessionController* mpSessionController;+ SessionPeerCounter mSessionPeerCounter; std::atomic<bool> mEnabled;@@ -779,22 +843,23 @@ std::atomic<bool> mStartStopSyncEnabled; util::Injected<IoContext> mIo;-- RtClientStateSetter mRtClientStateSetter;+ std::atomic<bool> mIoStopped{false}; 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>,- GatewayFactory,- typename util::Injected<IoContext>::type&>;+ typename util::Injected<GatewayFactory>::type,+ typename util::Injected<IoContext>::type&>; Discovery mDiscovery;++ RtClientStateSetter mRtClientStateSetter; }; } // namespace link
+ link/include/ableton/link/EndpointV4.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+{++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 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+{++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,6 +23,8 @@ #include <ableton/link/MeasurementService.hpp> #include <ableton/link/PeerState.hpp> +#include <optional>+ namespace ableton { namespace link@@ -33,21 +35,24 @@ { public: Gateway(util::Injected<IoContext> io,- discovery::IpAddress addr,- util::Injected<PeerObserver> observer,- NodeState nodeState,- GhostXForm ghostXForm,- Clock clock)+ discovery::IpAddress addr,+ util::Injected<PeerObserver> observer,+ NodeState nodeState,+ GhostXForm ghostXForm,+ Clock clock,+ std::optional<discovery::UdpEndpoint> audioEndpoint = std::nullopt) : mIo(std::move(io)) , mMeasurement(addr,- nodeState.sessionId,- std::move(ghostXForm),- std::move(clock),- util::injectRef(*mIo))- , mPeerGateway(discovery::makeGateway(util::injectRef(*mIo),+ nodeState.sessionId,+ std::move(ghostXForm),+ std::move(clock),+ util::injectRef(*mIo))+ , moAudioEndpoint(audioEndpoint)+ , mPeerGateway(discovery::makeGateway(+ util::injectRef(*mIo), std::move(addr), std::move(observer),- PeerState{std::move(nodeState), mMeasurement.endpoint()}))+ PeerState{std::move(nodeState), mMeasurement.endpoint(), moAudioEndpoint})) { } @@ -57,6 +62,7 @@ Gateway(Gateway&& rhs) : mIo(std::move(rhs.mIo)) , mMeasurement(std::move(rhs.mMeasurement))+ , moAudioEndpoint(std::move(rhs.moAudioEndpoint)) , mPeerGateway(std::move(rhs.mPeerGateway)) { }@@ -65,6 +71,7 @@ { mIo = std::move(rhs.mIo); mMeasurement = std::move(rhs.mMeasurement);+ moAudioEndpoint = std::move(rhs.moAudioEndpoint); mPeerGateway = std::move(rhs.mPeerGateway); return *this; }@@ -72,9 +79,15 @@ void updateNodeState(std::pair<NodeState, GhostXForm> state) { mMeasurement.updateNodeState(state.first.sessionId, state.second);- mPeerGateway.updateState(PeerState{std::move(state.first), mMeasurement.endpoint()});+ mPeerGateway.updateState(+ PeerState{std::move(state.first), mMeasurement.endpoint(), moAudioEndpoint}); } + void updateAudioEndpoint(std::optional<discovery::UdpEndpoint> audioEndpoint)+ {+ moAudioEndpoint = audioEndpoint;+ }+ template <typename Handler> void measurePeer(const PeerState& peer, Handler handler) {@@ -84,6 +97,7 @@ 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,20 +39,25 @@ { 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)- : mIo(std::move(io))- , mpImpl(std::make_shared<Impl>(- std::move(state), std::move(callback), std::move(address), std::move(clock), mIo))+ 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)) {- mpImpl->listen(); } Measurement(const Measurement&) = delete;@@ -60,36 +65,44 @@ 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)- : mSocket(io->template openUnicastSocket<v1::kMaxMessageSize>(address))+ Callback callback,+ discovery::IpAddress address,+ Clock clock,+ util::Injected<IoContext> io,+ Socket& socket)+ : mIo(std::move(io))+ , mSocket(socket) , mSessionId(state.nodeState.sessionId) , mCallback(std::move(callback)) , mClock(std::move(clock))- , mTimer(io->makeTimer())+ , mTimer(mIo->makeTimer()) , mMeasurementsStarted(0)- , mLog(channel(io->log(), "Measurement on gateway@" + address.to_string()))+ , mLog(channel(mIo->log(), "Measurement on gateway@" + address.to_string())) , mSuccess(false) {- if (state.endpoint.address().is_v4())+ if (state.measurementEndpoint.address().is_v4()) {- mEndpoint = state.endpoint;+ mEndpoint = state.measurementEndpoint; } else {- auto v6Address = state.endpoint.address().to_v6();+ auto v6Address = state.measurementEndpoint.address().to_v6(); v6Address.scope_id(address.to_v6().scope_id());- mEndpoint = {v6Address, state.endpoint.port()};+ mEndpoint = {v6Address, state.measurementEndpoint.port()}; } const auto ht = HostTime{mClock.micros()};@@ -101,33 +114,31 @@ { mTimer.cancel(); mTimer.expires_from_now(std::chrono::milliseconds(50));- mTimer.async_wait([this](const typename Timer::ErrorCode e) {- if (!e)+ mTimer.async_wait(+ [this](const typename Timer::ErrorCode e) {- if (mMeasurementsStarted < kNumberMeasurements)- {- const auto ht = HostTime{mClock.micros()};- sendPing(mEndpoint, discovery::makePayload(ht));- ++mMeasurementsStarted;- resetTimer();- }- else+ if (!e) {- fail();+ if (mMeasurementsStarted < kNumberMeasurements)+ {+ 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);@@ -147,7 +158,8 @@ 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); },@@ -156,7 +168,6 @@ catch (const std::runtime_error& err) { warning(mLog) << "Failed parsing payload, caught exception: " << err.what();- listen(); return; } @@ -168,9 +179,7 @@ discovery::makePayload(HostTime{hostTime}, PrevGHostTime{ghostTime}); sendPing(from, payload);- listen(); - if (ghostTime != Micros{0} && prevHostTime != Micros{0}) { mData.push_back(@@ -202,7 +211,6 @@ else { debug(mLog) << "Received invalid message from " << from;- listen(); } } @@ -230,17 +238,34 @@ mTimer.cancel(); mSuccess = true; debug(mLog) << "Measuring " << mEndpoint << " done.";- mCallback(mData);+ std::weak_ptr<Impl> pHandle = this->shared_from_this();+ mIo->async(+ [pHandle]()+ {+ if (auto pLocked = pHandle.lock())+ {+ pLocked->mCallback(pLocked->mData);+ }+ }); } void fail() {- mData.clear(); debug(mLog) << "Measuring " << mEndpoint << " failed.";- mCallback(mData);+ std::weak_ptr<Impl> pHandle = this->shared_from_this();+ mIo->async(+ [pHandle]()+ {+ if (auto pLocked = pHandle.lock())+ {+ pLocked->mData.clear();+ pLocked->mCallback(pLocked->mData);+ }+ }); } - Socket mSocket;+ util::Injected<IoContext> mIo;+ Socket& mSocket; SessionId mSessionId; discovery::UdpEndpoint mEndpoint; std::vector<double> mData;@@ -252,7 +277,6 @@ bool mSuccess; }; - util::Injected<IoContext> mIo; std::shared_ptr<Impl> mpImpl; };
− link/include/ableton/link/MeasurementEndpointV4.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-{--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
@@ -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-{--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,22 +39,19 @@ class MeasurementService { public:- using IoType = util::Injected<IoContext>;- using MeasurementInstance = Measurement<Clock, IoContext>;+ using IoType = typename util::Injected<IoContext>::type;+ using MeasurementInstance = Measurement<Clock, IoType&>; MeasurementService(discovery::IpAddress address,- SessionId sessionId,- GhostXForm ghostXForm,- Clock clock,- IoType io)+ SessionId sessionId,+ GhostXForm ghostXForm,+ Clock clock,+ util::Injected<IoContext> io) : mClock(std::move(clock))- , mIo(std::move(io))- , mPingResponder(std::move(address),- std::move(sessionId),- std::move(ghostXForm),- mClock,- util::injectRef(*mIo))+ , mpImpl(std::make_shared<Impl>(+ address, std::move(sessionId), std::move(ghostXForm), mClock, std::move(io))) {+ mpImpl->listen(); } MeasurementService(const MeasurementService&) = delete;@@ -62,13 +59,10 @@ void updateNodeState(const SessionId& sessionId, const GhostXForm& xform) {- mPingResponder.updateNodeState(sessionId, xform);+ mpImpl->updateNodeState(sessionId, xform); } - discovery::UdpEndpoint endpoint() const- {- return mPingResponder.endpoint();- }+ discovery::UdpEndpoint endpoint() const { return mpImpl->socket().endpoint(); } // Measure the peer and invoke the handler with a GhostXForm template <typename Handler>@@ -77,28 +71,83 @@ using namespace std; const auto nodeId = state.nodeState.nodeId;- auto addr = mPingResponder.endpoint().address();- auto callback = CompletionCallback<Handler>{*this, nodeId, handler};+ auto addr = mpImpl->socket().endpoint().address();+ auto callback = CompletionCallback<Handler>{mpImpl, nodeId, handler}; try {- mMeasurementMap[nodeId] =- std::unique_ptr<MeasurementInstance>(new MeasurementInstance{- state, std::move(callback), std::move(addr), mClock, mIo});+ mpImpl->mMeasurementMap[nodeId] =+ std::make_unique<MeasurementInstance>(state,+ std::move(callback),+ std::move(addr),+ mClock,+ util::injectRef(*(mpImpl->mIo)),+ mpImpl->socket()); } catch (const runtime_error& err) {- info(mIo->log()) << "gateway@" + addr.to_string()- << " Failed to measure. Reason: " << err.what();+ info(mpImpl->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;@@ -109,7 +158,7 @@ // gone by the time the block gets executed. auto nodeId = mNodeId; auto handler = mHandler;- auto& measurementMap = mMeasurementService.mMeasurementMap;+ auto& measurementMap = mpImpl->mMeasurementMap; const auto it = measurementMap.find(nodeId); if (it != measurementMap.end()) {@@ -125,7 +174,7 @@ } } - MeasurementService& mMeasurementService;+ std::shared_ptr<Impl> mpImpl; NodeId mNodeId; Handler mHandler; };@@ -133,11 +182,9 @@ // 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;- IoType mIo;- PingResponder<Clock, IoContext> mPingResponder;+ std::shared_ptr<Impl> mpImpl; }; } // namespace link
link/include/ableton/link/NodeId.hpp view
@@ -23,6 +23,7 @@ #include <algorithm> #include <array> #include <cstdint>+#include <iomanip> #include <string> namespace ableton@@ -55,7 +56,18 @@ friend std::ostream& operator<<(std::ostream& stream, const NodeId& id) {- return stream << std::string{id.cbegin(), id.cend()};+ 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; } template <typename It>
link/include/ableton/link/NodeState.hpp view
@@ -35,10 +35,7 @@ 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) {@@ -57,13 +54,14 @@ { 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
@@ -1,97 +0,0 @@-/* 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,10 +20,12 @@ #pragma once #include <ableton/discovery/Payload.hpp>-#include <ableton/link/MeasurementEndpointV4.hpp>-#include <ableton/link/MeasurementEndpointV6.hpp>+#include <ableton/link/EndpointV4.hpp>+#include <ableton/link/EndpointV6.hpp> #include <ableton/link/NodeState.hpp> +#include <optional>+ namespace ableton { namespace link@@ -35,61 +37,96 @@ 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.endpoint == rhs.endpoint;+ return lhs.nodeState == rhs.nodeState+ && lhs.measurementEndpoint == rhs.measurementEndpoint+ && lhs.audioEndpoint == rhs.audioEndpoint; } - friend auto toPayload(const PeerState& state) -> decltype(- std::declval<NodeState::Payload>() + discovery::makePayload(MeasurementEndpointV4{{}})- + discovery::makePayload(MeasurementEndpointV6{{}}))+ friend auto toPayload(const PeerState& state)+ -> decltype(std::declval<NodeState::Payload>()+ + discovery::makePayload(MeasurementEndpointV4{{}})+ + discovery::makePayload(MeasurementEndpointV6{{}})+ + discovery::makePayload(AudioEndpointV4{{}})+ + discovery::makePayload(AudioEndpointV6{{}})) { // 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.endpoint})- + discovery::makePayload(MeasurementEndpointV6{state.endpoint});+ + 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"), {}}++ }); } 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>(- std::move(begin), std::move(end),- [&peerState](MeasurementEndpointV4 me4) { peerState.endpoint = std::move(me4.ep); },- [&peerState](- MeasurementEndpointV6 me6) { peerState.endpoint = std::move(me6.ep); });+ 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));+ }); return peerState; } NodeState nodeState;- discovery::UdpEndpoint endpoint;+ discovery::UdpEndpoint measurementEndpoint;+ std::optional<discovery::UdpEndpoint> audioEndpoint; }; } // namespace link
link/include/ableton/link/Peers.hpp view
@@ -38,9 +38,10 @@ // whenever a new combination of these values is seen template <typename IoContext,- typename SessionMembershipCallback,- typename SessionTimelineCallback,- typename SessionStartStopStateCallback>+ typename SessionMembershipCallback,+ typename SessionTimelineCallback,+ typename SessionStartStopStateCallback,+ typename AudioEndpointCallback> class Peers { // non-movable private implementation type@@ -50,11 +51,15 @@ using Peer = std::pair<PeerState, discovery::IpAddress>; Peers(util::Injected<IoContext> io,- SessionMembershipCallback membership,- SessionTimelineCallback timeline,- SessionStartStopStateCallback startStop)- : mpImpl(std::make_shared<Impl>(- std::move(io), std::move(membership), std::move(timeline), std::move(startStop)))+ 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))) { } @@ -75,8 +80,10 @@ { 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)); } @@ -106,10 +113,7 @@ 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.@@ -147,21 +151,21 @@ auto pImpl = observer.mpImpl; auto addr = observer.mAddr; assert(pImpl);- pImpl->sawPeerOnGateway(std::move(state), std::move(addr));+ pImpl->sawPeerOnGateway(state, std::move(addr)); } friend void peerLeft(GatewayObserver& observer, const NodeId& id) { auto pImpl = observer.mpImpl; auto addr = observer.mAddr;- pImpl->peerLeftGateway(std::move(id), std::move(addr));+ pImpl->peerLeftGateway(id, std::move(addr)); } friend void peerTimedOut(GatewayObserver& observer, const NodeId& id) { auto pImpl = observer.mpImpl; auto addr = observer.mAddr;- pImpl->peerLeftGateway(std::move(id), std::move(addr));+ pImpl->peerLeftGateway(id, std::move(addr)); } std::shared_ptr<Impl> mpImpl;@@ -178,13 +182,15 @@ struct Impl { Impl(util::Injected<IoContext> io,- SessionMembershipCallback membership,- SessionTimelineCallback timeline,- SessionStartStopStateCallback startStop)+ SessionMembershipCallback membership,+ SessionTimelineCallback timeline,+ SessionStartStopStateCallback startStop,+ AudioEndpointCallback audioEndpointCallback) : mIo(std::move(io)) , mSessionMembershipCallback(std::move(membership)) , mSessionTimelineCallback(std::move(timeline)) , mSessionStartStopStateCallback(std::move(startStop))+ , mAudioEndpointCallback(std::move(audioEndpointCallback)) { } @@ -200,7 +206,7 @@ bool isNewSessionStartStopState = !sessionStartStopStateExists(peerSession, peerStartStopState); - auto peer = make_pair(std::move(peerState), std::move(gatewayAddr));+ auto peer = make_pair(peerState, gatewayAddr); const auto idRange = equal_range(begin(mPeers), end(mPeers), peer, PeerIdComp{}); bool didSessionMembershipChange = false;@@ -214,9 +220,10 @@ { // 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 =@@ -253,15 +260,19 @@ { 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))@@ -280,10 +291,11 @@ { 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(); }@@ -292,23 +304,27 @@ 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@@ -331,15 +347,13 @@ 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; };@@ -348,20 +362,26 @@ }; template <typename Io,- typename SessionMembershipCallback,- typename SessionTimelineCallback,- typename SessionStartStopStateCallback>+ typename SessionMembershipCallback,+ typename SessionTimelineCallback,+ typename SessionStartStopStateCallback,+ typename AudioEndpointCallback> Peers<Io,- SessionMembershipCallback,- SessionTimelineCallback,- SessionStartStopStateCallback>+ SessionMembershipCallback,+ SessionTimelineCallback,+ SessionStartStopStateCallback,+ AudioEndpointCallback> makePeers(util::Injected<Io> io,- SessionMembershipCallback membershipCallback,- SessionTimelineCallback timelineCallback,- SessionStartStopStateCallback startStopStateCallback)+ SessionMembershipCallback membershipCallback,+ SessionTimelineCallback timelineCallback,+ SessionStartStopStateCallback startStopStateCallback,+ AudioEndpointCallback audioEndpointCallback) {- return {std::move(io), std::move(membershipCallback), std::move(timelineCallback),- std::move(startStopStateCallback)};+ return {std::move(io),+ std::move(membershipCallback),+ std::move(timelineCallback),+ std::move(startStopStateCallback),+ std::move(audioEndpointCallback)}; } } // namespace link
link/include/ableton/link/Phase.hpp view
@@ -73,8 +73,9 @@ // 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);@@ -83,8 +84,9 @@ // 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,23 +36,21 @@ template <typename Clock, typename IoContext> class PingResponder {- using IoType = util::Injected<IoContext&>;- using Socket = typename IoType::type::template Socket<v1::kMaxMessageSize>;+ using IoType = typename util::Injected<IoContext>::type;+ using Socket = typename IoType::template Socket<v1::kMaxMessageSize>; public:- 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)))+ 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))) {- mpImpl->listen(); } PingResponder(const PingResponder&) = delete;@@ -64,42 +62,36 @@ mpImpl->mGhostXForm = std::move(xform); } - discovery::UdpEndpoint endpoint() const- {- return mpImpl->mSocket.endpoint();- }+ discovery::UdpEndpoint endpoint() const { return mpImpl->mSocket.endpoint(); } - discovery::IpAddress address() const- {- return endpoint().address();- }+ discovery::IpAddress address() const { return endpoint().address(); } - Socket socket() const+ Socket socket() const { return mpImpl->mSocket; }++ template <typename It>+ void operator()(const discovery::UdpEndpoint& from,+ const It messageBegin,+ const It messageEnd) {- return mpImpl->mSocket;+ (*mpImpl)(from, messageBegin, messageEnd); } private: struct Impl : std::enable_shared_from_this<Impl> {- Impl(discovery::IpAddress address,- SessionId sessionId,- GhostXForm ghostXForm,- Clock clock,- IoType io)+ Impl(Socket& socket,+ SessionId sessionId,+ GhostXForm ghostXForm,+ Clock clock,+ util::Injected<IoContext> io) : mSessionId(std::move(sessionId)) , mGhostXForm(std::move(ghostXForm)) , mClock(std::move(clock))- , mLog(channel(io->log(), "gateway@" + address.to_string()))- , mSocket(io->template openUnicastSocket<v1::kMaxMessageSize>(address))+ , mLog(channel(io->log(), "gateway@" + socket.endpoint().address().to_string()))+ , mSocket(socket) { } - 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)@@ -132,7 +124,6 @@ { info(mLog) << " Received invalid Message from " << from << "."; }- listen(); } template <typename It>@@ -159,11 +150,10 @@ SessionId mSessionId; GhostXForm mGhostXForm; Clock mClock;- typename IoType::type::Log mLog;- Socket mSocket;+ typename IoType::Log mLog;+ Socket& mSocket; }; - IoType mIo; std::shared_ptr<Impl> mpImpl; };
+ link/include/ableton/link/SessionController.hpp view
@@ -0,0 +1,106 @@+/* 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,20 +19,21 @@ #pragma once -#include <ableton/link/Optional.hpp>+#include <ableton/link/SessionId.hpp> #include <ableton/link/StartStopState.hpp> #include <ableton/link/Timeline.hpp>-#include <ableton/link/TripleBuffer.hpp>+#include <ableton/util/TripleBuffer.hpp> #include <mutex>+#include <optional> namespace ableton { namespace link { -using OptionalTimeline = Optional<Timeline>;-using OptionalStartStopState = Optional<StartStopState>;-using OptionalClientStartStopState = Optional<ClientStartStopState>;+using OptionalTimeline = std::optional<Timeline>;+using OptionalStartStopState = std::optional<StartStopState>;+using OptionalClientStartStopState = std::optional<ClientStartStopState>; struct SessionState {@@ -55,6 +56,7 @@ } Timeline timeline;+ SessionId timelineSessionId; ClientStartStopState startStopState; }; @@ -80,20 +82,18 @@ return mState; } - ClientState getRt() const- {- return mRtState.read();- }+ ClientState getRt() const { return mRtState.read(); } private: mutable std::mutex mMutex; ClientState mState;- mutable TripleBuffer<ClientState> mRtState;+ mutable util::TripleBuffer<ClientState> mRtState; }; struct RtClientState { Timeline timeline;+ SessionId timelineSessionId; ClientStartStopState startStopState; std::chrono::microseconds timelineTimestamp; std::chrono::microseconds startStopStateTimestamp;@@ -108,9 +108,33 @@ 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,10 +73,7 @@ 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.@@ -117,8 +114,10 @@ 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;@@ -161,7 +160,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;@@ -185,13 +184,15 @@ { // 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) {- if (!e)+ mTimer.async_wait(+ [this](const typename Timer::ErrorCode e) {- launchSessionMeasurement(mCurrent);- scheduleRemeasurement();- }- });+ if (!e)+ {+ launchSessionMeasurement(mCurrent);+ scheduleRemeasurement();+ }+ }); } void handleFailedMeasurement(const SessionId& id)@@ -280,10 +281,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,@@ -293,8 +294,12 @@ 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,8 +42,9 @@ 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)@@ -101,8 +102,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,10 +42,7 @@ { } - double bpm() const- {- return mValue;- }+ double bpm() const { return mValue; } std::chrono::microseconds microsPerBeat() const {@@ -55,8 +52,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
@@ -1,121 +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 <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,8 +87,9 @@ 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 {@@ -125,7 +126,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 view
@@ -0,0 +1,56 @@+/* 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 view
@@ -0,0 +1,245 @@+/* 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 view
@@ -0,0 +1,50 @@+/* 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 view
@@ -0,0 +1,67 @@+/* 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 view
@@ -0,0 +1,180 @@+/* 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 view
@@ -0,0 +1,63 @@+/* 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 view
@@ -0,0 +1,92 @@+/* 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 view
@@ -0,0 +1,594 @@+/* 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 view
@@ -0,0 +1,388 @@+/* 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 view
@@ -0,0 +1,69 @@+/* 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 view
@@ -0,0 +1,32 @@+/* 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 view
@@ -0,0 +1,242 @@+/* 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 view
@@ -0,0 +1,82 @@+#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 view
@@ -0,0 +1,116 @@+/* 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 view
@@ -0,0 +1,78 @@+/* 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 view
@@ -0,0 +1,154 @@+/* 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 view
@@ -0,0 +1,75 @@+/* 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 view
@@ -0,0 +1,217 @@+/* 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 view
@@ -0,0 +1,172 @@+/* 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 view
@@ -0,0 +1,147 @@+/* 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 view
@@ -0,0 +1,125 @@+/* 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 view
@@ -0,0 +1,144 @@+/* 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 view
@@ -0,0 +1,146 @@+/* 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 view
@@ -0,0 +1,67 @@+/* 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 view
@@ -0,0 +1,159 @@+/* 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 view
@@ -0,0 +1,617 @@+/* 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 view
@@ -0,0 +1,170 @@+/* 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,6 +20,7 @@ #pragma once #include <ableton/link/Controller.hpp>+#include <ableton/link/SessionController.hpp> #include <ableton/util/Log.hpp> #if defined(LINK_PLATFORM_WINDOWS)@@ -27,9 +28,7 @@ #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>@@ -47,6 +46,7 @@ #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,31 +61,36 @@ #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_service;+ using IoService = ::LINK_ASIO_NAMESPACE::io_context; using SystemTimer = ::LINK_ASIO_NAMESPACE::system_timer; @@ -82,15 +82,18 @@ template <typename T> void expires_from_now(T duration) {- mpTimer->expires_from_now(std::move(duration));+ mpTimer->expires_after(std::move(duration)); } - ErrorCode cancel()+ void cancel() {- ErrorCode ec;- mpTimer->cancel(ec);- mpAsyncHandler->mpHandler = nullptr;- return ec;+ try+ {+ mpTimer->cancel();+ }+ catch (...)+ {+ } } template <typename Handler>@@ -100,10 +103,7 @@ 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_28_0-#define LINK_ASIO_NAMESPACE link_asio_1_28_0+#define asio link_asio_1_36_0+#define LINK_ASIO_NAMESPACE link_asio_1_36_0 #define ASIO_STANDALONE 1 #endif
link/include/ableton/platforms/asio/Context.hpp view
@@ -23,9 +23,15 @@ #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@@ -59,8 +65,8 @@ template <std::size_t BufferSize> using Socket = Socket<BufferSize>;- using IoService = ::LINK_ASIO_NAMESPACE::io_service;- using Work = IoService::work;+ using IoService = ::LINK_ASIO_NAMESPACE::io_context;+ using Work = ::LINK_ASIO_NAMESPACE::executor_work_guard<IoService::executor_type>; Context() : Context(DefaultHandler{})@@ -70,10 +76,12 @@ template <typename ExceptionHandler> explicit Context(ExceptionHandler exceptHandler) : mpService(new IoService())- , mpWork(new Work(*mpService))+ , mpWork(new Work(mpService->get_executor())) {- mThread = ThreadFactoryT::makeThread("Link Main",- [](IoService& service, ExceptionHandler handler) {+ mThread = ThreadFactoryT::makeThread(+ "Link Main",+ [](IoService& service, ExceptionHandler handler)+ { for (;;) { try@@ -87,7 +95,8 @@ } } },- std::ref(*mpService), std::move(exceptHandler));+ std::ref(*mpService),+ std::move(exceptHandler)); } Context(const Context&) = delete;@@ -122,19 +131,21 @@ template <std::size_t BufferSize>- Socket<BufferSize> openUnicastSocket(const discovery::IpAddress addr)+ Socket<BufferSize> openUnicastSocket(const discovery::IpAddress addr, uint16_t port = 0) { 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(), 0});+ ::LINK_ASIO_NAMESPACE::ip::udp::endpoint{addr.to_v4(), port}); } else if (addr.is_v6()) {@@ -143,7 +154,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(), 0});+ ::LINK_ASIO_NAMESPACE::ip::udp::endpoint{addr.to_v6(), port}); } else {@@ -168,10 +179,22 @@ 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())); }@@ -194,25 +217,16 @@ 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) {- mpService->post(std::move(handler));+ ::LINK_ASIO_NAMESPACE::post(*mpService, std::move(handler)); } private:@@ -225,13 +239,11 @@ { }; - void operator()(const Exception&)- {- }+ void operator()(const Exception&) {} }; - std::unique_ptr<::LINK_ASIO_NAMESPACE::io_service> mpService;- std::unique_ptr<::LINK_ASIO_NAMESPACE::io_service::work> mpWork;+ std::unique_ptr<IoService> mpService;+ std::unique_ptr<Work> mpWork; std::thread mThread; Log mLog; ScanIpIfAddrs mScanIpIfAddrs;
link/include/ableton/platforms/asio/LockFreeCallbackDispatcher.hpp view
@@ -46,22 +46,33 @@ : mCallback(std::move(callback)) , mFallbackPeriod(std::move(fallbackPeriod)) , mRunning(true)- , mThread(ThreadFactory::makeThread("Link Dispatcher", [this] { run(); })) { } - ~LockFreeCallbackDispatcher()+ ~LockFreeCallbackDispatcher() { stop(); }++ void start() {- mRunning = false;- mCondition.notify_one();- mThread.join();+ mThread = ThreadFactory::makeThread("Link Dispatcher", [this] { run(); }); } - void invoke()+ void stop() {+ 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() {@@ -71,6 +82,12 @@ 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_service& io, ::LINK_ASIO_NAMESPACE::ip::udp protocol)+ Socket(::LINK_ASIO_NAMESPACE::io_context& io, ::LINK_ASIO_NAMESPACE::ip::udp protocol) : mpImpl(std::make_shared<Impl>(io, protocol)) { }@@ -47,10 +47,11 @@ { } - 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); } @@ -60,17 +61,15 @@ 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_service& io, ::LINK_ASIO_NAMESPACE::ip::udp protocol)+ Impl(::LINK_ASIO_NAMESPACE::io_context& io, ::LINK_ASIO_NAMESPACE::ip::udp protocol) : mSocket(io, protocol) { }@@ -84,8 +83,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,15 +55,9 @@ 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,6 +19,9 @@ #pragma once +#include <mach/mach.h>+#include <mach/mach_time.h>+#include <optional> #include <pthread.h> #include <thread> #include <utility>@@ -30,16 +33,98 @@ 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,7 +24,6 @@ #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> @@ -40,6 +39,10 @@ { 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);@@ -47,8 +50,7 @@ { try {- ulTaskNotifyTake(pdTRUE, portMAX_DELAY);- runner->mpService->poll_one();+ runner->mpService->run(); } catch (...) {@@ -56,41 +58,21 @@ } } - 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);-- 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));+ xTaskCreatePinnedToCore(run,+ "link",+ 8192,+ this,+ 2 | portPRIVILEGE_BIT,+ &mTaskHandle,+ LINK_ESP_TASK_CORE_ID); } - ~ServiceRunner()- {- esp_timer_delete(mTimer);- vTaskDelete(mTaskHandle);- }+ ~ServiceRunner() { vTaskDelete(mTaskHandle); } template <typename Handler> void async(Handler handler)@@ -98,14 +80,10 @@ 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; };@@ -138,9 +116,7 @@ { } - void stop()- {- }+ void stop() {} template <std::size_t BufferSize> Socket<BufferSize> openUnicastSocket(const ::asio::ip::address& addr)@@ -212,20 +188,11 @@ 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)@@ -243,9 +210,7 @@ { }; - void operator()(const Exception&)- {- }+ void operator()(const Exception&) {} }; static ServiceRunner& serviceRunner()
link/include/ableton/platforms/esp32/LockFreeCallbackDispatcher.hpp view
@@ -47,12 +47,20 @@ , mFallbackPeriod(std::move(fallbackPeriod)) , mRunning(true) {- xTaskCreate(run, "link", 4096, this, tskIDLE_PRIORITY, &mTaskHandle); } - ~LockFreeCallbackDispatcher()+ ~LockFreeCallbackDispatcher() { stop(); }++ void start() { xTaskCreate(run, "link", 4096, this, tskIDLE_PRIORITY, &mTaskHandle); }++ void stop() {- mRunning = false;+ const auto wasRunning = mRunning.exchange(false);+ if (!wasRunning)+ {+ return;+ }+ mCondition.notify_one(); vTaskDelete(mTaskHandle); }@@ -76,6 +84,12 @@ 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 view
@@ -0,0 +1,138 @@+/* 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,10 +19,17 @@ #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@@ -30,26 +37,36 @@ namespace esp32 { -// ESP32 implementation of ip interface address scanner+// 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. struct ScanIpIfAddrs { std::vector<discovery::IpAddress> operator()() { std::vector<discovery::IpAddress> addrs;- // 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))+ esp_netif_tcpip_exec(+ [](void* ctx) -> esp_err_t {- 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);- }+ 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); return addrs; } };
link/include/ableton/platforms/linux/ThreadFactory.hpp view
@@ -19,8 +19,10 @@ #pragma once +#include <optional> #include <pthread.h> #include <thread>+#include <utility> namespace ableton {@@ -28,6 +30,44 @@ { 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,43 +82,49 @@ std::map<std::string, discovery::IpAddress> IpInterfaceNames; detail::GetIfAddrs getIfAddrs;- getIfAddrs.withIfAddrs([&addrs, &IpInterfaceNames](const struct ifaddrs& interfaces) {- const struct ifaddrs* interface;- for (interface = &interfaces; interface; interface = interface->ifa_next)+ getIfAddrs.withIfAddrs(+ [&addrs, &IpInterfaceNames](const struct ifaddrs& interfaces) {- 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 struct ifaddrs* interface;+ for (interface = &interfaces; interface; interface = interface->ifa_next) {- 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));+ 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));+ } }- }- });+ }); - getIfAddrs.withIfAddrs([&addrs, &IpInterfaceNames](const struct ifaddrs& interfaces) {- const struct ifaddrs* interface;- for (interface = &interfaces; interface; interface = interface->ifa_next)+ // Add IPv6 addresses as backup in case multicast on IPv4 fails+ getIfAddrs.withIfAddrs(+ [&addrs, &IpInterfaceNames](const struct ifaddrs& interfaces) {- 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 struct ifaddrs* interface;+ for (interface = &interfaces; interface; interface = interface->ifa_next) {- 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 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) {- addrs.emplace_back(address);+ 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);+ } } }- }- });+ }); return addrs; };
link/include/ableton/platforms/stl/Random.hpp view
@@ -36,10 +36,7 @@ { } - 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,10 +58,7 @@ 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,10 +54,13 @@ 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) {@@ -106,58 +109,67 @@ std::map<std::string, discovery::IpAddress> IpInterfaceNames; detail::GetIfAddrs getIfAddrs;- getIfAddrs.withIfAddrs([&](const IP_ADAPTER_ADDRESSES& interfaces) {- const IP_ADAPTER_ADDRESSES* networkInterface;- for (networkInterface = &interfaces; networkInterface;- networkInterface = networkInterface->Next)+ getIfAddrs.withIfAddrs(+ [&](const IP_ADAPTER_ADDRESSES& interfaces) {- for (IP_ADAPTER_UNICAST_ADDRESS* address = networkInterface->FirstUnicastAddress;- NULL != address; address = address->Next)+ const IP_ADAPTER_ADDRESSES* networkInterface;+ for (networkInterface = &interfaces; networkInterface;+ networkInterface = networkInterface->Next) {- auto family = address->Address.lpSockaddr->sa_family;- if (AF_INET == family)+ for (IP_ADAPTER_UNICAST_ADDRESS* address =+ networkInterface->FirstUnicastAddress;+ NULL != address;+ address = address->Next) {- // 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));+ 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));+ } } }- }- });+ }); - getIfAddrs.withIfAddrs([&](const IP_ADAPTER_ADDRESSES& interfaces) {- const IP_ADAPTER_ADDRESSES* networkInterface;- for (networkInterface = &interfaces; networkInterface;- networkInterface = networkInterface->Next)+ // Add IPv6 addresses as backup in case multicast on IPv4 fails+ getIfAddrs.withIfAddrs(+ [&](const IP_ADAPTER_ADDRESSES& interfaces) {- for (IP_ADAPTER_UNICAST_ADDRESS* address = networkInterface->FirstUnicastAddress;- NULL != address; address = address->Next)+ const IP_ADAPTER_ADDRESSES* networkInterface;+ for (networkInterface = &interfaces; networkInterface;+ networkInterface = networkInterface->Next) {- auto family = address->Address.lpSockaddr->sa_family;- if (AF_INET6 == family- && IpInterfaceNames.find(networkInterface->AdapterName)- != IpInterfaceNames.end())+ for (IP_ADAPTER_UNICAST_ADDRESS* address =+ networkInterface->FirstUnicastAddress;+ NULL != address;+ address = address->Next) {- 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())+ auto family = address->Address.lpSockaddr->sa_family;+ if (AF_INET6 == family+ && IpInterfaceNames.find(networkInterface->AdapterName)+ != IpInterfaceNames.end()) {- addrs.emplace_back(addr6);+ 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);+ } } } }- }- });+ }); return addrs; }
link/include/ableton/platforms/windows/ThreadFactory.hpp view
@@ -19,6 +19,9 @@ #pragma once +#include <Windows.h>+#include <avrt.h>+#include <optional> #include <processthreadsapi.h> #include <thread> #include <utility>@@ -30,20 +33,54 @@ 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,9 +67,7 @@ { } - void stop()- {- }+ void stop() {} template <typename Handler> void async(Handler handler)@@ -79,22 +77,13 @@ 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,10 +40,7 @@ { } - ~Fixture()- {- flush();- }+ ~Fixture() { flush(); } Fixture(const Fixture&) = delete; Fixture& operator=(const Fixture&) = delete;@@ -55,15 +52,9 @@ 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,10 +93,7 @@ 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 view
@@ -0,0 +1,54 @@+/* 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,25 +55,13 @@ 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; };@@ -110,25 +98,13 @@ 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; };@@ -165,25 +141,13 @@ 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; };@@ -220,25 +184,13 @@ 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 view
@@ -0,0 +1,58 @@+/* 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,30 +20,15 @@ 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@@ -90,25 +75,13 @@ 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 view
@@ -0,0 +1,117 @@+/* 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,10 +41,7 @@ { } - 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)@@ -52,10 +49,7 @@ mpTimer->expires_from_now(duration); } - ErrorCode cancel()- {- return mpTimer->cancel();- }+ ErrorCode cancel() { return mpTimer->cancel(); } template <typename Handler> void async_wait(Handler handler)@@ -63,10 +57,7 @@ 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,10 +70,7 @@ 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -28,7 +28,6 @@ #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"@@ -59,21 +58,27 @@ #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"@@ -81,30 +86,15 @@ #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"@@ -113,14 +103,11 @@ #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"@@ -194,7 +181,6 @@ #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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -75,20 +75,18 @@ #endif // !defined(GENERATING_DOCUMENTATION) /// Default constructor.- ASIO_DECL any_completion_executor() ASIO_NOEXCEPT;+ ASIO_DECL any_completion_executor() noexcept; /// Construct in an empty state. Equivalent effects to default constructor.- ASIO_DECL any_completion_executor(nullptr_t) ASIO_NOEXCEPT;+ ASIO_DECL any_completion_executor(nullptr_t) noexcept; /// Copy constructor. ASIO_DECL any_completion_executor(- const any_completion_executor& e) ASIO_NOEXCEPT;+ const any_completion_executor& e) noexcept; -#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move constructor. ASIO_DECL any_completion_executor(- any_completion_executor&& e) ASIO_NOEXCEPT;-#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)+ any_completion_executor&& e) noexcept; /// Construct to point to the same target as another any_executor. #if defined(GENERATING_DOCUMENTATION)@@ -98,7 +96,7 @@ #else // defined(GENERATING_DOCUMENTATION) template <typename OtherAnyExecutor> any_completion_executor(OtherAnyExecutor e,- typename constraint<+ constraint_t< conditional< !is_same<OtherAnyExecutor, any_completion_executor>::value && is_base_of<execution::detail::any_executor_base,@@ -108,8 +106,8 @@ is_valid_target<OtherAnyExecutor>, false_type >::type::value- >::type = 0)- : base_type(ASIO_MOVE_CAST(OtherAnyExecutor)(e))+ > = 0)+ : base_type(static_cast<OtherAnyExecutor&&>(e)) { } #endif // defined(GENERATING_DOCUMENTATION)@@ -122,7 +120,7 @@ #else // defined(GENERATING_DOCUMENTATION) template <typename OtherAnyExecutor> any_completion_executor(std::nothrow_t, OtherAnyExecutor e,- typename constraint<+ constraint_t< conditional< !is_same<OtherAnyExecutor, any_completion_executor>::value && is_base_of<execution::detail::any_executor_base,@@ -132,21 +130,19 @@ is_valid_target<OtherAnyExecutor>, false_type >::type::value- >::type = 0) ASIO_NOEXCEPT- : base_type(std::nothrow, ASIO_MOVE_CAST(OtherAnyExecutor)(e))+ > = 0) noexcept+ : base_type(std::nothrow, static_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) ASIO_NOEXCEPT;+ const any_completion_executor& e) 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) ASIO_NOEXCEPT;-#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)+ any_completion_executor&& e) noexcept; /// Construct a polymorphic wrapper for the specified executor. #if defined(GENERATING_DOCUMENTATION)@@ -155,7 +151,7 @@ #else // defined(GENERATING_DOCUMENTATION) template <ASIO_EXECUTION_EXECUTOR Executor> any_completion_executor(Executor e,- typename constraint<+ constraint_t< conditional< !is_same<Executor, any_completion_executor>::value && !is_base_of<execution::detail::any_executor_base,@@ -164,8 +160,8 @@ Executor, supportable_properties_type>, false_type >::type::value- >::type = 0)- : base_type(ASIO_MOVE_CAST(Executor)(e))+ > = 0)+ : base_type(static_cast<Executor&&>(e)) { } #endif // defined(GENERATING_DOCUMENTATION)@@ -177,7 +173,7 @@ #else // defined(GENERATING_DOCUMENTATION) template <ASIO_EXECUTION_EXECUTOR Executor> any_completion_executor(std::nothrow_t, Executor e,- typename constraint<+ constraint_t< conditional< !is_same<Executor, any_completion_executor>::value && !is_base_of<execution::detail::any_executor_base,@@ -186,21 +182,19 @@ Executor, supportable_properties_type>, false_type >::type::value- >::type = 0) ASIO_NOEXCEPT- : base_type(std::nothrow, ASIO_MOVE_CAST(Executor)(e))+ > = 0) noexcept+ : base_type(std::nothrow, static_cast<Executor&&>(e)) { } #endif // defined(GENERATING_DOCUMENTATION) /// Assignment operator. ASIO_DECL any_completion_executor& operator=(- const any_completion_executor& e) ASIO_NOEXCEPT;+ const any_completion_executor& e) noexcept; -#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move assignment operator. ASIO_DECL any_completion_executor& operator=(- any_completion_executor&& e) ASIO_NOEXCEPT;-#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)+ any_completion_executor&& e) noexcept; /// Assignment operator that sets the polymorphic wrapper to the empty state. ASIO_DECL any_completion_executor& operator=(nullptr_t);@@ -209,7 +203,7 @@ ASIO_DECL ~any_completion_executor(); /// Swap targets with another polymorphic wrapper.- ASIO_DECL void swap(any_completion_executor& other) ASIO_NOEXCEPT;+ ASIO_DECL void swap(any_completion_executor& other) noexcept; /// Obtain a polymorphic wrapper with the specified property. /**@@ -222,9 +216,9 @@ */ template <typename Property> any_completion_executor require(const Property& p,- typename constraint<+ constraint_t< traits::require_member<const base_type&, const Property&>::is_valid- >::type = 0) const+ > = 0) const { return static_cast<const base_type&>(*this).require(p); }@@ -240,9 +234,9 @@ */ template <typename Property> any_completion_executor prefer(const Property& p,- typename constraint<+ constraint_t< traits::prefer_member<const base_type&, const Property&>::is_valid- >::type = 0) const+ > = 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -12,20 +12,16 @@ #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" @@ -39,11 +35,11 @@ public: template <typename S> explicit any_completion_handler_impl_base(S&& slot)- : cancel_state_(ASIO_MOVE_CAST(S)(slot), enable_total_cancellation())+ : cancel_state_(static_cast<S&&>(slot), enable_total_cancellation()) { } - cancellation_slot get_cancellation_slot() const ASIO_NOEXCEPT+ cancellation_slot get_cancellation_slot() const noexcept { return cancel_state_.slot(); }@@ -59,8 +55,8 @@ public: template <typename S, typename H> any_completion_handler_impl(S&& slot, H&& h)- : any_completion_handler_impl_base(ASIO_MOVE_CAST(S)(slot)),- handler_(ASIO_MOVE_CAST(H)(h))+ : any_completion_handler_impl_base(static_cast<S&&>(slot)),+ handler_(static_cast<H&&>(h)) { } @@ -103,7 +99,7 @@ any_completion_handler_impl* ptr = new (uninit_ptr.get()) any_completion_handler_impl(- ASIO_MOVE_CAST(S)(slot), ASIO_MOVE_CAST(H)(h));+ static_cast<S&&>(slot), static_cast<H&&>(h)); uninit_ptr.release(); return ptr;@@ -119,14 +115,21 @@ } any_completion_executor executor(- const any_completion_executor& candidate) const ASIO_NOEXCEPT+ const any_completion_executor& candidate) const noexcept { return any_completion_executor(std::nothrow, (get_associated_executor)(handler_, candidate)); } - void* allocate(std::size_t size, std::size_t align) const+ 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+ { typename std::allocator_traits< associated_allocator_t<Handler, asio::recycling_allocator<void>>>::template@@ -134,13 +137,13 @@ (get_associated_allocator)(handler_, asio::recycling_allocator<void>())); - std::size_t space = size + align - 1;+ std::size_t space = size + align_size - 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))+ if (detail::align(align_size, size, p, space)) { std::ptrdiff_t off = static_cast<unsigned char*>(p) - base; std::memcpy(static_cast<unsigned char*>(p) + size, &off, sizeof(off));@@ -180,11 +183,11 @@ asio::recycling_allocator<void>())}; std::unique_ptr<any_completion_handler_impl, deleter> ptr(this, d);- Handler handler(ASIO_MOVE_CAST(Handler)(handler_));+ Handler handler(static_cast<Handler&&>(handler_)); ptr.reset(); - ASIO_MOVE_CAST(Handler)(handler)(- ASIO_MOVE_CAST(Args)(args)...);+ static_cast<Handler&&>(handler)(+ static_cast<Args&&>(args)...); } private:@@ -207,14 +210,14 @@ void call(any_completion_handler_impl_base* impl, Args... args) const {- call_fn_(impl, ASIO_MOVE_CAST(Args)(args)...);+ call_fn_(impl, static_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(- ASIO_MOVE_CAST(Args)(args)...);+ static_cast<Args&&>(args)...); } private:@@ -305,6 +308,36 @@ 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:@@ -367,6 +400,7 @@ 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...>@@ -376,11 +410,13 @@ 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...)@@ -389,6 +425,7 @@ 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;@@ -401,6 +438,7 @@ 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>...);@@ -431,7 +469,7 @@ detail::any_completion_handler_impl_base* impl_; constexpr any_completion_handler_allocator(int,- const any_completion_handler<Signatures...>& h) ASIO_NOEXCEPT+ const any_completion_handler<Signatures...>& h) noexcept : fn_table_(h.fn_table_), impl_(h.impl_) {@@ -453,7 +491,7 @@ template <typename U> constexpr any_completion_handler_allocator( const any_completion_handler_allocator<U, Signatures...>& a)- ASIO_NOEXCEPT+ noexcept : fn_table_(a.fn_table_), impl_(a.impl_) {@@ -461,14 +499,14 @@ /// Equality operator. constexpr bool operator==(- const any_completion_handler_allocator& other) const ASIO_NOEXCEPT+ const any_completion_handler_allocator& other) const noexcept { return fn_table_ == other.fn_table_ && impl_ == other.impl_; } /// Inequality operator. constexpr bool operator!=(- const any_completion_handler_allocator& other) const ASIO_NOEXCEPT+ const any_completion_handler_allocator& other) const noexcept { return fn_table_ != other.fn_table_ || impl_ != other.impl_; }@@ -476,9 +514,15 @@ /// Allocate space for @c n objects of the allocator's value type. T* allocate(std::size_t n) const {- return static_cast<T*>(- fn_table_->allocate(- impl_, sizeof(T) * n, alignof(T)));+ 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; } /// Deallocate space for @c n objects of the allocator's value type.@@ -505,7 +549,7 @@ detail::any_completion_handler_impl_base* impl_; constexpr any_completion_handler_allocator(int,- const any_completion_handler<Signatures...>& h) ASIO_NOEXCEPT+ const any_completion_handler<Signatures...>& h) noexcept : fn_table_(h.fn_table_), impl_(h.impl_) {@@ -527,7 +571,7 @@ template <typename U> constexpr any_completion_handler_allocator( const any_completion_handler_allocator<U, Signatures...>& a)- ASIO_NOEXCEPT+ noexcept : fn_table_(a.fn_table_), impl_(a.impl_) {@@ -535,14 +579,14 @@ /// Equality operator. constexpr bool operator==(- const any_completion_handler_allocator& other) const ASIO_NOEXCEPT+ const any_completion_handler_allocator& other) const noexcept { return fn_table_ == other.fn_table_ && impl_ == other.impl_; } /// Inequality operator. constexpr bool operator!=(- const any_completion_handler_allocator& other) const ASIO_NOEXCEPT+ const any_completion_handler_allocator& other) const noexcept { return fn_table_ != other.fn_table_ || impl_ != other.impl_; }@@ -576,6 +620,9 @@ 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)@@ -604,16 +651,16 @@ } /// Construct an @c any_completion_handler to contain the specified target.- template <typename H, typename Handler = typename decay<H>::type>+ template <typename H, typename Handler = decay_t<H>> any_completion_handler(H&& h,- typename constraint<- !is_same<typename decay<H>::type, any_completion_handler>::value- >::type = 0)+ constraint_t<+ !is_same<decay_t<H>, any_completion_handler>::value+ > = 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), ASIO_MOVE_CAST(H)(h)))+ (get_associated_cancellation_slot)(h), static_cast<H&&>(h))) { } @@ -621,7 +668,7 @@ /** * After the operation, the moved-from object @c other has no target. */- any_completion_handler(any_completion_handler&& other) ASIO_NOEXCEPT+ any_completion_handler(any_completion_handler&& other) noexcept : fn_table_(other.fn_table_), impl_(other.impl_) {@@ -634,15 +681,15 @@ * After the operation, the moved-from object @c other has no target. */ any_completion_handler& operator=(- any_completion_handler&& other) ASIO_NOEXCEPT+ any_completion_handler&& other) noexcept { any_completion_handler(- ASIO_MOVE_CAST(any_completion_handler)(other)).swap(*this);+ static_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) ASIO_NOEXCEPT+ any_completion_handler& operator=(nullptr_t) noexcept { any_completion_handler().swap(*this); return *this;@@ -656,34 +703,34 @@ } /// Test if the polymorphic wrapper is empty.- constexpr explicit operator bool() const ASIO_NOEXCEPT+ constexpr explicit operator bool() const noexcept { return impl_ != nullptr; } /// Test if the polymorphic wrapper is non-empty.- constexpr bool operator!() const ASIO_NOEXCEPT+ constexpr bool operator!() const noexcept { return impl_ == nullptr; } /// Swap the content of an @c any_completion_handler with another.- void swap(any_completion_handler& other) ASIO_NOEXCEPT+ void swap(any_completion_handler& other) noexcept { std::swap(fn_table_, other.fn_table_); std::swap(impl_, other.impl_); } /// Get the associated allocator.- allocator_type get_allocator() const ASIO_NOEXCEPT+ allocator_type get_allocator() const noexcept { return allocator_type(0, *this); } /// Get the associated cancellation slot.- cancellation_slot_type get_cancellation_slot() const ASIO_NOEXCEPT+ cancellation_slot_type get_cancellation_slot() const noexcept {- return impl_->get_cancellation_slot();+ return impl_ ? impl_->get_cancellation_slot() : cancellation_slot_type(); } /// Function call operator.@@ -697,12 +744,12 @@ */ template <typename... Args> auto operator()(Args&&... args)- -> decltype(fn_table_->call(impl_, ASIO_MOVE_CAST(Args)(args)...))+ -> decltype(fn_table_->call(impl_, static_cast<Args&&>(args)...)) { if (detail::any_completion_handler_impl_base* impl = impl_) { impl_ = nullptr;- return fn_table_->call(impl, ASIO_MOVE_CAST(Args)(args)...);+ return fn_table_->call(impl, static_cast<Args&&>(args)...); } std::bad_function_call ex; asio::detail::throw_exception(ex);@@ -710,28 +757,28 @@ /// Equality operator. friend constexpr bool operator==(- const any_completion_handler& a, nullptr_t) ASIO_NOEXCEPT+ const any_completion_handler& a, nullptr_t) noexcept { return a.impl_ == nullptr; } /// Equality operator. friend constexpr bool operator==(- nullptr_t, const any_completion_handler& b) ASIO_NOEXCEPT+ nullptr_t, const any_completion_handler& b) noexcept { return nullptr == b.impl_; } /// Inequality operator. friend constexpr bool operator!=(- const any_completion_handler& a, nullptr_t) ASIO_NOEXCEPT+ const any_completion_handler& a, nullptr_t) noexcept { return a.impl_ != nullptr; } /// Inequality operator. friend constexpr bool operator!=(- nullptr_t, const any_completion_handler& b) ASIO_NOEXCEPT+ nullptr_t, const any_completion_handler& b) noexcept { return nullptr != b.impl_; }@@ -743,20 +790,33 @@ using type = any_completion_executor; static type get(const any_completion_handler<Signatures...>& handler,- const Candidate& candidate = Candidate()) ASIO_NOEXCEPT+ const Candidate& candidate = Candidate()) noexcept {- return handler.fn_table_->executor(handler.impl_,- any_completion_executor(std::nothrow, candidate));+ 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+ {+ any_io_executor any_candidate(std::nothrow, candidate);+ return handler.fn_table_+ ? handler.fn_table_->immediate_executor(handler.impl_, any_candidate)+ : any_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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -87,18 +87,16 @@ #endif // !defined(GENERATING_DOCUMENTATION) /// Default constructor.- ASIO_DECL any_io_executor() ASIO_NOEXCEPT;+ ASIO_DECL any_io_executor() noexcept; /// Construct in an empty state. Equivalent effects to default constructor.- ASIO_DECL any_io_executor(nullptr_t) ASIO_NOEXCEPT;+ ASIO_DECL any_io_executor(nullptr_t) noexcept; /// Copy constructor.- ASIO_DECL any_io_executor(const any_io_executor& e) ASIO_NOEXCEPT;+ ASIO_DECL any_io_executor(const any_io_executor& e) noexcept; -#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move constructor.- ASIO_DECL any_io_executor(any_io_executor&& e) ASIO_NOEXCEPT;-#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)+ ASIO_DECL any_io_executor(any_io_executor&& e) noexcept; /// Construct to point to the same target as another any_executor. #if defined(GENERATING_DOCUMENTATION)@@ -107,8 +105,8 @@ #else // defined(GENERATING_DOCUMENTATION) template <typename OtherAnyExecutor> any_io_executor(OtherAnyExecutor e,- typename constraint<- conditional<+ constraint_t<+ conditional_t< !is_same<OtherAnyExecutor, any_io_executor>::value && is_base_of<execution::detail::any_executor_base, OtherAnyExecutor>::value,@@ -116,9 +114,9 @@ 0, supportable_properties_type>::template is_valid_target<OtherAnyExecutor>, false_type- >::type::value- >::type = 0)- : base_type(ASIO_MOVE_CAST(OtherAnyExecutor)(e))+ >::value+ > = 0)+ : base_type(static_cast<OtherAnyExecutor&&>(e)) { } #endif // defined(GENERATING_DOCUMENTATION)@@ -131,8 +129,8 @@ #else // defined(GENERATING_DOCUMENTATION) template <typename OtherAnyExecutor> any_io_executor(std::nothrow_t, OtherAnyExecutor e,- typename constraint<- conditional<+ constraint_t<+ conditional_t< !is_same<OtherAnyExecutor, any_io_executor>::value && is_base_of<execution::detail::any_executor_base, OtherAnyExecutor>::value,@@ -140,22 +138,19 @@ 0, supportable_properties_type>::template is_valid_target<OtherAnyExecutor>, false_type- >::type::value- >::type = 0) ASIO_NOEXCEPT- : base_type(std::nothrow, ASIO_MOVE_CAST(OtherAnyExecutor)(e))+ >::value+ > = 0) noexcept+ : base_type(std::nothrow, static_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) ASIO_NOEXCEPT;+ const any_io_executor& e) 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) ASIO_NOEXCEPT;-#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)+ ASIO_DECL any_io_executor(std::nothrow_t, any_io_executor&& e) noexcept; /// Construct a polymorphic wrapper for the specified executor. #if defined(GENERATING_DOCUMENTATION)@@ -164,17 +159,17 @@ #else // defined(GENERATING_DOCUMENTATION) template <ASIO_EXECUTION_EXECUTOR Executor> any_io_executor(Executor e,- typename constraint<- conditional<+ constraint_t<+ conditional_t< !is_same<Executor, any_io_executor>::value && !is_base_of<execution::detail::any_executor_base, Executor>::value, execution::detail::is_valid_target_executor< Executor, supportable_properties_type>, false_type- >::type::value- >::type = 0)- : base_type(ASIO_MOVE_CAST(Executor)(e))+ >::value+ > = 0)+ : base_type(static_cast<Executor&&>(e)) { } #endif // defined(GENERATING_DOCUMENTATION)@@ -186,30 +181,27 @@ #else // defined(GENERATING_DOCUMENTATION) template <ASIO_EXECUTION_EXECUTOR Executor> any_io_executor(std::nothrow_t, Executor e,- typename constraint<- conditional<+ constraint_t<+ conditional_t< !is_same<Executor, any_io_executor>::value && !is_base_of<execution::detail::any_executor_base, Executor>::value, execution::detail::is_valid_target_executor< Executor, supportable_properties_type>, false_type- >::type::value- >::type = 0) ASIO_NOEXCEPT- : base_type(std::nothrow, ASIO_MOVE_CAST(Executor)(e))+ >::value+ > = 0) noexcept+ : base_type(std::nothrow, static_cast<Executor&&>(e)) { } #endif // defined(GENERATING_DOCUMENTATION) /// Assignment operator. ASIO_DECL any_io_executor& operator=(- const any_io_executor& e) ASIO_NOEXCEPT;+ const any_io_executor& e) noexcept; -#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move assignment operator.- ASIO_DECL any_io_executor& operator=(- any_io_executor&& e) ASIO_NOEXCEPT;-#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)+ ASIO_DECL any_io_executor& operator=(any_io_executor&& e) noexcept; /// Assignment operator that sets the polymorphic wrapper to the empty state. ASIO_DECL any_io_executor& operator=(nullptr_t);@@ -218,7 +210,7 @@ ASIO_DECL ~any_io_executor(); /// Swap targets with another polymorphic wrapper.- ASIO_DECL void swap(any_io_executor& other) ASIO_NOEXCEPT;+ ASIO_DECL void swap(any_io_executor& other) noexcept; /// Obtain a polymorphic wrapper with the specified property. /**@@ -231,9 +223,9 @@ */ template <typename Property> any_io_executor require(const Property& p,- typename constraint<+ constraint_t< traits::require_member<const base_type&, const Property&>::is_valid- >::type = 0) const+ > = 0) const { return static_cast<const base_type&>(*this).require(p); }@@ -249,9 +241,9 @@ */ template <typename Property> any_io_executor prefer(const Property& p,- typename constraint<+ constraint_t< traits::prefer_member<const base_type&, const Property&>::is_valid- >::type = 0) const+ > = 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -16,11 +16,6 @@ #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" @@ -37,11 +32,9 @@ public: /// Constructor. template <typename T, typename... V>- 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)...)+ constexpr explicit append_t(T&& completion_token, V&&... values)+ : token_(static_cast<T&&>(completion_token)),+ values_(static_cast<V&&>(values)...) { } @@ -54,15 +47,13 @@ /// arguments should be passed additional values after the results of the /// operation. template <typename CompletionToken, typename... 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)+ASIO_NODISCARD inline constexpr+append_t<decay_t<CompletionToken>, decay_t<Values>...>+append(CompletionToken&& completion_token, Values&&... values) {- return append_t<- typename decay<CompletionToken>::type, typename decay<Values>::type...>(- ASIO_MOVE_CAST(CompletionToken)(completion_token),- ASIO_MOVE_CAST(Values)(values)...);+ return append_t<decay_t<CompletionToken>, decay_t<Values>...>(+ static_cast<CompletionToken&&>(completion_token),+ static_cast<Values&&>(values)...); } } // namespace asio@@ -70,9 +61,5 @@ #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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -16,11 +16,6 @@ #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"@@ -50,18 +45,18 @@ * token is itself defaulted as an argument to allow it to capture a source * location. */- ASIO_CONSTEXPR as_tuple_t(+ constexpr as_tuple_t( default_constructor_tag = default_constructor_tag(), CompletionToken token = CompletionToken())- : token_(ASIO_MOVE_CAST(CompletionToken)(token))+ : token_(static_cast<CompletionToken&&>(token)) { } /// Constructor. template <typename T>- ASIO_CONSTEXPR explicit as_tuple_t(- ASIO_MOVE_ARG(T) completion_token)- : token_(ASIO_MOVE_CAST(T)(completion_token))+ constexpr explicit as_tuple_t(+ T&& completion_token)+ : token_(static_cast<T&&>(completion_token)) { } @@ -76,13 +71,13 @@ /// Construct the adapted executor from the inner executor type. template <typename InnerExecutor1> executor_with_default(const InnerExecutor1& ex,- typename constraint<- conditional<+ constraint_t<+ conditional_t< !is_same<InnerExecutor1, executor_with_default>::value, is_convertible<InnerExecutor1, InnerExecutor>, false_type- >::type::value- >::type = 0) ASIO_NOEXCEPT+ >::value+ > = 0) noexcept : InnerExecutor(ex) { }@@ -90,50 +85,68 @@ /// 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;-#endif // defined(ASIO_HAS_ALIAS_TEMPLATES)- // || defined(GENERATING_DOCUMENTATION)+ executor_with_default<typename T::executor_type>>::other; /// 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>::type::template rebind_executor<- executor_with_default<typename decay<T>::type::executor_type>+ static typename decay_t<T>::template rebind_executor<+ executor_with_default<typename decay_t<T>::executor_type> >::other- as_default_on(ASIO_MOVE_ARG(T) object)+ as_default_on(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));+ return typename decay_t<T>::template rebind_executor<+ executor_with_default<typename decay_t<T>::executor_type>+ >::other(static_cast<T&&>(object)); } //private: CompletionToken token_; }; -/// 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)+/// 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 {- return as_tuple_t<typename decay<CompletionToken>::type>(- ASIO_MOVE_CAST(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;+ } // 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -36,9 +36,7 @@ }; template <typename T>-struct has_allocator_type<T,- typename void_type<typename T::allocator_type>::type>- : true_type+struct has_allocator_type<T, void_t<typename T::allocator_type>> : true_type { }; @@ -49,33 +47,30 @@ typedef A type; - static type get(const T&) ASIO_NOEXCEPT+ static type get(const T&) noexcept { return type(); } - static const type& get(const T&, const A& a) ASIO_NOEXCEPT+ static const type& get(const T&, const A& a) noexcept { return a; } }; template <typename T, typename A>-struct associated_allocator_impl<T, A,- typename void_type<typename T::allocator_type>::type>+struct associated_allocator_impl<T, A, void_t<typename T::allocator_type>> { typedef typename T::allocator_type type; - static ASIO_AUTO_RETURN_TYPE_PREFIX(type) get(- const T& t) ASIO_NOEXCEPT- ASIO_AUTO_RETURN_TYPE_SUFFIX((t.get_allocator()))+ static auto get(const T& t) noexcept+ -> decltype(t.get_allocator()) { return 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()))+ static auto get(const T& t, const A&) noexcept+ -> decltype(t.get_allocator()) { return t.get_allocator(); }@@ -83,12 +78,12 @@ template <typename T, typename A> struct associated_allocator_impl<T, A,- typename enable_if<+ enable_if_t< !has_allocator_type<T>::value- >::type,- typename void_type<+ >,+ void_t< typename associator<associated_allocator, T, A>::type- >::type> : associator<associated_allocator, T, A>+ >> : associator<associated_allocator, T, A> { }; @@ -115,7 +110,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>@@ -128,11 +123,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) ASIO_NOEXCEPT;+ static decltype(auto) get(const T& t) 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) ASIO_NOEXCEPT;+ static decltype(auto) get(const T& t, const Allocator& a) noexcept; #endif // defined(GENERATING_DOCUMENTATION) }; @@ -142,7 +137,7 @@ */ template <typename T> ASIO_NODISCARD inline typename associated_allocator<T>::type-get_associated_allocator(const T& t) ASIO_NOEXCEPT+get_associated_allocator(const T& t) noexcept { return associated_allocator<T>::get(t); }@@ -152,23 +147,17 @@ * @returns <tt>associated_allocator<T, Allocator>::get(t, a)</tt> */ template <typename T, typename Allocator>-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)))+ASIO_NODISCARD inline auto get_associated_allocator(+ const T& t, const Allocator& a) noexcept+ -> decltype(associated_allocator<T, Allocator>::get(t, a)) { return associated_allocator<T, Allocator>::get(t, a); } -#if defined(ASIO_HAS_ALIAS_TEMPLATES)--template <typename T, typename Allocator = std::allocator<void> >+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>@@ -178,22 +167,19 @@ template <typename T, typename A> struct associated_allocator_forwarding_base<T, A,- typename enable_if<+ enable_if_t< 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>@@ -207,24 +193,19 @@ /// Forwards the request to get the allocator to the associator specialisation /// for the unwrapped type @c T.- static type get(reference_wrapper<T> t) ASIO_NOEXCEPT+ static type get(reference_wrapper<T> t) 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 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)))+ static auto get(reference_wrapper<T> t, const Allocator& a) noexcept+ -> decltype(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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -36,9 +36,8 @@ }; template <typename T>-struct has_cancellation_slot_type<T,- typename void_type<typename T::cancellation_slot_type>::type>- : true_type+struct has_cancellation_slot_type<T, void_t<typename T::cancellation_slot_type>>+ : true_type { }; @@ -49,12 +48,12 @@ typedef S type; - static type get(const T&) ASIO_NOEXCEPT+ static type get(const T&) noexcept { return type(); } - static const type& get(const T&, const S& s) ASIO_NOEXCEPT+ static const type& get(const T&, const S& s) noexcept { return s; }@@ -62,20 +61,18 @@ template <typename T, typename S> struct associated_cancellation_slot_impl<T, S,- typename void_type<typename T::cancellation_slot_type>::type>+ void_t<typename T::cancellation_slot_type>> { typedef typename T::cancellation_slot_type type; - static ASIO_AUTO_RETURN_TYPE_PREFIX(type) get(- const T& t) ASIO_NOEXCEPT- ASIO_AUTO_RETURN_TYPE_SUFFIX((t.get_cancellation_slot()))+ static auto get(const T& t) noexcept+ -> decltype(t.get_cancellation_slot()) { return 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()))+ static auto get(const T& t, const S&) noexcept+ -> decltype(t.get_cancellation_slot()) { return t.get_cancellation_slot(); }@@ -83,12 +80,12 @@ template <typename T, typename S> struct associated_cancellation_slot_impl<T, S,- typename enable_if<+ enable_if_t< !has_cancellation_slot_type<T>::value- >::type,- typename void_type<+ >,+ void_t< typename associator<associated_cancellation_slot, T, S>::type- >::type> : associator<associated_cancellation_slot, T, S>+ >> : associator<associated_cancellation_slot, T, S> { }; @@ -129,12 +126,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) ASIO_NOEXCEPT;+ static decltype(auto) get(const T& t) 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) ASIO_NOEXCEPT;+ const CancellationSlot& s) noexcept; #endif // defined(GENERATING_DOCUMENTATION) }; @@ -144,7 +141,7 @@ */ template <typename T> ASIO_NODISCARD inline typename associated_cancellation_slot<T>::type-get_associated_cancellation_slot(const T& t) ASIO_NOEXCEPT+get_associated_cancellation_slot(const T& t) noexcept { return associated_cancellation_slot<T>::get(t); }@@ -155,24 +152,17 @@ * CancellationSlot>::get(t, st)</tt> */ template <typename T, typename CancellationSlot>-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)))+ASIO_NODISCARD inline auto get_associated_cancellation_slot(+ const T& t, const CancellationSlot& st) noexcept+ -> decltype(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>@@ -182,22 +172,19 @@ template <typename T, typename S> struct associated_cancellation_slot_forwarding_base<T, S,- typename enable_if<+ enable_if_t< 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>@@ -212,24 +199,20 @@ /// 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) ASIO_NOEXCEPT+ static type get(reference_wrapper<T> t) 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 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)))+ static auto get(reference_wrapper<T> t, const CancellationSlot& s) noexcept+ -> decltype(+ 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -38,8 +38,7 @@ }; template <typename T>-struct has_executor_type<T,- typename void_type<typename T::executor_type>::type>+struct has_executor_type<T, void_t<typename T::executor_type>> : true_type { };@@ -51,33 +50,30 @@ typedef E type; - static type get(const T&) ASIO_NOEXCEPT+ static type get(const T&) noexcept { return type(); } - static const type& get(const T&, const E& e) ASIO_NOEXCEPT+ static const type& get(const T&, const E& e) noexcept { return e; } }; template <typename T, typename E>-struct associated_executor_impl<T, E,- typename void_type<typename T::executor_type>::type>+struct associated_executor_impl<T, E, void_t<typename T::executor_type>> { typedef typename T::executor_type type; - static ASIO_AUTO_RETURN_TYPE_PREFIX(type) get(- const T& t) ASIO_NOEXCEPT- ASIO_AUTO_RETURN_TYPE_SUFFIX((t.get_executor()))+ static auto get(const T& t) noexcept+ -> decltype(t.get_executor()) { return 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()))+ static auto get(const T& t, const E&) noexcept+ -> decltype(t.get_executor()) { return t.get_executor(); }@@ -85,12 +81,12 @@ template <typename T, typename E> struct associated_executor_impl<T, E,- typename enable_if<+ enable_if_t< !has_executor_type<T>::value- >::type,- typename void_type<+ >,+ void_t< typename associator<associated_executor, T, E>::type- >::type> : associator<associated_executor, T, E>+ >> : associator<associated_executor, T, E> { }; @@ -130,11 +126,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) ASIO_NOEXCEPT;+ static decltype(auto) get(const T& t) 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) ASIO_NOEXCEPT;+ static decltype(auto) get(const T& t, const Executor& ex) noexcept; #endif // defined(GENERATING_DOCUMENTATION) }; @@ -144,7 +140,7 @@ */ template <typename T> ASIO_NODISCARD inline typename associated_executor<T>::type-get_associated_executor(const T& t) ASIO_NOEXCEPT+get_associated_executor(const T& t) noexcept { return associated_executor<T>::get(t); }@@ -154,14 +150,12 @@ * @returns <tt>associated_executor<T, Executor>::get(t, ex)</tt> */ template <typename T, typename Executor>-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<+ASIO_NODISCARD inline auto get_associated_executor(+ const T& t, const Executor& ex,+ constraint_t< is_executor<Executor>::value || execution::is_executor<Executor>::value- >::type = 0) ASIO_NOEXCEPT- ASIO_AUTO_RETURN_TYPE_SUFFIX((- associated_executor<T, Executor>::get(t, ex)))+ > = 0) noexcept+ -> decltype(associated_executor<T, Executor>::get(t, ex)) { return associated_executor<T, Executor>::get(t, ex); }@@ -175,20 +169,16 @@ ASIO_NODISCARD inline typename associated_executor<T, typename ExecutionContext::executor_type>::type get_associated_executor(const T& t, ExecutionContext& ctx,- typename constraint<is_convertible<ExecutionContext&,- execution_context&>::value>::type = 0) ASIO_NOEXCEPT+ constraint_t<is_convertible<ExecutionContext&,+ execution_context&>::value> = 0) 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>@@ -198,22 +188,19 @@ template <typename T, typename E> struct associated_executor_forwarding_base<T, E,- typename enable_if<+ enable_if_t< 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>@@ -227,24 +214,19 @@ /// Forwards the request to get the executor to the associator specialisation /// for the unwrapped type @c T.- static type get(reference_wrapper<T> t) ASIO_NOEXCEPT+ static type get(reference_wrapper<T> t) 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 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)))+ static auto get(reference_wrapper<T> t, const Executor& ex) noexcept+ -> decltype(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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -41,7 +41,7 @@ template <typename T> struct has_immediate_executor_type<T,- typename void_type<typename T::immediate_executor_type>::type>+ void_t<typename T::immediate_executor_type>> : true_type { };@@ -49,9 +49,10 @@ template <typename E, typename = void, typename = void> struct default_immediate_executor {- typedef typename require_result<E, execution::blocking_t::never_t>::type type;+ typedef decay_t<require_result_t<E, execution::blocking_t::never_t>> type; - static type get(const E& e) ASIO_NOEXCEPT+ static auto get(const E& e) noexcept+ -> decltype(asio::require(e, execution::blocking.never)) { return asio::require(e, execution::blocking.never); }@@ -59,59 +60,57 @@ template <typename E> struct default_immediate_executor<E,- typename enable_if<+ enable_if_t< !execution::is_executor<E>::value- >::type,- typename enable_if<+ >,+ enable_if_t< is_executor<E>::value- >::type>+ >> { class type : public E { public: template <typename Executor1> explicit type(const Executor1& e,- typename constraint<- conditional<+ constraint_t<+ conditional_t< !is_same<Executor1, type>::value, is_convertible<Executor1, E>, false_type- >::type::value- >::type = 0) ASIO_NOEXCEPT+ >::value+ > = 0) noexcept : E(e) { } - type(const type& other) ASIO_NOEXCEPT+ type(const type& other) noexcept : E(static_cast<const E&>(other)) { } -#if defined(ASIO_HAS_MOVE)- type(type&& other) ASIO_NOEXCEPT- : E(ASIO_MOVE_CAST(E)(other))+ type(type&& other) noexcept+ : E(static_cast<E&&>(other)) { }-#endif // defined(ASIO_HAS_MOVE) template <typename Function, typename Allocator>- void dispatch(ASIO_MOVE_ARG(Function) f, const Allocator& a) const+ void dispatch(Function&& f, const Allocator& a) const {- this->post(ASIO_MOVE_CAST(Function)(f), a);+ this->post(static_cast<Function&&>(f), a); } - friend bool operator==(const type& a, const type& b) ASIO_NOEXCEPT+ friend bool operator==(const type& a, const type& b) noexcept { return static_cast<const E&>(a) == static_cast<const E&>(b); } - friend bool operator!=(const type& a, const type& b) ASIO_NOEXCEPT+ friend bool operator!=(const type& a, const type& b) noexcept { return static_cast<const E&>(a) != static_cast<const E&>(b); } }; - static type get(const E& e) ASIO_NOEXCEPT+ static type get(const E& e) noexcept { return type(e); }@@ -124,9 +123,8 @@ typedef typename default_immediate_executor<E>::type type; - 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)))+ static auto get(const T&, const E& e) noexcept+ -> decltype(default_immediate_executor<E>::get(e)) { return default_immediate_executor<E>::get(e); }@@ -134,13 +132,12 @@ template <typename T, typename E> struct associated_immediate_executor_impl<T, E,- typename void_type<typename T::immediate_executor_type>::type>+ void_t<typename T::immediate_executor_type>> { typedef typename T::immediate_executor_type type; - static ASIO_AUTO_RETURN_TYPE_PREFIX(type) get(- const T& t, const E&) ASIO_NOEXCEPT- ASIO_AUTO_RETURN_TYPE_SUFFIX((t.get_immediate_executor()))+ static auto get(const T& t, const E&) noexcept+ -> decltype(t.get_immediate_executor()) { return t.get_immediate_executor(); }@@ -148,12 +145,12 @@ template <typename T, typename E> struct associated_immediate_executor_impl<T, E,- typename enable_if<+ enable_if_t< !has_immediate_executor_type<T>::value- >::type,- typename void_type<+ >,+ void_t< typename associator<associated_immediate_executor, T, E>::type- >::type> : associator<associated_immediate_executor, T, E>+ >> : associator<associated_immediate_executor, T, E> { }; @@ -194,7 +191,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) ASIO_NOEXCEPT;+ static decltype(auto) get(const T& t, const Executor& ex) noexcept; #endif // defined(GENERATING_DOCUMENTATION) }; @@ -203,14 +200,12 @@ * @returns <tt>associated_immediate_executor<T, Executor>::get(t, ex)</tt> */ template <typename T, typename Executor>-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<+ASIO_NODISCARD inline auto get_associated_immediate_executor(+ const T& t, const Executor& ex,+ constraint_t< is_executor<Executor>::value || execution::is_executor<Executor>::value- >::type = 0) ASIO_NOEXCEPT- ASIO_AUTO_RETURN_TYPE_SUFFIX((- associated_immediate_executor<T, Executor>::get(t, ex)))+ > = 0) noexcept+ -> decltype(associated_immediate_executor<T, Executor>::get(t, ex)) { return associated_immediate_executor<T, Executor>::get(t, ex); }@@ -224,21 +219,18 @@ ASIO_NODISCARD inline typename associated_immediate_executor<T, typename ExecutionContext::executor_type>::type get_associated_immediate_executor(const T& t, ExecutionContext& ctx,- typename constraint<is_convertible<ExecutionContext&,- execution_context&>::value>::type = 0) ASIO_NOEXCEPT+ constraint_t<+ is_convertible<ExecutionContext&, execution_context&>::value+ > = 0) 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>@@ -248,22 +240,19 @@ template <typename T, typename E> struct associated_immediate_executor_forwarding_base<T, E,- typename enable_if<+ enable_if_t< 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>@@ -278,17 +267,12 @@ /// Forwards the request to get the executor to the associator specialisation /// for the unwrapped type @c T.- 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)))+ static auto get(reference_wrapper<T> t, const Executor& ex) noexcept+ -> decltype(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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -23,7 +23,7 @@ /// Used to generically specialise associators for a type. template <template <typename, typename> class Associator,- typename T, typename DefaultCandidate>+ typename T, typename DefaultCandidate, typename _ = void> struct associator { };
link/modules/asio-standalone/asio/include/asio/async_result.hpp view
@@ -2,1670 +2,967 @@ // async_result.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"+// 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" #endif // ASIO_ASYNC_RESULT_HPP
link/modules/asio-standalone/asio/include/asio/awaitable.hpp view
@@ -2,7 +2,7 @@ // awaitable.hpp // ~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -136,6 +136,9 @@ #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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -113,9 +113,9 @@ */ template <typename ExecutionContext> explicit basic_datagram_socket(ExecutionContext& context,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value- >::type = 0)+ > = 0) : basic_socket<Protocol, Executor>(context) { }@@ -151,10 +151,10 @@ template <typename ExecutionContext> basic_datagram_socket(ExecutionContext& context, const protocol_type& protocol,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- >::type = defaulted_constraint())+ > = defaulted_constraint()) : basic_socket<Protocol, Executor>(context, protocol) { }@@ -198,9 +198,9 @@ template <typename ExecutionContext> basic_datagram_socket(ExecutionContext& context, const endpoint_type& endpoint,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value- >::type = 0)+ > = 0) : basic_socket<Protocol, Executor>(context, endpoint) { }@@ -243,14 +243,13 @@ template <typename ExecutionContext> basic_datagram_socket(ExecutionContext& context, const protocol_type& protocol, const native_handle_type& native_socket,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value- >::type = 0)+ > = 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.@@ -262,7 +261,7 @@ * constructed using the @c basic_datagram_socket(const executor_type&) * constructor. */- basic_datagram_socket(basic_datagram_socket&& other) ASIO_NOEXCEPT+ basic_datagram_socket(basic_datagram_socket&& other) noexcept : basic_socket<Protocol, Executor>(std::move(other)) { }@@ -299,10 +298,10 @@ */ template <typename Protocol1, typename Executor1> basic_datagram_socket(basic_datagram_socket<Protocol1, Executor1>&& other,- typename constraint<+ constraint_t< is_convertible<Protocol1, Protocol>::value && is_convertible<Executor1, Executor>::value- >::type = 0)+ > = 0) : basic_socket<Protocol, Executor>(std::move(other)) { }@@ -321,16 +320,15 @@ * constructor. */ template <typename Protocol1, typename Executor1>- typename constraint<+ constraint_t< is_convertible<Protocol1, Protocol>::value && is_convertible<Executor1, Executor>::value, basic_datagram_socket&- >::type operator=(basic_datagram_socket<Protocol1, Executor1>&& other)+ > 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. /**@@ -347,7 +345,7 @@ * call will block until the data has been sent successfully or an error * occurs. *- * @param buffers One ore more data buffers to be sent on the socket.+ * @param buffers One or more data buffers to be sent on the socket. * * @returns The number of bytes sent. *@@ -379,7 +377,7 @@ * call will block until the data has been sent successfully or an error * occurs. *- * @param buffers One ore more data buffers to be sent on the socket.+ * @param buffers One or more data buffers to be sent on the socket. * * @param flags Flags specifying how the send call is to be made. *@@ -449,7 +447,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -479,18 +477,14 @@ */ template <typename ConstBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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((+ 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( 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)>(@@ -523,7 +517,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -544,18 +538,14 @@ */ template <typename ConstBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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,+ std::size_t)) WriteToken = default_completion_token_t<executor_type>>+ auto async_send(const ConstBufferSequence& buffers, socket_base::message_flags flags,- ASIO_MOVE_ARG(WriteToken) token- ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ WriteToken&& token = default_completion_token_t<executor_type>())+ -> decltype( 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)>(@@ -676,7 +666,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -705,19 +695,15 @@ */ template <typename ConstBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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,+ std::size_t)) WriteToken = default_completion_token_t<executor_type>>+ auto async_send_to(const ConstBufferSequence& buffers, const endpoint_type& destination,- ASIO_MOVE_ARG(WriteToken) token- ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ WriteToken&& token = default_completion_token_t<executor_type>())+ -> decltype( 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)>(@@ -753,7 +739,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -770,19 +756,15 @@ */ template <typename ConstBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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,+ std::size_t)) WriteToken = default_completion_token_t<executor_type>>+ auto async_send_to(const ConstBufferSequence& buffers, const endpoint_type& destination, socket_base::message_flags flags,- ASIO_MOVE_ARG(WriteToken) token- ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ WriteToken&& token = default_completion_token_t<executor_type>())+ -> decltype( 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)>(@@ -902,7 +884,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -933,18 +915,14 @@ */ template <typename MutableBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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((+ 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( 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)>(@@ -977,7 +955,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -998,18 +976,14 @@ */ template <typename MutableBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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,+ std::size_t)) ReadToken = default_completion_token_t<executor_type>>+ auto async_receive(const MutableBufferSequence& buffers, socket_base::message_flags flags,- ASIO_MOVE_ARG(ReadToken) token- ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ ReadToken&& token = default_completion_token_t<executor_type>())+ -> decltype( 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)>(@@ -1052,7 +1026,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@@ -1079,7 +1053,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@@ -1133,7 +1107,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -1159,19 +1133,15 @@ */ template <typename MutableBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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,+ std::size_t)) ReadToken = default_completion_token_t<executor_type>>+ auto async_receive_from(const MutableBufferSequence& buffers, endpoint_type& sender_endpoint,- ASIO_MOVE_ARG(ReadToken) token- ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ ReadToken&& token = default_completion_token_t<executor_type>())+ -> decltype( 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)>(@@ -1209,7 +1179,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -1226,19 +1196,15 @@ */ template <typename MutableBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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,+ std::size_t)) ReadToken = default_completion_token_t<executor_type>>+ auto async_receive_from(const MutableBufferSequence& buffers, endpoint_type& sender_endpoint, socket_base::message_flags flags,- ASIO_MOVE_ARG(ReadToken) token- ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ ReadToken&& token = default_completion_token_t<executor_type>())+ -> decltype( 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)>(@@ -1248,12 +1214,12 @@ private: // Disallow copying and assignment.- basic_datagram_socket(const basic_datagram_socket&) ASIO_DELETED;+ basic_datagram_socket(const basic_datagram_socket&) = delete; basic_datagram_socket& operator=(- const basic_datagram_socket&) ASIO_DELETED;+ const basic_datagram_socket&) = delete; class initiate_async_send- { + { public: typedef Executor executor_type; @@ -1262,13 +1228,13 @@ { } - const executor_type& get_executor() const ASIO_NOEXCEPT+ const executor_type& get_executor() const noexcept { return self_->get_executor(); } template <typename WriteHandler, typename ConstBufferSequence>- void operator()(ASIO_MOVE_ARG(WriteHandler) handler,+ void operator()(WriteHandler&& handler, const ConstBufferSequence& buffers, socket_base::message_flags flags) const {@@ -1296,13 +1262,13 @@ { } - const executor_type& get_executor() const ASIO_NOEXCEPT+ const executor_type& get_executor() const noexcept { return self_->get_executor(); } template <typename WriteHandler, typename ConstBufferSequence>- void operator()(ASIO_MOVE_ARG(WriteHandler) handler,+ void operator()(WriteHandler&& handler, const ConstBufferSequence& buffers, const endpoint_type& destination, socket_base::message_flags flags) const {@@ -1330,13 +1296,13 @@ { } - const executor_type& get_executor() const ASIO_NOEXCEPT+ const executor_type& get_executor() const noexcept { return self_->get_executor(); } template <typename ReadHandler, typename MutableBufferSequence>- void operator()(ASIO_MOVE_ARG(ReadHandler) handler,+ void operator()(ReadHandler&& handler, const MutableBufferSequence& buffers, socket_base::message_flags flags) const {@@ -1364,13 +1330,13 @@ { } - const executor_type& get_executor() const ASIO_NOEXCEPT+ const executor_type& get_executor() const noexcept { return self_->get_executor(); } template <typename ReadHandler, typename MutableBufferSequence>- void operator()(ASIO_MOVE_ARG(ReadHandler) handler,+ void operator()(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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -17,6 +17,8 @@ #include "asio/detail/config.hpp" +#if !defined(ASIO_NO_DEPRECATED)+ #if defined(ASIO_HAS_BOOST_DATE_TIME) \ || defined(GENERATING_DOCUMENTATION) @@ -35,7 +37,8 @@ namespace asio { -/// Provides waitable timer functionality.+/// (Deprecated: Use basic_waitable_timer.) 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.@@ -63,7 +66,7 @@ * timer.wait(); * @endcode *- * @par + * @par * Performing an asynchronous wait: * @code * void handler(const asio::error_code& error)@@ -178,9 +181,9 @@ */ template <typename ExecutionContext> explicit basic_deadline_timer(ExecutionContext& context,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value- >::type = 0)+ > = 0) : impl_(0, 0, context) { }@@ -216,9 +219,9 @@ */ template <typename ExecutionContext> basic_deadline_timer(ExecutionContext& context, const time_type& expiry_time,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value- >::type = 0)+ > = 0) : impl_(0, 0, context) { asio::error_code ec;@@ -260,9 +263,9 @@ template <typename ExecutionContext> basic_deadline_timer(ExecutionContext& context, const duration_type& expiry_time,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value- >::type = 0)+ > = 0) : impl_(0, 0, context) { asio::error_code ec;@@ -271,7 +274,6 @@ 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.@@ -305,7 +307,6 @@ impl_ = std::move(other.impl_); return *this; }-#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Destroys the timer. /**@@ -317,7 +318,7 @@ } /// Get the executor associated with the object.- const executor_type& get_executor() ASIO_NOEXCEPT+ const executor_type& get_executor() noexcept { return impl_.get_executor(); }@@ -632,7 +633,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code) @endcode@@ -649,15 +650,12 @@ */ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code))- 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((+ WaitToken = default_completion_token_t<executor_type>>+ auto async_wait(+ WaitToken&& token = default_completion_token_t<executor_type>())+ -> decltype( 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);@@ -665,9 +663,9 @@ private: // Disallow copying and assignment.- basic_deadline_timer(const basic_deadline_timer&) ASIO_DELETED;+ basic_deadline_timer(const basic_deadline_timer&) = delete; basic_deadline_timer& operator=(- const basic_deadline_timer&) ASIO_DELETED;+ const basic_deadline_timer&) = delete; class initiate_async_wait {@@ -679,13 +677,13 @@ { } - const executor_type& get_executor() const ASIO_NOEXCEPT+ const executor_type& get_executor() const noexcept { return self_->get_executor(); } template <typename WaitHandler>- void operator()(ASIO_MOVE_ARG(WaitHandler) handler) const+ void operator()(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.@@ -711,5 +709,7 @@ #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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -21,6 +21,7 @@ || defined(GENERATING_DOCUMENTATION) #include <string>+#include <utility> #include "asio/any_io_executor.hpp" #include "asio/async_result.hpp" #include "asio/detail/cstdint.hpp"@@ -39,10 +40,6 @@ # 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 {@@ -112,10 +109,10 @@ */ template <typename ExecutionContext> explicit basic_file(ExecutionContext& context,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- >::type = defaulted_constraint())+ > = defaulted_constraint()) : impl_(0, 0, context) { }@@ -131,6 +128,20 @@ * * @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)@@ -141,7 +152,7 @@ asio::detail::throw_error(ec, "open"); } - /// Construct a basic_file without opening it.+ /// Construct and open a basic_file. /** * This constructor initialises a file and opens it. *@@ -153,14 +164,28 @@ * * @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,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- >::type = defaulted_constraint())+ > = defaulted_constraint()) : impl_(0, 0, context) { asio::error_code ec;@@ -179,6 +204,20 @@ * * @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)@@ -190,7 +229,7 @@ asio::detail::throw_error(ec, "open"); } - /// Construct a basic_file without opening it.+ /// Construct and open a basic_file. /** * This constructor initialises a file and opens it. *@@ -202,14 +241,28 @@ * * @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,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- >::type = defaulted_constraint())+ > = defaulted_constraint()) : impl_(0, 0, context) { asio::error_code ec;@@ -252,10 +305,10 @@ */ template <typename ExecutionContext> basic_file(ExecutionContext& context, const native_handle_type& native_file,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- >::type = defaulted_constraint())+ > = defaulted_constraint()) : impl_(0, 0, context) { asio::error_code ec;@@ -264,7 +317,6 @@ 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.@@ -275,7 +327,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) ASIO_NOEXCEPT+ basic_file(basic_file&& other) noexcept : impl_(std::move(other.impl_)) { }@@ -312,10 +364,10 @@ */ template <typename Executor1> basic_file(basic_file<Executor1>&& other,- typename constraint<+ constraint_t< is_convertible<Executor1, Executor>::value, defaulted_constraint- >::type = defaulted_constraint())+ > = defaulted_constraint()) : impl_(std::move(other.impl_)) { }@@ -331,19 +383,18 @@ * constructed using the @c basic_file(const executor_type&) constructor. */ template <typename Executor1>- typename constraint<+ constraint_t< is_convertible<Executor1, Executor>::value, basic_file&- >::type operator=(basic_file<Executor1>&& other)+ > 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() ASIO_NOEXCEPT+ const executor_type& get_executor() noexcept { return impl_.get_executor(); }@@ -359,6 +410,20 @@ * * @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);@@ -381,6 +446,20 @@ * @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@@ -412,6 +491,20 @@ * * @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);@@ -437,6 +530,20 @@ * * @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);@@ -815,8 +922,8 @@ private: // Disallow copying and assignment.- basic_file(const basic_file&) ASIO_DELETED;- basic_file& operator=(const basic_file&) ASIO_DELETED;+ basic_file(const basic_file&) = delete;+ basic_file& operator=(const basic_file&) = delete; }; } // 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -16,13 +16,16 @@ #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.@@ -45,14 +48,13 @@ static_cast<implementation_type*>(0))) == 1; }; }-#endif // defined(ASIO_HAS_MOVE) -/// Base class for all I/O objects.+/// (Deprecated) Base class for all I/O objects. /** * @note All I/O objects are non-copyable. However, when using C++0x, certain * I/O objects do support move construction and move assignment. */-#if !defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)+#if defined(GENERATING_DOCUMENTATION) template <typename IoObjectService> #else template <typename IoObjectService,@@ -67,9 +69,7 @@ /// The underlying implementation type of I/O object. typedef typename service_type::implementation_type implementation_type; -#if !defined(ASIO_NO_DEPRECATED)- /// (Deprecated: Use get_executor().) Get the io_context associated with the- /// object.+ /// 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,8 +82,7 @@ return service_.get_io_context(); } - /// (Deprecated: Use get_executor().) Get the io_context associated with the- /// object.+ /// 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.@@ -95,13 +94,12 @@ { return service_.get_io_context(); }-#endif // !defined(ASIO_NO_DEPRECATED) /// The type of the executor associated with the object. typedef asio::io_context::executor_type executor_type; /// Get the executor associated with the object.- executor_type get_executor() ASIO_NOEXCEPT+ executor_type get_executor() noexcept { return service_.get_io_context().get_executor(); }@@ -190,7 +188,6 @@ implementation_type implementation_; }; -#if defined(ASIO_HAS_MOVE) // Specialisation for movable objects. template <typename IoObjectService> class basic_io_object<IoObjectService, true>@@ -199,7 +196,6 @@ 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();@@ -209,11 +205,10 @@ { return service_->get_io_context(); }-#endif // !defined(ASIO_NO_DEPRECATED) typedef asio::io_context::executor_type executor_type; - executor_type get_executor() ASIO_NOEXCEPT+ executor_type get_executor() noexcept { return service_->get_io_context().get_executor(); }@@ -281,10 +276,12 @@ 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -107,10 +107,10 @@ */ template <typename ExecutionContext> explicit basic_random_access_file(ExecutionContext& context,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- >::type = defaulted_constraint())+ > = 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,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- >::type = defaulted_constraint())+ > = 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,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- >::type = defaulted_constraint())+ > = defaulted_constraint()) : basic_file<Executor>(context, path, open_flags) { }@@ -241,15 +241,14 @@ template <typename ExecutionContext> basic_random_access_file(ExecutionContext& context, const native_handle_type& native_file,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- >::type = defaulted_constraint())+ > = 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.@@ -261,7 +260,7 @@ * constructed using the @c basic_random_access_file(const executor_type&) * constructor. */- basic_random_access_file(basic_random_access_file&& other) ASIO_NOEXCEPT+ basic_random_access_file(basic_random_access_file&& other) noexcept : basic_file<Executor>(std::move(other)) { }@@ -298,10 +297,10 @@ */ template <typename Executor1> basic_random_access_file(basic_random_access_file<Executor1>&& other,- typename constraint<+ constraint_t< is_convertible<Executor1, Executor>::value, defaulted_constraint- >::type = defaulted_constraint())+ > = defaulted_constraint()) : basic_file<Executor>(std::move(other)) { }@@ -320,15 +319,14 @@ * constructor. */ template <typename Executor1>- typename constraint<+ constraint_t< is_convertible<Executor1, Executor>::value, basic_random_access_file&- >::type operator=(basic_random_access_file<Executor1>&& other)+ > 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. /**@@ -429,7 +427,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -459,18 +457,13 @@ */ template <typename ConstBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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((+ 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( 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)>(@@ -569,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -600,18 +593,13 @@ */ template <typename MutableBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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((+ 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( 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)>(@@ -620,9 +608,9 @@ private: // Disallow copying and assignment.- basic_random_access_file(const basic_random_access_file&) ASIO_DELETED;+ basic_random_access_file(const basic_random_access_file&) = delete; basic_random_access_file& operator=(- const basic_random_access_file&) ASIO_DELETED;+ const basic_random_access_file&) = delete; class initiate_async_write_some_at {@@ -634,13 +622,13 @@ { } - const executor_type& get_executor() const ASIO_NOEXCEPT+ const executor_type& get_executor() const noexcept { return self_->get_executor(); } template <typename WriteHandler, typename ConstBufferSequence>- void operator()(ASIO_MOVE_ARG(WriteHandler) handler,+ void operator()(WriteHandler&& handler, uint64_t offset, const ConstBufferSequence& buffers) const { // If you get an error on the following line it means that your handler@@ -667,13 +655,13 @@ { } - const executor_type& get_executor() const ASIO_NOEXCEPT+ const executor_type& get_executor() const noexcept { return self_->get_executor(); } template <typename ReadHandler, typename MutableBufferSequence>- void operator()(ASIO_MOVE_ARG(ReadHandler) handler,+ void operator()(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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -113,9 +113,9 @@ */ template <typename ExecutionContext> explicit basic_raw_socket(ExecutionContext& context,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value- >::type = 0)+ > = 0) : basic_socket<Protocol, Executor>(context) { }@@ -150,10 +150,10 @@ */ template <typename ExecutionContext> basic_raw_socket(ExecutionContext& context, const protocol_type& protocol,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- >::type = defaulted_constraint())+ > = defaulted_constraint()) : basic_socket<Protocol, Executor>(context, protocol) { }@@ -196,9 +196,9 @@ */ template <typename ExecutionContext> basic_raw_socket(ExecutionContext& context, const endpoint_type& endpoint,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value- >::type = 0)+ > = 0) : basic_socket<Protocol, Executor>(context, endpoint) { }@@ -241,14 +241,13 @@ template <typename ExecutionContext> basic_raw_socket(ExecutionContext& context, const protocol_type& protocol, const native_handle_type& native_socket,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value- >::type = 0)+ > = 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.@@ -260,7 +259,7 @@ * constructed using the @c basic_raw_socket(const executor_type&) * constructor. */- basic_raw_socket(basic_raw_socket&& other) ASIO_NOEXCEPT+ basic_raw_socket(basic_raw_socket&& other) noexcept : basic_socket<Protocol, Executor>(std::move(other)) { }@@ -296,10 +295,10 @@ */ template <typename Protocol1, typename Executor1> basic_raw_socket(basic_raw_socket<Protocol1, Executor1>&& other,- typename constraint<+ constraint_t< is_convertible<Protocol1, Protocol>::value && is_convertible<Executor1, Executor>::value- >::type = 0)+ > = 0) : basic_socket<Protocol, Executor>(std::move(other)) { }@@ -316,16 +315,15 @@ * constructor. */ template <typename Protocol1, typename Executor1>- typename constraint<+ constraint_t< is_convertible<Protocol1, Protocol>::value && is_convertible<Executor1, Executor>::value, basic_raw_socket&- >::type operator=(basic_raw_socket<Protocol1, Executor1>&& other)+ > 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. /**@@ -341,7 +339,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 ore more data buffers to be sent on the socket.+ * @param buffers One or more data buffers to be sent on the socket. * * @returns The number of bytes sent. *@@ -372,7 +370,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 ore more data buffers to be sent on the socket.+ * @param buffers One or more data buffers to be sent on the socket. * * @param flags Flags specifying how the send call is to be made. *@@ -441,7 +439,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -471,18 +469,14 @@ */ template <typename ConstBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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((+ 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( 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)>(@@ -515,7 +509,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -536,18 +530,14 @@ */ template <typename ConstBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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,+ std::size_t)) WriteToken = default_completion_token_t<executor_type>>+ auto async_send(const ConstBufferSequence& buffers, socket_base::message_flags flags,- ASIO_MOVE_ARG(WriteToken) token- ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ WriteToken&& token = default_completion_token_t<executor_type>())+ -> decltype( 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)>(@@ -668,7 +658,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -697,19 +687,15 @@ */ template <typename ConstBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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,+ std::size_t)) WriteToken = default_completion_token_t<executor_type>>+ auto async_send_to(const ConstBufferSequence& buffers, const endpoint_type& destination,- ASIO_MOVE_ARG(WriteToken) token- ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ WriteToken&& token = default_completion_token_t<executor_type>())+ -> decltype( 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)>(@@ -745,7 +731,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -762,19 +748,15 @@ */ template <typename ConstBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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,+ std::size_t)) WriteToken = default_completion_token_t<executor_type>>+ auto async_send_to(const ConstBufferSequence& buffers, const endpoint_type& destination, socket_base::message_flags flags,- ASIO_MOVE_ARG(WriteToken) token- ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ WriteToken&& token = default_completion_token_t<executor_type>())+ -> decltype( 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)>(@@ -894,7 +876,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -925,18 +907,14 @@ */ template <typename MutableBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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((+ 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( 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)>(@@ -969,7 +947,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -991,17 +969,14 @@ template <typename MutableBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, 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,+ = default_completion_token_t<executor_type>>+ auto async_receive(const MutableBufferSequence& buffers, socket_base::message_flags flags,- ASIO_MOVE_ARG(ReadToken) token- ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ ReadToken&& token = default_completion_token_t<executor_type>())+ -> decltype( 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)>(@@ -1044,7 +1019,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@@ -1071,7 +1046,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@@ -1125,7 +1100,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -1151,19 +1126,16 @@ */ template <typename MutableBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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,+ std::size_t)) ReadToken = default_completion_token_t<executor_type>>+ auto async_receive_from(const MutableBufferSequence& buffers, endpoint_type& sender_endpoint,- ASIO_MOVE_ARG(ReadToken) token- ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ ReadToken&& token+ = default_completion_token_t<executor_type>())+ -> decltype( 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)>(@@ -1201,7 +1173,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -1219,18 +1191,15 @@ template <typename MutableBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, 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,+ = default_completion_token_t<executor_type>>+ auto async_receive_from(const MutableBufferSequence& buffers, endpoint_type& sender_endpoint, socket_base::message_flags flags,- ASIO_MOVE_ARG(ReadToken) token- ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ ReadToken&& token = default_completion_token_t<executor_type>())+ -> decltype( 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)>(@@ -1240,8 +1209,8 @@ private: // Disallow copying and assignment.- basic_raw_socket(const basic_raw_socket&) ASIO_DELETED;- basic_raw_socket& operator=(const basic_raw_socket&) ASIO_DELETED;+ basic_raw_socket(const basic_raw_socket&) = delete;+ basic_raw_socket& operator=(const basic_raw_socket&) = delete; class initiate_async_send {@@ -1253,13 +1222,13 @@ { } - const executor_type& get_executor() const ASIO_NOEXCEPT+ const executor_type& get_executor() const noexcept { return self_->get_executor(); } template <typename WriteHandler, typename ConstBufferSequence>- void operator()(ASIO_MOVE_ARG(WriteHandler) handler,+ void operator()(WriteHandler&& handler, const ConstBufferSequence& buffers, socket_base::message_flags flags) const {@@ -1287,13 +1256,13 @@ { } - const executor_type& get_executor() const ASIO_NOEXCEPT+ const executor_type& get_executor() const noexcept { return self_->get_executor(); } template <typename WriteHandler, typename ConstBufferSequence>- void operator()(ASIO_MOVE_ARG(WriteHandler) handler,+ void operator()(WriteHandler&& handler, const ConstBufferSequence& buffers, const endpoint_type& destination, socket_base::message_flags flags) const {@@ -1321,13 +1290,13 @@ { } - const executor_type& get_executor() const ASIO_NOEXCEPT+ const executor_type& get_executor() const noexcept { return self_->get_executor(); } template <typename ReadHandler, typename MutableBufferSequence>- void operator()(ASIO_MOVE_ARG(ReadHandler) handler,+ void operator()(ReadHandler&& handler, const MutableBufferSequence& buffers, socket_base::message_flags flags) const {@@ -1355,13 +1324,13 @@ { } - const executor_type& get_executor() const ASIO_NOEXCEPT+ const executor_type& get_executor() const noexcept { return self_->get_executor(); } template <typename ReadHandler, typename MutableBufferSequence>- void operator()(ASIO_MOVE_ARG(ReadHandler) handler,+ void operator()(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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -21,6 +21,7 @@ || 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"@@ -38,10 +39,6 @@ # 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 {@@ -112,10 +109,10 @@ */ template <typename ExecutionContext> explicit basic_readable_pipe(ExecutionContext& context,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- >::type = defaulted_constraint())+ > = defaulted_constraint()) : impl_(0, 0, context) { }@@ -159,9 +156,9 @@ template <typename ExecutionContext> basic_readable_pipe(ExecutionContext& context, const native_handle_type& native_pipe,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value- >::type = 0)+ > = 0) : impl_(0, 0, context) { asio::error_code ec;@@ -170,7 +167,6 @@ 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.@@ -221,10 +217,10 @@ */ template <typename Executor1> basic_readable_pipe(basic_readable_pipe<Executor1>&& other,- typename constraint<+ constraint_t< is_convertible<Executor1, Executor>::value, defaulted_constraint- >::type = defaulted_constraint())+ > = defaulted_constraint()) : impl_(std::move(other.impl_)) { }@@ -241,16 +237,15 @@ * constructor. */ template <typename Executor1>- typename constraint<+ constraint_t< is_convertible<Executor1, Executor>::value, basic_readable_pipe&- >::type operator=(basic_readable_pipe<Executor1>&& other)+ > 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. /**@@ -263,7 +258,7 @@ } /// Get the executor associated with the object.- const executor_type& get_executor() ASIO_NOEXCEPT+ const executor_type& get_executor() noexcept { return impl_.get_executor(); }@@ -539,7 +534,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -561,17 +556,13 @@ */ template <typename MutableBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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((+ 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( 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)>(@@ -580,8 +571,8 @@ private: // Disallow copying and assignment.- basic_readable_pipe(const basic_readable_pipe&) ASIO_DELETED;- basic_readable_pipe& operator=(const basic_readable_pipe&) ASIO_DELETED;+ basic_readable_pipe(const basic_readable_pipe&) = delete;+ basic_readable_pipe& operator=(const basic_readable_pipe&) = delete; class initiate_async_read_some {@@ -593,13 +584,13 @@ { } - const executor_type& get_executor() const ASIO_NOEXCEPT+ const executor_type& get_executor() const noexcept { return self_->get_executor(); } template <typename ReadHandler, typename MutableBufferSequence>- void operator()(ASIO_MOVE_ARG(ReadHandler) handler,+ void operator()(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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -111,9 +111,9 @@ */ template <typename ExecutionContext> explicit basic_seq_packet_socket(ExecutionContext& context,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value- >::type = 0)+ > = 0) : basic_socket<Protocol, Executor>(context) { }@@ -154,10 +154,10 @@ template <typename ExecutionContext> basic_seq_packet_socket(ExecutionContext& context, const protocol_type& protocol,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- >::type = defaulted_constraint())+ > = 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,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value- >::type = 0)+ > = 0) : basic_socket<Protocol, Executor>(context, endpoint) { }@@ -247,14 +247,13 @@ template <typename ExecutionContext> basic_seq_packet_socket(ExecutionContext& context, const protocol_type& protocol, const native_handle_type& native_socket,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value- >::type = 0)+ > = 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@@ -267,7 +266,7 @@ * constructed using the @c basic_seq_packet_socket(const executor_type&) * constructor. */- basic_seq_packet_socket(basic_seq_packet_socket&& other) ASIO_NOEXCEPT+ basic_seq_packet_socket(basic_seq_packet_socket&& other) noexcept : basic_socket<Protocol, Executor>(std::move(other)) { }@@ -305,10 +304,10 @@ */ template <typename Protocol1, typename Executor1> basic_seq_packet_socket(basic_seq_packet_socket<Protocol1, Executor1>&& other,- typename constraint<+ constraint_t< is_convertible<Protocol1, Protocol>::value && is_convertible<Executor1, Executor>::value- >::type = 0)+ > = 0) : basic_socket<Protocol, Executor>(std::move(other)) { }@@ -327,16 +326,15 @@ * constructor. */ template <typename Protocol1, typename Executor1>- typename constraint<+ constraint_t< is_convertible<Protocol1, Protocol>::value && is_convertible<Executor1, Executor>::value, basic_seq_packet_socket&- >::type operator=(basic_seq_packet_socket<Protocol1, Executor1>&& other)+ > 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. /**@@ -432,7 +430,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -459,17 +457,15 @@ template <typename ConstBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, 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,+ = default_completion_token_t<executor_type>>+ auto async_send(const ConstBufferSequence& buffers, socket_base::message_flags flags,- ASIO_MOVE_ARG(WriteToken) token- ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ WriteToken&& token+ = default_completion_token_t<executor_type>())+ -> decltype( 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)>(@@ -624,7 +620,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -651,19 +647,15 @@ */ template <typename MutableBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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,+ std::size_t)) ReadToken = default_completion_token_t<executor_type>>+ auto async_receive(const MutableBufferSequence& buffers, socket_base::message_flags& out_flags,- ASIO_MOVE_ARG(ReadToken) token- ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ ReadToken&& token = default_completion_token_t<executor_type>())+ -> decltype( 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)>(@@ -702,7 +694,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -731,20 +723,16 @@ */ template <typename MutableBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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,+ std::size_t)) ReadToken = default_completion_token_t<executor_type>>+ auto async_receive(const MutableBufferSequence& buffers, socket_base::message_flags in_flags, socket_base::message_flags& out_flags,- ASIO_MOVE_ARG(ReadToken) token- ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ ReadToken&& token = default_completion_token_t<executor_type>())+ -> decltype( 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)>(@@ -754,9 +742,9 @@ private: // Disallow copying and assignment.- basic_seq_packet_socket(const basic_seq_packet_socket&) ASIO_DELETED;+ basic_seq_packet_socket(const basic_seq_packet_socket&) = delete; basic_seq_packet_socket& operator=(- const basic_seq_packet_socket&) ASIO_DELETED;+ const basic_seq_packet_socket&) = delete; class initiate_async_send {@@ -768,13 +756,13 @@ { } - const executor_type& get_executor() const ASIO_NOEXCEPT+ const executor_type& get_executor() const noexcept { return self_->get_executor(); } template <typename WriteHandler, typename ConstBufferSequence>- void operator()(ASIO_MOVE_ARG(WriteHandler) handler,+ void operator()(WriteHandler&& handler, const ConstBufferSequence& buffers, socket_base::message_flags flags) const {@@ -802,13 +790,13 @@ { } - const executor_type& get_executor() const ASIO_NOEXCEPT+ const executor_type& get_executor() const noexcept { return self_->get_executor(); } template <typename ReadHandler, typename MutableBufferSequence>- void operator()(ASIO_MOVE_ARG(ReadHandler) handler,+ void operator()(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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2025 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,6 +22,7 @@ || 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"@@ -38,10 +39,6 @@ # 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 {@@ -112,10 +109,10 @@ */ template <typename ExecutionContext> explicit basic_serial_port(ExecutionContext& context,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- >::type = defaulted_constraint())+ > = defaulted_constraint()) : impl_(0, 0, context) { }@@ -154,9 +151,9 @@ */ template <typename ExecutionContext> basic_serial_port(ExecutionContext& context, const char* device,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value- >::type = 0)+ > = 0) : impl_(0, 0, context) { asio::error_code ec;@@ -198,9 +195,9 @@ */ template <typename ExecutionContext> basic_serial_port(ExecutionContext& context, const std::string& device,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value- >::type = 0)+ > = 0) : impl_(0, 0, context) { asio::error_code ec;@@ -247,9 +244,9 @@ template <typename ExecutionContext> basic_serial_port(ExecutionContext& context, const native_handle_type& native_serial_port,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value- >::type = 0)+ > = 0) : impl_(0, 0, context) { asio::error_code ec;@@ -258,7 +255,6 @@ 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.@@ -310,10 +306,10 @@ */ template <typename Executor1> basic_serial_port(basic_serial_port<Executor1>&& other,- typename constraint<+ constraint_t< is_convertible<Executor1, Executor>::value, defaulted_constraint- >::type = defaulted_constraint())+ > = defaulted_constraint()) : impl_(std::move(other.impl_)) { }@@ -331,16 +327,15 @@ * constructor. */ template <typename Executor1>- typename constraint<+ constraint_t< is_convertible<Executor1, Executor>::value, basic_serial_port&- >::type operator=(basic_serial_port<Executor1>&& other)+ > 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. /**@@ -353,7 +348,7 @@ } /// Get the executor associated with the object.- const executor_type& get_executor() ASIO_NOEXCEPT+ const executor_type& get_executor() noexcept { return impl_.get_executor(); }@@ -729,7 +724,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -760,17 +755,13 @@ */ template <typename ConstBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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((+ 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( 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)>(@@ -863,7 +854,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -895,17 +886,13 @@ */ template <typename MutableBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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((+ 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( 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)>(@@ -914,8 +901,8 @@ private: // Disallow copying and assignment.- basic_serial_port(const basic_serial_port&) ASIO_DELETED;- basic_serial_port& operator=(const basic_serial_port&) ASIO_DELETED;+ basic_serial_port(const basic_serial_port&) = delete;+ basic_serial_port& operator=(const basic_serial_port&) = delete; class initiate_async_write_some {@@ -927,13 +914,13 @@ { } - const executor_type& get_executor() const ASIO_NOEXCEPT+ const executor_type& get_executor() const noexcept { return self_->get_executor(); } template <typename WriteHandler, typename ConstBufferSequence>- void operator()(ASIO_MOVE_ARG(WriteHandler) handler,+ void operator()(WriteHandler&& handler, const ConstBufferSequence& buffers) const { // If you get an error on the following line it means that your handler@@ -960,13 +947,13 @@ { } - const executor_type& get_executor() const ASIO_NOEXCEPT+ const executor_type& get_executor() const noexcept { return self_->get_executor(); } template <typename ReadHandler, typename MutableBufferSequence>- void operator()(ASIO_MOVE_ARG(ReadHandler) handler,+ void operator()(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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -134,10 +134,10 @@ */ template <typename ExecutionContext> explicit basic_signal_set(ExecutionContext& context,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- >::type = defaulted_constraint())+ > = defaulted_constraint()) : impl_(0, 0, context) { }@@ -180,10 +180,10 @@ */ template <typename ExecutionContext> basic_signal_set(ExecutionContext& context, int signal_number_1,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- >::type = defaulted_constraint())+ > = 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,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- >::type = defaulted_constraint())+ > = 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,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- >::type = defaulted_constraint())+ > = 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() ASIO_NOEXCEPT+ const executor_type& get_executor() 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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, int) @endcode@@ -587,18 +587,20 @@ * @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 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((+ SignalToken = default_completion_token_t<executor_type>>+ auto async_wait(+ SignalToken&& token = default_completion_token_t<executor_type>())+ -> decltype( 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);@@ -606,8 +608,8 @@ private: // Disallow copying and assignment.- basic_signal_set(const basic_signal_set&) ASIO_DELETED;- basic_signal_set& operator=(const basic_signal_set&) ASIO_DELETED;+ basic_signal_set(const basic_signal_set&) = delete;+ basic_signal_set& operator=(const basic_signal_set&) = delete; class initiate_async_wait {@@ -619,13 +621,13 @@ { } - const executor_type& get_executor() const ASIO_NOEXCEPT+ const executor_type& get_executor() const noexcept { return self_->get_executor(); } template <typename SignalHandler>- void operator()(ASIO_MOVE_ARG(SignalHandler) handler) const+ void operator()(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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -15,6 +15,7 @@ # 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"@@ -38,10 +39,6 @@ # 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 {@@ -134,9 +131,9 @@ */ template <typename ExecutionContext> explicit basic_socket(ExecutionContext& context,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value- >::type = 0)+ > = 0) : impl_(0, 0, context) { }@@ -174,10 +171,10 @@ */ template <typename ExecutionContext> basic_socket(ExecutionContext& context, const protocol_type& protocol,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- >::type = defaulted_constraint())+ > = defaulted_constraint()) : impl_(0, 0, context) { asio::error_code ec;@@ -229,9 +226,9 @@ */ template <typename ExecutionContext> basic_socket(ExecutionContext& context, const endpoint_type& endpoint,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value- >::type = 0)+ > = 0) : impl_(0, 0, context) { asio::error_code ec;@@ -282,9 +279,9 @@ template <typename ExecutionContext> basic_socket(ExecutionContext& context, const protocol_type& protocol, const native_handle_type& native_socket,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value- >::type = 0)+ > = 0) : impl_(0, 0, context) { asio::error_code ec;@@ -293,7 +290,6 @@ 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.@@ -304,7 +300,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) ASIO_NOEXCEPT+ basic_socket(basic_socket&& other) noexcept : impl_(std::move(other.impl_)) { }@@ -341,10 +337,10 @@ */ template <typename Protocol1, typename Executor1> basic_socket(basic_socket<Protocol1, Executor1>&& other,- typename constraint<+ constraint_t< is_convertible<Protocol1, Protocol>::value && is_convertible<Executor1, Executor>::value- >::type = 0)+ > = 0) : impl_(std::move(other.impl_)) { }@@ -360,20 +356,19 @@ * constructed using the @c basic_socket(const executor_type&) constructor. */ template <typename Protocol1, typename Executor1>- typename constraint<+ constraint_t< is_convertible<Protocol1, Protocol>::value && is_convertible<Executor1, Executor>::value, basic_socket&- >::type operator=(basic_socket<Protocol1, Executor1>&& other)+ > 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() ASIO_NOEXCEPT+ const executor_type& get_executor() noexcept { return impl_.get_executor(); }@@ -932,7 +927,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code) @endcode@@ -967,16 +962,13 @@ */ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code))- 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((+ ConnectToken = default_completion_token_t<executor_type>>+ auto async_connect(const endpoint_type& peer_endpoint,+ ConnectToken&& token = default_completion_token_t<executor_type>())+ -> decltype( 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())@@ -1787,7 +1779,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code) @endcode@@ -1821,15 +1813,12 @@ */ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code))- 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((+ WaitToken = default_completion_token_t<executor_type>>+ auto async_wait(wait_type w,+ WaitToken&& token = default_completion_token_t<executor_type>())+ -> decltype( 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);@@ -1861,8 +1850,8 @@ private: // Disallow copying and assignment.- basic_socket(const basic_socket&) ASIO_DELETED;- basic_socket& operator=(const basic_socket&) ASIO_DELETED;+ basic_socket(const basic_socket&) = delete;+ basic_socket& operator=(const basic_socket&) = delete; class initiate_async_connect {@@ -1874,13 +1863,13 @@ { } - const executor_type& get_executor() const ASIO_NOEXCEPT+ const executor_type& get_executor() const noexcept { return self_->get_executor(); } template <typename ConnectHandler>- void operator()(ASIO_MOVE_ARG(ConnectHandler) handler,+ void operator()(ConnectHandler&& handler, const endpoint_type& peer_endpoint, const asio::error_code& open_ec) const {@@ -1892,7 +1881,7 @@ { asio::post(self_->impl_.get_executor(), asio::detail::bind_handler(- ASIO_MOVE_CAST(ConnectHandler)(handler), open_ec));+ static_cast<ConnectHandler&&>(handler), open_ec)); } else {@@ -1917,13 +1906,13 @@ { } - const executor_type& get_executor() const ASIO_NOEXCEPT+ const executor_type& get_executor() const noexcept { return self_->get_executor(); } template <typename WaitHandler>- void operator()(ASIO_MOVE_ARG(WaitHandler) handler, wait_type w) const+ void operator()(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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -15,6 +15,7 @@ # 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"@@ -37,10 +38,6 @@ # 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 {@@ -151,9 +148,9 @@ */ template <typename ExecutionContext> explicit basic_socket_acceptor(ExecutionContext& context,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value- >::type = 0)+ > = 0) : impl_(0, 0, context) { }@@ -193,10 +190,10 @@ template <typename ExecutionContext> basic_socket_acceptor(ExecutionContext& context, const protocol_type& protocol,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- >::type = defaulted_constraint())+ > = defaulted_constraint()) : impl_(0, 0, context) { asio::error_code ec;@@ -282,9 +279,9 @@ template <typename ExecutionContext> basic_socket_acceptor(ExecutionContext& context, const endpoint_type& endpoint, bool reuse_addr = true,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value- >::type = 0)+ > = 0) : impl_(0, 0, context) { asio::error_code ec;@@ -347,9 +344,9 @@ template <typename ExecutionContext> basic_socket_acceptor(ExecutionContext& context, const protocol_type& protocol, const native_handle_type& native_acceptor,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value- >::type = 0)+ > = 0) : impl_(0, 0, context) { asio::error_code ec;@@ -358,7 +355,6 @@ 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.@@ -370,7 +366,7 @@ * constructed using the @c basic_socket_acceptor(const executor_type&) * constructor. */- basic_socket_acceptor(basic_socket_acceptor&& other) ASIO_NOEXCEPT+ basic_socket_acceptor(basic_socket_acceptor&& other) noexcept : impl_(std::move(other.impl_)) { }@@ -410,10 +406,10 @@ */ template <typename Protocol1, typename Executor1> basic_socket_acceptor(basic_socket_acceptor<Protocol1, Executor1>&& other,- typename constraint<+ constraint_t< is_convertible<Protocol1, Protocol>::value && is_convertible<Executor1, Executor>::value- >::type = 0)+ > = 0) : impl_(std::move(other.impl_)) { }@@ -431,17 +427,16 @@ * constructor. */ template <typename Protocol1, typename Executor1>- typename constraint<+ constraint_t< is_convertible<Protocol1, Protocol>::value && is_convertible<Executor1, Executor>::value, basic_socket_acceptor&- >::type operator=(basic_socket_acceptor<Protocol1, Executor1>&& other)+ > 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. /**@@ -454,7 +449,7 @@ } /// Get the executor associated with the object.- const executor_type& get_executor() ASIO_NOEXCEPT+ const executor_type& get_executor() noexcept { return impl_.get_executor(); }@@ -1218,7 +1213,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code) @endcode@@ -1254,15 +1249,12 @@ */ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code))- 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((+ WaitToken = default_completion_token_t<executor_type>>+ auto async_wait(wait_type w,+ WaitToken&& token = default_completion_token_t<executor_type>())+ -> decltype( 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);@@ -1289,9 +1281,9 @@ */ template <typename Protocol1, typename Executor1> void accept(basic_socket<Protocol1, Executor1>& peer,- typename constraint<+ constraint_t< is_convertible<Protocol, Protocol1>::value- >::type = 0)+ > = 0) { asio::error_code ec; impl_.get_service().accept(impl_.get_implementation(),@@ -1325,9 +1317,9 @@ template <typename Protocol1, typename Executor1> ASIO_SYNC_OP_VOID accept( basic_socket<Protocol1, Executor1>& peer, asio::error_code& ec,- typename constraint<+ constraint_t< is_convertible<Protocol, Protocol1>::value- >::type = 0)+ > = 0) { impl_.get_service().accept(impl_.get_implementation(), peer, static_cast<endpoint_type*>(0), ec);@@ -1356,7 +1348,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code) @endcode@@ -1391,19 +1383,16 @@ */ template <typename Protocol1, typename Executor1, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code))- 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<+ 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< is_convertible<Protocol, Protocol1>::value- >::type = 0)- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ > = 0)+ -> decltype( 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,@@ -1507,7 +1496,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code) @endcode@@ -1524,23 +1513,19 @@ */ template <typename Executor1, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code))- 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,+ AcceptToken = default_completion_token_t<executor_type>>+ auto async_accept(basic_socket<protocol_type, Executor1>& peer, endpoint_type& peer_endpoint,- ASIO_MOVE_ARG(AcceptToken) token- ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ AcceptToken&& token = default_completion_token_t<executor_type>())+ -> decltype( 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@@ -1631,7 +1616,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code,@@ -1670,22 +1655,17 @@ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, typename Protocol::socket::template rebind_executor< executor_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<executor_type>::other))- async_accept(- ASIO_MOVE_ARG(MoveAcceptToken) token- ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ = default_completion_token_t<executor_type>>+ auto async_accept(+ MoveAcceptToken&& token = default_completion_token_t<executor_type>())+ -> decltype( async_initiate<MoveAcceptToken, void (asio::error_code, typename Protocol::socket::template rebind_executor<executor_type>::other)>( declval<initiate_async_move_accept>(), token,- declval<executor_type>(), static_cast<endpoint_type*>(0),+ declval<const 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@@ -1722,10 +1702,10 @@ template <typename Executor1> typename Protocol::socket::template rebind_executor<Executor1>::other accept(const Executor1& ex,- typename constraint<+ constraint_t< is_executor<Executor1>::value || execution::is_executor<Executor1>::value- >::type = 0)+ > = 0) { asio::error_code ec; typename Protocol::socket::template@@ -1762,9 +1742,9 @@ typename Protocol::socket::template rebind_executor< typename ExecutionContext::executor_type>::other accept(ExecutionContext& context,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value- >::type = 0)+ > = 0) { asio::error_code ec; typename Protocol::socket::template rebind_executor<@@ -1805,10 +1785,10 @@ template <typename Executor1> typename Protocol::socket::template rebind_executor<Executor1>::other accept(const Executor1& ex, asio::error_code& ec,- typename constraint<+ constraint_t< is_executor<Executor1>::value || execution::is_executor<Executor1>::value- >::type = 0)+ > = 0) { typename Protocol::socket::template rebind_executor<Executor1>::other peer(ex);@@ -1848,9 +1828,9 @@ typename Protocol::socket::template rebind_executor< typename ExecutionContext::executor_type>::other accept(ExecutionContext& context, asio::error_code& ec,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value- >::type = 0)+ > = 0) { typename Protocol::socket::template rebind_executor< typename ExecutionContext::executor_type>::other peer(context);@@ -1886,7 +1866,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code,@@ -1924,22 +1904,17 @@ template <typename Executor1, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, typename Protocol::socket::template rebind_executor<- typename constraint<is_executor<Executor1>::value+ constraint_t<is_executor<Executor1>::value || execution::is_executor<Executor1>::value,- 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<+ 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< is_executor<Executor1>::value || execution::is_executor<Executor1>::value- >::type = 0)- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ > = 0)+ -> decltype( async_initiate<MoveAcceptToken, void (asio::error_code, typename Protocol::socket::template rebind_executor<@@ -1947,7 +1922,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,@@ -1987,7 +1962,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code,@@ -2026,18 +2001,13 @@ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, typename Protocol::socket::template rebind_executor< typename ExecutionContext::executor_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<- typename ExecutionContext::executor_type>::other))- async_accept(ExecutionContext& context,- ASIO_MOVE_ARG(MoveAcceptToken) token- ASIO_DEFAULT_COMPLETION_TOKEN(executor_type),- typename constraint<+ = default_completion_token_t<executor_type>>+ auto async_accept(ExecutionContext& context,+ MoveAcceptToken&& token = default_completion_token_t<executor_type>(),+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value- >::type = 0)- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ > = 0)+ -> decltype( async_initiate<MoveAcceptToken, void (asio::error_code, typename Protocol::socket::template rebind_executor<@@ -2045,7 +2015,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,@@ -2162,7 +2132,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code,@@ -2202,22 +2172,17 @@ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, typename Protocol::socket::template rebind_executor< executor_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<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((+ = default_completion_token_t<executor_type>>+ auto async_accept(endpoint_type& peer_endpoint,+ MoveAcceptToken&& token = default_completion_token_t<executor_type>())+ -> decltype( async_initiate<MoveAcceptToken, void (asio::error_code, typename Protocol::socket::template rebind_executor<executor_type>::other)>( declval<initiate_async_move_accept>(), token,- declval<executor_type>(), &peer_endpoint,+ declval<const 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@@ -2259,10 +2224,10 @@ template <typename Executor1> typename Protocol::socket::template rebind_executor<Executor1>::other accept(const Executor1& ex, endpoint_type& peer_endpoint,- typename constraint<+ constraint_t< is_executor<Executor1>::value || execution::is_executor<Executor1>::value- >::type = 0)+ > = 0) { asio::error_code ec; typename Protocol::socket::template@@ -2305,9 +2270,9 @@ typename Protocol::socket::template rebind_executor< typename ExecutionContext::executor_type>::other accept(ExecutionContext& context, endpoint_type& peer_endpoint,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value- >::type = 0)+ > = 0) { asio::error_code ec; typename Protocol::socket::template rebind_executor<@@ -2355,10 +2320,10 @@ typename Protocol::socket::template rebind_executor<Executor1>::other accept(const executor_type& ex, endpoint_type& peer_endpoint, asio::error_code& ec,- typename constraint<+ constraint_t< is_executor<Executor1>::value || execution::is_executor<Executor1>::value- >::type = 0)+ > = 0) { typename Protocol::socket::template rebind_executor<Executor1>::other peer(ex);@@ -2405,9 +2370,9 @@ typename ExecutionContext::executor_type>::other accept(ExecutionContext& context, endpoint_type& peer_endpoint, asio::error_code& ec,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value- >::type = 0)+ > = 0) { typename Protocol::socket::template rebind_executor< typename ExecutionContext::executor_type>::other peer(context);@@ -2449,7 +2414,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code,@@ -2488,29 +2453,24 @@ template <typename Executor1, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, typename Protocol::socket::template rebind_executor<- typename constraint<is_executor<Executor1>::value+ constraint_t<is_executor<Executor1>::value || execution::is_executor<Executor1>::value,- 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<+ 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< is_executor<Executor1>::value || execution::is_executor<Executor1>::value- >::type = 0)- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ > = 0)+ -> decltype( 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,@@ -2554,7 +2514,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code,@@ -2594,19 +2554,13 @@ ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, typename Protocol::socket::template rebind_executor< typename ExecutionContext::executor_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<- 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<+ = 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< is_convertible<ExecutionContext&, execution_context&>::value- >::type = 0)- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ > = 0)+ -> decltype( async_initiate<MoveAcceptToken, void (asio::error_code, typename Protocol::socket::template rebind_executor<@@ -2614,7 +2568,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,@@ -2625,13 +2579,12 @@ 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&) ASIO_DELETED;+ basic_socket_acceptor(const basic_socket_acceptor&) = delete; basic_socket_acceptor& operator=(- const basic_socket_acceptor&) ASIO_DELETED;+ const basic_socket_acceptor&) = delete; class initiate_async_wait {@@ -2643,13 +2596,13 @@ { } - const executor_type& get_executor() const ASIO_NOEXCEPT+ const executor_type& get_executor() const noexcept { return self_->get_executor(); } template <typename WaitHandler>- void operator()(ASIO_MOVE_ARG(WaitHandler) handler, wait_type w) const+ void operator()(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.@@ -2675,13 +2628,13 @@ { } - const executor_type& get_executor() const ASIO_NOEXCEPT+ const executor_type& get_executor() const noexcept { return self_->get_executor(); } template <typename AcceptHandler, typename Protocol1, typename Executor1>- void operator()(ASIO_MOVE_ARG(AcceptHandler) handler,+ void operator()(AcceptHandler&& handler, basic_socket<Protocol1, Executor1>* peer, endpoint_type* peer_endpoint) const {@@ -2709,13 +2662,13 @@ { } - const executor_type& get_executor() const ASIO_NOEXCEPT+ const executor_type& get_executor() const noexcept { return self_->get_executor(); } template <typename MoveAcceptHandler, typename Executor1, typename Socket>- void operator()(ASIO_MOVE_ARG(MoveAcceptHandler) handler,+ void operator()(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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -23,55 +23,6 @@ #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 {@@ -87,7 +38,6 @@ { } -#if defined(ASIO_HAS_MOVE) socket_iostream_base(socket_iostream_base&& other) : streambuf_(std::move(other.streambuf_)) {@@ -103,7 +53,6 @@ streambuf_ = std::move(other.streambuf_); return *this; }-#endif // defined(ASIO_HAS_MOVE) basic_socket_streambuf<Protocol, Clock, WaitTraits> streambuf_; };@@ -115,16 +64,8 @@ // 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> >-#endif // defined(ASIO_HAS_BOOST_DATE_TIME)- // && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)+ typename WaitTraits = wait_traits<Clock>> class basic_socket_iostream; #endif // !defined(ASIO_BASIC_SOCKET_IOSTREAM_FWD_DECL)@@ -133,7 +74,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)@@ -142,16 +83,7 @@ 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.@@ -164,22 +96,12 @@ 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@@ -193,7 +115,6 @@ 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<@@ -205,8 +126,6 @@ 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<@@ -225,20 +144,13 @@ 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>(@@ -249,29 +161,19 @@ 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()@@ -311,18 +213,6 @@ 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.@@ -360,47 +250,16 @@ 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&) ASIO_DELETED;+ basic_socket_iostream(const basic_socket_iostream&) = delete; basic_socket_iostream& operator=(- const basic_socket_iostream&) ASIO_DELETED;+ const basic_socket_iostream&) = delete; }; } // 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -27,47 +27,7 @@ #include "asio/detail/memory.hpp" #include "asio/detail/throw_error.hpp" #include "asio/io_context.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/steady_timer.hpp" #include "asio/detail/push_options.hpp" @@ -113,16 +73,8 @@ // 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> >-#endif // defined(ASIO_HAS_BOOST_DATE_TIME)- // && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)+ typename WaitTraits = wait_traits<Clock>> class basic_socket_streambuf; #endif // !defined(ASIO_BASIC_SOCKET_STREAMBUF_FWD_DECL)@@ -131,7 +83,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)@@ -139,23 +91,10 @@ : 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.@@ -168,22 +107,12 @@ 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@@ -197,7 +126,6 @@ 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),@@ -241,7 +169,6 @@ other.init_buffers(); return *this; }-#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Destructor flushes buffered data. virtual ~basic_socket_streambuf()@@ -265,7 +192,6 @@ return !ec_ ? this : 0; } -#if defined(GENERATING_DOCUMENTATION) /// Establish a connection. /** * This function automatically establishes a connection based on the supplied@@ -275,9 +201,6 @@ * @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) {@@ -287,9 +210,6 @@ connect_to_endpoints(resolver.resolve(x..., ec_)); return !ec_ ? this : 0; }-#else- ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_CONNECT_DEF)-#endif /// Close the connection. /**@@ -321,30 +241,6 @@ 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@@ -383,33 +279,6 @@ 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() {@@ -559,9 +428,9 @@ private: // Disallow copying and assignment.- basic_socket_streambuf(const basic_socket_streambuf&) ASIO_DELETED;+ basic_socket_streambuf(const basic_socket_streambuf&) = delete; basic_socket_streambuf& operator=(- const basic_socket_streambuf&) ASIO_DELETED;+ const basic_socket_streambuf&) = delete; void init_buffers() {@@ -659,14 +528,7 @@ // 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 };@@ -677,10 +539,6 @@ } // 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -106,10 +106,10 @@ */ template <typename ExecutionContext> explicit basic_stream_file(ExecutionContext& context,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- >::type = defaulted_constraint())+ > = 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,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- >::type = defaulted_constraint())+ > = 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,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- >::type = defaulted_constraint())+ > = defaulted_constraint()) : basic_file<Executor>(context) { asio::error_code ec;@@ -272,17 +272,16 @@ template <typename ExecutionContext> basic_stream_file(ExecutionContext& context, const native_handle_type& native_file,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- >::type = defaulted_constraint())+ > = 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.@@ -294,7 +293,7 @@ * constructed using the @c basic_stream_file(const executor_type&) * constructor. */- basic_stream_file(basic_stream_file&& other) ASIO_NOEXCEPT+ basic_stream_file(basic_stream_file&& other) noexcept : basic_file<Executor>(std::move(other)) { }@@ -330,10 +329,10 @@ */ template <typename Executor1> basic_stream_file(basic_stream_file<Executor1>&& other,- typename constraint<+ constraint_t< is_convertible<Executor1, Executor>::value, defaulted_constraint- >::type = defaulted_constraint())+ > = defaulted_constraint()) : basic_file<Executor>(std::move(other)) { }@@ -350,15 +349,14 @@ * constructor. */ template <typename Executor1>- typename constraint<+ constraint_t< is_convertible<Executor1, Executor>::value, basic_stream_file&- >::type operator=(basic_stream_file<Executor1>&& other)+ > 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. /**@@ -492,7 +490,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -522,17 +520,13 @@ */ template <typename ConstBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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((+ 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( 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)>(@@ -624,7 +618,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -655,17 +649,13 @@ */ template <typename MutableBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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((+ 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( 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)>(@@ -674,8 +664,8 @@ private: // Disallow copying and assignment.- basic_stream_file(const basic_stream_file&) ASIO_DELETED;- basic_stream_file& operator=(const basic_stream_file&) ASIO_DELETED;+ basic_stream_file(const basic_stream_file&) = delete;+ basic_stream_file& operator=(const basic_stream_file&) = delete; class initiate_async_write_some {@@ -687,13 +677,13 @@ { } - const executor_type& get_executor() const ASIO_NOEXCEPT+ const executor_type& get_executor() const noexcept { return self_->get_executor(); } template <typename WriteHandler, typename ConstBufferSequence>- void operator()(ASIO_MOVE_ARG(WriteHandler) handler,+ void operator()(WriteHandler&& handler, const ConstBufferSequence& buffers) const { // If you get an error on the following line it means that your handler@@ -720,13 +710,13 @@ { } - const executor_type& get_executor() const ASIO_NOEXCEPT+ const executor_type& get_executor() const noexcept { return self_->get_executor(); } template <typename ReadHandler, typename MutableBufferSequence>- void operator()(ASIO_MOVE_ARG(ReadHandler) handler,+ void operator()(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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -116,9 +116,9 @@ */ template <typename ExecutionContext> explicit basic_stream_socket(ExecutionContext& context,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value- >::type = 0)+ > = 0) : basic_socket<Protocol, Executor>(context) { }@@ -155,10 +155,10 @@ */ template <typename ExecutionContext> basic_stream_socket(ExecutionContext& context, const protocol_type& protocol,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- >::type = defaulted_constraint())+ > = defaulted_constraint()) : basic_socket<Protocol, Executor>(context, protocol) { }@@ -201,9 +201,9 @@ */ template <typename ExecutionContext> basic_stream_socket(ExecutionContext& context, const endpoint_type& endpoint,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value- >::type = 0)+ > = 0) : basic_socket<Protocol, Executor>(context, endpoint) { }@@ -246,14 +246,13 @@ template <typename ExecutionContext> basic_stream_socket(ExecutionContext& context, const protocol_type& protocol, const native_handle_type& native_socket,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value- >::type = 0)+ > = 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.@@ -265,7 +264,7 @@ * constructed using the @c basic_stream_socket(const executor_type&) * constructor. */- basic_stream_socket(basic_stream_socket&& other) ASIO_NOEXCEPT+ basic_stream_socket(basic_stream_socket&& other) noexcept : basic_socket<Protocol, Executor>(std::move(other)) { }@@ -301,10 +300,10 @@ */ template <typename Protocol1, typename Executor1> basic_stream_socket(basic_stream_socket<Protocol1, Executor1>&& other,- typename constraint<+ constraint_t< is_convertible<Protocol1, Protocol>::value && is_convertible<Executor1, Executor>::value- >::type = 0)+ > = 0) : basic_socket<Protocol, Executor>(std::move(other)) { }@@ -321,16 +320,15 @@ * constructor. */ template <typename Protocol1, typename Executor1>- typename constraint<+ constraint_t< is_convertible<Protocol1, Protocol>::value && is_convertible<Executor1, Executor>::value, basic_stream_socket&- >::type operator=(basic_stream_socket<Protocol1, Executor1>&& other)+ > 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. /**@@ -463,7 +461,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -493,18 +491,14 @@ */ template <typename ConstBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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((+ 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( 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)>(@@ -537,7 +531,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -567,18 +561,14 @@ */ template <typename ConstBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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,+ std::size_t)) WriteToken = default_completion_token_t<executor_type>>+ auto async_send(const ConstBufferSequence& buffers, socket_base::message_flags flags,- ASIO_MOVE_ARG(WriteToken) token- ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ WriteToken&& token = default_completion_token_t<executor_type>())+ -> decltype( 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)>(@@ -713,7 +703,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -745,18 +735,14 @@ */ template <typename MutableBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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((+ 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( 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)>(@@ -789,7 +775,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -821,18 +807,14 @@ */ template <typename MutableBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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,+ std::size_t)) ReadToken = default_completion_token_t<executor_type>>+ auto async_receive(const MutableBufferSequence& buffers, socket_base::message_flags flags,- ASIO_MOVE_ARG(ReadToken) token- ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ ReadToken&& token = default_completion_token_t<executor_type>())+ -> decltype( 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)>(@@ -923,7 +905,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -953,18 +935,14 @@ */ template <typename ConstBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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((+ 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( 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)>(@@ -1058,7 +1036,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -1089,18 +1067,14 @@ */ template <typename MutableBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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((+ 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( 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)>(@@ -1110,8 +1084,8 @@ private: // Disallow copying and assignment.- basic_stream_socket(const basic_stream_socket&) ASIO_DELETED;- basic_stream_socket& operator=(const basic_stream_socket&) ASIO_DELETED;+ basic_stream_socket(const basic_stream_socket&) = delete;+ basic_stream_socket& operator=(const basic_stream_socket&) = delete; class initiate_async_send {@@ -1123,13 +1097,13 @@ { } - const executor_type& get_executor() const ASIO_NOEXCEPT+ const executor_type& get_executor() const noexcept { return self_->get_executor(); } template <typename WriteHandler, typename ConstBufferSequence>- void operator()(ASIO_MOVE_ARG(WriteHandler) handler,+ void operator()(WriteHandler&& handler, const ConstBufferSequence& buffers, socket_base::message_flags flags) const {@@ -1157,13 +1131,13 @@ { } - const executor_type& get_executor() const ASIO_NOEXCEPT+ const executor_type& get_executor() const noexcept { return self_->get_executor(); } template <typename ReadHandler, typename MutableBufferSequence>- void operator()(ASIO_MOVE_ARG(ReadHandler) handler,+ void operator()(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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -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 ASIO_CONST_BUFFER const_buffers_type;- typedef ASIO_MUTABLE_BUFFER mutable_buffers_type;+ typedef const_buffer const_buffers_type;+ typedef mutable_buffer mutable_buffers_type; #endif /// Construct a basic_streambuf object.@@ -155,7 +155,7 @@ * } * @endcode */- std::size_t size() const ASIO_NOEXCEPT+ std::size_t size() const 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 ASIO_NOEXCEPT+ std::size_t max_size() const 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 ASIO_NOEXCEPT+ std::size_t capacity() const 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 ASIO_NOEXCEPT+ const_buffers_type data() const 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,39 +383,37 @@ } /// Copy construct a basic_streambuf_ref.- basic_streambuf_ref(const basic_streambuf_ref& other) ASIO_NOEXCEPT+ basic_streambuf_ref(const basic_streambuf_ref& other) 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) ASIO_NOEXCEPT+ basic_streambuf_ref(basic_streambuf_ref&& other) noexcept : sb_(other.sb_) { }-#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Get the size of the input sequence.- std::size_t size() const ASIO_NOEXCEPT+ std::size_t size() const noexcept { return sb_.size(); } /// Get the maximum size of the dynamic buffer.- std::size_t max_size() const ASIO_NOEXCEPT+ std::size_t max_size() const noexcept { return sb_.max_size(); } /// Get the current capacity of the dynamic buffer.- std::size_t capacity() const ASIO_NOEXCEPT+ std::size_t capacity() const noexcept { return sb_.capacity(); } /// Get a list of buffers that represents the input sequence.- const_buffers_type data() const ASIO_NOEXCEPT+ const_buffers_type data() const 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -17,6 +17,7 @@ #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"@@ -27,10 +28,6 @@ #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 {@@ -78,7 +75,7 @@ * timer.wait(); * @endcode *- * @par + * @par * Performing an asynchronous wait (C++11): * @code * void handler(const asio::error_code& error)@@ -194,9 +191,9 @@ */ template <typename ExecutionContext> explicit basic_waitable_timer(ExecutionContext& context,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value- >::type = 0)+ > = 0) : impl_(0, 0, context) { }@@ -233,9 +230,9 @@ template <typename ExecutionContext> explicit basic_waitable_timer(ExecutionContext& context, const time_point& expiry_time,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value- >::type = 0)+ > = 0) : impl_(0, 0, context) { asio::error_code ec;@@ -276,9 +273,9 @@ template <typename ExecutionContext> explicit basic_waitable_timer(ExecutionContext& context, const duration& expiry_time,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value- >::type = 0)+ > = 0) : impl_(0, 0, context) { asio::error_code ec;@@ -287,7 +284,6 @@ 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.@@ -340,9 +336,9 @@ template <typename Executor1> basic_waitable_timer( basic_waitable_timer<Clock, WaitTraits, Executor1>&& other,- typename constraint<+ constraint_t< is_convertible<Executor1, Executor>::value- >::type = 0)+ > = 0) : impl_(std::move(other.impl_)) { }@@ -360,16 +356,15 @@ * constructor. */ template <typename Executor1>- typename constraint<+ constraint_t< is_convertible<Executor1, Executor>::value, basic_waitable_timer&- >::type operator=(basic_waitable_timer<Clock, WaitTraits, Executor1>&& other)+ > 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. /**@@ -381,7 +376,7 @@ } /// Get the executor associated with the object.- const executor_type& get_executor() ASIO_NOEXCEPT+ const executor_type& get_executor() noexcept { return impl_.get_executor(); }@@ -416,36 +411,6 @@ 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@@ -479,49 +444,6 @@ 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.@@ -563,38 +485,6 @@ 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@@ -626,80 +516,6 @@ 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@@ -751,7 +567,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code) @endcode@@ -768,15 +584,12 @@ */ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code))- 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((+ WaitToken = default_completion_token_t<executor_type>>+ auto async_wait(+ WaitToken&& token = default_completion_token_t<executor_type>())+ -> decltype( 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);@@ -784,9 +597,8 @@ private: // Disallow copying and assignment.- basic_waitable_timer(const basic_waitable_timer&) ASIO_DELETED;- basic_waitable_timer& operator=(- const basic_waitable_timer&) ASIO_DELETED;+ basic_waitable_timer(const basic_waitable_timer&) = delete;+ basic_waitable_timer& operator=(const basic_waitable_timer&) = delete; class initiate_async_wait {@@ -798,13 +610,13 @@ { } - const executor_type& get_executor() const ASIO_NOEXCEPT+ const executor_type& get_executor() const noexcept { return self_->get_executor(); } template <typename WaitHandler>- void operator()(ASIO_MOVE_ARG(WaitHandler) handler) const+ void operator()(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.@@ -822,7 +634,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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -21,6 +21,7 @@ || 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"@@ -38,10 +39,6 @@ # 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 {@@ -112,10 +109,10 @@ */ template <typename ExecutionContext> explicit basic_writable_pipe(ExecutionContext& context,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- >::type = defaulted_constraint())+ > = defaulted_constraint()) : impl_(0, 0, context) { }@@ -159,9 +156,9 @@ template <typename ExecutionContext> basic_writable_pipe(ExecutionContext& context, const native_handle_type& native_pipe,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value- >::type = 0)+ > = 0) : impl_(0, 0, context) { asio::error_code ec;@@ -170,7 +167,6 @@ 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.@@ -221,10 +217,10 @@ */ template <typename Executor1> basic_writable_pipe(basic_writable_pipe<Executor1>&& other,- typename constraint<+ constraint_t< is_convertible<Executor1, Executor>::value, defaulted_constraint- >::type = defaulted_constraint())+ > = defaulted_constraint()) : impl_(std::move(other.impl_)) { }@@ -241,16 +237,15 @@ * constructor. */ template <typename Executor1>- typename constraint<+ constraint_t< is_convertible<Executor1, Executor>::value, basic_writable_pipe&- >::type operator=(basic_writable_pipe<Executor1>&& other)+ > 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. /**@@ -263,7 +258,7 @@ } /// Get the executor associated with the object.- const executor_type& get_executor() ASIO_NOEXCEPT+ const executor_type& get_executor() noexcept { return impl_.get_executor(); }@@ -537,7 +532,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -557,17 +552,13 @@ */ template <typename ConstBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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((+ 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( 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)>(@@ -576,8 +567,8 @@ private: // Disallow copying and assignment.- basic_writable_pipe(const basic_writable_pipe&) ASIO_DELETED;- basic_writable_pipe& operator=(const basic_writable_pipe&) ASIO_DELETED;+ basic_writable_pipe(const basic_writable_pipe&) = delete;+ basic_writable_pipe& operator=(const basic_writable_pipe&) = delete; class initiate_async_write_some {@@ -589,13 +580,13 @@ { } - const executor_type& get_executor() const ASIO_NOEXCEPT+ const executor_type& get_executor() const noexcept { return self_->get_executor(); } template <typename WriteHandler, typename ConstBufferSequence>- void operator()(ASIO_MOVE_ARG(WriteHandler) handler,+ void operator()(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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -16,11 +16,12 @@ #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" @@ -37,8 +38,7 @@ }; template <typename T>-struct allocator_binder_result_type<T,- typename void_type<typename T::result_type>::type>+struct allocator_binder_result_type<T, void_t<typename T::result_type>> { typedef typename T::result_type result_type; protected:@@ -99,8 +99,7 @@ struct allocator_binder_argument_type {}; template <typename T>-struct allocator_binder_argument_type<T,- typename void_type<typename T::argument_type>::type>+struct allocator_binder_argument_type<T, void_t<typename T::argument_type>> { typedef typename T::argument_type argument_type; };@@ -125,7 +124,7 @@ template <typename T> struct allocator_binder_argument_types<T,- typename void_type<typename T::first_argument_type>::type>+ void_t<typename T::first_argument_type>> { typedef typename T::first_argument_type first_argument_type; typedef typename T::second_argument_type second_argument_type;@@ -145,21 +144,6 @@ 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@@ -247,10 +231,9 @@ * @c U. */ template <typename U>- allocator_binder(const allocator_type& s,- ASIO_MOVE_ARG(U) u)+ allocator_binder(const allocator_type& s, U&& u) : allocator_(s),- target_(ASIO_MOVE_CAST(U)(u))+ target_(static_cast<U&&>(u)) { } @@ -262,8 +245,7 @@ } /// 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()) {@@ -276,8 +258,9 @@ * constructible from type @c U. */ template <typename U, typename OtherAllocator>- allocator_binder(- const allocator_binder<U, OtherAllocator>& other)+ 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_(other.get_allocator()), target_(other.get()) {@@ -291,19 +274,18 @@ */ template <typename U, typename OtherAllocator> allocator_binder(const allocator_type& s,- const allocator_binder<U, OtherAllocator>& other)+ const allocator_binder<U, OtherAllocator>& other,+ constraint_t<is_constructible<T, U>::value> = 0) : allocator_(s), target_(other.get()) { } -#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)- /// Move constructor. allocator_binder(allocator_binder&& other)- : allocator_(ASIO_MOVE_CAST(allocator_type)(+ : allocator_(static_cast<allocator_type&&>( other.get_allocator())),- target_(ASIO_MOVE_CAST(T)(other.get()))+ target_(static_cast<T&&>(other.get())) { } @@ -311,17 +293,19 @@ allocator_binder(const allocator_type& s, allocator_binder&& other) : allocator_(s),- target_(ASIO_MOVE_CAST(T)(other.get()))+ target_(static_cast<T&&>(other.get())) { } /// Move construct from a different allocator wrapper type. template <typename U, typename OtherAllocator> allocator_binder(- allocator_binder<U, OtherAllocator>&& other)- : allocator_(ASIO_MOVE_CAST(OtherAllocator)(+ 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&&>( other.get_allocator())),- target_(ASIO_MOVE_CAST(U)(other.get()))+ target_(static_cast<U&&>(other.get())) { } @@ -329,162 +313,148 @@ /// specify a different allocator. template <typename U, typename OtherAllocator> allocator_binder(const allocator_type& s,- allocator_binder<U, OtherAllocator>&& other)+ allocator_binder<U, OtherAllocator>&& other,+ constraint_t<is_constructible<T, U>::value> = 0) : allocator_(s),- target_(ASIO_MOVE_CAST(U)(other.get()))+ target_(static_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() ASIO_NOEXCEPT+ target_type& get() noexcept { return target_; } /// Obtain a reference to the target object.- const target_type& get() const ASIO_NOEXCEPT+ const target_type& get() const noexcept { return target_; } /// Obtain the associated allocator.- allocator_type get_allocator() const ASIO_NOEXCEPT+ allocator_type get_allocator() const 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>- typename result_of<T(Args...)>::type operator()(- ASIO_MOVE_ARG(Args)... args)+ result_of_t<T(Args...)> operator()(Args&&... args) & {- return target_(ASIO_MOVE_CAST(Args)(args)...);+ return target_(static_cast<Args&&>(args)...); } /// Forwarding function call operator. template <typename... Args>- typename result_of<T(Args...)>::type operator()(- ASIO_MOVE_ARG(Args)... args) const- {- return target_(ASIO_MOVE_CAST(Args)(args)...);- }--#elif defined(ASIO_HAS_STD_TYPE_TRAITS) && !defined(_MSC_VER)-- typename detail::allocator_binder_result_of0<T>::type operator()()+ result_of_t<T(Args...)> operator()(Args&&... args) && {- return target_();+ return static_cast<T&&>(target_)(static_cast<Args&&>(args)...); } - typename detail::allocator_binder_result_of0<T>::type- operator()() const+ /// Forwarding function call operator.+ template <typename... Args>+ result_of_t<T(Args...)> operator()(Args&&... args) const& {- return target_();+ return target_(static_cast<Args&&>(args)...); } -#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;+private:+ Allocator allocator_;+ T target_;+}; - result_type_or_void operator()()+/// 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) {- return target_(); } - result_type_or_void operator()() const+ /// 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 {- return target_();+ return allocator_binder<decay_t<CompletionToken>, Allocator>(+ allocator_, static_cast<CompletionToken&&>(completion_token)); } -#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:+//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<typename decay<T>::type, Allocator>-bind_allocator(const Allocator& s, ASIO_MOVE_ARG(T) t)+ASIO_NODISCARD inline allocator_binder<decay_t<T>, Allocator>+bind_allocator(const Allocator& s, T&& t) {- return allocator_binder<- typename decay<T>::type, Allocator>(- s, ASIO_MOVE_CAST(T)(t));+ return allocator_binder<decay_t<T>, Allocator>(s, static_cast<T&&>(t)); } #if !defined(GENERATING_DOCUMENTATION) namespace detail { -template <typename TargetAsyncResult,- typename Allocator, typename = void>-struct allocator_binder_async_result_completion_handler_type+template <typename TargetAsyncResult, typename Allocator, typename = void>+class allocator_binder_completion_handler_async_result {+public:+ template <typename T>+ explicit allocator_binder_completion_handler_async_result(T&)+ {+ } }; template <typename TargetAsyncResult, typename Allocator>-struct allocator_binder_async_result_completion_handler_type<- TargetAsyncResult, Allocator,- typename void_type<- typename TargetAsyncResult::completion_handler_type- >::type>+class allocator_binder_completion_handler_async_result<+ TargetAsyncResult, Allocator,+ void_t<typename TargetAsyncResult::completion_handler_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>@@ -494,10 +464,7 @@ template <typename TargetAsyncResult> struct allocator_binder_async_result_return_type<- TargetAsyncResult,- typename void_type<- typename TargetAsyncResult::return_type- >::type>+ TargetAsyncResult, void_type<typename TargetAsyncResult::return_type>> { typedef typename TargetAsyncResult::return_type return_type; };@@ -506,219 +473,122 @@ template <typename T, typename Allocator, typename Signature> class async_result<allocator_binder<T, Allocator>, Signature> :- public detail::allocator_binder_async_result_completion_handler_type<- async_result<T, Signature>, Allocator>,+ public detail::allocator_binder_completion_handler_async_result<+ 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)- : target_(b.get())+ : detail::allocator_binder_completion_handler_async_result<+ async_result<T, Signature>, Allocator>(b.get()) { } - typename async_result<T, Signature>::return_type get()- {- return target_.get();- }- template <typename Initiation>- struct init_wrapper+ struct init_wrapper : detail::initiation_base<Initiation> {- 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)+ using detail::initiation_base<Initiation>::initiation_base; template <typename Handler, typename... Args>- void operator()(- ASIO_MOVE_ARG(Handler) handler,- ASIO_MOVE_ARG(Args)... args)+ void operator()(Handler&& handler, const Allocator& a, 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)...);+ static_cast<Initiation&&>(*this)(+ allocator_binder<decay_t<Handler>, Allocator>(+ a, static_cast<Handler&&>(handler)),+ static_cast<Args&&>(args)...); } template <typename Handler, typename... Args>- void operator()(- ASIO_MOVE_ARG(Handler) handler,- ASIO_MOVE_ARG(Args)... args) const- {- 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+ void operator()(Handler&& handler,+ const Allocator& a, Args&&... args) const & {- initiation_(- allocator_binder<- typename decay<Handler>::type, Allocator>(- allocator_, ASIO_MOVE_CAST(Handler)(handler)));+ static_cast<const Initiation&>(*this)(+ allocator_binder<decay_t<Handler>, Allocator>(+ a, static_cast<Handler&&>(handler)),+ static_cast<Args&&>(args)...); }--#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 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<T, Signature>(- init_wrapper<typename decay<Initiation>::type>(- token.get_allocator(),- ASIO_MOVE_CAST(Initiation)(initiation)),- token.get(), ASIO_MOVE_CAST(Args)(args)...);- }--#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)-- 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)+ 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)...)) {- return async_initiate<T, Signature>(- init_wrapper<typename decay<Initiation>::type>(- token.get_allocator(),- ASIO_MOVE_CAST(Initiation)(initiation)),- token.get());+ 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)...); } -#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(const async_result&) = delete;+ async_result& operator=(const async_result&) = delete; async_result<T, Signature> target_; }; +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)...))+ {+ 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)...);+ }+};+ 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) ASIO_NOEXCEPT+ static typename Associator<T, DefaultCandidate>::type get(+ const allocator_binder<T, Allocator>& b) noexcept { return Associator<T, DefaultCandidate>::get(b.get()); } - 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)))+ static auto get(const allocator_binder<T, Allocator>& b,+ const DefaultCandidate& c) noexcept+ -> decltype(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 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()))+ static auto get(const allocator_binder<T, Allocator>& b,+ const Allocator1& = Allocator1()) noexcept+ -> decltype(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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -16,11 +16,12 @@ #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" @@ -37,8 +38,7 @@ }; template <typename T>-struct cancellation_slot_binder_result_type<T,- typename void_type<typename T::result_type>::type>+struct cancellation_slot_binder_result_type<T, void_t<typename T::result_type>> { typedef typename T::result_type result_type; protected:@@ -100,7 +100,7 @@ template <typename T> struct cancellation_slot_binder_argument_type<T,- typename void_type<typename T::argument_type>::type>+ void_t<typename T::argument_type>> { typedef typename T::argument_type argument_type; };@@ -125,7 +125,7 @@ template <typename T> struct cancellation_slot_binder_argument_types<T,- typename void_type<typename T::first_argument_type>::type>+ void_t<typename T::first_argument_type>> { typedef typename T::first_argument_type first_argument_type; typedef typename T::second_argument_type second_argument_type;@@ -145,21 +145,6 @@ 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@@ -247,10 +232,9 @@ * @c U. */ template <typename U>- cancellation_slot_binder(const cancellation_slot_type& s,- ASIO_MOVE_ARG(U) u)+ cancellation_slot_binder(const cancellation_slot_type& s, U&& u) : slot_(s),- target_(ASIO_MOVE_CAST(U)(u))+ target_(static_cast<U&&>(u)) { } @@ -277,7 +261,10 @@ */ template <typename U, typename OtherCancellationSlot> cancellation_slot_binder(- const cancellation_slot_binder<U, OtherCancellationSlot>& other)+ const cancellation_slot_binder<U, OtherCancellationSlot>& other,+ constraint_t<is_constructible<CancellationSlot,+ OtherCancellationSlot>::value> = 0,+ constraint_t<is_constructible<T, U>::value> = 0) : slot_(other.get_cancellation_slot()), target_(other.get()) {@@ -291,19 +278,18 @@ */ template <typename U, typename OtherCancellationSlot> cancellation_slot_binder(const cancellation_slot_type& s,- const cancellation_slot_binder<U, OtherCancellationSlot>& other)+ const cancellation_slot_binder<U, OtherCancellationSlot>& other,+ constraint_t<is_constructible<T, U>::value> = 0) : slot_(s), target_(other.get()) { } -#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)- /// Move constructor. cancellation_slot_binder(cancellation_slot_binder&& other)- : slot_(ASIO_MOVE_CAST(cancellation_slot_type)(+ : slot_(static_cast<cancellation_slot_type&&>( other.get_cancellation_slot())),- target_(ASIO_MOVE_CAST(T)(other.get()))+ target_(static_cast<T&&>(other.get())) { } @@ -312,17 +298,20 @@ cancellation_slot_binder(const cancellation_slot_type& s, cancellation_slot_binder&& other) : slot_(s),- target_(ASIO_MOVE_CAST(T)(other.get()))+ target_(static_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)- : slot_(ASIO_MOVE_CAST(OtherCancellationSlot)(+ 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&&>( other.get_cancellation_slot())),- target_(ASIO_MOVE_CAST(U)(other.get()))+ target_(static_cast<U&&>(other.get())) { } @@ -330,141 +319,111 @@ /// specify a different cancellation slot. template <typename U, typename OtherCancellationSlot> cancellation_slot_binder(const cancellation_slot_type& s,- cancellation_slot_binder<U, OtherCancellationSlot>&& other)+ cancellation_slot_binder<U, OtherCancellationSlot>&& other,+ constraint_t<is_constructible<T, U>::value> = 0) : slot_(s),- target_(ASIO_MOVE_CAST(U)(other.get()))+ target_(static_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() ASIO_NOEXCEPT+ target_type& get() noexcept { return target_; } /// Obtain a reference to the target object.- const target_type& get() const ASIO_NOEXCEPT+ const target_type& get() const noexcept { return target_; } /// Obtain the associated cancellation slot.- cancellation_slot_type get_cancellation_slot() const ASIO_NOEXCEPT+ cancellation_slot_type get_cancellation_slot() const 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>- typename result_of<T(Args...)>::type operator()(- ASIO_MOVE_ARG(Args)... args)+ result_of_t<T(Args...)> operator()(Args&&... args) & {- return target_(ASIO_MOVE_CAST(Args)(args)...);+ return target_(static_cast<Args&&>(args)...); } /// Forwarding function call operator. template <typename... Args>- typename result_of<T(Args...)>::type operator()(- ASIO_MOVE_ARG(Args)... args) const- {- return target_(ASIO_MOVE_CAST(Args)(args)...);- }--#elif defined(ASIO_HAS_STD_TYPE_TRAITS) && !defined(_MSC_VER)-- typename detail::cancellation_slot_binder_result_of0<T>::type operator()()+ result_of_t<T(Args...)> operator()(Args&&... args) && {- return target_();+ return static_cast<T&&>(target_)(static_cast<Args&&>(args)...); } - typename detail::cancellation_slot_binder_result_of0<T>::type- operator()() const+ /// Forwarding function call operator.+ template <typename... Args>+ result_of_t<T(Args...)> operator()(Args&&... args) const& {- return target_();+ return target_(static_cast<Args&&>(args)...); } -#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;+private:+ CancellationSlot slot_;+ T target_;+}; - result_type_or_void operator()()+/// 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) {- return target_(); } - result_type_or_void operator()() const+ /// 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 {- return target_();+ return cancellation_slot_binder<decay_t<CompletionToken>, CancellationSlot>(+ static_cast<CompletionToken&&>(completion_token), 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--#endif // defined(ASIO_HAS_STD_TYPE_TRAITS) && !defined(_MSC_VER)--private:- CancellationSlot slot_;- T target_;+//private:+ CancellationSlot cancellation_slot_; }; +/// 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);+}+ /// 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<typename decay<T>::type, CancellationSlot>-bind_cancellation_slot(const CancellationSlot& s, ASIO_MOVE_ARG(T) t)+cancellation_slot_binder<decay_t<T>, CancellationSlot>+bind_cancellation_slot(const CancellationSlot& s, T&& t) {- return cancellation_slot_binder<- typename decay<T>::type, CancellationSlot>(- s, ASIO_MOVE_CAST(T)(t));+ return cancellation_slot_binder<decay_t<T>, CancellationSlot>(+ s, static_cast<T&&>(t)); } #if !defined(GENERATING_DOCUMENTATION)@@ -472,21 +431,39 @@ namespace detail { template <typename TargetAsyncResult,- typename CancellationSlot, typename = void>-struct cancellation_slot_binder_async_result_completion_handler_type+ typename CancellationSlot, typename = void>+class cancellation_slot_binder_completion_handler_async_result {+public:+ template <typename T>+ explicit cancellation_slot_binder_completion_handler_async_result(T&)+ {+ } }; template <typename TargetAsyncResult, typename CancellationSlot>-struct cancellation_slot_binder_async_result_completion_handler_type<- TargetAsyncResult, CancellationSlot,- typename void_type<- typename TargetAsyncResult::completion_handler_type- >::type>+class cancellation_slot_binder_completion_handler_async_result<+ TargetAsyncResult, CancellationSlot,+ void_t<typename TargetAsyncResult::completion_handler_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>@@ -496,10 +473,7 @@ template <typename TargetAsyncResult> struct cancellation_slot_binder_async_result_return_type<- TargetAsyncResult,- typename void_type<- typename TargetAsyncResult::return_type- >::type>+ TargetAsyncResult, void_t<typename TargetAsyncResult::return_type>> { typedef typename TargetAsyncResult::return_type return_type; };@@ -508,184 +482,99 @@ template <typename T, typename CancellationSlot, typename Signature> class async_result<cancellation_slot_binder<T, CancellationSlot>, Signature> :- public detail::cancellation_slot_binder_async_result_completion_handler_type<- async_result<T, Signature>, CancellationSlot>,+ public detail::cancellation_slot_binder_completion_handler_async_result<+ 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)- : target_(b.get())+ : detail::cancellation_slot_binder_completion_handler_async_result<+ async_result<T, Signature>, CancellationSlot>(b.get()) { } - typename async_result<T, Signature>::return_type get()- {- return target_.get();- }- template <typename Initiation>- struct init_wrapper+ struct init_wrapper : detail::initiation_base<Initiation> {- 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)+ using detail::initiation_base<Initiation>::initiation_base; template <typename Handler, typename... Args>- void operator()(- ASIO_MOVE_ARG(Handler) handler,- ASIO_MOVE_ARG(Args)... args)+ void operator()(Handler&& handler,+ const CancellationSlot& slot, 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)...);+ static_cast<Initiation&&>(*this)(+ cancellation_slot_binder<decay_t<Handler>, CancellationSlot>(+ slot, static_cast<Handler&&>(handler)),+ static_cast<Args&&>(args)...); } template <typename Handler, typename... Args>- void operator()(- ASIO_MOVE_ARG(Handler) handler,- ASIO_MOVE_ARG(Args)... args) const- {- 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+ void operator()(Handler&& handler,+ const CancellationSlot& slot, Args&&... args) const & {- initiation_(- cancellation_slot_binder<- typename decay<Handler>::type, CancellationSlot>(- slot_, ASIO_MOVE_CAST(Handler)(handler)));+ static_cast<const Initiation&>(*this)(+ cancellation_slot_binder<decay_t<Handler>, CancellationSlot>(+ slot, static_cast<Handler&&>(handler)),+ static_cast<Args&&>(args)...); }--#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 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<T, Signature>(- init_wrapper<typename decay<Initiation>::type>(- token.get_cancellation_slot(),- ASIO_MOVE_CAST(Initiation)(initiation)),- token.get(), ASIO_MOVE_CAST(Args)(args)...);- }--#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)-- 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)+ 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)...)) {- return async_initiate<T, Signature>(- init_wrapper<typename decay<Initiation>::type>(- token.get_cancellation_slot(),- ASIO_MOVE_CAST(Initiation)(initiation)),- token.get());+ 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)...); } -#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(const async_result&) = delete;+ async_result& operator=(const async_result&) = delete; async_result<T, Signature> target_; }; +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)...))+ {+ 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)...);+ }+};+ template <template <typename, typename> class Associator, typename T, typename CancellationSlot, typename DefaultCandidate> struct associator<Associator,@@ -693,19 +582,15 @@ DefaultCandidate> : Associator<T, DefaultCandidate> {- static typename Associator<T, DefaultCandidate>::type- get(const cancellation_slot_binder<T, CancellationSlot>& b)- ASIO_NOEXCEPT+ static typename Associator<T, DefaultCandidate>::type get(+ const cancellation_slot_binder<T, CancellationSlot>& b) noexcept { return Associator<T, DefaultCandidate>::get(b.get()); } - 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)))+ static auto get(const cancellation_slot_binder<T, CancellationSlot>& b,+ const DefaultCandidate& c) noexcept+ -> decltype(Associator<T, DefaultCandidate>::get(b.get(), c)) { return Associator<T, DefaultCandidate>::get(b.get(), c); }@@ -718,10 +603,9 @@ { typedef CancellationSlot type; - 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()))+ static auto get(const cancellation_slot_binder<T, CancellationSlot>& b,+ const CancellationSlot1& = CancellationSlot1()) noexcept+ -> decltype(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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -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,8 +41,7 @@ }; template <typename T>-struct executor_binder_result_type<T,- typename void_type<typename T::result_type>::type>+struct executor_binder_result_type<T, void_t<typename T::result_type>> { typedef typename T::result_type result_type; protected:@@ -103,8 +102,7 @@ struct executor_binder_argument_type {}; template <typename T>-struct executor_binder_argument_type<T,- typename void_type<typename T::argument_type>::type>+struct executor_binder_argument_type<T, void_t<typename T::argument_type>> { typedef typename T::argument_type argument_type; };@@ -129,7 +127,7 @@ template <typename T> struct executor_binder_argument_types<T,- typename void_type<typename T::first_argument_type>::type>+ void_t<typename T::first_argument_type>> { typedef typename T::first_argument_type first_argument_type; typedef typename T::second_argument_type second_argument_type;@@ -160,9 +158,9 @@ { protected: template <typename E, typename 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))+ executor_binder_base(E&& e, U&& u)+ : executor_(static_cast<E&&>(e)),+ target_(executor_arg_t(), executor_, static_cast<U&&>(u)) { } @@ -175,9 +173,9 @@ { protected: template <typename E, typename 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))+ executor_binder_base(E&& e, U&& u)+ : executor_(static_cast<E&&>(e)),+ target_(static_cast<U&&>(u)) { } @@ -185,21 +183,6 @@ 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@@ -290,8 +273,8 @@ */ template <typename U> executor_binder(executor_arg_t, const executor_type& e,- ASIO_MOVE_ARG(U) u)- : base_type(e, ASIO_MOVE_CAST(U)(u))+ U&& u)+ : base_type(e, static_cast<U&&>(u)) { } @@ -315,7 +298,9 @@ * @c U. */ template <typename U, typename OtherExecutor>- executor_binder(const executor_binder<U, OtherExecutor>& other)+ executor_binder(const executor_binder<U, OtherExecutor>& other,+ constraint_t<is_constructible<Executor, OtherExecutor>::value> = 0,+ constraint_t<is_constructible<T, U>::value> = 0) : base_type(other.get_executor(), other.get()) { }@@ -328,32 +313,33 @@ */ template <typename U, typename OtherExecutor> executor_binder(executor_arg_t, const executor_type& e,- const executor_binder<U, OtherExecutor>& other)+ const executor_binder<U, OtherExecutor>& other,+ constraint_t<is_constructible<T, U>::value> = 0) : base_type(e, other.get()) { } -#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)- /// Move constructor. executor_binder(executor_binder&& other)- : base_type(ASIO_MOVE_CAST(executor_type)(other.get_executor()),- ASIO_MOVE_CAST(T)(other.get()))+ : base_type(static_cast<executor_type&&>(other.get_executor()),+ static_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, ASIO_MOVE_CAST(T)(other.get()))+ : base_type(e, static_cast<T&&>(other.get())) { } /// Move construct from a different executor wrapper type. template <typename U, typename OtherExecutor>- executor_binder(executor_binder<U, OtherExecutor>&& other)- : base_type(ASIO_MOVE_CAST(OtherExecutor)(other.get_executor()),- ASIO_MOVE_CAST(U)(other.get()))+ 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())) { } @@ -361,152 +347,141 @@ /// different executor. template <typename U, typename OtherExecutor> executor_binder(executor_arg_t, const executor_type& e,- executor_binder<U, OtherExecutor>&& other)- : base_type(e, ASIO_MOVE_CAST(U)(other.get()))+ executor_binder<U, OtherExecutor>&& other,+ constraint_t<is_constructible<T, U>::value> = 0)+ : base_type(e, static_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() ASIO_NOEXCEPT+ target_type& get() noexcept { return this->target_; } /// Obtain a reference to the target object.- const target_type& get() const ASIO_NOEXCEPT+ const target_type& get() const noexcept { return this->target_; } /// Obtain the associated executor.- executor_type get_executor() const ASIO_NOEXCEPT+ executor_type get_executor() const 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>- typename result_of<T(Args...)>::type operator()(- ASIO_MOVE_ARG(Args)... args)+ result_of_t<T(Args...)> operator()(Args&&... args) & {- return this->target_(ASIO_MOVE_CAST(Args)(args)...);+ return this->target_(static_cast<Args&&>(args)...); } /// Forwarding function call operator. template <typename... Args>- typename result_of<T(Args...)>::type operator()(- ASIO_MOVE_ARG(Args)... args) const- {- return this->target_(ASIO_MOVE_CAST(Args)(args)...);- }--#elif defined(ASIO_HAS_STD_TYPE_TRAITS) && !defined(_MSC_VER)-- typename detail::executor_binder_result_of0<T>::type operator()()+ result_of_t<T(Args...)> operator()(Args&&... args) && {- return this->target_();+ return static_cast<T&&>(this->target_)(static_cast<Args&&>(args)...); } - typename detail::executor_binder_result_of0<T>::type operator()() const+ /// Forwarding function call operator.+ template <typename... Args>+ result_of_t<T(Args...)> operator()(Args&&... args) const& {- return this->target_();+ return this->target_(static_cast<Args&&>(args)...); } -#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;+private:+ typedef detail::executor_binder_base<T, Executor,+ uses_executor<T, Executor>::value> base_type;+}; - result_type_or_void operator()()+/// 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) {- return this->target_(); } - result_type_or_void operator()() const+ /// 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 {- return this->target_();+ return executor_binder<decay_t<CompletionToken>, Executor>(executor_arg_t(),+ static_cast<CompletionToken&&>(completion_token), 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--#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;+//private:+ Executor executor_; }; +/// 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);+}+ /// Associate an object of type @c T with an executor of type @c Executor. template <typename Executor, typename T>-ASIO_NODISCARD inline executor_binder<typename decay<T>::type, Executor>-bind_executor(const Executor& ex, ASIO_MOVE_ARG(T) t,- typename constraint<+ASIO_NODISCARD inline executor_binder<decay_t<T>, Executor>+bind_executor(const Executor& ex, T&& t,+ constraint_t< is_executor<Executor>::value || execution::is_executor<Executor>::value- >::type = 0)+ > = 0) {- return executor_binder<typename decay<T>::type, Executor>(- executor_arg_t(), ex, ASIO_MOVE_CAST(T)(t));+ 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)+{+ return partial_executor_binder<typename ExecutionContext::executor_type>(+ ctx.get_executor());+}+ /// Associate an object of type @c T with an execution context's executor. template <typename ExecutionContext, typename T>-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)+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) {- return executor_binder<typename decay<T>::type,- typename ExecutionContext::executor_type>(- executor_arg_t(), ctx.get_executor(), ASIO_MOVE_CAST(T)(t));+ return executor_binder<decay_t<T>, typename ExecutionContext::executor_type>(+ executor_arg_t(), ctx.get_executor(), static_cast<T&&>(t)); } #if !defined(GENERATING_DOCUMENTATION)@@ -529,11 +504,12 @@ template <typename TargetAsyncResult, typename Executor> class executor_binder_completion_handler_async_result<- TargetAsyncResult, Executor,- typename void_type<- typename TargetAsyncResult::completion_handler_type- >::type>+ TargetAsyncResult, Executor,+ void_t<typename TargetAsyncResult::completion_handler_type >> {+private:+ TargetAsyncResult target_;+ public: typedef executor_binder< typename TargetAsyncResult::completion_handler_type, Executor>@@ -545,13 +521,10 @@ { } - typename TargetAsyncResult::return_type get()+ auto get() -> decltype(target_.get()) { return target_.get(); }--private:- TargetAsyncResult target_; }; template <typename TargetAsyncResult, typename = void>@@ -560,11 +533,8 @@ }; template <typename TargetAsyncResult>-struct executor_binder_async_result_return_type<- TargetAsyncResult,- typename void_type<- typename TargetAsyncResult::return_type- >::type>+struct executor_binder_async_result_return_type<TargetAsyncResult,+ void_t<typename TargetAsyncResult::return_type>> { typedef typename TargetAsyncResult::return_type return_type; };@@ -574,9 +544,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)@@ -586,154 +556,78 @@ } template <typename Initiation>- struct init_wrapper+ struct init_wrapper : detail::initiation_base<Initiation> {- 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)+ using detail::initiation_base<Initiation>::initiation_base; template <typename Handler, typename... Args>- void operator()(- ASIO_MOVE_ARG(Handler) handler,- ASIO_MOVE_ARG(Args)... args)+ void operator()(Handler&& handler, const Executor& e, 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)...);+ static_cast<Initiation&&>(*this)(+ executor_binder<decay_t<Handler>, Executor>(+ executor_arg_t(), e, static_cast<Handler&&>(handler)),+ static_cast<Args&&>(args)...); } template <typename Handler, typename... Args>- void operator()(- ASIO_MOVE_ARG(Handler) handler,- ASIO_MOVE_ARG(Args)... args) const- {- 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+ void operator()(Handler&& handler,+ const Executor& e, Args&&... args) const & {- initiation_(- executor_binder<typename decay<Handler>::type, Executor>(- executor_arg_t(), ex_, ASIO_MOVE_CAST(Handler)(handler)));+ static_cast<const Initiation&>(*this)(+ executor_binder<decay_t<Handler>, Executor>(+ executor_arg_t(), e, static_cast<Handler&&>(handler)),+ static_cast<Args&&>(args)...); }--#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 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)+ 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)...)) {- 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)...);+ 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)...); } -#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)+private:+ async_result(const async_result&) = delete;+ async_result& operator=(const async_result&) = delete;+}; - 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)+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)...)) {- return async_initiate<T, Signature>(- init_wrapper<typename decay<Initiation>::type>(- token.get_executor(), ASIO_MOVE_CAST(Initiation)(initiation)),- token.get());+ 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)...); }--#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,@@ -741,18 +635,15 @@ struct associator<Associator, executor_binder<T, Executor>, DefaultCandidate> : Associator<T, DefaultCandidate> {- static typename Associator<T, DefaultCandidate>::type- get(const executor_binder<T, Executor>& b) ASIO_NOEXCEPT+ static typename Associator<T, DefaultCandidate>::type get(+ const executor_binder<T, Executor>& b) noexcept { return Associator<T, DefaultCandidate>::get(b.get()); } - 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)))+ static auto get(const executor_binder<T, Executor>& b,+ const DefaultCandidate& c) noexcept+ -> decltype(Associator<T, DefaultCandidate>::get(b.get(), c)) { return Associator<T, DefaultCandidate>::get(b.get(), c); }@@ -763,10 +654,9 @@ { typedef Executor type; - 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()))+ static auto get(const executor_binder<T, Executor>& b,+ const Executor1& = Executor1()) noexcept+ -> decltype(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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -16,11 +16,12 @@ #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/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" @@ -37,8 +38,7 @@ }; template <typename T>-struct immediate_executor_binder_result_type<T,- typename void_type<typename T::result_type>::type>+struct immediate_executor_binder_result_type<T, void_t<typename T::result_type>> { typedef typename T::result_type result_type; protected:@@ -100,7 +100,7 @@ template <typename T> struct immediate_executor_binder_argument_type<T,- typename void_type<typename T::argument_type>::type>+ void_t<typename T::argument_type>> { typedef typename T::argument_type argument_type; };@@ -125,7 +125,7 @@ template <typename T> struct immediate_executor_binder_argument_types<T,- typename void_type<typename T::first_argument_type>::type>+ void_t<typename T::first_argument_type>> { typedef typename T::first_argument_type first_argument_type; typedef typename T::second_argument_type second_argument_type;@@ -145,21 +145,6 @@ 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@@ -248,9 +233,9 @@ */ template <typename U> immediate_executor_binder(const immediate_executor_type& e,- ASIO_MOVE_ARG(U) u)+ U&& u) : executor_(e),- target_(ASIO_MOVE_CAST(U)(u))+ target_(static_cast<U&&>(u)) { } @@ -277,7 +262,9 @@ */ template <typename U, typename OtherExecutor> immediate_executor_binder(- const immediate_executor_binder<U, OtherExecutor>& other)+ const immediate_executor_binder<U, OtherExecutor>& other,+ constraint_t<is_constructible<Executor, OtherExecutor>::value> = 0,+ constraint_t<is_constructible<T, U>::value> = 0) : executor_(other.get_immediate_executor()), target_(other.get()) {@@ -291,19 +278,18 @@ */ template <typename U, typename OtherExecutor> immediate_executor_binder(const immediate_executor_type& e,- const immediate_executor_binder<U, OtherExecutor>& other)+ const immediate_executor_binder<U, OtherExecutor>& other,+ constraint_t<is_constructible<T, U>::value> = 0) : executor_(e), target_(other.get()) { } -#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)- /// Move constructor. immediate_executor_binder(immediate_executor_binder&& other)- : executor_(ASIO_MOVE_CAST(immediate_executor_type)(+ : executor_(static_cast<immediate_executor_type&&>( other.get_immediate_executor())),- target_(ASIO_MOVE_CAST(T)(other.get()))+ target_(static_cast<T&&>(other.get())) { } @@ -312,17 +298,19 @@ immediate_executor_binder(const immediate_executor_type& e, immediate_executor_binder&& other) : executor_(e),- target_(ASIO_MOVE_CAST(T)(other.get()))+ target_(static_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)- : executor_(ASIO_MOVE_CAST(OtherExecutor)(+ 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&&>( other.get_immediate_executor())),- target_(ASIO_MOVE_CAST(U)(other.get()))+ target_(static_cast<U&&>(other.get())) { } @@ -330,163 +318,152 @@ /// specify a different immediate executor. template <typename U, typename OtherExecutor> immediate_executor_binder(const immediate_executor_type& e,- immediate_executor_binder<U, OtherExecutor>&& other)+ immediate_executor_binder<U, OtherExecutor>&& other,+ constraint_t<is_constructible<T, U>::value> = 0) : executor_(e),- target_(ASIO_MOVE_CAST(U)(other.get()))+ target_(static_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() ASIO_NOEXCEPT+ target_type& get() noexcept { return target_; } /// Obtain a reference to the target object.- const target_type& get() const ASIO_NOEXCEPT+ const target_type& get() const noexcept { return target_; } /// Obtain the associated immediate executor.- immediate_executor_type get_immediate_executor() const ASIO_NOEXCEPT+ immediate_executor_type get_immediate_executor() const 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>- typename result_of<T(Args...)>::type operator()(- ASIO_MOVE_ARG(Args)... args)+ result_of_t<T(Args...)> operator()(Args&&... args) & {- return target_(ASIO_MOVE_CAST(Args)(args)...);+ return target_(static_cast<Args&&>(args)...); } /// Forwarding function call operator. template <typename... Args>- typename result_of<T(Args...)>::type operator()(- ASIO_MOVE_ARG(Args)... args) const- {- return target_(ASIO_MOVE_CAST(Args)(args)...);- }--#elif defined(ASIO_HAS_STD_TYPE_TRAITS) && !defined(_MSC_VER)-- typename detail::immediate_executor_binder_result_of0<T>::type operator()()+ result_of_t<T(Args...)> operator()(Args&&... args) && {- return target_();+ return static_cast<T&&>(target_)(static_cast<Args&&>(args)...); } - typename detail::immediate_executor_binder_result_of0<T>::type- operator()() const+ /// Forwarding function call operator.+ template <typename... Args>+ result_of_t<T(Args...)> operator()(Args&&... args) const& {- return target_();+ return target_(static_cast<Args&&>(args)...); } -#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;+private:+ Executor executor_;+ T target_;+}; - result_type_or_void operator()()+/// 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) {- return target_(); } - result_type_or_void operator()() const+ /// 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 {- return target_();+ return immediate_executor_binder<decay_t<CompletionToken>, Executor>(+ static_cast<CompletionToken&&>(completion_token), executor_); } -#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:+//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<typename decay<T>::type, Executor>-bind_immediate_executor(const Executor& e, ASIO_MOVE_ARG(T) t)+ASIO_NODISCARD inline immediate_executor_binder<decay_t<T>, Executor>+bind_immediate_executor(const Executor& e, T&& t) { return immediate_executor_binder<- typename decay<T>::type, Executor>(- e, ASIO_MOVE_CAST(T)(t));+ decay_t<T>, Executor>(+ e, static_cast<T&&>(t)); } #if !defined(GENERATING_DOCUMENTATION) namespace detail { -template <typename TargetAsyncResult,- typename Executor, typename = void>-struct immediate_executor_binder_async_result_completion_handler_type+template <typename TargetAsyncResult, typename Executor, typename = void>+class immediate_executor_binder_completion_handler_async_result {+public:+ template <typename T>+ explicit immediate_executor_binder_completion_handler_async_result(T&)+ {+ } }; template <typename TargetAsyncResult, typename Executor>-struct immediate_executor_binder_async_result_completion_handler_type<+class immediate_executor_binder_completion_handler_async_result< TargetAsyncResult, Executor,- typename void_type<+ void_t< 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>@@ -497,9 +474,9 @@ template <typename TargetAsyncResult> struct immediate_executor_binder_async_result_return_type< TargetAsyncResult,- typename void_type<+ void_t< typename TargetAsyncResult::return_type- >::type>+ >> { typedef typename TargetAsyncResult::return_type return_type; };@@ -508,184 +485,99 @@ template <typename T, typename Executor, typename Signature> class async_result<immediate_executor_binder<T, Executor>, Signature> :- public detail::immediate_executor_binder_async_result_completion_handler_type<+ public detail::immediate_executor_binder_completion_handler_async_result< 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)- : target_(b.get())+ : detail::immediate_executor_binder_completion_handler_async_result<+ async_result<T, Signature>, Executor>(b.get()) { } - typename async_result<T, Signature>::return_type get()- {- return target_.get();- }- template <typename Initiation>- struct init_wrapper+ struct init_wrapper : detail::initiation_base<Initiation> {- 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)+ using detail::initiation_base<Initiation>::initiation_base; template <typename Handler, typename... Args>- void operator()(- ASIO_MOVE_ARG(Handler) handler,- ASIO_MOVE_ARG(Args)... args)+ void operator()(Handler&& handler, const Executor& e, Args&&... args) && {- ASIO_MOVE_CAST(Initiation)(initiation_)(+ static_cast<Initiation&&>(*this)( immediate_executor_binder<- typename decay<Handler>::type, Executor>(- executor_, ASIO_MOVE_CAST(Handler)(handler)),- ASIO_MOVE_CAST(Args)(args)...);+ decay_t<Handler>, Executor>(+ e, static_cast<Handler&&>(handler)),+ static_cast<Args&&>(args)...); } template <typename Handler, typename... Args>- void operator()(- ASIO_MOVE_ARG(Handler) handler,- ASIO_MOVE_ARG(Args)... args) const- {- initiation_(- immediate_executor_binder<- 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+ void operator()(Handler&& handler,+ const Executor& e, Args&&... args) const & {- initiation_(+ static_cast<const Initiation&>(*this)( immediate_executor_binder<- typename decay<Handler>::type, Executor>(- executor_, ASIO_MOVE_CAST(Handler)(handler)));+ decay_t<Handler>, Executor>(+ e, static_cast<Handler&&>(handler)),+ static_cast<Args&&>(args)...); }--#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 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<T, Signature>(- init_wrapper<typename decay<Initiation>::type>(- token.get_immediate_executor(),- ASIO_MOVE_CAST(Initiation)(initiation)),- token.get(), ASIO_MOVE_CAST(Args)(args)...);- }--#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)-- 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)+ 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)...)) {- return async_initiate<T, Signature>(- init_wrapper<typename decay<Initiation>::type>(- token.get_immediate_executor(),- ASIO_MOVE_CAST(Initiation)(initiation)),- token.get());+ 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)...); } -#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(const async_result&) = delete;+ async_result& operator=(const async_result&) = delete; async_result<T, Signature> target_; }; +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)...))+ {+ 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)...);+ }+};+ template <template <typename, typename> class Associator, typename T, typename Executor, typename DefaultCandidate> struct associator<Associator,@@ -693,19 +585,15 @@ DefaultCandidate> : Associator<T, DefaultCandidate> {- static typename Associator<T, DefaultCandidate>::type- get(const immediate_executor_binder<T, Executor>& b)- ASIO_NOEXCEPT+ static typename Associator<T, DefaultCandidate>::type get(+ const immediate_executor_binder<T, Executor>& b) noexcept { return Associator<T, DefaultCandidate>::get(b.get()); } - 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)))+ static auto get(const immediate_executor_binder<T, Executor>& b,+ const DefaultCandidate& c) noexcept+ -> decltype(Associator<T, DefaultCandidate>::get(b.get(), c)) { return Associator<T, DefaultCandidate>::get(b.get(), c); }@@ -718,10 +606,9 @@ { typedef Executor type; - 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()))+ static auto get(const immediate_executor_binder<T, Executor>& b,+ const Executor1& = Executor1()) noexcept+ -> decltype(b.get_immediate_executor()) { return b.get_immediate_executor(); }
link/modules/asio-standalone/asio/include/asio/buffer.hpp view
@@ -2,2906 +2,2878 @@ // buffer.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_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)-+// 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 } // 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -17,6 +17,7 @@ #include "asio/detail/config.hpp" #include <iterator>+#include <utility> #include <vector> #include "asio/detail/memory.hpp" #include "asio/execution/context.hpp"@@ -31,10 +32,6 @@ # 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 {@@ -44,7 +41,7 @@ { protected: static mutable_registered_buffer make_buffer(const mutable_buffer& b,- const void* scope, int index) ASIO_NOEXCEPT+ const void* scope, int index) noexcept { return mutable_registered_buffer(b, registered_buffer_id(scope, index)); }@@ -58,7 +55,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 {@@ -82,9 +79,9 @@ buffer_registration(const Executor& ex, const MutableBufferSequence& buffer_sequence, const allocator_type& alloc = allocator_type(),- typename constraint<+ constraint_t< is_executor<Executor>::value || execution::is_executor<Executor>::value- >::type = 0)+ > = 0) : buffer_sequence_(buffer_sequence), buffers_( ASIO_REBIND_ALLOC(allocator_type,@@ -100,9 +97,9 @@ buffer_registration(ExecutionContext& ctx, const MutableBufferSequence& buffer_sequence, const allocator_type& alloc = allocator_type(),- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value- >::type = 0)+ > = 0) : buffer_sequence_(buffer_sequence), buffers_( ASIO_REBIND_ALLOC(allocator_type,@@ -113,9 +110,8 @@ asio::buffer_sequence_end(buffer_sequence_)); } -#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move constructor.- buffer_registration(buffer_registration&& other) ASIO_NOEXCEPT+ buffer_registration(buffer_registration&& other) noexcept : buffer_sequence_(std::move(other.buffer_sequence_)), buffers_(std::move(other.buffers_)) {@@ -124,7 +120,6 @@ other.service_ = 0; #endif // defined(ASIO_HAS_IO_URING) }-#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Unregisters the buffers. ~buffer_registration()@@ -134,11 +129,9 @@ 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) ASIO_NOEXCEPT+ buffer_registration& operator=(buffer_registration&& other) noexcept { if (this != &other) {@@ -153,59 +146,58 @@ } return *this; }-#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Get the number of registered buffers.- std::size_t size() const ASIO_NOEXCEPT+ std::size_t size() const noexcept { return buffers_.size(); } /// Get the begin iterator for the sequence of registered buffers.- const_iterator begin() const ASIO_NOEXCEPT+ const_iterator begin() const noexcept { return buffers_.begin(); } /// Get the begin iterator for the sequence of registered buffers.- const_iterator cbegin() const ASIO_NOEXCEPT+ const_iterator cbegin() const noexcept { return buffers_.cbegin(); } /// Get the end iterator for the sequence of registered buffers.- const_iterator end() const ASIO_NOEXCEPT+ const_iterator end() const noexcept { return buffers_.end(); } /// Get the end iterator for the sequence of registered buffers.- const_iterator cend() const ASIO_NOEXCEPT+ const_iterator cend() const noexcept { return buffers_.cend(); } /// Get the buffer at the specified index.- const mutable_registered_buffer& operator[](std::size_t i) ASIO_NOEXCEPT+ const mutable_registered_buffer& operator[](std::size_t i) noexcept { return buffers_[i]; } /// Get the buffer at the specified index.- const mutable_registered_buffer& at(std::size_t i) ASIO_NOEXCEPT+ const mutable_registered_buffer& at(std::size_t i) noexcept { return buffers_.at(i); } private: // Disallow copying and assignment.- buffer_registration(const buffer_registration&) ASIO_DELETED;- buffer_registration& operator=(const buffer_registration&) ASIO_DELETED;+ buffer_registration(const buffer_registration&) = delete;+ buffer_registration& operator=(const buffer_registration&) = delete; // Helper function to get an executor's context. template <typename T> static execution_context& get_context(const T& t,- typename enable_if<execution::is_executor<T>::value>::type* = 0)+ enable_if_t<execution::is_executor<T>::value>* = 0) { return asio::query(t, execution::context); }@@ -213,7 +205,7 @@ // Helper function to get an executor's context. template <typename T> static execution_context& get_context(const T& t,- typename enable_if<!execution::is_executor<T>::value>::type* = 0)+ enable_if_t<!execution::is_executor<T>::value>* = 0) { return t.context(); }@@ -264,16 +256,15 @@ #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,- typename constraint<+ constraint_t< is_executor<Executor>::value || execution::is_executor<Executor>::value- >::type = 0)+ > = 0) { return buffer_registration<MutableBufferSequence>(ex, buffer_sequence); }@@ -284,9 +275,9 @@ buffer_registration<MutableBufferSequence, Allocator> register_buffers(const Executor& ex, const MutableBufferSequence& buffer_sequence, const Allocator& alloc,- typename constraint<+ constraint_t< is_executor<Executor>::value || execution::is_executor<Executor>::value- >::type = 0)+ > = 0) { return buffer_registration<MutableBufferSequence, Allocator>( ex, buffer_sequence, alloc);@@ -298,9 +289,9 @@ buffer_registration<MutableBufferSequence> register_buffers(ExecutionContext& ctx, const MutableBufferSequence& buffer_sequence,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value- >::type = 0)+ > = 0) { return buffer_registration<MutableBufferSequence>(ctx, buffer_sequence); }@@ -312,14 +303,13 @@ buffer_registration<MutableBufferSequence, Allocator> register_buffers(ExecutionContext& ctx, const MutableBufferSequence& buffer_sequence, const Allocator& alloc,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value- >::type = 0)+ > = 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -55,7 +55,7 @@ { public: /// The type of the next layer.- typedef typename remove_reference<Stream>::type next_layer_type;+ typedef remove_reference_t<Stream> 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(ASIO_MOVE_OR_LVALUE_ARG(Arg) a)- : next_layer_(ASIO_MOVE_OR_LVALUE(Arg)(a)),+ explicit buffered_read_stream(Arg&& a)+ : next_layer_(static_cast<Arg&&>(a)), storage_(default_buffer_size) { } /// Construct, passing the specified argument to initialise the next layer. template <typename Arg>- buffered_read_stream(ASIO_MOVE_OR_LVALUE_ARG(Arg) a,+ buffered_read_stream(Arg&& a, std::size_t buffer_size)- : next_layer_(ASIO_MOVE_OR_LVALUE(Arg)(a)),+ : next_layer_(static_cast<Arg&&>(a)), storage_(buffer_size) { }@@ -106,7 +106,7 @@ } /// Get the executor associated with the object.- executor_type get_executor() ASIO_NOEXCEPT+ executor_type get_executor() noexcept { return next_layer_.lowest_layer().get_executor(); }@@ -149,20 +149,15 @@ */ template <typename ConstBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) WriteHandler- ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>- ASIO_INITFN_AUTO_RESULT_TYPE_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))))+ 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))) { return next_layer_.async_write_some(buffers,- ASIO_MOVE_CAST(WriteHandler)(handler));+ static_cast<WriteHandler&&>(handler)); } /// Fill the buffer with some data. Returns the number of bytes placed in the@@ -180,18 +175,14 @@ */ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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((+ std::size_t)) ReadHandler = default_completion_token_t<executor_type>>+ auto async_fill(+ ReadHandler&& handler = default_completion_token_t<executor_type>())+ -> decltype( 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.@@ -212,18 +203,14 @@ */ template <typename MutableBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) ReadHandler- ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>- ASIO_INITFN_AUTO_RESULT_TYPE_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((+ 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( 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/buffered_stream.hpp view
@@ -2,7 +2,7 @@ // buffered_stream.hpp // ~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -46,7 +46,7 @@ { public: /// The type of the next layer.- typedef typename remove_reference<Stream>::type next_layer_type;+ typedef remove_reference_t<Stream> 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(ASIO_MOVE_OR_LVALUE_ARG(Arg) a)- : inner_stream_impl_(ASIO_MOVE_OR_LVALUE(Arg)(a)),+ explicit buffered_stream(Arg&& a)+ : inner_stream_impl_(static_cast<Arg&&>(a)), stream_impl_(inner_stream_impl_) { } /// Construct, passing the specified argument to initialise the next layer. template <typename Arg>- explicit buffered_stream(ASIO_MOVE_OR_LVALUE_ARG(Arg) a,+ explicit buffered_stream(Arg&& a, std::size_t read_buffer_size, std::size_t write_buffer_size)- : inner_stream_impl_(ASIO_MOVE_OR_LVALUE(Arg)(a), write_buffer_size),+ : inner_stream_impl_(static_cast<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() ASIO_NOEXCEPT+ executor_type get_executor() noexcept { return stream_impl_.lowest_layer().get_executor(); }@@ -131,19 +131,15 @@ */ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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((+ std::size_t)) WriteHandler = default_completion_token_t<executor_type>>+ auto async_flush(+ WriteHandler&& handler = default_completion_token_t<executor_type>())+ -> decltype( declval<buffered_write_stream<Stream>&>().async_flush(- ASIO_MOVE_CAST(WriteHandler)(handler))))+ static_cast<WriteHandler&&>(handler))) { return stream_impl_.next_layer().async_flush(- ASIO_MOVE_CAST(WriteHandler)(handler));+ static_cast<WriteHandler&&>(handler)); } /// Write the given data to the stream. Returns the number of bytes written.@@ -171,19 +167,15 @@ */ template <typename ConstBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) WriteHandler- ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>- ASIO_INITFN_AUTO_RESULT_TYPE_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((+ 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<Stream&>().async_write_some(buffers,- ASIO_MOVE_CAST(WriteHandler)(handler))))+ static_cast<WriteHandler&&>(handler))) { return stream_impl_.async_write_some(buffers,- ASIO_MOVE_CAST(WriteHandler)(handler));+ static_cast<WriteHandler&&>(handler)); } /// Fill the buffer with some data. Returns the number of bytes placed in the@@ -207,19 +199,15 @@ */ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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((+ std::size_t)) ReadHandler = default_completion_token_t<executor_type>>+ auto async_fill(+ ReadHandler&& handler = default_completion_token_t<executor_type>())+ -> decltype( declval<buffered_read_stream<- buffered_write_stream<Stream> >&>().async_fill(- ASIO_MOVE_CAST(ReadHandler)(handler))))+ buffered_write_stream<Stream>>&>().async_fill(+ static_cast<ReadHandler&&>(handler))) {- return stream_impl_.async_fill(ASIO_MOVE_CAST(ReadHandler)(handler));+ return stream_impl_.async_fill(static_cast<ReadHandler&&>(handler)); } /// Read some data from the stream. Returns the number of bytes read. Throws@@ -247,19 +235,15 @@ */ template <typename MutableBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) ReadHandler- ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>- ASIO_INITFN_AUTO_RESULT_TYPE_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((+ 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<Stream&>().async_read_some(buffers,- ASIO_MOVE_CAST(ReadHandler)(handler))))+ static_cast<ReadHandler&&>(handler))) { return stream_impl_.async_read_some(buffers,- ASIO_MOVE_CAST(ReadHandler)(handler));+ static_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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/buffered_write_stream.hpp view
@@ -2,7 +2,7 @@ // buffered_write_stream.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -55,7 +55,7 @@ { public: /// The type of the next layer.- typedef typename remove_reference<Stream>::type next_layer_type;+ typedef remove_reference_t<Stream> 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(ASIO_MOVE_OR_LVALUE_ARG(Arg) a)- : next_layer_(ASIO_MOVE_OR_LVALUE(Arg)(a)),+ explicit buffered_write_stream(Arg&& a)+ : next_layer_(static_cast<Arg&&>(a)), storage_(default_buffer_size) { } /// Construct, passing the specified argument to initialise the next layer. template <typename Arg>- buffered_write_stream(ASIO_MOVE_OR_LVALUE_ARG(Arg) a,+ buffered_write_stream(Arg&& a, std::size_t buffer_size)- : next_layer_(ASIO_MOVE_OR_LVALUE(Arg)(a)),+ : next_layer_(static_cast<Arg&&>(a)), storage_(buffer_size) { }@@ -106,7 +106,7 @@ } /// Get the executor associated with the object.- executor_type get_executor() ASIO_NOEXCEPT+ executor_type get_executor() noexcept { return next_layer_.lowest_layer().get_executor(); }@@ -141,18 +141,14 @@ */ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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((+ std::size_t)) WriteHandler = default_completion_token_t<executor_type>>+ auto async_flush(+ WriteHandler&& handler = default_completion_token_t<executor_type>())+ -> decltype( 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.@@ -173,18 +169,14 @@ */ template <typename ConstBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) WriteHandler- ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>- ASIO_INITFN_AUTO_RESULT_TYPE_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((+ 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( 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.@@ -211,20 +203,15 @@ */ template <typename MutableBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- std::size_t)) ReadHandler- ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>- ASIO_INITFN_AUTO_RESULT_TYPE_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))))+ 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))) { return next_layer_.async_read_some(buffers,- ASIO_MOVE_CAST(ReadHandler)(handler));+ static_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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/buffers_iterator.hpp view
@@ -2,7 +2,7 @@ // buffers_iterator.hpp // ~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -38,7 +38,7 @@ template <typename ByteType> struct byte_type {- typedef typename add_const<ByteType>::type type;+ typedef add_const_t<ByteType> type; }; }; @@ -80,30 +80,10 @@ struct buffers_iterator_types<const_buffer, ByteType> { typedef const_buffer buffer_type;- typedef typename add_const<ByteType>::type byte_type;- typedef const const_buffer* const_iterator;- };--#if !defined(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 add_const_t<ByteType> byte_type; typedef const const_buffer* const_iterator; };--#endif // !defined(ASIO_NO_DEPRECATED)-}+} // namespace detail /// 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 view
@@ -0,0 +1,301 @@+//+// 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 view
@@ -0,0 +1,294 @@+//+// 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -22,7 +22,6 @@ #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" @@ -33,7 +32,7 @@ { public: virtual void call(cancellation_type_t) = 0;- virtual std::pair<void*, std::size_t> destroy() ASIO_NOEXCEPT = 0;+ virtual std::pair<void*, std::size_t> destroy() noexcept = 0; protected: ~cancellation_handler_base() {}@@ -44,45 +43,26 @@ : public cancellation_handler_base { public:-#if defined(ASIO_HAS_VARIADIC_TEMPLATES) template <typename... 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_(),+ cancellation_handler(std::size_t size, Args&&... args)+ : handler_(static_cast<Args&&>(args)...), 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() ASIO_NOEXCEPT+ std::pair<void*, std::size_t> destroy() noexcept { std::pair<void*, std::size_t> mem(this, size_); this->cancellation_handler::~cancellation_handler(); return mem; } - Handler& handler() ASIO_NOEXCEPT+ Handler& handler() noexcept { return handler_; }@@ -104,7 +84,7 @@ class cancellation_signal { public:- ASIO_CONSTEXPR cancellation_signal()+ constexpr cancellation_signal() : handler_(0) { }@@ -123,11 +103,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() ASIO_NOEXCEPT;+ cancellation_slot slot() noexcept; private:- cancellation_signal(const cancellation_signal&) ASIO_DELETED;- cancellation_signal& operator=(const cancellation_signal&) ASIO_DELETED;+ cancellation_signal(const cancellation_signal&) = delete;+ cancellation_signal& operator=(const cancellation_signal&) = delete; detail::cancellation_handler_base* handler_; };@@ -137,13 +117,11 @@ { public: /// Creates a slot that is not connected to any cancellation signal.- ASIO_CONSTEXPR cancellation_slot()+ 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,@@ -162,58 +140,21 @@ * be copy constructible or move constructible. */ template <typename CancellationHandler, typename... Args>- CancellationHandler& emplace(ASIO_MOVE_ARG(Args)... args)+ CancellationHandler& emplace(Args&&... args) { typedef detail::cancellation_handler<CancellationHandler> cancellation_handler_type; auto_delete_helper del = { prepare_memory( sizeof(cancellation_handler_type),- ASIO_ALIGNOF(CancellationHandler)) };+ alignof(CancellationHandler)) }; cancellation_handler_type* handler_obj = new (del.mem.first) cancellation_handler_type(- 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.second, static_cast<Args&&>(args)...); 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,@@ -228,11 +169,10 @@ * @returns A reference to the newly installed handler. */ template <typename CancellationHandler>- typename decay<CancellationHandler>::type& assign(- ASIO_MOVE_ARG(CancellationHandler) handler)+ decay_t<CancellationHandler>& assign(CancellationHandler&& handler) {- return this->emplace<typename decay<CancellationHandler>::type>(- ASIO_MOVE_CAST(CancellationHandler)(handler));+ return this->emplace<decay_t<CancellationHandler>>(+ static_cast<CancellationHandler&&>(handler)); } /// Clears the slot.@@ -242,27 +182,27 @@ ASIO_DECL void clear(); /// Returns whether the slot is connected to a signal.- ASIO_CONSTEXPR bool is_connected() const ASIO_NOEXCEPT+ constexpr bool is_connected() const noexcept { return handler_ != 0; } /// Returns whether the slot is connected and has an installed handler.- ASIO_CONSTEXPR bool has_handler() const ASIO_NOEXCEPT+ constexpr bool has_handler() const noexcept { return handler_ != 0 && *handler_ != 0; } /// Compare two slots for equality.- friend ASIO_CONSTEXPR bool operator==(const cancellation_slot& lhs,- const cancellation_slot& rhs) ASIO_NOEXCEPT+ friend constexpr bool operator==(const cancellation_slot& lhs,+ const cancellation_slot& rhs) noexcept { return lhs.handler_ == rhs.handler_; } /// Compare two slots for inequality.- friend ASIO_CONSTEXPR bool operator!=(const cancellation_slot& lhs,- const cancellation_slot& rhs) ASIO_NOEXCEPT+ friend constexpr bool operator!=(const cancellation_slot& lhs,+ const cancellation_slot& rhs) noexcept { return lhs.handler_ != rhs.handler_; }@@ -270,7 +210,7 @@ private: friend class cancellation_signal; - ASIO_CONSTEXPR cancellation_slot(int,+ constexpr cancellation_slot(int, detail::cancellation_handler_base** handler) : handler_(handler) {@@ -289,7 +229,7 @@ detail::cancellation_handler_base** handler_; }; -inline cancellation_slot cancellation_signal::slot() ASIO_NOEXCEPT+inline cancellation_slot cancellation_signal::slot() 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -32,7 +32,7 @@ { /// Returns <tt>type & Mask</tt>. cancellation_type_t operator()(- cancellation_type_t type) const ASIO_NOEXCEPT+ cancellation_type_t type) const noexcept { return type & Mask; }@@ -80,7 +80,7 @@ { public: /// Construct a disconnected cancellation state.- ASIO_CONSTEXPR cancellation_state() ASIO_NOEXCEPT+ constexpr cancellation_state() noexcept : impl_(0) { }@@ -95,8 +95,8 @@ * attached. */ template <typename CancellationSlot>- ASIO_CONSTEXPR explicit cancellation_state(CancellationSlot slot)- : impl_(slot.is_connected() ? &slot.template emplace<impl<> >() : 0)+ 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>- ASIO_CONSTEXPR cancellation_state(CancellationSlot slot, Filter filter)+ 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>- ASIO_CONSTEXPR cancellation_state(CancellationSlot slot,+ constexpr cancellation_state(CancellationSlot slot, InFilter in_filter, OutFilter out_filter) : impl_(slot.is_connected()- ? &slot.template emplace<impl<InFilter, OutFilter> >(- ASIO_MOVE_CAST(InFilter)(in_filter),- ASIO_MOVE_CAST(OutFilter)(out_filter))+ ? &slot.template emplace<impl<InFilter, OutFilter>>(+ static_cast<InFilter&&>(in_filter),+ static_cast<OutFilter&&>(out_filter)) : 0) { }@@ -165,20 +165,20 @@ /** * This sub-slot is used with the operations that are being composed. */- ASIO_CONSTEXPR cancellation_slot slot() const ASIO_NOEXCEPT+ constexpr cancellation_slot slot() const noexcept { return impl_ ? impl_->signal_.slot() : cancellation_slot(); } /// Returns the cancellation types that have been triggered.- cancellation_type_t cancelled() const ASIO_NOEXCEPT+ cancellation_type_t cancelled() const 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)- ASIO_NOEXCEPT+ noexcept { if (impl_) impl_->cancelled_ &= ~mask;@@ -208,8 +208,8 @@ } impl(InFilter in_filter, OutFilter out_filter)- : in_filter_(ASIO_MOVE_CAST(InFilter)(in_filter)),- out_filter_(ASIO_MOVE_CAST(OutFilter)(out_filter))+ : in_filter_(static_cast<InFilter&&>(in_filter)),+ out_filter_(static_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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -51,7 +51,7 @@ /// Portability typedef. typedef cancellation_type cancellation_type_t; -#elif defined(ASIO_HAS_ENUM_CLASS)+#else // defined(GENERATING_DOCUMENTATION) enum class cancellation_type : unsigned int {@@ -64,30 +64,13 @@ typedef cancellation_type cancellation_type_t; -#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)+#endif // defined(GENERATING_DOCUMENTATION) /// Negation operator. /** * @relates cancellation_type */-inline ASIO_CONSTEXPR bool operator!(cancellation_type_t x)+inline constexpr bool operator!(cancellation_type_t x) { return static_cast<unsigned int>(x) == 0; }@@ -96,7 +79,7 @@ /** * @relates cancellation_type */-inline ASIO_CONSTEXPR cancellation_type_t operator&(+inline constexpr cancellation_type_t operator&( cancellation_type_t x, cancellation_type_t y) { return static_cast<cancellation_type_t>(@@ -107,7 +90,7 @@ /** * @relates cancellation_type */-inline ASIO_CONSTEXPR cancellation_type_t operator|(+inline constexpr cancellation_type_t operator|( cancellation_type_t x, cancellation_type_t y) { return static_cast<cancellation_type_t>(@@ -118,7 +101,7 @@ /** * @relates cancellation_type */-inline ASIO_CONSTEXPR cancellation_type_t operator^(+inline constexpr cancellation_type_t operator^( cancellation_type_t x, cancellation_type_t y) { return static_cast<cancellation_type_t>(@@ -129,7 +112,7 @@ /** * @relates cancellation_type */-inline ASIO_CONSTEXPR cancellation_type_t operator~(cancellation_type_t x)+inline 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 view
@@ -0,0 +1,1319 @@+//+// 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -113,10 +113,10 @@ co_spawn(const Executor& ex, awaitable<T, AwaitableExecutor> a, CompletionToken&& token ASIO_DEFAULT_COMPLETION_TOKEN(Executor),- typename constraint<+ constraint_t< (is_executor<Executor>::value || execution::is_executor<Executor>::value) && is_convertible<Executor, AwaitableExecutor>::value- >::type = 0);+ > = 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),- typename constraint<+ constraint_t< (is_executor<Executor>::value || execution::is_executor<Executor>::value) && is_convertible<Executor, AwaitableExecutor>::value- >::type = 0);+ > = 0); /// Spawn a new coroutined-based thread of execution. /**@@ -251,11 +251,11 @@ CompletionToken&& token ASIO_DEFAULT_COMPLETION_TOKEN( typename ExecutionContext::executor_type),- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value && is_convertible<typename ExecutionContext::executor_type, AwaitableExecutor>::value- >::type = 0);+ > = 0); /// Spawn a new coroutined-based thread of execution. /**@@ -318,11 +318,11 @@ CompletionToken&& token ASIO_DEFAULT_COMPLETION_TOKEN( typename ExecutionContext::executor_type),- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value && is_convertible<typename ExecutionContext::executor_type, AwaitableExecutor>::value- >::type = 0);+ > = 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<- typename result_of<F()>::type>::type) CompletionToken+ result_of_t<F()>>::type) CompletionToken ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(Executor)> ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken,- typename detail::awaitable_signature<typename result_of<F()>::type>::type)+ typename detail::awaitable_signature<result_of_t<F()>>::type) co_spawn(const Executor& ex, F&& f, CompletionToken&& token ASIO_DEFAULT_COMPLETION_TOKEN(Executor),- typename constraint<+ constraint_t< is_executor<Executor>::value || execution::is_executor<Executor>::value- >::type = 0);+ > = 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<- typename result_of<F()>::type>::type) CompletionToken+ result_of_t<F()>>::type) CompletionToken ASIO_DEFAULT_COMPLETION_TOKEN_TYPE( typename ExecutionContext::executor_type)> ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken,- typename detail::awaitable_signature<typename result_of<F()>::type>::type)+ typename detail::awaitable_signature<result_of_t<F()>>::type) co_spawn(ExecutionContext& ctx, F&& f, CompletionToken&& token ASIO_DEFAULT_COMPLETION_TOKEN( typename ExecutionContext::executor_type),- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value- >::type = 0);+ > = 0); } // namespace asio
link/modules/asio-standalone/asio/include/asio/completion_condition.hpp view
@@ -2,7 +2,7 @@ // completion_condition.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -17,6 +17,8 @@ #include "asio/detail/config.hpp" #include <cstddef>+#include "asio/detail/type_traits.hpp"+#include "asio/error_code.hpp" #include "asio/detail/push_options.hpp" @@ -97,7 +99,54 @@ 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -16,311 +16,12 @@ #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_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/composed.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@@ -339,6 +40,13 @@ * @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@@ -382,8 +90,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>(),@@ -398,131 +106,20 @@ */ template <typename CompletionToken, typename Signature, typename Implementation, typename... IoObjectsOrExecutors>-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>(- 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>(- 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((+inline auto async_compose(Implementation&& implementation,+ type_identity_t<CompletionToken>& token,+ IoObjectsOrExecutors&&... io_objects_or_executors)+ -> decltype( async_initiate<CompletionToken, Signature>(- detail::make_initiate_composed_op<Signature>(- detail::make_composed_io_executors()),- token, ASIO_MOVE_CAST(Implementation)(implementation))))+ composed<Signature>(static_cast<Implementation&&>(implementation),+ static_cast<IoObjectsOrExecutors&&>(io_objects_or_executors)...),+ token)) { return async_initiate<CompletionToken, Signature>(- detail::make_initiate_composed_op<Signature>(- detail::make_composed_io_executors()),- token, ASIO_MOVE_CAST(Implementation)(implementation));+ composed<Signature>(static_cast<Implementation&&>(implementation),+ static_cast<IoObjectsOrExecutors&&>(io_objects_or_executors)...),+ token); }--# 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 view
@@ -0,0 +1,413 @@+//+// 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 view
@@ -0,0 +1,193 @@+//+// 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -31,34 +31,97 @@ template <typename, typename> class initiate_async_range_connect; template <typename, typename> class initiate_async_iterator_connect; - char (&has_iterator_helper(...))[2];+ template <typename T, typename = void, typename = void>+ struct is_endpoint_sequence_helper : false_type+ {+ }; template <typename T>- char has_iterator_helper(T*, typename T::iterator* = 0);+ struct is_endpoint_sequence_helper<T,+ void_t<+ decltype(declval<T>().begin())+ >,+ void_t<+ decltype(declval<T>().end())+ >+ > : true_type+ {+ }; - template <typename T>- struct has_iterator_typedef+ template <typename T, typename Iterator, typename = void>+ struct is_connect_condition_helper : false_type {- enum { value = (sizeof((has_iterator_helper)((T*)(0))) == 1) }; };++ 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+ {+ };++ struct default_connect_condition+ {+ template <typename Endpoint>+ bool operator()(const asio::error_code&, const Endpoint&)+ {+ return true;+ }+ }; } // 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;-#else- enum- {- value = detail::has_iterator_typedef<T>::value- };-#endif+ 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>+{+};++#endif // defined(GENERATING_DOCUMENTATION)+ /** * @defgroup connect asio::connect *@@ -94,8 +157,9 @@ template <typename Protocol, typename Executor, typename EndpointSequence> typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s, const EndpointSequence& endpoints,- typename constraint<is_endpoint_sequence<- EndpointSequence>::value>::type = 0);+ constraint_t<+ is_endpoint_sequence<EndpointSequence>::value+ > = 0); /// Establishes a socket connection by trying each endpoint in a sequence. /**@@ -130,67 +194,9 @@ template <typename Protocol, typename Executor, typename EndpointSequence> typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s, const EndpointSequence& endpoints, asio::error_code& ec,- 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)+ constraint_t<+ is_endpoint_sequence<EndpointSequence>::value+ > = 0); /// Establishes a socket connection by trying each endpoint in a sequence. /**@@ -315,8 +321,13 @@ typename EndpointSequence, typename ConnectCondition> typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s, const EndpointSequence& endpoints, ConnectCondition connect_condition,- typename constraint<is_endpoint_sequence<- EndpointSequence>::value>::type = 0);+ constraint_t<+ is_endpoint_sequence<EndpointSequence>::value+ > = 0,+ constraint_t<+ is_connect_condition<ConnectCondition,+ decltype(declval<const EndpointSequence&>().begin())>::value+ > = 0); /// Establishes a socket connection by trying each endpoint in a sequence. /**@@ -383,92 +394,13 @@ typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s, const EndpointSequence& endpoints, ConnectCondition connect_condition, asio::error_code& ec,- 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)+ constraint_t<+ is_endpoint_sequence<EndpointSequence>::value+ > = 0,+ constraint_t<+ is_connect_condition<ConnectCondition,+ decltype(declval<const EndpointSequence&>().begin())>::value+ > = 0); /// Establishes a socket connection by trying each endpoint in a sequence. /**@@ -527,7 +459,10 @@ template <typename Protocol, typename Executor, typename Iterator, typename ConnectCondition> Iterator connect(basic_socket<Protocol, Executor>& s, Iterator begin,- Iterator end, ConnectCondition connect_condition);+ Iterator end, ConnectCondition connect_condition,+ constraint_t<+ is_connect_condition<ConnectCondition, Iterator>::value+ > = 0); /// Establishes a socket connection by trying each endpoint in a sequence. /**@@ -596,7 +531,10 @@ typename Iterator, typename ConnectCondition> Iterator connect(basic_socket<Protocol, Executor>& s, Iterator begin, Iterator end, ConnectCondition connect_condition,- asio::error_code& ec);+ asio::error_code& ec,+ constraint_t<+ is_connect_condition<ConnectCondition, Iterator>::value+ > = 0); /*@}*/ @@ -640,7 +578,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, typename Protocol::endpoint) @endcode@@ -688,90 +626,28 @@ template <typename Protocol, typename Executor, typename EndpointSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, typename Protocol::endpoint)) RangeConnectToken- 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,+ = default_completion_token_t<Executor>>+inline auto async_connect(basic_socket<Protocol, Executor>& s, const EndpointSequence& endpoints,- 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((+ 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( 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>())));--#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)+ 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());+} /// Asynchronously establishes a socket connection by trying each endpoint in a /// sequence.@@ -807,7 +683,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, Iterator) @endcode@@ -840,18 +716,24 @@ */ 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, Iterator end,- ASIO_MOVE_ARG(IteratorConnectToken) token- ASIO_DEFAULT_COMPLETION_TOKEN(Executor))- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ 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( async_initiate<IteratorConnectToken, void (asio::error_code, Iterator)>(- declval<detail::initiate_async_iterator_connect<Protocol, Executor> >(),- token, begin, end, declval<detail::default_connect_condition>())));+ 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());+} /// Asynchronously establishes a socket connection by trying each endpoint in a /// sequence.@@ -896,7 +778,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, typename Protocol::endpoint) @endcode@@ -968,102 +850,28 @@ typename EndpointSequence, typename ConnectCondition, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, typename Protocol::endpoint)) RangeConnectToken- 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,+ = default_completion_token_t<Executor>>+inline auto async_connect(basic_socket<Protocol, Executor>& s, const EndpointSequence& endpoints, ConnectCondition connect_condition,- 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((+ 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( async_initiate<RangeConnectToken, void (asio::error_code, typename Protocol::endpoint)>(- 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)+ 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);+} /// Asynchronously establishes a socket connection by trying each endpoint in a /// sequence.@@ -1110,7 +918,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, Iterator) @endcode@@ -1182,19 +990,24 @@ 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,- Iterator end, ConnectCondition connect_condition,- ASIO_MOVE_ARG(IteratorConnectToken) token- ASIO_DEFAULT_COMPLETION_TOKEN(Executor))- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ 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( async_initiate<IteratorConnectToken, void (asio::error_code, Iterator)>(- declval<detail::initiate_async_iterator_connect<Protocol, Executor> >(),- token, begin, end, connect_condition)));+ 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);+} /*@}*/ @@ -1204,4 +1017,4 @@ #include "asio/impl/connect.hpp" -#endif+#endif // ASIO_CONNECT_HPP
link/modules/asio-standalone/asio/include/asio/connect_pipe.hpp view
@@ -2,7 +2,7 @@ // connect_pipe.hpp // ~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/consign.hpp view
@@ -1,8 +1,8 @@ // // consign.hpp-// ~~~~~~~~~~+// ~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -16,11 +16,6 @@ #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" @@ -41,11 +36,9 @@ public: /// Constructor. template <typename T, typename... V>- 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)...)+ constexpr explicit consign_t(T&& completion_token, V&&... values)+ : token_(static_cast<T&&>(completion_token)),+ values_(static_cast<V&&>(values)...) { } @@ -64,15 +57,13 @@ * called. */ template <typename CompletionToken, typename... 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)+ASIO_NODISCARD inline constexpr+consign_t<decay_t<CompletionToken>, decay_t<Values>...>+consign(CompletionToken&& completion_token, Values&&... values) {- return consign_t<- typename decay<CompletionToken>::type, typename decay<Values>::type...>(- ASIO_MOVE_CAST(CompletionToken)(completion_token),- ASIO_MOVE_CAST(Values)(values)...);+ return consign_t<decay_t<CompletionToken>, decay_t<Values>...>(+ static_cast<CompletionToken&&>(completion_token),+ static_cast<Values&&>(values)...); } } // namespace asio@@ -80,9 +71,5 @@ #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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -111,7 +111,7 @@ * * @code yield * {- * mutable_buffers_1 b = buffer(*buffer_);+ * mutable_buffer 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,7 +258,6 @@ int value_; }; - namespace detail { class coroutine_ref@@ -266,6 +265,7 @@ 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -17,6 +17,8 @@ #include "asio/detail/config.hpp" +#if !defined(ASIO_NO_DEPRECATED)+ #if defined(ASIO_HAS_BOOST_DATE_TIME) \ || defined(GENERATING_DOCUMENTATION) @@ -27,12 +29,15 @@ namespace asio { -/// Typedef for the typical usage of timer. Uses a UTC clock.+/// (Deprecated: Use system_timer.) 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 view
@@ -0,0 +1,89 @@+//+// 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -79,11 +79,10 @@ * @code void() @endcode */ template <ASIO_COMPLETION_TOKEN_FOR(void()) NullaryToken>-ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(NullaryToken, void()) defer(- ASIO_MOVE_ARG(NullaryToken) token)- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+auto defer(NullaryToken&& token)+ -> decltype( async_initiate<NullaryToken, void()>(- declval<detail::initiate_defer>(), token)))+ declval<detail::initiate_defer>(), token)) { return async_initiate<NullaryToken, void()>( detail::initiate_defer(), token);@@ -162,19 +161,18 @@ */ template <typename Executor, ASIO_COMPLETION_TOKEN_FOR(void()) NullaryToken- 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<+ = default_completion_token_t<Executor>>+auto defer(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- >::type = 0)- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ > = 0)+ -> decltype( 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);@@ -195,19 +193,17 @@ */ template <typename ExecutionContext, ASIO_COMPLETION_TOKEN_FOR(void()) NullaryToken- 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((+ = 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( 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -16,12 +16,6 @@ #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"@@ -67,19 +61,18 @@ { public: template <typename H, typename T>- 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))+ explicit deferred_sequence_handler(H&& handler, T&& tail)+ : handler_(static_cast<H&&>(handler)),+ tail_(static_cast<T&&>(tail)) { } template <typename... Args>- void operator()(ASIO_MOVE_ARG(Args)... args)+ void operator()(Args&&... args) {- ASIO_MOVE_OR_LVALUE(Tail)(tail_)(- ASIO_MOVE_CAST(Args)(args)...)(- ASIO_MOVE_OR_LVALUE(Handler)(handler_));+ static_cast<Tail&&>(tail_)(+ static_cast<Args&&>(args)...)(+ static_cast<Handler&&>(handler_)); } //private:@@ -94,15 +87,11 @@ struct initiate { template <typename Handler>- void operator()(ASIO_MOVE_ARG(Handler) handler,- Head head, ASIO_MOVE_ARG(Tail) tail)+ void operator()(Handler&& handler, Head head, 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)));+ static_cast<Head&&>(head)(+ deferred_sequence_handler<decay_t<Handler>, decay_t<Tail>>(+ static_cast<Handler&&>(handler), static_cast<Tail&&>(tail))); } }; @@ -111,40 +100,32 @@ public: template <typename H, typename T>- 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))+ constexpr explicit deferred_sequence_base(H&& head, T&& tail)+ : head_(static_cast<H&&>(head)),+ tail_(static_cast<T&&>(tail)) { } template <ASIO_COMPLETION_TOKEN_FOR(Signatures...) CompletionToken>- auto operator()(- ASIO_MOVE_ARG(CompletionToken) token) ASIO_RVALUE_REF_QUAL+ auto operator()(CompletionToken&& token) && -> decltype(- asio::async_initiate<CompletionToken, Signatures...>(- declval<initiate>(), token,- ASIO_MOVE_OR_LVALUE(Head)(this->head_),- ASIO_MOVE_OR_LVALUE(Tail)(this->tail_)))+ async_initiate<CompletionToken, Signatures...>(+ initiate(), token, static_cast<Head&&>(this->head_),+ static_cast<Tail&&>(this->tail_))) {- return asio::async_initiate<CompletionToken, Signatures...>(- initiate(), token,- ASIO_MOVE_OR_LVALUE(Head)(head_),- ASIO_MOVE_OR_LVALUE(Tail)(tail_));+ return async_initiate<CompletionToken, Signatures...>(initiate(),+ token, static_cast<Head&&>(head_), static_cast<Tail&&>(tail_)); } -#if defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS) template <ASIO_COMPLETION_TOKEN_FOR(Signatures...) CompletionToken>- auto operator()(- ASIO_MOVE_ARG(CompletionToken) token) const &+ auto operator()(CompletionToken&& token) const & -> decltype(- asio::async_initiate<CompletionToken, Signatures...>(- initiate(), token, this->head_, this->tail_))+ async_initiate<CompletionToken, Signatures...>(+ initiate(), token, this->head_, this->tail_)) {- return asio::async_initiate<CompletionToken, Signatures...>(+ return 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.@@ -176,17 +157,15 @@ { /// No effect. template <typename... Args>- void operator()(ASIO_MOVE_ARG(Args)...) ASIO_RVALUE_REF_QUAL+ void operator()(Args&&...) && { } -#if defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS) /// No effect. template <typename... Args>- void operator()(ASIO_MOVE_ARG(Args)...) const &+ void operator()(Args&&...) const & { }-#endif // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS) }; #if !defined(GENERATING_DOCUMENTATION)@@ -205,11 +184,10 @@ class deferred_function { public:- /// Constructor. + /// Constructor. template <typename F>- ASIO_CONSTEXPR explicit deferred_function(- deferred_init_tag, ASIO_MOVE_ARG(F) function)- : function_(ASIO_MOVE_CAST(F)(function))+ constexpr explicit deferred_function(deferred_init_tag, F&& function)+ : function_(static_cast<F&&>(function)) { } @@ -218,30 +196,24 @@ public: template <typename... Args>- auto operator()(- ASIO_MOVE_ARG(Args)... args) ASIO_RVALUE_REF_QUAL+ auto operator()(Args&&... args) && -> decltype(- ASIO_MOVE_CAST(Function)(this->function_)(- ASIO_MOVE_CAST(Args)(args)...))+ static_cast<Function&&>(this->function_)(static_cast<Args&&>(args)...)) {- return ASIO_MOVE_CAST(Function)(function_)(- ASIO_MOVE_CAST(Args)(args)...);+ return static_cast<Function&&>(function_)(static_cast<Args&&>(args)...); } -#if defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS) template <typename... Args>- auto operator()(- ASIO_MOVE_ARG(Args)... args) const &- -> decltype(Function(function_)(ASIO_MOVE_CAST(Args)(args)...))+ auto operator()(Args&&... args) const &+ -> decltype(Function(function_)(static_cast<Args&&>(args)...)) {- return Function(function_)(ASIO_MOVE_CAST(Args)(args)...);+ return Function(function_)(static_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)@@ -256,85 +228,72 @@ struct initiate { template <typename Handler, typename... V>- void operator()(Handler handler, ASIO_MOVE_ARG(V)... values)+ void operator()(Handler handler, V&&... values) {- ASIO_MOVE_OR_LVALUE(Handler)(handler)(- ASIO_MOVE_CAST(V)(values)...);+ static_cast<Handler&&>(handler)(static_cast<V&&>(values)...); } }; template <typename CompletionToken, std::size_t... I>- auto invoke_helper(- ASIO_MOVE_ARG(CompletionToken) token,- detail::index_sequence<I...>)+ auto invoke_helper(CompletionToken&& token, detail::index_sequence<I...>) -> decltype(- asio::async_initiate<CompletionToken, void(Values...)>(- initiate(), token,- std::get<I>(- ASIO_MOVE_CAST(std::tuple<Values...>)(this->values_))...))+ async_initiate<CompletionToken, void(Values...)>(initiate(), token,+ std::get<I>(static_cast<std::tuple<Values...>&&>(this->values_))...)) {- return asio::async_initiate<CompletionToken, void(Values...)>(- initiate(), token,- std::get<I>(ASIO_MOVE_CAST(std::tuple<Values...>)(values_))...);+ return async_initiate<CompletionToken, void(Values...)>(initiate(), token,+ std::get<I>(static_cast<std::tuple<Values...>&&>(values_))...); } -#if defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS) template <typename CompletionToken, std::size_t... I>- auto const_invoke_helper(- ASIO_MOVE_ARG(CompletionToken) token,+ auto const_invoke_helper(CompletionToken&& token, detail::index_sequence<I...>) -> decltype(- asio::async_initiate<CompletionToken, void(Values...)>(- initiate(), token, std::get<I>(values_)...))+ async_initiate<CompletionToken, void(Values...)>(+ initiate(), token, std::get<I>(values_)...)) {- return asio::async_initiate<CompletionToken, void(Values...)>(+ return 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>- ASIO_CONSTEXPR explicit deferred_values(- deferred_init_tag, ASIO_MOVE_ARG(V)... values)- : values_(ASIO_MOVE_CAST(V)(values)...)+ constexpr explicit deferred_values(+ deferred_init_tag, V&&... values)+ : values_(static_cast<V&&>(values)...) { } /// Initiate the deferred operation using the supplied completion token. template <ASIO_COMPLETION_TOKEN_FOR(void(Values...)) CompletionToken>- auto operator()(- ASIO_MOVE_ARG(CompletionToken) token) ASIO_RVALUE_REF_QUAL+ auto operator()(CompletionToken&& token) && -> decltype(- this->invoke_helper(- ASIO_MOVE_CAST(CompletionToken)(token),- detail::index_sequence_for<Values...>()))+ this->invoke_helper(+ static_cast<CompletionToken&&>(token),+ detail::index_sequence_for<Values...>())) { return this->invoke_helper(- ASIO_MOVE_CAST(CompletionToken)(token),+ static_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()(- ASIO_MOVE_ARG(CompletionToken) token) const &+ auto operator()(CompletionToken&& token) const & -> decltype(- this->const_invoke_helper(- ASIO_MOVE_CAST(CompletionToken)(token),- detail::index_sequence_for<Values...>()))+ this->const_invoke_helper(+ static_cast<CompletionToken&&>(token),+ detail::index_sequence_for<Values...>())) { return this->const_invoke_helper(- ASIO_MOVE_CAST(CompletionToken)(token),+ static_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)@@ -344,79 +303,70 @@ class ASIO_NODISCARD deferred_async_operation { private:- typedef typename decay<Initiation>::type initiation_t;+ typedef decay_t<Initiation> initiation_t; initiation_t initiation_;- typedef std::tuple<typename decay<InitArgs>::type...> init_args_t;+ typedef std::tuple<decay_t<InitArgs>...> init_args_t; init_args_t init_args_; template <typename CompletionToken, std::size_t... I>- auto invoke_helper(- ASIO_MOVE_ARG(CompletionToken) token,- detail::index_sequence<I...>)+ auto invoke_helper(CompletionToken&& token, detail::index_sequence<I...>) -> decltype(- asio::async_initiate<CompletionToken, Signature>(- ASIO_MOVE_CAST(initiation_t)(initiation_), token,- std::get<I>(ASIO_MOVE_CAST(init_args_t)(init_args_))...))+ 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_))...);+ return async_initiate<CompletionToken, Signature>(+ static_cast<initiation_t&&>(initiation_), token,+ std::get<I>(static_cast<init_args_t&&>(init_args_))...); } -#if defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS) template <typename CompletionToken, std::size_t... I>- auto const_invoke_helper(- ASIO_MOVE_ARG(CompletionToken) token,+ auto const_invoke_helper(CompletionToken&& token, detail::index_sequence<I...>) const & -> decltype(- asio::async_initiate<CompletionToken, Signature>(- initiation_t(initiation_), token, std::get<I>(init_args_)...))- {- return asio::async_initiate<CompletionToken, Signature>(+ async_initiate<CompletionToken, Signature>(+ conditional_t<true, initiation_t, CompletionToken>(initiation_),+ token, std::get<I>(init_args_)...))+ {+ return 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>- 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)...)+ 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)...) { } /// Initiate the asynchronous operation using the supplied completion token. template <ASIO_COMPLETION_TOKEN_FOR(Signature) CompletionToken>- auto operator()(- ASIO_MOVE_ARG(CompletionToken) token) ASIO_RVALUE_REF_QUAL+ auto operator()(CompletionToken&& token) && -> decltype(- this->invoke_helper(- ASIO_MOVE_CAST(CompletionToken)(token),- detail::index_sequence_for<InitArgs...>()))+ this->invoke_helper(+ static_cast<CompletionToken&&>(token),+ detail::index_sequence_for<InitArgs...>())) { return this->invoke_helper(- ASIO_MOVE_CAST(CompletionToken)(token),+ static_cast<CompletionToken&&>(token), detail::index_sequence_for<InitArgs...>()); } -#if defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS) template <ASIO_COMPLETION_TOKEN_FOR(Signature) CompletionToken>- auto operator()(- ASIO_MOVE_ARG(CompletionToken) token) const &+ auto operator()(CompletionToken&& token) const & -> decltype(- this->const_invoke_helper(- ASIO_MOVE_CAST(CompletionToken)(token),- detail::index_sequence_for<InitArgs...>()))+ this->const_invoke_helper(+ static_cast<CompletionToken&&>(token),+ detail::index_sequence_for<InitArgs...>())) { return this->const_invoke_helper(- ASIO_MOVE_CAST(CompletionToken)(token),+ static_cast<CompletionToken&&>(token), detail::index_sequence_for<InitArgs...>()); }-#endif // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS) }; /// Encapsulates a deferred asynchronous operation thas has multiple completion@@ -426,85 +376,75 @@ deferred_signatures<Signatures...>, Initiation, InitArgs...> { private:- typedef typename decay<Initiation>::type initiation_t;+ typedef decay_t<Initiation> initiation_t; initiation_t initiation_;- typedef std::tuple<typename decay<InitArgs>::type...> init_args_t;+ typedef std::tuple<decay_t<InitArgs>...> init_args_t; init_args_t init_args_; template <typename CompletionToken, std::size_t... I>- auto invoke_helper(- ASIO_MOVE_ARG(CompletionToken) token,- detail::index_sequence<I...>)+ auto invoke_helper(CompletionToken&& token, detail::index_sequence<I...>) -> decltype(- asio::async_initiate<CompletionToken, Signatures...>(- ASIO_MOVE_CAST(initiation_t)(initiation_), token,- std::get<I>(ASIO_MOVE_CAST(init_args_t)(init_args_))...))+ 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_))...);+ return async_initiate<CompletionToken, Signatures...>(+ static_cast<initiation_t&&>(initiation_), token,+ std::get<I>(static_cast<init_args_t&&>(init_args_))...); } -#if defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS) template <typename CompletionToken, std::size_t... I>- auto const_invoke_helper(- ASIO_MOVE_ARG(CompletionToken) token,+ auto const_invoke_helper(CompletionToken&& token, detail::index_sequence<I...>) const & -> decltype(- asio::async_initiate<CompletionToken, Signatures...>(- initiation_t(initiation_), token, std::get<I>(init_args_)...))- {- return asio::async_initiate<CompletionToken, Signatures...>(+ async_initiate<CompletionToken, Signatures...>(+ initiation_t(initiation_), token, std::get<I>(init_args_)...))+ {+ return 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>- 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)...)+ 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)...) { } /// Initiate the asynchronous operation using the supplied completion token. template <ASIO_COMPLETION_TOKEN_FOR(Signatures...) CompletionToken>- auto operator()(- ASIO_MOVE_ARG(CompletionToken) token) ASIO_RVALUE_REF_QUAL+ auto operator()(CompletionToken&& token) && -> decltype(- this->invoke_helper(- ASIO_MOVE_CAST(CompletionToken)(token),- detail::index_sequence_for<InitArgs...>()))+ this->invoke_helper(+ static_cast<CompletionToken&&>(token),+ detail::index_sequence_for<InitArgs...>())) { return this->invoke_helper(- ASIO_MOVE_CAST(CompletionToken)(token),+ static_cast<CompletionToken&&>(token), detail::index_sequence_for<InitArgs...>()); } -#if defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS) template <ASIO_COMPLETION_TOKEN_FOR(Signatures...) CompletionToken>- auto operator()(- ASIO_MOVE_ARG(CompletionToken) token) const &+ auto operator()(CompletionToken&& token) const & -> decltype(- this->const_invoke_helper(- ASIO_MOVE_CAST(CompletionToken)(token),- detail::index_sequence_for<InitArgs...>()))+ this->const_invoke_helper(+ static_cast<CompletionToken&&>(token),+ detail::index_sequence_for<InitArgs...>())) { return this->const_invoke_helper(- ASIO_MOVE_CAST(CompletionToken)(token),+ static_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)@@ -516,33 +456,30 @@ { public: template <typename H, typename T>- ASIO_CONSTEXPR explicit deferred_sequence(deferred_init_tag,- ASIO_MOVE_ARG(H) head, ASIO_MOVE_ARG(T) tail)+ constexpr explicit deferred_sequence(deferred_init_tag, H&& head, T&& tail) : detail::deferred_sequence_types<Head, Tail>::base(- ASIO_MOVE_CAST(H)(head), ASIO_MOVE_CAST(T)(tail))+ static_cast<H&&>(head), static_cast<T&&>(tail)) { } #if defined(GENERATING_DOCUMENTATION) template <typename CompletionToken>- auto operator()(ASIO_MOVE_ARG(CompletionToken) token)- ASIO_RVALUE_REF_QUAL;+ auto operator()(CompletionToken&& token) &&; template <typename CompletionToken>- auto operator()(ASIO_MOVE_ARG(CompletionToken) token) const &;-#endif // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)+ auto operator()(CompletionToken&& token) const &;+#endif // defined(GENERATING_DOCUMENTATION) }; #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:@@ -550,10 +487,9 @@ // Helper constructor. template <typename T, typename F>- 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)),+ 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)), bool_(b) { }@@ -565,94 +501,88 @@ public: /// Construct a deferred conditional with the value to determine which branch /// will be executed.- ASIO_CONSTEXPR explicit deferred_conditional(bool b)+ constexpr explicit deferred_conditional(bool b) : on_true_(), on_false_(), bool_(b) { } - /// Invoke the conditional branch bsaed on the stored alue.+ /// Invoke the conditional branch bsaed on the stored value. template <typename... 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)...))+ auto operator()(Args&&... args) &&+ -> decltype(static_cast<OnTrue&&>(on_true_)(static_cast<Args&&>(args)...)) { if (bool_) {- return ASIO_MOVE_OR_LVALUE(OnTrue)(on_true_)(- ASIO_MOVE_CAST(Args)(args)...);+ return static_cast<OnTrue&&>(on_true_)(static_cast<Args&&>(args)...); } else {- return ASIO_MOVE_OR_LVALUE(OnFalse)(on_false_)(- ASIO_MOVE_CAST(Args)(args)...);+ return static_cast<OnFalse&&>(on_false_)(static_cast<Args&&>(args)...); } } -#if defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS) template <typename... Args>- auto operator()(ASIO_MOVE_ARG(Args)... args) const &- -> decltype(on_true_(ASIO_MOVE_CAST(Args)(args)...))+ auto operator()(Args&&... args) const &+ -> decltype(on_true_(static_cast<Args&&>(args)...)) { if (bool_) {- return on_true_(ASIO_MOVE_CAST(Args)(args)...);+ return on_true_(static_cast<Args&&>(args)...); } else {- return on_false_(ASIO_MOVE_CAST(Args)(args)...);+ return on_false_(static_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,- typename constraint<+ constraint_t< is_deferred<T>::value- >::type* = 0,- typename constraint<+ >* = 0,+ constraint_t< is_same<- typename conditional<true, OnTrue, T>::type,+ conditional_t<true, OnTrue, T>, deferred_noop >::value- >::type* = 0) ASIO_RVALUE_REF_QUAL+ >* = 0) && { return deferred_conditional<T, OnFalse>(- bool_, ASIO_MOVE_CAST(T)(on_true),- ASIO_MOVE_CAST(OnFalse)(on_false_));+ bool_, static_cast<T&&>(on_true),+ static_cast<OnFalse&&>(on_false_)); } /// Set the false branch of the conditional. template <typename T> deferred_conditional<OnTrue, T> otherwise(T on_false,- typename constraint<+ constraint_t< is_deferred<T>::value- >::type* = 0,- typename constraint<+ >* = 0,+ constraint_t< !is_same<- typename conditional<true, OnTrue, T>::type,+ conditional_t<true, OnTrue, T>, deferred_noop >::value- >::type* = 0,- typename constraint<+ >* = 0,+ constraint_t< is_same<- typename conditional<true, OnFalse, T>::type,+ conditional_t<true, OnFalse, T>, deferred_noop >::value- >::type* = 0) ASIO_RVALUE_REF_QUAL+ >* = 0) && { return deferred_conditional<OnTrue, T>(- bool_, ASIO_MOVE_CAST(OnTrue)(on_true_),- ASIO_MOVE_CAST(T)(on_false));+ bool_, static_cast<OnTrue&&>(on_true_),+ static_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)@@ -663,9 +593,12 @@ * 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 using the special value @c asio::deferred. For- * example:+ * 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:+ * * @code auto my_deferred_op * = my_socket.async_read_some(my_buffer, * asio::deferred); @endcode@@ -677,7 +610,7 @@ { public: /// Default constructor.- ASIO_CONSTEXPR deferred_t()+ constexpr deferred_t() { } @@ -692,13 +625,13 @@ /// Construct the adapted executor from the inner executor type. template <typename InnerExecutor1> executor_with_default(const InnerExecutor1& ex,- typename constraint<- conditional<+ constraint_t<+ conditional_t< !is_same<InnerExecutor1, executor_with_default>::value, is_convertible<InnerExecutor1, InnerExecutor>, false_type- >::type::value- >::type = 0) ASIO_NOEXCEPT+ >::value+ > = 0) noexcept : InnerExecutor(ex) { }@@ -706,59 +639,54 @@ /// 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;-#endif // defined(ASIO_HAS_ALIAS_TEMPLATES)- // || defined(GENERATING_DOCUMENTATION)+ executor_with_default<typename T::executor_type>>::other; /// 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>::type::template rebind_executor<- executor_with_default<typename decay<T>::type::executor_type>+ static typename decay_t<T>::template rebind_executor<+ executor_with_default<typename decay_t<T>::executor_type> >::other- as_default_on(ASIO_MOVE_ARG(T) object)+ as_default_on(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));+ return typename decay_t<T>::template rebind_executor<+ executor_with_default<typename decay_t<T>::executor_type>+ >::other(static_cast<T&&>(object)); } /// Creates a new deferred from a function. template <typename Function>- typename constraint<- !is_deferred<typename decay<Function>::type>::value,- deferred_function<typename decay<Function>::type>- >::type operator()(ASIO_MOVE_ARG(Function) function) const+ constraint_t<+ !is_deferred<decay_t<Function>>::value,+ deferred_function<decay_t<Function>>+ > operator()(Function&& function) const {- return deferred_function<typename decay<Function>::type>(- deferred_init_tag{}, ASIO_MOVE_CAST(Function)(function));+ return deferred_function<decay_t<Function>>(+ deferred_init_tag{}, static_cast<Function&&>(function)); } /// Passes through anything that is already deferred. template <typename T>- typename constraint<- is_deferred<typename decay<T>::type>::value,- typename decay<T>::type- >::type operator()(ASIO_MOVE_ARG(T) t) const+ constraint_t<+ is_deferred<decay_t<T>>::value,+ decay_t<T>+ > operator()(T&& t) const {- return ASIO_MOVE_CAST(T)(t);+ return static_cast<T&&>(t); } /// Returns a deferred operation that returns the provided values. template <typename... Args>- static ASIO_CONSTEXPR deferred_values<typename decay<Args>::type...>- values(ASIO_MOVE_ARG(Args)... args)+ static constexpr deferred_values<decay_t<Args>...> values(Args&&... args) {- return deferred_values<typename decay<Args>::type...>(- deferred_init_tag{}, ASIO_MOVE_CAST(Args)(args)...);+ return deferred_values<decay_t<Args>...>(+ deferred_init_tag{}, static_cast<Args&&>(args)...); } /// Creates a conditional object for branching deferred operations.- static ASIO_CONSTEXPR deferred_conditional<> when(bool b)+ static constexpr deferred_conditional<> when(bool b) { return deferred_conditional<>(b); }@@ -766,15 +694,13 @@ /// Pipe operator used to chain deferred operations. template <typename Head, typename Tail>-inline auto operator|(Head head, ASIO_MOVE_ARG(Tail) tail)- -> typename constraint<+inline auto operator|(Head head, Tail&& tail)+ -> constraint_t< is_deferred<Head>::value,- decltype(ASIO_MOVE_OR_LVALUE(Head)(head)(- ASIO_MOVE_CAST(Tail)(tail)))- >::type+ decltype(static_cast<Head&&>(head)(static_cast<Tail&&>(tail)))+ > {- return ASIO_MOVE_OR_LVALUE(Head)(head)(- ASIO_MOVE_CAST(Tail)(tail));+ return static_cast<Head&&>(head)(static_cast<Tail&&>(tail)); } /// A @ref completion_token object used to specify that an asynchronous@@ -782,21 +708,12 @@ /** * See the documentation for asio::deferred_t for a usage example. */-#if defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)-constexpr deferred_t deferred;-#elif defined(ASIO_MSVC)-__declspec(selectany) deferred_t deferred;-#endif+ASIO_INLINE_VARIABLE constexpr deferred_t deferred; } // 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -38,8 +38,8 @@ class detached_t { public:- /// Constructor. - ASIO_CONSTEXPR detached_t()+ /// Constructor.+ 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) ASIO_NOEXCEPT+ executor_with_default(const InnerExecutor& ex) noexcept : InnerExecutor(ex) { }@@ -61,9 +61,9 @@ /// that to construct the adapted executor. template <typename OtherExecutor> executor_with_default(const OtherExecutor& ex,- typename constraint<+ constraint_t< is_convertible<OtherExecutor, InnerExecutor>::value- >::type = 0) ASIO_NOEXCEPT+ > = 0) noexcept : InnerExecutor(ex) { }@@ -71,25 +71,21 @@ /// 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;-#endif // defined(ASIO_HAS_ALIAS_TEMPLATES)- // || defined(GENERATING_DOCUMENTATION)+ executor_with_default<typename T::executor_type>>::other; /// 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>::type::template rebind_executor<- executor_with_default<typename decay<T>::type::executor_type>+ static typename decay_t<T>::template rebind_executor<+ executor_with_default<typename decay_t<T>::executor_type> >::other- as_default_on(ASIO_MOVE_ARG(T) object)+ as_default_on(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));+ return typename decay_t<T>::template rebind_executor<+ executor_with_default<typename decay_t<T>::executor_type>+ >::other(static_cast<T&&>(object)); } }; @@ -98,11 +94,7 @@ /** * See the documentation for asio::detached_t for a usage example. */-#if defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)-constexpr detached_t detached;-#elif defined(ASIO_MSVC)-__declspec(selectany) detached_t detached;-#endif+ASIO_INLINE_VARIABLE constexpr detached_t detached; } // namespace asio
link/modules/asio-standalone/asio/include/asio/detail/array.hpp view
@@ -2,7 +2,7 @@ // detail/array.hpp // ~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -17,20 +17,12 @@ #include "asio/detail/config.hpp" -#if defined(ASIO_HAS_STD_ARRAY)-# include <array>-#else // defined(ASIO_HAS_STD_ARRAY)-# include <boost/array.hpp>-#endif // defined(ASIO_HAS_STD_ARRAY)+#include <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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -27,8 +27,6 @@ // 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.-#if defined(ASIO_HAS_STD_ARRAY)-# include <array>-#endif // defined(ASIO_HAS_STD_ARRAY)+#include <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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/detail/atomic_count.hpp view
@@ -2,7 +2,7 @@ // detail/atomic_count.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -19,11 +19,9 @@ #if !defined(ASIO_HAS_THREADS) // Nothing to include.-#elif defined(ASIO_HAS_STD_ATOMIC)+#else // !defined(ASIO_HAS_THREADS) # include <atomic>-#else // defined(ASIO_HAS_STD_ATOMIC)-# include <boost/detail/atomic_count.hpp>-#endif // defined(ASIO_HAS_STD_ATOMIC)+#endif // !defined(ASIO_HAS_THREADS) namespace asio { namespace detail {@@ -34,7 +32,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; }-#elif defined(ASIO_HAS_STD_ATOMIC)+#else // !defined(ASIO_HAS_THREADS) 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; }@@ -53,13 +51,7 @@ } return false; }-#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)+#endif // !defined(ASIO_HAS_THREADS) } // 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -31,12 +31,12 @@ public: typedef cancellation_slot cancellation_slot_type; - cancellation_slot_type get_cancellation_slot() const ASIO_NOEXCEPT+ cancellation_slot_type get_cancellation_slot() const noexcept { return cancellation_state_.slot(); } - cancellation_state get_cancellation_state() const ASIO_NOEXCEPT+ cancellation_state get_cancellation_state() const noexcept { return cancellation_state_; }@@ -57,12 +57,12 @@ template <typename InFilter, typename OutFilter> base_from_cancellation_state(const Handler& handler,- ASIO_MOVE_ARG(InFilter) in_filter,- ASIO_MOVE_ARG(OutFilter) out_filter)+ InFilter&& in_filter,+ OutFilter&& out_filter) : cancellation_state_( asio::get_associated_cancellation_slot(handler),- ASIO_MOVE_CAST(InFilter)(in_filter),- ASIO_MOVE_CAST(OutFilter)(out_filter))+ static_cast<InFilter&&>(in_filter),+ static_cast<OutFilter&&>(out_filter)) { } @@ -81,16 +81,16 @@ template <typename InFilter, typename OutFilter> void reset_cancellation_state(const Handler& handler,- ASIO_MOVE_ARG(InFilter) in_filter,- ASIO_MOVE_ARG(OutFilter) out_filter)+ InFilter&& in_filter,+ OutFilter&& out_filter) { cancellation_state_ = cancellation_state( asio::get_associated_cancellation_slot(handler),- ASIO_MOVE_CAST(InFilter)(in_filter),- ASIO_MOVE_CAST(OutFilter)(out_filter));+ static_cast<InFilter&&>(in_filter),+ static_cast<OutFilter&&>(out_filter)); } - cancellation_type_t cancelled() const ASIO_NOEXCEPT+ cancellation_type_t cancelled() const noexcept { return cancellation_state_.cancelled(); }@@ -101,17 +101,18 @@ template <typename Handler> class base_from_cancellation_state<Handler,- typename enable_if<+ enable_if_t< 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 ASIO_NOEXCEPT+ cancellation_state get_cancellation_state() const noexcept { return cancellation_state(); }@@ -128,8 +129,8 @@ template <typename InFilter, typename OutFilter> base_from_cancellation_state(const Handler&,- ASIO_MOVE_ARG(InFilter),- ASIO_MOVE_ARG(OutFilter))+ InFilter&&,+ OutFilter&&) { } @@ -144,12 +145,12 @@ template <typename InFilter, typename OutFilter> void reset_cancellation_state(const Handler&,- ASIO_MOVE_ARG(InFilter),- ASIO_MOVE_ARG(OutFilter))+ InFilter&&,+ OutFilter&&) { } - ASIO_CONSTEXPR cancellation_type_t cancelled() const ASIO_NOEXCEPT+ constexpr cancellation_type_t cancelled() const 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -29,7 +29,7 @@ protected: explicit base_from_completion_cond(CompletionCondition& completion_condition) : completion_condition_(- ASIO_MOVE_CAST(CompletionCondition)(completion_condition))+ static_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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -17,9 +17,7 @@ #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"@@ -32,31 +30,29 @@ { public: template <typename T>- binder0(int, ASIO_MOVE_ARG(T) handler)- : handler_(ASIO_MOVE_CAST(T)(handler))+ binder0(int, T&& handler)+ : handler_(static_cast<T&&>(handler)) { } binder0(Handler& handler)- : handler_(ASIO_MOVE_CAST(Handler)(handler))+ : handler_(static_cast<Handler&&>(handler)) { } -#if defined(ASIO_HAS_MOVE) binder0(const binder0& other) : handler_(other.handler_) { } binder0(binder0&& other)- : handler_(ASIO_MOVE_CAST(Handler)(other.handler_))+ : handler_(static_cast<Handler&&>(other.handler_)) { }-#endif // defined(ASIO_HAS_MOVE) void operator()() {- ASIO_MOVE_OR_LVALUE(Handler)(handler_)();+ static_cast<Handler&&>(handler_)(); } void operator()() const@@ -69,32 +65,6 @@ }; 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) {@@ -102,36 +72,12 @@ 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<typename decay<Handler>::type> bind_handler(- ASIO_MOVE_ARG(Handler) handler)+inline binder0<decay_t<Handler>> bind_handler(+ Handler&& handler) {- return binder0<typename decay<Handler>::type>(- 0, ASIO_MOVE_CAST(Handler)(handler));+ return binder0<decay_t<Handler>>(+ 0, static_cast<Handler&&>(handler)); } template <typename Handler, typename Arg1>@@ -139,19 +85,18 @@ { public: template <typename T>- binder1(int, ASIO_MOVE_ARG(T) handler, const Arg1& arg1)- : handler_(ASIO_MOVE_CAST(T)(handler)),+ binder1(int, T&& handler, const Arg1& arg1)+ : handler_(static_cast<T&&>(handler)), arg1_(arg1) { } binder1(Handler& handler, const Arg1& arg1)- : handler_(ASIO_MOVE_CAST(Handler)(handler)),+ : handler_(static_cast<Handler&&>(handler)), arg1_(arg1) { } -#if defined(ASIO_HAS_MOVE) binder1(const binder1& other) : handler_(other.handler_), arg1_(other.arg1_)@@ -159,15 +104,14 @@ } binder1(binder1&& other)- : handler_(ASIO_MOVE_CAST(Handler)(other.handler_)),- arg1_(ASIO_MOVE_CAST(Arg1)(other.arg1_))+ : handler_(static_cast<Handler&&>(other.handler_)),+ arg1_(static_cast<Arg1&&>(other.arg1_)) { }-#endif // defined(ASIO_HAS_MOVE) void operator()() {- ASIO_MOVE_OR_LVALUE(Handler)(handler_)(+ static_cast<Handler&&>(handler_)( static_cast<const Arg1&>(arg1_)); } @@ -182,32 +126,6 @@ }; 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) {@@ -215,36 +133,12 @@ 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<typename decay<Handler>::type, Arg1> bind_handler(- ASIO_MOVE_ARG(Handler) handler, const Arg1& arg1)+inline binder1<decay_t<Handler>, Arg1> bind_handler(+ Handler&& handler, const Arg1& arg1) {- return binder1<typename decay<Handler>::type, Arg1>(0,- ASIO_MOVE_CAST(Handler)(handler), arg1);+ return binder1<decay_t<Handler>, Arg1>(0,+ static_cast<Handler&&>(handler), arg1); } template <typename Handler, typename Arg1, typename Arg2>@@ -252,22 +146,21 @@ { public: template <typename T>- binder2(int, ASIO_MOVE_ARG(T) handler,+ binder2(int, T&& handler, const Arg1& arg1, const Arg2& arg2)- : handler_(ASIO_MOVE_CAST(T)(handler)),+ : handler_(static_cast<T&&>(handler)), arg1_(arg1), arg2_(arg2) { } binder2(Handler& handler, const Arg1& arg1, const Arg2& arg2)- : handler_(ASIO_MOVE_CAST(Handler)(handler)),+ : handler_(static_cast<Handler&&>(handler)), arg1_(arg1), arg2_(arg2) { } -#if defined(ASIO_HAS_MOVE) binder2(const binder2& other) : handler_(other.handler_), arg1_(other.arg1_),@@ -276,16 +169,15 @@ } binder2(binder2&& other)- : handler_(ASIO_MOVE_CAST(Handler)(other.handler_)),- arg1_(ASIO_MOVE_CAST(Arg1)(other.arg1_)),- arg2_(ASIO_MOVE_CAST(Arg2)(other.arg2_))+ : handler_(static_cast<Handler&&>(other.handler_)),+ arg1_(static_cast<Arg1&&>(other.arg1_)),+ arg2_(static_cast<Arg2&&>(other.arg2_)) { }-#endif // defined(ASIO_HAS_MOVE) void operator()() {- ASIO_MOVE_OR_LVALUE(Handler)(handler_)(+ static_cast<Handler&&>(handler_)( static_cast<const Arg1&>(arg1_), static_cast<const Arg2&>(arg2_)); }@@ -302,32 +194,6 @@ }; 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) {@@ -335,36 +201,12 @@ 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<typename decay<Handler>::type, Arg1, Arg2> bind_handler(- ASIO_MOVE_ARG(Handler) handler, const Arg1& arg1, const Arg2& arg2)+inline binder2<decay_t<Handler>, Arg1, Arg2> bind_handler(+ Handler&& handler, const Arg1& arg1, const Arg2& arg2) {- return binder2<typename decay<Handler>::type, Arg1, Arg2>(0,- ASIO_MOVE_CAST(Handler)(handler), arg1, arg2);+ return binder2<decay_t<Handler>, Arg1, Arg2>(0,+ static_cast<Handler&&>(handler), arg1, arg2); } template <typename Handler, typename Arg1, typename Arg2, typename Arg3>@@ -372,9 +214,9 @@ { public: template <typename T>- binder3(int, ASIO_MOVE_ARG(T) handler, const Arg1& arg1,+ binder3(int, T&& handler, const Arg1& arg1, const Arg2& arg2, const Arg3& arg3)- : handler_(ASIO_MOVE_CAST(T)(handler)),+ : handler_(static_cast<T&&>(handler)), arg1_(arg1), arg2_(arg2), arg3_(arg3)@@ -383,14 +225,13 @@ binder3(Handler& handler, const Arg1& arg1, const Arg2& arg2, const Arg3& arg3)- : handler_(ASIO_MOVE_CAST(Handler)(handler)),+ : handler_(static_cast<Handler&&>(handler)), arg1_(arg1), arg2_(arg2), arg3_(arg3) { } -#if defined(ASIO_HAS_MOVE) binder3(const binder3& other) : handler_(other.handler_), arg1_(other.arg1_),@@ -400,17 +241,16 @@ } binder3(binder3&& other)- : 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_))+ : handler_(static_cast<Handler&&>(other.handler_)),+ arg1_(static_cast<Arg1&&>(other.arg1_)),+ arg2_(static_cast<Arg2&&>(other.arg2_)),+ arg3_(static_cast<Arg3&&>(other.arg3_)) { }-#endif // defined(ASIO_HAS_MOVE) void operator()() {- ASIO_MOVE_OR_LVALUE(Handler)(handler_)(+ static_cast<Handler&&>(handler_)( static_cast<const Arg1&>(arg1_), static_cast<const Arg2&>(arg2_), static_cast<const Arg3&>(arg3_));@@ -429,32 +269,6 @@ }; 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) {@@ -462,39 +276,13 @@ 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<typename decay<Handler>::type, Arg1, Arg2, Arg3> bind_handler(- ASIO_MOVE_ARG(Handler) handler, const Arg1& arg1, const Arg2& arg2,+inline binder3<decay_t<Handler>, Arg1, Arg2, Arg3> bind_handler(+ Handler&& handler, const Arg1& arg1, const Arg2& arg2, const Arg3& arg3) {- return binder3<typename decay<Handler>::type, Arg1, Arg2, Arg3>(0,- ASIO_MOVE_CAST(Handler)(handler), arg1, arg2, arg3);+ return binder3<decay_t<Handler>, Arg1, Arg2, Arg3>(0,+ static_cast<Handler&&>(handler), arg1, arg2, arg3); } template <typename Handler, typename Arg1,@@ -503,9 +291,9 @@ { public: template <typename T>- binder4(int, ASIO_MOVE_ARG(T) handler, const Arg1& arg1,+ binder4(int, T&& handler, const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, const Arg4& arg4)- : handler_(ASIO_MOVE_CAST(T)(handler)),+ : handler_(static_cast<T&&>(handler)), arg1_(arg1), arg2_(arg2), arg3_(arg3),@@ -515,7 +303,7 @@ binder4(Handler& handler, const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, const Arg4& arg4)- : handler_(ASIO_MOVE_CAST(Handler)(handler)),+ : handler_(static_cast<Handler&&>(handler)), arg1_(arg1), arg2_(arg2), arg3_(arg3),@@ -523,7 +311,6 @@ { } -#if defined(ASIO_HAS_MOVE) binder4(const binder4& other) : handler_(other.handler_), arg1_(other.arg1_),@@ -534,18 +321,17 @@ } binder4(binder4&& other)- : 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_))+ : 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_)) { }-#endif // defined(ASIO_HAS_MOVE) void operator()() {- ASIO_MOVE_OR_LVALUE(Handler)(handler_)(+ static_cast<Handler&&>(handler_)( static_cast<const Arg1&>(arg1_), static_cast<const Arg2&>(arg2_), static_cast<const Arg3&>(arg3_),@@ -567,34 +353,6 @@ 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) {@@ -602,40 +360,14 @@ 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<typename decay<Handler>::type, Arg1, Arg2, Arg3, Arg4>-bind_handler(ASIO_MOVE_ARG(Handler) handler, const Arg1& arg1,+inline binder4<decay_t<Handler>, Arg1, Arg2, Arg3, Arg4>+bind_handler(Handler&& handler, const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, const Arg4& arg4) {- return binder4<typename decay<Handler>::type, Arg1, Arg2, Arg3, Arg4>(0,- ASIO_MOVE_CAST(Handler)(handler), arg1, arg2, arg3, arg4);+ return binder4<decay_t<Handler>, Arg1, Arg2, Arg3, Arg4>(0,+ static_cast<Handler&&>(handler), arg1, arg2, arg3, arg4); } template <typename Handler, typename Arg1, typename Arg2,@@ -644,9 +376,9 @@ { public: template <typename T>- binder5(int, ASIO_MOVE_ARG(T) handler, const Arg1& arg1,+ binder5(int, T&& handler, const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, const Arg4& arg4, const Arg5& arg5)- : handler_(ASIO_MOVE_CAST(T)(handler)),+ : handler_(static_cast<T&&>(handler)), arg1_(arg1), arg2_(arg2), arg3_(arg3),@@ -657,7 +389,7 @@ binder5(Handler& handler, const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, const Arg4& arg4, const Arg5& arg5)- : handler_(ASIO_MOVE_CAST(Handler)(handler)),+ : handler_(static_cast<Handler&&>(handler)), arg1_(arg1), arg2_(arg2), arg3_(arg3),@@ -666,7 +398,6 @@ { } -#if defined(ASIO_HAS_MOVE) binder5(const binder5& other) : handler_(other.handler_), arg1_(other.arg1_),@@ -678,19 +409,18 @@ } binder5(binder5&& other)- : 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_))+ : 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_)) { }-#endif // defined(ASIO_HAS_MOVE) void operator()() {- ASIO_MOVE_OR_LVALUE(Handler)(handler_)(+ static_cast<Handler&&>(handler_)( static_cast<const Arg1&>(arg1_), static_cast<const Arg2&>(arg2_), static_cast<const Arg3&>(arg3_),@@ -714,34 +444,6 @@ 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) {@@ -749,65 +451,37 @@ 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<typename decay<Handler>::type, Arg1, Arg2, Arg3, Arg4, Arg5>-bind_handler(ASIO_MOVE_ARG(Handler) handler, const Arg1& arg1,+inline binder5<decay_t<Handler>, Arg1, Arg2, Arg3, Arg4, Arg5>+bind_handler(Handler&& handler, const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, const Arg4& arg4, const Arg5& arg5) {- return binder5<typename decay<Handler>::type, Arg1, Arg2, Arg3, Arg4, Arg5>(0,- ASIO_MOVE_CAST(Handler)(handler), arg1, arg2, arg3, arg4, arg5);+ return binder5<decay_t<Handler>, Arg1, Arg2, Arg3, Arg4, Arg5>(0,+ static_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, ASIO_MOVE_ARG(Handler) handler,- ASIO_MOVE_ARG(Arg1) arg1)- : handler_(ASIO_MOVE_CAST(Handler)(handler)),- arg1_(ASIO_MOVE_CAST(Arg1)(arg1))+ move_binder1(int, Handler&& handler,+ Arg1&& arg1)+ : handler_(static_cast<Handler&&>(handler)),+ arg1_(static_cast<Arg1&&>(arg1)) { } move_binder1(move_binder1&& other)- : handler_(ASIO_MOVE_CAST(Handler)(other.handler_)),- arg1_(ASIO_MOVE_CAST(Arg1)(other.arg1_))+ : handler_(static_cast<Handler&&>(other.handler_)),+ arg1_(static_cast<Arg1&&>(other.arg1_)) { } void operator()() {- ASIO_MOVE_OR_LVALUE(Handler)(handler_)(- ASIO_MOVE_CAST(Arg1)(arg1_));+ static_cast<Handler&&>(handler_)(+ static_cast<Arg1&&>(arg1_)); } //private:@@ -816,32 +490,6 @@ }; 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) {@@ -849,42 +497,30 @@ 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, ASIO_MOVE_ARG(Handler) handler,- const Arg1& arg1, ASIO_MOVE_ARG(Arg2) arg2)- : handler_(ASIO_MOVE_CAST(Handler)(handler)),+ move_binder2(int, Handler&& handler,+ const Arg1& arg1, Arg2&& arg2)+ : handler_(static_cast<Handler&&>(handler)), arg1_(arg1),- arg2_(ASIO_MOVE_CAST(Arg2)(arg2))+ arg2_(static_cast<Arg2&&>(arg2)) { } move_binder2(move_binder2&& other)- : handler_(ASIO_MOVE_CAST(Handler)(other.handler_)),- arg1_(ASIO_MOVE_CAST(Arg1)(other.arg1_)),- arg2_(ASIO_MOVE_CAST(Arg2)(other.arg2_))+ : handler_(static_cast<Handler&&>(other.handler_)),+ arg1_(static_cast<Arg1&&>(other.arg1_)),+ arg2_(static_cast<Arg2&&>(other.arg2_)) { } void operator()() {- ASIO_MOVE_OR_LVALUE(Handler)(handler_)(+ static_cast<Handler&&>(handler_)( static_cast<const Arg1&>(arg1_),- ASIO_MOVE_CAST(Arg2)(arg2_));+ static_cast<Arg2&&>(arg2_)); } //private:@@ -894,32 +530,6 @@ }; 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) {@@ -927,20 +537,6 @@ 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,@@ -949,18 +545,15 @@ detail::binder0<Handler>, DefaultCandidate> : Associator<Handler, DefaultCandidate> {- static typename Associator<Handler, DefaultCandidate>::type- get(const detail::binder0<Handler>& h) ASIO_NOEXCEPT+ static typename Associator<Handler, DefaultCandidate>::type get(+ const detail::binder0<Handler>& h) noexcept { return Associator<Handler, DefaultCandidate>::get(h.handler_); } - 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)))+ static auto get(const detail::binder0<Handler>& h,+ const DefaultCandidate& c) noexcept+ -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c)) { return Associator<Handler, DefaultCandidate>::get(h.handler_, c); }@@ -972,18 +565,15 @@ detail::binder1<Handler, Arg1>, DefaultCandidate> : Associator<Handler, DefaultCandidate> {- static typename Associator<Handler, DefaultCandidate>::type- get(const detail::binder1<Handler, Arg1>& h) ASIO_NOEXCEPT+ static typename Associator<Handler, DefaultCandidate>::type get(+ const detail::binder1<Handler, Arg1>& h) noexcept { return Associator<Handler, DefaultCandidate>::get(h.handler_); } - 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)))+ static auto get(const detail::binder1<Handler, Arg1>& h,+ const DefaultCandidate& c) noexcept+ -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c)) { return Associator<Handler, DefaultCandidate>::get(h.handler_, c); }@@ -996,18 +586,15 @@ detail::binder2<Handler, Arg1, Arg2>, DefaultCandidate> : Associator<Handler, DefaultCandidate> {- static typename Associator<Handler, DefaultCandidate>::type- get(const detail::binder2<Handler, Arg1, Arg2>& h) ASIO_NOEXCEPT+ static typename Associator<Handler, DefaultCandidate>::type get(+ const detail::binder2<Handler, Arg1, Arg2>& h) noexcept { return Associator<Handler, DefaultCandidate>::get(h.handler_); } - 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)))+ static auto get(const detail::binder2<Handler, Arg1, Arg2>& h,+ const DefaultCandidate& c) noexcept+ -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c)) { return Associator<Handler, DefaultCandidate>::get(h.handler_, c); }@@ -1020,18 +607,15 @@ 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) ASIO_NOEXCEPT+ static typename Associator<Handler, DefaultCandidate>::type get(+ const detail::binder3<Handler, Arg1, Arg2, Arg3>& h) noexcept { return Associator<Handler, DefaultCandidate>::get(h.handler_); } - 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)))+ static auto get(const detail::binder3<Handler, Arg1, Arg2, Arg3>& h,+ const DefaultCandidate& c) noexcept+ -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c)) { return Associator<Handler, DefaultCandidate>::get(h.handler_, c); }@@ -1044,19 +628,15 @@ 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)- ASIO_NOEXCEPT+ static typename Associator<Handler, DefaultCandidate>::type get(+ const detail::binder4<Handler, Arg1, Arg2, Arg3, Arg4>& h) noexcept { return Associator<Handler, DefaultCandidate>::get(h.handler_); } - 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)))+ static auto get(const detail::binder4<Handler, Arg1, Arg2, Arg3, Arg4>& h,+ const DefaultCandidate& c) noexcept+ -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c)) { return Associator<Handler, DefaultCandidate>::get(h.handler_, c); }@@ -1069,74 +649,60 @@ 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)- ASIO_NOEXCEPT+ static typename Associator<Handler, DefaultCandidate>::type get(+ const detail::binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>& h) noexcept { return Associator<Handler, DefaultCandidate>::get(h.handler_); } - 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)))+ 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)) { 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) ASIO_NOEXCEPT+ static typename Associator<Handler, DefaultCandidate>::type get(+ const detail::move_binder1<Handler, Arg1>& h) noexcept { return Associator<Handler, DefaultCandidate>::get(h.handler_); } - 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)))+ static auto get(const detail::move_binder1<Handler, Arg1>& h,+ const DefaultCandidate& c) noexcept+ -> decltype(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) ASIO_NOEXCEPT+ static typename Associator<Handler, DefaultCandidate>::type get(+ const detail::move_binder2<Handler, Arg1, Arg2>& h) noexcept { return Associator<Handler, DefaultCandidate>::get(h.handler_); } - 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)))+ static auto get(const detail::move_binder2<Handler, Arg1, Arg2>& h,+ const DefaultCandidate& c) noexcept+ -> decltype(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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -18,7 +18,6 @@ #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" @@ -91,7 +90,7 @@ { fenced_block b(fenced_block::half); ASIO_HANDLER_INVOCATION_BEGIN(());- asio_handler_invoke_helpers::invoke(o->handler_, o->handler_);+ static_cast<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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -385,147 +385,7 @@ 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 {@@ -674,7 +534,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:@@ -749,10 +609,8 @@ 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:@@ -826,8 +684,6 @@ 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -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
@@ -1,89 +0,0 @@-//-// 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/detail/chrono.hpp view
@@ -2,7 +2,7 @@ // detail/chrono.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -16,17 +16,11 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"--#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)+#include <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;@@ -44,21 +38,6 @@ #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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/detail/completion_handler.hpp view
@@ -2,7 +2,7 @@ // detail/completion_handler.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -35,7 +35,7 @@ completion_handler(Handler& h, const IoExecutor& io_ex) : operation(&completion_handler::do_complete),- handler_(ASIO_MOVE_CAST(Handler)(h)),+ handler_(static_cast<Handler&&>(h)), work_(handler_, io_ex) { }@@ -52,7 +52,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<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(ASIO_MOVE_CAST(Handler)(h->handler_));+ Handler handler(static_cast<Handler&&>(h->handler_)); p.h = asio::detail::addressof(handler); p.reset();
+ link/modules/asio-standalone/asio/include/asio/detail/completion_message.hpp view
@@ -0,0 +1,127 @@+//+// 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 view
@@ -0,0 +1,220 @@+//+// 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 view
@@ -0,0 +1,79 @@+//+// 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -17,7 +17,6 @@ #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"@@ -33,11 +32,9 @@ class composed_work_guard { public:- typedef typename decay<- typename prefer_result<Executor,- execution::outstanding_work_t::tracked_t- >::type- >::type executor_type;+ typedef decay_t<+ prefer_result_t<Executor, execution::outstanding_work_t::tracked_t>+ > executor_type; composed_work_guard(const Executor& ex) : executor_(asio::prefer(ex, execution::outstanding_work.tracked))@@ -48,7 +45,7 @@ { } - executor_type get_executor() const ASIO_NOEXCEPT+ executor_type get_executor() const noexcept { return executor_; }@@ -71,7 +68,7 @@ { } - executor_type get_executor() const ASIO_NOEXCEPT+ executor_type get_executor() const noexcept { return system_executor(); }@@ -81,9 +78,10 @@ template <typename Executor> struct composed_work_guard<Executor,- typename enable_if<+ enable_if_t< !execution::is_executor<Executor>::value- >::type> : executor_work_guard<Executor>+ >+ > : executor_work_guard<Executor> { composed_work_guard(const Executor& ex) : executor_work_guard<Executor>(ex)@@ -99,7 +97,7 @@ template <> struct composed_io_executors<void()> {- composed_io_executors() ASIO_NOEXCEPT+ composed_io_executors() noexcept : head_(system_executor()) { }@@ -116,7 +114,7 @@ template <typename Head> struct composed_io_executors<void(Head)> {- explicit composed_io_executors(const Head& ex) ASIO_NOEXCEPT+ explicit composed_io_executors(const Head& ex) noexcept : head_(ex) { }@@ -132,13 +130,11 @@ 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) ASIO_NOEXCEPT+ const Tail&... tail) noexcept : head_(head), tail_(tail...) {@@ -162,45 +158,6 @@ 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; @@ -209,7 +166,7 @@ { typedef composed_io_executors<void()> executors_type; - composed_work(const executors_type&) ASIO_NOEXCEPT+ composed_work(const executors_type&) noexcept : head_(system_executor()) { }@@ -228,7 +185,7 @@ { typedef composed_io_executors<void(Head)> executors_type; - explicit composed_work(const executors_type& ex) ASIO_NOEXCEPT+ explicit composed_work(const executors_type& ex) noexcept : head_(ex.head_) { }@@ -242,14 +199,12 @@ 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) ASIO_NOEXCEPT+ explicit composed_work(const executors_type& ex) noexcept : head_(ex.head_), tail_(ex.tail_) {@@ -266,56 +221,25 @@ 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,- typename enable_if<+ enable_if_t< !is_executor<IoObject>::value- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< !execution::is_executor<IoObject>::value- >::type* = 0)+ >* = 0) { return io_object.get_executor(); } template <typename Executor> inline const Executor& get_composed_io_executor(const Executor& ex,- typename enable_if<+ enable_if_t< is_executor<Executor>::value || execution::is_executor<Executor>::value- >::type* = 0)+ >* = 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -70,6 +70,14 @@ { 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; }@@ -104,8 +112,9 @@ }; // Constructor.- explicit conditionally_enabled_mutex(bool enabled)- : enabled_(enabled)+ explicit conditionally_enabled_mutex(bool enabled, int spin_count = 0)+ : spin_count_(spin_count),+ enabled_(enabled) { } @@ -120,11 +129,22 @@ 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.@@ -138,6 +158,7 @@ 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,2307 +2,1429 @@ // detail/config.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_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__)+// 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__) # 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -35,21 +35,17 @@ }; 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@@ -201,77 +197,39 @@ template <> class consuming_buffers<mutable_buffer, mutable_buffer, const mutable_buffer*>- : public consuming_single_buffer<ASIO_MUTABLE_BUFFER>+ : public consuming_single_buffer<mutable_buffer> { public: explicit consuming_buffers(const mutable_buffer& buffer)- : consuming_single_buffer<ASIO_MUTABLE_BUFFER>(buffer)+ : consuming_single_buffer<mutable_buffer>(buffer) { } }; template <> class consuming_buffers<const_buffer, mutable_buffer, const mutable_buffer*>- : public consuming_single_buffer<ASIO_CONST_BUFFER>+ : public consuming_single_buffer<const_buffer> { public: explicit consuming_buffers(const mutable_buffer& buffer)- : consuming_single_buffer<ASIO_CONST_BUFFER>(buffer)+ : consuming_single_buffer<const_buffer>(buffer) { } }; template <> class consuming_buffers<const_buffer, const_buffer, const const_buffer*>- : public consuming_single_buffer<ASIO_CONST_BUFFER>+ : public consuming_single_buffer<const_buffer> { public: explicit consuming_buffers(const const_buffer& buffer)- : consuming_single_buffer<ASIO_CONST_BUFFER>(buffer)+ : consuming_single_buffer<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> {@@ -356,8 +314,6 @@ 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>@@ -407,8 +363,6 @@ 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -20,11 +20,7 @@ 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -16,16 +16,10 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"--#if defined(ASIO_HAS_CSTDINT)-# include <cstdint>-#else // defined(ASIO_HAS_CSTDINT)-# include <boost/cstdint.hpp>-#endif // defined(ASIO_HAS_CSTDINT)+#include <cstdint> namespace asio { -#if defined(ASIO_HAS_CSTDINT) using std::int16_t; using std::int_least16_t; using std::uint16_t;@@ -40,22 +34,6 @@ 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -19,6 +19,7 @@ #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"@@ -28,7 +29,6 @@ #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,17 +43,20 @@ namespace asio { namespace detail { -template <typename Time_Traits>+template <typename TimeTraits> class deadline_timer_service- : public execution_context_service_base<deadline_timer_service<Time_Traits> >+ : public execution_context_service_base<deadline_timer_service<TimeTraits>> { public: // The time type.- typedef typename Time_Traits::time_type time_type;+ typedef typename TimeTraits::time_type time_type; // The duration type.- typedef typename Time_Traits::duration_type duration_type;+ typedef typename TimeTraits::duration_type duration_type; + // The allocator type.+ typedef execution_context::allocator<void> allocator_type;+ // The implementation type of the timer. This type is dependent on the // underlying implementation of the timer service. struct implementation_type@@ -61,13 +64,15 @@ { time_type expiry; bool might_have_pending_waits;- typename timer_queue<Time_Traits>::per_timer_data timer_data;+ typename timer_queue<TimeTraits, allocator_type>::per_timer_data timer_data; }; // Constructor. deadline_timer_service(execution_context& context) : execution_context_service_base<- deadline_timer_service<Time_Traits> >(context),+ deadline_timer_service<TimeTraits>>(context),+ timer_queue_(allocator_type(context),+ config(context).get("timer", "heap_reserve", 0U)), scheduler_(asio::use_service<timer_scheduler>(context)) { scheduler_.init_task();@@ -103,7 +108,11 @@ void move_construct(implementation_type& impl, implementation_type& other_impl) {- scheduler_.move_timer(timer_queue_, impl.timer_data, other_impl.timer_data);+ if (other_impl.might_have_pending_waits)+ {+ scheduler_.move_timer(timer_queue_,+ impl.timer_data, other_impl.timer_data);+ } impl.expiry = other_impl.expiry; other_impl.expiry = time_type();@@ -200,7 +209,7 @@ // Get the expiry time for the timer relative to now. duration_type expires_from_now(const implementation_type& impl) const {- return Time_Traits::subtract(this->expiry(impl), Time_Traits::now());+ return TimeTraits::subtract(this->expiry(impl), TimeTraits::now()); } // Set the expiry time for the timer as an absolute time.@@ -218,7 +227,7 @@ const duration_type& expiry_time, asio::error_code& ec) { return expires_at(impl,- Time_Traits::add(Time_Traits::now(), expiry_time), ec);+ TimeTraits::add(TimeTraits::now(), expiry_time), ec); } // Set the expiry time for the timer relative to now.@@ -226,19 +235,19 @@ const duration_type& expiry_time, asio::error_code& ec) { return expires_at(impl,- Time_Traits::add(Time_Traits::now(), expiry_time), ec);+ TimeTraits::add(TimeTraits::now(), expiry_time), ec); } // Perform a blocking wait on the timer. void wait(implementation_type& impl, asio::error_code& ec) {- time_type now = Time_Traits::now();+ time_type now = TimeTraits::now(); ec = asio::error_code();- while (Time_Traits::less_than(now, impl.expiry) && !ec)+ while (TimeTraits::less_than(now, impl.expiry) && !ec) {- this->do_wait(Time_Traits::to_posix_duration(- Time_Traits::subtract(impl.expiry, now)), ec);- now = Time_Traits::now();+ this->do_wait(TimeTraits::to_posix_duration(+ TimeTraits::subtract(impl.expiry, now)), ec);+ now = TimeTraits::now(); } } @@ -247,7 +256,7 @@ void async_wait(implementation_type& impl, Handler& handler, const IoExecutor& io_ex) {- typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -297,7 +306,7 @@ { public: op_cancellation(deadline_timer_service* s,- typename timer_queue<Time_Traits>::per_timer_data* p)+ typename timer_queue<TimeTraits, allocator_type>::per_timer_data* p) : service_(s), timer_data_(p) {@@ -317,11 +326,12 @@ private: deadline_timer_service* service_;- typename timer_queue<Time_Traits>::per_timer_data* timer_data_;+ typename timer_queue<TimeTraits, allocator_type>::per_timer_data*+ timer_data_; }; // The queue of timers.- timer_queue<Time_Traits> timer_queue_;+ timer_queue<TimeTraits, allocator_type> 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/detail/descriptor_ops.hpp view
@@ -2,7 +2,7 @@ // detail/descriptor_ops.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -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_(ASIO_MOVE_CAST(Handler)(handler)),+ handler_(static_cast<Handler&&>(handler)), work_(handler_, io_ex) { }@@ -115,7 +115,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<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(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -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_(ASIO_MOVE_CAST(Handler)(handler)),+ handler_(static_cast<Handler&&>(handler)), work_(handler_, io_ex) { }@@ -114,7 +114,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<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(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -108,10 +108,9 @@ { start_op(op_type, descriptor, descriptor_data, op, is_continuation, allow_speculative,- &epoll_reactor::call_post_immediate_completion, this);+ &dev_poll_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.@@ -141,38 +140,39 @@ ASIO_DECL void cleanup_descriptor_data(per_descriptor_data&); // Add a new timer queue to the reactor.- template <typename Time_Traits>- void add_timer_queue(timer_queue<Time_Traits>& queue);+ template <typename TimeTraits, typename Allocator>+ void add_timer_queue(timer_queue<TimeTraits, Allocator>& queue); // Remove a timer queue from the reactor.- template <typename Time_Traits>- void remove_timer_queue(timer_queue<Time_Traits>& queue);+ template <typename TimeTraits, typename Allocator>+ void remove_timer_queue(timer_queue<TimeTraits, Allocator>& queue); // Schedule a new operation in the given timer queue to expire at the // specified absolute time.- 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);+ 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); // Cancel the timer operations associated with the given token. Returns the // number of operations that have been posted or dispatched.- template <typename Time_Traits>- std::size_t cancel_timer(timer_queue<Time_Traits>& queue,- typename timer_queue<Time_Traits>::per_timer_data& timer,+ template <typename TimeTraits, typename Allocator>+ std::size_t cancel_timer(timer_queue<TimeTraits, Allocator>& queue,+ typename timer_queue<TimeTraits, Allocator>::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 Time_Traits>- void cancel_timer_by_key(timer_queue<Time_Traits>& queue,- typename timer_queue<Time_Traits>::per_timer_data* timer,+ template <typename TimeTraits, typename Allocator>+ void cancel_timer_by_key(timer_queue<TimeTraits, Allocator>& queue,+ typename timer_queue<TimeTraits, Allocator>::per_timer_data* timer, void* cancellation_key); // Move the timer operations associated with the given timer.- 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);+ 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); // 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -55,11 +55,8 @@ connect_op = 1, except_op = 2, max_ops = 3 }; // Per-descriptor queues.- class descriptor_state : operation+ struct descriptor_state : operation {- friend class epoll_reactor;- friend class object_pool_access;- descriptor_state* next_; descriptor_state* prev_; @@ -71,7 +68,7 @@ bool try_speculative_[max_ops]; bool shutdown_; - ASIO_DECL descriptor_state(bool locking);+ ASIO_DECL descriptor_state(bool locking, int spin_count); 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);@@ -172,38 +169,39 @@ per_descriptor_data& descriptor_data); // Add a new timer queue to the reactor.- template <typename Time_Traits>- void add_timer_queue(timer_queue<Time_Traits>& timer_queue);+ template <typename TimeTraits, typename Allocator>+ void add_timer_queue(timer_queue<TimeTraits, Allocator>& timer_queue); // Remove a timer queue from the reactor.- template <typename Time_Traits>- void remove_timer_queue(timer_queue<Time_Traits>& timer_queue);+ template <typename TimeTraits, typename Allocator>+ void remove_timer_queue(timer_queue<TimeTraits, Allocator>& timer_queue); // Schedule a new operation in the given timer queue to expire at the // specified absolute time.- 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);+ 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); // Cancel the timer operations associated with the given token. Returns the // number of operations that have been posted or dispatched.- template <typename Time_Traits>- std::size_t cancel_timer(timer_queue<Time_Traits>& queue,- typename timer_queue<Time_Traits>::per_timer_data& timer,+ template <typename TimeTraits, typename Allocator>+ std::size_t cancel_timer(timer_queue<TimeTraits, Allocator>& queue,+ typename timer_queue<TimeTraits, Allocator>::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 Time_Traits>- void cancel_timer_by_key(timer_queue<Time_Traits>& queue,- typename timer_queue<Time_Traits>::per_timer_data* timer,+ template <typename TimeTraits, typename Allocator>+ void cancel_timer_by_key(timer_queue<TimeTraits, Allocator>& queue,+ typename timer_queue<TimeTraits, Allocator>::per_timer_data* timer, void* cancellation_key); // Move the timer operations associated with the given timer.- 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);+ 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); // Run epoll once until interrupted or events are ready to be dispatched. ASIO_DECL void run(long usec, op_queue<operation>& ops);@@ -269,11 +267,18 @@ // 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> registered_descriptors_;+ object_pool<descriptor_state, execution_context::allocator<void>>+ 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -23,10 +23,8 @@ # include "asio/detail/win_event.hpp" #elif defined(ASIO_HAS_PTHREADS) # include "asio/detail/posix_event.hpp"-#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!+# include "asio/detail/std_event.hpp" #endif namespace asio {@@ -38,7 +36,7 @@ typedef win_event event; #elif defined(ASIO_HAS_PTHREADS) typedef posix_event event;-#elif defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR)+#else 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2025 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -16,24 +16,13 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"--#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)+#include <exception> 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -17,7 +17,6 @@ #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"@@ -25,8 +24,6 @@ namespace asio { namespace detail { -#if defined(ASIO_HAS_MOVE)- // Lightweight, move-only function object wrapper. class executor_function {@@ -38,11 +35,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(ASIO_MOVE_CAST(F)(f), a);+ impl_ = new (p.v) impl_type(static_cast<F&&>(f), a); p.v = 0; } - executor_function(executor_function&& other) ASIO_NOEXCEPT+ executor_function(executor_function&& other) noexcept : impl_(other.impl_) { other.impl_ = 0;@@ -79,8 +76,8 @@ thread_info_base::executor_function_tag, impl); template <typename F>- impl(ASIO_MOVE_ARG(F) f, const Alloc& a)- : function_(ASIO_MOVE_CAST(F)(f)),+ impl(F&& f, const Alloc& a)+ : function_(static_cast<F&&>(f)), allocator_(a) { complete_ = &executor_function::complete<Function, Alloc>;@@ -106,74 +103,25 @@ // 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(ASIO_MOVE_CAST(Function)(i->function_));+ Function function(static_cast<Function&&>(i->function_)); p.reset(); // Make the upcall if required. if (call) {- asio_handler_invoke_helpers::invoke(function, function);+ static_cast<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) ASIO_NOEXCEPT+ explicit executor_function_view(F& f) 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -18,7 +18,6 @@ #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"@@ -34,9 +33,9 @@ ASIO_DEFINE_HANDLER_ALLOCATOR_PTR(executor_op); template <typename H>- executor_op(ASIO_MOVE_ARG(H) h, const Alloc& allocator)+ executor_op(H&& h, const Alloc& allocator) : Operation(&executor_op::do_complete),- handler_(ASIO_MOVE_CAST(H)(h)),+ handler_(static_cast<H&&>(h)), allocator_(allocator) { }@@ -59,7 +58,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(ASIO_MOVE_CAST(Handler)(o->handler_));+ Handler handler(static_cast<Handler&&>(o->handler_)); p.reset(); // Make the upcall if required.@@ -67,7 +66,7 @@ { fenced_block b(fenced_block::half); ASIO_HANDLER_INVOCATION_BEGIN(());- asio_handler_invoke_helpers::invoke(handler, handler);+ static_cast<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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/detail/fenced_block.hpp view
@@ -2,7 +2,7 @@ // detail/fenced_block.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -20,28 +20,8 @@ #if !defined(ASIO_HAS_THREADS) \ || defined(ASIO_DISABLE_FENCED_BLOCK) # include "asio/detail/null_fenced_block.hpp"-#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"+# include "asio/detail/std_fenced_block.hpp" #endif namespace asio {@@ -50,28 +30,8 @@ #if !defined(ASIO_HAS_THREADS) \ || defined(ASIO_DISABLE_FENCED_BLOCK) typedef null_fenced_block fenced_block;-#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;+typedef std_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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -16,28 +16,17 @@ #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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -16,18 +16,17 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"-#if defined(ASIO_HAS_STD_FUTURE)-# include <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)-# define ASIO_HAS_STD_FUTURE_CLASS 1-# endif // defined(_GLIBCXX_HAS_GTHREADS)-# else // defined(__GNUC__) && !defined(ASIO_HAS_CLANG_LIBCXX)+#if defined(__GNUC__) && !defined(ASIO_HAS_CLANG_LIBCXX)+# if defined(_GLIBCXX_HAS_GTHREADS) # define ASIO_HAS_STD_FUTURE_CLASS 1-# endif // defined(__GNUC__) && !defined(ASIO_HAS_CLANG_LIBCXX)-#endif // defined(ASIO_HAS_STD_FUTURE)+# 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 // ASIO_DETAIL_FUTURE_HPP
− link/modules/asio-standalone/asio/include/asio/detail/gcc_arm_fenced_block.hpp
@@ -1,91 +0,0 @@-//-// 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
@@ -1,68 +0,0 @@-//-// 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
@@ -1,65 +0,0 @@-//-// 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
@@ -1,99 +0,0 @@-//-// 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -23,10 +23,8 @@ # include "asio/detail/win_global.hpp" #elif defined(ASIO_HAS_PTHREADS) # include "asio/detail/posix_global.hpp"-#elif defined(ASIO_HAS_STD_CALL_ONCE)-# include "asio/detail/std_global.hpp" #else-# error Only Windows, POSIX and std::call_once are supported!+# include "asio/detail/std_global.hpp" #endif namespace asio {@@ -41,7 +39,7 @@ return win_global<T>(); #elif defined(ASIO_HAS_PTHREADS) return posix_global<T>();-#elif defined(ASIO_HAS_STD_CALL_ONCE)+#else 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -17,182 +17,12 @@ #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" -// 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) \+#define ASIO_DEFINE_TAGGED_HANDLER_PTR(purpose, op) \ struct ptr \ { \ Handler* h; \@@ -206,12 +36,12 @@ { \ typedef typename ::asio::associated_allocator< \ Handler>::type associated_allocator_type; \- 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))); \+ 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))); \ return a.allocate(1); \ } \ void reset() \@@ -225,17 +55,22 @@ { \ typedef typename ::asio::associated_allocator< \ Handler>::type associated_allocator_type; \- 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))); \+ 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))); \ 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
− link/modules/asio-standalone/asio/include/asio/detail/handler_invoke_helpers.hpp
@@ -1,80 +0,0 @@-//-// 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -99,8 +99,8 @@ private: // Disallow copying and assignment.- location(const location&) ASIO_DELETED;- location& operator=(const location&) ASIO_DELETED;+ location(const location&) = delete;+ location& operator=(const location&) = delete; 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -64,7 +64,7 @@ auto zero_arg_copyable_handler_test(Handler h, void*) -> decltype( sizeof(Handler(static_cast<const Handler&>(h))),- (ASIO_MOVE_OR_LVALUE(Handler)(h)()),+ (static_cast<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(ASIO_MOVE_CAST(Handler)(h))),- (ASIO_MOVE_OR_LVALUE(Handler)(h)(*a1)),+ sizeof(Handler(static_cast<Handler&&>(h))),+ (static_cast<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(ASIO_MOVE_CAST(Handler)(h))),- (ASIO_MOVE_OR_LVALUE(Handler)(h)(*a1, *a2)),+ sizeof(Handler(static_cast<Handler&&>(h))),+ (static_cast<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(ASIO_MOVE_CAST(Handler)(h))),- (ASIO_MOVE_OR_LVALUE(Handler)(h)(- *a1, ASIO_MOVE_CAST(Arg2)(*a2))),+ sizeof(Handler(static_cast<Handler&&>(h))),+ (static_cast<Handler&&>(h)(+ *a1, static_cast<Arg2&&>(*a2))), char(0)); template <typename Handler>@@ -114,43 +114,15 @@ 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -19,13 +19,11 @@ #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"@@ -47,17 +45,8 @@ 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 { @@ -67,31 +56,29 @@ class handler_work_base { public:- explicit handler_work_base(int, int, const Executor& ex) ASIO_NOEXCEPT+ explicit handler_work_base(int, int, const Executor& ex) 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*/) ASIO_NOEXCEPT+ const OtherExecutor& /*candidate*/) noexcept : executor_(asio::prefer(ex, execution::outstanding_work.tracked)) { } - handler_work_base(const handler_work_base& other) ASIO_NOEXCEPT+ handler_work_base(const handler_work_base& other) noexcept : executor_(other.executor_) { } -#if defined(ASIO_HAS_MOVE)- handler_work_base(handler_work_base&& other) ASIO_NOEXCEPT- : executor_(ASIO_MOVE_CAST(executor_type)(other.executor_))+ handler_work_base(handler_work_base&& other) noexcept+ : executor_(static_cast<executor_type&&>(other.executor_)) { }-#endif // defined(ASIO_HAS_MOVE) - bool owns_work() const ASIO_NOEXCEPT+ bool owns_work() const noexcept { return true; }@@ -99,24 +86,15 @@ 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(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)+ ).execute(static_cast<Function&&>(function)); } private:- typedef typename decay<- typename prefer_result<Executor,- execution::outstanding_work_t::tracked_t- >::type- >::type executor_type;+ typedef decay_t<+ prefer_result_t<Executor, execution::outstanding_work_t::tracked_t>+ > executor_type; executor_type executor_; };@@ -125,14 +103,15 @@ typename IoContext, typename PolymorphicExecutor> class handler_work_base<Executor, CandidateExecutor, IoContext, PolymorphicExecutor,- typename enable_if<+ enable_if_t< !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) ASIO_NOEXCEPT+ explicit handler_work_base(int, int, const Executor& ex) noexcept : executor_(ex), owns_work_(true) {@@ -140,7 +119,7 @@ } handler_work_base(bool /*base1_owns_work*/, const Executor& ex,- const Executor& candidate) ASIO_NOEXCEPT+ const Executor& candidate) noexcept : executor_(ex), owns_work_(ex != candidate) {@@ -150,14 +129,14 @@ template <typename OtherExecutor> handler_work_base(bool /*base1_owns_work*/, const Executor& ex,- const OtherExecutor& /*candidate*/) ASIO_NOEXCEPT+ const OtherExecutor& /*candidate*/) noexcept : executor_(ex), owns_work_(true) { executor_.on_work_started(); } - handler_work_base(const handler_work_base& other) ASIO_NOEXCEPT+ handler_work_base(const handler_work_base& other) noexcept : executor_(other.executor_), owns_work_(other.owns_work_) {@@ -165,14 +144,12 @@ executor_.on_work_started(); } -#if defined(ASIO_HAS_MOVE)- handler_work_base(handler_work_base&& other) ASIO_NOEXCEPT- : executor_(ASIO_MOVE_CAST(Executor)(other.executor_)),+ handler_work_base(handler_work_base&& other) noexcept+ : executor_(static_cast<Executor&&>(other.executor_)), owns_work_(other.owns_work_) { other.owns_work_ = false; }-#endif // defined(ASIO_HAS_MOVE) ~handler_work_base() {@@ -180,7 +157,7 @@ executor_.on_work_finished(); } - bool owns_work() const ASIO_NOEXCEPT+ bool owns_work() const noexcept { return owns_work_; }@@ -188,7 +165,7 @@ template <typename Function, typename Handler> void dispatch(Function& function, Handler& handler) {- executor_.dispatch(ASIO_MOVE_CAST(Function)(function),+ executor_.dispatch(static_cast<Function&&>(function), asio::get_associated_allocator(handler)); } @@ -199,30 +176,31 @@ template <typename Executor, typename IoContext, typename PolymorphicExecutor> class handler_work_base<Executor, void, IoContext, PolymorphicExecutor,- typename enable_if<+ enable_if_t< is_same< Executor, typename IoContext::executor_type >::value- >::type>+ >+ > { public: explicit handler_work_base(int, int, const Executor&) { } - bool owns_work() const ASIO_NOEXCEPT+ bool owns_work() const noexcept { return false; } template <typename Function, typename Handler>- void dispatch(Function& function, Handler& handler)+ void dispatch(Function& function, 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.- asio_handler_invoke_helpers::invoke(function, handler);+ static_cast<Function&&>(function)(); } }; @@ -230,7 +208,7 @@ class handler_work_base<Executor, void, IoContext, Executor> { public:- explicit handler_work_base(int, int, const Executor& ex) ASIO_NOEXCEPT+ explicit handler_work_base(int, int, const Executor& ex) noexcept #if !defined(ASIO_NO_TYPEID) : executor_( ex.target_type() == typeid(typename IoContext::executor_type)@@ -244,7 +222,7 @@ } handler_work_base(bool /*base1_owns_work*/, const Executor& ex,- const Executor& candidate) ASIO_NOEXCEPT+ const Executor& candidate) noexcept : executor_(ex != candidate ? ex : Executor()) { if (executor_)@@ -253,25 +231,23 @@ template <typename OtherExecutor> handler_work_base(const Executor& ex,- const OtherExecutor&) ASIO_NOEXCEPT+ const OtherExecutor&) noexcept : executor_(ex) { executor_.on_work_started(); } - handler_work_base(const handler_work_base& other) ASIO_NOEXCEPT+ handler_work_base(const handler_work_base& other) noexcept : executor_(other.executor_) { if (executor_) executor_.on_work_started(); } -#if defined(ASIO_HAS_MOVE)- handler_work_base(handler_work_base&& other) ASIO_NOEXCEPT- : executor_(ASIO_MOVE_CAST(Executor)(other.executor_))+ handler_work_base(handler_work_base&& other) noexcept+ : executor_(static_cast<Executor&&>(other.executor_)) { }-#endif // defined(ASIO_HAS_MOVE) ~handler_work_base() {@@ -279,7 +255,7 @@ executor_.on_work_finished(); } - bool owns_work() const ASIO_NOEXCEPT+ bool owns_work() const noexcept { return !!executor_; }@@ -287,7 +263,7 @@ template <typename Function, typename Handler> void dispatch(Function& function, Handler& handler) {- executor_.dispatch(ASIO_MOVE_CAST(Function)(function),+ executor_.dispatch(static_cast<Function&&>(function), asio::get_associated_allocator(handler)); } @@ -295,34 +271,15 @@ Executor executor_; }; -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)+template <typename... SupportableProperties, typename CandidateExecutor,+ typename IoContext, typename PolymorphicExecutor>+class handler_work_base<execution::any_executor<SupportableProperties...>, CandidateExecutor, IoContext, PolymorphicExecutor> { public:- 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;+ typedef execution::any_executor<SupportableProperties...> executor_type; - explicit handler_work_base(int, int,- const executor_type& ex) ASIO_NOEXCEPT+ explicit handler_work_base(int, int, const executor_type& ex) noexcept #if !defined(ASIO_NO_TYPEID) : executor_( ex.target_type() == typeid(typename IoContext::executor_type)@@ -335,7 +292,7 @@ } handler_work_base(bool base1_owns_work, const executor_type& ex,- const executor_type& candidate) ASIO_NOEXCEPT+ const executor_type& candidate) noexcept : executor_( !base1_owns_work && ex == candidate ? executor_type()@@ -345,24 +302,22 @@ template <typename OtherExecutor> handler_work_base(bool /*base1_owns_work*/, const executor_type& ex,- const OtherExecutor& /*candidate*/) ASIO_NOEXCEPT+ const OtherExecutor& /*candidate*/) noexcept : executor_(asio::prefer(ex, execution::outstanding_work.tracked)) { } - handler_work_base(const handler_work_base& other) ASIO_NOEXCEPT+ handler_work_base(const handler_work_base& other) noexcept : executor_(other.executor_) { } -#if defined(ASIO_HAS_MOVE)- handler_work_base(handler_work_base&& other) ASIO_NOEXCEPT- : executor_(ASIO_MOVE_CAST(executor_type)(other.executor_))+ handler_work_base(handler_work_base&& other) noexcept+ : executor_(static_cast<executor_type&&>(other.executor_)) { }-#endif // defined(ASIO_HAS_MOVE) - bool owns_work() const ASIO_NOEXCEPT+ bool owns_work() const noexcept { return !!executor_; }@@ -370,11 +325,7 @@ template <typename Function, typename Handler> void dispatch(Function& function, Handler&) {-#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)+ executor_.execute(static_cast<Function&&>(function)); } private:@@ -388,16 +339,17 @@ class handler_work_base< Executor, CandidateExecutor, IoContext, PolymorphicExecutor,- typename enable_if<+ enable_if_t< 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) ASIO_NOEXCEPT+ const executor_type& ex) noexcept #if !defined(ASIO_NO_TYPEID) : executor_( ex.target_type() == typeid(typename IoContext::executor_type)@@ -410,7 +362,7 @@ } handler_work_base(bool base1_owns_work, const executor_type& ex,- const executor_type& candidate) ASIO_NOEXCEPT+ const executor_type& candidate) noexcept : executor_( !base1_owns_work && ex == candidate ? executor_type()@@ -420,24 +372,22 @@ template <typename OtherExecutor> handler_work_base(bool /*base1_owns_work*/, const executor_type& ex,- const OtherExecutor& /*candidate*/) ASIO_NOEXCEPT+ const OtherExecutor& /*candidate*/) noexcept : executor_(asio::prefer(ex, execution::outstanding_work.tracked)) { } - handler_work_base(const handler_work_base& other) ASIO_NOEXCEPT+ handler_work_base(const handler_work_base& other) noexcept : executor_(other.executor_) { } -#if defined(ASIO_HAS_MOVE)- handler_work_base(handler_work_base&& other) ASIO_NOEXCEPT- : executor_(ASIO_MOVE_CAST(executor_type)(other.executor_))+ handler_work_base(handler_work_base&& other) noexcept+ : executor_(static_cast<executor_type&&>(other.executor_)) { }-#endif // defined(ASIO_HAS_MOVE) - bool owns_work() const ASIO_NOEXCEPT+ bool owns_work() const noexcept { return !!executor_; }@@ -445,11 +395,7 @@ template <typename Function, typename Handler> void dispatch(Function& function, Handler&) {-#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)+ executor_.execute(static_cast<Function&&>(function)); } private:@@ -461,15 +407,14 @@ template <typename Handler, typename IoExecutor, typename = void> class handler_work : handler_work_base<IoExecutor>,- handler_work_base<typename associated_executor<- Handler, IoExecutor>::type, IoExecutor>+ handler_work_base<associated_executor_t<Handler, IoExecutor>, IoExecutor> { public: typedef handler_work_base<IoExecutor> base1_type;- typedef handler_work_base<typename associated_executor<- Handler, IoExecutor>::type, IoExecutor> base2_type;+ typedef handler_work_base<associated_executor_t<Handler, IoExecutor>,+ IoExecutor> base2_type; - handler_work(Handler& handler, const IoExecutor& io_ex) ASIO_NOEXCEPT+ handler_work(Handler& handler, const IoExecutor& io_ex) noexcept : base1_type(0, 0, io_ex), base2_type(base1_type::owns_work(), asio::get_associated_executor(handler, io_ex), io_ex)@@ -484,7 +429,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.- asio_handler_invoke_helpers::invoke(function, handler);+ static_cast<Function&&>(function)(); } else {@@ -496,18 +441,19 @@ template <typename Handler, typename IoExecutor> class handler_work< Handler, IoExecutor,- typename enable_if<+ enable_if_t< is_same< typename associated_executor<Handler, IoExecutor>::asio_associated_executor_is_unspecialised, void >::value- >::type> : handler_work_base<IoExecutor>+ >+ > : handler_work_base<IoExecutor> { public: typedef handler_work_base<IoExecutor> base1_type; - handler_work(Handler&, const IoExecutor& io_ex) ASIO_NOEXCEPT+ handler_work(Handler&, const IoExecutor& io_ex) noexcept : base1_type(0, 0, io_ex) { }@@ -520,7 +466,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.- asio_handler_invoke_helpers::invoke(function, handler);+ static_cast<Function&&>(function)(); } else {@@ -535,22 +481,22 @@ public: typedef handler_work<Handler, IoExecutor> handler_work_type; - explicit immediate_handler_work(ASIO_MOVE_ARG(handler_work_type) w)- : handler_work_(ASIO_MOVE_CAST(handler_work_type)(w))+ explicit immediate_handler_work(handler_work_type&& w)+ : handler_work_(static_cast<handler_work_type&&>(w)) { } template <typename Function> void complete(Function& function, Handler& handler, const void* io_ex) {- typedef typename associated_immediate_executor<Handler, IoExecutor>::type+ typedef associated_immediate_executor_t<Handler, IoExecutor> 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))(- ASIO_MOVE_CAST(Function)(function));+ static_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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -69,18 +69,24 @@ ::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)- result = ::ioctl(d, FIONBIO, &arg);- get_last_error(ec, result < 0);- if (ec.value() == ENOTTY)+ || ec.value() == ENOTTY+# endif // defined(ENOTTY)+# if defined(ENOTCAPABLE)+ || ec.value() == ENOTCAPABLE+# endif // defined(ENOTCAPABLE)+ ) { 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; @@ -107,26 +113,35 @@ if (result >= 0) { int flag = (value ? (result | O_NONBLOCK) : (result & ~O_NONBLOCK));- result = ::fcntl(d, F_SETFL, flag);+ result = (flag != result) ? ::fcntl(d, F_SETFL, flag) : 0; get_last_error(ec, result < 0); } #else // defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__) ioctl_arg_type arg = (value ? 1 : 0);- int result = ::ioctl(d, FIONBIO, &arg);- get_last_error(ec, result < 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 # if defined(ENOTTY)- if (ec.value() == ENOTTY)+ || ec.value() == ENOTTY+# endif // defined(ENOTTY)+# if defined(ENOTCAPABLE)+ || ec.value() == ENOTCAPABLE+# endif // defined(ENOTCAPABLE)+ ) { 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 = ::fcntl(d, F_SETFL, flag);+ result = (flag != result) ? ::fcntl(d, F_SETFL, flag) : 0; get_last_error(ec, result < 0); } }-# endif // defined(ENOTTY) #endif // defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__) if (result >= 0)@@ -170,26 +185,35 @@ if (result >= 0) { int flag = (value ? (result | O_NONBLOCK) : (result & ~O_NONBLOCK));- result = ::fcntl(d, F_SETFL, flag);+ result = (flag != result) ? ::fcntl(d, F_SETFL, flag) : 0; get_last_error(ec, result < 0); } #else // defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__) ioctl_arg_type arg = (value ? 1 : 0);- int result = ::ioctl(d, FIONBIO, &arg);- get_last_error(ec, result < 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 # if defined(ENOTTY)- if (ec.value() == ENOTTY)+ || ec.value() == ENOTTY+# endif // defined(ENOTTY)+# if defined(ENOTCAPABLE)+ || ec.value() == ENOTCAPABLE+# endif // defined(ENOTCAPABLE)+ ) { 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 = ::fcntl(d, F_SETFL, flag);+ result = (flag != result) ? ::fcntl(d, F_SETFL, flag) : 0; 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -32,22 +32,26 @@ scheduler_.post_immediate_completion(op, is_continuation); } -template <typename Time_Traits>-void dev_poll_reactor::add_timer_queue(timer_queue<Time_Traits>& queue)+template <typename TimeTraits, typename Allocator>+void dev_poll_reactor::add_timer_queue(+ timer_queue<TimeTraits, Allocator>& queue) { do_add_timer_queue(queue); } -template <typename Time_Traits>-void dev_poll_reactor::remove_timer_queue(timer_queue<Time_Traits>& queue)+template <typename TimeTraits, typename Allocator>+void dev_poll_reactor::remove_timer_queue(+ timer_queue<TimeTraits, Allocator>& queue) { do_remove_timer_queue(queue); } -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)+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) { asio::detail::mutex::scoped_lock lock(mutex_); @@ -63,9 +67,10 @@ interrupter_.interrupt(); } -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,+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, std::size_t max_cancelled) { asio::detail::mutex::scoped_lock lock(mutex_);@@ -76,9 +81,10 @@ return n; } -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,+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, void* cancellation_key) { asio::detail::mutex::scoped_lock lock(mutex_);@@ -88,10 +94,10 @@ scheduler_.post_deferred_completions(ops); } -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)+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) { 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -30,22 +30,25 @@ scheduler_.post_immediate_completion(op, is_continuation); } -template <typename Time_Traits>-void epoll_reactor::add_timer_queue(timer_queue<Time_Traits>& queue)+template <typename TimeTraits, typename Allocator>+void epoll_reactor::add_timer_queue(+ timer_queue<TimeTraits, Allocator>& queue) { do_add_timer_queue(queue); } -template <typename Time_Traits>-void epoll_reactor::remove_timer_queue(timer_queue<Time_Traits>& queue)+template <typename TimeTraits, typename Allocator>+void epoll_reactor::remove_timer_queue(+ timer_queue<TimeTraits, Allocator>& queue) { do_remove_timer_queue(queue); } -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)+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) { mutex::scoped_lock lock(mutex_); @@ -61,9 +64,10 @@ update_timeout(); } -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,+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, std::size_t max_cancelled) { mutex::scoped_lock lock(mutex_);@@ -74,9 +78,10 @@ return n; } -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,+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, void* cancellation_key) { mutex::scoped_lock lock(mutex_);@@ -86,10 +91,10 @@ scheduler_.post_deferred_completions(ops); } -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)+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) { 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -21,6 +21,7 @@ #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"@@ -38,13 +39,19 @@ epoll_reactor::epoll_reactor(asio::execution_context& ctx) : execution_context_service_base<epoll_reactor>(ctx), scheduler_(use_service<scheduler>(ctx)),- mutex_(ASIO_CONCURRENCY_HINT_IS_LOCKING(- REACTOR_REGISTRATION, scheduler_.concurrency_hint())),+ mutex_(config(ctx).get("reactor", "registration_locking", true),+ config(ctx).get("reactor", "registration_locking_spin_count", 0)), interrupter_(), epoll_fd_(do_epoll_create()), timer_fd_(do_timerfd_create()), shutdown_(false),- registered_descriptors_mutex_(mutex_.enabled())+ 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_) { // Add the interrupter's descriptor to epoll. epoll_event ev = { 0, { 0 } };@@ -130,14 +137,18 @@ for (descriptor_state* state = registered_descriptors_.first(); state != 0; state = state->next_) {- ev.events = state->registered_events_;- ev.data.ptr = state;- int result = epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, state->descriptor_, &ev);- if (result != 0)+ if (state->registered_events_ != 0) {- asio::error_code ec(errno,- asio::error::get_system_category());- asio::detail::throw_error(ec, "epoll re-registration");+ 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");+ } } } }@@ -216,7 +227,11 @@ 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; }@@ -663,8 +678,7 @@ epoll_reactor::descriptor_state* epoll_reactor::allocate_descriptor_state() { mutex::scoped_lock descriptors_lock(registered_descriptors_mutex_);- return registered_descriptors_.alloc(ASIO_CONCURRENCY_HINT_IS_LOCKING(- REACTOR_IO, scheduler_.concurrency_hint()));+ return registered_descriptors_.alloc(io_locking_, io_locking_spin_count_); } void epoll_reactor::free_descriptor_state(epoll_reactor::descriptor_state* s)@@ -756,9 +770,9 @@ operation* first_op_; }; -epoll_reactor::descriptor_state::descriptor_state(bool locking)+epoll_reactor::descriptor_state::descriptor_state(bool locking, int spin_count) : operation(&epoll_reactor::descriptor_state::do_complete),- mutex_(locking)+ mutex_(locking, spin_count) { }
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2025 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -25,15 +25,10 @@ #include <cstdarg> #include <cstdio>+#include "asio/detail/chrono.hpp"+#include "asio/detail/chrono_time_traits.hpp" #include "asio/detail/handler_tracking.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)+#include "asio/wait_traits.hpp" #if defined(ASIO_WINDOWS_RUNTIME) # include "asio/detail/socket_types.hpp"@@ -53,16 +48,10 @@ 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -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)- ASIO_NOEXCEPT+ 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -30,22 +30,26 @@ scheduler_.post_immediate_completion(op, is_continuation); } -template <typename Time_Traits>-void io_uring_service::add_timer_queue(timer_queue<Time_Traits>& queue)+template <typename TimeTraits, typename Allocator>+void io_uring_service::add_timer_queue(+ timer_queue<TimeTraits, Allocator>& queue) { do_add_timer_queue(queue); } -template <typename Time_Traits>-void io_uring_service::remove_timer_queue(timer_queue<Time_Traits>& queue)+template <typename TimeTraits, typename Allocator>+void io_uring_service::remove_timer_queue(+ timer_queue<TimeTraits, Allocator>& queue) { do_remove_timer_queue(queue); } -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)+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) { mutex::scoped_lock lock(mutex_); @@ -64,9 +68,10 @@ } } -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,+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, std::size_t max_cancelled) { mutex::scoped_lock lock(mutex_);@@ -77,9 +82,10 @@ return n; } -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,+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, void* cancellation_key) { mutex::scoped_lock lock(mutex_);@@ -89,10 +95,10 @@ scheduler_.post_deferred_completions(ops); } -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)+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) { 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -35,15 +35,21 @@ io_uring_service::io_uring_service(asio::execution_context& ctx) : execution_context_service_base<io_uring_service>(ctx), scheduler_(use_service<scheduler>(ctx)),- mutex_(ASIO_CONCURRENCY_HINT_IS_LOCKING(- REACTOR_REGISTRATION, scheduler_.concurrency_hint())),+ mutex_(config(ctx).get("reactor", "registration_locking", true),+ config(ctx).get("reactor", "registration_locking_spin_count", 0)), 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)@@ -435,15 +441,16 @@ ? ::io_uring_peek_cqe(&ring_, &cqe) : ::io_uring_wait_cqe(&ring_, &cqe); - if (result == 0 && usec > 0)+ if (local_ops > 0) {- if (::io_uring_cqe_get_data(cqe) != &ts)+ if (result != 0 || ::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(); } }@@ -451,37 +458,41 @@ bool check_timers = false; int count = 0;- while (result == 0)+ while (result == 0 || local_ops > 0) {- if (void* ptr = ::io_uring_cqe_get_data(cqe))+ if (result == 0) {- 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+ if (void* ptr = ::io_uring_cqe_get_data(cqe)) {- io_queue* io_q = static_cast<io_queue*>(ptr);- io_q->set_result(cqe->res);- ops.push(io_q);+ 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);+ } }+ ::io_uring_cqe_seen(&ring_, cqe);+ ++count; }- ::io_uring_cqe_seen(&ring_, cqe);- result = (++count < complete_batch_size || local_ops > 0)+ result = (count < complete_batch_size || local_ops > 0) ? ::io_uring_peek_cqe(&ring_, &cqe) : -EAGAIN; } @@ -607,9 +618,7 @@ io_uring_service::io_object* io_uring_service::allocate_io_object() { mutex::scoped_lock registration_lock(registration_mutex_);- return registered_io_objects_.alloc(- ASIO_CONCURRENCY_HINT_IS_LOCKING(- REACTOR_IO, scheduler_.concurrency_hint()));+ return registered_io_objects_.alloc(io_locking_, io_locking_spin_count_); } void io_uring_service::free_io_object(io_uring_service::io_object* io_obj)@@ -894,8 +903,8 @@ } } -io_uring_service::io_object::io_object(bool locking)- : mutex_(locking)+io_uring_service::io_object::io_object(bool locking, int spin_count)+ : mutex_(locking, spin_count) { }
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -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)- ASIO_NOEXCEPT+ 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2025 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,23 +33,25 @@ scheduler_.post_immediate_completion(op, is_continuation); } -template <typename Time_Traits>-void kqueue_reactor::add_timer_queue(timer_queue<Time_Traits>& queue)+template <typename TimeTraits, typename Allocator>+void kqueue_reactor::add_timer_queue(timer_queue<TimeTraits, Allocator>& queue) { do_add_timer_queue(queue); } // Remove a timer queue from the reactor.-template <typename Time_Traits>-void kqueue_reactor::remove_timer_queue(timer_queue<Time_Traits>& queue)+template <typename TimeTraits, typename Allocator>+void kqueue_reactor::remove_timer_queue(+ timer_queue<TimeTraits, Allocator>& queue) { do_remove_timer_queue(queue); } -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)+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) { mutex::scoped_lock lock(mutex_); @@ -65,9 +67,10 @@ interrupt(); } -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,+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, std::size_t max_cancelled) { mutex::scoped_lock lock(mutex_);@@ -78,9 +81,10 @@ return n; } -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,+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, void* cancellation_key) { mutex::scoped_lock lock(mutex_);@@ -90,10 +94,10 @@ scheduler_.post_deferred_completions(ops); } -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)+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) { 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2025 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,6 +20,7 @@ #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"@@ -46,12 +47,18 @@ kqueue_reactor::kqueue_reactor(asio::execution_context& ctx) : execution_context_service_base<kqueue_reactor>(ctx), scheduler_(use_service<scheduler>(ctx)),- mutex_(ASIO_CONCURRENCY_HINT_IS_LOCKING(- REACTOR_REGISTRATION, scheduler_.concurrency_hint())),+ mutex_(config(ctx).get("reactor", "registration_locking", true),+ config(ctx).get("reactor", "registration_locking_spin_count", 0)), kqueue_fd_(do_kqueue_create()), interrupter_(), shutdown_(false),- registered_descriptors_mutex_(mutex_.enabled())+ 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_) { struct kevent events[1]; ASIO_KQUEUE_EV_SET(&events[0], interrupter_.read_descriptor(),@@ -562,8 +569,7 @@ kqueue_reactor::descriptor_state* kqueue_reactor::allocate_descriptor_state() { mutex::scoped_lock descriptors_lock(registered_descriptors_mutex_);- return registered_descriptors_.alloc(ASIO_CONCURRENCY_HINT_IS_LOCKING(- REACTOR_IO, scheduler_.concurrency_hint()));+ return registered_descriptors_.alloc(io_locking_, io_locking_spin_count_); } 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2025 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -30,16 +30,17 @@ posix_thread::~posix_thread() {- if (!joined_)- ::pthread_detach(thread_);+ if (arg_)+ std::terminate(); } void posix_thread::join() {- if (!joined_)+ if (arg_) {- ::pthread_join(thread_, 0);- joined_ = true;+ ::pthread_join(arg_->thread_, 0);+ arg_->destroy();+ arg_ = 0; } } @@ -53,24 +54,23 @@ return 0; } -void posix_thread::start_thread(func_base* arg)+posix_thread::func_base* posix_thread::start_thread(func_base* arg) {- int error = ::pthread_create(&thread_, 0,+ int error = ::pthread_create(&arg->thread_, 0, asio_detail_posix_thread_function, arg); if (error != 0) {- delete arg;+ arg->destroy(); 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) {- posix_thread::auto_func_base_ptr func = {- static_cast<posix_thread::func_base*>(arg) };- func.ptr->run();+ static_cast<posix_thread::func_base*>(arg)->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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -53,7 +53,7 @@ void reactive_descriptor_service::move_construct( reactive_descriptor_service::implementation_type& impl, reactive_descriptor_service::implementation_type& other_impl)- ASIO_NOEXCEPT+ noexcept { impl.descriptor_ = other_impl.descriptor_; other_impl.descriptor_ = -1;@@ -198,18 +198,20 @@ } void reactive_descriptor_service::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*),+ 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*), const void* immediate_arg) { if (!noop) {- if ((impl.state_ & descriptor_ops::non_blocking) ||- descriptor_ops::set_internal_non_blocking(+ if ((impl.state_ & descriptor_ops::non_blocking)+ || !needs_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, is_non_blocking, on_immediate, immediate_arg);+ is_continuation, allow_speculative, 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -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)- ASIO_NOEXCEPT+ noexcept { impl.socket_ = other_impl.socket_; other_impl.socket_ = invalid_socket;@@ -234,19 +234,21 @@ } 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 is_non_blocking, bool noop,+ 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, 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, is_non_blocking, on_immediate, immediate_arg);+ is_continuation, allow_speculative, on_immediate, immediate_arg); return; } }@@ -263,7 +265,7 @@ if (!peer_is_open) { do_start_op(impl, reactor::read_op, op, is_continuation,- true, false, on_immediate, immediate_arg);+ true, false, true, 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -16,6 +16,8 @@ #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"@@ -23,70 +25,15 @@ 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)- : scheduler_(asio::use_service<scheduler_impl>(context)),- work_scheduler_(new scheduler_impl(context, -1, false)),- work_thread_(0)+ : thread_pool_(asio::use_service<resolver_thread_pool>(context)) {- 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) {@@ -96,7 +43,7 @@ void resolver_service_base::destroy( resolver_service_base::implementation_type& impl) {- ASIO_HANDLER_OPERATION((scheduler_.context(),+ ASIO_HANDLER_OPERATION((thread_pool_.context(), "resolver", &impl, 0, "cancel")); impl.reset();@@ -105,49 +52,23 @@ void resolver_service_base::move_construct(implementation_type& impl, implementation_type& other_impl) {- impl = ASIO_MOVE_CAST(implementation_type)(other_impl);+ impl = static_cast<implementation_type&&>(other_impl); } void resolver_service_base::move_assign(implementation_type& impl, resolver_service_base&, implementation_type& other_impl) { destroy(impl);- impl = ASIO_MOVE_CAST(implementation_type)(other_impl);+ impl = static_cast<implementation_type&&>(other_impl); } void resolver_service_base::cancel( resolver_service_base::implementation_type& impl) {- ASIO_HANDLER_OPERATION((scheduler_.context(),+ ASIO_HANDLER_OPERATION((thread_pool_.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 view
@@ -0,0 +1,124 @@+//+// 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -17,7 +17,7 @@ #include "asio/detail/config.hpp" -#include "asio/detail/concurrency_hint.hpp"+#include "asio/config.hpp" #include "asio/detail/event.hpp" #include "asio/detail/limits.hpp" #include "asio/detail/scheduler.hpp"@@ -109,44 +109,56 @@ }; scheduler::scheduler(asio::execution_context& ctx,- int concurrency_hint, bool own_thread, get_task_func_type get_task)+ bool own_thread, get_task_func_type get_task) : asio::detail::execution_context_service_base<scheduler>(ctx),- 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)),+ 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)), task_(0), get_task_(get_task), task_interrupted_(true),- outstanding_work_(0), stopped_(false), shutdown_(false),- concurrency_hint_(concurrency_hint),- thread_(0)+ outstanding_work_(0),+ task_usec_(config(ctx).get("scheduler", "task_usec", -1L)),+ wait_usec_(config(ctx).get("scheduler", "wait_usec", -1L)),+ thread_() { ASIO_HANDLER_TRACKING_INIT; if (own_thread) { ++outstanding_work_;- asio::detail::signal_blocker sb;- thread_ = new asio::detail::thread(thread_function(this));+ signal_blocker sb;+ thread_ = 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_)+ if (thread_.joinable()) { mutex::scoped_lock lock(mutex_); shutdown_ = true; stop_all_threads(lock); lock.unlock();- thread_->join();- delete thread_;+ thread_.join(); } } @@ -154,17 +166,12 @@ { mutex::scoped_lock lock(mutex_); shutdown_ = true;- if (thread_)+ if (thread_.joinable()) stop_all_threads(lock); lock.unlock(); // Join thread to ensure task operation is returned to queue.- if (thread_)- {- thread_->join();- delete thread_;- thread_ = 0;- }+ thread_.join(); // Destroy handler objects. while (!op_queue_.empty())@@ -460,9 +467,9 @@ if (o == &task_operation_) {- task_interrupted_ = more_handlers;+ task_interrupted_ = more_handlers || task_usec_ == 0; - if (more_handlers && !one_thread_)+ if (more_handlers && !one_thread_ && wait_usec_ != 0) wakeup_event_.unlock_and_signal_one(lock); else lock.unlock();@@ -473,7 +480,8 @@ // 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 : -1, this_thread.private_op_queue);+ task_->run(more_handlers ? 0 : task_usec_,+ this_thread.private_op_queue); } else {@@ -497,8 +505,19 @@ } else {- wakeup_event_.clear(lock);- wakeup_event_.wait(lock);+ 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);+ } } } @@ -516,6 +535,7 @@ 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();@@ -526,9 +546,10 @@ op_queue_.pop(); bool more_handlers = (!op_queue_.empty()); - task_interrupted_ = more_handlers;+ usec = (task_usec_ >= 0 && task_usec_ < usec) ? task_usec_ : usec;+ task_interrupted_ = more_handlers || usec == 0; - if (more_handlers && !one_thread_)+ if (more_handlers && !one_thread_ && wait_usec_ != 0) wakeup_event_.unlock_and_signal_one(lock); else lock.unlock();@@ -647,7 +668,7 @@ void scheduler::wake_one_thread_and_unlock( mutex::scoped_lock& lock) {- if (!wakeup_event_.maybe_unlock_and_signal_one(lock))+ if (wait_usec_ == 0 || !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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -40,23 +40,27 @@ scheduler_.post_immediate_completion(op, is_continuation); } -template <typename Time_Traits>-void select_reactor::add_timer_queue(timer_queue<Time_Traits>& queue)+template <typename TimeTraits, typename Allocator>+void select_reactor::add_timer_queue(+ timer_queue<TimeTraits, Allocator>& queue) { do_add_timer_queue(queue); } // Remove a timer queue from the reactor.-template <typename Time_Traits>-void select_reactor::remove_timer_queue(timer_queue<Time_Traits>& queue)+template <typename TimeTraits, typename Allocator>+void select_reactor::remove_timer_queue(+ timer_queue<TimeTraits, Allocator>& queue) { do_remove_timer_queue(queue); } -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)+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) { asio::detail::mutex::scoped_lock lock(mutex_); @@ -72,9 +76,10 @@ interrupter_.interrupt(); } -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,+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, std::size_t max_cancelled) { asio::detail::mutex::scoped_lock lock(mutex_);@@ -85,9 +90,10 @@ return n; } -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,+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, void* cancellation_key) { mutex::scoped_lock lock(mutex_);@@ -97,10 +103,10 @@ scheduler_.post_deferred_completions(ops); } -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)+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) { 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -65,14 +65,14 @@ interrupter_(), #if defined(ASIO_HAS_IOCP) stop_thread_(false),- thread_(0),+ thread_(), restart_reactor_(this), #endif // defined(ASIO_HAS_IOCP) shutdown_(false) { #if defined(ASIO_HAS_IOCP) asio::detail::signal_blocker sb;- thread_ = new asio::detail::thread(thread_function(this));+ thread_ = thread(thread_function(this)); #endif // defined(ASIO_HAS_IOCP) } @@ -87,18 +87,13 @@ shutdown_ = true; #if defined(ASIO_HAS_IOCP) stop_thread_ = true;- if (thread_)+ if (thread_.joinable()) interrupter_.interrupt(); #endif // defined(ASIO_HAS_IOCP) lock.unlock(); #if defined(ASIO_HAS_IOCP)- if (thread_)- {- thread_->join();- delete thread_;- thread_ = 0;- }+ thread_.join(); #endif // defined(ASIO_HAS_IOCP) op_queue<operation> ops;@@ -330,12 +325,7 @@ { select_reactor* reactor = static_cast<restart_reactor*>(base)->reactor_; - if (reactor->thread_)- {- reactor->thread_->join();- delete reactor->thread_;- reactor->thread_ = 0;- }+ reactor->thread_.join(); asio::detail::mutex::scoped_lock lock(reactor->mutex_); reactor->interrupter_.recreate();@@ -343,8 +333,7 @@ lock.unlock(); asio::detail::signal_blocker sb;- reactor->thread_ =- new asio::detail::thread(thread_function(reactor));+ reactor->thread_ = 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -38,6 +38,18 @@ 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) {@@ -64,8 +76,7 @@ #if !defined(ASIO_NO_TYPEID) template <typename Service> void service_registry::init_key(execution_context::service::key& key,- typename enable_if<- is_base_of<typename Service::key_type, Service>::value>::type*)+ enable_if_t<is_base_of<typename Service::key_type, Service>::value>*) { key.type_info_ = &typeid(typeid_wrapper<Service>); key.id_ = 0;@@ -80,10 +91,22 @@ } #endif // !defined(ASIO_NO_TYPEID) -template <typename Service, typename Owner>-execution_context::service* service_registry::create(void* owner)+template <typename Service, typename Owner, typename... Args>+execution_context::service* service_registry::create(+ execution_context& context, void* owner, Args&&... args) {- return new Service(*static_cast<Owner*>(owner));+ 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)+{+ deallocate_object(execution_context::allocator<void>(service->owner_),+ static_cast<Service*>(service)); } } // 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -50,7 +50,7 @@ while (first_service_) { execution_context::service* next_service = first_service_->next_;- destroy(first_service_);+ first_service_->destroy_(first_service_); first_service_ = next_service; } }@@ -104,11 +104,17 @@ return false; } -void service_registry::destroy(execution_context::service* service)+void service_registry::destroy_added(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)@@ -128,7 +134,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) };+ auto_service_ptr new_service = { factory(owner_, owner) }; new_service.ptr_->key_ = key; lock.lock(); @@ -168,6 +174,8 @@ } // 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -386,6 +386,7 @@ if (state->flags_[signal_number] != signal_set_base::flags::dont_care) { ec = asio::error::invalid_argument;+ delete new_registration; return ec; } struct sigaction sa;@@ -397,6 +398,7 @@ { ec = asio::error_code(errno, asio::error::get_system_category());+ delete new_registration; return ec; } state->flags_[signal_number] = f;@@ -656,10 +658,9 @@ // scheduler used to create signal_set objects. if (state->service_list_ != 0) {- if (!ASIO_CONCURRENCY_HINT_IS_LOCKING(SCHEDULER,- service->scheduler_.concurrency_hint())- || !ASIO_CONCURRENCY_HINT_IS_LOCKING(SCHEDULER,- state->service_list_->scheduler_.concurrency_hint()))+ if (!config(service->context()).get("scheduler", "locking", true)+ || !config(state->service_list_->context()).get(+ "scheduler", "locking", true)) { 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -41,6 +41,10 @@ #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 {@@ -339,7 +343,24 @@ ::fcntl(s, F_SETFL, flags & ~O_NONBLOCK); # else // defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__) ioctl_arg_type arg = 0;- ::ioctl(s, FIONBIO, &arg);+ 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);+ } # endif // defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__) #endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__) state &= ~non_blocking;@@ -375,14 +396,36 @@ if (result >= 0) { int flag = (value ? (result | O_NONBLOCK) : (result & ~O_NONBLOCK));- result = ::fcntl(s, F_SETFL, flag);+ result = (flag != result) ? ::fcntl(s, F_SETFL, flag) : 0; get_last_error(ec, result < 0); }-#else+#else // defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__) ioctl_arg_type arg = (value ? 1 : 0);- int result = ::ioctl(s, FIONBIO, &arg);- get_last_error(ec, result < 0);-#endif+ 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__) if (result >= 0) {@@ -429,14 +472,36 @@ if (result >= 0) { int flag = (value ? (result | O_NONBLOCK) : (result & ~O_NONBLOCK));- result = ::fcntl(s, F_SETFL, flag);+ result = (flag != result) ? ::fcntl(s, F_SETFL, flag) : 0; get_last_error(ec, result < 0); }-#else+#else // defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__) ioctl_arg_type arg = (value ? 1 : 0);- int result = ::ioctl(s, FIONBIO, &arg);- get_last_error(ec, result < 0);-#endif+ 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__) if (result >= 0) {@@ -2521,9 +2586,11 @@ || 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);-#else // defined(ASIO_HAS_SNPRINTF)+#elif defined(ASIO_HAS_SECURE_RTL)+ sprintf_s(if_name + 1, sizeof(if_name) -1, "%lu", scope_id);+#else // defined(ASIO_HAS_SECURE_RTL) sprintf(if_name + 1, "%lu", scope_id);-#endif // defined(ASIO_HAS_SNPRINTF)+#endif // defined(ASIO_HAS_SECURE_RTL) 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -16,7 +16,6 @@ #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"@@ -34,8 +33,8 @@ public: typedef Allocator allocator_type; - allocator_binder(ASIO_MOVE_ARG(F) f, const Allocator& a)- : f_(ASIO_MOVE_CAST(F)(f)),+ allocator_binder(F&& f, const Allocator& a)+ : f_(static_cast<F&&>(f)), allocator_(a) { }@@ -46,15 +45,13 @@ { } -#if defined(ASIO_HAS_MOVE) allocator_binder(allocator_binder&& other)- : f_(ASIO_MOVE_CAST(F)(other.f_)),- allocator_(ASIO_MOVE_CAST(allocator_type)(other.allocator_))+ : f_(static_cast<F&&>(other.f_)),+ allocator_(static_cast<allocator_type&&>(other.allocator_)) { }-#endif // defined(ASIO_HAS_MOVE) - allocator_type get_allocator() const ASIO_NOEXCEPT+ allocator_type get_allocator() const noexcept { return allocator_; }@@ -71,9 +68,9 @@ template <typename Executor> class strand_executor_service::invoker<Executor,- typename enable_if<+ enable_if_t< execution::is_executor<Executor>::value- >::type>+ >> { public: invoker(const implementation_type& impl, Executor& ex)@@ -88,13 +85,11 @@ { } -#if defined(ASIO_HAS_MOVE) invoker(invoker&& other)- : impl_(ASIO_MOVE_CAST(implementation_type)(other.impl_)),- executor_(ASIO_MOVE_CAST(executor_type)(other.executor_))+ : impl_(static_cast<implementation_type&&>(other.impl_)),+ executor_(static_cast<executor_type&&>(other.executor_)) { }-#endif // defined(ASIO_HAS_MOVE) struct on_invoker_exit {@@ -106,22 +101,12 @@ { recycling_allocator<void> allocator; executor_type ex = this_->executor_;-#if defined(ASIO_NO_DEPRECATED) asio::prefer( asio::require(- ASIO_MOVE_CAST(executor_type)(ex),+ static_cast<executor_type&&>(ex), execution::blocking.never), execution::allocator(allocator)- ).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)+ ).execute(static_cast<invoker&&>(*this_)); } } };@@ -136,12 +121,12 @@ } private:- typedef typename decay<- typename prefer_result<+ typedef decay_t<+ prefer_result_t< Executor, execution::outstanding_work_t::tracked_t- >::type- >::type executor_type;+ >+ > executor_type; implementation_type impl_; executor_type executor_;@@ -151,9 +136,9 @@ template <typename Executor> class strand_executor_service::invoker<Executor,- typename enable_if<+ enable_if_t< !execution::is_executor<Executor>::value- >::type>+ >> { public: invoker(const implementation_type& impl, Executor& ex)@@ -168,13 +153,11 @@ { } -#if defined(ASIO_HAS_MOVE) invoker(invoker&& other)- : impl_(ASIO_MOVE_CAST(implementation_type)(other.impl_)),- work_(ASIO_MOVE_CAST(executor_work_guard<Executor>)(other.work_))+ : impl_(static_cast<implementation_type&&>(other.impl_)),+ work_(static_cast<executor_work_guard<Executor>&&>(other.work_)) { }-#endif // defined(ASIO_HAS_MOVE) struct on_invoker_exit {@@ -186,7 +169,7 @@ { Executor ex(this_->work_.get_executor()); recycling_allocator<void> allocator;- ex.post(ASIO_MOVE_CAST(invoker)(*this_), allocator);+ ex.post(static_cast<invoker&&>(*this_), allocator); } } };@@ -209,33 +192,33 @@ template <typename Executor, typename Function> inline void strand_executor_service::execute(const implementation_type& impl,- Executor& ex, ASIO_MOVE_ARG(Function) function,- typename enable_if<- can_query<Executor, execution::allocator_t<void> >::value- >::type*)+ Executor& ex, Function&& function,+ enable_if_t<+ can_query<Executor, execution::allocator_t<void>>::value+ >*) { return strand_executor_service::do_execute(impl, ex,- ASIO_MOVE_CAST(Function)(function),+ static_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, ASIO_MOVE_ARG(Function) function,- typename enable_if<- !can_query<Executor, execution::allocator_t<void> >::value- >::type*)+ Executor& ex, Function&& function,+ enable_if_t<+ !can_query<Executor, execution::allocator_t<void>>::value+ >*) { return strand_executor_service::do_execute(impl, ex,- ASIO_MOVE_CAST(Function)(function),+ static_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, ASIO_MOVE_ARG(Function) function, const Allocator& a)+ Executor& ex, Function&& function, const Allocator& a) {- typedef typename decay<Function>::type function_type;+ typedef decay_t<Function> function_type; // If the executor is not never-blocking, and we are already in the strand, // then the function can run immediately.@@ -243,17 +226,17 @@ && running_in_this_thread(impl)) { // Make a local, non-const copy of the function.- function_type tmp(ASIO_MOVE_CAST(Function)(function));+ function_type tmp(static_cast<Function&&>(function)); fenced_block b(fenced_block::full);- asio_handler_invoke_helpers::invoke(tmp, tmp);+ static_cast<function_type&&>(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(ASIO_MOVE_CAST(Function)(function), a);+ p.p = new (p.v) op(static_cast<Function&&>(function), a); ASIO_HANDLER_CREATION((impl->service_->context(), *p.p, "strand_executor", impl.get(), 0, "execute"));@@ -263,35 +246,31 @@ 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, ASIO_MOVE_ARG(Function) function, const Allocator& a)+ Executor& ex, Function&& function, const Allocator& a) {- typedef typename decay<Function>::type function_type;+ typedef decay_t<Function> 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(ASIO_MOVE_CAST(Function)(function));+ function_type tmp(static_cast<Function&&>(function)); fenced_block b(fenced_block::full);- asio_handler_invoke_helpers::invoke(tmp, tmp);+ static_cast<function_type&&>(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(ASIO_MOVE_CAST(Function)(function), a);+ p.p = new (p.v) op(static_cast<Function&&>(function), a); ASIO_HANDLER_CREATION((impl->service_->context(), *p.p, "strand_executor", impl.get(), 0, "dispatch"));@@ -310,14 +289,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, ASIO_MOVE_ARG(Function) function, const Allocator& a)+ Executor& ex, Function&& function, const Allocator& a) {- typedef typename decay<Function>::type function_type;+ typedef decay_t<Function> 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(ASIO_MOVE_CAST(Function)(function), a);+ p.p = new (p.v) op(static_cast<Function&&>(function), a); ASIO_HANDLER_CREATION((impl->service_->context(), *p.p, "strand_executor", impl.get(), 0, "post"));@@ -336,14 +315,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, ASIO_MOVE_ARG(Function) function, const Allocator& a)+ Executor& ex, Function&& function, const Allocator& a) {- typedef typename decay<Function>::type function_type;+ typedef decay_t<Function> 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(ASIO_MOVE_CAST(Function)(function), a);+ p.p = new (p.v) op(static_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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -52,7 +52,8 @@ strand_executor_service::implementation_type strand_executor_service::create_implementation() {- implementation_type new_impl(new strand_impl);+ execution_context::allocator<void> alloc(context());+ implementation_type new_impl = allocate_shared<strand_impl>(alloc); new_impl->locked_ = false; new_impl->shutdown_ = false; @@ -64,8 +65,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].get())- mutexes_[mutex_index].reset(new mutex);+ if (!mutexes_[mutex_index])+ mutexes_[mutex_index] = allocate_shared<mutex>(alloc); 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -18,7 +18,6 @@ #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"@@ -40,7 +39,7 @@ if (running_in_this_thread(impl)) { fenced_block b(fenced_block::full);- asio_handler_invoke_helpers::invoke(handler, handler);+ static_cast<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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -80,8 +80,11 @@ #endif // defined(ASIO_ENABLE_SEQUENTIAL_STRAND_ALLOCATION) index = index % num_implementations; - if (!implementations_[index].get())- implementations_[index].reset(new strand_impl);+ if (!implementations_[index])+ {+ execution_context::allocator<void> alloc(context());+ implementations_[index] = allocate_shared<strand_impl>(alloc);+ } 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -37,29 +37,8 @@ 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
@@ -1,97 +0,0 @@-//-// 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/detail/impl/win_event.ipp view
@@ -2,7 +2,7 @@ // detail/win_event.ipp // ~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -94,25 +94,48 @@ 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 && (open_flags & file_base::truncate) != 0)+ if (disposition == OPEN_ALWAYS) {- if (!::SetEndOfFile(handle))+ if ((open_flags & file_base::truncate) != 0) {- DWORD last_error = ::GetLastError();- ::CloseHandle(handle);- ec.assign(last_error, asio::error::get_system_category());- ASIO_ERROR_LOCATION(ec);- return ec;+ 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 ((open_flags & file_base::append) != 0)+ {+ 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;+ }+ }+ } 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2025 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -22,7 +22,6 @@ #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"@@ -30,24 +29,26 @@ namespace asio { namespace detail { -template <typename Time_Traits>+template <typename TimeTraits, typename Allocator> void win_iocp_io_context::add_timer_queue(- timer_queue<Time_Traits>& queue)+ timer_queue<TimeTraits, Allocator>& queue) { do_add_timer_queue(queue); } -template <typename Time_Traits>+template <typename TimeTraits, typename Allocator> void win_iocp_io_context::remove_timer_queue(- timer_queue<Time_Traits>& queue)+ timer_queue<TimeTraits, Allocator>& queue) { do_remove_timer_queue(queue); } -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)+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) { // If the service has been shut down we silently discard the timer. if (::InterlockedExchangeAdd(&shutdown_, 0) != 0)@@ -64,9 +65,10 @@ update_timeout(); } -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,+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, std::size_t max_cancelled) { // If the service has been shut down we silently ignore the cancellation.@@ -81,9 +83,10 @@ return n; } -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,+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, void* cancellation_key) { // If the service has been shut down we silently ignore the cancellation.@@ -97,10 +100,10 @@ post_deferred_completions(ops); } -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)+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) { 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -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() ASIO_NOEXCEPT_IF(false)+ ~work_finished_on_block_exit() noexcept(false) { io_context_->work_finished(); }@@ -79,7 +79,7 @@ }; win_iocp_io_context::win_iocp_io_context(- asio::execution_context& ctx, int concurrency_hint, bool own_thread)+ asio::execution_context& ctx, bool own_thread) : execution_context_service_base<win_iocp_io_context>(ctx), iocp_(), outstanding_work_(0),@@ -88,12 +88,13 @@ shutdown_(0), gqcs_timeout_(get_gqcs_timeout()), dispatch_required_(0),- concurrency_hint_(concurrency_hint)+ concurrency_hint_(config(ctx).get("scheduler", "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)));+ static_cast<DWORD>(concurrency_hint_ >= 0+ ? concurrency_hint_ : DWORD(~0))); if (!iocp_.handle) { DWORD last_error = ::GetLastError();@@ -105,17 +106,42 @@ if (own_thread) { ::InterlockedIncrement(&outstanding_work_);- thread_.reset(new asio::detail::thread(thread_function(this)));+ 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");+ }+}+ win_iocp_io_context::~win_iocp_io_context() {- if (thread_.get())+ if (thread_.joinable()) { stop();- thread_->join();- thread_.reset();+ thread_.join(); } } @@ -123,18 +149,17 @@ { ::InterlockedExchange(&shutdown_, 1); - if (timer_thread_.get())+ if (timer_thread_.joinable()) { LARGE_INTEGER timeout; timeout.QuadPart = 1; ::SetWaitableTimer(waitable_timer_.handle, &timeout, 1, 0, 0, FALSE); } - if (thread_.get())+ if (thread_.joinable()) { stop();- thread_->join();- thread_.reset();+ thread_.join(); ::InterlockedDecrement(&outstanding_work_); } @@ -167,11 +192,7 @@ } } - if (timer_thread_.get())- {- timer_thread_->join();- timer_thread_.reset();- }+ timer_thread_.join(); } asio::error_code win_iocp_io_context::register_handle(@@ -572,10 +593,10 @@ &timeout, max_timeout_msec, 0, 0, FALSE); } - if (!timer_thread_.get())+ if (!timer_thread_.joinable()) { timer_thread_function thread_function = { this };- timer_thread_.reset(new thread(thread_function, 65536));+ timer_thread_ = thread(thread_function, 65536); } } @@ -588,7 +609,7 @@ void win_iocp_io_context::update_timeout() {- if (timer_thread_.get())+ if (timer_thread_.joinable()) { // 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2025 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -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)- ASIO_NOEXCEPT+ 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2025 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -33,25 +33,29 @@ win_thread::~win_thread() {- ::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.+ if (arg_)+ std::terminate(); } void win_thread::join() {- HANDLE handles[2] = { exit_event_, thread_ };- ::WaitForMultipleObjects(2, handles, FALSE, INFINITE);- ::CloseHandle(exit_event_);- if (terminate_threads())- {- ::TerminateThread(thread_, 0);- }- else+ if (arg_) {- ::QueueUserAPC(apc_function, thread_, 0);- ::WaitForSingleObject(thread_, INFINITE);+ 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; } } @@ -62,60 +66,60 @@ return system_info.dwNumberOfProcessors; } -void win_thread::start_thread(func_base* arg, unsigned int stack_size)+win_thread::func_base* win_thread::start_thread(+ func_base* arg, unsigned int stack_size) {- ::HANDLE entry_event = 0;- arg->entry_event_ = entry_event = ::CreateEventW(0, true, false, 0);- if (!entry_event)+ arg->entry_event_ = ::CreateEventW(0, true, false, 0);+ if (!arg->entry_event_) { DWORD last_error = ::GetLastError();- delete arg;+ arg->destroy(); asio::error_code ec(last_error, asio::error::get_system_category()); asio::detail::throw_error(ec, "thread.entry_event"); } - arg->exit_event_ = exit_event_ = ::CreateEventW(0, true, false, 0);- if (!exit_event_)+ arg->exit_event_ = ::CreateEventW(0, true, false, 0);+ if (!arg->exit_event_) { DWORD last_error = ::GetLastError();- delete arg;+ ::CloseHandle(arg->entry_event_);+ arg->destroy(); asio::error_code ec(last_error, asio::error::get_system_category()); asio::detail::throw_error(ec, "thread.exit_event"); } unsigned int thread_id = 0;- thread_ = reinterpret_cast<HANDLE>(::_beginthreadex(0,+ arg->thread_ = reinterpret_cast<HANDLE>(::_beginthreadex(0, stack_size, win_thread_function, arg, 0, &thread_id));- if (!thread_)+ if (!arg->thread_) { DWORD last_error = ::GetLastError();- delete arg;- if (entry_event)- ::CloseHandle(entry_event);- if (exit_event_)- ::CloseHandle(exit_event_);+ ::CloseHandle(arg->entry_event_);+ ::CloseHandle(arg->exit_event_);+ arg->destroy(); asio::error_code ec(last_error, asio::error::get_system_category()); asio::detail::throw_error(ec, "thread"); } - if (entry_event)+ if (arg->entry_event_) {- ::WaitForSingleObject(entry_event, INFINITE);- ::CloseHandle(entry_event);+ ::WaitForSingleObject(arg->entry_event_, INFINITE);+ ::CloseHandle(arg->entry_event_);+ arg->entry_event_ = 0; }++ return arg; } unsigned int __stdcall win_thread_function(void* arg) {- win_thread::auto_func_base_ptr func = {- static_cast<win_thread::func_base*>(arg) };-- ::SetEvent(func.ptr->entry_event_);+ win_thread::func_base* func = static_cast<win_thread::func_base*>(arg);+ ::SetEvent(func->entry_event_); - func.ptr->run();+ func->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@@ -123,10 +127,7 @@ // TerminateThread (to avoid a deadlock in DllMain). Otherwise, the SleepEx // call will be interrupted using QueueUserAPC and the thread will shut down // cleanly.- HANDLE exit_event = func.ptr->exit_event_;- delete func.ptr;- func.ptr = 0;- ::SetEvent(exit_event);+ ::SetEvent(func->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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -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)- ASIO_NOEXCEPT+ 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -24,23 +24,27 @@ namespace asio { namespace detail { -template <typename Time_Traits>-void winrt_timer_scheduler::add_timer_queue(timer_queue<Time_Traits>& queue)+template <typename TimeTraits, typename Allocator>+void winrt_timer_scheduler::add_timer_queue(+ timer_queue<TimeTraits, Allocator>& queue) { do_add_timer_queue(queue); } // Remove a timer queue from the reactor.-template <typename Time_Traits>-void winrt_timer_scheduler::remove_timer_queue(timer_queue<Time_Traits>& queue)+template <typename TimeTraits, typename Allocator>+void winrt_timer_scheduler::remove_timer_queue(+ timer_queue<TimeTraits, Allocator>& queue) { do_remove_timer_queue(queue); } -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)+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) { asio::detail::mutex::scoped_lock lock(mutex_); @@ -56,9 +60,10 @@ event_.signal(lock); } -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,+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, std::size_t max_cancelled) { asio::detail::mutex::scoped_lock lock(mutex_);@@ -69,10 +74,11 @@ return n; } -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)+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) { 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -33,12 +33,11 @@ mutex_(), event_(), timer_queues_(),- thread_(0),+ thread_(), stop_thread_(false), shutdown_(false) {- thread_ = new asio::detail::thread(- bind_handler(&winrt_timer_scheduler::call_run_thread, this));+ thread_ = thread(bind_handler(&winrt_timer_scheduler::call_run_thread, this)); } winrt_timer_scheduler::~winrt_timer_scheduler()@@ -53,13 +52,7 @@ stop_thread_ = true; event_.signal(lock); lock.unlock();-- if (thread_)- {- thread_->join();- delete thread_;- thread_ = 0;- }+ thread_.join(); 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/detail/initiate_defer.hpp view
@@ -2,7 +2,7 @@ // detail/initiate_defer.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -34,62 +34,44 @@ { public: template <typename CompletionHandler>- void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,- typename enable_if<+ void operator()(CompletionHandler&& handler,+ enable_if_t< execution::is_executor<- typename associated_executor<- typename decay<CompletionHandler>::type- >::type+ associated_executor_t<decay_t<CompletionHandler>> >::value- >::type* = 0) const+ >* = 0) const {- typedef typename decay<CompletionHandler>::type handler_t;-- typename associated_executor<handler_t>::type ex(+ associated_executor_t<decay_t<CompletionHandler>> ex( (get_associated_executor)(handler)); - typename associated_allocator<handler_t>::type alloc(+ associated_allocator_t<decay_t<CompletionHandler>> 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(- 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)+ static_cast<CompletionHandler&&>(handler))); } template <typename CompletionHandler>- void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,- typename enable_if<+ void operator()(CompletionHandler&& handler,+ enable_if_t< !execution::is_executor<- typename associated_executor<- typename decay<CompletionHandler>::type- >::type+ associated_executor_t<decay_t<CompletionHandler>> >::value- >::type* = 0) const+ >* = 0) const {- typedef typename decay<CompletionHandler>::type handler_t;-- typename associated_executor<handler_t>::type ex(+ associated_executor_t<decay_t<CompletionHandler>> ex( (get_associated_executor)(handler)); - typename associated_allocator<handler_t>::type alloc(+ associated_allocator_t<decay_t<CompletionHandler>> alloc( (get_associated_allocator)(handler)); ex.defer(asio::detail::bind_handler(- ASIO_MOVE_CAST(CompletionHandler)(handler)), alloc);+ static_cast<CompletionHandler&&>(handler)), alloc); } }; @@ -104,140 +86,113 @@ { } - executor_type get_executor() const ASIO_NOEXCEPT+ executor_type get_executor() const noexcept { return ex_; } template <typename CompletionHandler>- void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,- typename enable_if<+ void operator()(CompletionHandler&& handler,+ enable_if_t< execution::is_executor<- typename conditional<true, executor_type, CompletionHandler>::type+ conditional_t<true, executor_type, CompletionHandler> >::value- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< !detail::is_work_dispatcher_required<- typename decay<CompletionHandler>::type,+ decay_t<CompletionHandler>, Executor >::value- >::type* = 0) const+ >* = 0) const {- typedef typename decay<CompletionHandler>::type handler_t;-- typename associated_allocator<handler_t>::type alloc(+ associated_allocator_t<decay_t<CompletionHandler>> 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(- 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)+ static_cast<CompletionHandler&&>(handler))); } template <typename CompletionHandler>- void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,- typename enable_if<+ void operator()(CompletionHandler&& handler,+ enable_if_t< execution::is_executor<- typename conditional<true, executor_type, CompletionHandler>::type+ conditional_t<true, executor_type, CompletionHandler> >::value- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< detail::is_work_dispatcher_required<- typename decay<CompletionHandler>::type,+ decay_t<CompletionHandler>, Executor >::value- >::type* = 0) const+ >* = 0) const {- typedef typename decay<CompletionHandler>::type handler_t;+ typedef decay_t<CompletionHandler> handler_t; - typedef typename associated_executor<- handler_t, Executor>::type handler_ex_t;+ typedef associated_executor_t<handler_t, Executor> handler_ex_t; handler_ex_t handler_ex((get_associated_executor)(handler, ex_)); - typename associated_allocator<handler_t>::type alloc(+ associated_allocator_t<handler_t> 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>(- 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)+ static_cast<CompletionHandler&&>(handler), handler_ex)); } template <typename CompletionHandler>- void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,- typename enable_if<+ void operator()(CompletionHandler&& handler,+ enable_if_t< !execution::is_executor<- typename conditional<true, executor_type, CompletionHandler>::type+ conditional_t<true, executor_type, CompletionHandler> >::value- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< !detail::is_work_dispatcher_required<- typename decay<CompletionHandler>::type,+ decay_t<CompletionHandler>, Executor >::value- >::type* = 0) const+ >* = 0) const {- typedef typename decay<CompletionHandler>::type handler_t;-- typename associated_allocator<handler_t>::type alloc(+ associated_allocator_t<decay_t<CompletionHandler>> alloc( (get_associated_allocator)(handler)); ex_.defer(asio::detail::bind_handler(- ASIO_MOVE_CAST(CompletionHandler)(handler)), alloc);+ static_cast<CompletionHandler&&>(handler)), alloc); } template <typename CompletionHandler>- void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,- typename enable_if<+ void operator()(CompletionHandler&& handler,+ enable_if_t< !execution::is_executor<- typename conditional<true, executor_type, CompletionHandler>::type+ conditional_t<true, executor_type, CompletionHandler> >::value- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< detail::is_work_dispatcher_required<- typename decay<CompletionHandler>::type,+ decay_t<CompletionHandler>, Executor >::value- >::type* = 0) const+ >* = 0) const {- typedef typename decay<CompletionHandler>::type handler_t;+ typedef decay_t<CompletionHandler> handler_t; - typedef typename associated_executor<- handler_t, Executor>::type handler_ex_t;+ typedef associated_executor_t<handler_t, Executor> handler_ex_t; handler_ex_t handler_ex((get_associated_executor)(handler, ex_)); - typename associated_allocator<handler_t>::type alloc(+ associated_allocator_t<handler_t> alloc( (get_associated_allocator)(handler)); ex_.defer(detail::work_dispatcher<handler_t, handler_ex_t>(- ASIO_MOVE_CAST(CompletionHandler)(handler),- handler_ex), alloc);+ static_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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -32,55 +32,40 @@ { public: template <typename CompletionHandler>- void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,- typename enable_if<+ void operator()(CompletionHandler&& handler,+ enable_if_t< execution::is_executor<- typename associated_executor<- typename decay<CompletionHandler>::type- >::type+ associated_executor_t<decay_t<CompletionHandler>> >::value- >::type* = 0) const+ >* = 0) const {- typedef typename decay<CompletionHandler>::type handler_t;-- typename associated_executor<handler_t>::type ex(+ associated_executor_t<decay_t<CompletionHandler>> ex( (get_associated_executor)(handler)); - typename associated_allocator<handler_t>::type alloc(+ associated_allocator_t<decay_t<CompletionHandler>> alloc( (get_associated_allocator)(handler)); -#if defined(ASIO_NO_DEPRECATED) asio::prefer(ex, execution::allocator(alloc)).execute( asio::detail::bind_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)+ static_cast<CompletionHandler&&>(handler))); } template <typename CompletionHandler>- void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,- typename enable_if<+ void operator()(CompletionHandler&& handler,+ enable_if_t< !execution::is_executor<- typename associated_executor<- typename decay<CompletionHandler>::type- >::type+ associated_executor_t<decay_t<CompletionHandler>> >::value- >::type* = 0) const+ >* = 0) const {- typedef typename decay<CompletionHandler>::type handler_t;-- typename associated_executor<handler_t>::type ex(+ associated_executor_t<decay_t<CompletionHandler>> ex( (get_associated_executor)(handler)); - typename associated_allocator<handler_t>::type alloc(+ associated_allocator_t<decay_t<CompletionHandler>> alloc( (get_associated_allocator)(handler)); ex.dispatch(asio::detail::bind_handler(- ASIO_MOVE_CAST(CompletionHandler)(handler)), alloc);+ static_cast<CompletionHandler&&>(handler)), alloc); } }; @@ -95,126 +80,105 @@ { } - executor_type get_executor() const ASIO_NOEXCEPT+ executor_type get_executor() const noexcept { return ex_; } template <typename CompletionHandler>- void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,- typename enable_if<+ void operator()(CompletionHandler&& handler,+ enable_if_t< execution::is_executor<- typename conditional<true, executor_type, CompletionHandler>::type+ conditional_t<true, executor_type, CompletionHandler> >::value- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< !detail::is_work_dispatcher_required<- typename decay<CompletionHandler>::type,+ decay_t<CompletionHandler>, Executor >::value- >::type* = 0) const+ >* = 0) const {- typedef typename decay<CompletionHandler>::type handler_t;-- typename associated_allocator<handler_t>::type alloc(+ associated_allocator_t<decay_t<CompletionHandler>> alloc( (get_associated_allocator)(handler)); -#if defined(ASIO_NO_DEPRECATED) asio::prefer(ex_, execution::allocator(alloc)).execute( asio::detail::bind_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)+ static_cast<CompletionHandler&&>(handler))); } template <typename CompletionHandler>- void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,- typename enable_if<+ void operator()(CompletionHandler&& handler,+ enable_if_t< execution::is_executor<- typename conditional<true, executor_type, CompletionHandler>::type+ conditional_t<true, executor_type, CompletionHandler> >::value- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< detail::is_work_dispatcher_required<- typename decay<CompletionHandler>::type,+ decay_t<CompletionHandler>, Executor >::value- >::type* = 0) const+ >* = 0) const {- typedef typename decay<CompletionHandler>::type handler_t;+ typedef decay_t<CompletionHandler> handler_t; - typedef typename associated_executor<- handler_t, Executor>::type handler_ex_t;+ typedef associated_executor_t<handler_t, Executor> handler_ex_t; handler_ex_t handler_ex((get_associated_executor)(handler, ex_)); - typename associated_allocator<handler_t>::type alloc(+ associated_allocator_t<handler_t> 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>(- 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)+ static_cast<CompletionHandler&&>(handler), handler_ex)); } template <typename CompletionHandler>- void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,- typename enable_if<+ void operator()(CompletionHandler&& handler,+ enable_if_t< !execution::is_executor<- typename conditional<true, executor_type, CompletionHandler>::type+ conditional_t<true, executor_type, CompletionHandler> >::value- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< !detail::is_work_dispatcher_required<- typename decay<CompletionHandler>::type,+ decay_t<CompletionHandler>, Executor >::value- >::type* = 0) const+ >* = 0) const {- typedef typename decay<CompletionHandler>::type handler_t;-- typename associated_allocator<handler_t>::type alloc(+ associated_allocator_t<decay_t<CompletionHandler>> alloc( (get_associated_allocator)(handler)); ex_.dispatch(asio::detail::bind_handler(- ASIO_MOVE_CAST(CompletionHandler)(handler)), alloc);+ static_cast<CompletionHandler&&>(handler)), alloc); } template <typename CompletionHandler>- void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,- typename enable_if<+ void operator()(CompletionHandler&& handler,+ enable_if_t< !execution::is_executor<- typename conditional<true, executor_type, CompletionHandler>::type+ conditional_t<true, executor_type, CompletionHandler> >::value- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< detail::is_work_dispatcher_required<- typename decay<CompletionHandler>::type,+ decay_t<CompletionHandler>, Executor >::value- >::type* = 0) const+ >* = 0) const {- typedef typename decay<CompletionHandler>::type handler_t;+ typedef decay_t<CompletionHandler> handler_t; - typedef typename associated_executor<- handler_t, Executor>::type handler_ex_t;+ typedef associated_executor_t<handler_t, Executor> handler_ex_t; handler_ex_t handler_ex((get_associated_executor)(handler, ex_)); - typename associated_allocator<handler_t>::type alloc(+ associated_allocator_t<handler_t> alloc( (get_associated_allocator)(handler)); ex_.dispatch(detail::work_dispatcher<handler_t, handler_ex_t>(- ASIO_MOVE_CAST(CompletionHandler)(handler),- handler_ex), alloc);+ static_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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -34,62 +34,44 @@ { public: template <typename CompletionHandler>- void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,- typename enable_if<+ void operator()(CompletionHandler&& handler,+ enable_if_t< execution::is_executor<- typename associated_executor<- typename decay<CompletionHandler>::type- >::type+ associated_executor_t<decay_t<CompletionHandler>> >::value- >::type* = 0) const+ >* = 0) const {- typedef typename decay<CompletionHandler>::type handler_t;-- typename associated_executor<handler_t>::type ex(+ associated_executor_t<decay_t<CompletionHandler>> ex( (get_associated_executor)(handler)); - typename associated_allocator<handler_t>::type alloc(+ associated_allocator_t<decay_t<CompletionHandler>> 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(- 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)+ static_cast<CompletionHandler&&>(handler))); } template <typename CompletionHandler>- void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,- typename enable_if<+ void operator()(CompletionHandler&& handler,+ enable_if_t< !execution::is_executor<- typename associated_executor<- typename decay<CompletionHandler>::type- >::type+ associated_executor_t<decay_t<CompletionHandler>> >::value- >::type* = 0) const+ >* = 0) const {- typedef typename decay<CompletionHandler>::type handler_t;-- typename associated_executor<handler_t>::type ex(+ associated_executor_t<decay_t<CompletionHandler>> ex( (get_associated_executor)(handler)); - typename associated_allocator<handler_t>::type alloc(+ associated_allocator_t<decay_t<CompletionHandler>> alloc( (get_associated_allocator)(handler)); ex.post(asio::detail::bind_handler(- ASIO_MOVE_CAST(CompletionHandler)(handler)), alloc);+ static_cast<CompletionHandler&&>(handler)), alloc); } }; @@ -104,140 +86,113 @@ { } - executor_type get_executor() const ASIO_NOEXCEPT+ executor_type get_executor() const noexcept { return ex_; } template <typename CompletionHandler>- void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,- typename enable_if<+ void operator()(CompletionHandler&& handler,+ enable_if_t< execution::is_executor<- typename conditional<true, executor_type, CompletionHandler>::type+ conditional_t<true, executor_type, CompletionHandler> >::value- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< !detail::is_work_dispatcher_required<- typename decay<CompletionHandler>::type,+ decay_t<CompletionHandler>, Executor >::value- >::type* = 0) const+ >* = 0) const {- typedef typename decay<CompletionHandler>::type handler_t;-- typename associated_allocator<handler_t>::type alloc(+ associated_allocator_t<decay_t<CompletionHandler>> 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(- 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)+ static_cast<CompletionHandler&&>(handler))); } template <typename CompletionHandler>- void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,- typename enable_if<+ void operator()(CompletionHandler&& handler,+ enable_if_t< execution::is_executor<- typename conditional<true, executor_type, CompletionHandler>::type+ conditional_t<true, executor_type, CompletionHandler> >::value- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< detail::is_work_dispatcher_required<- typename decay<CompletionHandler>::type,+ decay_t<CompletionHandler>, Executor >::value- >::type* = 0) const+ >* = 0) const {- typedef typename decay<CompletionHandler>::type handler_t;+ typedef decay_t<CompletionHandler> handler_t; - typedef typename associated_executor<- handler_t, Executor>::type handler_ex_t;+ typedef associated_executor_t<handler_t, Executor> handler_ex_t; handler_ex_t handler_ex((get_associated_executor)(handler, ex_)); - typename associated_allocator<handler_t>::type alloc(+ associated_allocator_t<handler_t> 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>(- 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)+ static_cast<CompletionHandler&&>(handler), handler_ex)); } template <typename CompletionHandler>- void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,- typename enable_if<+ void operator()(CompletionHandler&& handler,+ enable_if_t< !execution::is_executor<- typename conditional<true, executor_type, CompletionHandler>::type+ conditional_t<true, executor_type, CompletionHandler> >::value- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< !detail::is_work_dispatcher_required<- typename decay<CompletionHandler>::type,+ decay_t<CompletionHandler>, Executor >::value- >::type* = 0) const+ >* = 0) const {- typedef typename decay<CompletionHandler>::type handler_t;-- typename associated_allocator<handler_t>::type alloc(+ associated_allocator_t<decay_t<CompletionHandler>> alloc( (get_associated_allocator)(handler)); ex_.post(asio::detail::bind_handler(- ASIO_MOVE_CAST(CompletionHandler)(handler)), alloc);+ static_cast<CompletionHandler&&>(handler)), alloc); } template <typename CompletionHandler>- void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,- typename enable_if<+ void operator()(CompletionHandler&& handler,+ enable_if_t< !execution::is_executor<- typename conditional<true, executor_type, CompletionHandler>::type+ conditional_t<true, executor_type, CompletionHandler> >::value- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< detail::is_work_dispatcher_required<- typename decay<CompletionHandler>::type,+ decay_t<CompletionHandler>, Executor >::value- >::type* = 0) const+ >* = 0) const {- typedef typename decay<CompletionHandler>::type handler_t;+ typedef decay_t<CompletionHandler> handler_t; - typedef typename associated_executor<- handler_t, Executor>::type handler_ex_t;+ typedef associated_executor_t<handler_t, Executor> handler_ex_t; handler_ex_t handler_ex((get_associated_executor)(handler, ex_)); - typename associated_allocator<handler_t>::type alloc(+ associated_allocator_t<handler_t> alloc( (get_associated_allocator)(handler)); ex_.post(detail::work_dispatcher<handler_t, handler_ex_t>(- ASIO_MOVE_CAST(CompletionHandler)(handler),- handler_ex), alloc);+ static_cast<CompletionHandler&&>(handler), handler_ex), alloc); } private:
+ link/modules/asio-standalone/asio/include/asio/detail/initiation_base.hpp view
@@ -0,0 +1,62 @@+//+// 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/detail/io_object_impl.hpp view
@@ -1,8 +1,8 @@ //-// io_object_impl.hpp-// ~~~~~~~~~~~~~~~~~~+// detail/io_object_impl.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -60,7 +60,6 @@ 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()),@@ -88,7 +87,6 @@ service_->converting_move_construct(implementation_, other.get_service(), other.get_implementation()); }-#endif // defined(ASIO_HAS_MOVE) // Destructor. ~io_object_impl()@@ -96,7 +94,6 @@ service_->destroy(implementation_); } -#if defined(ASIO_HAS_MOVE) // Move-assign an I/O object. io_object_impl& operator=(io_object_impl&& other) {@@ -110,10 +107,9 @@ } return *this; }-#endif // defined(ASIO_HAS_MOVE) // Get the executor associated with the object.- const executor_type& get_executor() ASIO_NOEXCEPT+ const executor_type& get_executor() noexcept { return executor_; }@@ -146,7 +142,7 @@ // Helper function to get an executor's context. template <typename T> static execution_context& get_context(const T& t,- typename enable_if<execution::is_executor<T>::value>::type* = 0)+ enable_if_t<execution::is_executor<T>::value>* = 0) { return asio::query(t, execution::context); }@@ -154,7 +150,7 @@ // Helper function to get an executor's context. template <typename T> static execution_context& get_context(const T& t,- typename enable_if<!execution::is_executor<T>::value>::type* = 0)+ enable_if_t<!execution::is_executor<T>::value>* = 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -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_(ASIO_MOVE_CAST(Handler)(handler)),+ handler_(static_cast<Handler&&>(handler)), work_(handler_, io_ex) { }@@ -154,7 +154,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -63,7 +63,7 @@ { ::io_uring_prep_read_fixed(sqe, o->descriptor_, o->bufs_.buffers()->iov_base, o->bufs_.buffers()->iov_len,- 0, o->bufs_.registered_id().native_handle());+ -1, 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_(ASIO_MOVE_CAST(Handler)(handler)),+ handler_(static_cast<Handler&&>(handler)), work_(handler_, io_ex) { }@@ -149,7 +149,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -85,7 +85,7 @@ // Move-construct a new descriptor implementation. ASIO_DECL void move_construct(implementation_type& impl,- implementation_type& other_impl) ASIO_NOEXCEPT;+ implementation_type& other_impl) 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); - typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> slot = asio::get_associated_cancellation_slot(handler); int op_type;@@ -304,7 +304,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> 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); - typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> 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); - typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> 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); - typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> 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); - typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> 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); - typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -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_(ASIO_MOVE_CAST(Handler)(handler)),+ handler_(static_cast<Handler&&>(handler)), work_(handler_, io_ex) { }@@ -148,7 +148,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -63,7 +63,7 @@ { ::io_uring_prep_write_fixed(sqe, o->descriptor_, o->bufs_.buffers()->iov_base, o->bufs_.buffers()->iov_len,- 0, o->bufs_.registered_id().native_handle());+ -1, 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_(ASIO_MOVE_CAST(Handler)(handler)),+ handler_(static_cast<Handler&&>(handler)), work_(handler_, io_ex) { }@@ -144,7 +144,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -19,7 +19,6 @@ #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"@@ -41,7 +40,7 @@ &io_uring_null_buffers_op::do_prepare, &io_uring_null_buffers_op::do_perform, &io_uring_null_buffers_op::do_complete),- handler_(ASIO_MOVE_CAST(Handler)(handler)),+ handler_(static_cast<Handler&&>(handler)), work_(handler_, io_ex), descriptor_(descriptor), poll_flags_(poll_flags)@@ -74,7 +73,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -69,11 +69,8 @@ }; // Per I/O object state.- class io_object+ struct io_object {- friend class io_uring_service;- friend class object_pool_access;- io_object* next_; io_object* prev_; @@ -82,7 +79,7 @@ io_queue queues_[max_ops]; bool shutdown_; - ASIO_DECL io_object(bool locking);+ ASIO_DECL io_object(bool locking, int spin_count); }; // Per I/O object data.@@ -146,38 +143,39 @@ ASIO_DECL void cleanup_io_object(per_io_object_data& io_obj); // Add a new timer queue to the reactor.- template <typename Time_Traits>- void add_timer_queue(timer_queue<Time_Traits>& timer_queue);+ template <typename TimeTraits, typename Allocator>+ void add_timer_queue(timer_queue<TimeTraits, Allocator>& timer_queue); // Remove a timer queue from the reactor.- template <typename Time_Traits>- void remove_timer_queue(timer_queue<Time_Traits>& timer_queue);+ template <typename TimeTraits, typename Allocator>+ void remove_timer_queue(timer_queue<TimeTraits, Allocator>& timer_queue); // Schedule a new operation in the given timer queue to expire at the // specified absolute time.- 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);+ 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); // Cancel the timer operations associated with the given token. Returns the // number of operations that have been posted or dispatched.- template <typename Time_Traits>- std::size_t cancel_timer(timer_queue<Time_Traits>& queue,- typename timer_queue<Time_Traits>::per_timer_data& timer,+ template <typename TimeTraits, typename Allocator>+ std::size_t cancel_timer(timer_queue<TimeTraits, Allocator>& queue,+ typename timer_queue<TimeTraits, Allocator>::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 Time_Traits>- void cancel_timer_by_key(timer_queue<Time_Traits>& queue,- typename timer_queue<Time_Traits>::per_timer_data* timer,+ template <typename TimeTraits, typename Allocator>+ void cancel_timer_by_key(timer_queue<TimeTraits, Allocator>& queue,+ typename timer_queue<TimeTraits, Allocator>::per_timer_data* timer, void* cancellation_key); // Move the timer operations associated with the given timer.- 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);+ 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); // Wait on io_uring once until interrupted or events are ready to be // dispatched.@@ -277,6 +275,12 @@ // 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_; @@ -288,7 +292,8 @@ mutex registration_mutex_; // Keep track of all registered I/O objects.- object_pool<io_object> registered_io_objects_;+ object_pool<io_object, execution_context::allocator<void>>+ 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -22,7 +22,6 @@ #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"@@ -139,7 +138,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_(ASIO_MOVE_CAST(Handler)(handler)),+ handler_(static_cast<Handler&&>(handler)), work_(handler_, io_ex) { }@@ -161,7 +160,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<handler_work<Handler, IoExecutor>&&>( o->work_)); ASIO_ERROR_LOCATION(o->ec_);@@ -192,8 +191,6 @@ 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 :@@ -214,7 +211,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_(ASIO_MOVE_CAST(Handler)(handler)),+ handler_(static_cast<Handler&&>(handler)), work_(handler_, io_ex) { }@@ -237,7 +234,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<handler_work<Handler, IoExecutor>&&>( o->work_)); ASIO_ERROR_LOCATION(o->ec_);@@ -250,8 +247,8 @@ // deallocated the memory here. detail::move_binder2<Handler, asio::error_code, peer_socket_type>- handler(0, ASIO_MOVE_CAST(Handler)(o->handler_), o->ec_,- ASIO_MOVE_CAST(peer_socket_type)(*o));+ handler(0, static_cast<Handler&&>(o->handler_), o->ec_,+ static_cast<peer_socket_type&&>(*o)); p.h = asio::detail::addressof(handler.handler_); p.reset(); @@ -272,8 +269,6 @@ 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -22,7 +22,6 @@ #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"@@ -81,7 +80,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_(ASIO_MOVE_CAST(Handler)(handler)),+ handler_(static_cast<Handler&&>(handler)), work_(handler_, io_ex) { }@@ -100,7 +99,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -70,7 +70,7 @@ { ::io_uring_prep_read_fixed(sqe, o->socket_, o->bufs_.buffers()->iov_base, o->bufs_.buffers()->iov_len,- 0, o->bufs_.registered_id().native_handle());+ -1, 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_(ASIO_MOVE_CAST(Handler)(handler)),+ handler_(static_cast<Handler&&>(handler)), work_(handler_, io_ex) { }@@ -164,7 +164,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -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_(ASIO_MOVE_CAST(Handler)(handler)),+ handler_(static_cast<Handler&&>(handler)), work_(handler_, io_ex) { }@@ -165,7 +165,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -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_(ASIO_MOVE_CAST(Handler)(handler)),+ handler_(static_cast<Handler&&>(handler)), work_(handler_, io_ex) { }@@ -151,7 +151,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -69,7 +69,7 @@ { ::io_uring_prep_write_fixed(sqe, o->socket_, o->bufs_.buffers()->iov_base, o->bufs_.buffers()->iov_len,- 0, o->bufs_.registered_id().native_handle());+ -1, 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_(ASIO_MOVE_CAST(Handler)(handler)),+ handler_(static_cast<Handler&&>(handler)), work_(handler_, io_ex) { }@@ -150,7 +150,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -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_(ASIO_MOVE_CAST(Handler)(handler)),+ handler_(static_cast<Handler&&>(handler)), work_(handler_, io_ex) { }@@ -153,7 +153,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -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) ASIO_NOEXCEPT+ implementation_type& other_impl) noexcept { this->base_move_construct(impl, other_impl); @@ -275,7 +275,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> 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); - typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> 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; - typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -446,7 +446,7 @@ poll_flags = POLLIN; } - typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> 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); - typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -539,7 +539,6 @@ 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>@@ -550,7 +549,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -575,7 +574,6 @@ 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,@@ -595,7 +593,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -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) ASIO_NOEXCEPT;+ base_implementation_type& other_impl) 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); - typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> slot = asio::get_associated_cancellation_slot(handler); int op_type;@@ -289,7 +289,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> 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); - typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> 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; - typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -448,7 +448,7 @@ poll_flags = POLLIN; } - typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> 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; - typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -566,7 +566,7 @@ poll_flags = POLLIN; } - typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -19,7 +19,6 @@ #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"@@ -39,7 +38,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_(ASIO_MOVE_CAST(Handler)(handler)),+ handler_(static_cast<Handler&&>(handler)), work_(handler_, io_ex), descriptor_(descriptor), poll_flags_(poll_flags)@@ -72,7 +71,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -55,53 +55,23 @@ { }; -#if defined(ASIO_HAS_DECLTYPE)- template <typename> char buffer_sequence_begin_helper(...); template <typename T> char (&buffer_sequence_begin_helper(T* t,- typename enable_if<!is_same<+ enable_if_t<!is_same< decltype(asio::buffer_sequence_begin(*t)),- 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)+ void>::value>*))[2]; template <typename> char buffer_sequence_end_helper(...); template <typename T> char (&buffer_sequence_end_helper(T* t,- typename enable_if<!is_same<+ enable_if_t<!is_same< decltype(asio::buffer_sequence_end(*t)),- 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)+ void>::value>*))[2]; template <typename> char (&size_memfn_helper(...))[2];@@ -187,23 +157,11 @@ 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,- typename enable_if<is_convertible<+ enable_if_t<is_convertible< decltype(*asio::buffer_sequence_begin(*t)),- 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)+ Buffer>::value>*); 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/detail/kqueue_reactor.hpp view
@@ -2,7 +2,7 @@ // detail/kqueue_reactor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2025 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,10 +65,8 @@ // Per-descriptor queues. struct descriptor_state {- descriptor_state(bool locking) : mutex_(locking) {}-- friend class kqueue_reactor;- friend class object_pool_access;+ descriptor_state(bool locking, int spin_count)+ : mutex_(locking, spin_count) {} descriptor_state* next_; descriptor_state* prev_;@@ -172,38 +170,39 @@ per_descriptor_data& descriptor_data); // Add a new timer queue to the reactor.- template <typename Time_Traits>- void add_timer_queue(timer_queue<Time_Traits>& queue);+ template <typename TimeTraits, typename Allocator>+ void add_timer_queue(timer_queue<TimeTraits, Allocator>& timer_queue); // Remove a timer queue from the reactor.- template <typename Time_Traits>- void remove_timer_queue(timer_queue<Time_Traits>& queue);+ template <typename TimeTraits, typename Allocator>+ void remove_timer_queue(timer_queue<TimeTraits, Allocator>& timer_queue); // Schedule a new operation in the given timer queue to expire at the // specified absolute time.- 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);+ 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); // Cancel the timer operations associated with the given token. Returns the // number of operations that have been posted or dispatched.- template <typename Time_Traits>- std::size_t cancel_timer(timer_queue<Time_Traits>& queue,- typename timer_queue<Time_Traits>::per_timer_data& timer,+ template <typename TimeTraits, typename Allocator>+ std::size_t cancel_timer(timer_queue<TimeTraits, Allocator>& queue,+ typename timer_queue<TimeTraits, Allocator>::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 Time_Traits>- void cancel_timer_by_key(timer_queue<Time_Traits>& queue,- typename timer_queue<Time_Traits>::per_timer_data* timer,+ template <typename TimeTraits, typename Allocator>+ void cancel_timer_by_key(timer_queue<TimeTraits, Allocator>& queue,+ typename timer_queue<TimeTraits, Allocator>::per_timer_data* timer, void* cancellation_key); // Move the timer operations associated with the given timer.- 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);+ 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); // Run the kqueue loop. ASIO_DECL void run(long usec, op_queue<operation>& ops);@@ -249,11 +248,18 @@ // 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> registered_descriptors_;+ object_pool<descriptor_state, execution_context::allocator<void>>+ registered_descriptors_; }; } // namespace detail
link/modules/asio-standalone/asio/include/asio/detail/limits.hpp view
@@ -16,11 +16,6 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"--#if defined(ASIO_HAS_BOOST_LIMITS)-# include <boost/limits.hpp>-#else // defined(ASIO_HAS_BOOST_LIMITS)-# include <limits>-#endif // defined(ASIO_HAS_BOOST_LIMITS)+#include <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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
− link/modules/asio-standalone/asio/include/asio/detail/macos_fenced_block.hpp
@@ -1,62 +0,0 @@-//-// 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -23,42 +23,20 @@ #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_ALIGNOF)+ && defined(ASIO_HAS_BOOST_ALIGN) # 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 { -#if defined(ASIO_HAS_STD_SHARED_PTR)+using std::allocate_shared; 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;@@ -76,23 +54,39 @@ 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);-#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) } +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);+}+ } // namespace detail -#if defined(ASIO_HAS_CXX11_ALLOCATORS) using std::allocator_arg_t; # define ASIO_USES_ALLOCATOR(t) \ namespace std { \@@ -103,17 +97,10 @@ # 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) && defined(ASIO_HAS_ALIGNOF)+#if defined(ASIO_HAS_STD_ALIGNED_ALLOC) 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);@@ -123,7 +110,7 @@ asio::detail::throw_exception(ex); } return ptr;-#elif defined(ASIO_HAS_BOOST_ALIGN) && defined(ASIO_HAS_ALIGNOF)+#elif defined(ASIO_HAS_BOOST_ALIGN) 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);@@ -133,7 +120,7 @@ asio::detail::throw_exception(ex); } return ptr;-#elif defined(ASIO_MSVC) && defined(ASIO_HAS_ALIGNOF)+#elif defined(ASIO_MSVC) align = (align < ASIO_DEFAULT_ALIGN) ? ASIO_DEFAULT_ALIGN : align; size = (size % align == 0) ? size : size + (align - size % align); void* ptr = _aligned_malloc(size, align);@@ -143,23 +130,23 @@ asio::detail::throw_exception(ex); } return ptr;-#else // defined(ASIO_MSVC) && defined(ASIO_HAS_ALIGNOF)+#else // defined(ASIO_MSVC) (void)align; return ::operator new(size);-#endif // defined(ASIO_MSVC) && defined(ASIO_HAS_ALIGNOF)+#endif // defined(ASIO_MSVC) } inline void aligned_delete(void* ptr) {-#if defined(ASIO_HAS_STD_ALIGNED_ALLOC) && defined(ASIO_HAS_ALIGNOF)+#if defined(ASIO_HAS_STD_ALIGNED_ALLOC) std::free(ptr);-#elif defined(ASIO_HAS_BOOST_ALIGN) && defined(ASIO_HAS_ALIGNOF)+#elif defined(ASIO_HAS_BOOST_ALIGN) boost::alignment::aligned_free(ptr);-#elif defined(ASIO_MSVC) && defined(ASIO_HAS_ALIGNOF)+#elif defined(ASIO_MSVC) _aligned_free(ptr);-#else // defined(ASIO_MSVC) && defined(ASIO_HAS_ALIGNOF)+#else // defined(ASIO_MSVC) ::operator delete(ptr);-#endif // defined(ASIO_MSVC) && defined(ASIO_HAS_ALIGNOF)+#endif // defined(ASIO_MSVC) } } // namespace asio
link/modules/asio-standalone/asio/include/asio/detail/mutex.hpp view
@@ -2,7 +2,7 @@ // detail/mutex.hpp // ~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -23,10 +23,8 @@ # include "asio/detail/win_mutex.hpp" #elif defined(ASIO_HAS_PTHREADS) # include "asio/detail/posix_mutex.hpp"-#elif defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR)-# include "asio/detail/std_mutex.hpp" #else-# error Only Windows, POSIX and std::mutex are supported!+# include "asio/detail/std_mutex.hpp" #endif namespace asio {@@ -38,7 +36,7 @@ typedef win_mutex mutex; #elif defined(ASIO_HAS_PTHREADS) typedef posix_mutex mutex;-#elif defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR)+#else 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -26,24 +26,13 @@ template <typename T> struct non_const_lvalue {-#if defined(ASIO_HAS_MOVE) explicit non_const_lvalue(T& t)- : value(static_cast<typename conditional<- is_same<T, typename decay<T>::type>::value,- typename decay<T>::type&, T&&>::type>(t))- {- }-- 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)+ : value(static_cast<conditional_t<+ is_same<T, decay_t<T>>::value, decay_t<T>&, T&&>>(t)) { } - typename decay<T>::type value;-#endif // defined(ASIO_HAS_MOVE)+ conditional_t<is_same<T, decay_t<T>>::value, decay_t<T>&, decay_t<T>> value; }; } // namespace detail
link/modules/asio-standalone/asio/include/asio/detail/noncopyable.hpp view
@@ -2,7 +2,7 @@ // detail/noncopyable.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/detail/null_event.hpp view
@@ -2,7 +2,7 @@ // detail/null_event.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/detail/null_global.hpp view
@@ -2,7 +2,7 @@ // detail/null_global.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/detail/null_mutex.hpp view
@@ -2,7 +2,7 @@ // detail/null_mutex.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -39,6 +39,12 @@ // 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -33,6 +33,12 @@ // 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -19,7 +19,6 @@ #if !defined(ASIO_HAS_THREADS) -#include "asio/detail/noncopyable.hpp" #include "asio/detail/throw_error.hpp" #include "asio/error.hpp" @@ -29,9 +28,13 @@ 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)@@ -40,9 +43,34 @@ 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/detail/object_pool.hpp view
@@ -2,7 +2,7 @@ // detail/object_pool.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -15,60 +15,34 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include "asio/detail/noncopyable.hpp"+#include "asio/detail/config.hpp"+#include "asio/detail/memory.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { -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>+template <typename Object, typename Allocator> class object_pool- : private noncopyable { public: // Constructor.- object_pool()- : live_list_(0),+ template <typename... Args>+ object_pool(const Allocator& allocator,+ unsigned int preallocated, Args... args)+ : allocator_(allocator),+ 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.@@ -84,38 +58,20 @@ 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 Arg>- Object* alloc(Arg arg)+ template <typename... Args>+ Object* alloc(Args... args) { Object* o = free_list_; if (o)- free_list_ = object_pool_access::next(free_list_);+ free_list_ = free_list_->next_; else- o = object_pool_access::create<Object>(arg);+ o = allocate_object<Object>(allocator_, args...); - object_pool_access::next(o) = live_list_;- object_pool_access::prev(o) = 0;+ o->next_ = live_list_;+ o->prev_ = 0; if (live_list_)- object_pool_access::prev(live_list_) = o;+ live_list_->prev_ = o; live_list_ = o; return o;@@ -125,36 +81,36 @@ void free(Object* o) { if (live_list_ == o)- live_list_ = object_pool_access::next(o);+ live_list_ = o->next_; - if (object_pool_access::prev(o))- {- object_pool_access::next(object_pool_access::prev(o))- = object_pool_access::next(o);- }+ if (o->prev_)+ o->prev_->next_ = o->next_; - if (object_pool_access::next(o))- {- object_pool_access::prev(object_pool_access::next(o))- = object_pool_access::prev(o);- }+ if (o->next_)+ o->next_->prev_ = o->prev_; - object_pool_access::next(o) = free_list_;- object_pool_access::prev(o) = 0;+ o->next_ = free_list_;+ o->prev_ = 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 = object_pool_access::next(o);- object_pool_access::destroy(o);+ list = o->next_;+ deallocate_object(allocator_, 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/detail/op_queue.hpp view
@@ -2,7 +2,7 @@ // detail/op_queue.hpp // ~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/detail/operation.hpp view
@@ -2,7 +2,7 @@ // detail/operation.hpp // ~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/detail/pop_options.hpp view
@@ -2,7 +2,7 @@ // detail/pop_options.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/detail/posix_event.hpp view
@@ -2,7 +2,7 @@ // detail/posix_event.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/detail/posix_global.hpp view
@@ -2,7 +2,7 @@ // detail/posix_global.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/detail/posix_mutex.hpp view
@@ -2,7 +2,7 @@ // detail/posix_mutex.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -43,6 +43,12 @@ ~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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2025 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/detail/posix_thread.hpp view
@@ -2,7 +2,7 @@ // detail/posix_thread.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -21,7 +21,7 @@ #include <cstddef> #include <pthread.h>-#include "asio/detail/noncopyable.hpp"+#include "asio/detail/memory.hpp" #include "asio/detail/push_options.hpp" @@ -34,20 +34,53 @@ } 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)- : joined_(false)+ : posix_thread(std::allocator_arg, std::allocator<void>(), f) {- start_thread(new func<Function>(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_)+ {+ other.arg_ = 0;+ }+ // 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(); @@ -62,21 +95,18 @@ public: virtual ~func_base() {} virtual void run() = 0;- };-- struct auto_func_base_ptr- {- func_base* ptr;- ~auto_func_base_ptr() { delete ptr; }+ virtual void destroy() = 0;+ ::pthread_t thread_; }; - template <typename Function>+ template <typename Function, typename Allocator> class func : public func_base { public:- func(Function f)- : f_(f)+ func(Function f, const Allocator& a)+ : f_(f),+ allocator_(a) { } @@ -85,14 +115,19 @@ f_(); } + virtual void destroy()+ {+ deallocate_object(allocator_, this);+ }+ private: Function f_;+ Allocator allocator_; }; - ASIO_DECL void start_thread(func_base* arg);+ ASIO_DECL func_base* start_thread(func_base* arg); - ::pthread_t thread_;- bool joined_;+ func_base* arg_; }; } // 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/detail/push_options.hpp view
@@ -2,7 +2,7 @@ // detail/push_options.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -89,7 +89,7 @@ // Move-construct a new descriptor implementation. ASIO_DECL void move_construct(implementation_type& impl,- implementation_type& other_impl) ASIO_NOEXCEPT;+ implementation_type& other_impl) 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); - typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> 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, &io_ex, 0);+ is_continuation, false, true, false, &io_ex, 0); p.v = p.p = 0; return; }@@ -252,7 +252,8 @@ &reactor_, &impl.reactor_data_, impl.descriptor_, op_type); } - start_op(impl, op_type, p.p, is_continuation, false, false, &io_ex, 0);+ start_op(impl, op_type, p.p, is_continuation,+ false, false, false, &io_ex, 0); p.v = p.p = 0; } @@ -303,7 +304,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -326,7 +327,7 @@ start_op(impl, reactor::write_op, p.p, is_continuation, true, buffer_sequence_adapter<asio::const_buffer,- ConstBufferSequence>::all_empty(buffers), &io_ex, 0);+ ConstBufferSequence>::all_empty(buffers), true, &io_ex, 0); p.v = p.p = 0; } @@ -338,7 +339,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -360,7 +361,7 @@ &impl, impl.descriptor_, "async_write_some(null_buffers)")); start_op(impl, reactor::write_op, p.p,- is_continuation, false, false, &io_ex, 0);+ is_continuation, false, false, false, &io_ex, 0); p.v = p.p = 0; } @@ -412,7 +413,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -435,7 +436,7 @@ start_op(impl, reactor::read_op, p.p, is_continuation, true, buffer_sequence_adapter<asio::mutable_buffer,- MutableBufferSequence>::all_empty(buffers), &io_ex, 0);+ MutableBufferSequence>::all_empty(buffers), true, &io_ex, 0); p.v = p.p = 0; } @@ -447,7 +448,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -469,14 +470,15 @@ &impl, impl.descriptor_, "async_read_some(null_buffers)")); start_op(impl, reactor::read_op, p.p,- is_continuation, false, false, &io_ex, 0);+ is_continuation, false, 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 is_non_blocking, bool noop,+ 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, void (*on_immediate)(operation* op, bool, const void*), const void* immediate_arg); @@ -484,19 +486,20 @@ // immediate completion. template <typename Op> void start_op(implementation_type& impl, int op_type, Op* op,- bool is_continuation, bool is_non_blocking, bool noop,- const void* io_ex, ...)+ bool is_continuation, bool allow_speculative, bool noop,+ bool needs_non_blocking, const void* io_ex, ...) {- return do_start_op(impl, op_type, op, is_continuation,- is_non_blocking, noop, &Op::do_immediate, io_ex);+ return do_start_op(impl, op_type, op, is_continuation, allow_speculative,+ noop, needs_non_blocking, &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 is_non_blocking, bool noop, const void*,- typename enable_if<+ 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< is_same< typename associated_immediate_executor< typename Op::handler_type,@@ -504,10 +507,11 @@ >::asio_associated_immediate_executor_is_unspecialised, void >::value- >::type*)+ >*) {- return do_start_op(impl, op_type, op, is_continuation, is_non_blocking,- noop, &reactor::call_post_immediate_completion, &reactor_);+ return do_start_op(impl, op_type, op, is_continuation,+ allow_speculative, noop, needs_non_blocking,+ &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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -19,7 +19,6 @@ #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"@@ -42,7 +41,7 @@ Handler& handler, const IoExecutor& io_ex) : reactor_op(success_ec, &reactive_null_buffers_op::do_perform, &reactive_null_buffers_op::do_complete),- handler_(ASIO_MOVE_CAST(Handler)(handler)),+ handler_(static_cast<Handler&&>(handler)), work_(handler_, io_ex) { }@@ -65,7 +64,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<handler_work<Handler, IoExecutor>&&>( o->work_)); // Make a copy of the handler so that the memory can be deallocated before@@ -100,7 +99,7 @@ // Take ownership of the operation's outstanding work. immediate_handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -19,7 +19,6 @@ #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"@@ -108,7 +107,7 @@ : reactive_socket_accept_op_base<Socket, Protocol>( success_ec, socket, state, peer, protocol, peer_endpoint, &reactive_socket_accept_op::do_complete),- handler_(ASIO_MOVE_CAST(Handler)(handler)),+ handler_(static_cast<Handler&&>(handler)), work_(handler_, io_ex) { }@@ -130,7 +129,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<handler_work<Handler, IoExecutor>&&>( o->work_)); ASIO_ERROR_LOCATION(o->ec_);@@ -170,7 +169,7 @@ // Take ownership of the operation's outstanding work. immediate_handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<handler_work<Handler, IoExecutor>&&>( o->work_)); ASIO_ERROR_LOCATION(o->ec_);@@ -196,8 +195,6 @@ 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 :@@ -221,7 +218,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_(ASIO_MOVE_CAST(Handler)(handler)),+ handler_(static_cast<Handler&&>(handler)), work_(handler_, io_ex) { }@@ -244,7 +241,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<handler_work<Handler, IoExecutor>&&>( o->work_)); ASIO_ERROR_LOCATION(o->ec_);@@ -257,8 +254,8 @@ // deallocated the memory here. detail::move_binder2<Handler, asio::error_code, peer_socket_type>- handler(0, ASIO_MOVE_CAST(Handler)(o->handler_), o->ec_,- ASIO_MOVE_CAST(peer_socket_type)(*o));+ handler(0, static_cast<Handler&&>(o->handler_), o->ec_,+ static_cast<peer_socket_type&&>(*o)); p.h = asio::detail::addressof(handler.handler_); p.reset(); @@ -287,7 +284,7 @@ // Take ownership of the operation's outstanding work. immediate_handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<handler_work<Handler, IoExecutor>&&>( o->work_)); ASIO_ERROR_LOCATION(o->ec_);@@ -300,8 +297,8 @@ // deallocated the memory here. detail::move_binder2<Handler, asio::error_code, peer_socket_type>- handler(0, ASIO_MOVE_CAST(Handler)(o->handler_), o->ec_,- ASIO_MOVE_CAST(peer_socket_type)(*o));+ handler(0, static_cast<Handler&&>(o->handler_), o->ec_,+ static_cast<peer_socket_type&&>(*o)); p.h = asio::detail::addressof(handler.handler_); p.reset(); @@ -317,8 +314,6 @@ 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -19,7 +19,6 @@ #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"@@ -72,7 +71,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_(ASIO_MOVE_CAST(Handler)(handler)),+ handler_(static_cast<Handler&&>(handler)), work_(handler_, io_ex) { }@@ -91,7 +90,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<handler_work<Handler, IoExecutor>&&>( o->work_)); ASIO_ERROR_LOCATION(o->ec_);@@ -129,7 +128,7 @@ // Take ownership of the operation's outstanding work. immediate_handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -20,7 +20,6 @@ #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"@@ -109,7 +108,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_(ASIO_MOVE_CAST(Handler)(handler)),+ handler_(static_cast<Handler&&>(handler)), work_(handler_, io_ex) { }@@ -127,7 +126,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<handler_work<Handler, IoExecutor>&&>( o->work_)); ASIO_ERROR_LOCATION(o->ec_);@@ -164,7 +163,7 @@ // Take ownership of the operation's outstanding work. immediate_handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -20,7 +20,6 @@ #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"@@ -113,7 +112,7 @@ : reactive_socket_recvfrom_op_base<MutableBufferSequence, Endpoint>( success_ec, socket, protocol_type, buffers, endpoint, flags, &reactive_socket_recvfrom_op::do_complete),- handler_(ASIO_MOVE_CAST(Handler)(handler)),+ handler_(static_cast<Handler&&>(handler)), work_(handler_, io_ex) { }@@ -132,7 +131,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<handler_work<Handler, IoExecutor>&&>( o->work_)); ASIO_ERROR_LOCATION(o->ec_);@@ -170,7 +169,7 @@ // Take ownership of the operation's outstanding work. immediate_handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -20,7 +20,6 @@ #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"@@ -94,7 +93,7 @@ : reactive_socket_recvmsg_op_base<MutableBufferSequence>( success_ec, socket, buffers, in_flags, out_flags, &reactive_socket_recvmsg_op::do_complete),- handler_(ASIO_MOVE_CAST(Handler)(handler)),+ handler_(static_cast<Handler&&>(handler)), work_(handler_, io_ex) { }@@ -113,7 +112,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<handler_work<Handler, IoExecutor>&&>( o->work_)); ASIO_ERROR_LOCATION(o->ec_);@@ -151,7 +150,7 @@ // Take ownership of the operation's outstanding work. immediate_handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -20,7 +20,6 @@ #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 +111,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_(ASIO_MOVE_CAST(Handler)(handler)),+ handler_(static_cast<Handler&&>(handler)), work_(handler_, io_ex) { }@@ -130,7 +129,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<handler_work<Handler, IoExecutor>&&>( o->work_)); ASIO_ERROR_LOCATION(o->ec_);@@ -167,7 +166,7 @@ // Take ownership of the operation's outstanding work. immediate_handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<handler_work<Handler, IoExecutor>&&>( o->work_)); ASIO_ERROR_LOCATION(o->ec_);@@ -187,7 +186,6 @@ 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -20,7 +20,6 @@ #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"@@ -106,7 +105,7 @@ : reactive_socket_sendto_op_base<ConstBufferSequence, Endpoint>( success_ec, socket, buffers, endpoint, flags, &reactive_socket_sendto_op::do_complete),- handler_(ASIO_MOVE_CAST(Handler)(handler)),+ handler_(static_cast<Handler&&>(handler)), work_(handler_, io_ex) { }@@ -124,7 +123,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<handler_work<Handler, IoExecutor>&&>( o->work_)); ASIO_ERROR_LOCATION(o->ec_);@@ -161,7 +160,7 @@ // Take ownership of the operation's outstanding work. immediate_handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -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) ASIO_NOEXCEPT+ implementation_type& other_impl) noexcept { this->base_move_construct(impl, other_impl); @@ -284,7 +284,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> 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, &io_ex, 0);+ is_continuation, true, false, true, &io_ex, 0); p.v = p.p = 0; } @@ -320,7 +320,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> 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, &io_ex, 0);+ is_continuation, false, false, false, &io_ex, 0); p.v = p.p = 0; } @@ -406,7 +406,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> 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, &io_ex, 0);+ p.p, is_continuation, true, false, true, &io_ex, 0); p.v = p.p = 0; } @@ -445,7 +445,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> 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, &io_ex, 0);+ p.p, is_continuation, false, false, false, &io_ex, 0); p.v = p.p = 0; } @@ -516,7 +516,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -541,7 +541,6 @@ 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>@@ -552,7 +551,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -577,7 +576,6 @@ 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,@@ -598,7 +596,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -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) ASIO_NOEXCEPT;+ base_implementation_type& other_impl) 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); - typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> 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, &io_ex, 0);+ is_continuation, false, true, false, &io_ex, 0); p.v = p.p = 0; return; }@@ -242,7 +242,8 @@ &reactor_, &impl.reactor_data_, impl.socket_, op_type); } - start_op(impl, op_type, p.p, is_continuation, false, false, &io_ex, 0);+ start_op(impl, op_type, p.p, is_continuation,+ false, false, false, &io_ex, 0); p.v = p.p = 0; } @@ -289,7 +290,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -314,7 +315,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)), &io_ex, 0);+ ConstBufferSequence>::all_empty(buffers)), true, &io_ex, 0); p.v = p.p = 0; } @@ -326,7 +327,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -347,7 +348,7 @@ &impl, impl.socket_, "async_send(null_buffers)")); start_op(impl, reactor::write_op, p.p,- is_continuation, false, false, &io_ex, 0);+ is_continuation, false, false, false, &io_ex, 0); p.v = p.p = 0; } @@ -395,7 +396,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -424,7 +425,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)), &io_ex, 0);+ MutableBufferSequence>::all_empty(buffers)), true, &io_ex, 0); p.v = p.p = 0; } @@ -437,7 +438,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -460,7 +461,7 @@ start_op(impl, (flags & socket_base::message_out_of_band) ? reactor::except_op : reactor::read_op,- p.p, is_continuation, false, false, &io_ex, 0);+ p.p, is_continuation, false, false, false, &io_ex, 0); p.v = p.p = 0; } @@ -506,7 +507,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -532,7 +533,8 @@ (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, &io_ex, 0);+ (in_flags & socket_base::message_out_of_band) == 0,+ false, true, &io_ex, 0); p.v = p.p = 0; } @@ -546,7 +548,7 @@ bool is_continuation = asio_handler_cont_helpers::is_continuation(handler); - typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -573,7 +575,7 @@ start_op(impl, (in_flags & socket_base::message_out_of_band) ? reactor::except_op : reactor::read_op,- p.p, is_continuation, false, false, &io_ex, 0);+ p.p, is_continuation, false, false, false, &io_ex, 0); p.v = p.p = 0; } @@ -589,8 +591,9 @@ 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 is_non_blocking, bool noop,+ 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, void (*on_immediate)(operation* op, bool, const void*), const void* immediate_arg); @@ -598,19 +601,20 @@ // immediate completion. template <typename Op> void start_op(base_implementation_type& impl, int op_type, Op* op,- bool is_continuation, bool is_non_blocking, bool noop,- const void* io_ex, ...)+ bool is_continuation, bool allow_speculative, bool noop,+ bool needs_non_blocking, const void* io_ex, ...) {- return do_start_op(impl, op_type, op, is_continuation,- is_non_blocking, noop, &Op::do_immediate, io_ex);+ return do_start_op(impl, op_type, op, is_continuation, allow_speculative,+ noop, needs_non_blocking, &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 is_non_blocking, bool noop, const void*,- typename enable_if<+ 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< is_same< typename associated_immediate_executor< typename Op::handler_type,@@ -618,10 +622,11 @@ >::asio_associated_immediate_executor_is_unspecialised, void >::value- >::type*)+ >*) {- return do_start_op(impl, op_type, op, is_continuation, is_non_blocking,- noop, &reactor::call_post_immediate_completion, &reactor_);+ return do_start_op(impl, op_type, op, is_continuation,+ allow_speculative, noop, needs_non_blocking,+ &reactor::call_post_immediate_completion, &reactor_); } // Start the asynchronous accept operation.@@ -645,7 +650,7 @@ template <typename Op> void start_accept_op(base_implementation_type& impl, Op* op, bool is_continuation, bool peer_is_open, const void*,- typename enable_if<+ enable_if_t< is_same< typename associated_immediate_executor< typename Op::handler_type,@@ -653,7 +658,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_);@@ -681,7 +686,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*,- typename enable_if<+ enable_if_t< is_same< typename associated_immediate_executor< typename Op::handler_type,@@ -689,7 +694,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_);@@ -700,7 +705,7 @@ { public: reactor_op_cancellation(reactor* r,- reactor::per_descriptor_data* p, int d, int o)+ reactor::per_descriptor_data* p, socket_type d, int o) : reactor_(r), reactor_data_(p), descriptor_(d),@@ -723,7 +728,7 @@ private: reactor* reactor_; reactor::per_descriptor_data* reactor_data_;- int descriptor_;+ socket_type 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -19,7 +19,6 @@ #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"@@ -42,7 +41,7 @@ Handler& handler, const IoExecutor& io_ex) : reactor_op(success_ec, &reactive_wait_op::do_perform, &reactive_wait_op::do_complete),- handler_(ASIO_MOVE_CAST(Handler)(handler)),+ handler_(static_cast<Handler&&>(handler)), work_(handler_, io_ex) { }@@ -65,7 +64,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<handler_work<Handler, IoExecutor>&&>( o->work_)); // Make a copy of the handler so that the memory can be deallocated before@@ -100,7 +99,7 @@ // Take ownership of the operation's outstanding work. immediate_handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/detail/reactor_op.hpp view
@@ -2,7 +2,7 @@ // detail/reactor_op.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/detail/recycling_allocator.hpp view
@@ -2,7 +2,7 @@ // detail/recycling_allocator.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -48,16 +48,25 @@ 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, ASIO_ALIGNOF(T));+ 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) 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -17,18 +17,6 @@ #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>@@ -36,6 +24,9 @@ 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -19,7 +19,6 @@ #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 +59,7 @@ cancel_token_(cancel_token), endpoint_(endpoint), scheduler_(sched),- handler_(ASIO_MOVE_CAST(Handler)(handler)),+ handler_(static_cast<Handler&&>(handler)), work_(handler_, io_ex) { }@@ -78,7 +77,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] = "";@@ -100,7 +99,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -19,7 +19,6 @@ #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"@@ -61,7 +60,7 @@ cancel_token_(cancel_token), query_(qry), scheduler_(sched),- handler_(ASIO_MOVE_CAST(Handler)(handler)),+ handler_(static_cast<Handler&&>(handler)), work_(handler_, io_ex), addrinfo_(0) {@@ -86,7 +85,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(),@@ -105,7 +104,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -21,7 +21,6 @@ #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"@@ -34,7 +33,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:@@ -53,7 +52,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) { }@@ -61,15 +60,8 @@ // 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)@@ -94,12 +86,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, scheduler_, handler, io_ex);+ p.p = new (p.v) op(impl, qry, thread_pool_.scheduler(), handler, io_ex); - ASIO_HANDLER_CREATION((scheduler_.context(),+ ASIO_HANDLER_CREATION((thread_pool_.context(), *p.p, "resolver", &impl, 0, "async_resolve")); - start_resolve_op(p.p);+ thread_pool_.start_resolve_op(p.p); p.v = p.p = 0; } @@ -127,12 +119,13 @@ 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, scheduler_, handler, io_ex);+ p.p = new (p.v) op(impl, endpoint,+ thread_pool_.scheduler(), handler, io_ex); - ASIO_HANDLER_CREATION((scheduler_.context(),+ ASIO_HANDLER_CREATION((thread_pool_.context(), *p.p, "resolver", &impl, 0, "async_resolve")); - start_resolve_op(p.p);+ thread_pool_.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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -18,13 +18,11 @@ #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"@@ -50,13 +48,6 @@ // 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); @@ -91,9 +82,6 @@ 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@@ -121,29 +109,8 @@ }; #endif // !defined(ASIO_WINDOWS_RUNTIME) - // 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_;+ // Private thread pool used for performing asynchronous host resolution.+ resolver_thread_pool& thread_pool_; }; } // namespace detail
+ link/modules/asio-standalone/asio/include/asio/detail/resolver_thread_pool.hpp view
@@ -0,0 +1,105 @@+//+// 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -42,16 +42,21 @@ 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. Specifies the number of concurrent threads that are likely to- // run the scheduler. If set to 1 certain optimisation are performed.+ // Constructor. ASIO_DECL scheduler(asio::execution_context& ctx,- int concurrency_hint = 0, bool own_thread = true,+ 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(); @@ -135,12 +140,6 @@ // 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;@@ -210,23 +209,26 @@ // 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_; - // Flag to indicate that the dispatcher has been stopped.- bool stopped_;-- // Flag to indicate that the dispatcher has been shut down.- bool shutdown_;+ // The time limit on running the scheduler task, in microseconds.+ const long task_usec_; - // The concurrency hint used to initialise the scheduler.- const int concurrency_hint_;+ // The time limit on waiting when the queue is empty, in microseconds.+ const long wait_usec_; // 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/detail/scheduler_task.hpp view
@@ -2,7 +2,7 @@ // detail/scheduler_task.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/detail/scoped_lock.hpp view
@@ -2,7 +2,7 @@ // detail/scoped_lock.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/detail/scoped_ptr.hpp view
@@ -2,7 +2,7 @@ // detail/scoped_ptr.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/detail/select_interrupter.hpp view
@@ -2,7 +2,7 @@ // detail/select_interrupter.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/detail/select_reactor.hpp view
@@ -2,7 +2,7 @@ // detail/select_reactor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -152,38 +152,39 @@ per_descriptor_data& source_descriptor_data); // Add a new timer queue to the reactor.- template <typename Time_Traits>- void add_timer_queue(timer_queue<Time_Traits>& queue);+ template <typename TimeTraits, typename Allocator>+ void add_timer_queue(timer_queue<TimeTraits, Allocator>& queue); // Remove a timer queue from the reactor.- template <typename Time_Traits>- void remove_timer_queue(timer_queue<Time_Traits>& queue);+ template <typename TimeTraits, typename Allocator>+ void remove_timer_queue(timer_queue<TimeTraits, Allocator>& queue); // Schedule a new operation in the given timer queue to expire at the // specified absolute time.- 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);+ 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); // Cancel the timer operations associated with the given token. Returns the // number of operations that have been posted or dispatched.- template <typename Time_Traits>- std::size_t cancel_timer(timer_queue<Time_Traits>& queue,- typename timer_queue<Time_Traits>::per_timer_data& timer,+ template <typename TimeTraits, typename Allocator>+ std::size_t cancel_timer(timer_queue<TimeTraits, Allocator>& queue,+ typename timer_queue<TimeTraits, Allocator>::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 Time_Traits>- void cancel_timer_by_key(timer_queue<Time_Traits>& queue,- typename timer_queue<Time_Traits>::per_timer_data* timer,+ template <typename TimeTraits, typename Allocator>+ void cancel_timer_by_key(timer_queue<TimeTraits, Allocator>& queue,+ typename timer_queue<TimeTraits, Allocator>::per_timer_data* timer, void* cancellation_key); // Move the timer operations associated with the given timer.- 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);+ 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); // Run select once until interrupted or events are ready to be dispatched. ASIO_DECL void run(long usec, op_queue<operation>& ops);@@ -243,7 +244,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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -66,6 +66,10 @@ 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>@@ -76,16 +80,15 @@ bool has_service() const; private:- // Initalise a service's key when the key_type typedef is not available.+ // Initialise 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)- // Initalise a service's key when the key_type typedef is available.+ // Initialise a service's key when the key_type typedef is available. template <typename Service> static void init_key(execution_context::service::key& key,- typename enable_if<- is_base_of<typename Service::key_type, Service>::value>::type*);+ enable_if_t<is_base_of<typename Service::key_type, Service>::value>*); #endif // !defined(ASIO_NO_TYPEID) // Initialise a service's key based on its id.@@ -106,22 +109,28 @@ const execution_context::service::key& key2); // The type of a factory function used for creating a service instance.- typedef execution_context::service*(*factory_type)(void*);+ typedef execution_context::service*(*factory_type)(execution_context&, void*); // Factory function for creating a service instance.- template <typename Service, typename Owner>- static execution_context::service* create(void* owner);+ template <typename Service, typename Owner, typename... Args>+ static execution_context::service* create(+ execution_context& context, void* owner, Args&&... args); - // Destroy a service instance.- ASIO_DECL static void destroy(execution_context::service* service);+ // Helper function to destroy an allocated service instance.+ template <typename Service>+ static void destroy_allocated(execution_context::service* service); + // Helper function to destroy an added service instance.+ ASIO_DECL static void destroy_added(+ execution_context::service* service);+ // Helper class to manage service pointers. struct auto_service_ptr; friend struct auto_service_ptr; struct auto_service_ptr { execution_context::service* ptr_;- ~auto_service_ptr() { destroy(ptr_); }+ ASIO_DECL ~auto_service_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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/detail/signal_handler.hpp view
@@ -2,7 +2,7 @@ // detail/signal_handler.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -36,7 +36,7 @@ signal_handler(Handler& h, const IoExecutor& io_ex) : signal_op(&signal_handler::do_complete),- handler_(ASIO_MOVE_CAST(Handler)(h)),+ handler_(static_cast<Handler&&>(h)), work_(handler_, io_ex) { }@@ -53,7 +53,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/detail/signal_op.hpp view
@@ -2,7 +2,7 @@ // detail/signal_op.hpp // ~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -173,7 +173,7 @@ void async_wait(implementation_type& impl, Handler& handler, const IoExecutor& io_ex) {- typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/detail/socket_ops.hpp view
@@ -2,7 +2,7 @@ // detail/socket_ops.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/detail/socket_option.hpp view
@@ -2,7 +2,7 @@ // detail/socket_option.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/detail/socket_types.hpp view
@@ -2,7 +2,7 @@ // detail/socket_types.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -413,7 +413,11 @@ # endif # define ASIO_OS_DEF_SA_RESTART SA_RESTART # define ASIO_OS_DEF_SA_NOCLDSTOP SA_NOCLDSTOP-# define ASIO_OS_DEF_SA_NOCLDWAIT SA_NOCLDWAIT+# 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) #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
@@ -1,62 +0,0 @@-//-// 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/detail/static_mutex.hpp view
@@ -2,7 +2,7 @@ // detail/static_mutex.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -23,10 +23,8 @@ # include "asio/detail/win_static_mutex.hpp" #elif defined(ASIO_HAS_PTHREADS) # include "asio/detail/posix_static_mutex.hpp"-#elif defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR)-# include "asio/detail/std_static_mutex.hpp" #else-# error Only Windows and POSIX are supported!+# include "asio/detail/std_static_mutex.hpp" #endif namespace asio {@@ -41,7 +39,7 @@ #elif defined(ASIO_HAS_PTHREADS) typedef posix_static_mutex static_mutex; # define ASIO_STATIC_MUTEX_INIT ASIO_POSIX_STATIC_MUTEX_INIT-#elif defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR)+#else 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -16,9 +16,6 @@ #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"@@ -182,7 +179,5 @@ } // 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -16,9 +16,6 @@ #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" @@ -56,7 +53,5 @@ } // 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -16,9 +16,6 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"--#if defined(ASIO_HAS_STD_CALL_ONCE)- #include <exception> #include <mutex> @@ -64,7 +61,5 @@ } // 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -16,9 +16,6 @@ #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"@@ -46,6 +43,12 @@ { } + // Try to lock the mutex.+ bool try_lock()+ {+ return mutex_.try_lock();+ }+ // Lock the mutex. void lock() {@@ -67,7 +70,5 @@ } // 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -16,9 +16,6 @@ #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"@@ -75,7 +72,5 @@ } // 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -16,11 +16,8 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"--#if defined(ASIO_HAS_STD_THREAD)- #include <thread>-#include "asio/detail/noncopyable.hpp"+#include "asio/detail/memory.hpp" #include "asio/detail/push_options.hpp" @@ -28,9 +25,14 @@ 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)@@ -38,12 +40,37 @@ { } + // 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() {- join(); } + // 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();+ }+ // Wait for the thread to exit. void join() {@@ -65,7 +92,5 @@ } // 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -22,7 +22,6 @@ #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"@@ -90,33 +89,33 @@ // Request invocation of the given function. template <typename Executor, typename Function> static void execute(const implementation_type& impl, Executor& ex,- ASIO_MOVE_ARG(Function) function,- typename enable_if<- can_query<Executor, execution::allocator_t<void> >::value- >::type* = 0);+ Function&& function,+ enable_if_t<+ can_query<Executor, execution::allocator_t<void>>::value+ >* = 0); // Request invocation of the given function. template <typename Executor, typename Function> static void execute(const implementation_type& impl, Executor& ex,- ASIO_MOVE_ARG(Function) function,- typename enable_if<- !can_query<Executor, execution::allocator_t<void> >::value- >::type* = 0);+ Function&& function,+ enable_if_t<+ !can_query<Executor, execution::allocator_t<void>>::value+ >* = 0); // Request invocation of the given function. template <typename Executor, typename Function, typename Allocator> static void dispatch(const implementation_type& impl, Executor& ex,- ASIO_MOVE_ARG(Function) function, const Allocator& a);+ 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,- ASIO_MOVE_ARG(Function) function, const Allocator& a);+ 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,- ASIO_MOVE_ARG(Function) function, const Allocator& a);+ Function&& function, const Allocator& a); // Determine whether the strand is running in the current thread. ASIO_DECL static bool running_in_this_thread(@@ -141,7 +140,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,- ASIO_MOVE_ARG(Function) function, const Allocator& a);+ Function&& function, const Allocator& a); // Mutex to protect access to the service-wide state. mutex mutex_;@@ -150,7 +149,7 @@ enum { num_mutexes = 193 }; // Pool of mutexes.- scoped_ptr<mutex> mutexes_[num_mutexes];+ shared_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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -20,7 +20,6 @@ #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" @@ -124,7 +123,7 @@ #endif // defined(ASIO_STRAND_IMPLEMENTATIONS) // Pool of implementations.- scoped_ptr<strand_impl> implementations_[num_implementations];+ shared_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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/detail/thread.hpp view
@@ -2,7 +2,7 @@ // detail/thread.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -29,10 +29,8 @@ # else # include "asio/detail/win_thread.hpp" # endif-#elif defined(ASIO_HAS_STD_THREAD)-# include "asio/detail/std_thread.hpp" #else-# error Only Windows, POSIX and std::thread are supported!+# include "asio/detail/std_thread.hpp" #endif namespace asio {@@ -50,7 +48,7 @@ # else typedef win_thread thread; # endif-#elif defined(ASIO_HAS_STD_THREAD)+#else 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/detail/thread_group.hpp view
@@ -2,7 +2,7 @@ // detail/thread_group.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -16,7 +16,7 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"-#include "asio/detail/scoped_ptr.hpp"+#include "asio/detail/memory.hpp" #include "asio/detail/thread.hpp" #include "asio/detail/push_options.hpp"@@ -24,12 +24,14 @@ namespace asio { namespace detail { +template <typename Allocator> class thread_group { public: // Constructor initialises an empty thread group.- thread_group()- : first_(0)+ explicit thread_group(const Allocator& a)+ : allocator_(a),+ first_(0) { } @@ -43,7 +45,7 @@ template <typename Function> void create_thread(Function f) {- first_ = new item(f, first_);+ first_ = allocate_object<item>(allocator_, allocator_, f, first_); } // Create new threads in the group.@@ -62,7 +64,7 @@ first_->thread_.join(); item* tmp = first_; first_ = first_->next_;- delete tmp;+ deallocate_object(allocator_, tmp); } } @@ -77,8 +79,8 @@ struct item { template <typename Function>- explicit item(Function f, item* next)- : thread_(f),+ explicit item(const Allocator& a, Function f, item* next)+ : thread_(std::allocator_arg, a, f), next_(next) { }@@ -86,6 +88,9 @@ 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -21,12 +21,10 @@ #include "asio/detail/memory.hpp" #include "asio/detail/noncopyable.hpp" -#if defined(ASIO_HAS_STD_EXCEPTION_PTR) \- && !defined(ASIO_NO_EXCEPTIONS)+#if !defined(ASIO_NO_EXCEPTIONS) # include <exception> # include "asio/multiple_exceptions.hpp"-#endif // defined(ASIO_HAS_STD_EXCEPTION_PTR)- // && !defined(ASIO_NO_EXCEPTIONS)+#endif // !defined(ASIO_NO_EXCEPTIONS) #include "asio/detail/push_options.hpp" @@ -91,14 +89,22 @@ }; }; - enum { max_mem_index = parallel_group_tag::end_mem_index };+ 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 };+ thread_info_base()-#if defined(ASIO_HAS_STD_EXCEPTION_PTR) \- && !defined(ASIO_NO_EXCEPTIONS)+#if !defined(ASIO_NO_EXCEPTIONS) : has_pending_exception_(0)-#endif // defined(ASIO_HAS_STD_EXCEPTION_PTR)- // && !defined(ASIO_NO_EXCEPTIONS)+#endif // !defined(ASIO_NO_EXCEPTIONS) { for (int i = 0; i < max_mem_index; ++i) reusable_memory_[i] = 0;@@ -199,8 +205,7 @@ void capture_current_exception() {-#if defined(ASIO_HAS_STD_EXCEPTION_PTR) \- && !defined(ASIO_NO_EXCEPTIONS)+#if !defined(ASIO_NO_EXCEPTIONS) switch (has_pending_exception_) { case 0:@@ -216,24 +221,21 @@ default: break; }-#endif // defined(ASIO_HAS_STD_EXCEPTION_PTR)- // && !defined(ASIO_NO_EXCEPTIONS)+#endif // !defined(ASIO_NO_EXCEPTIONS) } void rethrow_pending_exception() {-#if defined(ASIO_HAS_STD_EXCEPTION_PTR) \- && !defined(ASIO_NO_EXCEPTIONS)+#if !defined(ASIO_NO_EXCEPTIONS) if (has_pending_exception_ > 0) { has_pending_exception_ = 0; std::exception_ptr ex(- ASIO_MOVE_CAST(std::exception_ptr)(+ static_cast<std::exception_ptr&&>( pending_exception_)); std::rethrow_exception(ex); }-#endif // defined(ASIO_HAS_STD_EXCEPTION_PTR)- // && !defined(ASIO_NO_EXCEPTIONS)+#endif // !defined(ASIO_NO_EXCEPTIONS) } private:@@ -244,12 +246,10 @@ #endif // defined(ASIO_HAS_IO_URING) void* reusable_memory_[max_mem_index]; -#if defined(ASIO_HAS_STD_EXCEPTION_PTR) \- && !defined(ASIO_NO_EXCEPTIONS)+#if !defined(ASIO_NO_EXCEPTIONS) int has_pending_exception_; std::exception_ptr pending_exception_;-#endif // defined(ASIO_HAS_STD_EXCEPTION_PTR)- // && !defined(ASIO_NO_EXCEPTIONS)+#endif // !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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/detail/throw_exception.hpp view
@@ -2,7 +2,7 @@ // detail/throw_exception.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -30,7 +30,7 @@ // Declare the throw_exception function for all targets. template <typename Exception>-void throw_exception(+[[noreturn]] void throw_exception( const Exception& e ASIO_SOURCE_LOCATION_DEFAULTED_PARAM);
+ link/modules/asio-standalone/asio/include/asio/detail/timed_cancel_op.hpp view
@@ -0,0 +1,361 @@+//+// 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -31,16 +31,16 @@ namespace asio { namespace detail { -template <typename Time_Traits>+template <typename TimeTraits, typename Allocator> class timer_queue : public timer_queue_base { public: // The time type.- typedef typename Time_Traits::time_type time_type;+ typedef typename TimeTraits::time_type time_type; // The duration type.- typedef typename Time_Traits::duration_type duration_type;+ typedef typename TimeTraits::duration_type duration_type; // Per-timer data. class per_timer_data@@ -67,10 +67,12 @@ }; // Constructor.- timer_queue()+ timer_queue(const Allocator& alloc, std::size_t heap_reserve) : timers_(),- heap_()+ heap_(alloc) {+ if (heap_reserve > 0)+ heap_.reserve(heap_reserve); } // Add a new timer to the queue. Returns true if this is the timer that is@@ -124,8 +126,8 @@ return max_duration; return this->to_msec(- Time_Traits::to_posix_duration(- Time_Traits::subtract(heap_[0].time_, Time_Traits::now())),+ TimeTraits::to_posix_duration(+ TimeTraits::subtract(heap_[0].time_, TimeTraits::now())), max_duration); } @@ -136,8 +138,8 @@ return max_duration; return this->to_usec(- Time_Traits::to_posix_duration(- Time_Traits::subtract(heap_[0].time_, Time_Traits::now())),+ TimeTraits::to_posix_duration(+ TimeTraits::subtract(heap_[0].time_, TimeTraits::now())), max_duration); } @@ -146,8 +148,8 @@ { if (!heap_.empty()) {- const time_type now = Time_Traits::now();- while (!heap_.empty() && !Time_Traits::less_than(now, heap_[0].time_))+ const time_type now = TimeTraits::now();+ while (!heap_.empty() && !TimeTraits::less_than(now, heap_[0].time_)) { per_timer_data* timer = heap_[0].timer_; while (wait_op* op = timer->op_queue_.front())@@ -251,7 +253,7 @@ while (index > 0) { std::size_t parent = (index - 1) / 2;- if (!Time_Traits::less_than(heap_[index].time_, heap_[parent].time_))+ if (!TimeTraits::less_than(heap_[index].time_, heap_[parent].time_)) break; swap_heap(index, parent); index = parent;@@ -265,10 +267,10 @@ while (child < heap_.size()) { std::size_t min_child = (child + 1 == heap_.size()- || Time_Traits::less_than(+ || TimeTraits::less_than( heap_[child].time_, heap_[child + 1].time_)) ? child : child + 1;- if (Time_Traits::less_than(heap_[index].time_, heap_[min_child].time_))+ if (TimeTraits::less_than(heap_[index].time_, heap_[min_child].time_)) break; swap_heap(index, min_child); index = min_child;@@ -303,7 +305,7 @@ swap_heap(index, heap_.size() - 1); timer.heap_index_ = (std::numeric_limits<std::size_t>::max)(); heap_.pop_back();- if (index > 0 && Time_Traits::less_than(+ if (index > 0 && TimeTraits::less_than( heap_[index].time_, heap_[(index - 1) / 2].time_)) up_heap(index); else@@ -378,7 +380,9 @@ }; // The heap of timers, with the earliest timer at the front.- std::vector<heap_entry> heap_;+ std::vector<heap_entry,+ typename std::allocator_traits<Allocator>::template+ rebind_alloc<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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -57,7 +57,7 @@ timer_queue_base* next_; }; -template <typename Time_Traits>+template <typename TimeTraits, typename Allocator> class timer_queue; } // namespace detail
− link/modules/asio-standalone/asio/include/asio/detail/timer_queue_ptime.hpp
@@ -1,103 +0,0 @@-//-// 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/detail/timer_scheduler.hpp view
@@ -2,7 +2,7 @@ // detail/timer_scheduler.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/detail/tss_ptr.hpp view
@@ -2,7 +2,7 @@ // detail/tss_ptr.hpp // ~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/detail/type_traits.hpp view
@@ -2,7 +2,7 @@ // detail/type_traits.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -16,148 +16,174 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"--#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)+#include <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;-#if defined(ASIO_MSVC) && (_MSC_VER < 1900)-using std::aligned_storage;-#else // defined(ASIO_MSVC) && (_MSC_VER < 1900)++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]; }; };-#endif // defined(ASIO_MSVC) && (_MSC_VER < 1900)+struct aligned_storage+{+ struct type+ {+ alignas(A) unsigned char data[N];+ };+};++template <std::size_t N, std::size_t A>+using aligned_storage_t = typename aligned_storage<N, A>::type;+ 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>-struct remove_cvref : remove_cv<typename std::remove_reference<T>::type> {};+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;+ 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;+}; -#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+template <typename T>+using void_t = typename void_type<T>::type; 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 {}; -#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+template <typename Head, typename... Tail>+struct conjunction<Head, Tail...> :+ conditional_t<Head::value, conjunction<Tail...>, Head> {}; struct defaulted_constraint {- ASIO_CONSTEXPR defaulted_constraint() {}+ constexpr defaulted_constraint() {} }; template <bool Condition, typename Type = int>-struct constraint : enable_if<Condition, Type> {};+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; } // namespace asio
link/modules/asio-standalone/asio/include/asio/detail/utility.hpp view
@@ -2,7 +2,7 @@ // detail/utility.hpp // ~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -27,7 +27,7 @@ using std::index_sequence_for; using std::make_index_sequence; -#elif defined(ASIO_HAS_VARIADIC_TEMPLATES)+#else // defined(ASIO_HAS_STD_INDEX_SEQUENCE) 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_VARIADIC_TEMPLATES)+#endif // defined(ASIO_HAS_STD_INDEX_SEQUENCE) } // namespace detail } // namespace asio
− link/modules/asio-standalone/asio/include/asio/detail/variadic_templates.hpp
@@ -1,294 +0,0 @@-//-// 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -36,7 +36,7 @@ wait_handler(Handler& h, const IoExecutor& io_ex) : wait_op(&wait_handler::do_complete),- handler_(ASIO_MOVE_CAST(Handler)(h)),+ handler_(static_cast<Handler&&>(h)), work_(handler_, io_ex) { }@@ -53,7 +53,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/detail/win_event.hpp view
@@ -2,7 +2,7 @@ // detail/win_event.hpp // ~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
− link/modules/asio-standalone/asio/include/asio/detail/win_fenced_block.hpp
@@ -1,90 +0,0 @@-//-// 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2025 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,7 +24,6 @@ #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"@@ -45,7 +44,7 @@ Handler& handler, const IoExecutor& io_ex) : operation(&win_iocp_handle_read_op::do_complete), buffers_(buffers),- handler_(ASIO_MOVE_CAST(Handler)(handler)),+ handler_(static_cast<Handler&&>(handler)), work_(handler_, io_ex) { }@@ -65,7 +64,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2025 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) {- typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> 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) {- typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> 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) {- typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> 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) {- typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2025 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,7 +24,6 @@ #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"@@ -45,7 +44,7 @@ Handler& handler, const IoExecutor& io_ex) : operation(&win_iocp_handle_write_op::do_complete), buffers_(buffers),- handler_(ASIO_MOVE_CAST(Handler)(handler)),+ handler_(static_cast<Handler&&>(handler)), work_(handler_, io_ex) { }@@ -64,7 +63,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -22,7 +22,6 @@ #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"@@ -45,11 +44,17 @@ public thread_context { public:- // 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);+ // 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);+ // Destructor. ASIO_DECL ~win_iocp_io_context(); @@ -176,44 +181,39 @@ const asio::error_code& ec, DWORD bytes_transferred = 0); // Add a new timer queue to the service.- template <typename Time_Traits>- void add_timer_queue(timer_queue<Time_Traits>& timer_queue);+ template <typename TimeTraits, typename Allocator>+ void add_timer_queue(timer_queue<TimeTraits, Allocator>& timer_queue); // Remove a timer queue from the service.- template <typename Time_Traits>- void remove_timer_queue(timer_queue<Time_Traits>& timer_queue);+ template <typename TimeTraits, typename Allocator>+ void remove_timer_queue(timer_queue<TimeTraits, Allocator>& timer_queue); // Schedule a new operation in the given timer queue to expire at the // specified absolute time.- 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);+ 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); // Cancel the timer associated with the given token. Returns the number of // handlers that have been posted or dispatched.- template <typename Time_Traits>- std::size_t cancel_timer(timer_queue<Time_Traits>& queue,- typename timer_queue<Time_Traits>::per_timer_data& timer,+ template <typename TimeTraits, typename Allocator>+ std::size_t cancel_timer(timer_queue<TimeTraits, Allocator>& queue,+ typename timer_queue<TimeTraits, Allocator>::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 Time_Traits>- void cancel_timer_by_key(timer_queue<Time_Traits>& queue,- typename timer_queue<Time_Traits>::per_timer_data* timer,+ template <typename TimeTraits, typename Allocator>+ void cancel_timer_by_key(timer_queue<TimeTraits, Allocator>& queue,+ typename timer_queue<TimeTraits, Allocator>::per_timer_data* timer, void* cancellation_key); // Move the timer operations associated with the given timer.- 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_;- }+ 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); private: #if defined(WINVER) && (WINVER < 0x0500)@@ -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 resouce we limit the number of outstanding events.+ // avoid exhausting this resource 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.- scoped_ptr<thread> timer_thread_;+ asio::detail::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.- scoped_ptr<thread> thread_;+ asio::detail::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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -22,7 +22,6 @@ #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"@@ -46,7 +45,7 @@ &win_iocp_null_buffers_op::do_perform, &win_iocp_null_buffers_op::do_complete), cancel_token_(cancel_token),- handler_(ASIO_MOVE_CAST(Handler)(handler)),+ handler_(static_cast<Handler&&>(handler)), work_(handler_, io_ex) { }@@ -71,7 +70,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -22,7 +22,6 @@ #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"@@ -41,7 +40,7 @@ win_iocp_overlapped_op(Handler& handler, const IoExecutor& io_ex) : operation(&win_iocp_overlapped_op::do_complete),- handler_(ASIO_MOVE_CAST(Handler)(handler)),+ handler_(static_cast<Handler&&>(handler)), work_(handler_, io_ex) { }@@ -60,7 +59,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -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,- ASIO_MOVE_ARG(Handler) handler)+ Handler&& handler) : ptr_(0), iocp_service_(0) {- this->reset(ex, ASIO_MOVE_CAST(Handler)(handler));+ this->reset(ex, static_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,- typename enable_if<+ enable_if_t< can_query<const Executor&, execution::context_t>::value- >::type* = 0)+ >* = 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,- typename enable_if<+ enable_if_t< !can_query<const Executor&, execution::context_t>::value- >::type* = 0)+ >* = 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2025 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -22,7 +22,6 @@ #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"@@ -55,7 +54,7 @@ enable_connection_aborted_(enable_connection_aborted), proxy_op_(0), cancel_requested_(0),- handler_(ASIO_MOVE_CAST(Handler)(handler)),+ handler_(static_cast<Handler&&>(handler)), work_(handler_, io_ex) { }@@ -138,7 +137,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<handler_work<Handler, IoExecutor>&&>( o->work_)); ASIO_ERROR_LOCATION(ec);@@ -179,8 +178,6 @@ 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@@ -202,7 +199,7 @@ enable_connection_aborted_(enable_connection_aborted), cancel_requested_(0), proxy_op_(0),- handler_(ASIO_MOVE_CAST(Handler)(handler)),+ handler_(static_cast<Handler&&>(handler)), work_(handler_, io_ex) { }@@ -286,7 +283,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<handler_work<Handler, IoExecutor>&&>( o->work_)); ASIO_ERROR_LOCATION(ec);@@ -299,8 +296,8 @@ // deallocated the memory here. detail::move_binder2<Handler, asio::error_code, peer_socket_type>- handler(0, ASIO_MOVE_CAST(Handler)(o->handler_), ec,- ASIO_MOVE_CAST(peer_socket_type)(o->peer_));+ handler(0, static_cast<Handler&&>(o->handler_), ec,+ static_cast<peer_socket_type&&>(o->peer_)); p.h = asio::detail::addressof(handler.handler_); p.reset(); @@ -331,8 +328,6 @@ 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -22,7 +22,6 @@ #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"@@ -69,7 +68,7 @@ Handler& handler, const IoExecutor& io_ex) : win_iocp_socket_connect_op_base(socket, &win_iocp_socket_connect_op::do_complete),- handler_(ASIO_MOVE_CAST(Handler)(handler)),+ handler_(static_cast<Handler&&>(handler)), work_(handler_, io_ex) { }@@ -98,7 +97,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -23,7 +23,6 @@ #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"@@ -49,7 +48,7 @@ state_(state), cancel_token_(cancel_token), buffers_(buffers),- handler_(ASIO_MOVE_CAST(Handler)(handler)),+ handler_(static_cast<Handler&&>(handler)), work_(handler_, io_ex) { }@@ -69,7 +68,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -23,7 +23,6 @@ #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"@@ -51,7 +50,7 @@ endpoint_size_(static_cast<int>(endpoint.capacity())), cancel_token_(cancel_token), buffers_(buffers),- handler_(ASIO_MOVE_CAST(Handler)(handler)),+ handler_(static_cast<Handler&&>(handler)), work_(handler_, io_ex) { }@@ -77,7 +76,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -23,7 +23,6 @@ #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"@@ -51,7 +50,7 @@ cancel_token_(cancel_token), buffers_(buffers), out_flags_(out_flags),- handler_(ASIO_MOVE_CAST(Handler)(handler)),+ handler_(static_cast<Handler&&>(handler)), work_(handler_, io_ex) { }@@ -72,7 +71,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -23,7 +23,6 @@ #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"@@ -47,7 +46,7 @@ : operation(&win_iocp_socket_send_op::do_complete), cancel_token_(cancel_token), buffers_(buffers),- handler_(ASIO_MOVE_CAST(Handler)(handler)),+ handler_(static_cast<Handler&&>(handler)), work_(handler_, io_ex) { }@@ -67,7 +66,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -27,7 +27,6 @@ #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"@@ -51,7 +50,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:@@ -131,7 +130,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) { }@@ -144,7 +143,7 @@ // Move-construct a new socket implementation. void move_construct(implementation_type& impl,- implementation_type& other_impl) ASIO_NOEXCEPT+ implementation_type& other_impl) noexcept { this->base_move_construct(impl, other_impl); @@ -349,7 +348,7 @@ socket_base::message_flags flags, Handler& handler, const IoExecutor& io_ex) {- typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -443,7 +442,7 @@ socket_base::message_flags flags, Handler& handler, const IoExecutor& io_ex) {- typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -475,7 +474,7 @@ endpoint_type& sender_endpoint, socket_base::message_flags flags, Handler& handler, const IoExecutor& io_ex) {- typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -548,7 +547,7 @@ void async_accept(implementation_type& impl, Socket& peer, endpoint_type* peer_endpoint, Handler& handler, const IoExecutor& io_ex) {- typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -580,7 +579,6 @@ 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>@@ -588,7 +586,7 @@ const PeerIoExecutor& peer_io_ex, endpoint_type* peer_endpoint, Handler& handler, const IoExecutor& io_ex) {- typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -620,7 +618,6 @@ 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,@@ -638,7 +635,7 @@ const endpoint_type& peer_endpoint, Handler& handler, const IoExecutor& io_ex) {- typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -27,7 +27,6 @@ #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"@@ -96,7 +95,7 @@ // Move-construct a new socket implementation. ASIO_DECL void base_move_construct(base_implementation_type& impl,- base_implementation_type& other_impl) ASIO_NOEXCEPT;+ base_implementation_type& other_impl) noexcept; // Move-assign from another socket implementation. ASIO_DECL void base_move_assign(base_implementation_type& impl,@@ -214,7 +213,7 @@ void async_wait(base_implementation_type& impl, socket_base::wait_type w, Handler& handler, const IoExecutor& io_ex) {- typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> slot = asio::get_associated_cancellation_slot(handler); bool is_continuation =@@ -298,7 +297,7 @@ const ConstBufferSequence& buffers, socket_base::message_flags flags, Handler& handler, const IoExecutor& io_ex) {- typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -374,7 +373,7 @@ const MutableBufferSequence& buffers, socket_base::message_flags flags, Handler& handler, const IoExecutor& io_ex) {- typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -407,7 +406,7 @@ const null_buffers&, socket_base::message_flags flags, Handler& handler, const IoExecutor& io_ex) {- typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -478,7 +477,7 @@ socket_base::message_flags& out_flags, Handler& handler, const IoExecutor& io_ex) {- typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -510,7 +509,7 @@ socket_base::message_flags& out_flags, Handler& handler, const IoExecutor& io_ex) {- typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -809,7 +808,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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -23,7 +23,6 @@ #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"@@ -47,7 +46,7 @@ &win_iocp_wait_op::do_perform, &win_iocp_wait_op::do_complete), cancel_token_(cancel_token),- handler_(ASIO_MOVE_CAST(Handler)(handler)),+ handler_(static_cast<Handler&&>(handler)), work_(handler_, io_ex) { }@@ -72,7 +71,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -41,6 +41,12 @@ ~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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2025 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,7 +20,6 @@ #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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/detail/win_thread.hpp view
@@ -2,7 +2,7 @@ // detail/win_thread.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -22,7 +22,7 @@ && !defined(UNDER_CE) #include <cstddef>-#include "asio/detail/noncopyable.hpp"+#include "asio/detail/memory.hpp" #include "asio/detail/socket_types.hpp" #include "asio/detail/push_options.hpp"@@ -60,22 +60,55 @@ long win_thread_base<T>::terminate_threads_ = 0; class win_thread- : private noncopyable,- public win_thread_base<win_thread>+ : 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)- : thread_(0),- exit_event_(0)+ : win_thread(std::allocator_arg, std::allocator<void>(), f, stack_size) {- start_thread(new func<Function>(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_)+ {+ other.arg_ = 0;+ }+ // 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(); @@ -96,23 +129,20 @@ public: virtual ~func_base() {} virtual void run() = 0;+ virtual void destroy() = 0;+ ::HANDLE thread_; ::HANDLE entry_event_; ::HANDLE exit_event_; }; - struct auto_func_base_ptr- {- func_base* ptr;- ~auto_func_base_ptr() { delete ptr; }- };-- template <typename Function>+ template <typename Function, typename Allocator> class func : public func_base { public:- func(Function f)- : f_(f)+ func(Function f, const Allocator& a)+ : f_(f),+ allocator_(a) { } @@ -121,14 +151,20 @@ f_(); } + virtual void destroy()+ {+ deallocate_object(allocator_, this);+ }+ private: Function f_;+ Allocator allocator_; }; - ASIO_DECL void start_thread(func_base* arg, unsigned int stack_size);+ ASIO_DECL func_base* start_thread(+ func_base* arg, unsigned int stack_size); - ::HANDLE thread_;- ::HANDLE exit_event_;+ func_base* arg_; }; } // 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/detail/winapp_thread.hpp view
@@ -2,7 +2,7 @@ // detail/winapp_thread.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -19,8 +19,7 @@ #if defined(ASIO_WINDOWS) && defined(ASIO_WINDOWS_APP) -#include "asio/detail/noncopyable.hpp"-#include "asio/detail/scoped_ptr.hpp"+#include "asio/detail/memory.hpp" #include "asio/detail/socket_types.hpp" #include "asio/detail/throw_error.hpp" #include "asio/error.hpp"@@ -33,37 +32,62 @@ 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) {- 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(); } + // 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;+ }+ // Destructor. ~winapp_thread() {- ::CloseHandle(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_;+ }+ // Wait for the thread to exit. void join() {- ::WaitForSingleObjectEx(thread_, INFINITE, false);+ if (arg_)+ ::WaitForSingleObjectEx(arg_->thread_, INFINITE, false); } // Get number of CPUs.@@ -82,15 +106,18 @@ public: virtual ~func_base() {} virtual void run() = 0;+ virtual void destroy() = 0;+ ::HANDLE thread_; }; - template <typename Function>+ template <typename Function, typename Allocator> class func : public func_base { public:- func(Function f)- : f_(f)+ func(Function f, const Allocator& a)+ : f_(f),+ allocator_(a) { } @@ -99,18 +126,38 @@ f_(); } + virtual void destroy()+ {+ deallocate_object(allocator_, this);+ }+ private: Function f_;+ Allocator allocator_; }; - ::HANDLE thread_;+ 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_; }; inline DWORD WINAPI winapp_thread_function(LPVOID arg) {- scoped_ptr<winapp_thread::func_base> func(- static_cast<winapp_thread::func_base*>(arg));- func->run();+ static_cast<winapp_thread::func_base*>(arg)->run(); return 0; } @@ -119,6 +166,6 @@ #include "asio/detail/pop_options.hpp" -#endif // defined(ASIO_WINDOWS) && defined(ASIO_WINDOWS_APP)+#endif // defined(ASIO_WINDOWS) && defined(UNDER_CE) #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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -19,8 +19,7 @@ #if defined(ASIO_WINDOWS) && defined(UNDER_CE) -#include "asio/detail/noncopyable.hpp"-#include "asio/detail/scoped_ptr.hpp"+#include "asio/detail/memory.hpp" #include "asio/detail/socket_types.hpp" #include "asio/detail/throw_error.hpp" #include "asio/error.hpp"@@ -33,37 +32,62 @@ 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) {- 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(); } + // 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;+ }+ // Destructor. ~wince_thread() {- ::CloseHandle(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_;+ }+ // Wait for the thread to exit. void join() {- ::WaitForSingleObject(thread_, INFINITE);+ if (arg_)+ ::WaitForSingleObject(arg_->thread_, INFINITE); } // Get number of CPUs.@@ -82,15 +106,18 @@ public: virtual ~func_base() {} virtual void run() = 0;+ virtual void destroy() = 0;+ ::HANDLE thread_; }; - template <typename Function>+ template <typename Function, typename Allocator> class func : public func_base { public:- func(Function f)- : f_(f)+ func(Function f, const Allocator& a)+ : f_(f),+ allocator_(a) { } @@ -99,18 +126,38 @@ f_(); } + virtual void destroy()+ {+ deallocate_object(allocator_, this);+ }+ private: Function f_;+ Allocator allocator_; }; - ::HANDLE thread_;+ 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_; }; inline DWORD WINAPI wince_thread_function(LPVOID arg) {- scoped_ptr<wince_thread::func_base> func(- static_cast<wince_thread::func_base*>(arg));- func->run();+ static_cast<wince_thread::func_base*>(arg)->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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -22,7 +22,6 @@ #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"@@ -54,7 +53,7 @@ Windows::Networking::EndpointPair^>^>( &winrt_resolve_op::do_complete), query_(query),- handler_(ASIO_MOVE_CAST(Handler)(handler)),+ handler_(static_cast<Handler&&>(handler)), work_(handler_, io_ex) { }@@ -71,7 +70,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -23,7 +23,6 @@ #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"@@ -43,7 +42,7 @@ winrt_socket_connect_op(Handler& handler, const IoExecutor& io_ex) : winrt_async_op<void>(&winrt_socket_connect_op::do_complete),- handler_(ASIO_MOVE_CAST(Handler)(handler)),+ handler_(static_cast<Handler&&>(handler)), work_(handler_, io_ex) { }@@ -60,7 +59,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -23,7 +23,6 @@ #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"@@ -46,7 +45,7 @@ : winrt_async_op<Windows::Storage::Streams::IBuffer^>( &winrt_socket_recv_op::do_complete), buffers_(buffers),- handler_(ASIO_MOVE_CAST(Handler)(handler)),+ handler_(static_cast<Handler&&>(handler)), work_(handler_, io_ex) { }@@ -63,7 +62,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -23,7 +23,6 @@ #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 +44,7 @@ Handler& handler, const IoExecutor& io_ex) : winrt_async_op<unsigned int>(&winrt_socket_send_op::do_complete), buffers_(buffers),- handler_(ASIO_MOVE_CAST(Handler)(handler)),+ handler_(static_cast<Handler&&>(handler)), work_(handler_, io_ex) { }@@ -62,7 +61,7 @@ // Take ownership of the operation's outstanding work. handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(+ static_cast<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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -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) ASIO_NOEXCEPT+ implementation_type& other_impl) 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -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) ASIO_NOEXCEPT;+ base_implementation_type& other_impl) 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -65,32 +65,33 @@ ASIO_DECL void init_task(); // Add a new timer queue to the reactor.- template <typename Time_Traits>- void add_timer_queue(timer_queue<Time_Traits>& queue);+ template <typename TimeTraits, typename Allocator>+ void add_timer_queue(timer_queue<TimeTraits, Allocator>& queue); // Remove a timer queue from the reactor.- template <typename Time_Traits>- void remove_timer_queue(timer_queue<Time_Traits>& queue);+ template <typename TimeTraits, typename Allocator>+ void remove_timer_queue(timer_queue<TimeTraits, Allocator>& queue); // Schedule a new operation in the given timer queue to expire at the // specified absolute time.- 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);+ 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); // Cancel the timer operations associated with the given token. Returns the // number of operations that have been posted or dispatched.- template <typename Time_Traits>- std::size_t cancel_timer(timer_queue<Time_Traits>& queue,- typename timer_queue<Time_Traits>::per_timer_data& timer,+ template <typename TimeTraits, typename Allocator>+ std::size_t cancel_timer(timer_queue<TimeTraits, Allocator>& queue,+ typename timer_queue<TimeTraits, Allocator>::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 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);+ 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); private: // Run the select loop in the thread.@@ -123,7 +124,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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/detail/winsock_init.hpp view
@@ -2,7 +2,7 @@ // detail/winsock_init.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -47,7 +47,7 @@ ASIO_DECL static void throw_on_error(data& d); }; -template <int Major = 2, int Minor = 0>+template <int Major = 2, int Minor = 2> 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -39,13 +39,13 @@ template <typename Handler, typename Executor> struct is_work_dispatcher_required<Handler, Executor,- typename enable_if<+ enable_if_t< is_same< typename associated_executor<Handler, Executor>::asio_associated_executor_is_unspecialised, void >::value- >::type> : false_type+ >> : false_type { }; @@ -54,15 +54,14 @@ { public: template <typename CompletionHandler>- work_dispatcher(ASIO_MOVE_ARG(CompletionHandler) handler,+ work_dispatcher(CompletionHandler&& handler, const Executor& handler_ex)- : handler_(ASIO_MOVE_CAST(CompletionHandler)(handler)),+ : handler_(static_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_)@@ -70,34 +69,25 @@ } work_dispatcher(work_dispatcher&& other)- : handler_(ASIO_MOVE_CAST(Handler)(other.handler_)),- executor_(ASIO_MOVE_CAST(work_executor_type)(other.executor_))+ : handler_(static_cast<Handler&&>(other.handler_)),+ executor_(static_cast<work_executor_type&&>(other.executor_)) { }-#endif // defined(ASIO_HAS_MOVE) void operator()() {- typename associated_allocator<Handler>::type alloc(- (get_associated_allocator)(handler_));-#if defined(ASIO_NO_DEPRECATED)+ associated_allocator_t<Handler> alloc((get_associated_allocator)(handler_)); asio::prefer(executor_, execution::allocator(alloc)).execute( asio::detail::bind_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)+ static_cast<Handler&&>(handler_))); } private:- typedef typename decay<- typename prefer_result<const Executor&,+ typedef decay_t<+ prefer_result_t<const Executor&, execution::outstanding_work_t::tracked_t- >::type- >::type work_executor_type;+ >+ > work_executor_type; Handler handler_; work_executor_type executor_;@@ -107,18 +97,16 @@ template <typename Handler, typename Executor> class work_dispatcher<Handler, Executor,- typename enable_if<!execution::is_executor<Executor>::value>::type>+ enable_if_t<!execution::is_executor<Executor>::value>> { public: template <typename CompletionHandler>- work_dispatcher(ASIO_MOVE_ARG(CompletionHandler) handler,- const Executor& handler_ex)+ work_dispatcher(CompletionHandler&& handler, const Executor& handler_ex) : work_(handler_ex),- handler_(ASIO_MOVE_CAST(CompletionHandler)(handler))+ handler_(static_cast<CompletionHandler&&>(handler)) { } -#if defined(ASIO_HAS_MOVE) work_dispatcher(const work_dispatcher& other) : work_(other.work_), handler_(other.handler_)@@ -126,19 +114,17 @@ } work_dispatcher(work_dispatcher&& other)- : work_(ASIO_MOVE_CAST(executor_work_guard<Executor>)(other.work_)),- handler_(ASIO_MOVE_CAST(Handler)(other.handler_))+ : work_(static_cast<executor_work_guard<Executor>&&>(other.work_)),+ handler_(static_cast<Handler&&>(other.handler_)) { }-#endif // defined(ASIO_HAS_MOVE) void operator()() {- typename associated_allocator<Handler>::type alloc(- (get_associated_allocator)(handler_));+ associated_allocator_t<Handler> alloc((get_associated_allocator)(handler_)); work_.get_executor().dispatch( asio::detail::bind_handler(- ASIO_MOVE_CAST(Handler)(handler_)), alloc);+ static_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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -16,9 +16,8 @@ #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/handler_invoke_helpers.hpp"+#include "asio/detail/initiate_dispatch.hpp" #include "asio/detail/push_options.hpp" @@ -43,20 +42,43 @@ } }; +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_(ASIO_MOVE_CAST(Handler)(handler))+ handler_(static_cast<Handler&&>(handler)) { } -#if defined(ASIO_HAS_MOVE) wrapped_handler(const wrapped_handler& other) : dispatcher_(other.dispatcher_), handler_(other.handler_)@@ -65,71 +87,85 @@ wrapped_handler(wrapped_handler&& other) : dispatcher_(other.dispatcher_),- handler_(ASIO_MOVE_CAST(Handler)(other.handler_))+ handler_(static_cast<Handler&&>(other.handler_)) { }-#endif // defined(ASIO_HAS_MOVE) + executor_type get_executor() const noexcept+ {+ return wrapped_executor<Dispatcher>::get(dispatcher_);+ }+ void operator()() {- dispatcher_.dispatch(ASIO_MOVE_CAST(Handler)(handler_));+ detail::initiate_dispatch_with_executor<executor_type>(+ this->get_executor())(static_cast<Handler&&>(handler_)); } void operator()() const {- dispatcher_.dispatch(handler_);+ detail::initiate_dispatch_with_executor<executor_type>(+ this->get_executor())(handler_); } template <typename Arg1> void operator()(const Arg1& arg1) {- dispatcher_.dispatch(detail::bind_handler(handler_, arg1));+ detail::initiate_dispatch_with_executor<executor_type>(+ this->get_executor())(detail::bind_handler(handler_, arg1)); } template <typename Arg1> void operator()(const Arg1& arg1) const {- dispatcher_.dispatch(detail::bind_handler(handler_, arg1));+ detail::initiate_dispatch_with_executor<executor_type>(+ this->get_executor())(detail::bind_handler(handler_, arg1)); } template <typename Arg1, typename Arg2> void operator()(const Arg1& arg1, const Arg2& arg2) {- dispatcher_.dispatch(detail::bind_handler(handler_, arg1, arg2));+ detail::initiate_dispatch_with_executor<executor_type>(+ this->get_executor())(detail::bind_handler(handler_, arg1, arg2)); } template <typename Arg1, typename Arg2> void operator()(const Arg1& arg1, const Arg2& arg2) const {- dispatcher_.dispatch(detail::bind_handler(handler_, arg1, arg2));+ detail::initiate_dispatch_with_executor<executor_type>(+ this->get_executor())(detail::bind_handler(handler_, arg1, arg2)); } template <typename Arg1, typename Arg2, typename Arg3> void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3) {- dispatcher_.dispatch(detail::bind_handler(handler_, arg1, arg2, arg3));+ detail::initiate_dispatch_with_executor<executor_type>(+ this->get_executor())(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 {- dispatcher_.dispatch(detail::bind_handler(handler_, arg1, arg2, arg3));+ detail::initiate_dispatch_with_executor<executor_type>(+ this->get_executor())(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) {- dispatcher_.dispatch(- detail::bind_handler(handler_, arg1, arg2, arg3, arg4));+ detail::initiate_dispatch_with_executor<executor_type>(+ this->get_executor())(+ 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 {- dispatcher_.dispatch(- detail::bind_handler(handler_, arg1, arg2, arg3, arg4));+ detail::initiate_dispatch_with_executor<executor_type>(+ this->get_executor())(+ detail::bind_handler(handler_, arg1, arg2, arg3, arg4)); } template <typename Arg1, typename Arg2, typename Arg3, typename Arg4,@@ -137,8 +173,9 @@ void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, const Arg4& arg4, const Arg5& arg5) {- dispatcher_.dispatch(- detail::bind_handler(handler_, arg1, arg2, arg3, arg4, arg5));+ detail::initiate_dispatch_with_executor<executor_type>(+ this->get_executor())(+ detail::bind_handler(handler_, arg1, arg2, arg3, arg4, arg5)); } template <typename Arg1, typename Arg2, typename Arg3, typename Arg4,@@ -146,8 +183,9 @@ void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3, const Arg4& arg4, const Arg5& arg5) const {- dispatcher_.dispatch(- detail::bind_handler(handler_, arg1, arg2, arg3, arg4, arg5));+ detail::initiate_dispatch_with_executor<executor_type>(+ this->get_executor())(+ detail::bind_handler(handler_, arg1, arg2, arg3, arg4, arg5)); } //private:@@ -155,168 +193,11 @@ 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -69,11 +69,10 @@ * @code void() @endcode */ template <ASIO_COMPLETION_TOKEN_FOR(void()) NullaryToken>-ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(NullaryToken, void()) dispatch(- ASIO_MOVE_ARG(NullaryToken) token)- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+inline auto dispatch(NullaryToken&& token)+ -> decltype( async_initiate<NullaryToken, void()>(- declval<detail::initiate_dispatch>(), token)))+ declval<detail::initiate_dispatch>(), token)) { return async_initiate<NullaryToken, void()>( detail::initiate_dispatch(), token);@@ -143,17 +142,15 @@ */ template <typename Executor, ASIO_COMPLETION_TOKEN_FOR(void()) NullaryToken- 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<+ = default_completion_token_t<Executor>>+inline auto dispatch(const Executor& ex,+ NullaryToken&& token = default_completion_token_t<Executor>(),+ constraint_t< execution::is_executor<Executor>::value || is_executor<Executor>::value- >::type = 0)- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ > = 0)+ -> decltype( 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);@@ -175,19 +172,17 @@ */ template <typename ExecutionContext, ASIO_COMPLETION_TOKEN_FOR(void()) NullaryToken- 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((+ = 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( 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 view
@@ -0,0 +1,282 @@+//+// 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -304,7 +304,6 @@ } // namespace error } // namespace asio -#if defined(ASIO_HAS_STD_SYSTEM_ERROR) namespace std { template<> struct is_error_code_enum<asio::error::basic_errors>@@ -328,7 +327,6 @@ }; } // 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -16,180 +16,17 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"--#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 <system_error> #include "asio/detail/push_options.hpp" namespace asio { -#if defined(ASIO_HAS_STD_SYSTEM_ERROR)- typedef std::error_category error_category;--#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)+typedef std::error_code error_code; /// 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -20,29 +20,14 @@ #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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -18,8 +18,6 @@ #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"@@ -37,10 +35,9 @@ template <typename ProtoAllocator> struct allocator_t {- /// The allocator_t property applies to executors, senders, and schedulers.+ /// The allocator_t property applies to executors. template <typename T>- static constexpr bool is_applicable_property_v =- is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;+ static constexpr bool is_applicable_property_v = is_executor_v<T>; /// The allocator_t property can be required. static constexpr bool is_requirable = true;@@ -78,32 +75,12 @@ struct allocator_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)+ static constexpr bool is_applicable_property_v = is_executor<T>::value; #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) - ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);- ASIO_STATIC_CONSTEXPR(bool, is_preferable = true);+ static constexpr bool is_requirable = true;+ static constexpr bool is_preferable = true; template <typename T> struct static_proxy@@ -112,17 +89,17 @@ struct type { template <typename P>- static constexpr auto query(ASIO_MOVE_ARG(P) p)+ static constexpr auto query(P&& p) noexcept( noexcept(- conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p))+ conditional_t<true, T, P>::query(static_cast<P&&>(p)) ) ) -> decltype(- conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p))+ conditional_t<true, T, P>::query(static_cast<P&&>(p)) ) {- return T::query(ASIO_MOVE_CAST(P)(p));+ return T::query(static_cast<P&&>(p)); } }; #else // defined(ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)@@ -138,22 +115,19 @@ #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 constexpr typename query_static_constexpr_member<T>::result_type static_query()- ASIO_NOEXCEPT_IF((- query_static_constexpr_member<T>::is_noexcept))+ noexcept(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 ASIO_CONSTEXPR const T static_query_v- = allocator_t::static_query<E>();+ static 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) - ASIO_CONSTEXPR ProtoAllocator value() const+ constexpr ProtoAllocator value() const { return a_; }@@ -161,7 +135,7 @@ private: friend struct allocator_t<void>; - explicit ASIO_CONSTEXPR allocator_t(const ProtoAllocator& a)+ explicit constexpr allocator_t(const ProtoAllocator& a) : a_(a) { }@@ -180,34 +154,14 @@ struct allocator_t<void> { #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)+ static constexpr bool is_applicable_property_v = is_executor<T>::value; #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) - ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);- ASIO_STATIC_CONSTEXPR(bool, is_preferable = true);+ static constexpr bool is_requirable = true;+ static constexpr bool is_preferable = true; - ASIO_CONSTEXPR allocator_t()+ constexpr allocator_t() { } @@ -218,17 +172,17 @@ struct type { template <typename P>- static constexpr auto query(ASIO_MOVE_ARG(P) p)+ static constexpr auto query(P&& p) noexcept( noexcept(- conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p))+ conditional_t<true, T, P>::query(static_cast<P&&>(p)) ) ) -> decltype(- conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p))+ conditional_t<true, T, P>::query(static_cast<P&&>(p)) ) {- return T::query(ASIO_MOVE_CAST(P)(p));+ return T::query(static_cast<P&&>(p)); } }; #else // defined(ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)@@ -244,23 +198,20 @@ #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 constexpr typename query_static_constexpr_member<T>::result_type static_query()- ASIO_NOEXCEPT_IF((- query_static_constexpr_member<T>::is_noexcept))+ noexcept(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 ASIO_CONSTEXPR const T static_query_v- = allocator_t::static_query<E>();+ static 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>- ASIO_CONSTEXPR allocator_t<OtherProtoAllocator> operator()(+ constexpr allocator_t<OtherProtoAllocator> operator()( const OtherProtoAllocator& a) const { return allocator_t<OtherProtoAllocator>(a);@@ -274,44 +225,15 @@ #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) -#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+ASIO_INLINE_VARIABLE constexpr allocator_t<void> allocator; } // 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-#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)- >+struct is_applicable_property<T, execution::allocator_t<ProtoAllocator>>+ : integral_constant<bool, execution::is_executor<T>::value> { }; @@ -324,18 +246,18 @@ template <typename T, typename ProtoAllocator> struct static_query<T, execution::allocator_t<ProtoAllocator>,- typename enable_if<+ enable_if_t< execution::allocator_t<ProtoAllocator>::template query_static_constexpr_member<T>::is_valid- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef typename execution::allocator_t<ProtoAllocator>::template query_static_constexpr_member<T>::result_type result_type; - static ASIO_CONSTEXPR result_type value()+ static 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,2654 +2,1924 @@ // execution/any_executor.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_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)+// 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;+};+ #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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -28,11 +28,10 @@ { public: /// Constructor.- ASIO_DECL bad_executor() ASIO_NOEXCEPT;+ ASIO_DECL bad_executor() noexcept; /// Obtain message associated with exception.- ASIO_DECL virtual const char* what() const- ASIO_NOEXCEPT_OR_NOTHROW;+ ASIO_DECL virtual const char* what() const noexcept; }; } // namespace execution
link/modules/asio-standalone/asio/include/asio/execution/blocking.hpp view
@@ -2,7 +2,7 @@ // execution/blocking.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -17,10 +17,7 @@ #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"@@ -44,10 +41,9 @@ /// behaviour of their execution functions. struct blocking_t {- /// The blocking_t property applies to executors, senders, and schedulers.+ /// The blocking_t property applies to executors. template <typename T>- static constexpr bool is_applicable_property_v =- is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;+ static constexpr bool is_applicable_property_v = is_executor_v<T>; /// The top-level blocking_t property cannot be required. static constexpr bool is_requirable = false;@@ -63,11 +59,9 @@ /// submitted function object. struct possibly_t {- /// The blocking_t::possibly_t property applies to executors, senders, and- /// schedulers.+ /// The blocking_t::possibly_t property applies to executors. template <typename T>- static constexpr bool is_applicable_property_v =- is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;+ static constexpr bool is_applicable_property_v = is_executor_v<T>; /// The blocking_t::possibly_t property can be required. static constexpr bool is_requirable = true;@@ -93,11 +87,9 @@ /// function object. struct always_t {- /// The blocking_t::always_t property applies to executors, senders, and- /// schedulers.+ /// The blocking_t::always_t property applies to executors. template <typename T>- static constexpr bool is_applicable_property_v =- is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;+ static constexpr bool is_applicable_property_v = is_executor_v<T>; /// The blocking_t::always_t property can be required. static constexpr bool is_requirable = true;@@ -123,11 +115,9 @@ /// submitted function object. struct never_t {- /// The blocking_t::never_t property applies to executors, senders, and- /// schedulers.+ /// The blocking_t::never_t property applies to executors. template <typename T>- static constexpr bool is_applicable_property_v =- is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;+ static constexpr bool is_applicable_property_v = is_executor_v<T>; /// The blocking_t::never_t property can be required. static constexpr bool is_requirable = true;@@ -200,8 +190,8 @@ template <typename Executor, typename Function> void blocking_execute(- ASIO_MOVE_ARG(Executor) ex,- ASIO_MOVE_ARG(Function) func);+ Executor&& ex,+ Function&& func); } // namespace blocking_adaptation @@ -209,54 +199,34 @@ struct blocking_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)+ static constexpr bool is_applicable_property_v = is_executor<T>::value; #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) - ASIO_STATIC_CONSTEXPR(bool, is_requirable = false);- ASIO_STATIC_CONSTEXPR(bool, is_preferable = false);+ static constexpr bool is_requirable = false;+ 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; - ASIO_CONSTEXPR blocking_t()+ constexpr blocking_t() : value_(-1) { } - ASIO_CONSTEXPR blocking_t(possibly_t)+ constexpr blocking_t(possibly_t) : value_(0) { } - ASIO_CONSTEXPR blocking_t(always_t)+ constexpr blocking_t(always_t) : value_(1) { } - ASIO_CONSTEXPR blocking_t(never_t)+ constexpr blocking_t(never_t) : value_(2) { }@@ -268,16 +238,14 @@ struct type { template <typename P>- auto query(ASIO_MOVE_ARG(P) p) const+ auto query(P&& p) const noexcept( noexcept(- declval<typename conditional<true, T, P>::type>().query(- ASIO_MOVE_CAST(P)(p))+ declval<conditional_t<true, T, P>>().query(static_cast<P&&>(p)) ) ) -> decltype(- declval<typename conditional<true, T, P>::type>().query(- ASIO_MOVE_CAST(P)(p))+ declval<conditional_t<true, T, P>>().query(static_cast<P&&>(p)) ); }; #else // defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)@@ -292,17 +260,17 @@ struct type { template <typename P>- static constexpr auto query(ASIO_MOVE_ARG(P) p)+ static constexpr auto query(P&& p) noexcept( noexcept(- conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p))+ conditional_t<true, T, P>::query(static_cast<P&&>(p)) ) ) -> decltype(- conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p))+ conditional_t<true, T, P>::query(static_cast<P&&>(p)) ) {- return T::query(ASIO_MOVE_CAST(P)(p));+ return T::query(static_cast<P&&>(p)); } }; #else // defined(ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)@@ -322,88 +290,87 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T>- static ASIO_CONSTEXPR+ static constexpr typename query_static_constexpr_member<T>::result_type static_query()- ASIO_NOEXCEPT_IF((- query_static_constexpr_member<T>::is_noexcept))+ noexcept(query_static_constexpr_member<T>::is_noexcept) { return query_static_constexpr_member<T>::value(); } template <typename T>- static ASIO_CONSTEXPR+ static constexpr typename traits::static_query<T, possibly_t>::result_type static_query(- typename enable_if<+ enable_if_t< !query_static_constexpr_member<T>::is_valid- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< !query_member<T>::is_valid- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< traits::static_query<T, possibly_t>::is_valid- >::type* = 0) ASIO_NOEXCEPT+ >* = 0) noexcept { return traits::static_query<T, possibly_t>::value(); } template <typename T>- static ASIO_CONSTEXPR+ static constexpr typename traits::static_query<T, always_t>::result_type static_query(- typename enable_if<+ enable_if_t< !query_static_constexpr_member<T>::is_valid- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< !query_member<T>::is_valid- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< !traits::static_query<T, possibly_t>::is_valid- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< traits::static_query<T, always_t>::is_valid- >::type* = 0) ASIO_NOEXCEPT+ >* = 0) noexcept { return traits::static_query<T, always_t>::value(); } template <typename T>- static ASIO_CONSTEXPR+ static constexpr typename traits::static_query<T, never_t>::result_type static_query(- typename enable_if<+ enable_if_t< !query_static_constexpr_member<T>::is_valid- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< !query_member<T>::is_valid- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< !traits::static_query<T, possibly_t>::is_valid- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< !traits::static_query<T, always_t>::is_valid- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< traits::static_query<T, never_t>::is_valid- >::type* = 0) ASIO_NOEXCEPT+ >* = 0) noexcept { return traits::static_query<T, never_t>::value(); } template <typename E, typename T = decltype(blocking_t::static_query<E>())>- static ASIO_CONSTEXPR const T static_query_v+ static 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 ASIO_CONSTEXPR bool operator==(+ friend constexpr bool operator==( const blocking_t& a, const blocking_t& b) { return a.value_ == b.value_; } - friend ASIO_CONSTEXPR bool operator!=(+ friend constexpr bool operator!=( const blocking_t& a, const blocking_t& b) { return a.value_ != b.value_;@@ -411,22 +378,20 @@ struct convertible_from_blocking_t {- ASIO_CONSTEXPR convertible_from_blocking_t(blocking_t) {}+ constexpr convertible_from_blocking_t(blocking_t) {} }; template <typename Executor>- friend ASIO_CONSTEXPR blocking_t query(+ friend constexpr blocking_t query( const Executor& ex, convertible_from_blocking_t,- typename enable_if<+ enable_if_t< can_query<const Executor&, possibly_t>::value- >::type* = 0)+ >* = 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&, blocking_t<>::possibly_t>::value))+ noexcept(is_nothrow_query<const Executor&, blocking_t<>::possibly_t>::value) #else // defined(ASIO_MSVC)- ASIO_NOEXCEPT_IF((- is_nothrow_query<const Executor&, possibly_t>::value))+ noexcept(is_nothrow_query<const Executor&, possibly_t>::value) #endif // defined(ASIO_MSVC) #endif // !defined(__clang__) {@@ -434,21 +399,19 @@ } template <typename Executor>- friend ASIO_CONSTEXPR blocking_t query(+ friend constexpr blocking_t query( const Executor& ex, convertible_from_blocking_t,- typename enable_if<+ enable_if_t< !can_query<const Executor&, possibly_t>::value- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< can_query<const Executor&, always_t>::value- >::type* = 0)+ >* = 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&, blocking_t<>::always_t>::value))+ noexcept(is_nothrow_query<const Executor&, blocking_t<>::always_t>::value) #else // defined(ASIO_MSVC)- ASIO_NOEXCEPT_IF((- is_nothrow_query<const Executor&, always_t>::value))+ noexcept(is_nothrow_query<const Executor&, always_t>::value) #endif // defined(ASIO_MSVC) #endif // !defined(__clang__) {@@ -456,24 +419,22 @@ } template <typename Executor>- friend ASIO_CONSTEXPR blocking_t query(+ friend constexpr blocking_t query( const Executor& ex, convertible_from_blocking_t,- typename enable_if<+ enable_if_t< !can_query<const Executor&, possibly_t>::value- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< !can_query<const Executor&, always_t>::value- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< can_query<const Executor&, never_t>::value- >::type* = 0)+ >* = 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&, blocking_t<>::never_t>::value))+ noexcept(is_nothrow_query<const Executor&, blocking_t<>::never_t>::value) #else // defined(ASIO_MSVC)- ASIO_NOEXCEPT_IF((- is_nothrow_query<const Executor&, never_t>::value))+ noexcept(is_nothrow_query<const Executor&, never_t>::value) #endif // defined(ASIO_MSVC) #endif // !defined(__clang__) {@@ -484,10 +445,6 @@ 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_; };@@ -499,12 +456,7 @@ #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>@@ -519,35 +471,15 @@ struct possibly_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)+ static constexpr bool is_applicable_property_v = is_executor<T>::value; #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) - ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);- ASIO_STATIC_CONSTEXPR(bool, is_preferable = true);+ static constexpr bool is_requirable = true;+ static constexpr bool is_preferable = true; typedef blocking_t<I> polymorphic_query_result_type; - ASIO_CONSTEXPR possibly_t()+ constexpr possibly_t() { } @@ -564,78 +496,77 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T>- static ASIO_CONSTEXPR+ static constexpr typename query_static_constexpr_member<T>::result_type static_query()- ASIO_NOEXCEPT_IF((- query_static_constexpr_member<T>::is_noexcept))+ noexcept(query_static_constexpr_member<T>::is_noexcept) { return query_static_constexpr_member<T>::value(); } template <typename T>- static ASIO_CONSTEXPR possibly_t static_query(- typename enable_if<+ static constexpr possibly_t static_query(+ enable_if_t< !query_static_constexpr_member<T>::is_valid- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< !query_member<T>::is_valid- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< !traits::query_free<T, possibly_t>::is_valid- >::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+ >* = 0,+ enable_if_t<+ !can_query<T, always_t<I>>::value+ >* = 0,+ enable_if_t<+ !can_query<T, never_t<I>>::value+ >* = 0) noexcept { return possibly_t(); } template <typename E, typename T = decltype(possibly_t::static_query<E>())>- static ASIO_CONSTEXPR const T static_query_v+ static 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 ASIO_CONSTEXPR blocking_t<I> value()+ static constexpr blocking_t<I> value() { return possibly_t(); } - friend ASIO_CONSTEXPR bool operator==(+ friend constexpr bool operator==( const possibly_t&, const possibly_t&) { return true; } - friend ASIO_CONSTEXPR bool operator!=(+ friend constexpr bool operator!=( const possibly_t&, const possibly_t&) { return false; } - friend ASIO_CONSTEXPR bool operator==(+ friend constexpr bool operator==( const possibly_t&, const always_t<I>&) { return false; } - friend ASIO_CONSTEXPR bool operator!=(+ friend constexpr bool operator!=( const possibly_t&, const always_t<I>&) { return true; } - friend ASIO_CONSTEXPR bool operator==(+ friend constexpr bool operator==( const possibly_t&, const never_t<I>&) { return false; } - friend ASIO_CONSTEXPR bool operator!=(+ friend constexpr bool operator!=( const possibly_t&, const never_t<I>&) { return true;@@ -653,129 +584,110 @@ class adapter { public:- adapter(int, const Executor& e) ASIO_NOEXCEPT+ adapter(int, const Executor& e) noexcept : executor_(e) { } - adapter(const adapter& other) ASIO_NOEXCEPT+ adapter(const adapter& other) noexcept : executor_(other.executor_) { } -#if defined(ASIO_HAS_MOVE)- adapter(adapter&& other) ASIO_NOEXCEPT- : executor_(ASIO_MOVE_CAST(Executor)(other.executor_))+ adapter(adapter&& other) noexcept+ : executor_(static_cast<Executor&&>(other.executor_)) { }-#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) template <int I>- static ASIO_CONSTEXPR always_t<I> query(- blocking_t<I>) ASIO_NOEXCEPT+ static constexpr always_t<I> query(blocking_t<I>) noexcept { return always_t<I>(); } template <int I>- static ASIO_CONSTEXPR always_t<I> query(- possibly_t<I>) ASIO_NOEXCEPT+ static constexpr always_t<I> query(possibly_t<I>) noexcept { return always_t<I>(); } template <int I>- static ASIO_CONSTEXPR always_t<I> query(- always_t<I>) ASIO_NOEXCEPT+ static constexpr always_t<I> query(always_t<I>) noexcept { return always_t<I>(); } template <int I>- static ASIO_CONSTEXPR always_t<I> query(- never_t<I>) ASIO_NOEXCEPT+ static constexpr always_t<I> query(never_t<I>) noexcept { return always_t<I>(); } template <typename Property>- typename enable_if<+ enable_if_t< 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))+ query_result_t<const Executor&, Property>+ > query(const Property& p) const+ noexcept(is_nothrow_query<const Executor&, Property>::value) { return asio::query(executor_, p); } template <int I>- 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+ 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 { return asio::require(executor_, possibly_t<I>()); } template <int I>- 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+ 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 { return asio::require(executor_, never_t<I>()); } template <typename Property>- typename enable_if<+ enable_if_t< 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))+ adapter<decay_t<require_result_t<const Executor&, Property>>>+ > require(const Property& p) const+ noexcept(is_nothrow_require<const Executor&, Property>::value) {- return adapter<typename decay<- typename require_result<const Executor&, Property>::type- >::type>(0, asio::require(executor_, p));+ return adapter<decay_t<require_result_t<const Executor&, Property>>>(+ 0, asio::require(executor_, p)); } template <typename Property>- typename enable_if<+ enable_if_t< 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))+ adapter<decay_t<prefer_result_t<const Executor&, Property>>>+ > prefer(const Property& p) const+ noexcept(is_nothrow_prefer<const Executor&, Property>::value) {- return adapter<typename decay<- typename prefer_result<const Executor&, Property>::type- >::type>(0, asio::prefer(executor_, p));+ return adapter<decay_t<prefer_result_t<const Executor&, Property>>>(+ 0, asio::prefer(executor_, p)); } template <typename Function>- typename enable_if<-#if defined(ASIO_NO_DEPRECATED)+ enable_if_t< 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 execute(ASIO_MOVE_ARG(Function) f) const+ > execute(Function&& f) const { blocking_adaptation::blocking_execute(- executor_, ASIO_MOVE_CAST(Function)(f));+ executor_, static_cast<Function&&>(f)); } - friend bool operator==(const adapter& a, const adapter& b) ASIO_NOEXCEPT+ friend bool operator==(const adapter& a, const adapter& b) noexcept { return a.executor_ == b.executor_; } - friend bool operator!=(const adapter& a, const adapter& b) ASIO_NOEXCEPT+ friend bool operator!=(const adapter& a, const adapter& b) noexcept { return a.executor_ != b.executor_; }@@ -788,35 +700,15 @@ struct always_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)+ static constexpr bool is_applicable_property_v = is_executor<T>::value; #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) - ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);- ASIO_STATIC_CONSTEXPR(bool, is_preferable = false);+ static constexpr bool is_requirable = true;+ static constexpr bool is_preferable = false; typedef blocking_t<I> polymorphic_query_result_type; - ASIO_CONSTEXPR always_t()+ constexpr always_t() { } @@ -833,57 +725,54 @@ #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 constexpr typename query_static_constexpr_member<T>::result_type static_query()- ASIO_NOEXCEPT_IF((- query_static_constexpr_member<T>::is_noexcept))+ noexcept(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 ASIO_CONSTEXPR const T static_query_v- = always_t::static_query<E>();+ static 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 ASIO_CONSTEXPR blocking_t<I> value()+ static constexpr blocking_t<I> value() { return always_t(); } - friend ASIO_CONSTEXPR bool operator==(+ friend constexpr bool operator==( const always_t&, const always_t&) { return true; } - friend ASIO_CONSTEXPR bool operator!=(+ friend constexpr bool operator!=( const always_t&, const always_t&) { return false; } - friend ASIO_CONSTEXPR bool operator==(+ friend constexpr bool operator==( const always_t&, const possibly_t<I>&) { return false; } - friend ASIO_CONSTEXPR bool operator!=(+ friend constexpr bool operator!=( const always_t&, const possibly_t<I>&) { return true; } - friend ASIO_CONSTEXPR bool operator==(+ friend constexpr bool operator==( const always_t&, const never_t<I>&) { return false; } - friend ASIO_CONSTEXPR bool operator!=(+ friend constexpr bool operator!=( const always_t&, const never_t<I>&) { return true;@@ -892,15 +781,15 @@ template <typename Executor> friend adapter<Executor> require( const Executor& e, const always_t&,- typename enable_if<+ enable_if_t< is_executor<Executor>::value- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< traits::static_require< const Executor&, blocking_adaptation::allowed_t<0> >::is_valid- >::type* = 0)+ >* = 0) { return adapter<Executor>(0, e); }@@ -917,35 +806,15 @@ struct never_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)+ static constexpr bool is_applicable_property_v = is_executor<T>::value; #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) - ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);- ASIO_STATIC_CONSTEXPR(bool, is_preferable = true);+ static constexpr bool is_requirable = true;+ static constexpr bool is_preferable = true; typedef blocking_t<I> polymorphic_query_result_type; - ASIO_CONSTEXPR never_t()+ constexpr never_t() { } @@ -962,58 +831,51 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T>- static ASIO_CONSTEXPR+ static constexpr typename query_static_constexpr_member<T>::result_type static_query()- ASIO_NOEXCEPT_IF((- query_static_constexpr_member<T>::is_noexcept))+ noexcept(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 ASIO_CONSTEXPR const T static_query_v+ static 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 ASIO_CONSTEXPR blocking_t<I> value()+ static constexpr blocking_t<I> value() { return never_t(); } - friend ASIO_CONSTEXPR bool operator==(- const never_t&, const never_t&)+ friend constexpr bool operator==(const never_t&, const never_t&) { return true; } - friend ASIO_CONSTEXPR bool operator!=(- const never_t&, const never_t&)+ friend constexpr bool operator!=(const never_t&, const never_t&) { return false; } - friend ASIO_CONSTEXPR bool operator==(- const never_t&, const possibly_t<I>&)+ friend constexpr bool operator==(const never_t&, const possibly_t<I>&) { return false; } - friend ASIO_CONSTEXPR bool operator!=(- const never_t&, const possibly_t<I>&)+ friend constexpr bool operator!=(const never_t&, const possibly_t<I>&) { return true; } - friend ASIO_CONSTEXPR bool operator==(- const never_t&, const always_t<I>&)+ friend constexpr bool operator==(const never_t&, const always_t<I>&) { return false; } - friend ASIO_CONSTEXPR bool operator!=(- const never_t&, const always_t<I>&)+ friend constexpr bool operator!=(const never_t&, const always_t<I>&) { return true; }@@ -1030,11 +892,7 @@ typedef detail::blocking_t<> blocking_t; -#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+ASIO_INLINE_VARIABLE constexpr blocking_t blocking; } // namespace execution @@ -1042,81 +900,25 @@ template <typename T> struct is_applicable_property<T, execution::blocking_t>- : 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)- >+ : integral_constant<bool, execution::is_executor<T>::value> { }; template <typename T> struct is_applicable_property<T, execution::blocking_t::possibly_t>- : 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)- >+ : integral_constant<bool, execution::is_executor<T>::value> { }; template <typename T> struct is_applicable_property<T, execution::blocking_t::always_t>- : 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)- >+ : integral_constant<bool, execution::is_executor<T>::value> { }; template <typename T> struct is_applicable_property<T, execution::blocking_t::never_t>- : 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)- >+ : integral_constant<bool, execution::is_executor<T>::value> { }; @@ -1128,42 +930,42 @@ template <typename T> struct query_free_default<T, execution::blocking_t,- typename enable_if<+ enable_if_t< can_query<T, execution::blocking_t::possibly_t>::value- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept =- (is_nothrow_query<T, execution::blocking_t::possibly_t>::value));+ static constexpr bool is_valid = true;+ 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,- typename enable_if<+ enable_if_t< !can_query<T, execution::blocking_t::possibly_t>::value && can_query<T, execution::blocking_t::always_t>::value- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept =- (is_nothrow_query<T, execution::blocking_t::always_t>::value));+ static constexpr bool is_valid = true;+ 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,- typename enable_if<+ enable_if_t< !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>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept =- (is_nothrow_query<T, execution::blocking_t::never_t>::value));+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept =+ is_nothrow_query<T, execution::blocking_t::never_t>::value; typedef execution::blocking_t result_type; };@@ -1175,18 +977,18 @@ template <typename T> struct static_query<T, execution::blocking_t,- typename enable_if<+ enable_if_t< execution::detail::blocking_t<0>:: query_static_constexpr_member<T>::is_valid- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef typename execution::detail::blocking_t<0>:: query_static_constexpr_member<T>::result_type result_type; - static ASIO_CONSTEXPR result_type value()+ static constexpr result_type value() { return execution::blocking_t::query_static_constexpr_member<T>::value(); }@@ -1194,21 +996,21 @@ template <typename T> struct static_query<T, execution::blocking_t,- typename enable_if<+ enable_if_t< !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>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef typename traits::static_query<T, execution::blocking_t::possibly_t>::result_type result_type; - static ASIO_CONSTEXPR result_type value()+ static constexpr result_type value() { return traits::static_query<T, execution::blocking_t::possibly_t>::value(); }@@ -1216,22 +1018,22 @@ template <typename T> struct static_query<T, execution::blocking_t,- typename enable_if<+ enable_if_t< !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>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef typename traits::static_query<T, execution::blocking_t::always_t>::result_type result_type; - static ASIO_CONSTEXPR result_type value()+ static constexpr result_type value() { return traits::static_query<T, execution::blocking_t::always_t>::value(); }@@ -1239,7 +1041,7 @@ template <typename T> struct static_query<T, execution::blocking_t,- typename enable_if<+ enable_if_t< !execution::detail::blocking_t<0>:: query_static_constexpr_member<T>::is_valid && !execution::detail::blocking_t<0>::@@ -1247,15 +1049,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>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef typename traits::static_query<T, execution::blocking_t::never_t>::result_type result_type; - static ASIO_CONSTEXPR result_type value()+ static constexpr result_type value() { return traits::static_query<T, execution::blocking_t::never_t>::value(); }@@ -1263,18 +1065,18 @@ template <typename T> struct static_query<T, execution::blocking_t::possibly_t,- typename enable_if<+ enable_if_t< execution::detail::blocking::possibly_t<0>:: query_static_constexpr_member<T>::is_valid- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef typename execution::detail::blocking::possibly_t<0>:: query_static_constexpr_member<T>::result_type result_type; - static ASIO_CONSTEXPR result_type value()+ static constexpr result_type value() { return execution::detail::blocking::possibly_t<0>:: query_static_constexpr_member<T>::value();@@ -1283,7 +1085,7 @@ template <typename T> struct static_query<T, execution::blocking_t::possibly_t,- typename enable_if<+ enable_if_t< !execution::detail::blocking::possibly_t<0>:: query_static_constexpr_member<T>::is_valid && !execution::detail::blocking::possibly_t<0>::@@ -1291,14 +1093,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>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef execution::blocking_t::possibly_t result_type; - static ASIO_CONSTEXPR result_type value()+ static constexpr result_type value() { return result_type(); }@@ -1306,18 +1108,18 @@ template <typename T> struct static_query<T, execution::blocking_t::always_t,- typename enable_if<+ enable_if_t< execution::detail::blocking::always_t<0>:: query_static_constexpr_member<T>::is_valid- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef typename execution::detail::blocking::always_t<0>:: query_static_constexpr_member<T>::result_type result_type; - static ASIO_CONSTEXPR result_type value()+ static constexpr result_type value() { return execution::detail::blocking::always_t<0>:: query_static_constexpr_member<T>::value();@@ -1326,18 +1128,18 @@ template <typename T> struct static_query<T, execution::blocking_t::never_t,- typename enable_if<+ enable_if_t< execution::detail::blocking::never_t<0>:: query_static_constexpr_member<T>::is_valid- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef typename execution::detail::blocking::never_t<0>:: query_static_constexpr_member<T>::result_type result_type; - static ASIO_CONSTEXPR result_type value()+ static constexpr result_type value() { return execution::detail::blocking::never_t<0>:: query_static_constexpr_member<T>::value();@@ -1347,61 +1149,21 @@ #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,- typename enable_if<- is_same<T, typename decay<T>::type>::value+ enable_if_t<+ is_same<T, decay_t<T>>::value && execution::is_executor<T>::value && traits::static_require< const T&, execution::detail::blocking_adaptation::allowed_t<0> >::is_valid- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = false; typedef execution::detail::blocking::adapter<T> result_type; }; @@ -1411,10 +1173,10 @@ template <typename Executor> struct equality_comparable<- execution::detail::blocking::adapter<Executor> >+ execution::detail::blocking::adapter<Executor>> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; }; #endif // !defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)@@ -1425,8 +1187,8 @@ struct execute_member< execution::detail::blocking::adapter<Executor>, Function> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = false; typedef void result_type; }; @@ -1437,13 +1199,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>> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef execution::blocking_t::always_t result_type; - static ASIO_CONSTEXPR result_type value() ASIO_NOEXCEPT+ static constexpr result_type value() noexcept { return result_type(); }@@ -1452,13 +1214,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>> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef execution::blocking_t::always_t result_type; - static ASIO_CONSTEXPR result_type value() ASIO_NOEXCEPT+ static constexpr result_type value() noexcept { return result_type(); }@@ -1467,13 +1229,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>> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef execution::blocking_t::always_t result_type; - static ASIO_CONSTEXPR result_type value() ASIO_NOEXCEPT+ static constexpr result_type value() noexcept { return result_type(); }@@ -1482,13 +1244,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>> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef execution::blocking_t::always_t result_type; - static ASIO_CONSTEXPR result_type value() ASIO_NOEXCEPT+ static constexpr result_type value() noexcept { return result_type(); }@@ -1501,14 +1263,14 @@ template <typename Executor, typename Property> struct query_member< execution::detail::blocking::adapter<Executor>, Property,- typename enable_if<+ enable_if_t< can_query<const Executor&, Property>::value- >::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;+ 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; }; #endif // !defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)@@ -1519,53 +1281,52 @@ struct require_member< execution::detail::blocking::adapter<Executor>, execution::detail::blocking::possibly_t<I>,- typename enable_if<+ enable_if_t< can_require< const Executor&, execution::detail::blocking::possibly_t<I> >::value- >::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;+ 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; }; template <typename Executor, int I> struct require_member< execution::detail::blocking::adapter<Executor>, execution::detail::blocking::never_t<I>,- typename enable_if<+ enable_if_t< can_require< const Executor&, execution::detail::blocking::never_t<I> >::value- >::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;+ 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; }; template <typename Executor, typename Property> struct require_member< execution::detail::blocking::adapter<Executor>, Property,- typename enable_if<+ enable_if_t< can_require<const Executor&, Property>::value- >::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;+ 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; }; #endif // !defined(ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)@@ -1575,16 +1336,15 @@ template <typename Executor, typename Property> struct prefer_member< execution::detail::blocking::adapter<Executor>, Property,- typename enable_if<+ enable_if_t< can_prefer<const Executor&, Property>::value- >::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;+ 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; }; #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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -19,10 +19,7 @@ #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"@@ -47,11 +44,9 @@ /// allowed in order to apply the blocking_adaptation_t::allowed_t property. struct blocking_adaptation_t {- /// The blocking_adaptation_t property applies to executors, senders, and- /// schedulers.+ /// The blocking_adaptation_t property applies to executors. template <typename T>- static constexpr bool is_applicable_property_v =- is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;+ static constexpr bool is_applicable_property_v = is_executor_v<T>; /// The top-level blocking_adaptation_t property cannot be required. static constexpr bool is_requirable = false;@@ -65,11 +60,9 @@ /// A sub-property that indicates that automatic adaptation is not allowed. struct disallowed_t {- /// The blocking_adaptation_t::disallowed_t property applies to executors,- /// senders, and schedulers.+ /// The blocking_adaptation_t::disallowed_t property applies to executors. template <typename T>- static constexpr bool is_applicable_property_v =- is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;+ static constexpr bool is_applicable_property_v = is_executor_v<T>; /// The blocking_adaptation_t::disallowed_t property can be required. static constexpr bool is_requirable = true;@@ -93,11 +86,9 @@ /// A sub-property that indicates that automatic adaptation is allowed. struct allowed_t {- /// The blocking_adaptation_t::allowed_t property applies to executors,- /// senders, and schedulers.+ /// The blocking_adaptation_t::allowed_t property applies to executors. template <typename T>- static constexpr bool is_applicable_property_v =- is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;+ static constexpr bool is_applicable_property_v = is_executor_v<T>; /// The blocking_adaptation_t::allowed_t property can be required. static constexpr bool is_requirable = true;@@ -164,48 +155,28 @@ struct blocking_adaptation_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)+ static constexpr bool is_applicable_property_v = is_executor<T>::value; #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) - ASIO_STATIC_CONSTEXPR(bool, is_requirable = false);- ASIO_STATIC_CONSTEXPR(bool, is_preferable = false);+ static constexpr bool is_requirable = false;+ 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; - ASIO_CONSTEXPR blocking_adaptation_t()+ constexpr blocking_adaptation_t() : value_(-1) { } - ASIO_CONSTEXPR blocking_adaptation_t(disallowed_t)+ constexpr blocking_adaptation_t(disallowed_t) : value_(0) { } - ASIO_CONSTEXPR blocking_adaptation_t(allowed_t)+ constexpr blocking_adaptation_t(allowed_t) : value_(1) { }@@ -217,16 +188,14 @@ struct type { template <typename P>- auto query(ASIO_MOVE_ARG(P) p) const+ auto query(P&& p) const noexcept( noexcept(- declval<typename conditional<true, T, P>::type>().query(- ASIO_MOVE_CAST(P)(p))+ declval<conditional_t<true, T, P>>().query(static_cast<P&&>(p)) ) ) -> decltype(- declval<typename conditional<true, T, P>::type>().query(- ASIO_MOVE_CAST(P)(p))+ declval<conditional_t<true, T, P>>().query(static_cast<P&&>(p)) ); }; #else // defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)@@ -241,17 +210,17 @@ struct type { template <typename P>- static constexpr auto query(ASIO_MOVE_ARG(P) p)+ static constexpr auto query(P&& p) noexcept( noexcept(- conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p))+ conditional_t<true, T, P>::query(static_cast<P&&>(p)) ) ) -> decltype(- conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p))+ conditional_t<true, T, P>::query(static_cast<P&&>(p)) ) {- return T::query(ASIO_MOVE_CAST(P)(p));+ return T::query(static_cast<P&&>(p)); } }; #else // defined(ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)@@ -271,66 +240,64 @@ #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 constexpr typename query_static_constexpr_member<T>::result_type static_query()- ASIO_NOEXCEPT_IF((- query_static_constexpr_member<T>::is_noexcept))+ noexcept(query_static_constexpr_member<T>::is_noexcept) { return query_static_constexpr_member<T>::value(); } template <typename T>- static ASIO_CONSTEXPR+ static constexpr typename traits::static_query<T, disallowed_t>::result_type static_query(- typename enable_if<+ enable_if_t< !query_static_constexpr_member<T>::is_valid- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< !query_member<T>::is_valid- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< traits::static_query<T, disallowed_t>::is_valid- >::type* = 0) ASIO_NOEXCEPT+ >* = 0) noexcept { return traits::static_query<T, disallowed_t>::value(); } template <typename T>- static ASIO_CONSTEXPR+ static constexpr typename traits::static_query<T, allowed_t>::result_type static_query(- typename enable_if<+ enable_if_t< !query_static_constexpr_member<T>::is_valid- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< !query_member<T>::is_valid- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< !traits::static_query<T, disallowed_t>::is_valid- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< traits::static_query<T, allowed_t>::is_valid- >::type* = 0) ASIO_NOEXCEPT+ >* = 0) noexcept { return traits::static_query<T, allowed_t>::value(); } template <typename E, typename T = decltype(blocking_adaptation_t::static_query<E>())>- static ASIO_CONSTEXPR const T static_query_v+ static 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 ASIO_CONSTEXPR bool operator==(+ friend constexpr bool operator==( const blocking_adaptation_t& a, const blocking_adaptation_t& b) { return a.value_ == b.value_; } - friend ASIO_CONSTEXPR bool operator!=(+ friend constexpr bool operator!=( const blocking_adaptation_t& a, const blocking_adaptation_t& b) { return a.value_ != b.value_;@@ -338,26 +305,24 @@ struct convertible_from_blocking_adaptation_t {- ASIO_CONSTEXPR convertible_from_blocking_adaptation_t(+ constexpr convertible_from_blocking_adaptation_t( blocking_adaptation_t) { } }; template <typename Executor>- friend ASIO_CONSTEXPR blocking_adaptation_t query(+ friend constexpr blocking_adaptation_t query( const Executor& ex, convertible_from_blocking_adaptation_t,- typename enable_if<+ enable_if_t< can_query<const Executor&, disallowed_t>::value- >::type* = 0)+ >* = 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&,- blocking_adaptation_t<>::disallowed_t>::value))+ noexcept(is_nothrow_query<const Executor&,+ blocking_adaptation_t<>::disallowed_t>::value) #else // defined(ASIO_MSVC)- ASIO_NOEXCEPT_IF((- is_nothrow_query<const Executor&, disallowed_t>::value))+ noexcept(is_nothrow_query<const Executor&, disallowed_t>::value) #endif // defined(ASIO_MSVC) #endif // !defined(__clang__) {@@ -365,22 +330,20 @@ } template <typename Executor>- friend ASIO_CONSTEXPR blocking_adaptation_t query(+ friend constexpr blocking_adaptation_t query( const Executor& ex, convertible_from_blocking_adaptation_t,- typename enable_if<+ enable_if_t< !can_query<const Executor&, disallowed_t>::value- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< can_query<const Executor&, allowed_t>::value- >::type* = 0)+ >* = 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&,- blocking_adaptation_t<>::allowed_t>::value))+ noexcept(is_nothrow_query<const Executor&,+ blocking_adaptation_t<>::allowed_t>::value) #else // defined(ASIO_MSVC)- ASIO_NOEXCEPT_IF((- is_nothrow_query<const Executor&, allowed_t>::value))+ noexcept(is_nothrow_query<const Executor&, allowed_t>::value) #endif // defined(ASIO_MSVC) #endif // !defined(__clang__) {@@ -390,10 +353,6 @@ 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_; };@@ -405,12 +364,7 @@ #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; @@ -424,35 +378,15 @@ struct disallowed_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)+ static constexpr bool is_applicable_property_v = is_executor<T>::value; #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) - ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);- ASIO_STATIC_CONSTEXPR(bool, is_preferable = true);+ static constexpr bool is_requirable = true;+ static constexpr bool is_preferable = true; typedef blocking_adaptation_t<I> polymorphic_query_result_type; - ASIO_CONSTEXPR disallowed_t()+ constexpr disallowed_t() { } @@ -471,55 +405,62 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T>- static ASIO_CONSTEXPR+ static constexpr typename query_static_constexpr_member<T>::result_type static_query()- ASIO_NOEXCEPT_IF((- query_static_constexpr_member<T>::is_noexcept))+ noexcept(query_static_constexpr_member<T>::is_noexcept) { return query_static_constexpr_member<T>::value(); } template <typename T>- static ASIO_CONSTEXPR disallowed_t static_query(- typename enable_if<+ static constexpr disallowed_t static_query(+ enable_if_t< !query_static_constexpr_member<T>::is_valid- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< !query_member<T>::is_valid- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< !traits::query_free<T, disallowed_t>::is_valid- >::type* = 0,- typename enable_if<- !can_query<T, allowed_t<I> >::value- >::type* = 0) ASIO_NOEXCEPT+ >* = 0,+ enable_if_t<+ !can_query<T, allowed_t<I>>::value+ >* = 0) noexcept { return disallowed_t(); } template <typename E, typename T = decltype(disallowed_t::static_query<E>())>- static ASIO_CONSTEXPR const T static_query_v+ static 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 ASIO_CONSTEXPR blocking_adaptation_t<I> value()+ static constexpr blocking_adaptation_t<I> value() { return disallowed_t(); } - friend ASIO_CONSTEXPR bool operator==(- const disallowed_t&, const disallowed_t&)+ friend constexpr bool operator==(const disallowed_t&, const disallowed_t&) { return true; } - friend ASIO_CONSTEXPR bool operator!=(- const disallowed_t&, const disallowed_t&)+ friend constexpr bool operator!=(const disallowed_t&, const disallowed_t&) { return false; }++ friend constexpr bool operator==(const disallowed_t&, const allowed_t<I>&)+ {+ return false;+ }++ friend constexpr bool operator!=(const disallowed_t&, const allowed_t<I>&)+ {+ return true;+ } }; #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \@@ -529,117 +470,134 @@ #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) ASIO_NOEXCEPT+ adapter(int, const Executor& e) noexcept : executor_(e) { } - adapter(const adapter& other) ASIO_NOEXCEPT+ adapter(const adapter& other) noexcept : executor_(other.executor_) { } -#if defined(ASIO_HAS_MOVE)- adapter(adapter&& other) ASIO_NOEXCEPT- : executor_(ASIO_MOVE_CAST(Executor)(other.executor_))+ adapter(adapter&& other) noexcept+ : executor_(static_cast<Executor&&>(other.executor_)) { }-#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) template <int I>- static ASIO_CONSTEXPR allowed_t<I> query(- blocking_adaptation_t<I>) ASIO_NOEXCEPT+ static constexpr allowed_t<I> query(blocking_adaptation_t<I>) noexcept { return allowed_t<I>(); } template <int I>- static ASIO_CONSTEXPR allowed_t<I> query(- allowed_t<I>) ASIO_NOEXCEPT+ static constexpr allowed_t<I> query(allowed_t<I>) noexcept { return allowed_t<I>(); } template <int I>- static ASIO_CONSTEXPR allowed_t<I> query(- disallowed_t<I>) ASIO_NOEXCEPT+ static constexpr allowed_t<I> query(disallowed_t<I>) noexcept { return allowed_t<I>(); } template <typename Property>- 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))+ 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) { return asio::query(executor_, p); } template <int I>- Executor require(disallowed_t<I>) const ASIO_NOEXCEPT+ Executor require(disallowed_t<I>) const noexcept { return executor_; } template <typename Property>- 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))+ 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) {- return adapter<typename decay<- typename require_result<const Executor&, Property>::type- >::type>(0, asio::require(executor_, p));+ return adapter<decay_t<require_result_t<const Executor&, Property>>>(+ 0, asio::require(executor_, p)); } template <typename Property>- 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))+ 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) {- return adapter<typename decay<- typename prefer_result<const Executor&, Property>::type- >::type>(0, asio::prefer(executor_, p));+ return adapter<decay_t<prefer_result_t<const Executor&, Property>>>(+ 0, asio::prefer(executor_, p)); } template <typename Function>- typename enable_if<-#if defined(ASIO_NO_DEPRECATED)+ enable_if_t< 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 execute(ASIO_MOVE_ARG(Function) f) const+ > execute(Function&& f) const {-#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)+ executor_.execute(static_cast<Function&&>(f)); } - friend bool operator==(const adapter& a, const adapter& b) ASIO_NOEXCEPT+ friend bool operator==(const adapter& a, const adapter& b) noexcept { return a.executor_ == b.executor_; } - friend bool operator!=(const adapter& a, const adapter& b) ASIO_NOEXCEPT+ friend bool operator!=(const adapter& a, const adapter& b) noexcept { return a.executor_ != b.executor_; }@@ -652,35 +610,15 @@ struct allowed_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)+ static constexpr bool is_applicable_property_v = is_executor<T>::value; #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) - ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);- ASIO_STATIC_CONSTEXPR(bool, is_preferable = false);+ static constexpr bool is_requirable = true;+ static constexpr bool is_preferable = false; typedef blocking_adaptation_t<I> polymorphic_query_result_type; - ASIO_CONSTEXPR allowed_t()+ constexpr allowed_t() { } @@ -699,44 +637,49 @@ #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 constexpr typename query_static_constexpr_member<T>::result_type static_query()- ASIO_NOEXCEPT_IF((- query_static_constexpr_member<T>::is_noexcept))+ noexcept(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 ASIO_CONSTEXPR const T static_query_v- = allowed_t::static_query<E>();+ static 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 ASIO_CONSTEXPR blocking_adaptation_t<I> value()+ static constexpr blocking_adaptation_t<I> value() { return allowed_t(); } - friend ASIO_CONSTEXPR bool operator==(- const allowed_t&, const allowed_t&)+ friend constexpr bool operator==(const allowed_t&, const allowed_t&) { return true; } - friend ASIO_CONSTEXPR bool operator!=(- const allowed_t&, const allowed_t&)+ friend constexpr bool operator!=(const allowed_t&, const allowed_t&) { return false; } + friend constexpr bool operator==(const allowed_t&, const disallowed_t<I>&)+ {+ 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&,- typename enable_if<+ enable_if_t< is_executor<Executor>::value- >::type* = 0)+ >* = 0) { return adapter<Executor>(0, e); }@@ -754,21 +697,17 @@ { public: template <typename F>- blocking_execute_state(ASIO_MOVE_ARG(F) f)- : func_(ASIO_MOVE_CAST(F)(f)),+ blocking_execute_state(F&& f)+ : func_(static_cast<F&&>(f)), is_complete_(false) { } template <typename Executor>- void execute_and_wait(ASIO_MOVE_ARG(Executor) ex)+ void execute_and_wait(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);@@ -805,11 +744,11 @@ template <typename Executor, typename Function> void blocking_execute(- ASIO_MOVE_ARG(Executor) ex,- ASIO_MOVE_ARG(Function) func)+ Executor&& ex,+ Function&& func) {- typedef typename decay<Function>::type func_t;- blocking_execute_state<func_t> state(ASIO_MOVE_CAST(Function)(func));+ typedef decay_t<Function> func_t;+ blocking_execute_state<func_t> state(static_cast<Function&&>(func)); state.execute_and_wait(ex); } @@ -818,12 +757,7 @@ typedef detail::blocking_adaptation_t<> blocking_adaptation_t; -#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+ASIO_INLINE_VARIABLE constexpr blocking_adaptation_t blocking_adaptation; } // namespace execution @@ -831,61 +765,19 @@ template <typename T> struct is_applicable_property<T, execution::blocking_adaptation_t>- : 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)- >+ : integral_constant<bool, execution::is_executor<T>::value> { }; template <typename T> struct is_applicable_property<T, execution::blocking_adaptation_t::disallowed_t>- : 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)- >+ : integral_constant<bool, execution::is_executor<T>::value> { }; template <typename T> struct is_applicable_property<T, execution::blocking_adaptation_t::allowed_t>- : 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)- >+ : integral_constant<bool, execution::is_executor<T>::value> { }; @@ -897,27 +789,27 @@ template <typename T> struct query_free_default<T, execution::blocking_adaptation_t,- typename enable_if<+ enable_if_t< can_query<T, execution::blocking_adaptation_t::disallowed_t>::value- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = (is_nothrow_query<T,- execution::blocking_adaptation_t::disallowed_t>::value));+ static constexpr bool is_valid = true;+ 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,- typename enable_if<+ enable_if_t< !can_query<T, execution::blocking_adaptation_t::disallowed_t>::value && can_query<T, execution::blocking_adaptation_t::allowed_t>::value- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept =- (is_nothrow_query<T, execution::blocking_adaptation_t::allowed_t>::value));+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept =+ is_nothrow_query<T, execution::blocking_adaptation_t::allowed_t>::value; typedef execution::blocking_adaptation_t result_type; };@@ -929,18 +821,18 @@ template <typename T> struct static_query<T, execution::blocking_adaptation_t,- typename enable_if<+ enable_if_t< execution::detail::blocking_adaptation_t<0>:: query_static_constexpr_member<T>::is_valid- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef typename execution::detail::blocking_adaptation_t<0>:: query_static_constexpr_member<T>::result_type result_type; - static ASIO_CONSTEXPR result_type value()+ static constexpr result_type value() { return execution::detail::blocking_adaptation_t<0>:: query_static_constexpr_member<T>::value();@@ -949,22 +841,22 @@ template <typename T> struct static_query<T, execution::blocking_adaptation_t,- typename enable_if<+ enable_if_t< !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>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef typename traits::static_query<T, execution::blocking_adaptation_t::disallowed_t>::result_type result_type; - static ASIO_CONSTEXPR result_type value()+ static constexpr result_type value() { return traits::static_query<T, execution::blocking_adaptation_t::disallowed_t>::value();@@ -973,7 +865,7 @@ template <typename T> struct static_query<T, execution::blocking_adaptation_t,- typename enable_if<+ enable_if_t< !execution::detail::blocking_adaptation_t<0>:: query_static_constexpr_member<T>::is_valid && !execution::detail::blocking_adaptation_t<0>::@@ -982,15 +874,15 @@ execution::blocking_adaptation_t::disallowed_t>::is_valid && traits::static_query<T, execution::blocking_adaptation_t::allowed_t>::is_valid- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef typename traits::static_query<T, execution::blocking_adaptation_t::allowed_t>::result_type result_type; - static ASIO_CONSTEXPR result_type value()+ static constexpr result_type value() { return traits::static_query<T, execution::blocking_adaptation_t::allowed_t>::value();@@ -999,18 +891,18 @@ template <typename T> struct static_query<T, execution::blocking_adaptation_t::disallowed_t,- typename enable_if<+ enable_if_t< execution::detail::blocking_adaptation::disallowed_t<0>:: query_static_constexpr_member<T>::is_valid- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ 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 ASIO_CONSTEXPR result_type value()+ static constexpr result_type value() { return execution::detail::blocking_adaptation::disallowed_t<0>:: query_static_constexpr_member<T>::value();@@ -1019,7 +911,7 @@ template <typename T> struct static_query<T, execution::blocking_adaptation_t::disallowed_t,- typename enable_if<+ enable_if_t< !execution::detail::blocking_adaptation::disallowed_t<0>:: query_static_constexpr_member<T>::is_valid && !execution::detail::blocking_adaptation::disallowed_t<0>::@@ -1027,14 +919,14 @@ && !traits::query_free<T, execution::blocking_adaptation_t::disallowed_t>::is_valid && !can_query<T, execution::blocking_adaptation_t::allowed_t>::value- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef execution::blocking_adaptation_t::disallowed_t result_type; - static ASIO_CONSTEXPR result_type value()+ static constexpr result_type value() { return result_type(); }@@ -1042,18 +934,18 @@ template <typename T> struct static_query<T, execution::blocking_adaptation_t::allowed_t,- typename enable_if<+ enable_if_t< execution::detail::blocking_adaptation::allowed_t<0>:: query_static_constexpr_member<T>::is_valid- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ 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 ASIO_CONSTEXPR result_type value()+ static constexpr result_type value() { return execution::detail::blocking_adaptation::allowed_t<0>:: query_static_constexpr_member<T>::value();@@ -1063,45 +955,17 @@ #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,- typename enable_if<- is_same<T, typename decay<T>::type>::value+ enable_if_t<+ is_same<T, decay_t<T>>::value && execution::is_executor<T>::value- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = false; typedef execution::detail::blocking_adaptation::adapter<T> result_type; }; @@ -1111,10 +975,10 @@ template <typename Executor> struct equality_comparable<- execution::detail::blocking_adaptation::adapter<Executor> >+ execution::detail::blocking_adaptation::adapter<Executor>> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; }; #endif // !defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)@@ -1125,8 +989,8 @@ struct execute_member< execution::detail::blocking_adaptation::adapter<Executor>, Function> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = false; typedef void result_type; }; @@ -1137,13 +1001,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>> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef execution::blocking_adaptation_t::allowed_t result_type; - static ASIO_CONSTEXPR result_type value() ASIO_NOEXCEPT+ static constexpr result_type value() noexcept { return result_type(); }@@ -1152,13 +1016,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>> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef execution::blocking_adaptation_t::allowed_t result_type; - static ASIO_CONSTEXPR result_type value() ASIO_NOEXCEPT+ static constexpr result_type value() noexcept { return result_type(); }@@ -1167,13 +1031,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>> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef execution::blocking_adaptation_t::allowed_t result_type; - static ASIO_CONSTEXPR result_type value() ASIO_NOEXCEPT+ static constexpr result_type value() noexcept { return result_type(); }@@ -1186,14 +1050,14 @@ template <typename Executor, typename Property> struct query_member< execution::detail::blocking_adaptation::adapter<Executor>, Property,- typename enable_if<+ enable_if_t< can_query<const Executor&, Property>::value- >::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;+ 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; }; #endif // !defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)@@ -1203,26 +1067,25 @@ 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>> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ 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,- typename enable_if<+ enable_if_t< can_require<const Executor&, Property>::value- >::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;+ 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; }; #endif // !defined(ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)@@ -1232,16 +1095,15 @@ template <typename Executor, typename Property> struct prefer_member< execution::detail::blocking_adaptation::adapter<Executor>, Property,- typename enable_if<+ enable_if_t< can_prefer<const Executor&, Property>::value- >::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;+ 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; }; #endif // !defined(ASIO_HAS_DEDUCED_PREFER_MEMBER_TRAIT)
− link/modules/asio-standalone/asio/include/asio/execution/bulk_execute.hpp
@@ -1,402 +0,0 @@-//-// 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
@@ -1,1252 +0,0 @@-//-// 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
@@ -1,494 +0,0 @@-//-// 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -18,8 +18,6 @@ #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"@@ -40,10 +38,9 @@ /// with an executor. struct context_t {- /// The context_t property applies to executors, senders, and schedulers.+ /// The context_t property applies to executors. template <typename T>- static constexpr bool is_applicable_property_v =- is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;+ static constexpr bool is_applicable_property_v = is_executor_v<T>; /// The context_t property cannot be required. static constexpr bool is_requirable = false;@@ -69,38 +66,18 @@ struct context_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)+ static constexpr bool is_applicable_property_v = is_executor<T>::value; #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) - ASIO_STATIC_CONSTEXPR(bool, is_requirable = false);- ASIO_STATIC_CONSTEXPR(bool, is_preferable = false);+ static constexpr bool is_requirable = false;+ 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) - ASIO_CONSTEXPR context_t()+ constexpr context_t() { } @@ -111,17 +88,17 @@ struct type { template <typename P>- static constexpr auto query(ASIO_MOVE_ARG(P) p)+ static constexpr auto query(P&& p) noexcept( noexcept(- conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p))+ conditional_t<true, T, P>::query(static_cast<P&&>(p)) ) ) -> decltype(- conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p))+ conditional_t<true, T, P>::query(static_cast<P&&>(p)) ) {- return T::query(ASIO_MOVE_CAST(P)(p));+ return T::query(static_cast<P&&>(p)); } }; #else // defined(ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)@@ -137,24 +114,17 @@ #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 constexpr typename query_static_constexpr_member<T>::result_type static_query()- ASIO_NOEXCEPT_IF((- query_static_constexpr_member<T>::is_noexcept))+ noexcept(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 ASIO_CONSTEXPR const T static_query_v- = context_t::static_query<E>();+ static 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) \@@ -164,20 +134,11 @@ #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; -#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+ASIO_INLINE_VARIABLE constexpr context_t context; } // namespace execution @@ -185,21 +146,7 @@ template <typename T> struct is_applicable_property<T, execution::context_t>- : 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)- >+ : integral_constant<bool, execution::is_executor<T>::value> { }; @@ -212,18 +159,18 @@ template <typename T> struct static_query<T, execution::context_t,- typename enable_if<+ enable_if_t< execution::detail::context_t<0>:: query_static_constexpr_member<T>::is_valid- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef typename execution::detail::context_t<0>:: query_static_constexpr_member<T>::result_type result_type; - static ASIO_CONSTEXPR result_type value()+ static 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -19,8 +19,6 @@ #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"@@ -39,10 +37,9 @@ template <typename U> struct context_as_t {- /// The context_as_t property applies to executors, senders, and schedulers.+ /// The context_as_t property applies to executors. template <typename T>- static constexpr bool is_applicable_property_v =- is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;+ static constexpr bool is_applicable_property_v = is_executor_v<T>; /// The context_t property cannot be required. static constexpr bool is_requirable = false;@@ -68,77 +65,54 @@ struct context_as_t { #if defined(ASIO_HAS_VARIABLE_TEMPLATES)-# if defined(ASIO_NO_DEPRECATED) template <typename U>- 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)+ static constexpr bool is_applicable_property_v = is_executor<U>::value; #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) - ASIO_STATIC_CONSTEXPR(bool, is_requirable = false);- ASIO_STATIC_CONSTEXPR(bool, is_preferable = false);+ static constexpr bool is_requirable = false;+ static constexpr bool is_preferable = false; typedef T polymorphic_query_result_type; - ASIO_CONSTEXPR context_as_t()+ constexpr context_as_t() { } - ASIO_CONSTEXPR context_as_t(context_t)+ constexpr context_as_t(context_t) { } #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename E>- static ASIO_CONSTEXPR+ static constexpr typename context_t::query_static_constexpr_member<E>::result_type static_query()- ASIO_NOEXCEPT_IF((- context_t::query_static_constexpr_member<E>::is_noexcept))+ noexcept(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 ASIO_CONSTEXPR const U static_query_v+ static 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 ASIO_CONSTEXPR U query(+ friend constexpr U query( const Executor& ex, const context_as_t<U>&,- typename enable_if<+ enable_if_t< is_same<T, U>::value- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< can_query<const Executor&, const context_t&>::value- >::type* = 0)+ >* = 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&, const context_t&>::value))+ noexcept(is_nothrow_query<const Executor&, const context_t&>::value) #else // defined(ASIO_MSVC)- ASIO_NOEXCEPT_IF((- is_nothrow_query<const Executor&, const context_t&>::value))+ noexcept(is_nothrow_query<const Executor&, const context_t&>::value) #endif // defined(ASIO_MSVC) #endif // !defined(__clang__) {@@ -153,13 +127,11 @@ #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) -#if (defined(ASIO_HAS_VARIABLE_TEMPLATES) \- && defined(ASIO_HAS_CONSTEXPR)) \+#if defined(ASIO_HAS_VARIABLE_TEMPLATES) \ || defined(GENERATING_DOCUMENTATION) template <typename T> constexpr context_as_t<T> context_as{};-#endif // (defined(ASIO_HAS_VARIABLE_TEMPLATES)- // && defined(ASIO_HAS_CONSTEXPR))+#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) // || defined(GENERATING_DOCUMENTATION) } // namespace execution@@ -167,22 +139,8 @@ #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-#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)- >+struct is_applicable_property<T, execution::context_as_t<U>>+ : integral_constant<bool, execution::is_executor<T>::value> { }; @@ -195,9 +153,9 @@ template <typename T, typename U> struct static_query<T, execution::context_as_t<U>,- typename enable_if<+ enable_if_t< static_query<T, execution::context_t>::is_valid- >::type> : static_query<T, execution::context_t>+ >> : static_query<T, execution::context_t> { }; @@ -208,13 +166,13 @@ template <typename T, typename U> struct query_free<T, execution::context_as_t<U>,- typename enable_if<- can_query<const T&, const execution::context_t&>::value- >::type>+ enable_if_t<+ can_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));+ static constexpr bool is_valid = true;+ 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
@@ -1,152 +0,0 @@-//-// 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
@@ -1,109 +0,0 @@-//-// 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
@@ -1,128 +0,0 @@-//-// 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
@@ -1,261 +0,0 @@-//-// 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
@@ -1,233 +0,0 @@-//-// 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
@@ -1,90 +0,0 @@-//-// 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
@@ -1,290 +0,0 @@-//-// 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -21,16 +21,10 @@ #include "asio/traits/equality_comparable.hpp" #include "asio/traits/execute_member.hpp" -#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) \+#if 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_FREE_TRAIT)- // && defined(ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)+#endif // defined(ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT) // && defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT) #include "asio/detail/push_options.hpp"@@ -48,78 +42,33 @@ template <typename T, typename F> struct is_executor_of_impl<T, F,-#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<+ 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< is_nothrow_copy_constructible<T>::value- >::type,- typename enable_if<+ >,+ enable_if_t< is_nothrow_destructible<T>::value- >::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<+ >,+ enable_if_t< traits::equality_comparable<T>::is_valid- >::type,- typename enable_if<+ >,+ enable_if_t< traits::equality_comparable<T>::is_noexcept- >::type> : true_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@@ -142,7 +91,7 @@ #if defined(ASIO_HAS_VARIABLE_TEMPLATES) template <typename T>-ASIO_CONSTEXPR const bool is_executor_v = is_executor<T>::value;+constexpr const bool is_executor_v = is_executor<T>::value; #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) @@ -158,101 +107,6 @@ #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 @@ //-// exection/impl/bad_executor.ipp-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+// execution/impl/bad_executor.ipp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -23,11 +23,11 @@ namespace asio { namespace execution { -bad_executor::bad_executor() ASIO_NOEXCEPT+bad_executor::bad_executor() noexcept { } -const char* bad_executor::what() const ASIO_NOEXCEPT_OR_NOTHROW+const char* bad_executor::what() const noexcept { return "bad executor"; }
− link/modules/asio-standalone/asio/include/asio/execution/impl/receiver_invocation_error.ipp
@@ -1,36 +0,0 @@-//-// 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -17,7 +17,6 @@ #include "asio/detail/config.hpp" #include "asio/detail/type_traits.hpp"-#include "asio/detail/variadic_templates.hpp" #include "asio/detail/push_options.hpp" @@ -28,38 +27,11 @@ /// 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()(ASIO_MOVE_ARG(Args)...)- {- }--#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)- // || defined(GENERATING_DOCUMENTATION)-- void operator()()+ void operator()(Args&&...) { }--#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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -18,8 +18,6 @@ #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"@@ -40,10 +38,9 @@ /// of execution agents on to threads of execution. struct mapping_t {- /// The mapping_t property applies to executors, senders, and schedulers.+ /// The mapping_t property applies to executors. template <typename T>- static constexpr bool is_applicable_property_v =- is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;+ static constexpr bool is_applicable_property_v = is_executor_v<T>; /// The top-level mapping_t property cannot be required. static constexpr bool is_requirable = false;@@ -58,11 +55,9 @@ /// threads of execution. struct thread_t {- /// The mapping_t::thread_t property applies to executors, senders, and- /// schedulers.+ /// The mapping_t::thread_t property applies to executors. template <typename T>- static constexpr bool is_applicable_property_v =- is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;+ static constexpr bool is_applicable_property_v = is_executor_v<T>; /// The mapping_t::thread_t property can be required. static constexpr bool is_requirable = true;@@ -87,11 +82,9 @@ /// new threads of execution. struct new_thread_t {- /// The mapping_t::new_thread_t property applies to executors, senders, and- /// schedulers.+ /// The mapping_t::new_thread_t property applies to executors. template <typename T>- static constexpr bool is_applicable_property_v =- is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;+ static constexpr bool is_applicable_property_v = is_executor_v<T>; /// The mapping_t::new_thread_t property can be required. static constexpr bool is_requirable = true;@@ -116,11 +109,9 @@ /// implementation-defined. struct other_t {- /// The mapping_t::other_t property applies to executors, senders, and- /// schedulers.+ /// The mapping_t::other_t property applies to executors. template <typename T>- static constexpr bool is_applicable_property_v =- is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;+ static constexpr bool is_applicable_property_v = is_executor_v<T>; /// The mapping_t::other_t property can be required. static constexpr bool is_requirable = true;@@ -192,54 +183,34 @@ struct mapping_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)+ static constexpr bool is_applicable_property_v = is_executor<T>::value; #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) - ASIO_STATIC_CONSTEXPR(bool, is_requirable = false);- ASIO_STATIC_CONSTEXPR(bool, is_preferable = false);+ static constexpr bool is_requirable = false;+ 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; - ASIO_CONSTEXPR mapping_t()+ constexpr mapping_t() : value_(-1) { } - ASIO_CONSTEXPR mapping_t(thread_t)+ constexpr mapping_t(thread_t) : value_(0) { } - ASIO_CONSTEXPR mapping_t(new_thread_t)+ constexpr mapping_t(new_thread_t) : value_(1) { } - ASIO_CONSTEXPR mapping_t(other_t)+ constexpr mapping_t(other_t) : value_(2) { }@@ -251,16 +222,14 @@ struct type { template <typename P>- auto query(ASIO_MOVE_ARG(P) p) const+ auto query(P&& p) const noexcept( noexcept(- declval<typename conditional<true, T, P>::type>().query(- ASIO_MOVE_CAST(P)(p))+ declval<conditional_t<true, T, P>>().query(static_cast<P&&>(p)) ) ) -> decltype(- declval<typename conditional<true, T, P>::type>().query(- ASIO_MOVE_CAST(P)(p))+ declval<conditional_t<true, T, P>>().query(static_cast<P&&>(p)) ); }; #else // defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)@@ -275,17 +244,17 @@ struct type { template <typename P>- static constexpr auto query(ASIO_MOVE_ARG(P) p)+ static constexpr auto query(P&& p) noexcept( noexcept(- conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p))+ conditional_t<true, T, P>::query(static_cast<P&&>(p)) ) ) -> decltype(- conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p))+ conditional_t<true, T, P>::query(static_cast<P&&>(p)) ) {- return T::query(ASIO_MOVE_CAST(P)(p));+ return T::query(static_cast<P&&>(p)); } }; #else // defined(ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)@@ -305,88 +274,87 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T>- static ASIO_CONSTEXPR+ static constexpr typename query_static_constexpr_member<T>::result_type static_query()- ASIO_NOEXCEPT_IF((- query_static_constexpr_member<T>::is_noexcept))+ noexcept(query_static_constexpr_member<T>::is_noexcept) { return query_static_constexpr_member<T>::value(); } template <typename T>- static ASIO_CONSTEXPR+ static constexpr typename traits::static_query<T, thread_t>::result_type static_query(- typename enable_if<+ enable_if_t< !query_static_constexpr_member<T>::is_valid- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< !query_member<T>::is_valid- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< traits::static_query<T, thread_t>::is_valid- >::type* = 0) ASIO_NOEXCEPT+ >* = 0) noexcept { return traits::static_query<T, thread_t>::value(); } template <typename T>- static ASIO_CONSTEXPR+ static constexpr typename traits::static_query<T, new_thread_t>::result_type static_query(- typename enable_if<+ enable_if_t< !query_static_constexpr_member<T>::is_valid- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< !query_member<T>::is_valid- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< !traits::static_query<T, thread_t>::is_valid- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< traits::static_query<T, new_thread_t>::is_valid- >::type* = 0) ASIO_NOEXCEPT+ >* = 0) noexcept { return traits::static_query<T, new_thread_t>::value(); } template <typename T>- static ASIO_CONSTEXPR+ static constexpr typename traits::static_query<T, other_t>::result_type static_query(- typename enable_if<+ enable_if_t< !query_static_constexpr_member<T>::is_valid- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< !query_member<T>::is_valid- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< !traits::static_query<T, thread_t>::is_valid- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< !traits::static_query<T, new_thread_t>::is_valid- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< traits::static_query<T, other_t>::is_valid- >::type* = 0) ASIO_NOEXCEPT+ >* = 0) noexcept { return traits::static_query<T, other_t>::value(); } template <typename E, typename T = decltype(mapping_t::static_query<E>())>- static ASIO_CONSTEXPR const T static_query_v+ static 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 ASIO_CONSTEXPR bool operator==(+ friend constexpr bool operator==( const mapping_t& a, const mapping_t& b) { return a.value_ == b.value_; } - friend ASIO_CONSTEXPR bool operator!=(+ friend constexpr bool operator!=( const mapping_t& a, const mapping_t& b) { return a.value_ != b.value_;@@ -394,22 +362,20 @@ struct convertible_from_mapping_t {- ASIO_CONSTEXPR convertible_from_mapping_t(mapping_t) {}+ constexpr convertible_from_mapping_t(mapping_t) {} }; template <typename Executor>- friend ASIO_CONSTEXPR mapping_t query(+ friend constexpr mapping_t query( const Executor& ex, convertible_from_mapping_t,- typename enable_if<+ enable_if_t< can_query<const Executor&, thread_t>::value- >::type* = 0)+ >* = 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&, mapping_t<>::thread_t>::value))+ noexcept(is_nothrow_query<const Executor&, mapping_t<>::thread_t>::value) #else // defined(ASIO_MSVC)- ASIO_NOEXCEPT_IF((- is_nothrow_query<const Executor&, thread_t>::value))+ noexcept(is_nothrow_query<const Executor&, thread_t>::value) #endif // defined(ASIO_MSVC) #endif // !defined(__clang__) {@@ -417,21 +383,20 @@ } template <typename Executor>- friend ASIO_CONSTEXPR mapping_t query(+ friend constexpr mapping_t query( const Executor& ex, convertible_from_mapping_t,- typename enable_if<+ enable_if_t< !can_query<const Executor&, thread_t>::value- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< can_query<const Executor&, new_thread_t>::value- >::type* = 0)+ >* = 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&, mapping_t<>::new_thread_t>::value))+ noexcept(+ is_nothrow_query<const Executor&, mapping_t<>::new_thread_t>::value) #else // defined(ASIO_MSVC)- ASIO_NOEXCEPT_IF((- is_nothrow_query<const Executor&, new_thread_t>::value))+ noexcept(is_nothrow_query<const Executor&, new_thread_t>::value) #endif // defined(ASIO_MSVC) #endif // !defined(__clang__) {@@ -439,24 +404,22 @@ } template <typename Executor>- friend ASIO_CONSTEXPR mapping_t query(+ friend constexpr mapping_t query( const Executor& ex, convertible_from_mapping_t,- typename enable_if<+ enable_if_t< !can_query<const Executor&, thread_t>::value- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< !can_query<const Executor&, new_thread_t>::value- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< can_query<const Executor&, other_t>::value- >::type* = 0)+ >* = 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&, mapping_t<>::other_t>::value))+ noexcept(is_nothrow_query<const Executor&, mapping_t<>::other_t>::value) #else // defined(ASIO_MSVC)- ASIO_NOEXCEPT_IF((- is_nothrow_query<const Executor&, other_t>::value))+ noexcept(is_nothrow_query<const Executor&, other_t>::value) #endif // defined(ASIO_MSVC) #endif // !defined(__clang__) {@@ -467,10 +430,6 @@ 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_; };@@ -482,12 +441,7 @@ #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>@@ -502,35 +456,15 @@ struct thread_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)+ static constexpr bool is_applicable_property_v = is_executor<T>::value; #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) - ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);- ASIO_STATIC_CONSTEXPR(bool, is_preferable = true);+ static constexpr bool is_requirable = true;+ static constexpr bool is_preferable = true; typedef mapping_t<I> polymorphic_query_result_type; - ASIO_CONSTEXPR thread_t()+ constexpr thread_t() { } @@ -547,58 +481,75 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T>- static ASIO_CONSTEXPR+ static constexpr typename query_static_constexpr_member<T>::result_type static_query()- ASIO_NOEXCEPT_IF((- query_static_constexpr_member<T>::is_noexcept))+ noexcept(query_static_constexpr_member<T>::is_noexcept) { return query_static_constexpr_member<T>::value(); } template <typename T>- static ASIO_CONSTEXPR thread_t static_query(- typename enable_if<+ static constexpr thread_t static_query(+ enable_if_t< !query_static_constexpr_member<T>::is_valid- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< !query_member<T>::is_valid- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< !traits::query_free<T, thread_t>::is_valid- >::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+ >* = 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 { return thread_t(); } template <typename E, typename T = decltype(thread_t::static_query<E>())>- static ASIO_CONSTEXPR const T static_query_v+ static 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 ASIO_CONSTEXPR mapping_t<I> value()+ static constexpr mapping_t<I> value() { return thread_t(); } - friend ASIO_CONSTEXPR bool operator==(- const thread_t&, const thread_t&)+ friend constexpr bool operator==(const thread_t&, const thread_t&) { return true; } - friend ASIO_CONSTEXPR bool operator!=(- const thread_t&, const thread_t&)+ 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>&)+ {+ return true;+ }++ friend constexpr bool operator==(const thread_t&, const other_t<I>&)+ {+ return false;+ }++ friend constexpr bool operator!=(const thread_t&, const other_t<I>&)+ {+ return true;+ } }; #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \@@ -612,35 +563,15 @@ struct new_thread_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)+ static constexpr bool is_applicable_property_v = is_executor<T>::value; #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) - ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);- ASIO_STATIC_CONSTEXPR(bool, is_preferable = true);+ static constexpr bool is_requirable = true;+ static constexpr bool is_preferable = true; typedef mapping_t<I> polymorphic_query_result_type; - ASIO_CONSTEXPR new_thread_t()+ constexpr new_thread_t() { } @@ -657,37 +588,52 @@ #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 constexpr typename query_static_constexpr_member<T>::result_type static_query()- ASIO_NOEXCEPT_IF((- query_static_constexpr_member<T>::is_noexcept))+ noexcept(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 ASIO_CONSTEXPR const T static_query_v- = new_thread_t::static_query<E>();+ static 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 ASIO_CONSTEXPR mapping_t<I> value()+ static constexpr mapping_t<I> value() { return new_thread_t(); } - friend ASIO_CONSTEXPR bool operator==(- const new_thread_t&, const new_thread_t&)+ friend constexpr bool operator==(const new_thread_t&, const new_thread_t&) { return true; } - friend ASIO_CONSTEXPR bool operator!=(- const new_thread_t&, const new_thread_t&)+ 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>&)+ {+ return true;+ }++ friend constexpr bool operator==(const new_thread_t&, const other_t<I>&)+ {+ return false;+ }++ friend constexpr bool operator!=(const new_thread_t&, const other_t<I>&)+ {+ return true;+ } }; #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \@@ -701,35 +647,15 @@ struct other_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)+ static constexpr bool is_applicable_property_v = is_executor<T>::value; #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) - ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);- ASIO_STATIC_CONSTEXPR(bool, is_preferable = true);+ static constexpr bool is_requirable = true;+ static constexpr bool is_preferable = true; typedef mapping_t<I> polymorphic_query_result_type; - ASIO_CONSTEXPR other_t()+ constexpr other_t() { } @@ -746,37 +672,53 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T>- static ASIO_CONSTEXPR+ static constexpr typename query_static_constexpr_member<T>::result_type static_query()- ASIO_NOEXCEPT_IF((- query_static_constexpr_member<T>::is_noexcept))+ noexcept(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 ASIO_CONSTEXPR const T static_query_v- = other_t::static_query<E>();+ static 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 ASIO_CONSTEXPR mapping_t<I> value()+ static constexpr mapping_t<I> value() { return other_t(); } - friend ASIO_CONSTEXPR bool operator==(- const other_t&, const other_t&)+ friend constexpr bool operator==(const other_t&, const other_t&) { return true; } - friend ASIO_CONSTEXPR bool operator!=(- const other_t&, const other_t&)+ 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>&)+ {+ return true;+ }++ friend constexpr bool operator==(const other_t&, const new_thread_t<I>&)+ {+ return false;+ }++ friend constexpr bool operator!=(const other_t&, const new_thread_t<I>&)+ {+ return true;+ } }; #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \@@ -791,11 +733,7 @@ typedef detail::mapping_t<> mapping_t; -#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+ASIO_INLINE_VARIABLE constexpr mapping_t mapping; } // namespace execution @@ -803,81 +741,25 @@ template <typename T> struct is_applicable_property<T, execution::mapping_t>- : 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)- >+ : integral_constant<bool, execution::is_executor<T>::value> { }; template <typename T> struct is_applicable_property<T, execution::mapping_t::thread_t>- : 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)- >+ : integral_constant<bool, execution::is_executor<T>::value> { }; template <typename T> struct is_applicable_property<T, execution::mapping_t::new_thread_t>- : 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)- >+ : integral_constant<bool, execution::is_executor<T>::value> { }; template <typename T> struct is_applicable_property<T, execution::mapping_t::other_t>- : 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)- >+ : integral_constant<bool, execution::is_executor<T>::value> { }; @@ -889,42 +771,42 @@ template <typename T> struct query_free_default<T, execution::mapping_t,- typename enable_if<+ enable_if_t< can_query<T, execution::mapping_t::thread_t>::value- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept =- (is_nothrow_query<T, execution::mapping_t::thread_t>::value));+ static constexpr bool is_valid = true;+ 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,- typename enable_if<+ enable_if_t< !can_query<T, execution::mapping_t::thread_t>::value && can_query<T, execution::mapping_t::new_thread_t>::value- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept =- (is_nothrow_query<T, execution::mapping_t::new_thread_t>::value));+ static constexpr bool is_valid = true;+ 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,- typename enable_if<+ enable_if_t< !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>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept =- (is_nothrow_query<T, execution::mapping_t::other_t>::value));+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept =+ is_nothrow_query<T, execution::mapping_t::other_t>::value; typedef execution::mapping_t result_type; };@@ -936,18 +818,18 @@ template <typename T> struct static_query<T, execution::mapping_t,- typename enable_if<+ enable_if_t< execution::detail::mapping_t<0>:: query_static_constexpr_member<T>::is_valid- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef typename execution::detail::mapping_t<0>:: query_static_constexpr_member<T>::result_type result_type; - static ASIO_CONSTEXPR result_type value()+ static constexpr result_type value() { return execution::detail::mapping_t<0>:: query_static_constexpr_member<T>::value();@@ -956,21 +838,21 @@ template <typename T> struct static_query<T, execution::mapping_t,- typename enable_if<+ enable_if_t< !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>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef typename traits::static_query<T, execution::mapping_t::thread_t>::result_type result_type; - static ASIO_CONSTEXPR result_type value()+ static constexpr result_type value() { return traits::static_query<T, execution::mapping_t::thread_t>::value(); }@@ -978,22 +860,22 @@ template <typename T> struct static_query<T, execution::mapping_t,- typename enable_if<+ enable_if_t< !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>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef typename traits::static_query<T, execution::mapping_t::new_thread_t>::result_type result_type; - static ASIO_CONSTEXPR result_type value()+ static constexpr result_type value() { return traits::static_query<T, execution::mapping_t::new_thread_t>::value(); }@@ -1001,7 +883,7 @@ template <typename T> struct static_query<T, execution::mapping_t,- typename enable_if<+ enable_if_t< !execution::detail::mapping_t<0>:: query_static_constexpr_member<T>::is_valid && !execution::detail::mapping_t<0>::@@ -1009,15 +891,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>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef typename traits::static_query<T, execution::mapping_t::other_t>::result_type result_type; - static ASIO_CONSTEXPR result_type value()+ static constexpr result_type value() { return traits::static_query<T, execution::mapping_t::other_t>::value(); }@@ -1025,18 +907,18 @@ template <typename T> struct static_query<T, execution::mapping_t::thread_t,- typename enable_if<+ enable_if_t< execution::detail::mapping::thread_t<0>:: query_static_constexpr_member<T>::is_valid- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef typename execution::detail::mapping::thread_t<0>:: query_static_constexpr_member<T>::result_type result_type; - static ASIO_CONSTEXPR result_type value()+ static constexpr result_type value() { return execution::detail::mapping::thread_t<0>:: query_static_constexpr_member<T>::value();@@ -1045,7 +927,7 @@ template <typename T> struct static_query<T, execution::mapping_t::thread_t,- typename enable_if<+ enable_if_t< !execution::detail::mapping::thread_t<0>:: query_static_constexpr_member<T>::is_valid && !execution::detail::mapping::thread_t<0>::@@ -1053,14 +935,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>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef execution::mapping_t::thread_t result_type; - static ASIO_CONSTEXPR result_type value()+ static constexpr result_type value() { return result_type(); }@@ -1068,18 +950,18 @@ template <typename T> struct static_query<T, execution::mapping_t::new_thread_t,- typename enable_if<+ enable_if_t< execution::detail::mapping::new_thread_t<0>:: query_static_constexpr_member<T>::is_valid- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ 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 ASIO_CONSTEXPR result_type value()+ static constexpr result_type value() { return execution::detail::mapping::new_thread_t<0>:: query_static_constexpr_member<T>::value();@@ -1088,18 +970,18 @@ template <typename T> struct static_query<T, execution::mapping_t::other_t,- typename enable_if<+ enable_if_t< execution::detail::mapping::other_t<0>:: query_static_constexpr_member<T>::is_valid- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef typename execution::detail::mapping::other_t<0>:: query_static_constexpr_member<T>::result_type result_type; - static ASIO_CONSTEXPR result_type value()+ static constexpr result_type value() { return execution::detail::mapping::other_t<0>:: query_static_constexpr_member<T>::value();@@ -1108,46 +990,6 @@ #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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -18,8 +18,6 @@ #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"@@ -36,10 +34,9 @@ /// should occupy the associated execution context. struct occupancy_t {- /// The occupancy_t property applies to executors, senders, and schedulers.+ /// The occupancy_t property applies to executors. template <typename T>- static constexpr bool is_applicable_property_v =- is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;+ static constexpr bool is_applicable_property_v = is_executor_v<T>; /// The occupancy_t property cannot be required. static constexpr bool is_requirable = false;@@ -65,35 +62,15 @@ struct occupancy_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)+ static constexpr bool is_applicable_property_v = is_executor<T>::value; #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) - ASIO_STATIC_CONSTEXPR(bool, is_requirable = false);- ASIO_STATIC_CONSTEXPR(bool, is_preferable = false);+ static constexpr bool is_requirable = false;+ static constexpr bool is_preferable = false; typedef std::size_t polymorphic_query_result_type; - ASIO_CONSTEXPR occupancy_t()+ constexpr occupancy_t() { } @@ -104,17 +81,17 @@ struct type { template <typename P>- static constexpr auto query(ASIO_MOVE_ARG(P) p)+ static constexpr auto query(P&& p) noexcept( noexcept(- conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p))+ conditional_t<true, T, P>::query(static_cast<P&&>(p)) ) ) -> decltype(- conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p))+ conditional_t<true, T, P>::query(static_cast<P&&>(p)) ) {- return T::query(ASIO_MOVE_CAST(P)(p));+ return T::query(static_cast<P&&>(p)); } }; #else // defined(ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)@@ -130,24 +107,17 @@ #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 constexpr typename query_static_constexpr_member<T>::result_type static_query()- ASIO_NOEXCEPT_IF((- query_static_constexpr_member<T>::is_noexcept))+ noexcept(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 ASIO_CONSTEXPR const T static_query_v- = occupancy_t::static_query<E>();+ static 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) \@@ -157,20 +127,11 @@ #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; -#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+ASIO_INLINE_VARIABLE constexpr occupancy_t occupancy; } // namespace execution @@ -178,21 +139,7 @@ template <typename T> struct is_applicable_property<T, execution::occupancy_t>- : 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)- >+ : integral_constant<bool, execution::is_executor<T>::value> { }; @@ -205,18 +152,18 @@ template <typename T> struct static_query<T, execution::occupancy_t,- typename enable_if<+ enable_if_t< execution::detail::occupancy_t<0>:: query_static_constexpr_member<T>::is_valid- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef typename execution::detail::occupancy_t<0>:: query_static_constexpr_member<T>::result_type result_type; - static ASIO_CONSTEXPR result_type value()+ static 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
@@ -1,99 +0,0 @@-//-// 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -18,8 +18,6 @@ #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"@@ -39,11 +37,9 @@ /// A property to describe whether task submission is likely in the future. struct outstanding_work_t {- /// The outstanding_work_t property applies to executors, senders, and- /// schedulers.+ /// The outstanding_work_t property applies to executors. template <typename T>- static constexpr bool is_applicable_property_v =- is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;+ static constexpr bool is_applicable_property_v = is_executor_v<T>; /// The top-level outstanding_work_t property cannot be required. static constexpr bool is_requirable = false;@@ -58,11 +54,9 @@ /// future submission of a function object. struct untracked_t {- /// The outstanding_work_t::untracked_t property applies to executors,- /// senders, and schedulers.+ /// The outstanding_work_t::untracked_t property applies to executors. template <typename T>- static constexpr bool is_applicable_property_v =- is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;+ static constexpr bool is_applicable_property_v = is_executor_v<T>; /// The outstanding_work_t::untracked_t property can be required. static constexpr bool is_requirable = true;@@ -87,11 +81,9 @@ /// future submission of a function object. struct tracked_t {- /// The outstanding_work_t::untracked_t property applies to executors,- /// senders, and schedulers.+ /// The outstanding_work_t::untracked_t property applies to executors. template <typename T>- static constexpr bool is_applicable_property_v =- is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;+ static constexpr bool is_applicable_property_v = is_executor_v<T>; /// The outstanding_work_t::tracked_t property can be required. static constexpr bool is_requirable = true;@@ -158,48 +150,28 @@ struct outstanding_work_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)+ static constexpr bool is_applicable_property_v = is_executor<T>::value; #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) - ASIO_STATIC_CONSTEXPR(bool, is_requirable = false);- ASIO_STATIC_CONSTEXPR(bool, is_preferable = false);+ static constexpr bool is_requirable = false;+ 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; - ASIO_CONSTEXPR outstanding_work_t()+ constexpr outstanding_work_t() : value_(-1) { } - ASIO_CONSTEXPR outstanding_work_t(untracked_t)+ constexpr outstanding_work_t(untracked_t) : value_(0) { } - ASIO_CONSTEXPR outstanding_work_t(tracked_t)+ constexpr outstanding_work_t(tracked_t) : value_(1) { }@@ -211,16 +183,14 @@ struct type { template <typename P>- auto query(ASIO_MOVE_ARG(P) p) const+ auto query(P&& p) const noexcept( noexcept(- declval<typename conditional<true, T, P>::type>().query(- ASIO_MOVE_CAST(P)(p))+ declval<conditional_t<true, T, P>>().query(static_cast<P&&>(p)) ) ) -> decltype(- declval<typename conditional<true, T, P>::type>().query(- ASIO_MOVE_CAST(P)(p))+ declval<conditional_t<true, T, P>>().query(static_cast<P&&>(p)) ); }; #else // defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)@@ -235,17 +205,17 @@ struct type { template <typename P>- static constexpr auto query(ASIO_MOVE_ARG(P) p)+ static constexpr auto query(P&& p) noexcept( noexcept(- conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p))+ conditional_t<true, T, P>::query(static_cast<P&&>(p)) ) ) -> decltype(- conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p))+ conditional_t<true, T, P>::query(static_cast<P&&>(p)) ) {- return T::query(ASIO_MOVE_CAST(P)(p));+ return T::query(static_cast<P&&>(p)); } }; #else // defined(ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)@@ -265,66 +235,65 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T>- static ASIO_CONSTEXPR+ static constexpr typename query_static_constexpr_member<T>::result_type static_query()- ASIO_NOEXCEPT_IF((- query_static_constexpr_member<T>::is_noexcept))+ noexcept(query_static_constexpr_member<T>::is_noexcept) { return query_static_constexpr_member<T>::value(); } template <typename T>- static ASIO_CONSTEXPR+ static constexpr typename traits::static_query<T, untracked_t>::result_type static_query(- typename enable_if<+ enable_if_t< !query_static_constexpr_member<T>::is_valid- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< !query_member<T>::is_valid- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< traits::static_query<T, untracked_t>::is_valid- >::type* = 0) ASIO_NOEXCEPT+ >* = 0) noexcept { return traits::static_query<T, untracked_t>::value(); } template <typename T>- static ASIO_CONSTEXPR+ static constexpr typename traits::static_query<T, tracked_t>::result_type static_query(- typename enable_if<+ enable_if_t< !query_static_constexpr_member<T>::is_valid- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< !query_member<T>::is_valid- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< !traits::static_query<T, untracked_t>::is_valid- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< traits::static_query<T, tracked_t>::is_valid- >::type* = 0) ASIO_NOEXCEPT+ >* = 0) noexcept { return traits::static_query<T, tracked_t>::value(); } template <typename E, typename T = decltype(outstanding_work_t::static_query<E>())>- static ASIO_CONSTEXPR const T static_query_v+ static 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 ASIO_CONSTEXPR bool operator==(+ friend constexpr bool operator==( const outstanding_work_t& a, const outstanding_work_t& b) { return a.value_ == b.value_; } - friend ASIO_CONSTEXPR bool operator!=(+ friend constexpr bool operator!=( const outstanding_work_t& a, const outstanding_work_t& b) { return a.value_ != b.value_;@@ -332,25 +301,23 @@ struct convertible_from_outstanding_work_t {- ASIO_CONSTEXPR convertible_from_outstanding_work_t(outstanding_work_t)+ constexpr convertible_from_outstanding_work_t(outstanding_work_t) { } }; template <typename Executor>- friend ASIO_CONSTEXPR outstanding_work_t query(+ friend constexpr outstanding_work_t query( const Executor& ex, convertible_from_outstanding_work_t,- typename enable_if<+ enable_if_t< can_query<const Executor&, untracked_t>::value- >::type* = 0)+ >* = 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&,- outstanding_work_t<>::untracked_t>::value))+ noexcept(is_nothrow_query<const Executor&,+ outstanding_work_t<>::untracked_t>::value) #else // defined(ASIO_MSVC)- ASIO_NOEXCEPT_IF((- is_nothrow_query<const Executor&, untracked_t>::value))+ noexcept(is_nothrow_query<const Executor&, untracked_t>::value) #endif // defined(ASIO_MSVC) #endif // !defined(__clang__) {@@ -358,22 +325,20 @@ } template <typename Executor>- friend ASIO_CONSTEXPR outstanding_work_t query(+ friend constexpr outstanding_work_t query( const Executor& ex, convertible_from_outstanding_work_t,- typename enable_if<+ enable_if_t< !can_query<const Executor&, untracked_t>::value- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< can_query<const Executor&, tracked_t>::value- >::type* = 0)+ >* = 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&,- outstanding_work_t<>::tracked_t>::value))+ noexcept(is_nothrow_query<const Executor&,+ outstanding_work_t<>::tracked_t>::value) #else // defined(ASIO_MSVC)- ASIO_NOEXCEPT_IF((- is_nothrow_query<const Executor&, tracked_t>::value))+ noexcept(is_nothrow_query<const Executor&, tracked_t>::value) #endif // defined(ASIO_MSVC) #endif // !defined(__clang__) {@@ -383,10 +348,6 @@ 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_; };@@ -398,12 +359,7 @@ #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; @@ -417,35 +373,15 @@ struct untracked_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)+ static constexpr bool is_applicable_property_v = is_executor<T>::value; #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) - ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);- ASIO_STATIC_CONSTEXPR(bool, is_preferable = true);+ static constexpr bool is_requirable = true;+ static constexpr bool is_preferable = true; typedef outstanding_work_t<I> polymorphic_query_result_type; - ASIO_CONSTEXPR untracked_t()+ constexpr untracked_t() { } @@ -463,55 +399,61 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T>- static ASIO_CONSTEXPR+ static constexpr typename query_static_constexpr_member<T>::result_type static_query()- ASIO_NOEXCEPT_IF((- query_static_constexpr_member<T>::is_noexcept))+ noexcept(query_static_constexpr_member<T>::is_noexcept) { return query_static_constexpr_member<T>::value(); } template <typename T>- static ASIO_CONSTEXPR untracked_t static_query(- typename enable_if<+ static constexpr untracked_t static_query(+ enable_if_t< !query_static_constexpr_member<T>::is_valid- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< !query_member<T>::is_valid- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< !traits::query_free<T, untracked_t>::is_valid- >::type* = 0,- typename enable_if<- !can_query<T, tracked_t<I> >::value- >::type* = 0) ASIO_NOEXCEPT+ >* = 0,+ enable_if_t<+ !can_query<T, tracked_t<I>>::value+ >* = 0) noexcept { return untracked_t(); } template <typename E, typename T = decltype(untracked_t::static_query<E>())>- static ASIO_CONSTEXPR const T static_query_v- = untracked_t::static_query<E>();+ static 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 ASIO_CONSTEXPR outstanding_work_t<I> value()+ static constexpr outstanding_work_t<I> value() { return untracked_t(); } - friend ASIO_CONSTEXPR bool operator==(- const untracked_t&, const untracked_t&)+ friend constexpr bool operator==(const untracked_t&, const untracked_t&) { return true; } - friend ASIO_CONSTEXPR bool operator!=(- const untracked_t&, const untracked_t&)+ friend constexpr bool operator!=(const untracked_t&, const untracked_t&) { return false; }++ friend constexpr bool operator==(const untracked_t&, const tracked_t<I>&)+ {+ return false;+ }++ friend constexpr bool operator!=(const untracked_t&, const tracked_t<I>&)+ {+ return true;+ } }; #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \@@ -525,35 +467,15 @@ struct tracked_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)+ static constexpr bool is_applicable_property_v = is_executor<T>::value; #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) - ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);- ASIO_STATIC_CONSTEXPR(bool, is_preferable = true);+ static constexpr bool is_requirable = true;+ static constexpr bool is_preferable = true; typedef outstanding_work_t<I> polymorphic_query_result_type; - ASIO_CONSTEXPR tracked_t()+ constexpr tracked_t() { } @@ -571,37 +493,43 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T>- static ASIO_CONSTEXPR+ static constexpr typename query_static_constexpr_member<T>::result_type static_query()- ASIO_NOEXCEPT_IF((- query_static_constexpr_member<T>::is_noexcept))+ noexcept(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 ASIO_CONSTEXPR const T static_query_v- = tracked_t::static_query<E>();+ static 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 ASIO_CONSTEXPR outstanding_work_t<I> value()+ static constexpr outstanding_work_t<I> value() { return tracked_t(); } - friend ASIO_CONSTEXPR bool operator==(- const tracked_t&, const tracked_t&)+ friend constexpr bool operator==(const tracked_t&, const tracked_t&) { return true; } - friend ASIO_CONSTEXPR bool operator!=(- const tracked_t&, const tracked_t&)+ friend constexpr bool operator!=(const tracked_t&, const tracked_t&) { return false; }++ friend constexpr bool operator==(const tracked_t&, const untracked_t<I>&)+ {+ return false;+ }++ friend constexpr bool operator!=(const tracked_t&, const untracked_t<I>&)+ {+ return true;+ } }; #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \@@ -616,12 +544,7 @@ typedef detail::outstanding_work_t<> outstanding_work_t; -#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+ASIO_INLINE_VARIABLE constexpr outstanding_work_t outstanding_work; } // namespace execution @@ -629,61 +552,19 @@ template <typename T> struct is_applicable_property<T, execution::outstanding_work_t>- : 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)- >+ : integral_constant<bool, execution::is_executor<T>::value> { }; template <typename T> struct is_applicable_property<T, execution::outstanding_work_t::untracked_t>- : 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)- >+ : integral_constant<bool, execution::is_executor<T>::value> { }; template <typename T> struct is_applicable_property<T, execution::outstanding_work_t::tracked_t>- : 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)- >+ : integral_constant<bool, execution::is_executor<T>::value> { }; @@ -695,27 +576,27 @@ template <typename T> struct query_free_default<T, execution::outstanding_work_t,- typename enable_if<+ enable_if_t< can_query<T, execution::outstanding_work_t::untracked_t>::value- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept =- (is_nothrow_query<T, execution::outstanding_work_t::untracked_t>::value));+ static constexpr bool is_valid = true;+ 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,- typename enable_if<+ enable_if_t< !can_query<T, execution::outstanding_work_t::untracked_t>::value && can_query<T, execution::outstanding_work_t::tracked_t>::value- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept =- (is_nothrow_query<T, execution::outstanding_work_t::tracked_t>::value));+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept =+ is_nothrow_query<T, execution::outstanding_work_t::tracked_t>::value; typedef execution::outstanding_work_t result_type; };@@ -727,18 +608,18 @@ template <typename T> struct static_query<T, execution::outstanding_work_t,- typename enable_if<+ enable_if_t< execution::detail::outstanding_work_t<0>:: query_static_constexpr_member<T>::is_valid- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef typename execution::detail::outstanding_work_t<0>:: query_static_constexpr_member<T>::result_type result_type; - static ASIO_CONSTEXPR result_type value()+ static constexpr result_type value() { return execution::detail::outstanding_work_t<0>:: query_static_constexpr_member<T>::value();@@ -747,22 +628,22 @@ template <typename T> struct static_query<T, execution::outstanding_work_t,- typename enable_if<+ enable_if_t< !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>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef typename traits::static_query<T, execution::outstanding_work_t::untracked_t>::result_type result_type; - static ASIO_CONSTEXPR result_type value()+ static constexpr result_type value() { return traits::static_query<T, execution::outstanding_work_t::untracked_t>::value();@@ -771,7 +652,7 @@ template <typename T> struct static_query<T, execution::outstanding_work_t,- typename enable_if<+ enable_if_t< !execution::detail::outstanding_work_t<0>:: query_static_constexpr_member<T>::is_valid && !execution::detail::outstanding_work_t<0>::@@ -780,15 +661,15 @@ execution::outstanding_work_t::untracked_t>::is_valid && traits::static_query<T, execution::outstanding_work_t::tracked_t>::is_valid- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef typename traits::static_query<T, execution::outstanding_work_t::tracked_t>::result_type result_type; - static ASIO_CONSTEXPR result_type value()+ static constexpr result_type value() { return traits::static_query<T, execution::outstanding_work_t::tracked_t>::value();@@ -797,18 +678,18 @@ template <typename T> struct static_query<T, execution::outstanding_work_t::untracked_t,- typename enable_if<+ enable_if_t< execution::detail::outstanding_work::untracked_t<0>:: query_static_constexpr_member<T>::is_valid- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ 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 ASIO_CONSTEXPR result_type value()+ static constexpr result_type value() { return execution::detail::outstanding_work::untracked_t<0>:: query_static_constexpr_member<T>::value();@@ -817,7 +698,7 @@ template <typename T> struct static_query<T, execution::outstanding_work_t::untracked_t,- typename enable_if<+ enable_if_t< !execution::detail::outstanding_work::untracked_t<0>:: query_static_constexpr_member<T>::is_valid && !execution::detail::outstanding_work::untracked_t<0>::@@ -825,14 +706,14 @@ && !traits::query_free<T, execution::outstanding_work_t::untracked_t>::is_valid && !can_query<T, execution::outstanding_work_t::tracked_t>::value- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef execution::outstanding_work_t::untracked_t result_type; - static ASIO_CONSTEXPR result_type value()+ static constexpr result_type value() { return result_type(); }@@ -840,18 +721,18 @@ template <typename T> struct static_query<T, execution::outstanding_work_t::tracked_t,- typename enable_if<+ enable_if_t< execution::detail::outstanding_work::tracked_t<0>:: query_static_constexpr_member<T>::is_valid- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ 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 ASIO_CONSTEXPR result_type value()+ static constexpr result_type value() { return execution::detail::outstanding_work::tracked_t<0>:: query_static_constexpr_member<T>::value();@@ -860,34 +741,6 @@ #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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -65,16 +65,17 @@ template <typename InnerProperty, typename = void> struct prefer_only_is_preferable {- ASIO_STATIC_CONSTEXPR(bool, is_preferable = false);+ static constexpr bool is_preferable = false; }; template <typename InnerProperty> struct prefer_only_is_preferable<InnerProperty,- typename enable_if<+ enable_if_t< InnerProperty::is_preferable- >::type>+ >+ > {- ASIO_STATIC_CONSTEXPR(bool, is_preferable = true);+ static constexpr bool is_preferable = true; }; template <typename InnerProperty, typename = void>@@ -84,9 +85,10 @@ template <typename InnerProperty> struct prefer_only_polymorphic_query_result_type<InnerProperty,- typename void_type<+ void_t< typename InnerProperty::polymorphic_query_result_type- >::type>+ >+ > { typedef typename InnerProperty::polymorphic_query_result_type polymorphic_query_result_type;@@ -103,14 +105,14 @@ } }; -#if defined(ASIO_HAS_DECLTYPE) \- && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#if defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) template <typename InnerProperty> struct prefer_only_property<InnerProperty,- typename void_type<+ void_t< decltype(asio::declval<const InnerProperty>().value())- >::type>+ >+ > { InnerProperty property; @@ -119,17 +121,15 @@ { } - ASIO_CONSTEXPR auto value() const- ASIO_NOEXCEPT_IF((- noexcept(asio::declval<const InnerProperty>().value())))+ constexpr auto value() const+ noexcept(noexcept(asio::declval<const InnerProperty>().value())) -> decltype(asio::declval<const InnerProperty>().value()) { return property.value(); } }; -#else // defined(ASIO_HAS_DECLTYPE)- // && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#else // defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) struct prefer_only_memfns_base {@@ -158,11 +158,12 @@ template <typename InnerProperty> struct prefer_only_property<InnerProperty,- typename enable_if<+ enable_if_t< sizeof(prefer_only_value_memfn_helper<InnerProperty>(0)) != 1 && !is_same<typename InnerProperty::polymorphic_query_result_type, void>::value- >::type>+ >+ > { InnerProperty property; @@ -171,15 +172,14 @@ { } - ASIO_CONSTEXPR typename InnerProperty::polymorphic_query_result_type+ constexpr typename InnerProperty::polymorphic_query_result_type value() const { return property.value(); } }; -#endif // defined(ASIO_HAS_DECLTYPE)- // && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#endif // 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> {- ASIO_STATIC_CONSTEXPR(bool, is_requirable = false);+ static constexpr bool is_requirable = false; - ASIO_CONSTEXPR prefer_only(const InnerProperty& p)+ constexpr prefer_only(const InnerProperty& p) : detail::prefer_only_property<InnerProperty>(p) { }@@ -199,35 +199,33 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T>- static ASIO_CONSTEXPR+ static constexpr typename traits::static_query<T, InnerProperty>::result_type static_query()- ASIO_NOEXCEPT_IF((- traits::static_query<T, InnerProperty>::is_noexcept))+ noexcept(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 ASIO_CONSTEXPR const T static_query_v+ static 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 ASIO_CONSTEXPR- typename prefer_result<const Executor&, const InnerProperty&>::type+ friend constexpr+ prefer_result_t<const Executor&, const InnerProperty&> prefer(const Executor& ex, const prefer_only<Property>& p,- typename enable_if<+ enable_if_t< is_same<Property, InnerProperty>::value- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< can_prefer<const Executor&, const InnerProperty&>::value- >::type* = 0)+ >* = 0) #if !defined(ASIO_MSVC) \ && !defined(__clang__) // Clang crashes if noexcept is used here.- ASIO_NOEXCEPT_IF((- is_nothrow_prefer<const Executor&, const InnerProperty&>::value))+ noexcept(is_nothrow_prefer<const Executor&, const InnerProperty&>::value) #endif // !defined(ASIO_MSVC) // && !defined(__clang__) {@@ -235,19 +233,18 @@ } template <typename Executor, typename Property>- friend ASIO_CONSTEXPR- typename query_result<const Executor&, const InnerProperty&>::type+ friend constexpr+ query_result_t<const Executor&, const InnerProperty&> query(const Executor& ex, const prefer_only<Property>& p,- typename enable_if<+ enable_if_t< is_same<Property, InnerProperty>::value- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< can_query<const Executor&, const InnerProperty&>::value- >::type* = 0)+ >* = 0) #if !defined(ASIO_MSVC) \ && !defined(__clang__) // Clang crashes if noexcept is used here.- ASIO_NOEXCEPT_IF((- is_nothrow_query<const Executor&, const InnerProperty&>::value))+ noexcept(is_nothrow_query<const Executor&, const InnerProperty&>::value) #endif // !defined(ASIO_MSVC) // && !defined(__clang__) {@@ -265,7 +262,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> { };@@ -276,7 +273,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&> { };@@ -288,16 +285,16 @@ template <typename T, typename InnerProperty> struct prefer_free_default<T, execution::prefer_only<InnerProperty>,- typename enable_if<+ enable_if_t< can_prefer<const T&, const InnerProperty&>::value- >::type>+ >+ > {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept =- (is_nothrow_prefer<const T&, const InnerProperty&>::value));+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept =+ is_nothrow_prefer<const T&, const InnerProperty&>::value; - typedef typename prefer_result<const T&,- const InnerProperty&>::type result_type;+ typedef prefer_result_t<const T&, const InnerProperty&> result_type; }; #endif // !defined(ASIO_HAS_DEDUCED_PREFER_FREE_TRAIT)@@ -306,16 +303,16 @@ template <typename T, typename InnerProperty> struct query_free<T, execution::prefer_only<InnerProperty>,- typename enable_if<+ enable_if_t< can_query<const T&, const InnerProperty&>::value- >::type>+ >+ > {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept =- (is_nothrow_query<const T&, const InnerProperty&>::value));+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept =+ is_nothrow_query<const T&, const InnerProperty&>::value; - typedef typename query_result<const T&,- const InnerProperty&>::type result_type;+ typedef query_result_t<const T&, const InnerProperty&> result_type; }; #endif // !defined(ASIO_HAS_DEDUCED_QUERY_FREE_TRAIT)
− link/modules/asio-standalone/asio/include/asio/execution/receiver.hpp
@@ -1,285 +0,0 @@-//-// 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
@@ -1,48 +0,0 @@-//-// 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -18,8 +18,6 @@ #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"@@ -40,10 +38,9 @@ /// the calling context. struct relationship_t {- /// The relationship_t property applies to executors, senders, and schedulers.+ /// The relationship_t property applies to executors. template <typename T>- static constexpr bool is_applicable_property_v =- is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;+ static constexpr bool is_applicable_property_v = is_executor_v<T>; /// The top-level relationship_t property cannot be required. static constexpr bool is_requirable = false;@@ -58,11 +55,9 @@ /// continuation of the calling context. struct fork_t {- /// The relationship_t::fork_t property applies to executors, senders, and- /// schedulers.+ /// The relationship_t::fork_t property applies to executors. template <typename T>- static constexpr bool is_applicable_property_v =- is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;+ static constexpr bool is_applicable_property_v = is_executor_v<T>; /// The relationship_t::fork_t property can be required. static constexpr bool is_requirable = true;@@ -87,11 +82,9 @@ /// of the calling context. struct continuation_t {- /// The relationship_t::continuation_t property applies to executors,- /// senders, and schedulers.+ /// The relationship_t::continuation_t property applies to executors. template <typename T>- static constexpr bool is_applicable_property_v =- is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;+ static constexpr bool is_applicable_property_v = is_executor_v<T>; /// The relationship_t::continuation_t property can be required. static constexpr bool is_requirable = true;@@ -157,48 +150,28 @@ struct relationship_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)+ static constexpr bool is_applicable_property_v = is_executor<T>::value; #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) - ASIO_STATIC_CONSTEXPR(bool, is_requirable = false);- ASIO_STATIC_CONSTEXPR(bool, is_preferable = false);+ static constexpr bool is_requirable = false;+ 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; - ASIO_CONSTEXPR relationship_t()+ constexpr relationship_t() : value_(-1) { } - ASIO_CONSTEXPR relationship_t(fork_t)+ constexpr relationship_t(fork_t) : value_(0) { } - ASIO_CONSTEXPR relationship_t(continuation_t)+ constexpr relationship_t(continuation_t) : value_(1) { }@@ -210,16 +183,14 @@ struct type { template <typename P>- auto query(ASIO_MOVE_ARG(P) p) const+ auto query(P&& p) const noexcept( noexcept(- declval<typename conditional<true, T, P>::type>().query(- ASIO_MOVE_CAST(P)(p))+ declval<conditional_t<true, T, P>>().query(static_cast<P&&>(p)) ) ) -> decltype(- declval<typename conditional<true, T, P>::type>().query(- ASIO_MOVE_CAST(P)(p))+ declval<conditional_t<true, T, P>>().query(static_cast<P&&>(p)) ); }; #else // defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)@@ -234,17 +205,17 @@ struct type { template <typename P>- static constexpr auto query(ASIO_MOVE_ARG(P) p)+ static constexpr auto query(P&& p) noexcept( noexcept(- conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p))+ conditional_t<true, T, P>::query(static_cast<P&&>(p)) ) ) -> decltype(- conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p))+ conditional_t<true, T, P>::query(static_cast<P&&>(p)) ) {- return T::query(ASIO_MOVE_CAST(P)(p));+ return T::query(static_cast<P&&>(p)); } }; #else // defined(ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)@@ -264,66 +235,65 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \ && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) template <typename T>- static ASIO_CONSTEXPR+ static constexpr typename query_static_constexpr_member<T>::result_type static_query()- ASIO_NOEXCEPT_IF((- query_static_constexpr_member<T>::is_noexcept))+ noexcept(query_static_constexpr_member<T>::is_noexcept) { return query_static_constexpr_member<T>::value(); } template <typename T>- static ASIO_CONSTEXPR+ static constexpr typename traits::static_query<T, fork_t>::result_type static_query(- typename enable_if<+ enable_if_t< !query_static_constexpr_member<T>::is_valid- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< !query_member<T>::is_valid- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< traits::static_query<T, fork_t>::is_valid- >::type* = 0) ASIO_NOEXCEPT+ >* = 0) noexcept { return traits::static_query<T, fork_t>::value(); } template <typename T>- static ASIO_CONSTEXPR+ static constexpr typename traits::static_query<T, continuation_t>::result_type static_query(- typename enable_if<+ enable_if_t< !query_static_constexpr_member<T>::is_valid- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< !query_member<T>::is_valid- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< !traits::static_query<T, fork_t>::is_valid- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< traits::static_query<T, continuation_t>::is_valid- >::type* = 0) ASIO_NOEXCEPT+ >* = 0) noexcept { return traits::static_query<T, continuation_t>::value(); } template <typename E, typename T = decltype(relationship_t::static_query<E>())>- static ASIO_CONSTEXPR const T static_query_v+ static 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 ASIO_CONSTEXPR bool operator==(+ friend constexpr bool operator==( const relationship_t& a, const relationship_t& b) { return a.value_ == b.value_; } - friend ASIO_CONSTEXPR bool operator!=(+ friend constexpr bool operator!=( const relationship_t& a, const relationship_t& b) { return a.value_ != b.value_;@@ -331,24 +301,22 @@ struct convertible_from_relationship_t {- ASIO_CONSTEXPR convertible_from_relationship_t(relationship_t)+ constexpr convertible_from_relationship_t(relationship_t) { } }; template <typename Executor>- friend ASIO_CONSTEXPR relationship_t query(+ friend constexpr relationship_t query( const Executor& ex, convertible_from_relationship_t,- typename enable_if<+ enable_if_t< can_query<const Executor&, fork_t>::value- >::type* = 0)+ >* = 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&, relationship_t<>::fork_t>::value))+ noexcept(is_nothrow_query<const Executor&, relationship_t<>::fork_t>::value) #else // defined(ASIO_MSVC)- ASIO_NOEXCEPT_IF((- is_nothrow_query<const Executor&, fork_t>::value))+ noexcept(is_nothrow_query<const Executor&, fork_t>::value) #endif // defined(ASIO_MSVC) #endif // !defined(__clang__) {@@ -356,22 +324,20 @@ } template <typename Executor>- friend ASIO_CONSTEXPR relationship_t query(+ friend constexpr relationship_t query( const Executor& ex, convertible_from_relationship_t,- typename enable_if<+ enable_if_t< !can_query<const Executor&, fork_t>::value- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< can_query<const Executor&, continuation_t>::value- >::type* = 0)+ >* = 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&,- relationship_t<>::continuation_t>::value))+ noexcept(is_nothrow_query<const Executor&,+ relationship_t<>::continuation_t>::value) #else // defined(ASIO_MSVC)- ASIO_NOEXCEPT_IF((- is_nothrow_query<const Executor&, continuation_t>::value))+ noexcept(is_nothrow_query<const Executor&, continuation_t>::value) #endif // defined(ASIO_MSVC) #endif // !defined(__clang__) {@@ -381,10 +347,6 @@ 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_; };@@ -396,14 +358,8 @@ #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) // && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) -#if !defined(ASIO_HAS_CONSTEXPR) template <int I>-const relationship_t<I> relationship_t<I>::instance;-#endif--template <int I>-const typename relationship_t<I>::fork_t-relationship_t<I>::fork;+const typename relationship_t<I>::fork_t relationship_t<I>::fork; template <int I> const typename relationship_t<I>::continuation_t@@ -415,35 +371,15 @@ struct fork_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)+ static constexpr bool is_applicable_property_v = is_executor<T>::value; #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) - ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);- ASIO_STATIC_CONSTEXPR(bool, is_preferable = true);+ static constexpr bool is_requirable = true;+ static constexpr bool is_preferable = true; typedef relationship_t<I> polymorphic_query_result_type; - ASIO_CONSTEXPR fork_t()+ constexpr fork_t() { } @@ -460,55 +396,61 @@ #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 constexpr typename query_static_constexpr_member<T>::result_type static_query()- ASIO_NOEXCEPT_IF((- query_static_constexpr_member<T>::is_noexcept))+ noexcept(query_static_constexpr_member<T>::is_noexcept) { return query_static_constexpr_member<T>::value(); } template <typename T>- static ASIO_CONSTEXPR fork_t static_query(- typename enable_if<+ static constexpr fork_t static_query(+ enable_if_t< !query_static_constexpr_member<T>::is_valid- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< !query_member<T>::is_valid- >::type* = 0,- typename enable_if<+ >* = 0,+ enable_if_t< !traits::query_free<T, fork_t>::is_valid- >::type* = 0,- typename enable_if<- !can_query<T, continuation_t<I> >::value- >::type* = 0) ASIO_NOEXCEPT+ >* = 0,+ enable_if_t<+ !can_query<T, continuation_t<I>>::value+ >* = 0) noexcept { return fork_t(); } template <typename E, typename T = decltype(fork_t::static_query<E>())>- static ASIO_CONSTEXPR const T static_query_v+ static 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 ASIO_CONSTEXPR relationship_t<I> value()+ static constexpr relationship_t<I> value() { return fork_t(); } - friend ASIO_CONSTEXPR bool operator==(- const fork_t&, const fork_t&)+ friend constexpr bool operator==(const fork_t&, const fork_t&) { return true; } - friend ASIO_CONSTEXPR bool operator!=(- const fork_t&, const fork_t&)+ friend constexpr bool operator!=(const fork_t&, const fork_t&) { return false; }++ friend constexpr bool operator==(const fork_t&, const continuation_t<I>&)+ {+ return false;+ }++ friend constexpr bool operator!=(const fork_t&, const continuation_t<I>&)+ {+ return true;+ } }; #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \@@ -522,35 +464,15 @@ struct continuation_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)+ static constexpr bool is_applicable_property_v = is_executor<T>::value; #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) - ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);- ASIO_STATIC_CONSTEXPR(bool, is_preferable = true);+ static constexpr bool is_requirable = true;+ static constexpr bool is_preferable = true; typedef relationship_t<I> polymorphic_query_result_type; - ASIO_CONSTEXPR continuation_t()+ constexpr continuation_t() { } @@ -568,38 +490,44 @@ #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 constexpr typename query_static_constexpr_member<T>::result_type static_query()- ASIO_NOEXCEPT_IF((- query_static_constexpr_member<T>::is_noexcept))+ noexcept(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 ASIO_CONSTEXPR const T static_query_v+ static 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 ASIO_CONSTEXPR relationship_t<I> value()+ static constexpr relationship_t<I> value() { return continuation_t(); } - friend ASIO_CONSTEXPR bool operator==(- const continuation_t&, const continuation_t&)+ friend constexpr bool operator==(const continuation_t&, const continuation_t&) { return true; } - friend ASIO_CONSTEXPR bool operator!=(- const continuation_t&, const continuation_t&)+ friend constexpr bool operator!=(const continuation_t&, const continuation_t&) { return false; }++ friend constexpr bool operator==(const continuation_t&, const fork_t<I>&)+ {+ return false;+ }++ friend constexpr bool operator!=(const continuation_t&, const fork_t<I>&)+ {+ return true;+ } }; #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \@@ -614,12 +542,7 @@ typedef detail::relationship_t<> relationship_t; -#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+ASIO_INLINE_VARIABLE constexpr relationship_t relationship; } // namespace execution @@ -627,61 +550,19 @@ template <typename T> struct is_applicable_property<T, execution::relationship_t>- : 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)- >+ : integral_constant<bool, execution::is_executor<T>::value> { }; template <typename T> struct is_applicable_property<T, execution::relationship_t::fork_t>- : 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)- >+ : integral_constant<bool, execution::is_executor<T>::value> { }; template <typename T> struct is_applicable_property<T, execution::relationship_t::continuation_t>- : 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)- >+ : integral_constant<bool, execution::is_executor<T>::value> { }; @@ -693,27 +574,27 @@ template <typename T> struct query_free_default<T, execution::relationship_t,- typename enable_if<+ enable_if_t< can_query<T, execution::relationship_t::fork_t>::value- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept =- (is_nothrow_query<T, execution::relationship_t::fork_t>::value));+ static constexpr bool is_valid = true;+ 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,- typename enable_if<+ enable_if_t< !can_query<T, execution::relationship_t::fork_t>::value && can_query<T, execution::relationship_t::continuation_t>::value- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept =- (is_nothrow_query<T, execution::relationship_t::continuation_t>::value));+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept =+ is_nothrow_query<T, execution::relationship_t::continuation_t>::value; typedef execution::relationship_t result_type; };@@ -725,18 +606,18 @@ template <typename T> struct static_query<T, execution::relationship_t,- typename enable_if<+ enable_if_t< execution::detail::relationship_t<0>:: query_static_constexpr_member<T>::is_valid- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef typename execution::detail::relationship_t<0>:: query_static_constexpr_member<T>::result_type result_type; - static ASIO_CONSTEXPR result_type value()+ static constexpr result_type value() { return execution::detail::relationship_t<0>:: query_static_constexpr_member<T>::value();@@ -745,22 +626,22 @@ template <typename T> struct static_query<T, execution::relationship_t,- typename enable_if<+ enable_if_t< !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>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef typename traits::static_query<T, execution::relationship_t::fork_t>::result_type result_type; - static ASIO_CONSTEXPR result_type value()+ static constexpr result_type value() { return traits::static_query<T, execution::relationship_t::fork_t>::value();@@ -769,7 +650,7 @@ template <typename T> struct static_query<T, execution::relationship_t,- typename enable_if<+ enable_if_t< !execution::detail::relationship_t<0>:: query_static_constexpr_member<T>::is_valid && !execution::detail::relationship_t<0>::@@ -778,15 +659,15 @@ execution::relationship_t::fork_t>::is_valid && traits::static_query<T, execution::relationship_t::continuation_t>::is_valid- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef typename traits::static_query<T, execution::relationship_t::continuation_t>::result_type result_type; - static ASIO_CONSTEXPR result_type value()+ static constexpr result_type value() { return traits::static_query<T, execution::relationship_t::continuation_t>::value();@@ -795,18 +676,18 @@ template <typename T> struct static_query<T, execution::relationship_t::fork_t,- typename enable_if<+ enable_if_t< execution::detail::relationship::fork_t<0>:: query_static_constexpr_member<T>::is_valid- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef typename execution::detail::relationship::fork_t<0>:: query_static_constexpr_member<T>::result_type result_type; - static ASIO_CONSTEXPR result_type value()+ static constexpr result_type value() { return execution::detail::relationship::fork_t<0>:: query_static_constexpr_member<T>::value();@@ -815,7 +696,7 @@ template <typename T> struct static_query<T, execution::relationship_t::fork_t,- typename enable_if<+ enable_if_t< !execution::detail::relationship::fork_t<0>:: query_static_constexpr_member<T>::is_valid && !execution::detail::relationship::fork_t<0>::@@ -823,14 +704,14 @@ && !traits::query_free<T, execution::relationship_t::fork_t>::is_valid && !can_query<T, execution::relationship_t::continuation_t>::value- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef execution::relationship_t::fork_t result_type; - static ASIO_CONSTEXPR result_type value()+ static constexpr result_type value() { return result_type(); }@@ -838,18 +719,18 @@ template <typename T> struct static_query<T, execution::relationship_t::continuation_t,- typename enable_if<+ enable_if_t< execution::detail::relationship::continuation_t<0>:: query_static_constexpr_member<T>::is_valid- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef typename execution::detail::relationship::continuation_t<0>:: query_static_constexpr_member<T>::result_type result_type; - static ASIO_CONSTEXPR result_type value()+ static constexpr result_type value() { return execution::detail::relationship::continuation_t<0>:: query_static_constexpr_member<T>::value();@@ -858,34 +739,6 @@ #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
@@ -1,292 +0,0 @@-//-// 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
@@ -1,91 +0,0 @@-//-// 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
@@ -1,316 +0,0 @@-//-// 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
@@ -1,255 +0,0 @@-//-// 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
@@ -1,255 +0,0 @@-//-// 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
@@ -1,488 +0,0 @@-//-// 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
@@ -1,252 +0,0 @@-//-// 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
@@ -1,455 +0,0 @@-//-// 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -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,13 +106,51 @@ : 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(); @@ -224,8 +262,6 @@ 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.@@ -241,27 +277,6 @@ 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. /**@@ -298,10 +313,152 @@ 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.- asio::detail::service_registry* 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_;+};+ /// Class used to uniquely identify a service. class execution_context::id : private noncopyable@@ -311,7 +468,7 @@ id() {} }; -/// Base class for all io_context services.+/// Base class for all execution context services. class execution_context::service : private noncopyable {@@ -342,7 +499,7 @@ ASIO_DECL virtual void notify_fork( execution_context::fork_event event); - friend class asio::detail::service_registry;+ friend class detail::service_registry; struct key { key() : type_info_(0), id_(0) {}@@ -352,6 +509,24 @@ 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -19,6 +19,7 @@ #if !defined(ASIO_NO_TS_EXECUTORS) +#include <new> #include <typeinfo> #include "asio/detail/cstddef.hpp" #include "asio/detail/executor_function.hpp"@@ -36,11 +37,11 @@ { public: /// Constructor.- ASIO_DECL bad_executor() ASIO_NOEXCEPT;+ ASIO_DECL bad_executor() noexcept; /// Obtain message associated with exception. ASIO_DECL virtual const char* what() const- ASIO_NOEXCEPT_OR_NOTHROW;+ noexcept; }; /// Polymorphic wrapper for executors.@@ -48,36 +49,53 @@ { public: /// Default constructor.- executor() ASIO_NOEXCEPT+ executor() noexcept : impl_(0) { } /// Construct from nullptr.- executor(nullptr_t) ASIO_NOEXCEPT+ executor(nullptr_t) noexcept : impl_(0) { } /// Copy constructor.- executor(const executor& other) ASIO_NOEXCEPT+ executor(const executor& other) noexcept : impl_(other.clone()) { } -#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move constructor.- executor(executor&& other) ASIO_NOEXCEPT+ executor(executor&& other) 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>@@ -90,26 +108,24 @@ } /// Assignment operator.- executor& operator=(const executor& other) ASIO_NOEXCEPT+ executor& operator=(const executor& other) noexcept { destroy(); impl_ = other.clone(); return *this; } -#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) // Move assignment operator.- executor& operator=(executor&& other) ASIO_NOEXCEPT+ executor& operator=(executor&& other) 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) ASIO_NOEXCEPT+ executor& operator=(nullptr_t) noexcept { destroy(); impl_ = 0;@@ -119,9 +135,9 @@ /// Assignment operator to create a polymorphic wrapper for the specified /// executor. template <typename Executor>- executor& operator=(ASIO_MOVE_ARG(Executor) e) ASIO_NOEXCEPT+ executor& operator=(Executor&& e) noexcept {- executor tmp(ASIO_MOVE_CAST(Executor)(e));+ executor tmp(static_cast<Executor&&>(e)); destroy(); impl_ = tmp.impl_; tmp.impl_ = 0;@@ -129,19 +145,19 @@ } /// Obtain the underlying execution context.- execution_context& context() const ASIO_NOEXCEPT+ execution_context& context() const noexcept { return get_impl()->context(); } /// Inform the executor that it has some outstanding work to do.- void on_work_started() const ASIO_NOEXCEPT+ void on_work_started() const noexcept { get_impl()->on_work_started(); } /// Inform the executor that some work is no longer outstanding.- void on_work_finished() const ASIO_NOEXCEPT+ void on_work_finished() const noexcept { get_impl()->on_work_finished(); }@@ -160,7 +176,7 @@ * internal storage needed for function invocation. */ template <typename Function, typename Allocator>- void dispatch(ASIO_MOVE_ARG(Function) f, const Allocator& a) const;+ void dispatch(Function&& f, const Allocator& a) const; /// Request the executor to invoke the given function object. /**@@ -176,7 +192,7 @@ * internal storage needed for function invocation. */ template <typename Function, typename Allocator>- void post(ASIO_MOVE_ARG(Function) f, const Allocator& a) const;+ void post(Function&& f, const Allocator& a) const; /// Request the executor to invoke the given function object. /**@@ -192,14 +208,14 @@ * internal storage needed for function invocation. */ template <typename Function, typename Allocator>- void defer(ASIO_MOVE_ARG(Function) f, const Allocator& a) const;+ void defer(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 ASIO_NOEXCEPT+ operator unspecified_bool_type() const noexcept { return impl_ ? &executor::unspecified_bool_true : 0; }@@ -210,12 +226,12 @@ * otherwise, <tt>typeid(void)</tt>. */ #if !defined(ASIO_NO_TYPEID) || defined(GENERATING_DOCUMENTATION)- const std::type_info& target_type() const ASIO_NOEXCEPT+ const std::type_info& target_type() const noexcept { return impl_ ? impl_->target_type() : typeid(void); } #else // !defined(ASIO_NO_TYPEID) || defined(GENERATING_DOCUMENTATION)- const void* target_type() const ASIO_NOEXCEPT+ const void* target_type() const noexcept { return impl_ ? impl_->target_type() : 0; }@@ -227,7 +243,7 @@ * executor target; otherwise, a null pointer. */ template <typename Executor>- Executor* target() ASIO_NOEXCEPT;+ Executor* target() noexcept; /// Obtain a pointer to the target executor object. /**@@ -235,11 +251,11 @@ * executor target; otherwise, a null pointer. */ template <typename Executor>- const Executor* target() const ASIO_NOEXCEPT;+ const Executor* target() const noexcept; /// Compare two executors for equality. friend bool operator==(const executor& a,- const executor& b) ASIO_NOEXCEPT+ const executor& b) noexcept { if (a.impl_ == b.impl_) return true;@@ -250,7 +266,7 @@ /// Compare two executors for inequality. friend bool operator!=(const executor& a,- const executor& b) ASIO_NOEXCEPT+ const executor& b) noexcept { return !(a == b); }@@ -281,18 +297,18 @@ class impl_base { public:- 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;+ 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; protected: impl_base(bool fast_dispatch) : fast_dispatch_(fast_dispatch) {}@@ -315,13 +331,13 @@ } // Helper function to clone another implementation.- impl_base* clone() const ASIO_NOEXCEPT+ impl_base* clone() const noexcept { return impl_ ? impl_->clone() : 0; } // Helper function to destroy an implementation.- void destroy() ASIO_NOEXCEPT+ void destroy() 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -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) ASIO_NOEXCEPT;+ explicit executor_work_guard(const executor_type& e) noexcept; /// Copy constructor.- executor_work_guard(const executor_work_guard& other) ASIO_NOEXCEPT;+ executor_work_guard(const executor_work_guard& other) noexcept; /// Move constructor.- executor_work_guard(executor_work_guard&& other) ASIO_NOEXCEPT;+ executor_work_guard(executor_work_guard&& other) noexcept; /// Destructor. /**@@ -65,17 +65,17 @@ ~executor_work_guard(); /// Obtain the associated executor.- executor_type get_executor() const ASIO_NOEXCEPT;+ executor_type get_executor() const noexcept; /// Whether the executor_work_guard object owns some outstanding work.- bool owns_work() const ASIO_NOEXCEPT;+ bool owns_work() const 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() ASIO_NOEXCEPT;+ void reset() noexcept; }; #endif // defined(GENERATING_DOCUMENTATION)@@ -86,21 +86,21 @@ template <typename Executor> class executor_work_guard<Executor,- typename enable_if<+ enable_if_t< is_executor<Executor>::value- >::type>+ >> { public: typedef Executor executor_type; - explicit executor_work_guard(const executor_type& e) ASIO_NOEXCEPT+ explicit executor_work_guard(const executor_type& e) noexcept : executor_(e), owns_(true) { executor_.on_work_started(); } - executor_work_guard(const executor_work_guard& other) ASIO_NOEXCEPT+ executor_work_guard(const executor_work_guard& other) noexcept : executor_(other.executor_), owns_(other.owns_) {@@ -108,14 +108,12 @@ executor_.on_work_started(); } -#if defined(ASIO_HAS_MOVE)- executor_work_guard(executor_work_guard&& other) ASIO_NOEXCEPT- : executor_(ASIO_MOVE_CAST(Executor)(other.executor_)),+ executor_work_guard(executor_work_guard&& other) noexcept+ : executor_(static_cast<Executor&&>(other.executor_)), owns_(other.owns_) { other.owns_ = false; }-#endif // defined(ASIO_HAS_MOVE) ~executor_work_guard() {@@ -123,17 +121,17 @@ executor_.on_work_finished(); } - executor_type get_executor() const ASIO_NOEXCEPT+ executor_type get_executor() const noexcept { return executor_; } - bool owns_work() const ASIO_NOEXCEPT+ bool owns_work() const noexcept { return owns_; } - void reset() ASIO_NOEXCEPT+ void reset() noexcept { if (owns_) {@@ -154,17 +152,17 @@ template <typename Executor> class executor_work_guard<Executor,- typename enable_if<+ enable_if_t< !is_executor<Executor>::value- >::type,- typename enable_if<+ >,+ enable_if_t< execution::is_executor<Executor>::value- >::type>+ >> { public: typedef Executor executor_type; - explicit executor_work_guard(const executor_type& e) ASIO_NOEXCEPT+ explicit executor_work_guard(const executor_type& e) noexcept : executor_(e), owns_(true) {@@ -172,7 +170,7 @@ execution::outstanding_work.tracked)); } - executor_work_guard(const executor_work_guard& other) ASIO_NOEXCEPT+ executor_work_guard(const executor_work_guard& other) noexcept : executor_(other.executor_), owns_(other.owns_) {@@ -183,21 +181,19 @@ } } -#if defined(ASIO_HAS_MOVE)- executor_work_guard(executor_work_guard&& other) ASIO_NOEXCEPT- : executor_(ASIO_MOVE_CAST(Executor)(other.executor_)),+ executor_work_guard(executor_work_guard&& other) noexcept+ : executor_(static_cast<Executor&&>(other.executor_)), owns_(other.owns_) { if (owns_) { new (&work_) work_type(- ASIO_MOVE_CAST(work_type)(+ static_cast<work_type&&>( *static_cast<work_type*>( static_cast<void*>(&other.work_)))); other.owns_ = false; } }-#endif // defined(ASIO_HAS_MOVE) ~executor_work_guard() {@@ -205,17 +201,17 @@ static_cast<work_type*>(static_cast<void*>(&work_))->~work_type(); } - executor_type get_executor() const ASIO_NOEXCEPT+ executor_type get_executor() const noexcept { return executor_; } - bool owns_work() const ASIO_NOEXCEPT+ bool owns_work() const noexcept { return owns_; } - void reset() ASIO_NOEXCEPT+ void reset() noexcept { if (owns_) {@@ -228,16 +224,15 @@ // Disallow assignment. executor_work_guard& operator=(const executor_work_guard&); - typedef typename decay<- typename prefer_result<+ typedef decay_t<+ prefer_result_t< const executor_type&, execution::outstanding_work_t::tracked_t- >::type- >::type work_type;+ >+ > work_type; executor_type executor_;- typename aligned_storage<sizeof(work_type),- alignment_of<work_type>::value>::type work_;+ aligned_storage_t<sizeof(work_type), alignment_of<work_type>::value> work_; bool owns_; }; @@ -252,9 +247,9 @@ template <typename Executor> ASIO_NODISCARD inline executor_work_guard<Executor> make_work_guard(const Executor& ex,- typename constraint<+ constraint_t< is_executor<Executor>::value || execution::is_executor<Executor>::value- >::type = 0)+ > = 0) { return executor_work_guard<Executor>(ex); }@@ -270,9 +265,9 @@ ASIO_NODISCARD inline executor_work_guard<typename ExecutionContext::executor_type> make_work_guard(ExecutionContext& ctx,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value- >::type = 0)+ > = 0) { return executor_work_guard<typename ExecutionContext::executor_type>( ctx.get_executor());@@ -289,15 +284,15 @@ template <typename T> ASIO_NODISCARD inline executor_work_guard<- typename constraint<+ typename constraint_t< !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<typename associated_executor<T>::type>(+ return executor_work_guard<associated_executor_t<T>>( associated_executor<T>::get(t)); } @@ -315,13 +310,13 @@ */ template <typename T, typename Executor> ASIO_NODISCARD inline-executor_work_guard<typename associated_executor<T, Executor>::type>+executor_work_guard<associated_executor_t<T, Executor>> make_work_guard(const T& t, const Executor& ex,- typename constraint<+ constraint_t< is_executor<Executor>::value || execution::is_executor<Executor>::value- >::type = 0)+ > = 0) {- return executor_work_guard<typename associated_executor<T, Executor>::type>(+ return executor_work_guard<associated_executor_t<T, Executor>>( associated_executor<T, Executor>::get(t, ex)); } @@ -338,24 +333,24 @@ * ctx.get_executor())</tt>. */ template <typename T, typename ExecutionContext>-ASIO_NODISCARD inline executor_work_guard<typename associated_executor<T,- typename ExecutionContext::executor_type>::type>+ASIO_NODISCARD inline executor_work_guard<+ associated_executor_t<T, typename ExecutionContext::executor_type>> make_work_guard(const T& t, ExecutionContext& ctx,- typename constraint<+ constraint_t< !is_executor<T>::value- >::type = 0,- typename constraint<+ > = 0,+ constraint_t< !execution::is_executor<T>::value- >::type = 0,- typename constraint<+ > = 0,+ constraint_t< !is_convertible<T&, execution_context&>::value- >::type = 0,- typename constraint<+ > = 0,+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value- >::type = 0)+ > = 0) {- return executor_work_guard<typename associated_executor<T,- typename ExecutionContext::executor_type>::type>(+ return executor_work_guard<+ associated_executor_t<T, typename ExecutionContext::executor_type>>( associated_executor<T, typename ExecutionContext::executor_type>::get( t, ctx.get_executor())); }
− link/modules/asio-standalone/asio/include/asio/experimental/append.hpp
@@ -1,36 +0,0 @@-//-// 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -47,18 +47,18 @@ * token is itself defaulted as an argument to allow it to capture a source * location. */- ASIO_CONSTEXPR as_single_t(+ constexpr as_single_t( default_constructor_tag = default_constructor_tag(), CompletionToken token = CompletionToken())- : token_(ASIO_MOVE_CAST(CompletionToken)(token))+ : token_(static_cast<CompletionToken&&>(token)) { } /// Constructor. template <typename T>- ASIO_CONSTEXPR explicit as_single_t(- ASIO_MOVE_ARG(T) completion_token)- : token_(ASIO_MOVE_CAST(T)(completion_token))+ constexpr explicit as_single_t(+ T&& completion_token)+ : token_(static_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) ASIO_NOEXCEPT+ executor_with_default(const InnerExecutor& ex) noexcept : InnerExecutor(ex) { }@@ -80,9 +80,9 @@ /// that to construct the adapted executor. template <typename OtherExecutor> executor_with_default(const OtherExecutor& ex,- typename constraint<+ constraint_t< is_convertible<OtherExecutor, InnerExecutor>::value- >::type = 0) ASIO_NOEXCEPT+ > = 0) noexcept : InnerExecutor(ex) { }@@ -90,25 +90,21 @@ /// 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;-#endif // defined(ASIO_HAS_ALIAS_TEMPLATES)- // || defined(GENERATING_DOCUMENTATION)+ executor_with_default<typename T::executor_type>>::other; /// 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>::type::template rebind_executor<- executor_with_default<typename decay<T>::type::executor_type>+ static typename decay_t<T>::template rebind_executor<+ executor_with_default<typename decay_t<T>::executor_type> >::other- as_default_on(ASIO_MOVE_ARG(T) object)+ as_default_on(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));+ return typename decay_t<T>::template rebind_executor<+ executor_with_default<typename decay_t<T>::executor_type>+ >::other(static_cast<T&&>(object)); } //private:@@ -119,11 +115,11 @@ /// arguments should be combined into a single argument. template <typename CompletionToken> ASIO_NODISCARD inline-ASIO_CONSTEXPR as_single_t<typename decay<CompletionToken>::type>-as_single(ASIO_MOVE_ARG(CompletionToken) completion_token)+constexpr as_single_t<decay_t<CompletionToken>>+as_single(CompletionToken&& completion_token) {- return as_single_t<typename decay<CompletionToken>::type>(- ASIO_MOVE_CAST(CompletionToken)(completion_token));+ return as_single_t<decay_t<CompletionToken>>(+ static_cast<CompletionToken&&>(completion_token)); } } // namespace experimental
− link/modules/asio-standalone/asio/include/asio/experimental/as_tuple.hpp
@@ -1,36 +0,0 @@-//-// 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -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,- typename constraint<is_constructible<T>::value>::type* = 0)+ constraint_t<is_constructible<T>::value>* = 0) { return a; } template <typename T, typename Executor> awaitable<std::optional<T>, Executor> awaitable_wrap(awaitable<T, Executor> a,- typename constraint<!is_constructible<T>::value>::type* = 0)+ constraint_t<!is_constructible<T>::value>* = 0) { co_return std::optional<T>(co_await std::move(a)); } template <typename T>-T& awaitable_unwrap(typename conditional<true, T, void>::type& r,- typename constraint<is_constructible<T>::value>::type* = 0)+T& awaitable_unwrap(conditional_t<true, T, void>& r,+ constraint_t<is_constructible<T>::value>* = 0) { return r; } template <typename T>-T& awaitable_unwrap(std::optional<typename conditional<true, T, void>::type>& r,- typename constraint<!is_constructible<T>::value>::type* = 0)+T& awaitable_unwrap(std::optional<conditional_t<true, T, void>>& r,+ constraint_t<!is_constructible<T>::value>* = 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -110,8 +110,9 @@ template <typename... PayloadSignatures, ASIO_COMPLETION_TOKEN_FOR(PayloadSignatures...) CompletionToken>- auto do_async_receive(detail::channel_payload<PayloadSignatures...>*,- ASIO_MOVE_ARG(CompletionToken) token)+ auto do_async_receive(+ asio::detail::completion_payload<PayloadSignatures...>*,+ CompletionToken&& token) -> decltype( async_initiate<CompletionToken, PayloadSignatures...>( declval<initiate_async_receive>(), token))@@ -167,10 +168,10 @@ */ template <typename ExecutionContext> basic_channel(ExecutionContext& context, std::size_t max_buffer_size = 0,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- >::type = defaulted_constraint())+ > = defaulted_constraint()) : service_(&asio::use_service<service_type>(context)), impl_(), executor_(context.get_executor())@@ -178,7 +179,6 @@ 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,- typename constraint<+ constraint_t< is_convertible<Executor1, Executor>::value- >::type = 0)+ > = 0) : service_(other.service_), executor_(other.executor_) {- service_->move_construct(impl_, *other.service_, other.impl_);+ service_->move_construct(impl_, other.impl_); } /// Move-assign a basic_channel from another.@@ -259,10 +259,10 @@ * constructor. */ template <typename Executor1>- typename constraint<+ constraint_t< is_convertible<Executor1, Executor>::value, basic_channel&- >::type operator=(basic_channel<Executor1, Traits, Signatures...>&& other)+ > operator=(basic_channel<Executor1, Traits, Signatures...>&& other) { if (this != &other) {@@ -273,7 +273,6 @@ } return *this; }-#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Destructor. ~basic_channel()@@ -282,19 +281,19 @@ } /// Get the executor associated with the object.- const executor_type& get_executor() ASIO_NOEXCEPT+ const executor_type& get_executor() noexcept { return executor_; } /// Get the capacity of the channel's buffer.- std::size_t capacity() ASIO_NOEXCEPT+ std::size_t capacity() noexcept { return service_->capacity(impl_); } /// Determine whether the channel is open.- bool is_open() const ASIO_NOEXCEPT+ bool is_open() const noexcept { return service_->is_open(impl_); }@@ -323,7 +322,7 @@ } /// Determine whether a message can be received without blocking.- bool ready() const ASIO_NOEXCEPT+ bool ready() const noexcept { return service_->ready(impl_); }@@ -337,15 +336,39 @@ * @returns @c true on success, @c false on failure. */ template <typename... Args>- bool try_send(ASIO_MOVE_ARG(Args)... 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);+ /// 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, ASIO_MOVE_ARG(Args)... 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);+ /// Asynchronously send a message. /** * @par Completion Signature@@ -354,8 +377,8 @@ template <typename... Args, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code)) CompletionToken ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>- auto async_send(ASIO_MOVE_ARG(Args)... args,- ASIO_MOVE_ARG(CompletionToken) token);+ auto async_send(Args&&... args,+ CompletionToken&& token); #endif // defined(GENERATING_DOCUMENTATION) @@ -366,9 +389,9 @@ * @returns @c true on success, @c false on failure. */ template <typename Handler>- bool try_receive(ASIO_MOVE_ARG(Handler) handler)+ bool try_receive(Handler&& handler) {- return service_->try_receive(impl_, ASIO_MOVE_CAST(Handler)(handler));+ return service_->try_receive(impl_, static_cast<Handler&&>(handler)); } /// Asynchronously receive a message.@@ -380,22 +403,22 @@ template <typename CompletionToken ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)> auto async_receive(- ASIO_MOVE_ARG(CompletionToken) token+ CompletionToken&& token ASIO_DEFAULT_COMPLETION_TOKEN(Executor)) #if !defined(GENERATING_DOCUMENTATION) -> decltype( this->do_async_receive(static_cast<payload_type*>(0),- ASIO_MOVE_CAST(CompletionToken)(token)))+ static_cast<CompletionToken&&>(token))) #endif // !defined(GENERATING_DOCUMENTATION) { return this->do_async_receive(static_cast<payload_type*>(0),- ASIO_MOVE_CAST(CompletionToken)(token));+ static_cast<CompletionToken&&>(token)); } private: // Disallow copying and assignment.- basic_channel(const basic_channel&) ASIO_DELETED;- basic_channel& operator=(const basic_channel&) ASIO_DELETED;+ basic_channel(const basic_channel&) = delete;+ basic_channel& operator=(const basic_channel&) = delete; template <typename, typename, typename...> friend class detail::channel_send_functions;@@ -403,7 +426,7 @@ // Helper function to get an executor's context. template <typename T> static execution_context& get_context(const T& t,- typename enable_if<execution::is_executor<T>::value>::type* = 0)+ enable_if_t<execution::is_executor<T>::value>* = 0) { return asio::query(t, execution::context); }@@ -411,7 +434,7 @@ // Helper function to get an executor's context. template <typename T> static execution_context& get_context(const T& t,- typename enable_if<!execution::is_executor<T>::value>::type* = 0)+ enable_if_t<!execution::is_executor<T>::value>* = 0) { return t.context(); }@@ -426,18 +449,18 @@ { } - const executor_type& get_executor() const ASIO_NOEXCEPT+ const executor_type& get_executor() const noexcept { return self_->get_executor(); } template <typename SendHandler>- void operator()(ASIO_MOVE_ARG(SendHandler) handler,- ASIO_MOVE_ARG(payload_type) payload) const+ void operator()(SendHandler&& handler,+ payload_type&& payload) const { asio::detail::non_const_lvalue<SendHandler> handler2(handler); self_->service_->async_send(self_->impl_,- ASIO_MOVE_CAST(payload_type)(payload),+ static_cast<payload_type&&>(payload), handler2.value, self_->get_executor()); } @@ -455,13 +478,13 @@ { } - const executor_type& get_executor() const ASIO_NOEXCEPT+ const executor_type& get_executor() const noexcept { return self_->get_executor(); } template <typename ReceiveHandler>- void operator()(ASIO_MOVE_ARG(ReceiveHandler) handler) const+ void operator()(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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -110,8 +110,9 @@ template <typename... PayloadSignatures, ASIO_COMPLETION_TOKEN_FOR(PayloadSignatures...) CompletionToken>- auto do_async_receive(detail::channel_payload<PayloadSignatures...>*,- ASIO_MOVE_ARG(CompletionToken) token)+ auto do_async_receive(+ asio::detail::completion_payload<PayloadSignatures...>*,+ CompletionToken&& token) -> decltype( async_initiate<CompletionToken, PayloadSignatures...>( declval<initiate_async_receive>(), token))@@ -169,10 +170,10 @@ template <typename ExecutionContext> basic_concurrent_channel(ExecutionContext& context, std::size_t max_buffer_size = 0,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- >::type = defaulted_constraint())+ > = defaulted_constraint()) : service_(&asio::use_service<service_type>(context)), impl_(), executor_(context.get_executor())@@ -180,7 +181,6 @@ 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,- typename constraint<+ constraint_t< is_convertible<Executor1, Executor>::value- >::type = 0)+ > = 0) : service_(other.service_), executor_(other.executor_) {- service_->move_construct(impl_, *other.service_, other.impl_);+ service_->move_construct(impl_, other.impl_); } /// Move-assign a basic_concurrent_channel from another.@@ -265,10 +265,10 @@ * constructor. */ template <typename Executor1>- typename constraint<+ constraint_t< is_convertible<Executor1, Executor>::value, basic_concurrent_channel&- >::type operator=(+ > operator=( basic_concurrent_channel<Executor1, Traits, Signatures...>&& other) { if (this != &other)@@ -280,7 +280,6 @@ } return *this; }-#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Destructor. ~basic_concurrent_channel()@@ -289,19 +288,19 @@ } /// Get the executor associated with the object.- const executor_type& get_executor() ASIO_NOEXCEPT+ const executor_type& get_executor() noexcept { return executor_; } /// Get the capacity of the channel's buffer.- std::size_t capacity() ASIO_NOEXCEPT+ std::size_t capacity() noexcept { return service_->capacity(impl_); } /// Determine whether the channel is open.- bool is_open() const ASIO_NOEXCEPT+ bool is_open() const noexcept { return service_->is_open(impl_); }@@ -330,7 +329,7 @@ } /// Determine whether a message can be received without blocking.- bool ready() const ASIO_NOEXCEPT+ bool ready() const noexcept { return service_->ready(impl_); }@@ -344,21 +343,45 @@ * @returns @c true on success, @c false on failure. */ template <typename... Args>- bool try_send(ASIO_MOVE_ARG(Args)... 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);+ /// 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, ASIO_MOVE_ARG(Args)... 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);+ /// 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(ASIO_MOVE_ARG(Args)... args,- ASIO_MOVE_ARG(CompletionToken) token);+ auto async_send(Args&&... args,+ CompletionToken&& token); #endif // defined(GENERATING_DOCUMENTATION) @@ -369,33 +392,33 @@ * @returns @c true on success, @c false on failure. */ template <typename Handler>- bool try_receive(ASIO_MOVE_ARG(Handler) handler)+ bool try_receive(Handler&& handler) {- return service_->try_receive(impl_, ASIO_MOVE_CAST(Handler)(handler));+ return service_->try_receive(impl_, static_cast<Handler&&>(handler)); } /// Asynchronously receive a message. template <typename CompletionToken ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)> auto async_receive(- ASIO_MOVE_ARG(CompletionToken) token+ CompletionToken&& token ASIO_DEFAULT_COMPLETION_TOKEN(Executor)) #if !defined(GENERATING_DOCUMENTATION) -> decltype( this->do_async_receive(static_cast<payload_type*>(0),- ASIO_MOVE_CAST(CompletionToken)(token)))+ static_cast<CompletionToken&&>(token))) #endif // !defined(GENERATING_DOCUMENTATION) { return this->do_async_receive(static_cast<payload_type*>(0),- ASIO_MOVE_CAST(CompletionToken)(token));+ static_cast<CompletionToken&&>(token)); } private: // Disallow copying and assignment. basic_concurrent_channel(- const basic_concurrent_channel&) ASIO_DELETED;+ const basic_concurrent_channel&) = delete; basic_concurrent_channel& operator=(- const basic_concurrent_channel&) ASIO_DELETED;+ const basic_concurrent_channel&) = delete; template <typename, typename, typename...> friend class detail::channel_send_functions;@@ -403,7 +426,7 @@ // Helper function to get an executor's context. template <typename T> static execution_context& get_context(const T& t,- typename enable_if<execution::is_executor<T>::value>::type* = 0)+ enable_if_t<execution::is_executor<T>::value>* = 0) { return asio::query(t, execution::context); }@@ -411,7 +434,7 @@ // Helper function to get an executor's context. template <typename T> static execution_context& get_context(const T& t,- typename enable_if<!execution::is_executor<T>::value>::type* = 0)+ enable_if_t<!execution::is_executor<T>::value>* = 0) { return t.context(); }@@ -426,18 +449,18 @@ { } - const executor_type& get_executor() const ASIO_NOEXCEPT+ const executor_type& get_executor() const noexcept { return self_->get_executor(); } template <typename SendHandler>- void operator()(ASIO_MOVE_ARG(SendHandler) handler,- ASIO_MOVE_ARG(payload_type) payload) const+ void operator()(SendHandler&& handler,+ payload_type&& payload) const { asio::detail::non_const_lvalue<SendHandler> handler2(handler); self_->service_->async_send(self_->impl_,- ASIO_MOVE_CAST(payload_type)(payload),+ static_cast<payload_type&&>(payload), handler2.value, self_->get_executor()); } @@ -455,13 +478,13 @@ { } - const executor_type& get_executor() const ASIO_NOEXCEPT+ const executor_type& get_executor() const noexcept { return self_->get_executor(); } template <typename ReceiveHandler>- void operator()(ASIO_MOVE_ARG(ReceiveHandler) handler) const+ void operator()(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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -16,9 +16,8 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"-#include <exception> #include "asio/cancellation_type.hpp"-#include "asio/error_code.hpp"+#include "asio/disposition.hpp" #include "asio/detail/type_traits.hpp" #include "asio/detail/push_options.hpp"@@ -31,8 +30,7 @@ { public: template <typename... Args>- ASIO_CONSTEXPR cancellation_type_t operator()(- Args&&...) const ASIO_NOEXCEPT+ constexpr cancellation_type_t operator()(Args&&...) const noexcept { return cancellation_type::none; }@@ -42,15 +40,14 @@ class wait_for_one { public:- ASIO_CONSTEXPR explicit wait_for_one(+ constexpr explicit wait_for_one( cancellation_type_t cancel_type = cancellation_type::all) : cancel_type_(cancel_type) { } template <typename... Args>- ASIO_CONSTEXPR cancellation_type_t operator()(- Args&&...) const ASIO_NOEXCEPT+ constexpr cancellation_type_t operator()(Args&&...) const noexcept { return cancel_type_; }@@ -67,36 +64,30 @@ class wait_for_one_success { public:- ASIO_CONSTEXPR explicit wait_for_one_success(+ constexpr explicit wait_for_one_success( cancellation_type_t cancel_type = cancellation_type::all) : cancel_type_(cancel_type) { } - ASIO_CONSTEXPR cancellation_type_t- operator()() const ASIO_NOEXCEPT+ constexpr cancellation_type_t+ operator()() const noexcept { return cancel_type_; } template <typename E, typename... Args>- 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+ constexpr constraint_t<!is_disposition<E>::value, cancellation_type_t>+ operator()(const E&, Args&&...) const noexcept { return cancel_type_; } template <typename E, typename... Args>- 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+ constexpr constraint_t<is_disposition<E>::value, cancellation_type_t>+ operator()(const E& e, Args&&...) const noexcept {- return !!e ? cancellation_type::none : cancel_type_;+ return e != no_error ? cancellation_type::none : cancel_type_; } private:@@ -111,36 +102,29 @@ class wait_for_one_error { public:- ASIO_CONSTEXPR explicit wait_for_one_error(+ constexpr explicit wait_for_one_error( cancellation_type_t cancel_type = cancellation_type::all) : cancel_type_(cancel_type) { } - ASIO_CONSTEXPR cancellation_type_t- operator()() const ASIO_NOEXCEPT+ constexpr cancellation_type_t operator()() const noexcept { return cancellation_type::none; } template <typename E, typename... Args>- 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+ constexpr constraint_t<!is_disposition<E>::value, cancellation_type_t>+ operator()(const E&, Args&&...) const noexcept { return cancellation_type::none; } template <typename E, typename... Args>- 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+ constexpr constraint_t<is_disposition<E>::value, cancellation_type_t>+ operator()(const E& e, Args&&...) const noexcept {- return !!e ? cancel_type_ : cancellation_type::none;+ return e != no_error ? 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -42,10 +42,10 @@ template <typename ExecutorOrSignature> struct channel_type<ExecutorOrSignature,- typename enable_if<+ enable_if_t< is_executor<ExecutorOrSignature>::value || execution::is_executor<ExecutorOrSignature>::value- >::type>+ >> { template <typename... Signatures> struct inner@@ -58,9 +58,15 @@ } // 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -49,7 +49,6 @@ } // namespace experimental } // namespace asio -#if defined(ASIO_HAS_STD_SYSTEM_ERROR) namespace std { template<> struct is_error_code_enum<@@ -59,7 +58,6 @@ }; } // 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -102,7 +102,7 @@ static void invoke_receive_cancelled(F f) { const asio::error_code e = error::channel_cancelled;- ASIO_MOVE_OR_LVALUE(F)(f)(e);+ static_cast<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;- ASIO_MOVE_OR_LVALUE(F)(f)(e);+ static_cast<F&&>(f)(e); } }; @@ -136,7 +136,7 @@ static void invoke_receive_cancelled(F f) { const asio::error_code e = error::channel_cancelled;- ASIO_MOVE_OR_LVALUE(F)(f)(e, typename decay<Args>::type()...);+ static_cast<F&&>(f)(e, decay_t<Args>()...); } 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;- ASIO_MOVE_OR_LVALUE(F)(f)(e, typename decay<Args>::type()...);+ static_cast<F&&>(f)(e, decay_t<Args>()...); } }; @@ -170,7 +170,7 @@ static void invoke_receive_cancelled(F f) { const asio::error_code e = error::channel_cancelled;- ASIO_MOVE_OR_LVALUE(F)(f)(+ static_cast<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;- ASIO_MOVE_OR_LVALUE(F)(f)(+ static_cast<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;- ASIO_MOVE_OR_LVALUE(F)(f)(+ static_cast<F&&>(f)( std::make_exception_ptr(asio::system_error(e)),- typename decay<Args>::type()...);+ decay_t<Args>()...); } 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;- ASIO_MOVE_OR_LVALUE(F)(f)(+ static_cast<F&&>(f)( std::make_exception_ptr(asio::system_error(e)),- typename decay<Args>::type()...);+ decay_t<Args>()...); } }; @@ -244,7 +244,7 @@ static void invoke_receive_cancelled(F f) { const asio::error_code e = error::channel_cancelled;- ASIO_MOVE_OR_LVALUE(F)(f)(e);+ static_cast<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;- ASIO_MOVE_OR_LVALUE(F)(f)(e);+ static_cast<F&&>(f)(e); } }; @@ -278,7 +278,7 @@ static void invoke_receive_cancelled(F f) { const asio::error_code e = error::channel_cancelled;- ASIO_MOVE_OR_LVALUE(F)(f)(e);+ static_cast<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;- ASIO_MOVE_OR_LVALUE(F)(f)(e);+ static_cast<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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -16,129 +16,18 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"-#include "asio/async_result.hpp"+#include "asio/co_composed.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace experimental { -/// 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);+using asio::co_composed; } // 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/experimental/deferred.hpp"-#include "asio/experimental/prepend.hpp"+#include "asio/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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -42,10 +42,10 @@ template <typename ExecutorOrSignature> struct concurrent_channel_type<ExecutorOrSignature,- typename enable_if<+ enable_if_t< is_executor<ExecutorOrSignature>::value || execution::is_executor<ExecutorOrSignature>::value- >::type>+ >> { template <typename... Signatures> struct inner@@ -58,9 +58,15 @@ } // 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
@@ -1,36 +0,0 @@-//-// 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
@@ -1,80 +0,0 @@-//-// 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
@@ -1,129 +0,0 @@-//-// 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -39,7 +39,7 @@ class channel_operation ASIO_INHERIT_TRACKED_HANDLER { public:- template <typename Executor, typename = void>+ template <typename Executor, typename = void, typename = void> class handler_work_base; template <typename Handler, typename IoExecutor, typename = void>@@ -55,9 +55,10 @@ { destroy_op = 0, immediate_op = 1,- complete_op = 2,- cancel_op = 3,- close_op = 4+ post_op = 2,+ dispatch_op = 3,+ cancel_op = 4,+ close_op = 5 }; typedef void (*func_type)(channel_operation*, action, void*);@@ -83,46 +84,98 @@ void* cancellation_key_; }; -template <typename Executor, typename>+template <typename Executor, typename, typename> class channel_operation::handler_work_base { public:- typedef typename decay<- typename prefer_result<Executor,+ typedef decay_t<+ prefer_result_t<Executor, execution::outstanding_work_t::tracked_t- >::type- >::type executor_type;+ >+ > executor_type; handler_work_base(int, const Executor& ex) : executor_(asio::prefer(ex, execution::outstanding_work.tracked)) { } - const executor_type& get_executor() const ASIO_NOEXCEPT+ const executor_type& get_executor() const 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 post(Function& function, Handler& handler)+ void dispatch(Function& function, Handler& handler) {- typename associated_allocator<Handler>::type allocator =+ associated_allocator_t<Handler> allocator = (get_associated_allocator)(handler); -#if defined(ASIO_NO_DEPRECATED)+ 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)+ {+ associated_allocator_t<Handler> allocator =+ (get_associated_allocator)(handler);+ asio::prefer( asio::require(executor_, execution::blocking.never), execution::allocator(allocator)- ).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)+ ).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));+ }+ private: executor_type executor_; };@@ -131,9 +184,10 @@ template <typename Executor> class channel_operation::handler_work_base<Executor,- typename enable_if<+ enable_if_t< !execution::is_executor<Executor>::value- >::type>+ >+ > { public: typedef Executor executor_type;@@ -143,21 +197,31 @@ { } - executor_type get_executor() const ASIO_NOEXCEPT+ executor_type get_executor() const noexcept { return work_.get_executor(); } - template <typename Function, typename Handler>- void post(Function& function, Handler& handler)+ template <typename IoExecutor, typename Function, typename Handler>+ void post(const IoExecutor&, Function& function, Handler& handler) {- typename associated_allocator<Handler>::type allocator =+ associated_allocator_t<Handler> allocator = (get_associated_allocator)(handler); work_.get_executor().post(- ASIO_MOVE_CAST(Function)(function), allocator);+ static_cast<Function&&>(function), allocator); } + template <typename Function, typename Handler>+ void dispatch(Function& function, Handler& handler)+ {+ associated_allocator_t<Handler> allocator =+ (get_associated_allocator)(handler);++ work_.get_executor().dispatch(+ static_cast<Function&&>(function), allocator);+ }+ private: executor_work_guard<Executor> work_; };@@ -168,110 +232,123 @@ class channel_operation::handler_work : channel_operation::handler_work_base<IoExecutor>, channel_operation::handler_work_base<- typename associated_executor<Handler, IoExecutor>::type, IoExecutor>+ associated_executor_t<Handler, IoExecutor>, IoExecutor> { public: typedef channel_operation::handler_work_base<IoExecutor> base1_type; typedef channel_operation::handler_work_base<- typename associated_executor<Handler, IoExecutor>::type, IoExecutor>+ associated_executor_t<Handler, IoExecutor>, IoExecutor> base2_type; - handler_work(Handler& handler, const IoExecutor& io_ex) ASIO_NOEXCEPT+ handler_work(Handler& handler, const IoExecutor& io_ex) noexcept : base1_type(0, io_ex), base2_type(0, (get_associated_executor)(handler, io_ex)) { } template <typename Function>- void complete(Function& function, Handler& handler)+ void post(Function& function, Handler& handler) {- base2_type::post(function, handler);+ base2_type::post(base1_type::get_executor(), function, handler); } template <typename Function>+ void dispatch(Function& function, Handler& handler)+ {+ base2_type::dispatch(function, handler);+ }++ template <typename Function> void immediate(Function& function, Handler& handler, ...) {- typedef typename associated_immediate_executor<Handler,- typename base1_type::executor_type>::type immediate_ex_type;+ typedef associated_immediate_executor_t<Handler,+ typename base1_type::executor_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))(ASIO_MOVE_CAST(Function)(function));+ immediate_ex))(static_cast<Function&&>(function)); } template <typename Function> void immediate(Function& function, Handler&,- typename enable_if<+ enable_if_t< is_same< typename associated_immediate_executor<- typename conditional<false, Function, Handler>::type,+ conditional_t<false, Function, Handler>, 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()))(- ASIO_MOVE_CAST(Function)(function));+ static_cast<Function&&>(function)); } }; template <typename Handler, typename IoExecutor> class channel_operation::handler_work< Handler, IoExecutor,- typename enable_if<+ enable_if_t< is_same< typename associated_executor<Handler, IoExecutor>::asio_associated_executor_is_unspecialised, void >::value- >::type> : handler_work_base<IoExecutor>+ >+ > : handler_work_base<IoExecutor> { public: typedef channel_operation::handler_work_base<IoExecutor> base1_type; - handler_work(Handler&, const IoExecutor& io_ex) ASIO_NOEXCEPT+ handler_work(Handler&, const IoExecutor& io_ex) noexcept : base1_type(0, io_ex) { } template <typename Function>- void complete(Function& function, Handler& handler)+ void post(Function& function, Handler& handler) {- base1_type::post(function, handler);+ base1_type::post(base1_type::get_executor(), function, handler); } template <typename Function>+ void dispatch(Function& function, Handler& handler)+ {+ base1_type::dispatch(function, handler);+ }++ template <typename Function> void immediate(Function& function, Handler& handler, ...) {- typedef typename associated_immediate_executor<Handler,- typename base1_type::executor_type>::type immediate_ex_type;+ typedef associated_immediate_executor_t<Handler,+ typename base1_type::executor_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))(ASIO_MOVE_CAST(Function)(function));+ immediate_ex))(static_cast<Function&&>(function)); } template <typename Function> void immediate(Function& function, Handler& handler,- typename enable_if<+ enable_if_t< is_same< typename associated_immediate_executor<- typename conditional<false, Function, Handler>::type,+ conditional_t<false, Function, Handler>, typename base1_type::executor_type>:: asio_associated_immediate_executor_is_unspecialised, void >::value- >::type*)+ >*) {- base1_type::post(function, handler);+ base1_type::post(base1_type::get_executor(), function, handler); } };
− link/modules/asio-standalone/asio/include/asio/experimental/detail/channel_payload.hpp
@@ -1,139 +0,0 @@-//-// 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -17,11 +17,10 @@ #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" @@ -38,11 +37,16 @@ func_(this, immediate_op, &payload); } - void complete(Payload payload)+ void post(Payload payload) {- func_(this, complete_op, &payload);+ func_(this, post_op, &payload); } + void dispatch(Payload payload)+ {+ func_(this, dispatch_op, &payload);+ }+ protected: channel_receive(func_type func) : channel_operation(func)@@ -59,7 +63,7 @@ template <typename... Args> channel_receive_op(Handler& handler, const IoExecutor& io_ex) : channel_receive<Payload>(&channel_receive_op::do_action),- handler_(ASIO_MOVE_CAST(Handler)(handler)),+ handler_(static_cast<Handler&&>(handler)), work_(handler_, io_ex) { }@@ -75,8 +79,8 @@ // Take ownership of the operation's outstanding work. channel_operation::handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(channel_operation::handler_work<- Handler, IoExecutor>)(o->work_));+ static_cast<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@@ -87,15 +91,17 @@ if (a != channel_operation::destroy_op) { Payload* payload = static_cast<Payload*>(v);- channel_handler<Payload, Handler> handler(- ASIO_MOVE_CAST(Payload)(*payload), o->handler_);+ asio::detail::completion_payload_handler<Payload, Handler> handler(+ static_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.complete(handler, handler.handler_);+ w.post(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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -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,48 +35,76 @@ { public: template <typename... Args2>- typename enable_if<- is_constructible<detail::channel_message<R(Args...)>, int, Args2...>::value,+ enable_if_t<+ is_constructible<asio::detail::completion_message<R(Args...)>,+ int, Args2...>::value, bool- >::type try_send(ASIO_MOVE_ARG(Args2)... args)+ > try_send(Args2&&... args) {- typedef typename detail::channel_message<R(Args...)> message_type;+ 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_, ASIO_MOVE_CAST(Args2)(args)...);+ self->impl_, false, static_cast<Args2&&>(args)...); } template <typename... Args2>- typename enable_if<- is_constructible<detail::channel_message<R(Args...)>, int, Args2...>::value,+ enable_if_t<+ is_constructible<asio::detail::completion_message<R(Args...)>,+ int, Args2...>::value,+ bool+ > try_send_via_dispatch(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_, 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- >::type try_send_n(std::size_t count, ASIO_MOVE_ARG(Args2)... args)+ > try_send_n(std::size_t count, Args2&&... args) {- typedef typename detail::channel_message<R(Args...)> message_type;+ 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, ASIO_MOVE_CAST(Args2)(args)...);+ self->impl_, count, false, 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_via_dispatch(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, true, static_cast<Args2&&>(args)...);+ }+ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code)) CompletionToken ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(Executor)> auto async_send(Args... args,- ASIO_MOVE_ARG(CompletionToken) token+ CompletionToken&& token ASIO_DEFAULT_COMPLETION_TOKEN(Executor)) -> decltype( async_initiate<CompletionToken, void (asio::error_code)>(- declval<typename conditional<false, CompletionToken,- Derived>::type::initiate_async_send>(), token,- declval<typename conditional<false, CompletionToken,- Derived>::type::payload_type>()))+ declval<typename conditional_t<false, CompletionToken,+ Derived>::initiate_async_send>(), token,+ declval<typename conditional_t<false, CompletionToken,+ Derived>::payload_type>())) { typedef typename Derived::payload_type payload_type;- typedef typename detail::channel_message<R(Args...)> message_type;+ typedef asio::detail::completion_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, ASIO_MOVE_CAST(Args)(args)...)));+ payload_type(message_type(0, static_cast<Args&&>(args)...))); } }; @@ -90,48 +118,76 @@ using channel_send_functions<Derived, Executor, Signatures...>::async_send; template <typename... Args2>- typename enable_if<- is_constructible<detail::channel_message<R(Args...)>, int, Args2...>::value,+ enable_if_t<+ is_constructible<asio::detail::completion_message<R(Args...)>,+ int, Args2...>::value, bool- >::type try_send(ASIO_MOVE_ARG(Args2)... args)+ > try_send(Args2&&... args) {- typedef typename detail::channel_message<R(Args...)> message_type;+ 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_, ASIO_MOVE_CAST(Args2)(args)...);+ self->impl_, false, static_cast<Args2&&>(args)...); } template <typename... Args2>- typename enable_if<- is_constructible<detail::channel_message<R(Args...)>, int, Args2...>::value,+ enable_if_t<+ is_constructible<asio::detail::completion_message<R(Args...)>,+ int, Args2...>::value,+ bool+ > try_send_via_dispatch(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_, 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- >::type try_send_n(std::size_t count, ASIO_MOVE_ARG(Args2)... args)+ > try_send_n(std::size_t count, Args2&&... args) {- typedef typename detail::channel_message<R(Args...)> message_type;+ 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, ASIO_MOVE_CAST(Args2)(args)...);+ self->impl_, count, false, 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_via_dispatch(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, true, static_cast<Args2&&>(args)...);+ }+ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code)) CompletionToken ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(Executor)> auto async_send(Args... args,- ASIO_MOVE_ARG(CompletionToken) token+ CompletionToken&& token ASIO_DEFAULT_COMPLETION_TOKEN(Executor)) -> decltype( async_initiate<CompletionToken, void (asio::error_code)>(- declval<typename conditional<false, CompletionToken,- Derived>::type::initiate_async_send>(), token,- declval<typename conditional<false, CompletionToken,- Derived>::type::payload_type>()))+ declval<typename conditional_t<false, CompletionToken,+ Derived>::initiate_async_send>(), token,+ declval<typename conditional_t<false, CompletionToken,+ Derived>::payload_type>())) { typedef typename Derived::payload_type payload_type;- typedef typename detail::channel_message<R(Args...)> message_type;+ typedef asio::detail::completion_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, ASIO_MOVE_CAST(Args)(args)...)));+ payload_type(message_type(0, static_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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -21,7 +21,6 @@ #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" @@ -35,7 +34,7 @@ public: Payload get_payload() {- return ASIO_MOVE_CAST(Payload)(payload_);+ return static_cast<Payload&&>(payload_); } void immediate()@@ -43,9 +42,9 @@ func_(this, immediate_op, 0); } - void complete()+ void post() {- func_(this, complete_op, 0);+ func_(this, post_op, 0); } void cancel()@@ -59,9 +58,9 @@ } protected:- channel_send(func_type func, ASIO_MOVE_ARG(Payload) payload)+ channel_send(func_type func, Payload&& payload) : channel_operation(func),- payload_(ASIO_MOVE_CAST(Payload)(payload))+ payload_(static_cast<Payload&&>(payload)) { } @@ -75,11 +74,11 @@ public: ASIO_DEFINE_HANDLER_PTR(channel_send_op); - channel_send_op(ASIO_MOVE_ARG(Payload) payload,+ channel_send_op(Payload&& payload, Handler& handler, const IoExecutor& io_ex) : channel_send<Payload>(&channel_send_op::do_action,- ASIO_MOVE_CAST(Payload)(payload)),- handler_(ASIO_MOVE_CAST(Handler)(handler)),+ static_cast<Payload&&>(payload)),+ handler_(static_cast<Handler&&>(handler)), work_(handler_, io_ex) { }@@ -95,8 +94,8 @@ // Take ownership of the operation's outstanding work. channel_operation::handler_work<Handler, IoExecutor> w(- ASIO_MOVE_CAST2(channel_operation::handler_work<- Handler, IoExecutor>)(o->work_));+ static_cast<channel_operation::handler_work<Handler, IoExecutor>&&>(+ o->work_)); asio::error_code ec; switch (a)@@ -129,7 +128,7 @@ if (a == channel_operation::immediate_op) w.immediate(handler, handler.handler_, 0); else- w.complete(handler, handler.handler_);+ w.post(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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -18,10 +18,12 @@ #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"@@ -35,7 +37,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.@@ -83,7 +85,7 @@ struct implementation_type; // Constructor.- channel_service(execution_context& ctx);+ channel_service(asio::execution_context& ctx); // Destroy all user-defined handler objects owned by the service. void shutdown();@@ -108,10 +110,10 @@ // Get the capacity of the channel. std::size_t capacity(- const base_implementation_type& impl) const ASIO_NOEXCEPT;+ const base_implementation_type& impl) const noexcept; // Determine whether the channel is open.- bool is_open(const base_implementation_type& impl) const ASIO_NOEXCEPT;+ bool is_open(const base_implementation_type& impl) const noexcept; // Reset the channel to its initial state. template <typename Traits, typename... Signatures>@@ -131,29 +133,29 @@ void* cancellation_key); // Determine whether a value can be read from the channel without blocking.- bool ready(const base_implementation_type& impl) const ASIO_NOEXCEPT;+ bool ready(const base_implementation_type& impl) const 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,- ASIO_MOVE_ARG(Args)... args);+ bool via_dispatch, 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, ASIO_MOVE_ARG(Args)... args);+ std::size_t count, bool via_dispatch, 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,- ASIO_MOVE_ARG2(typename implementation_type<- Traits, Signatures...>::payload_type) payload,+ typename implementation_type<Traits,+ Signatures...>::payload_type&& payload, Handler& handler, const IoExecutor& io_ex) {- typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -162,14 +164,14 @@ Handler, IoExecutor> op; typename op::ptr p = { asio::detail::addressof(handler), op::ptr::allocate(handler), 0 };- p.p = new (p.v) op(ASIO_MOVE_CAST2(typename implementation_type<- Traits, Signatures...>::payload_type)(payload), handler, io_ex);+ p.p = new (p.v) op(static_cast<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); } @@ -183,7 +185,7 @@ // Synchronously receive a value from the channel. template <typename Traits, typename... Signatures, typename Handler> bool try_receive(implementation_type<Traits, Signatures...>& impl,- ASIO_MOVE_ARG(Handler) handler);+ Handler&& handler); // Asynchronously receive a value from the channel. template <typename Traits, typename... Signatures,@@ -191,7 +193,7 @@ void async_receive(implementation_type<Traits, Signatures...>& impl, Handler& handler, const IoExecutor& io_ex) {- typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> slot = asio::get_associated_cancellation_slot(handler); // Allocate and construct an operation to wrap the handler.@@ -206,7 +208,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); } @@ -220,19 +222,19 @@ private: // Helper function object to handle a closed notification. template <typename Payload, typename Signature>- struct complete_receive+ struct post_receive {- explicit complete_receive(channel_receive<Payload>* op)+ explicit post_receive(channel_receive<Payload>* op) : op_(op) { } template <typename... Args>- void operator()(ASIO_MOVE_ARG(Args)... args)+ void operator()(Args&&... args) {- op_->complete(- channel_message<Signature>(0,- ASIO_MOVE_CAST(Args)(args)...));+ op_->post(+ asio::detail::completion_message<Signature>(0,+ static_cast<Args&&>(args)...)); } channel_receive<Payload>* op_;@@ -297,46 +299,46 @@ typedef typename Traits::template rebind<Signatures...>::other traits_type; // Type of an element stored in the buffer.- typedef typename conditional<+ typedef conditional_t< has_signature< typename traits_type::receive_cancelled_signature, Signatures... >::value,- typename conditional<+ conditional_t< has_signature< typename traits_type::receive_closed_signature, Signatures... >::value,- channel_payload<Signatures...>,- channel_payload<+ asio::detail::completion_payload<Signatures...>,+ asio::detail::completion_payload< Signatures..., typename traits_type::receive_closed_signature >- >::type,- typename conditional<+ >,+ conditional_t< has_signature< typename traits_type::receive_closed_signature, Signatures..., typename traits_type::receive_cancelled_signature >::value,- channel_payload<+ asio::detail::completion_payload< Signatures..., typename traits_type::receive_cancelled_signature >,- channel_payload<+ asio::detail::completion_payload< Signatures..., typename traits_type::receive_cancelled_signature, typename traits_type::receive_closed_signature >- >::type- >::type payload_type;+ >+ > payload_type; // Move from another buffer. void buffer_move_from(implementation_type& other) {- buffer_ = ASIO_MOVE_CAST(- typename traits_type::template container<- payload_type>::type)(other.buffer_);+ buffer_ = static_cast<+ typename traits_type::template container<payload_type>::type&&>(+ other.buffer_); other.buffer_clear(); } @@ -349,7 +351,7 @@ // Push a new value to the back of the buffer. void buffer_push(payload_type payload) {- buffer_.push_back(ASIO_MOVE_CAST(payload_type)(payload));+ buffer_.push_back(static_cast<payload_type&&>(payload)); } // Push new values to the back of the buffer.@@ -364,7 +366,7 @@ // Get the element at the front of the buffer. payload_type buffer_front() {- return ASIO_MOVE_CAST(payload_type)(buffer_.front());+ return static_cast<payload_type&&>(buffer_.front()); } // Pop a value from the front of the buffer.@@ -394,39 +396,39 @@ typedef typename Traits::template rebind<R()>::other traits_type; // Type of an element stored in the buffer.- typedef typename conditional<+ typedef conditional_t< has_signature< typename traits_type::receive_cancelled_signature, R() >::value,- typename conditional<+ conditional_t< has_signature< typename traits_type::receive_closed_signature, R() >::value,- channel_payload<R()>,- channel_payload<+ asio::detail::completion_payload<R()>,+ asio::detail::completion_payload< R(), typename traits_type::receive_closed_signature >- >::type,- typename conditional<+ >,+ conditional_t< has_signature< typename traits_type::receive_closed_signature, R(), typename traits_type::receive_cancelled_signature >::value,- channel_payload<+ asio::detail::completion_payload< R(), typename traits_type::receive_cancelled_signature >,- channel_payload<+ asio::detail::completion_payload< R(), typename traits_type::receive_cancelled_signature, typename traits_type::receive_closed_signature >- >::type- >::type payload_type;+ >+ > payload_type; // Construct with empty buffer. implementation_type()@@ -465,7 +467,7 @@ // Get the element at the front of the buffer. payload_type buffer_front() {- return payload_type(channel_message<R()>(0));+ return payload_type(asio::detail::completion_message<R()>(0)); } // Pop a value from the front of the buffer.@@ -497,39 +499,39 @@ traits_type; // Type of an element stored in the buffer.- typedef typename conditional<+ typedef conditional_t< has_signature< typename traits_type::receive_cancelled_signature, R(asio::error_code) >::value,- typename conditional<+ conditional_t< has_signature< typename traits_type::receive_closed_signature, R(asio::error_code) >::value,- channel_payload<R(asio::error_code)>,- channel_payload<+ asio::detail::completion_payload<R(asio::error_code)>,+ asio::detail::completion_payload< R(asio::error_code), typename traits_type::receive_closed_signature >- >::type,- typename conditional<+ >,+ conditional_t< has_signature< typename traits_type::receive_closed_signature, R(asio::error_code), typename traits_type::receive_cancelled_signature >::value,- channel_payload<+ asio::detail::completion_payload< R(asio::error_code), typename traits_type::receive_cancelled_signature >,- channel_payload<+ asio::detail::completion_payload< R(asio::error_code), typename traits_type::receive_cancelled_signature, typename traits_type::receive_closed_signature >- >::type- >::type payload_type;+ >+ > payload_type; // Construct with empty buffer. implementation_type()@@ -541,13 +543,13 @@ // Move from another buffer. void buffer_move_from(implementation_type& other) {- size_ = other.buffer_;+ size_ = other.size_; other.size_ = 0; first_ = other.first_;- other.first.count_ = 0;- rest_ = ASIO_MOVE_CAST(- typename traits_type::template container<- buffered_value>::type)(other.rest_);+ other.first_.count_ = 0;+ rest_ = static_cast<+ typename traits_type::template container<buffered_value>::type&&>(+ other.rest_); other.buffer_clear(); } @@ -628,7 +630,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,6 +13,7 @@ #define ASIO_EXPERIMENTAL_DETAIL_CORO_PROMISE_ALLOCATOR_HPP #include "asio/detail/config.hpp"+#include <limits> #include "asio/experimental/coro_traits.hpp" namespace asio {@@ -64,7 +65,6 @@ 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(const std::size_t size, Args & ... args)+ void* operator new(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, const std::size_t size)+ void operator delete(void* raw, 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -22,7 +22,8 @@ namespace detail { template <typename Mutex>-inline channel_service<Mutex>::channel_service(execution_context& ctx)+inline channel_service<Mutex>::channel_service(+ asio::execution_context& ctx) : asio::detail::execution_context_service_base<channel_service>(ctx), mutex_(), impl_list_(0)@@ -155,7 +156,7 @@ template <typename Mutex> inline std::size_t channel_service<Mutex>::capacity( const channel_service<Mutex>::base_implementation_type& impl)- const ASIO_NOEXCEPT+ const noexcept { typename Mutex::scoped_lock lock(impl.mutex_); @@ -165,7 +166,7 @@ template <typename Mutex> inline bool channel_service<Mutex>::is_open( const channel_service<Mutex>::base_implementation_type& impl)- const ASIO_NOEXCEPT+ const noexcept { typename Mutex::scoped_lock lock(impl.mutex_); @@ -204,7 +205,7 @@ { impl.waiters_.pop(); traits_type::invoke_receive_closed(- complete_receive<payload_type,+ post_receive<payload_type, typename traits_type::receive_closed_signature>( static_cast<channel_receive<payload_type>*>(op))); }@@ -238,7 +239,7 @@ { impl.waiters_.pop(); traits_type::invoke_receive_cancelled(- complete_receive<payload_type,+ post_receive<payload_type, typename traits_type::receive_cancelled_signature>( static_cast<channel_receive<payload_type>*>(op))); }@@ -277,7 +278,7 @@ { impl.waiters_.pop(); traits_type::invoke_receive_cancelled(- complete_receive<payload_type,+ post_receive<payload_type, typename traits_type::receive_cancelled_signature>( static_cast<channel_receive<payload_type>*>(op))); }@@ -302,7 +303,7 @@ template <typename Mutex> inline bool channel_service<Mutex>::ready( const channel_service<Mutex>::base_implementation_type& impl)- const ASIO_NOEXCEPT+ const noexcept { typename Mutex::scoped_lock lock(impl.mutex_); @@ -314,7 +315,7 @@ typename... Signatures, typename... Args> bool channel_service<Mutex>::try_send( channel_service<Mutex>::implementation_type<Traits, Signatures...>& impl,- ASIO_MOVE_ARG(Args)... args)+ bool via_dispatch, Args&&... args) { typedef typename implementation_type<Traits, Signatures...>::payload_type payload_type;@@ -329,7 +330,7 @@ } case buffer: {- impl.buffer_push(Message(0, ASIO_MOVE_CAST(Args)(args)...));+ impl.buffer_push(Message(0, static_cast<Args&&>(args)...)); impl.receive_state_ = buffer; if (impl.buffer_size() == impl.max_buffer_size_) impl.send_state_ = block;@@ -337,13 +338,17 @@ } case waiter: {- payload_type payload(Message(0, ASIO_MOVE_CAST(Args)(args)...));+ payload_type payload(Message(0, static_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:@@ -359,7 +364,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, ASIO_MOVE_ARG(Args)... args)+ std::size_t count, bool via_dispatch, Args&&... args) { typedef typename implementation_type<Traits, Signatures...>::payload_type payload_type;@@ -381,7 +386,7 @@ return 0; } - payload_type payload(Message(0, ASIO_MOVE_CAST(Args)(args)...));+ payload_type payload(Message(0, static_cast<Args&&>(args)...)); for (std::size_t i = 0; i < count; ++i) {@@ -394,7 +399,7 @@ case buffer: { i += impl.buffer_push_n(count - i,- ASIO_MOVE_CAST(payload_type)(payload));+ static_cast<payload_type&&>(payload)); impl.receive_state_ = buffer; if (impl.buffer_size() == impl.max_buffer_size_) impl.send_state_ = block;@@ -405,9 +410,13 @@ 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:@@ -456,9 +465,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; }@@ -475,7 +484,7 @@ template <typename Traits, typename... Signatures, typename Handler> bool channel_service<Mutex>::try_receive( channel_service<Mutex>::implementation_type<Traits, Signatures...>& impl,- ASIO_MOVE_ARG(Handler) handler)+ Handler&& handler) { typedef typename implementation_type<Traits, Signatures...>::payload_type payload_type;@@ -497,7 +506,7 @@ impl.buffer_pop(); impl.buffer_push(send_op->get_payload()); impl.waiters_.pop();- send_op->complete();+ send_op->post(); } else {@@ -508,8 +517,9 @@ } lock.unlock(); asio::detail::non_const_lvalue<Handler> handler2(handler);- channel_handler<payload_type, typename decay<Handler>::type>(- ASIO_MOVE_CAST(payload_type)(payload), handler2.value)();+ asio::detail::completion_payload_handler<+ payload_type, decay_t<Handler>>(+ static_cast<payload_type&&>(payload), handler2.value)(); return true; } case waiter:@@ -518,13 +528,14 @@ 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);- channel_handler<payload_type, typename decay<Handler>::type>(- ASIO_MOVE_CAST(payload_type)(payload), handler2.value)();+ asio::detail::completion_payload_handler<+ payload_type, decay_t<Handler>>(+ static_cast<payload_type&&>(payload), handler2.value)(); return true; } case closed:@@ -561,14 +572,14 @@ case buffer: { payload_type payload(- ASIO_MOVE_CAST(payload_type)(impl.buffer_front()));+ static_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->complete();+ send_op->post(); } else {@@ -577,7 +588,7 @@ impl.receive_state_ = (impl.send_state_ == closed) ? closed : block; impl.send_state_ = (impl.send_state_ == closed) ? closed : buffer; }- receive_op->immediate(ASIO_MOVE_CAST(payload_type)(payload));+ receive_op->immediate(static_cast<payload_type&&>(payload)); break; } case waiter:@@ -586,17 +597,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;- receive_op->immediate(ASIO_MOVE_CAST(payload_type)(payload));+ send_op->post();+ receive_op->immediate(static_cast<payload_type&&>(payload)); break; } case closed: default: { traits_type::invoke_receive_closed(- complete_receive<payload_type,+ post_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(const std::size_t size, Executor&, Token& tk, Args&...)+ void* operator new(std::size_t size, Executor&, Token& tk, Args&...) { return allocate_coroutine<Allocator>(size, get_associated_allocator(tk)); } - void operator delete(void* raw, const std::size_t size)+ void operator delete(void* raw, std::size_t size) { deallocate_coroutine<Allocator>(raw, size); }@@ -110,9 +110,7 @@ } }; ---}; // 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -16,16 +16,12 @@ #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/handler_invoke_helpers.hpp"+#include "asio/detail/initiation_base.hpp" #include "asio/detail/type_traits.hpp"-#include "asio/detail/variadic_templates.hpp" #include "asio/detail/push_options.hpp" @@ -42,33 +38,32 @@ template <typename CompletionToken> as_single_handler(as_single_t<CompletionToken> e)- : handler_(ASIO_MOVE_CAST(CompletionToken)(e.token_))+ : handler_(static_cast<CompletionToken&&>(e.token_)) { } template <typename RedirectedHandler>- as_single_handler(ASIO_MOVE_ARG(RedirectedHandler) h)- : handler_(ASIO_MOVE_CAST(RedirectedHandler)(h))+ as_single_handler(RedirectedHandler&& h)+ : handler_(static_cast<RedirectedHandler&&>(h)) { } void operator()() {- ASIO_MOVE_OR_LVALUE(Handler)(handler_)();+ static_cast<Handler&&>(handler_)(); } template <typename Arg>- void operator()(ASIO_MOVE_ARG(Arg) arg)+ void operator()(Arg&& arg) {- ASIO_MOVE_OR_LVALUE(Handler)(handler_)(- ASIO_MOVE_CAST(Arg)(arg));+ static_cast<Handler&&>(handler_)(static_cast<Arg&&>(arg)); } template <typename... Args>- void operator()(ASIO_MOVE_ARG(Args)... args)+ void operator()(Args&&... args) {- ASIO_MOVE_OR_LVALUE(Handler)(handler_)(- std::make_tuple(ASIO_MOVE_CAST(Args)(args)...));+ static_cast<Handler&&>(handler_)(+ std::make_tuple(static_cast<Args&&>(args)...)); } //private:@@ -76,32 +71,6 @@ }; 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) {@@ -109,30 +78,6 @@ 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 {@@ -154,7 +99,7 @@ template <typename R, typename... Args> struct as_single_signature<R(Args...)> {- typedef R type(std::tuple<typename decay<Args>::type...>);+ typedef R type(std::tuple<decay_t<Args>...>); }; } // namespace detail@@ -165,44 +110,45 @@ 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+ struct init_wrapper : detail::initiation_base<Initiation> {- init_wrapper(Initiation init)- : initiation_(ASIO_MOVE_CAST(Initiation)(init))+ using detail::initiation_base<Initiation>::initiation_base;++ template <typename Handler, typename... Args>+ void operator()(Handler&& handler, Args&&... args) && {+ 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()(- ASIO_MOVE_ARG(Handler) handler,- ASIO_MOVE_ARG(Args)... args)+ void operator()(Handler&& handler, Args&&... args) const & {- ASIO_MOVE_CAST(Initiation)(initiation_)(- experimental::detail::as_single_handler<- typename decay<Handler>::type>(- ASIO_MOVE_CAST(Handler)(handler)),- ASIO_MOVE_CAST(Args)(args)...);+ static_cast<const Initiation&>(*this)(+ experimental::detail::as_single_handler<decay_t<Handler>>(+ static_cast<Handler&&>(handler)),+ static_cast<Args&&>(args)...); }-- Initiation initiation_; }; 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)+ 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)...)) { return async_initiate<CompletionToken, typename experimental::detail::as_single_signature<Signature>::type>(- init_wrapper<typename decay<Initiation>::type>(- ASIO_MOVE_CAST(Initiation)(initiation)),- token.token_, ASIO_MOVE_CAST(Args)(args)...);+ init_wrapper<decay_t<Initiation>>(+ static_cast<Initiation&&>(initiation)),+ token.token_, static_cast<Args&&>(args)...); } }; @@ -212,19 +158,15 @@ 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)- ASIO_NOEXCEPT+ static typename Associator<Handler, DefaultCandidate>::type get(+ const experimental::detail::as_single_handler<Handler>& h) noexcept { return Associator<Handler, DefaultCandidate>::get(h.handler_); } - 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)))+ static auto get(const experimental::detail::as_single_handler<Handler>& h,+ const DefaultCandidate& c) noexcept+ -> decltype(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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -28,7 +28,7 @@ class channel_category : public asio::error_category { public:- const char* name() const ASIO_ERROR_CATEGORY_NOEXCEPT+ const char* name() const noexcept { return "asio.channel"; }
− link/modules/asio-standalone/asio/include/asio/experimental/impl/co_composed.hpp
@@ -1,1175 +0,0 @@-//-// 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(ASIO_MOVE_ARG(Filter) filter)+ void reset_cancellation_state(Filter&& filter) {- state = cancellation_state(slot, ASIO_MOVE_CAST(Filter)(filter));+ state = cancellation_state(slot, static_cast<Filter&&>(filter)); } template <typename InFilter, typename OutFilter>- void reset_cancellation_state(ASIO_MOVE_ARG(InFilter) in_filter,- ASIO_MOVE_ARG(OutFilter) out_filter)+ void reset_cancellation_state(InFilter&& in_filter,+ OutFilter&& out_filter) { state = cancellation_state(slot,- ASIO_MOVE_CAST(InFilter)(in_filter),- ASIO_MOVE_CAST(OutFilter)(out_filter));+ static_cast<InFilter&&>(in_filter),+ static_cast<OutFilter&&>(out_filter)); } bool throw_if_cancelled() const@@ -600,7 +600,7 @@ cancellation_slot_type get_cancellation_slot() const noexcept {- return cancel ? cancel->slot : cancellation_slot_type{};+ return cancel ? cancel->state.slot() : cancellation_slot_type{}; } using allocator_type =@@ -767,11 +767,11 @@ auto await_resume() { return src_->reset_cancellation_state(- ASIO_MOVE_CAST(Filter)(filter_));+ static_cast<Filter&&>(filter_)); } }; - return result{cancel, ASIO_MOVE_CAST(Filter)(reset.filter)};+ return result{cancel, static_cast<Filter&&>(reset.filter)}; } // This await transformation resets the associated cancellation state.@@ -798,14 +798,14 @@ auto await_resume() { return src_->reset_cancellation_state(- ASIO_MOVE_CAST(InFilter)(in_filter_),- ASIO_MOVE_CAST(OutFilter)(out_filter_));+ static_cast<InFilter&&>(in_filter_),+ static_cast<OutFilter&&>(out_filter_)); } }; return result{cancel,- ASIO_MOVE_CAST(InFilter)(reset.in_filter),- ASIO_MOVE_CAST(OutFilter)(reset.out_filter)};+ static_cast<InFilter&&>(reset.in_filter),+ static_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,- typename constraint<is_async_operation<Op>::value>::type = 0)+ constraint_t<is_async_operation<Op>::value> = 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 = typename completion_signature_of<Op>::type;+ using signature = completion_signature_of_t<Op>; 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, coro = coro_,+ return [this, the_coro = coro_, h = std::forward<WaitHandler>(handler), exec = std::move(exec)]() mutable {- assert(coro);+ assert(the_coro); - auto ch = detail::coroutine_handle<promise_type>::from_promise(*coro);+ auto ch = detail::coroutine_handle<promise_type>::from_promise(*the_coro); assert(ch && !ch.done()); - coro->awaited_from = post_coroutine(std::move(exec), std::move(h));- coro->reset_error();+ the_coro->awaited_from = post_coroutine(std::move(exec), std::move(h));+ the_coro->reset_error(); ch.resume(); }; }@@ -1090,18 +1090,18 @@ std::true_type /* error is noexcept */, std::false_type /* result is void */) //noexcept {- return [coro = coro_,+ return [the_coro = coro_, h = std::forward<WaitHandler>(handler), exec = std::move(exec)]() mutable {- assert(coro);+ assert(the_coro); - auto ch = detail::coroutine_handle<promise_type>::from_promise(*coro);+ auto ch = detail::coroutine_handle<promise_type>::from_promise(*the_coro); assert(ch && !ch.done()); - coro->awaited_from = detail::post_coroutine(- exec, std::move(h), coro->result_).handle;- coro->reset_error();+ the_coro->awaited_from = detail::post_coroutine(+ exec, std::move(h), the_coro->result_).handle;+ the_coro->reset_error(); ch.resume(); }; }@@ -1111,16 +1111,16 @@ std::false_type /* error is noexcept */, std::true_type /* result is void */) {- return [coro = coro_,+ return [the_coro = coro_, h = std::forward<WaitHandler>(handler), exec = std::move(exec)]() mutable {- if (!coro)+ if (!the_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(*coro);+ auto ch = detail::coroutine_handle<promise_type>::from_promise(*the_coro); if (!ch) return asio::post(exec, asio::append(std::move(h),@@ -1131,9 +1131,9 @@ detail::coro_error<error_type>::done())); else {- coro->awaited_from = detail::post_coroutine(- exec, std::move(h), coro->error_).handle;- coro->reset_error();+ the_coro->awaited_from = detail::post_coroutine(+ exec, std::move(h), the_coro->error_).handle;+ the_coro->reset_error(); ch.resume(); } };@@ -1144,17 +1144,17 @@ std::false_type /* error is noexcept */, std::false_type /* result is void */) {- return [coro = coro_,+ return [the_coro = coro_, h = std::forward<WaitHandler>(handler), exec = std::move(exec)]() mutable {- if (!coro)+ if (!the_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(*coro);+ detail::coroutine_handle<promise_type>::from_promise(*the_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 {- coro->awaited_from = detail::post_coroutine(- exec, std::move(h), coro->error_, coro->result_).handle;- coro->reset_error();+ the_coro->awaited_from = detail::post_coroutine(+ exec, std::move(h), the_coro->error_, the_coro->result_).handle;+ the_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), coro = coro_]() mutable+ in = std::forward<Input>(input), the_coro = coro_]() mutable {- coro->input_ = std::move(in);+ the_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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -78,18 +78,18 @@ bool has_value_; }; -// Proxy completion handler for the group of parallel operatations. Unpacks and+// Proxy completion handler for the group of parallel operations. 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 typename decay<- typename prefer_result<- typename associated_executor<Handler>::type,+ typedef decay_t<+ prefer_result_t<+ associated_executor_t<Handler>, execution::outstanding_work_t::tracked_t- >::type- >::type executor_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<- typename completion_signature_of<Ops>::type+ completion_signature_of_t<Ops> >::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 typename associated_executor<Op>::type ex_type;+ typedef associated_executor_t<Op> 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,- typename enable_if<+ enable_if_t< 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.- typename associated_cancellation_slot<Handler>::type slot+ associated_cancellation_slot_t<Handler> 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 operatations.+// Proxy completion handler for the ranged group of parallel operations. // 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 typename decay<- typename prefer_result<- typename associated_executor<Handler>::type,+ typedef decay_t<+ prefer_result_t<+ associated_executor_t<Handler>, execution::outstanding_work_t::tracked_t- >::type- >::type executor_type;+ >+ > executor_type; typedef typename parallel_op_signature_as_tuple<- typename completion_signature_of<Op>::type+ completion_signature_of_t<Op> >::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<- typename completion_signature_of<Op>::type,+ completion_signature_of_t<Op>, Allocator >::raw_type >::type vectors_type;@@ -473,7 +473,8 @@ (void)pushback_fold; } - std::move(handler_)(completion_order_, std::move(std::get<I>(vectors))...);+ std::move(handler_)(std::move(completion_order_),+ std::move(std::get<I>(vectors))...); } Handler handler_;@@ -543,7 +544,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)@@ -587,7 +588,7 @@ } std::shared_ptr<ranged_parallel_group_state<- Condition, Handler, Op, Allocator> > state_;+ Condition, Handler, Op, Allocator>> state_; std::size_t idx_; }; @@ -605,7 +606,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)@@ -630,7 +631,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))@@ -648,7 +649,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_; };@@ -661,7 +662,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)) { }@@ -679,7 +680,7 @@ } std::weak_ptr<ranged_parallel_group_state<- Condition, Handler, Op, Allocator> > state_;+ Condition, Handler, Op, Allocator>> state_; }; template <typename Condition, typename Handler,@@ -689,12 +690,11 @@ { // Get the user's completion handler's cancellation slot, so that we can allow // cancellation of the entire group.- typename associated_cancellation_slot<Handler>::type slot- = asio::get_associated_cancellation_slot(handler);+ associated_cancellation_slot_t<Handler> slot+ = asio::get_associated_cancellation_slot(handler); // The type of the asynchronous operation.- typedef typename std::decay<decltype(- *std::declval<typename Range::iterator>())>::type op_type;+ typedef decay_t<decltype(*declval<typename Range::iterator>())> op_type; // Create the shared state for the operation. typedef ranged_parallel_group_state<Condition,@@ -706,9 +706,10 @@ 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 typename associated_executor<op_type>::type ex_type;+ typedef associated_executor_t<op_type> ex_type; ex_type ex = asio::get_associated_executor(op); std::move(op)( ranged_parallel_group_op_handler_with_executor<@@ -718,7 +719,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_); @@ -726,7 +727,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@@ -739,20 +740,18 @@ DefaultCandidate> : Associator<Handler, DefaultCandidate> {- static typename Associator<Handler, DefaultCandidate>::type- get(const experimental::detail::parallel_group_completion_handler<- Handler, Ops...>& h) ASIO_NOEXCEPT+ static typename Associator<Handler, DefaultCandidate>::type get(+ const experimental::detail::parallel_group_completion_handler<+ Handler, Ops...>& h) noexcept { return Associator<Handler, DefaultCandidate>::get(h.handler_); } - static ASIO_AUTO_RETURN_TYPE_PREFIX2(- typename Associator<Handler, DefaultCandidate>::type)- get(const experimental::detail::parallel_group_completion_handler<+ static auto get(+ const experimental::detail::parallel_group_completion_handler< Handler, Ops...>& h,- const DefaultCandidate& c) ASIO_NOEXCEPT- ASIO_AUTO_RETURN_TYPE_SUFFIX((- Associator<Handler, DefaultCandidate>::get(h.handler_, c)))+ const DefaultCandidate& c) noexcept+ -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c)) { return Associator<Handler, DefaultCandidate>::get(h.handler_, c); }@@ -766,20 +765,18 @@ DefaultCandidate> : Associator<Handler, DefaultCandidate> {- static typename Associator<Handler, DefaultCandidate>::type- get(const experimental::detail::ranged_parallel_group_completion_handler<- Handler, Op, Allocator>& h) ASIO_NOEXCEPT+ static typename Associator<Handler, DefaultCandidate>::type get(+ const experimental::detail::ranged_parallel_group_completion_handler<+ Handler, Op, Allocator>& h) noexcept { return Associator<Handler, DefaultCandidate>::get(h.handler_); } - static ASIO_AUTO_RETURN_TYPE_PREFIX2(- typename Associator<Handler, DefaultCandidate>::type)- get(const experimental::detail::ranged_parallel_group_completion_handler<+ static auto get(+ const experimental::detail::ranged_parallel_group_completion_handler< Handler, Op, Allocator>& h,- const DefaultCandidate& c) ASIO_NOEXCEPT- ASIO_AUTO_RETURN_TYPE_SUFFIX((- Associator<Handler, DefaultCandidate>::get(h.handler_, c)))+ const DefaultCandidate& c) noexcept+ -> decltype(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,6 +18,8 @@ #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"@@ -56,8 +58,7 @@ reinterpret_cast<result_type*>(&result)->~result_type(); } - typename aligned_storage<sizeof(result_type),- alignof(result_type)>::type result;+ aligned_storage_t<sizeof(result_type), alignof(result_type)> result; std::atomic<bool> done{false}; cancellation_signal cancel; Allocator allocator;@@ -186,7 +187,7 @@ template<typename Signature = void(), typename Executor = asio::any_io_executor,- typename Allocator = any_io_executor>+ typename Allocator = std::allocator<void>> 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(typename decay<Args>::type...),+ -> experimental::promise<void(decay_t<Args>...), asio::associated_executor_t<Initiation>, Allocator> { using handler_type = experimental::detail::promise_handler<- void(typename decay<Args>::type...),+ void(decay_t<Args>...), 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -17,8 +17,10 @@ #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" @@ -36,7 +38,7 @@ template <typename R, typename... Args> struct parallel_op_signature_as_tuple<R(Args...)> {- typedef std::tuple<typename decay<Args>::type...> type;+ typedef std::tuple<decay_t<Args>...> type; }; // Helper trait for concatenating completion signatures.@@ -162,7 +164,7 @@ /// The completion signature for the group of operations. typedef typename detail::parallel_group_signature<sizeof...(Ops),- typename completion_signature_of<Ops>::type...>::type signature;+ completion_signature_of_t<Ops>...>::type signature; /// Initiate an asynchronous wait for the group of operations. /**@@ -188,13 +190,12 @@ */ template <typename CancellationCondition, ASIO_COMPLETION_TOKEN_FOR(signature) CompletionToken>- ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(CompletionToken, signature)- async_wait(CancellationCondition cancellation_condition,+ auto async_wait(CancellationCondition cancellation_condition, CompletionToken&& token)- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ -> decltype( 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,@@ -206,6 +207,36 @@ /** * 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);@@ -252,7 +283,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:@@ -281,9 +312,8 @@ /// The completion signature for the group of operations. typedef typename detail::ranged_parallel_group_signature<- typename completion_signature_of<- typename std::decay<- decltype(*std::declval<typename Range::iterator>())>::type>::type,+ completion_signature_of_t<+ decay_t<decltype(*std::declval<typename Range::iterator>())>>, Allocator>::type signature; /// Initiate an asynchronous wait for the group of operations.@@ -311,14 +341,13 @@ */ template <typename CancellationCondition, ASIO_COMPLETION_TOKEN_FOR(signature) CompletionToken>- ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(CompletionToken, signature)- async_wait(CancellationCondition cancellation_condition,+ auto async_wait(CancellationCondition cancellation_condition, CompletionToken&& token)- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ -> decltype( 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,@@ -333,28 +362,12 @@ * * For example: * @code- * using op_type = decltype(- * socket1.async_read_some(- * asio::buffer(data1),- * asio::deferred- * )- * );+ * using op_type =+ * decltype(socket1.async_read_some(asio::buffer(data1))); * * std::vector<op_type> ops;- *- * ops.push_back(- * socket1.async_read_some(- * asio::buffer(data1),- * asio::deferred- * )- * );- *- * ops.push_back(- * socket2.async_read_some(- * asio::buffer(data2),- * asio::deferred- * )- * );+ * ops.push_back(socket1.async_read_some(asio::buffer(data1)));+ * ops.push_back(socket2.async_read_some(asio::buffer(data2))); * * asio::experimental::make_parallel_group(ops).async_wait( * asio::experimental::wait_for_all(),@@ -375,15 +388,13 @@ * @endcode */ template <typename Range>-ASIO_NODISCARD inline-ranged_parallel_group<typename std::decay<Range>::type>+ASIO_NODISCARD inline ranged_parallel_group<decay_t<Range>> make_parallel_group(Range&& range,- typename constraint<- is_async_operation_range<typename std::decay<Range>::type>::value- >::type = 0)+ constraint_t<+ is_async_operation_range<decay_t<Range>>::value+ > = 0) {- return ranged_parallel_group<typename std::decay<Range>::type>(- std::forward<Range>(range));+ return ranged_parallel_group<decay_t<Range>>(std::forward<Range>(range)); } /// Create a group of operations that may be launched in parallel.@@ -394,28 +405,12 @@ * * For example: * @code- * using op_type = decltype(- * socket1.async_read_some(- * asio::buffer(data1),- * asio::deferred- * )- * );+ * using op_type =+ * decltype(socket1.async_read_some(asio::buffer(data1))); * * std::vector<op_type> ops;- *- * ops.push_back(- * socket1.async_read_some(- * asio::buffer(data1),- * asio::deferred- * )- * );- *- * ops.push_back(- * socket2.async_read_some(- * asio::buffer(data2),- * asio::deferred- * )- * );+ * ops.push_back(socket1.async_read_some(asio::buffer(data1)));+ * ops.push_back(socket2.async_read_some(asio::buffer(data2))); * * asio::experimental::make_parallel_group( * std::allocator_arg_t,@@ -440,14 +435,13 @@ * @endcode */ template <typename Allocator, typename Range>-ASIO_NODISCARD inline-ranged_parallel_group<typename std::decay<Range>::type, Allocator>+ASIO_NODISCARD inline ranged_parallel_group<decay_t<Range>, Allocator> make_parallel_group(allocator_arg_t, const Allocator& allocator, Range&& range,- typename constraint<- is_async_operation_range<typename std::decay<Range>::type>::value- >::type = 0)+ constraint_t<+ is_async_operation_range<decay_t<Range>>::value+ > = 0) {- return ranged_parallel_group<typename std::decay<Range>::type, Allocator>(+ return ranged_parallel_group<decay_t<Range>, Allocator>( std::forward<Range>(range), allocator); }
− link/modules/asio-standalone/asio/include/asio/experimental/prepend.hpp
@@ -1,36 +0,0 @@-//-// 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,8 +84,9 @@ * 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::use_awaitable);- * co_await asio::async_write_some(to_write, asio::deferred);+ * auto p = asio::async_read(read_buf,+ * asio::experimental::use_promise);+ * co_await asio::async_write_some(to_write); * co_await p; * } * @endcode@@ -138,7 +139,6 @@ * 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,8 +47,9 @@ * the asynchronous operation completes, and the result of the operation is * returned. *- * 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.+ * 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. */ template <typename Allocator = std::allocator<void>> struct use_coro_t@@ -59,7 +60,7 @@ typedef Allocator allocator_type; /// Default constructor.- ASIO_CONSTEXPR use_coro_t(+ constexpr use_coro_t( allocator_type allocator = allocator_type{} #if defined(ASIO_ENABLE_HANDLER_TRACKING) # if defined(ASIO_HAS_SOURCE_LOCATION)@@ -83,7 +84,6 @@ { } - /// 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.- ASIO_CONSTEXPR use_coro_t(const char* file_name,+ 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,- typename constraint<- conditional<+ constraint_t<+ conditional_t< !is_same<InnerExecutor1, executor_with_default>::value, is_convertible<InnerExecutor1, InnerExecutor>, false_type- >::type::value- >::type = 0) ASIO_NOEXCEPT+ >::value+ > = 0) noexcept : InnerExecutor(ex) { }@@ -140,25 +140,21 @@ /// 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;-#endif // defined(ASIO_HAS_ALIAS_TEMPLATES)- // || defined(GENERATING_DOCUMENTATION)+ executor_with_default<typename T::executor_type>>::other; /// 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>::type::template rebind_executor<- executor_with_default<typename decay<T>::type::executor_type>+ static typename decay_t<T>::template rebind_executor<+ executor_with_default<typename decay_t<T>::executor_type> >::other- as_default_on(ASIO_MOVE_ARG(T) object)+ as_default_on(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));+ return typename decay_t<T>::template rebind_executor<+ executor_with_default<typename decay_t<T>::executor_type>+ >::other(static_cast<T&&>(object)); } #if defined(ASIO_ENABLE_HANDLER_TRACKING)@@ -177,11 +173,9 @@ * See the documentation for asio::use_coro_t for a usage example. */ #if defined(GENERATING_DOCUMENTATION)-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);+ASIO_INLINE_VARIABLE constexpr use_coro_t<> use_coro;+#else+ASIO_INLINE_VARIABLE constexpr 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.- ASIO_CONSTEXPR use_promise_t()+ constexpr use_promise_t() { } @@ -44,7 +44,7 @@ } /// Obtain allocator.- allocator_type get_allocator() const ASIO_NOEXCEPT+ allocator_type get_allocator() const 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) ASIO_NOEXCEPT+ executor_with_default(const InnerExecutor& ex) noexcept : InnerExecutor(ex) { }@@ -67,9 +67,9 @@ /// that to construct the adapted executor. template <typename OtherExecutor> executor_with_default(const OtherExecutor& ex,- typename constraint<+ constraint_t< is_convertible<OtherExecutor, InnerExecutor>::value- >::type = 0) ASIO_NOEXCEPT+ > = 0) 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>::type::template rebind_executor<- executor_with_default<typename decay<T>::type::executor_type>+ static typename decay_t<T>::template rebind_executor<+ executor_with_default<typename decay_t<T>::executor_type> >::other- as_default_on(ASIO_MOVE_ARG(T) object)+ as_default_on(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));+ return typename decay_t<T>::template rebind_executor<+ executor_with_default<typename decay_t<T>::executor_type>+ >::other(static_cast<T&&>(object)); } /// Specify an alternate allocator.@@ -99,7 +99,7 @@ Allocator allocator_; }; -constexpr use_promise_t<> use_promise;+ASIO_INLINE_VARIABLE 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/generic/basic_endpoint.hpp view
@@ -2,7 +2,7 @@ // generic/basic_endpoint.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -54,7 +54,7 @@ #endif /// Default constructor.- basic_endpoint() ASIO_NOEXCEPT+ basic_endpoint() noexcept { } @@ -78,13 +78,11 @@ { } -#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)@@ -93,14 +91,12 @@ 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -73,19 +73,19 @@ } /// Obtain an identifier for the type of the protocol.- int type() const ASIO_NOEXCEPT+ int type() const noexcept { return ASIO_OS_DEF(SOCK_DGRAM); } /// Obtain an identifier for the protocol.- int protocol() const ASIO_NOEXCEPT+ int protocol() const noexcept { return protocol_; } /// Obtain an identifier for the protocol family.- int family() const ASIO_NOEXCEPT+ int family() const 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/generic/raw_protocol.hpp view
@@ -2,7 +2,7 @@ // generic/raw_protocol.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -73,19 +73,19 @@ } /// Obtain an identifier for the type of the protocol.- int type() const ASIO_NOEXCEPT+ int type() const noexcept { return ASIO_OS_DEF(SOCK_RAW); } /// Obtain an identifier for the protocol.- int protocol() const ASIO_NOEXCEPT+ int protocol() const noexcept { return protocol_; } /// Obtain an identifier for the protocol family.- int family() const ASIO_NOEXCEPT+ int family() const 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -72,19 +72,19 @@ } /// Obtain an identifier for the type of the protocol.- int type() const ASIO_NOEXCEPT+ int type() const noexcept { return ASIO_OS_DEF(SOCK_SEQPACKET); } /// Obtain an identifier for the protocol.- int protocol() const ASIO_NOEXCEPT+ int protocol() const noexcept { return protocol_; } /// Obtain an identifier for the protocol family.- int family() const ASIO_NOEXCEPT+ int family() const 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -74,19 +74,19 @@ } /// Obtain an identifier for the type of the protocol.- int type() const ASIO_NOEXCEPT+ int type() const noexcept { return ASIO_OS_DEF(SOCK_STREAM); } /// Obtain an identifier for the protocol.- int protocol() const ASIO_NOEXCEPT+ int protocol() const noexcept { return protocol_; } /// Obtain an identifier for the protocol family.- int family() const ASIO_NOEXCEPT+ int family() const noexcept { return family_; }
− link/modules/asio-standalone/asio/include/asio/handler_alloc_hook.hpp
@@ -1,104 +0,0 @@-//-// 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
− link/modules/asio-standalone/asio/include/asio/handler_invoke_hook.hpp
@@ -1,111 +0,0 @@-//-// 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -16,9 +16,6 @@ #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" @@ -38,7 +35,5 @@ 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 view
@@ -0,0 +1,142 @@+//+// 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -25,57 +25,53 @@ namespace asio { -any_completion_executor::any_completion_executor() ASIO_NOEXCEPT+any_completion_executor::any_completion_executor() noexcept : base_type() { } -any_completion_executor::any_completion_executor(nullptr_t) ASIO_NOEXCEPT+any_completion_executor::any_completion_executor(nullptr_t) noexcept : base_type(nullptr_t()) { } any_completion_executor::any_completion_executor(- const any_completion_executor& e) ASIO_NOEXCEPT+ const any_completion_executor& e) noexcept : base_type(static_cast<const base_type&>(e)) { } any_completion_executor::any_completion_executor(std::nothrow_t,- const any_completion_executor& e) ASIO_NOEXCEPT+ const any_completion_executor& e) noexcept : base_type(static_cast<const base_type&>(e)) { } -#if defined(ASIO_HAS_MOVE) any_completion_executor::any_completion_executor(- any_completion_executor&& e) ASIO_NOEXCEPT+ any_completion_executor&& e) noexcept : base_type(static_cast<base_type&&>(e)) { } any_completion_executor::any_completion_executor(std::nothrow_t,- any_completion_executor&& e) ASIO_NOEXCEPT+ any_completion_executor&& e) 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) ASIO_NOEXCEPT+ const any_completion_executor& e) 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) ASIO_NOEXCEPT+ any_completion_executor&& e) 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) {@@ -88,7 +84,7 @@ } void any_completion_executor::swap(- any_completion_executor& other) ASIO_NOEXCEPT+ any_completion_executor& other) 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -25,55 +25,48 @@ namespace asio { -any_io_executor::any_io_executor() ASIO_NOEXCEPT+any_io_executor::any_io_executor() noexcept : base_type() { } -any_io_executor::any_io_executor(nullptr_t) ASIO_NOEXCEPT+any_io_executor::any_io_executor(nullptr_t) noexcept : base_type(nullptr_t()) { } -any_io_executor::any_io_executor(const any_io_executor& e) ASIO_NOEXCEPT+any_io_executor::any_io_executor(const any_io_executor& e) noexcept : base_type(static_cast<const base_type&>(e)) { } any_io_executor::any_io_executor(std::nothrow_t,- const any_io_executor& e) ASIO_NOEXCEPT+ const any_io_executor& e) noexcept : base_type(static_cast<const base_type&>(e)) { } -#if defined(ASIO_HAS_MOVE)-any_io_executor::any_io_executor(any_io_executor&& e) ASIO_NOEXCEPT+any_io_executor::any_io_executor(any_io_executor&& e) noexcept : base_type(static_cast<base_type&&>(e)) { } -any_io_executor::any_io_executor(std::nothrow_t,- any_io_executor&& e) ASIO_NOEXCEPT+any_io_executor::any_io_executor(std::nothrow_t, any_io_executor&& e) 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) ASIO_NOEXCEPT+any_io_executor& any_io_executor::operator=(const any_io_executor& e) noexcept { base_type::operator=(static_cast<const base_type&>(e)); return *this; } -#if defined(ASIO_HAS_MOVE)-any_io_executor& any_io_executor::operator=(- any_io_executor&& e) ASIO_NOEXCEPT+any_io_executor& any_io_executor::operator=(any_io_executor&& e) 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) {@@ -85,7 +78,7 @@ { } -void any_io_executor::swap(any_io_executor& other) ASIO_NOEXCEPT+void any_io_executor::swap(any_io_executor& other) 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -16,15 +16,12 @@ #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/handler_invoke_helpers.hpp"+#include "asio/detail/initiation_base.hpp" #include "asio/detail/type_traits.hpp" #include "asio/detail/utility.hpp"-#include "asio/detail/variadic_templates.hpp" #include "asio/detail/push_options.hpp" @@ -39,26 +36,26 @@ typedef void result_type; template <typename H>- 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))+ append_handler(H&& handler, std::tuple<Values...> values)+ : handler_(static_cast<H&&>(handler)),+ values_(static_cast<std::tuple<Values...>&&>(values)) { } template <typename... Args>- void operator()(ASIO_MOVE_ARG(Args)... args)+ void operator()(Args&&... args) { this->invoke( index_sequence_for<Values...>{},- ASIO_MOVE_CAST(Args)(args)...);+ static_cast<Args&&>(args)...); } template <std::size_t... I, typename... Args>- void invoke(index_sequence<I...>, ASIO_MOVE_ARG(Args)... args)+ void invoke(index_sequence<I...>, Args&&... args) {- ASIO_MOVE_OR_LVALUE(Handler)(handler_)(- ASIO_MOVE_CAST(Args)(args)...,- ASIO_MOVE_CAST(Values)(std::get<I>(values_))...);+ static_cast<Handler&&>(handler_)(+ static_cast<Args&&>(args)...,+ static_cast<Values&&>(std::get<I>(values_))...); } //private:@@ -67,32 +64,6 @@ }; 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) {@@ -100,37 +71,13 @@ 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(typename decay<Args>::type..., Values...);+ typedef R type(decay_t<Args>..., Values...); }; } // namespace detail@@ -138,8 +85,7 @@ #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>@@ -148,48 +94,49 @@ Signature, Values...>::type signature; template <typename Initiation>- struct init_wrapper+ struct init_wrapper : detail::initiation_base<Initiation> {- init_wrapper(Initiation init)- : initiation_(ASIO_MOVE_CAST(Initiation)(init))+ using detail::initiation_base<Initiation>::initiation_base;++ template <typename Handler, typename... Args>+ void operator()(Handler&& handler,+ std::tuple<Values...> values, Args&&... args) && {+ 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()(- ASIO_MOVE_ARG(Handler) handler,- std::tuple<Values...> values,- ASIO_MOVE_ARG(Args)... args)+ void operator()(Handler&& handler,+ std::tuple<Values...> values, Args&&... args) const & {- 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)...);+ 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)...); }-- Initiation initiation_; }; template <typename Initiation, typename RawCompletionToken, typename... 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)+ 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)...)) { return async_initiate<CompletionToken, signature>(- init_wrapper<typename decay<Initiation>::type>(- ASIO_MOVE_CAST(Initiation)(initiation)),+ init_wrapper<decay_t<Initiation>>(+ static_cast<Initiation&&>(initiation)), token.token_,- ASIO_MOVE_CAST(std::tuple<Values...>)(token.values_),- ASIO_MOVE_CAST(Args)(args)...);+ static_cast<std::tuple<Values...>&&>(token.values_),+ static_cast<Args&&>(args)...); } }; @@ -199,18 +146,15 @@ detail::append_handler<Handler, Values...>, DefaultCandidate> : Associator<Handler, DefaultCandidate> {- static typename Associator<Handler, DefaultCandidate>::type- get(const detail::append_handler<Handler, Values...>& h) ASIO_NOEXCEPT+ static typename Associator<Handler, DefaultCandidate>::type get(+ const detail::append_handler<Handler, Values...>& h) noexcept { return Associator<Handler, DefaultCandidate>::get(h.handler_); } - 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)))+ static auto get(const detail::append_handler<Handler, Values...>& h,+ const DefaultCandidate& c) noexcept+ -> decltype(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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -16,16 +16,13 @@ #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/handler_invoke_helpers.hpp"+#include "asio/detail/initiation_base.hpp" #include "asio/detail/type_traits.hpp"-#include "asio/detail/variadic_templates.hpp" #include "asio/detail/push_options.hpp" @@ -41,21 +38,21 @@ template <typename CompletionToken> as_tuple_handler(as_tuple_t<CompletionToken> e)- : handler_(ASIO_MOVE_CAST(CompletionToken)(e.token_))+ : handler_(static_cast<CompletionToken&&>(e.token_)) { } template <typename RedirectedHandler>- as_tuple_handler(ASIO_MOVE_ARG(RedirectedHandler) h)- : handler_(ASIO_MOVE_CAST(RedirectedHandler)(h))+ as_tuple_handler(RedirectedHandler&& h)+ : handler_(static_cast<RedirectedHandler&&>(h)) { } template <typename... Args>- void operator()(ASIO_MOVE_ARG(Args)... args)+ void operator()(Args&&... args) {- ASIO_MOVE_OR_LVALUE(Handler)(handler_)(- std::make_tuple(ASIO_MOVE_CAST(Args)(args)...));+ static_cast<Handler&&>(handler_)(+ std::make_tuple(static_cast<Args&&>(args)...)); } //private:@@ -63,32 +60,6 @@ }; 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) {@@ -96,75 +67,48 @@ 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<typename decay<Args>::type...>);+ typedef R type(std::tuple<decay_t<Args>...>); }; -#if defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)- template <typename R, typename... Args> struct as_tuple_signature<R(Args...) &> {- typedef R type(std::tuple<typename decay<Args>::type...>) &;+ typedef R type(std::tuple<decay_t<Args>...>) &; }; template <typename R, typename... Args> struct as_tuple_signature<R(Args...) &&> {- typedef R type(std::tuple<typename decay<Args>::type...>) &&;+ typedef R type(std::tuple<decay_t<Args>...>) &&; }; -# 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<typename decay<Args>::type...>) noexcept;+ typedef R type(std::tuple<decay_t<Args>...>) noexcept; }; template <typename R, typename... Args> struct as_tuple_signature<R(Args...) & noexcept> {- typedef R type(std::tuple<typename decay<Args>::type...>) & noexcept;+ typedef R type(std::tuple<decay_t<Args>...>) & noexcept; }; template <typename R, typename... Args> struct as_tuple_signature<R(Args...) && noexcept> {- typedef R type(std::tuple<typename decay<Args>::type...>) && noexcept;+ typedef R type(std::tuple<decay_t<Args>...>) && noexcept; }; -# endif // defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)-#endif // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)+#endif // defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE) } // namespace detail @@ -176,53 +120,50 @@ typename detail::as_tuple_signature<Signatures>::type...> { template <typename Initiation>- struct init_wrapper+ struct init_wrapper : detail::initiation_base<Initiation> {- init_wrapper(Initiation init)- : initiation_(ASIO_MOVE_CAST(Initiation)(init))+ using detail::initiation_base<Initiation>::initiation_base;++ template <typename Handler, typename... Args>+ void operator()(Handler&& handler, Args&&... args) && {+ 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()(- ASIO_MOVE_ARG(Handler) handler,- ASIO_MOVE_ARG(Args)... args)+ void operator()(Handler&& handler, Args&&... args) const & {- ASIO_MOVE_CAST(Initiation)(initiation_)(- detail::as_tuple_handler<- typename decay<Handler>::type>(- ASIO_MOVE_CAST(Handler)(handler)),- ASIO_MOVE_CAST(Args)(args)...);+ static_cast<const Initiation&>(*this)(+ detail::as_tuple_handler<decay_t<Handler>>(+ static_cast<Handler&&>(handler)),+ static_cast<Args&&>(args)...); }-- Initiation initiation_; }; template <typename Initiation, typename RawCompletionToken, typename... Args>- 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((+ static auto initiate(Initiation&& initiation,+ RawCompletionToken&& token, Args&&... args)+ -> decltype( async_initiate<- typename conditional<- is_const<typename remove_reference<RawCompletionToken>::type>::value,- const CompletionToken, CompletionToken>::type,+ conditional_t<+ is_const<remove_reference_t<RawCompletionToken>>::value,+ const CompletionToken, CompletionToken>, typename detail::as_tuple_signature<Signatures>::type...>(- init_wrapper<typename decay<Initiation>::type>(- ASIO_MOVE_CAST(Initiation)(initiation)),- token.token_, ASIO_MOVE_CAST(Args)(args)...)))+ init_wrapper<decay_t<Initiation>>(+ static_cast<Initiation&&>(initiation)),+ token.token_, static_cast<Args&&>(args)...)) { return async_initiate<- typename conditional<- is_const<typename remove_reference<RawCompletionToken>::type>::value,- const CompletionToken, CompletionToken>::type,+ conditional_t<+ is_const<remove_reference_t<RawCompletionToken>>::value,+ const CompletionToken, CompletionToken>, typename detail::as_tuple_signature<Signatures>::type...>(- init_wrapper<typename decay<Initiation>::type>(- ASIO_MOVE_CAST(Initiation)(initiation)),- token.token_, ASIO_MOVE_CAST(Args)(args)...);+ init_wrapper<decay_t<Initiation>>(+ static_cast<Initiation&&>(initiation)),+ token.token_, static_cast<Args&&>(args)...); } }; @@ -236,53 +177,50 @@ typename detail::as_tuple_signature<Signature>::type> { template <typename Initiation>- struct init_wrapper+ struct init_wrapper : detail::initiation_base<Initiation> {- init_wrapper(Initiation init)- : initiation_(ASIO_MOVE_CAST(Initiation)(init))+ using detail::initiation_base<Initiation>::initiation_base;++ template <typename Handler, typename... Args>+ void operator()(Handler&& handler, Args&&... args) && {+ 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()(- ASIO_MOVE_ARG(Handler) handler,- ASIO_MOVE_ARG(Args)... args)+ void operator()(Handler&& handler, Args&&... args) const & {- ASIO_MOVE_CAST(Initiation)(initiation_)(- detail::as_tuple_handler<- typename decay<Handler>::type>(- ASIO_MOVE_CAST(Handler)(handler)),- ASIO_MOVE_CAST(Args)(args)...);+ static_cast<const Initiation&>(*this)(+ detail::as_tuple_handler<decay_t<Handler>>(+ static_cast<Handler&&>(handler)),+ static_cast<Args&&>(args)...); }-- Initiation initiation_; }; template <typename Initiation, typename RawCompletionToken, typename... Args>- 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((+ static auto initiate(Initiation&& initiation,+ RawCompletionToken&& token, Args&&... args)+ -> decltype( async_initiate<- typename conditional<- is_const<typename remove_reference<RawCompletionToken>::type>::value,- const CompletionToken, CompletionToken>::type,+ conditional_t<+ is_const<remove_reference_t<RawCompletionToken>>::value,+ const CompletionToken, CompletionToken>, typename detail::as_tuple_signature<Signature>::type>(- init_wrapper<typename decay<Initiation>::type>(- ASIO_MOVE_CAST(Initiation)(initiation)),- token.token_, ASIO_MOVE_CAST(Args)(args)...)))+ init_wrapper<decay_t<Initiation>>(+ static_cast<Initiation&&>(initiation)),+ token.token_, static_cast<Args&&>(args)...)) { return async_initiate<- typename conditional<- is_const<typename remove_reference<RawCompletionToken>::type>::value,- const CompletionToken, CompletionToken>::type,+ conditional_t<+ is_const<remove_reference_t<RawCompletionToken>>::value,+ const CompletionToken, CompletionToken>, typename detail::as_tuple_signature<Signature>::type>(- init_wrapper<typename decay<Initiation>::type>(- ASIO_MOVE_CAST(Initiation)(initiation)),- token.token_, ASIO_MOVE_CAST(Args)(args)...);+ init_wrapper<decay_t<Initiation>>(+ static_cast<Initiation&&>(initiation)),+ token.token_, static_cast<Args&&>(args)...); } }; @@ -294,20 +232,38 @@ detail::as_tuple_handler<Handler>, DefaultCandidate> : Associator<Handler, DefaultCandidate> {- static typename Associator<Handler, DefaultCandidate>::type- get(const detail::as_tuple_handler<Handler>& h) ASIO_NOEXCEPT+ static typename Associator<Handler, DefaultCandidate>::type get(+ const detail::as_tuple_handler<Handler>& h) noexcept { return Associator<Handler, DefaultCandidate>::get(h.handler_); } - 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)))+ static auto get(const detail::as_tuple_handler<Handler>& h,+ const DefaultCandidate& c) noexcept+ -> decltype(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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -21,10 +21,12 @@ #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"@@ -41,8 +43,7 @@ namespace asio { namespace detail { -struct awaitable_thread_has_context_switched {};-template <typename, typename> class awaitable_async_op_handler;+template <typename, 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@@ -81,8 +82,17 @@ // | | // +-----------------+ +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+class awaitable_frame_base : public awaitable_launch_context { public: #if !defined(ASIO_DISABLE_AWAITABLE_FRAME_RECYCLING)@@ -135,19 +145,15 @@ return result{this}; } - void set_except(std::exception_ptr e) noexcept- {- pending_exception_ = e;- }-- void set_error(const asio::error_code& ec)+ template <typename Disposition>+ void set_disposition(Disposition&& d) noexcept {- this->set_except(std::make_exception_ptr(asio::system_error(ec)));+ pending_exception_ = (to_exception_ptr)(static_cast<Disposition&&>(d)); } void unhandled_exception() {- set_except(std::current_exception());+ set_disposition(std::current_exception()); } void rethrow_exception()@@ -175,7 +181,7 @@ template <typename Op> auto await_transform(Op&& op,- typename constraint<is_async_operation<Op>::value>::type = 0+ constraint_t<is_async_operation<Op>::value> = 0 #if defined(ASIO_ENABLE_HANDLER_TRACKING) # if defined(ASIO_HAS_SOURCE_LOCATION) , detail::source_location location = detail::source_location::current()@@ -187,8 +193,8 @@ if (!!attached_thread_->get_cancellation_state().cancelled()) throw_error(asio::error::operation_aborted, "co_await"); - return awaitable_async_op<typename completion_signature_of<Op>::type,- typename decay<Op>::type, Executor>{+ return awaitable_async_op<+ completion_signature_of_t<Op>, decay_t<Op>, Executor>{ std::forward<Op>(op), this #if defined(ASIO_ENABLE_HANDLER_TRACKING) # if defined(ASIO_HAS_SOURCE_LOCATION)@@ -297,11 +303,11 @@ auto await_resume() { return this_->attached_thread_->reset_cancellation_state(- ASIO_MOVE_CAST(Filter)(filter_));+ static_cast<Filter&&>(filter_)); } }; - return result{this, ASIO_MOVE_CAST(Filter)(reset.filter)};+ return result{this, static_cast<Filter&&>(reset.filter)}; } // This await transformation resets the associated cancellation state.@@ -328,14 +334,14 @@ auto await_resume() { return this_->attached_thread_->reset_cancellation_state(- ASIO_MOVE_CAST(InFilter)(in_filter_),- ASIO_MOVE_CAST(OutFilter)(out_filter_));+ static_cast<InFilter&&>(in_filter_),+ static_cast<OutFilter&&>(out_filter_)); } }; return result{this,- ASIO_MOVE_CAST(InFilter)(reset.in_filter),- ASIO_MOVE_CAST(OutFilter)(reset.out_filter)};+ static_cast<InFilter&&>(reset.in_filter),+ static_cast<OutFilter&&>(reset.out_filter)}; } // This await transformation determines whether cancellation is propagated as@@ -399,12 +405,12 @@ // race condition. template <typename Function> auto await_transform(Function f,- typename enable_if<+ enable_if_t< is_convertible<- typename result_of<Function(awaitable_frame_base*)>::type,+ result_of_t<Function(awaitable_frame_base*)>, awaitable_thread<Executor>* >::value- >::type* = nullptr)+ >* = nullptr) { struct result {@@ -434,8 +440,8 @@ return result{std::move(f), this}; } - // Access the awaitable thread's has_context_switched_ flag.- auto await_transform(detail::awaitable_thread_has_context_switched) noexcept+ // Determine whether the awaitable thread is launching.+ auto await_transform(detail::awaitable_thread_is_launching) noexcept { struct result {@@ -450,9 +456,9 @@ { } - bool& await_resume() const noexcept+ bool await_resume() const noexcept {- return this_->attached_thread_->entry_point()->has_context_switched_;+ return this_->is_launching(); } }; @@ -466,7 +472,6 @@ awaitable_thread<Executor>* detach_thread() noexcept {- attached_thread_->entry_point()->has_context_switched_ = true; return std::exchange(attached_thread_, nullptr); } @@ -538,14 +543,14 @@ ~awaitable_frame() { if (has_result_)- static_cast<T*>(static_cast<void*>(result_))->~T();+ std::launder(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)@@ -564,7 +569,8 @@ { this->caller_ = nullptr; this->rethrow_exception();- return std::move(*static_cast<T*>(static_cast<void*>(result_)));+ return std::move(*std::launder(+ static_cast<T*>(static_cast<void*>(result_)))); } private:@@ -581,7 +587,7 @@ { this->coro_ = coroutine_handle<awaitable_frame>::from_promise(*this); return awaitable<void, Executor>(this);- };+ } void return_void() {@@ -604,7 +610,6 @@ awaitable_frame() : top_of_stack_(0), has_executor_(false),- has_context_switched_(false), throw_if_cancelled_(true) { }@@ -619,7 +624,7 @@ { this->coro_ = coroutine_handle<awaitable_frame>::from_promise(*this); return awaitable<awaitable_thread_entry_point, Executor>(this);- };+ } void return_void() {@@ -633,7 +638,8 @@ private: template <typename> friend class awaitable_frame_base;- template <typename, typename> friend class awaitable_async_op_handler;+ template <typename, typename, typename>+ friend class awaitable_async_op_handler; template <typename, typename> friend class awaitable_handler_base; template <typename> friend class awaitable_thread; @@ -649,7 +655,6 @@ asio::cancellation_slot parent_cancellation_slot_; asio::cancellation_state cancellation_state_; bool has_executor_;- bool has_context_switched_; bool throw_if_cancelled_; }; @@ -718,21 +723,21 @@ } template <typename Filter>- void reset_cancellation_state(ASIO_MOVE_ARG(Filter) filter)+ void reset_cancellation_state(Filter&& filter) { bottom_of_stack_.frame_->cancellation_state_ = cancellation_state(bottom_of_stack_.frame_->parent_cancellation_slot_,- ASIO_MOVE_CAST(Filter)(filter));+ static_cast<Filter&&>(filter)); } template <typename InFilter, typename OutFilter>- void reset_cancellation_state(ASIO_MOVE_ARG(InFilter) in_filter,- ASIO_MOVE_ARG(OutFilter) out_filter)+ void reset_cancellation_state(InFilter&& in_filter,+ OutFilter&& out_filter) { bottom_of_stack_.frame_->cancellation_state_ = cancellation_state(bottom_of_stack_.frame_->parent_cancellation_slot_,- ASIO_MOVE_CAST(InFilter)(in_filter),- ASIO_MOVE_CAST(OutFilter)(out_filter));+ static_cast<InFilter&&>(in_filter),+ static_cast<OutFilter&&>(out_filter)); } bool throw_if_cancelled() const@@ -754,7 +759,7 @@ void launch() { bottom_of_stack_.frame_->top_of_stack_->attach_thread(this);- pump();+ bottom_of_stack_.frame_->launch(&awaitable_thread::do_pump, this); } protected:@@ -776,10 +781,15 @@ } } + 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>+template <typename Signature, typename Executor, typename = void> class awaitable_async_op_handler; template <typename R, typename Executor>@@ -807,74 +817,9 @@ } }; -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>+class awaitable_async_op_handler<R(T), Executor,+ enable_if_t<!is_disposition<T>::value>> : public awaitable_thread<Executor> { public:@@ -889,7 +834,7 @@ void operator()(T result) {- result_ = &result;+ result_ = detail::addressof(result); this->entry_point()->top_of_stack_->attach_thread(this); this->entry_point()->top_of_stack_->clear_cancellation_slot(); this->pump();@@ -904,16 +849,13 @@ result_type& result_; }; -template <typename R, typename T, typename Executor>-class awaitable_async_op_handler<R(asio::error_code, T), Executor>+template <typename R, typename Disposition, typename Executor>+class awaitable_async_op_handler<R(Disposition), Executor,+ enable_if_t<is_disposition<Disposition>::value>> : public awaitable_thread<Executor> { public:- struct result_type- {- asio::error_code* ec_;- T* value_;- };+ typedef Disposition* result_type; awaitable_async_op_handler( awaitable_thread<Executor>* h, result_type& result)@@ -922,33 +864,36 @@ { } - void operator()(asio::error_code ec, T value)+ void operator()(Disposition d) {- result_.ec_ = &ec;- result_.value_ = &value;+ result_ = detail::addressof(d); this->entry_point()->top_of_stack_->attach_thread(this); this->entry_point()->top_of_stack_->clear_cancellation_slot(); this->pump(); } - static T resume(result_type& result)+ static void resume(result_type& result) {- throw_error(*result.ec_);- return std::move(*result.value_);+ if (*result != no_error)+ {+ Disposition d = std::exchange(*result, Disposition());+ asio::throw_exception(static_cast<Disposition&&>(d));+ } } private: result_type& result_; }; -template <typename R, typename T, typename Executor>-class awaitable_async_op_handler<R(std::exception_ptr, T), Executor>+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>> : public awaitable_thread<Executor> { public: struct result_type {- std::exception_ptr* ex_;+ Disposition* disposition_; T* value_; }; @@ -959,10 +904,10 @@ { } - void operator()(std::exception_ptr ex, T value)+ void operator()(Disposition d, T value) {- result_.ex_ = &ex;- result_.value_ = &value;+ result_.disposition_ = detail::addressof(d);+ result_.value_ = detail::addressof(value); this->entry_point()->top_of_stack_->attach_thread(this); this->entry_point()->top_of_stack_->clear_cancellation_slot(); this->pump();@@ -970,10 +915,10 @@ static T resume(result_type& result) {- if (*result.ex_)+ if (*result.disposition_ != no_error) {- std::exception_ptr ex = std::exchange(*result.ex_, nullptr);- std::rethrow_exception(ex);+ Disposition d = std::exchange(*result.disposition_, Disposition());+ asio::throw_exception(static_cast<Disposition&&>(d)); } return std::move(*result.value_); }@@ -982,12 +927,13 @@ result_type& result_; }; -template <typename R, typename... Ts, typename Executor>-class awaitable_async_op_handler<R(Ts...), Executor>+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>> : public awaitable_thread<Executor> { public:- typedef std::tuple<Ts...>* result_type;+ typedef std::tuple<T, Ts...>* result_type; awaitable_async_op_handler( awaitable_thread<Executor>* h, result_type& result)@@ -999,14 +945,14 @@ template <typename... Args> void operator()(Args&&... args) {- std::tuple<Ts...> result(std::forward<Args>(args)...);- result_ = &result;+ std::tuple<T, Ts...> result(std::forward<Args>(args)...);+ result_ = detail::addressof(result); 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)+ static std::tuple<T, Ts...> resume(result_type& result) { return std::move(*result); }@@ -1015,53 +961,15 @@ result_type& result_; }; -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- {- asio::error_code* ec_;- 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()(asio::error_code ec, Args&&... args)- {- result_.ec_ = &ec;- 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)- {- 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>+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>> : public awaitable_thread<Executor> { public: struct result_type {- std::exception_ptr* ex_;+ Disposition* disposition_; std::tuple<Ts...>* value_; }; @@ -1073,11 +981,11 @@ } template <typename... Args>- void operator()(std::exception_ptr ex, Args&&... args)+ void operator()(Disposition d, Args&&... args) {- result_.ex_ = &ex;+ result_.disposition_ = detail::addressof(d); std::tuple<Ts...> value(std::forward<Args>(args)...);- result_.value_ = &value;+ result_.value_ = detail::addressof(value); this->entry_point()->top_of_stack_->attach_thread(this); this->entry_point()->top_of_stack_->clear_cancellation_slot(); this->pump();@@ -1085,10 +993,10 @@ static std::tuple<Ts...> resume(result_type& result) {- if (*result.ex_)+ if (*result.disposition_ != no_error) {- std::exception_ptr ex = std::exchange(*result.ex_, nullptr);- std::rethrow_exception(ex);+ Disposition d = std::exchange(*result.disposition_, Disposition());+ asio::throw_exception(static_cast<Disposition&&>(d)); } return std::move(*result.value_); }
+ link/modules/asio-standalone/asio/include/asio/impl/awaitable.ipp view
@@ -0,0 +1,48 @@+//+// 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -16,9 +16,7 @@ #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"@@ -66,11 +64,10 @@ std::size_t previous_size, ReadHandler& handler) : storage_(storage), previous_size_(previous_size),- handler_(ASIO_MOVE_CAST(ReadHandler)(handler))+ handler_(static_cast<ReadHandler&&>(handler)) { } -#if defined(ASIO_HAS_MOVE) buffered_fill_handler(const buffered_fill_handler& other) : storage_(other.storage_), previous_size_(other.previous_size_),@@ -81,16 +78,15 @@ buffered_fill_handler(buffered_fill_handler&& other) : storage_(other.storage_), previous_size_(other.previous_size_),- handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_))+ handler_(static_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);- ASIO_MOVE_OR_LVALUE(ReadHandler)(handler_)(ec, bytes_transferred);+ static_cast<ReadHandler&&>(handler_)(ec, bytes_transferred); } //private:@@ -100,32 +96,6 @@ }; 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) {@@ -133,50 +103,26 @@ 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<- Stream>::type::lowest_layer_type::executor_type executor_type;+ typedef typename remove_reference_t<+ Stream>::lowest_layer_type::executor_type executor_type; explicit initiate_async_buffered_fill(- typename remove_reference<Stream>::type& next_layer)+ remove_reference_t<Stream>& next_layer) : next_layer_(next_layer) { } - executor_type get_executor() const ASIO_NOEXCEPT+ executor_type get_executor() const noexcept { return next_layer_.lowest_layer().get_executor(); } template <typename ReadHandler>- void operator()(ASIO_MOVE_ARG(ReadHandler) handler,+ void operator()(ReadHandler&& handler, buffered_stream_storage* storage) const { // If you get an error on the following line it means that your handler@@ -190,12 +136,12 @@ buffer( storage->data() + previous_size, storage->size() - previous_size),- buffered_fill_handler<typename decay<ReadHandler>::type>(+ buffered_fill_handler<decay_t<ReadHandler>>( *storage, previous_size, handler2.value)); } private:- typename remove_reference<Stream>::type& next_layer_;+ remove_reference_t<Stream>& next_layer_; }; } // namespace detail @@ -208,18 +154,15 @@ DefaultCandidate> : Associator<ReadHandler, DefaultCandidate> {- static typename Associator<ReadHandler, DefaultCandidate>::type- get(const detail::buffered_fill_handler<ReadHandler>& h) ASIO_NOEXCEPT+ static typename Associator<ReadHandler, DefaultCandidate>::type get(+ const detail::buffered_fill_handler<ReadHandler>& h) noexcept { return Associator<ReadHandler, DefaultCandidate>::get(h.handler_); } - 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)))+ static auto get(const detail::buffered_fill_handler<ReadHandler>& h,+ const DefaultCandidate& c) noexcept+ -> decltype(Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c)) { return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c); }@@ -231,15 +174,12 @@ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, std::size_t)) ReadHandler>-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((+inline auto buffered_read_stream<Stream>::async_fill(ReadHandler&& handler)+ -> decltype( 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)>(@@ -289,39 +229,37 @@ const MutableBufferSequence& buffers, ReadHandler& handler) : storage_(storage), buffers_(buffers),- handler_(ASIO_MOVE_CAST(ReadHandler)(handler))+ handler_(static_cast<ReadHandler&&>(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(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_(ASIO_MOVE_CAST(ReadHandler)(other.handler_))- {- }-#endif // defined(ASIO_HAS_MOVE)+ buffered_read_some_handler(buffered_read_some_handler&& other)+ : storage_(other.storage_),+ buffers_(other.buffers_),+ handler_(static_cast<ReadHandler&&>(other.handler_))+ {+ } void operator()(const asio::error_code& ec, std::size_t) { if (ec || storage_.empty()) { const std::size_t length = 0;- ASIO_MOVE_OR_LVALUE(ReadHandler)(handler_)(ec, length);+ static_cast<ReadHandler&&>(handler_)(ec, length); } else { const std::size_t bytes_copied = asio::buffer_copy( buffers_, storage_.data(), storage_.size()); storage_.consume(bytes_copied);- ASIO_MOVE_OR_LVALUE(ReadHandler)(handler_)(ec, bytes_copied);+ static_cast<ReadHandler&&>(handler_)(ec, bytes_copied); } } @@ -332,34 +270,6 @@ }; 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)@@ -368,54 +278,26 @@ 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<- Stream>::type::lowest_layer_type::executor_type executor_type;+ typedef typename remove_reference_t<+ Stream>::lowest_layer_type::executor_type executor_type; explicit initiate_async_buffered_read_some(- typename remove_reference<Stream>::type& next_layer)+ remove_reference_t<Stream>& next_layer) : next_layer_(next_layer) { } - executor_type get_executor() const ASIO_NOEXCEPT+ executor_type get_executor() const noexcept { return next_layer_.lowest_layer().get_executor(); } template <typename ReadHandler, typename MutableBufferSequence>- void operator()(ASIO_MOVE_ARG(ReadHandler) handler,+ void operator()(ReadHandler&& handler, buffered_stream_storage* storage, const MutableBufferSequence& buffers) const {@@ -427,23 +309,23 @@ non_const_lvalue<ReadHandler> handler2(handler); if (buffer_size(buffers) == 0 || !storage->empty()) {- next_layer_.async_read_some(ASIO_MUTABLE_BUFFER(0, 0),+ next_layer_.async_read_some(mutable_buffer(0, 0), buffered_read_some_handler<MutableBufferSequence,- typename decay<ReadHandler>::type>(+ decay_t<ReadHandler>>( *storage, buffers, handler2.value)); } else { initiate_async_buffered_fill<Stream>(this->next_layer_)( buffered_read_some_handler<MutableBufferSequence,- typename decay<ReadHandler>::type>(+ decay_t<ReadHandler>>( *storage, buffers, handler2.value), storage); } } private:- typename remove_reference<Stream>::type& next_layer_;+ remove_reference_t<Stream>& next_layer_; }; } // namespace detail @@ -457,20 +339,18 @@ DefaultCandidate> : Associator<ReadHandler, DefaultCandidate> {- static typename Associator<ReadHandler, DefaultCandidate>::type- get(const detail::buffered_read_some_handler<- MutableBufferSequence, ReadHandler>& h) ASIO_NOEXCEPT+ static typename Associator<ReadHandler, DefaultCandidate>::type get(+ const detail::buffered_read_some_handler<+ MutableBufferSequence, ReadHandler>& h) noexcept { return Associator<ReadHandler, DefaultCandidate>::get(h.handler_); } - static ASIO_AUTO_RETURN_TYPE_PREFIX2(- typename Associator<ReadHandler, DefaultCandidate>::type)- get(const detail::buffered_read_some_handler<+ static auto get(+ const detail::buffered_read_some_handler< MutableBufferSequence, ReadHandler>& h,- const DefaultCandidate& c) ASIO_NOEXCEPT- ASIO_AUTO_RETURN_TYPE_SUFFIX((- Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c)))+ const DefaultCandidate& c) noexcept+ -> decltype(Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c)) { return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c); }@@ -482,16 +362,13 @@ template <typename MutableBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, std::size_t)) ReadHandler>-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((+inline auto buffered_read_stream<Stream>::async_read_some(+ const MutableBufferSequence& buffers, ReadHandler&& handler)+ -> decltype( 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -16,9 +16,7 @@ #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" @@ -54,11 +52,10 @@ buffered_flush_handler(detail::buffered_stream_storage& storage, WriteHandler& handler) : storage_(storage),- handler_(ASIO_MOVE_CAST(WriteHandler)(handler))+ handler_(static_cast<WriteHandler&&>(handler)) { } -#if defined(ASIO_HAS_MOVE) buffered_flush_handler(const buffered_flush_handler& other) : storage_(other.storage_), handler_(other.handler_)@@ -67,16 +64,15 @@ buffered_flush_handler(buffered_flush_handler&& other) : storage_(other.storage_),- handler_(ASIO_MOVE_CAST(WriteHandler)(other.handler_))+ handler_(static_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);- ASIO_MOVE_OR_LVALUE(WriteHandler)(handler_)(ec, bytes_written);+ static_cast<WriteHandler&&>(handler_)(ec, bytes_written); } //private:@@ -85,32 +81,6 @@ }; 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) {@@ -118,50 +88,26 @@ 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<- Stream>::type::lowest_layer_type::executor_type executor_type;+ typedef typename remove_reference_t<+ Stream>::lowest_layer_type::executor_type executor_type; explicit initiate_async_buffered_flush(- typename remove_reference<Stream>::type& next_layer)+ remove_reference_t<Stream>& next_layer) : next_layer_(next_layer) { } - executor_type get_executor() const ASIO_NOEXCEPT+ executor_type get_executor() const noexcept { return next_layer_.lowest_layer().get_executor(); } template <typename WriteHandler>- void operator()(ASIO_MOVE_ARG(WriteHandler) handler,+ void operator()(WriteHandler&& handler, buffered_stream_storage* storage) const { // If you get an error on the following line it means that your handler@@ -170,12 +116,12 @@ non_const_lvalue<WriteHandler> handler2(handler); async_write(next_layer_, buffer(storage->data(), storage->size()),- buffered_flush_handler<typename decay<WriteHandler>::type>(+ buffered_flush_handler<decay_t<WriteHandler>>( *storage, handler2.value)); } private:- typename remove_reference<Stream>::type& next_layer_;+ remove_reference_t<Stream>& next_layer_; }; } // namespace detail @@ -188,18 +134,15 @@ DefaultCandidate> : Associator<WriteHandler, DefaultCandidate> {- static typename Associator<WriteHandler, DefaultCandidate>::type- get(const detail::buffered_flush_handler<WriteHandler>& h) ASIO_NOEXCEPT+ static typename Associator<WriteHandler, DefaultCandidate>::type get(+ const detail::buffered_flush_handler<WriteHandler>& h) noexcept { return Associator<WriteHandler, DefaultCandidate>::get(h.handler_); } - 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)))+ static auto get(const detail::buffered_flush_handler<WriteHandler>& h,+ const DefaultCandidate& c) noexcept+ -> decltype(Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c)) { return Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c); }@@ -211,15 +154,12 @@ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, std::size_t)) WriteHandler>-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((+inline auto buffered_write_stream<Stream>::async_flush(WriteHandler&& handler)+ -> decltype( 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)>(@@ -269,32 +209,30 @@ const ConstBufferSequence& buffers, WriteHandler& handler) : storage_(storage), buffers_(buffers),- handler_(ASIO_MOVE_CAST(WriteHandler)(handler))+ handler_(static_cast<WriteHandler&&>(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(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_(ASIO_MOVE_CAST(WriteHandler)(other.handler_))- {- }-#endif // defined(ASIO_HAS_MOVE)+ buffered_write_some_handler(buffered_write_some_handler&& other)+ : storage_(other.storage_),+ buffers_(other.buffers_),+ handler_(static_cast<WriteHandler&&>(other.handler_))+ {+ } void operator()(const asio::error_code& ec, std::size_t) { if (ec) { const std::size_t length = 0;- ASIO_MOVE_OR_LVALUE(WriteHandler)(handler_)(ec, length);+ static_cast<WriteHandler&&>(handler_)(ec, length); } else {@@ -307,7 +245,7 @@ storage_.resize(orig_size + length); const std::size_t bytes_copied = asio::buffer_copy( storage_.data() + orig_size, buffers_, length);- ASIO_MOVE_OR_LVALUE(WriteHandler)(handler_)(ec, bytes_copied);+ static_cast<WriteHandler&&>(handler_)(ec, bytes_copied); } } @@ -318,34 +256,6 @@ }; 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)@@ -354,54 +264,26 @@ 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<- Stream>::type::lowest_layer_type::executor_type executor_type;+ typedef typename remove_reference_t<+ Stream>::lowest_layer_type::executor_type executor_type; explicit initiate_async_buffered_write_some(- typename remove_reference<Stream>::type& next_layer)+ remove_reference_t<Stream>& next_layer) : next_layer_(next_layer) { } - executor_type get_executor() const ASIO_NOEXCEPT+ executor_type get_executor() const noexcept { return next_layer_.lowest_layer().get_executor(); } template <typename WriteHandler, typename ConstBufferSequence>- void operator()(ASIO_MOVE_ARG(WriteHandler) handler,+ void operator()(WriteHandler&& handler, buffered_stream_storage* storage, const ConstBufferSequence& buffers) const {@@ -413,23 +295,23 @@ non_const_lvalue<WriteHandler> handler2(handler); if (buffer_size(buffers) == 0 || storage->size() < storage->capacity()) {- next_layer_.async_write_some(ASIO_CONST_BUFFER(0, 0),+ next_layer_.async_write_some(const_buffer(0, 0), buffered_write_some_handler<ConstBufferSequence,- typename decay<WriteHandler>::type>(+ decay_t<WriteHandler>>( *storage, buffers, handler2.value)); } else { initiate_async_buffered_flush<Stream>(this->next_layer_)( buffered_write_some_handler<ConstBufferSequence,- typename decay<WriteHandler>::type>(+ decay_t<WriteHandler>>( *storage, buffers, handler2.value), storage); } } private:- typename remove_reference<Stream>::type& next_layer_;+ remove_reference_t<Stream>& next_layer_; }; } // namespace detail @@ -443,20 +325,18 @@ DefaultCandidate> : Associator<WriteHandler, DefaultCandidate> {- static typename Associator<WriteHandler, DefaultCandidate>::type- get(const detail::buffered_write_some_handler<- ConstBufferSequence, WriteHandler>& h) ASIO_NOEXCEPT+ static typename Associator<WriteHandler, DefaultCandidate>::type get(+ const detail::buffered_write_some_handler<+ ConstBufferSequence, WriteHandler>& h) noexcept { return Associator<WriteHandler, DefaultCandidate>::get(h.handler_); } - static ASIO_AUTO_RETURN_TYPE_PREFIX2(- typename Associator<WriteHandler, DefaultCandidate>::type)- get(const detail::buffered_write_some_handler<+ static auto get(+ const detail::buffered_write_some_handler< ConstBufferSequence, WriteHandler>& h,- const DefaultCandidate& c) ASIO_NOEXCEPT- ASIO_AUTO_RETURN_TYPE_SUFFIX((- Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c)))+ const DefaultCandidate& c) noexcept+ -> decltype(Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c)) { return Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c); }@@ -468,16 +348,13 @@ template <typename ConstBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, std::size_t)) WriteHandler>-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((+inline auto buffered_write_stream<Stream>::async_write_some(+ const ConstBufferSequence& buffers, WriteHandler&& handler)+ -> decltype( 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 view
@@ -0,0 +1,268 @@+//+// 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 view
@@ -0,0 +1,268 @@+//+// 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/impl/co_spawn.hpp view
@@ -2,7 +2,7 @@ // impl/co_spawn.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -18,6 +18,8 @@ #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"@@ -33,18 +35,18 @@ class co_spawn_work_guard { public:- typedef typename decay<- typename prefer_result<Executor,+ typedef decay_t<+ prefer_result_t<Executor, execution::outstanding_work_t::tracked_t- >::type- >::type executor_type;+ >+ > executor_type; co_spawn_work_guard(const Executor& ex) : executor_(asio::prefer(ex, execution::outstanding_work.tracked)) { } - executor_type get_executor() const ASIO_NOEXCEPT+ executor_type get_executor() const noexcept { return executor_; }@@ -57,9 +59,9 @@ template <typename Executor> struct co_spawn_work_guard<Executor,- typename enable_if<+ enable_if_t< !execution::is_executor<Executor>::value- >::type> : executor_work_guard<Executor>+ >> : executor_work_guard<Executor> { co_spawn_work_guard(const Executor& ex) : executor_work_guard<Executor>(ex)@@ -69,49 +71,100 @@ #endif // !defined(ASIO_NO_TS_EXECUTORS) -template <typename Executor>-inline co_spawn_work_guard<Executor>-make_co_spawn_work_guard(const Executor& ex)+template <typename Handler, typename Executor,+ typename Function, typename = void>+struct co_spawn_state {- return co_spawn_work_guard<Executor>(ex);-}+ 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))+ {+ } -template <typename T, typename Executor, typename F, typename Handler>-awaitable<awaitable_thread_entry_point, Executor> co_spawn_entry_point(- awaitable<T, Executor>*, Executor ex, F f, Handler handler)+ 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+ >> {- auto spawn_work = make_co_spawn_work_guard(ex);- auto handler_work = make_co_spawn_work_guard(- asio::get_associated_executor(handler, ex));+ 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))+ {+ } - (void) co_await (dispatch)(- use_awaitable_t<Executor>{__FILE__, __LINE__, "co_spawn_entry_point"});+ Handler handler;+ co_spawn_work_guard<Executor> handler_work;+ Function function;+}; - (co_await awaitable_thread_has_context_switched{}) = false;+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 CompletionToken>+ auto operator()(CompletionToken&& token) const+ -> decltype(asio::post(std::forward<CompletionToken>(token)))+ {+ return asio::post(std::forward<CompletionToken>(token));+ }+};++template <typename T, typename Handler, typename Executor, typename Function>+awaitable<awaitable_thread_entry_point, Executor> co_spawn_entry_point(+ awaitable<T, Executor>*, co_spawn_state<Handler, Executor, Function> s)+{+ (void) co_await co_spawn_dispatch{};+ std::exception_ptr e = nullptr; bool done = false;+#if !defined(ASIO_NO_EXCEPTIONS) try+#endif // !defined(ASIO_NO_EXCEPTIONS) {- T t = co_await f();+ T t = co_await s.function(); done = true; - bool switched = (co_await awaitable_thread_has_context_switched{});- if (!switched)+ bool is_launching = (co_await awaitable_thread_is_launching{});+ if (is_launching) {- (void) co_await (post)(- use_awaitable_t<Executor>{__FILE__,- __LINE__, "co_spawn_entry_point"});+ co_await this_coro::throw_if_cancelled(false);+ (void) co_await co_spawn_post(); } - (dispatch)(handler_work.get_executor(),- [handler = std::move(handler), t = std::move(t)]() mutable+ (dispatch)(s.handler_work.get_executor(),+ [handler = std::move(s.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)@@ -119,52 +172,51 @@ e = std::current_exception(); }+#endif // !defined(ASIO_NO_EXCEPTIONS) - bool switched = (co_await awaitable_thread_has_context_switched{});- if (!switched)+ bool is_launching = (co_await awaitable_thread_is_launching{});+ if (is_launching) {- (void) co_await (post)(- use_awaitable_t<Executor>{__FILE__, __LINE__, "co_spawn_entry_point"});+ co_await this_coro::throw_if_cancelled(false);+ (void) co_await co_spawn_post(); } - (dispatch)(handler_work.get_executor(),- [handler = std::move(handler), e]() mutable+ (dispatch)(s.handler_work.get_executor(),+ [handler = std::move(s.handler), e]() mutable { std::move(handler)(e, T()); }); } -template <typename Executor, typename F, typename Handler>+template <typename Handler, typename Executor, typename Function> awaitable<awaitable_thread_entry_point, Executor> co_spawn_entry_point(- awaitable<void, Executor>*, Executor ex, F f, Handler handler)+ awaitable<void, Executor>*, co_spawn_state<Handler, Executor, Function> s) {- 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"});+ (void) co_await co_spawn_dispatch{}; - (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 f();+ co_await s.function(); }+#if !defined(ASIO_NO_EXCEPTIONS) catch (...) { e = std::current_exception(); }+#endif // !defined(ASIO_NO_EXCEPTIONS) - bool switched = (co_await awaitable_thread_has_context_switched{});- if (!switched)+ bool is_launching = (co_await awaitable_thread_is_launching{});+ if (is_launching) {- (void) co_await (post)(- use_awaitable_t<Executor>{__FILE__, __LINE__, "co_spawn_entry_point"});+ co_await this_coro::throw_if_cancelled(false);+ (void) co_await co_spawn_post(); } - (dispatch)(handler_work.get_executor(),- [handler = std::move(handler), e]() mutable+ (dispatch)(s.handler_work.get_executor(),+ [handler = std::move(s.handler), e]() mutable { std::move(handler)(e); });@@ -193,36 +245,38 @@ { public: co_spawn_cancellation_handler(const Handler&, const Executor& ex)- : ex_(ex)+ : signal_(detail::allocate_shared<cancellation_signal>(+ detail::recycling_allocator<cancellation_signal,+ detail::thread_info_base::cancellation_signal_tag>())),+ ex_(ex) { } cancellation_slot slot() {- return signal_.slot();+ return signal_->slot(); } void operator()(cancellation_type_t type) {- cancellation_signal* sig = &signal_;+ shared_ptr<cancellation_signal> sig = signal_; asio::dispatch(ex_, [sig, type]{ sig->emit(type); }); } private:- cancellation_signal signal_;+ shared_ptr<cancellation_signal> signal_; Executor ex_; }; - template <typename Handler, typename Executor> class co_spawn_cancellation_handler<Handler, Executor,- typename enable_if<+ enable_if_t< is_same< typename associated_executor<Handler, Executor>::asio_associated_executor_is_unspecialised, void >::value- >::type>+ >> { public: co_spawn_cancellation_handler(const Handler&, const Executor&)@@ -255,7 +309,7 @@ { } - executor_type get_executor() const ASIO_NOEXCEPT+ executor_type get_executor() const noexcept { return ex_; }@@ -263,8 +317,9 @@ template <typename Handler, typename F> void operator()(Handler&& handler, F&& f) const {- typedef typename result_of<F()>::type awaitable_type;- typedef typename decay<Handler>::type handler_type;+ typedef result_of_t<F()> awaitable_type;+ typedef decay_t<Handler> handler_type;+ typedef decay_t<F> function_type; typedef co_spawn_cancellation_handler< handler_type, Executor> cancel_handler_type; @@ -281,7 +336,8 @@ cancellation_state cancel_state(proxy_slot); auto a = (co_spawn_entry_point)(static_cast<awaitable_type*>(nullptr),- ex_, std::forward<F>(f), std::forward<Handler>(handler));+ co_spawn_state<handler_type, Executor, function_type>(+ std::forward<Handler>(handler), ex_, std::forward<F>(f))); awaitable_handler<executor_type, void>(std::move(a), ex_, proxy_slot, cancel_state).launch(); }@@ -299,10 +355,10 @@ CompletionToken, void(std::exception_ptr, T)) co_spawn(const Executor& ex, awaitable<T, AwaitableExecutor> a, CompletionToken&& token,- typename constraint<+ constraint_t< (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)),@@ -316,10 +372,10 @@ CompletionToken, void(std::exception_ptr)) co_spawn(const Executor& ex, awaitable<void, AwaitableExecutor> a, CompletionToken&& token,- typename constraint<+ constraint_t< (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)),@@ -334,11 +390,11 @@ CompletionToken, void(std::exception_ptr, T)) co_spawn(ExecutionContext& ctx, awaitable<T, AwaitableExecutor> a, CompletionToken&& token,- typename constraint<+ constraint_t< 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));@@ -351,11 +407,11 @@ CompletionToken, void(std::exception_ptr)) co_spawn(ExecutionContext& ctx, awaitable<void, AwaitableExecutor> a, CompletionToken&& token,- typename constraint<+ constraint_t< 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));@@ -363,30 +419,30 @@ template <typename Executor, typename F, ASIO_COMPLETION_TOKEN_FOR(typename detail::awaitable_signature<- typename result_of<F()>::type>::type) CompletionToken>+ result_of_t<F()>>::type) CompletionToken> inline ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken,- typename detail::awaitable_signature<typename result_of<F()>::type>::type)+ typename detail::awaitable_signature<result_of_t<F()>>::type) co_spawn(const Executor& ex, F&& f, CompletionToken&& token,- typename constraint<+ constraint_t< is_executor<Executor>::value || execution::is_executor<Executor>::value- >::type)+ >) { return async_initiate<CompletionToken,- typename detail::awaitable_signature<typename result_of<F()>::type>::type>(+ typename detail::awaitable_signature<result_of_t<F()>>::type>( detail::initiate_co_spawn<- typename result_of<F()>::type::executor_type>(ex),+ typename result_of_t<F()>::executor_type>(ex), token, std::forward<F>(f)); } template <typename ExecutionContext, typename F, ASIO_COMPLETION_TOKEN_FOR(typename detail::awaitable_signature<- typename result_of<F()>::type>::type) CompletionToken>+ result_of_t<F()>>::type) CompletionToken> inline ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken,- typename detail::awaitable_signature<typename result_of<F()>::type>::type)+ typename detail::awaitable_signature<result_of_t<F()>>::type) co_spawn(ExecutionContext& ctx, F&& f, CompletionToken&& token,- typename constraint<+ constraint_t< 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 view
@@ -0,0 +1,102 @@+//+// 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 view
@@ -0,0 +1,345 @@+//+// 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -19,9 +19,7 @@ #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"@@ -36,15 +34,6 @@ 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)@@ -52,38 +41,15 @@ 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,- typename enable_if<is_legacy_connect_condition<- ConnectCondition, Iterator>::value>::type* = 0)+ constraint_t<+ is_same<+ result_of_t<ConnectCondition(asio::error_code, Iterator)>,+ Iterator+ >::value+ > = 0) { if (next != end) return connect_condition(ec, next);@@ -93,21 +59,27 @@ template <typename ConnectCondition, typename Iterator> inline Iterator call_connect_condition(ConnectCondition& connect_condition, const asio::error_code& ec, Iterator next, Iterator end,- typename enable_if<!is_legacy_connect_condition<- ConnectCondition, Iterator>::value>::type* = 0)+ constraint_t<+ is_same<+ result_of_t<ConnectCondition(asio::error_code,+ decltype(*declval<Iterator>()))>,+ bool+ >::value+ > = 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,- typename constraint<is_endpoint_sequence<- EndpointSequence>::value>::type)+ constraint_t<+ is_endpoint_sequence<EndpointSequence>::value+ >) { asio::error_code ec; typename Protocol::endpoint result = connect(s, endpoints, ec);@@ -118,35 +90,16 @@ template <typename Protocol, typename Executor, typename EndpointSequence> typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s, const EndpointSequence& endpoints, asio::error_code& ec,- typename constraint<is_endpoint_sequence<- EndpointSequence>::value>::type)+ constraint_t<+ is_endpoint_sequence<EndpointSequence>::value+ >) { 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) {@@ -167,8 +120,13 @@ typename EndpointSequence, typename ConnectCondition> typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s, const EndpointSequence& endpoints, ConnectCondition connect_condition,- typename constraint<is_endpoint_sequence<- EndpointSequence>::value>::type)+ constraint_t<+ is_endpoint_sequence<EndpointSequence>::value+ >,+ constraint_t<+ is_connect_condition<ConnectCondition,+ decltype(declval<const EndpointSequence&>().begin())>::value+ >) { asio::error_code ec; typename Protocol::endpoint result = connect(@@ -182,42 +140,26 @@ typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s, const EndpointSequence& endpoints, ConnectCondition connect_condition, asio::error_code& ec,- typename constraint<is_endpoint_sequence<- EndpointSequence>::value>::type)+ constraint_t<+ is_endpoint_sequence<EndpointSequence>::value+ >,+ constraint_t<+ is_connect_condition<ConnectCondition,+ decltype(declval<const EndpointSequence&>().begin())>::value+ >) { 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)+ Iterator end, ConnectCondition connect_condition,+ constraint_t<+ is_connect_condition<ConnectCondition, Iterator>::value+ >) { asio::error_code ec; Iterator result = connect(s, begin, end, connect_condition, ec);@@ -229,7 +171,10 @@ typename Iterator, typename ConnectCondition> Iterator connect(basic_socket<Protocol, Executor>& s, Iterator begin, Iterator end, ConnectCondition connect_condition,- asio::error_code& ec)+ asio::error_code& ec,+ constraint_t<+ is_connect_condition<ConnectCondition, Iterator>::value+ >) { ec = asio::error_code(); @@ -311,11 +256,10 @@ endpoints_(endpoints), index_(0), start_(0),- handler_(ASIO_MOVE_CAST(RangeConnectHandler)(handler))+ handler_(static_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),@@ -329,17 +273,16 @@ range_connect_op(range_connect_op&& other) : base_from_cancellation_state<RangeConnectHandler>(- ASIO_MOVE_CAST(base_from_cancellation_state<- RangeConnectHandler>)(other)),+ static_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_(ASIO_MOVE_CAST(RangeConnectHandler)(other.handler_))+ handler_(static_cast<RangeConnectHandler&&>(other.handler_)) { }-#endif // defined(ASIO_HAS_MOVE) void operator()(asio::error_code ec, int start = 0) {@@ -369,7 +312,7 @@ socket_.close(ec); ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_connect")); socket_.async_connect(*iter,- ASIO_MOVE_CAST(range_connect_op)(*this));+ static_cast<range_connect_op&&>(*this)); return; } @@ -379,7 +322,7 @@ ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_connect")); asio::post(socket_.get_executor(), detail::bind_handler(- ASIO_MOVE_CAST(range_connect_op)(*this), ec));+ static_cast<range_connect_op&&>(*this), ec)); return; } @@ -407,7 +350,7 @@ ++index_; } - ASIO_MOVE_OR_LVALUE(RangeConnectHandler)(handler_)(+ static_cast<RangeConnectHandler&&>(handler_)( static_cast<const asio::error_code&>(ec), static_cast<const typename Protocol::endpoint&>( ec || iter == end ? typename Protocol::endpoint() : *iter));@@ -423,36 +366,6 @@ 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)@@ -461,36 +374,6 @@ 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 {@@ -502,14 +385,14 @@ { } - executor_type get_executor() const ASIO_NOEXCEPT+ executor_type get_executor() const noexcept { return socket_.get_executor(); } template <typename RangeConnectHandler, typename EndpointSequence, typename ConnectCondition>- void operator()(ASIO_MOVE_ARG(RangeConnectHandler) handler,+ void operator()(RangeConnectHandler&& handler, const EndpointSequence& endpoints, const ConnectCondition& connect_condition) const {@@ -521,7 +404,7 @@ non_const_lvalue<RangeConnectHandler> handler2(handler); range_connect_op<Protocol, Executor, EndpointSequence, ConnectCondition,- typename decay<RangeConnectHandler>::type>(socket_, endpoints,+ decay_t<RangeConnectHandler>>(socket_, endpoints, connect_condition, handler2.value)(asio::error_code(), 1); } @@ -547,11 +430,10 @@ iter_(begin), end_(end), start_(0),- handler_(ASIO_MOVE_CAST(IteratorConnectHandler)(handler))+ handler_(static_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),@@ -565,17 +447,16 @@ iterator_connect_op(iterator_connect_op&& other) : base_from_cancellation_state<IteratorConnectHandler>(- ASIO_MOVE_CAST(base_from_cancellation_state<- IteratorConnectHandler>)(other)),+ static_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_(ASIO_MOVE_CAST(IteratorConnectHandler)(other.handler_))+ handler_(static_cast<IteratorConnectHandler&&>(other.handler_)) { }-#endif // defined(ASIO_HAS_MOVE) void operator()(asio::error_code ec, int start = 0) {@@ -591,7 +472,7 @@ socket_.close(ec); ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_connect")); socket_.async_connect(*iter_,- ASIO_MOVE_CAST(iterator_connect_op)(*this));+ static_cast<iterator_connect_op&&>(*this)); return; } @@ -601,7 +482,7 @@ ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_connect")); asio::post(socket_.get_executor(), detail::bind_handler(- ASIO_MOVE_CAST(iterator_connect_op)(*this), ec));+ static_cast<iterator_connect_op&&>(*this), ec)); return; } @@ -628,7 +509,7 @@ ++iter_; } - ASIO_MOVE_OR_LVALUE(IteratorConnectHandler)(handler_)(+ static_cast<IteratorConnectHandler&&>(handler_)( static_cast<const asio::error_code&>(ec), static_cast<const Iterator&>(iter_)); }@@ -644,36 +525,6 @@ 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)@@ -682,36 +533,6 @@ 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 {@@ -724,14 +545,14 @@ { } - executor_type get_executor() const ASIO_NOEXCEPT+ executor_type get_executor() const noexcept { return socket_.get_executor(); } template <typename IteratorConnectHandler, typename Iterator, typename ConnectCondition>- void operator()(ASIO_MOVE_ARG(IteratorConnectHandler) handler,+ void operator()(IteratorConnectHandler&& handler, Iterator begin, Iterator end, const ConnectCondition& connect_condition) const {@@ -743,7 +564,7 @@ non_const_lvalue<IteratorConnectHandler> handler2(handler); iterator_connect_op<Protocol, Executor, Iterator, ConnectCondition,- typename decay<IteratorConnectHandler>::type>(socket_, begin, end,+ decay_t<IteratorConnectHandler>>(socket_, begin, end, connect_condition, handler2.value)(asio::error_code(), 1); } @@ -764,21 +585,20 @@ DefaultCandidate> : Associator<RangeConnectHandler, DefaultCandidate> {- static typename Associator<RangeConnectHandler, DefaultCandidate>::type- get(const detail::range_connect_op<Protocol, Executor, EndpointSequence,- ConnectCondition, RangeConnectHandler>& h) ASIO_NOEXCEPT+ static typename Associator<RangeConnectHandler, DefaultCandidate>::type get(+ const detail::range_connect_op<Protocol, Executor, EndpointSequence,+ ConnectCondition, RangeConnectHandler>& h) noexcept { return Associator<RangeConnectHandler, DefaultCandidate>::get(h.handler_); } - static ASIO_AUTO_RETURN_TYPE_PREFIX2(- typename Associator<RangeConnectHandler, DefaultCandidate>::type)- get(const detail::range_connect_op<Protocol, Executor,+ static auto get(+ const detail::range_connect_op<Protocol, Executor, EndpointSequence, ConnectCondition, RangeConnectHandler>& h,- const DefaultCandidate& c) ASIO_NOEXCEPT- ASIO_AUTO_RETURN_TYPE_SUFFIX((+ const DefaultCandidate& c) noexcept+ -> decltype( Associator<RangeConnectHandler, DefaultCandidate>::get(- h.handler_, c)))+ h.handler_, c)) { return Associator<RangeConnectHandler, DefaultCandidate>::get( h.handler_, c);@@ -797,20 +617,19 @@ { static typename Associator<IteratorConnectHandler, DefaultCandidate>::type get(const detail::iterator_connect_op<Protocol, Executor, Iterator,- ConnectCondition, IteratorConnectHandler>& h) ASIO_NOEXCEPT+ ConnectCondition, IteratorConnectHandler>& h) noexcept { return Associator<IteratorConnectHandler, DefaultCandidate>::get( h.handler_); } - static ASIO_AUTO_RETURN_TYPE_PREFIX2(- typename Associator<IteratorConnectHandler, DefaultCandidate>::type)- get(const detail::iterator_connect_op<Protocol, Executor,+ static auto get(+ const detail::iterator_connect_op<Protocol, Executor, Iterator, ConnectCondition, IteratorConnectHandler>& h,- const DefaultCandidate& c) ASIO_NOEXCEPT- ASIO_AUTO_RETURN_TYPE_SUFFIX((+ const DefaultCandidate& c) noexcept+ -> decltype( Associator<IteratorConnectHandler, DefaultCandidate>::get(- h.handler_, c)))+ h.handler_, c)) { return Associator<IteratorConnectHandler, DefaultCandidate>::get( h.handler_, c);@@ -818,139 +637,6 @@ }; #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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/impl/connect_pipe.ipp view
@@ -2,7 +2,7 @@ // impl/connect_pipe.ipp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2021 Klemens D. Morgenstern // (klemens dot morgenstern at gmx dot net) //@@ -62,8 +62,9 @@ _snwprintf( #endif // defined(ASIO_HAS_SECURE_RTL) pipe_name, 128,- L"\\\\.\\pipe\\asio-A0812896-741A-484D-AF23-BE51BF620E22-%u-%ld-%ld",- static_cast<unsigned int>(::GetCurrentProcessId()), n1, n2);+ // 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); 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -16,15 +16,12 @@ #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/handler_invoke_helpers.hpp"+#include "asio/detail/initiation_base.hpp" #include "asio/detail/type_traits.hpp" #include "asio/detail/utility.hpp"-#include "asio/detail/variadic_templates.hpp" #include "asio/detail/push_options.hpp" @@ -39,17 +36,16 @@ typedef void result_type; template <typename H>- 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))+ consign_handler(H&& handler, std::tuple<Values...> values)+ : handler_(static_cast<H&&>(handler)),+ values_(static_cast<std::tuple<Values...>&&>(values)) { } template <typename... Args>- void operator()(ASIO_MOVE_ARG(Args)... args)+ void operator()(Args&&... args) {- ASIO_MOVE_OR_LVALUE(Handler)(handler_)(- ASIO_MOVE_CAST(Args)(args)...);+ static_cast<Handler&&>(handler_)(static_cast<Args&&>(args)...); } //private:@@ -58,32 +54,6 @@ }; 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) {@@ -91,82 +61,57 @@ 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+ struct init_wrapper : detail::initiation_base<Initiation> {- init_wrapper(Initiation init)- : initiation_(ASIO_MOVE_CAST(Initiation)(init))+ using detail::initiation_base<Initiation>::initiation_base;++ template <typename Handler, typename... Args>+ void operator()(Handler&& handler,+ std::tuple<Values...> values, Args&&... args) && {+ 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()(- ASIO_MOVE_ARG(Handler) handler,- std::tuple<Values...> values,- ASIO_MOVE_ARG(Args)... args)+ void operator()(Handler&& handler,+ std::tuple<Values...> values, Args&&... args) const & {- 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)...);+ 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)...); }-- Initiation initiation_; }; template <typename Initiation, typename RawCompletionToken, typename... 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)+ 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)...)) { return async_initiate<CompletionToken, Signatures...>(- 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)...);+ init_wrapper<decay_t<Initiation>>(+ static_cast<Initiation&&>(initiation)),+ token.token_, static_cast<std::tuple<Values...>&&>(token.values_),+ static_cast<Args&&>(args)...); } }; @@ -176,18 +121,15 @@ detail::consign_handler<Handler, Values...>, DefaultCandidate> : Associator<Handler, DefaultCandidate> {- static typename Associator<Handler, DefaultCandidate>::type- get(const detail::consign_handler<Handler, Values...>& h) ASIO_NOEXCEPT+ static typename Associator<Handler, DefaultCandidate>::type get(+ const detail::consign_handler<Handler, Values...>& h) noexcept { return Associator<Handler, DefaultCandidate>::get(h.handler_); } - 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)))+ static auto get(const detail::consign_handler<Handler, Values...>& h,+ const DefaultCandidate& c) noexcept+ -> decltype(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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -27,15 +27,13 @@ public: template <typename Initiation, typename... InitArgs> static deferred_async_operation<Signature, Initiation, InitArgs...>- initiate(ASIO_MOVE_ARG(Initiation) initiation,- deferred_t, ASIO_MOVE_ARG(InitArgs)... args)+ initiate(Initiation&& initiation, deferred_t, InitArgs&&... args) {- return deferred_async_operation<- Signature, Initiation, InitArgs...>(- deferred_init_tag{},- ASIO_MOVE_CAST(Initiation)(initiation),- ASIO_MOVE_CAST(InitArgs)(args)...);- }+ return deferred_async_operation<Signature, Initiation, InitArgs...>(+ deferred_init_tag{},+ static_cast<Initiation&&>(initiation),+ static_cast<InitArgs&&>(args)...);+ } }; template <typename... Signatures>@@ -45,15 +43,14 @@ template <typename Initiation, typename... InitArgs> static deferred_async_operation< deferred_signatures<Signatures...>, Initiation, InitArgs...>- initiate(ASIO_MOVE_ARG(Initiation) initiation,- deferred_t, ASIO_MOVE_ARG(InitArgs)... args)+ initiate(Initiation&& initiation, deferred_t, InitArgs&&... args) { return deferred_async_operation< deferred_signatures<Signatures...>, Initiation, InitArgs...>( deferred_init_tag{},- ASIO_MOVE_CAST(Initiation)(initiation),- ASIO_MOVE_CAST(InitArgs)(args)...);- }+ static_cast<Initiation&&>(initiation),+ static_cast<InitArgs&&>(args)...);+ } }; template <typename Function, typename Signature>@@ -61,9 +58,8 @@ { public: template <typename Initiation, typename... InitArgs>- static auto initiate(ASIO_MOVE_ARG(Initiation) initiation,- deferred_function<Function> token,- ASIO_MOVE_ARG(InitArgs)... init_args)+ static auto initiate(Initiation&& initiation,+ deferred_function<Function> token, InitArgs&&... init_args) -> decltype( deferred_sequence< deferred_async_operation<@@ -72,9 +68,9 @@ deferred_async_operation< Signature, Initiation, InitArgs...>( deferred_init_tag{},- ASIO_MOVE_CAST(Initiation)(initiation),- ASIO_MOVE_CAST(InitArgs)(init_args)...),- ASIO_MOVE_CAST(Function)(token.function_)))+ static_cast<Initiation&&>(initiation),+ static_cast<InitArgs&&>(init_args)...),+ static_cast<Function&&>(token.function_))) { return deferred_sequence< deferred_async_operation<@@ -83,9 +79,9 @@ deferred_async_operation< Signature, Initiation, InitArgs...>( deferred_init_tag{},- ASIO_MOVE_CAST(Initiation)(initiation),- ASIO_MOVE_CAST(InitArgs)(init_args)...),- ASIO_MOVE_CAST(Function)(token.function_));+ static_cast<Initiation&&>(initiation),+ static_cast<InitArgs&&>(init_args)...),+ static_cast<Function&&>(token.function_)); } }; @@ -94,9 +90,8 @@ { public: template <typename Initiation, typename... InitArgs>- static auto initiate(ASIO_MOVE_ARG(Initiation) initiation,- deferred_function<Function> token,- ASIO_MOVE_ARG(InitArgs)... init_args)+ static auto initiate(Initiation&& initiation,+ deferred_function<Function> token, InitArgs&&... init_args) -> decltype( deferred_sequence< deferred_async_operation<@@ -105,9 +100,9 @@ deferred_async_operation< deferred_signatures<Signatures...>, Initiation, InitArgs...>( deferred_init_tag{},- ASIO_MOVE_CAST(Initiation)(initiation),- ASIO_MOVE_CAST(InitArgs)(init_args)...),- ASIO_MOVE_CAST(Function)(token.function_)))+ static_cast<Initiation&&>(initiation),+ static_cast<InitArgs&&>(init_args)...),+ static_cast<Function&&>(token.function_))) { return deferred_sequence< deferred_async_operation<@@ -116,9 +111,9 @@ deferred_async_operation< deferred_signatures<Signatures...>, Initiation, InitArgs...>( deferred_init_tag{},- ASIO_MOVE_CAST(Initiation)(initiation),- ASIO_MOVE_CAST(InitArgs)(init_args)...),- ASIO_MOVE_CAST(Function)(token.function_));+ static_cast<Initiation&&>(initiation),+ static_cast<InitArgs&&>(init_args)...),+ static_cast<Function&&>(token.function_)); } }; @@ -129,19 +124,15 @@ DefaultCandidate> : Associator<Handler, DefaultCandidate> {- static typename Associator<Handler, DefaultCandidate>::type- get(const detail::deferred_sequence_handler<Handler, Tail>& h)- ASIO_NOEXCEPT+ static typename Associator<Handler, DefaultCandidate>::type get(+ const detail::deferred_sequence_handler<Handler, Tail>& h) noexcept { return Associator<Handler, DefaultCandidate>::get(h.handler_); } - 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)))+ static auto get(const detail::deferred_sequence_handler<Handler, Tail>& h,+ const DefaultCandidate& c) noexcept+ -> decltype(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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -17,7 +17,6 @@ #include "asio/detail/config.hpp" #include "asio/async_result.hpp"-#include "asio/detail/variadic_templates.hpp" #include "asio/detail/push_options.hpp" @@ -34,37 +33,18 @@ { } -#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 Signature>-struct async_result<detached_t, Signature>+template <typename... Signatures>+struct async_result<detached_t, Signatures...> { typedef asio::detail::detached_handler completion_handler_type; @@ -78,47 +58,14 @@ { } -#if defined(ASIO_HAS_VARIADIC_TEMPLATES)- template <typename Initiation, typename RawCompletionToken, typename... Args>- static return_type initiate(- ASIO_MOVE_ARG(Initiation) initiation,- ASIO_MOVE_ARG(RawCompletionToken),- ASIO_MOVE_ARG(Args)... args)+ static return_type initiate(Initiation&& initiation,+ RawCompletionToken&&, Args&&... args) {- ASIO_MOVE_CAST(Initiation)(initiation)(+ static_cast<Initiation&&>(initiation)( detail::detached_handler(detached_t()),- 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()));+ static_cast<Args&&>(args)...); }--#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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -31,7 +31,7 @@ class netdb_category : public asio::error_category { public:- const char* name() const ASIO_ERROR_CATEGORY_NOEXCEPT+ const char* name() const noexcept { return "asio.netdb"; }@@ -63,7 +63,7 @@ class addrinfo_category : public asio::error_category { public:- const char* name() const ASIO_ERROR_CATEGORY_NOEXCEPT+ const char* name() const noexcept { return "asio.addrinfo"; }@@ -93,7 +93,7 @@ class misc_category : public asio::error_category { public:- const char* name() const ASIO_ERROR_CATEGORY_NOEXCEPT+ const char* name() const 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -37,7 +37,7 @@ class system_category : public error_category { public:- const char* name() const ASIO_ERROR_CATEGORY_NOEXCEPT+ const char* name() const noexcept { return "asio.system"; }@@ -108,7 +108,7 @@ #if defined(ASIO_HAS_STD_ERROR_CODE) std::error_condition default_error_condition(- int ev) const ASIO_ERROR_CATEGORY_NOEXCEPT+ int ev) const noexcept { switch (ev) {@@ -182,6 +182,7 @@ 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -15,67 +15,103 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) +#include <cstring> #include "asio/detail/handler_type_requirements.hpp"-#include "asio/detail/scoped_ptr.hpp"+#include "asio/detail/memory.hpp" #include "asio/detail/service_registry.hpp"+#include "asio/detail/throw_exception.hpp" #include "asio/detail/push_options.hpp" namespace asio { -#if !defined(GENERATING_DOCUMENTATION)+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 Service>-inline Service& use_service(execution_context& e)+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) {- // Check that Service meets the necessary type requirements.- (void)static_cast<execution_context::service*>(static_cast<Service*>(0));+} - return e.service_registry_->template use_service<Service>();+inline execution_context::auto_allocator_ptr::~auto_allocator_ptr()+{+ ptr_->destroy(); } -#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+template <typename Allocator>+void execution_context::allocator_impl<Allocator>::destroy()+{+ detail::deallocate_object(allocator_, this);+} -template <typename Service, typename... Args>-Service& make_service(execution_context& e, ASIO_MOVE_ARG(Args)... args)+template <typename Allocator>+void* execution_context::allocator_impl<Allocator>::allocate(+ std::size_t size, std::size_t align) {- 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;+ 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; } -#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)+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>-Service& make_service(execution_context& e)+inline Service& use_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;+ // Check that Service meets the necessary type requirements.+ (void)static_cast<execution_context::service*>(static_cast<Service*>(0));++ return e.service_registry_->template use_service<Service>(); } -#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+template <typename Service, typename... Args>+Service& make_service(execution_context& e, Args&&... args)+{+ // Check that Service meets the necessary type requirements.+ (void)static_cast<execution_context::service*>(static_cast<Service*>(0)); -#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+ return e.service_registry_->template make_service<Service>(+ static_cast<Args&&>(args)...);+} 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -24,15 +24,44 @@ namespace asio { execution_context::execution_context()- : service_registry_(new asio::detail::service_registry(*this))+ : 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)+{+}++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();- delete service_registry_;+ detail::deallocate_object(allocator<void>(*this), service_registry_); } void execution_context::shutdown()@@ -51,9 +80,14 @@ service_registry_->notify_fork(event); } +execution_context::allocator_impl_base::~allocator_impl_base()+{+}+ execution_context::service::service(execution_context& owner) : owner_(owner),- next_(0)+ next_(0),+ destroy_(0) { } @@ -62,6 +96,10 @@ } 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -19,6 +19,7 @@ #if !defined(ASIO_NO_TS_EXECUTORS) +#include <new> #include "asio/detail/atomic_count.hpp" #include "asio/detail/global.hpp" #include "asio/detail/memory.hpp"@@ -47,7 +48,12 @@ return p; } - impl(const Executor& e, const Allocator& a) ASIO_NOEXCEPT+ 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_base(false), ref_count_(1), executor_(e),@@ -55,13 +61,13 @@ { } - impl_base* clone() const ASIO_NOEXCEPT+ impl_base* clone() const noexcept { detail::ref_count_up(ref_count_); return const_cast<impl_base*>(static_cast<const impl_base*>(this)); } - void destroy() ASIO_NOEXCEPT+ void destroy() noexcept { if (detail::ref_count_down(ref_count_)) {@@ -72,52 +78,52 @@ } } - void on_work_started() ASIO_NOEXCEPT+ void on_work_started() noexcept { executor_.on_work_started(); } - void on_work_finished() ASIO_NOEXCEPT+ void on_work_finished() noexcept { executor_.on_work_finished(); } - execution_context& context() ASIO_NOEXCEPT+ execution_context& context() noexcept { return executor_.context(); } - void dispatch(ASIO_MOVE_ARG(function) f)+ void dispatch(function&& f) {- executor_.dispatch(ASIO_MOVE_CAST(function)(f), allocator_);+ executor_.dispatch(static_cast<function&&>(f), allocator_); } - void post(ASIO_MOVE_ARG(function) f)+ void post(function&& f) {- executor_.post(ASIO_MOVE_CAST(function)(f), allocator_);+ executor_.post(static_cast<function&&>(f), allocator_); } - void defer(ASIO_MOVE_ARG(function) f)+ void defer(function&& f) {- executor_.defer(ASIO_MOVE_CAST(function)(f), allocator_);+ executor_.defer(static_cast<function&&>(f), allocator_); } - type_id_result_type target_type() const ASIO_NOEXCEPT+ type_id_result_type target_type() const noexcept { return type_id<Executor>(); } - void* target() ASIO_NOEXCEPT+ void* target() noexcept { return &executor_; } - const void* target() const ASIO_NOEXCEPT+ const void* target() const noexcept { return &executor_; } - bool equals(const impl_base* e) const ASIO_NOEXCEPT+ bool equals(const impl_base* e) const noexcept { if (this == e) return true;@@ -164,72 +170,77 @@ static impl_base* create(const system_executor&, const Allocator& = Allocator()) {- return &detail::global<impl<system_executor, std::allocator<void> > >();+ 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>> >();+ }+ impl() : impl_base(true) { } - impl_base* clone() const ASIO_NOEXCEPT+ impl_base* clone() const noexcept { return const_cast<impl_base*>(static_cast<const impl_base*>(this)); } - void destroy() ASIO_NOEXCEPT+ void destroy() noexcept { } - void on_work_started() ASIO_NOEXCEPT+ void on_work_started() noexcept { executor_.on_work_started(); } - void on_work_finished() ASIO_NOEXCEPT+ void on_work_finished() noexcept { executor_.on_work_finished(); } - execution_context& context() ASIO_NOEXCEPT+ execution_context& context() noexcept { return executor_.context(); } - void dispatch(ASIO_MOVE_ARG(function) f)+ void dispatch(function&& f) {- executor_.dispatch(ASIO_MOVE_CAST(function)(f),+ executor_.dispatch(static_cast<function&&>(f), std::allocator<void>()); } - void post(ASIO_MOVE_ARG(function) f)+ void post(function&& f) {- executor_.post(ASIO_MOVE_CAST(function)(f),+ executor_.post(static_cast<function&&>(f), std::allocator<void>()); } - void defer(ASIO_MOVE_ARG(function) f)+ void defer(function&& f) {- executor_.defer(ASIO_MOVE_CAST(function)(f),+ executor_.defer(static_cast<function&&>(f), std::allocator<void>()); } - type_id_result_type target_type() const ASIO_NOEXCEPT+ type_id_result_type target_type() const noexcept { return type_id<system_executor>(); } - void* target() ASIO_NOEXCEPT+ void* target() noexcept { return &executor_; } - const void* target() const ASIO_NOEXCEPT+ const void* target() const noexcept { return &executor_; } - bool equals(const impl_base* e) const ASIO_NOEXCEPT+ bool equals(const impl_base* e) const noexcept { return this == e; }@@ -240,10 +251,16 @@ template <typename Executor> executor::executor(Executor e)- : impl_(impl<Executor, std::allocator<void> >::create(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))+{+}+ template <typename Executor, typename Allocator> executor::executor(allocator_arg_t, const Allocator& a, Executor e) : impl_(impl<Executor, Allocator>::create(e, a))@@ -251,39 +268,39 @@ } template <typename Function, typename Allocator>-void executor::dispatch(ASIO_MOVE_ARG(Function) f,+void executor::dispatch(Function&& f, const Allocator& a) const { impl_base* i = get_impl(); if (i->fast_dispatch_)- system_executor().dispatch(ASIO_MOVE_CAST(Function)(f), a);+ system_executor().dispatch(static_cast<Function&&>(f), a); else- i->dispatch(function(ASIO_MOVE_CAST(Function)(f), a));+ i->dispatch(function(static_cast<Function&&>(f), a)); } template <typename Function, typename Allocator>-void executor::post(ASIO_MOVE_ARG(Function) f,+void executor::post(Function&& f, const Allocator& a) const {- get_impl()->post(function(ASIO_MOVE_CAST(Function)(f), a));+ get_impl()->post(function(static_cast<Function&&>(f), a)); } template <typename Function, typename Allocator>-void executor::defer(ASIO_MOVE_ARG(Function) f,+void executor::defer(Function&& f, const Allocator& a) const {- get_impl()->defer(function(ASIO_MOVE_CAST(Function)(f), a));+ get_impl()->defer(function(static_cast<Function&&>(f), a)); } template <typename Executor>-Executor* executor::target() ASIO_NOEXCEPT+Executor* executor::target() noexcept { return impl_ && impl_->target_type() == type_id<Executor>() ? static_cast<Executor*>(impl_->target()) : 0; } template <typename Executor>-const Executor* executor::target() const ASIO_NOEXCEPT+const Executor* executor::target() const 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -25,11 +25,11 @@ namespace asio { -bad_executor::bad_executor() ASIO_NOEXCEPT+bad_executor::bad_executor() noexcept { } -const char* bad_executor::what() const ASIO_NOEXCEPT_OR_NOTHROW+const char* bad_executor::what() const noexcept { return "bad executor"; }
− link/modules/asio-standalone/asio/include/asio/impl/handler_alloc_hook.ipp
@@ -1,62 +0,0 @@-//-// 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -15,6 +15,7 @@ # 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"@@ -28,6 +29,30 @@ 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>@@ -50,13 +75,11 @@ #endif // !defined(GENERATING_DOCUMENTATION) inline io_context::executor_type-io_context::get_executor() ASIO_NOEXCEPT+io_context::get_executor() 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)@@ -108,104 +131,8 @@ 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@@ -222,7 +149,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) ASIO_NOEXCEPT+ const basic_executor_type& other) noexcept { if (this != &other) {@@ -240,11 +167,10 @@ 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) ASIO_NOEXCEPT+ basic_executor_type&& other) noexcept { if (this != &other) {@@ -260,11 +186,10 @@ } 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 ASIO_NOEXCEPT+ Bits>::running_in_this_thread() const noexcept { return context_ptr()->impl_.can_dispatch(); }@@ -272,36 +197,32 @@ template <typename Allocator, uintptr_t Bits> template <typename Function> void io_context::basic_executor_type<Allocator, Bits>::execute(- ASIO_MOVE_ARG(Function) f) const+ Function&& f) const {- typedef typename decay<Function>::type function_type;+ typedef decay_t<Function> 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(ASIO_MOVE_CAST(Function)(f));+ function_type tmp(static_cast<Function&&>(f)); -#if defined(ASIO_HAS_STD_EXCEPTION_PTR) \- && !defined(ASIO_NO_EXCEPTIONS)+#if !defined(ASIO_NO_EXCEPTIONS) try {-#endif // defined(ASIO_HAS_STD_EXCEPTION_PTR)- // && !defined(ASIO_NO_EXCEPTIONS)+#endif // !defined(ASIO_NO_EXCEPTIONS) detail::fenced_block b(detail::fenced_block::full);- asio_handler_invoke_helpers::invoke(tmp, tmp);+ static_cast<function_type&&>(tmp)(); return;-#if defined(ASIO_HAS_STD_EXCEPTION_PTR) \- && !defined(ASIO_NO_EXCEPTIONS)+#if !defined(ASIO_NO_EXCEPTIONS) } catch (...) { context_ptr()->impl_.capture_current_exception(); return; }-#endif // defined(ASIO_HAS_STD_EXCEPTION_PTR)- // && !defined(ASIO_NO_EXCEPTIONS)+#endif // !defined(ASIO_NO_EXCEPTIONS) } // Allocate and construct an operation to wrap the function.@@ -309,7 +230,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(ASIO_MOVE_CAST(Function)(f),+ p.p = new (p.v) op(static_cast<Function&&>(f), static_cast<const Allocator&>(*this)); ASIO_HANDLER_CREATION((*context_ptr(), *p.p,@@ -323,21 +244,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 ASIO_NOEXCEPT+ Allocator, Bits>::context() const noexcept { return *context_ptr(); } template <typename Allocator, uintptr_t Bits> inline void io_context::basic_executor_type<Allocator,- Bits>::on_work_started() const ASIO_NOEXCEPT+ Bits>::on_work_started() const 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 ASIO_NOEXCEPT+ Bits>::on_work_finished() const noexcept { context_ptr()->impl_.work_finished(); }@@ -345,18 +266,18 @@ template <typename Allocator, uintptr_t Bits> template <typename Function, typename OtherAllocator> void io_context::basic_executor_type<Allocator, Bits>::dispatch(- ASIO_MOVE_ARG(Function) f, const OtherAllocator& a) const+ Function&& f, const OtherAllocator& a) const {- typedef typename decay<Function>::type function_type;+ typedef decay_t<Function> 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(ASIO_MOVE_CAST(Function)(f));+ function_type tmp(static_cast<Function&&>(f)); detail::fenced_block b(detail::fenced_block::full);- asio_handler_invoke_helpers::invoke(tmp, tmp);+ static_cast<function_type&&>(tmp)(); return; } @@ -364,7 +285,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(ASIO_MOVE_CAST(Function)(f), a);+ p.p = new (p.v) op(static_cast<Function&&>(f), a); ASIO_HANDLER_CREATION((*context_ptr(), *p.p, "io_context", context_ptr(), 0, "dispatch"));@@ -376,15 +297,13 @@ template <typename Allocator, uintptr_t Bits> template <typename Function, typename OtherAllocator> void io_context::basic_executor_type<Allocator, Bits>::post(- ASIO_MOVE_ARG(Function) f, const OtherAllocator& a) const+ 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<function_type,+ typedef detail::executor_op<decay_t<Function>, OtherAllocator, detail::operation> op; typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 };- p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(f), a);+ p.p = new (p.v) op(static_cast<Function&&>(f), a); ASIO_HANDLER_CREATION((*context_ptr(), *p.p, "io_context", context_ptr(), 0, "post"));@@ -396,15 +315,13 @@ template <typename Allocator, uintptr_t Bits> template <typename Function, typename OtherAllocator> void io_context::basic_executor_type<Allocator, Bits>::defer(- ASIO_MOVE_ARG(Function) f, const OtherAllocator& a) const+ 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<function_type,+ typedef detail::executor_op<decay_t<Function>, OtherAllocator, detail::operation> op; typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 };- p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(f), a);+ p.p = new (p.v) op(static_cast<Function&&>(f), a); ASIO_HANDLER_CREATION((*context_ptr(), *p.p, "io_context", context_ptr(), 0, "defer"));@@ -413,30 +330,6 @@ 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -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,22 +34,21 @@ namespace asio { io_context::io_context()- : impl_(add_impl(new impl_type(*this,- ASIO_CONCURRENCY_HINT_DEFAULT, false)))+ : execution_context(config_from_concurrency_hint()),+ impl_(asio::make_service<impl_type>(*this, false)) { } io_context::io_context(int concurrency_hint)- : impl_(add_impl(new impl_type(*this, concurrency_hint == 1- ? ASIO_CONCURRENCY_HINT_1 : concurrency_hint, false)))+ : execution_context(config_from_concurrency_hint(concurrency_hint)),+ impl_(asio::make_service<impl_type>(*this, false)) { } -io_context::impl_type& io_context::add_impl(io_context::impl_type* impl)+io_context::io_context(const execution_context::service_maker& initial_services)+ : execution_context(initial_services),+ impl_(asio::make_service<impl_type>(*this, false)) {- 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()@@ -65,13 +64,6 @@ 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;@@ -80,13 +72,6 @@ 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;@@ -95,13 +80,6 @@ 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;@@ -110,13 +88,6 @@ 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();@@ -143,31 +114,11 @@ void io_context::service::shutdown() {-#if !defined(ASIO_NO_DEPRECATED)- shutdown_service();-#endif // !defined(ASIO_NO_DEPRECATED) } -#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)+void io_context::service::notify_fork(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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -22,15 +22,13 @@ namespace asio { -#if defined(ASIO_HAS_STD_EXCEPTION_PTR)- multiple_exceptions::multiple_exceptions(- std::exception_ptr first) ASIO_NOEXCEPT- : first_(ASIO_MOVE_CAST(std::exception_ptr)(first))+ std::exception_ptr first) noexcept+ : first_(static_cast<std::exception_ptr&&>(first)) { } -const char* multiple_exceptions::what() const ASIO_NOEXCEPT_OR_NOTHROW+const char* multiple_exceptions::what() const noexcept { return "multiple exceptions"; }@@ -39,8 +37,6 @@ { 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -16,15 +16,12 @@ #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/handler_invoke_helpers.hpp"+#include "asio/detail/initiation_base.hpp" #include "asio/detail/type_traits.hpp" #include "asio/detail/utility.hpp"-#include "asio/detail/variadic_templates.hpp" #include "asio/detail/push_options.hpp" @@ -39,26 +36,26 @@ typedef void result_type; template <typename H>- 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))+ prepend_handler(H&& handler, std::tuple<Values...> values)+ : handler_(static_cast<H&&>(handler)),+ values_(static_cast<std::tuple<Values...>&&>(values)) { } template <typename... Args>- void operator()(ASIO_MOVE_ARG(Args)... args)+ void operator()(Args&&... args) { this->invoke( index_sequence_for<Values...>{},- ASIO_MOVE_CAST(Args)(args)...);+ static_cast<Args&&>(args)...); } template <std::size_t... I, typename... Args>- void invoke(index_sequence<I...>, ASIO_MOVE_ARG(Args)... args)+ void invoke(index_sequence<I...>, Args&&... args) {- ASIO_MOVE_OR_LVALUE(Handler)(handler_)(- ASIO_MOVE_CAST(Values)(std::get<I>(values_))...,- ASIO_MOVE_CAST(Args)(args)...);+ static_cast<Handler&&>(handler_)(+ static_cast<Values&&>(std::get<I>(values_))...,+ static_cast<Args&&>(args)...); } //private:@@ -67,32 +64,6 @@ }; 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) {@@ -100,37 +71,13 @@ 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..., typename decay<Args>::type...);+ typedef R type(Values..., decay_t<Args>...); }; } // namespace detail@@ -148,48 +95,49 @@ Signature, Values...>::type signature; template <typename Initiation>- struct init_wrapper+ struct init_wrapper : detail::initiation_base<Initiation> {- init_wrapper(Initiation init)- : initiation_(ASIO_MOVE_CAST(Initiation)(init))+ using detail::initiation_base<Initiation>::initiation_base;++ template <typename Handler, typename... Args>+ void operator()(Handler&& handler,+ std::tuple<Values...> values, Args&&... args) && {+ 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()(- ASIO_MOVE_ARG(Handler) handler,- std::tuple<Values...> values,- ASIO_MOVE_ARG(Args)... args)+ void operator()(Handler&& handler,+ std::tuple<Values...> values, Args&&... args) const & {- 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)...);+ 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)...); }-- Initiation initiation_; }; template <typename Initiation, typename RawCompletionToken, typename... 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)+ 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)...)) { return async_initiate<CompletionToken, signature>(- init_wrapper<typename decay<Initiation>::type>(- ASIO_MOVE_CAST(Initiation)(initiation)),+ init_wrapper<decay_t<Initiation>>(+ static_cast<Initiation&&>(initiation)), token.token_,- ASIO_MOVE_CAST(std::tuple<Values...>)(token.values_),- ASIO_MOVE_CAST(Args)(args)...);+ static_cast<std::tuple<Values...>&&>(token.values_),+ static_cast<Args&&>(args)...); } }; @@ -199,18 +147,15 @@ detail::prepend_handler<Handler, Values...>, DefaultCandidate> : Associator<Handler, DefaultCandidate> {- static typename Associator<Handler, DefaultCandidate>::type- get(const detail::prepend_handler<Handler, Values...>& h) ASIO_NOEXCEPT+ static typename Associator<Handler, DefaultCandidate>::type get(+ const detail::prepend_handler<Handler, Values...>& h) noexcept { return Associator<Handler, DefaultCandidate>::get(h.handler_); } - 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)))+ static auto get(const detail::prepend_handler<Handler, Values...>& h,+ const DefaultCandidate& c) noexcept+ -> decltype(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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -24,9 +24,7 @@ #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,20 +62,23 @@ typename CompletionCondition> std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers, CompletionCondition completion_condition, asio::error_code& ec,- typename constraint<+ constraint_t< is_mutable_buffer_sequence<MutableBufferSequence>::value- >::type)+ >,+ constraint_t<+ is_completion_condition<CompletionCondition>::value+ >) { return detail::read_buffer_seq(s, buffers, asio::buffer_sequence_begin(buffers),- ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);+ static_cast<CompletionCondition&&>(completion_condition), ec); } template <typename SyncReadStream, typename MutableBufferSequence> inline std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers,- typename constraint<+ constraint_t< is_mutable_buffer_sequence<MutableBufferSequence>::value- >::type)+ >) { asio::error_code ec; std::size_t bytes_transferred = read(s, buffers, transfer_all(), ec);@@ -88,9 +89,9 @@ template <typename SyncReadStream, typename MutableBufferSequence> inline std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers, asio::error_code& ec,- typename constraint<+ constraint_t< is_mutable_buffer_sequence<MutableBufferSequence>::value- >::type)+ >) { return read(s, buffers, transfer_all(), ec); }@@ -99,13 +100,16 @@ typename CompletionCondition> inline std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers, CompletionCondition completion_condition,- typename constraint<+ constraint_t< is_mutable_buffer_sequence<MutableBufferSequence>::value- >::type)+ >,+ constraint_t<+ is_completion_condition<CompletionCondition>::value+ >) { asio::error_code ec; std::size_t bytes_transferred = read(s, buffers,- ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);+ static_cast<CompletionCondition&&>(completion_condition), ec); asio::detail::throw_error(ec, "read"); return bytes_transferred; }@@ -115,17 +119,20 @@ template <typename SyncReadStream, typename DynamicBuffer_v1, typename CompletionCondition> std::size_t read(SyncReadStream& s,- ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+ DynamicBuffer_v1&& buffers, CompletionCondition completion_condition, 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)+ 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 decay<DynamicBuffer_v1>::type b(- ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers));+ decay_t<DynamicBuffer_v1> b(+ static_cast<DynamicBuffer_v1&&>(buffers)); ec = asio::error_code(); std::size_t total_transferred = 0;@@ -150,52 +157,55 @@ template <typename SyncReadStream, typename DynamicBuffer_v1> inline std::size_t read(SyncReadStream& s,- 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)+ 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::error_code ec; std::size_t bytes_transferred = read(s,- ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), transfer_all(), ec);+ static_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,- ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+ DynamicBuffer_v1&& buffers, 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)+ constraint_t<+ is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value+ >,+ constraint_t<+ !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value+ >) {- return read(s, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+ return read(s, static_cast<DynamicBuffer_v1&&>(buffers), transfer_all(), ec); } template <typename SyncReadStream, typename DynamicBuffer_v1, typename CompletionCondition> inline std::size_t read(SyncReadStream& s,- ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+ DynamicBuffer_v1&& buffers, CompletionCondition completion_condition,- 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)+ 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+ >) { asio::error_code ec; std::size_t bytes_transferred = read(s,- ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),- ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);+ static_cast<DynamicBuffer_v1&&>(buffers),+ static_cast<CompletionCondition&&>(completion_condition), ec); asio::detail::throw_error(ec, "read"); return bytes_transferred; }@@ -207,10 +217,13 @@ typename CompletionCondition> inline std::size_t read(SyncReadStream& s, asio::basic_streambuf<Allocator>& b,- CompletionCondition completion_condition, asio::error_code& ec)+ CompletionCondition completion_condition, asio::error_code& ec,+ constraint_t<+ is_completion_condition<CompletionCondition>::value+ >) { return read(s, basic_streambuf_ref<Allocator>(b),- ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);+ static_cast<CompletionCondition&&>(completion_condition), ec); } template <typename SyncReadStream, typename Allocator>@@ -232,10 +245,13 @@ typename CompletionCondition> inline std::size_t read(SyncReadStream& s, asio::basic_streambuf<Allocator>& b,- CompletionCondition completion_condition)+ CompletionCondition completion_condition,+ constraint_t<+ is_completion_condition<CompletionCondition>::value+ >) { return read(s, basic_streambuf_ref<Allocator>(b),- ASIO_MOVE_CAST(CompletionCondition)(completion_condition));+ static_cast<CompletionCondition&&>(completion_condition)); } #endif // !defined(ASIO_NO_IOSTREAM)@@ -246,9 +262,12 @@ typename CompletionCondition> std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers, CompletionCondition completion_condition, asio::error_code& ec,- typename constraint<+ constraint_t< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- >::type)+ >,+ constraint_t<+ is_completion_condition<CompletionCondition>::value+ >) { DynamicBuffer_v2& b = buffers; @@ -278,13 +297,13 @@ template <typename SyncReadStream, typename DynamicBuffer_v2> inline std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers,- typename constraint<+ constraint_t< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- >::type)+ >) { asio::error_code ec; std::size_t bytes_transferred = read(s,- ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), transfer_all(), ec);+ static_cast<DynamicBuffer_v2&&>(buffers), transfer_all(), ec); asio::detail::throw_error(ec, "read"); return bytes_transferred; }@@ -292,11 +311,11 @@ template <typename SyncReadStream, typename DynamicBuffer_v2> inline std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers, asio::error_code& ec,- typename constraint<+ constraint_t< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- >::type)+ >) {- return read(s, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+ return read(s, static_cast<DynamicBuffer_v2&&>(buffers), transfer_all(), ec); } @@ -304,14 +323,17 @@ typename CompletionCondition> inline std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers, CompletionCondition completion_condition,- typename constraint<+ constraint_t< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- >::type)+ >,+ constraint_t<+ is_completion_condition<CompletionCondition>::value+ >) { asio::error_code ec; std::size_t bytes_transferred = read(s,- ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),- ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);+ static_cast<DynamicBuffer_v2&&>(buffers),+ static_cast<CompletionCondition&&>(completion_condition), ec); asio::detail::throw_error(ec, "read"); return bytes_transferred; }@@ -334,11 +356,10 @@ stream_(stream), buffers_(buffers), start_(0),- handler_(ASIO_MOVE_CAST(ReadHandler)(handler))+ handler_(static_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),@@ -351,18 +372,15 @@ read_op(read_op&& other) : base_from_cancellation_state<ReadHandler>(- ASIO_MOVE_CAST(base_from_cancellation_state<- ReadHandler>)(other)),+ static_cast<base_from_cancellation_state<ReadHandler>&&>(other)), base_from_completion_cond<CompletionCondition>(- ASIO_MOVE_CAST(base_from_completion_cond<- CompletionCondition>)(other)),+ static_cast<base_from_completion_cond<CompletionCondition>&&>(other)), stream_(other.stream_),- buffers_(ASIO_MOVE_CAST(buffers_type)(other.buffers_)),+ buffers_(static_cast<buffers_type&&>(other.buffers_)), start_(other.start_),- handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_))+ handler_(static_cast<ReadHandler&&>(other.handler_)) { }-#endif // defined(ASIO_HAS_MOVE) void operator()(asio::error_code ec, std::size_t bytes_transferred, int start = 0)@@ -377,7 +395,7 @@ { ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_read")); stream_.async_read_some(buffers_.prepare(max_size),- ASIO_MOVE_CAST(read_op)(*this));+ static_cast<read_op&&>(*this)); } return; default: buffers_.consume(bytes_transferred);@@ -393,7 +411,7 @@ } } - ASIO_MOVE_OR_LVALUE(ReadHandler)(handler_)(+ static_cast<ReadHandler&&>(handler_)( static_cast<const asio::error_code&>(ec), static_cast<const std::size_t&>(buffers_.total_consumed())); }@@ -412,38 +430,6 @@ 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)@@ -453,36 +439,6 @@ 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>@@ -507,16 +463,16 @@ { } - executor_type get_executor() const ASIO_NOEXCEPT+ executor_type get_executor() const noexcept { return stream_.get_executor(); } template <typename ReadHandler, typename MutableBufferSequence, typename CompletionCondition>- void operator()(ASIO_MOVE_ARG(ReadHandler) handler,+ void operator()(ReadHandler&& handler, const MutableBufferSequence& buffers,- ASIO_MOVE_ARG(CompletionCondition) completion_cond) const+ 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.@@ -546,21 +502,18 @@ DefaultCandidate> : Associator<ReadHandler, DefaultCandidate> {- static typename Associator<ReadHandler, DefaultCandidate>::type- get(const detail::read_op<AsyncReadStream, MutableBufferSequence,- MutableBufferIterator, CompletionCondition, ReadHandler>& h)- ASIO_NOEXCEPT+ static typename Associator<ReadHandler, DefaultCandidate>::type get(+ const detail::read_op<AsyncReadStream, MutableBufferSequence,+ MutableBufferIterator, CompletionCondition, ReadHandler>& h) noexcept { return Associator<ReadHandler, DefaultCandidate>::get(h.handler_); } - static ASIO_AUTO_RETURN_TYPE_PREFIX2(- typename Associator<ReadHandler, DefaultCandidate>::type)- get(const detail::read_op<AsyncReadStream, MutableBufferSequence,+ static auto get(+ const detail::read_op<AsyncReadStream, MutableBufferSequence, MutableBufferIterator, CompletionCondition, ReadHandler>& h,- const DefaultCandidate& c) ASIO_NOEXCEPT- ASIO_AUTO_RETURN_TYPE_SUFFIX((- Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c)))+ const DefaultCandidate& c) noexcept+ -> decltype(Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c)) { return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c); }@@ -568,54 +521,6 @@ #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@@ -629,20 +534,19 @@ public: template <typename BufferSequence> read_dynbuf_v1_op(AsyncReadStream& stream,- ASIO_MOVE_ARG(BufferSequence) buffers,+ 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_(ASIO_MOVE_CAST(BufferSequence)(buffers)),+ buffers_(static_cast<BufferSequence&&>(buffers)), start_(0), total_transferred_(0),- handler_(ASIO_MOVE_CAST(ReadHandler)(handler))+ handler_(static_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),@@ -656,19 +560,16 @@ read_dynbuf_v1_op(read_dynbuf_v1_op&& other) : base_from_cancellation_state<ReadHandler>(- ASIO_MOVE_CAST(base_from_cancellation_state<- ReadHandler>)(other)),+ static_cast<base_from_cancellation_state<ReadHandler>&&>(other)), base_from_completion_cond<CompletionCondition>(- ASIO_MOVE_CAST(base_from_completion_cond<- CompletionCondition>)(other)),+ static_cast<base_from_completion_cond<CompletionCondition>&&>(other)), stream_(other.stream_),- buffers_(ASIO_MOVE_CAST(DynamicBuffer_v1)(other.buffers_)),+ buffers_(static_cast<DynamicBuffer_v1&&>(other.buffers_)), start_(other.start_), total_transferred_(other.total_transferred_),- handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_))+ handler_(static_cast<ReadHandler&&>(other.handler_)) { }-#endif // defined(ASIO_HAS_MOVE) void operator()(asio::error_code ec, std::size_t bytes_transferred, int start = 0)@@ -688,7 +589,7 @@ { ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_read")); stream_.async_read_some(buffers_.prepare(bytes_available),- ASIO_MOVE_CAST(read_dynbuf_v1_op)(*this));+ static_cast<read_dynbuf_v1_op&&>(*this)); } return; default: total_transferred_ += bytes_transferred;@@ -708,7 +609,7 @@ } } - ASIO_MOVE_OR_LVALUE(ReadHandler)(handler_)(+ static_cast<ReadHandler&&>(handler_)( static_cast<const asio::error_code&>(ec), static_cast<const std::size_t&>(total_transferred_)); }@@ -724,36 +625,6 @@ 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)@@ -763,36 +634,6 @@ 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 {@@ -804,16 +645,16 @@ { } - executor_type get_executor() const ASIO_NOEXCEPT+ executor_type get_executor() const noexcept { return stream_.get_executor(); } template <typename ReadHandler, typename DynamicBuffer_v1, typename CompletionCondition>- void operator()(ASIO_MOVE_ARG(ReadHandler) handler,- ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,- ASIO_MOVE_ARG(CompletionCondition) completion_cond) const+ void operator()(ReadHandler&& handler,+ DynamicBuffer_v1&& buffers,+ 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.@@ -821,9 +662,9 @@ non_const_lvalue<ReadHandler> handler2(handler); non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);- read_dynbuf_v1_op<AsyncReadStream, typename decay<DynamicBuffer_v1>::type,- CompletionCondition, typename decay<ReadHandler>::type>(- stream_, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+ read_dynbuf_v1_op<AsyncReadStream, decay_t<DynamicBuffer_v1>,+ CompletionCondition, decay_t<ReadHandler>>(+ stream_, static_cast<DynamicBuffer_v1&&>(buffers), completion_cond2.value, handler2.value)( asio::error_code(), 0, 1); }@@ -845,20 +686,18 @@ DefaultCandidate> : Associator<ReadHandler, DefaultCandidate> {- static typename Associator<ReadHandler, DefaultCandidate>::type- get(const detail::read_dynbuf_v1_op<AsyncReadStream, DynamicBuffer_v1,- CompletionCondition, ReadHandler>& h) ASIO_NOEXCEPT+ static typename Associator<ReadHandler, DefaultCandidate>::type get(+ const detail::read_dynbuf_v1_op<AsyncReadStream, DynamicBuffer_v1,+ CompletionCondition, ReadHandler>& h) noexcept { return Associator<ReadHandler, DefaultCandidate>::get(h.handler_); } - static ASIO_AUTO_RETURN_TYPE_PREFIX2(- typename Associator<ReadHandler, DefaultCandidate>::type)- get(const detail::read_dynbuf_v1_op<AsyncReadStream,+ static auto get(+ const detail::read_dynbuf_v1_op<AsyncReadStream, DynamicBuffer_v1, CompletionCondition, ReadHandler>& h,- const DefaultCandidate& c) ASIO_NOEXCEPT- ASIO_AUTO_RETURN_TYPE_SUFFIX((- Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c)))+ const DefaultCandidate& c) noexcept+ -> decltype(Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c)) { return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c); }@@ -866,103 +705,6 @@ #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@@ -976,21 +718,20 @@ public: template <typename BufferSequence> read_dynbuf_v2_op(AsyncReadStream& stream,- ASIO_MOVE_ARG(BufferSequence) buffers,+ 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_(ASIO_MOVE_CAST(BufferSequence)(buffers)),+ buffers_(static_cast<BufferSequence&&>(buffers)), start_(0), total_transferred_(0), bytes_available_(0),- handler_(ASIO_MOVE_CAST(ReadHandler)(handler))+ handler_(static_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),@@ -1005,20 +746,17 @@ read_dynbuf_v2_op(read_dynbuf_v2_op&& other) : base_from_cancellation_state<ReadHandler>(- ASIO_MOVE_CAST(base_from_cancellation_state<- ReadHandler>)(other)),+ static_cast<base_from_cancellation_state<ReadHandler>&&>(other)), base_from_completion_cond<CompletionCondition>(- ASIO_MOVE_CAST(base_from_completion_cond<- CompletionCondition>)(other)),+ static_cast<base_from_completion_cond<CompletionCondition>&&>(other)), stream_(other.stream_),- buffers_(ASIO_MOVE_CAST(DynamicBuffer_v2)(other.buffers_)),+ buffers_(static_cast<DynamicBuffer_v2&&>(other.buffers_)), start_(other.start_), total_transferred_(other.total_transferred_), bytes_available_(other.bytes_available_),- handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_))+ handler_(static_cast<ReadHandler&&>(other.handler_)) { }-#endif // defined(ASIO_HAS_MOVE) void operator()(asio::error_code ec, std::size_t bytes_transferred, int start = 0)@@ -1040,7 +778,7 @@ { ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_read")); stream_.async_read_some(buffers_.data(pos, bytes_available_),- ASIO_MOVE_CAST(read_dynbuf_v2_op)(*this));+ static_cast<read_dynbuf_v2_op&&>(*this)); } return; default: total_transferred_ += bytes_transferred;@@ -1060,7 +798,7 @@ } } - ASIO_MOVE_OR_LVALUE(ReadHandler)(handler_)(+ static_cast<ReadHandler&&>(handler_)( static_cast<const asio::error_code&>(ec), static_cast<const std::size_t&>(total_transferred_)); }@@ -1077,36 +815,6 @@ 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)@@ -1116,36 +824,6 @@ 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 {@@ -1157,16 +835,16 @@ { } - executor_type get_executor() const ASIO_NOEXCEPT+ executor_type get_executor() const noexcept { return stream_.get_executor(); } template <typename ReadHandler, typename DynamicBuffer_v2, typename CompletionCondition>- void operator()(ASIO_MOVE_ARG(ReadHandler) handler,- ASIO_MOVE_ARG(DynamicBuffer_v2) buffers,- ASIO_MOVE_ARG(CompletionCondition) completion_cond) const+ void operator()(ReadHandler&& handler,+ DynamicBuffer_v2&& buffers,+ 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.@@ -1174,9 +852,9 @@ non_const_lvalue<ReadHandler> handler2(handler); non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);- read_dynbuf_v2_op<AsyncReadStream, typename decay<DynamicBuffer_v2>::type,- CompletionCondition, typename decay<ReadHandler>::type>(- stream_, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+ read_dynbuf_v2_op<AsyncReadStream, decay_t<DynamicBuffer_v2>,+ CompletionCondition, decay_t<ReadHandler>>(+ stream_, static_cast<DynamicBuffer_v2&&>(buffers), completion_cond2.value, handler2.value)( asio::error_code(), 0, 1); }@@ -1198,76 +876,24 @@ DefaultCandidate> : Associator<ReadHandler, DefaultCandidate> {- static typename Associator<ReadHandler, DefaultCandidate>::type- get(const detail::read_dynbuf_v2_op<AsyncReadStream, DynamicBuffer_v2,- CompletionCondition, ReadHandler>& h) ASIO_NOEXCEPT+ static typename Associator<ReadHandler, DefaultCandidate>::type get(+ const detail::read_dynbuf_v2_op<AsyncReadStream, DynamicBuffer_v2,+ CompletionCondition, ReadHandler>& h) noexcept { return Associator<ReadHandler, DefaultCandidate>::get(h.handler_); } - static ASIO_AUTO_RETURN_TYPE_PREFIX2(- typename Associator<ReadHandler, DefaultCandidate>::type)- get(const detail::read_dynbuf_v2_op<AsyncReadStream,+ static auto get(+ const detail::read_dynbuf_v2_op<AsyncReadStream, DynamicBuffer_v2, CompletionCondition, ReadHandler>& h,- const DefaultCandidate& c) ASIO_NOEXCEPT- ASIO_AUTO_RETURN_TYPE_SUFFIX((- Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c)))+ const DefaultCandidate& c) noexcept+ -> decltype(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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -24,9 +24,7 @@ #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"@@ -68,11 +66,14 @@ typename CompletionCondition> std::size_t read_at(SyncRandomAccessReadDevice& d, uint64_t offset, const MutableBufferSequence& buffers,- CompletionCondition completion_condition, asio::error_code& ec)+ CompletionCondition completion_condition, asio::error_code& ec,+ constraint_t<+ is_completion_condition<CompletionCondition>::value+ >) { return detail::read_at_buffer_sequence(d, offset, buffers, asio::buffer_sequence_begin(buffers),- ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);+ static_cast<CompletionCondition&&>(completion_condition), ec); } template <typename SyncRandomAccessReadDevice, typename MutableBufferSequence>@@ -98,11 +99,14 @@ typename CompletionCondition> inline std::size_t read_at(SyncRandomAccessReadDevice& d, uint64_t offset, const MutableBufferSequence& buffers,- CompletionCondition completion_condition)+ CompletionCondition completion_condition,+ constraint_t<+ is_completion_condition<CompletionCondition>::value+ >) { asio::error_code ec; std::size_t bytes_transferred = read_at(d, offset, buffers,- ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);+ static_cast<CompletionCondition&&>(completion_condition), ec); asio::detail::throw_error(ec, "read_at"); return bytes_transferred; }@@ -114,7 +118,10 @@ typename CompletionCondition> std::size_t read_at(SyncRandomAccessReadDevice& d, uint64_t offset, asio::basic_streambuf<Allocator>& b,- CompletionCondition completion_condition, asio::error_code& ec)+ CompletionCondition completion_condition, asio::error_code& ec,+ constraint_t<+ is_completion_condition<CompletionCondition>::value+ >) { ec = asio::error_code(); std::size_t total_transferred = 0;@@ -157,11 +164,14 @@ typename CompletionCondition> inline std::size_t read_at(SyncRandomAccessReadDevice& d, uint64_t offset, asio::basic_streambuf<Allocator>& b,- CompletionCondition completion_condition)+ CompletionCondition completion_condition,+ constraint_t<+ is_completion_condition<CompletionCondition>::value+ >) { asio::error_code ec; std::size_t bytes_transferred = read_at(d, offset, b,- ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);+ static_cast<CompletionCondition&&>(completion_condition), ec); asio::detail::throw_error(ec, "read_at"); return bytes_transferred; }@@ -189,11 +199,10 @@ offset_(offset), buffers_(buffers), start_(0),- handler_(ASIO_MOVE_CAST(ReadHandler)(handler))+ handler_(static_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),@@ -207,19 +216,16 @@ read_at_op(read_at_op&& other) : base_from_cancellation_state<ReadHandler>(- ASIO_MOVE_CAST(base_from_cancellation_state<- ReadHandler>)(other)),+ static_cast<base_from_cancellation_state<ReadHandler>&&>(other)), base_from_completion_cond<CompletionCondition>(- ASIO_MOVE_CAST(base_from_completion_cond<- CompletionCondition>)(other)),+ static_cast<base_from_completion_cond<CompletionCondition>&&>(other)), device_(other.device_), offset_(other.offset_),- buffers_(ASIO_MOVE_CAST(buffers_type)(other.buffers_)),+ buffers_(static_cast<buffers_type&&>(other.buffers_)), start_(other.start_),- handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_))+ handler_(static_cast<ReadHandler&&>(other.handler_)) { }-#endif // defined(ASIO_HAS_MOVE) void operator()(asio::error_code ec, std::size_t bytes_transferred, int start = 0)@@ -235,7 +241,7 @@ ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_read_at")); device_.async_read_some_at( offset_ + buffers_.total_consumed(), buffers_.prepare(max_size),- ASIO_MOVE_CAST(read_at_op)(*this));+ static_cast<read_at_op&&>(*this)); } return; default: buffers_.consume(bytes_transferred);@@ -251,7 +257,7 @@ } } - ASIO_MOVE_OR_LVALUE(ReadHandler)(handler_)(+ static_cast<ReadHandler&&>(handler_)( static_cast<const asio::error_code&>(ec), static_cast<const std::size_t&>(buffers_.total_consumed())); }@@ -271,38 +277,6 @@ 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)@@ -312,36 +286,6 @@ 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>@@ -367,16 +311,16 @@ { } - executor_type get_executor() const ASIO_NOEXCEPT+ executor_type get_executor() const noexcept { return device_.get_executor(); } template <typename ReadHandler, typename MutableBufferSequence, typename CompletionCondition>- void operator()(ASIO_MOVE_ARG(ReadHandler) handler,+ void operator()(ReadHandler&& handler, uint64_t offset, const MutableBufferSequence& buffers,- ASIO_MOVE_ARG(CompletionCondition) completion_cond) const+ 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.@@ -406,22 +350,20 @@ 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) ASIO_NOEXCEPT+ CompletionCondition, ReadHandler>& h) noexcept { return Associator<ReadHandler, DefaultCandidate>::get(h.handler_); } - static ASIO_AUTO_RETURN_TYPE_PREFIX2(- typename Associator<ReadHandler, DefaultCandidate>::type)- get(const detail::read_at_op<AsyncRandomAccessReadDevice,+ static auto get(+ const detail::read_at_op<AsyncRandomAccessReadDevice, MutableBufferSequence, MutableBufferIterator, CompletionCondition, ReadHandler>& h,- const DefaultCandidate& c) ASIO_NOEXCEPT- ASIO_AUTO_RETURN_TYPE_SUFFIX((- Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c)))+ const DefaultCandidate& c) noexcept+ -> decltype(Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c)) { return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c); }@@ -429,50 +371,6 @@ #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) @@ -496,11 +394,10 @@ streambuf_(streambuf), start_(0), total_transferred_(0),- handler_(ASIO_MOVE_CAST(ReadHandler)(handler))+ handler_(static_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),@@ -515,20 +412,17 @@ read_at_streambuf_op(read_at_streambuf_op&& other) : base_from_cancellation_state<ReadHandler>(- ASIO_MOVE_CAST(base_from_cancellation_state<- ReadHandler>)(other)),+ static_cast<base_from_cancellation_state<ReadHandler>&&>(other)), base_from_completion_cond<CompletionCondition>(- ASIO_MOVE_CAST(base_from_completion_cond<- CompletionCondition>)(other)),+ static_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_(ASIO_MOVE_CAST(ReadHandler)(other.handler_))+ handler_(static_cast<ReadHandler&&>(other.handler_)) { }-#endif // defined(ASIO_HAS_MOVE) void operator()(asio::error_code ec, std::size_t bytes_transferred, int start = 0)@@ -545,7 +439,7 @@ ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_read_at")); device_.async_read_some_at(offset_ + total_transferred_, streambuf_.prepare(bytes_available),- ASIO_MOVE_CAST(read_at_streambuf_op)(*this));+ static_cast<read_at_streambuf_op&&>(*this)); } return; default: total_transferred_ += bytes_transferred;@@ -561,7 +455,7 @@ } } - ASIO_MOVE_OR_LVALUE(ReadHandler)(handler_)(+ static_cast<ReadHandler&&>(handler_)( static_cast<const asio::error_code&>(ec), static_cast<const std::size_t&>(total_transferred_)); }@@ -578,36 +472,6 @@ 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)@@ -617,34 +481,6 @@ 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 {@@ -657,16 +493,16 @@ { } - executor_type get_executor() const ASIO_NOEXCEPT+ executor_type get_executor() const noexcept { return device_.get_executor(); } template <typename ReadHandler, typename Allocator, typename CompletionCondition>- void operator()(ASIO_MOVE_ARG(ReadHandler) handler,+ void operator()(ReadHandler&& handler, uint64_t offset, basic_streambuf<Allocator>* b,- ASIO_MOVE_ARG(CompletionCondition) completion_cond) const+ 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.@@ -675,7 +511,7 @@ non_const_lvalue<ReadHandler> handler2(handler); non_const_lvalue<CompletionCondition> completion_cond2(completion_cond); read_at_streambuf_op<AsyncRandomAccessReadDevice, Allocator,- CompletionCondition, typename decay<ReadHandler>::type>(+ CompletionCondition, decay_t<ReadHandler>>( device_, offset, *b, completion_cond2.value, handler2.value)( asio::error_code(), 0, 1); }@@ -697,72 +533,24 @@ DefaultCandidate> : Associator<ReadHandler, DefaultCandidate> {- static typename Associator<ReadHandler, DefaultCandidate>::type- get(const detail::read_at_streambuf_op<AsyncRandomAccessReadDevice,- Executor, CompletionCondition, ReadHandler>& h) ASIO_NOEXCEPT+ static typename Associator<ReadHandler, DefaultCandidate>::type get(+ const detail::read_at_streambuf_op<AsyncRandomAccessReadDevice,+ Executor, CompletionCondition, ReadHandler>& h) noexcept { return Associator<ReadHandler, DefaultCandidate>::get(h.handler_); } - static ASIO_AUTO_RETURN_TYPE_PREFIX2(- typename Associator<ReadHandler, DefaultCandidate>::type)- get(const detail::read_at_streambuf_op<AsyncRandomAccessReadDevice,+ static auto get(+ const detail::read_at_streambuf_op<AsyncRandomAccessReadDevice, Executor, CompletionCondition, ReadHandler>& h,- const DefaultCandidate& c) ASIO_NOEXCEPT- ASIO_AUTO_RETURN_TYPE_SUFFIX((- Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c)))+ const DefaultCandidate& c) noexcept+ -> decltype(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,3449 +2,2662 @@ // impl/read_until.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_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);-}+// 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) #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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -16,13 +16,12 @@ #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/handler_invoke_helpers.hpp"+#include "asio/detail/initiation_base.hpp" #include "asio/detail/type_traits.hpp"-#include "asio/detail/variadic_templates.hpp" #include "asio/system_error.hpp" #include "asio/detail/push_options.hpp"@@ -40,121 +39,47 @@ template <typename CompletionToken> redirect_error_handler(redirect_error_t<CompletionToken> e) : ec_(e.ec_),- handler_(ASIO_MOVE_CAST(CompletionToken)(e.token_))+ handler_(static_cast<CompletionToken&&>(e.token_)) { } template <typename RedirectedHandler> redirect_error_handler(asio::error_code& ec,- ASIO_MOVE_ARG(RedirectedHandler) h)+ RedirectedHandler&& h) : ec_(ec),- handler_(ASIO_MOVE_CAST(RedirectedHandler)(h))+ handler_(static_cast<RedirectedHandler&&>(h)) { } void operator()() {- ASIO_MOVE_OR_LVALUE(Handler)(handler_)();+ static_cast<Handler&&>(handler_)(); } -#if defined(ASIO_HAS_VARIADIC_TEMPLATES)- template <typename Arg, typename... 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)+ enable_if_t<+ !is_same<decay_t<Arg>, asio::error_code>::value+ >+ operator()(Arg&& arg, Args&&... args) {- ASIO_MOVE_OR_LVALUE(Handler)(handler_)(- ASIO_MOVE_CAST(Arg)(arg),- ASIO_MOVE_CAST(Args)(args)...);+ static_cast<Handler&&>(handler_)(+ static_cast<Arg&&>(arg),+ static_cast<Args&&>(args)...); } template <typename... Args>- void operator()(const asio::error_code& ec,- ASIO_MOVE_ARG(Args)... args)- {- ec_ = ec;- 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)+ void operator()(const asio::error_code& ec, Args&&... args) { ec_ = ec;- ASIO_MOVE_OR_LVALUE(Handler)(handler_)();+ static_cast<Handler&&>(handler_)(static_cast<Args&&>(args)...); } -#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) {@@ -162,38 +87,12 @@ 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...)> {@@ -206,8 +105,6 @@ 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...) &> {@@ -232,7 +129,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<@@ -276,196 +173,7 @@ typedef R type(Args...) && noexcept; }; -# 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)+#endif // defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE) } // namespace detail @@ -476,130 +184,53 @@ : async_result<CompletionToken, typename detail::redirect_error_signature<Signature>::type> {-- struct init_wrapper+ template <typename Initiation>+ struct init_wrapper : detail::initiation_base<Initiation> {- explicit init_wrapper(asio::error_code& ec)- : ec_(ec)- {- }--#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+ using detail::initiation_base<Initiation>::initiation_base; - 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+ template <typename Handler, typename... Args>+ void operator()(Handler&& handler,+ asio::error_code* ec, 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)...);+ static_cast<Initiation&&>(*this)(+ detail::redirect_error_handler<decay_t<Handler>>(+ *ec, static_cast<Handler&&>(handler)),+ static_cast<Args&&>(args)...); } -#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)-- template <typename Handler, typename Initiation>- void operator()(- ASIO_MOVE_ARG(Handler) handler,- ASIO_MOVE_ARG(Initiation) initiation) const+ template <typename Handler, typename... Args>+ void operator()(Handler&& handler,+ asio::error_code* ec, Args&&... args) const & {- ASIO_MOVE_CAST(Initiation)(initiation)(- detail::redirect_error_handler<- typename decay<Handler>::type>(- ec_, ASIO_MOVE_CAST(Handler)(handler)));+ static_cast<const Initiation&>(*this)(+ detail::redirect_error_handler<decay_t<Handler>>(+ *ec, static_cast<Handler&&>(handler)),+ static_cast<Args&&>(args)...); }--#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 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>(), 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,- typename detail::redirect_error_signature<Signature>::type>(- 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,+ static auto initiate(Initiation&& initiation,+ RawCompletionToken&& token, Args&&... args)+ -> decltype(+ async_initiate<+ conditional_t<+ is_const<remove_reference_t<RawCompletionToken>>::value,+ const CompletionToken, 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)+ declval<init_wrapper<decay_t<Initiation>>>(),+ token.token_, &token.ec_, static_cast<Args&&>(args)...)) {- return async_initiate<CompletionToken,+ return async_initiate<+ conditional_t<+ is_const<remove_reference_t<RawCompletionToken>>::value,+ const CompletionToken, CompletionToken>, typename detail::redirect_error_signature<Signature>::type>(- init_wrapper(token.ec_), token.token_,- ASIO_MOVE_CAST(Initiation)(initiation));+ init_wrapper<decay_t<Initiation>>(+ static_cast<Initiation&&>(initiation)),+ token.token_, &token.ec_, static_cast<Args&&>(args)...); }--#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,@@ -608,20 +239,42 @@ detail::redirect_error_handler<Handler>, DefaultCandidate> : Associator<Handler, DefaultCandidate> {- static typename Associator<Handler, DefaultCandidate>::type- get(const detail::redirect_error_handler<Handler>& h) ASIO_NOEXCEPT+ static typename Associator<Handler, DefaultCandidate>::type get(+ const detail::redirect_error_handler<Handler>& h) noexcept { return Associator<Handler, DefaultCandidate>::get(h.handler_); } - 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)))+ static auto get(const detail::redirect_error_handler<Handler>& h,+ const DefaultCandidate& c) noexcept+ -> decltype(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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2025 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2025 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -16,6 +16,7 @@ #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"@@ -23,20 +24,15 @@ #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/detail/variadic_templates.hpp"+#include "asio/disposition.hpp"+#include "asio/error.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)@@ -54,137 +50,6 @@ } #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.@@ -193,8 +58,8 @@ public: typedef boost::context::fiber fiber_type; - spawned_fiber_thread(ASIO_MOVE_ARG(fiber_type) caller)- : caller_(ASIO_MOVE_CAST(fiber_type)(caller)),+ spawned_fiber_thread(fiber_type&& caller)+ : caller_(static_cast<fiber_type&&>(caller)), on_suspend_fn_(0), on_suspend_arg_(0) {@@ -202,35 +67,35 @@ template <typename StackAllocator, typename F> static spawned_thread_base* spawn(allocator_arg_t,- ASIO_MOVE_ARG(StackAllocator) stack_allocator,- ASIO_MOVE_ARG(F) f,+ StackAllocator&& stack_allocator,+ 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(),- 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);+ 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); 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,+ static spawned_thread_base* spawn(F&& f, cancellation_slot parent_cancel_slot = cancellation_slot(), cancellation_state cancel_state = cancellation_state()) { return spawn(allocator_arg_t(), boost::context::fixedsize_stack(),- ASIO_MOVE_CAST(F)(f), parent_cancel_slot, cancel_state);+ static_cast<F&&>(f), parent_cancel_slot, cancel_state); } void resume() {- callee_ = fiber_type(ASIO_MOVE_CAST(fiber_type)(callee_)).resume();+ callee_ = fiber_type(static_cast<fiber_type&&>(callee_)).resume(); if (on_suspend_fn_) { void (*fn)(void*) = on_suspend_fn_;@@ -248,14 +113,14 @@ has_context_switched_ = true; on_suspend_fn_ = fn; on_suspend_arg_ = arg;- caller_ = fiber_type(ASIO_MOVE_CAST(fiber_type)(caller_)).resume();+ caller_ = fiber_type(static_cast<fiber_type&&>(caller_)).resume(); } void destroy() {- fiber_type callee = ASIO_MOVE_CAST(fiber_type)(callee_);+ fiber_type callee = static_cast<fiber_type&&>(callee_); if (terminal_)- fiber_type(ASIO_MOVE_CAST(fiber_type)(callee)).resume();+ fiber_type(static_cast<fiber_type&&>(callee)).resume(); } private:@@ -264,18 +129,18 @@ { public: template <typename F>- entry_point(ASIO_MOVE_ARG(F) f,+ entry_point(F&& f, spawned_fiber_thread** spawned_thread_out)- : function_(ASIO_MOVE_CAST(F)(f)),+ : function_(static_cast<F&&>(f)), spawned_thread_out_(spawned_thread_out) { } - fiber_type operator()(ASIO_MOVE_ARG(fiber_type) caller)+ fiber_type operator()(fiber_type&& caller) {- Function function(ASIO_MOVE_CAST(Function)(function_));+ Function function(static_cast<Function&&>(function_)); spawned_fiber_thread spawned_thread(- ASIO_MOVE_CAST(fiber_type)(caller));+ static_cast<fiber_type&&>(caller)); *spawned_thread_out_ = &spawned_thread; spawned_thread_out_ = 0; spawned_thread.suspend();@@ -299,7 +164,7 @@ spawned_thread.suspend_with(spawned_thread_rethrow, &ex); } #endif // !defined(ASIO_NO_EXCEPTIONS)- return ASIO_MOVE_CAST(fiber_type)(spawned_thread.caller_);+ return static_cast<fiber_type&&>(spawned_thread.caller_); } private:@@ -317,8 +182,6 @@ #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@@ -330,32 +193,14 @@ 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) } -#if defined(ASIO_HAS_MOVE)-- spawned_thread_resumer(spawned_thread_resumer&& other) ASIO_NOEXCEPT+ spawned_thread_resumer(spawned_thread_resumer&& other) 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_)@@ -364,9 +209,7 @@ void operator()() {-#if defined(ASIO_HAS_MOVE) spawned_thread_->attach(&spawned_thread_);-#endif // defined(ASIO_HAS_MOVE) spawned_thread_->resume(); } @@ -382,31 +225,14 @@ : spawned_thread_(spawned_thread) { spawned_thread->detach();-#if !defined(ASIO_HAS_MOVE)- spawned_thread->attach(&spawned_thread_);-#endif // !defined(ASIO_HAS_MOVE) } -#if defined(ASIO_HAS_MOVE)-- spawned_thread_destroyer(spawned_thread_destroyer&& other) ASIO_NOEXCEPT+ spawned_thread_destroyer(spawned_thread_destroyer&& other) 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_)@@ -439,14 +265,9 @@ spawned_thread_(yield.spawned_thread_) { spawned_thread_->detach();-#if !defined(ASIO_HAS_MOVE)- spawned_thread_->attach(&spawned_thread_);-#endif // !defined(ASIO_HAS_MOVE) } -#if defined(ASIO_HAS_MOVE)-- spawn_handler_base(spawn_handler_base&& other) ASIO_NOEXCEPT+ spawn_handler_base(spawn_handler_base&& other) noexcept : yield_(other.yield_), spawned_thread_(other.spawned_thread_) @@ -454,30 +275,18 @@ 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 ASIO_NOEXCEPT+ executor_type get_executor() const noexcept { return yield_.executor_; } - cancellation_slot_type get_cancellation_slot() const ASIO_NOEXCEPT+ cancellation_slot_type get_cancellation_slot() const noexcept { return spawned_thread_->get_cancellation_slot(); }@@ -495,7 +304,7 @@ }; // Completion handlers for when basic_yield_context is used as a token.-template <typename Executor, typename Signature>+template <typename Executor, typename Signature, typename = void> class spawn_handler; template <typename Executor, typename R>@@ -558,13 +367,14 @@ result_type& result_; }; -template <typename Executor, typename R>-class spawn_handler<Executor, R(exception_ptr)>- : public spawn_handler_base<Executor>+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> { public: typedef void return_type;- typedef exception_ptr* result_type;+ typedef Disposition* result_type; spawn_handler(const basic_yield_context<Executor>& yield, result_type& result) : spawn_handler_base<Executor>(yield),@@ -572,16 +382,16 @@ { } - void operator()(exception_ptr ex)+ void operator()(Disposition d) {- result_ = &ex;+ result_ = detail::addressof(d); this->resume(); } static return_type on_resume(result_type& result) {- if (result)- rethrow_exception(*result);+ if (*result != no_error)+ asio::throw_exception(static_cast<Disposition&&>(*result)); } private:@@ -589,8 +399,9 @@ }; template <typename Executor, typename R, typename T>-class spawn_handler<Executor, R(T)>- : public spawn_handler_base<Executor>+class spawn_handler<Executor, R(T),+ enable_if_t<!is_disposition<T>::value>+ > : public spawn_handler_base<Executor> { public: typedef T return_type;@@ -604,13 +415,13 @@ void operator()(T value) {- result_ = &value;+ result_ = detail::addressof(value); this->resume(); } static return_type on_resume(result_type& result) {- return ASIO_MOVE_CAST(return_type)(*result);+ return static_cast<return_type&&>(*result); } private:@@ -645,7 +456,7 @@ } else result_.ec_ = &ec;- result_.value_ = &value;+ result_.value_ = detail::addressof(value); this->resume(); } @@ -653,23 +464,24 @@ { if (result.ec_) throw_error(*result.ec_);- return ASIO_MOVE_CAST(return_type)(*result.value_);+ return static_cast<return_type&&>(*result.value_); } private: result_type& result_; }; -template <typename Executor, typename R, typename T>-class spawn_handler<Executor, R(exception_ptr, T)>- : public spawn_handler_base<Executor>+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> { public: typedef T return_type; struct result_type {- exception_ptr ex_;+ Disposition* disposition_; return_type* value_; }; @@ -679,33 +491,34 @@ { } - void operator()(exception_ptr ex, T value)+ void operator()(Disposition d, T value) {- result_.ex_ = &ex;- result_.value_ = &value;+ result_.disposition_ = detail::addressof(d);+ result_.value_ = detail::addressof(value); this->resume(); } static return_type on_resume(result_type& result) {- if (result.ex_)- rethrow_exception(*result.ex_);- return ASIO_MOVE_CAST(return_type)(*result.value_);+ if (*result.disposition_ != no_error)+ {+ asio::throw_exception(+ static_cast<Disposition&&>(*result.disposition_));+ }+ return static_cast<return_type&&>(*result.value_); } private: result_type& result_; }; -#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>+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> { public:- typedef std::tuple<Ts...> return_type;+ typedef std::tuple<T, Ts...> return_type; typedef return_type* result_type; @@ -716,16 +529,16 @@ } template <typename... Args>- void operator()(ASIO_MOVE_ARG(Args)... args)+ void operator()(Args&&... args) {- return_type value(ASIO_MOVE_CAST(Args)(args)...);- result_ = &value;+ return_type value(static_cast<Args&&>(args)...);+ result_ = detail::addressof(value); this->resume(); } static return_type on_resume(result_type& result) {- return ASIO_MOVE_CAST(return_type)(*result);+ return static_cast<return_type&&>(*result); } private:@@ -753,9 +566,9 @@ template <typename... Args> void operator()(asio::error_code ec,- ASIO_MOVE_ARG(Args)... args)+ Args&&... args) {- return_type value(ASIO_MOVE_CAST(Args)(args)...);+ return_type value(static_cast<Args&&>(args)...); if (this->yield_.ec_) { *this->yield_.ec_ = ec;@@ -763,7 +576,7 @@ } else result_.ec_ = &ec;- result_.value_ = &value;+ result_.value_ = detail::addressof(value); this->resume(); } @@ -771,23 +584,24 @@ { if (result.ec_) throw_error(*result.ec_);- return ASIO_MOVE_CAST(return_type)(*result.value_);+ return static_cast<return_type&&>(*result.value_); } private: result_type& result_; }; -template <typename Executor, typename R, typename... Ts>-class spawn_handler<Executor, R(exception_ptr, Ts...)>- : public spawn_handler_base<Executor>+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> { public: typedef std::tuple<Ts...> return_type; struct result_type {- exception_ptr ex_;+ Disposition* disposition_; return_type* value_; }; @@ -798,28 +612,28 @@ } template <typename... Args>- void operator()(exception_ptr ex, ASIO_MOVE_ARG(Args)... args)+ void operator()(Disposition d, Args&&... args) {- return_type value(ASIO_MOVE_CAST(Args)(args)...);- result_.ex_ = &ex;- result_.value_ = &value;+ return_type value(static_cast<Args&&>(args)...);+ result_.disposition_ = detail::addressof(d);+ result_.value_ = detail::addressof(value); this->resume(); } static return_type on_resume(result_type& result) {- if (result.ex_)- rethrow_exception(*result.ex_);- return ASIO_MOVE_CAST(return_type)(*result.value_);+ if (*result.disposition_ != no_error)+ {+ asio::throw_exception(+ static_cast<Disposition&&>(*result.disposition_));+ }+ return static_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>*) {@@ -828,6 +642,8 @@ } // namespace detail +#if !defined(GENERATING_DOCUMENTATION)+ template <typename Executor, typename Signature> class async_result<basic_yield_context<Executor>, Signature> {@@ -835,13 +651,12 @@ typedef typename detail::spawn_handler<Executor, Signature> handler_type; typedef typename handler_type::return_type return_type; -#if defined(ASIO_HAS_VARIADIC_TEMPLATES)-# if defined(ASIO_HAS_VARIADIC_LAMBDA_CAPTURES)+#if defined(ASIO_HAS_VARIADIC_LAMBDA_CAPTURES) template <typename Initiation, typename... InitArgs>- static return_type initiate(ASIO_MOVE_ARG(Initiation) init,+ static return_type initiate(Initiation&& init, const basic_yield_context<Executor>& yield,- ASIO_MOVE_ARG(InitArgs)... init_args)+ InitArgs&&... init_args) { typename handler_type::result_type result = typename handler_type::result_type();@@ -849,30 +664,30 @@ yield.spawned_thread_->suspend_with( [&]() {- ASIO_MOVE_CAST(Initiation)(init)(+ static_cast<Initiation&&>(init)( handler_type(yield, result),- ASIO_MOVE_CAST(InitArgs)(init_args)...);+ static_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_;- ASIO_MOVE_ARG(Initiation) init_;+ Initiation&& init_; const basic_yield_context<Executor>& yield_;- std::tuple<ASIO_MOVE_ARG(InitArgs)...> init_args_;+ std::tuple<InitArgs&&...> init_args_; template <std::size_t... I> void do_invoke(detail::index_sequence<I...>) {- ASIO_MOVE_CAST(Initiation)(init_)(+ static_cast<Initiation&&>(init_)( handler_type(yield_, result_),- ASIO_MOVE_CAST(InitArgs)(std::get<I>(init_args_))...);+ static_cast<InitArgs&&>(std::get<I>(init_args_))...); } void operator()()@@ -882,123 +697,27 @@ }; template <typename Initiation, typename... InitArgs>- static return_type initiate(ASIO_MOVE_ARG(Initiation) init,+ static return_type initiate(Initiation&& init, const basic_yield_context<Executor>& yield,- ASIO_MOVE_ARG(InitArgs)... init_args)+ 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, 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)-#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)-- 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);+ result, static_cast<Initiation&&>(init), yield,+ std::tuple<InitArgs&&...>(+ static_cast<InitArgs&&>(init_args)...)}); 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)+#endif // defined(ASIO_HAS_VARIADIC_LAMBDA_CAPTURES) }; +#endif // !defined(GENERATING_DOCUMENTATION)+ namespace detail { template <typename Executor, typename Function, typename Handler>@@ -1007,10 +726,10 @@ public: template <typename F, typename H> spawn_entry_point(const Executor& ex,- ASIO_MOVE_ARG(F) f, ASIO_MOVE_ARG(H) h)+ F&& f, H&& h) : executor_(ex),- function_(ASIO_MOVE_CAST(F)(f)),- handler_(ASIO_MOVE_CAST(H)(h)),+ function_(static_cast<F&&>(f)),+ handler_(static_cast<H&&>(h)), work_(handler_, executor_) { }@@ -1019,8 +738,7 @@ { const basic_yield_context<Executor> yield(spawned_thread, executor_); this->call(yield,- void_type<typename result_of<Function(- basic_yield_context<Executor>)>::type>());+ void_type<result_of_t<Function(basic_yield_context<Executor>)>>()); } private:@@ -1044,12 +762,6 @@ 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();@@ -1071,8 +783,9 @@ T result(function_(yield)); if (!yield.spawned_thread_->has_context_switched()) (post)(yield);- detail::binder2<Handler, exception_ptr, T>- handler(handler_, exception_ptr(), ASIO_MOVE_CAST(T)(result));+ detail::move_binder2<Handler, exception_ptr, T>+ handler(0, static_cast<Handler&&>(handler_),+ exception_ptr(), static_cast<T&&>(result)); work_.complete(handler, handler.handler_); } #if !defined(ASIO_NO_EXCEPTIONS)@@ -1082,18 +795,13 @@ 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::binder2<Handler, exception_ptr, T> handler(handler_, ex, T());+ detail::move_binder2<Handler, exception_ptr, T>+ handler(0, static_cast<Handler&&>(handler_), ex, T()); work_.complete(handler, handler.handler_); } #endif // !defined(ASIO_NO_EXCEPTIONS)@@ -1141,16 +849,15 @@ Executor ex_; }; - template <typename Handler, typename Executor> class spawn_cancellation_handler<Handler, Executor,- typename enable_if<+ enable_if_t< is_same< typename associated_executor<Handler, Executor>::asio_associated_executor_is_unspecialised, void >::value- >::type>+ >> { public: spawn_cancellation_handler(const Handler&, const Executor&)@@ -1182,21 +889,21 @@ { } - executor_type get_executor() const ASIO_NOEXCEPT+ executor_type get_executor() const noexcept { return executor_; } template <typename Handler, typename F>- void operator()(ASIO_MOVE_ARG(Handler) handler,- ASIO_MOVE_ARG(F) f) const+ void operator()(Handler&& handler,+ F&& f) const {- typedef typename decay<Handler>::type handler_type;- typedef typename decay<F>::type function_type;+ typedef decay_t<Handler> handler_type;+ typedef decay_t<F> function_type; typedef spawn_cancellation_handler< handler_type, Executor> cancel_handler_type; - typename associated_cancellation_slot<handler_type>::type slot+ associated_cancellation_slot_t<handler_type> slot = asio::get_associated_cancellation_slot(handler); cancel_handler_type* cancel_handler = slot.is_connected()@@ -1214,24 +921,24 @@ spawned_thread_resumer( default_spawned_thread_type::spawn( spawn_entry_point<Executor, function_type, handler_type>(- executor_, ASIO_MOVE_CAST(F)(f),- ASIO_MOVE_CAST(Handler)(handler)),+ executor_, static_cast<F&&>(f),+ static_cast<Handler&&>(handler)), proxy_slot, cancel_state))); } #if defined(ASIO_HAS_BOOST_CONTEXT_FIBER) template <typename Handler, typename StackAllocator, typename F>- void operator()(ASIO_MOVE_ARG(Handler) handler, allocator_arg_t,- ASIO_MOVE_ARG(StackAllocator) stack_allocator,- ASIO_MOVE_ARG(F) f) const+ void operator()(Handler&& handler, allocator_arg_t,+ StackAllocator&& stack_allocator,+ F&& f) const {- typedef typename decay<Handler>::type handler_type;- typedef typename decay<F>::type function_type;+ typedef decay_t<Handler> handler_type;+ typedef decay_t<F> function_type; typedef spawn_cancellation_handler< handler_type, Executor> cancel_handler_type; - typename associated_cancellation_slot<handler_type>::type slot+ associated_cancellation_slot_t<handler_type> slot = asio::get_associated_cancellation_slot(handler); cancel_handler_type* cancel_handler = slot.is_connected()@@ -1248,10 +955,10 @@ (dispatch)(executor_, spawned_thread_resumer( spawned_fiber_thread::spawn(allocator_arg_t(),- ASIO_MOVE_CAST(StackAllocator)(stack_allocator),+ static_cast<StackAllocator&&>(stack_allocator), spawn_entry_point<Executor, function_type, handler_type>(- executor_, ASIO_MOVE_CAST(F)(f),- ASIO_MOVE_CAST(Handler)(handler)),+ executor_, static_cast<F&&>(f),+ static_cast<Handler&&>(handler)), proxy_slot, cancel_state))); } @@ -1265,349 +972,141 @@ template <typename Executor, typename F, ASIO_COMPLETION_TOKEN_FOR(typename detail::spawn_signature<- 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<+ result_of_t<F(basic_yield_context<Executor>)>>::type) CompletionToken>+inline auto spawn(const Executor& ex, F&& function, CompletionToken&& token,+ constraint_t< is_executor<Executor>::value || execution::is_executor<Executor>::value- >::type)- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ >)+ -> decltype( async_initiate<CompletionToken, typename detail::spawn_signature<- typename result_of<F(basic_yield_context<Executor>)>::type>::type>(- declval<detail::initiate_spawn<Executor> >(),- token, ASIO_MOVE_CAST(F)(function))))+ result_of_t<F(basic_yield_context<Executor>)>>::type>(+ declval<detail::initiate_spawn<Executor>>(),+ token, static_cast<F&&>(function))) { return async_initiate<CompletionToken, typename detail::spawn_signature<- typename result_of<F(basic_yield_context<Executor>)>::type>::type>(+ result_of_t<F(basic_yield_context<Executor>)>>::type>( detail::initiate_spawn<Executor>(ex),- token, ASIO_MOVE_CAST(F)(function));+ token, static_cast<F&&>(function)); } template <typename ExecutionContext, typename F, ASIO_COMPLETION_TOKEN_FOR(typename detail::spawn_signature<- 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<+ result_of_t<F(basic_yield_context<+ typename ExecutionContext::executor_type>)>>::type) CompletionToken>+inline auto spawn(ExecutionContext& ctx, F&& function, CompletionToken&& token,+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value- >::type)- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ >)+ -> decltype( async_initiate<CompletionToken, typename detail::spawn_signature<- typename result_of<F(basic_yield_context<- typename ExecutionContext::executor_type>)>::type>::type>(+ result_of_t<F(basic_yield_context<+ typename ExecutionContext::executor_type>)>>::type>( declval<detail::initiate_spawn<- typename ExecutionContext::executor_type> >(),- token, ASIO_MOVE_CAST(F)(function))))+ typename ExecutionContext::executor_type>>(),+ token, static_cast<F&&>(function))) {- return (spawn)(ctx.get_executor(), ASIO_MOVE_CAST(F)(function),- ASIO_MOVE_CAST(CompletionToken)(token));+ return (spawn)(ctx.get_executor(), static_cast<F&&>(function),+ static_cast<CompletionToken&&>(token)); } template <typename Executor, typename F, ASIO_COMPLETION_TOKEN_FOR(typename detail::spawn_signature<- typename result_of<F(basic_yield_context<Executor>)>::type>::type)+ result_of_t<F(basic_yield_context<Executor>)>>::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,- 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<+inline auto spawn(const basic_yield_context<Executor>& ctx,+ F&& function, CompletionToken&& token,+ constraint_t< is_executor<Executor>::value || execution::is_executor<Executor>::value- >::type)- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ >)+ -> decltype( async_initiate<CompletionToken, typename detail::spawn_signature<- typename result_of<F(basic_yield_context<Executor>)>::type>::type>(- declval<detail::initiate_spawn<Executor> >(),- token, ASIO_MOVE_CAST(F)(function))))+ result_of_t<F(basic_yield_context<Executor>)>>::type>(+ declval<detail::initiate_spawn<Executor>>(),+ token, static_cast<F&&>(function))) {- return (spawn)(ctx.get_executor(), ASIO_MOVE_CAST(F)(function),- ASIO_MOVE_CAST(CompletionToken)(token));+ return (spawn)(ctx.get_executor(), static_cast<F&&>(function),+ static_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<- typename result_of<F(basic_yield_context<Executor>)>::type>::type)+ result_of_t<F(basic_yield_context<Executor>)>>::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, allocator_arg_t,- ASIO_MOVE_ARG(StackAllocator) stack_allocator,- ASIO_MOVE_ARG(F) function,- ASIO_MOVE_ARG(CompletionToken) token,- typename constraint<+inline auto spawn(const Executor& ex, allocator_arg_t,+ StackAllocator&& stack_allocator, F&& function, CompletionToken&& token,+ constraint_t< is_executor<Executor>::value || execution::is_executor<Executor>::value- >::type)- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ >)+ -> decltype( async_initiate<CompletionToken, typename detail::spawn_signature<- typename result_of<F(basic_yield_context<Executor>)>::type>::type>(- declval<detail::initiate_spawn<Executor> >(),+ result_of_t<F(basic_yield_context<Executor>)>>::type>(+ declval<detail::initiate_spawn<Executor>>(), token, allocator_arg_t(),- ASIO_MOVE_CAST(StackAllocator)(stack_allocator),- ASIO_MOVE_CAST(F)(function))))+ static_cast<StackAllocator&&>(stack_allocator),+ static_cast<F&&>(function))) { return async_initiate<CompletionToken, typename detail::spawn_signature<- typename result_of<F(basic_yield_context<Executor>)>::type>::type>(+ result_of_t<F(basic_yield_context<Executor>)>>::type>( detail::initiate_spawn<Executor>(ex), token, allocator_arg_t(),- ASIO_MOVE_CAST(StackAllocator)(stack_allocator),- ASIO_MOVE_CAST(F)(function));+ static_cast<StackAllocator&&>(stack_allocator),+ static_cast<F&&>(function)); } template <typename ExecutionContext, typename StackAllocator, typename F, ASIO_COMPLETION_TOKEN_FOR(typename detail::spawn_signature<- 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<+ 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< is_convertible<ExecutionContext&, execution_context&>::value- >::type)- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ >)+ -> decltype( async_initiate<CompletionToken, typename detail::spawn_signature<- typename result_of<F(basic_yield_context<- typename ExecutionContext::executor_type>)>::type>::type>(+ result_of_t<F(basic_yield_context<+ typename ExecutionContext::executor_type>)>>::type>( declval<detail::initiate_spawn<- typename ExecutionContext::executor_type> >(),+ typename ExecutionContext::executor_type>>(), token, allocator_arg_t(),- ASIO_MOVE_CAST(StackAllocator)(stack_allocator),- ASIO_MOVE_CAST(F)(function))))+ static_cast<StackAllocator&&>(stack_allocator),+ static_cast<F&&>(function))) { return (spawn)(ctx.get_executor(), allocator_arg_t(),- ASIO_MOVE_CAST(StackAllocator)(stack_allocator),- ASIO_MOVE_CAST(F)(function),- ASIO_MOVE_CAST(CompletionToken)(token));+ static_cast<StackAllocator&&>(stack_allocator),+ static_cast<F&&>(function), static_cast<CompletionToken&&>(token)); } template <typename Executor, typename StackAllocator, typename F, ASIO_COMPLETION_TOKEN_FOR(typename detail::spawn_signature<- 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<+ 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< is_executor<Executor>::value || execution::is_executor<Executor>::value- >::type)- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ >)+ -> decltype( 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))))+ 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))) { return (spawn)(ctx.get_executor(), allocator_arg_t(),- ASIO_MOVE_CAST(StackAllocator)(stack_allocator),- ASIO_MOVE_CAST(F)(function),- ASIO_MOVE_CAST(CompletionToken)(token));+ static_cast<StackAllocator&&>(stack_allocator),+ static_cast<F&&>(function), static_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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -21,13 +21,14 @@ #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"@@ -54,6 +55,7 @@ #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"@@ -64,7 +66,6 @@ #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"@@ -81,7 +82,6 @@ #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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -22,7 +22,7 @@ namespace asio { inline system_context::executor_type-system_context::get_executor() ASIO_NOEXCEPT+system_context::get_executor() 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -45,7 +45,8 @@ }; system_context::system_context()- : scheduler_(add_scheduler(new detail::scheduler(*this, 0, false)))+ : scheduler_(add_scheduler(new detail::scheduler(*this, false))),+ threads_(std::allocator<void>()) { scheduler_.work_started(); @@ -67,7 +68,7 @@ scheduler_.stop(); } -bool system_context::stopped() const ASIO_NOEXCEPT+bool system_context::stopped() const 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -27,7 +27,7 @@ template <typename Blocking, typename Relationship, typename Allocator> inline system_context& basic_system_executor<Blocking, Relationship, Allocator>::query(- execution::context_t) ASIO_NOEXCEPT+ execution::context_t) 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 ASIO_NOEXCEPT+ execution::occupancy_t) const 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(- ASIO_MOVE_ARG(Function) f, execution::blocking_t::possibly_t) const+ 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);- asio_handler_invoke_helpers::invoke(f2.value, f2.value);+ static_cast<decay_t<Function>&&>(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(- ASIO_MOVE_ARG(Function) f, execution::blocking_t::always_t) const+ 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);- asio_handler_invoke_helpers::invoke(f2.value, f2.value);+ static_cast<decay_t<Function>&&>(f2.value)(); #if !defined(ASIO_NO_EXCEPTIONS) } catch (...)@@ -91,16 +91,15 @@ template <typename Blocking, typename Relationship, typename Allocator> template <typename Function> void basic_system_executor<Blocking, Relationship, Allocator>::do_execute(- ASIO_MOVE_ARG(Function) f, execution::blocking_t::never_t) const+ 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 typename decay<Function>::type function_type;- typedef detail::executor_op<function_type, Allocator> op;+ typedef detail::executor_op<decay_t<Function>, Allocator> op; typename op::ptr p = { detail::addressof(allocator_), op::ptr::allocate(allocator_), 0 };- p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(f), allocator_);+ p.p = new (p.v) op(static_cast<Function&&>(f), allocator_); if (is_same<Relationship, execution::relationship_t::continuation_t>::value) {@@ -121,7 +120,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 ASIO_NOEXCEPT+ Blocking, Relationship, Allocator>::context() const noexcept { return detail::global<system_context>(); }@@ -129,25 +128,22 @@ template <typename Blocking, typename Relationship, typename Allocator> template <typename Function, typename OtherAllocator> void basic_system_executor<Blocking, Relationship, Allocator>::dispatch(- ASIO_MOVE_ARG(Function) f, const OtherAllocator&) const+ Function&& f, const OtherAllocator&) const {- typename decay<Function>::type tmp(ASIO_MOVE_CAST(Function)(f));- asio_handler_invoke_helpers::invoke(tmp, tmp);+ decay_t<Function>(static_cast<Function&&>(f))(); } template <typename Blocking, typename Relationship, typename Allocator> template <typename Function, typename OtherAllocator> void basic_system_executor<Blocking, Relationship, Allocator>::post(- ASIO_MOVE_ARG(Function) f, const OtherAllocator& a) const+ 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<function_type, OtherAllocator> op;+ typedef detail::executor_op<decay_t<Function>, OtherAllocator> op; typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 };- p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(f), a);+ p.p = new (p.v) op(static_cast<Function&&>(f), a); ASIO_HANDLER_CREATION((ctx, *p.p, "system_executor", &this->context(), 0, "post"));@@ -159,16 +155,14 @@ template <typename Blocking, typename Relationship, typename Allocator> template <typename Function, typename OtherAllocator> void basic_system_executor<Blocking, Relationship, Allocator>::defer(- ASIO_MOVE_ARG(Function) f, const OtherAllocator& a) const+ 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<function_type, OtherAllocator> op;+ typedef detail::executor_op<decay_t<Function>, OtherAllocator> op; typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 };- p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(f), a);+ p.p = new (p.v) op(static_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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -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,28 +27,63 @@ namespace asio { -inline thread_pool::executor_type-thread_pool::get_executor() ASIO_NOEXCEPT+#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) {- return executor_type(*this);+ 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)+{+ start();+}+ inline thread_pool::executor_type-thread_pool::executor() ASIO_NOEXCEPT+thread_pool::get_executor() noexcept { return executor_type(*this); } -inline thread_pool::scheduler_type-thread_pool::scheduler() ASIO_NOEXCEPT+inline thread_pool::executor_type+thread_pool::executor() noexcept {- return scheduler_type(*this);+ return executor_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) ASIO_NOEXCEPT+ const basic_executor_type& other) noexcept { if (this != &other) {@@ -67,11 +102,10 @@ 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) ASIO_NOEXCEPT+ basic_executor_type&& other) noexcept { if (this != &other) {@@ -88,11 +122,10 @@ } 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 ASIO_NOEXCEPT+ Bits>::running_in_this_thread() const noexcept { return pool_->scheduler_.can_dispatch(); }@@ -100,43 +133,39 @@ template <typename Allocator, unsigned int Bits> template <typename Function> void thread_pool::basic_executor_type<Allocator,- Bits>::do_execute(ASIO_MOVE_ARG(Function) f, false_type) const+ Bits>::do_execute(Function&& f, false_type) const {- typedef typename decay<Function>::type function_type;+ typedef decay_t<Function> 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(ASIO_MOVE_CAST(Function)(f));+ function_type tmp(static_cast<Function&&>(f)); -#if defined(ASIO_HAS_STD_EXCEPTION_PTR) \- && !defined(ASIO_NO_EXCEPTIONS)+#if !defined(ASIO_NO_EXCEPTIONS) try {-#endif // defined(ASIO_HAS_STD_EXCEPTION_PTR)- // && !defined(ASIO_NO_EXCEPTIONS)+#endif // !defined(ASIO_NO_EXCEPTIONS) detail::fenced_block b(detail::fenced_block::full);- asio_handler_invoke_helpers::invoke(tmp, tmp);+ static_cast<function_type&&>(tmp)(); return;-#if defined(ASIO_HAS_STD_EXCEPTION_PTR) \- && !defined(ASIO_NO_EXCEPTIONS)+#if !defined(ASIO_NO_EXCEPTIONS) } catch (...) { pool_->scheduler_.capture_current_exception(); return; }-#endif // defined(ASIO_HAS_STD_EXCEPTION_PTR)- // && !defined(ASIO_NO_EXCEPTIONS)+#endif // !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(ASIO_MOVE_CAST(Function)(f), allocator_);+ p.p = new (p.v) op(static_cast<Function&&>(f), allocator_); if ((bits_ & relationship_continuation) != 0) {@@ -157,7 +186,7 @@ template <typename Allocator, unsigned int Bits> template <typename Function> void thread_pool::basic_executor_type<Allocator,- Bits>::do_execute(ASIO_MOVE_ARG(Function) f, true_type) const+ Bits>::do_execute(Function&& f, true_type) const { // Obtain a non-const instance of the function. detail::non_const_lvalue<Function> f2(f);@@ -170,7 +199,7 @@ { #endif // !defined(ASIO_NO_EXCEPTIONS) detail::fenced_block b(detail::fenced_block::full);- asio_handler_invoke_helpers::invoke(f2.value, f2.value);+ static_cast<decay_t<Function>&&>(f2.value)(); return; #if !defined(ASIO_NO_EXCEPTIONS) }@@ -182,7 +211,7 @@ } // Construct an operation to wrap the function.- typedef typename decay<Function>::type function_type;+ typedef decay_t<Function> function_type; detail::blocking_executor_op<function_type> op(f2.value); ASIO_HANDLER_CREATION((*pool_, op,@@ -192,88 +221,24 @@ 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 ASIO_NOEXCEPT+ Allocator, Bits>::context() const noexcept { return *pool_; } template <typename Allocator, unsigned int Bits> inline void thread_pool::basic_executor_type<Allocator,- Bits>::on_work_started() const ASIO_NOEXCEPT+ Bits>::on_work_started() const noexcept { pool_->scheduler_.work_started(); } template <typename Allocator, unsigned int Bits> inline void thread_pool::basic_executor_type<Allocator,- Bits>::on_work_finished() const ASIO_NOEXCEPT+ Bits>::on_work_finished() const noexcept { pool_->scheduler_.work_finished(); }@@ -281,25 +246,25 @@ template <typename Allocator, unsigned int Bits> template <typename Function, typename OtherAllocator> void thread_pool::basic_executor_type<Allocator, Bits>::dispatch(- ASIO_MOVE_ARG(Function) f, const OtherAllocator& a) const+ Function&& f, const OtherAllocator& a) const {- typedef typename decay<Function>::type function_type;+ typedef decay_t<Function> 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(ASIO_MOVE_CAST(Function)(f));+ function_type tmp(static_cast<Function&&>(f)); detail::fenced_block b(detail::fenced_block::full);- asio_handler_invoke_helpers::invoke(tmp, tmp);+ static_cast<function_type&&>(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(ASIO_MOVE_CAST(Function)(f), a);+ p.p = new (p.v) op(static_cast<Function&&>(f), a); ASIO_HANDLER_CREATION((*pool_, *p.p, "thread_pool", pool_, 0, "dispatch"));@@ -311,14 +276,14 @@ template <typename Allocator, unsigned int Bits> template <typename Function, typename OtherAllocator> void thread_pool::basic_executor_type<Allocator, Bits>::post(- ASIO_MOVE_ARG(Function) f, const OtherAllocator& a) const+ Function&& f, const OtherAllocator& a) const {- typedef typename decay<Function>::type function_type;+ typedef decay_t<Function> 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(ASIO_MOVE_CAST(Function)(f), a);+ p.p = new (p.v) op(static_cast<Function&&>(f), a); ASIO_HANDLER_CREATION((*pool_, *p.p, "thread_pool", pool_, 0, "post"));@@ -330,14 +295,14 @@ template <typename Allocator, unsigned int Bits> template <typename Function, typename OtherAllocator> void thread_pool::basic_executor_type<Allocator, Bits>::defer(- ASIO_MOVE_ARG(Function) f, const OtherAllocator& a) const+ Function&& f, const OtherAllocator& a) const {- typedef typename decay<Function>::type function_type;+ typedef decay_t<Function> 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(ASIO_MOVE_CAST(Function)(f), a);+ p.p = new (p.v) op(static_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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -47,31 +47,26 @@ }; #if !defined(ASIO_NO_TS_EXECUTORS)-namespace detail { -inline long default_thread_pool_size()+long thread_pool::default_thread_pool_size() {- std::size_t num_threads = thread::hardware_concurrency() * 2;+ std::size_t num_threads = detail::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_(add_scheduler(new detail::scheduler(*this, 0, false))),- num_threads_(detail::default_thread_pool_size())+ : scheduler_(asio::make_service<detail::scheduler>(*this, false)),+ threads_(allocator<void>(*this)),+ num_threads_(default_thread_pool_size()),+ joinable_(true) {- scheduler_.work_started();-- thread_function f = { &scheduler_ };- threads_.create_threads(f, static_cast<std::size_t>(num_threads_));+ start(); }-#endif // !defined(ASIO_NO_TS_EXECUTORS) -namespace detail {+#endif // !defined(ASIO_NO_TS_EXECUTORS) -inline long clamp_thread_pool_size(std::size_t n)+long thread_pool::clamp_thread_pool_size(std::size_t n) { if (n > 0x7FFFFFFF) {@@ -81,17 +76,25 @@ return static_cast<long>(n & 0x7FFFFFFF); } -} // namespace detail- thread_pool::thread_pool(std::size_t num_threads)- : scheduler_(add_scheduler(new detail::scheduler(- *this, num_threads == 1 ? 1 : 0, false))),- num_threads_(detail::clamp_thread_pool_size(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_.work_started();+ start();+} - thread_function f = { &scheduler_ };- threads_.create_threads(f, static_cast<std::size_t>(num_threads_));+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_pool::~thread_pool()@@ -101,6 +104,13 @@ 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();@@ -115,24 +125,17 @@ void thread_pool::join() {- if (num_threads_)+ if (joinable_)+ {+ joinable_ = false; 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() {- scheduler_.work_finished();- threads_.join();+ 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -18,6 +18,7 @@ #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" @@ -73,98 +74,27 @@ } }; -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, T>+ : public awaitable_handler_base<Executor,+ conditional_t<is_disposition<T>::value, void, T>> { public:- using awaitable_handler_base<Executor, T>::awaitable_handler_base;+ using awaitable_handler_base<Executor,+ conditional_t<is_disposition<T>::value, void, T>>+ ::awaitable_handler_base; template <typename Arg> void operator()(Arg&& arg) { this->frame()->attach_thread(this);- 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();- this->frame()->pop_frame();- this->pump();- }-};--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);+ if constexpr (is_disposition<T>::value)+ {+ if (arg == no_error)+ this->frame()->return_void();+ else+ this->frame()->set_disposition(arg);+ } else this->frame()->return_value(std::forward<Arg>(arg)); this->frame()->clear_cancellation_slot();@@ -173,63 +103,66 @@ } }; -template <typename Executor, typename... Ts>-class awaitable_handler- : 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()(Args&&... args)- {- this->frame()->attach_thread(this);- 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...>>+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>>> { public: using awaitable_handler_base<Executor,- std::tuple<Ts...>>::awaitable_handler_base;+ conditional_t<is_disposition<T0>::value, T1, std::tuple<T0, T1>>>+ ::awaitable_handler_base; - template <typename... Args>- void operator()(const asio::error_code& ec, Args&&... args)+ template <typename Arg0, typename Arg1>+ void operator()(Arg0&& arg0, Arg1&& arg1) { this->frame()->attach_thread(this);- if (ec)- this->frame()->set_error(ec);+ 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));+ } else- this->frame()->return_values(std::forward<Args>(args)...);+ {+ this->frame()->return_values(std::forward<Arg0>(arg0),+ std::forward<Arg1>(arg1));+ } this->frame()->clear_cancellation_slot(); this->frame()->pop_frame(); this->pump(); } }; -template <typename Executor, typename... Ts>-class awaitable_handler<Executor, std::exception_ptr, Ts...>- : public awaitable_handler_base<Executor, std::tuple<Ts...>>+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...>>> { public: using awaitable_handler_base<Executor,- std::tuple<Ts...>>::awaitable_handler_base;+ conditional_t<is_disposition<T0>::value,+ std::tuple<Ts...>, std::tuple<T0, Ts...>>>+ ::awaitable_handler_base; - template <typename... Args>- void operator()(std::exception_ptr ex, Args&&... args)+ template <typename Arg0, typename... Args>+ void operator()(Arg0&& arg0, Args&&... args) { this->frame()->attach_thread(this);- if (ex)- this->frame()->set_except(ex);+ 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));+ } else- this->frame()->return_values(std::forward<Args>(args)...);+ {+ this->frame()->return_values(std::forward<Arg0>(arg0),+ std::forward<Args>(args)...);+ } this->frame()->clear_cancellation_slot(); this->frame()->pop_frame(); this->pump();@@ -258,7 +191,7 @@ { public: typedef typename detail::awaitable_handler<- Executor, typename decay<Args>::type...> handler_type;+ Executor, decay_t<Args>...> handler_type; typedef typename handler_type::awaitable_type return_type; template <typename Initiation, typename... InitArgs>@@ -286,9 +219,9 @@ }; for (;;) {} // Never reached.-#if defined(_MSC_VER)+#if defined(_MSC_VER) && !defined(__clang__) co_return dummy_return<typename return_type::value_type>();-#endif // defined(_MSC_VER)+#endif // defined(_MSC_VER) && !defined(__clang__) } };
link/modules/asio-standalone/asio/include/asio/impl/use_future.hpp view
@@ -2,7 +2,7 @@ // impl/use_future.hpp // ~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -19,8 +19,9 @@ #include <tuple> #include "asio/async_result.hpp" #include "asio/detail/memory.hpp"+#include "asio/detail/type_traits.hpp" #include "asio/dispatch.hpp"-#include "asio/error_code.hpp"+#include "asio/disposition.hpp" #include "asio/execution.hpp" #include "asio/packaged_task.hpp" #include "asio/system_error.hpp"@@ -31,17 +32,15 @@ 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, ASIO_MOVE_ARG(Args)... args)+ F& f, Args&&... args) { #if !defined(ASIO_NO_EXCEPTIONS) try #endif // !defined(ASIO_NO_EXCEPTIONS) {- p.set_value(f(ASIO_MOVE_CAST(Args)(args)...));+ p.set_value(f(static_cast<Args&&>(args)...)); } #if !defined(ASIO_NO_EXCEPTIONS) catch (...)@@ -53,13 +52,13 @@ template <typename F, typename... Args> inline void promise_invoke_and_set(std::promise<void>& p,- F& f, ASIO_MOVE_ARG(Args)... args)+ F& f, Args&&... args) { #if !defined(ASIO_NO_EXCEPTIONS) try #endif // !defined(ASIO_NO_EXCEPTIONS) {- f(ASIO_MOVE_CAST(Args)(args)...);+ f(static_cast<Args&&>(args)...); p.set_value(); } #if !defined(ASIO_NO_EXCEPTIONS)@@ -70,112 +69,15 @@ #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,- ASIO_MOVE_ARG(F) f)- : p_(p), f_(ASIO_MOVE_CAST(F)(f))+ promise_invoker(const shared_ptr<std::promise<T>>& p,+ F&& f)+ : p_(p), f_(static_cast<F&&>(f)) { } @@ -196,27 +98,27 @@ } private:- shared_ptr<std::promise<T> > p_;- typename decay<F>::type f_;+ shared_ptr<std::promise<T>> p_;+ decay_t<F> f_; }; -// An executor that adapts the system_executor to capture any exeption thrown+// An executor that adapts the system_executor to capture any exception 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 ASIO_NOEXCEPT+ execution_context& query(execution::context_t) const noexcept { return asio::query(system_executor(), execution::context); } - static ASIO_CONSTEXPR Blocking query(execution::blocking_t)+ static constexpr Blocking query(execution::blocking_t) { return Blocking(); }@@ -234,62 +136,56 @@ } template <typename F>- void execute(ASIO_MOVE_ARG(F) f) const+ void execute(F&& f) const {-#if defined(ASIO_NO_DEPRECATED) asio::require(system_executor(), Blocking()).execute(- 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)+ promise_invoker<T, F>(p_, static_cast<F&&>(f))); } #if !defined(ASIO_NO_TS_EXECUTORS)- execution_context& context() const ASIO_NOEXCEPT+ execution_context& context() const noexcept { return system_executor().context(); } - void on_work_started() const ASIO_NOEXCEPT {}- void on_work_finished() const ASIO_NOEXCEPT {}+ void on_work_started() const noexcept {}+ void on_work_finished() const noexcept {} template <typename F, typename A>- void dispatch(ASIO_MOVE_ARG(F) f, const A&) const+ void dispatch(F&& f, const A&) const {- promise_invoker<T, F>(p_, ASIO_MOVE_CAST(F)(f))();+ promise_invoker<T, F>(p_, static_cast<F&&>(f))(); } template <typename F, typename A>- void post(ASIO_MOVE_ARG(F) f, const A& a) const+ void post(F&& f, const A& a) const { system_executor().post(- promise_invoker<T, F>(p_, ASIO_MOVE_CAST(F)(f)), a);+ promise_invoker<T, F>(p_, static_cast<F&&>(f)), a); } template <typename F, typename A>- void defer(ASIO_MOVE_ARG(F) f, const A& a) const+ void defer(F&& f, const A& a) const { system_executor().defer(- promise_invoker<T, F>(p_, ASIO_MOVE_CAST(F)(f)), a);+ promise_invoker<T, F>(p_, static_cast<F&&>(f)), a); } #endif // !defined(ASIO_NO_TS_EXECUTORS) friend bool operator==(const promise_executor& a,- const promise_executor& b) ASIO_NOEXCEPT+ const promise_executor& b) noexcept { return a.p_ == b.p_; } friend bool operator!=(const promise_executor& a,- const promise_executor& b) ASIO_NOEXCEPT+ const promise_executor& b) 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.@@ -299,7 +195,7 @@ public: typedef promise_executor<T> executor_type; - executor_type get_executor() const ASIO_NOEXCEPT+ executor_type get_executor() const noexcept { return executor_type(p_); }@@ -319,7 +215,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().@@ -333,36 +229,18 @@ } }; -// For completion signature void(error_code).-class promise_handler_ec_0+// For completion signature void(disposition auto).+template <typename Disposition>+class promise_handler_d_0 : public promise_creator<void> { public:- void operator()(const asio::error_code& ec)+ void operator()(Disposition d) {- if (ec)+ if (d != no_error) { this->p_->set_exception(- std::make_exception_ptr(- asio::system_error(ec)));- }- else- {- this->p_->set_value();- }- }-};--// 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);+ (to_exception_ptr)(static_cast<Disposition&&>(d))); } else {@@ -378,47 +256,28 @@ { public: template <typename Arg>- void operator()(ASIO_MOVE_ARG(Arg) arg)+ void operator()(Arg&& arg) {- this->p_->set_value(ASIO_MOVE_CAST(Arg)(arg));+ this->p_->set_value(static_cast<Arg&&>(arg)); } }; -// For completion signature void(error_code, T).-template <typename T>-class promise_handler_ec_1+// For completion signature void(disposition auto, T).+template <typename Disposition, typename T>+class promise_handler_d_1 : public promise_creator<T> { public: template <typename Arg>- void operator()(const asio::error_code& ec,- ASIO_MOVE_ARG(Arg) arg)+ void operator()(Disposition d, Arg&& arg) {- if (ec)+ if (d != no_error) { this->p_->set_exception(- std::make_exception_ptr(- asio::system_error(ec)));+ (to_exception_ptr)(static_cast<Disposition&&>(d))); } else- 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));+ this->p_->set_value(static_cast<Arg&&>(arg)); } }; @@ -428,198 +287,70 @@ : public promise_creator<T> { public:-#if defined(ASIO_HAS_VARIADIC_TEMPLATES)- template <typename... Args>- void operator()(ASIO_MOVE_ARG(Args)... args)+ void operator()(Args&&... args) { this->p_->set_value( std::forward_as_tuple(- ASIO_MOVE_CAST(Args)(args)...));+ static_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 T>-class promise_handler_ec_n+template <typename Disposition, typename T>+class promise_handler_d_n : public promise_creator<T> { public:-#if defined(ASIO_HAS_VARIADIC_TEMPLATES)- template <typename... Args>- void operator()(const asio::error_code& ec,- ASIO_MOVE_ARG(Args)... args)+ void operator()(Disposition d, Args&&... args) {- if (ec)+ if (d != no_error) { this->p_->set_exception(- std::make_exception_ptr(- asio::system_error(ec)));+ (to_exception_ptr)(static_cast<Disposition&&>(d))); } else { this->p_->set_value( std::forward_as_tuple(- ASIO_MOVE_CAST(Args)(args)...));+ static_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> class promise_handler_selector;+template <typename, typename = void> 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)>- : public promise_handler_1<Arg> {};--template <typename Arg>-class promise_handler_selector<void(asio::error_code, Arg)>- : public promise_handler_ec_1<Arg> {};+class promise_handler_selector<void(Arg),+ enable_if_t<is_disposition<Arg>::value>>+ : public promise_handler_d_0<Arg> {}; template <typename Arg>-class promise_handler_selector<void(std::exception_ptr, Arg)>- : public promise_handler_ex_1<Arg> {};--#if defined(ASIO_HAS_VARIADIC_TEMPLATES)--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...> > {};+class promise_handler_selector<void(Arg),+ enable_if_t<!is_disposition<Arg>::value>>+ : public promise_handler_1<Arg> {}; -#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)+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> {}; -#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+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...>> {}; -#endif // 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...>> {}; // Completion handlers produced from the use_future completion token, when not // using use_future::operator().@@ -637,7 +368,7 @@ this->create_promise(allocator_); } - allocator_type get_allocator() const ASIO_NOEXCEPT+ allocator_type get_allocator() const noexcept { return allocator_; }@@ -650,7 +381,7 @@ struct promise_function_wrapper { explicit promise_function_wrapper(Function& f)- : function_(ASIO_MOVE_CAST(Function)(f))+ : function_(static_cast<Function&&>(f)) { } @@ -667,28 +398,6 @@ 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@@ -704,7 +413,7 @@ return_type get() {- return ASIO_MOVE_CAST(return_type)(future_);+ return static_cast<return_type&&>(future_); } private:@@ -717,7 +426,7 @@ { public: packaged_token(Function f, const Allocator& a)- : function_(ASIO_MOVE_CAST(Function)(f)),+ : function_(static_cast<Function&&>(f)), allocator_(a) { }@@ -738,75 +447,29 @@ typedef void result_type; packaged_handler(packaged_token<Function, Allocator> t)- : function_(ASIO_MOVE_CAST(Function)(t.function_)),+ : function_(static_cast<Function&&>(t.function_)), allocator_(t.allocator_) { this->create_promise(allocator_); } - allocator_type get_allocator() const ASIO_NOEXCEPT+ allocator_type get_allocator() const noexcept { return allocator_; } -#if defined(ASIO_HAS_VARIADIC_TEMPLATES)- template <typename... Args>- void operator()(ASIO_MOVE_ARG(Args)... args)+ void operator()(Args&&... args) { (promise_invoke_and_set)(*this->p_,- function_, ASIO_MOVE_CAST(Args)(args)...);- }--#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)-- void operator()()- {- (promise_invoke_and_set)(*this->p_, function_);+ function_, static_cast<Args&&>(args)...); } -#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@@ -822,7 +485,7 @@ return_type get() {- return ASIO_MOVE_CAST(return_type)(future_);+ return static_cast<return_type&&>(future_); } private:@@ -832,28 +495,26 @@ } // namespace detail template <typename Allocator> template <typename Function>-inline detail::packaged_token<typename decay<Function>::type, Allocator>-use_future_t<Allocator>::operator()(ASIO_MOVE_ARG(Function) f) const+inline detail::packaged_token<decay_t<Function>, Allocator>+use_future_t<Allocator>::operator()(Function&& f) const {- return detail::packaged_token<typename decay<Function>::type, Allocator>(- ASIO_MOVE_CAST(Function)(f), allocator_);+ return detail::packaged_token<decay_t<Function>, Allocator>(+ static_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(typename decay<Args>::type...), Allocator>+ void(decay_t<Args>...), Allocator> { public: explicit async_result(- typename detail::promise_async_result<void(typename decay<Args>::type...),+ typename detail::promise_async_result<void(decay_t<Args>...), Allocator>::completion_handler_type& h) : detail::promise_async_result<- void(typename decay<Args>::type...), Allocator>(h)+ void(decay_t<Args>...), Allocator>(h) { } };@@ -862,100 +523,28 @@ typename Result, typename... Args> class async_result<detail::packaged_token<Function, Allocator>, Result(Args...)> : public detail::packaged_async_result<Function, Allocator,- typename result_of<Function(Args...)>::type>-{-public:- explicit async_result(- typename detail::packaged_async_result<Function, Allocator,- typename result_of<Function(Args...)>::type>::completion_handler_type& h)- : detail::packaged_async_result<Function, Allocator,- 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>+ result_of_t<Function(Args...)>> { public: explicit async_result( typename detail::packaged_async_result<Function, Allocator,- typename result_of<Function()>::type>::completion_handler_type& h)+ result_of_t<Function(Args...)>>::completion_handler_type& h) : detail::packaged_async_result<Function, Allocator,- typename result_of<Function()>::type>(h)+ result_of_t<Function(Args...)>>(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>> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; }; #endif // !defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)@@ -966,8 +555,8 @@ struct execute_member< asio::detail::promise_executor<T, Blocking>, Function> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = false; typedef void result_type; }; @@ -987,11 +576,11 @@ >::type > {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef Blocking result_type; - static ASIO_CONSTEXPR result_type value() ASIO_NOEXCEPT+ static constexpr result_type value() noexcept { return Blocking(); }@@ -1007,8 +596,8 @@ execution::context_t > {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef asio::system_context& result_type; }; @@ -1022,8 +611,8 @@ execution::blocking_t::possibly_t > {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef asio::detail::promise_executor<T, execution::blocking_t::possibly_t> result_type; };@@ -1034,8 +623,8 @@ execution::blocking_t::never_t > {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -23,9 +23,7 @@ #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,20 +60,23 @@ typename CompletionCondition> inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers, CompletionCondition completion_condition, asio::error_code& ec,- typename constraint<+ constraint_t< is_const_buffer_sequence<ConstBufferSequence>::value- >::type)+ >,+ constraint_t<+ is_completion_condition<CompletionCondition>::value+ >) { return detail::write(s, buffers, asio::buffer_sequence_begin(buffers),- ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);+ static_cast<CompletionCondition&&>(completion_condition), ec); } template <typename SyncWriteStream, typename ConstBufferSequence> inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers,- typename constraint<+ constraint_t< is_const_buffer_sequence<ConstBufferSequence>::value- >::type)+ >) { asio::error_code ec; std::size_t bytes_transferred = write(s, buffers, transfer_all(), ec);@@ -86,9 +87,9 @@ template <typename SyncWriteStream, typename ConstBufferSequence> inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers, asio::error_code& ec,- typename constraint<+ constraint_t< is_const_buffer_sequence<ConstBufferSequence>::value- >::type)+ >) { return write(s, buffers, transfer_all(), ec); }@@ -97,13 +98,16 @@ typename CompletionCondition> inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers, CompletionCondition completion_condition,- typename constraint<+ constraint_t< is_const_buffer_sequence<ConstBufferSequence>::value- >::type)+ >,+ constraint_t<+ is_completion_condition<CompletionCondition>::value+ >) { asio::error_code ec; std::size_t bytes_transferred = write(s, buffers,- ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);+ static_cast<CompletionCondition&&>(completion_condition), ec); asio::detail::throw_error(ec, "write"); return bytes_transferred; }@@ -113,37 +117,40 @@ template <typename SyncWriteStream, typename DynamicBuffer_v1, typename CompletionCondition> std::size_t write(SyncWriteStream& s,- ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+ DynamicBuffer_v1&& buffers, CompletionCondition completion_condition, 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)+ 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 decay<DynamicBuffer_v1>::type b(- ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers));+ decay_t<DynamicBuffer_v1> b(+ static_cast<DynamicBuffer_v1&&>(buffers)); std::size_t bytes_transferred = write(s, b.data(),- ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);+ static_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,- 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)+ 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::error_code ec; std::size_t bytes_transferred = write(s,- ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+ static_cast<DynamicBuffer_v1&&>(buffers), transfer_all(), ec); asio::detail::throw_error(ec, "write"); return bytes_transferred;@@ -151,35 +158,38 @@ template <typename SyncWriteStream, typename DynamicBuffer_v1> inline std::size_t write(SyncWriteStream& s,- ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+ DynamicBuffer_v1&& buffers, 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)+ constraint_t<+ is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value+ >,+ constraint_t<+ !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value+ >) {- return write(s, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+ return write(s, static_cast<DynamicBuffer_v1&&>(buffers), transfer_all(), ec); } template <typename SyncWriteStream, typename DynamicBuffer_v1, typename CompletionCondition> inline std::size_t write(SyncWriteStream& s,- ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+ DynamicBuffer_v1&& buffers, CompletionCondition completion_condition,- 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)+ 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+ >) { asio::error_code ec; std::size_t bytes_transferred = write(s,- ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),- ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);+ static_cast<DynamicBuffer_v1&&>(buffers),+ static_cast<CompletionCondition&&>(completion_condition), ec); asio::detail::throw_error(ec, "write"); return bytes_transferred; }@@ -191,10 +201,13 @@ typename CompletionCondition> inline std::size_t write(SyncWriteStream& s, asio::basic_streambuf<Allocator>& b,- CompletionCondition completion_condition, asio::error_code& ec)+ CompletionCondition completion_condition, asio::error_code& ec,+ constraint_t<+ is_completion_condition<CompletionCondition>::value+ >) { return write(s, basic_streambuf_ref<Allocator>(b),- ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);+ static_cast<CompletionCondition&&>(completion_condition), ec); } template <typename SyncWriteStream, typename Allocator>@@ -216,10 +229,13 @@ typename CompletionCondition> inline std::size_t write(SyncWriteStream& s, asio::basic_streambuf<Allocator>& b,- CompletionCondition completion_condition)+ CompletionCondition completion_condition,+ constraint_t<+ is_completion_condition<CompletionCondition>::value+ >) { return write(s, basic_streambuf_ref<Allocator>(b),- ASIO_MOVE_CAST(CompletionCondition)(completion_condition));+ static_cast<CompletionCondition&&>(completion_condition)); } #endif // !defined(ASIO_NO_IOSTREAM)@@ -230,25 +246,28 @@ typename CompletionCondition> std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers, CompletionCondition completion_condition, asio::error_code& ec,- typename constraint<+ constraint_t< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- >::type)+ >,+ constraint_t<+ is_completion_condition<CompletionCondition>::value+ >) { std::size_t bytes_transferred = write(s, buffers.data(0, buffers.size()),- ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);+ static_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,- typename constraint<+ constraint_t< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- >::type)+ >) { asio::error_code ec; std::size_t bytes_transferred = write(s,- ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+ static_cast<DynamicBuffer_v2&&>(buffers), transfer_all(), ec); asio::detail::throw_error(ec, "write"); return bytes_transferred;@@ -257,11 +276,11 @@ template <typename SyncWriteStream, typename DynamicBuffer_v2> inline std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers, asio::error_code& ec,- typename constraint<+ constraint_t< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- >::type)+ >) {- return write(s, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+ return write(s, static_cast<DynamicBuffer_v2&&>(buffers), transfer_all(), ec); } @@ -269,14 +288,17 @@ typename CompletionCondition> inline std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers, CompletionCondition completion_condition,- typename constraint<+ constraint_t< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- >::type)+ >,+ constraint_t<+ is_completion_condition<CompletionCondition>::value+ >) { asio::error_code ec; std::size_t bytes_transferred = write(s,- ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),- ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);+ static_cast<DynamicBuffer_v2&&>(buffers),+ static_cast<CompletionCondition&&>(completion_condition), ec); asio::detail::throw_error(ec, "write"); return bytes_transferred; }@@ -299,11 +321,10 @@ stream_(stream), buffers_(buffers), start_(0),- handler_(ASIO_MOVE_CAST(WriteHandler)(handler))+ handler_(static_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),@@ -316,18 +337,15 @@ write_op(write_op&& other) : base_from_cancellation_state<WriteHandler>(- ASIO_MOVE_CAST(base_from_cancellation_state<- WriteHandler>)(other)),+ static_cast<base_from_cancellation_state<WriteHandler>&&>(other)), base_from_completion_cond<CompletionCondition>(- ASIO_MOVE_CAST(base_from_completion_cond<- CompletionCondition>)(other)),+ static_cast<base_from_completion_cond<CompletionCondition>&&>(other)), stream_(other.stream_),- buffers_(ASIO_MOVE_CAST(buffers_type)(other.buffers_)),+ buffers_(static_cast<buffers_type&&>(other.buffers_)), start_(other.start_),- handler_(ASIO_MOVE_CAST(WriteHandler)(other.handler_))+ handler_(static_cast<WriteHandler&&>(other.handler_)) { }-#endif // defined(ASIO_HAS_MOVE) void operator()(asio::error_code ec, std::size_t bytes_transferred, int start = 0)@@ -342,7 +360,7 @@ { ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_write")); stream_.async_write_some(buffers_.prepare(max_size),- ASIO_MOVE_CAST(write_op)(*this));+ static_cast<write_op&&>(*this)); } return; default: buffers_.consume(bytes_transferred);@@ -358,7 +376,7 @@ } } - ASIO_MOVE_OR_LVALUE(WriteHandler)(handler_)(+ static_cast<WriteHandler&&>(handler_)( static_cast<const asio::error_code&>(ec), static_cast<const std::size_t&>(buffers_.total_consumed())); }@@ -377,38 +395,6 @@ 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)@@ -418,36 +404,6 @@ 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>@@ -472,16 +428,16 @@ { } - executor_type get_executor() const ASIO_NOEXCEPT+ executor_type get_executor() const noexcept { return stream_.get_executor(); } template <typename WriteHandler, typename ConstBufferSequence, typename CompletionCondition>- void operator()(ASIO_MOVE_ARG(WriteHandler) handler,+ void operator()(WriteHandler&& handler, const ConstBufferSequence& buffers,- ASIO_MOVE_ARG(CompletionCondition) completion_cond) const+ 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.@@ -511,21 +467,18 @@ DefaultCandidate> : Associator<WriteHandler, DefaultCandidate> {- static typename Associator<WriteHandler, DefaultCandidate>::type- get(const detail::write_op<AsyncWriteStream, ConstBufferSequence,- ConstBufferIterator, CompletionCondition, WriteHandler>& h)- ASIO_NOEXCEPT+ static typename Associator<WriteHandler, DefaultCandidate>::type get(+ const detail::write_op<AsyncWriteStream, ConstBufferSequence,+ ConstBufferIterator, CompletionCondition, WriteHandler>& h) noexcept { return Associator<WriteHandler, DefaultCandidate>::get(h.handler_); } - static ASIO_AUTO_RETURN_TYPE_PREFIX2(- typename Associator<WriteHandler, DefaultCandidate>::type)- get(const detail::write_op<AsyncWriteStream, ConstBufferSequence,+ static auto get(+ const detail::write_op<AsyncWriteStream, ConstBufferSequence, ConstBufferIterator, CompletionCondition, WriteHandler>& h,- const DefaultCandidate& c) ASIO_NOEXCEPT- ASIO_AUTO_RETURN_TYPE_SUFFIX((- Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c)))+ const DefaultCandidate& c) noexcept+ -> decltype(Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c)) { return Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c); }@@ -533,54 +486,6 @@ #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@@ -592,17 +497,16 @@ public: template <typename BufferSequence> write_dynbuf_v1_op(AsyncWriteStream& stream,- ASIO_MOVE_ARG(BufferSequence) buffers,+ BufferSequence&& buffers, CompletionCondition& completion_condition, WriteHandler& handler) : stream_(stream),- buffers_(ASIO_MOVE_CAST(BufferSequence)(buffers)),+ buffers_(static_cast<BufferSequence&&>(buffers)), completion_condition_(- ASIO_MOVE_CAST(CompletionCondition)(completion_condition)),- handler_(ASIO_MOVE_CAST(WriteHandler)(handler))+ static_cast<CompletionCondition&&>(completion_condition)),+ handler_(static_cast<WriteHandler&&>(handler)) { } -#if defined(ASIO_HAS_MOVE) write_dynbuf_v1_op(const write_dynbuf_v1_op& other) : stream_(other.stream_), buffers_(other.buffers_),@@ -613,14 +517,13 @@ write_dynbuf_v1_op(write_dynbuf_v1_op&& other) : stream_(other.stream_),- buffers_(ASIO_MOVE_CAST(DynamicBuffer_v1)(other.buffers_)),+ buffers_(static_cast<DynamicBuffer_v1&&>(other.buffers_)), completion_condition_(- ASIO_MOVE_CAST(CompletionCondition)(+ static_cast<CompletionCondition&&>( other.completion_condition_)),- handler_(ASIO_MOVE_CAST(WriteHandler)(other.handler_))+ handler_(static_cast<WriteHandler&&>(other.handler_)) { }-#endif // defined(ASIO_HAS_MOVE) void operator()(const asio::error_code& ec, std::size_t bytes_transferred, int start = 0)@@ -629,11 +532,11 @@ { case 1: async_write(stream_, buffers_.data(),- ASIO_MOVE_CAST(CompletionCondition)(completion_condition_),- ASIO_MOVE_CAST(write_dynbuf_v1_op)(*this));+ static_cast<CompletionCondition&&>(completion_condition_),+ static_cast<write_dynbuf_v1_op&&>(*this)); return; default: buffers_.consume(bytes_transferred);- ASIO_MOVE_OR_LVALUE(WriteHandler)(handler_)(ec,+ static_cast<WriteHandler&&>(handler_)(ec, static_cast<const std::size_t&>(bytes_transferred)); } }@@ -647,36 +550,6 @@ 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)@@ -685,36 +558,6 @@ 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 {@@ -726,16 +569,16 @@ { } - executor_type get_executor() const ASIO_NOEXCEPT+ executor_type get_executor() const noexcept { return stream_.get_executor(); } template <typename WriteHandler, typename DynamicBuffer_v1, typename CompletionCondition>- void operator()(ASIO_MOVE_ARG(WriteHandler) handler,- ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,- ASIO_MOVE_ARG(CompletionCondition) completion_cond) const+ void operator()(WriteHandler&& handler,+ DynamicBuffer_v1&& buffers,+ 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.@@ -744,9 +587,9 @@ non_const_lvalue<WriteHandler> handler2(handler); non_const_lvalue<CompletionCondition> completion_cond2(completion_cond); write_dynbuf_v1_op<AsyncWriteStream,- typename decay<DynamicBuffer_v1>::type,- CompletionCondition, typename decay<WriteHandler>::type>(- stream_, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+ decay_t<DynamicBuffer_v1>,+ CompletionCondition, decay_t<WriteHandler>>(+ stream_, static_cast<DynamicBuffer_v1&&>(buffers), completion_cond2.value, handler2.value)( asio::error_code(), 0, 1); }@@ -768,20 +611,18 @@ DefaultCandidate> : Associator<WriteHandler, DefaultCandidate> {- static typename Associator<WriteHandler, DefaultCandidate>::type- get(const detail::write_dynbuf_v1_op<AsyncWriteStream, DynamicBuffer_v1,- CompletionCondition, WriteHandler>& h) ASIO_NOEXCEPT+ static typename Associator<WriteHandler, DefaultCandidate>::type get(+ const detail::write_dynbuf_v1_op<AsyncWriteStream, DynamicBuffer_v1,+ CompletionCondition, WriteHandler>& h) noexcept { return Associator<WriteHandler, DefaultCandidate>::get(h.handler_); } - static ASIO_AUTO_RETURN_TYPE_PREFIX2(- typename Associator<WriteHandler, DefaultCandidate>::type)- get(const detail::write_dynbuf_v1_op<AsyncWriteStream,+ static auto get(+ const detail::write_dynbuf_v1_op<AsyncWriteStream, DynamicBuffer_v1, CompletionCondition, WriteHandler>& h,- const DefaultCandidate& c) ASIO_NOEXCEPT- ASIO_AUTO_RETURN_TYPE_SUFFIX((- Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c)))+ const DefaultCandidate& c) noexcept+ -> decltype(Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c)) { return Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c); }@@ -789,105 +630,6 @@ #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@@ -899,17 +641,16 @@ public: template <typename BufferSequence> write_dynbuf_v2_op(AsyncWriteStream& stream,- ASIO_MOVE_ARG(BufferSequence) buffers,+ BufferSequence&& buffers, CompletionCondition& completion_condition, WriteHandler& handler) : stream_(stream),- buffers_(ASIO_MOVE_CAST(BufferSequence)(buffers)),+ buffers_(static_cast<BufferSequence&&>(buffers)), completion_condition_(- ASIO_MOVE_CAST(CompletionCondition)(completion_condition)),- handler_(ASIO_MOVE_CAST(WriteHandler)(handler))+ static_cast<CompletionCondition&&>(completion_condition)),+ handler_(static_cast<WriteHandler&&>(handler)) { } -#if defined(ASIO_HAS_MOVE) write_dynbuf_v2_op(const write_dynbuf_v2_op& other) : stream_(other.stream_), buffers_(other.buffers_),@@ -920,14 +661,13 @@ write_dynbuf_v2_op(write_dynbuf_v2_op&& other) : stream_(other.stream_),- buffers_(ASIO_MOVE_CAST(DynamicBuffer_v2)(other.buffers_)),+ buffers_(static_cast<DynamicBuffer_v2&&>(other.buffers_)), completion_condition_(- ASIO_MOVE_CAST(CompletionCondition)(+ static_cast<CompletionCondition&&>( other.completion_condition_)),- handler_(ASIO_MOVE_CAST(WriteHandler)(other.handler_))+ handler_(static_cast<WriteHandler&&>(other.handler_)) { }-#endif // defined(ASIO_HAS_MOVE) void operator()(const asio::error_code& ec, std::size_t bytes_transferred, int start = 0)@@ -936,11 +676,11 @@ { case 1: async_write(stream_, buffers_.data(0, buffers_.size()),- ASIO_MOVE_CAST(CompletionCondition)(completion_condition_),- ASIO_MOVE_CAST(write_dynbuf_v2_op)(*this));+ static_cast<CompletionCondition&&>(completion_condition_),+ static_cast<write_dynbuf_v2_op&&>(*this)); return; default: buffers_.consume(bytes_transferred);- ASIO_MOVE_OR_LVALUE(WriteHandler)(handler_)(ec,+ static_cast<WriteHandler&&>(handler_)(ec, static_cast<const std::size_t&>(bytes_transferred)); } }@@ -954,36 +694,6 @@ 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)@@ -992,36 +702,6 @@ 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 {@@ -1033,16 +713,16 @@ { } - executor_type get_executor() const ASIO_NOEXCEPT+ executor_type get_executor() const noexcept { return stream_.get_executor(); } template <typename WriteHandler, typename DynamicBuffer_v2, typename CompletionCondition>- void operator()(ASIO_MOVE_ARG(WriteHandler) handler,- ASIO_MOVE_ARG(DynamicBuffer_v2) buffers,- ASIO_MOVE_ARG(CompletionCondition) completion_cond) const+ void operator()(WriteHandler&& handler,+ DynamicBuffer_v2&& buffers,+ 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.@@ -1050,12 +730,11 @@ non_const_lvalue<WriteHandler> handler2(handler); non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);- 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);+ 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); } private:@@ -1075,76 +754,24 @@ DefaultCandidate> : Associator<WriteHandler, DefaultCandidate> {- static typename Associator<WriteHandler, DefaultCandidate>::type- get(const detail::write_dynbuf_v2_op<AsyncWriteStream, DynamicBuffer_v2,- CompletionCondition, WriteHandler>& h) ASIO_NOEXCEPT+ static typename Associator<WriteHandler, DefaultCandidate>::type get(+ const detail::write_dynbuf_v2_op<AsyncWriteStream, DynamicBuffer_v2,+ CompletionCondition, WriteHandler>& h) noexcept { return Associator<WriteHandler, DefaultCandidate>::get(h.handler_); } - static ASIO_AUTO_RETURN_TYPE_PREFIX2(- typename Associator<WriteHandler, DefaultCandidate>::type)- get(const detail::write_dynbuf_v2_op<AsyncWriteStream,+ static auto get(+ const detail::write_dynbuf_v2_op<AsyncWriteStream, DynamicBuffer_v2, CompletionCondition, WriteHandler>& h,- const DefaultCandidate& c) ASIO_NOEXCEPT- ASIO_AUTO_RETURN_TYPE_SUFFIX((- Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c)))+ const DefaultCandidate& c) noexcept+ -> decltype(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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -23,9 +23,7 @@ #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,11 +64,14 @@ typename CompletionCondition> std::size_t write_at(SyncRandomAccessWriteDevice& d, uint64_t offset, const ConstBufferSequence& buffers,- CompletionCondition completion_condition, asio::error_code& ec)+ CompletionCondition completion_condition, asio::error_code& ec,+ constraint_t<+ is_completion_condition<CompletionCondition>::value+ >) { return detail::write_at_buffer_sequence(d, offset, buffers, asio::buffer_sequence_begin(buffers),- ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);+ static_cast<CompletionCondition&&>(completion_condition), ec); } template <typename SyncRandomAccessWriteDevice, typename ConstBufferSequence>@@ -96,11 +97,14 @@ typename CompletionCondition> inline std::size_t write_at(SyncRandomAccessWriteDevice& d, uint64_t offset, const ConstBufferSequence& buffers,- CompletionCondition completion_condition)+ CompletionCondition completion_condition,+ constraint_t<+ is_completion_condition<CompletionCondition>::value+ >) { asio::error_code ec; std::size_t bytes_transferred = write_at(d, offset, buffers,- ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);+ static_cast<CompletionCondition&&>(completion_condition), ec); asio::detail::throw_error(ec, "write_at"); return bytes_transferred; }@@ -112,10 +116,13 @@ typename CompletionCondition> std::size_t write_at(SyncRandomAccessWriteDevice& d, uint64_t offset, asio::basic_streambuf<Allocator>& b,- CompletionCondition completion_condition, asio::error_code& ec)+ CompletionCondition completion_condition, asio::error_code& ec,+ constraint_t<+ is_completion_condition<CompletionCondition>::value+ >) { std::size_t bytes_transferred = write_at(d, offset, b.data(),- ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);+ static_cast<CompletionCondition&&>(completion_condition), ec); b.consume(bytes_transferred); return bytes_transferred; }@@ -142,11 +149,14 @@ typename CompletionCondition> inline std::size_t write_at(SyncRandomAccessWriteDevice& d, uint64_t offset, asio::basic_streambuf<Allocator>& b,- CompletionCondition completion_condition)+ CompletionCondition completion_condition,+ constraint_t<+ is_completion_condition<CompletionCondition>::value+ >) { asio::error_code ec; std::size_t bytes_transferred = write_at(d, offset, b,- ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);+ static_cast<CompletionCondition&&>(completion_condition), ec); asio::detail::throw_error(ec, "write_at"); return bytes_transferred; }@@ -174,11 +184,10 @@ offset_(offset), buffers_(buffers), start_(0),- handler_(ASIO_MOVE_CAST(WriteHandler)(handler))+ handler_(static_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),@@ -192,19 +201,16 @@ write_at_op(write_at_op&& other) : base_from_cancellation_state<WriteHandler>(- ASIO_MOVE_CAST(base_from_cancellation_state<- WriteHandler>)(other)),+ static_cast<base_from_cancellation_state<WriteHandler>&&>(other)), base_from_completion_cond<CompletionCondition>(- ASIO_MOVE_CAST(base_from_completion_cond<- CompletionCondition>)(other)),+ static_cast<base_from_completion_cond<CompletionCondition>&&>(other)), device_(other.device_), offset_(other.offset_),- buffers_(ASIO_MOVE_CAST(buffers_type)(other.buffers_)),+ buffers_(static_cast<buffers_type&&>(other.buffers_)), start_(other.start_),- handler_(ASIO_MOVE_CAST(WriteHandler)(other.handler_))+ handler_(static_cast<WriteHandler&&>(other.handler_)) { }-#endif // defined(ASIO_HAS_MOVE) void operator()(asio::error_code ec, std::size_t bytes_transferred, int start = 0)@@ -220,7 +226,7 @@ ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_write_at")); device_.async_write_some_at( offset_ + buffers_.total_consumed(), buffers_.prepare(max_size),- ASIO_MOVE_CAST(write_at_op)(*this));+ static_cast<write_at_op&&>(*this)); } return; default: buffers_.consume(bytes_transferred);@@ -236,7 +242,7 @@ } } - ASIO_MOVE_OR_LVALUE(WriteHandler)(handler_)(+ static_cast<WriteHandler&&>(handler_)( static_cast<const asio::error_code&>(ec), static_cast<const std::size_t&>(buffers_.total_consumed())); }@@ -256,38 +262,6 @@ 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)@@ -297,36 +271,6 @@ 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>@@ -352,16 +296,16 @@ { } - executor_type get_executor() const ASIO_NOEXCEPT+ executor_type get_executor() const noexcept { return device_.get_executor(); } template <typename WriteHandler, typename ConstBufferSequence, typename CompletionCondition>- void operator()(ASIO_MOVE_ARG(WriteHandler) handler,+ void operator()(WriteHandler&& handler, uint64_t offset, const ConstBufferSequence& buffers,- ASIO_MOVE_ARG(CompletionCondition) completion_cond) const+ 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.@@ -391,22 +335,20 @@ 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) ASIO_NOEXCEPT+ CompletionCondition, WriteHandler>& h) noexcept { return Associator<WriteHandler, DefaultCandidate>::get(h.handler_); } - static ASIO_AUTO_RETURN_TYPE_PREFIX2(- typename Associator<WriteHandler, DefaultCandidate>::type)- get(const detail::write_at_op<AsyncRandomAccessWriteDevice,+ static auto get(+ const detail::write_at_op<AsyncRandomAccessWriteDevice, ConstBufferSequence, ConstBufferIterator, CompletionCondition, WriteHandler>& h,- const DefaultCandidate& c) ASIO_NOEXCEPT- ASIO_AUTO_RETURN_TYPE_SUFFIX((- Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c)))+ const DefaultCandidate& c) noexcept+ -> decltype(Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c)) { return Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c); }@@ -414,52 +356,6 @@ #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) @@ -473,11 +369,10 @@ asio::basic_streambuf<Allocator>& streambuf, WriteHandler& handler) : streambuf_(streambuf),- handler_(ASIO_MOVE_CAST(WriteHandler)(handler))+ handler_(static_cast<WriteHandler&&>(handler)) { } -#if defined(ASIO_HAS_MOVE) write_at_streambuf_op(const write_at_streambuf_op& other) : streambuf_(other.streambuf_), handler_(other.handler_)@@ -486,16 +381,15 @@ write_at_streambuf_op(write_at_streambuf_op&& other) : streambuf_(other.streambuf_),- handler_(ASIO_MOVE_CAST(WriteHandler)(other.handler_))+ handler_(static_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);- ASIO_MOVE_OR_LVALUE(WriteHandler)(handler_)(ec, bytes_transferred);+ static_cast<WriteHandler&&>(handler_)(ec, bytes_transferred); } //private:@@ -504,32 +398,6 @@ }; 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) {@@ -537,30 +405,6 @@ 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 {@@ -573,16 +417,16 @@ { } - executor_type get_executor() const ASIO_NOEXCEPT+ executor_type get_executor() const noexcept { return device_.get_executor(); } template <typename WriteHandler, typename Allocator, typename CompletionCondition>- void operator()(ASIO_MOVE_ARG(WriteHandler) handler,+ void operator()(WriteHandler&& handler, uint64_t offset, basic_streambuf<Allocator>* b,- ASIO_MOVE_ARG(CompletionCondition) completion_condition) const+ 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.@@ -590,8 +434,8 @@ non_const_lvalue<WriteHandler> handler2(handler); async_write_at(device_, offset, b->data(),- ASIO_MOVE_CAST(CompletionCondition)(completion_condition),- write_at_streambuf_op<Allocator, typename decay<WriteHandler>::type>(+ static_cast<CompletionCondition&&>(completion_condition),+ write_at_streambuf_op<Allocator, decay_t<WriteHandler>>( *b, handler2.value)); } @@ -609,73 +453,22 @@ DefaultCandidate> : Associator<WriteHandler, DefaultCandidate> {- static typename Associator<WriteHandler, DefaultCandidate>::type- get(const detail::write_at_streambuf_op<Executor, WriteHandler>& h)- ASIO_NOEXCEPT+ static typename Associator<WriteHandler, DefaultCandidate>::type get(+ const detail::write_at_streambuf_op<Executor, WriteHandler>& h) noexcept { return Associator<WriteHandler, DefaultCandidate>::get(h.handler_); } - 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)))+ static auto get(+ const detail::write_at_streambuf_op<Executor, WriteHandler>& h,+ const DefaultCandidate& c) noexcept+ -> decltype(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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -20,6 +20,7 @@ #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"@@ -27,10 +28,6 @@ #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) \@@ -58,10 +55,10 @@ struct io_context_bits {- 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);+ 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; }; } // namespace detail @@ -200,11 +197,6 @@ 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;@@ -215,11 +207,6 @@ /// 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) \@@ -236,6 +223,15 @@ /// 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@@ -243,6 +239,47 @@ */ 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@@ -278,7 +315,7 @@ ASIO_DECL ~io_context(); /// Obtains the executor associated with the io_context.- executor_type get_executor() ASIO_NOEXCEPT;+ executor_type get_executor() noexcept; /// Run the io_context object's event processing loop. /**@@ -300,46 +337,13 @@ * @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 caller's responsibility 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. /**@@ -366,7 +370,6 @@ */ 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.@@ -383,34 +386,10 @@ * @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.+ * deadlock. It is the caller's responsibility 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. /**@@ -439,7 +418,6 @@ 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.@@ -451,20 +429,6 @@ */ 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. /**@@ -475,20 +439,6 @@ */ 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@@ -524,79 +474,6 @@ 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. /**@@ -617,7 +494,8 @@ * 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 io_context.dispatch(boost::bind(f, a1, ... an)); @endcode+ * @code asio::dispatch(io_context,+ * boost::bind(f, a1, ... an)); @endcode */ template <typename Handler> #if defined(GENERATING_DOCUMENTATION)@@ -629,11 +507,8 @@ #endif // !defined(ASIO_NO_DEPRECATED) private:- 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);+ io_context(const io_context&) = delete;+ io_context& operator=(const io_context&) = delete; // Backwards compatible overload for use with services derived from // io_context::service.@@ -651,10 +526,6 @@ 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 :@@ -662,8 +533,7 @@ { public: /// Copy constructor.- basic_executor_type(- const basic_executor_type& other) ASIO_NOEXCEPT+ basic_executor_type(const basic_executor_type& other) noexcept : Allocator(static_cast<const Allocator&>(other)), target_(other.target_) {@@ -672,19 +542,17 @@ context_ptr()->impl_.work_started(); } -#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move constructor.- basic_executor_type(basic_executor_type&& other) ASIO_NOEXCEPT- : Allocator(ASIO_MOVE_CAST(Allocator)(other)),+ basic_executor_type(basic_executor_type&& other) noexcept+ : Allocator(static_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() ASIO_NOEXCEPT+ ~basic_executor_type() noexcept { if (Bits & outstanding_work_tracked) if (context_ptr())@@ -692,14 +560,10 @@ } /// Assignment operator.- basic_executor_type& operator=(- const basic_executor_type& other) ASIO_NOEXCEPT;+ basic_executor_type& operator=(const basic_executor_type& other) noexcept; -#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move assignment operator.- basic_executor_type& operator=(- basic_executor_type&& other) ASIO_NOEXCEPT;-#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)+ basic_executor_type& operator=(basic_executor_type&& other) noexcept; #if !defined(GENERATING_DOCUMENTATION) private:@@ -717,8 +581,7 @@ * auto ex2 = asio::require(ex1, * asio::execution::blocking.possibly); @endcode */- ASIO_CONSTEXPR basic_executor_type require(- execution::blocking_t::possibly_t) const+ constexpr basic_executor_type require(execution::blocking_t::possibly_t) const { return basic_executor_type(context_ptr(), *this, bits() & ~blocking_never);@@ -734,8 +597,7 @@ * auto ex2 = asio::require(ex1, * asio::execution::blocking.never); @endcode */- ASIO_CONSTEXPR basic_executor_type require(- execution::blocking_t::never_t) const+ constexpr basic_executor_type require(execution::blocking_t::never_t) const { return basic_executor_type(context_ptr(), *this, bits() | blocking_never);@@ -751,8 +613,7 @@ * auto ex2 = asio::require(ex1, * asio::execution::relationship.fork); @endcode */- ASIO_CONSTEXPR basic_executor_type require(- execution::relationship_t::fork_t) const+ constexpr basic_executor_type require(execution::relationship_t::fork_t) const { return basic_executor_type(context_ptr(), *this, bits() & ~relationship_continuation);@@ -768,7 +629,7 @@ * auto ex2 = asio::require(ex1, * asio::execution::relationship.continuation); @endcode */- ASIO_CONSTEXPR basic_executor_type require(+ constexpr basic_executor_type require( execution::relationship_t::continuation_t) const { return basic_executor_type(context_ptr(),@@ -785,7 +646,7 @@ * auto ex2 = asio::require(ex1, * asio::execution::outstanding_work.tracked); @endcode */- ASIO_CONSTEXPR basic_executor_type<Allocator,+ constexpr basic_executor_type<Allocator, ASIO_UNSPECIFIED(Bits | outstanding_work_tracked)> require(execution::outstanding_work_t::tracked_t) const {@@ -803,7 +664,7 @@ * auto ex2 = asio::require(ex1, * asio::execution::outstanding_work.untracked); @endcode */- ASIO_CONSTEXPR basic_executor_type<Allocator,+ constexpr basic_executor_type<Allocator, ASIO_UNSPECIFIED(Bits & ~outstanding_work_tracked)> require(execution::outstanding_work_t::untracked_t) const {@@ -822,7 +683,7 @@ * asio::execution::allocator(my_allocator)); @endcode */ template <typename OtherAllocator>- ASIO_CONSTEXPR basic_executor_type<OtherAllocator, Bits>+ constexpr basic_executor_type<OtherAllocator, Bits> require(execution::allocator_t<OtherAllocator> a) const { return basic_executor_type<OtherAllocator, Bits>(@@ -839,7 +700,7 @@ * auto ex2 = asio::require(ex1, * asio::execution::allocator); @endcode */- ASIO_CONSTEXPR basic_executor_type<std::allocator<void>, Bits>+ constexpr basic_executor_type<std::allocator<void>, Bits> require(execution::allocator_t<void>) const { return basic_executor_type<std::allocator<void>, Bits>(@@ -864,8 +725,7 @@ * == asio::execution::mapping.thread) * ... @endcode */- static ASIO_CONSTEXPR execution::mapping_t query(- execution::mapping_t) ASIO_NOEXCEPT+ static constexpr execution::mapping_t query(execution::mapping_t) noexcept { return execution::mapping.thread; }@@ -880,7 +740,7 @@ * asio::io_context& ctx = asio::query( * ex, asio::execution::context); @endcode */- io_context& query(execution::context_t) const ASIO_NOEXCEPT+ io_context& query(execution::context_t) const noexcept { return *context_ptr(); }@@ -896,8 +756,7 @@ * == asio::execution::blocking.always) * ... @endcode */- ASIO_CONSTEXPR execution::blocking_t query(- execution::blocking_t) const ASIO_NOEXCEPT+ constexpr execution::blocking_t query(execution::blocking_t) const noexcept { return (bits() & blocking_never) ? execution::blocking_t(execution::blocking.never)@@ -915,8 +774,8 @@ * == asio::execution::relationship.continuation) * ... @endcode */- ASIO_CONSTEXPR execution::relationship_t query(- execution::relationship_t) const ASIO_NOEXCEPT+ constexpr execution::relationship_t query(+ execution::relationship_t) const noexcept { return (bits() & relationship_continuation) ? execution::relationship_t(execution::relationship.continuation)@@ -934,8 +793,8 @@ * == asio::execution::outstanding_work.tracked) * ... @endcode */- static ASIO_CONSTEXPR execution::outstanding_work_t query(- execution::outstanding_work_t) ASIO_NOEXCEPT+ static constexpr execution::outstanding_work_t query(+ execution::outstanding_work_t) noexcept { return (Bits & outstanding_work_tracked) ? execution::outstanding_work_t(execution::outstanding_work.tracked)@@ -953,8 +812,8 @@ * asio::execution::allocator); @endcode */ template <typename OtherAllocator>- ASIO_CONSTEXPR Allocator query(- execution::allocator_t<OtherAllocator>) const ASIO_NOEXCEPT+ constexpr Allocator query(+ execution::allocator_t<OtherAllocator>) const noexcept { return static_cast<const Allocator&>(*this); }@@ -969,8 +828,7 @@ * auto alloc = asio::query(ex, * asio::execution::allocator); @endcode */- ASIO_CONSTEXPR Allocator query(- execution::allocator_t<void>) const ASIO_NOEXCEPT+ constexpr Allocator query(execution::allocator_t<void>) const noexcept { return static_cast<const Allocator&>(*this); }@@ -981,14 +839,14 @@ * @return @c true if the current thread is running the io_context. Otherwise * returns @c false. */- bool running_in_this_thread() const ASIO_NOEXCEPT;+ bool running_in_this_thread() const 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) ASIO_NOEXCEPT+ const basic_executor_type& b) noexcept { return a.target_ == b.target_ && static_cast<const Allocator&>(a) == static_cast<const Allocator&>(b);@@ -999,7 +857,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) ASIO_NOEXCEPT+ const basic_executor_type& b) noexcept { return a.target_ != b.target_ || static_cast<const Allocator&>(a) != static_cast<const Allocator&>(b);@@ -1007,12 +865,12 @@ /// Execution function. template <typename Function>- void execute(ASIO_MOVE_ARG(Function) f) const;+ void execute(Function&& f) const; #if !defined(ASIO_NO_TS_EXECUTORS) public: /// Obtain the underlying execution context.- io_context& context() const ASIO_NOEXCEPT;+ io_context& context() const noexcept; /// Inform the io_context that it has some outstanding work to do. /**@@ -1020,7 +878,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 ASIO_NOEXCEPT;+ void on_work_started() const noexcept; /// Inform the io_context that some work is no longer outstanding. /**@@ -1028,7 +886,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 ASIO_NOEXCEPT;+ void on_work_finished() const noexcept; /// Request the io_context to invoke the given function object. /**@@ -1045,8 +903,7 @@ * internal storage needed for function invocation. */ template <typename Function, typename OtherAllocator>- void dispatch(ASIO_MOVE_ARG(Function) f,- const OtherAllocator& a) const;+ void dispatch(Function&& f, const OtherAllocator& a) const; /// Request the io_context to invoke the given function object. /**@@ -1062,8 +919,7 @@ * internal storage needed for function invocation. */ template <typename Function, typename OtherAllocator>- void post(ASIO_MOVE_ARG(Function) f,- const OtherAllocator& a) const;+ void post(Function&& f, const OtherAllocator& a) const; /// Request the io_context to invoke the given function object. /**@@ -1083,8 +939,7 @@ * internal storage needed for function invocation. */ template <typename Function, typename OtherAllocator>- void defer(ASIO_MOVE_ARG(Function) f,- const OtherAllocator& a) const;+ void defer(Function&& f, const OtherAllocator& a) const; #endif // !defined(ASIO_NO_TS_EXECUTORS) private:@@ -1092,7 +947,7 @@ template <typename, uintptr_t> friend class basic_executor_type; // Constructor used by io_context::get_executor().- explicit basic_executor_type(io_context& i) ASIO_NOEXCEPT+ explicit basic_executor_type(io_context& i) noexcept : Allocator(), target_(reinterpret_cast<uintptr_t>(&i)) {@@ -1102,7 +957,7 @@ // Constructor used by require(). basic_executor_type(io_context* i,- const Allocator& a, uintptr_t bits) ASIO_NOEXCEPT+ const Allocator& a, uintptr_t bits) noexcept : Allocator(a), target_(reinterpret_cast<uintptr_t>(i) | bits) {@@ -1111,12 +966,12 @@ context_ptr()->impl_.work_started(); } - io_context* context_ptr() const ASIO_NOEXCEPT+ io_context* context_ptr() const noexcept { return reinterpret_cast<io_context*>(target_ & ~runtime_bits); } - uintptr_t bits() const ASIO_NOEXCEPT+ uintptr_t bits() const noexcept { return target_ & runtime_bits; }@@ -1125,57 +980,6 @@ 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@@ -1188,12 +992,6 @@ /// 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. /**@@ -1203,17 +1001,6 @@ 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. /**@@ -1258,8 +1045,8 @@ asio::io_context::basic_executor_type<Allocator, Bits> > {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; }; #endif // !defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)@@ -1272,8 +1059,8 @@ Function > {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = false; typedef void result_type; }; @@ -1287,8 +1074,8 @@ asio::execution::blocking_t::possibly_t > {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = false; typedef asio::io_context::basic_executor_type< Allocator, Bits> result_type; };@@ -1299,8 +1086,8 @@ asio::execution::blocking_t::never_t > {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = false; typedef asio::io_context::basic_executor_type< Allocator, Bits> result_type; };@@ -1311,8 +1098,8 @@ asio::execution::relationship_t::fork_t > {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = false; typedef asio::io_context::basic_executor_type< Allocator, Bits> result_type; };@@ -1323,8 +1110,8 @@ asio::execution::relationship_t::continuation_t > {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = false; typedef asio::io_context::basic_executor_type< Allocator, Bits> result_type; };@@ -1335,8 +1122,8 @@ asio::execution::outstanding_work_t::tracked_t > : asio::detail::io_context_bits {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = false; typedef asio::io_context::basic_executor_type< Allocator, Bits | outstanding_work_tracked> result_type; };@@ -1347,8 +1134,8 @@ asio::execution::outstanding_work_t::untracked_t > : asio::detail::io_context_bits {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = false; typedef asio::io_context::basic_executor_type< Allocator, Bits & ~outstanding_work_tracked> result_type; };@@ -1359,8 +1146,8 @@ asio::execution::allocator_t<void> > {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = false; typedef asio::io_context::basic_executor_type< std::allocator<void>, Bits> result_type; };@@ -1372,8 +1159,8 @@ asio::execution::allocator_t<OtherAllocator> > {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = false; typedef asio::io_context::basic_executor_type< OtherAllocator, Bits> result_type; };@@ -1394,11 +1181,11 @@ >::type > : asio::detail::io_context_bits {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef asio::execution::outstanding_work_t result_type; - static ASIO_CONSTEXPR result_type value() ASIO_NOEXCEPT+ static constexpr result_type value() noexcept { return (Bits & outstanding_work_tracked) ? execution::outstanding_work_t(execution::outstanding_work.tracked)@@ -1418,11 +1205,11 @@ >::type > {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef asio::execution::mapping_t::thread_t result_type; - static ASIO_CONSTEXPR result_type value() ASIO_NOEXCEPT+ static constexpr result_type value() noexcept { return result_type(); }@@ -1444,8 +1231,8 @@ >::type > {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef asio::execution::blocking_t result_type; }; @@ -1461,8 +1248,8 @@ >::type > {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef asio::execution::relationship_t result_type; }; @@ -1472,8 +1259,8 @@ asio::execution::context_t > {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef asio::io_context& result_type; }; @@ -1483,8 +1270,8 @@ asio::execution::allocator_t<void> > {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef Allocator result_type; }; @@ -1494,8 +1281,8 @@ asio::execution::allocator_t<OtherAllocator> > {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -54,19 +54,18 @@ * 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 asio_handler_invoke(a1, &a1) happens-before- * @c asio_handler_invoke(b1, &b1).- * + *+ * then @c a() happens-before @c b()+ * * Note that in the following case: * @code async_op_1(..., s.wrap(a)); * async_op_2(..., s.wrap(b)); @endcode@@ -88,12 +87,6 @@ */ class io_context::strand {-private:-#if !defined(ASIO_NO_DEPRECATED)- struct initiate_dispatch;- struct initiate_post;-#endif // !defined(ASIO_NO_DEPRECATED)- public: /// Constructor. /**@@ -109,6 +102,17 @@ 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.@@ -121,7 +125,7 @@ } /// Obtain the underlying execution context.- asio::io_context& context() const ASIO_NOEXCEPT+ asio::io_context& context() const noexcept { return service_.get_io_context(); }@@ -130,7 +134,7 @@ /** * The strand delegates this call to its underlying io_context. */- void on_work_started() const ASIO_NOEXCEPT+ void on_work_started() const noexcept { context().get_executor().on_work_started(); }@@ -139,7 +143,7 @@ /** * The strand delegates this call to its underlying io_context. */- void on_work_finished() const ASIO_NOEXCEPT+ void on_work_finished() const noexcept { context().get_executor().on_work_finished(); }@@ -160,46 +164,13 @@ * internal storage needed for function invocation. */ template <typename Function, typename Allocator>- void dispatch(ASIO_MOVE_ARG(Function) f, const Allocator& a) const+ void dispatch(Function&& f, const Allocator& a) const {- typename decay<Function>::type tmp(ASIO_MOVE_CAST(Function)(f));+ decay_t<Function> tmp(static_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@@ -214,42 +185,13 @@ * internal storage needed for function invocation. */ template <typename Function, typename Allocator>- void post(ASIO_MOVE_ARG(Function) f, const Allocator& a) const+ void post(Function&& f, const Allocator& a) const {- typename decay<Function>::type tmp(ASIO_MOVE_CAST(Function)(f));+ decay_t<Function> tmp(static_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@@ -264,9 +206,9 @@ * internal storage needed for function invocation. */ template <typename Function, typename Allocator>- void defer(ASIO_MOVE_ARG(Function) f, const Allocator& a) const+ void defer(Function&& f, const Allocator& a) const {- typename decay<Function>::type tmp(ASIO_MOVE_CAST(Function)(f));+ decay_t<Function> tmp(static_cast<Function&&>(f)); service_.post(impl_, tmp); (void)a; }@@ -291,7 +233,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 strand.dispatch(boost::bind(f, a1, ... an)); @endcode+ * @code asio::dispatch(strand, boost::bind(f, a1, ... an)); @endcode */ template <typename Handler> #if defined(GENERATING_DOCUMENTATION)@@ -312,7 +254,7 @@ * submitted to the strand using post(), dispatch() or wrap(). Otherwise * returns @c false. */- bool running_in_this_thread() const ASIO_NOEXCEPT+ bool running_in_this_thread() const noexcept { return service_.running_in_this_thread(impl_); }@@ -322,7 +264,7 @@ * Two strands are equal if they refer to the same ordered, non-concurrent * state. */- friend bool operator==(const strand& a, const strand& b) ASIO_NOEXCEPT+ friend bool operator==(const strand& a, const strand& b) noexcept { return a.impl_ == b.impl_; }@@ -332,48 +274,12 @@ * Two strands are equal if they refer to the same ordered, non-concurrent * state. */- friend bool operator!=(const strand& a, const strand& b) ASIO_NOEXCEPT+ friend bool operator!=(const strand& a, const strand& b) 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
@@ -1,33 +0,0 @@-//-// 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
@@ -1,20 +0,0 @@-//-// 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -16,6 +16,7 @@ #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"@@ -25,10 +26,6 @@ #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)@@ -51,48 +48,44 @@ { public: /// Default constructor.- ASIO_DECL address() ASIO_NOEXCEPT;+ ASIO_DECL address() noexcept; /// Construct an address from an IPv4 address. ASIO_DECL address(- const asio::ip::address_v4& ipv4_address) ASIO_NOEXCEPT;+ const asio::ip::address_v4& ipv4_address) noexcept; /// Construct an address from an IPv6 address. ASIO_DECL address(- const asio::ip::address_v6& ipv6_address) ASIO_NOEXCEPT;+ const asio::ip::address_v6& ipv6_address) noexcept; /// Copy constructor.- ASIO_DECL address(const address& other) ASIO_NOEXCEPT;+ ASIO_DECL address(const address& other) noexcept; -#if defined(ASIO_HAS_MOVE) /// Move constructor.- ASIO_DECL address(address&& other) ASIO_NOEXCEPT;-#endif // defined(ASIO_HAS_MOVE)+ ASIO_DECL address(address&& other) noexcept; /// Assign from another address.- ASIO_DECL address& operator=(const address& other) ASIO_NOEXCEPT;+ ASIO_DECL address& operator=(const address& other) noexcept; -#if defined(ASIO_HAS_MOVE) /// Move-assign from another address.- ASIO_DECL address& operator=(address&& other) ASIO_NOEXCEPT;-#endif // defined(ASIO_HAS_MOVE)+ ASIO_DECL address& operator=(address&& other) noexcept; /// Assign from an IPv4 address. ASIO_DECL address& operator=(- const asio::ip::address_v4& ipv4_address) ASIO_NOEXCEPT;+ const asio::ip::address_v4& ipv4_address) noexcept; /// Assign from an IPv6 address. ASIO_DECL address& operator=(- const asio::ip::address_v6& ipv6_address) ASIO_NOEXCEPT;+ const asio::ip::address_v6& ipv6_address) noexcept; /// Get whether the address is an IP version 4 address.- bool is_v4() const ASIO_NOEXCEPT+ bool is_v4() const noexcept { return type_ == ipv4; } /// Get whether the address is an IP version 6 address.- bool is_v6() const ASIO_NOEXCEPT+ bool is_v6() const noexcept { return type_ == ipv6; }@@ -106,73 +99,47 @@ /// 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 ASIO_NOEXCEPT;+ ASIO_DECL bool is_loopback() const noexcept; /// Determine whether the address is unspecified.- ASIO_DECL bool is_unspecified() const ASIO_NOEXCEPT;+ ASIO_DECL bool is_unspecified() const noexcept; /// Determine whether the address is a multicast address.- ASIO_DECL bool is_multicast() const ASIO_NOEXCEPT;+ ASIO_DECL bool is_multicast() const noexcept; /// Compare two addresses for equality. ASIO_DECL friend bool operator==(const address& a1,- const address& a2) ASIO_NOEXCEPT;+ const address& a2) noexcept; /// Compare two addresses for inequality. friend bool operator!=(const address& a1,- const address& a2) ASIO_NOEXCEPT+ const address& a2) noexcept { return !(a1 == a2); } /// Compare addresses for ordering. ASIO_DECL friend bool operator<(const address& a1,- const address& a2) ASIO_NOEXCEPT;+ const address& a2) noexcept; /// Compare addresses for ordering. friend bool operator>(const address& a1,- const address& a2) ASIO_NOEXCEPT+ const address& a2) noexcept { return a2 < a1; } /// Compare addresses for ordering. friend bool operator<=(const address& a1,- const address& a2) ASIO_NOEXCEPT+ const address& a2) noexcept { return !(a2 < a1); } /// Compare addresses for ordering. friend bool operator>=(const address& a1,- const address& a2) ASIO_NOEXCEPT+ const address& a2) noexcept { return !(a1 < a2); }@@ -201,7 +168,7 @@ * @relates address */ ASIO_DECL address make_address(const char* str,- asio::error_code& ec) ASIO_NOEXCEPT;+ asio::error_code& ec) noexcept; /// Create an address from an IPv4 address string in dotted decimal form, /// or from an IPv6 address in hexadecimal notation.@@ -216,7 +183,7 @@ * @relates address */ ASIO_DECL address make_address(const std::string& str,- asio::error_code& ec) ASIO_NOEXCEPT;+ asio::error_code& ec) noexcept; #if defined(ASIO_HAS_STRING_VIEW) \ || defined(GENERATING_DOCUMENTATION)@@ -234,7 +201,7 @@ * @relates address */ ASIO_DECL address make_address(string_view str,- asio::error_code& ec) ASIO_NOEXCEPT;+ asio::error_code& ec) noexcept; #endif // defined(ASIO_HAS_STRING_VIEW) // || defined(GENERATING_DOCUMENTATION)@@ -262,14 +229,13 @@ } // 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 ASIO_NOEXCEPT+ const noexcept { return addr.is_v4() ? std::hash<asio::ip::address_v4>()(addr.to_v4())@@ -278,7 +244,6 @@ }; } // 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -16,6 +16,7 @@ #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"@@ -24,10 +25,6 @@ #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)@@ -69,7 +66,7 @@ * @li <tt>to_bytes()</tt> yields <tt>{0, 0, 0, 0}</tt>; and * @li <tt>to_uint() == 0</tt>. */- address_v4() ASIO_NOEXCEPT+ address_v4() noexcept { addr_.s_addr = 0; }@@ -92,74 +89,40 @@ ASIO_DECL explicit address_v4(uint_type addr); /// Copy constructor.- address_v4(const address_v4& other) ASIO_NOEXCEPT+ address_v4(const address_v4& other) noexcept : addr_(other.addr_) { } -#if defined(ASIO_HAS_MOVE) /// Move constructor.- address_v4(address_v4&& other) ASIO_NOEXCEPT+ address_v4(address_v4&& other) noexcept : addr_(other.addr_) { }-#endif // defined(ASIO_HAS_MOVE) /// Assign from another address.- address_v4& operator=(const address_v4& other) ASIO_NOEXCEPT+ address_v4& operator=(const address_v4& other) noexcept { addr_ = other.addr_; return *this; } -#if defined(ASIO_HAS_MOVE) /// Move-assign from another address.- address_v4& operator=(address_v4&& other) ASIO_NOEXCEPT+ address_v4& operator=(address_v4&& other) 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 ASIO_NOEXCEPT;+ ASIO_DECL bytes_type to_bytes() const noexcept; /// Get the address as an unsigned integer in host byte order.- 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)+ ASIO_DECL uint_type to_uint() const noexcept; /// 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@@ -168,7 +131,7 @@ * * @returns <tt>(to_uint() & 0xFF000000) == 0x7F000000</tt>. */- ASIO_DECL bool is_loopback() const ASIO_NOEXCEPT;+ ASIO_DECL bool is_loopback() const noexcept; /// Determine whether the address is unspecified. /**@@ -177,21 +140,7 @@ * * @returns <tt>to_uint() == 0</tt>. */- 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)+ ASIO_DECL bool is_unspecified() const noexcept; /// Determine whether the address is a multicast address. /**@@ -201,18 +150,18 @@ * * @returns <tt>(to_uint() & 0xF0000000) == 0xE0000000</tt>. */- ASIO_DECL bool is_multicast() const ASIO_NOEXCEPT;+ ASIO_DECL bool is_multicast() const noexcept; /// Compare two addresses for equality. friend bool operator==(const address_v4& a1,- const address_v4& a2) ASIO_NOEXCEPT+ const address_v4& a2) 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) ASIO_NOEXCEPT+ const address_v4& a2) noexcept { return a1.addr_.s_addr != a2.addr_.s_addr; }@@ -224,7 +173,7 @@ * @returns <tt>a1.to_uint() < a2.to_uint()</tt>. */ friend bool operator<(const address_v4& a1,- const address_v4& a2) ASIO_NOEXCEPT+ const address_v4& a2) noexcept { return a1.to_uint() < a2.to_uint(); }@@ -236,7 +185,7 @@ * @returns <tt>a1.to_uint() > a2.to_uint()</tt>. */ friend bool operator>(const address_v4& a1,- const address_v4& a2) ASIO_NOEXCEPT+ const address_v4& a2) noexcept { return a1.to_uint() > a2.to_uint(); }@@ -248,7 +197,7 @@ * @returns <tt>a1.to_uint() <= a2.to_uint()</tt>. */ friend bool operator<=(const address_v4& a1,- const address_v4& a2) ASIO_NOEXCEPT+ const address_v4& a2) noexcept { return a1.to_uint() <= a2.to_uint(); }@@ -260,7 +209,7 @@ * @returns <tt>a1.to_uint() >= a2.to_uint()</tt>. */ friend bool operator>=(const address_v4& a1,- const address_v4& a2) ASIO_NOEXCEPT+ const address_v4& a2) noexcept { return a1.to_uint() >= a2.to_uint(); }@@ -272,7 +221,7 @@ * * @returns A default-constructed @c address_v4 object. */- static address_v4 any() ASIO_NOEXCEPT+ static address_v4 any() noexcept { return address_v4(); }@@ -284,7 +233,7 @@ * * @returns <tt>address_v4(0x7F000001)</tt>. */- static address_v4 loopback() ASIO_NOEXCEPT+ static address_v4 loopback() noexcept { return address_v4(0x7F000001); }@@ -296,23 +245,11 @@ * * @returns <tt>address_v4(0xFFFFFFFF)</tt>. */- static address_v4 broadcast() ASIO_NOEXCEPT+ static address_v4 broadcast() 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_;@@ -347,7 +284,7 @@ * @relates address_v4 */ ASIO_DECL address_v4 make_address_v4(const char* str,- asio::error_code& ec) ASIO_NOEXCEPT;+ asio::error_code& ec) noexcept; /// Create an IPv4 address from an IP address string in dotted decimal form. /**@@ -360,7 +297,7 @@ * @relates address_v4 */ ASIO_DECL address_v4 make_address_v4(const std::string& str,- asio::error_code& ec) ASIO_NOEXCEPT;+ asio::error_code& ec) noexcept; #if defined(ASIO_HAS_STRING_VIEW) \ || defined(GENERATING_DOCUMENTATION)@@ -376,7 +313,7 @@ * @relates address_v4 */ ASIO_DECL address_v4 make_address_v4(string_view str,- asio::error_code& ec) ASIO_NOEXCEPT;+ asio::error_code& ec) noexcept; #endif // defined(ASIO_HAS_STRING_VIEW) // || defined(GENERATING_DOCUMENTATION)@@ -404,21 +341,19 @@ } // 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 ASIO_NOEXCEPT+ const 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -53,65 +53,59 @@ typedef std::input_iterator_tag iterator_category; /// Construct an iterator that points to the specified address.- basic_address_iterator(const address_v4& addr) ASIO_NOEXCEPT+ basic_address_iterator(const address_v4& addr) noexcept : address_(addr) { } /// Copy constructor.- basic_address_iterator(- const basic_address_iterator& other) ASIO_NOEXCEPT+ basic_address_iterator(const basic_address_iterator& other) noexcept : address_(other.address_) { } -#if defined(ASIO_HAS_MOVE) /// Move constructor.- basic_address_iterator(basic_address_iterator&& other) ASIO_NOEXCEPT- : address_(ASIO_MOVE_CAST(address_v4)(other.address_))+ basic_address_iterator(basic_address_iterator&& other) noexcept+ : address_(static_cast<address_v4&&>(other.address_)) { }-#endif // defined(ASIO_HAS_MOVE) /// Assignment operator. basic_address_iterator& operator=(- const basic_address_iterator& other) ASIO_NOEXCEPT+ const basic_address_iterator& other) noexcept { address_ = other.address_; return *this; } -#if defined(ASIO_HAS_MOVE) /// Move assignment operator.- basic_address_iterator& operator=(- basic_address_iterator&& other) ASIO_NOEXCEPT+ basic_address_iterator& operator=(basic_address_iterator&& other) noexcept {- address_ = ASIO_MOVE_CAST(address_v4)(other.address_);+ address_ = static_cast<address_v4&&>(other.address_); return *this; }-#endif // defined(ASIO_HAS_MOVE) /// Dereference the iterator.- const address_v4& operator*() const ASIO_NOEXCEPT+ const address_v4& operator*() const noexcept { return address_; } /// Dereference the iterator.- const address_v4* operator->() const ASIO_NOEXCEPT+ const address_v4* operator->() const noexcept { return &address_; } /// Pre-increment operator.- basic_address_iterator& operator++() ASIO_NOEXCEPT+ basic_address_iterator& operator++() noexcept { address_ = address_v4((address_.to_uint() + 1) & 0xFFFFFFFF); return *this; } /// Post-increment operator.- basic_address_iterator operator++(int) ASIO_NOEXCEPT+ basic_address_iterator operator++(int) noexcept { basic_address_iterator tmp(*this); ++*this;@@ -119,7 +113,7 @@ } /// Pre-decrement operator.- basic_address_iterator& operator--() ASIO_NOEXCEPT+ basic_address_iterator& operator--() 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -38,7 +38,7 @@ typedef basic_address_iterator<address_v4> iterator; /// Construct an empty range.- basic_address_range() ASIO_NOEXCEPT+ basic_address_range() noexcept : begin_(address_v4()), end_(address_v4()) {@@ -46,74 +46,68 @@ /// Construct an range that represents the given range of addresses. explicit basic_address_range(const iterator& first,- const iterator& last) ASIO_NOEXCEPT+ const iterator& last) noexcept : begin_(first), end_(last) { } /// Copy constructor.- basic_address_range(const basic_address_range& other) ASIO_NOEXCEPT+ basic_address_range(const basic_address_range& other) noexcept : begin_(other.begin_), end_(other.end_) { } -#if defined(ASIO_HAS_MOVE) /// Move constructor.- basic_address_range(basic_address_range&& other) ASIO_NOEXCEPT- : begin_(ASIO_MOVE_CAST(iterator)(other.begin_)),- end_(ASIO_MOVE_CAST(iterator)(other.end_))+ basic_address_range(basic_address_range&& other) noexcept+ : begin_(static_cast<iterator&&>(other.begin_)),+ end_(static_cast<iterator&&>(other.end_)) { }-#endif // defined(ASIO_HAS_MOVE) /// Assignment operator.- basic_address_range& operator=(- const basic_address_range& other) ASIO_NOEXCEPT+ basic_address_range& operator=(const basic_address_range& other) 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) ASIO_NOEXCEPT+ basic_address_range& operator=(basic_address_range&& other) noexcept {- begin_ = ASIO_MOVE_CAST(iterator)(other.begin_);- end_ = ASIO_MOVE_CAST(iterator)(other.end_);+ begin_ = static_cast<iterator&&>(other.begin_);+ end_ = static_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 ASIO_NOEXCEPT+ iterator begin() const noexcept { return begin_; } /// Obtain an iterator that points to the end of the range.- iterator end() const ASIO_NOEXCEPT+ iterator end() const noexcept { return end_; } /// Determine whether the range is empty.- bool empty() const ASIO_NOEXCEPT+ bool empty() const noexcept { return size() == 0; } /// Return the size of the range.- std::size_t size() const ASIO_NOEXCEPT+ std::size_t size() const noexcept { return end_->to_uint() - begin_->to_uint(); } /// Find an address in the range.- iterator find(const address_v4& addr) const ASIO_NOEXCEPT+ iterator find(const address_v4& addr) const 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -16,6 +16,7 @@ #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,10 +26,6 @@ #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)@@ -72,7 +69,7 @@ * @li <tt>to_bytes()</tt> yields <tt>{0, 0, ..., 0}</tt>; and * @li <tt>scope_id() == 0</tt>. */- ASIO_DECL address_v6() ASIO_NOEXCEPT;+ ASIO_DECL address_v6() noexcept; /// Construct an address from raw bytes and scope ID. /**@@ -88,27 +85,23 @@ scope_id_type scope_id = 0); /// Copy constructor.- ASIO_DECL address_v6(const address_v6& other) ASIO_NOEXCEPT;+ ASIO_DECL address_v6(const address_v6& other) noexcept; -#if defined(ASIO_HAS_MOVE) /// Move constructor.- ASIO_DECL address_v6(address_v6&& other) ASIO_NOEXCEPT;-#endif // defined(ASIO_HAS_MOVE)+ ASIO_DECL address_v6(address_v6&& other) noexcept; /// Assign from another address. ASIO_DECL address_v6& operator=(- const address_v6& other) ASIO_NOEXCEPT;+ const address_v6& other) noexcept; -#if defined(ASIO_HAS_MOVE) /// Move-assign from another address.- ASIO_DECL address_v6& operator=(address_v6&& other) ASIO_NOEXCEPT;-#endif // defined(ASIO_HAS_MOVE)+ ASIO_DECL address_v6& operator=(address_v6&& other) noexcept; /// The scope ID of the address. /** * Returns the scope ID associated with the IPv6 address. */- scope_id_type scope_id() const ASIO_NOEXCEPT+ scope_id_type scope_id() const noexcept { return scope_id_; }@@ -119,123 +112,90 @@ * * @param id The new scope ID. */- void scope_id(scope_id_type id) ASIO_NOEXCEPT+ void scope_id(scope_id_type id) noexcept { scope_id_ = id; } /// Get the address in bytes, in network byte order.- ASIO_DECL bytes_type to_bytes() const ASIO_NOEXCEPT;+ ASIO_DECL bytes_type to_bytes() const 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 ASIO_NOEXCEPT;+ ASIO_DECL bool is_loopback() const 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 ASIO_NOEXCEPT;+ ASIO_DECL bool is_unspecified() const noexcept; /// Determine whether the address is link local.- ASIO_DECL bool is_link_local() const ASIO_NOEXCEPT;+ ASIO_DECL bool is_link_local() const noexcept; /// Determine whether the address is site local.- ASIO_DECL bool is_site_local() const ASIO_NOEXCEPT;+ ASIO_DECL bool is_site_local() const noexcept; /// Determine whether the address is a mapped IPv4 address.- 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)+ ASIO_DECL bool is_v4_mapped() const noexcept; /// Determine whether the address is a multicast address.- ASIO_DECL bool is_multicast() const ASIO_NOEXCEPT;+ ASIO_DECL bool is_multicast() const noexcept; /// Determine whether the address is a global multicast address.- ASIO_DECL bool is_multicast_global() const ASIO_NOEXCEPT;+ ASIO_DECL bool is_multicast_global() const noexcept; /// Determine whether the address is a link-local multicast address.- ASIO_DECL bool is_multicast_link_local() const ASIO_NOEXCEPT;+ ASIO_DECL bool is_multicast_link_local() const noexcept; /// Determine whether the address is a node-local multicast address.- ASIO_DECL bool is_multicast_node_local() const ASIO_NOEXCEPT;+ ASIO_DECL bool is_multicast_node_local() const noexcept; /// Determine whether the address is a org-local multicast address.- ASIO_DECL bool is_multicast_org_local() const ASIO_NOEXCEPT;+ ASIO_DECL bool is_multicast_org_local() const noexcept; /// Determine whether the address is a site-local multicast address.- ASIO_DECL bool is_multicast_site_local() const ASIO_NOEXCEPT;+ ASIO_DECL bool is_multicast_site_local() const noexcept; /// Compare two addresses for equality. ASIO_DECL friend bool operator==(const address_v6& a1,- const address_v6& a2) ASIO_NOEXCEPT;+ const address_v6& a2) noexcept; /// Compare two addresses for inequality. friend bool operator!=(const address_v6& a1,- const address_v6& a2) ASIO_NOEXCEPT+ const address_v6& a2) noexcept { return !(a1 == a2); } /// Compare addresses for ordering. ASIO_DECL friend bool operator<(const address_v6& a1,- const address_v6& a2) ASIO_NOEXCEPT;+ const address_v6& a2) noexcept; /// Compare addresses for ordering. friend bool operator>(const address_v6& a1,- const address_v6& a2) ASIO_NOEXCEPT+ const address_v6& a2) noexcept { return a2 < a1; } /// Compare addresses for ordering. friend bool operator<=(const address_v6& a1,- const address_v6& a2) ASIO_NOEXCEPT+ const address_v6& a2) noexcept { return !(a2 < a1); } /// Compare addresses for ordering. friend bool operator>=(const address_v6& a1,- const address_v6& a2) ASIO_NOEXCEPT+ const address_v6& a2) noexcept { return !(a1 < a2); }@@ -247,7 +207,7 @@ * * @returns A default-constructed @c address_v6 object. */- static address_v6 any() ASIO_NOEXCEPT+ static address_v6 any() noexcept { return address_v6(); }@@ -257,15 +217,7 @@ * This function returns an address that represents the well-known loopback * address <tt>::1</tt>. */- 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)+ ASIO_DECL static address_v6 loopback() noexcept; private: friend class basic_address_iterator<address_v6>;@@ -298,7 +250,7 @@ * @relates address_v6 */ ASIO_DECL address_v6 make_address_v6(const char* str,- asio::error_code& ec) ASIO_NOEXCEPT;+ asio::error_code& ec) noexcept; /// Createan IPv6 address from an IP address string. /**@@ -311,7 +263,7 @@ * @relates address_v6 */ ASIO_DECL address_v6 make_address_v6(const std::string& str,- asio::error_code& ec) ASIO_NOEXCEPT;+ asio::error_code& ec) noexcept; #if defined(ASIO_HAS_STRING_VIEW) \ || defined(GENERATING_DOCUMENTATION)@@ -327,7 +279,7 @@ * @relates address_v6 */ ASIO_DECL address_v6 make_address_v6(string_view str,- asio::error_code& ec) ASIO_NOEXCEPT;+ asio::error_code& ec) noexcept; #endif // defined(ASIO_HAS_STRING_VIEW) // || defined(GENERATING_DOCUMENTATION)@@ -373,14 +325,13 @@ } // 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 ASIO_NOEXCEPT+ const noexcept { const asio::ip::address_v6::bytes_type bytes = addr.to_bytes(); std::size_t result = static_cast<std::size_t>(addr.scope_id());@@ -404,7 +355,6 @@ }; } // 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2025 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,58 +54,53 @@ typedef std::input_iterator_tag iterator_category; /// Construct an iterator that points to the specified address.- basic_address_iterator(const address_v6& addr) ASIO_NOEXCEPT+ basic_address_iterator(const address_v6& addr) noexcept : address_(addr) { } /// Copy constructor. basic_address_iterator(- const basic_address_iterator& other) ASIO_NOEXCEPT+ const basic_address_iterator& other) noexcept : address_(other.address_) { } -#if defined(ASIO_HAS_MOVE) /// Move constructor.- basic_address_iterator(basic_address_iterator&& other) ASIO_NOEXCEPT- : address_(ASIO_MOVE_CAST(address_v6)(other.address_))+ basic_address_iterator(basic_address_iterator&& other) noexcept+ : address_(static_cast<address_v6&&>(other.address_)) { }-#endif // defined(ASIO_HAS_MOVE) /// Assignment operator. basic_address_iterator& operator=(- const basic_address_iterator& other) ASIO_NOEXCEPT+ const basic_address_iterator& other) noexcept { address_ = other.address_; return *this; } -#if defined(ASIO_HAS_MOVE) /// Move assignment operator.- basic_address_iterator& operator=(- basic_address_iterator&& other) ASIO_NOEXCEPT+ basic_address_iterator& operator=(basic_address_iterator&& other) noexcept {- address_ = ASIO_MOVE_CAST(address_v6)(other.address_);+ address_ = static_cast<address_v6&&>(other.address_); return *this; }-#endif // defined(ASIO_HAS_MOVE) /// Dereference the iterator.- const address_v6& operator*() const ASIO_NOEXCEPT+ const address_v6& operator*() const noexcept { return address_; } /// Dereference the iterator.- const address_v6* operator->() const ASIO_NOEXCEPT+ const address_v6* operator->() const noexcept { return &address_; } /// Pre-increment operator.- basic_address_iterator& operator++() ASIO_NOEXCEPT+ basic_address_iterator& operator++() noexcept { for (int i = 15; i >= 0; --i) {@@ -122,7 +117,7 @@ } /// Post-increment operator.- basic_address_iterator operator++(int) ASIO_NOEXCEPT+ basic_address_iterator operator++(int) noexcept { basic_address_iterator tmp(*this); ++*this;@@ -130,7 +125,7 @@ } /// Pre-decrement operator.- basic_address_iterator& operator--() ASIO_NOEXCEPT+ basic_address_iterator& operator--() 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2025 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() ASIO_NOEXCEPT+ basic_address_range() noexcept : begin_(address_v6()), end_(address_v6()) {@@ -47,68 +47,63 @@ /// Construct an range that represents the given range of addresses. explicit basic_address_range(const iterator& first,- const iterator& last) ASIO_NOEXCEPT+ const iterator& last) noexcept : begin_(first), end_(last) { } /// Copy constructor.- basic_address_range(const basic_address_range& other) ASIO_NOEXCEPT+ basic_address_range(const basic_address_range& other) noexcept : begin_(other.begin_), end_(other.end_) { } -#if defined(ASIO_HAS_MOVE) /// Move constructor.- basic_address_range(basic_address_range&& other) ASIO_NOEXCEPT- : begin_(ASIO_MOVE_CAST(iterator)(other.begin_)),- end_(ASIO_MOVE_CAST(iterator)(other.end_))+ basic_address_range(basic_address_range&& other) noexcept+ : begin_(static_cast<iterator&&>(other.begin_)),+ end_(static_cast<iterator&&>(other.end_)) { }-#endif // defined(ASIO_HAS_MOVE) /// Assignment operator. basic_address_range& operator=(- const basic_address_range& other) ASIO_NOEXCEPT+ const basic_address_range& other) 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) ASIO_NOEXCEPT+ basic_address_range& operator=(basic_address_range&& other) noexcept {- begin_ = ASIO_MOVE_CAST(iterator)(other.begin_);- end_ = ASIO_MOVE_CAST(iterator)(other.end_);+ begin_ = static_cast<iterator&&>(other.begin_);+ end_ = static_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 ASIO_NOEXCEPT+ iterator begin() const noexcept { return begin_; } /// Obtain an iterator that points to the end of the range.- iterator end() const ASIO_NOEXCEPT+ iterator end() const noexcept { return end_; } /// Determine whether the range is empty.- bool empty() const ASIO_NOEXCEPT+ bool empty() const noexcept { return begin_ == end_; } /// Find an address in the range.- iterator find(const address_v6& addr) const ASIO_NOEXCEPT+ iterator find(const address_v6& addr) const 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -35,11 +35,21 @@ /// 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() ASIO_NOEXCEPT_OR_NOTHROW {}+ virtual ~bad_address_cast() noexcept {} /// Get the message associated with the exception.- virtual const char* what() const ASIO_NOEXCEPT_OR_NOTHROW+ virtual const char* what() const noexcept { 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -16,14 +16,11 @@ #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)@@ -64,7 +61,7 @@ #endif /// Default constructor.- basic_endpoint() ASIO_NOEXCEPT+ basic_endpoint() noexcept : impl_() { }@@ -86,7 +83,7 @@ * @endcode */ basic_endpoint(const InternetProtocol& internet_protocol,- port_type port_num) ASIO_NOEXCEPT+ port_type port_num) noexcept : impl_(internet_protocol.family(), port_num) { }@@ -95,43 +92,39 @@ /// 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) ASIO_NOEXCEPT+ port_type port_num) noexcept : impl_(addr, port_num) { } /// Copy constructor.- basic_endpoint(const basic_endpoint& other) ASIO_NOEXCEPT+ basic_endpoint(const basic_endpoint& other) noexcept : impl_(other.impl_) { } -#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move constructor.- basic_endpoint(basic_endpoint&& other) ASIO_NOEXCEPT+ basic_endpoint(basic_endpoint&& other) noexcept : impl_(other.impl_) { }-#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Assign from another endpoint.- basic_endpoint& operator=(const basic_endpoint& other) ASIO_NOEXCEPT+ basic_endpoint& operator=(const basic_endpoint& other) 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) ASIO_NOEXCEPT+ basic_endpoint& operator=(basic_endpoint&& other) noexcept { impl_ = other.impl_; return *this; }-#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// The protocol associated with the endpoint.- protocol_type protocol() const ASIO_NOEXCEPT+ protocol_type protocol() const noexcept { if (impl_.is_v4()) return InternetProtocol::v4();@@ -139,19 +132,19 @@ } /// Get the underlying endpoint in the native type.- data_type* data() ASIO_NOEXCEPT+ data_type* data() noexcept { return impl_.data(); } /// Get the underlying endpoint in the native type.- const data_type* data() const ASIO_NOEXCEPT+ const data_type* data() const noexcept { return impl_.data(); } /// Get the underlying size of the endpoint in the native type.- std::size_t size() const ASIO_NOEXCEPT+ std::size_t size() const noexcept { return impl_.size(); }@@ -163,75 +156,75 @@ } /// Get the capacity of the endpoint in the native type.- std::size_t capacity() const ASIO_NOEXCEPT+ std::size_t capacity() const 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 ASIO_NOEXCEPT+ port_type port() const 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) ASIO_NOEXCEPT+ void port(port_type port_num) noexcept { impl_.port(port_num); } /// Get the IP address associated with the endpoint.- asio::ip::address address() const ASIO_NOEXCEPT+ asio::ip::address address() const noexcept { return impl_.address(); } /// Set the IP address associated with the endpoint.- void address(const asio::ip::address& addr) ASIO_NOEXCEPT+ void address(const asio::ip::address& addr) noexcept { impl_.address(addr); } /// Compare two endpoints for equality. friend bool operator==(const basic_endpoint<InternetProtocol>& e1,- const basic_endpoint<InternetProtocol>& e2) ASIO_NOEXCEPT+ const basic_endpoint<InternetProtocol>& e2) noexcept { return e1.impl_ == e2.impl_; } /// Compare two endpoints for inequality. friend bool operator!=(const basic_endpoint<InternetProtocol>& e1,- const basic_endpoint<InternetProtocol>& e2) ASIO_NOEXCEPT+ const basic_endpoint<InternetProtocol>& e2) noexcept { return !(e1 == e2); } /// Compare endpoints for ordering. friend bool operator<(const basic_endpoint<InternetProtocol>& e1,- const basic_endpoint<InternetProtocol>& e2) ASIO_NOEXCEPT+ const basic_endpoint<InternetProtocol>& e2) noexcept { return e1.impl_ < e2.impl_; } /// Compare endpoints for ordering. friend bool operator>(const basic_endpoint<InternetProtocol>& e1,- const basic_endpoint<InternetProtocol>& e2) ASIO_NOEXCEPT+ const basic_endpoint<InternetProtocol>& e2) noexcept { return e2.impl_ < e1.impl_; } /// Compare endpoints for ordering. friend bool operator<=(const basic_endpoint<InternetProtocol>& e1,- const basic_endpoint<InternetProtocol>& e2) ASIO_NOEXCEPT+ const basic_endpoint<InternetProtocol>& e2) noexcept { return !(e2 < e1); } /// Compare endpoints for ordering. friend bool operator>=(const basic_endpoint<InternetProtocol>& e1,- const basic_endpoint<InternetProtocol>& e2) ASIO_NOEXCEPT+ const basic_endpoint<InternetProtocol>& e2) noexcept { return !(e1 < e2); }@@ -265,15 +258,14 @@ } // 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 ASIO_NOEXCEPT+ const noexcept { std::size_t hash1 = std::hash<asio::ip::address>()(ep.address()); std::size_t hash2 = std::hash<unsigned short>()(ep.port());@@ -282,7 +274,6 @@ }; } // 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -17,6 +17,7 @@ #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"@@ -36,10 +37,6 @@ # 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 {@@ -88,14 +85,6 @@ /// 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; @@ -122,14 +111,13 @@ */ template <typename ExecutionContext> explicit basic_resolver(ExecutionContext& context,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value- >::type = 0)+ > = 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.@@ -161,9 +149,9 @@ */ template <typename Executor1> basic_resolver(basic_resolver<InternetProtocol, Executor1>&& other,- typename constraint<+ constraint_t< is_convertible<Executor1, Executor>::value- >::type = 0)+ > = 0) : impl_(std::move(other.impl_)) { }@@ -199,16 +187,15 @@ * constructed using the @c basic_resolver(const executor_type&) constructor. */ template <typename Executor1>- typename constraint<+ constraint_t< is_convertible<Executor1, Executor>::value, basic_resolver&- >::type operator=(basic_resolver<InternetProtocol, Executor1>&& other)+ > 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. /**@@ -221,7 +208,7 @@ } /// Get the executor associated with the object.- executor_type get_executor() ASIO_NOEXCEPT+ executor_type get_executor() noexcept { return impl_.get_executor(); }@@ -237,50 +224,8 @@ 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. *@@ -645,58 +590,8 @@ 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. *@@ -723,7 +618,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::post().+ * manner equivalent to using asio::async_immediate(). * * A successful resolve operation is guaranteed to pass a non-empty range to * the handler.@@ -744,22 +639,18 @@ */ 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(ASIO_STRING_VIEW_PARAM host,+ results_type)) ResolveToken = default_completion_token_t<executor_type>>+ auto async_resolve(ASIO_STRING_VIEW_PARAM host, ASIO_STRING_VIEW_PARAM service,- ASIO_MOVE_ARG(ResolveToken) token- ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ ResolveToken&& token = default_completion_token_t<executor_type>())+ -> decltype( 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(),- ASIO_MOVE_CAST(ResolveToken)(token));+ static_cast<ResolveToken&&>(token)); } /// Asynchronously perform forward resolution of a query to a list of entries.@@ -796,7 +687,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::post().+ * manner equivalent to using asio::async_immediate(). * * A successful resolve operation is guaranteed to pass a non-empty range to * the handler.@@ -817,20 +708,15 @@ */ 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(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((+ 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( 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);@@ -872,7 +758,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::post().+ * manner equivalent to using asio::async_immediate(). * * A successful resolve operation is guaranteed to pass a non-empty range to * the handler.@@ -893,22 +779,18 @@ */ 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 protocol_type& protocol,+ results_type)) ResolveToken = default_completion_token_t<executor_type>>+ auto async_resolve(const protocol_type& protocol, ASIO_STRING_VIEW_PARAM host, ASIO_STRING_VIEW_PARAM service,- ASIO_MOVE_ARG(ResolveToken) token- ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ ResolveToken&& token = default_completion_token_t<executor_type>())+ -> decltype( 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(),- ASIO_MOVE_CAST(ResolveToken)(token));+ static_cast<ResolveToken&&>(token)); } /// Asynchronously perform forward resolution of a query to a list of entries.@@ -948,7 +830,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::post().+ * manner equivalent to using asio::async_immediate(). * * A successful resolve operation is guaranteed to pass a non-empty range to * the handler.@@ -969,20 +851,16 @@ */ 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 protocol_type& protocol,+ results_type)) ResolveToken = default_completion_token_t<executor_type>>+ auto async_resolve(const protocol_type& protocol, 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((+ ResolveToken&& token = default_completion_token_t<executor_type>())+ -> decltype( 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),@@ -1057,7 +935,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::post().+ * manner equivalent to using asio::async_immediate(). * * A successful resolve operation is guaranteed to pass a non-empty range to * the handler.@@ -1067,17 +945,13 @@ */ 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 endpoint_type& e,- ASIO_MOVE_ARG(ResolveToken) token- ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ 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( 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)>(@@ -1086,8 +960,8 @@ private: // Disallow copying and assignment.- basic_resolver(const basic_resolver&) ASIO_DELETED;- basic_resolver& operator=(const basic_resolver&) ASIO_DELETED;+ basic_resolver(const basic_resolver&) = delete;+ basic_resolver& operator=(const basic_resolver&) = delete; class initiate_async_resolve {@@ -1099,13 +973,13 @@ { } - executor_type get_executor() const ASIO_NOEXCEPT+ executor_type get_executor() const noexcept { return self_->get_executor(); } template <typename ResolveHandler, typename Query>- void operator()(ASIO_MOVE_ARG(ResolveHandler) handler,+ void operator()(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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -79,15 +79,13 @@ { } -#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move constructor. basic_resolver_iterator(basic_resolver_iterator&& other)- : values_(ASIO_MOVE_CAST(values_ptr_type)(other.values_)),+ : values_(static_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)@@ -97,20 +95,18 @@ 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_ = ASIO_MOVE_CAST(values_ptr_type)(other.values_);+ values_ = static_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@@ -178,7 +174,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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -210,6 +210,22 @@ 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -48,11 +48,7 @@ */ 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.@@ -93,14 +89,12 @@ { } -#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move constructor. basic_resolver_results(basic_resolver_results&& other) : basic_resolver_iterator<InternetProtocol>(- ASIO_MOVE_CAST(basic_resolver_results)(other))+ static_cast<basic_resolver_results&&>(other)) { }-#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Assignment operator. basic_resolver_results& operator=(const basic_resolver_results& other)@@ -109,15 +103,13 @@ 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=(- ASIO_MOVE_CAST(basic_resolver_results)(other));+ static_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.@@ -230,19 +222,19 @@ #endif // !defined(GENERATING_DOCUMENTATION) /// Get the number of entries in the results range.- size_type size() const ASIO_NOEXCEPT+ size_type size() const noexcept { return this->values_ ? this->values_->size() : 0; } /// Get the maximum number of entries permitted in a results range.- size_type max_size() const ASIO_NOEXCEPT+ size_type max_size() const noexcept { return this->values_ ? this->values_->max_size() : values_type().max_size(); } /// Determine whether the results range is empty.- bool empty() const ASIO_NOEXCEPT+ bool empty() const noexcept { return this->values_ ? this->values_->empty() : true; }@@ -252,7 +244,7 @@ { basic_resolver_results tmp(*this); tmp.index_ = 0;- return ASIO_MOVE_CAST(basic_resolver_results)(tmp);+ return static_cast<basic_resolver_results&&>(tmp); } /// Obtain an end iterator for the results range.@@ -274,7 +266,7 @@ } /// Swap the results range with another.- void swap(basic_resolver_results& that) ASIO_NOEXCEPT+ void swap(basic_resolver_results& that) noexcept { if (this != &that) {@@ -300,7 +292,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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -28,48 +28,48 @@ namespace ip { namespace detail { -// Helper class for implementating an IP endpoint.+// Helper class for implementing an IP endpoint. class endpoint { public: // Default constructor.- ASIO_DECL endpoint() ASIO_NOEXCEPT;+ ASIO_DECL endpoint() noexcept; // Construct an endpoint using a family and port number. ASIO_DECL endpoint(int family,- unsigned short port_num) ASIO_NOEXCEPT;+ unsigned short port_num) noexcept; // Construct an endpoint using an address and port number. ASIO_DECL endpoint(const asio::ip::address& addr,- unsigned short port_num) ASIO_NOEXCEPT;+ unsigned short port_num) noexcept; // Copy constructor.- endpoint(const endpoint& other) ASIO_NOEXCEPT+ endpoint(const endpoint& other) noexcept : data_(other.data_) { } // Assign from another endpoint.- endpoint& operator=(const endpoint& other) ASIO_NOEXCEPT+ endpoint& operator=(const endpoint& other) noexcept { data_ = other.data_; return *this; } // Get the underlying endpoint in the native type.- asio::detail::socket_addr_type* data() ASIO_NOEXCEPT+ asio::detail::socket_addr_type* data() noexcept {- return &data_.base;+ return &data_.base[0]; } // Get the underlying endpoint in the native type.- const asio::detail::socket_addr_type* data() const ASIO_NOEXCEPT+ const asio::detail::socket_addr_type* data() const noexcept {- return &data_.base;+ return &data_.base[0]; } // Get the underlying size of the endpoint in the native type.- std::size_t size() const ASIO_NOEXCEPT+ std::size_t size() const 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 ASIO_NOEXCEPT+ std::size_t capacity() const noexcept { return sizeof(data_); } // Get the port associated with the endpoint.- ASIO_DECL unsigned short port() const ASIO_NOEXCEPT;+ ASIO_DECL unsigned short port() const noexcept; // Set the port associated with the endpoint.- ASIO_DECL void port(unsigned short port_num) ASIO_NOEXCEPT;+ ASIO_DECL void port(unsigned short port_num) noexcept; // Get the IP address associated with the endpoint.- ASIO_DECL asio::ip::address address() const ASIO_NOEXCEPT;+ ASIO_DECL asio::ip::address address() const noexcept; // Set the IP address associated with the endpoint. ASIO_DECL void address(- const asio::ip::address& addr) ASIO_NOEXCEPT;+ const asio::ip::address& addr) noexcept; // Compare two endpoints for equality. ASIO_DECL friend bool operator==(const endpoint& e1,- const endpoint& e2) ASIO_NOEXCEPT;+ const endpoint& e2) noexcept; // Compare endpoints for ordering. ASIO_DECL friend bool operator<(const endpoint& e1,- const endpoint& e2) ASIO_NOEXCEPT;+ const endpoint& e2) noexcept; // Determine whether the endpoint is IPv4.- bool is_v4() const ASIO_NOEXCEPT+ bool is_v4() const noexcept {- return data_.base.sa_family == ASIO_OS_DEF(AF_INET);+ return data_.base[0].sa_family == ASIO_OS_DEF(AF_INET); } #if !defined(ASIO_NO_IOSTREAM)@@ -122,7 +122,11 @@ // The underlying IP socket address. union data_union {- asio::detail::socket_addr_type base;+#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::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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -31,7 +31,7 @@ namespace ip { namespace detail { -endpoint::endpoint() ASIO_NOEXCEPT+endpoint::endpoint() 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) ASIO_NOEXCEPT+endpoint::endpoint(int family, unsigned short port_num) noexcept : data_() { using namespace std; // For memcpy.@@ -69,7 +69,7 @@ } endpoint::endpoint(const asio::ip::address& addr,- unsigned short port_num) ASIO_NOEXCEPT+ unsigned short port_num) noexcept : data_() { using namespace std; // For memcpy.@@ -106,7 +106,7 @@ } } -unsigned short endpoint::port() const ASIO_NOEXCEPT+unsigned short endpoint::port() const noexcept { if (is_v4()) {@@ -120,7 +120,7 @@ } } -void endpoint::port(unsigned short port_num) ASIO_NOEXCEPT+void endpoint::port(unsigned short port_num) noexcept { if (is_v4()) {@@ -134,7 +134,7 @@ } } -asio::ip::address endpoint::address() const ASIO_NOEXCEPT+asio::ip::address endpoint::address() const noexcept { using namespace std; // For memcpy. if (is_v4())@@ -146,27 +146,23 @@ 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) ASIO_NOEXCEPT+void endpoint::address(const asio::ip::address& addr) noexcept { endpoint tmp_endpoint(addr, port()); data_ = tmp_endpoint.data_; } -bool operator==(const endpoint& e1, const endpoint& e2) ASIO_NOEXCEPT+bool operator==(const endpoint& e1, const endpoint& e2) noexcept { return e1.address() == e2.address() && e1.port() == e2.port(); } -bool operator<(const endpoint& e1, const endpoint& e2) ASIO_NOEXCEPT+bool operator<(const endpoint& e1, const endpoint& e2) 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/ip/icmp.hpp view
@@ -2,7 +2,7 @@ // ip/icmp.hpp // ~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -46,33 +46,33 @@ typedef basic_endpoint<icmp> endpoint; /// Construct to represent the IPv4 ICMP protocol.- static icmp v4() ASIO_NOEXCEPT+ static icmp v4() noexcept { return icmp(ASIO_OS_DEF(IPPROTO_ICMP), ASIO_OS_DEF(AF_INET)); } /// Construct to represent the IPv6 ICMP protocol.- static icmp v6() ASIO_NOEXCEPT+ static icmp v6() 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 ASIO_NOEXCEPT+ int type() const noexcept { return ASIO_OS_DEF(SOCK_RAW); } /// Obtain an identifier for the protocol.- int protocol() const ASIO_NOEXCEPT+ int protocol() const noexcept { return protocol_; } /// Obtain an identifier for the protocol family.- int family() const ASIO_NOEXCEPT+ int family() const noexcept { return family_; }@@ -97,7 +97,7 @@ private: // Construct with a specific family.- explicit icmp(int protocol_id, int protocol_family) ASIO_NOEXCEPT+ explicit icmp(int protocol_id, int protocol_family) 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -17,38 +17,10 @@ #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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -29,7 +29,7 @@ namespace asio { namespace ip { -address::address() ASIO_NOEXCEPT+address::address() noexcept : type_(ipv4), ipv4_address_(), ipv6_address_()@@ -37,7 +37,7 @@ } address::address(- const asio::ip::address_v4& ipv4_address) ASIO_NOEXCEPT+ const asio::ip::address_v4& ipv4_address) noexcept : type_(ipv4), ipv4_address_(ipv4_address), ipv6_address_()@@ -45,30 +45,28 @@ } address::address(- const asio::ip::address_v6& ipv6_address) ASIO_NOEXCEPT+ const asio::ip::address_v6& ipv6_address) noexcept : type_(ipv6), ipv4_address_(), ipv6_address_(ipv6_address) { } -address::address(const address& other) ASIO_NOEXCEPT+address::address(const address& other) noexcept : type_(other.type_), ipv4_address_(other.ipv4_address_), ipv6_address_(other.ipv6_address_) { } -#if defined(ASIO_HAS_MOVE)-address::address(address&& other) ASIO_NOEXCEPT+address::address(address&& other) 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) ASIO_NOEXCEPT+address& address::operator=(const address& other) noexcept { type_ = other.type_; ipv4_address_ = other.ipv4_address_;@@ -76,18 +74,16 @@ return *this; } -#if defined(ASIO_HAS_MOVE)-address& address::operator=(address&& other) ASIO_NOEXCEPT+address& address::operator=(address&& other) 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) ASIO_NOEXCEPT+ const asio::ip::address_v4& ipv4_address) noexcept { type_ = ipv4; ipv4_address_ = ipv4_address;@@ -96,7 +92,7 @@ } address& address::operator=(- const asio::ip::address_v6& ipv6_address) ASIO_NOEXCEPT+ const asio::ip::address_v6& ipv6_address) noexcept { type_ = ipv6; ipv4_address_ = asio::ip::address_v4();@@ -113,7 +109,7 @@ } address make_address(const char* str,- asio::error_code& ec) ASIO_NOEXCEPT+ asio::error_code& ec) noexcept { asio::ip::address_v6 ipv6_address = asio::ip::make_address_v6(str, ec);@@ -134,7 +130,7 @@ } address make_address(const std::string& str,- asio::error_code& ec) ASIO_NOEXCEPT+ asio::error_code& ec) noexcept { return make_address(str.c_str(), ec); }@@ -147,7 +143,7 @@ } address make_address(string_view str,- asio::error_code& ec) ASIO_NOEXCEPT+ asio::error_code& ec) noexcept { return make_address(static_cast<std::string>(str), ec); }@@ -181,37 +177,28 @@ return ipv4_address_.to_string(); } -#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+bool address::is_loopback() const noexcept { return (type_ == ipv4) ? ipv4_address_.is_loopback() : ipv6_address_.is_loopback(); } -bool address::is_unspecified() const ASIO_NOEXCEPT+bool address::is_unspecified() const noexcept { return (type_ == ipv4) ? ipv4_address_.is_unspecified() : ipv6_address_.is_unspecified(); } -bool address::is_multicast() const ASIO_NOEXCEPT+bool address::is_multicast() const noexcept { return (type_ == ipv4) ? ipv4_address_.is_multicast() : ipv6_address_.is_multicast(); } -bool operator==(const address& a1, const address& a2) ASIO_NOEXCEPT+bool operator==(const address& a1, const address& a2) noexcept { if (a1.type_ != a2.type_) return false;@@ -220,7 +207,7 @@ return a1.ipv4_address_ == a2.ipv4_address_; } -bool operator<(const address& a1, const address& a2) ASIO_NOEXCEPT+bool operator<(const address& a1, const address& a2) 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -17,38 +17,10 @@ #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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -57,30 +57,19 @@ static_cast<asio::detail::u_long_type>(addr)); } -address_v4::bytes_type address_v4::to_bytes() const ASIO_NOEXCEPT+address_v4::bytes_type address_v4::to_bytes() const 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 ASIO_NOEXCEPT+address_v4::uint_type address_v4::to_uint() const 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;@@ -94,70 +83,21 @@ return addr; } -#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+bool address_v4::is_loopback() const noexcept { return (to_uint() & 0xFF000000) == 0x7F000000; } -bool address_v4::is_unspecified() const ASIO_NOEXCEPT+bool address_v4::is_unspecified() const noexcept { return to_uint() == 0; } -#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+bool address_v4::is_multicast() const 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;@@ -167,7 +107,7 @@ } address_v4 make_address_v4(const char* str,- asio::error_code& ec) ASIO_NOEXCEPT+ asio::error_code& ec) noexcept { address_v4::bytes_type bytes; if (asio::detail::socket_ops::inet_pton(@@ -182,7 +122,7 @@ } address_v4 make_address_v4(const std::string& str,- asio::error_code& ec) ASIO_NOEXCEPT+ asio::error_code& ec) noexcept { return make_address_v4(str.c_str(), ec); }@@ -195,7 +135,7 @@ } address_v4 make_address_v4(string_view str,- asio::error_code& ec) ASIO_NOEXCEPT+ asio::error_code& ec) 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -17,38 +17,10 @@ #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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -31,7 +31,7 @@ namespace asio { namespace ip { -address_v6::address_v6() ASIO_NOEXCEPT+address_v6::address_v6() noexcept : addr_(), scope_id_(0) {@@ -56,45 +56,37 @@ memcpy(addr_.s6_addr, bytes.data(), 16); } -address_v6::address_v6(const address_v6& other) ASIO_NOEXCEPT+address_v6::address_v6(const address_v6& other) noexcept : addr_(other.addr_), scope_id_(other.scope_id_) { } -#if defined(ASIO_HAS_MOVE)-address_v6::address_v6(address_v6&& other) ASIO_NOEXCEPT+address_v6::address_v6(address_v6&& other) noexcept : addr_(other.addr_), scope_id_(other.scope_id_) { }-#endif // defined(ASIO_HAS_MOVE) -address_v6& address_v6::operator=(const address_v6& other) ASIO_NOEXCEPT+address_v6& address_v6::operator=(const address_v6& other) noexcept { addr_ = other.addr_; scope_id_ = other.scope_id_; return *this; } -#if defined(ASIO_HAS_MOVE)-address_v6& address_v6::operator=(address_v6&& other) ASIO_NOEXCEPT+address_v6& address_v6::operator=(address_v6&& other) 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 ASIO_NOEXCEPT+address_v6::bytes_type address_v6::to_bytes() const 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; } @@ -111,34 +103,7 @@ return addr; } -#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+bool address_v6::is_loopback() const noexcept { return ((addr_.s6_addr[0] == 0) && (addr_.s6_addr[1] == 0) && (addr_.s6_addr[2] == 0) && (addr_.s6_addr[3] == 0)@@ -150,7 +115,7 @@ && (addr_.s6_addr[14] == 0) && (addr_.s6_addr[15] == 1)); } -bool address_v6::is_unspecified() const ASIO_NOEXCEPT+bool address_v6::is_unspecified() const noexcept { return ((addr_.s6_addr[0] == 0) && (addr_.s6_addr[1] == 0) && (addr_.s6_addr[2] == 0) && (addr_.s6_addr[3] == 0)@@ -162,17 +127,17 @@ && (addr_.s6_addr[14] == 0) && (addr_.s6_addr[15] == 0)); } -bool address_v6::is_link_local() const ASIO_NOEXCEPT+bool address_v6::is_link_local() const noexcept { return ((addr_.s6_addr[0] == 0xfe) && ((addr_.s6_addr[1] & 0xc0) == 0x80)); } -bool address_v6::is_site_local() const ASIO_NOEXCEPT+bool address_v6::is_site_local() const noexcept { return ((addr_.s6_addr[0] == 0xfe) && ((addr_.s6_addr[1] & 0xc0) == 0xc0)); } -bool address_v6::is_v4_mapped() const ASIO_NOEXCEPT+bool address_v6::is_v4_mapped() const noexcept { return ((addr_.s6_addr[0] == 0) && (addr_.s6_addr[1] == 0) && (addr_.s6_addr[2] == 0) && (addr_.s6_addr[3] == 0)@@ -182,53 +147,37 @@ && (addr_.s6_addr[10] == 0xff) && (addr_.s6_addr[11] == 0xff)); } -#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+bool address_v6::is_multicast() const noexcept { return (addr_.s6_addr[0] == 0xff); } -bool address_v6::is_multicast_global() const ASIO_NOEXCEPT+bool address_v6::is_multicast_global() const noexcept { return ((addr_.s6_addr[0] == 0xff) && ((addr_.s6_addr[1] & 0x0f) == 0x0e)); } -bool address_v6::is_multicast_link_local() const ASIO_NOEXCEPT+bool address_v6::is_multicast_link_local() const noexcept { return ((addr_.s6_addr[0] == 0xff) && ((addr_.s6_addr[1] & 0x0f) == 0x02)); } -bool address_v6::is_multicast_node_local() const ASIO_NOEXCEPT+bool address_v6::is_multicast_node_local() const noexcept { return ((addr_.s6_addr[0] == 0xff) && ((addr_.s6_addr[1] & 0x0f) == 0x01)); } -bool address_v6::is_multicast_org_local() const ASIO_NOEXCEPT+bool address_v6::is_multicast_org_local() const noexcept { return ((addr_.s6_addr[0] == 0xff) && ((addr_.s6_addr[1] & 0x0f) == 0x08)); } -bool address_v6::is_multicast_site_local() const ASIO_NOEXCEPT+bool address_v6::is_multicast_site_local() const noexcept { return ((addr_.s6_addr[0] == 0xff) && ((addr_.s6_addr[1] & 0x0f) == 0x05)); } -bool operator==(const address_v6& a1, const address_v6& a2) ASIO_NOEXCEPT+bool operator==(const address_v6& a1, const address_v6& a2) noexcept { using namespace std; // For memcmp. return memcmp(&a1.addr_, &a2.addr_,@@ -236,7 +185,7 @@ && a1.scope_id_ == a2.scope_id_; } -bool operator<(const address_v6& a1, const address_v6& a2) ASIO_NOEXCEPT+bool operator<(const address_v6& a1, const address_v6& a2) noexcept { using namespace std; // For memcmp. int memcmp_result = memcmp(&a1.addr_, &a2.addr_,@@ -248,31 +197,13 @@ return a1.scope_id_ < a2.scope_id_; } -address_v6 address_v6::loopback() ASIO_NOEXCEPT+address_v6 address_v6::loopback() 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;@@ -282,14 +213,14 @@ } address_v6 make_address_v6(const char* str,- asio::error_code& ec) ASIO_NOEXCEPT+ asio::error_code& ec) 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, scope_id);+ return address_v6(bytes, static_cast<scope_id_type>(scope_id)); } address_v6 make_address_v6(const std::string& str)@@ -298,7 +229,7 @@ } address_v6 make_address_v6(const std::string& str,- asio::error_code& ec) ASIO_NOEXCEPT+ asio::error_code& ec) noexcept { return make_address_v6(str.c_str(), ec); }@@ -311,7 +242,7 @@ } address_v6 make_address_v6(string_view str,- asio::error_code& ec) ASIO_NOEXCEPT+ asio::error_code& ec) 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2025 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2025 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 ASIO_NOEXCEPT+address_v4 network_v4::netmask() const noexcept { uint32_t nmbits = 0xffffffff; if (prefix_length_ == 0)@@ -101,7 +101,7 @@ return address_v4(nmbits); } -address_v4_range network_v4::hosts() const ASIO_NOEXCEPT+address_v4_range network_v4::hosts() const 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2025 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 ASIO_NOEXCEPT+ASIO_DECL address_v6 network_v6::network() const 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 ASIO_NOEXCEPT+address_v6_range network_v6::hosts() const 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/ip/network_v4.hpp view
@@ -2,7 +2,7 @@ // ip/network_v4.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2025 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() ASIO_NOEXCEPT+ network_v4() noexcept : address_(), prefix_length_(0) {@@ -55,78 +55,74 @@ const address_v4& mask); /// Copy constructor.- network_v4(const network_v4& other) ASIO_NOEXCEPT+ network_v4(const network_v4& other) noexcept : address_(other.address_), prefix_length_(other.prefix_length_) { } -#if defined(ASIO_HAS_MOVE) /// Move constructor.- network_v4(network_v4&& other) ASIO_NOEXCEPT- : address_(ASIO_MOVE_CAST(address_v4)(other.address_)),+ network_v4(network_v4&& other) noexcept+ : address_(static_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) ASIO_NOEXCEPT+ network_v4& operator=(const network_v4& other) 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) ASIO_NOEXCEPT+ network_v4& operator=(network_v4&& other) noexcept {- address_ = ASIO_MOVE_CAST(address_v4)(other.address_);+ address_ = static_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 ASIO_NOEXCEPT+ address_v4 address() const noexcept { return address_; } /// Obtain the prefix length that was specified when the network object was /// created.- unsigned short prefix_length() const ASIO_NOEXCEPT+ unsigned short prefix_length() const noexcept { return prefix_length_; } /// Obtain the netmask that was specified when the network object was created.- ASIO_DECL address_v4 netmask() const ASIO_NOEXCEPT;+ ASIO_DECL address_v4 netmask() const noexcept; /// Obtain an address object that represents the network address.- address_v4 network() const ASIO_NOEXCEPT+ address_v4 network() const 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 ASIO_NOEXCEPT+ address_v4 broadcast() const 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 ASIO_NOEXCEPT;+ ASIO_DECL address_v4_range hosts() const noexcept; /// Obtain the true network address, omitting any host bits.- network_v4 canonical() const ASIO_NOEXCEPT+ network_v4 canonical() const noexcept { return network_v4(network(), prefix_length()); } /// Test if network is a valid host address.- bool is_host() const ASIO_NOEXCEPT+ bool is_host() const 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2025 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() ASIO_NOEXCEPT+ network_v6() noexcept : address_(), prefix_length_(0) {@@ -51,66 +51,62 @@ unsigned short prefix_len); /// Copy constructor.- network_v6(const network_v6& other) ASIO_NOEXCEPT+ network_v6(const network_v6& other) noexcept : address_(other.address_), prefix_length_(other.prefix_length_) { } -#if defined(ASIO_HAS_MOVE) /// Move constructor.- network_v6(network_v6&& other) ASIO_NOEXCEPT- : address_(ASIO_MOVE_CAST(address_v6)(other.address_)),+ network_v6(network_v6&& other) noexcept+ : address_(static_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) ASIO_NOEXCEPT+ network_v6& operator=(const network_v6& other) 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) ASIO_NOEXCEPT+ network_v6& operator=(network_v6&& other) noexcept {- address_ = ASIO_MOVE_CAST(address_v6)(other.address_);+ address_ = static_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 ASIO_NOEXCEPT+ address_v6 address() const noexcept { return address_; } /// Obtain the prefix length that was specified when the network object was /// created.- unsigned short prefix_length() const ASIO_NOEXCEPT+ unsigned short prefix_length() const noexcept { return prefix_length_; } /// Obtain an address object that represents the network address.- ASIO_DECL address_v6 network() const ASIO_NOEXCEPT;+ ASIO_DECL address_v6 network() const noexcept; /// Obtain an address range corresponding to the hosts in the network.- ASIO_DECL address_v6_range hosts() const ASIO_NOEXCEPT;+ ASIO_DECL address_v6_range hosts() const noexcept; /// Obtain the true network address, omitting any host bits.- network_v6 canonical() const ASIO_NOEXCEPT+ network_v6 canonical() const noexcept { return network_v6(network(), prefix_length()); } /// Test if network is a valid host address.- bool is_host() const ASIO_NOEXCEPT+ bool is_host() const 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/ip/tcp.hpp view
@@ -2,7 +2,7 @@ // ip/tcp.hpp // ~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -49,31 +49,31 @@ typedef basic_endpoint<tcp> endpoint; /// Construct to represent the IPv4 TCP protocol.- static tcp v4() ASIO_NOEXCEPT+ static tcp v4() noexcept { return tcp(ASIO_OS_DEF(AF_INET)); } /// Construct to represent the IPv6 TCP protocol.- static tcp v6() ASIO_NOEXCEPT+ static tcp v6() noexcept { return tcp(ASIO_OS_DEF(AF_INET6)); } /// Obtain an identifier for the type of the protocol.- int type() const ASIO_NOEXCEPT+ int type() const noexcept { return ASIO_OS_DEF(SOCK_STREAM); } /// Obtain an identifier for the protocol.- int protocol() const ASIO_NOEXCEPT+ int protocol() const noexcept { return ASIO_OS_DEF(IPPROTO_TCP); } /// Obtain an identifier for the protocol family.- int family() const ASIO_NOEXCEPT+ int family() const noexcept { return family_; }@@ -139,7 +139,7 @@ private: // Construct with a specific family.- explicit tcp(int protocol_family) ASIO_NOEXCEPT+ explicit tcp(int protocol_family) 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -46,31 +46,31 @@ typedef basic_endpoint<udp> endpoint; /// Construct to represent the IPv4 UDP protocol.- static udp v4() ASIO_NOEXCEPT+ static udp v4() noexcept { return udp(ASIO_OS_DEF(AF_INET)); } /// Construct to represent the IPv6 UDP protocol.- static udp v6() ASIO_NOEXCEPT+ static udp v6() noexcept { return udp(ASIO_OS_DEF(AF_INET6)); } /// Obtain an identifier for the type of the protocol.- int type() const ASIO_NOEXCEPT+ int type() const noexcept { return ASIO_OS_DEF(SOCK_DGRAM); } /// Obtain an identifier for the protocol.- int protocol() const ASIO_NOEXCEPT+ int protocol() const noexcept { return ASIO_OS_DEF(IPPROTO_UDP); } /// Obtain an identifier for the protocol family.- int family() const ASIO_NOEXCEPT+ int family() const noexcept { return family_; }@@ -95,7 +95,7 @@ private: // Construct with a specific family.- explicit udp(int protocol_family) ASIO_NOEXCEPT+ explicit udp(int protocol_family) 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/ip/v6_only.hpp view
@@ -2,7 +2,7 @@ // ip/v6_only.hpp // ~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/is_applicable_property.hpp view
@@ -2,7 +2,7 @@ // is_applicable_property.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -30,11 +30,11 @@ template <typename T, typename Property> struct is_applicable_property_trait<T, Property,- typename void_type<- typename enable_if<+ void_t<+ enable_if_t< !!Property::template is_applicable_property_v<T>- >::type- >::type> : true_type+ >+ >> : true_type { }; @@ -51,7 +51,7 @@ #if defined(ASIO_HAS_VARIABLE_TEMPLATES) template <typename T, typename Property>-ASIO_CONSTEXPR const bool is_applicable_property_v+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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/is_read_buffered.hpp view
@@ -2,7 +2,7 @@ // is_read_buffered.hpp // ~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/is_write_buffered.hpp view
@@ -2,7 +2,7 @@ // is_write_buffered.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/local/basic_endpoint.hpp view
@@ -2,7 +2,7 @@ // local/basic_endpoint.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2025 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() ASIO_NOEXCEPT+ basic_endpoint() noexcept { } @@ -85,55 +85,51 @@ #endif // defined(ASIO_HAS_STRING_VIEW) /// Copy constructor.- basic_endpoint(const basic_endpoint& other)+ basic_endpoint(const basic_endpoint& other) noexcept : impl_(other.impl_) { } -#if defined(ASIO_HAS_MOVE) /// Move constructor.- basic_endpoint(basic_endpoint&& other)+ basic_endpoint(basic_endpoint&& other) noexcept : impl_(other.impl_) { }-#endif // defined(ASIO_HAS_MOVE) /// Assign from another endpoint.- basic_endpoint& operator=(const basic_endpoint& other)+ basic_endpoint& operator=(const basic_endpoint& other) noexcept { impl_ = other.impl_; return *this; } -#if defined(ASIO_HAS_MOVE) /// Move-assign from another endpoint.- basic_endpoint& operator=(basic_endpoint&& other)+ basic_endpoint& operator=(basic_endpoint&& other) noexcept { impl_ = other.impl_; return *this; }-#endif // defined(ASIO_HAS_MOVE) /// The protocol associated with the endpoint.- protocol_type protocol() const+ protocol_type protocol() const noexcept { return protocol_type(); } /// Get the underlying endpoint in the native type.- data_type* data()+ data_type* data() noexcept { return impl_.data(); } /// Get the underlying endpoint in the native type.- const data_type* data() const+ const data_type* data() const noexcept { return impl_.data(); } /// Get the underlying size of the endpoint in the native type.- std::size_t size() const+ std::size_t size() const noexcept { return impl_.size(); }@@ -145,7 +141,7 @@ } /// Get the capacity of the endpoint in the native type.- std::size_t capacity() const+ std::size_t capacity() const noexcept { return impl_.capacity(); }@@ -170,42 +166,42 @@ /// Compare two endpoints for equality. friend bool operator==(const basic_endpoint<Protocol>& e1,- const basic_endpoint<Protocol>& e2)+ const basic_endpoint<Protocol>& e2) noexcept { return e1.impl_ == e2.impl_; } /// Compare two endpoints for inequality. friend bool operator!=(const basic_endpoint<Protocol>& e1,- const basic_endpoint<Protocol>& e2)+ const basic_endpoint<Protocol>& e2) noexcept { return !(e1.impl_ == e2.impl_); } /// Compare endpoints for ordering. friend bool operator<(const basic_endpoint<Protocol>& e1,- const basic_endpoint<Protocol>& e2)+ const basic_endpoint<Protocol>& e2) noexcept { return e1.impl_ < e2.impl_; } /// Compare endpoints for ordering. friend bool operator>(const basic_endpoint<Protocol>& e1,- const basic_endpoint<Protocol>& e2)+ const basic_endpoint<Protocol>& e2) noexcept { return e2.impl_ < e1.impl_; } /// Compare endpoints for ordering. friend bool operator<=(const basic_endpoint<Protocol>& e1,- const basic_endpoint<Protocol>& e2)+ const basic_endpoint<Protocol>& e2) noexcept { return !(e2 < e1); } /// Compare endpoints for ordering. friend bool operator>=(const basic_endpoint<Protocol>& e1,- const basic_endpoint<Protocol>& e2)+ const basic_endpoint<Protocol>& e2) noexcept { 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/local/datagram_protocol.hpp view
@@ -2,7 +2,7 @@ // local/datagram_protocol.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -45,19 +45,19 @@ { public: /// Obtain an identifier for the type of the protocol.- int type() const ASIO_NOEXCEPT+ int type() const noexcept { return SOCK_DGRAM; } /// Obtain an identifier for the protocol.- int protocol() const ASIO_NOEXCEPT+ int protocol() const noexcept { return 0; } /// Obtain an identifier for the protocol family.- int family() const ASIO_NOEXCEPT+ int family() const 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2025 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();+ ASIO_DECL endpoint() noexcept; // 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)+ endpoint(const endpoint& other) noexcept : data_(other.data_), path_length_(other.path_length_) { } // Assign from another endpoint.- endpoint& operator=(const endpoint& other)+ endpoint& operator=(const endpoint& other) noexcept { 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()+ asio::detail::socket_addr_type* data() noexcept { return &data_.base; } // Get the underlying endpoint in the native type.- const asio::detail::socket_addr_type* data() const+ const asio::detail::socket_addr_type* data() const noexcept { return &data_.base; } // Get the underlying size of the endpoint in the native type.- std::size_t size() const+ std::size_t size() const noexcept { 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+ std::size_t capacity() const noexcept { 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);+ const endpoint& e1, const endpoint& e2) noexcept; // Compare endpoints for ordering. ASIO_DECL friend bool operator<(- const endpoint& e1, const endpoint& e2);+ const endpoint& e1, const endpoint& e2) noexcept; 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2025 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()+endpoint::endpoint() noexcept { init("", 0); }@@ -93,12 +93,12 @@ init(p.data(), p.length()); } -bool operator==(const endpoint& e1, const endpoint& e2)+bool operator==(const endpoint& e1, const endpoint& e2) noexcept { return e1.path() == e2.path(); } -bool operator<(const endpoint& e1, const endpoint& e2)+bool operator<(const endpoint& e1, const endpoint& e2) noexcept { 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -46,19 +46,19 @@ { public: /// Obtain an identifier for the type of the protocol.- int type() const ASIO_NOEXCEPT+ int type() const noexcept { return SOCK_SEQPACKET; } /// Obtain an identifier for the protocol.- int protocol() const ASIO_NOEXCEPT+ int protocol() const noexcept { return 0; } /// Obtain an identifier for the protocol family.- int family() const ASIO_NOEXCEPT+ int family() const 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -47,19 +47,19 @@ { public: /// Obtain an identifier for the type of the protocol.- int type() const ASIO_NOEXCEPT+ int type() const noexcept { return SOCK_STREAM; } /// Obtain an identifier for the protocol.- int protocol() const ASIO_NOEXCEPT+ int protocol() const noexcept { return 0; } /// Obtain an identifier for the protocol family.- int family() const ASIO_NOEXCEPT+ int family() const 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -21,9 +21,6 @@ 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@@ -31,11 +28,11 @@ public: /// Constructor. ASIO_DECL multiple_exceptions(- std::exception_ptr first) ASIO_NOEXCEPT;+ std::exception_ptr first) noexcept; /// Obtain message associated with exception. ASIO_DECL virtual const char* what() const- ASIO_NOEXCEPT_OR_NOTHROW;+ noexcept; /// Obtain a pointer to the first exception. ASIO_DECL std::exception_ptr first_exception() const;@@ -43,9 +40,6 @@ 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -23,15 +23,11 @@ #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>@@ -59,62 +55,6 @@ 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -16,10 +16,7 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"--#if defined(ASIO_HAS_BOOST_BIND)-# include <boost/bind/arg.hpp>-#endif // defined(ASIO_HAS_BOOST_BIND)+#include "asio/detail/functional.hpp" #include "asio/detail/push_options.hpp" @@ -28,119 +25,52 @@ #if defined(GENERATING_DOCUMENTATION) -/// An argument placeholder, for use with boost::bind(), that corresponds to-/// the error argument of a handler for any of the asynchronous functions.+/// 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. unspecified error; -/// 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+/// 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 /// asio::async_write. unspecified bytes_transferred; -/// 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.+/// 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. unspecified iterator; -/// 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.+/// 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. unspecified results; -/// 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.+/// 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. unspecified endpoint; -/// 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.+/// 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. unspecified signal_number; -#elif defined(ASIO_HAS_BOOST_BIND)-# if defined(__BORLANDC__) || defined(__GNUC__)--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+#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+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; -# 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -20,6 +20,7 @@ #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"@@ -36,10 +37,6 @@ # 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 {@@ -110,10 +107,10 @@ */ template <typename ExecutionContext> explicit basic_descriptor(ExecutionContext& context,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- >::type = defaulted_constraint())+ > = defaulted_constraint()) : impl_(0, 0, context) { }@@ -157,9 +154,9 @@ template <typename ExecutionContext> basic_descriptor(ExecutionContext& context, const native_handle_type& native_descriptor,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value- >::type = 0)+ > = 0) : impl_(0, 0, context) { asio::error_code ec;@@ -168,7 +165,6 @@ 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.@@ -180,7 +176,7 @@ * constructed using the @c basic_descriptor(const executor_type&) * constructor. */- basic_descriptor(basic_descriptor&& other) ASIO_NOEXCEPT+ basic_descriptor(basic_descriptor&& other) noexcept : impl_(std::move(other.impl_)) { }@@ -220,10 +216,10 @@ */ template <typename Executor1> basic_descriptor(basic_descriptor<Executor1>&& other,- typename constraint<+ constraint_t< is_convertible<Executor1, Executor>::value, defaulted_constraint- >::type = defaulted_constraint())+ > = defaulted_constraint()) : impl_(std::move(other.impl_)) { }@@ -240,19 +236,18 @@ * constructor. */ template <typename Executor1>- typename constraint<+ constraint_t< is_convertible<Executor1, Executor>::value, basic_descriptor&- >::type operator=(basic_descriptor<Executor1> && other)+ > 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() ASIO_NOEXCEPT+ const executor_type& get_executor() noexcept { return impl_.get_executor(); }@@ -665,7 +660,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code) @endcode@@ -701,15 +696,12 @@ */ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code))- 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((+ WaitToken = default_completion_token_t<executor_type>>+ auto async_wait(wait_type w,+ WaitToken&& token = default_completion_token_t<executor_type>())+ -> decltype( 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);@@ -734,8 +726,8 @@ private: // Disallow copying and assignment.- basic_descriptor(const basic_descriptor&) ASIO_DELETED;- basic_descriptor& operator=(const basic_descriptor&) ASIO_DELETED;+ basic_descriptor(const basic_descriptor&) = delete;+ basic_descriptor& operator=(const basic_descriptor&) = delete; class initiate_async_wait {@@ -747,13 +739,13 @@ { } - const executor_type& get_executor() const ASIO_NOEXCEPT+ const executor_type& get_executor() const noexcept { return self_->get_executor(); } template <typename WaitHandler>- void operator()(ASIO_MOVE_ARG(WaitHandler) handler, wait_type w) const+ void operator()(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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -95,10 +95,10 @@ */ template <typename ExecutionContext> explicit basic_stream_descriptor(ExecutionContext& context,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- >::type = defaulted_constraint())+ > = defaulted_constraint()) : basic_descriptor<Executor>(context) { }@@ -138,14 +138,13 @@ template <typename ExecutionContext> basic_stream_descriptor(ExecutionContext& context, const native_handle_type& native_descriptor,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value- >::type = 0)+ > = 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.@@ -157,7 +156,7 @@ * constructed using the @c basic_stream_descriptor(const executor_type&) * constructor. */- basic_stream_descriptor(basic_stream_descriptor&& other) ASIO_NOEXCEPT+ basic_stream_descriptor(basic_stream_descriptor&& other) noexcept : basic_descriptor<Executor>(std::move(other)) { }@@ -194,10 +193,10 @@ */ template <typename Executor1> basic_stream_descriptor(basic_stream_descriptor<Executor1>&& other,- typename constraint<+ constraint_t< is_convertible<Executor1, Executor>::value, defaulted_constraint- >::type = defaulted_constraint())+ > = defaulted_constraint()) : basic_descriptor<Executor>(std::move(other)) { }@@ -215,15 +214,14 @@ * constructor. */ template <typename Executor1>- typename constraint<+ constraint_t< is_convertible<Executor1, Executor>::value, basic_stream_descriptor&- >::type operator=(basic_stream_descriptor<Executor1> && other)+ > 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. /**@@ -309,7 +307,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -339,17 +337,13 @@ */ template <typename ConstBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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((+ 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( 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)>(@@ -442,7 +436,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -473,17 +467,13 @@ */ template <typename MutableBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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((+ 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( 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)>(@@ -501,13 +491,13 @@ { } - const executor_type& get_executor() const ASIO_NOEXCEPT+ const executor_type& get_executor() const noexcept { return self_->get_executor(); } template <typename WriteHandler, typename ConstBufferSequence>- void operator()(ASIO_MOVE_ARG(WriteHandler) handler,+ void operator()(WriteHandler&& handler, const ConstBufferSequence& buffers) const { // If you get an error on the following line it means that your handler@@ -534,13 +524,13 @@ { } - const executor_type& get_executor() const ASIO_NOEXCEPT+ const executor_type& get_executor() const noexcept { return self_->get_executor(); } template <typename ReadHandler, typename MutableBufferSequence>- void operator()(ASIO_MOVE_ARG(ReadHandler) handler,+ void operator()(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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/posix/descriptor_base.hpp view
@@ -2,7 +2,7 @@ // posix/descriptor_base.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/posix/stream_descriptor.hpp view
@@ -2,7 +2,7 @@ // posix/stream_descriptor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/post.hpp view
@@ -2,7 +2,7 @@ // post.hpp // ~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -77,11 +77,10 @@ * @code void() @endcode */ template <ASIO_COMPLETION_TOKEN_FOR(void()) NullaryToken>-ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(NullaryToken, void()) post(- ASIO_MOVE_ARG(NullaryToken) token)- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+inline auto post(NullaryToken&& token)+ -> decltype( async_initiate<NullaryToken, void()>(- declval<detail::initiate_post>(), token)))+ declval<detail::initiate_post>(), token)) { return async_initiate<NullaryToken, void()>( detail::initiate_post(), token);@@ -158,19 +157,17 @@ */ template <typename Executor, ASIO_COMPLETION_TOKEN_FOR(void()) NullaryToken- 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<+ = default_completion_token_t<Executor>>+inline auto post(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- >::type = 0)- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ > = 0)+ -> decltype( 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);@@ -191,19 +188,17 @@ */ template <typename ExecutionContext, ASIO_COMPLETION_TOKEN_FOR(void()) NullaryToken- 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((+ = 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( 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -118,10 +118,10 @@ namespace asio_prefer_fn { -using asio::conditional;-using asio::decay;+using asio::conditional_t;+using asio::decay_t; using asio::declval;-using asio::enable_if;+using asio::enable_if_t; using asio::is_applicable_property; using asio::traits::prefer_free; using asio::traits::prefer_member;@@ -149,195 +149,187 @@ typename = void, typename = void, typename = void> struct call_traits {- ASIO_STATIC_CONSTEXPR(overload_type, overload = ill_formed);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ static constexpr overload_type overload = ill_formed;+ static constexpr bool is_noexcept = false; typedef void result_type; }; template <typename Impl, typename T, typename Property> struct call_traits<Impl, T, void(Property),- typename enable_if<+ enable_if_t< is_applicable_property<- typename decay<T>::type,- typename decay<Property>::type+ decay_t<T>,+ decay_t<Property> >::value- >::type,- typename enable_if<- decay<Property>::type::is_preferable- >::type,- typename enable_if<+ >,+ enable_if_t<+ decay_t<Property>::is_preferable+ >,+ enable_if_t< static_require<T, Property>::is_valid- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(overload_type, overload = identity);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr overload_type overload = identity;+ static constexpr bool is_noexcept = true; -#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)+ typedef T&& result_type; }; template <typename Impl, typename T, typename Property> struct call_traits<Impl, T, void(Property),- typename enable_if<+ enable_if_t< is_applicable_property<- typename decay<T>::type,- typename decay<Property>::type+ decay_t<T>,+ decay_t<Property> >::value- >::type,- typename enable_if<- decay<Property>::type::is_preferable- >::type,- typename enable_if<+ >,+ enable_if_t<+ decay_t<Property>::is_preferable+ >,+ enable_if_t< !static_require<T, Property>::is_valid- >::type,- typename enable_if<+ >,+ enable_if_t< require_member<typename Impl::template proxy<T>::type, Property>::is_valid- >::type> :+ >> : require_member<typename Impl::template proxy<T>::type, Property> {- ASIO_STATIC_CONSTEXPR(overload_type, overload = call_require_member);+ static constexpr overload_type overload = call_require_member; }; template <typename Impl, typename T, typename Property> struct call_traits<Impl, T, void(Property),- typename enable_if<+ enable_if_t< is_applicable_property<- typename decay<T>::type,- typename decay<Property>::type+ decay_t<T>,+ decay_t<Property> >::value- >::type,- typename enable_if<- decay<Property>::type::is_preferable- >::type,- typename enable_if<+ >,+ enable_if_t<+ decay_t<Property>::is_preferable+ >,+ enable_if_t< !static_require<T, Property>::is_valid- >::type,- typename enable_if<+ >,+ enable_if_t< !require_member<typename Impl::template proxy<T>::type, Property>::is_valid- >::type,- typename enable_if<+ >,+ enable_if_t< require_free<T, Property>::is_valid- >::type> :+ >> : require_free<T, Property> {- ASIO_STATIC_CONSTEXPR(overload_type, overload = call_require_free);+ static constexpr overload_type overload = call_require_free; }; template <typename Impl, typename T, typename Property> struct call_traits<Impl, T, void(Property),- typename enable_if<+ enable_if_t< is_applicable_property<- typename decay<T>::type,- typename decay<Property>::type+ decay_t<T>,+ decay_t<Property> >::value- >::type,- typename enable_if<- decay<Property>::type::is_preferable- >::type,- typename enable_if<+ >,+ enable_if_t<+ decay_t<Property>::is_preferable+ >,+ enable_if_t< !static_require<T, Property>::is_valid- >::type,- typename enable_if<+ >,+ enable_if_t< !require_member<typename Impl::template proxy<T>::type, Property>::is_valid- >::type,- typename enable_if<+ >,+ enable_if_t< !require_free<T, Property>::is_valid- >::type,- typename enable_if<+ >,+ enable_if_t< prefer_member<typename Impl::template proxy<T>::type, Property>::is_valid- >::type> :+ >> : prefer_member<typename Impl::template proxy<T>::type, Property> {- ASIO_STATIC_CONSTEXPR(overload_type, overload = call_prefer_member);+ static constexpr overload_type overload = call_prefer_member; }; template <typename Impl, typename T, typename Property> struct call_traits<Impl, T, void(Property),- typename enable_if<+ enable_if_t< is_applicable_property<- typename decay<T>::type,- typename decay<Property>::type+ decay_t<T>,+ decay_t<Property> >::value- >::type,- typename enable_if<- decay<Property>::type::is_preferable- >::type,- typename enable_if<+ >,+ enable_if_t<+ decay_t<Property>::is_preferable+ >,+ enable_if_t< !static_require<T, Property>::is_valid- >::type,- typename enable_if<+ >,+ enable_if_t< !require_member<typename Impl::template proxy<T>::type, Property>::is_valid- >::type,- typename enable_if<+ >,+ enable_if_t< !require_free<T, Property>::is_valid- >::type,- typename enable_if<+ >,+ enable_if_t< !prefer_member<typename Impl::template proxy<T>::type, Property>::is_valid- >::type,- typename enable_if<+ >,+ enable_if_t< prefer_free<T, Property>::is_valid- >::type> :+ >> : prefer_free<T, Property> {- ASIO_STATIC_CONSTEXPR(overload_type, overload = call_prefer_free);+ static constexpr overload_type overload = call_prefer_free; }; template <typename Impl, typename T, typename Property> struct call_traits<Impl, T, void(Property),- typename enable_if<+ enable_if_t< is_applicable_property<- typename decay<T>::type,- typename decay<Property>::type+ decay_t<T>,+ decay_t<Property> >::value- >::type,- typename enable_if<- decay<Property>::type::is_preferable- >::type,- typename enable_if<+ >,+ enable_if_t<+ decay_t<Property>::is_preferable+ >,+ enable_if_t< !static_require<T, Property>::is_valid- >::type,- typename enable_if<+ >,+ enable_if_t< !require_member<typename Impl::template proxy<T>::type, Property>::is_valid- >::type,- typename enable_if<+ >,+ enable_if_t< !require_free<T, Property>::is_valid- >::type,- typename enable_if<+ >,+ enable_if_t< !prefer_member<typename Impl::template proxy<T>::type, Property>::is_valid- >::type,- typename enable_if<+ >,+ enable_if_t< !prefer_free<T, Property>::is_valid- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(overload_type, overload = identity);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr overload_type overload = identity;+ static constexpr bool is_noexcept = true; -#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)+ typedef T&& result_type; }; template <typename Impl, typename T, typename P0, typename P1> struct call_traits<Impl, T, void(P0, P1),- typename enable_if<+ enable_if_t< call_traits<Impl, T, void(P0)>::overload != ill_formed- >::type,- typename enable_if<+ >,+ enable_if_t< call_traits< Impl, typename call_traits<Impl, T, void(P0)>::result_type, void(P1) >::overload != ill_formed- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(overload_type, overload = two_props);+ static constexpr overload_type overload = two_props; - ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+ static constexpr bool is_noexcept = ( call_traits<Impl, T, void(P0)>::is_noexcept &&@@ -346,51 +338,51 @@ typename call_traits<Impl, T, void(P0)>::result_type, void(P1) >::is_noexcept- ));+ ); - typedef typename decay<+ typedef decay_t< typename call_traits< Impl, typename call_traits<Impl, T, void(P0)>::result_type, void(P1) >::result_type- >::type result_type;+ > result_type; }; template <typename Impl, typename T, typename P0,- typename P1, typename ASIO_ELLIPSIS PN>-struct call_traits<Impl, T, void(P0, P1, PN ASIO_ELLIPSIS),- typename enable_if<+ typename P1, typename... PN>+struct call_traits<Impl, T, void(P0, P1, PN...),+ enable_if_t< call_traits<Impl, T, void(P0)>::overload != ill_formed- >::type,- typename enable_if<+ >,+ enable_if_t< call_traits< Impl, typename call_traits<Impl, T, void(P0)>::result_type,- void(P1, PN ASIO_ELLIPSIS)+ void(P1, PN...) >::overload != ill_formed- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(overload_type, overload = n_props);+ static constexpr overload_type overload = n_props; - ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+ 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 ASIO_ELLIPSIS)+ void(P1, PN...) >::is_noexcept- ));+ ); - typedef typename decay<+ typedef decay_t< typename call_traits< Impl, typename call_traits<Impl, T, void(P0)>::result_type,- void(P1, PN ASIO_ELLIPSIS)+ void(P1, PN...) >::result_type- >::type result_type;+ > result_type; }; struct impl@@ -403,29 +395,25 @@ struct type { template <typename P>- auto require(ASIO_MOVE_ARG(P) p)+ auto require(P&& p) noexcept( noexcept(- declval<typename conditional<true, T, P>::type>().require(- ASIO_MOVE_CAST(P)(p))+ declval<conditional_t<true, T, P>>().require(static_cast<P&&>(p)) ) ) -> decltype(- declval<typename conditional<true, T, P>::type>().require(- ASIO_MOVE_CAST(P)(p))+ declval<conditional_t<true, T, P>>().require(static_cast<P&&>(p)) ); template <typename P>- auto prefer(ASIO_MOVE_ARG(P) p)+ auto prefer(P&& p) noexcept( noexcept(- declval<typename conditional<true, T, P>::type>().prefer(- ASIO_MOVE_CAST(P)(p))+ declval<conditional_t<true, T, P>>().prefer(static_cast<P&&>(p)) ) ) -> decltype(- declval<typename conditional<true, T, P>::type>().prefer(- ASIO_MOVE_CAST(P)(p))+ declval<conditional_t<true, T, P>>().prefer(static_cast<P&&>(p)) ); }; #else // defined(ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)@@ -436,122 +424,85 @@ }; template <typename T, typename Property>- ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if<+ ASIO_NODISCARD constexpr enable_if_t< call_traits<impl, T, void(Property)>::overload == identity, typename call_traits<impl, T, void(Property)>::result_type- >::type- operator()(- ASIO_MOVE_ARG(T) t,- ASIO_MOVE_ARG(Property)) const- ASIO_NOEXCEPT_IF((- call_traits<impl, T, void(Property)>::is_noexcept))+ >+ operator()(T&& t, Property&&) const+ noexcept(call_traits<impl, T, void(Property)>::is_noexcept) {- return ASIO_MOVE_CAST(T)(t);+ return static_cast<T&&>(t); } template <typename T, typename Property>- ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if<+ ASIO_NODISCARD constexpr enable_if_t< call_traits<impl, T, void(Property)>::overload == call_require_member, typename call_traits<impl, T, void(Property)>::result_type- >::type- operator()(- ASIO_MOVE_ARG(T) t,- ASIO_MOVE_ARG(Property) p) const- ASIO_NOEXCEPT_IF((- call_traits<impl, T, void(Property)>::is_noexcept))+ >+ operator()(T&& t, Property&& p) const+ noexcept(call_traits<impl, T, void(Property)>::is_noexcept) {- return ASIO_MOVE_CAST(T)(t).require(- ASIO_MOVE_CAST(Property)(p));+ return static_cast<T&&>(t).require(static_cast<Property&&>(p)); } template <typename T, typename Property>- ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if<+ ASIO_NODISCARD constexpr enable_if_t< call_traits<impl, T, void(Property)>::overload == call_require_free, typename call_traits<impl, T, void(Property)>::result_type- >::type- operator()(- ASIO_MOVE_ARG(T) t,- ASIO_MOVE_ARG(Property) p) const- ASIO_NOEXCEPT_IF((- call_traits<impl, T, void(Property)>::is_noexcept))+ >+ operator()(T&& t, Property&& p) const+ noexcept(call_traits<impl, T, void(Property)>::is_noexcept) {- return require(- ASIO_MOVE_CAST(T)(t),- ASIO_MOVE_CAST(Property)(p));+ return require(static_cast<T&&>(t), static_cast<Property&&>(p)); } template <typename T, typename Property>- ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if<+ ASIO_NODISCARD constexpr enable_if_t< call_traits<impl, T, void(Property)>::overload == call_prefer_member, typename call_traits<impl, T, void(Property)>::result_type- >::type- operator()(- ASIO_MOVE_ARG(T) t,- ASIO_MOVE_ARG(Property) p) const- ASIO_NOEXCEPT_IF((- call_traits<impl, T, void(Property)>::is_noexcept))+ >+ operator()(T&& t, Property&& p) const+ noexcept(call_traits<impl, T, void(Property)>::is_noexcept) {- return ASIO_MOVE_CAST(T)(t).prefer(- ASIO_MOVE_CAST(Property)(p));+ return static_cast<T&&>(t).prefer(static_cast<Property&&>(p)); } template <typename T, typename Property>- ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if<+ ASIO_NODISCARD constexpr enable_if_t< call_traits<impl, T, void(Property)>::overload == call_prefer_free, typename call_traits<impl, T, void(Property)>::result_type- >::type- operator()(- ASIO_MOVE_ARG(T) t,- ASIO_MOVE_ARG(Property) p) const- ASIO_NOEXCEPT_IF((- call_traits<impl, T, void(Property)>::is_noexcept))+ >+ operator()(T&& t, Property&& p) const+ noexcept(call_traits<impl, T, void(Property)>::is_noexcept) {- return prefer(- ASIO_MOVE_CAST(T)(t),- ASIO_MOVE_CAST(Property)(p));+ return prefer(static_cast<T&&>(t), static_cast<Property&&>(p)); } template <typename T, typename P0, typename P1>- ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if<+ ASIO_NODISCARD constexpr enable_if_t< call_traits<impl, T, void(P0, P1)>::overload == two_props, typename call_traits<impl, T, void(P0, P1)>::result_type- >::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))+ >+ operator()(T&& t, P0&& p0, P1&& p1) const+ noexcept(call_traits<impl, T, void(P0, P1)>::is_noexcept) { return (*this)(- (*this)(- ASIO_MOVE_CAST(T)(t),- ASIO_MOVE_CAST(P0)(p0)),- ASIO_MOVE_CAST(P1)(p1));+ (*this)(static_cast<T&&>(t), static_cast<P0&&>(p0)),+ static_cast<P1&&>(p1)); } template <typename T, typename P0, typename P1,- 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))+ 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) { return (*this)(- (*this)(- ASIO_MOVE_CAST(T)(t),- ASIO_MOVE_CAST(P0)(p0)),- ASIO_MOVE_CAST(P1)(p1),- ASIO_MOVE_CAST(PN)(pn) ASIO_ELLIPSIS);+ (*this)(static_cast<T&&>(t), static_cast<P0&&>(p0)),+ static_cast<P1&&>(p1), static_cast<PN&&>(pn)...); } }; @@ -568,15 +519,13 @@ namespace asio { namespace { -static ASIO_CONSTEXPR const asio_prefer_fn::impl&+static 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,@@ -586,54 +535,14 @@ { }; -#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 ASIO_ELLIPSIS Properties>+template <typename T, typename... Properties> constexpr bool can_prefer_v- = can_prefer<T, Properties ASIO_ELLIPSIS>::value;+ = can_prefer<T, Properties...>::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,@@ -642,51 +551,13 @@ { }; -#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 ASIO_ELLIPSIS Properties>-constexpr bool is_nothrow_prefer_v- = is_nothrow_prefer<T, Properties ASIO_ELLIPSIS>::value;+template <typename T, typename... Properties>+constexpr bool is_nothrow_prefer_v = is_nothrow_prefer<T, Properties...>::value; #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) -#if defined(ASIO_HAS_VARIADIC_TEMPLATES)- template <typename T, typename... Properties> struct prefer_result {@@ -694,36 +565,8 @@ prefer_t, T, void(Properties...)>::result_type 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)+template <typename T, typename... Properties>+using prefer_result_t = typename prefer_result<T, Properties...>::type; } // namespace asio
link/modules/asio-standalone/asio/include/asio/prepend.hpp view
@@ -2,7 +2,7 @@ // prepend.hpp // ~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -16,11 +16,6 @@ #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" @@ -37,11 +32,9 @@ public: /// Constructor. template <typename T, typename... V>- 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)...)+ constexpr explicit prepend_t(T&& completion_token, V&&... values)+ : token_(static_cast<T&&>(completion_token)),+ values_(static_cast<V&&>(values)...) { } @@ -54,15 +47,14 @@ /// arguments should be passed additional values before the results of the /// operation. template <typename CompletionToken, typename... 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)+ASIO_NODISCARD inline constexpr+prepend_t<decay_t<CompletionToken>, decay_t<Values>...>+prepend(CompletionToken&& completion_token,+ Values&&... values) {- return prepend_t<- typename decay<CompletionToken>::type, typename decay<Values>::type...>(- ASIO_MOVE_CAST(CompletionToken)(completion_token),- ASIO_MOVE_CAST(Values)(values)...);+ return prepend_t<decay_t<CompletionToken>, decay_t<Values>...>(+ static_cast<CompletionToken&&>(completion_token),+ static_cast<Values&&>(values)...); } } // namespace asio@@ -70,9 +62,5 @@ #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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -100,10 +100,10 @@ namespace asio_query_fn { -using asio::conditional;-using asio::decay;+using asio::conditional_t;+using asio::decay_t; using asio::declval;-using asio::enable_if;+using asio::enable_if_t; 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 {- ASIO_STATIC_CONSTEXPR(overload_type, overload = ill_formed);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ static constexpr overload_type overload = ill_formed;+ static constexpr bool is_noexcept = false; typedef void result_type; }; template <typename Impl, typename T, typename Property> struct call_traits<Impl, T, void(Property),- typename enable_if<+ enable_if_t< is_applicable_property<- typename decay<T>::type,- typename decay<Property>::type+ decay_t<T>,+ decay_t<Property> >::value- >::type,- typename enable_if<+ >,+ enable_if_t< static_query<T, Property>::is_valid- >::type> :+ >> : static_query<T, Property> {- ASIO_STATIC_CONSTEXPR(overload_type, overload = static_value);+ static constexpr overload_type overload = static_value; }; template <typename Impl, typename T, typename Property> struct call_traits<Impl, T, void(Property),- typename enable_if<+ enable_if_t< is_applicable_property<- typename decay<T>::type,- typename decay<Property>::type+ decay_t<T>,+ decay_t<Property> >::value- >::type,- typename enable_if<+ >,+ enable_if_t< !static_query<T, Property>::is_valid- >::type,- typename enable_if<+ >,+ enable_if_t< query_member<typename Impl::template proxy<T>::type, Property>::is_valid- >::type> :+ >> : query_member<typename Impl::template proxy<T>::type, Property> {- ASIO_STATIC_CONSTEXPR(overload_type, overload = call_member);+ static constexpr overload_type overload = call_member; }; template <typename Impl, typename T, typename Property> struct call_traits<Impl, T, void(Property),- typename enable_if<+ enable_if_t< is_applicable_property<- typename decay<T>::type,- typename decay<Property>::type+ decay_t<T>,+ decay_t<Property> >::value- >::type,- typename enable_if<+ >,+ enable_if_t< !static_query<T, Property>::is_valid- >::type,- typename enable_if<+ >,+ enable_if_t< !query_member<typename Impl::template proxy<T>::type, Property>::is_valid- >::type,- typename enable_if<+ >,+ enable_if_t< query_free<T, Property>::is_valid- >::type> :+ >> : query_free<T, Property> {- ASIO_STATIC_CONSTEXPR(overload_type, overload = call_free);+ static constexpr overload_type overload = call_free; }; struct impl@@ -194,16 +194,14 @@ struct type { template <typename P>- auto query(ASIO_MOVE_ARG(P) p)+ auto query(P&& p) noexcept( noexcept(- declval<typename conditional<true, T, P>::type>().query(- ASIO_MOVE_CAST(P)(p))+ declval<conditional_t<true, T, P>>().query(static_cast<P&&>(p)) ) ) -> decltype(- declval<typename conditional<true, T, P>::type>().query(- ASIO_MOVE_CAST(P)(p))+ declval<conditional_t<true, T, P>>().query(static_cast<P&&>(p)) ); }; #else // defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)@@ -212,48 +210,36 @@ }; template <typename T, typename Property>- ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if<+ ASIO_NODISCARD constexpr enable_if_t< call_traits<impl, T, void(Property)>::overload == static_value, typename call_traits<impl, T, void(Property)>::result_type- >::type- operator()(- ASIO_MOVE_ARG(T),- ASIO_MOVE_ARG(Property)) const- ASIO_NOEXCEPT_IF((- call_traits<impl, T, void(Property)>::is_noexcept))+ >+ operator()(T&&, Property&&) const+ noexcept(call_traits<impl, T, void(Property)>::is_noexcept) {- return static_query<- typename decay<T>::type,- typename decay<Property>::type- >::value();+ return static_query<decay_t<T>, decay_t<Property>>::value(); } template <typename T, typename Property>- ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if<+ ASIO_NODISCARD constexpr enable_if_t< call_traits<impl, T, void(Property)>::overload == call_member, typename call_traits<impl, T, void(Property)>::result_type- >::type- operator()(- ASIO_MOVE_ARG(T) t,- ASIO_MOVE_ARG(Property) p) const- ASIO_NOEXCEPT_IF((- call_traits<impl, T, void(Property)>::is_noexcept))+ >+ operator()(T&& t, Property&& p) const+ noexcept(call_traits<impl, T, void(Property)>::is_noexcept) {- return ASIO_MOVE_CAST(T)(t).query(ASIO_MOVE_CAST(Property)(p));+ return static_cast<T&&>(t).query(static_cast<Property&&>(p)); } template <typename T, typename Property>- ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if<+ ASIO_NODISCARD constexpr enable_if_t< call_traits<impl, T, void(Property)>::overload == call_free, typename call_traits<impl, T, void(Property)>::result_type- >::type- operator()(- ASIO_MOVE_ARG(T) t,- ASIO_MOVE_ARG(Property) p) const- ASIO_NOEXCEPT_IF((- call_traits<impl, T, void(Property)>::is_noexcept))+ >+ operator()(T&& t, Property&& p) const+ noexcept(call_traits<impl, T, void(Property)>::is_noexcept) {- return query(ASIO_MOVE_CAST(T)(t), ASIO_MOVE_CAST(Property)(p));+ return query(static_cast<T&&>(t), static_cast<Property&&>(p)); } }; @@ -270,7 +256,7 @@ namespace asio { namespace { -static ASIO_CONSTEXPR const asio_query_fn::impl&+static constexpr const asio_query_fn::impl& query = asio_query_fn::static_instance<>::instance; } // namespace@@ -288,8 +274,7 @@ #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) @@ -303,8 +288,7 @@ #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) @@ -314,6 +298,9 @@ 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/read.hpp view
@@ -2,7 +2,7 @@ // read.hpp // ~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -85,9 +85,9 @@ */ template <typename SyncReadStream, typename MutableBufferSequence> std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers,- typename constraint<+ constraint_t< is_mutable_buffer_sequence<MutableBufferSequence>::value- >::type = 0);+ > = 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,- typename constraint<+ constraint_t< is_mutable_buffer_sequence<MutableBufferSequence>::value- >::type = 0);+ > = 0); /// Attempt to read a certain amount of data from a stream before returning. /**@@ -182,9 +182,12 @@ typename CompletionCondition> std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers, CompletionCondition completion_condition,- typename constraint<+ constraint_t< is_mutable_buffer_sequence<MutableBufferSequence>::value- >::type = 0);+ > = 0,+ constraint_t<+ is_completion_condition<CompletionCondition>::value+ > = 0); /// Attempt to read a certain amount of data from a stream before returning. /**@@ -229,9 +232,12 @@ typename CompletionCondition> std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers, CompletionCondition completion_condition, asio::error_code& ec,- typename constraint<+ constraint_t< is_mutable_buffer_sequence<MutableBufferSequence>::value- >::type = 0);+ > = 0,+ constraint_t<+ is_completion_condition<CompletionCondition>::value+ > = 0); #if !defined(ASIO_NO_DYNAMIC_BUFFER_V1) @@ -264,13 +270,13 @@ */ template <typename SyncReadStream, typename DynamicBuffer_v1> std::size_t read(SyncReadStream& s,- 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);+ 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); /// Attempt to read a certain amount of data from a stream before returning. /**@@ -300,14 +306,14 @@ */ template <typename SyncReadStream, typename DynamicBuffer_v1> std::size_t read(SyncReadStream& s,- ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+ DynamicBuffer_v1&& buffers, 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);+ constraint_t<+ is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value+ > = 0,+ constraint_t<+ !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value+ > = 0); /// Attempt to read a certain amount of data from a stream before returning. /**@@ -348,14 +354,17 @@ template <typename SyncReadStream, typename DynamicBuffer_v1, typename CompletionCondition> std::size_t read(SyncReadStream& s,- ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+ DynamicBuffer_v1&& buffers, CompletionCondition completion_condition,- 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);+ 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); /// Attempt to read a certain amount of data from a stream before returning. /**@@ -397,14 +406,17 @@ template <typename SyncReadStream, typename DynamicBuffer_v1, typename CompletionCondition> std::size_t read(SyncReadStream& s,- ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+ DynamicBuffer_v1&& buffers, CompletionCondition completion_condition, 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);+ 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); #if !defined(ASIO_NO_EXTENSIONS) #if !defined(ASIO_NO_IOSTREAM)@@ -506,7 +518,10 @@ template <typename SyncReadStream, typename Allocator, typename CompletionCondition> std::size_t read(SyncReadStream& s, basic_streambuf<Allocator>& b,- CompletionCondition completion_condition);+ CompletionCondition completion_condition,+ constraint_t<+ is_completion_condition<CompletionCondition>::value+ > = 0); /// Attempt to read a certain amount of data from a stream before returning. /**@@ -547,7 +562,10 @@ template <typename SyncReadStream, typename Allocator, typename CompletionCondition> std::size_t read(SyncReadStream& s, basic_streambuf<Allocator>& b,- CompletionCondition completion_condition, asio::error_code& ec);+ CompletionCondition completion_condition, asio::error_code& ec,+ constraint_t<+ is_completion_condition<CompletionCondition>::value+ > = 0); #endif // !defined(ASIO_NO_IOSTREAM) #endif // !defined(ASIO_NO_EXTENSIONS)@@ -582,9 +600,9 @@ */ template <typename SyncReadStream, typename DynamicBuffer_v2> std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers,- typename constraint<+ constraint_t< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- >::type = 0);+ > = 0); /// Attempt to read a certain amount of data from a stream before returning. /**@@ -615,9 +633,9 @@ template <typename SyncReadStream, typename DynamicBuffer_v2> std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers, asio::error_code& ec,- typename constraint<+ constraint_t< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- >::type = 0);+ > = 0); /// Attempt to read a certain amount of data from a stream before returning. /**@@ -659,9 +677,12 @@ typename CompletionCondition> std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers, CompletionCondition completion_condition,- typename constraint<+ constraint_t< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- >::type = 0);+ > = 0,+ constraint_t<+ is_completion_condition<CompletionCondition>::value+ > = 0); /// Attempt to read a certain amount of data from a stream before returning. /**@@ -704,9 +725,12 @@ typename CompletionCondition> std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers, CompletionCondition completion_condition, asio::error_code& ec,- typename constraint<+ constraint_t< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- >::type = 0);+ > = 0,+ constraint_t<+ is_completion_condition<CompletionCondition>::value+ > = 0); /*@}*/ /**@@ -762,7 +786,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -795,23 +819,28 @@ */ template <typename AsyncReadStream, typename MutableBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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<+ 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< is_mutable_buffer_sequence<MutableBufferSequence>::value- >::type = 0)- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ > = 0,+ constraint_t<+ !is_completion_condition<ReadToken>::value+ > = 0)+ -> decltype( async_initiate<ReadToken, void (asio::error_code, std::size_t)>(- declval<detail::initiate_async_read<AsyncReadStream> >(),- token, buffers, transfer_all())));+ 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());+} /// Start an asynchronous operation to read a certain amount of data from a /// stream.@@ -866,7 +895,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -895,25 +924,30 @@ template <typename AsyncReadStream, typename MutableBufferSequence, typename CompletionCondition, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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,+ std::size_t)) ReadToken = default_completion_token_t<+ typename AsyncReadStream::executor_type>>+inline auto async_read(AsyncReadStream& s, const MutableBufferSequence& buffers, CompletionCondition completion_condition,- ASIO_MOVE_ARG(ReadToken) token- ASIO_DEFAULT_COMPLETION_TOKEN(- typename AsyncReadStream::executor_type),- typename constraint<+ ReadToken&& token = default_completion_token_t<+ typename AsyncReadStream::executor_type>(),+ constraint_t< is_mutable_buffer_sequence<MutableBufferSequence>::value- >::type = 0)- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ > = 0,+ constraint_t<+ is_completion_condition<CompletionCondition>::value+ > = 0)+ -> decltype( async_initiate<ReadToken, void (asio::error_code, std::size_t)>(- declval<detail::initiate_async_read<AsyncReadStream> >(),+ declval<detail::initiate_async_read<AsyncReadStream>>(), token, buffers,- ASIO_MOVE_CAST(CompletionCondition)(completion_condition))));+ 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));+} #if !defined(ASIO_NO_DYNAMIC_BUFFER_V1) @@ -961,7 +995,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -985,28 +1019,31 @@ */ template <typename AsyncReadStream, typename DynamicBuffer_v1, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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((+ 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( 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())));+ 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());+} /// Start an asynchronous operation to read a certain amount of data from a /// stream.@@ -1066,7 +1103,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -1085,29 +1122,34 @@ template <typename AsyncReadStream, typename DynamicBuffer_v1, typename CompletionCondition, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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,+ std::size_t)) ReadToken = default_completion_token_t<+ typename AsyncReadStream::executor_type>>+inline auto async_read(AsyncReadStream& s, DynamicBuffer_v1&& buffers, CompletionCondition completion_condition,- 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((+ 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( 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))));+ 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));+} #if !defined(ASIO_NO_EXTENSIONS) #if !defined(ASIO_NO_IOSTREAM)@@ -1154,7 +1196,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -1178,18 +1220,25 @@ */ template <typename AsyncReadStream, typename Allocator, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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))));+ 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());+} /// Start an asynchronous operation to read a certain amount of data from a /// stream.@@ -1247,7 +1296,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -1266,20 +1315,28 @@ template <typename AsyncReadStream, typename Allocator, typename CompletionCondition, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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,+ std::size_t)) ReadToken = default_completion_token_t<+ typename AsyncReadStream::executor_type>>+inline auto async_read(AsyncReadStream& s, basic_streambuf<Allocator>& b, 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))));+ 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));+} #endif // !defined(ASIO_NO_IOSTREAM) #endif // !defined(ASIO_NO_EXTENSIONS)@@ -1329,7 +1386,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -1353,24 +1410,28 @@ */ template <typename AsyncReadStream, typename DynamicBuffer_v2, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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<+ 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< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- >::type = 0)- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ > = 0,+ 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_v2<AsyncReadStream> >(),- token, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),- transfer_all())));+ 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());+} /// Start an asynchronous operation to read a certain amount of data from a /// stream.@@ -1430,7 +1491,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -1449,25 +1510,31 @@ template <typename AsyncReadStream, typename DynamicBuffer_v2, typename CompletionCondition, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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,+ std::size_t)) ReadToken = default_completion_token_t<+ typename AsyncReadStream::executor_type>>+inline auto async_read(AsyncReadStream& s, DynamicBuffer_v2 buffers, CompletionCondition completion_condition,- ASIO_MOVE_ARG(ReadToken) token- ASIO_DEFAULT_COMPLETION_TOKEN(- typename AsyncReadStream::executor_type),- typename constraint<+ ReadToken&& token = default_completion_token_t<+ typename AsyncReadStream::executor_type>(),+ constraint_t< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- >::type = 0)- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ > = 0,+ 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_v2<AsyncReadStream> >(),- token, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),- ASIO_MOVE_CAST(CompletionCondition)(completion_condition))));+ 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));+} /*@}*/
link/modules/asio-standalone/asio/include/asio/read_at.hpp view
@@ -2,7 +2,7 @@ // read_at.hpp // ~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -190,7 +190,10 @@ typename CompletionCondition> std::size_t read_at(SyncRandomAccessReadDevice& d, uint64_t offset, const MutableBufferSequence& buffers,- CompletionCondition completion_condition);+ CompletionCondition completion_condition,+ constraint_t<+ is_completion_condition<CompletionCondition>::value+ > = 0); /// Attempt to read a certain amount of data at the specified offset before /// returning.@@ -239,7 +242,10 @@ typename CompletionCondition> std::size_t read_at(SyncRandomAccessReadDevice& d, uint64_t offset, const MutableBufferSequence& buffers,- CompletionCondition completion_condition, asio::error_code& ec);+ CompletionCondition completion_condition, asio::error_code& ec,+ constraint_t<+ is_completion_condition<CompletionCondition>::value+ > = 0); #if !defined(ASIO_NO_EXTENSIONS) #if !defined(ASIO_NO_IOSTREAM)@@ -350,7 +356,10 @@ typename CompletionCondition> std::size_t read_at(SyncRandomAccessReadDevice& d, uint64_t offset, basic_streambuf<Allocator>& b,- CompletionCondition completion_condition);+ CompletionCondition completion_condition,+ constraint_t<+ is_completion_condition<CompletionCondition>::value+ > = 0); /// Attempt to read a certain amount of data at the specified offset before /// returning.@@ -394,7 +403,10 @@ typename CompletionCondition> std::size_t read_at(SyncRandomAccessReadDevice& d, uint64_t offset, basic_streambuf<Allocator>& b,- CompletionCondition completion_condition, asio::error_code& ec);+ CompletionCondition completion_condition, asio::error_code& ec,+ constraint_t<+ is_completion_condition<CompletionCondition>::value+ > = 0); #endif // !defined(ASIO_NO_IOSTREAM) #endif // !defined(ASIO_NO_EXTENSIONS)@@ -453,7 +465,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -486,21 +498,26 @@ */ template <typename AsyncRandomAccessReadDevice, typename MutableBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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((+ 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( async_initiate<ReadToken, void (asio::error_code, std::size_t)>(- declval<detail::initiate_async_read_at<AsyncRandomAccessReadDevice> >(),- token, offset, buffers, transfer_all())));+ 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());+} /// Start an asynchronous operation to read a certain amount of data at the /// specified offset.@@ -558,7 +575,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -587,23 +604,29 @@ template <typename AsyncRandomAccessReadDevice, typename MutableBufferSequence, typename CompletionCondition, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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,+ 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, CompletionCondition completion_condition,- ASIO_MOVE_ARG(ReadToken) token- ASIO_DEFAULT_COMPLETION_TOKEN(- typename AsyncRandomAccessReadDevice::executor_type))- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ ReadToken&& token = default_completion_token_t<+ typename AsyncRandomAccessReadDevice::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_at<AsyncRandomAccessReadDevice> >(),+ declval<detail::initiate_async_read_at<AsyncRandomAccessReadDevice>>(), token, offset, buffers,- ASIO_MOVE_CAST(CompletionCondition)(completion_condition))));+ 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));+} #if !defined(ASIO_NO_EXTENSIONS) #if !defined(ASIO_NO_IOSTREAM)@@ -648,7 +671,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -672,22 +695,27 @@ */ template <typename AsyncRandomAccessReadDevice, typename Allocator, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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,+ 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,- ASIO_MOVE_ARG(ReadToken) token- ASIO_DEFAULT_COMPLETION_TOKEN(- typename AsyncRandomAccessReadDevice::executor_type))- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ ReadToken&& token = default_completion_token_t<+ typename AsyncRandomAccessReadDevice::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_at_streambuf<- AsyncRandomAccessReadDevice> >(),- token, offset, &b, transfer_all())));+ 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());+} /// Start an asynchronous operation to read a certain amount of data at the /// specified offset.@@ -743,7 +771,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -762,24 +790,29 @@ template <typename AsyncRandomAccessReadDevice, typename Allocator, typename CompletionCondition, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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((+ 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( async_initiate<ReadToken, void (asio::error_code, std::size_t)>( declval<detail::initiate_async_read_at_streambuf<- AsyncRandomAccessReadDevice> >(),+ AsyncRandomAccessReadDevice>>(), token, offset, &b,- ASIO_MOVE_CAST(CompletionCondition)(completion_condition))));+ 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));+} #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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -73,8 +73,7 @@ #else enum {- value = asio::is_function<- typename asio::remove_pointer<T>::type>::value+ value = asio::is_function<remove_pointer_t<T>>::value || detail::has_result_type<T>::value }; #endif@@ -147,13 +146,13 @@ */ template <typename SyncReadStream, typename DynamicBuffer_v1> 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 = 0,- typename constraint<- !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value- >::type = 0);+ 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); /// Read data into a dynamic buffer sequence until it contains a specified /// delimiter.@@ -191,14 +190,14 @@ */ template <typename SyncReadStream, typename DynamicBuffer_v1> std::size_t read_until(SyncReadStream& s,- ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+ DynamicBuffer_v1&& buffers, char delim, 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);+ constraint_t<+ is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value+ > = 0,+ constraint_t<+ !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value+ > = 0); /// Read data into a dynamic buffer sequence until it contains a specified /// delimiter.@@ -253,14 +252,14 @@ */ template <typename SyncReadStream, typename DynamicBuffer_v1> std::size_t read_until(SyncReadStream& s,- ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+ DynamicBuffer_v1&& buffers, ASIO_STRING_VIEW_PARAM 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);+ constraint_t<+ is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value+ > = 0,+ constraint_t<+ !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value+ > = 0); /// Read data into a dynamic buffer sequence until it contains a specified /// delimiter.@@ -298,15 +297,15 @@ */ template <typename SyncReadStream, typename DynamicBuffer_v1> std::size_t read_until(SyncReadStream& s,- ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+ 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 = 0,- typename constraint<- !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value- >::type = 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); #if !defined(ASIO_NO_EXTENSIONS) #if defined(ASIO_HAS_BOOST_REGEX) \@@ -366,16 +365,15 @@ * 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>-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);+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); /// Read data into a dynamic buffer sequence until some part of the data it /// contains matches a regular expression.@@ -413,16 +411,15 @@ * 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>-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);+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); #endif // defined(ASIO_HAS_BOOST_REGEX) // || defined(GENERATING_DOCUMENTATION)@@ -483,7 +480,7 @@ * @par Examples * To read data into a dynamic buffer sequence until whitespace is encountered: * @code typedef asio::buffers_iterator<- * asio::const_buffers_1> iterator;+ * asio::const_buffer> iterator; * * std::pair<iterator, bool> * match_whitespace(iterator begin, iterator end)@@ -532,17 +529,17 @@ template <typename SyncReadStream, typename DynamicBuffer_v1, typename MatchCondition> std::size_t read_until(SyncReadStream& s,- ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+ DynamicBuffer_v1&& buffers, MatchCondition match_condition,- typename constraint<+ constraint_t< is_match_condition<MatchCondition>::value- >::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);+ > = 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); /// Read data into a dynamic buffer sequence until a function object indicates a /// match.@@ -600,17 +597,17 @@ template <typename SyncReadStream, typename DynamicBuffer_v1, typename MatchCondition> std::size_t read_until(SyncReadStream& s,- ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+ DynamicBuffer_v1&& buffers, MatchCondition match_condition, asio::error_code& ec,- typename constraint<+ constraint_t< is_match_condition<MatchCondition>::value- >::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);+ > = 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); #if !defined(ASIO_NO_IOSTREAM) @@ -842,9 +839,10 @@ * 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>+template <typename SyncReadStream, typename Allocator, typename Traits> std::size_t read_until(SyncReadStream& s,- asio::basic_streambuf<Allocator>& b, const boost::regex& expr);+ asio::basic_streambuf<Allocator>& b,+ const boost::basic_regex<char, Traits>& expr); /// Read data into a streambuf until some part of the data it contains matches /// a regular expression.@@ -879,9 +877,10 @@ * application will typically leave that data in the streambuf for a subsequent * read_until operation to examine. */-template <typename SyncReadStream, typename Allocator>+template <typename SyncReadStream, typename Allocator, typename Traits> std::size_t read_until(SyncReadStream& s,- asio::basic_streambuf<Allocator>& b, const boost::regex& expr,+ asio::basic_streambuf<Allocator>& b,+ const boost::basic_regex<char, Traits>& expr, asio::error_code& ec); #endif // defined(ASIO_HAS_BOOST_REGEX)@@ -990,7 +989,7 @@ template <typename SyncReadStream, typename Allocator, typename MatchCondition> std::size_t read_until(SyncReadStream& s, asio::basic_streambuf<Allocator>& b, MatchCondition match_condition,- typename constraint<is_match_condition<MatchCondition>::value>::type = 0);+ constraint_t<is_match_condition<MatchCondition>::value> = 0); /// Read data into a streambuf until a function object indicates a match. /**@@ -1047,7 +1046,7 @@ 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 = 0);+ constraint_t<is_match_condition<MatchCondition>::value> = 0); #endif // !defined(ASIO_NO_IOSTREAM) #endif // !defined(ASIO_NO_EXTENSIONS)@@ -1108,9 +1107,9 @@ */ template <typename SyncReadStream, typename DynamicBuffer_v2> std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers, char delim,- typename constraint<+ constraint_t< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- >::type = 0);+ > = 0); /// Read data into a dynamic buffer sequence until it contains a specified /// delimiter.@@ -1149,9 +1148,9 @@ template <typename SyncReadStream, typename DynamicBuffer_v2> std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers, char delim, asio::error_code& ec,- typename constraint<+ constraint_t< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- >::type = 0);+ > = 0); /// Read data into a dynamic buffer sequence until it contains a specified /// delimiter.@@ -1207,9 +1206,9 @@ template <typename SyncReadStream, typename DynamicBuffer_v2> std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers, ASIO_STRING_VIEW_PARAM delim,- typename constraint<+ constraint_t< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- >::type = 0);+ > = 0); /// Read data into a dynamic buffer sequence until it contains a specified /// delimiter.@@ -1248,9 +1247,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,- typename constraint<+ constraint_t< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- >::type = 0);+ > = 0); #if !defined(ASIO_NO_EXTENSIONS) #if defined(ASIO_HAS_BOOST_REGEX) \@@ -1310,12 +1309,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>+template <typename SyncReadStream, typename DynamicBuffer_v2, typename Traits> std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers,- const boost::regex& expr,- typename constraint<+ const boost::basic_regex<char, Traits>& expr,+ constraint_t< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- >::type = 0);+ > = 0); /// Read data into a dynamic buffer sequence until some part of the data it /// contains matches a regular expression.@@ -1353,12 +1352,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>+template <typename SyncReadStream, typename DynamicBuffer_v2, typename Traits> std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers,- const boost::regex& expr, asio::error_code& ec,- typename constraint<+ const boost::basic_regex<char, Traits>& expr, asio::error_code& ec,+ constraint_t< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- >::type = 0);+ > = 0); #endif // defined(ASIO_HAS_BOOST_REGEX) // || defined(GENERATING_DOCUMENTATION)@@ -1419,7 +1418,7 @@ * @par Examples * To read data into a dynamic buffer sequence until whitespace is encountered: * @code typedef asio::buffers_iterator<- * asio::const_buffers_1> iterator;+ * asio::const_buffer> iterator; * * std::pair<iterator, bool> * match_whitespace(iterator begin, iterator end)@@ -1469,12 +1468,12 @@ typename DynamicBuffer_v2, typename MatchCondition> std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers, MatchCondition match_condition,- typename constraint<+ constraint_t< is_match_condition<MatchCondition>::value- >::type = 0,- typename constraint<+ > = 0,+ constraint_t< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- >::type = 0);+ > = 0); /// Read data into a dynamic buffer sequence until a function object indicates a /// match.@@ -1533,12 +1532,12 @@ typename DynamicBuffer_v2, typename MatchCondition> std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers, MatchCondition match_condition, asio::error_code& ec,- typename constraint<+ constraint_t< is_match_condition<MatchCondition>::value- >::type = 0,- typename constraint<+ > = 0,+ constraint_t< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- >::type = 0);+ > = 0); #endif // !defined(ASIO_NO_EXTENSIONS) @@ -1603,7 +1602,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -1654,27 +1653,29 @@ */ template <typename AsyncReadStream, typename DynamicBuffer_v1, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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((+ 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( 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)));+ 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);+} /// Start an asynchronous operation to read data into a dynamic buffer sequence /// until it contains a specified delimiter.@@ -1724,7 +1725,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -1775,30 +1776,33 @@ */ template <typename AsyncReadStream, typename DynamicBuffer_v1, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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,+ std::size_t)) ReadToken = default_completion_token_t<+ typename AsyncReadStream::executor_type>>+inline auto async_read_until(AsyncReadStream& s,+ DynamicBuffer_v1&& buffers, ASIO_STRING_VIEW_PARAM 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((+ 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( 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))));+ 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));+} #if !defined(ASIO_NO_EXTENSIONS) #if defined(ASIO_HAS_BOOST_REGEX) \@@ -1856,7 +1860,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -1906,30 +1910,31 @@ * if they are also supported by the @c AsyncReadStream type's * @c async_read_some operation. */-template <typename AsyncReadStream, typename DynamicBuffer_v1,+template <typename AsyncReadStream, typename DynamicBuffer_v1, typename Traits, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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((+ 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( 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)));+ 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);+} #endif // defined(ASIO_HAS_BOOST_REGEX) // || defined(GENERATING_DOCUMENTATION)@@ -1997,7 +2002,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::post().+ * manner equivalent to using asio::async_immediate(). * * @note After a successful async_read_until operation, the dynamic buffer * sequence may contain additional data beyond that which matched the function@@ -2016,7 +2021,7 @@ * To asynchronously read data into a @c std::string until whitespace is * encountered: * @code typedef asio::buffers_iterator<- * asio::const_buffers_1> iterator;+ * asio::const_buffer> iterator; * * std::pair<iterator, bool> * match_whitespace(iterator begin, iterator end)@@ -2081,32 +2086,34 @@ template <typename AsyncReadStream, typename DynamicBuffer_v1, typename MatchCondition, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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<+ 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< is_match_condition<MatchCondition>::value- >::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((+ > = 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( 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)));+ 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);+} #if !defined(ASIO_NO_IOSTREAM) @@ -2157,7 +2164,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -2207,19 +2214,23 @@ */ template <typename AsyncReadStream, typename Allocator, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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,+ std::size_t)) ReadToken = default_completion_token_t<+ typename AsyncReadStream::executor_type>>+inline auto async_read_until(AsyncReadStream& s, asio::basic_streambuf<Allocator>& b, char 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))));+ 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);+} /// Start an asynchronous operation to read data into a streambuf until it /// contains a specified delimiter.@@ -2268,7 +2279,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -2318,20 +2329,27 @@ */ template <typename AsyncReadStream, typename Allocator, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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,+ std::size_t)) ReadToken = default_completion_token_t<+ typename AsyncReadStream::executor_type>>+inline auto async_read_until(AsyncReadStream& s, asio::basic_streambuf<Allocator>& b, ASIO_STRING_VIEW_PARAM 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))));+ 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));+} #if defined(ASIO_HAS_BOOST_REGEX) \ || defined(GENERATING_DOCUMENTATION)@@ -2385,7 +2403,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -2434,21 +2452,26 @@ * if they are also supported by the @c AsyncReadStream type's * @c async_read_some operation. */-template <typename AsyncReadStream, typename Allocator,+template <typename AsyncReadStream, typename Allocator, typename Traits, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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))));+ 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);+} #endif // defined(ASIO_HAS_BOOST_REGEX) // || defined(GENERATING_DOCUMENTATION)@@ -2513,7 +2536,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::post().+ * manner equivalent to using asio::async_immediate(). * * @note After a successful async_read_until operation, the streambuf may * contain additional data beyond that which matched the function object. An@@ -2595,21 +2618,24 @@ */ template <typename AsyncReadStream, typename Allocator, typename MatchCondition, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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))));+ 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);+} #endif // !defined(ASIO_NO_IOSTREAM) #endif // !defined(ASIO_NO_EXTENSIONS)@@ -2664,7 +2690,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -2715,23 +2741,26 @@ */ template <typename AsyncReadStream, typename DynamicBuffer_v2, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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<+ 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< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- >::type = 0)- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ > = 0)+ -> decltype( 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)));+ 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);+} /// Start an asynchronous operation to read data into a dynamic buffer sequence /// until it contains a specified delimiter.@@ -2781,7 +2810,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -2832,26 +2861,29 @@ */ template <typename AsyncReadStream, typename DynamicBuffer_v2, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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,+ std::size_t)) ReadToken = default_completion_token_t<+ typename AsyncReadStream::executor_type>>+inline auto async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers, ASIO_STRING_VIEW_PARAM delim,- ASIO_MOVE_ARG(ReadToken) token- ASIO_DEFAULT_COMPLETION_TOKEN(- typename AsyncReadStream::executor_type),- typename constraint<+ ReadToken&& token = default_completion_token_t<+ typename AsyncReadStream::executor_type>(),+ constraint_t< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- >::type = 0)- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ > = 0)+ -> decltype( 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))));+ 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));+} #if !defined(ASIO_NO_EXTENSIONS) #if defined(ASIO_HAS_BOOST_REGEX) \@@ -2909,7 +2941,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -2959,26 +2991,28 @@ * if they are also supported by the @c AsyncReadStream type's * @c async_read_some operation. */-template <typename AsyncReadStream, typename DynamicBuffer_v2,+template <typename AsyncReadStream, typename DynamicBuffer_v2, typename Traits, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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<+ 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< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- >::type = 0)- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ > = 0)+ -> decltype( 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)));+ 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);+} #endif // defined(ASIO_HAS_BOOST_REGEX) // || defined(GENERATING_DOCUMENTATION)@@ -3046,7 +3080,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::post().+ * manner equivalent to using asio::async_immediate(). * * @note After a successful async_read_until operation, the dynamic buffer * sequence may contain additional data beyond that which matched the function@@ -3065,7 +3099,7 @@ * To asynchronously read data into a @c std::string until whitespace is * encountered: * @code typedef asio::buffers_iterator<- * asio::const_buffers_1> iterator;+ * asio::const_buffer> iterator; * * std::pair<iterator, bool> * match_whitespace(iterator begin, iterator end)@@ -3130,28 +3164,30 @@ template <typename AsyncReadStream, typename DynamicBuffer_v2, typename MatchCondition, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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<+ 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< is_match_condition<MatchCondition>::value- >::type = 0,- typename constraint<+ > = 0,+ constraint_t< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- >::type = 0)- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ > = 0)+ -> decltype( 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)));+ 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);+} #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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/recycling_allocator.hpp view
@@ -2,7 +2,7 @@ // recycling_allocator.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -44,27 +44,27 @@ }; /// Default constructor.- ASIO_CONSTEXPR recycling_allocator() ASIO_NOEXCEPT+ constexpr recycling_allocator() noexcept { } /// Converting constructor. template <typename U>- ASIO_CONSTEXPR recycling_allocator(- const recycling_allocator<U>&) ASIO_NOEXCEPT+ constexpr recycling_allocator(+ const recycling_allocator<U>&) noexcept { } /// Equality operator. Always returns true.- ASIO_CONSTEXPR bool operator==(- const recycling_allocator&) const ASIO_NOEXCEPT+ constexpr bool operator==(+ const recycling_allocator&) const noexcept { return true; } /// Inequality operator. Always returns false.- ASIO_CONSTEXPR bool operator!=(- const recycling_allocator&) const ASIO_NOEXCEPT+ constexpr bool operator!=(+ const recycling_allocator&) const noexcept { return false; }@@ -105,27 +105,27 @@ }; /// Default constructor.- ASIO_CONSTEXPR recycling_allocator() ASIO_NOEXCEPT+ constexpr recycling_allocator() noexcept { } /// Converting constructor. template <typename U>- ASIO_CONSTEXPR recycling_allocator(- const recycling_allocator<U>&) ASIO_NOEXCEPT+ constexpr recycling_allocator(+ const recycling_allocator<U>&) noexcept { } /// Equality operator. Always returns true.- ASIO_CONSTEXPR bool operator==(- const recycling_allocator&) const ASIO_NOEXCEPT+ constexpr bool operator==(+ const recycling_allocator&) const noexcept { return true; } /// Inequality operator. Always returns false.- ASIO_CONSTEXPR bool operator!=(- const recycling_allocator&) const ASIO_NOEXCEPT+ constexpr bool operator!=(+ const recycling_allocator&) const noexcept { return false; }
link/modules/asio-standalone/asio/include/asio/redirect_error.hpp view
@@ -2,7 +2,7 @@ // redirect_error.hpp // ~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -33,11 +33,10 @@ class redirect_error_t { public:- /// Constructor. + /// Constructor. template <typename T>- redirect_error_t(ASIO_MOVE_ARG(T) completion_token,- asio::error_code& ec)- : token_(ASIO_MOVE_CAST(T)(completion_token)),+ redirect_error_t(T&& completion_token, asio::error_code& ec)+ : token_(static_cast<T&&>(completion_token)), ec_(ec) { }@@ -47,14 +46,53 @@ 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>-inline redirect_error_t<typename decay<CompletionToken>::type> redirect_error(- ASIO_MOVE_ARG(CompletionToken) completion_token,+ASIO_NODISCARD inline redirect_error_t<decay_t<CompletionToken>>+redirect_error(CompletionToken&& completion_token, asio::error_code& ec) {- return redirect_error_t<typename decay<CompletionToken>::type>(- ASIO_MOVE_CAST(CompletionToken)(completion_token), ec);+ return redirect_error_t<decay_t<CompletionToken>>(+ static_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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -37,28 +37,28 @@ typedef int native_handle_type; /// Default constructor creates an invalid registered buffer identifier.- registered_buffer_id() ASIO_NOEXCEPT+ registered_buffer_id() noexcept : scope_(0), index_(-1) { } /// Get the native buffer identifier type.- native_handle_type native_handle() const ASIO_NOEXCEPT+ native_handle_type native_handle() const noexcept { return index_; } /// Compare two IDs for equality. friend bool operator==(const registered_buffer_id& lhs,- const registered_buffer_id& rhs) ASIO_NOEXCEPT+ const registered_buffer_id& rhs) 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) ASIO_NOEXCEPT+ const registered_buffer_id& rhs) 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) ASIO_NOEXCEPT+ registered_buffer_id(const void* scope, int index) noexcept : scope_(scope), index_(index) {@@ -78,27 +78,21 @@ }; /// 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() ASIO_NOEXCEPT+ mutable_registered_buffer() noexcept : buffer_(), id_() { } /// Get the underlying mutable buffer.- const mutable_buffer& buffer() const ASIO_NOEXCEPT+ const mutable_buffer& buffer() const noexcept { return buffer_; }@@ -107,7 +101,7 @@ /** * @returns <tt>buffer().data()</tt>. */- void* data() const ASIO_NOEXCEPT+ void* data() const noexcept { return buffer_.data(); }@@ -116,19 +110,19 @@ /** * @returns <tt>buffer().size()</tt>. */- std::size_t size() const ASIO_NOEXCEPT+ std::size_t size() const noexcept { return buffer_.size(); } /// Get the registered buffer identifier.- const registered_buffer_id& id() const ASIO_NOEXCEPT+ const registered_buffer_id& id() const noexcept { return id_; } /// Move the start of the buffer by the specified number of bytes.- mutable_registered_buffer& operator+=(std::size_t n) ASIO_NOEXCEPT+ mutable_registered_buffer& operator+=(std::size_t n) noexcept { buffer_ += n; return *this;@@ -139,7 +133,7 @@ // Hidden constructor used by buffer registration and operators. mutable_registered_buffer(const mutable_buffer& b,- const registered_buffer_id& i) ASIO_NOEXCEPT+ const registered_buffer_id& i) noexcept : buffer_(b), id_(i) {@@ -147,7 +141,7 @@ #if !defined(GENERATING_DOCUMENTATION) friend mutable_registered_buffer buffer(- const mutable_registered_buffer& b, std::size_t n) ASIO_NOEXCEPT;+ const mutable_registered_buffer& b, std::size_t n) noexcept; #endif // !defined(GENERATING_DOCUMENTATION) mutable_buffer buffer_;@@ -155,20 +149,14 @@ }; /// 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() ASIO_NOEXCEPT+ const_registered_buffer() noexcept : buffer_(), id_() {@@ -176,14 +164,14 @@ /// Construct a non-modifiable buffer from a modifiable one. const_registered_buffer(- const mutable_registered_buffer& b) ASIO_NOEXCEPT+ const mutable_registered_buffer& b) noexcept : buffer_(b.buffer()), id_(b.id()) { } /// Get the underlying constant buffer.- const const_buffer& buffer() const ASIO_NOEXCEPT+ const const_buffer& buffer() const noexcept { return buffer_; }@@ -192,7 +180,7 @@ /** * @returns <tt>buffer().data()</tt>. */- const void* data() const ASIO_NOEXCEPT+ const void* data() const noexcept { return buffer_.data(); }@@ -201,19 +189,19 @@ /** * @returns <tt>buffer().size()</tt>. */- std::size_t size() const ASIO_NOEXCEPT+ std::size_t size() const noexcept { return buffer_.size(); } /// Get the registered buffer identifier.- const registered_buffer_id& id() const ASIO_NOEXCEPT+ const registered_buffer_id& id() const noexcept { return id_; } /// Move the start of the buffer by the specified number of bytes.- const_registered_buffer& operator+=(std::size_t n) ASIO_NOEXCEPT+ const_registered_buffer& operator+=(std::size_t n) noexcept { buffer_ += n; return *this;@@ -222,7 +210,7 @@ private: // Hidden constructor used by operators. const_registered_buffer(const const_buffer& b,- const registered_buffer_id& i) ASIO_NOEXCEPT+ const registered_buffer_id& i) noexcept : buffer_(b), id_(i) {@@ -230,7 +218,7 @@ #if !defined(GENERATING_DOCUMENTATION) friend const_registered_buffer buffer(- const const_registered_buffer& b, std::size_t n) ASIO_NOEXCEPT;+ const const_registered_buffer& b, std::size_t n) noexcept; #endif // !defined(GENERATING_DOCUMENTATION) const_buffer buffer_;@@ -241,14 +229,14 @@ /// Get an iterator to the first element in a buffer sequence. inline const mutable_buffer* buffer_sequence_begin(- const mutable_registered_buffer& b) ASIO_NOEXCEPT+ const mutable_registered_buffer& b) 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) ASIO_NOEXCEPT+ const const_registered_buffer& b) noexcept { return &b.buffer(); }@@ -258,14 +246,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) ASIO_NOEXCEPT+ const mutable_registered_buffer& b) 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) ASIO_NOEXCEPT+ const const_registered_buffer& b) noexcept { return &b.buffer() + 1; }@@ -275,28 +263,28 @@ /// Obtain a buffer representing the entire registered buffer. inline mutable_registered_buffer buffer(- const mutable_registered_buffer& b) ASIO_NOEXCEPT+ const mutable_registered_buffer& b) noexcept { return b; } /// Obtain a buffer representing the entire registered buffer. inline const_registered_buffer buffer(- const const_registered_buffer& b) ASIO_NOEXCEPT+ const const_registered_buffer& b) 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) ASIO_NOEXCEPT+ const mutable_registered_buffer& b, std::size_t n) 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) ASIO_NOEXCEPT+ const const_registered_buffer& b, std::size_t n) noexcept { return const_registered_buffer(buffer(b.buffer_, n), b.id_); }@@ -309,7 +297,7 @@ * @relates mutable_registered_buffer */ inline mutable_registered_buffer operator+(- const mutable_registered_buffer& b, std::size_t n) ASIO_NOEXCEPT+ const mutable_registered_buffer& b, std::size_t n) noexcept { mutable_registered_buffer tmp(b); tmp += n;@@ -321,7 +309,7 @@ * @relates mutable_registered_buffer */ inline mutable_registered_buffer operator+(std::size_t n,- const mutable_registered_buffer& b) ASIO_NOEXCEPT+ const mutable_registered_buffer& b) noexcept { return b + n; }@@ -332,7 +320,7 @@ * @relates const_registered_buffer */ inline const_registered_buffer operator+(const const_registered_buffer& b,- std::size_t n) ASIO_NOEXCEPT+ std::size_t n) noexcept { const_registered_buffer tmp(b); tmp += n;@@ -344,7 +332,7 @@ * @relates const_registered_buffer */ inline const_registered_buffer operator+(std::size_t n,- const const_registered_buffer& b) ASIO_NOEXCEPT+ const const_registered_buffer& b) noexcept { return b + n; }
link/modules/asio-standalone/asio/include/asio/require.hpp view
@@ -2,7 +2,7 @@ // require.hpp // ~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -107,10 +107,10 @@ namespace asio_require_fn { -using asio::conditional;-using asio::decay;+using asio::conditional_t;+using asio::decay_t; using asio::declval;-using asio::enable_if;+using asio::enable_if_t; using asio::is_applicable_property; using asio::traits::require_free; using asio::traits::require_member;@@ -132,99 +132,95 @@ 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);+ static constexpr overload_type overload = ill_formed;+ static constexpr bool is_noexcept = false; typedef void result_type; }; template <typename Impl, typename T, typename Property> struct call_traits<Impl, T, void(Property),- typename enable_if<+ enable_if_t< is_applicable_property<- typename decay<T>::type,- typename decay<Property>::type+ decay_t<T>,+ decay_t<Property> >::value- >::type,- typename enable_if<- decay<Property>::type::is_requirable- >::type,- typename enable_if<+ >,+ enable_if_t<+ decay_t<Property>::is_requirable+ >,+ enable_if_t< static_require<T, Property>::is_valid- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(overload_type, overload = identity);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr overload_type overload = identity;+ static constexpr bool is_noexcept = true; -#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)+ typedef T&& result_type; }; template <typename Impl, typename T, typename Property> struct call_traits<Impl, T, void(Property),- typename enable_if<+ enable_if_t< is_applicable_property<- typename decay<T>::type,- typename decay<Property>::type+ decay_t<T>,+ decay_t<Property> >::value- >::type,- typename enable_if<- decay<Property>::type::is_requirable- >::type,- typename enable_if<+ >,+ enable_if_t<+ decay_t<Property>::is_requirable+ >,+ enable_if_t< !static_require<T, Property>::is_valid- >::type,- typename enable_if<+ >,+ enable_if_t< require_member<typename Impl::template proxy<T>::type, Property>::is_valid- >::type> :+ >> : require_member<typename Impl::template proxy<T>::type, Property> {- ASIO_STATIC_CONSTEXPR(overload_type, overload = call_member);+ static constexpr overload_type overload = call_member; }; template <typename Impl, typename T, typename Property> struct call_traits<Impl, T, void(Property),- typename enable_if<+ enable_if_t< is_applicable_property<- typename decay<T>::type,- typename decay<Property>::type+ decay_t<T>,+ decay_t<Property> >::value- >::type,- typename enable_if<- decay<Property>::type::is_requirable- >::type,- typename enable_if<+ >,+ enable_if_t<+ decay_t<Property>::is_requirable+ >,+ enable_if_t< !static_require<T, Property>::is_valid- >::type,- typename enable_if<+ >,+ enable_if_t< !require_member<typename Impl::template proxy<T>::type, Property>::is_valid- >::type,- typename enable_if<+ >,+ enable_if_t< require_free<T, Property>::is_valid- >::type> :+ >> : require_free<T, Property> {- ASIO_STATIC_CONSTEXPR(overload_type, overload = call_free);+ static constexpr overload_type overload = call_free; }; template <typename Impl, typename T, typename P0, typename P1> struct call_traits<Impl, T, void(P0, P1),- typename enable_if<+ enable_if_t< call_traits<Impl, T, void(P0)>::overload != ill_formed- >::type,- typename enable_if<+ >,+ enable_if_t< call_traits< Impl, typename call_traits<Impl, T, void(P0)>::result_type, void(P1) >::overload != ill_formed- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(overload_type, overload = two_props);+ static constexpr overload_type overload = two_props; - ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+ static constexpr bool is_noexcept = ( call_traits<Impl, T, void(P0)>::is_noexcept &&@@ -233,51 +229,51 @@ typename call_traits<Impl, T, void(P0)>::result_type, void(P1) >::is_noexcept- ));+ ); - typedef typename decay<+ typedef decay_t< typename call_traits< Impl, typename call_traits<Impl, T, void(P0)>::result_type, void(P1) >::result_type- >::type result_type;+ > result_type; }; template <typename Impl, typename T, typename P0,- typename P1, typename ASIO_ELLIPSIS PN>-struct call_traits<Impl, T, void(P0, P1, PN ASIO_ELLIPSIS),- typename enable_if<+ typename P1, typename... PN>+struct call_traits<Impl, T, void(P0, P1, PN...),+ enable_if_t< call_traits<Impl, T, void(P0)>::overload != ill_formed- >::type,- typename enable_if<+ >,+ enable_if_t< call_traits< Impl, typename call_traits<Impl, T, void(P0)>::result_type,- void(P1, PN ASIO_ELLIPSIS)+ void(P1, PN...) >::overload != ill_formed- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(overload_type, overload = n_props);+ static constexpr overload_type overload = n_props; - ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+ 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 ASIO_ELLIPSIS)+ void(P1, PN...) >::is_noexcept- ));+ ); - typedef typename decay<+ typedef decay_t< typename call_traits< Impl, typename call_traits<Impl, T, void(P0)>::result_type,- void(P1, PN ASIO_ELLIPSIS)+ void(P1, PN...) >::result_type- >::type result_type;+ > result_type; }; struct impl@@ -289,16 +285,14 @@ struct type { template <typename P>- auto require(ASIO_MOVE_ARG(P) p)+ auto require(P&& p) noexcept( noexcept(- declval<typename conditional<true, T, P>::type>().require(- ASIO_MOVE_CAST(P)(p))+ declval<conditional_t<true, T, P>>().require(static_cast<P&&>(p)) ) ) -> decltype(- declval<typename conditional<true, T, P>::type>().require(- ASIO_MOVE_CAST(P)(p))+ declval<conditional_t<true, T, P>>().require(static_cast<P&&>(p)) ); }; #else // defined(ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)@@ -307,91 +301,63 @@ }; template <typename T, typename Property>- ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if<+ ASIO_NODISCARD constexpr enable_if_t< call_traits<impl, T, void(Property)>::overload == identity, typename call_traits<impl, T, void(Property)>::result_type- >::type- operator()(- ASIO_MOVE_ARG(T) t,- ASIO_MOVE_ARG(Property)) const- ASIO_NOEXCEPT_IF((- call_traits<impl, T, void(Property)>::is_noexcept))+ >+ operator()(T&& t, Property&&) const+ noexcept(call_traits<impl, T, void(Property)>::is_noexcept) {- return ASIO_MOVE_CAST(T)(t);+ return static_cast<T&&>(t); } template <typename T, typename Property>- ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if<+ ASIO_NODISCARD constexpr enable_if_t< call_traits<impl, T, void(Property)>::overload == call_member, typename call_traits<impl, T, void(Property)>::result_type- >::type- operator()(- ASIO_MOVE_ARG(T) t,- ASIO_MOVE_ARG(Property) p) const- ASIO_NOEXCEPT_IF((- call_traits<impl, T, void(Property)>::is_noexcept))+ >+ operator()(T&& t, Property&& p) const+ noexcept(call_traits<impl, T, void(Property)>::is_noexcept) {- return ASIO_MOVE_CAST(T)(t).require(- ASIO_MOVE_CAST(Property)(p));+ return static_cast<T&&>(t).require(static_cast<Property&&>(p)); } template <typename T, typename Property>- ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if<+ ASIO_NODISCARD constexpr enable_if_t< call_traits<impl, T, void(Property)>::overload == call_free, typename call_traits<impl, T, void(Property)>::result_type- >::type- operator()(- ASIO_MOVE_ARG(T) t,- ASIO_MOVE_ARG(Property) p) const- ASIO_NOEXCEPT_IF((- call_traits<impl, T, void(Property)>::is_noexcept))+ >+ operator()(T&& t, Property&& p) const+ noexcept(call_traits<impl, T, void(Property)>::is_noexcept) {- return require(- ASIO_MOVE_CAST(T)(t),- ASIO_MOVE_CAST(Property)(p));+ return require(static_cast<T&&>(t), static_cast<Property&&>(p)); } template <typename T, typename P0, typename P1>- ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if<+ ASIO_NODISCARD constexpr enable_if_t< call_traits<impl, T, void(P0, P1)>::overload == two_props, typename call_traits<impl, T, void(P0, P1)>::result_type- >::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))+ >+ operator()(T&& t, P0&& p0, P1&& p1) const+ noexcept(call_traits<impl, T, void(P0, P1)>::is_noexcept) { return (*this)(- (*this)(- ASIO_MOVE_CAST(T)(t),- ASIO_MOVE_CAST(P0)(p0)),- ASIO_MOVE_CAST(P1)(p1));+ (*this)(static_cast<T&&>(t), static_cast<P0&&>(p0)),+ static_cast<P1&&>(p1)); } template <typename T, typename P0, typename P1,- 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))+ 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) { return (*this)(- (*this)(- ASIO_MOVE_CAST(T)(t),- ASIO_MOVE_CAST(P0)(p0)),- ASIO_MOVE_CAST(P1)(p1),- ASIO_MOVE_CAST(PN)(pn) ASIO_ELLIPSIS);+ (*this)(static_cast<T&&>(t), static_cast<P0&&>(p0)),+ static_cast<P1&&>(p1), static_cast<PN&&>(pn)...); } }; @@ -408,15 +374,13 @@ namespace asio { namespace { -static ASIO_CONSTEXPR const asio_require_fn::impl&+static 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,@@ -426,51 +390,14 @@ { }; -#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 ASIO_ELLIPSIS Properties>+template <typename T, typename... Properties> constexpr bool can_require_v- = can_require<T, Properties ASIO_ELLIPSIS>::value;+ = can_require<T, Properties...>::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,@@ -479,51 +406,14 @@ { }; -#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 ASIO_ELLIPSIS Properties>+template <typename T, typename... Properties> constexpr bool is_nothrow_require_v- = is_nothrow_require<T, Properties ASIO_ELLIPSIS>::value;+ = is_nothrow_require<T, Properties...>::value; #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) -#if defined(ASIO_HAS_VARIADIC_TEMPLATES)- template <typename T, typename... Properties> struct require_result {@@ -531,36 +421,8 @@ require_t, T, void(Properties...)>::result_type 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)+template <typename T, typename... Properties>+using require_result_t = typename require_result<T, Properties...>::type; } // namespace asio
link/modules/asio-standalone/asio/include/asio/require_concept.hpp view
@@ -2,7 +2,7 @@ // require_concept.hpp // ~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -107,10 +107,10 @@ namespace asio_require_concept_fn { -using asio::conditional;-using asio::decay;+using asio::conditional_t;+using asio::decay_t; using asio::declval;-using asio::enable_if;+using asio::enable_if_t; 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 {- ASIO_STATIC_CONSTEXPR(overload_type, overload = ill_formed);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ static constexpr overload_type overload = ill_formed;+ static constexpr bool is_noexcept = false; typedef void result_type; }; template <typename Impl, typename T, typename Property> struct call_traits<Impl, T, void(Property),- typename enable_if<+ enable_if_t< is_applicable_property<- typename decay<T>::type,- typename decay<Property>::type+ decay_t<T>,+ decay_t<Property> >::value- >::type,- typename enable_if<- decay<Property>::type::is_requirable_concept- >::type,- typename enable_if<+ >,+ enable_if_t<+ decay_t<Property>::is_requirable_concept+ >,+ enable_if_t< static_require_concept<T, Property>::is_valid- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(overload_type, overload = identity);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);- typedef ASIO_MOVE_ARG(T) result_type;+ static constexpr overload_type overload = identity;+ static constexpr bool is_noexcept = true;+ typedef T&& result_type; }; template <typename Impl, typename T, typename Property> struct call_traits<Impl, T, void(Property),- typename enable_if<+ enable_if_t< is_applicable_property<- typename decay<T>::type,- typename decay<Property>::type+ decay_t<T>,+ decay_t<Property> >::value- >::type,- typename enable_if<- decay<Property>::type::is_requirable_concept- >::type,- typename enable_if<+ >,+ enable_if_t<+ decay_t<Property>::is_requirable_concept+ >,+ enable_if_t< !static_require_concept<T, Property>::is_valid- >::type,- typename enable_if<+ >,+ enable_if_t< require_concept_member< typename Impl::template proxy<T>::type, Property >::is_valid- >::type> :+ >> : require_concept_member< typename Impl::template proxy<T>::type, Property > {- ASIO_STATIC_CONSTEXPR(overload_type, overload = call_member);+ static constexpr overload_type overload = call_member; }; template <typename Impl, typename T, typename Property> struct call_traits<Impl, T, void(Property),- typename enable_if<+ enable_if_t< is_applicable_property<- typename decay<T>::type,- typename decay<Property>::type+ decay_t<T>,+ decay_t<Property> >::value- >::type,- typename enable_if<- decay<Property>::type::is_requirable_concept- >::type,- typename enable_if<+ >,+ enable_if_t<+ decay_t<Property>::is_requirable_concept+ >,+ enable_if_t< !static_require_concept<T, Property>::is_valid- >::type,- typename enable_if<+ >,+ enable_if_t< !require_concept_member< typename Impl::template proxy<T>::type, Property >::is_valid- >::type,- typename enable_if<+ >,+ enable_if_t< require_concept_free<T, Property>::is_valid- >::type> :+ >> : require_concept_free<T, Property> {- ASIO_STATIC_CONSTEXPR(overload_type, overload = call_free);+ static constexpr overload_type overload = call_free; }; struct impl@@ -220,16 +220,16 @@ struct type { template <typename P>- auto require_concept(ASIO_MOVE_ARG(P) p)+ auto require_concept(P&& p) noexcept( noexcept(- declval<typename conditional<true, T, P>::type>().require_concept(- ASIO_MOVE_CAST(P)(p))+ declval<conditional_t<true, T, P>>().require_concept(+ static_cast<P&&>(p)) ) ) -> decltype(- declval<typename conditional<true, T, P>::type>().require_concept(- ASIO_MOVE_CAST(P)(p))+ declval<conditional_t<true, T, P>>().require_concept(+ static_cast<P&&>(p)) ); }; #else // defined(ASIO_HAS_DEDUCED_REQUIRE_CONCEPT_MEMBER_TRAIT)@@ -238,48 +238,36 @@ }; template <typename T, typename Property>- ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if<+ ASIO_NODISCARD constexpr enable_if_t< call_traits<impl, T, void(Property)>::overload == identity, typename call_traits<impl, T, void(Property)>::result_type- >::type- operator()(- ASIO_MOVE_ARG(T) t,- ASIO_MOVE_ARG(Property)) const- ASIO_NOEXCEPT_IF((- call_traits<impl, T, void(Property)>::is_noexcept))+ >+ operator()(T&& t, Property&&) const+ noexcept(call_traits<impl, T, void(Property)>::is_noexcept) {- return ASIO_MOVE_CAST(T)(t);+ return static_cast<T&&>(t); } template <typename T, typename Property>- ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if<+ ASIO_NODISCARD constexpr enable_if_t< call_traits<impl, T, void(Property)>::overload == call_member, typename call_traits<impl, T, void(Property)>::result_type- >::type- operator()(- ASIO_MOVE_ARG(T) t,- ASIO_MOVE_ARG(Property) p) const- ASIO_NOEXCEPT_IF((- call_traits<impl, T, void(Property)>::is_noexcept))+ >+ operator()(T&& t, Property&& p) const+ noexcept(call_traits<impl, T, void(Property)>::is_noexcept) {- return ASIO_MOVE_CAST(T)(t).require_concept(- ASIO_MOVE_CAST(Property)(p));+ return static_cast<T&&>(t).require_concept(static_cast<Property&&>(p)); } template <typename T, typename Property>- ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if<+ ASIO_NODISCARD constexpr enable_if_t< call_traits<impl, T, void(Property)>::overload == call_free, typename call_traits<impl, T, void(Property)>::result_type- >::type- operator()(- ASIO_MOVE_ARG(T) t,- ASIO_MOVE_ARG(Property) p) const- ASIO_NOEXCEPT_IF((- call_traits<impl, T, void(Property)>::is_noexcept))+ >+ operator()(T&& t, Property&& p) const+ noexcept(call_traits<impl, T, void(Property)>::is_noexcept) {- return require_concept(- ASIO_MOVE_CAST(T)(t),- ASIO_MOVE_CAST(Property)(p));+ return require_concept(static_cast<T&&>(t), static_cast<Property&&>(p)); } }; @@ -296,7 +284,7 @@ namespace asio { namespace { -static ASIO_CONSTEXPR const asio_require_concept_fn::impl&+static constexpr const asio_require_concept_fn::impl& require_concept = asio_require_concept_fn::static_instance<>::instance; } // namespace@@ -315,8 +303,7 @@ #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) @@ -342,6 +329,10 @@ 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2025 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2025 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/signal_set_base.hpp view
@@ -2,7 +2,7 @@ // signal_set_base.hpp // ~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -56,7 +56,9 @@ /// Portability typedef. typedef flags flags_t;-#elif defined(ASIO_HAS_ENUM_CLASS)++#else // defined(GENERATING_DOCUMENTATION)+ enum class flags : int { none = 0,@@ -67,21 +69,8 @@ }; 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- };- }; - typedef flags::flags_t flags_t;-#endif // defined(ASIO_HAS_ENUM_CLASS)+#endif // defined(GENERATING_DOCUMENTATION) protected: /// Protected destructor to prevent deletion through this type.@@ -94,7 +83,7 @@ /** * @relates signal_set_base::flags */-inline ASIO_CONSTEXPR bool operator!(signal_set_base::flags_t x)+inline constexpr bool operator!(signal_set_base::flags_t x) { return static_cast<int>(x) == 0; }@@ -103,7 +92,7 @@ /** * @relates signal_set_base::flags */-inline ASIO_CONSTEXPR signal_set_base::flags_t operator&(+inline 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 +103,7 @@ /** * @relates signal_set_base::flags */-inline ASIO_CONSTEXPR signal_set_base::flags_t operator|(+inline 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 +114,7 @@ /** * @relates signal_set_base::flags */-inline ASIO_CONSTEXPR signal_set_base::flags_t operator^(+inline 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>(@@ -136,7 +125,7 @@ /** * @relates signal_set_base::flags */-inline ASIO_CONSTEXPR signal_set_base::flags_t operator~(+inline 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -533,17 +533,6 @@ 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -26,10 +26,6 @@ #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 {@@ -76,12 +72,12 @@ suspend_with(&spawned_thread_base::call<F>, &f); } - cancellation_slot get_cancellation_slot() const ASIO_NOEXCEPT+ cancellation_slot get_cancellation_slot() const noexcept { return cancellation_state_.slot(); } - cancellation_state get_cancellation_state() const ASIO_NOEXCEPT+ cancellation_state get_cancellation_state() const noexcept { return cancellation_state_; }@@ -105,22 +101,22 @@ parent_cancellation_slot_, in_filter, out_filter); } - cancellation_type_t cancelled() const ASIO_NOEXCEPT+ cancellation_type_t cancelled() const noexcept { return cancellation_state_.cancelled(); } - bool has_context_switched() const ASIO_NOEXCEPT+ bool has_context_switched() const noexcept { return has_context_switched_; } - bool throw_if_cancelled() const ASIO_NOEXCEPT+ bool throw_if_cancelled() const noexcept { return throw_if_cancelled_; } - void throw_if_cancelled(bool value) ASIO_NOEXCEPT+ void throw_if_cancelled(bool value) noexcept { throw_if_cancelled_ = value; }@@ -135,8 +131,8 @@ private: // Disallow copying and assignment.- spawned_thread_base(const spawned_thread_base&) ASIO_DELETED;- spawned_thread_base& operator=(const spawned_thread_base&) ASIO_DELETED;+ spawned_thread_base(const spawned_thread_base&) = delete;+ spawned_thread_base& operator=(const spawned_thread_base&) = delete; template <typename F> static void call(void* f)@@ -145,7 +141,6 @@ } }; - template <typename T> struct spawn_signature {@@ -198,9 +193,9 @@ */ template <typename OtherExecutor> basic_yield_context(const basic_yield_context<OtherExecutor>& other,- typename constraint<+ constraint_t< is_convertible<OtherExecutor, Executor>::value- >::type = 0)+ > = 0) : spawned_thread_(other.spawned_thread_), executor_(other.executor_), ec_(other.ec_)@@ -208,19 +203,19 @@ } /// Get the executor associated with the yield context.- executor_type get_executor() const ASIO_NOEXCEPT+ executor_type get_executor() const noexcept { return executor_; } /// Get the cancellation slot associated with the coroutine.- cancellation_slot_type get_cancellation_slot() const ASIO_NOEXCEPT+ cancellation_slot_type get_cancellation_slot() const noexcept { return spawned_thread_->get_cancellation_slot(); } /// Get the cancellation state associated with the coroutine.- cancellation_state get_cancellation_state() const ASIO_NOEXCEPT+ cancellation_state get_cancellation_state() const noexcept { return spawned_thread_->get_cancellation_state(); }@@ -246,10 +241,10 @@ * cancellation state object. */ template <typename Filter>- void reset_cancellation_state(ASIO_MOVE_ARG(Filter) filter) const+ void reset_cancellation_state(Filter&& filter) const { spawned_thread_->reset_cancellation_state(- ASIO_MOVE_CAST(Filter)(filter));+ static_cast<Filter&&>(filter)); } /// Reset the cancellation state associated with the coroutine.@@ -262,30 +257,30 @@ * cancellation state object. */ template <typename InFilter, typename OutFilter>- void reset_cancellation_state(ASIO_MOVE_ARG(InFilter) in_filter,- ASIO_MOVE_ARG(OutFilter) out_filter) const+ void reset_cancellation_state(InFilter&& in_filter,+ OutFilter&& out_filter) const { spawned_thread_->reset_cancellation_state(- ASIO_MOVE_CAST(InFilter)(in_filter),- ASIO_MOVE_CAST(OutFilter)(out_filter));+ static_cast<InFilter&&>(in_filter),+ static_cast<OutFilter&&>(out_filter)); } /// Determine whether the current coroutine has been cancelled.- cancellation_type_t cancelled() const ASIO_NOEXCEPT+ cancellation_type_t cancelled() const noexcept { return spawned_thread_->cancelled(); } /// Determine whether the coroutine throws if trying to suspend when it has /// been cancelled.- bool throw_if_cancelled() const ASIO_NOEXCEPT+ bool throw_if_cancelled() const 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 ASIO_NOEXCEPT+ void throw_if_cancelled(bool value) const noexcept { spawned_thread_->throw_if_cancelled(value); }@@ -402,31 +397,19 @@ */ template <typename Executor, typename F, ASIO_COMPLETION_TOKEN_FOR(typename detail::spawn_signature<- 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<+ 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< is_executor<Executor>::value || execution::is_executor<Executor>::value- >::type = 0)- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ > = 0)+ -> decltype( async_initiate<CompletionToken, typename detail::spawn_signature<- typename result_of<F(basic_yield_context<Executor>)>::type>::type>(- declval<detail::initiate_spawn<Executor> >(),- token, ASIO_MOVE_CAST(F)(function))));+ result_of_t<F(basic_yield_context<Executor>)>>::type>(+ declval<detail::initiate_spawn<Executor>>(),+ token, static_cast<F&&>(function))); /// Start a new stackful coroutine that executes on a given execution context. /**@@ -459,37 +442,24 @@ */ template <typename ExecutionContext, typename F, ASIO_COMPLETION_TOKEN_FOR(typename detail::spawn_signature<- 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<+ 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< is_convertible<ExecutionContext&, execution_context&>::value- >::type = 0)- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ > = 0)+ -> decltype( async_initiate<CompletionToken, typename detail::spawn_signature<- typename result_of<F(basic_yield_context<- typename ExecutionContext::executor_type>)>::type>::type>(+ result_of_t<F(basic_yield_context<+ typename ExecutionContext::executor_type>)>>::type>( declval<detail::initiate_spawn<- typename ExecutionContext::executor_type> >(),- token, ASIO_MOVE_CAST(F)(function))));+ typename ExecutionContext::executor_type>>(),+ token, static_cast<F&&>(function))); /// Start a new stackful coroutine, inheriting the executor of another. /**@@ -524,32 +494,19 @@ */ template <typename Executor, typename F, ASIO_COMPLETION_TOKEN_FOR(typename detail::spawn_signature<- 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<+ 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< is_executor<Executor>::value || execution::is_executor<Executor>::value- >::type = 0)- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ > = 0)+ -> decltype( async_initiate<CompletionToken, typename detail::spawn_signature<- typename result_of<F(basic_yield_context<Executor>)>::type>::type>(- declval<detail::initiate_spawn<Executor> >(),- token, ASIO_MOVE_CAST(F)(function))));+ result_of_t<F(basic_yield_context<Executor>)>>::type>(+ declval<detail::initiate_spawn<Executor>>(),+ token, static_cast<F&&>(function))); #if defined(ASIO_HAS_BOOST_CONTEXT_FIBER) \ || defined(GENERATING_DOCUMENTATION)@@ -589,27 +546,22 @@ */ template <typename Executor, typename StackAllocator, typename F, ASIO_COMPLETION_TOKEN_FOR(typename detail::spawn_signature<- 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<+ 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< is_executor<Executor>::value || execution::is_executor<Executor>::value- >::type = 0)- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ > = 0)+ -> decltype( async_initiate<CompletionToken, typename detail::spawn_signature<- typename result_of<F(basic_yield_context<Executor>)>::type>::type>(- declval<detail::initiate_spawn<Executor> >(),+ result_of_t<F(basic_yield_context<Executor>)>>::type>(+ declval<detail::initiate_spawn<Executor>>(), token, allocator_arg_t(),- ASIO_MOVE_CAST(StackAllocator)(stack_allocator),- ASIO_MOVE_CAST(F)(function))));+ static_cast<StackAllocator&&>(stack_allocator),+ static_cast<F&&>(function))); /// Start a new stackful coroutine that executes on a given execution context. /**@@ -646,33 +598,27 @@ */ template <typename ExecutionContext, typename StackAllocator, typename F, ASIO_COMPLETION_TOKEN_FOR(typename detail::spawn_signature<- 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<+ 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< is_convertible<ExecutionContext&, execution_context&>::value- >::type = 0)- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ > = 0)+ -> decltype( async_initiate<CompletionToken, typename detail::spawn_signature<- typename result_of<F(basic_yield_context<- typename ExecutionContext::executor_type>)>::type>::type>(+ result_of_t<F(basic_yield_context<+ typename ExecutionContext::executor_type>)>>::type>( declval<detail::initiate_spawn<- typename ExecutionContext::executor_type> >(),+ typename ExecutionContext::executor_type>>(), token, allocator_arg_t(),- ASIO_MOVE_CAST(StackAllocator)(stack_allocator),- ASIO_MOVE_CAST(F)(function))));+ static_cast<StackAllocator&&>(stack_allocator),+ static_cast<F&&>(function))); /// Start a new stackful coroutine, inheriting the executor of another. /**@@ -713,186 +659,24 @@ */ template <typename Executor, typename StackAllocator, typename F, ASIO_COMPLETION_TOKEN_FOR(typename detail::spawn_signature<- 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<+ 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- >::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);+ > = 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))); -#endif // defined(ASIO_HAS_BOOST_COROUTINE)+#endif // defined(ASIO_HAS_BOOST_CONTEXT_FIBER) // || defined(GENERATING_DOCUMENTATION) /*@}*/
link/modules/asio-standalone/asio/include/asio/ssl.hpp view
@@ -2,7 +2,7 @@ // ssl.hpp // ~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -18,7 +18,6 @@ #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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -46,7 +46,6 @@ /// 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.@@ -72,7 +71,6 @@ * @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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -29,7 +29,7 @@ class buffered_handshake_op { public:- static ASIO_CONSTEXPR const char* tracking_name()+ static 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 {- ASIO_MOVE_OR_LVALUE(Handler)(handler)(ec, bytes_transferred);+ static_cast<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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -61,18 +61,14 @@ // 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) ASIO_NOEXCEPT;-#endif // defined(ASIO_HAS_MOVE)+ ASIO_DECL engine(engine&& other) noexcept; // Destructor. ASIO_DECL ~engine(); -#if defined(ASIO_HAS_MOVE) // Move assign from another engine.- ASIO_DECL engine& operator=(engine&& other) ASIO_NOEXCEPT;-#endif // defined(ASIO_HAS_MOVE)+ ASIO_DECL engine& operator=(engine&& other) noexcept; // 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -28,7 +28,7 @@ class handshake_op { public:- static ASIO_CONSTEXPR const char* tracking_name()+ static constexpr const char* tracking_name() { return "ssl::stream<>::async_handshake"; }@@ -51,7 +51,7 @@ const asio::error_code& ec, const std::size_t&) const {- ASIO_MOVE_OR_LVALUE(Handler)(handler)(ec);+ static_cast<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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -73,15 +73,13 @@ ::SSL_set_bio(ssl_, int_bio, int_bio); } -#if defined(ASIO_HAS_MOVE)-engine::engine(engine&& other) ASIO_NOEXCEPT+engine::engine(engine&& other) noexcept : ssl_(other.ssl_), ext_bio_(other.ext_bio_) { other.ssl_ = 0; other.ext_bio_ = 0; }-#endif // defined(ASIO_HAS_MOVE) engine::~engine() {@@ -98,11 +96,16 @@ ::SSL_free(ssl_); } -#if defined(ASIO_HAS_MOVE)-engine& engine::operator=(engine&& other) ASIO_NOEXCEPT+engine& engine::operator=(engine&& other) 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;@@ -110,7 +113,6 @@ } 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2005-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)@@ -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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -107,11 +107,10 @@ start_(0), want_(engine::want_nothing), bytes_transferred_(0),- handler_(ASIO_MOVE_CAST(Handler)(handler))+ handler_(static_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_),@@ -127,20 +126,18 @@ io_op(io_op&& other) : asio::detail::base_from_cancellation_state<Handler>(- ASIO_MOVE_CAST(- asio::detail::base_from_cancellation_state<Handler>)(- other)),+ static_cast<+ asio::detail::base_from_cancellation_state<Handler>&&>(other)), next_layer_(other.next_layer_), core_(other.core_),- op_(ASIO_MOVE_CAST(Operation)(other.op_)),+ op_(static_cast<Operation&&>(other.op_)), start_(other.start_), want_(other.want_), ec_(other.ec_), bytes_transferred_(other.bytes_transferred_),- handler_(ASIO_MOVE_CAST(Handler)(other.handler_))+ handler_(static_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)@@ -177,7 +174,7 @@ // Start reading some data from the underlying transport. next_layer_.async_read_some( asio::buffer(core_.input_buffer_),- ASIO_MOVE_CAST(io_op)(*this));+ static_cast<io_op&&>(*this)); } else {@@ -185,7 +182,7 @@ __FILE__, __LINE__, Operation::tracking_name())); // Wait until the current read operation completes.- core_.pending_read_.async_wait(ASIO_MOVE_CAST(io_op)(*this));+ core_.pending_read_.async_wait(static_cast<io_op&&>(*this)); } // Yield control until asynchronous operation completes. Control@@ -210,7 +207,7 @@ // Start writing all the data to the underlying transport. asio::async_write(next_layer_, core_.engine_.get_output(core_.output_buffer_),- ASIO_MOVE_CAST(io_op)(*this));+ static_cast<io_op&&>(*this)); } else {@@ -218,7 +215,7 @@ __FILE__, __LINE__, Operation::tracking_name())); // Wait until the current write operation completes.- core_.pending_write_.async_wait(ASIO_MOVE_CAST(io_op)(*this));+ core_.pending_write_.async_wait(static_cast<io_op&&>(*this)); } // Yield control until asynchronous operation completes. Control@@ -239,7 +236,7 @@ next_layer_.async_read_some( asio::buffer(core_.input_buffer_, 0),- ASIO_MOVE_CAST(io_op)(*this));+ static_cast<io_op&&>(*this)); // Yield control until asynchronous operation completes. Control // resumes at the "default:" label below.@@ -331,32 +328,6 @@ }; 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) {@@ -364,32 +335,6 @@ : 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)@@ -410,19 +355,15 @@ DefaultCandidate> : Associator<Handler, DefaultCandidate> {- static typename Associator<Handler, DefaultCandidate>::type- get(const ssl::detail::io_op<Stream, Operation, Handler>& h)- ASIO_NOEXCEPT+ static typename Associator<Handler, DefaultCandidate>::type get(+ const ssl::detail::io_op<Stream, Operation, Handler>& h) noexcept { return Associator<Handler, DefaultCandidate>::get(h.handler_); } - 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)))+ static auto get(const ssl::detail::io_op<Stream, Operation, Handler>& h,+ const DefaultCandidate& c) noexcept+ -> decltype(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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -30,7 +30,7 @@ class read_op { public:- static ASIO_CONSTEXPR const char* tracking_name()+ static 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 {- ASIO_MOVE_OR_LVALUE(Handler)(handler)(ec, bytes_transferred);+ static_cast<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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -28,7 +28,7 @@ class shutdown_op { public:- static ASIO_CONSTEXPR const char* tracking_name()+ static 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.- ASIO_MOVE_OR_LVALUE(Handler)(handler)(asio::error_code());+ static_cast<Handler&&>(handler)(asio::error_code()); } else {- ASIO_MOVE_OR_LVALUE(Handler)(handler)(ec);+ static_cast<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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -17,13 +17,9 @@ #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" @@ -65,30 +61,20 @@ pending_write_.expires_at(neg_infin()); } -#if defined(ASIO_HAS_MOVE) stream_core(stream_core&& other)- : engine_(ASIO_MOVE_CAST(engine)(other.engine_)),-#if defined(ASIO_HAS_BOOST_DATE_TIME)- pending_read_(- ASIO_MOVE_CAST(asio::deadline_timer)(- other.pending_read_)),- pending_write_(- ASIO_MOVE_CAST(asio::deadline_timer)(- other.pending_write_)),-#else // defined(ASIO_HAS_BOOST_DATE_TIME)+ : engine_(static_cast<engine&&>(other.engine_)), pending_read_(- ASIO_MOVE_CAST(asio::steady_timer)(+ static_cast<asio::steady_timer&&>( other.pending_read_)), pending_write_(- ASIO_MOVE_CAST(asio::steady_timer)(+ static_cast<asio::steady_timer&&>( other.pending_write_)),-#endif // defined(ASIO_HAS_BOOST_DATE_TIME) output_buffer_space_(- ASIO_MOVE_CAST(std::vector<unsigned char>)(+ static_cast<std::vector<unsigned char>&&>( other.output_buffer_space_)), output_buffer_(other.output_buffer_), input_buffer_space_(- ASIO_MOVE_CAST(std::vector<unsigned char>)(+ static_cast<std::vector<unsigned char>&&>( other.input_buffer_space_)), input_buffer_(other.input_buffer_), input_(other.input_)@@ -97,39 +83,28 @@ 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_ = ASIO_MOVE_CAST(engine)(other.engine_);-#if defined(ASIO_HAS_BOOST_DATE_TIME)- pending_read_ =- ASIO_MOVE_CAST(asio::deadline_timer)(- other.pending_read_);- pending_write_ =- ASIO_MOVE_CAST(asio::deadline_timer)(- other.pending_write_);-#else // defined(ASIO_HAS_BOOST_DATE_TIME)+ engine_ = static_cast<engine&&>(other.engine_); pending_read_ =- ASIO_MOVE_CAST(asio::steady_timer)(+ static_cast<asio::steady_timer&&>( other.pending_read_); pending_write_ =- ASIO_MOVE_CAST(asio::steady_timer)(+ static_cast<asio::steady_timer&&>( other.pending_write_);-#endif // defined(ASIO_HAS_BOOST_DATE_TIME) output_buffer_space_ =- ASIO_MOVE_CAST(std::vector<unsigned char>)(+ static_cast<std::vector<unsigned char>&&>( other.output_buffer_space_); output_buffer_ = other.output_buffer_; input_buffer_space_ =- ASIO_MOVE_CAST(std::vector<unsigned char>)(+ static_cast<std::vector<unsigned char>&&>( other.input_buffer_space_); input_buffer_ = other.input_buffer_; input_ = other.input_;@@ -139,38 +114,11 @@ } 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.@@ -194,7 +142,6 @@ { 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -30,7 +30,7 @@ class write_op { public:- static ASIO_CONSTEXPR const char* tracking_name()+ static 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 {- ASIO_MOVE_OR_LVALUE(Handler)(handler)(ec, bytes_transferred);+ static_cast<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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -77,7 +77,6 @@ } // namespace ssl } // namespace asio -#if defined(ASIO_HAS_STD_SYSTEM_ERROR) namespace std { template<> struct is_error_code_enum<asio::error::ssl_errors>@@ -91,7 +90,6 @@ }; } // 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2005-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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2005-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)@@ -269,8 +269,9 @@ #endif // defined(SSL_TXT_TLSV1_2) // TLS v1.3.-#if (OPENSSL_VERSION_NUMBER >= 0x10101000L) \- && !defined(LIBRESSL_VERSION_NUMBER)+#if ((OPENSSL_VERSION_NUMBER >= 0x10101000L) \+ && !defined(LIBRESSL_VERSION_NUMBER)) \+ || defined(ASIO_USE_WOLFSSL) case context::tlsv13: handle_ = ::SSL_CTX_new(::TLS_method()); if (handle_)@@ -295,16 +296,18 @@ SSL_CTX_set_max_proto_version(handle_, TLS1_3_VERSION); } break;-#else // (OPENSSL_VERSION_NUMBER >= 0x10101000L)- // && !defined(LIBRESSL_VERSION_NUMBER)+#else // ((OPENSSL_VERSION_NUMBER >= 0x10101000L)+ // && !defined(LIBRESSL_VERSION_NUMBER))+ // || defined(ASIO_USE_WOLFSSL) 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)+#endif // ((OPENSSL_VERSION_NUMBER >= 0x10101000L)+ // && !defined(LIBRESSL_VERSION_NUMBER))+ // || defined(ASIO_USE_WOLFSSL) // Any supported SSL/TLS version. case context::sslv23:@@ -376,7 +379,6 @@ } } -#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) context::context(context&& other) { handle_ = other.handle_;@@ -385,12 +387,11 @@ context& context::operator=(context&& other) {- context tmp(ASIO_MOVE_CAST(context)(*this));+ context tmp(static_cast<context&&>(*this)); handle_ = other.handle_; other.handle_ = 0; return *this; }-#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) context::~context() {@@ -796,7 +797,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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -28,7 +28,7 @@ class ssl_category : public asio::error_category { public:- const char* name() const ASIO_ERROR_CATEGORY_NOEXCEPT+ const char* name() const noexcept { return "asio.ssl"; }@@ -88,7 +88,7 @@ class stream_category : public asio::error_category { public:- const char* name() const ASIO_ERROR_CATEGORY_NOEXCEPT+ const char* name() const 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
− link/modules/asio-standalone/asio/include/asio/ssl/impl/rfc2818_verification.ipp
@@ -1,164 +0,0 @@-//-// 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -24,6 +24,5 @@ #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
@@ -1,98 +0,0 @@-//-// 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -18,6 +18,7 @@ #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"@@ -54,7 +55,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:@@ -83,7 +84,7 @@ }; /// The type of the next layer.- typedef typename remove_reference<Stream>::type next_layer_type;+ typedef remove_reference_t<Stream> next_layer_type; /// The type of the lowest layer. typedef typename next_layer_type::lowest_layer_type lowest_layer_type;@@ -91,7 +92,6 @@ /// 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_(ASIO_MOVE_CAST(Arg)(arg)),+ : next_layer_(static_cast<Arg&&>(arg)), core_(ctx.native_handle(), next_layer_.lowest_layer().get_executor()) { }@@ -120,27 +120,11 @@ */ template <typename Arg> stream(Arg&& arg, native_handle_type handle)- : next_layer_(ASIO_MOVE_CAST(Arg)(arg)),+ : next_layer_(static_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@@ -149,8 +133,8 @@ * operation is destruction, or use as the target of a move assignment. */ stream(stream&& other)- : next_layer_(ASIO_MOVE_CAST(Stream)(other.next_layer_)),- core_(ASIO_MOVE_CAST(detail::stream_core)(other.core_))+ : next_layer_(static_cast<Stream&&>(other.next_layer_)),+ core_(static_cast<detail::stream_core&&>(other.core_)) { } @@ -165,12 +149,11 @@ { if (this != &other) {- next_layer_ = ASIO_MOVE_CAST(Stream)(other.next_layer_);- core_ = ASIO_MOVE_CAST(detail::stream_core)(other.core_);+ next_layer_ = static_cast<Stream&&>(other.next_layer_);+ core_ = static_cast<detail::stream_core&&>(other.core_); } return *this; }-#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Destructor. /**@@ -188,7 +171,7 @@ * * @return A copy of the executor that stream will use to dispatch handlers. */- executor_type get_executor() ASIO_NOEXCEPT+ executor_type get_executor() noexcept { return next_layer_.lowest_layer().get_executor(); }@@ -204,7 +187,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(my_context, ctx);+ * asio::ssl::stream<asio::ip::tcp::socket> sock(io_ctx, ctx); * * // ... establish connection and perform handshake ... *@@ -498,7 +481,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code) @endcode@@ -516,17 +499,13 @@ */ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code))- 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((+ HandshakeToken = default_completion_token_t<executor_type>>+ auto async_handshake(handshake_type type,+ HandshakeToken&& token = default_completion_token_t<executor_type>())+ -> decltype( 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)>(@@ -559,7 +538,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -578,16 +557,17 @@ template <typename ConstBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, std::size_t)) BufferedHandshakeToken- 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((+ = 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( 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)>(@@ -638,7 +618,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code) @endcode@@ -657,16 +637,13 @@ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code)) ShutdownToken- 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((+ = default_completion_token_t<executor_type>>+ auto async_shutdown(+ ShutdownToken&& token = default_completion_token_t<executor_type>())+ -> decltype( 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)>(@@ -745,7 +722,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -768,17 +745,13 @@ */ template <typename ConstBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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((+ 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( 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)>(@@ -857,7 +830,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -880,17 +853,13 @@ */ template <typename MutableBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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((+ 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( 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)>(@@ -908,13 +877,13 @@ { } - executor_type get_executor() const ASIO_NOEXCEPT+ executor_type get_executor() const noexcept { return self_->get_executor(); } template <typename HandshakeHandler>- void operator()(ASIO_MOVE_ARG(HandshakeHandler) handler,+ void operator()(HandshakeHandler&& handler, handshake_type type) const { // If you get an error on the following line it means that your handler@@ -940,13 +909,13 @@ { } - executor_type get_executor() const ASIO_NOEXCEPT+ executor_type get_executor() const noexcept { return self_->get_executor(); } template <typename BufferedHandshakeHandler, typename ConstBufferSequence>- void operator()(ASIO_MOVE_ARG(BufferedHandshakeHandler) handler,+ void operator()(BufferedHandshakeHandler&& handler, handshake_type type, const ConstBufferSequence& buffers) const { // If you get an error on the following line it means that your@@ -976,13 +945,13 @@ { } - executor_type get_executor() const ASIO_NOEXCEPT+ executor_type get_executor() const noexcept { return self_->get_executor(); } template <typename ShutdownHandler>- void operator()(ASIO_MOVE_ARG(ShutdownHandler) handler) const+ void operator()(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.@@ -1007,13 +976,13 @@ { } - executor_type get_executor() const ASIO_NOEXCEPT+ executor_type get_executor() const noexcept { return self_->get_executor(); } template <typename WriteHandler, typename ConstBufferSequence>- void operator()(ASIO_MOVE_ARG(WriteHandler) handler,+ void operator()(WriteHandler&& handler, const ConstBufferSequence& buffers) const { // If you get an error on the following line it means that your handler@@ -1039,13 +1008,13 @@ { } - executor_type get_executor() const ASIO_NOEXCEPT+ executor_type get_executor() const noexcept { return self_->get_executor(); } template <typename ReadHandler, typename MutableBufferSequence>- void operator()(ASIO_MOVE_ARG(ReadHandler) handler,+ void operator()(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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/ssl/verify_context.hpp view
@@ -2,7 +2,7 @@ // ssl/verify_context.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/ssl/verify_mode.hpp view
@@ -2,7 +2,7 @@ // ssl/verify_mode.hpp // ~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/static_thread_pool.hpp view
@@ -2,7 +2,7 @@ // static_thread_pool.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/steady_timer.hpp view
@@ -2,7 +2,7 @@ // steady_timer.hpp // ~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -16,9 +16,6 @@ #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" @@ -36,7 +33,5 @@ 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -48,20 +48,20 @@ /// Construct a strand for the specified executor. template <typename Executor1> explicit strand(const Executor1& e,- typename constraint<- conditional<+ constraint_t<+ conditional_t< !is_same<Executor1, strand>::value, is_convertible<Executor1, Executor>, false_type- >::type::value- >::type = 0)+ >::value+ > = 0) : executor_(e), impl_(strand::create_implementation(executor_)) { } /// Copy constructor.- strand(const strand& other) ASIO_NOEXCEPT+ strand(const strand& other) noexcept : executor_(other.executor_), impl_(other.impl_) {@@ -74,14 +74,14 @@ */ template <class OtherExecutor> strand(- const strand<OtherExecutor>& other) ASIO_NOEXCEPT+ const strand<OtherExecutor>& other) noexcept : executor_(other.executor_), impl_(other.impl_) { } /// Assignment operator.- strand& operator=(const strand& other) ASIO_NOEXCEPT+ strand& operator=(const strand& other) noexcept { executor_ = other.executor_; impl_ = other.impl_;@@ -95,18 +95,17 @@ */ template <class OtherExecutor> strand& operator=(- const strand<OtherExecutor>& other) ASIO_NOEXCEPT+ const strand<OtherExecutor>& other) noexcept { executor_ = other.executor_; impl_ = other.impl_; return *this; } -#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move constructor.- strand(strand&& other) ASIO_NOEXCEPT- : executor_(ASIO_MOVE_CAST(Executor)(other.executor_)),- impl_(ASIO_MOVE_CAST(implementation_type)(other.impl_))+ strand(strand&& other) noexcept+ : executor_(static_cast<Executor&&>(other.executor_)),+ impl_(static_cast<implementation_type&&>(other.impl_)) { } @@ -116,17 +115,17 @@ * to @c Executor. */ template <class OtherExecutor>- strand(strand<OtherExecutor>&& other) ASIO_NOEXCEPT- : executor_(ASIO_MOVE_CAST(OtherExecutor)(other.executor_)),- impl_(ASIO_MOVE_CAST(implementation_type)(other.impl_))+ strand(strand<OtherExecutor>&& other) noexcept+ : executor_(static_cast<OtherExecutor&&>(other.executor_)),+ impl_(static_cast<implementation_type&&>(other.impl_)) { } /// Move assignment operator.- strand& operator=(strand&& other) ASIO_NOEXCEPT+ strand& operator=(strand&& other) noexcept {- executor_ = ASIO_MOVE_CAST(Executor)(other.executor_);- impl_ = ASIO_MOVE_CAST(implementation_type)(other.impl_);+ executor_ = static_cast<Executor&&>(other.executor_);+ impl_ = static_cast<implementation_type&&>(other.impl_); return *this; } @@ -136,21 +135,20 @@ * convertible to @c Executor. */ template <class OtherExecutor>- strand& operator=(strand<OtherExecutor>&& other) ASIO_NOEXCEPT+ strand& operator=(strand<OtherExecutor>&& other) noexcept {- executor_ = ASIO_MOVE_CAST(OtherExecutor)(other.executor_);- impl_ = ASIO_MOVE_CAST(implementation_type)(other.impl_);+ executor_ = static_cast<OtherExecutor&&>(other.executor_);+ impl_ = static_cast<implementation_type&&>(other.impl_); return *this; }-#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Destructor.- ~strand() ASIO_NOEXCEPT+ ~strand() noexcept { } /// Obtain the underlying executor.- inner_executor_type get_inner_executor() const ASIO_NOEXCEPT+ inner_executor_type get_inner_executor() const noexcept { return executor_; }@@ -167,16 +165,15 @@ * ... @endcode */ template <typename Property>- typename constraint<+ constraint_t< can_query<const Executor&, Property>::value,- typename conditional<+ conditional_t< is_convertible<Property, execution::blocking_t>::value, execution::blocking_t,- typename query_result<const Executor&, Property>::type- >::type- >::type query(const Property& p) const- ASIO_NOEXCEPT_IF((- is_nothrow_query<const Executor&, Property>::value))+ query_result_t<const Executor&, Property>+ >+ > query(const Property& p) const+ noexcept(is_nothrow_query<const Executor&, Property>::value) { return this->query_helper( is_convertible<Property, execution::blocking_t>(), p);@@ -193,19 +190,15 @@ * asio::execution::blocking.never); @endcode */ template <typename Property>- typename constraint<+ constraint_t< can_require<const Executor&, Property>::value && !is_convertible<Property, execution::blocking_t::always_t>::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))+ strand<decay_t<require_result_t<const Executor&, Property>>>+ > require(const Property& p) const+ noexcept(is_nothrow_require<const Executor&, Property>::value) {- return strand<typename decay<- typename require_result<const Executor&, Property>::type- >::type>(asio::require(executor_, p), impl_);+ return strand<decay_t<require_result_t<const Executor&, Property>>>(+ asio::require(executor_, p), impl_); } /// Forward a preference to the underlying executor.@@ -219,24 +212,20 @@ * asio::execution::blocking.never); @endcode */ template <typename Property>- typename constraint<+ constraint_t< can_prefer<const Executor&, Property>::value && !is_convertible<Property, execution::blocking_t::always_t>::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))+ strand<decay_t<prefer_result_t<const Executor&, Property>>>+ > prefer(const Property& p) const+ noexcept(is_nothrow_prefer<const Executor&, Property>::value) {- return strand<typename decay<- typename prefer_result<const Executor&, Property>::type- >::type>(asio::prefer(executor_, p), impl_);+ return strand<decay_t<prefer_result_t<const Executor&, Property>>>(+ asio::prefer(executor_, p), impl_); } #if !defined(ASIO_NO_TS_EXECUTORS) /// Obtain the underlying execution context.- execution_context& context() const ASIO_NOEXCEPT+ execution_context& context() const noexcept { return executor_.context(); }@@ -245,7 +234,7 @@ /** * The strand delegates this call to its underlying executor. */- void on_work_started() const ASIO_NOEXCEPT+ void on_work_started() const noexcept { executor_.on_work_started(); }@@ -254,7 +243,7 @@ /** * The strand delegates this call to its underlying executor. */- void on_work_finished() const ASIO_NOEXCEPT+ void on_work_finished() const noexcept { executor_.on_work_finished(); }@@ -271,20 +260,13 @@ * function object must be: @code void function(); @endcode */ template <typename Function>- typename constraint<-#if defined(ASIO_NO_DEPRECATED) \- || defined(GENERATING_DOCUMENTATION)+ constraint_t< 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- >::type execute(ASIO_MOVE_ARG(Function) f) const+ > execute(Function&& f) const { detail::strand_executor_service::execute(impl_,- executor_, ASIO_MOVE_CAST(Function)(f));+ executor_, static_cast<Function&&>(f)); } #if !defined(ASIO_NO_TS_EXECUTORS)@@ -304,10 +286,10 @@ * internal storage needed for function invocation. */ template <typename Function, typename Allocator>- void dispatch(ASIO_MOVE_ARG(Function) f, const Allocator& a) const+ void dispatch(Function&& f, const Allocator& a) const { detail::strand_executor_service::dispatch(impl_,- executor_, ASIO_MOVE_CAST(Function)(f), a);+ executor_, static_cast<Function&&>(f), a); } /// Request the strand to invoke the given function object.@@ -324,10 +306,10 @@ * internal storage needed for function invocation. */ template <typename Function, typename Allocator>- void post(ASIO_MOVE_ARG(Function) f, const Allocator& a) const+ void post(Function&& f, const Allocator& a) const { detail::strand_executor_service::post(impl_,- executor_, ASIO_MOVE_CAST(Function)(f), a);+ executor_, static_cast<Function&&>(f), a); } /// Request the strand to invoke the given function object.@@ -344,10 +326,10 @@ * internal storage needed for function invocation. */ template <typename Function, typename Allocator>- void defer(ASIO_MOVE_ARG(Function) f, const Allocator& a) const+ void defer(Function&& f, const Allocator& a) const { detail::strand_executor_service::defer(impl_,- executor_, ASIO_MOVE_CAST(Function)(f), a);+ executor_, static_cast<Function&&>(f), a); } #endif // !defined(ASIO_NO_TS_EXECUTORS) @@ -357,7 +339,7 @@ * submitted to the strand using post(), dispatch() or defer(). Otherwise * returns @c false. */- bool running_in_this_thread() const ASIO_NOEXCEPT+ bool running_in_this_thread() const noexcept { return detail::strand_executor_service::running_in_this_thread(impl_); }@@ -367,7 +349,7 @@ * Two strands are equal if they refer to the same ordered, non-concurrent * state. */- friend bool operator==(const strand& a, const strand& b) ASIO_NOEXCEPT+ friend bool operator==(const strand& a, const strand& b) noexcept { return a.impl_ == b.impl_; }@@ -377,7 +359,7 @@ * Two strands are equal if they refer to the same ordered, non-concurrent * state. */- friend bool operator!=(const strand& a, const strand& b) ASIO_NOEXCEPT+ friend bool operator!=(const strand& a, const strand& b) noexcept { return a.impl_ != b.impl_; }@@ -390,9 +372,9 @@ template <typename InnerExecutor> static implementation_type create_implementation(const InnerExecutor& ex,- typename constraint<+ constraint_t< can_query<InnerExecutor, execution::context_t>::value- >::type = 0)+ > = 0) { return use_service<detail::strand_executor_service>( asio::query(ex, execution::context)).create_implementation();@@ -400,9 +382,9 @@ template <typename InnerExecutor> static implementation_type create_implementation(const InnerExecutor& ex,- typename constraint<+ constraint_t< !can_query<InnerExecutor, execution::context_t>::value- >::type = 0)+ > = 0) { return use_service<detail::strand_executor_service>( ex.context()).create_implementation();@@ -415,7 +397,7 @@ } template <typename Property>- typename query_result<const Executor&, Property>::type query_helper(+ query_result_t<const Executor&, Property> query_helper( false_type, const Property& property) const { return asio::query(executor_, property);@@ -448,9 +430,9 @@ */ template <typename Executor> inline strand<Executor> make_strand(const Executor& ex,- typename constraint<+ constraint_t< is_executor<Executor>::value || execution::is_executor<Executor>::value- >::type = 0)+ > = 0) { return strand<Executor>(ex); }@@ -465,9 +447,9 @@ template <typename ExecutionContext> inline strand<typename ExecutionContext::executor_type> make_strand(ExecutionContext& ctx,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value- >::type = 0)+ > = 0) { return strand<typename ExecutionContext::executor_type>(ctx.get_executor()); }@@ -481,10 +463,10 @@ #if !defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT) template <typename Executor>-struct equality_comparable<strand<Executor> >+struct equality_comparable<strand<Executor>> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; }; #endif // !defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)@@ -493,16 +475,12 @@ template <typename Executor, typename Function> struct execute_member<strand<Executor>, Function,- typename enable_if<-#if defined(ASIO_NO_DEPRECATED)+ enable_if_t< 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>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = false; typedef void result_type; }; @@ -512,17 +490,16 @@ template <typename Executor, typename Property> struct query_member<strand<Executor>, Property,- typename enable_if<+ enable_if_t< can_query<const Executor&, Property>::value- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept =- (is_nothrow_query<Executor, Property>::value));- typedef typename conditional<+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept =+ is_nothrow_query<Executor, Property>::value;+ typedef conditional_t< is_convertible<Property, execution::blocking_t>::value,- execution::blocking_t, typename query_result<Executor, Property>::type- >::type result_type;+ execution::blocking_t, query_result_t<Executor, Property>> result_type; }; #endif // !defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)@@ -531,17 +508,15 @@ template <typename Executor, typename Property> struct require_member<strand<Executor>, Property,- typename enable_if<+ enable_if_t< can_require<const Executor&, Property>::value && !is_convertible<Property, execution::blocking_t::always_t>::value- >::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;+ 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; }; #endif // !defined(ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)@@ -550,17 +525,15 @@ template <typename Executor, typename Property> struct prefer_member<strand<Executor>, Property,- typename enable_if<+ enable_if_t< can_prefer<const Executor&, Property>::value && !is_convertible<Property, execution::blocking_t::always_t>::value- >::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;+ 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; }; #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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/streambuf.hpp view
@@ -2,7 +2,7 @@ // streambuf.hpp // ~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/system_context.hpp view
@@ -2,7 +2,7 @@ // system_context.hpp // ~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -43,13 +43,13 @@ ASIO_DECL ~system_context(); /// Obtain an executor for the context.- executor_type get_executor() ASIO_NOEXCEPT;+ executor_type get_executor() 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 ASIO_NOEXCEPT;+ ASIO_DECL bool stopped() const 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 threads_;+ detail::thread_group<std::allocator<void>> 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -16,113 +16,13 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp"--#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 <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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -39,7 +39,7 @@ { public: /// Default constructor.- basic_system_executor() ASIO_NOEXCEPT+ basic_system_executor() 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 ASIO_CONSTEXPR execution::mapping_t query(- execution::mapping_t) ASIO_NOEXCEPT+ static constexpr execution::mapping_t query(+ execution::mapping_t) 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) ASIO_NOEXCEPT;+ static system_context& query(execution::context_t) noexcept; /// Query the current value of the @c blocking property. /**@@ -224,8 +224,8 @@ * == asio::execution::blocking.always) * ... @endcode */- static ASIO_CONSTEXPR execution::blocking_t query(- execution::blocking_t) ASIO_NOEXCEPT+ static constexpr execution::blocking_t query(+ execution::blocking_t) noexcept { return Blocking(); }@@ -241,8 +241,8 @@ * == asio::execution::relationship.continuation) * ... @endcode */- static ASIO_CONSTEXPR execution::relationship_t query(- execution::relationship_t) ASIO_NOEXCEPT+ static constexpr execution::relationship_t query(+ execution::relationship_t) noexcept { return Relationship(); }@@ -258,8 +258,8 @@ * asio::execution::allocator); @endcode */ template <typename OtherAllocator>- ASIO_CONSTEXPR Allocator query(- execution::allocator_t<OtherAllocator>) const ASIO_NOEXCEPT+ constexpr Allocator query(+ execution::allocator_t<OtherAllocator>) const noexcept { return allocator_; }@@ -274,8 +274,8 @@ * auto alloc = asio::query(ex, * asio::execution::allocator); @endcode */- ASIO_CONSTEXPR Allocator query(- execution::allocator_t<void>) const ASIO_NOEXCEPT+ constexpr Allocator query(+ execution::allocator_t<void>) const 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 ASIO_NOEXCEPT;+ std::size_t query(execution::occupancy_t) const 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&) ASIO_NOEXCEPT+ const basic_system_executor&) 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&) ASIO_NOEXCEPT+ const basic_system_executor&) noexcept { return false; } /// Execution function. template <typename Function>- void execute(ASIO_MOVE_ARG(Function) f) const+ void execute(Function&& f) const {- this->do_execute(ASIO_MOVE_CAST(Function)(f), Blocking());+ this->do_execute(static_cast<Function&&>(f), Blocking()); } #if !defined(ASIO_NO_TS_EXECUTORS) public: /// Obtain the underlying execution context.- system_context& context() const ASIO_NOEXCEPT;+ system_context& context() const 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 ASIO_NOEXCEPT+ void on_work_started() const noexcept { } @@ -338,7 +338,7 @@ /** * For the system executor, this is a no-op. */- void on_work_finished() const ASIO_NOEXCEPT+ void on_work_finished() const noexcept { } @@ -355,7 +355,7 @@ * internal storage needed for function invocation. */ template <typename Function, typename OtherAllocator>- void dispatch(ASIO_MOVE_ARG(Function) f, const OtherAllocator& a) const;+ void dispatch(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(ASIO_MOVE_ARG(Function) f, const OtherAllocator& a) const;+ void post(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(ASIO_MOVE_ARG(Function) f, const OtherAllocator& a) const;+ void defer(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(ASIO_MOVE_ARG(Function) f,+ void do_execute(Function&& f, execution::blocking_t::possibly_t) const; /// Execution helper implementation for the always blocking property. template <typename Function>- void do_execute(ASIO_MOVE_ARG(Function) f,+ void do_execute(Function&& f, execution::blocking_t::always_t) const; /// Execution helper implementation for the never blocking property. template <typename Function>- void do_execute(ASIO_MOVE_ARG(Function) f,+ void do_execute(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> > {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; }; #endif // !defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)@@ -457,8 +457,8 @@ Function > {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = false; typedef void result_type; }; @@ -472,8 +472,8 @@ asio::execution::blocking_t::possibly_t > {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ static constexpr bool is_valid = true;+ 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 > {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ static constexpr bool is_valid = true;+ 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 > {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ static constexpr bool is_valid = true;+ 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 > {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ static constexpr bool is_valid = true;+ 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 > {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ static constexpr bool is_valid = true;+ 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> > {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ static constexpr bool is_valid = true;+ 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> > {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = false; typedef asio::basic_system_executor<Blocking, Relationship, OtherAllocator> result_type; };@@ -573,11 +573,11 @@ >::type > {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef asio::execution::mapping_t::thread_t result_type; - static ASIO_CONSTEXPR result_type value() ASIO_NOEXCEPT+ static constexpr result_type value() noexcept { return result_type(); }@@ -600,8 +600,8 @@ >::type > {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef asio::execution::blocking_t result_type; }; @@ -618,8 +618,8 @@ >::type > {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef asio::execution::relationship_t result_type; }; @@ -629,8 +629,8 @@ asio::execution::context_t > {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef asio::system_context& result_type; }; @@ -640,8 +640,8 @@ asio::execution::allocator_t<void> > {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef Allocator result_type; }; @@ -651,8 +651,8 @@ asio::execution::allocator_t<Allocator> > {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -16,9 +16,6 @@ #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" @@ -36,7 +33,5 @@ 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -26,22 +26,18 @@ /// Awaitable type that returns the executor of the current coroutine. struct executor_t {- ASIO_CONSTEXPR executor_t()+ constexpr executor_t() { } }; /// Awaitable object that returns the executor of the current coroutine.-#if defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)-constexpr executor_t executor;-#elif defined(ASIO_MSVC)-__declspec(selectany) executor_t executor;-#endif+ASIO_INLINE_VARIABLE constexpr executor_t executor; /// Awaitable type that returns the cancellation state of the current coroutine. struct cancellation_state_t {- ASIO_CONSTEXPR cancellation_state_t()+ constexpr cancellation_state_t() { } };@@ -61,11 +57,7 @@ * // ... * } @endcode */-#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+ASIO_INLINE_VARIABLE constexpr cancellation_state_t cancellation_state; #if defined(GENERATING_DOCUMENTATION) @@ -88,7 +80,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 ASIO_CONSTEXPR unspecified+ASIO_NODISCARD constexpr unspecified reset_cancellation_state(); /// Returns an awaitable object that may be used to reset the cancellation state@@ -113,8 +105,8 @@ * of execution" that was created using asio::co_spawn. */ template <typename Filter>-ASIO_NODISCARD ASIO_CONSTEXPR unspecified-reset_cancellation_state(ASIO_MOVE_ARG(Filter) filter);+ASIO_NODISCARD constexpr unspecified+reset_cancellation_state(Filter&& filter); /// Returns an awaitable object that may be used to reset the cancellation state /// of the current coroutine.@@ -140,10 +132,10 @@ * of execution" that was created using asio::co_spawn. */ template <typename InFilter, typename OutFilter>-ASIO_NODISCARD ASIO_CONSTEXPR unspecified+ASIO_NODISCARD constexpr unspecified reset_cancellation_state(- ASIO_MOVE_ARG(InFilter) in_filter,- ASIO_MOVE_ARG(OutFilter) out_filter);+ InFilter&& in_filter,+ 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.@@ -157,7 +149,7 @@ * // ... * } @endcode */-ASIO_NODISCARD ASIO_CONSTEXPR unspecified+ASIO_NODISCARD constexpr unspecified throw_if_cancelled(); /// Returns an awaitable object that may be used to specify whether the@@ -171,19 +163,19 @@ * // ... * } @endcode */-ASIO_NODISCARD ASIO_CONSTEXPR unspecified+ASIO_NODISCARD constexpr unspecified throw_if_cancelled(bool value); #else // defined(GENERATING_DOCUMENTATION) struct reset_cancellation_state_0_t {- ASIO_CONSTEXPR reset_cancellation_state_0_t()+ constexpr reset_cancellation_state_0_t() { } }; -ASIO_NODISCARD inline ASIO_CONSTEXPR reset_cancellation_state_0_t+ASIO_NODISCARD inline constexpr reset_cancellation_state_0_t reset_cancellation_state() { return reset_cancellation_state_0_t();@@ -193,9 +185,9 @@ struct reset_cancellation_state_1_t { template <typename F>- explicit ASIO_CONSTEXPR reset_cancellation_state_1_t(- ASIO_MOVE_ARG(F) filt)- : filter(ASIO_MOVE_CAST(F)(filt))+ explicit constexpr reset_cancellation_state_1_t(+ F&& filt)+ : filter(static_cast<F&&>(filt)) { } @@ -203,22 +195,22 @@ }; template <typename Filter>-ASIO_NODISCARD inline ASIO_CONSTEXPR reset_cancellation_state_1_t<- typename decay<Filter>::type>-reset_cancellation_state(ASIO_MOVE_ARG(Filter) filter)+ASIO_NODISCARD inline constexpr reset_cancellation_state_1_t<+ decay_t<Filter>>+reset_cancellation_state(Filter&& filter) {- return reset_cancellation_state_1_t<typename decay<Filter>::type>(- ASIO_MOVE_CAST(Filter)(filter));+ return reset_cancellation_state_1_t<decay_t<Filter>>(+ static_cast<Filter&&>(filter)); } template <typename InFilter, typename OutFilter> struct reset_cancellation_state_2_t { template <typename F1, typename F2>- 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))+ 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)) { } @@ -227,28 +219,23 @@ }; template <typename InFilter, typename OutFilter>-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)+ASIO_NODISCARD inline constexpr+reset_cancellation_state_2_t<decay_t<InFilter>, decay_t<OutFilter>>+reset_cancellation_state(InFilter&& in_filter, 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));+ return reset_cancellation_state_2_t<decay_t<InFilter>, decay_t<OutFilter>>(+ static_cast<InFilter&&>(in_filter),+ static_cast<OutFilter&&>(out_filter)); } struct throw_if_cancelled_0_t {- ASIO_CONSTEXPR throw_if_cancelled_0_t()+ constexpr throw_if_cancelled_0_t() { } }; -ASIO_NODISCARD inline ASIO_CONSTEXPR throw_if_cancelled_0_t+ASIO_NODISCARD inline constexpr throw_if_cancelled_0_t throw_if_cancelled() { return throw_if_cancelled_0_t();@@ -256,7 +243,7 @@ struct throw_if_cancelled_1_t {- explicit ASIO_CONSTEXPR throw_if_cancelled_1_t(bool val)+ explicit constexpr throw_if_cancelled_1_t(bool val) : value(val) { }@@ -264,7 +251,7 @@ bool value; }; -ASIO_NODISCARD inline ASIO_CONSTEXPR throw_if_cancelled_1_t+ASIO_NODISCARD inline 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/thread_pool.hpp view
@@ -2,7 +2,7 @@ // thread_pool.hpp // ~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -28,11 +28,11 @@ namespace detail { struct thread_pool_bits {- 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);+ 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; }; } // namespace detail @@ -41,6 +41,17 @@ * 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,@@ -84,17 +95,68 @@ /// 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.- ASIO_DECL thread_pool(std::size_t num_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);+ /// Destructor. /** * Automatically stops and joins the pool, if not explicitly done beforehand.@@ -102,13 +164,10 @@ ASIO_DECL ~thread_pool(); /// Obtains the executor associated with the pool.- executor_type get_executor() ASIO_NOEXCEPT;+ executor_type get_executor() noexcept; /// Obtains the executor associated with the pool.- executor_type executor() ASIO_NOEXCEPT;-- /// Obtains the scheduler associated with the pool.- scheduler_type scheduler() ASIO_NOEXCEPT;+ executor_type executor() noexcept; /// Stops the threads. /**@@ -138,26 +197,39 @@ * 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&) ASIO_DELETED;- thread_pool& operator=(const thread_pool&) ASIO_DELETED;+ thread_pool(const thread_pool&) = delete;+ thread_pool& operator=(const thread_pool&) = delete; struct thread_function; - // Helper function to create the underlying scheduler.- ASIO_DECL detail::scheduler& add_scheduler(detail::scheduler* s);+#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();+ // The underlying scheduler. detail::scheduler& scheduler_; // The threads in the pool.- detail::thread_group threads_;+ detail::thread_group<allocator<void>> 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.@@ -165,34 +237,8 @@ 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) ASIO_NOEXCEPT+ basic_executor_type(const basic_executor_type& other) noexcept : pool_(other.pool_), allocator_(other.allocator_), bits_(other.bits_)@@ -202,20 +248,18 @@ pool_->scheduler_.work_started(); } -#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move constructor.- basic_executor_type(basic_executor_type&& other) ASIO_NOEXCEPT+ basic_executor_type(basic_executor_type&& other) noexcept : pool_(other.pool_),- allocator_(ASIO_MOVE_CAST(Allocator)(other.allocator_)),+ allocator_(static_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() ASIO_NOEXCEPT+ ~basic_executor_type() noexcept { if (Bits & outstanding_work_tracked) if (pool_)@@ -223,14 +267,10 @@ } /// Assignment operator.- basic_executor_type& operator=(- const basic_executor_type& other) ASIO_NOEXCEPT;+ basic_executor_type& operator=(const basic_executor_type& other) noexcept; -#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move assignment operator.- basic_executor_type& operator=(- basic_executor_type&& other) ASIO_NOEXCEPT;-#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)+ basic_executor_type& operator=(basic_executor_type&& other) noexcept; #if !defined(GENERATING_DOCUMENTATION) private:@@ -248,7 +288,7 @@ * auto ex2 = asio::require(ex1, * asio::execution::blocking.possibly); @endcode */- ASIO_CONSTEXPR basic_executor_type<Allocator,+ constexpr basic_executor_type<Allocator, ASIO_UNSPECIFIED(Bits & ~blocking_mask)> require(execution::blocking_t::possibly_t) const {@@ -266,7 +306,7 @@ * auto ex2 = asio::require(ex1, * asio::execution::blocking.always); @endcode */- ASIO_CONSTEXPR basic_executor_type<Allocator,+ constexpr basic_executor_type<Allocator, ASIO_UNSPECIFIED((Bits & ~blocking_mask) | blocking_always)> require(execution::blocking_t::always_t) const {@@ -285,7 +325,7 @@ * auto ex2 = asio::require(ex1, * asio::execution::blocking.never); @endcode */- ASIO_CONSTEXPR basic_executor_type<Allocator,+ constexpr basic_executor_type<Allocator, ASIO_UNSPECIFIED(Bits & ~blocking_mask)> require(execution::blocking_t::never_t) const {@@ -303,8 +343,7 @@ * auto ex2 = asio::require(ex1, * asio::execution::relationship.fork); @endcode */- ASIO_CONSTEXPR basic_executor_type require(- execution::relationship_t::fork_t) const+ constexpr basic_executor_type require(execution::relationship_t::fork_t) const { return basic_executor_type(pool_, allocator_, bits_ & ~relationship_continuation);@@ -320,7 +359,7 @@ * auto ex2 = asio::require(ex1, * asio::execution::relationship.continuation); @endcode */- ASIO_CONSTEXPR basic_executor_type require(+ constexpr basic_executor_type require( execution::relationship_t::continuation_t) const { return basic_executor_type(pool_,@@ -337,7 +376,7 @@ * auto ex2 = asio::require(ex1, * asio::execution::outstanding_work.tracked); @endcode */- ASIO_CONSTEXPR basic_executor_type<Allocator,+ constexpr basic_executor_type<Allocator, ASIO_UNSPECIFIED(Bits | outstanding_work_tracked)> require(execution::outstanding_work_t::tracked_t) const {@@ -355,7 +394,7 @@ * auto ex2 = asio::require(ex1, * asio::execution::outstanding_work.untracked); @endcode */- ASIO_CONSTEXPR basic_executor_type<Allocator,+ constexpr basic_executor_type<Allocator, ASIO_UNSPECIFIED(Bits & ~outstanding_work_tracked)> require(execution::outstanding_work_t::untracked_t) const {@@ -374,7 +413,7 @@ * asio::execution::allocator(my_allocator)); @endcode */ template <typename OtherAllocator>- ASIO_CONSTEXPR basic_executor_type<OtherAllocator, Bits>+ constexpr basic_executor_type<OtherAllocator, Bits> require(execution::allocator_t<OtherAllocator> a) const { return basic_executor_type<OtherAllocator, Bits>(@@ -391,7 +430,7 @@ * auto ex2 = asio::require(ex1, * asio::execution::allocator); @endcode */- ASIO_CONSTEXPR basic_executor_type<std::allocator<void>, Bits>+ constexpr basic_executor_type<std::allocator<void>, Bits> require(execution::allocator_t<void>) const { return basic_executor_type<std::allocator<void>, Bits>(@@ -405,25 +444,6 @@ 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@@ -435,8 +455,7 @@ * == asio::execution::mapping.thread) * ... @endcode */- static ASIO_CONSTEXPR execution::mapping_t query(- execution::mapping_t) ASIO_NOEXCEPT+ static constexpr execution::mapping_t query(execution::mapping_t) noexcept { return execution::mapping.thread; }@@ -451,7 +470,7 @@ * asio::thread_pool& pool = asio::query( * ex, asio::execution::context); @endcode */- thread_pool& query(execution::context_t) const ASIO_NOEXCEPT+ thread_pool& query(execution::context_t) const noexcept { return *pool_; }@@ -467,8 +486,7 @@ * == asio::execution::blocking.always) * ... @endcode */- ASIO_CONSTEXPR execution::blocking_t query(- execution::blocking_t) const ASIO_NOEXCEPT+ constexpr execution::blocking_t query(execution::blocking_t) const noexcept { return (bits_ & blocking_never) ? execution::blocking_t(execution::blocking.never)@@ -488,8 +506,8 @@ * == asio::execution::relationship.continuation) * ... @endcode */- ASIO_CONSTEXPR execution::relationship_t query(- execution::relationship_t) const ASIO_NOEXCEPT+ constexpr execution::relationship_t query(+ execution::relationship_t) const noexcept { return (bits_ & relationship_continuation) ? execution::relationship_t(execution::relationship.continuation)@@ -507,8 +525,8 @@ * == asio::execution::outstanding_work.tracked) * ... @endcode */- static ASIO_CONSTEXPR execution::outstanding_work_t query(- execution::outstanding_work_t) ASIO_NOEXCEPT+ static constexpr execution::outstanding_work_t query(+ execution::outstanding_work_t) noexcept { return (Bits & outstanding_work_tracked) ? execution::outstanding_work_t(execution::outstanding_work.tracked)@@ -526,8 +544,8 @@ * asio::execution::allocator); @endcode */ template <typename OtherAllocator>- ASIO_CONSTEXPR Allocator query(- execution::allocator_t<OtherAllocator>) const ASIO_NOEXCEPT+ constexpr Allocator query(+ execution::allocator_t<OtherAllocator>) const noexcept { return allocator_; }@@ -542,8 +560,7 @@ * auto alloc = asio::query(ex, * asio::execution::allocator); @endcode */- ASIO_CONSTEXPR Allocator query(- execution::allocator_t<void>) const ASIO_NOEXCEPT+ constexpr Allocator query(execution::allocator_t<void>) const noexcept { return allocator_; }@@ -558,7 +575,7 @@ * std::size_t occupancy = asio::query( * ex, asio::execution::occupancy); @endcode */- std::size_t query(execution::occupancy_t) const ASIO_NOEXCEPT+ std::size_t query(execution::occupancy_t) const noexcept { return static_cast<std::size_t>(pool_->num_threads_); }@@ -569,14 +586,14 @@ * @return @c true if the current thread is running the thread pool. Otherwise * returns @c false. */- bool running_in_this_thread() const ASIO_NOEXCEPT;+ bool running_in_this_thread() const 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) ASIO_NOEXCEPT+ const basic_executor_type& b) noexcept { return a.pool_ == b.pool_ && a.allocator_ == b.allocator_@@ -588,7 +605,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) ASIO_NOEXCEPT+ const basic_executor_type& b) noexcept { return a.pool_ != b.pool_ || a.allocator_ != b.allocator_@@ -597,58 +614,16 @@ /// Execution function. template <typename Function>- void execute(ASIO_MOVE_ARG(Function) f) const+ void execute(Function&& f) const {- this->do_execute(ASIO_MOVE_CAST(Function)(f),+ this->do_execute(static_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 ASIO_NOEXCEPT;+ thread_pool& context() const noexcept; /// Inform the thread pool that it has some outstanding work to do. /**@@ -656,7 +631,7 @@ * This ensures that the thread pool's join() function will not return while * the work is underway. */- void on_work_started() const ASIO_NOEXCEPT;+ void on_work_started() const noexcept; /// Inform the thread pool that some work is no longer outstanding. /**@@ -664,7 +639,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 ASIO_NOEXCEPT;+ void on_work_finished() const noexcept; /// Request the thread pool to invoke the given function object. /**@@ -681,8 +656,7 @@ * internal storage needed for function invocation. */ template <typename Function, typename OtherAllocator>- void dispatch(ASIO_MOVE_ARG(Function) f,- const OtherAllocator& a) const;+ void dispatch(Function&& f, const OtherAllocator& a) const; /// Request the thread pool to invoke the given function object. /**@@ -698,8 +672,7 @@ * internal storage needed for function invocation. */ template <typename Function, typename OtherAllocator>- void post(ASIO_MOVE_ARG(Function) f,- const OtherAllocator& a) const;+ void post(Function&& f, const OtherAllocator& a) const; /// Request the thread pool to invoke the given function object. /**@@ -719,8 +692,7 @@ * internal storage needed for function invocation. */ template <typename Function, typename OtherAllocator>- void defer(ASIO_MOVE_ARG(Function) f,- const OtherAllocator& a) const;+ void defer(Function&& f, const OtherAllocator& a) const; #endif // !defined(ASIO_NO_TS_EXECUTORS) private:@@ -728,7 +700,7 @@ template <typename, unsigned int> friend class basic_executor_type; // Constructor used by thread_pool::get_executor().- explicit basic_executor_type(thread_pool& p) ASIO_NOEXCEPT+ explicit basic_executor_type(thread_pool& p) noexcept : pool_(&p), allocator_(), bits_(0)@@ -739,7 +711,7 @@ // Constructor used by require(). basic_executor_type(thread_pool* p,- const Allocator& a, unsigned int bits) ASIO_NOEXCEPT+ const Allocator& a, unsigned int bits) noexcept : pool_(p), allocator_(a), bits_(bits)@@ -751,21 +723,11 @@ /// Execution helper implementation for possibly and never blocking. template <typename Function>- void do_execute(ASIO_MOVE_ARG(Function) f, false_type) const;+ void do_execute(Function&& f, false_type) const; /// Execution helper implementation for always blocking. template <typename Function>- 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;+ void do_execute(Function&& f, true_type) const; // The underlying thread pool. thread_pool* pool_;@@ -788,8 +750,8 @@ asio::thread_pool::basic_executor_type<Allocator, Bits> > {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; }; #endif // !defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)@@ -802,53 +764,13 @@ Function > {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ 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_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>@@ -857,8 +779,8 @@ asio::execution::blocking_t::possibly_t > : asio::detail::thread_pool_bits {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef asio::thread_pool::basic_executor_type< Allocator, Bits & ~blocking_mask> result_type; };@@ -869,8 +791,8 @@ asio::execution::blocking_t::always_t > : asio::detail::thread_pool_bits {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = false; typedef asio::thread_pool::basic_executor_type<Allocator, (Bits & ~blocking_mask) | blocking_always> result_type; };@@ -881,8 +803,8 @@ asio::execution::blocking_t::never_t > : asio::detail::thread_pool_bits {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = false; typedef asio::thread_pool::basic_executor_type< Allocator, Bits & ~blocking_mask> result_type; };@@ -893,8 +815,8 @@ asio::execution::relationship_t::fork_t > {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = false; typedef asio::thread_pool::basic_executor_type< Allocator, Bits> result_type; };@@ -905,8 +827,8 @@ asio::execution::relationship_t::continuation_t > {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = false; typedef asio::thread_pool::basic_executor_type< Allocator, Bits> result_type; };@@ -917,8 +839,8 @@ asio::execution::outstanding_work_t::tracked_t > : asio::detail::thread_pool_bits {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = false; typedef asio::thread_pool::basic_executor_type< Allocator, Bits | outstanding_work_tracked> result_type; };@@ -929,8 +851,8 @@ asio::execution::outstanding_work_t::untracked_t > : asio::detail::thread_pool_bits {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = false; typedef asio::thread_pool::basic_executor_type< Allocator, Bits & ~outstanding_work_tracked> result_type; };@@ -941,8 +863,8 @@ asio::execution::allocator_t<void> > {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = false; typedef asio::thread_pool::basic_executor_type< std::allocator<void>, Bits> result_type; };@@ -954,8 +876,8 @@ asio::execution::allocator_t<OtherAllocator> > {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = false; typedef asio::thread_pool::basic_executor_type< OtherAllocator, Bits> result_type; };@@ -964,8 +886,6 @@ #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>,@@ -973,40 +893,16 @@ 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 {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef asio::execution::outstanding_work_t result_type; - static ASIO_CONSTEXPR result_type value() ASIO_NOEXCEPT+ static constexpr result_type value() noexcept { return (Bits & outstanding_work_tracked) ? execution::outstanding_work_t(execution::outstanding_work.tracked)@@ -1026,11 +922,11 @@ >::type > {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef asio::execution::mapping_t::thread_t result_type; - static ASIO_CONSTEXPR result_type value() ASIO_NOEXCEPT+ static constexpr result_type value() noexcept { return result_type(); }@@ -1052,8 +948,8 @@ >::type > {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef asio::execution::blocking_t result_type; }; @@ -1069,8 +965,8 @@ >::type > {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef asio::execution::relationship_t result_type; }; @@ -1080,8 +976,8 @@ asio::execution::occupancy_t > {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef std::size_t result_type; }; @@ -1091,8 +987,8 @@ asio::execution::context_t > {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef asio::thread_pool& result_type; }; @@ -1102,8 +998,8 @@ asio::execution::allocator_t<void> > {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ static constexpr bool is_noexcept = true; typedef Allocator result_type; }; @@ -1113,8 +1009,8 @@ asio::execution::allocator_t<OtherAllocator> > {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+ static constexpr bool is_valid = true;+ 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -17,6 +17,8 @@ #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) @@ -26,11 +28,11 @@ namespace asio { -/// Time traits suitable for use with the deadline timer.+/// (Deprecated) Time traits suitable for use with the deadline timer. template <typename Time> struct time_traits; -/// Time traits specialised for posix_time.+/// (Deprecated) Time traits specialised for posix_time. template <> struct time_traits<boost::posix_time::ptime> {@@ -82,5 +84,7 @@ #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
@@ -1,114 +0,0 @@-//-// 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
@@ -1,114 +0,0 @@-//-// 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
@@ -1,112 +0,0 @@-//-// 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
@@ -1,112 +0,0 @@-//-// 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -18,13 +18,9 @@ #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)+#if defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) # define ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT 1-#endif // defined(ASIO_HAS_DECLTYPE)- // && defined(ASIO_HAS_NOEXCEPT)- // && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#endif // defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) namespace asio { namespace traits {@@ -40,8 +36,8 @@ struct no_equality_comparable {- ASIO_STATIC_CONSTEXPR(bool, is_valid = false);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ static constexpr bool is_valid = false;+ static constexpr bool is_noexcept = false; }; #if defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)@@ -53,7 +49,7 @@ template <typename T> struct equality_comparable_trait<T,- typename void_type<+ void_t< decltype( static_cast<void>( static_cast<bool>(declval<const T>() == declval<const T>())@@ -62,24 +58,24 @@ static_cast<bool>(declval<const T>() != declval<const T>()) ) )- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ static constexpr bool is_valid = true; - ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+ 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<- is_same<T, typename decay<T>::type>::value,+ conditional_t<+ is_same<T, decay_t<T>>::value, no_equality_comparable,- traits::equality_comparable<typename decay<T>::type>- >::type+ traits::equality_comparable<decay_t<T>>+ > { };
− link/modules/asio-standalone/asio/include/asio/traits/execute_free.hpp
@@ -1,108 +0,0 @@-//-// 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -18,13 +18,9 @@ #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)+#if defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) # define ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT 1-#endif // defined(ASIO_HAS_DECLTYPE)- // && defined(ASIO_HAS_NOEXCEPT)- // && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#endif // defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) #include "asio/detail/push_options.hpp" @@ -42,8 +38,8 @@ struct no_execute_member {- ASIO_STATIC_CONSTEXPR(bool, is_valid = false);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ static constexpr bool is_valid = false;+ static constexpr bool is_noexcept = false; }; #if defined(ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)@@ -55,31 +51,31 @@ template <typename T, typename F> struct execute_member_trait<T, F,- typename void_type<+ void_t< decltype(declval<T>().execute(declval<F>()))- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ static constexpr bool is_valid = true; using result_type = decltype( declval<T>().execute(declval<F>())); - ASIO_STATIC_CONSTEXPR(bool, is_noexcept = noexcept(- declval<T>().execute(declval<F>())));+ 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<- is_same<T, typename decay<T>::type>::value- && is_same<F, typename decay<F>::type>::value,+ conditional_t<+ is_same<T, decay_t<T>>::value+ && is_same<F, decay_t<F>>::value, no_execute_member, traits::execute_member<- typename decay<T>::type,- typename decay<F>::type>- >::type+ decay_t<T>,+ decay_t<F>>+ > { };
link/modules/asio-standalone/asio/include/asio/traits/prefer_free.hpp view
@@ -2,7 +2,7 @@ // traits/prefer_free.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -18,13 +18,9 @@ #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)+#if defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) # define ASIO_HAS_DEDUCED_PREFER_FREE_TRAIT 1-#endif // defined(ASIO_HAS_DECLTYPE)- // && defined(ASIO_HAS_NOEXCEPT)- // && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#endif // defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) #include "asio/detail/push_options.hpp" @@ -42,8 +38,8 @@ struct no_prefer_free {- ASIO_STATIC_CONSTEXPR(bool, is_valid = false);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ static constexpr bool is_valid = false;+ static constexpr bool is_noexcept = false; }; #if defined(ASIO_HAS_DEDUCED_PREFER_FREE_TRAIT)@@ -55,31 +51,31 @@ template <typename T, typename Property> struct prefer_free_trait<T, Property,- typename void_type<+ void_t< decltype(prefer(declval<T>(), declval<Property>()))- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ static constexpr bool is_valid = true; using result_type = decltype( prefer(declval<T>(), declval<Property>())); - ASIO_STATIC_CONSTEXPR(bool, is_noexcept = noexcept(- prefer(declval<T>(), declval<Property>())));+ 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<- is_same<T, typename decay<T>::type>::value- && is_same<Property, typename decay<Property>::type>::value,+ conditional_t<+ is_same<T, decay_t<T>>::value+ && is_same<Property, decay_t<Property>>::value, no_prefer_free, traits::prefer_free<- typename decay<T>::type,- typename decay<Property>::type>- >::type+ decay_t<T>,+ decay_t<Property>>+ > { };
link/modules/asio-standalone/asio/include/asio/traits/prefer_member.hpp view
@@ -2,7 +2,7 @@ // traits/prefer_member.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -18,13 +18,9 @@ #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)+#if defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) # define ASIO_HAS_DEDUCED_PREFER_MEMBER_TRAIT 1-#endif // defined(ASIO_HAS_DECLTYPE)- // && defined(ASIO_HAS_NOEXCEPT)- // && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#endif // defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) #include "asio/detail/push_options.hpp" @@ -42,8 +38,8 @@ struct no_prefer_member {- ASIO_STATIC_CONSTEXPR(bool, is_valid = false);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ static constexpr bool is_valid = false;+ static constexpr bool is_noexcept = false; }; #if defined(ASIO_HAS_DEDUCED_PREFER_MEMBER_TRAIT)@@ -55,31 +51,31 @@ template <typename T, typename Property> struct prefer_member_trait<T, Property,- typename void_type<+ void_t< decltype(declval<T>().prefer(declval<Property>()))- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ static constexpr bool is_valid = true; using result_type = decltype( declval<T>().prefer(declval<Property>())); - ASIO_STATIC_CONSTEXPR(bool, is_noexcept = noexcept(- declval<T>().prefer(declval<Property>())));+ 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<- is_same<T, typename decay<T>::type>::value- && is_same<Property, typename decay<Property>::type>::value,+ conditional_t<+ is_same<T, decay_t<T>>::value+ && is_same<Property, decay_t<Property>>::value, no_prefer_member, traits::prefer_member<- typename decay<T>::type,- typename decay<Property>::type>- >::type+ decay_t<T>,+ decay_t<Property>>+ > { };
link/modules/asio-standalone/asio/include/asio/traits/query_free.hpp view
@@ -2,7 +2,7 @@ // traits/query_free.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -18,13 +18,9 @@ #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)+#if defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) # define ASIO_HAS_DEDUCED_QUERY_FREE_TRAIT 1-#endif // defined(ASIO_HAS_DECLTYPE)- // && defined(ASIO_HAS_NOEXCEPT)- // && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#endif // defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) #include "asio/detail/push_options.hpp" @@ -42,8 +38,8 @@ struct no_query_free {- ASIO_STATIC_CONSTEXPR(bool, is_valid = false);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ static constexpr bool is_valid = false;+ static constexpr bool is_noexcept = false; }; #if defined(ASIO_HAS_DEDUCED_QUERY_FREE_TRAIT)@@ -55,31 +51,31 @@ template <typename T, typename Property> struct query_free_trait<T, Property,- typename void_type<+ void_t< decltype(query(declval<T>(), declval<Property>()))- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ static constexpr bool is_valid = true; using result_type = decltype( query(declval<T>(), declval<Property>())); - ASIO_STATIC_CONSTEXPR(bool, is_noexcept = noexcept(- query(declval<T>(), declval<Property>())));+ 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<- is_same<T, typename decay<T>::type>::value- && is_same<Property, typename decay<Property>::type>::value,+ conditional_t<+ is_same<T, decay_t<T>>::value+ && is_same<Property, decay_t<Property>>::value, no_query_free, traits::query_free<- typename decay<T>::type,- typename decay<Property>::type>- >::type+ decay_t<T>,+ decay_t<Property>>+ > { };
link/modules/asio-standalone/asio/include/asio/traits/query_member.hpp view
@@ -2,7 +2,7 @@ // traits/query_member.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -18,13 +18,9 @@ #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)+#if defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) # define ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT 1-#endif // defined(ASIO_HAS_DECLTYPE)- // && defined(ASIO_HAS_NOEXCEPT)- // && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#endif // defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) #include "asio/detail/push_options.hpp" @@ -42,8 +38,8 @@ struct no_query_member {- ASIO_STATIC_CONSTEXPR(bool, is_valid = false);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ static constexpr bool is_valid = false;+ static constexpr bool is_noexcept = false; }; #if defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)@@ -55,31 +51,31 @@ template <typename T, typename Property> struct query_member_trait<T, Property,- typename void_type<+ void_t< decltype(declval<T>().query(declval<Property>()))- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ static constexpr bool is_valid = true; using result_type = decltype( declval<T>().query(declval<Property>())); - ASIO_STATIC_CONSTEXPR(bool, is_noexcept = noexcept(- declval<T>().query(declval<Property>())));+ 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<- is_same<T, typename decay<T>::type>::value- && is_same<Property, typename decay<Property>::type>::value,+ conditional_t<+ is_same<T, decay_t<T>>::value+ && is_same<Property, decay_t<Property>>::value, no_query_member, traits::query_member<- typename decay<T>::type,- typename decay<Property>::type>- >::type+ decay_t<T>,+ decay_t<Property>>+ > { };
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -18,16 +18,10 @@ #include "asio/detail/config.hpp" #include "asio/detail/type_traits.hpp" -#if defined(ASIO_HAS_DECLTYPE) \- && defined(ASIO_HAS_NOEXCEPT) \- && defined(ASIO_HAS_CONSTEXPR) \- && defined(ASIO_HAS_CONSTANT_EXPRESSION_SFINAE) \+#if 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_DECLTYPE)- // && defined(ASIO_HAS_NOEXCEPT)- // && defined(ASIO_HAS_CONSTEXPR)- // && defined(ASIO_HAS_CONSTANT_EXPRESSION_SFINAE)+#endif // defined(ASIO_HAS_CONSTANT_EXPRESSION_SFINAE) // && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) #include "asio/detail/push_options.hpp"@@ -46,19 +40,19 @@ struct no_query_static_constexpr_member {- ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+ static constexpr bool is_valid = false; }; template <typename T, typename Property, typename = void> struct query_static_constexpr_member_trait :- conditional<- is_same<T, typename decay<T>::type>::value- && is_same<Property, typename decay<Property>::type>::value,+ conditional_t<+ is_same<T, decay_t<T>>::value+ && is_same<Property, decay_t<Property>>::value, no_query_static_constexpr_member, traits::query_static_constexpr_member<- typename decay<T>::type,- typename decay<Property>::type>- >::type+ decay_t<T>,+ decay_t<Property>>+ > { }; @@ -66,18 +60,17 @@ template <typename T, typename Property> struct query_static_constexpr_member_trait<T, Property,- typename enable_if<+ enable_if_t< (static_cast<void>(T::query(Property{})), true)- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ static constexpr bool is_valid = true; using result_type = decltype(T::query(Property{})); - ASIO_STATIC_CONSTEXPR(bool, is_noexcept =- noexcept(T::query(Property{})));+ static constexpr bool is_noexcept = noexcept(T::query(Property{})); - static ASIO_CONSTEXPR result_type value() noexcept(is_noexcept)+ static 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -18,13 +18,9 @@ #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)+#if defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) # define ASIO_HAS_DEDUCED_REQUIRE_CONCEPT_FREE_TRAIT 1-#endif // defined(ASIO_HAS_DECLTYPE)- // && defined(ASIO_HAS_NOEXCEPT)- // && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#endif // defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) #include "asio/detail/push_options.hpp" @@ -42,8 +38,8 @@ struct no_require_concept_free {- ASIO_STATIC_CONSTEXPR(bool, is_valid = false);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ static constexpr bool is_valid = false;+ static constexpr bool is_noexcept = false; }; #if defined(ASIO_HAS_DEDUCED_REQUIRE_CONCEPT_FREE_TRAIT)@@ -55,31 +51,31 @@ template <typename T, typename Property> struct require_concept_free_trait<T, Property,- typename void_type<+ void_t< decltype(require_concept(declval<T>(), declval<Property>()))- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ static constexpr bool is_valid = true; using result_type = decltype( require_concept(declval<T>(), declval<Property>())); - ASIO_STATIC_CONSTEXPR(bool, is_noexcept = noexcept(- require_concept(declval<T>(), declval<Property>())));+ 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<- is_same<T, typename decay<T>::type>::value- && is_same<Property, typename decay<Property>::type>::value,+ conditional_t<+ is_same<T, decay_t<T>>::value+ && is_same<Property, decay_t<Property>>::value, no_require_concept_free, traits::require_concept_free<- typename decay<T>::type,- typename decay<Property>::type>- >::type+ decay_t<T>,+ decay_t<Property>>+ > { };
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -18,13 +18,9 @@ #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)+#if defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) # define ASIO_HAS_DEDUCED_REQUIRE_CONCEPT_MEMBER_TRAIT 1-#endif // defined(ASIO_HAS_DECLTYPE)- // && defined(ASIO_HAS_NOEXCEPT)- // && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#endif // defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) #include "asio/detail/push_options.hpp" @@ -42,8 +38,8 @@ struct no_require_concept_member {- ASIO_STATIC_CONSTEXPR(bool, is_valid = false);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ static constexpr bool is_valid = false;+ static constexpr bool is_noexcept = false; }; #if defined(ASIO_HAS_DEDUCED_REQUIRE_CONCEPT_MEMBER_TRAIT)@@ -55,31 +51,31 @@ template <typename T, typename Property> struct require_concept_member_trait<T, Property,- typename void_type<+ void_t< decltype(declval<T>().require_concept(declval<Property>()))- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ static constexpr bool is_valid = true; using result_type = decltype( declval<T>().require_concept(declval<Property>())); - ASIO_STATIC_CONSTEXPR(bool, is_noexcept = noexcept(- declval<T>().require_concept(declval<Property>())));+ 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<- is_same<T, typename decay<T>::type>::value- && is_same<Property, typename decay<Property>::type>::value,+ conditional_t<+ is_same<T, decay_t<T>>::value+ && is_same<Property, decay_t<Property>>::value, no_require_concept_member, traits::require_concept_member<- typename decay<T>::type,- typename decay<Property>::type>- >::type+ decay_t<T>,+ decay_t<Property>>+ > { };
link/modules/asio-standalone/asio/include/asio/traits/require_free.hpp view
@@ -2,7 +2,7 @@ // traits/require_free.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -18,13 +18,9 @@ #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)+#if defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) # define ASIO_HAS_DEDUCED_REQUIRE_FREE_TRAIT 1-#endif // defined(ASIO_HAS_DECLTYPE)- // && defined(ASIO_HAS_NOEXCEPT)- // && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#endif // defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) #include "asio/detail/push_options.hpp" @@ -42,8 +38,8 @@ struct no_require_free {- ASIO_STATIC_CONSTEXPR(bool, is_valid = false);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ static constexpr bool is_valid = false;+ static constexpr bool is_noexcept = false; }; #if defined(ASIO_HAS_DEDUCED_REQUIRE_FREE_TRAIT)@@ -55,31 +51,31 @@ template <typename T, typename Property> struct require_free_trait<T, Property,- typename void_type<+ void_t< decltype(require(declval<T>(), declval<Property>()))- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ static constexpr bool is_valid = true; using result_type = decltype( require(declval<T>(), declval<Property>())); - ASIO_STATIC_CONSTEXPR(bool, is_noexcept = noexcept(- require(declval<T>(), declval<Property>())));+ 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<- is_same<T, typename decay<T>::type>::value- && is_same<Property, typename decay<Property>::type>::value,+ conditional_t<+ is_same<T, decay_t<T>>::value+ && is_same<Property, decay_t<Property>>::value, no_require_free, traits::require_free<- typename decay<T>::type,- typename decay<Property>::type>- >::type+ decay_t<T>,+ decay_t<Property>>+ > { };
link/modules/asio-standalone/asio/include/asio/traits/require_member.hpp view
@@ -2,7 +2,7 @@ // traits/require_member.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -18,13 +18,9 @@ #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)+#if defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) # define ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT 1-#endif // defined(ASIO_HAS_DECLTYPE)- // && defined(ASIO_HAS_NOEXCEPT)- // && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#endif // defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) #include "asio/detail/push_options.hpp" @@ -42,8 +38,8 @@ struct no_require_member {- ASIO_STATIC_CONSTEXPR(bool, is_valid = false);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ static constexpr bool is_valid = false;+ static constexpr bool is_noexcept = false; }; #if defined(ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)@@ -55,31 +51,31 @@ template <typename T, typename Property> struct require_member_trait<T, Property,- typename void_type<+ void_t< decltype(declval<T>().require(declval<Property>()))- >::type>+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ static constexpr bool is_valid = true; using result_type = decltype( declval<T>().require(declval<Property>())); - ASIO_STATIC_CONSTEXPR(bool, is_noexcept = noexcept(- declval<T>().require(declval<Property>())));+ 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<- is_same<T, typename decay<T>::type>::value- && is_same<Property, typename decay<Property>::type>::value,+ conditional_t<+ is_same<T, decay_t<T>>::value+ && is_same<Property, decay_t<Property>>::value, no_require_member, traits::require_member<- typename decay<T>::type,- typename decay<Property>::type>- >::type+ decay_t<T>,+ decay_t<Property>>+ > { };
− link/modules/asio-standalone/asio/include/asio/traits/schedule_free.hpp
@@ -1,108 +0,0 @@-//-// 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
@@ -1,108 +0,0 @@-//-// 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
@@ -1,108 +0,0 @@-//-// 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
@@ -1,108 +0,0 @@-//-// 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
@@ -1,112 +0,0 @@-//-// 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
@@ -1,112 +0,0 @@-//-// 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
@@ -1,234 +0,0 @@-//-// 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
@@ -1,234 +0,0 @@-//-// 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
@@ -1,108 +0,0 @@-//-// 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
@@ -1,108 +0,0 @@-//-// 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -18,16 +18,10 @@ #include "asio/detail/config.hpp" #include "asio/detail/type_traits.hpp" -#if defined(ASIO_HAS_DECLTYPE) \- && defined(ASIO_HAS_NOEXCEPT) \- && defined(ASIO_HAS_CONSTEXPR) \- && defined(ASIO_HAS_VARIABLE_TEMPLATES) \+#if defined(ASIO_HAS_VARIABLE_TEMPLATES) \ && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) # define ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT 1-#endif // defined(ASIO_HAS_DECLTYPE)- // && defined(ASIO_HAS_NOEXCEPT)- // && defined(ASIO_HAS_CONSTEXPR)- // && defined(ASIO_HAS_VARIABLE_TEMPLATES)+#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) // && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) #include "asio/detail/push_options.hpp"@@ -46,20 +40,20 @@ struct no_static_query {- ASIO_STATIC_CONSTEXPR(bool, is_valid = false);- ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+ static constexpr bool is_valid = false;+ static constexpr bool is_noexcept = false; }; template <typename T, typename Property, typename = void> struct static_query_trait :- conditional<- is_same<T, typename decay<T>::type>::value- && is_same<Property, typename decay<Property>::type>::value,+ conditional_t<+ is_same<T, decay_t<T>>::value+ && is_same<Property, decay_t<Property>>::value, no_static_query, traits::static_query<- typename decay<T>::type,- typename decay<Property>::type>- >::type+ decay_t<T>,+ decay_t<Property>>+ > { }; @@ -67,21 +61,21 @@ template <typename T, typename Property> struct static_query_trait<T, Property,- typename void_type<- decltype(decay<Property>::type::template static_query_v<T>)- >::type>+ void_t<+ decltype(decay_t<Property>::template static_query_v<T>)+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ static constexpr bool is_valid = true; using result_type = decltype(- decay<Property>::type::template static_query_v<T>);+ 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 bool is_noexcept =+ noexcept(decay_t<Property>::template static_query_v<T>); - static ASIO_CONSTEXPR result_type value() noexcept(is_noexcept)+ static constexpr result_type value() noexcept(is_noexcept) {- return decay<Property>::type::template static_query_v<T>;+ return decay_t<Property>::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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -19,11 +19,7 @@ #include "asio/detail/type_traits.hpp" #include "asio/traits/static_query.hpp" -#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)+#define ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT 1 #include "asio/detail/push_options.hpp" @@ -41,33 +37,31 @@ struct no_static_require {- ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+ static constexpr bool is_valid = false; }; template <typename T, typename Property, typename = void> struct static_require_trait :- conditional<- is_same<T, typename decay<T>::type>::value- && is_same<Property, typename decay<Property>::type>::value,+ conditional_t<+ is_same<T, decay_t<T>>::value+ && is_same<Property, decay_t<Property>>::value, no_static_require, traits::static_require<- typename decay<T>::type,- typename decay<Property>::type>- >::type+ decay_t<T>,+ decay_t<Property>>+ > { }; -#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,- typename enable_if<- decay<Property>::type::value() == traits::static_query<T, Property>::value()- >::type>+ enable_if_t<+ decay_t<Property>::value() == traits::static_query<T, Property>::value()+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ static constexpr bool is_valid = true; }; #else // defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)@@ -76,31 +70,29 @@ template <typename T, typename Property> true_type static_require_test(T*, Property*,- typename enable_if<+ enable_if_t< Property::value() == traits::static_query<T, Property>::value()- >::type* = 0);+ >* = 0); template <typename T, typename Property> struct has_static_require {- ASIO_STATIC_CONSTEXPR(bool, value =+ 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,- typename enable_if<- has_static_require<typename decay<T>::type,- typename decay<Property>::type>::value- >::type>+ enable_if_t<+ has_static_require<decay_t<T>,+ decay_t<Property>>::value+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -19,11 +19,7 @@ #include "asio/detail/type_traits.hpp" #include "asio/traits/static_query.hpp" -#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)+#define ASIO_HAS_DEDUCED_STATIC_REQUIRE_CONCEPT_TRAIT 1 #include "asio/detail/push_options.hpp" @@ -41,33 +37,31 @@ struct no_static_require_concept {- ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+ static constexpr bool is_valid = false; }; template <typename T, typename Property, typename = void> struct static_require_concept_trait :- conditional<- is_same<T, typename decay<T>::type>::value- && is_same<Property, typename decay<Property>::type>::value,+ conditional_t<+ is_same<T, decay_t<T>>::value+ && is_same<Property, decay_t<Property>>::value, no_static_require_concept, traits::static_require_concept<- typename decay<T>::type,- typename decay<Property>::type>- >::type+ decay_t<T>,+ decay_t<Property>>+ > { }; -#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,- typename enable_if<- decay<Property>::type::value() == traits::static_query<T, Property>::value()- >::type>+ enable_if_t<+ decay_t<Property>::value() == traits::static_query<T, Property>::value()+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ static constexpr bool is_valid = true; }; #else // defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)@@ -76,31 +70,29 @@ template <typename T, typename Property> true_type static_require_concept_test(T*, Property*,- typename enable_if<+ enable_if_t< Property::value() == traits::static_query<T, Property>::value()- >::type* = 0);+ >* = 0); template <typename T, typename Property> struct has_static_require_concept {- ASIO_STATIC_CONSTEXPR(bool, value =+ 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,- typename enable_if<- has_static_require_concept<typename decay<T>::type,- typename decay<Property>::type>::value- >::type>+ enable_if_t<+ has_static_require_concept<decay_t<T>,+ decay_t<Property>>::value+ >> {- ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+ 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
@@ -1,112 +0,0 @@-//-// 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
@@ -1,112 +0,0 @@-//-// 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/ts/executor.hpp view
@@ -2,7 +2,7 @@ // ts/executor.hpp // ~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/ts/internet.hpp view
@@ -2,7 +2,7 @@ // ts/internet.hpp // ~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/ts/io_context.hpp view
@@ -2,7 +2,7 @@ // ts/io_context.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/ts/net.hpp view
@@ -2,7 +2,7 @@ // ts/net.hpp // ~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/ts/netfwd.hpp view
@@ -2,7 +2,7 @@ // ts/netfwd.hpp // ~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -16,14 +16,7 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.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)+#include "asio/detail/chrono.hpp" #if !defined(ASIO_USE_TS_EXECUTOR_AS_DEFAULT) #include "asio/execution/blocking.hpp"@@ -66,20 +59,9 @@ #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>@@ -102,13 +84,6 @@ 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 @@ -119,8 +94,6 @@ #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;@@ -128,8 +101,6 @@ 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 @@ -168,14 +139,8 @@ // 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> >-#endif+ typename WaitTraits = wait_traits<Clock>> class basic_socket_streambuf; #endif // !defined(ASIO_BASIC_SOCKET_STREAMBUF_FWD_DECL)@@ -185,14 +150,8 @@ // 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> >-#endif+ typename WaitTraits = wait_traits<Clock>> 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/ts/timer.hpp view
@@ -2,7 +2,7 @@ // ts/timer.hpp // ~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/unyield.hpp view
@@ -2,7 +2,7 @@ // unyield.hpp // ~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/use_awaitable.hpp view
@@ -2,7 +2,7 @@ // use_awaitable.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -53,7 +53,7 @@ struct use_awaitable_t { /// Default constructor.- ASIO_CONSTEXPR use_awaitable_t(+ 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.- ASIO_CONSTEXPR use_awaitable_t(const char* file_name,+ 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,- typename constraint<- conditional<+ constraint_t<+ conditional_t< !is_same<InnerExecutor1, executor_with_default>::value, is_convertible<InnerExecutor1, InnerExecutor>, false_type- >::type::value- >::type = 0) ASIO_NOEXCEPT+ >::value+ > = 0) noexcept : InnerExecutor(ex) { }@@ -115,25 +115,21 @@ /// 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;-#endif // defined(ASIO_HAS_ALIAS_TEMPLATES)- // || defined(GENERATING_DOCUMENTATION)+ executor_with_default<typename T::executor_type>>::other; /// 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>::type::template rebind_executor<- executor_with_default<typename decay<T>::type::executor_type>+ static typename decay_t<T>::template rebind_executor<+ executor_with_default<typename decay_t<T>::executor_type> >::other- as_default_on(ASIO_MOVE_ARG(T) object)+ as_default_on(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));+ return typename decay_t<T>::template rebind_executor<+ executor_with_default<typename decay_t<T>::executor_type>+ >::other(static_cast<T&&>(object)); } #if defined(ASIO_ENABLE_HANDLER_TRACKING)@@ -149,11 +145,9 @@ * See the documentation for asio::use_awaitable_t for a usage example. */ #if defined(GENERATING_DOCUMENTATION)-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);+ASIO_INLINE_VARIABLE constexpr use_awaitable_t<> use_awaitable;+#else+ASIO_INLINE_VARIABLE constexpr 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -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.- ASIO_CONSTEXPR use_future_t()+ constexpr use_future_t() { } @@ -73,15 +73,6 @@ { } -#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@@ -99,7 +90,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 retuned via a std::future.+ * operation, the result of the function object is returned via a std::future. * * @par Example *@@ -116,16 +107,16 @@ #if defined(GENERATING_DOCUMENTATION) unspecified #else // defined(GENERATING_DOCUMENTATION)- detail::packaged_token<typename decay<Function>::type, Allocator>+ detail::packaged_token<decay_t<Function>, Allocator> #endif // defined(GENERATING_DOCUMENTATION)- operator()(ASIO_MOVE_ARG(Function) f) const;+ operator()(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 {- ASIO_CONSTEXPR std_allocator_void()+ constexpr std_allocator_void() { } @@ -135,9 +126,9 @@ } }; - typename conditional<+ conditional_t< is_same<std::allocator<void>, Allocator>::value,- std_allocator_void, Allocator>::type allocator_;+ std_allocator_void, Allocator> allocator_; }; /// A @ref completion_token object that causes an asynchronous operation to@@ -145,11 +136,7 @@ /** * See the documentation for asio::use_future_t for a usage example. */-#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+ASIO_INLINE_VARIABLE constexpr use_future_t<> use_future; } // namespace asio
link/modules/asio-standalone/asio/include/asio/uses_executor.hpp view
@@ -2,7 +2,7 @@ // uses_executor.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -34,7 +34,7 @@ struct executor_arg_t { /// Constructor.- ASIO_CONSTEXPR executor_arg_t() ASIO_NOEXCEPT+ constexpr executor_arg_t() noexcept { } };@@ -45,11 +45,7 @@ * See asio::executor_arg_t and asio::uses_executor * for more information. */-#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+ASIO_INLINE_VARIABLE constexpr executor_arg_t executor_arg; /// 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -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 102800 // 1.28.0+#define ASIO_VERSION 103600 // 1.36.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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2025 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,6 +21,7 @@ #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"@@ -29,10 +30,6 @@ #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 {@@ -99,10 +96,10 @@ */ template <typename ExecutionContext> explicit basic_object_handle(ExecutionContext& context,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- >::type = defaulted_constraint())+ > = defaulted_constraint()) : impl_(0, 0, context) { }@@ -145,9 +142,9 @@ template <typename ExecutionContext> basic_object_handle(ExecutionContext& context, const native_handle_type& native_handle,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value- >::type = 0)+ > = 0) : impl_(0, 0, context) { asio::error_code ec;@@ -155,7 +152,6 @@ 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.@@ -206,10 +202,10 @@ */ template<typename Executor1> basic_object_handle(basic_object_handle<Executor1>&& other,- typename constraint<+ constraint_t< is_convertible<Executor1, Executor>::value, defaulted_constraint- >::type = defaulted_constraint())+ > = defaulted_constraint()) : impl_(std::move(other.impl_)) { }@@ -226,18 +222,17 @@ * constructor. */ template<typename Executor1>- typename constraint<+ constraint_t< is_convertible<Executor1, Executor>::value, basic_object_handle&- >::type operator=(basic_object_handle<Executor1>&& other)+ > 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() ASIO_NOEXCEPT+ const executor_type& get_executor() noexcept { return impl_.get_executor(); }@@ -420,22 +415,19 @@ * 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().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code) @endcode */ template < ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code))- 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((+ WaitToken = default_completion_token_t<executor_type>>+ auto async_wait(+ WaitToken&& token = default_completion_token_t<executor_type>())+ -> decltype( 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);@@ -443,8 +435,8 @@ private: // Disallow copying and assignment.- basic_object_handle(const basic_object_handle&) ASIO_DELETED;- basic_object_handle& operator=(const basic_object_handle&) ASIO_DELETED;+ basic_object_handle(const basic_object_handle&) = delete;+ basic_object_handle& operator=(const basic_object_handle&) = delete; class initiate_async_wait {@@ -456,13 +448,13 @@ { } - const executor_type& get_executor() const ASIO_NOEXCEPT+ const executor_type& get_executor() const noexcept { return self_->get_executor(); } template <typename WaitHandler>- void operator()(ASIO_MOVE_ARG(WaitHandler) handler) const+ void operator()(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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -22,6 +22,7 @@ || 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"@@ -30,10 +31,6 @@ #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 {@@ -99,10 +96,10 @@ */ template <typename ExecutionContext> explicit basic_overlapped_handle(ExecutionContext& context,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- >::type = defaulted_constraint())+ > = defaulted_constraint()) : impl_(0, 0, context) { }@@ -145,9 +142,9 @@ template <typename ExecutionContext> basic_overlapped_handle(ExecutionContext& context, const native_handle_type& native_handle,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value- >::type = 0)+ > = 0) : impl_(0, 0, context) { asio::error_code ec;@@ -155,7 +152,6 @@ 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.@@ -207,10 +203,10 @@ */ template<typename Executor1> basic_overlapped_handle(basic_overlapped_handle<Executor1>&& other,- typename constraint<+ constraint_t< is_convertible<Executor1, Executor>::value, defaulted_constraint- >::type = defaulted_constraint())+ > = defaulted_constraint()) : impl_(std::move(other.impl_)) { }@@ -227,18 +223,17 @@ * constructor. */ template<typename Executor1>- typename constraint<+ constraint_t< is_convertible<Executor1, Executor>::value, basic_overlapped_handle&- >::type operator=(basic_overlapped_handle<Executor1>&& other)+ > 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() ASIO_NOEXCEPT+ const executor_type& get_executor() noexcept { return impl_.get_executor(); }@@ -443,9 +438,9 @@ private: // Disallow copying and assignment.- basic_overlapped_handle(const basic_overlapped_handle&) ASIO_DELETED;+ basic_overlapped_handle(const basic_overlapped_handle&) = delete; basic_overlapped_handle& operator=(- const basic_overlapped_handle&) ASIO_DELETED;+ const basic_overlapped_handle&) = delete; }; } // 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -88,10 +88,10 @@ */ template <typename ExecutionContext> explicit basic_random_access_handle(ExecutionContext& context,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- >::type = defaulted_constraint())+ > = defaulted_constraint()) : basic_overlapped_handle<Executor>(context) { }@@ -131,14 +131,13 @@ template <typename ExecutionContext> basic_random_access_handle(ExecutionContext& context, const native_handle_type& handle,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value- >::type = 0)+ > = 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.@@ -187,10 +186,10 @@ */ template<typename Executor1> basic_random_access_handle(basic_random_access_handle<Executor1>&& other,- typename constraint<+ constraint_t< is_convertible<Executor1, Executor>::value, defaulted_constraint- >::type = defaulted_constraint())+ > = defaulted_constraint()) : basic_overlapped_handle<Executor>(std::move(other)) { }@@ -209,15 +208,14 @@ * constructor. */ template<typename Executor1>- typename constraint<+ constraint_t< is_convertible<Executor1, Executor>::value, basic_random_access_handle&- >::type operator=(basic_random_access_handle<Executor1>&& other)+ > 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. /**@@ -310,7 +308,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -340,18 +338,13 @@ */ template <typename ConstBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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((+ 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( 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)>(@@ -451,7 +444,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -482,18 +475,13 @@ */ template <typename MutableBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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((+ 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( 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)>(@@ -511,13 +499,13 @@ { } - const executor_type& get_executor() const ASIO_NOEXCEPT+ const executor_type& get_executor() const noexcept { return self_->get_executor(); } template <typename WriteHandler, typename ConstBufferSequence>- void operator()(ASIO_MOVE_ARG(WriteHandler) handler,+ void operator()(WriteHandler&& handler, uint64_t offset, const ConstBufferSequence& buffers) const { // If you get an error on the following line it means that your handler@@ -544,13 +532,13 @@ { } - const executor_type& get_executor() const ASIO_NOEXCEPT+ const executor_type& get_executor() const noexcept { return self_->get_executor(); } template <typename ReadHandler, typename MutableBufferSequence>- void operator()(ASIO_MOVE_ARG(ReadHandler) handler,+ void operator()(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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -91,10 +91,10 @@ */ template <typename ExecutionContext> explicit basic_stream_handle(ExecutionContext& context,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value, defaulted_constraint- >::type = defaulted_constraint())+ > = defaulted_constraint()) : basic_overlapped_handle<Executor>(context) { }@@ -133,14 +133,13 @@ template <typename ExecutionContext> basic_stream_handle(ExecutionContext& context, const native_handle_type& handle,- typename constraint<+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value- >::type = 0)+ > = 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.@@ -187,10 +186,10 @@ */ template<typename Executor1> basic_stream_handle(basic_stream_handle<Executor1>&& other,- typename constraint<+ constraint_t< is_convertible<Executor1, Executor>::value, defaulted_constraint- >::type = defaulted_constraint())+ > = defaulted_constraint()) : basic_overlapped_handle<Executor>(std::move(other)) { }@@ -207,15 +206,14 @@ * constructor. */ template<typename Executor1>- typename constraint<+ constraint_t< is_convertible<Executor1, Executor>::value, basic_stream_handle&- >::type operator=(basic_stream_handle<Executor1>&& other)+ > 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. /**@@ -301,7 +299,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -331,17 +329,13 @@ */ template <typename ConstBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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((+ 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( 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)>(@@ -434,7 +428,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -465,17 +459,13 @@ */ template <typename MutableBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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((+ 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( 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)>(@@ -493,13 +483,13 @@ { } - const executor_type& get_executor() const ASIO_NOEXCEPT+ const executor_type& get_executor() const noexcept { return self_->get_executor(); } template <typename WriteHandler, typename ConstBufferSequence>- void operator()(ASIO_MOVE_ARG(WriteHandler) handler,+ void operator()(WriteHandler&& handler, const ConstBufferSequence& buffers) const { // If you get an error on the following line it means that your handler@@ -526,13 +516,13 @@ { } - const executor_type& get_executor() const ASIO_NOEXCEPT+ const executor_type& get_executor() const noexcept { return self_->get_executor(); } template <typename ReadHandler, typename MutableBufferSequence>- void operator()(ASIO_MOVE_ARG(ReadHandler) handler,+ void operator()(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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2025 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/windows/overlapped_ptr.hpp view
@@ -2,7 +2,7 @@ // windows/overlapped_ptr.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -51,23 +51,23 @@ /// Construct an overlapped_ptr to contain the specified handler. template <typename ExecutionContext, typename Handler> explicit overlapped_ptr(ExecutionContext& context,- ASIO_MOVE_ARG(Handler) handler,- typename constraint<+ Handler&& handler,+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value- >::type = 0)- : impl_(context.get_executor(), ASIO_MOVE_CAST(Handler)(handler))+ > = 0)+ : impl_(context.get_executor(), static_cast<Handler&&>(handler)) { } /// Construct an overlapped_ptr to contain the specified handler. template <typename Executor, typename Handler> explicit overlapped_ptr(const Executor& ex,- ASIO_MOVE_ARG(Handler) handler,- typename constraint<+ Handler&& handler,+ constraint_t< execution::is_executor<Executor>::value || is_executor<Executor>::value- >::type = 0)- : impl_(ex, ASIO_MOVE_CAST(Handler)(handler))+ > = 0)+ : impl_(ex, static_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, ASIO_MOVE_ARG(Handler) handler,- typename constraint<+ void reset(ExecutionContext& context, Handler&& handler,+ constraint_t< is_convertible<ExecutionContext&, execution_context&>::value- >::type = 0)+ > = 0) {- impl_.reset(context.get_executor(), ASIO_MOVE_CAST(Handler)(handler));+ impl_.reset(context.get_executor(), static_cast<Handler&&>(handler)); } /// Reset to contain the specified handler, freeing any current OVERLAPPED /// object. template <typename Executor, typename Handler>- void reset(const Executor& ex, ASIO_MOVE_ARG(Handler) handler,- typename constraint<+ void reset(const Executor& ex, Handler&& handler,+ constraint_t< execution::is_executor<Executor>::value || is_executor<Executor>::value- >::type = 0)+ > = 0) {- impl_.reset(ex, ASIO_MOVE_CAST(Handler)(handler));+ impl_.reset(ex, static_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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/windows/stream_handle.hpp view
@@ -2,7 +2,7 @@ // windows/stream_handle.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/writable_pipe.hpp view
@@ -2,7 +2,7 @@ // writable_pipe.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/include/asio/write.hpp view
@@ -2,7 +2,7 @@ // write.hpp // ~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -85,9 +85,9 @@ */ template <typename SyncWriteStream, typename ConstBufferSequence> std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers,- typename constraint<+ constraint_t< is_const_buffer_sequence<ConstBufferSequence>::value- >::type = 0);+ > = 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,- typename constraint<+ constraint_t< is_const_buffer_sequence<ConstBufferSequence>::value- >::type = 0);+ > = 0); /// Write a certain amount of data to a stream before returning. /**@@ -182,9 +182,12 @@ typename CompletionCondition> std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers, CompletionCondition completion_condition,- typename constraint<+ constraint_t< is_const_buffer_sequence<ConstBufferSequence>::value- >::type = 0);+ > = 0,+ constraint_t<+ is_completion_condition<CompletionCondition>::value+ > = 0); /// Write a certain amount of data to a stream before returning. /**@@ -229,9 +232,12 @@ typename CompletionCondition> std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers, CompletionCondition completion_condition, asio::error_code& ec,- typename constraint<+ constraint_t< is_const_buffer_sequence<ConstBufferSequence>::value- >::type = 0);+ > = 0,+ constraint_t<+ is_completion_condition<CompletionCondition>::value+ > = 0); #if !defined(ASIO_NO_DYNAMIC_BUFFER_V1) @@ -264,13 +270,13 @@ */ template <typename SyncWriteStream, typename DynamicBuffer_v1> std::size_t write(SyncWriteStream& s,- 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);+ 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); /// Write all of the supplied data to a stream before returning. /**@@ -301,14 +307,14 @@ */ template <typename SyncWriteStream, typename DynamicBuffer_v1> std::size_t write(SyncWriteStream& s,- ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+ DynamicBuffer_v1&& buffers, 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);+ constraint_t<+ is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value+ > = 0,+ constraint_t<+ !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value+ > = 0); /// Write a certain amount of data to a stream before returning. /**@@ -349,14 +355,17 @@ template <typename SyncWriteStream, typename DynamicBuffer_v1, typename CompletionCondition> std::size_t write(SyncWriteStream& s,- ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+ DynamicBuffer_v1&& buffers, CompletionCondition completion_condition,- 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);+ 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); /// Write a certain amount of data to a stream before returning. /**@@ -398,14 +407,17 @@ template <typename SyncWriteStream, typename DynamicBuffer_v1, typename CompletionCondition> std::size_t write(SyncWriteStream& s,- ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+ DynamicBuffer_v1&& buffers, CompletionCondition completion_condition, 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);+ 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); #if !defined(ASIO_NO_EXTENSIONS) #if !defined(ASIO_NO_IOSTREAM)@@ -507,7 +519,10 @@ template <typename SyncWriteStream, typename Allocator, typename CompletionCondition> std::size_t write(SyncWriteStream& s, basic_streambuf<Allocator>& b,- CompletionCondition completion_condition);+ CompletionCondition completion_condition,+ constraint_t<+ is_completion_condition<CompletionCondition>::value+ > = 0); /// Write a certain amount of data to a stream before returning. /**@@ -548,7 +563,10 @@ template <typename SyncWriteStream, typename Allocator, typename CompletionCondition> std::size_t write(SyncWriteStream& s, basic_streambuf<Allocator>& b,- CompletionCondition completion_condition, asio::error_code& ec);+ CompletionCondition completion_condition, asio::error_code& ec,+ constraint_t<+ is_completion_condition<CompletionCondition>::value+ > = 0); #endif // !defined(ASIO_NO_IOSTREAM) #endif // !defined(ASIO_NO_EXTENSIONS)@@ -583,9 +601,9 @@ */ template <typename SyncWriteStream, typename DynamicBuffer_v2> std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers,- typename constraint<+ constraint_t< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- >::type = 0);+ > = 0); /// Write all of the supplied data to a stream before returning. /**@@ -617,9 +635,9 @@ template <typename SyncWriteStream, typename DynamicBuffer_v2> std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers, asio::error_code& ec,- typename constraint<+ constraint_t< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- >::type = 0);+ > = 0); /// Write a certain amount of data to a stream before returning. /**@@ -661,9 +679,12 @@ typename CompletionCondition> std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers, CompletionCondition completion_condition,- typename constraint<+ constraint_t< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- >::type = 0);+ > = 0,+ constraint_t<+ is_completion_condition<CompletionCondition>::value+ > = 0); /// Write a certain amount of data to a stream before returning. /**@@ -706,9 +727,12 @@ typename CompletionCondition> std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers, CompletionCondition completion_condition, asio::error_code& ec,- typename constraint<+ constraint_t< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- >::type = 0);+ > = 0,+ constraint_t<+ is_completion_condition<CompletionCondition>::value+ > = 0); /*@}*/ /**@@ -762,7 +786,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -790,22 +814,27 @@ template <typename AsyncWriteStream, typename ConstBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, std::size_t)) WriteToken- 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<+ = 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< is_const_buffer_sequence<ConstBufferSequence>::value- >::type = 0)- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ > = 0,+ 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<AsyncWriteStream> >(),- token, buffers, transfer_all())));+ 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());+} /// Start an asynchronous operation to write a certain amount of data to a /// stream.@@ -864,7 +893,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -893,21 +922,31 @@ template <typename AsyncWriteStream, typename ConstBufferSequence, typename CompletionCondition, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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,+ std::size_t)) WriteToken+ = default_completion_token_t<typename AsyncWriteStream::executor_type>>+inline auto async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers, CompletionCondition completion_condition,- ASIO_MOVE_ARG(WriteToken) token,- typename constraint<+ WriteToken&& token+ = default_completion_token_t<typename AsyncWriteStream::executor_type>(),+ constraint_t< is_const_buffer_sequence<ConstBufferSequence>::value- >::type = 0)- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ > = 0,+ constraint_t<+ is_completion_condition<CompletionCondition>::value+ > = 0)+ -> decltype( async_initiate<WriteToken, void (asio::error_code, std::size_t)>(- declval<detail::initiate_async_write<AsyncWriteStream> >(),+ declval<detail::initiate_async_write<AsyncWriteStream>>(), token, buffers,- ASIO_MOVE_CAST(CompletionCondition)(completion_condition))));+ 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));+} #if !defined(ASIO_NO_DYNAMIC_BUFFER_V1) @@ -954,7 +993,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -973,27 +1012,32 @@ template <typename AsyncWriteStream, typename DynamicBuffer_v1, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, std::size_t)) WriteToken- 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((+ = 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( 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())));+ 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());+} /// Start an asynchronous operation to write a certain amount of data to a /// stream.@@ -1052,7 +1096,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -1071,25 +1115,34 @@ template <typename AsyncWriteStream, typename DynamicBuffer_v1, typename CompletionCondition, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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,+ std::size_t)) WriteToken+ = default_completion_token_t<typename AsyncWriteStream::executor_type>>+inline auto async_write(AsyncWriteStream& s, DynamicBuffer_v1&& buffers, CompletionCondition completion_condition,- 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((+ 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( 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))));+ 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));+} #if !defined(ASIO_NO_EXTENSIONS) #if !defined(ASIO_NO_IOSTREAM)@@ -1135,7 +1188,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -1154,17 +1207,24 @@ template <typename AsyncWriteStream, typename Allocator, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, std::size_t)) WriteToken- 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))));+ = 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());+} /// Start an asynchronous operation to write a certain amount of data to a /// stream.@@ -1221,7 +1281,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -1240,16 +1300,28 @@ template <typename AsyncWriteStream, typename Allocator, typename CompletionCondition, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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,+ std::size_t)) WriteToken+ = default_completion_token_t<typename AsyncWriteStream::executor_type>>+inline auto async_write(AsyncWriteStream& s, 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))));+ 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));+} #endif // !defined(ASIO_NO_IOSTREAM) #endif // !defined(ASIO_NO_EXTENSIONS)@@ -1298,7 +1370,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -1317,23 +1389,29 @@ template <typename AsyncWriteStream, typename DynamicBuffer_v2, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, std::size_t)) WriteToken- 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<+ = 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< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- >::type = 0)- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ > = 0,+ 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_v2<AsyncWriteStream> >(),- token, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),- transfer_all())));+ 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());+} /// Start an asynchronous operation to write a certain amount of data to a /// stream.@@ -1392,7 +1470,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -1411,21 +1489,31 @@ template <typename AsyncWriteStream, typename DynamicBuffer_v2, typename CompletionCondition, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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,+ std::size_t)) WriteToken+ = default_completion_token_t<typename AsyncWriteStream::executor_type>>+inline auto async_write(AsyncWriteStream& s, DynamicBuffer_v2 buffers, CompletionCondition completion_condition,- ASIO_MOVE_ARG(WriteToken) token,- typename constraint<+ WriteToken&& token+ = default_completion_token_t<typename AsyncWriteStream::executor_type>(),+ constraint_t< is_dynamic_buffer_v2<DynamicBuffer_v2>::value- >::type = 0)- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ > = 0,+ 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_v2<AsyncWriteStream> >(),- token, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),- ASIO_MOVE_CAST(CompletionCondition)(completion_condition))));+ 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));+} /*@}*/
link/modules/asio-standalone/asio/include/asio/write_at.hpp view
@@ -2,7 +2,7 @@ // write_at.hpp // ~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -187,7 +187,10 @@ typename CompletionCondition> std::size_t write_at(SyncRandomAccessWriteDevice& d, uint64_t offset, const ConstBufferSequence& buffers,- CompletionCondition completion_condition);+ CompletionCondition completion_condition,+ constraint_t<+ is_completion_condition<CompletionCondition>::value+ > = 0); /// Write a certain amount of data at a specified offset before returning. /**@@ -235,7 +238,10 @@ typename CompletionCondition> std::size_t write_at(SyncRandomAccessWriteDevice& d, uint64_t offset, const ConstBufferSequence& buffers,- CompletionCondition completion_condition, asio::error_code& ec);+ CompletionCondition completion_condition, asio::error_code& ec,+ constraint_t<+ is_completion_condition<CompletionCondition>::value+ > = 0); #if !defined(ASIO_NO_EXTENSIONS) #if !defined(ASIO_NO_IOSTREAM)@@ -348,7 +354,10 @@ template <typename SyncRandomAccessWriteDevice, typename Allocator, typename CompletionCondition> std::size_t write_at(SyncRandomAccessWriteDevice& d, uint64_t offset,- basic_streambuf<Allocator>& b, CompletionCondition completion_condition);+ basic_streambuf<Allocator>& b, CompletionCondition completion_condition,+ constraint_t<+ is_completion_condition<CompletionCondition>::value+ > = 0); /// Write a certain amount of data at a specified offset before returning. /**@@ -391,9 +400,12 @@ */ 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);+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); #endif // !defined(ASIO_NO_IOSTREAM) #endif // !defined(ASIO_NO_EXTENSIONS)@@ -456,7 +468,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -483,22 +495,27 @@ */ template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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((+ 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( async_initiate<WriteToken, void (asio::error_code, std::size_t)>( declval<detail::initiate_async_write_at<- AsyncRandomAccessWriteDevice> >(),- token, offset, buffers, transfer_all())));+ 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());+} /// Start an asynchronous operation to write a certain amount of data at the /// specified offset.@@ -562,7 +579,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -591,24 +608,30 @@ template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence, typename CompletionCondition, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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,+ 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, CompletionCondition completion_condition,- ASIO_MOVE_ARG(WriteToken) token- ASIO_DEFAULT_COMPLETION_TOKEN(- typename AsyncRandomAccessWriteDevice::executor_type))- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ WriteToken&& token = default_completion_token_t<+ typename AsyncRandomAccessWriteDevice::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_at<- AsyncRandomAccessWriteDevice> >(),+ AsyncRandomAccessWriteDevice>>(), token, offset, buffers,- ASIO_MOVE_CAST(CompletionCondition)(completion_condition))));+ 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));+} #if !defined(ASIO_NO_EXTENSIONS) #if !defined(ASIO_NO_IOSTREAM)@@ -659,7 +682,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -677,22 +700,28 @@ */ template <typename AsyncRandomAccessWriteDevice, typename Allocator, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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,+ std::size_t)) WriteToken = default_completion_token_t<+ typename AsyncRandomAccessWriteDevice::executor_type>>+inline auto async_write_at(AsyncRandomAccessWriteDevice& d, uint64_t offset, basic_streambuf<Allocator>& b,- ASIO_MOVE_ARG(WriteToken) token- ASIO_DEFAULT_COMPLETION_TOKEN(- typename AsyncRandomAccessWriteDevice::executor_type))- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ WriteToken&& token = default_completion_token_t<+ typename AsyncRandomAccessWriteDevice::executor_type>(),+ constraint_t<+ !is_completion_condition<WriteToken>::value+ > = 0)+ -> decltype( async_initiate<WriteToken, void (asio::error_code, std::size_t)>( declval<detail::initiate_async_write_at_streambuf<- AsyncRandomAccessWriteDevice> >(),- token, offset, &b, transfer_all())));+ 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());+} /// Start an asynchronous operation to write a certain amount of data at the /// specified offset.@@ -754,7 +783,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::post().+ * manner equivalent to using asio::async_immediate(). * * @par Completion Signature * @code void(asio::error_code, std::size_t) @endcode@@ -773,23 +802,30 @@ template <typename AsyncRandomAccessWriteDevice, typename Allocator, typename CompletionCondition, ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,- 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,+ std::size_t)) WriteToken = default_completion_token_t<+ typename AsyncRandomAccessWriteDevice::executor_type>>+inline auto async_write_at(AsyncRandomAccessWriteDevice& d, uint64_t offset, basic_streambuf<Allocator>& b, CompletionCondition completion_condition,- ASIO_MOVE_ARG(WriteToken) token- ASIO_DEFAULT_COMPLETION_TOKEN(- typename AsyncRandomAccessWriteDevice::executor_type))- ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+ WriteToken&& token = default_completion_token_t<+ typename AsyncRandomAccessWriteDevice::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_at_streambuf<- AsyncRandomAccessWriteDevice> >(),+ AsyncRandomAccessWriteDevice>>(), token, offset, &b,- ASIO_MOVE_CAST(CompletionCondition)(completion_condition))));+ 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));+} #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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
− link/modules/asio-standalone/asio/src/examples/cpp03/chat/chat_message.hpp
@@ -1,96 +0,0 @@-//-// 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
@@ -1,83 +0,0 @@-//-// 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
@@ -1,44 +0,0 @@-//-// 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
@@ -1,28 +0,0 @@-//-// 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
@@ -1,27 +0,0 @@-//-// 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
@@ -1,64 +0,0 @@-//-// 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
@@ -1,34 +0,0 @@-//-// 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
@@ -1,46 +0,0 @@-//-// 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
@@ -1,95 +0,0 @@-//-// 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
@@ -1,69 +0,0 @@-//-// 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
@@ -1,75 +0,0 @@-//-// 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
@@ -1,28 +0,0 @@-//-// 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
@@ -1,58 +0,0 @@-//-// 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
@@ -1,27 +0,0 @@-//-// 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
@@ -1,64 +0,0 @@-//-// 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
@@ -1,34 +0,0 @@-//-// 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
@@ -1,46 +0,0 @@-//-// 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
@@ -1,95 +0,0 @@-//-// 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
@@ -1,68 +0,0 @@-//-// 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
@@ -1,78 +0,0 @@-//-// 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
@@ -1,28 +0,0 @@-//-// 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
@@ -1,27 +0,0 @@-//-// 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
@@ -1,64 +0,0 @@-//-// 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
@@ -1,34 +0,0 @@-//-// 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
@@ -1,46 +0,0 @@-//-// 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
@@ -1,95 +0,0 @@-//-// 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
@@ -1,70 +0,0 @@-//-// 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
@@ -1,44 +0,0 @@-//-// 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
@@ -1,28 +0,0 @@-//-// 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
@@ -1,27 +0,0 @@-//-// 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
@@ -1,64 +0,0 @@-//-// 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
@@ -1,46 +0,0 @@-//-// 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
@@ -1,78 +0,0 @@-//-// 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
@@ -1,73 +0,0 @@-//-// 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
@@ -1,94 +0,0 @@-//-// 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
@@ -1,102 +0,0 @@-//-// 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
@@ -1,156 +0,0 @@-//-// 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
@@ -1,188 +0,0 @@-//-// 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
@@ -1,50 +0,0 @@-//-// 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
@@ -1,77 +0,0 @@-//-// 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
@@ -1,24 +0,0 @@-//-// 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
@@ -1,145 +0,0 @@-//-// 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
@@ -1,144 +0,0 @@-//-// 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -79,7 +79,8 @@ void encode_header() { char header[header_length + 1] = "";- std::sprintf(header, "%4d", static_cast<int>(body_length_));+ std::snprintf(header, header_length + 1,+ "%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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -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 asio::error_code& ec)+ const char* op_name, const std::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 asio::error_code& ec,+ const char* op_name, const std::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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/src/examples/cpp11/http/server/header.hpp view
@@ -2,7 +2,7 @@ // header.hpp // ~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/src/examples/cpp11/http/server/mime_types.hpp view
@@ -2,7 +2,7 @@ // mime_types.hpp // ~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/src/examples/cpp11/http/server/reply.hpp view
@@ -2,7 +2,7 @@ // reply.hpp // ~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/src/examples/cpp11/http/server/request.hpp view
@@ -2,7 +2,7 @@ // request.hpp // ~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/src/examples/cpp11/http/server/request_handler.hpp view
@@ -2,7 +2,7 @@ // request_handler.hpp // ~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/src/examples/cpp11/http/server/request_parser.hpp view
@@ -2,7 +2,7 @@ // request_parser.hpp // ~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/src/examples/cpp11/http/server/server.hpp view
@@ -2,7 +2,7 @@ // server.hpp // ~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
+ link/modules/asio-standalone/asio/src/examples/cpp11/http/server2/connection.hpp view
@@ -0,0 +1,71 @@+//+// 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 view
@@ -0,0 +1,28 @@+//+// 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 view
@@ -0,0 +1,59 @@+//+// 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 view
@@ -0,0 +1,27 @@+//+// 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 view
@@ -0,0 +1,64 @@+//+// 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 view
@@ -0,0 +1,34 @@+//+// 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 view
@@ -0,0 +1,47 @@+//+// 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 view
@@ -0,0 +1,96 @@+//+// 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 view
@@ -0,0 +1,60 @@+//+// 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 view
@@ -0,0 +1,71 @@+//+// 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 view
@@ -0,0 +1,28 @@+//+// 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 view
@@ -0,0 +1,27 @@+//+// 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 view
@@ -0,0 +1,64 @@+//+// 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 view
@@ -0,0 +1,34 @@+//+// 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 view
@@ -0,0 +1,47 @@+//+// 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 view
@@ -0,0 +1,96 @@+//+// 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 view
@@ -0,0 +1,62 @@+//+// 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 view
@@ -0,0 +1,44 @@+//+// 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 view
@@ -0,0 +1,28 @@+//+// 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 view
@@ -0,0 +1,27 @@+//+// 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 view
@@ -0,0 +1,64 @@+//+// 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 view
@@ -0,0 +1,34 @@+//+// 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 view
@@ -0,0 +1,47 @@+//+// 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 view
@@ -0,0 +1,96 @@+//+// 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 view
@@ -0,0 +1,73 @@+//+// 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 view
@@ -0,0 +1,94 @@+//+// 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 view
@@ -0,0 +1,102 @@+//+// 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 view
@@ -0,0 +1,156 @@+//+// 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 view
@@ -0,0 +1,184 @@+//+// 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 view
@@ -0,0 +1,50 @@+//+// 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 view
@@ -0,0 +1,78 @@+//+// 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 view
@@ -0,0 +1,24 @@+//+// 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 view
@@ -0,0 +1,145 @@+//+// 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -39,7 +39,7 @@ // Only IPv4 is supported by the SOCKS 4 protocol. if (endpoint.protocol() != asio::ip::tcp::v4()) {- throw asio::system_error(+ throw std::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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -20,7 +20,7 @@ { private: virtual void async_read_line_impl(std::string prompt,- asio::any_completion_handler<void(asio::error_code, std::string)> handler) = 0;+ asio::any_completion_handler<void(std::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(asio::error_code, std::string)>(+ asio::async_initiate<CompletionToken, void(std::error_code, std::string)>( initiate_read_line(), token, this, prompt)) {- return asio::async_initiate<CompletionToken, void(asio::error_code, std::string)>(+ return asio::async_initiate<CompletionToken, void(std::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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -21,7 +21,7 @@ private: void async_read_line_impl(std::string prompt,- asio::any_completion_handler<void(asio::error_code, std::string)> handler) override;+ asio::any_completion_handler<void(std::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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/src/examples/cpp20/type_erasure/sleep.hpp view
@@ -2,7 +2,7 @@ // sleep.hpp // ~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/src/tests/latency/allocator.hpp view
@@ -2,7 +2,7 @@ // allocator.hpp // ~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/src/tests/latency/high_res_clock.hpp view
@@ -2,7 +2,7 @@ // high_res_clock.hpp // ~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/src/tests/performance/handler_allocator.hpp view
@@ -2,7 +2,7 @@ // handler_allocator.cpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -12,15 +12,12 @@ #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()@@ -28,12 +25,15 @@ { } + handler_allocator(const handler_allocator&) = delete;+ handler_allocator& operator=(const handler_allocator&) = delete;+ void* allocate(std::size_t size) {- if (!in_use_ && size < storage_.size)+ if (!in_use_ && size < sizeof(storage_)) { in_use_ = true;- return storage_.address();+ return storage_; } return ::operator new(size);@@ -41,7 +41,7 @@ void deallocate(void* pointer) {- if (pointer == storage_.address())+ if (pointer == storage_) { in_use_ = false; }@@ -53,7 +53,7 @@ private: // Storage space used for handler-based custom memory allocation.- boost::aligned_storage<1024> storage_;+ alignas(std::max_align_t) unsigned char storage_[1024]; // 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 @@ //-// async_ops.hpp-// ~~~~~~~~~~~~~+// archetypes/async_ops.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -11,403 +11,448 @@ #ifndef ARCHETYPES_ASYNC_OPS_HPP #define ARCHETYPES_ASYNC_OPS_HPP -#include <asio/associated_allocator.hpp>-#include <asio/associated_executor.hpp>-#include <asio/async_result.hpp>-#include <asio/error.hpp>--#if defined(ASIO_HAS_BOOST_BIND)-# include <boost/bind/bind.hpp>-#else // defined(ASIO_HAS_BOOST_BIND)-# include <functional>-#endif // defined(ASIO_HAS_BOOST_BIND)+#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" namespace archetypes { -#if defined(ASIO_HAS_BOOST_BIND)-namespace bindns = boost;-#else // defined(ASIO_HAS_BOOST_BIND) namespace bindns = std;-#endif // defined(ASIO_HAS_BOOST_BIND) -template <typename CompletionToken>-ASIO_INITFN_RESULT_TYPE(CompletionToken, void())-async_op_0(ASIO_MOVE_ARG(CompletionToken) token)+struct initiate_op_0 {- typedef typename asio::async_completion<CompletionToken,- void()>::completion_handler_type handler_type;-- asio::async_completion<CompletionToken,- void()> completion(token);-- typename asio::associated_allocator<handler_type>::type a- = asio::get_associated_allocator(completion.completion_handler);-- typename asio::associated_executor<handler_type>::type ex- = asio::get_associated_executor(completion.completion_handler);+ template <typename Handler>+ void operator()(Handler&& handler)+ {+ typename asio::associated_allocator<Handler>::type a+ = asio::get_associated_allocator(handler); - ex.post(ASIO_MOVE_CAST(handler_type)(completion.completion_handler), a);+ typename asio::associated_executor<Handler>::type ex+ = asio::get_associated_executor(handler); - return completion.result.get();-}+ asio::post(ex,+ asio::bind_allocator(a, static_cast<Handler&&>(handler)));+ }+}; template <typename CompletionToken>-ASIO_INITFN_RESULT_TYPE(CompletionToken, void(asio::error_code))-async_op_ec_0(bool ok, ASIO_MOVE_ARG(CompletionToken) token)+auto async_op_0(CompletionToken&& token)+ -> decltype(+ asio::async_initiate<CompletionToken, void()>(+ initiate_op_0(), token)) {- typedef typename asio::async_completion<CompletionToken,- void(asio::error_code)>::completion_handler_type handler_type;-- asio::async_completion<CompletionToken,- void(asio::error_code)> completion(token);+ return asio::async_initiate<CompletionToken, void()>(+ initiate_op_0(), token);+} - typename asio::associated_allocator<handler_type>::type a- = asio::get_associated_allocator(completion.completion_handler);+struct initiate_op_ec_0+{+ template <typename Handler>+ void operator()(Handler&& handler, bool ok)+ {+ typename asio::associated_allocator<Handler>::type a+ = asio::get_associated_allocator(handler); - typename asio::associated_executor<handler_type>::type ex- = asio::get_associated_executor(completion.completion_handler);+ typename asio::associated_executor<Handler>::type ex+ = asio::get_associated_executor(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);+ 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))));+ } }-- return completion.result.get();-}+}; template <typename CompletionToken>-ASIO_INITFN_RESULT_TYPE(CompletionToken, void(std::exception_ptr))-async_op_ex_0(bool ok, ASIO_MOVE_ARG(CompletionToken) token)+auto async_op_ec_0(bool ok, CompletionToken&& token)+ -> decltype(+ asio::async_initiate<CompletionToken,+ void(asio::error_code)>(+ initiate_op_ec_0(), token, ok)) {- typedef typename asio::async_completion<CompletionToken,- void(std::exception_ptr)>::completion_handler_type handler_type;-- asio::async_completion<CompletionToken,- void(std::exception_ptr)> completion(token);+ return asio::async_initiate<CompletionToken,+ void(asio::error_code)>(+ initiate_op_ec_0(), token, ok);+} - typename asio::associated_allocator<handler_type>::type a- = asio::get_associated_allocator(completion.completion_handler);+struct initiate_op_ex_0+{+ template <typename Handler>+ void operator()(Handler&& handler, bool ok)+ {+ typename asio::associated_allocator<Handler>::type a+ = asio::get_associated_allocator(handler); - typename asio::associated_executor<handler_type>::type ex- = asio::get_associated_executor(completion.completion_handler);+ typename asio::associated_executor<Handler>::type ex+ = asio::get_associated_executor(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);+ 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")))));+ } }-- return completion.result.get();-}+}; template <typename CompletionToken>-ASIO_INITFN_RESULT_TYPE(CompletionToken, void(int))-async_op_1(ASIO_MOVE_ARG(CompletionToken) token)+auto async_op_ex_0(bool ok, CompletionToken&& token)+ -> decltype(+ asio::async_initiate<CompletionToken,+ void(std::exception_ptr)>(+ initiate_op_ex_0(), token, ok)) {- typedef typename asio::async_completion<CompletionToken,- void(int)>::completion_handler_type handler_type;-- asio::async_completion<CompletionToken,- void(int)> completion(token);-- typename asio::associated_allocator<handler_type>::type a- = asio::get_associated_allocator(completion.completion_handler);+ return asio::async_initiate<CompletionToken,+ void(std::exception_ptr)>(+ initiate_op_ex_0(), token, ok);+} - typename asio::associated_executor<handler_type>::type ex- = asio::get_associated_executor(completion.completion_handler);+struct initiate_op_1+{+ template <typename Handler>+ void operator()(Handler&& handler)+ {+ typename asio::associated_allocator<Handler>::type a+ = asio::get_associated_allocator(handler); - ex.post(- bindns::bind(- ASIO_MOVE_CAST(handler_type)(completion.completion_handler),- 42), a);+ typename asio::associated_executor<Handler>::type ex+ = asio::get_associated_executor(handler); - return completion.result.get();-}+ asio::post(ex,+ asio::bind_allocator(a,+ bindns::bind(static_cast<Handler&&>(handler), 42)));+ }+}; template <typename CompletionToken>-ASIO_INITFN_RESULT_TYPE(CompletionToken,- void(asio::error_code, int))-async_op_ec_1(bool ok, ASIO_MOVE_ARG(CompletionToken) token)+auto async_op_1(CompletionToken&& token)+ -> decltype(+ asio::async_initiate<CompletionToken, void(int)>(+ initiate_op_1(), token)) {- typedef typename asio::async_completion<CompletionToken,- void(asio::error_code, int)>::completion_handler_type- handler_type;-- asio::async_completion<CompletionToken,- void(asio::error_code, int)> completion(token);+ return asio::async_initiate<CompletionToken, void(int)>(+ initiate_op_1(), token);+} - typename asio::associated_allocator<handler_type>::type a- = asio::get_associated_allocator(completion.completion_handler);+struct initiate_op_ec_1+{+ template <typename Handler>+ void operator()(Handler&& handler, bool ok)+ {+ typename asio::associated_allocator<Handler>::type a+ = asio::get_associated_allocator(handler); - typename asio::associated_executor<handler_type>::type ex- = asio::get_associated_executor(completion.completion_handler);+ typename asio::associated_executor<Handler>::type ex+ = asio::get_associated_executor(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);+ 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)));+ } }-- return completion.result.get();-}+}; template <typename CompletionToken>-ASIO_INITFN_RESULT_TYPE(CompletionToken, void(std::exception_ptr, int))-async_op_ex_1(bool ok, ASIO_MOVE_ARG(CompletionToken) token)+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)) {- typedef typename asio::async_completion<CompletionToken,- void(std::exception_ptr, int)>::completion_handler_type- handler_type;-- asio::async_completion<CompletionToken,- void(std::exception_ptr, int)> completion(token);+ return asio::async_initiate<CompletionToken,+ void(asio::error_code, int)>(+ initiate_op_ec_1(), token, ok);+} - typename asio::associated_allocator<handler_type>::type a- = asio::get_associated_allocator(completion.completion_handler);+struct initiate_op_ex_1+{+ template <typename Handler>+ void operator()(Handler&& handler, bool ok)+ {+ typename asio::associated_allocator<Handler>::type a+ = asio::get_associated_allocator(handler); - typename asio::associated_executor<handler_type>::type ex- = asio::get_associated_executor(completion.completion_handler);+ typename asio::associated_executor<Handler>::type ex+ = asio::get_associated_executor(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);+ 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)));+ } }-- return completion.result.get();-}+}; template <typename CompletionToken>-ASIO_INITFN_RESULT_TYPE(CompletionToken, void(int, double))-async_op_2(ASIO_MOVE_ARG(CompletionToken) token)+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)) {- typedef typename asio::async_completion<CompletionToken,- void(int, double)>::completion_handler_type handler_type;-- asio::async_completion<CompletionToken,- void(int, double)> completion(token);-- typename asio::associated_allocator<handler_type>::type a- = asio::get_associated_allocator(completion.completion_handler);+ return asio::async_initiate<CompletionToken,+ void(std::exception_ptr, int)>(+ initiate_op_ex_1(), token, ok);+} - typename asio::associated_executor<handler_type>::type ex- = asio::get_associated_executor(completion.completion_handler);+struct initiate_op_2+{+ template <typename Handler>+ void operator()(Handler&& handler)+ {+ typename asio::associated_allocator<Handler>::type a+ = asio::get_associated_allocator(handler); - ex.post(- bindns::bind(- ASIO_MOVE_CAST(handler_type)(completion.completion_handler),- 42, 2.0), a);+ typename asio::associated_executor<Handler>::type ex+ = asio::get_associated_executor(handler); - return completion.result.get();-}+ asio::post(ex,+ asio::bind_allocator(a,+ bindns::bind(static_cast<Handler&&>(handler), 42, 2.0)));+ }+}; 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)+auto async_op_2(CompletionToken&& token)+ -> decltype(+ asio::async_initiate<CompletionToken, void(int, double)>(+ initiate_op_2(), token)) {- typedef typename asio::async_completion<CompletionToken,- void(asio::error_code, int, double)>::completion_handler_type- handler_type;-- asio::async_completion<CompletionToken,- void(asio::error_code, int, double)> completion(token);+ return asio::async_initiate<CompletionToken, void(int, double)>(+ initiate_op_2(), token);+} - typename asio::associated_allocator<handler_type>::type a- = asio::get_associated_allocator(completion.completion_handler);+struct initiate_op_ec_2+{+ template <typename Handler>+ void operator()(Handler&& handler, bool ok)+ {+ typename asio::associated_allocator<Handler>::type a+ = asio::get_associated_allocator(handler); - typename asio::associated_executor<handler_type>::type ex- = asio::get_associated_executor(completion.completion_handler);+ typename asio::associated_executor<Handler>::type ex+ = asio::get_associated_executor(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);+ 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)));+ } }-- return completion.result.get();-}+}; template <typename CompletionToken>-ASIO_INITFN_RESULT_TYPE(CompletionToken,- void(std::exception_ptr, int, double))-async_op_ex_2(bool ok, ASIO_MOVE_ARG(CompletionToken) token)+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)) {- typedef typename asio::async_completion<CompletionToken,- void(std::exception_ptr, int, double)>::completion_handler_type- handler_type;-- asio::async_completion<CompletionToken,- void(std::exception_ptr, int, double)> completion(token);+ return asio::async_initiate<CompletionToken,+ void(asio::error_code, int, double)>(+ initiate_op_ec_2(), token, ok);+} - typename asio::associated_allocator<handler_type>::type a- = asio::get_associated_allocator(completion.completion_handler);+struct initiate_op_ex_2+{+ template <typename Handler>+ void operator()(Handler&& handler, bool ok)+ {+ typename asio::associated_allocator<Handler>::type a+ = asio::get_associated_allocator(handler); - typename asio::associated_executor<handler_type>::type ex- = asio::get_associated_executor(completion.completion_handler);+ typename asio::associated_executor<Handler>::type ex+ = asio::get_associated_executor(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);+ 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)));+ } }-- return completion.result.get();-}+}; template <typename CompletionToken>-ASIO_INITFN_RESULT_TYPE(CompletionToken, void(int, double, char))-async_op_3(ASIO_MOVE_ARG(CompletionToken) token)+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)) {- typedef typename asio::async_completion<CompletionToken,- void(int, double, char)>::completion_handler_type handler_type;-- asio::async_completion<CompletionToken,- void(int, double, char)> completion(token);-- typename asio::associated_allocator<handler_type>::type a- = asio::get_associated_allocator(completion.completion_handler);+ return asio::async_initiate<CompletionToken,+ void(std::exception_ptr, int, double)>(+ initiate_op_ex_2(), token, ok);+} - typename asio::associated_executor<handler_type>::type ex- = asio::get_associated_executor(completion.completion_handler);+struct initiate_op_3+{+ template <typename Handler>+ void operator()(Handler&& handler)+ {+ typename asio::associated_allocator<Handler>::type a+ = asio::get_associated_allocator(handler); - ex.post(- bindns::bind(- ASIO_MOVE_CAST(handler_type)(completion.completion_handler),- 42, 2.0, 'a'), a);+ typename asio::associated_executor<Handler>::type ex+ = asio::get_associated_executor(handler); - return completion.result.get();-}+ asio::post(ex,+ asio::bind_allocator(a,+ bindns::bind(static_cast<Handler&&>(handler), 42, 2.0, 'a')));+ }+}; 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)+auto async_op_3(CompletionToken&& token)+ -> decltype(+ asio::async_initiate<CompletionToken, void(int, double, char)>(+ initiate_op_3(), token)) {- typedef typename asio::async_completion<CompletionToken,- void(asio::error_code, int, double, char)>::completion_handler_type- handler_type;-- asio::async_completion<CompletionToken,- void(asio::error_code, int, double, char)> completion(token);+ return asio::async_initiate<CompletionToken, void(int, double, char)>(+ initiate_op_3(), token);+} - typename asio::associated_allocator<handler_type>::type a- = asio::get_associated_allocator(completion.completion_handler);+struct initiate_op_ec_3+{+ template <typename Handler>+ void operator()(Handler&& handler, bool ok)+ {+ typename asio::associated_allocator<Handler>::type a+ = asio::get_associated_allocator(handler); - typename asio::associated_executor<handler_type>::type ex- = asio::get_associated_executor(completion.completion_handler);+ typename asio::associated_executor<Handler>::type ex+ = asio::get_associated_executor(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);+ 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')));+ } }-- return completion.result.get();-}+}; template <typename CompletionToken>-ASIO_INITFN_RESULT_TYPE(CompletionToken,- void(std::exception_ptr, int, double, char))-async_op_ex_3(bool ok, ASIO_MOVE_ARG(CompletionToken) token)+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)) {- typedef typename asio::async_completion<CompletionToken,- void(std::exception_ptr, int, double, char)>::completion_handler_type- handler_type;-- asio::async_completion<CompletionToken,- void(std::exception_ptr, int, double, char)> completion(token);+ return asio::async_initiate<CompletionToken,+ void(asio::error_code, int, double, char)>(+ initiate_op_ec_3(), token, ok);+} - typename asio::associated_allocator<handler_type>::type a- = asio::get_associated_allocator(completion.completion_handler);+struct initiate_op_ex_3+{+ template <typename Handler>+ void operator()(Handler&& handler, bool ok)+ {+ typename asio::associated_allocator<Handler>::type a+ = asio::get_associated_allocator(handler); - typename asio::associated_executor<handler_type>::type ex- = asio::get_associated_executor(completion.completion_handler);+ typename asio::associated_executor<Handler>::type ex+ = asio::get_associated_executor(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);+ 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')));+ } }+}; - return completion.result.get();+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); } } // 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -38,11 +38,9 @@ { } -#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>@@ -67,16 +65,14 @@ { } - immediate_executor_type get_immediate_executor() const ASIO_NOEXCEPT+ immediate_executor_type get_immediate_executor() const 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>@@ -86,11 +82,9 @@ { } -#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@@ -120,8 +114,8 @@ private: // Disallow copying and assignment.- async_result(const async_result&) ASIO_DELETED;- async_result& operator=(const async_result&) ASIO_DELETED;+ async_result(const async_result&) = delete;+ async_result& operator=(const async_result&) = delete; }; template <typename Signature>@@ -147,8 +141,8 @@ private: // Disallow copying and assignment.- async_result(const async_result&) ASIO_DELETED;- async_result& operator=(const async_result&) ASIO_DELETED;+ async_result(const async_result&) = delete;+ async_result& operator=(const async_result&) = delete; }; } // 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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
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-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)
link/modules/asio-standalone/asio/src/tests/unit/unit_test.hpp view
@@ -2,7 +2,7 @@ // unit_test.hpp // ~~~~~~~~~~~~~ //-// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// 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)@@ -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 abl_link}- sizeOf _ = #{size abl_link}+ alignment _ = #{alignment struct abl_link}+ sizeOf _ = #{size struct abl_link} peek ptr = do- impl <- #{peek abl_link,impl} ptr- return (AbletonLink impl)- poke ptr (AbletonLink impl) = do- #{poke abl_link,impl} ptr impl+ impl <- #{peek struct abl_link, impl} ptr+ pure (AbletonLink impl)+ poke ptr (AbletonLink impl) =+ #{poke struct abl_link, impl} ptr impl instance Storable SessionState where- alignment _ = #{alignment abl_link_session_state}- sizeOf _ = #{size abl_link_session_state}+ alignment _ = #{alignment struct abl_link_session_state}+ sizeOf _ = #{size struct abl_link_session_state} peek ptr = do- impl <- #{peek abl_link_session_state,impl} ptr- return (SessionState impl)- poke ptr (SessionState impl) = do- #{poke abl_link_session_state,impl} ptr impl+ 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 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.0+version: 1.2.1 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++14 -Wno-multichar -Wno-subobject-linkage+ -DLINK_PLATFORM_MACOSX=1 -std=c++17 -Wno-multichar -Wno-subobject-linkage else cxx-options:- -DLINK_PLATFORM_LINUX=1 -std=c++14 -Wno-multichar -Wno-subobject-linkage+ -DLINK_PLATFORM_LINUX=1 -std=c++17 -Wno-multichar -Wno-subobject-linkage if impl(ghc >= 9.4) build-depends: system-cxx-std-lib@@ -67,7 +67,7 @@ source-repository head type: git- location: https://github.com/tidalcycles/Tidal+ location: https://codeberg.org/uzu/tidal executable tidal-linktest ghc-options: -Wall