1
0
mirror of https://git.suyu.dev/suyu/suyu synced 2025-09-22 14:02:07 -05:00

Initial commit

This commit is contained in:
Crimson-Hawk
2024-03-05 16:42:40 +08:00
commit f1e4595ebf
39576 changed files with 7006612 additions and 0 deletions

View File

@@ -0,0 +1,289 @@
#
# Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
#
# Distributed under the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#
import feature ;
lib socket ; # SOLARIS, QNXNTO
lib nsl ; # SOLARIS
lib ws2_32 ; # NT
lib mswsock ; # NT
lib ipv6 ; # HPUX
lib network ; # HAIKU
local USE_SELECT =
<define>BOOST_ASIO_DISABLE_DEV_POLL
<define>BOOST_ASIO_DISABLE_EPOLL
<define>BOOST_ASIO_DISABLE_KQUEUE
<define>BOOST_ASIO_DISABLE_IOCP
;
project
: requirements
<library>/boost/date_time//boost_date_time
<library>/boost/system//boost_system
<library>/boost/chrono//boost_chrono
<library>/boost/regex//boost_regex
<define>BOOST_ALL_NO_LIB=1
<threading>multi
<target-os>linux:<define>_XOPEN_SOURCE=600
<target-os>linux:<define>_GNU_SOURCE=1
<target-os>solaris:<define>_XOPEN_SOURCE=500
<target-os>solaris:<define>__EXTENSIONS__
<target-os>solaris:<library>socket
<target-os>solaris:<library>nsl
<target-os>windows:<define>_WIN32_WINNT=0x0501
<target-os>windows,<toolset>cw:<library>ws2_32
<target-os>windows,<toolset>cw:<library>mswsock
<target-os>windows,<toolset>gcc:<library>ws2_32
<target-os>windows,<toolset>gcc:<library>mswsock
<target-os>windows,<toolset>gcc-cygwin:<define>__USE_W32_SOCKETS
<target-os>hpux,<toolset>gcc:<define>_XOPEN_SOURCE_EXTENDED
<target-os>hpux:<library>ipv6
<target-os>qnxnto:<library>socket
<target-os>haiku:<library>network
;
test-suite "asio" :
[ link associated_allocator.cpp ]
[ link associated_allocator.cpp : $(USE_SELECT) : associated_allocator_select ]
[ link associated_cancellation_slot.cpp ]
[ link associated_cancellation_slot.cpp : $(USE_SELECT) : associated_cancellation_slot_select ]
[ link associated_executor.cpp ]
[ link associated_executor.cpp : $(USE_SELECT) : associated_executor_select ]
[ link associator.cpp ]
[ link associator.cpp : $(USE_SELECT) : associator_select ]
[ link awaitable.cpp ]
[ link awaitable.cpp : $(USE_SELECT) : awaitable_select ]
[ link basic_datagram_socket.cpp ]
[ link basic_datagram_socket.cpp : $(USE_SELECT) : basic_datagram_socket_select ]
[ link basic_deadline_timer.cpp ]
[ link basic_deadline_timer.cpp : $(USE_SELECT) : basic_deadline_timer_select ]
[ link basic_file.cpp ]
[ link basic_file.cpp : $(USE_SELECT) : basic_file_select ]
[ link basic_random_access_file.cpp ]
[ link basic_random_access_file.cpp : $(USE_SELECT) : basic_random_access_file_select ]
[ link basic_raw_socket.cpp ]
[ link basic_raw_socket.cpp : $(USE_SELECT) : basic_raw_socket_select ]
[ link basic_readable_pipe.cpp ]
[ link basic_readable_pipe.cpp : $(USE_SELECT) : basic_readable_pipe_select ]
[ link basic_seq_packet_socket.cpp ]
[ link basic_seq_packet_socket.cpp : $(USE_SELECT) : basic_seq_packet_socket_select ]
[ link basic_signal_set.cpp ]
[ link basic_signal_set.cpp : $(USE_SELECT) : basic_signal_set_select ]
[ link basic_socket_acceptor.cpp ]
[ link basic_socket_acceptor.cpp : $(USE_SELECT) : basic_socket_acceptor_select ]
[ link basic_stream_file.cpp ]
[ link basic_stream_file.cpp : $(USE_SELECT) : basic_stream_file_select ]
[ link basic_stream_socket.cpp ]
[ link basic_stream_socket.cpp : $(USE_SELECT) : basic_stream_socket_select ]
[ link basic_streambuf.cpp ]
[ link basic_streambuf.cpp : $(USE_SELECT) : basic_streambuf_select ]
[ link basic_waitable_timer.cpp ]
[ link basic_waitable_timer.cpp : $(USE_SELECT) : basic_waitable_timer_select ]
[ link basic_writable_pipe.cpp ]
[ link basic_writable_pipe.cpp : $(USE_SELECT) : basic_writable_pipe_select ]
[ run bind_allocator.cpp ]
[ run bind_allocator.cpp : : : $(USE_SELECT) : bind_allocator_select ]
[ run bind_cancellation_slot.cpp ]
[ run bind_cancellation_slot.cpp : : : $(USE_SELECT) : bind_cancellation_slot_select ]
[ run bind_executor.cpp ]
[ run bind_executor.cpp : : : $(USE_SELECT) : bind_executor_select ]
[ run buffer.cpp ]
[ run buffer.cpp : : : $(USE_SELECT) : buffer_select ]
[ link buffer_registration.cpp ]
[ link buffer_registration.cpp : $(USE_SELECT) : buffer_registration_select ]
[ run buffered_read_stream.cpp ]
[ run buffered_read_stream.cpp : : : $(USE_SELECT) : buffered_read_stream_select ]
[ run buffered_stream.cpp ]
[ run buffered_stream.cpp : : : $(USE_SELECT) : buffered_stream_select ]
[ run buffered_write_stream.cpp ]
[ run buffered_write_stream.cpp : : : $(USE_SELECT) : buffered_write_stream_select ]
[ run buffers_iterator.cpp ]
[ run buffers_iterator.cpp : : : $(USE_SELECT) : buffers_iterator_select ]
[ link cancellation_signal.cpp ]
[ link cancellation_signal.cpp : $(USE_SELECT) : cancellation_signal_select ]
[ link cancellation_state.cpp ]
[ link cancellation_state.cpp : $(USE_SELECT) : cancellation_state_select ]
[ link cancellation_type.cpp ]
[ link cancellation_type.cpp : $(USE_SELECT) : cancellation_type_select ]
[ link co_spawn.cpp ]
[ link co_spawn.cpp : $(USE_SELECT) : co_spawn_select ]
[ link completion_condition.cpp ]
[ link completion_condition.cpp : $(USE_SELECT) : completion_condition_select ]
[ run compose.cpp ]
[ run compose.cpp : : : $(USE_SELECT) : compose_select ]
[ link connect.cpp ]
[ link connect.cpp : $(USE_SELECT) : connect_select ]
[ run connect_pipe.cpp ]
[ run connect_pipe.cpp : : : $(USE_SELECT) : connect_pipe_select ]
[ link coroutine.cpp ]
[ link coroutine.cpp : $(USE_SELECT) : coroutine_select ]
[ run deadline_timer.cpp ]
[ run deadline_timer.cpp : : : $(USE_SELECT) : deadline_timer_select ]
[ link detached.cpp ]
[ link detached.cpp : $(USE_SELECT) : detached_select ]
[ run error.cpp ]
[ run error.cpp : : : $(USE_SELECT) : error_select ]
[ link file_base.cpp ]
[ link file_base.cpp : $(USE_SELECT) : file_base_select ]
[ link generic/basic_endpoint.cpp : : generic_basic_endpoint ]
[ link generic/basic_endpoint.cpp : $(USE_SELECT) : generic_basic_endpoint_select ]
[ link generic/datagram_protocol.cpp : : generic_datagram_protocol ]
[ link generic/datagram_protocol.cpp : $(USE_SELECT) : generic_datagram_protocol_select ]
[ link generic/raw_protocol.cpp : : generic_raw_protocol ]
[ link generic/raw_protocol.cpp : $(USE_SELECT) : generic_raw_protocol_select ]
[ link generic/seq_packet_protocol.cpp : : generic_seq_packet_protocol ]
[ link generic/seq_packet_protocol.cpp : $(USE_SELECT) : generic_seq_packet_protocol_select ]
[ link generic/stream_protocol.cpp : : generic_stream_protocol ]
[ link generic/stream_protocol.cpp : $(USE_SELECT) : generic_stream_protocol_select ]
[ link high_resolution_timer.cpp ]
[ link high_resolution_timer.cpp : $(USE_SELECT) : high_resolution_timer_select ]
[ run io_context.cpp ]
[ run io_context.cpp : : : $(USE_SELECT) : io_context_select ]
[ run io_context_strand.cpp ]
[ run io_context_strand.cpp : : : $(USE_SELECT) : io_context_strand_select ]
[ link ip/address.cpp : : ip_address ]
[ link ip/address.cpp : $(USE_SELECT) : ip_address_select ]
[ link ip/address_v4.cpp : : ip_address_v4 ]
[ link ip/address_v4.cpp : $(USE_SELECT) : ip_address_v4_select ]
[ link ip/address_v6.cpp : : ip_address_v6 ]
[ link ip/address_v6.cpp : $(USE_SELECT) : ip_address_v6_select ]
[ link ip/basic_endpoint.cpp : : ip_basic_endpoint ]
[ link ip/basic_endpoint.cpp : $(USE_SELECT) : ip_basic_endpoint_select ]
[ link ip/basic_resolver.cpp : : ip_basic_resolver ]
[ link ip/basic_resolver.cpp : $(USE_SELECT) : ip_basic_resolver_select ]
[ link ip/basic_resolver_entry.cpp : : ip_basic_resolver_entry ]
[ link ip/basic_resolver_entry.cpp : $(USE_SELECT) : ip_basic_resolver_entry_select ]
[ link ip/basic_resolver_iterator.cpp : : ip_basic_resolver_iterator ]
[ link ip/basic_resolver_iterator.cpp : $(USE_SELECT) : ip_basic_resolver_iterator_select ]
[ link ip/basic_resolver_query.cpp : : ip_basic_resolver_query ]
[ link ip/basic_resolver_query.cpp : $(USE_SELECT) : ip_basic_resolver_query_select ]
[ run ip/host_name.cpp : : : : ip_host_name ]
[ run ip/host_name.cpp : : : $(USE_SELECT) : ip_host_name_select ]
[ run ip/icmp.cpp : : : : ip_icmp ]
[ run ip/icmp.cpp : : : $(USE_SELECT) : ip_icmp_select ]
[ run ip/multicast.cpp : : : : ip_multicast ]
[ run ip/multicast.cpp : : : $(USE_SELECT) : ip_multicast_select ]
[ link ip/resolver_query_base.cpp : : ip_resolver_query_base ]
[ link ip/resolver_query_base.cpp : $(USE_SELECT) : ip_resolver_query_base_select ]
[ run ip/tcp.cpp : : : : ip_tcp ]
[ run ip/tcp.cpp : : : $(USE_SELECT) : ip_tcp_select ]
[ run ip/udp.cpp : : : : ip_udp ]
[ run ip/udp.cpp : : : $(USE_SELECT) : ip_udp_select ]
[ run ip/unicast.cpp : : : : ip_unicast ]
[ run ip/unicast.cpp : : : $(USE_SELECT) : ip_unicast_select ]
[ run ip/v6_only.cpp : : : : ip_v6_only ]
[ run ip/v6_only.cpp : : : $(USE_SELECT) : ip_v6_only_select ]
[ run is_read_buffered.cpp ]
[ run is_read_buffered.cpp : : : $(USE_SELECT) : is_read_buffered_select ]
[ run is_write_buffered.cpp ]
[ run is_write_buffered.cpp : : : $(USE_SELECT) : is_write_buffered_select ]
[ link local/basic_endpoint.cpp : : local_basic_endpoint ]
[ link local/basic_endpoint.cpp : $(USE_SELECT) : local_basic_endpoint_select ]
[ link local/connect_pair.cpp : : local_connect_pair ]
[ link local/connect_pair.cpp : $(USE_SELECT) : local_connect_pair_select ]
[ link local/datagram_protocol.cpp : : local_datagram_protocol ]
[ link local/datagram_protocol.cpp : $(USE_SELECT) : local_datagram_protocol_select ]
[ link local/stream_protocol.cpp : : local_stream_protocol ]
[ link local/stream_protocol.cpp : $(USE_SELECT) : local_stream_protocol_select ]
[ link placeholders.cpp ]
[ link placeholders.cpp : $(USE_SELECT) : placeholders_select ]
[ link posix/basic_descriptor.cpp : : posix_basic_descriptor ]
[ link posix/basic_descriptor.cpp : $(USE_SELECT) : posix_basic_descriptor_select ]
[ link posix/basic_stream_descriptor.cpp : : posix_basic_stream_descriptor ]
[ link posix/basic_stream_descriptor.cpp : $(USE_SELECT) : posix_basic_stream_descriptor_select ]
[ link posix/descriptor_base.cpp : : posix_descriptor_base ]
[ link posix/descriptor_base.cpp : $(USE_SELECT) : posix_descriptor_base_select ]
[ link posix/stream_descriptor.cpp : : posix_stream_descriptor ]
[ link posix/stream_descriptor.cpp : $(USE_SELECT) : posix_stream_descriptor_select ]
[ link random_access_file.cpp ]
[ link random_access_file.cpp : $(USE_SELECT) : random_access_file_select ]
[ run read.cpp ]
[ run read.cpp : : : $(USE_SELECT) : read_select ]
[ run read_at.cpp ]
[ run read_at.cpp : : : $(USE_SELECT) : read_at_select ]
[ run read_until.cpp ]
[ run read_until.cpp : : : $(USE_SELECT) : read_until_select ]
[ link readable_pipe.cpp ]
[ link readable_pipe.cpp : $(USE_SELECT) : readable_pipe_select ]
[ run recycling_allocator.cpp ]
[ run recycling_allocator.cpp : : : $(USE_SELECT) : recycling_allocator_select ]
[ link redirect_error.cpp ]
[ link redirect_error.cpp : $(USE_SELECT) : redirect_error_select ]
[ link registered_buffer.cpp ]
[ link registered_buffer.cpp : $(USE_SELECT) : registered_buffer_select ]
[ run signal_set.cpp ]
[ run signal_set.cpp : : : $(USE_SELECT) : signal_set_select ]
[ run socket_base.cpp ]
[ run socket_base.cpp : : : $(USE_SELECT) : socket_base_select ]
[ run static_thread_pool.cpp ]
[ run static_thread_pool.cpp : : : $(USE_SELECT) : static_thread_pool_select ]
[ link steady_timer.cpp ]
[ link steady_timer.cpp : $(USE_SELECT) : steady_timer_select ]
[ run strand.cpp ]
[ run strand.cpp : : : $(USE_SELECT) : strand_select ]
[ link stream_file.cpp ]
[ link stream_file.cpp : $(USE_SELECT) : stream_file_select ]
[ run streambuf.cpp ]
[ run streambuf.cpp : : : $(USE_SELECT) : streambuf_select ]
[ link system_timer.cpp ]
[ link system_timer.cpp : $(USE_SELECT) : system_timer_select ]
[ link system_context.cpp ]
[ link system_context.cpp : $(USE_SELECT) : system_context_select ]
[ link system_executor.cpp ]
[ link system_executor.cpp : $(USE_SELECT) : system_executor_select ]
[ link this_coro.cpp ]
[ link this_coro.cpp : $(USE_SELECT) : this_coro_select ]
[ run thread_pool.cpp ]
[ run thread_pool.cpp : : : $(USE_SELECT) : thread_pool_select ]
[ link time_traits.cpp ]
[ link time_traits.cpp : $(USE_SELECT) : time_traits_select ]
[ link ts/buffer.cpp : : ts_buffer ]
[ link ts/buffer.cpp : $(USE_SELECT) : ts_buffer_select ]
[ link ts/executor.cpp : : ts_executor ]
[ link ts/executor.cpp : $(USE_SELECT) : ts_executor_select ]
[ link ts/internet.cpp : : ts_internet ]
[ link ts/internet.cpp : $(USE_SELECT) : ts_internet_select ]
[ link ts/io_context.cpp : : ts_io_context ]
[ link ts/io_context.cpp : $(USE_SELECT) : ts_io_context_select ]
[ link ts/net.cpp : : ts_net ]
[ link ts/net.cpp : $(USE_SELECT) : ts_net_select ]
[ link ts/netfwd.cpp : : ts_netfwd ]
[ link ts/netfwd.cpp : $(USE_SELECT) : ts_netfwd_select ]
[ link ts/socket.cpp : : ts_socket ]
[ link ts/socket.cpp : $(USE_SELECT) : ts_socket_select ]
[ link ts/timer.cpp : : ts_timer ]
[ link ts/timer.cpp : $(USE_SELECT) : ts_timer_select ]
[ link use_awaitable.cpp ]
[ link use_awaitable.cpp : $(USE_SELECT) : use_awaitable_select ]
[ link wait_traits.cpp ]
[ link wait_traits.cpp : $(USE_SELECT) : wait_traits_select ]
[ link windows/basic_object_handle.cpp : : windows_basic_object_handle ]
[ link windows/basic_object_handle.cpp : $(USE_SELECT) : windows_basic_object_handle_select ]
[ link windows/basic_overlapped_handle.cpp : : windows_basic_overlapped_handle ]
[ link windows/basic_overlapped_handle.cpp : $(USE_SELECT) : windows_basic_overlapped_handle_select ]
[ link windows/basic_random_access_handle.cpp : : windows_basic_random_access_handle ]
[ link windows/basic_random_access_handle.cpp : $(USE_SELECT) : windows_basic_random_access_handle_select ]
[ link windows/basic_stream_handle.cpp : : windows_basic_stream_handle ]
[ link windows/basic_stream_handle.cpp : $(USE_SELECT) : windows_basic_stream_handle_select ]
[ link windows/object_handle.cpp : : windows_object_handle ]
[ link windows/object_handle.cpp : $(USE_SELECT) : windows_object_handle_select ]
[ link windows/overlapped_ptr.cpp : : windows_overlapped_ptr ]
[ link windows/overlapped_ptr.cpp : $(USE_SELECT) : windows_overlapped_ptr_select ]
[ link windows/random_access_handle.cpp : : windows_random_access_handle ]
[ link windows/random_access_handle.cpp : $(USE_SELECT) : windows_random_access_handle_select ]
[ link windows/stream_handle.cpp : : windows_stream_handle ]
[ link windows/stream_handle.cpp : $(USE_SELECT) : windows_stream_handle_select ]
[ link writable_pipe.cpp ]
[ link writable_pipe.cpp : $(USE_SELECT) : writable_pipe_select ]
[ run write.cpp ]
[ run write.cpp : : : $(USE_SELECT) : write_select ]
[ run write_at.cpp ]
[ run write_at.cpp : : : $(USE_SELECT) : write_at_select ]
;
build-project execution ;

View File

@@ -0,0 +1,415 @@
//
// async_ops.hpp
// ~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef ARCHETYPES_ASYNC_OPS_HPP
#define ARCHETYPES_ASYNC_OPS_HPP
#include <boost/asio/associated_allocator.hpp>
#include <boost/asio/associated_executor.hpp>
#include <boost/asio/async_result.hpp>
#include <boost/asio/error.hpp>
#if defined(BOOST_ASIO_HAS_BOOST_BIND)
# include <boost/bind/bind.hpp>
#else // defined(BOOST_ASIO_HAS_BOOST_BIND)
# include <functional>
#endif // defined(BOOST_ASIO_HAS_BOOST_BIND)
namespace archetypes {
#if defined(BOOST_ASIO_HAS_BOOST_BIND)
namespace bindns = boost;
#else // defined(BOOST_ASIO_HAS_BOOST_BIND)
namespace bindns = std;
#endif // defined(BOOST_ASIO_HAS_BOOST_BIND)
template <typename CompletionToken>
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void())
async_op_0(BOOST_ASIO_MOVE_ARG(CompletionToken) token)
{
typedef typename boost::asio::async_completion<CompletionToken,
void()>::completion_handler_type handler_type;
boost::asio::async_completion<CompletionToken,
void()> completion(token);
typename boost::asio::associated_allocator<handler_type>::type a
= boost::asio::get_associated_allocator(completion.completion_handler);
typename boost::asio::associated_executor<handler_type>::type ex
= boost::asio::get_associated_executor(completion.completion_handler);
ex.post(BOOST_ASIO_MOVE_CAST(handler_type)(completion.completion_handler), a);
return completion.result.get();
}
template <typename CompletionToken>
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void(boost::system::error_code))
async_op_ec_0(bool ok, BOOST_ASIO_MOVE_ARG(CompletionToken) token)
{
typedef typename boost::asio::async_completion<CompletionToken,
void(boost::system::error_code)>::completion_handler_type handler_type;
boost::asio::async_completion<CompletionToken,
void(boost::system::error_code)> completion(token);
typename boost::asio::associated_allocator<handler_type>::type a
= boost::asio::get_associated_allocator(completion.completion_handler);
typename boost::asio::associated_executor<handler_type>::type ex
= boost::asio::get_associated_executor(completion.completion_handler);
if (ok)
{
ex.post(
bindns::bind(
BOOST_ASIO_MOVE_CAST(handler_type)(completion.completion_handler),
boost::system::error_code()), a);
}
else
{
ex.post(
bindns::bind(
BOOST_ASIO_MOVE_CAST(handler_type)(completion.completion_handler),
boost::system::error_code(boost::asio::error::operation_aborted)), a);
}
return completion.result.get();
}
template <typename CompletionToken>
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void(std::exception_ptr))
async_op_ex_0(bool ok, BOOST_ASIO_MOVE_ARG(CompletionToken) token)
{
typedef typename boost::asio::async_completion<CompletionToken,
void(std::exception_ptr)>::completion_handler_type handler_type;
boost::asio::async_completion<CompletionToken,
void(std::exception_ptr)> completion(token);
typename boost::asio::associated_allocator<handler_type>::type a
= boost::asio::get_associated_allocator(completion.completion_handler);
typename boost::asio::associated_executor<handler_type>::type ex
= boost::asio::get_associated_executor(completion.completion_handler);
if (ok)
{
ex.post(
bindns::bind(
BOOST_ASIO_MOVE_CAST(handler_type)(completion.completion_handler),
std::exception_ptr()), a);
}
else
{
ex.post(
bindns::bind(
BOOST_ASIO_MOVE_CAST(handler_type)(completion.completion_handler),
std::make_exception_ptr(std::runtime_error("blah"))), a);
}
return completion.result.get();
}
template <typename CompletionToken>
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void(int))
async_op_1(BOOST_ASIO_MOVE_ARG(CompletionToken) token)
{
typedef typename boost::asio::async_completion<CompletionToken,
void(int)>::completion_handler_type handler_type;
boost::asio::async_completion<CompletionToken,
void(int)> completion(token);
typename boost::asio::associated_allocator<handler_type>::type a
= boost::asio::get_associated_allocator(completion.completion_handler);
typename boost::asio::associated_executor<handler_type>::type ex
= boost::asio::get_associated_executor(completion.completion_handler);
ex.post(
bindns::bind(
BOOST_ASIO_MOVE_CAST(handler_type)(completion.completion_handler),
42), a);
return completion.result.get();
}
template <typename CompletionToken>
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken,
void(boost::system::error_code, int))
async_op_ec_1(bool ok, BOOST_ASIO_MOVE_ARG(CompletionToken) token)
{
typedef typename boost::asio::async_completion<CompletionToken,
void(boost::system::error_code, int)>::completion_handler_type
handler_type;
boost::asio::async_completion<CompletionToken,
void(boost::system::error_code, int)> completion(token);
typename boost::asio::associated_allocator<handler_type>::type a
= boost::asio::get_associated_allocator(completion.completion_handler);
typename boost::asio::associated_executor<handler_type>::type ex
= boost::asio::get_associated_executor(completion.completion_handler);
if (ok)
{
ex.post(
bindns::bind(
BOOST_ASIO_MOVE_CAST(handler_type)(completion.completion_handler),
boost::system::error_code(), 42), a);
}
else
{
ex.post(
bindns::bind(
BOOST_ASIO_MOVE_CAST(handler_type)(completion.completion_handler),
boost::system::error_code(boost::asio::error::operation_aborted),
0), a);
}
return completion.result.get();
}
template <typename CompletionToken>
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void(std::exception_ptr, int))
async_op_ex_1(bool ok, BOOST_ASIO_MOVE_ARG(CompletionToken) token)
{
typedef typename boost::asio::async_completion<CompletionToken,
void(std::exception_ptr, int)>::completion_handler_type
handler_type;
boost::asio::async_completion<CompletionToken,
void(std::exception_ptr, int)> completion(token);
typename boost::asio::associated_allocator<handler_type>::type a
= boost::asio::get_associated_allocator(completion.completion_handler);
typename boost::asio::associated_executor<handler_type>::type ex
= boost::asio::get_associated_executor(completion.completion_handler);
if (ok)
{
ex.post(
bindns::bind(
BOOST_ASIO_MOVE_CAST(handler_type)(completion.completion_handler),
std::exception_ptr(), 42), a);
}
else
{
ex.post(
bindns::bind(
BOOST_ASIO_MOVE_CAST(handler_type)(completion.completion_handler),
std::make_exception_ptr(std::runtime_error("blah")), 0), a);
}
return completion.result.get();
}
template <typename CompletionToken>
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void(int, double))
async_op_2(BOOST_ASIO_MOVE_ARG(CompletionToken) token)
{
typedef typename boost::asio::async_completion<CompletionToken,
void(int, double)>::completion_handler_type handler_type;
boost::asio::async_completion<CompletionToken,
void(int, double)> completion(token);
typename boost::asio::associated_allocator<handler_type>::type a
= boost::asio::get_associated_allocator(completion.completion_handler);
typename boost::asio::associated_executor<handler_type>::type ex
= boost::asio::get_associated_executor(completion.completion_handler);
ex.post(
bindns::bind(
BOOST_ASIO_MOVE_CAST(handler_type)(completion.completion_handler),
42, 2.0), a);
return completion.result.get();
}
template <typename CompletionToken>
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken,
void(boost::system::error_code, int, double))
async_op_ec_2(bool ok, BOOST_ASIO_MOVE_ARG(CompletionToken) token)
{
typedef typename boost::asio::async_completion<CompletionToken,
void(boost::system::error_code, int, double)>::completion_handler_type
handler_type;
boost::asio::async_completion<CompletionToken,
void(boost::system::error_code, int, double)> completion(token);
typename boost::asio::associated_allocator<handler_type>::type a
= boost::asio::get_associated_allocator(completion.completion_handler);
typename boost::asio::associated_executor<handler_type>::type ex
= boost::asio::get_associated_executor(completion.completion_handler);
if (ok)
{
ex.post(
bindns::bind(
BOOST_ASIO_MOVE_CAST(handler_type)(completion.completion_handler),
boost::system::error_code(), 42, 2.0), a);
}
else
{
ex.post(
bindns::bind(
BOOST_ASIO_MOVE_CAST(handler_type)(completion.completion_handler),
boost::system::error_code(boost::asio::error::operation_aborted),
0, 0.0), a);
}
return completion.result.get();
}
template <typename CompletionToken>
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken,
void(std::exception_ptr, int, double))
async_op_ex_2(bool ok, BOOST_ASIO_MOVE_ARG(CompletionToken) token)
{
typedef typename boost::asio::async_completion<CompletionToken,
void(std::exception_ptr, int, double)>::completion_handler_type
handler_type;
boost::asio::async_completion<CompletionToken,
void(std::exception_ptr, int, double)> completion(token);
typename boost::asio::associated_allocator<handler_type>::type a
= boost::asio::get_associated_allocator(completion.completion_handler);
typename boost::asio::associated_executor<handler_type>::type ex
= boost::asio::get_associated_executor(completion.completion_handler);
if (ok)
{
ex.post(
bindns::bind(
BOOST_ASIO_MOVE_CAST(handler_type)(completion.completion_handler),
std::exception_ptr(), 42, 2.0), a);
}
else
{
ex.post(
bindns::bind(
BOOST_ASIO_MOVE_CAST(handler_type)(completion.completion_handler),
std::make_exception_ptr(std::runtime_error("blah")), 0, 0.0), a);
}
return completion.result.get();
}
template <typename CompletionToken>
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void(int, double, char))
async_op_3(BOOST_ASIO_MOVE_ARG(CompletionToken) token)
{
typedef typename boost::asio::async_completion<CompletionToken,
void(int, double, char)>::completion_handler_type handler_type;
boost::asio::async_completion<CompletionToken,
void(int, double, char)> completion(token);
typename boost::asio::associated_allocator<handler_type>::type a
= boost::asio::get_associated_allocator(completion.completion_handler);
typename boost::asio::associated_executor<handler_type>::type ex
= boost::asio::get_associated_executor(completion.completion_handler);
ex.post(
bindns::bind(
BOOST_ASIO_MOVE_CAST(handler_type)(completion.completion_handler),
42, 2.0, 'a'), a);
return completion.result.get();
}
template <typename CompletionToken>
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken,
void(boost::system::error_code, int, double, char))
async_op_ec_3(bool ok, BOOST_ASIO_MOVE_ARG(CompletionToken) token)
{
typedef typename boost::asio::async_completion<CompletionToken,
void(boost::system::error_code, int, double, char)>::completion_handler_type
handler_type;
boost::asio::async_completion<CompletionToken,
void(boost::system::error_code, int, double, char)> completion(token);
typename boost::asio::associated_allocator<handler_type>::type a
= boost::asio::get_associated_allocator(completion.completion_handler);
typename boost::asio::associated_executor<handler_type>::type ex
= boost::asio::get_associated_executor(completion.completion_handler);
if (ok)
{
ex.post(
bindns::bind(
BOOST_ASIO_MOVE_CAST(handler_type)(completion.completion_handler),
boost::system::error_code(), 42, 2.0, 'a'), a);
}
else
{
ex.post(
bindns::bind(
BOOST_ASIO_MOVE_CAST(handler_type)(completion.completion_handler),
boost::system::error_code(boost::asio::error::operation_aborted),
0, 0.0, 'z'), a);
}
return completion.result.get();
}
template <typename CompletionToken>
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken,
void(std::exception_ptr, int, double, char))
async_op_ex_3(bool ok, BOOST_ASIO_MOVE_ARG(CompletionToken) token)
{
typedef typename boost::asio::async_completion<CompletionToken,
void(std::exception_ptr, int, double, char)>::completion_handler_type
handler_type;
boost::asio::async_completion<CompletionToken,
void(std::exception_ptr, int, double, char)> completion(token);
typename boost::asio::associated_allocator<handler_type>::type a
= boost::asio::get_associated_allocator(completion.completion_handler);
typename boost::asio::associated_executor<handler_type>::type ex
= boost::asio::get_associated_executor(completion.completion_handler);
if (ok)
{
ex.post(
bindns::bind(
BOOST_ASIO_MOVE_CAST(handler_type)(completion.completion_handler),
std::exception_ptr(), 42, 2.0, 'a'), a);
}
else
{
ex.post(
bindns::bind(
BOOST_ASIO_MOVE_CAST(handler_type)(completion.completion_handler),
std::make_exception_ptr(std::runtime_error("blah")),
0, 0.0, 'z'), a);
}
return completion.result.get();
}
} // namespace archetypes
#endif // ARCHETYPES_ASYNC_OPS_HPP

View File

@@ -0,0 +1,96 @@
//
// async_result.hpp
// ~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef ARCHETYPES_ASYNC_RESULT_HPP
#define ARCHETYPES_ASYNC_RESULT_HPP
#include <boost/asio/async_result.hpp>
namespace archetypes {
struct lazy_handler
{
};
template <typename Signature>
struct concrete_handler;
template <typename R, typename Arg1>
struct concrete_handler<R(Arg1)>
{
concrete_handler(lazy_handler)
{
}
void operator()(typename boost::asio::decay<Arg1>::type)
{
}
#if defined(BOOST_ASIO_HAS_MOVE)
concrete_handler(concrete_handler&&) {}
private:
concrete_handler(const concrete_handler&);
#endif // defined(BOOST_ASIO_HAS_MOVE)
};
template <typename R, typename Arg1, typename Arg2>
struct concrete_handler<R(Arg1, Arg2)>
{
concrete_handler(lazy_handler)
{
}
void operator()(typename boost::asio::decay<Arg1>::type, typename boost::asio::decay<Arg2>::type)
{
}
#if defined(BOOST_ASIO_HAS_MOVE)
concrete_handler(concrete_handler&&) {}
private:
concrete_handler(const concrete_handler&);
#endif // defined(BOOST_ASIO_HAS_MOVE)
};
} // namespace archetypes
namespace boost {
namespace asio {
template <typename Signature>
class async_result<archetypes::lazy_handler, Signature>
{
public:
// The concrete completion handler type.
typedef archetypes::concrete_handler<Signature> completion_handler_type;
// The return type of the initiating function.
typedef int return_type;
// Construct an async_result from a given handler.
explicit async_result(completion_handler_type&)
{
}
// Obtain the value to be returned from the initiating function.
return_type get()
{
return 42;
}
private:
// Disallow copying and assignment.
async_result(const async_result&) BOOST_ASIO_DELETED;
async_result& operator=(const async_result&) BOOST_ASIO_DELETED;
};
} // namespace asio
} // namespace boost
#endif // ARCHETYPES_ASYNC_RESULT_HPP

View File

@@ -0,0 +1,54 @@
//
// gettable_socket_option.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef ARCHETYPES_GETTABLE_SOCKET_OPTION_HPP
#define ARCHETYPES_GETTABLE_SOCKET_OPTION_HPP
#include <cstddef>
namespace archetypes {
template <typename PointerType>
class gettable_socket_option
{
public:
template <typename Protocol>
int level(const Protocol&) const
{
return 0;
}
template <typename Protocol>
int name(const Protocol&) const
{
return 0;
}
template <typename Protocol>
PointerType* data(const Protocol&)
{
return 0;
}
template <typename Protocol>
std::size_t size(const Protocol&) const
{
return 0;
}
template <typename Protocol>
void resize(const Protocol&, std::size_t)
{
}
};
} // namespace archetypes
#endif // ARCHETYPES_GETTABLE_SOCKET_OPTION_HPP

View File

@@ -0,0 +1,32 @@
//
// io_control_command.hpp
// ~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef ARCHETYPES_IO_CONTROL_COMMAND_HPP
#define ARCHETYPES_IO_CONTROL_COMMAND_HPP
namespace archetypes {
class io_control_command
{
public:
int name() const
{
return 0;
}
void* data()
{
return 0;
}
};
} // namespace archetypes
#endif // ARCHETYPES_IO_CONTROL_COMMAND_HPP

View File

@@ -0,0 +1,49 @@
//
// settable_socket_option.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef ARCHETYPES_SETTABLE_SOCKET_OPTION_HPP
#define ARCHETYPES_SETTABLE_SOCKET_OPTION_HPP
#include <cstddef>
namespace archetypes {
template <typename PointerType>
class settable_socket_option
{
public:
template <typename Protocol>
int level(const Protocol&) const
{
return 0;
}
template <typename Protocol>
int name(const Protocol&) const
{
return 0;
}
template <typename Protocol>
const PointerType* data(const Protocol&) const
{
return 0;
}
template <typename Protocol>
std::size_t size(const Protocol&) const
{
return 0;
}
};
} // namespace archetypes
#endif // ARCHETYPES_SETTABLE_SOCKET_OPTION_HPP

View File

@@ -0,0 +1,25 @@
//
// associated_allocator.cpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/associated_allocator.hpp>
#include "unit_test.hpp"
BOOST_ASIO_TEST_SUITE
(
"associated_allocator",
BOOST_ASIO_TEST_CASE(null_test)
)

View File

@@ -0,0 +1,25 @@
//
// associated_cancellation_slot.cpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/associated_cancellation_slot.hpp>
#include "unit_test.hpp"
BOOST_ASIO_TEST_SUITE
(
"associated_cancellation_slot",
BOOST_ASIO_TEST_CASE(null_test)
)

View File

@@ -0,0 +1,25 @@
//
// associated_executor.cpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/associated_executor.hpp>
#include "unit_test.hpp"
BOOST_ASIO_TEST_SUITE
(
"associated_executor",
BOOST_ASIO_TEST_CASE(null_test)
)

View File

@@ -0,0 +1,25 @@
//
// associator.cpp
// ~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/associator.hpp>
#include "unit_test.hpp"
BOOST_ASIO_TEST_SUITE
(
"associator",
BOOST_ASIO_TEST_CASE(null_test)
)

View File

@@ -0,0 +1,25 @@
//
// async_result.cpp
// ~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/async_result.hpp>
#include "unit_test.hpp"
BOOST_ASIO_TEST_SUITE
(
"async_result",
BOOST_ASIO_TEST_CASE(null_test)
)

View File

@@ -0,0 +1,25 @@
//
// awaitable.cpp
// ~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/awaitable.hpp>
#include "unit_test.hpp"
BOOST_ASIO_TEST_SUITE
(
"awaitable",
BOOST_ASIO_TEST_CASE(null_test)
)

View File

@@ -0,0 +1,25 @@
//
// basic_datagram_socket.cpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/basic_datagram_socket.hpp>
#include "unit_test.hpp"
BOOST_ASIO_TEST_SUITE
(
"basic_datagram_socket",
BOOST_ASIO_TEST_CASE(null_test)
)

View File

@@ -0,0 +1,25 @@
//
// basic_deadline_timer.cpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/basic_deadline_timer.hpp>
#include "unit_test.hpp"
BOOST_ASIO_TEST_SUITE
(
"basic_deadline_timer",
BOOST_ASIO_TEST_CASE(null_test)
)

View File

@@ -0,0 +1,25 @@
//
// basic_file.cpp
// ~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/basic_file.hpp>
#include "unit_test.hpp"
BOOST_ASIO_TEST_SUITE
(
"basic_file",
BOOST_ASIO_TEST_CASE(null_test)
)

View File

@@ -0,0 +1,25 @@
//
// basic_random_access_file.cpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/basic_random_access_file.hpp>
#include "unit_test.hpp"
BOOST_ASIO_TEST_SUITE
(
"basic_random_access_file",
BOOST_ASIO_TEST_CASE(null_test)
)

View File

@@ -0,0 +1,25 @@
//
// basic_raw_socket.cpp
// ~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/basic_raw_socket.hpp>
#include "unit_test.hpp"
BOOST_ASIO_TEST_SUITE
(
"basic_raw_socket",
BOOST_ASIO_TEST_CASE(null_test)
)

View File

@@ -0,0 +1,25 @@
//
// basic_readable_pipe.cpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/basic_readable_pipe.hpp>
#include "unit_test.hpp"
BOOST_ASIO_TEST_SUITE
(
"basic_readable_pipe",
BOOST_ASIO_TEST_CASE(null_test)
)

View File

@@ -0,0 +1,25 @@
//
// basic_seq_packet_socket.cpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/basic_seq_packet_socket.hpp>
#include "unit_test.hpp"
BOOST_ASIO_TEST_SUITE
(
"basic_seq_packet_socket",
BOOST_ASIO_TEST_CASE(null_test)
)

View File

@@ -0,0 +1,26 @@
//
// basic_serial_port.cpp
// ~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/basic_serial_port.hpp>
#include "unit_test.hpp"
BOOST_ASIO_TEST_SUITE
(
"basic_serial_port",
BOOST_ASIO_TEST_CASE(null_test)
)

View File

@@ -0,0 +1,25 @@
//
// basic_signal_set.cpp
// ~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/basic_signal_set.hpp>
#include "unit_test.hpp"
BOOST_ASIO_TEST_SUITE
(
"basic_signal_set",
BOOST_ASIO_TEST_CASE(null_test)
)

View File

@@ -0,0 +1,25 @@
//
// basic_socket.cpp
// ~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/basic_socket.hpp>
#include "unit_test.hpp"
BOOST_ASIO_TEST_SUITE
(
"basic_socket",
BOOST_ASIO_TEST_CASE(null_test)
)

View File

@@ -0,0 +1,25 @@
//
// basic_socket_acceptor.cpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/basic_socket_acceptor.hpp>
#include "unit_test.hpp"
BOOST_ASIO_TEST_SUITE
(
"basic_socket_acceptor",
BOOST_ASIO_TEST_CASE(null_test)
)

View File

@@ -0,0 +1,25 @@
//
// basic_stream_file.cpp
// ~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/basic_stream_file.hpp>
#include "unit_test.hpp"
BOOST_ASIO_TEST_SUITE
(
"basic_stream_file",
BOOST_ASIO_TEST_CASE(null_test)
)

View File

@@ -0,0 +1,25 @@
//
// basic_stream_socket.cpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/basic_stream_socket.hpp>
#include "unit_test.hpp"
BOOST_ASIO_TEST_SUITE
(
"basic_stream_socket",
BOOST_ASIO_TEST_CASE(null_test)
)

View File

@@ -0,0 +1,25 @@
//
// basic_streambuf.cpp
// ~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/basic_streambuf.hpp>
#include "unit_test.hpp"
BOOST_ASIO_TEST_SUITE
(
"basic_streambuf",
BOOST_ASIO_TEST_CASE(null_test)
)

View File

@@ -0,0 +1,25 @@
//
// basic_waitable_timer.cpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/basic_waitable_timer.hpp>
#include "unit_test.hpp"
BOOST_ASIO_TEST_SUITE
(
"basic_waitable_timer",
BOOST_ASIO_TEST_CASE(null_test)
)

View File

@@ -0,0 +1,25 @@
//
// basic_writable_pipe.cpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/basic_writable_pipe.hpp>
#include "unit_test.hpp"
BOOST_ASIO_TEST_SUITE
(
"basic_writable_pipe",
BOOST_ASIO_TEST_CASE(null_test)
)

View File

@@ -0,0 +1,257 @@
//
// bind_allocator.cpp
// ~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/bind_allocator.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/steady_timer.hpp>
#include "unit_test.hpp"
#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
# include <boost/asio/deadline_timer.hpp>
#else // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
# include <boost/asio/steady_timer.hpp>
#endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
#if defined(BOOST_ASIO_HAS_BOOST_BIND)
# include <boost/bind/bind.hpp>
#else // defined(BOOST_ASIO_HAS_BOOST_BIND)
# include <functional>
#endif // defined(BOOST_ASIO_HAS_BOOST_BIND)
using namespace boost::asio;
#if defined(BOOST_ASIO_HAS_BOOST_BIND)
namespace bindns = boost;
#else // defined(BOOST_ASIO_HAS_BOOST_BIND)
namespace bindns = std;
#endif
#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
typedef deadline_timer timer;
namespace chronons = boost::posix_time;
#elif defined(BOOST_ASIO_HAS_CHRONO)
typedef steady_timer timer;
namespace chronons = boost::asio::chrono;
#endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
template <typename T>
class test_allocator
{
public:
typedef T value_type;
explicit test_allocator(int* allocations)
: allocations_(allocations)
{
}
template <typename U>
test_allocator(const test_allocator<U>& other)
: allocations_(other.allocations_)
{
}
template <typename U>
struct rebind
{
typedef test_allocator<U> other;
};
bool operator==(const test_allocator&) const
{
return true;
}
bool operator!=(const test_allocator&) const
{
return false;
}
T* allocate(std::size_t n) const
{
++(*allocations_);
return static_cast<T*>(::operator new(sizeof(T) * n));
}
void deallocate(T* p, std::size_t /*n*/) const
{
--(*allocations_);
::operator delete(p);
}
//private:
int* allocations_;
};
void increment(int* count)
{
++(*count);
}
void bind_allocator_to_function_object_test()
{
io_context ioc;
int count = 0;
int allocations = 0;
timer t(ioc, chronons::seconds(1));
t.async_wait(
bind_allocator(
test_allocator<int>(&allocations),
bindns::bind(&increment, &count)));
BOOST_ASIO_CHECK(count == 0);
BOOST_ASIO_CHECK(allocations == 1);
ioc.run();
BOOST_ASIO_CHECK(count == 1);
BOOST_ASIO_CHECK(allocations == 0);
}
struct incrementer_token_v1
{
explicit incrementer_token_v1(int* c) : count(c) {}
int* count;
};
struct incrementer_handler_v1
{
explicit incrementer_handler_v1(incrementer_token_v1 t) : count(t.count) {}
void operator()(boost::system::error_code){ increment(count); }
int* count;
};
namespace boost {
namespace asio {
template <>
class async_result<incrementer_token_v1, void(boost::system::error_code)>
{
public:
typedef incrementer_handler_v1 completion_handler_type;
typedef void return_type;
explicit async_result(completion_handler_type&) {}
return_type get() {}
};
} // namespace asio
} // namespace boost
void bind_allocator_to_completion_token_v1_test()
{
io_context ioc;
int count = 0;
int allocations = 0;
timer t(ioc, chronons::seconds(1));
t.async_wait(
bind_allocator(
test_allocator<int>(&allocations),
incrementer_token_v1(&count)));
BOOST_ASIO_CHECK(count == 0);
BOOST_ASIO_CHECK(allocations == 1);
ioc.run();
BOOST_ASIO_CHECK(count == 1);
BOOST_ASIO_CHECK(allocations == 0);
}
struct incrementer_token_v2
{
explicit incrementer_token_v2(int* c) : count(c) {}
int* count;
};
namespace boost {
namespace asio {
template <>
class async_result<incrementer_token_v2, void(boost::system::error_code)>
{
public:
typedef void return_type;
#if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
template <typename Initiation, typename... Args>
static void initiate(Initiation initiation,
incrementer_token_v2 token, BOOST_ASIO_MOVE_ARG(Args)... args)
{
initiation(bindns::bind(&increment, token.count),
BOOST_ASIO_MOVE_CAST(Args)(args)...);
}
#else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
template <typename Initiation>
static void initiate(Initiation initiation, incrementer_token_v2 token)
{
initiation(bindns::bind(&increment, token.count));
}
#define BOOST_ASIO_PRIVATE_INITIATE_DEF(n) \
template <typename Initiation, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
static return_type initiate(Initiation initiation, \
incrementer_token_v2 token, BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
{ \
initiation(bindns::bind(&increment, token.count), \
BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
} \
/**/
BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_INITIATE_DEF)
#undef BOOST_ASIO_PRIVATE_INITIATE_DEF
#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
};
} // namespace asio
} // namespace boost
void bind_allocator_to_completion_token_v2_test()
{
io_context ioc;
int count = 0;
int allocations = 0;
timer t(ioc, chronons::seconds(1));
t.async_wait(
bind_allocator(
test_allocator<int>(&allocations),
incrementer_token_v2(&count)));
BOOST_ASIO_CHECK(count == 0);
BOOST_ASIO_CHECK(allocations == 1);
ioc.run();
BOOST_ASIO_CHECK(count == 1);
BOOST_ASIO_CHECK(allocations == 0);
}
BOOST_ASIO_TEST_SUITE
(
"bind_allocator",
BOOST_ASIO_TEST_CASE(bind_allocator_to_function_object_test)
BOOST_ASIO_TEST_CASE(bind_allocator_to_completion_token_v1_test)
BOOST_ASIO_TEST_CASE(bind_allocator_to_completion_token_v2_test)
)

View File

@@ -0,0 +1,225 @@
//
// bind_cancellation_slot.cpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/bind_cancellation_slot.hpp>
#include <boost/asio/cancellation_signal.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/steady_timer.hpp>
#include "unit_test.hpp"
#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
# include <boost/asio/deadline_timer.hpp>
#else // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
# include <boost/asio/steady_timer.hpp>
#endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
#if defined(BOOST_ASIO_HAS_BOOST_BIND)
# include <boost/bind/bind.hpp>
#else // defined(BOOST_ASIO_HAS_BOOST_BIND)
# include <functional>
#endif // defined(BOOST_ASIO_HAS_BOOST_BIND)
using namespace boost::asio;
#if defined(BOOST_ASIO_HAS_BOOST_BIND)
namespace bindns = boost;
#else // defined(BOOST_ASIO_HAS_BOOST_BIND)
namespace bindns = std;
#endif
#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
typedef deadline_timer timer;
namespace chronons = boost::posix_time;
#elif defined(BOOST_ASIO_HAS_CHRONO)
typedef steady_timer timer;
namespace chronons = boost::asio::chrono;
#endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
void increment_on_cancel(int* count, const boost::system::error_code& error)
{
if (error == boost::asio::error::operation_aborted)
++(*count);
}
void bind_cancellation_slot_to_function_object_test()
{
io_context ioc;
cancellation_signal sig;
int count = 0;
timer t(ioc, chronons::seconds(5));
t.async_wait(
bind_cancellation_slot(sig.slot(),
bindns::bind(&increment_on_cancel,
&count, bindns::placeholders::_1)));
ioc.poll();
BOOST_ASIO_CHECK(count == 0);
sig.emit(boost::asio::cancellation_type::all);
ioc.run();
BOOST_ASIO_CHECK(count == 1);
}
struct incrementer_token_v1
{
explicit incrementer_token_v1(int* c) : count(c) {}
int* count;
};
struct incrementer_handler_v1
{
explicit incrementer_handler_v1(incrementer_token_v1 t) : count(t.count) {}
void operator()(boost::system::error_code error)
{
increment_on_cancel(count, error);
}
int* count;
};
namespace boost {
namespace asio {
template <>
class async_result<incrementer_token_v1, void(boost::system::error_code)>
{
public:
typedef incrementer_handler_v1 completion_handler_type;
typedef void return_type;
explicit async_result(completion_handler_type&) {}
return_type get() {}
};
} // namespace asio
} // namespace boost
void bind_cancellation_slot_to_completion_token_v1_test()
{
io_context ioc;
cancellation_signal sig;
int count = 0;
timer t(ioc, chronons::seconds(5));
t.async_wait(
bind_cancellation_slot(sig.slot(),
incrementer_token_v1(&count)));
ioc.poll();
BOOST_ASIO_CHECK(count == 0);
sig.emit(boost::asio::cancellation_type::all);
ioc.run();
BOOST_ASIO_CHECK(count == 1);
}
struct incrementer_token_v2
{
explicit incrementer_token_v2(int* c) : count(c) {}
int* count;
};
namespace boost {
namespace asio {
template <>
class async_result<incrementer_token_v2, void(boost::system::error_code)>
{
public:
typedef void return_type;
#if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
template <typename Initiation, typename... Args>
static void initiate(Initiation initiation,
incrementer_token_v2 token, BOOST_ASIO_MOVE_ARG(Args)... args)
{
initiation(
bindns::bind(&increment_on_cancel,
token.count, bindns::placeholders::_1),
BOOST_ASIO_MOVE_CAST(Args)(args)...);
}
#else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
template <typename Initiation>
static void initiate(Initiation initiation, incrementer_token_v2 token)
{
initiation(
bindns::bind(&increment_on_cancel,
token.count, bindns::placeholders::_1));
}
#define BOOST_ASIO_PRIVATE_INITIATE_DEF(n) \
template <typename Initiation, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
static return_type initiate(Initiation initiation, \
incrementer_token_v2 token, BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
{ \
initiation( \
bindns::bind(&increment_on_cancel, \
token.count, bindns::placeholders::_1), \
BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
} \
/**/
BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_INITIATE_DEF)
#undef BOOST_ASIO_PRIVATE_INITIATE_DEF
#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
};
} // namespace asio
} // namespace boost
void bind_cancellation_slot_to_completion_token_v2_test()
{
io_context ioc;
cancellation_signal sig;
int count = 0;
timer t(ioc, chronons::seconds(5));
t.async_wait(
bind_cancellation_slot(sig.slot(),
incrementer_token_v2(&count)));
ioc.poll();
BOOST_ASIO_CHECK(count == 0);
sig.emit(boost::asio::cancellation_type::all);
ioc.run();
BOOST_ASIO_CHECK(count == 1);
}
BOOST_ASIO_TEST_SUITE
(
"bind_cancellation_slot",
BOOST_ASIO_TEST_CASE(bind_cancellation_slot_to_function_object_test)
BOOST_ASIO_TEST_CASE(bind_cancellation_slot_to_completion_token_v1_test)
BOOST_ASIO_TEST_CASE(bind_cancellation_slot_to_completion_token_v2_test)
)

View File

@@ -0,0 +1,208 @@
//
// bind_executor.cpp
// ~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/bind_executor.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/steady_timer.hpp>
#include "unit_test.hpp"
#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
# include <boost/asio/deadline_timer.hpp>
#else // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
# include <boost/asio/steady_timer.hpp>
#endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
#if defined(BOOST_ASIO_HAS_BOOST_BIND)
# include <boost/bind/bind.hpp>
#else // defined(BOOST_ASIO_HAS_BOOST_BIND)
# include <functional>
#endif // defined(BOOST_ASIO_HAS_BOOST_BIND)
using namespace boost::asio;
#if defined(BOOST_ASIO_HAS_BOOST_BIND)
namespace bindns = boost;
#else // defined(BOOST_ASIO_HAS_BOOST_BIND)
namespace bindns = std;
#endif
#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
typedef deadline_timer timer;
namespace chronons = boost::posix_time;
#elif defined(BOOST_ASIO_HAS_CHRONO)
typedef steady_timer timer;
namespace chronons = boost::asio::chrono;
#endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
void increment(int* count)
{
++(*count);
}
void bind_executor_to_function_object_test()
{
io_context ioc1;
io_context ioc2;
int count = 0;
timer t(ioc1, chronons::seconds(1));
t.async_wait(
bind_executor(
ioc2.get_executor(),
bindns::bind(&increment, &count)));
ioc1.run();
BOOST_ASIO_CHECK(count == 0);
ioc2.run();
BOOST_ASIO_CHECK(count == 1);
}
struct incrementer_token_v1
{
explicit incrementer_token_v1(int* c) : count(c) {}
int* count;
};
struct incrementer_handler_v1
{
explicit incrementer_handler_v1(incrementer_token_v1 t) : count(t.count) {}
void operator()(boost::system::error_code){ increment(count); }
int* count;
};
namespace boost {
namespace asio {
template <>
class async_result<incrementer_token_v1, void(boost::system::error_code)>
{
public:
typedef incrementer_handler_v1 completion_handler_type;
typedef void return_type;
explicit async_result(completion_handler_type&) {}
return_type get() {}
};
} // namespace asio
} // namespace boost
void bind_executor_to_completion_token_v1_test()
{
io_context ioc1;
io_context ioc2;
int count = 0;
timer t(ioc1, chronons::seconds(1));
t.async_wait(
bind_executor(
ioc2.get_executor(),
incrementer_token_v1(&count)));
ioc1.run();
BOOST_ASIO_CHECK(count == 0);
ioc2.run();
BOOST_ASIO_CHECK(count == 1);
}
struct incrementer_token_v2
{
explicit incrementer_token_v2(int* c) : count(c) {}
int* count;
};
namespace boost {
namespace asio {
template <>
class async_result<incrementer_token_v2, void(boost::system::error_code)>
{
public:
typedef void return_type;
#if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
template <typename Initiation, typename... Args>
static void initiate(Initiation initiation,
incrementer_token_v2 token, BOOST_ASIO_MOVE_ARG(Args)... args)
{
initiation(bindns::bind(&increment, token.count),
BOOST_ASIO_MOVE_CAST(Args)(args)...);
}
#else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
template <typename Initiation>
static void initiate(Initiation initiation, incrementer_token_v2 token)
{
initiation(bindns::bind(&increment, token.count));
}
#define BOOST_ASIO_PRIVATE_INITIATE_DEF(n) \
template <typename Initiation, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
static return_type initiate(Initiation initiation, \
incrementer_token_v2 token, BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
{ \
initiation(bindns::bind(&increment, token.count), \
BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
} \
/**/
BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_INITIATE_DEF)
#undef BOOST_ASIO_PRIVATE_INITIATE_DEF
#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
};
} // namespace asio
} // namespace boost
void bind_executor_to_completion_token_v2_test()
{
io_context ioc1;
io_context ioc2;
int count = 0;
timer t(ioc1, chronons::seconds(1));
t.async_wait(
bind_executor(
ioc2.get_executor(),
incrementer_token_v2(&count)));
ioc1.run();
BOOST_ASIO_CHECK(count == 0);
ioc2.run();
BOOST_ASIO_CHECK(count == 1);
}
BOOST_ASIO_TEST_SUITE
(
"bind_executor",
BOOST_ASIO_TEST_CASE(bind_executor_to_function_object_test)
BOOST_ASIO_TEST_CASE(bind_executor_to_completion_token_v1_test)
BOOST_ASIO_TEST_CASE(bind_executor_to_completion_token_v2_test)
)

View File

@@ -0,0 +1,830 @@
//
// buffer.cpp
// ~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/buffer.hpp>
#include "unit_test.hpp"
#if defined(BOOST_ASIO_HAS_BOOST_ARRAY)
# include <boost/array.hpp>
#endif // defined(BOOST_ASIO_HAS_BOOST_ARRAY)
#if defined(BOOST_ASIO_HAS_STD_ARRAY)
# include <array>
#endif // defined(BOOST_ASIO_HAS_STD_ARRAY)
//------------------------------------------------------------------------------
// buffer_compile test
// ~~~~~~~~~~~~~~~~~~~
// The following test checks that all overloads of the buffer function compile
// and link correctly. Runtime failures are ignored.
namespace buffer_compile {
using namespace boost::asio;
void test()
{
try
{
char raw_data[1024];
const char const_raw_data[1024] = "";
void* void_ptr_data = raw_data;
const void* const_void_ptr_data = const_raw_data;
#if defined(BOOST_ASIO_HAS_BOOST_ARRAY)
boost::array<char, 1024> array_data;
const boost::array<char, 1024>& const_array_data_1 = array_data;
boost::array<const char, 1024> const_array_data_2 = { { 0 } };
#endif // defined(BOOST_ASIO_HAS_BOOST_ARRAY)
#if defined(BOOST_ASIO_HAS_STD_ARRAY)
std::array<char, 1024> std_array_data;
const std::array<char, 1024>& const_std_array_data_1 = std_array_data;
std::array<const char, 1024> const_std_array_data_2 = { { 0 } };
#endif // defined(BOOST_ASIO_HAS_STD_ARRAY)
std::vector<char> vector_data(1024);
const std::vector<char>& const_vector_data = vector_data;
std::string string_data(1024, ' ');
const std::string const_string_data(1024, ' ');
std::vector<mutable_buffer> mutable_buffer_sequence;
std::vector<const_buffer> const_buffer_sequence;
#if defined(BOOST_ASIO_HAS_STD_STRING_VIEW)
std::string_view string_view_data(string_data);
#elif defined(BOOST_ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW)
std::experimental::string_view string_view_data(string_data);
#endif // defined(BOOST_ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW)
// mutable_buffer constructors.
mutable_buffer mb1;
mutable_buffer mb2(void_ptr_data, 1024);
mutable_buffer mb3(mb1);
(void)mb3;
// mutable_buffer functions.
void* ptr1 = mb1.data();
(void)ptr1;
std::size_t n1 = mb1.size();
(void)n1;
// mutable_buffer operators.
mb1 += 128;
mb1 = mb2 + 128;
mb1 = 128 + mb2;
#if !defined(BOOST_ASIO_NO_DEPRECATED)
// mutable_buffers_1 constructors.
mutable_buffers_1 mbc1(mb1);
mutable_buffers_1 mbc2(mbc1);
// mutable_buffers_1 functions.
mutable_buffers_1::const_iterator iter1 = mbc1.begin();
(void)iter1;
mutable_buffers_1::const_iterator iter2 = mbc1.end();
(void)iter2;
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
// const_buffer constructors.
const_buffer cb1;
const_buffer cb2(const_void_ptr_data, 1024);
const_buffer cb3(cb1);
(void)cb3;
const_buffer cb4(mb1);
(void)cb4;
// const_buffer functions.
const void* ptr2 = cb1.data();
(void)ptr2;
std::size_t n2 = cb1.size();
(void)n2;
// const_buffer operators.
cb1 += 128;
cb1 = cb2 + 128;
cb1 = 128 + cb2;
#if !defined(BOOST_ASIO_NO_DEPRECATED)
// const_buffers_1 constructors.
const_buffers_1 cbc1(cb1);
const_buffers_1 cbc2(cbc1);
// const_buffers_1 functions.
const_buffers_1::const_iterator iter3 = cbc1.begin();
(void)iter3;
const_buffers_1::const_iterator iter4 = cbc1.end();
(void)iter4;
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
// buffer_size function overloads.
std::size_t size1 = buffer_size(mb1);
(void)size1;
std::size_t size2 = buffer_size(cb1);
(void)size2;
#if !defined(BOOST_ASIO_NO_DEPRECATED)
std::size_t size3 = buffer_size(mbc1);
(void)size3;
std::size_t size4 = buffer_size(cbc1);
(void)size4;
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
std::size_t size5 = buffer_size(mutable_buffer_sequence);
(void)size5;
std::size_t size6 = buffer_size(const_buffer_sequence);
(void)size6;
// buffer_cast function overloads.
#if !defined(BOOST_ASIO_NO_DEPRECATED)
void* ptr3 = buffer_cast<void*>(mb1);
(void)ptr3;
const void* ptr4 = buffer_cast<const void*>(cb1);
(void)ptr4;
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
// buffer function overloads.
mb1 = buffer(mb2);
mb1 = buffer(mb2, 128);
cb1 = buffer(cb2);
cb1 = buffer(cb2, 128);
mb1 = buffer(void_ptr_data, 1024);
cb1 = buffer(const_void_ptr_data, 1024);
mb1 = buffer(raw_data);
mb1 = buffer(raw_data, 1024);
cb1 = buffer(const_raw_data);
cb1 = buffer(const_raw_data, 1024);
#if defined(BOOST_ASIO_HAS_BOOST_ARRAY)
mb1 = buffer(array_data);
mb1 = buffer(array_data, 1024);
cb1 = buffer(const_array_data_1);
cb1 = buffer(const_array_data_1, 1024);
cb1 = buffer(const_array_data_2);
cb1 = buffer(const_array_data_2, 1024);
#endif // defined(BOOST_ASIO_HAS_BOOST_ARRAY)
#if defined(BOOST_ASIO_HAS_STD_ARRAY)
mb1 = buffer(std_array_data);
mb1 = buffer(std_array_data, 1024);
cb1 = buffer(const_std_array_data_1);
cb1 = buffer(const_std_array_data_1, 1024);
cb1 = buffer(const_std_array_data_2);
cb1 = buffer(const_std_array_data_2, 1024);
#endif // defined(BOOST_ASIO_HAS_STD_ARRAY)
mb1 = buffer(vector_data);
mb1 = buffer(vector_data, 1024);
cb1 = buffer(const_vector_data);
cb1 = buffer(const_vector_data, 1024);
mb1 = buffer(string_data);
mb1 = buffer(string_data, 1024);
cb1 = buffer(const_string_data);
cb1 = buffer(const_string_data, 1024);
#if defined(BOOST_ASIO_HAS_STRING_VIEW)
cb1 = buffer(string_view_data);
cb1 = buffer(string_view_data, 1024);
#endif // defined(BOOST_ASIO_HAS_STRING_VIEW)
// buffer_copy function overloads.
std::size_t size7 = buffer_copy(mb1, cb2);
(void)size7;
#if !defined(BOOST_ASIO_NO_DEPRECATED)
std::size_t size8 = buffer_copy(mb1, cbc2);
(void)size8;
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
std::size_t size9 = buffer_copy(mb1, mb2);
(void)size9;
#if !defined(BOOST_ASIO_NO_DEPRECATED)
std::size_t size10 = buffer_copy(mb1, mbc2);
(void)size10;
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
std::size_t size11 = buffer_copy(mb1, const_buffer_sequence);
(void)size11;
#if !defined(BOOST_ASIO_NO_DEPRECATED)
std::size_t size12 = buffer_copy(mbc1, cb2);
(void)size12;
std::size_t size13 = buffer_copy(mbc1, cbc2);
(void)size13;
std::size_t size14 = buffer_copy(mbc1, mb2);
(void)size14;
std::size_t size15 = buffer_copy(mbc1, mbc2);
(void)size15;
std::size_t size16 = buffer_copy(mbc1, const_buffer_sequence);
(void)size16;
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
std::size_t size17 = buffer_copy(mutable_buffer_sequence, cb2);
(void)size17;
#if !defined(BOOST_ASIO_NO_DEPRECATED)
std::size_t size18 = buffer_copy(mutable_buffer_sequence, cbc2);
(void)size18;
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
std::size_t size19 = buffer_copy(mutable_buffer_sequence, mb2);
(void)size19;
#if !defined(BOOST_ASIO_NO_DEPRECATED)
std::size_t size20 = buffer_copy(mutable_buffer_sequence, mbc2);
(void)size20;
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
std::size_t size21 = buffer_copy(
mutable_buffer_sequence, const_buffer_sequence);
(void)size21;
std::size_t size22 = buffer_copy(mb1, cb2, 128);
(void)size22;
#if !defined(BOOST_ASIO_NO_DEPRECATED)
std::size_t size23 = buffer_copy(mb1, cbc2, 128);
(void)size23;
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
std::size_t size24 = buffer_copy(mb1, mb2, 128);
(void)size24;
#if !defined(BOOST_ASIO_NO_DEPRECATED)
std::size_t size25 = buffer_copy(mb1, mbc2, 128);
(void)size25;
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
std::size_t size26 = buffer_copy(mb1, const_buffer_sequence, 128);
(void)size26;
#if !defined(BOOST_ASIO_NO_DEPRECATED)
std::size_t size27 = buffer_copy(mbc1, cb2, 128);
(void)size27;
std::size_t size28 = buffer_copy(mbc1, cbc2, 128);
(void)size28;
std::size_t size29 = buffer_copy(mbc1, mb2, 128);
(void)size29;
std::size_t size30 = buffer_copy(mbc1, mbc2, 128);
(void)size30;
std::size_t size31 = buffer_copy(mbc1, const_buffer_sequence, 128);
(void)size31;
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
std::size_t size32 = buffer_copy(mutable_buffer_sequence, cb2, 128);
(void)size32;
#if !defined(BOOST_ASIO_NO_DEPRECATED)
std::size_t size33 = buffer_copy(mutable_buffer_sequence, cbc2, 128);
(void)size33;
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
std::size_t size34 = buffer_copy(mutable_buffer_sequence, mb2, 128);
(void)size34;
#if !defined(BOOST_ASIO_NO_DEPRECATED)
std::size_t size35 = buffer_copy(mutable_buffer_sequence, mbc2, 128);
(void)size35;
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
std::size_t size36 = buffer_copy(
mutable_buffer_sequence, const_buffer_sequence, 128);
(void)size36;
// dynamic_buffer function overloads.
dynamic_string_buffer<char, std::string::traits_type,
std::string::allocator_type> db1 = dynamic_buffer(string_data);
(void)db1;
dynamic_string_buffer<char, std::string::traits_type,
std::string::allocator_type> db2 = dynamic_buffer(string_data, 1024);
(void)db2;
dynamic_vector_buffer<char, std::allocator<char> >
db3 = dynamic_buffer(vector_data);
(void)db3;
dynamic_vector_buffer<char, std::allocator<char> >
db4 = dynamic_buffer(vector_data, 1024);
(void)db4;
// dynamic_buffer member functions.
std::size_t size37 = db1.size();
(void)size37;
std::size_t size38 = db3.size();
(void)size38;
std::size_t size39 = db1.max_size();
(void)size39;
std::size_t size40 = db3.max_size();
(void)size40;
#if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
dynamic_string_buffer<char, std::string::traits_type,
std::string::allocator_type>::const_buffers_type
cb5 = db1.data();
(void)cb5;
dynamic_vector_buffer<char, std::allocator<char> >::const_buffers_type
cb6 = db3.data();
(void)cb6;
dynamic_string_buffer<char, std::string::traits_type,
std::string::allocator_type>::mutable_buffers_type mb5
= db1.prepare(1024);
(void)mb5;
dynamic_vector_buffer<char, std::allocator<char> >::mutable_buffers_type
mb6 = db3.prepare(1024);
(void)mb6;
db1.commit(1024);
db3.commit(1024);
#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
dynamic_string_buffer<char, std::string::traits_type,
std::string::allocator_type>::mutable_buffers_type
mb7 = db1.data(0, 1);
(void)mb7;
dynamic_vector_buffer<char, std::allocator<char> >::mutable_buffers_type
mb8 = db3.data(0, 1);
(void)mb8;
dynamic_string_buffer<char, std::string::traits_type,
std::string::allocator_type>::const_buffers_type
cb7 = static_cast<const dynamic_string_buffer<char,
std::string::traits_type,
std::string::allocator_type>&>(db1).data(0, 1);
(void)cb7;
dynamic_vector_buffer<char, std::allocator<char> >::const_buffers_type
cb8 = static_cast<const dynamic_vector_buffer<char,
std::allocator<char> >&>(db3).data(0, 1);
(void)cb8;
db1.grow(1024);
db3.grow(1024);
db1.shrink(1024);
db3.shrink(1024);
db1.consume(0);
db3.consume(0);
}
catch (std::exception&)
{
}
}
} // namespace buffer_compile
//------------------------------------------------------------------------------
namespace buffer_copy_runtime {
using namespace boost::asio;
using namespace std;
void test()
{
char dest_data[256];
char source_data[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
memset(dest_data, 0, sizeof(dest_data));
mutable_buffer mb1 = boost::asio::buffer(dest_data);
mutable_buffer mb2 = boost::asio::buffer(source_data);
std::size_t n = buffer_copy(mb1, mb2);
BOOST_ASIO_CHECK(n == sizeof(source_data));
BOOST_ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
memset(dest_data, 0, sizeof(dest_data));
mb1 = boost::asio::buffer(dest_data);
const_buffer cb1 = boost::asio::buffer(source_data);
n = buffer_copy(mb1, cb1);
BOOST_ASIO_CHECK(n == sizeof(source_data));
BOOST_ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
#if !defined(BOOST_ASIO_NO_DEPRECATED)
memset(dest_data, 0, sizeof(dest_data));
mb1 = boost::asio::buffer(dest_data);
mutable_buffers_1 mbc1 = boost::asio::buffer(source_data);
n = buffer_copy(mb1, mbc1);
BOOST_ASIO_CHECK(n == sizeof(source_data));
BOOST_ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
memset(dest_data, 0, sizeof(dest_data));
mb1 = boost::asio::buffer(dest_data);
const_buffers_1 cbc1 = const_buffers_1(boost::asio::buffer(source_data));
n = buffer_copy(mb1, cbc1);
BOOST_ASIO_CHECK(n == sizeof(source_data));
BOOST_ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
memset(dest_data, 0, sizeof(dest_data));
mbc1 = boost::asio::buffer(dest_data);
mb1 = boost::asio::buffer(source_data);
n = buffer_copy(mbc1, mb1);
BOOST_ASIO_CHECK(n == sizeof(source_data));
BOOST_ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
memset(dest_data, 0, sizeof(dest_data));
mbc1 = boost::asio::buffer(dest_data);
cb1 = boost::asio::buffer(source_data);
n = buffer_copy(mbc1, cb1);
BOOST_ASIO_CHECK(n == sizeof(source_data));
BOOST_ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
memset(dest_data, 0, sizeof(dest_data));
mbc1 = boost::asio::buffer(dest_data);
mutable_buffers_1 mbc2 = boost::asio::buffer(source_data);
n = buffer_copy(mbc1, mbc2);
BOOST_ASIO_CHECK(n == sizeof(source_data));
BOOST_ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
memset(dest_data, 0, sizeof(dest_data));
mbc1 = boost::asio::buffer(dest_data);
cbc1 = const_buffers_1(boost::asio::buffer(source_data));
n = buffer_copy(mbc1, cbc1);
BOOST_ASIO_CHECK(n == sizeof(source_data));
BOOST_ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
memset(dest_data, 0, sizeof(dest_data));
mb1 = boost::asio::buffer(dest_data);
std::vector<mutable_buffer> mv1;
mv1.push_back(boost::asio::buffer(source_data, 5));
mv1.push_back(boost::asio::buffer(source_data) + 5);
n = buffer_copy(mb1, mv1);
BOOST_ASIO_CHECK(n == sizeof(source_data));
BOOST_ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
memset(dest_data, 0, sizeof(dest_data));
mb1 = boost::asio::buffer(dest_data);
std::vector<const_buffer> cv1;
cv1.push_back(boost::asio::buffer(source_data, 6));
cv1.push_back(boost::asio::buffer(source_data) + 6);
n = buffer_copy(mb1, cv1);
BOOST_ASIO_CHECK(n == sizeof(source_data));
BOOST_ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
memset(dest_data, 0, sizeof(dest_data));
mv1.clear();
mv1.push_back(boost::asio::buffer(dest_data, 7));
mv1.push_back(boost::asio::buffer(dest_data) + 7);
cb1 = boost::asio::buffer(source_data);
n = buffer_copy(mv1, cb1);
BOOST_ASIO_CHECK(n == sizeof(source_data));
BOOST_ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
memset(dest_data, 0, sizeof(dest_data));
mv1.clear();
mv1.push_back(boost::asio::buffer(dest_data, 7));
mv1.push_back(boost::asio::buffer(dest_data) + 7);
cv1.clear();
cv1.push_back(boost::asio::buffer(source_data, 8));
cv1.push_back(boost::asio::buffer(source_data) + 8);
n = buffer_copy(mv1, cv1);
BOOST_ASIO_CHECK(n == sizeof(source_data));
BOOST_ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
memset(dest_data, 0, sizeof(dest_data));
mb1 = boost::asio::buffer(dest_data);
mb2 = boost::asio::buffer(source_data);
n = buffer_copy(mb1, mb2, 10);
BOOST_ASIO_CHECK(n == 10);
BOOST_ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
memset(dest_data, 0, sizeof(dest_data));
mb1 = boost::asio::buffer(dest_data);
cb1 = boost::asio::buffer(source_data);
n = buffer_copy(mb1, cb1, 10);
BOOST_ASIO_CHECK(n == 10);
BOOST_ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
#if !defined(BOOST_ASIO_NO_DEPRECATED)
memset(dest_data, 0, sizeof(dest_data));
mb1 = boost::asio::buffer(dest_data);
mbc1 = boost::asio::buffer(source_data);
n = buffer_copy(mb1, mbc1, 10);
BOOST_ASIO_CHECK(n == 10);
BOOST_ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
memset(dest_data, 0, sizeof(dest_data));
mb1 = boost::asio::buffer(dest_data);
cbc1 = const_buffers_1(boost::asio::buffer(source_data));
n = buffer_copy(mb1, cbc1, 10);
BOOST_ASIO_CHECK(n == 10);
BOOST_ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
memset(dest_data, 0, sizeof(dest_data));
mbc1 = boost::asio::buffer(dest_data);
mb1 = boost::asio::buffer(source_data);
n = buffer_copy(mbc1, mb1, 10);
BOOST_ASIO_CHECK(n == 10);
BOOST_ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
memset(dest_data, 0, sizeof(dest_data));
mbc1 = boost::asio::buffer(dest_data);
cb1 = boost::asio::buffer(source_data);
n = buffer_copy(mbc1, cb1, 10);
BOOST_ASIO_CHECK(n == 10);
BOOST_ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
memset(dest_data, 0, sizeof(dest_data));
mbc1 = boost::asio::buffer(dest_data);
mbc2 = boost::asio::buffer(source_data);
n = buffer_copy(mbc1, mbc2, 10);
BOOST_ASIO_CHECK(n == 10);
BOOST_ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
memset(dest_data, 0, sizeof(dest_data));
mbc1 = boost::asio::buffer(dest_data);
cbc1 = const_buffers_1(boost::asio::buffer(source_data));
n = buffer_copy(mbc1, cbc1, 10);
BOOST_ASIO_CHECK(n == 10);
BOOST_ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
memset(dest_data, 0, sizeof(dest_data));
mb1 = boost::asio::buffer(dest_data);
mv1.clear();
mv1.push_back(boost::asio::buffer(source_data, 5));
mv1.push_back(boost::asio::buffer(source_data) + 5);
n = buffer_copy(mb1, mv1, 10);
BOOST_ASIO_CHECK(n == 10);
BOOST_ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
memset(dest_data, 0, sizeof(dest_data));
mb1 = boost::asio::buffer(dest_data);
cv1.clear();
cv1.push_back(boost::asio::buffer(source_data, 6));
cv1.push_back(boost::asio::buffer(source_data) + 6);
n = buffer_copy(mb1, cv1, 10);
BOOST_ASIO_CHECK(n == 10);
BOOST_ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
memset(dest_data, 0, sizeof(dest_data));
mv1.clear();
mv1.push_back(boost::asio::buffer(dest_data, 7));
mv1.push_back(boost::asio::buffer(dest_data) + 7);
cb1 = boost::asio::buffer(source_data);
n = buffer_copy(mv1, cb1, 10);
BOOST_ASIO_CHECK(n == 10);
BOOST_ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
memset(dest_data, 0, sizeof(dest_data));
mv1.clear();
mv1.push_back(boost::asio::buffer(dest_data, 7));
mv1.push_back(boost::asio::buffer(dest_data) + 7);
cv1.clear();
cv1.push_back(boost::asio::buffer(source_data, 8));
cv1.push_back(boost::asio::buffer(source_data) + 8);
n = buffer_copy(mv1, cv1, 10);
BOOST_ASIO_CHECK(n == 10);
BOOST_ASIO_CHECK(memcmp(dest_data, source_data, n) == 0);
}
} // namespace buffer_copy_runtime
//------------------------------------------------------------------------------
namespace buffer_sequence {
using namespace boost::asio;
using namespace std;
struct valid_const_a
{
typedef const_buffer* const_iterator;
typedef const_buffer value_type;
const_buffer* begin() const { return 0; }
const_buffer* end() const { return 0; }
};
#if defined(BOOST_ASIO_HAS_DECLTYPE)
struct valid_const_b
{
const_buffer* begin() const { return 0; }
const_buffer* end() const { return 0; }
};
#endif // defined(BOOST_ASIO_HAS_DECLTYPE)
struct valid_mutable_a
{
typedef mutable_buffer* const_iterator;
typedef mutable_buffer value_type;
mutable_buffer* begin() const { return 0; }
mutable_buffer* end() const { return 0; }
};
#if defined(BOOST_ASIO_HAS_DECLTYPE)
struct valid_mutable_b
{
mutable_buffer* begin() const { return 0; }
mutable_buffer* end() const { return 0; }
};
#endif // defined(BOOST_ASIO_HAS_DECLTYPE)
struct invalid_const_a
{
typedef int value_type;
int* begin() const { return 0; }
const_buffer* end() const { return 0; }
};
struct invalid_const_b
{
typedef const_buffer value_type;
const_buffer* begin() const { return 0; }
};
struct invalid_const_c
{
typedef const_buffer value_type;
const_buffer* end() const { return 0; }
};
#if defined(BOOST_ASIO_HAS_DECLTYPE)
struct invalid_const_d
{
int* begin() const { return 0; }
const_buffer* end() const { return 0; }
};
struct invalid_const_e
{
const_buffer* begin() const { return 0; }
};
struct invalid_const_f
{
const_buffer* end() const { return 0; }
};
#endif // defined(BOOST_ASIO_HAS_DECLTYPE)
struct invalid_mutable_a
{
typedef int value_type;
int* begin() const { return 0; }
mutable_buffer* end() const { return 0; }
};
struct invalid_mutable_b
{
typedef mutable_buffer value_type;
mutable_buffer* begin() const { return 0; }
};
struct invalid_mutable_c
{
typedef mutable_buffer value_type;
mutable_buffer* end() const { return 0; }
};
#if defined(BOOST_ASIO_HAS_DECLTYPE)
struct invalid_mutable_d
{
int* begin() const { return 0; }
mutable_buffer* end() const { return 0; }
};
struct invalid_mutable_e
{
mutable_buffer* begin() const { return 0; }
};
struct invalid_mutable_f
{
mutable_buffer* end() const { return 0; }
};
#endif // defined(BOOST_ASIO_HAS_DECLTYPE)
void test()
{
BOOST_ASIO_CHECK(is_const_buffer_sequence<const_buffer>::value);
BOOST_ASIO_CHECK(!is_mutable_buffer_sequence<const_buffer>::value);
const_buffer b1;
BOOST_ASIO_CHECK(buffer_sequence_begin(b1) == &b1);
BOOST_ASIO_CHECK(buffer_sequence_end(b1) == &b1 + 1);
BOOST_ASIO_CHECK(is_const_buffer_sequence<mutable_buffer>::value);
BOOST_ASIO_CHECK(is_mutable_buffer_sequence<mutable_buffer>::value);
mutable_buffer b2;
BOOST_ASIO_CHECK(buffer_sequence_begin(b2) == &b2);
BOOST_ASIO_CHECK(buffer_sequence_end(b2) == &b2 + 1);
#if !defined(BOOST_ASIO_NO_DEPRECATED)
BOOST_ASIO_CHECK(is_const_buffer_sequence<const_buffers_1>::value);
BOOST_ASIO_CHECK(!is_mutable_buffer_sequence<const_buffers_1>::value);
const_buffers_1 b3(0, 0);
BOOST_ASIO_CHECK(buffer_sequence_begin(b3) == &b3);
BOOST_ASIO_CHECK(buffer_sequence_end(b3) == &b3 + 1);
BOOST_ASIO_CHECK(is_const_buffer_sequence<mutable_buffers_1>::value);
BOOST_ASIO_CHECK(is_mutable_buffer_sequence<mutable_buffers_1>::value);
mutable_buffers_1 b4(0, 0);
BOOST_ASIO_CHECK(buffer_sequence_begin(b4) == &b4);
BOOST_ASIO_CHECK(buffer_sequence_end(b4) == &b4 + 1);
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
BOOST_ASIO_CHECK(is_const_buffer_sequence<vector<const_buffer> >::value);
BOOST_ASIO_CHECK(!is_mutable_buffer_sequence<vector<const_buffer> >::value);
vector<const_buffer> b5;
BOOST_ASIO_CHECK(buffer_sequence_begin(b5) == b5.begin());
BOOST_ASIO_CHECK(buffer_sequence_end(b5) == b5.end());
BOOST_ASIO_CHECK(is_const_buffer_sequence<vector<mutable_buffer> >::value);
BOOST_ASIO_CHECK(is_mutable_buffer_sequence<vector<mutable_buffer> >::value);
vector<mutable_buffer> b6;
BOOST_ASIO_CHECK(buffer_sequence_begin(b6) == b6.begin());
BOOST_ASIO_CHECK(buffer_sequence_end(b6) == b6.end());
BOOST_ASIO_CHECK(is_const_buffer_sequence<valid_const_a>::value);
BOOST_ASIO_CHECK(!is_mutable_buffer_sequence<valid_const_a>::value);
valid_const_a b7;
BOOST_ASIO_CHECK(buffer_sequence_begin(b7) == b7.begin());
BOOST_ASIO_CHECK(buffer_sequence_end(b7) == b7.end());
#if defined(BOOST_ASIO_HAS_DECLTYPE)
BOOST_ASIO_CHECK(is_const_buffer_sequence<valid_const_b>::value);
BOOST_ASIO_CHECK(!is_mutable_buffer_sequence<valid_const_b>::value);
valid_const_b b8;
BOOST_ASIO_CHECK(buffer_sequence_begin(b8) == b8.begin());
BOOST_ASIO_CHECK(buffer_sequence_end(b8) == b8.end());
#endif // defined(BOOST_ASIO_HAS_DECLTYPE)
BOOST_ASIO_CHECK(is_const_buffer_sequence<valid_mutable_a>::value);
BOOST_ASIO_CHECK(is_mutable_buffer_sequence<valid_mutable_a>::value);
valid_mutable_a b9;
BOOST_ASIO_CHECK(buffer_sequence_begin(b9) == b9.begin());
BOOST_ASIO_CHECK(buffer_sequence_end(b9) == b9.end());
#if defined(BOOST_ASIO_HAS_DECLTYPE)
BOOST_ASIO_CHECK(is_const_buffer_sequence<valid_mutable_b>::value);
BOOST_ASIO_CHECK(is_mutable_buffer_sequence<valid_mutable_b>::value);
valid_mutable_b b10;
BOOST_ASIO_CHECK(buffer_sequence_begin(b10) == b10.begin());
BOOST_ASIO_CHECK(buffer_sequence_end(b10) == b10.end());
#endif // defined(BOOST_ASIO_HAS_DECLTYPE)
BOOST_ASIO_CHECK(!is_const_buffer_sequence<invalid_const_a>::value);
BOOST_ASIO_CHECK(!is_mutable_buffer_sequence<invalid_const_a>::value);
BOOST_ASIO_CHECK(!is_const_buffer_sequence<invalid_const_b>::value);
BOOST_ASIO_CHECK(!is_mutable_buffer_sequence<invalid_const_b>::value);
BOOST_ASIO_CHECK(!is_const_buffer_sequence<invalid_const_c>::value);
BOOST_ASIO_CHECK(!is_mutable_buffer_sequence<invalid_const_c>::value);
#if defined(BOOST_ASIO_HAS_DECLTYPE)
BOOST_ASIO_CHECK(!is_const_buffer_sequence<invalid_const_d>::value);
BOOST_ASIO_CHECK(!is_mutable_buffer_sequence<invalid_const_d>::value);
BOOST_ASIO_CHECK(!is_const_buffer_sequence<invalid_const_e>::value);
BOOST_ASIO_CHECK(!is_mutable_buffer_sequence<invalid_const_e>::value);
BOOST_ASIO_CHECK(!is_const_buffer_sequence<invalid_const_f>::value);
BOOST_ASIO_CHECK(!is_mutable_buffer_sequence<invalid_const_f>::value);
#endif // defined(BOOST_ASIO_HAS_DECLTYPE)
BOOST_ASIO_CHECK(!is_mutable_buffer_sequence<invalid_mutable_a>::value);
BOOST_ASIO_CHECK(!is_mutable_buffer_sequence<invalid_mutable_a>::value);
BOOST_ASIO_CHECK(!is_mutable_buffer_sequence<invalid_mutable_b>::value);
BOOST_ASIO_CHECK(!is_mutable_buffer_sequence<invalid_mutable_b>::value);
BOOST_ASIO_CHECK(!is_mutable_buffer_sequence<invalid_mutable_c>::value);
BOOST_ASIO_CHECK(!is_mutable_buffer_sequence<invalid_mutable_c>::value);
#if defined(BOOST_ASIO_HAS_DECLTYPE)
BOOST_ASIO_CHECK(!is_mutable_buffer_sequence<invalid_mutable_d>::value);
BOOST_ASIO_CHECK(!is_mutable_buffer_sequence<invalid_mutable_d>::value);
BOOST_ASIO_CHECK(!is_mutable_buffer_sequence<invalid_mutable_e>::value);
BOOST_ASIO_CHECK(!is_mutable_buffer_sequence<invalid_mutable_e>::value);
BOOST_ASIO_CHECK(!is_mutable_buffer_sequence<invalid_mutable_f>::value);
BOOST_ASIO_CHECK(!is_mutable_buffer_sequence<invalid_mutable_f>::value);
#endif // defined(BOOST_ASIO_HAS_DECLTYPE)
}
} // namespace buffer_sequence
//------------------------------------------------------------------------------
BOOST_ASIO_TEST_SUITE
(
"buffer",
BOOST_ASIO_COMPILE_TEST_CASE(buffer_compile::test)
BOOST_ASIO_TEST_CASE(buffer_copy_runtime::test)
BOOST_ASIO_TEST_CASE(buffer_sequence::test)
)

View File

@@ -0,0 +1,25 @@
//
// buffer_registration.cpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/buffer_registration.hpp>
#include "unit_test.hpp"
BOOST_ASIO_TEST_SUITE
(
"buffer_registration",
BOOST_ASIO_TEST_CASE(null_test)
)

View File

@@ -0,0 +1,338 @@
//
// buffered_read_stream.cpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/buffered_read_stream.hpp>
#include <cstring>
#include "archetypes/async_result.hpp"
#include <boost/asio/buffer.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <boost/system/system_error.hpp>
#include "unit_test.hpp"
#if defined(BOOST_ASIO_HAS_BOOST_ARRAY)
# include <boost/array.hpp>
#else // defined(BOOST_ASIO_HAS_BOOST_ARRAY)
# include <array>
#endif // defined(BOOST_ASIO_HAS_BOOST_ARRAY)
#if defined(BOOST_ASIO_HAS_BOOST_BIND)
# include <boost/bind/bind.hpp>
#else // defined(BOOST_ASIO_HAS_BOOST_BIND)
# include <functional>
#endif // defined(BOOST_ASIO_HAS_BOOST_BIND)
typedef boost::asio::buffered_read_stream<
boost::asio::ip::tcp::socket> stream_type;
void write_some_handler(const boost::system::error_code&, std::size_t)
{
}
void fill_handler(const boost::system::error_code&, std::size_t)
{
}
void read_some_handler(const boost::system::error_code&, std::size_t)
{
}
void test_compile()
{
#if defined(BOOST_ASIO_HAS_BOOST_ARRAY)
using boost::array;
#else // defined(BOOST_ASIO_HAS_BOOST_ARRAY)
using std::array;
#endif // defined(BOOST_ASIO_HAS_BOOST_ARRAY)
using namespace boost::asio;
try
{
io_context ioc;
char mutable_char_buffer[128] = "";
const char const_char_buffer[128] = "";
array<boost::asio::mutable_buffer, 2> mutable_buffers = {{
boost::asio::buffer(mutable_char_buffer, 10),
boost::asio::buffer(mutable_char_buffer + 10, 10) }};
array<boost::asio::const_buffer, 2> const_buffers = {{
boost::asio::buffer(const_char_buffer, 10),
boost::asio::buffer(const_char_buffer + 10, 10) }};
archetypes::lazy_handler lazy;
boost::system::error_code ec;
stream_type stream1(ioc);
stream_type stream2(ioc, 1024);
stream_type::executor_type ex = stream1.get_executor();
(void)ex;
stream_type::lowest_layer_type& lowest_layer = stream1.lowest_layer();
(void)lowest_layer;
stream1.write_some(buffer(mutable_char_buffer));
stream1.write_some(buffer(const_char_buffer));
stream1.write_some(mutable_buffers);
stream1.write_some(const_buffers);
stream1.write_some(null_buffers());
stream1.write_some(buffer(mutable_char_buffer), ec);
stream1.write_some(buffer(const_char_buffer), ec);
stream1.write_some(mutable_buffers, ec);
stream1.write_some(const_buffers, ec);
stream1.write_some(null_buffers(), ec);
stream1.async_write_some(buffer(mutable_char_buffer), &write_some_handler);
stream1.async_write_some(buffer(const_char_buffer), &write_some_handler);
stream1.async_write_some(mutable_buffers, &write_some_handler);
stream1.async_write_some(const_buffers, &write_some_handler);
stream1.async_write_some(null_buffers(), &write_some_handler);
int i1 = stream1.async_write_some(buffer(mutable_char_buffer), lazy);
(void)i1;
int i2 = stream1.async_write_some(buffer(const_char_buffer), lazy);
(void)i2;
int i3 = stream1.async_write_some(mutable_buffers, lazy);
(void)i3;
int i4 = stream1.async_write_some(const_buffers, lazy);
(void)i4;
int i5 = stream1.async_write_some(null_buffers(), lazy);
(void)i5;
stream1.fill();
stream1.fill(ec);
stream1.async_fill(&fill_handler);
int i6 = stream1.async_fill(lazy);
(void)i6;
stream1.read_some(buffer(mutable_char_buffer));
stream1.read_some(mutable_buffers);
stream1.read_some(null_buffers());
stream1.read_some(buffer(mutable_char_buffer), ec);
stream1.read_some(mutable_buffers, ec);
stream1.read_some(null_buffers(), ec);
stream1.async_read_some(buffer(mutable_char_buffer), &read_some_handler);
stream1.async_read_some(mutable_buffers, &read_some_handler);
stream1.async_read_some(null_buffers(), &read_some_handler);
int i7 = stream1.async_read_some(buffer(mutable_char_buffer), lazy);
(void)i7;
int i8 = stream1.async_read_some(mutable_buffers, lazy);
(void)i8;
int i9 = stream1.async_read_some(null_buffers(), lazy);
(void)i9;
}
catch (std::exception&)
{
}
}
void test_sync_operations()
{
using namespace std; // For memcmp.
boost::asio::io_context io_context;
boost::asio::ip::tcp::acceptor acceptor(io_context,
boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), 0));
boost::asio::ip::tcp::endpoint server_endpoint = acceptor.local_endpoint();
server_endpoint.address(boost::asio::ip::address_v4::loopback());
stream_type client_socket(io_context);
client_socket.lowest_layer().connect(server_endpoint);
stream_type server_socket(io_context);
acceptor.accept(server_socket.lowest_layer());
const char write_data[]
= "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
const boost::asio::const_buffer write_buf = boost::asio::buffer(write_data);
std::size_t bytes_written = 0;
while (bytes_written < sizeof(write_data))
{
bytes_written += client_socket.write_some(
boost::asio::buffer(write_buf + bytes_written));
}
char read_data[sizeof(write_data)];
const boost::asio::mutable_buffer read_buf = boost::asio::buffer(read_data);
std::size_t bytes_read = 0;
while (bytes_read < sizeof(read_data))
{
bytes_read += server_socket.read_some(
boost::asio::buffer(read_buf + bytes_read));
}
BOOST_ASIO_CHECK(bytes_written == sizeof(write_data));
BOOST_ASIO_CHECK(bytes_read == sizeof(read_data));
BOOST_ASIO_CHECK(memcmp(write_data, read_data, sizeof(write_data)) == 0);
bytes_written = 0;
while (bytes_written < sizeof(write_data))
{
bytes_written += server_socket.write_some(
boost::asio::buffer(write_buf + bytes_written));
}
bytes_read = 0;
while (bytes_read < sizeof(read_data))
{
bytes_read += client_socket.read_some(
boost::asio::buffer(read_buf + bytes_read));
}
BOOST_ASIO_CHECK(bytes_written == sizeof(write_data));
BOOST_ASIO_CHECK(bytes_read == sizeof(read_data));
BOOST_ASIO_CHECK(memcmp(write_data, read_data, sizeof(write_data)) == 0);
server_socket.close();
boost::system::error_code error;
bytes_read = client_socket.read_some(
boost::asio::buffer(read_buf), error);
BOOST_ASIO_CHECK(bytes_read == 0);
BOOST_ASIO_CHECK(error == boost::asio::error::eof);
client_socket.close(error);
}
void handle_accept(const boost::system::error_code& e)
{
BOOST_ASIO_CHECK(!e);
}
void handle_write(const boost::system::error_code& e,
std::size_t bytes_transferred,
std::size_t* total_bytes_written)
{
BOOST_ASIO_CHECK(!e);
if (e)
throw boost::system::system_error(e); // Terminate test.
*total_bytes_written += bytes_transferred;
}
void handle_read(const boost::system::error_code& e,
std::size_t bytes_transferred,
std::size_t* total_bytes_read)
{
BOOST_ASIO_CHECK(!e);
if (e)
throw boost::system::system_error(e); // Terminate test.
*total_bytes_read += bytes_transferred;
}
void handle_read_eof(const boost::system::error_code& e,
std::size_t bytes_transferred)
{
BOOST_ASIO_CHECK(e == boost::asio::error::eof);
BOOST_ASIO_CHECK(bytes_transferred == 0);
}
void test_async_operations()
{
using namespace std; // For memcmp.
#if defined(BOOST_ASIO_HAS_BOOST_BIND)
namespace bindns = boost;
#else // defined(BOOST_ASIO_HAS_BOOST_BIND)
namespace bindns = std;
#endif // defined(BOOST_ASIO_HAS_BOOST_BIND)
using bindns::placeholders::_1;
using bindns::placeholders::_2;
boost::asio::io_context io_context;
boost::asio::ip::tcp::acceptor acceptor(io_context,
boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), 0));
boost::asio::ip::tcp::endpoint server_endpoint = acceptor.local_endpoint();
server_endpoint.address(boost::asio::ip::address_v4::loopback());
stream_type client_socket(io_context);
client_socket.lowest_layer().connect(server_endpoint);
stream_type server_socket(io_context);
acceptor.async_accept(server_socket.lowest_layer(), &handle_accept);
io_context.run();
io_context.restart();
const char write_data[]
= "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
const boost::asio::const_buffer write_buf = boost::asio::buffer(write_data);
std::size_t bytes_written = 0;
while (bytes_written < sizeof(write_data))
{
client_socket.async_write_some(
boost::asio::buffer(write_buf + bytes_written),
bindns::bind(handle_write, _1, _2, &bytes_written));
io_context.run();
io_context.restart();
}
char read_data[sizeof(write_data)];
const boost::asio::mutable_buffer read_buf = boost::asio::buffer(read_data);
std::size_t bytes_read = 0;
while (bytes_read < sizeof(read_data))
{
server_socket.async_read_some(
boost::asio::buffer(read_buf + bytes_read),
bindns::bind(handle_read, _1, _2, &bytes_read));
io_context.run();
io_context.restart();
}
BOOST_ASIO_CHECK(bytes_written == sizeof(write_data));
BOOST_ASIO_CHECK(bytes_read == sizeof(read_data));
BOOST_ASIO_CHECK(memcmp(write_data, read_data, sizeof(write_data)) == 0);
bytes_written = 0;
while (bytes_written < sizeof(write_data))
{
server_socket.async_write_some(
boost::asio::buffer(write_buf + bytes_written),
bindns::bind(handle_write, _1, _2, &bytes_written));
io_context.run();
io_context.restart();
}
bytes_read = 0;
while (bytes_read < sizeof(read_data))
{
client_socket.async_read_some(
boost::asio::buffer(read_buf + bytes_read),
bindns::bind(handle_read, _1, _2, &bytes_read));
io_context.run();
io_context.restart();
}
BOOST_ASIO_CHECK(bytes_written == sizeof(write_data));
BOOST_ASIO_CHECK(bytes_read == sizeof(read_data));
BOOST_ASIO_CHECK(memcmp(write_data, read_data, sizeof(write_data)) == 0);
server_socket.close();
client_socket.async_read_some(boost::asio::buffer(read_buf), handle_read_eof);
}
BOOST_ASIO_TEST_SUITE
(
"buffered_read_stream",
BOOST_ASIO_TEST_CASE(test_compile)
BOOST_ASIO_TEST_CASE(test_sync_operations)
BOOST_ASIO_TEST_CASE(test_async_operations)
)

View File

@@ -0,0 +1,364 @@
//
// buffered_stream.cpp
// ~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/buffered_stream.hpp>
#include <cstring>
#include "archetypes/async_result.hpp"
#include <boost/asio/buffer.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <boost/system/system_error.hpp>
#include "unit_test.hpp"
#if defined(BOOST_ASIO_HAS_BOOST_ARRAY)
# include <boost/array.hpp>
#else // defined(BOOST_ASIO_HAS_BOOST_ARRAY)
# include <array>
#endif // defined(BOOST_ASIO_HAS_BOOST_ARRAY)
#if defined(BOOST_ASIO_HAS_BOOST_BIND)
# include <boost/bind/bind.hpp>
#else // defined(BOOST_ASIO_HAS_BOOST_BIND)
# include <functional>
#endif // defined(BOOST_ASIO_HAS_BOOST_BIND)
typedef boost::asio::buffered_stream<
boost::asio::ip::tcp::socket> stream_type;
void write_some_handler(const boost::system::error_code&, std::size_t)
{
}
void flush_handler(const boost::system::error_code&, std::size_t)
{
}
void fill_handler(const boost::system::error_code&, std::size_t)
{
}
void read_some_handler(const boost::system::error_code&, std::size_t)
{
}
void test_compile()
{
#if defined(BOOST_ASIO_HAS_BOOST_ARRAY)
using boost::array;
#else // defined(BOOST_ASIO_HAS_BOOST_ARRAY)
using std::array;
#endif // defined(BOOST_ASIO_HAS_BOOST_ARRAY)
using namespace boost::asio;
try
{
io_context ioc;
char mutable_char_buffer[128] = "";
const char const_char_buffer[128] = "";
array<boost::asio::mutable_buffer, 2> mutable_buffers = {{
boost::asio::buffer(mutable_char_buffer, 10),
boost::asio::buffer(mutable_char_buffer + 10, 10) }};
array<boost::asio::const_buffer, 2> const_buffers = {{
boost::asio::buffer(const_char_buffer, 10),
boost::asio::buffer(const_char_buffer + 10, 10) }};
archetypes::lazy_handler lazy;
boost::system::error_code ec;
stream_type stream1(ioc);
stream_type stream2(ioc, 1024, 1024);
stream_type::executor_type ex = stream1.get_executor();
(void)ex;
stream_type::lowest_layer_type& lowest_layer = stream1.lowest_layer();
(void)lowest_layer;
stream1.write_some(buffer(mutable_char_buffer));
stream1.write_some(buffer(const_char_buffer));
stream1.write_some(mutable_buffers);
stream1.write_some(const_buffers);
stream1.write_some(null_buffers());
stream1.write_some(buffer(mutable_char_buffer), ec);
stream1.write_some(buffer(const_char_buffer), ec);
stream1.write_some(mutable_buffers, ec);
stream1.write_some(const_buffers, ec);
stream1.write_some(null_buffers(), ec);
stream1.async_write_some(buffer(mutable_char_buffer), &write_some_handler);
stream1.async_write_some(buffer(const_char_buffer), &write_some_handler);
stream1.async_write_some(mutable_buffers, &write_some_handler);
stream1.async_write_some(const_buffers, &write_some_handler);
stream1.async_write_some(null_buffers(), &write_some_handler);
int i1 = stream1.async_write_some(buffer(mutable_char_buffer), lazy);
(void)i1;
int i2 = stream1.async_write_some(buffer(const_char_buffer), lazy);
(void)i2;
int i3 = stream1.async_write_some(mutable_buffers, lazy);
(void)i3;
int i4 = stream1.async_write_some(const_buffers, lazy);
(void)i4;
int i5 = stream1.async_write_some(null_buffers(), lazy);
(void)i5;
stream1.flush();
stream1.flush(ec);
stream1.async_flush(&flush_handler);
int i6 = stream1.async_flush(lazy);
(void)i6;
stream1.fill();
stream1.fill(ec);
stream1.async_fill(&fill_handler);
int i7 = stream1.async_fill(lazy);
(void)i7;
stream1.read_some(buffer(mutable_char_buffer));
stream1.read_some(mutable_buffers);
stream1.read_some(null_buffers());
stream1.read_some(buffer(mutable_char_buffer), ec);
stream1.read_some(mutable_buffers, ec);
stream1.read_some(null_buffers(), ec);
stream1.async_read_some(buffer(mutable_char_buffer), &read_some_handler);
stream1.async_read_some(mutable_buffers, &read_some_handler);
stream1.async_read_some(null_buffers(), &read_some_handler);
int i8 = stream1.async_read_some(buffer(mutable_char_buffer), lazy);
(void)i8;
int i9 = stream1.async_read_some(mutable_buffers, lazy);
(void)i9;
int i10 = stream1.async_read_some(null_buffers(), lazy);
(void)i10;
}
catch (std::exception&)
{
}
}
void test_sync_operations()
{
using namespace std; // For memcmp.
boost::asio::io_context io_context;
boost::asio::ip::tcp::acceptor acceptor(io_context,
boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), 0));
boost::asio::ip::tcp::endpoint server_endpoint = acceptor.local_endpoint();
server_endpoint.address(boost::asio::ip::address_v4::loopback());
stream_type client_socket(io_context);
client_socket.lowest_layer().connect(server_endpoint);
stream_type server_socket(io_context);
acceptor.accept(server_socket.lowest_layer());
const char write_data[]
= "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
const boost::asio::const_buffer write_buf = boost::asio::buffer(write_data);
std::size_t bytes_written = 0;
while (bytes_written < sizeof(write_data))
{
bytes_written += client_socket.write_some(
boost::asio::buffer(write_buf + bytes_written));
client_socket.flush();
}
char read_data[sizeof(write_data)];
const boost::asio::mutable_buffer read_buf = boost::asio::buffer(read_data);
std::size_t bytes_read = 0;
while (bytes_read < sizeof(read_data))
{
bytes_read += server_socket.read_some(
boost::asio::buffer(read_buf + bytes_read));
}
BOOST_ASIO_CHECK(bytes_written == sizeof(write_data));
BOOST_ASIO_CHECK(bytes_read == sizeof(read_data));
BOOST_ASIO_CHECK(memcmp(write_data, read_data, sizeof(write_data)) == 0);
bytes_written = 0;
while (bytes_written < sizeof(write_data))
{
bytes_written += server_socket.write_some(
boost::asio::buffer(write_buf + bytes_written));
server_socket.flush();
}
bytes_read = 0;
while (bytes_read < sizeof(read_data))
{
bytes_read += client_socket.read_some(
boost::asio::buffer(read_buf + bytes_read));
}
BOOST_ASIO_CHECK(bytes_written == sizeof(write_data));
BOOST_ASIO_CHECK(bytes_read == sizeof(read_data));
BOOST_ASIO_CHECK(memcmp(write_data, read_data, sizeof(write_data)) == 0);
server_socket.close();
boost::system::error_code error;
bytes_read = client_socket.read_some(
boost::asio::buffer(read_buf), error);
BOOST_ASIO_CHECK(bytes_read == 0);
BOOST_ASIO_CHECK(error == boost::asio::error::eof);
client_socket.close(error);
}
void handle_accept(const boost::system::error_code& e)
{
BOOST_ASIO_CHECK(!e);
}
void handle_write(const boost::system::error_code& e,
std::size_t bytes_transferred,
std::size_t* total_bytes_written)
{
BOOST_ASIO_CHECK(!e);
if (e)
throw boost::system::system_error(e); // Terminate test.
*total_bytes_written += bytes_transferred;
}
void handle_flush(const boost::system::error_code& e)
{
BOOST_ASIO_CHECK(!e);
}
void handle_read(const boost::system::error_code& e,
std::size_t bytes_transferred,
std::size_t* total_bytes_read)
{
BOOST_ASIO_CHECK(!e);
if (e)
throw boost::system::system_error(e); // Terminate test.
*total_bytes_read += bytes_transferred;
}
void handle_read_eof(const boost::system::error_code& e,
std::size_t bytes_transferred)
{
BOOST_ASIO_CHECK(e == boost::asio::error::eof);
BOOST_ASIO_CHECK(bytes_transferred == 0);
}
void test_async_operations()
{
using namespace std; // For memcmp.
#if defined(BOOST_ASIO_HAS_BOOST_BIND)
namespace bindns = boost;
#else // defined(BOOST_ASIO_HAS_BOOST_BIND)
namespace bindns = std;
#endif // defined(BOOST_ASIO_HAS_BOOST_BIND)
using bindns::placeholders::_1;
using bindns::placeholders::_2;
boost::asio::io_context io_context;
boost::asio::ip::tcp::acceptor acceptor(io_context,
boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), 0));
boost::asio::ip::tcp::endpoint server_endpoint = acceptor.local_endpoint();
server_endpoint.address(boost::asio::ip::address_v4::loopback());
stream_type client_socket(io_context);
client_socket.lowest_layer().connect(server_endpoint);
stream_type server_socket(io_context);
acceptor.async_accept(server_socket.lowest_layer(), &handle_accept);
io_context.run();
io_context.restart();
const char write_data[]
= "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
const boost::asio::const_buffer write_buf = boost::asio::buffer(write_data);
std::size_t bytes_written = 0;
while (bytes_written < sizeof(write_data))
{
client_socket.async_write_some(
boost::asio::buffer(write_buf + bytes_written),
bindns::bind(handle_write, _1, _2, &bytes_written));
io_context.run();
io_context.restart();
client_socket.async_flush(
bindns::bind(handle_flush, _1));
io_context.run();
io_context.restart();
}
char read_data[sizeof(write_data)];
const boost::asio::mutable_buffer read_buf = boost::asio::buffer(read_data);
std::size_t bytes_read = 0;
while (bytes_read < sizeof(read_data))
{
server_socket.async_read_some(
boost::asio::buffer(read_buf + bytes_read),
bindns::bind(handle_read, _1, _2, &bytes_read));
io_context.run();
io_context.restart();
}
BOOST_ASIO_CHECK(bytes_written == sizeof(write_data));
BOOST_ASIO_CHECK(bytes_read == sizeof(read_data));
BOOST_ASIO_CHECK(memcmp(write_data, read_data, sizeof(write_data)) == 0);
bytes_written = 0;
while (bytes_written < sizeof(write_data))
{
server_socket.async_write_some(
boost::asio::buffer(write_buf + bytes_written),
bindns::bind(handle_write, _1, _2, &bytes_written));
io_context.run();
io_context.restart();
server_socket.async_flush(
bindns::bind(handle_flush, _1));
io_context.run();
io_context.restart();
}
bytes_read = 0;
while (bytes_read < sizeof(read_data))
{
client_socket.async_read_some(
boost::asio::buffer(read_buf + bytes_read),
bindns::bind(handle_read, _1, _2, &bytes_read));
io_context.run();
io_context.restart();
}
BOOST_ASIO_CHECK(bytes_written == sizeof(write_data));
BOOST_ASIO_CHECK(bytes_read == sizeof(read_data));
BOOST_ASIO_CHECK(memcmp(write_data, read_data, sizeof(write_data)) == 0);
server_socket.close();
client_socket.async_read_some(boost::asio::buffer(read_buf), handle_read_eof);
}
BOOST_ASIO_TEST_SUITE
(
"buffered_stream",
BOOST_ASIO_TEST_CASE(test_compile)
BOOST_ASIO_TEST_CASE(test_sync_operations)
BOOST_ASIO_TEST_CASE(test_async_operations)
)

View File

@@ -0,0 +1,353 @@
//
// buffered_write_stream.cpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/buffered_write_stream.hpp>
#include <cstring>
#include "archetypes/async_result.hpp"
#include <boost/asio/buffer.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <boost/system/system_error.hpp>
#include "unit_test.hpp"
#if defined(BOOST_ASIO_HAS_BOOST_ARRAY)
# include <boost/array.hpp>
#else // defined(BOOST_ASIO_HAS_BOOST_ARRAY)
# include <array>
#endif // defined(BOOST_ASIO_HAS_BOOST_ARRAY)
#if defined(BOOST_ASIO_HAS_BOOST_BIND)
# include <boost/bind/bind.hpp>
#else // defined(BOOST_ASIO_HAS_BOOST_BIND)
# include <functional>
#endif // defined(BOOST_ASIO_HAS_BOOST_BIND)
typedef boost::asio::buffered_write_stream<
boost::asio::ip::tcp::socket> stream_type;
void write_some_handler(const boost::system::error_code&, std::size_t)
{
}
void flush_handler(const boost::system::error_code&, std::size_t)
{
}
void read_some_handler(const boost::system::error_code&, std::size_t)
{
}
void test_compile()
{
#if defined(BOOST_ASIO_HAS_BOOST_ARRAY)
using boost::array;
#else // defined(BOOST_ASIO_HAS_BOOST_ARRAY)
using std::array;
#endif // defined(BOOST_ASIO_HAS_BOOST_ARRAY)
using namespace boost::asio;
try
{
io_context ioc;
char mutable_char_buffer[128] = "";
const char const_char_buffer[128] = "";
array<boost::asio::mutable_buffer, 2> mutable_buffers = {{
boost::asio::buffer(mutable_char_buffer, 10),
boost::asio::buffer(mutable_char_buffer + 10, 10) }};
array<boost::asio::const_buffer, 2> const_buffers = {{
boost::asio::buffer(const_char_buffer, 10),
boost::asio::buffer(const_char_buffer + 10, 10) }};
archetypes::lazy_handler lazy;
boost::system::error_code ec;
stream_type stream1(ioc);
stream_type stream2(ioc, 1024);
stream_type::executor_type ex = stream1.get_executor();
(void)ex;
stream_type::lowest_layer_type& lowest_layer = stream1.lowest_layer();
(void)lowest_layer;
stream1.write_some(buffer(mutable_char_buffer));
stream1.write_some(buffer(const_char_buffer));
stream1.write_some(mutable_buffers);
stream1.write_some(const_buffers);
stream1.write_some(null_buffers());
stream1.write_some(buffer(mutable_char_buffer), ec);
stream1.write_some(buffer(const_char_buffer), ec);
stream1.write_some(mutable_buffers, ec);
stream1.write_some(const_buffers, ec);
stream1.write_some(null_buffers(), ec);
stream1.async_write_some(buffer(mutable_char_buffer), &write_some_handler);
stream1.async_write_some(buffer(const_char_buffer), &write_some_handler);
stream1.async_write_some(mutable_buffers, &write_some_handler);
stream1.async_write_some(const_buffers, &write_some_handler);
stream1.async_write_some(null_buffers(), &write_some_handler);
int i1 = stream1.async_write_some(buffer(mutable_char_buffer), lazy);
(void)i1;
int i2 = stream1.async_write_some(buffer(const_char_buffer), lazy);
(void)i2;
int i3 = stream1.async_write_some(mutable_buffers, lazy);
(void)i3;
int i4 = stream1.async_write_some(const_buffers, lazy);
(void)i4;
int i5 = stream1.async_write_some(null_buffers(), lazy);
(void)i5;
stream1.flush();
stream1.flush(ec);
stream1.async_flush(&flush_handler);
int i6 = stream1.async_flush(lazy);
(void)i6;
stream1.read_some(buffer(mutable_char_buffer));
stream1.read_some(mutable_buffers);
stream1.read_some(null_buffers());
stream1.read_some(buffer(mutable_char_buffer), ec);
stream1.read_some(mutable_buffers, ec);
stream1.read_some(null_buffers(), ec);
stream1.async_read_some(buffer(mutable_char_buffer), &read_some_handler);
stream1.async_read_some(mutable_buffers, &read_some_handler);
stream1.async_read_some(null_buffers(), &read_some_handler);
int i7 = stream1.async_read_some(buffer(mutable_char_buffer), lazy);
(void)i7;
int i8 = stream1.async_read_some(mutable_buffers, lazy);
(void)i8;
int i9 = stream1.async_read_some(null_buffers(), lazy);
(void)i9;
}
catch (std::exception&)
{
}
}
void test_sync_operations()
{
using namespace std; // For memcmp.
boost::asio::io_context io_context;
boost::asio::ip::tcp::acceptor acceptor(io_context,
boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), 0));
boost::asio::ip::tcp::endpoint server_endpoint = acceptor.local_endpoint();
server_endpoint.address(boost::asio::ip::address_v4::loopback());
stream_type client_socket(io_context);
client_socket.lowest_layer().connect(server_endpoint);
stream_type server_socket(io_context);
acceptor.accept(server_socket.lowest_layer());
const char write_data[]
= "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
const boost::asio::const_buffer write_buf = boost::asio::buffer(write_data);
std::size_t bytes_written = 0;
while (bytes_written < sizeof(write_data))
{
bytes_written += client_socket.write_some(
boost::asio::buffer(write_buf + bytes_written));
client_socket.flush();
}
char read_data[sizeof(write_data)];
const boost::asio::mutable_buffer read_buf = boost::asio::buffer(read_data);
std::size_t bytes_read = 0;
while (bytes_read < sizeof(read_data))
{
bytes_read += server_socket.read_some(
boost::asio::buffer(read_buf + bytes_read));
}
BOOST_ASIO_CHECK(bytes_written == sizeof(write_data));
BOOST_ASIO_CHECK(bytes_read == sizeof(read_data));
BOOST_ASIO_CHECK(memcmp(write_data, read_data, sizeof(write_data)) == 0);
bytes_written = 0;
while (bytes_written < sizeof(write_data))
{
bytes_written += server_socket.write_some(
boost::asio::buffer(write_buf + bytes_written));
server_socket.flush();
}
bytes_read = 0;
while (bytes_read < sizeof(read_data))
{
bytes_read += client_socket.read_some(
boost::asio::buffer(read_buf + bytes_read));
}
BOOST_ASIO_CHECK(bytes_written == sizeof(write_data));
BOOST_ASIO_CHECK(bytes_read == sizeof(read_data));
BOOST_ASIO_CHECK(memcmp(write_data, read_data, sizeof(write_data)) == 0);
server_socket.close();
boost::system::error_code error;
bytes_read = client_socket.read_some(
boost::asio::buffer(read_buf), error);
BOOST_ASIO_CHECK(bytes_read == 0);
BOOST_ASIO_CHECK(error == boost::asio::error::eof);
client_socket.close(error);
}
void handle_accept(const boost::system::error_code& e)
{
BOOST_ASIO_CHECK(!e);
}
void handle_write(const boost::system::error_code& e,
std::size_t bytes_transferred,
std::size_t* total_bytes_written)
{
BOOST_ASIO_CHECK(!e);
if (e)
throw boost::system::system_error(e); // Terminate test.
*total_bytes_written += bytes_transferred;
}
void handle_flush(const boost::system::error_code& e)
{
BOOST_ASIO_CHECK(!e);
}
void handle_read(const boost::system::error_code& e,
std::size_t bytes_transferred,
std::size_t* total_bytes_read)
{
BOOST_ASIO_CHECK(!e);
if (e)
throw boost::system::system_error(e); // Terminate test.
*total_bytes_read += bytes_transferred;
}
void handle_read_eof(const boost::system::error_code& e,
std::size_t bytes_transferred)
{
BOOST_ASIO_CHECK(e == boost::asio::error::eof);
BOOST_ASIO_CHECK(bytes_transferred == 0);
}
void test_async_operations()
{
using namespace std; // For memcmp.
#if defined(BOOST_ASIO_HAS_BOOST_BIND)
namespace bindns = boost;
#else // defined(BOOST_ASIO_HAS_BOOST_BIND)
namespace bindns = std;
#endif // defined(BOOST_ASIO_HAS_BOOST_BIND)
using bindns::placeholders::_1;
using bindns::placeholders::_2;
boost::asio::io_context io_context;
boost::asio::ip::tcp::acceptor acceptor(io_context,
boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), 0));
boost::asio::ip::tcp::endpoint server_endpoint = acceptor.local_endpoint();
server_endpoint.address(boost::asio::ip::address_v4::loopback());
stream_type client_socket(io_context);
client_socket.lowest_layer().connect(server_endpoint);
stream_type server_socket(io_context);
acceptor.async_accept(server_socket.lowest_layer(), &handle_accept);
io_context.run();
io_context.restart();
const char write_data[]
= "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
const boost::asio::const_buffer write_buf = boost::asio::buffer(write_data);
std::size_t bytes_written = 0;
while (bytes_written < sizeof(write_data))
{
client_socket.async_write_some(
boost::asio::buffer(write_buf + bytes_written),
bindns::bind(handle_write, _1, _2, &bytes_written));
io_context.run();
io_context.restart();
client_socket.async_flush(
bindns::bind(handle_flush, _1));
io_context.run();
io_context.restart();
}
char read_data[sizeof(write_data)];
const boost::asio::mutable_buffer read_buf = boost::asio::buffer(read_data);
std::size_t bytes_read = 0;
while (bytes_read < sizeof(read_data))
{
server_socket.async_read_some(
boost::asio::buffer(read_buf + bytes_read),
bindns::bind(handle_read, _1, _2, &bytes_read));
io_context.run();
io_context.restart();
}
BOOST_ASIO_CHECK(bytes_written == sizeof(write_data));
BOOST_ASIO_CHECK(bytes_read == sizeof(read_data));
BOOST_ASIO_CHECK(memcmp(write_data, read_data, sizeof(write_data)) == 0);
bytes_written = 0;
while (bytes_written < sizeof(write_data))
{
server_socket.async_write_some(
boost::asio::buffer(write_buf + bytes_written),
bindns::bind(handle_write, _1, _2, &bytes_written));
io_context.run();
io_context.restart();
server_socket.async_flush(
bindns::bind(handle_flush, _1));
io_context.run();
io_context.restart();
}
bytes_read = 0;
while (bytes_read < sizeof(read_data))
{
client_socket.async_read_some(
boost::asio::buffer(read_buf + bytes_read),
bindns::bind(handle_read, _1, _2, &bytes_read));
io_context.run();
io_context.restart();
}
BOOST_ASIO_CHECK(bytes_written == sizeof(write_data));
BOOST_ASIO_CHECK(bytes_read == sizeof(read_data));
BOOST_ASIO_CHECK(memcmp(write_data, read_data, sizeof(write_data)) == 0);
server_socket.close();
client_socket.async_read_some(boost::asio::buffer(read_buf), handle_read_eof);
}
BOOST_ASIO_TEST_SUITE
(
"buffered_write_stream",
BOOST_ASIO_TEST_CASE(test_compile)
BOOST_ASIO_TEST_CASE(test_sync_operations)
BOOST_ASIO_TEST_CASE(test_async_operations)
)

View File

@@ -0,0 +1,292 @@
//
// buffers_iterator.cpp
// ~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/buffers_iterator.hpp>
#include <boost/asio/buffer.hpp>
#include "unit_test.hpp"
#if defined(BOOST_ASIO_HAS_BOOST_ARRAY)
# include <boost/array.hpp>
#endif // defined(BOOST_ASIO_HAS_BOOST_ARRAY)
#if defined(BOOST_ASIO_HAS_STD_ARRAY)
# include <array>
#endif // defined(BOOST_ASIO_HAS_STD_ARRAY)
//------------------------------------------------------------------------------
// buffers_iterator_compile test
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// The following test checks that all operations on the buffers_iterator compile
// and link correctly. Runtime failures are ignored.
namespace buffers_iterator_compile {
#if defined(BOOST_ASIO_HAS_BOOST_ARRAY)
using boost::array;
#elif defined(BOOST_ASIO_HAS_STD_ARRAY)
using std::array;
#endif // defined(BOOST_ASIO_HAS_BOOST_ARRAY)
using std::vector;
using namespace boost::asio;
void test()
{
try
{
char data1[16], data2[16];
const char cdata1[16] = "", cdata2[16] = "";
mutable_buffer mb1 = buffer(data1);
array<mutable_buffer, 2> mb2 = {{ buffer(data1), buffer(data2) }};
std::vector<mutable_buffer> mb3;
mb3.push_back(buffer(data1));
const_buffer cb1 = buffer(cdata1);
array<const_buffer, 2> cb2 = {{ buffer(cdata1), buffer(cdata2) }};
vector<const_buffer> cb3;
cb3.push_back(buffer(cdata1));
// buffers_iterator constructors.
buffers_iterator<mutable_buffer, char> bi1;
buffers_iterator<mutable_buffer, const char> bi2;
buffers_iterator<array<mutable_buffer, 2>, char> bi3;
buffers_iterator<array<mutable_buffer, 2>, const char> bi4;
buffers_iterator<vector<mutable_buffer>, char> bi5;
buffers_iterator<vector<mutable_buffer>, const char> bi6;
buffers_iterator<const_buffer, char> bi7;
buffers_iterator<const_buffer, const char> bi8;
buffers_iterator<array<const_buffer, 2>, char> bi9;
buffers_iterator<array<const_buffer, 2>, const char> bi10;
buffers_iterator<vector<const_buffer>, char> bi11;
buffers_iterator<vector<const_buffer>, const char> bi12;
buffers_iterator<mutable_buffer, char> bi13(
buffers_iterator<mutable_buffer, char>::begin(mb1));
buffers_iterator<mutable_buffer, const char> bi14(
buffers_iterator<mutable_buffer, const char>::begin(mb1));
buffers_iterator<array<mutable_buffer, 2>, char> bi15(
buffers_iterator<array<mutable_buffer, 2>, char>::begin(mb2));
buffers_iterator<array<mutable_buffer, 2>, const char> bi16(
buffers_iterator<array<mutable_buffer, 2>, const char>::begin(mb2));
buffers_iterator<vector<mutable_buffer>, char> bi17(
buffers_iterator<vector<mutable_buffer>, char>::begin(mb3));
buffers_iterator<vector<mutable_buffer>, const char> bi18(
buffers_iterator<vector<mutable_buffer>, const char>::begin(mb3));
buffers_iterator<const_buffer, char> bi19(
buffers_iterator<const_buffer, char>::begin(cb1));
buffers_iterator<const_buffer, const char> bi20(
buffers_iterator<const_buffer, const char>::begin(cb1));
buffers_iterator<array<const_buffer, 2>, char> bi21(
buffers_iterator<array<const_buffer, 2>, char>::begin(cb2));
buffers_iterator<array<const_buffer, 2>, const char> bi22(
buffers_iterator<array<const_buffer, 2>, const char>::begin(cb2));
buffers_iterator<vector<const_buffer>, char> bi23(
buffers_iterator<vector<const_buffer>, char>::begin(cb3));
buffers_iterator<vector<const_buffer>, const char> bi24(
buffers_iterator<vector<const_buffer>, const char>::begin(cb3));
// buffers_iterator member functions.
bi1 = buffers_iterator<mutable_buffer, char>::begin(mb1);
bi2 = buffers_iterator<mutable_buffer, const char>::begin(mb1);
bi3 = buffers_iterator<array<mutable_buffer, 2>, char>::begin(mb2);
bi4 = buffers_iterator<array<mutable_buffer, 2>, const char>::begin(mb2);
bi5 = buffers_iterator<vector<mutable_buffer>, char>::begin(mb3);
bi6 = buffers_iterator<vector<mutable_buffer>, const char>::begin(mb3);
bi7 = buffers_iterator<const_buffer, char>::begin(cb1);
bi8 = buffers_iterator<const_buffer, const char>::begin(cb1);
bi9 = buffers_iterator<array<const_buffer, 2>, char>::begin(cb2);
bi10 = buffers_iterator<array<const_buffer, 2>, const char>::begin(cb2);
bi11 = buffers_iterator<vector<const_buffer>, char>::begin(cb3);
bi12 = buffers_iterator<vector<const_buffer>, const char>::begin(cb3);
bi1 = buffers_iterator<mutable_buffer, char>::end(mb1);
bi2 = buffers_iterator<mutable_buffer, const char>::end(mb1);
bi3 = buffers_iterator<array<mutable_buffer, 2>, char>::end(mb2);
bi4 = buffers_iterator<array<mutable_buffer, 2>, const char>::end(mb2);
bi5 = buffers_iterator<vector<mutable_buffer>, char>::end(mb3);
bi6 = buffers_iterator<vector<mutable_buffer>, const char>::end(mb3);
bi7 = buffers_iterator<const_buffer, char>::end(cb1);
bi8 = buffers_iterator<const_buffer, const char>::end(cb1);
bi9 = buffers_iterator<array<const_buffer, 2>, char>::end(cb2);
bi10 = buffers_iterator<array<const_buffer, 2>, const char>::end(cb2);
bi11 = buffers_iterator<vector<const_buffer>, char>::end(cb3);
bi12 = buffers_iterator<vector<const_buffer>, const char>::end(cb3);
// buffers_iterator related functions.
bi1 = buffers_begin(mb1);
bi3 = buffers_begin(mb2);
bi5 = buffers_begin(mb3);
bi7 = buffers_begin(cb1);
bi9 = buffers_begin(cb2);
bi11 = buffers_begin(cb3);
bi1 = buffers_end(mb1);
bi3 = buffers_end(mb2);
bi5 = buffers_end(mb3);
bi7 = buffers_end(cb1);
bi9 = buffers_end(cb2);
bi11 = buffers_end(cb3);
// RandomAccessIterator operations.
--bi1;
--bi2;
--bi3;
--bi4;
--bi5;
--bi6;
--bi7;
--bi8;
--bi9;
--bi10;
--bi11;
--bi12;
++bi1;
++bi2;
++bi3;
++bi4;
++bi5;
++bi6;
++bi7;
++bi8;
++bi9;
++bi10;
++bi11;
++bi12;
bi1--;
bi2--;
bi3--;
bi4--;
bi5--;
bi6--;
bi7--;
bi8--;
bi9--;
bi10--;
bi11--;
bi12--;
bi1++;
bi2++;
bi3++;
bi4++;
bi5++;
bi6++;
bi7++;
bi8++;
bi9++;
bi10++;
bi11++;
bi12++;
bi1 -= 1;
bi2 -= 1;
bi3 -= 1;
bi4 -= 1;
bi5 -= 1;
bi6 -= 1;
bi7 -= 1;
bi8 -= 1;
bi9 -= 1;
bi10 -= 1;
bi11 -= 1;
bi12 -= 1;
bi1 += 1;
bi2 += 1;
bi3 += 1;
bi4 += 1;
bi5 += 1;
bi6 += 1;
bi7 += 1;
bi8 += 1;
bi9 += 1;
bi10 += 1;
bi11 += 1;
bi12 += 1;
bi1 = bi1 - 1;
bi2 = bi2 - 1;
bi3 = bi3 - 1;
bi4 = bi4 - 1;
bi5 = bi5 - 1;
bi6 = bi6 - 1;
bi7 = bi7 - 1;
bi8 = bi8 - 1;
bi9 = bi9 - 1;
bi10 = bi10 - 1;
bi11 = bi11 - 1;
bi12 = bi12 - 1;
bi1 = bi1 + 1;
bi2 = bi2 + 1;
bi3 = bi3 + 1;
bi4 = bi4 + 1;
bi5 = bi5 + 1;
bi6 = bi6 + 1;
bi7 = bi7 + 1;
bi8 = bi8 + 1;
bi9 = bi9 + 1;
bi10 = bi10 + 1;
bi11 = bi11 + 1;
bi12 = bi12 + 1;
bi1 = (-1) + bi1;
bi2 = (-1) + bi2;
bi3 = (-1) + bi3;
bi4 = (-1) + bi4;
bi5 = (-1) + bi5;
bi6 = (-1) + bi6;
bi7 = (-1) + bi7;
bi8 = (-1) + bi8;
bi9 = (-1) + bi9;
bi10 = (-1) + bi10;
bi11 = (-1) + bi11;
bi12 = (-1) + bi12;
(void)static_cast<std::ptrdiff_t>(bi13 - bi1);
(void)static_cast<std::ptrdiff_t>(bi14 - bi2);
(void)static_cast<std::ptrdiff_t>(bi15 - bi3);
(void)static_cast<std::ptrdiff_t>(bi16 - bi4);
(void)static_cast<std::ptrdiff_t>(bi17 - bi5);
(void)static_cast<std::ptrdiff_t>(bi18 - bi6);
(void)static_cast<std::ptrdiff_t>(bi19 - bi7);
(void)static_cast<std::ptrdiff_t>(bi20 - bi8);
(void)static_cast<std::ptrdiff_t>(bi21 - bi9);
(void)static_cast<std::ptrdiff_t>(bi22 - bi10);
(void)static_cast<std::ptrdiff_t>(bi23 - bi11);
(void)static_cast<std::ptrdiff_t>(bi24 - bi12);
}
catch (std::exception&)
{
}
}
} // namespace buffers_iterator_compile
//------------------------------------------------------------------------------
BOOST_ASIO_TEST_SUITE
(
"buffers_iterator",
BOOST_ASIO_TEST_CASE(buffers_iterator_compile::test)
)

View File

@@ -0,0 +1,25 @@
//
// cancellation_signal.cpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/cancellation_signal.hpp>
#include "unit_test.hpp"
BOOST_ASIO_TEST_SUITE
(
"cancellation_signal",
BOOST_ASIO_TEST_CASE(null_test)
)

View File

@@ -0,0 +1,25 @@
//
// cancellation_state.cpp
// ~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/cancellation_state.hpp>
#include "unit_test.hpp"
BOOST_ASIO_TEST_SUITE
(
"cancellation_state",
BOOST_ASIO_TEST_CASE(null_test)
)

View File

@@ -0,0 +1,25 @@
//
// cancellation_type.cpp
// ~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/cancellation_type.hpp>
#include "unit_test.hpp"
BOOST_ASIO_TEST_SUITE
(
"cancellation_type",
BOOST_ASIO_TEST_CASE(null_test)
)

View File

@@ -0,0 +1,25 @@
//
// co_spawn.cpp
// ~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/co_spawn.hpp>
#include "unit_test.hpp"
BOOST_ASIO_TEST_SUITE
(
"co_spawn",
BOOST_ASIO_TEST_CASE(null_test)
)

View File

@@ -0,0 +1,25 @@
//
// completion_condition.cpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/completion_condition.hpp>
#include "unit_test.hpp"
BOOST_ASIO_TEST_SUITE
(
"completion_condition",
BOOST_ASIO_TEST_CASE(null_test)
)

View File

@@ -0,0 +1,554 @@
//
// compose.cpp
// ~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/compose.hpp>
#include "unit_test.hpp"
#include <boost/asio/bind_cancellation_slot.hpp>
#include <boost/asio/cancellation_signal.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/post.hpp>
#include <boost/asio/system_timer.hpp>
#if defined(BOOST_ASIO_HAS_BOOST_BIND)
# include <boost/bind/bind.hpp>
#else // defined(BOOST_ASIO_HAS_BOOST_BIND)
# include <functional>
#endif // defined(BOOST_ASIO_HAS_BOOST_BIND)
//------------------------------------------------------------------------------
class impl_0_completion_args
{
public:
explicit impl_0_completion_args(boost::asio::io_context& ioc)
: ioc_(ioc),
state_(starting)
{
}
template <typename Self>
void operator()(Self& self)
{
switch (state_)
{
case starting:
state_ = posting;
boost::asio::post(ioc_, BOOST_ASIO_MOVE_CAST(Self)(self));
break;
case posting:
self.complete();
break;
default:
break;
}
}
private:
boost::asio::io_context& ioc_;
enum { starting, posting } state_;
};
template <typename CompletionToken>
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void())
async_0_completion_args(boost::asio::io_context& ioc,
BOOST_ASIO_MOVE_ARG(CompletionToken) token)
{
return boost::asio::async_compose<CompletionToken, void()>(
impl_0_completion_args(ioc), token);
}
void compose_0_args_handler(int* count)
{
++(*count);
}
struct compose_0_args_lvalue_handler
{
int* count_;
void operator()()
{
++(*count_);
}
};
void compose_0_completion_args_test()
{
#if defined(BOOST_ASIO_HAS_BOOST_BIND)
namespace bindns = boost;
#else // defined(BOOST_ASIO_HAS_BOOST_BIND)
namespace bindns = std;
#endif // defined(BOOST_ASIO_HAS_BOOST_BIND)
boost::asio::io_context ioc;
int count = 0;
async_0_completion_args(ioc, bindns::bind(&compose_0_args_handler, &count));
// No handlers can be called until run() is called.
BOOST_ASIO_CHECK(!ioc.stopped());
BOOST_ASIO_CHECK(count == 0);
ioc.run();
// The run() call will not return until all work has finished.
BOOST_ASIO_CHECK(ioc.stopped());
BOOST_ASIO_CHECK(count == 1);
ioc.restart();
count = 0;
compose_0_args_lvalue_handler lvalue_handler = { &count };
async_0_completion_args(ioc, lvalue_handler);
// No handlers can be called until run() is called.
BOOST_ASIO_CHECK(!ioc.stopped());
BOOST_ASIO_CHECK(count == 0);
ioc.run();
// The run() call will not return until all work has finished.
BOOST_ASIO_CHECK(ioc.stopped());
BOOST_ASIO_CHECK(count == 1);
}
//------------------------------------------------------------------------------
class impl_1_completion_arg
{
public:
explicit impl_1_completion_arg(boost::asio::io_context& ioc)
: ioc_(ioc),
state_(starting)
{
}
template <typename Self>
void operator()(Self& self)
{
switch (state_)
{
case starting:
state_ = posting;
boost::asio::post(ioc_, BOOST_ASIO_MOVE_CAST(Self)(self));
break;
case posting:
self.complete(42);
break;
default:
break;
}
}
private:
boost::asio::io_context& ioc_;
enum { starting, posting } state_;
};
template <typename CompletionToken>
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void(int))
async_1_completion_arg(boost::asio::io_context& ioc,
BOOST_ASIO_MOVE_ARG(CompletionToken) token)
{
return boost::asio::async_compose<CompletionToken, void(int)>(
impl_1_completion_arg(ioc), token);
}
void compose_1_arg_handler(int* count, int* result_out, int result)
{
++(*count);
*result_out = result;
}
struct compose_1_arg_lvalue_handler
{
int* count_;
int* result_out_;
void operator()(int result)
{
++(*count_);
*result_out_ = result;
}
};
void compose_1_completion_arg_test()
{
#if defined(BOOST_ASIO_HAS_BOOST_BIND)
namespace bindns = boost;
#else // defined(BOOST_ASIO_HAS_BOOST_BIND)
namespace bindns = std;
#endif // defined(BOOST_ASIO_HAS_BOOST_BIND)
using bindns::placeholders::_1;
boost::asio::io_context ioc;
int count = 0;
int result = 0;
async_1_completion_arg(ioc,
bindns::bind(&compose_1_arg_handler, &count, &result, _1));
// No handlers can be called until run() is called.
BOOST_ASIO_CHECK(!ioc.stopped());
BOOST_ASIO_CHECK(count == 0);
BOOST_ASIO_CHECK(result == 0);
ioc.run();
// The run() call will not return until all work has finished.
BOOST_ASIO_CHECK(ioc.stopped());
BOOST_ASIO_CHECK(count == 1);
BOOST_ASIO_CHECK(result == 42);
ioc.restart();
count = 0;
result = 0;
compose_1_arg_lvalue_handler lvalue_handler = { &count, &result };
async_1_completion_arg(ioc, lvalue_handler);
// No handlers can be called until run() is called.
BOOST_ASIO_CHECK(!ioc.stopped());
BOOST_ASIO_CHECK(count == 0);
BOOST_ASIO_CHECK(result == 0);
ioc.run();
// The run() call will not return until all work has finished.
BOOST_ASIO_CHECK(ioc.stopped());
BOOST_ASIO_CHECK(count == 1);
BOOST_ASIO_CHECK(result == 42);
}
//------------------------------------------------------------------------------
typedef boost::asio::enable_terminal_cancellation default_filter;
template <typename CancellationFilter>
class impl_cancellable
{
public:
explicit impl_cancellable(CancellationFilter cancellation_filter,
boost::asio::system_timer& timer)
: cancellation_filter_(cancellation_filter),
timer_(timer),
state_(starting)
{
}
template <typename Self>
void operator()(Self& self,
const boost::system::error_code& ec = boost::system::error_code())
{
switch (state_)
{
case starting:
if (!boost::asio::is_same<CancellationFilter, default_filter>::value)
self.reset_cancellation_state(cancellation_filter_);
state_ = waiting;
timer_.expires_after(boost::asio::chrono::milliseconds(100));
timer_.async_wait(BOOST_ASIO_MOVE_CAST(Self)(self));
break;
case waiting:
self.complete(!ec);
break;
default:
break;
}
}
private:
CancellationFilter cancellation_filter_;
boost::asio::system_timer& timer_;
enum { starting, waiting } state_;
};
template <typename CancellationFilter, typename CompletionToken>
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void(bool))
async_cancellable(CancellationFilter cancellation_filter,
boost::asio::system_timer& timer,
BOOST_ASIO_MOVE_ARG(CompletionToken) token)
{
return boost::asio::async_compose<CompletionToken, void(bool)>(
impl_cancellable<CancellationFilter>(cancellation_filter, timer), token);
}
void compose_partial_cancellation_handler(
int* count, bool* result_out, bool result)
{
++(*count);
*result_out = result;
}
void compose_default_cancellation_test()
{
#if defined(BOOST_ASIO_HAS_BOOST_BIND)
namespace bindns = boost;
#else // defined(BOOST_ASIO_HAS_BOOST_BIND)
namespace bindns = std;
#endif // defined(BOOST_ASIO_HAS_BOOST_BIND)
using bindns::placeholders::_1;
boost::asio::io_context ioc;
boost::asio::system_timer timer(ioc);
boost::asio::cancellation_signal signal;
int count = 0;
bool result = false;
async_cancellable(default_filter(), timer,
bindns::bind(&compose_partial_cancellation_handler,
&count, &result, _1));
ioc.run();
// No cancellation, operation completes successfully.
BOOST_ASIO_CHECK(ioc.stopped());
BOOST_ASIO_CHECK(count == 1);
BOOST_ASIO_CHECK(result == true);
ioc.restart();
count = 0;
result = 0;
async_cancellable(default_filter(), timer,
boost::asio::bind_cancellation_slot(signal.slot(),
bindns::bind(&compose_partial_cancellation_handler,
&count, &result, _1)));
// Total cancellation unsupported. Operation completes successfully.
signal.emit(boost::asio::cancellation_type::total);
ioc.run();
BOOST_ASIO_CHECK(ioc.stopped());
BOOST_ASIO_CHECK(count == 1);
BOOST_ASIO_CHECK(result == true);
ioc.restart();
count = 0;
result = 0;
async_cancellable(default_filter(), timer,
boost::asio::bind_cancellation_slot(signal.slot(),
bindns::bind(&compose_partial_cancellation_handler,
&count, &result, _1)));
// Partial cancellation unsupported. Operation completes successfully.
signal.emit(boost::asio::cancellation_type::partial);
ioc.run();
BOOST_ASIO_CHECK(ioc.stopped());
BOOST_ASIO_CHECK(count == 1);
BOOST_ASIO_CHECK(result == true);
ioc.restart();
count = 0;
result = 0;
async_cancellable(default_filter(), timer,
boost::asio::bind_cancellation_slot(signal.slot(),
bindns::bind(&compose_partial_cancellation_handler,
&count, &result, _1)));
// Terminal cancellation works. Operation completes with failure.
signal.emit(boost::asio::cancellation_type::terminal);
ioc.run();
BOOST_ASIO_CHECK(ioc.stopped());
BOOST_ASIO_CHECK(count == 1);
BOOST_ASIO_CHECK(result == false);
}
void compose_partial_cancellation_test()
{
#if defined(BOOST_ASIO_HAS_BOOST_BIND)
namespace bindns = boost;
#else // defined(BOOST_ASIO_HAS_BOOST_BIND)
namespace bindns = std;
#endif // defined(BOOST_ASIO_HAS_BOOST_BIND)
using bindns::placeholders::_1;
boost::asio::io_context ioc;
boost::asio::system_timer timer(ioc);
boost::asio::cancellation_signal signal;
int count = 0;
bool result = false;
async_cancellable(boost::asio::enable_partial_cancellation(), timer,
bindns::bind(&compose_partial_cancellation_handler,
&count, &result, _1));
ioc.run();
// No cancellation, operation completes successfully.
BOOST_ASIO_CHECK(ioc.stopped());
BOOST_ASIO_CHECK(count == 1);
BOOST_ASIO_CHECK(result == true);
ioc.restart();
count = 0;
result = 0;
async_cancellable(boost::asio::enable_partial_cancellation(), timer,
boost::asio::bind_cancellation_slot(signal.slot(),
bindns::bind(&compose_partial_cancellation_handler,
&count, &result, _1)));
// Total cancellation unsupported. Operation completes successfully.
signal.emit(boost::asio::cancellation_type::total);
ioc.run();
BOOST_ASIO_CHECK(ioc.stopped());
BOOST_ASIO_CHECK(count == 1);
BOOST_ASIO_CHECK(result == true);
ioc.restart();
count = 0;
result = 0;
async_cancellable(boost::asio::enable_partial_cancellation(), timer,
boost::asio::bind_cancellation_slot(signal.slot(),
bindns::bind(&compose_partial_cancellation_handler,
&count, &result, _1)));
// Partial cancellation works. Operation completes with failure.
signal.emit(boost::asio::cancellation_type::partial);
ioc.run();
BOOST_ASIO_CHECK(ioc.stopped());
BOOST_ASIO_CHECK(count == 1);
BOOST_ASIO_CHECK(result == false);
ioc.restart();
count = 0;
result = 0;
async_cancellable(boost::asio::enable_partial_cancellation(), timer,
boost::asio::bind_cancellation_slot(signal.slot(),
bindns::bind(&compose_partial_cancellation_handler,
&count, &result, _1)));
// Terminal cancellation works. Operation completes with failure.
signal.emit(boost::asio::cancellation_type::terminal);
ioc.run();
BOOST_ASIO_CHECK(ioc.stopped());
BOOST_ASIO_CHECK(count == 1);
BOOST_ASIO_CHECK(result == false);
}
void compose_total_cancellation_test()
{
#if defined(BOOST_ASIO_HAS_BOOST_BIND)
namespace bindns = boost;
#else // defined(BOOST_ASIO_HAS_BOOST_BIND)
namespace bindns = std;
#endif // defined(BOOST_ASIO_HAS_BOOST_BIND)
using bindns::placeholders::_1;
boost::asio::io_context ioc;
boost::asio::system_timer timer(ioc);
boost::asio::cancellation_signal signal;
int count = 0;
bool result = false;
async_cancellable(boost::asio::enable_total_cancellation(), timer,
bindns::bind(&compose_partial_cancellation_handler,
&count, &result, _1));
ioc.run();
// No cancellation, operation completes successfully.
BOOST_ASIO_CHECK(ioc.stopped());
BOOST_ASIO_CHECK(count == 1);
BOOST_ASIO_CHECK(result == true);
ioc.restart();
count = 0;
result = 0;
async_cancellable(boost::asio::enable_total_cancellation(), timer,
boost::asio::bind_cancellation_slot(signal.slot(),
bindns::bind(&compose_partial_cancellation_handler,
&count, &result, _1)));
// Total cancellation works. Operation completes with failure.
signal.emit(boost::asio::cancellation_type::total);
ioc.run();
BOOST_ASIO_CHECK(ioc.stopped());
BOOST_ASIO_CHECK(count == 1);
BOOST_ASIO_CHECK(result == false);
ioc.restart();
count = 0;
result = 0;
async_cancellable(boost::asio::enable_total_cancellation(), timer,
boost::asio::bind_cancellation_slot(signal.slot(),
bindns::bind(&compose_partial_cancellation_handler,
&count, &result, _1)));
// Partial cancellation works. Operation completes with failure.
signal.emit(boost::asio::cancellation_type::partial);
ioc.run();
BOOST_ASIO_CHECK(ioc.stopped());
BOOST_ASIO_CHECK(count == 1);
BOOST_ASIO_CHECK(result == false);
ioc.restart();
count = 0;
result = 0;
async_cancellable(boost::asio::enable_total_cancellation(), timer,
boost::asio::bind_cancellation_slot(signal.slot(),
bindns::bind(&compose_partial_cancellation_handler,
&count, &result, _1)));
// Terminal cancellation works. Operation completes with failure.
signal.emit(boost::asio::cancellation_type::terminal);
ioc.run();
BOOST_ASIO_CHECK(ioc.stopped());
BOOST_ASIO_CHECK(count == 1);
BOOST_ASIO_CHECK(result == false);
}
//------------------------------------------------------------------------------
BOOST_ASIO_TEST_SUITE
(
"compose",
BOOST_ASIO_TEST_CASE(compose_0_completion_args_test)
BOOST_ASIO_TEST_CASE(compose_1_completion_arg_test)
BOOST_ASIO_TEST_CASE(compose_default_cancellation_test)
BOOST_ASIO_TEST_CASE(compose_partial_cancellation_test)
BOOST_ASIO_TEST_CASE(compose_total_cancellation_test)
)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,163 @@
//
// connect_pipe.cpp
// ~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/connect_pipe.hpp>
#include <string>
#include <boost/asio/io_context.hpp>
#include <boost/asio/read.hpp>
#include <boost/asio/readable_pipe.hpp>
#include <boost/asio/writable_pipe.hpp>
#include <boost/asio/write.hpp>
#include "unit_test.hpp"
#if defined(BOOST_ASIO_HAS_BOOST_BIND)
# include <boost/bind/bind.hpp>
#else // defined(BOOST_ASIO_HAS_BOOST_BIND)
# include <functional>
#endif // defined(BOOST_ASIO_HAS_BOOST_BIND)
//------------------------------------------------------------------------------
// connect_pipe_compile test
// ~~~~~~~~~~~~~~~~~~~~~~~~~
// The following test checks that all connect_pipe functions compile and link
// correctly. Runtime failures are ignored.
namespace connect_pipe_compile {
void test()
{
#if defined(BOOST_ASIO_HAS_PIPE)
using namespace boost::asio;
try
{
boost::asio::io_context io_context;
boost::system::error_code ec1;
readable_pipe p1(io_context);
writable_pipe p2(io_context);
connect_pipe(p1, p2);
readable_pipe p3(io_context);
writable_pipe p4(io_context);
connect_pipe(p3, p4, ec1);
}
catch (std::exception&)
{
}
#endif // defined(BOOST_ASIO_HAS_PIPE)
}
} // namespace connect_pipe_compile
//------------------------------------------------------------------------------
// connect_pipe_runtime test
// ~~~~~~~~~~~~~~~~~~~~~~~~~
// The following test checks that connect_pipe operates correctly at runtime.
namespace connect_pipe_runtime {
static const char write_data[]
= "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
void handle_read(const boost::system::error_code& err,
size_t bytes_transferred, bool* called)
{
*called = true;
BOOST_ASIO_CHECK(!err);
BOOST_ASIO_CHECK(bytes_transferred == sizeof(write_data));
}
void handle_write(const boost::system::error_code& err,
size_t bytes_transferred, bool* called)
{
*called = true;
BOOST_ASIO_CHECK(!err);
BOOST_ASIO_CHECK(bytes_transferred == sizeof(write_data));
}
void test()
{
#if defined(BOOST_ASIO_HAS_PIPE)
using namespace std; // For memcmp.
using namespace boost::asio;
#if defined(BOOST_ASIO_HAS_BOOST_BIND)
namespace bindns = boost;
#else // defined(BOOST_ASIO_HAS_BOOST_BIND)
namespace bindns = std;
#endif // defined(BOOST_ASIO_HAS_BOOST_BIND)
using bindns::placeholders::_1;
using bindns::placeholders::_2;
try
{
boost::asio::io_context io_context;
boost::system::error_code ec1;
boost::system::error_code ec2;
readable_pipe p1(io_context);
writable_pipe p2(io_context);
connect_pipe(p1, p2);
std::string data1 = write_data;
boost::asio::write(p2, boost::asio::buffer(data1));
std::string data2;
data2.resize(data1.size());
boost::asio::read(p1, boost::asio::buffer(data2));
BOOST_ASIO_CHECK(data1 == data2);
char read_buffer[sizeof(write_data)];
bool read_completed = false;
boost::asio::async_read(p1,
boost::asio::buffer(read_buffer),
bindns::bind(handle_read,
_1, _2, &read_completed));
bool write_completed = false;
boost::asio::async_write(p2,
boost::asio::buffer(write_data),
bindns::bind(handle_write,
_1, _2, &write_completed));
io_context.run();
BOOST_ASIO_CHECK(read_completed);
BOOST_ASIO_CHECK(write_completed);
BOOST_ASIO_CHECK(memcmp(read_buffer, write_data, sizeof(write_data)) == 0);
}
catch (std::exception&)
{
BOOST_ASIO_CHECK(false);
}
#endif // defined(BOOST_ASIO_HAS_PIPE)
}
} // namespace connect_pipe_compile
//------------------------------------------------------------------------------
BOOST_ASIO_TEST_SUITE
(
"connect_pipe",
BOOST_ASIO_TEST_CASE(connect_pipe_compile::test)
BOOST_ASIO_TEST_CASE(connect_pipe_runtime::test)
)

View File

@@ -0,0 +1,112 @@
//
// coroutine.cpp
// ~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/coroutine.hpp>
#include "unit_test.hpp"
// Must come after all other headers.
#include <boost/asio/yield.hpp>
//------------------------------------------------------------------------------
// Coroutine completes via yield break.
void yield_break_coro(boost::asio::coroutine& coro)
{
reenter (coro)
{
yield return;
yield break;
}
}
void yield_break_test()
{
boost::asio::coroutine coro;
BOOST_ASIO_CHECK(!coro.is_complete());
yield_break_coro(coro);
BOOST_ASIO_CHECK(!coro.is_complete());
yield_break_coro(coro);
BOOST_ASIO_CHECK(coro.is_complete());
}
//------------------------------------------------------------------------------
// Coroutine completes via return.
void return_coro(boost::asio::coroutine& coro)
{
reenter (coro)
{
return;
}
}
void return_test()
{
boost::asio::coroutine coro;
return_coro(coro);
BOOST_ASIO_CHECK(coro.is_complete());
}
//------------------------------------------------------------------------------
// Coroutine completes via exception.
void exception_coro(boost::asio::coroutine& coro)
{
reenter (coro)
{
throw 1;
}
}
void exception_test()
{
boost::asio::coroutine coro;
try { exception_coro(coro); } catch (int) {}
BOOST_ASIO_CHECK(coro.is_complete());
}
//------------------------------------------------------------------------------
// Coroutine completes by falling off the end.
void fall_off_end_coro(boost::asio::coroutine& coro)
{
reenter (coro)
{
}
}
void fall_off_end_test()
{
boost::asio::coroutine coro;
fall_off_end_coro(coro);
BOOST_ASIO_CHECK(coro.is_complete());
}
//------------------------------------------------------------------------------
BOOST_ASIO_TEST_SUITE
(
"coroutine",
BOOST_ASIO_TEST_CASE(yield_break_test)
BOOST_ASIO_TEST_CASE(return_test)
BOOST_ASIO_TEST_CASE(exception_test)
BOOST_ASIO_TEST_CASE(fall_off_end_test)
)

View File

@@ -0,0 +1,448 @@
//
// deadline_timer.cpp
// ~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/deadline_timer.hpp>
#include "unit_test.hpp"
#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
#include <boost/bind/bind.hpp>
#include "archetypes/async_result.hpp"
#include <boost/asio/executor_work_guard.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/placeholders.hpp>
#include <boost/asio/detail/thread.hpp>
using namespace boost::posix_time;
void increment(int* count)
{
++(*count);
}
void decrement_to_zero(boost::asio::deadline_timer* t, int* count)
{
if (*count > 0)
{
--(*count);
int before_value = *count;
t->expires_at(t->expires_at() + seconds(1));
t->async_wait(boost::bind(decrement_to_zero, t, count));
// Completion cannot nest, so count value should remain unchanged.
BOOST_ASIO_CHECK(*count == before_value);
}
}
void increment_if_not_cancelled(int* count,
const boost::system::error_code& ec)
{
if (!ec)
++(*count);
}
void cancel_timer(boost::asio::deadline_timer* t)
{
std::size_t num_cancelled = t->cancel();
BOOST_ASIO_CHECK(num_cancelled == 1);
}
void cancel_one_timer(boost::asio::deadline_timer* t)
{
std::size_t num_cancelled = t->cancel_one();
BOOST_ASIO_CHECK(num_cancelled == 1);
}
ptime now()
{
#if defined(BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK)
return microsec_clock::universal_time();
#else // defined(BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK)
return second_clock::universal_time();
#endif // defined(BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK)
}
void deadline_timer_test()
{
boost::asio::io_context ioc;
int count = 0;
ptime start = now();
boost::asio::deadline_timer t1(ioc, seconds(1));
t1.wait();
// The timer must block until after its expiry time.
ptime end = now();
ptime expected_end = start + seconds(1);
BOOST_ASIO_CHECK(expected_end < end || expected_end == end);
start = now();
boost::asio::deadline_timer t2(ioc, seconds(1) + microseconds(500000));
t2.wait();
// The timer must block until after its expiry time.
end = now();
expected_end = start + seconds(1) + microseconds(500000);
BOOST_ASIO_CHECK(expected_end < end || expected_end == end);
t2.expires_at(t2.expires_at() + seconds(1));
t2.wait();
// The timer must block until after its expiry time.
end = now();
expected_end += seconds(1);
BOOST_ASIO_CHECK(expected_end < end || expected_end == end);
start = now();
t2.expires_from_now(seconds(1) + microseconds(200000));
t2.wait();
// The timer must block until after its expiry time.
end = now();
expected_end = start + seconds(1) + microseconds(200000);
BOOST_ASIO_CHECK(expected_end < end || expected_end == end);
start = now();
boost::asio::deadline_timer t3(ioc, seconds(5));
t3.async_wait(boost::bind(increment, &count));
// No completions can be delivered until run() is called.
BOOST_ASIO_CHECK(count == 0);
ioc.run();
// The run() call will not return until all operations have finished, and
// this should not be until after the timer's expiry time.
BOOST_ASIO_CHECK(count == 1);
end = now();
expected_end = start + seconds(1);
BOOST_ASIO_CHECK(expected_end < end || expected_end == end);
count = 3;
start = now();
boost::asio::deadline_timer t4(ioc, seconds(1));
t4.async_wait(boost::bind(decrement_to_zero, &t4, &count));
// No completions can be delivered until run() is called.
BOOST_ASIO_CHECK(count == 3);
ioc.restart();
ioc.run();
// The run() call will not return until all operations have finished, and
// this should not be until after the timer's final expiry time.
BOOST_ASIO_CHECK(count == 0);
end = now();
expected_end = start + seconds(3);
BOOST_ASIO_CHECK(expected_end < end || expected_end == end);
count = 0;
start = now();
boost::asio::deadline_timer t5(ioc, seconds(10));
t5.async_wait(boost::bind(increment_if_not_cancelled, &count,
boost::asio::placeholders::error));
boost::asio::deadline_timer t6(ioc, seconds(1));
t6.async_wait(boost::bind(cancel_timer, &t5));
// No completions can be delivered until run() is called.
BOOST_ASIO_CHECK(count == 0);
ioc.restart();
ioc.run();
// The timer should have been cancelled, so count should not have changed.
// The total run time should not have been much more than 1 second (and
// certainly far less than 10 seconds).
BOOST_ASIO_CHECK(count == 0);
end = now();
expected_end = start + seconds(2);
BOOST_ASIO_CHECK(end < expected_end);
// Wait on the timer again without cancelling it. This time the asynchronous
// wait should run to completion and increment the counter.
t5.async_wait(boost::bind(increment_if_not_cancelled, &count,
boost::asio::placeholders::error));
ioc.restart();
ioc.run();
// The timer should not have been cancelled, so count should have changed.
// The total time since the timer was created should be more than 10 seconds.
BOOST_ASIO_CHECK(count == 1);
end = now();
expected_end = start + seconds(10);
BOOST_ASIO_CHECK(expected_end < end || expected_end == end);
count = 0;
start = now();
// Start two waits on a timer, one of which will be cancelled. The one
// which is not cancelled should still run to completion and increment the
// counter.
boost::asio::deadline_timer t7(ioc, seconds(3));
t7.async_wait(boost::bind(increment_if_not_cancelled, &count,
boost::asio::placeholders::error));
t7.async_wait(boost::bind(increment_if_not_cancelled, &count,
boost::asio::placeholders::error));
boost::asio::deadline_timer t8(ioc, seconds(1));
t8.async_wait(boost::bind(cancel_one_timer, &t7));
ioc.restart();
ioc.run();
// One of the waits should not have been cancelled, so count should have
// changed. The total time since the timer was created should be more than 3
// seconds.
BOOST_ASIO_CHECK(count == 1);
end = now();
expected_end = start + seconds(3);
BOOST_ASIO_CHECK(expected_end < end || expected_end == end);
}
void timer_handler(const boost::system::error_code&)
{
}
void deadline_timer_cancel_test()
{
static boost::asio::io_context io_context;
struct timer
{
boost::asio::deadline_timer t;
timer() : t(io_context) { t.expires_at(boost::posix_time::pos_infin); }
} timers[50];
timers[2].t.async_wait(&timer_handler);
timers[41].t.async_wait(&timer_handler);
for (int i = 10; i < 20; ++i)
timers[i].t.async_wait(&timer_handler);
BOOST_ASIO_CHECK(timers[2].t.cancel() == 1);
BOOST_ASIO_CHECK(timers[41].t.cancel() == 1);
for (int i = 10; i < 20; ++i)
BOOST_ASIO_CHECK(timers[i].t.cancel() == 1);
}
struct custom_allocation_timer_handler
{
custom_allocation_timer_handler(int* count) : count_(count) {}
void operator()(const boost::system::error_code&) {}
int* count_;
template <typename T>
struct allocator
{
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef T value_type;
template <typename U>
struct rebind
{
typedef allocator<U> other;
};
explicit allocator(int* count) BOOST_ASIO_NOEXCEPT
: count_(count)
{
}
allocator(const allocator& other) BOOST_ASIO_NOEXCEPT
: count_(other.count_)
{
}
template <typename U>
allocator(const allocator<U>& other) BOOST_ASIO_NOEXCEPT
: count_(other.count_)
{
}
pointer allocate(size_type n, const void* = 0)
{
++(*count_);
return static_cast<T*>(::operator new(sizeof(T) * n));
}
void deallocate(pointer p, size_type)
{
--(*count_);
::operator delete(p);
}
size_type max_size() const
{
return ~size_type(0);
}
void construct(pointer p, const T& v)
{
new (p) T(v);
}
void destroy(pointer p)
{
p->~T();
}
int* count_;
};
typedef allocator<int> allocator_type;
allocator_type get_allocator() const BOOST_ASIO_NOEXCEPT
{
return allocator_type(count_);
}
};
void deadline_timer_custom_allocation_test()
{
static boost::asio::io_context io_context;
struct timer
{
boost::asio::deadline_timer t;
timer() : t(io_context) {}
} timers[100];
int allocation_count = 0;
for (int i = 0; i < 50; ++i)
{
timers[i].t.expires_at(boost::posix_time::pos_infin);
timers[i].t.async_wait(custom_allocation_timer_handler(&allocation_count));
}
for (int i = 50; i < 100; ++i)
{
timers[i].t.expires_at(boost::posix_time::neg_infin);
timers[i].t.async_wait(custom_allocation_timer_handler(&allocation_count));
}
for (int i = 0; i < 50; ++i)
timers[i].t.cancel();
io_context.run();
BOOST_ASIO_CHECK(allocation_count == 0);
}
void io_context_run(boost::asio::io_context* ioc)
{
ioc->run();
}
void deadline_timer_thread_test()
{
boost::asio::io_context ioc;
boost::asio::executor_work_guard<boost::asio::io_context::executor_type> work
= boost::asio::make_work_guard(ioc);
boost::asio::deadline_timer t1(ioc);
boost::asio::deadline_timer t2(ioc);
int count = 0;
boost::asio::detail::thread th(boost::bind(io_context_run, &ioc));
t2.expires_from_now(boost::posix_time::seconds(2));
t2.wait();
t1.expires_from_now(boost::posix_time::seconds(2));
t1.async_wait(boost::bind(increment, &count));
t2.expires_from_now(boost::posix_time::seconds(4));
t2.wait();
ioc.stop();
th.join();
BOOST_ASIO_CHECK(count == 1);
}
void deadline_timer_async_result_test()
{
boost::asio::io_context ioc;
boost::asio::deadline_timer t1(ioc);
t1.expires_from_now(boost::posix_time::seconds(1));
int i = t1.async_wait(archetypes::lazy_handler());
BOOST_ASIO_CHECK(i == 42);
ioc.run();
}
#if defined(BOOST_ASIO_HAS_MOVE)
boost::asio::deadline_timer make_timer(boost::asio::io_context& ioc, int* count)
{
boost::asio::deadline_timer t(ioc);
t.expires_from_now(boost::posix_time::seconds(1));
t.async_wait(boost::bind(increment, count));
return t;
}
#endif // defined(BOOST_ASIO_HAS_MOVE)
void deadline_timer_move_test()
{
#if defined(BOOST_ASIO_HAS_MOVE)
boost::asio::io_context io_context1;
boost::asio::io_context io_context2;
int count = 0;
boost::asio::deadline_timer t1 = make_timer(io_context1, &count);
boost::asio::deadline_timer t2 = make_timer(io_context2, &count);
boost::asio::deadline_timer t3 = std::move(t1);
t2 = std::move(t1);
io_context2.run();
BOOST_ASIO_CHECK(count == 1);
io_context1.run();
BOOST_ASIO_CHECK(count == 2);
#endif // defined(BOOST_ASIO_HAS_MOVE)
}
BOOST_ASIO_TEST_SUITE
(
"deadline_timer",
BOOST_ASIO_TEST_CASE(deadline_timer_test)
BOOST_ASIO_TEST_CASE(deadline_timer_cancel_test)
BOOST_ASIO_TEST_CASE(deadline_timer_custom_allocation_test)
BOOST_ASIO_TEST_CASE(deadline_timer_thread_test)
BOOST_ASIO_TEST_CASE(deadline_timer_async_result_test)
BOOST_ASIO_TEST_CASE(deadline_timer_move_test)
)
#else // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
BOOST_ASIO_TEST_SUITE
(
"deadline_timer",
BOOST_ASIO_TEST_CASE(null_test)
)
#endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)

View File

@@ -0,0 +1,25 @@
//
// defer.cpp
// ~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/defer.hpp>
#include "unit_test.hpp"
BOOST_ASIO_TEST_SUITE
(
"defer",
BOOST_ASIO_TEST_CASE(null_test)
)

View File

@@ -0,0 +1,25 @@
//
// detached.cpp
// ~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/detached.hpp>
#include "unit_test.hpp"
BOOST_ASIO_TEST_SUITE
(
"detached",
BOOST_ASIO_TEST_CASE(null_test)
)

View File

@@ -0,0 +1,25 @@
//
// dispatch.cpp
// ~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/dispatch.hpp>
#include "unit_test.hpp"
BOOST_ASIO_TEST_SUITE
(
"dispatch",
BOOST_ASIO_TEST_CASE(null_test)
)

View File

@@ -0,0 +1,89 @@
//
// error.cpp
// ~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/error.hpp>
#include <sstream>
#include "unit_test.hpp"
void test_error_code(const boost::system::error_code& code)
{
boost::system::error_code error(code);
BOOST_ASIO_CHECK(code == error);
BOOST_ASIO_CHECK(!code || error);
BOOST_ASIO_CHECK(!code || !!error);
boost::system::error_code error2(error);
BOOST_ASIO_CHECK(error == error2);
BOOST_ASIO_CHECK(!(error != error2));
boost::system::error_code error3;
error3 = error;
BOOST_ASIO_CHECK(error == error3);
BOOST_ASIO_CHECK(!(error != error3));
std::ostringstream os;
os << error;
BOOST_ASIO_CHECK(!os.str().empty());
}
void error_test()
{
test_error_code(boost::asio::error::access_denied);
test_error_code(boost::asio::error::address_family_not_supported);
test_error_code(boost::asio::error::address_in_use);
test_error_code(boost::asio::error::already_connected);
test_error_code(boost::asio::error::already_started);
test_error_code(boost::asio::error::connection_aborted);
test_error_code(boost::asio::error::connection_refused);
test_error_code(boost::asio::error::connection_reset);
test_error_code(boost::asio::error::bad_descriptor);
test_error_code(boost::asio::error::eof);
test_error_code(boost::asio::error::fault);
test_error_code(boost::asio::error::host_not_found);
test_error_code(boost::asio::error::host_not_found_try_again);
test_error_code(boost::asio::error::host_unreachable);
test_error_code(boost::asio::error::in_progress);
test_error_code(boost::asio::error::interrupted);
test_error_code(boost::asio::error::invalid_argument);
test_error_code(boost::asio::error::message_size);
test_error_code(boost::asio::error::network_down);
test_error_code(boost::asio::error::network_reset);
test_error_code(boost::asio::error::network_unreachable);
test_error_code(boost::asio::error::no_descriptors);
test_error_code(boost::asio::error::no_buffer_space);
test_error_code(boost::asio::error::no_data);
test_error_code(boost::asio::error::no_memory);
test_error_code(boost::asio::error::no_permission);
test_error_code(boost::asio::error::no_protocol_option);
test_error_code(boost::asio::error::no_recovery);
test_error_code(boost::asio::error::not_connected);
test_error_code(boost::asio::error::not_socket);
test_error_code(boost::asio::error::operation_aborted);
test_error_code(boost::asio::error::operation_not_supported);
test_error_code(boost::asio::error::service_not_found);
test_error_code(boost::asio::error::shut_down);
test_error_code(boost::asio::error::timed_out);
test_error_code(boost::asio::error::try_again);
test_error_code(boost::asio::error::would_block);
}
BOOST_ASIO_TEST_SUITE
(
"error",
BOOST_ASIO_TEST_CASE(error_test)
)

View File

@@ -0,0 +1,68 @@
#
# Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
#
# Distributed under the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#
import feature ;
lib socket ; # SOLARIS, QNXNTO
lib nsl ; # SOLARIS
lib ws2_32 ; # NT
lib mswsock ; # NT
lib ipv6 ; # HPUX
lib network ; # HAIKU
project
: requirements
<library>/boost/date_time//boost_date_time
<library>/boost/system//boost_system
<library>/boost/chrono//boost_chrono
<library>/boost/regex//boost_regex
<define>BOOST_ALL_NO_LIB=1
<threading>multi
<target-os>linux:<define>_XOPEN_SOURCE=600
<target-os>linux:<define>_GNU_SOURCE=1
<target-os>solaris:<define>_XOPEN_SOURCE=500
<target-os>solaris:<define>__EXTENSIONS__
<target-os>solaris:<library>socket
<target-os>solaris:<library>nsl
<target-os>windows:<define>_WIN32_WINNT=0x0501
<target-os>windows,<toolset>cw:<library>ws2_32
<target-os>windows,<toolset>cw:<library>mswsock
<target-os>windows,<toolset>gcc:<library>ws2_32
<target-os>windows,<toolset>gcc:<library>mswsock
<target-os>windows,<toolset>gcc-cygwin:<define>__USE_W32_SOCKETS
<target-os>hpux,<toolset>gcc:<define>_XOPEN_SOURCE_EXTENDED
<target-os>hpux:<library>ipv6
<target-os>qnxnto:<library>socket
<target-os>haiku:<library>network
;
test-suite "asio" :
[ run any_executor.cpp ]
[ run blocking.cpp ]
[ run blocking_adaptation.cpp ]
[ run bulk_execute.cpp ]
[ run bulk_guarantee.cpp ]
[ run connect.cpp : : : : execution_connect ]
[ run context_as.cpp ]
[ run execute.cpp ]
[ run executor.cpp ]
[ run invocable_archetype.cpp ]
[ run mapping.cpp ]
[ run operation_state.cpp ]
[ run outstanding_work.cpp ]
[ run prefer_only.cpp ]
[ run receiver.cpp ]
[ run relationship.cpp ]
[ run schedule.cpp ]
[ run scheduler.cpp ]
[ run sender.cpp ]
[ run set_done.cpp ]
[ run set_error.cpp ]
[ run set_value.cpp ]
[ run start.cpp ]
[ run submit.cpp ]
;

View File

@@ -0,0 +1,888 @@
//
// any_executor.cpp
// ~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/execution/any_executor.hpp>
#include <cstring>
#include <boost/asio/thread_pool.hpp>
#include "../unit_test.hpp"
#if defined(BOOST_ASIO_HAS_BOOST_BIND)
# include <boost/bind/bind.hpp>
#else // defined(BOOST_ASIO_HAS_BOOST_BIND)
# include <functional>
#endif // defined(BOOST_ASIO_HAS_BOOST_BIND)
using namespace boost::asio;
#if defined(BOOST_ASIO_HAS_BOOST_BIND)
namespace bindns = boost;
#else // defined(BOOST_ASIO_HAS_BOOST_BIND)
namespace bindns = std;
#endif
struct fat_executor
{
fat_executor(int id)
: id_(id)
{
std::memset(data_, 0, sizeof(data_));
}
template <typename F>
void execute(const F&) const
{
}
std::size_t query(execution::occupancy_t) const
{
return 1;
}
friend bool operator==(const fat_executor& a,
const fat_executor& b) BOOST_ASIO_NOEXCEPT
{
return a.id_ == b.id_;
}
friend bool operator!=(const fat_executor& a,
const fat_executor& b) BOOST_ASIO_NOEXCEPT
{
return a.id_ != b.id_;
}
int id_;
unsigned char data_[1024];
};
namespace boost {
namespace asio {
namespace traits {
#if !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
template <typename F>
struct execute_member<fat_executor, F>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
typedef void result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
#if !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)
template <>
struct query_member<fat_executor, execution::occupancy_t>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
typedef std::size_t result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)
#if !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
template <>
struct equality_comparable<fat_executor>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
} // namespace traits
} // namespace asio
} // namespace boost
void increment(int* count)
{
++(*count);
}
void any_executor_construction_test()
{
typedef execution::any_executor<> ex_no_props_t;
typedef execution::any_executor<
execution::blocking_t
> ex_one_prop_t;
typedef execution::any_executor<
execution::blocking_t,
execution::occupancy_t
> ex_two_props_t;
thread_pool pool(1);
boost::asio::nullptr_t null_ptr = boost::asio::nullptr_t();
ex_two_props_t ex_two_props_1;
BOOST_ASIO_CHECK(ex_two_props_1.target<void>() == 0);
BOOST_ASIO_CHECK(ex_two_props_1 == null_ptr);
ex_two_props_t ex_two_props_2(null_ptr);
BOOST_ASIO_CHECK(ex_two_props_2.target<void>() == 0);
BOOST_ASIO_CHECK(ex_two_props_2 == null_ptr);
BOOST_ASIO_CHECK(ex_two_props_2 == ex_two_props_1);
ex_two_props_t ex_two_props_3(pool.executor());
BOOST_ASIO_CHECK(ex_two_props_3.target<void>() != 0);
BOOST_ASIO_CHECK(ex_two_props_3 != null_ptr);
BOOST_ASIO_CHECK(ex_two_props_3 != ex_two_props_1);
ex_two_props_t ex_two_props_4(ex_two_props_1);
BOOST_ASIO_CHECK(ex_two_props_4.target<void>() == 0);
BOOST_ASIO_CHECK(ex_two_props_4 == null_ptr);
BOOST_ASIO_CHECK(ex_two_props_4 == ex_two_props_1);
ex_two_props_t ex_two_props_5(ex_two_props_3);
BOOST_ASIO_CHECK(ex_two_props_5.target<void>() != 0);
BOOST_ASIO_CHECK(ex_two_props_5 != null_ptr);
BOOST_ASIO_CHECK(ex_two_props_5 == ex_two_props_3);
ex_two_props_t ex_two_props_6 = fat_executor(1);
BOOST_ASIO_CHECK(ex_two_props_6.target<void>() != 0);
BOOST_ASIO_CHECK(ex_two_props_6 != null_ptr);
BOOST_ASIO_CHECK(ex_two_props_6 != ex_two_props_1);
ex_two_props_t ex_two_props_7 = fat_executor(1);
BOOST_ASIO_CHECK(ex_two_props_7.target<void>() != 0);
BOOST_ASIO_CHECK(ex_two_props_7 != null_ptr);
BOOST_ASIO_CHECK(ex_two_props_7 != ex_two_props_1);
BOOST_ASIO_CHECK(ex_two_props_7 == ex_two_props_6);
ex_two_props_t ex_two_props_8 = fat_executor(2);
BOOST_ASIO_CHECK(ex_two_props_8.target<void>() != 0);
BOOST_ASIO_CHECK(ex_two_props_8 != null_ptr);
BOOST_ASIO_CHECK(ex_two_props_8 != ex_two_props_1);
BOOST_ASIO_CHECK(ex_two_props_8 != ex_two_props_6);
BOOST_ASIO_CHECK(ex_two_props_8 != ex_two_props_7);
ex_two_props_t ex_two_props_9(ex_two_props_6);
BOOST_ASIO_CHECK(ex_two_props_9.target<void>() != 0);
BOOST_ASIO_CHECK(ex_two_props_9 != null_ptr);
BOOST_ASIO_CHECK(ex_two_props_9 != ex_two_props_1);
BOOST_ASIO_CHECK(ex_two_props_9 == ex_two_props_6);
BOOST_ASIO_CHECK(ex_two_props_9 == ex_two_props_7);
BOOST_ASIO_CHECK(ex_two_props_9 != ex_two_props_8);
#if defined(BOOST_ASIO_HAS_MOVE)
ex_two_props_t ex_two_props_10(std::move(ex_two_props_1));
BOOST_ASIO_CHECK(ex_two_props_10.target<void>() == 0);
BOOST_ASIO_CHECK(ex_two_props_10 == null_ptr);
BOOST_ASIO_CHECK(ex_two_props_1.target<void>() == 0);
BOOST_ASIO_CHECK(ex_two_props_1 == null_ptr);
ex_two_props_t ex_two_props_11(std::move(ex_two_props_3));
BOOST_ASIO_CHECK(ex_two_props_11.target<void>() != 0);
BOOST_ASIO_CHECK(ex_two_props_11 != null_ptr);
BOOST_ASIO_CHECK(ex_two_props_3.target<void>() == 0);
BOOST_ASIO_CHECK(ex_two_props_3 == null_ptr);
BOOST_ASIO_CHECK(ex_two_props_11 == ex_two_props_5);
ex_two_props_t ex_two_props_12(std::move(ex_two_props_7));
BOOST_ASIO_CHECK(ex_two_props_12.target<void>() != 0);
BOOST_ASIO_CHECK(ex_two_props_12 != null_ptr);
BOOST_ASIO_CHECK(ex_two_props_7.target<void>() == 0);
BOOST_ASIO_CHECK(ex_two_props_7 == null_ptr);
BOOST_ASIO_CHECK(ex_two_props_12 == ex_two_props_6);
BOOST_ASIO_CHECK(ex_two_props_12 != ex_two_props_8);
#endif // defined(BOOST_ASIO_HAS_MOVE)
ex_one_prop_t ex_one_prop_1;
BOOST_ASIO_CHECK(ex_one_prop_1.target<void>() == 0);
BOOST_ASIO_CHECK(ex_one_prop_1 == null_ptr);
ex_one_prop_t ex_one_prop_2(null_ptr);
BOOST_ASIO_CHECK(ex_one_prop_2.target<void>() == 0);
BOOST_ASIO_CHECK(ex_one_prop_2 == null_ptr);
BOOST_ASIO_CHECK(ex_one_prop_2 == ex_one_prop_1);
ex_one_prop_t ex_one_prop_3(pool.executor());
BOOST_ASIO_CHECK(ex_one_prop_3.target<void>() != 0);
BOOST_ASIO_CHECK(ex_one_prop_3 != null_ptr);
BOOST_ASIO_CHECK(ex_one_prop_3 != ex_one_prop_1);
ex_one_prop_t ex_one_prop_4(ex_one_prop_1);
BOOST_ASIO_CHECK(ex_one_prop_4.target<void>() == 0);
BOOST_ASIO_CHECK(ex_one_prop_4 == null_ptr);
BOOST_ASIO_CHECK(ex_one_prop_4 == ex_one_prop_1);
ex_one_prop_t ex_one_prop_5(ex_one_prop_3);
BOOST_ASIO_CHECK(ex_one_prop_5.target<void>() != 0);
BOOST_ASIO_CHECK(ex_one_prop_5 != null_ptr);
BOOST_ASIO_CHECK(ex_one_prop_5 == ex_one_prop_3);
ex_one_prop_t ex_one_prop_6 = fat_executor(1);
BOOST_ASIO_CHECK(ex_one_prop_6.target<void>() != 0);
BOOST_ASIO_CHECK(ex_one_prop_6 != null_ptr);
BOOST_ASIO_CHECK(ex_one_prop_6 != ex_one_prop_1);
ex_one_prop_t ex_one_prop_7 = fat_executor(1);
BOOST_ASIO_CHECK(ex_one_prop_7.target<void>() != 0);
BOOST_ASIO_CHECK(ex_one_prop_7 != null_ptr);
BOOST_ASIO_CHECK(ex_one_prop_7 != ex_one_prop_1);
BOOST_ASIO_CHECK(ex_one_prop_7 == ex_one_prop_6);
ex_one_prop_t ex_one_prop_8 = fat_executor(2);
BOOST_ASIO_CHECK(ex_one_prop_8.target<void>() != 0);
BOOST_ASIO_CHECK(ex_one_prop_8 != null_ptr);
BOOST_ASIO_CHECK(ex_one_prop_8 != ex_one_prop_1);
BOOST_ASIO_CHECK(ex_one_prop_8 != ex_one_prop_6);
BOOST_ASIO_CHECK(ex_one_prop_8 != ex_one_prop_7);
ex_one_prop_t ex_one_prop_9(ex_one_prop_6);
BOOST_ASIO_CHECK(ex_one_prop_9.target<void>() != 0);
BOOST_ASIO_CHECK(ex_one_prop_9 != null_ptr);
BOOST_ASIO_CHECK(ex_one_prop_9 != ex_one_prop_1);
BOOST_ASIO_CHECK(ex_one_prop_9 == ex_one_prop_6);
BOOST_ASIO_CHECK(ex_one_prop_9 == ex_one_prop_7);
BOOST_ASIO_CHECK(ex_one_prop_9 != ex_one_prop_8);
#if defined(BOOST_ASIO_HAS_MOVE)
ex_one_prop_t ex_one_prop_10(std::move(ex_one_prop_1));
BOOST_ASIO_CHECK(ex_one_prop_10.target<void>() == 0);
BOOST_ASIO_CHECK(ex_one_prop_10 == null_ptr);
BOOST_ASIO_CHECK(ex_one_prop_1.target<void>() == 0);
BOOST_ASIO_CHECK(ex_one_prop_1 == null_ptr);
ex_one_prop_t ex_one_prop_11(std::move(ex_one_prop_3));
BOOST_ASIO_CHECK(ex_one_prop_11.target<void>() != 0);
BOOST_ASIO_CHECK(ex_one_prop_11 != null_ptr);
BOOST_ASIO_CHECK(ex_one_prop_3.target<void>() == 0);
BOOST_ASIO_CHECK(ex_one_prop_3 == null_ptr);
BOOST_ASIO_CHECK(ex_one_prop_11 == ex_one_prop_5);
ex_one_prop_t ex_one_prop_12(std::move(ex_one_prop_7));
BOOST_ASIO_CHECK(ex_one_prop_12.target<void>() != 0);
BOOST_ASIO_CHECK(ex_one_prop_12 != null_ptr);
BOOST_ASIO_CHECK(ex_one_prop_7.target<void>() == 0);
BOOST_ASIO_CHECK(ex_one_prop_7 == null_ptr);
BOOST_ASIO_CHECK(ex_one_prop_12 == ex_one_prop_6);
BOOST_ASIO_CHECK(ex_one_prop_12 != ex_one_prop_8);
#endif // defined(BOOST_ASIO_HAS_MOVE)
ex_one_prop_t ex_one_prop_13(ex_two_props_1);
BOOST_ASIO_CHECK(ex_one_prop_13.target<void>() == 0);
BOOST_ASIO_CHECK(ex_one_prop_13 == null_ptr);
ex_one_prop_t ex_one_prop_14(ex_two_props_5);
BOOST_ASIO_CHECK(ex_one_prop_14.target<void>() != 0);
BOOST_ASIO_CHECK(ex_one_prop_14 != null_ptr);
ex_one_prop_t ex_one_prop_15(ex_two_props_9);
BOOST_ASIO_CHECK(ex_one_prop_15.target<void>() != 0);
BOOST_ASIO_CHECK(ex_one_prop_15 != null_ptr);
ex_no_props_t ex_no_props_1;
BOOST_ASIO_CHECK(ex_no_props_1.target<void>() == 0);
BOOST_ASIO_CHECK(ex_no_props_1 == null_ptr);
ex_no_props_t ex_no_props_2(null_ptr);
BOOST_ASIO_CHECK(ex_no_props_2.target<void>() == 0);
BOOST_ASIO_CHECK(ex_no_props_2 == null_ptr);
BOOST_ASIO_CHECK(ex_no_props_2 == ex_no_props_1);
ex_no_props_t ex_no_props_3(pool.executor());
BOOST_ASIO_CHECK(ex_no_props_3.target<void>() != 0);
BOOST_ASIO_CHECK(ex_no_props_3 != null_ptr);
BOOST_ASIO_CHECK(ex_no_props_3 != ex_no_props_1);
ex_no_props_t ex_no_props_4(ex_no_props_1);
BOOST_ASIO_CHECK(ex_no_props_4.target<void>() == 0);
BOOST_ASIO_CHECK(ex_no_props_4 == null_ptr);
BOOST_ASIO_CHECK(ex_no_props_4 == ex_no_props_1);
ex_no_props_t ex_no_props_5(ex_no_props_3);
BOOST_ASIO_CHECK(ex_no_props_5.target<void>() != 0);
BOOST_ASIO_CHECK(ex_no_props_5 != null_ptr);
BOOST_ASIO_CHECK(ex_no_props_5 == ex_no_props_3);
ex_no_props_t ex_no_props_6 = fat_executor(1);
BOOST_ASIO_CHECK(ex_no_props_6.target<void>() != 0);
BOOST_ASIO_CHECK(ex_no_props_6 != null_ptr);
BOOST_ASIO_CHECK(ex_no_props_6 != ex_no_props_1);
ex_no_props_t ex_no_props_7 = fat_executor(1);
BOOST_ASIO_CHECK(ex_no_props_7.target<void>() != 0);
BOOST_ASIO_CHECK(ex_no_props_7 != null_ptr);
BOOST_ASIO_CHECK(ex_no_props_7 != ex_no_props_1);
BOOST_ASIO_CHECK(ex_no_props_7 == ex_no_props_6);
ex_no_props_t ex_no_props_8 = fat_executor(2);
BOOST_ASIO_CHECK(ex_no_props_8.target<void>() != 0);
BOOST_ASIO_CHECK(ex_no_props_8 != null_ptr);
BOOST_ASIO_CHECK(ex_no_props_8 != ex_no_props_1);
BOOST_ASIO_CHECK(ex_no_props_8 != ex_no_props_6);
BOOST_ASIO_CHECK(ex_no_props_8 != ex_no_props_7);
ex_no_props_t ex_no_props_9(ex_no_props_6);
BOOST_ASIO_CHECK(ex_no_props_9.target<void>() != 0);
BOOST_ASIO_CHECK(ex_no_props_9 != null_ptr);
BOOST_ASIO_CHECK(ex_no_props_9 != ex_no_props_1);
BOOST_ASIO_CHECK(ex_no_props_9 == ex_no_props_6);
BOOST_ASIO_CHECK(ex_no_props_9 == ex_no_props_7);
BOOST_ASIO_CHECK(ex_no_props_9 != ex_no_props_8);
#if defined(BOOST_ASIO_HAS_MOVE)
ex_no_props_t ex_no_props_10(std::move(ex_no_props_1));
BOOST_ASIO_CHECK(ex_no_props_10.target<void>() == 0);
BOOST_ASIO_CHECK(ex_no_props_10 == null_ptr);
BOOST_ASIO_CHECK(ex_no_props_1.target<void>() == 0);
BOOST_ASIO_CHECK(ex_no_props_1 == null_ptr);
ex_no_props_t ex_no_props_11(std::move(ex_no_props_3));
BOOST_ASIO_CHECK(ex_no_props_11.target<void>() != 0);
BOOST_ASIO_CHECK(ex_no_props_11 != null_ptr);
BOOST_ASIO_CHECK(ex_no_props_3.target<void>() == 0);
BOOST_ASIO_CHECK(ex_no_props_3 == null_ptr);
BOOST_ASIO_CHECK(ex_no_props_11 == ex_no_props_5);
ex_no_props_t ex_no_props_12(std::move(ex_no_props_7));
BOOST_ASIO_CHECK(ex_no_props_12.target<void>() != 0);
BOOST_ASIO_CHECK(ex_no_props_12 != null_ptr);
BOOST_ASIO_CHECK(ex_no_props_7.target<void>() == 0);
BOOST_ASIO_CHECK(ex_no_props_7 == null_ptr);
BOOST_ASIO_CHECK(ex_no_props_12 == ex_no_props_6);
BOOST_ASIO_CHECK(ex_no_props_12 != ex_no_props_8);
#endif // defined(BOOST_ASIO_HAS_MOVE)
ex_no_props_t ex_no_props_13(ex_two_props_1);
BOOST_ASIO_CHECK(ex_no_props_13.target<void>() == 0);
BOOST_ASIO_CHECK(ex_no_props_13 == null_ptr);
ex_no_props_t ex_no_props_14(ex_two_props_5);
BOOST_ASIO_CHECK(ex_no_props_14.target<void>() != 0);
BOOST_ASIO_CHECK(ex_no_props_14 != null_ptr);
ex_no_props_t ex_no_props_15(ex_two_props_9);
BOOST_ASIO_CHECK(ex_no_props_15.target<void>() != 0);
BOOST_ASIO_CHECK(ex_no_props_15 != null_ptr);
ex_no_props_t ex_no_props_16(ex_one_prop_1);
BOOST_ASIO_CHECK(ex_no_props_16.target<void>() == 0);
BOOST_ASIO_CHECK(ex_no_props_16 == null_ptr);
ex_no_props_t ex_no_props_17(ex_one_prop_5);
BOOST_ASIO_CHECK(ex_no_props_17.target<void>() != 0);
BOOST_ASIO_CHECK(ex_no_props_17 != null_ptr);
ex_no_props_t ex_no_props_18(ex_one_prop_9);
BOOST_ASIO_CHECK(ex_no_props_18.target<void>() != 0);
BOOST_ASIO_CHECK(ex_no_props_18 != null_ptr);
}
void any_executor_assignment_test()
{
typedef execution::any_executor<> ex_no_props_t;
typedef execution::any_executor<
execution::blocking_t
> ex_one_prop_t;
typedef execution::any_executor<
execution::blocking_t,
execution::occupancy_t
> ex_two_props_t;
thread_pool pool(1);
boost::asio::nullptr_t null_ptr = boost::asio::nullptr_t();
ex_two_props_t ex_two_props_1;
ex_two_props_t ex_two_props_2;
ex_two_props_2 = null_ptr;
BOOST_ASIO_CHECK(ex_two_props_2.target<void>() == 0);
ex_two_props_t ex_two_props_3;
ex_two_props_3 = pool.executor();
BOOST_ASIO_CHECK(ex_two_props_3.target<void>() != 0);
ex_two_props_t ex_two_props_4;
ex_two_props_4 = ex_two_props_1;
BOOST_ASIO_CHECK(ex_two_props_4.target<void>() == 0);
BOOST_ASIO_CHECK(ex_two_props_4 == ex_two_props_1);
ex_two_props_4 = ex_two_props_3;
BOOST_ASIO_CHECK(ex_two_props_4.target<void>() != 0);
BOOST_ASIO_CHECK(ex_two_props_4 == ex_two_props_3);
ex_two_props_t ex_two_props_5;
ex_two_props_5 = fat_executor(1);
BOOST_ASIO_CHECK(ex_two_props_5.target<void>() != 0);
BOOST_ASIO_CHECK(ex_two_props_5 != null_ptr);
BOOST_ASIO_CHECK(ex_two_props_5 != ex_two_props_1);
ex_two_props_t ex_two_props_6;
ex_two_props_6 = fat_executor(1);
BOOST_ASIO_CHECK(ex_two_props_6.target<void>() != 0);
BOOST_ASIO_CHECK(ex_two_props_6 != null_ptr);
BOOST_ASIO_CHECK(ex_two_props_6 != ex_two_props_1);
BOOST_ASIO_CHECK(ex_two_props_6 == ex_two_props_5);
ex_two_props_6 = fat_executor(2);
BOOST_ASIO_CHECK(ex_two_props_6.target<void>() != 0);
BOOST_ASIO_CHECK(ex_two_props_6 != null_ptr);
BOOST_ASIO_CHECK(ex_two_props_6 != ex_two_props_1);
BOOST_ASIO_CHECK(ex_two_props_6 != ex_two_props_5);
ex_two_props_t ex_two_props_7;
ex_two_props_7 = ex_two_props_5;
BOOST_ASIO_CHECK(ex_two_props_7.target<void>() != 0);
BOOST_ASIO_CHECK(ex_two_props_7 != null_ptr);
BOOST_ASIO_CHECK(ex_two_props_7 != ex_two_props_1);
BOOST_ASIO_CHECK(ex_two_props_7 == ex_two_props_5);
BOOST_ASIO_CHECK(ex_two_props_7 != ex_two_props_6);
#if defined(BOOST_ASIO_HAS_MOVE)
ex_two_props_t ex_two_props_8;
ex_two_props_8 = std::move(ex_two_props_1);
BOOST_ASIO_CHECK(ex_two_props_8.target<void>() == 0);
BOOST_ASIO_CHECK(ex_two_props_1.target<void>() == 0);
ex_two_props_8 = std::move(ex_two_props_3);
BOOST_ASIO_CHECK(ex_two_props_8.target<void>() != 0);
BOOST_ASIO_CHECK(ex_two_props_3.target<void>() == 0);
BOOST_ASIO_CHECK(ex_two_props_8 == ex_two_props_4);
ex_two_props_8 = std::move(ex_two_props_5);
BOOST_ASIO_CHECK(ex_two_props_8.target<void>() != 0);
BOOST_ASIO_CHECK(ex_two_props_5.target<void>() == 0);
BOOST_ASIO_CHECK(ex_two_props_8 == ex_two_props_7);
#endif // defined(BOOST_ASIO_HAS_MOVE)
ex_one_prop_t ex_one_prop_1;
ex_one_prop_t ex_one_prop_2;
ex_one_prop_2 = null_ptr;
BOOST_ASIO_CHECK(ex_one_prop_2.target<void>() == 0);
ex_one_prop_t ex_one_prop_3;
ex_one_prop_3 = pool.executor();
BOOST_ASIO_CHECK(ex_one_prop_3.target<void>() != 0);
ex_one_prop_t ex_one_prop_4;
ex_one_prop_4 = ex_one_prop_1;
BOOST_ASIO_CHECK(ex_one_prop_4.target<void>() == 0);
BOOST_ASIO_CHECK(ex_one_prop_4 == ex_one_prop_1);
ex_one_prop_4 = ex_one_prop_3;
BOOST_ASIO_CHECK(ex_one_prop_4.target<void>() != 0);
BOOST_ASIO_CHECK(ex_one_prop_4 == ex_one_prop_3);
ex_one_prop_t ex_one_prop_5;
ex_one_prop_5 = fat_executor(1);
BOOST_ASIO_CHECK(ex_one_prop_5.target<void>() != 0);
BOOST_ASIO_CHECK(ex_one_prop_5 != null_ptr);
BOOST_ASIO_CHECK(ex_one_prop_5 != ex_one_prop_1);
ex_one_prop_t ex_one_prop_6;
ex_one_prop_6 = fat_executor(1);
BOOST_ASIO_CHECK(ex_one_prop_6.target<void>() != 0);
BOOST_ASIO_CHECK(ex_one_prop_6 != null_ptr);
BOOST_ASIO_CHECK(ex_one_prop_6 != ex_one_prop_1);
BOOST_ASIO_CHECK(ex_one_prop_6 == ex_one_prop_5);
ex_one_prop_6 = fat_executor(2);
BOOST_ASIO_CHECK(ex_one_prop_6.target<void>() != 0);
BOOST_ASIO_CHECK(ex_one_prop_6 != null_ptr);
BOOST_ASIO_CHECK(ex_one_prop_6 != ex_one_prop_1);
BOOST_ASIO_CHECK(ex_one_prop_6 != ex_one_prop_5);
ex_one_prop_t ex_one_prop_7;
ex_one_prop_7 = ex_one_prop_5;
BOOST_ASIO_CHECK(ex_one_prop_7.target<void>() != 0);
BOOST_ASIO_CHECK(ex_one_prop_7 != null_ptr);
BOOST_ASIO_CHECK(ex_one_prop_7 != ex_one_prop_1);
BOOST_ASIO_CHECK(ex_one_prop_7 == ex_one_prop_5);
BOOST_ASIO_CHECK(ex_one_prop_7 != ex_one_prop_6);
#if defined(BOOST_ASIO_HAS_MOVE)
ex_one_prop_t ex_one_prop_8;
ex_one_prop_8 = std::move(ex_one_prop_1);
BOOST_ASIO_CHECK(ex_one_prop_8.target<void>() == 0);
BOOST_ASIO_CHECK(ex_one_prop_1.target<void>() == 0);
ex_one_prop_8 = std::move(ex_one_prop_3);
BOOST_ASIO_CHECK(ex_one_prop_8.target<void>() != 0);
BOOST_ASIO_CHECK(ex_one_prop_3.target<void>() == 0);
BOOST_ASIO_CHECK(ex_one_prop_8 == ex_one_prop_4);
ex_one_prop_8 = std::move(ex_one_prop_5);
BOOST_ASIO_CHECK(ex_one_prop_8.target<void>() != 0);
BOOST_ASIO_CHECK(ex_one_prop_5.target<void>() == 0);
BOOST_ASIO_CHECK(ex_one_prop_8 == ex_one_prop_7);
#endif // defined(BOOST_ASIO_HAS_MOVE)
ex_one_prop_t ex_one_prop_9;
ex_one_prop_9 = ex_two_props_1;
BOOST_ASIO_CHECK(ex_one_prop_9.target<void>() == 0);
ex_one_prop_9 = ex_two_props_4;
BOOST_ASIO_CHECK(ex_one_prop_9.target<void>() != 0);
ex_one_prop_9 = ex_two_props_7;
BOOST_ASIO_CHECK(ex_one_prop_9.target<void>() != 0);
ex_no_props_t ex_no_props_1;
ex_no_props_t ex_no_props_2;
ex_no_props_2 = null_ptr;
BOOST_ASIO_CHECK(ex_no_props_2.target<void>() == 0);
ex_no_props_t ex_no_props_3;
ex_no_props_3 = pool.executor();
BOOST_ASIO_CHECK(ex_no_props_3.target<void>() != 0);
ex_no_props_t ex_no_props_4;
ex_no_props_4 = ex_no_props_1;
BOOST_ASIO_CHECK(ex_no_props_4.target<void>() == 0);
BOOST_ASIO_CHECK(ex_no_props_4 == ex_no_props_1);
ex_no_props_4 = ex_no_props_3;
BOOST_ASIO_CHECK(ex_no_props_4.target<void>() != 0);
BOOST_ASIO_CHECK(ex_no_props_4 == ex_no_props_3);
ex_no_props_t ex_no_props_5;
ex_no_props_5 = fat_executor(1);
BOOST_ASIO_CHECK(ex_no_props_5.target<void>() != 0);
BOOST_ASIO_CHECK(ex_no_props_5 != null_ptr);
BOOST_ASIO_CHECK(ex_no_props_5 != ex_no_props_1);
ex_no_props_t ex_no_props_6;
ex_no_props_6 = fat_executor(1);
BOOST_ASIO_CHECK(ex_no_props_6.target<void>() != 0);
BOOST_ASIO_CHECK(ex_no_props_6 != null_ptr);
BOOST_ASIO_CHECK(ex_no_props_6 != ex_no_props_1);
BOOST_ASIO_CHECK(ex_no_props_6 == ex_no_props_5);
ex_no_props_6 = fat_executor(2);
BOOST_ASIO_CHECK(ex_no_props_6.target<void>() != 0);
BOOST_ASIO_CHECK(ex_no_props_6 != null_ptr);
BOOST_ASIO_CHECK(ex_no_props_6 != ex_no_props_1);
BOOST_ASIO_CHECK(ex_no_props_6 != ex_no_props_5);
ex_no_props_t ex_no_props_7;
ex_no_props_7 = ex_no_props_5;
BOOST_ASIO_CHECK(ex_no_props_7.target<void>() != 0);
BOOST_ASIO_CHECK(ex_no_props_7 != null_ptr);
BOOST_ASIO_CHECK(ex_no_props_7 != ex_no_props_1);
BOOST_ASIO_CHECK(ex_no_props_7 == ex_no_props_5);
BOOST_ASIO_CHECK(ex_no_props_7 != ex_no_props_6);
#if defined(BOOST_ASIO_HAS_MOVE)
ex_no_props_t ex_no_props_8;
ex_no_props_8 = std::move(ex_no_props_1);
BOOST_ASIO_CHECK(ex_no_props_8.target<void>() == 0);
BOOST_ASIO_CHECK(ex_no_props_1.target<void>() == 0);
ex_no_props_8 = std::move(ex_no_props_3);
BOOST_ASIO_CHECK(ex_no_props_8.target<void>() != 0);
BOOST_ASIO_CHECK(ex_no_props_3.target<void>() == 0);
BOOST_ASIO_CHECK(ex_no_props_8 == ex_no_props_4);
ex_no_props_8 = std::move(ex_no_props_5);
BOOST_ASIO_CHECK(ex_no_props_8.target<void>() != 0);
BOOST_ASIO_CHECK(ex_no_props_5.target<void>() == 0);
BOOST_ASIO_CHECK(ex_no_props_8 == ex_no_props_7);
#endif // defined(BOOST_ASIO_HAS_MOVE)
ex_no_props_t ex_no_props_9;
ex_no_props_9 = ex_two_props_1;
BOOST_ASIO_CHECK(ex_no_props_9.target<void>() == 0);
ex_no_props_9 = ex_two_props_4;
BOOST_ASIO_CHECK(ex_no_props_9.target<void>() != 0);
ex_no_props_9 = ex_two_props_7;
BOOST_ASIO_CHECK(ex_no_props_9.target<void>() != 0);
ex_no_props_9 = ex_one_prop_1;
BOOST_ASIO_CHECK(ex_no_props_9.target<void>() == 0);
ex_no_props_9 = ex_one_prop_4;
BOOST_ASIO_CHECK(ex_no_props_9.target<void>() != 0);
ex_no_props_9 = ex_one_prop_7;
BOOST_ASIO_CHECK(ex_no_props_9.target<void>() != 0);
}
void any_executor_swap_test()
{
typedef execution::any_executor<> ex_no_props_t;
typedef execution::any_executor<
execution::blocking_t
> ex_one_prop_t;
typedef execution::any_executor<
execution::blocking_t,
execution::occupancy_t
> ex_two_props_t;
thread_pool pool1(1);
thread_pool pool2(1);
ex_no_props_t ex_no_props_1(pool1.executor());
ex_no_props_t ex_no_props_2(pool2.executor());
ex_no_props_t ex_no_props_3(ex_no_props_1);
ex_no_props_t ex_no_props_4(ex_no_props_2);
BOOST_ASIO_CHECK(ex_no_props_3 == ex_no_props_1);
BOOST_ASIO_CHECK(ex_no_props_4 == ex_no_props_2);
ex_no_props_3.swap(ex_no_props_4);
BOOST_ASIO_CHECK(ex_no_props_3 == ex_no_props_2);
BOOST_ASIO_CHECK(ex_no_props_4 == ex_no_props_1);
execution::swap(ex_no_props_3, ex_no_props_4);
BOOST_ASIO_CHECK(ex_no_props_3 == ex_no_props_1);
BOOST_ASIO_CHECK(ex_no_props_4 == ex_no_props_2);
ex_one_prop_t ex_one_prop_1(pool1.executor());
ex_one_prop_t ex_one_prop_2(pool2.executor());
ex_one_prop_t ex_one_prop_3(ex_one_prop_1);
ex_one_prop_t ex_one_prop_4(ex_one_prop_2);
BOOST_ASIO_CHECK(ex_one_prop_3 == ex_one_prop_1);
BOOST_ASIO_CHECK(ex_one_prop_4 == ex_one_prop_2);
ex_one_prop_3.swap(ex_one_prop_4);
BOOST_ASIO_CHECK(ex_one_prop_3 == ex_one_prop_2);
BOOST_ASIO_CHECK(ex_one_prop_4 == ex_one_prop_1);
execution::swap(ex_one_prop_3, ex_one_prop_4);
BOOST_ASIO_CHECK(ex_one_prop_3 == ex_one_prop_1);
BOOST_ASIO_CHECK(ex_one_prop_4 == ex_one_prop_2);
ex_two_props_t ex_two_props_1(pool1.executor());
ex_two_props_t ex_two_props_2(pool2.executor());
ex_two_props_t ex_two_props_3(ex_two_props_1);
ex_two_props_t ex_two_props_4(ex_two_props_2);
BOOST_ASIO_CHECK(ex_two_props_3 == ex_two_props_1);
BOOST_ASIO_CHECK(ex_two_props_4 == ex_two_props_2);
ex_two_props_3.swap(ex_two_props_4);
BOOST_ASIO_CHECK(ex_two_props_3 == ex_two_props_2);
BOOST_ASIO_CHECK(ex_two_props_4 == ex_two_props_1);
execution::swap(ex_two_props_3, ex_two_props_4);
BOOST_ASIO_CHECK(ex_two_props_3 == ex_two_props_1);
BOOST_ASIO_CHECK(ex_two_props_4 == ex_two_props_2);
}
void any_executor_query_test()
{
thread_pool pool(1);
execution::any_executor<
execution::blocking_t,
execution::outstanding_work_t,
execution::relationship_t,
execution::mapping_t::thread_t,
execution::occupancy_t>
ex(pool.executor());
BOOST_ASIO_CHECK(
boost::asio::query(ex, boost::asio::execution::blocking)
== boost::asio::execution::blocking.possibly);
BOOST_ASIO_CHECK(
boost::asio::query(ex, boost::asio::execution::blocking.possibly)
== boost::asio::execution::blocking.possibly);
BOOST_ASIO_CHECK(
boost::asio::query(ex, boost::asio::execution::outstanding_work)
== boost::asio::execution::outstanding_work.untracked);
BOOST_ASIO_CHECK(
boost::asio::query(ex, boost::asio::execution::outstanding_work.untracked)
== boost::asio::execution::outstanding_work.untracked);
BOOST_ASIO_CHECK(
boost::asio::query(ex, boost::asio::execution::relationship)
== boost::asio::execution::relationship.fork);
BOOST_ASIO_CHECK(
boost::asio::query(ex, boost::asio::execution::relationship.fork)
== boost::asio::execution::relationship.fork);
BOOST_ASIO_CHECK(
boost::asio::query(ex, boost::asio::execution::mapping)
== boost::asio::execution::mapping.thread);
BOOST_ASIO_CHECK(
boost::asio::query(ex, boost::asio::execution::occupancy)
== 1);
}
void any_executor_execute_test()
{
int count = 0;
thread_pool pool(1);
execution::any_executor<
execution::blocking_t::possibly_t,
execution::blocking_t::never_t,
execution::outstanding_work_t::untracked_t,
execution::outstanding_work_t::tracked_t,
execution::relationship_t::continuation_t>
ex(pool.executor());
boost::asio::execution::execute(pool.executor(),
bindns::bind(increment, &count));
boost::asio::execution::execute(
boost::asio::require(pool.executor(),
boost::asio::execution::blocking.possibly),
bindns::bind(increment, &count));
boost::asio::execution::execute(
boost::asio::require(pool.executor(),
boost::asio::execution::blocking.never),
bindns::bind(increment, &count));
boost::asio::execution::execute(
boost::asio::require(pool.executor(),
boost::asio::execution::blocking.never,
boost::asio::execution::outstanding_work.tracked),
bindns::bind(increment, &count));
boost::asio::execution::execute(
boost::asio::require(pool.executor(),
boost::asio::execution::blocking.never,
boost::asio::execution::outstanding_work.untracked),
bindns::bind(increment, &count));
boost::asio::execution::execute(
boost::asio::require(pool.executor(),
boost::asio::execution::blocking.never,
boost::asio::execution::outstanding_work.untracked,
boost::asio::execution::relationship.continuation),
bindns::bind(increment, &count));
pool.wait();
BOOST_ASIO_CHECK(count == 6);
}
BOOST_ASIO_TEST_SUITE
(
"any_executor",
BOOST_ASIO_TEST_CASE(any_executor_construction_test)
BOOST_ASIO_TEST_CASE(any_executor_assignment_test)
BOOST_ASIO_TEST_CASE(any_executor_swap_test)
BOOST_ASIO_TEST_CASE(any_executor_query_test)
BOOST_ASIO_TEST_CASE(any_executor_execute_test)
)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,330 @@
//
// bulk_execute.cpp
// ~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/execution/bulk_execute.hpp>
#include <boost/asio/execution.hpp>
#include "../unit_test.hpp"
namespace exec = boost::asio::execution;
int call_count = 0;
struct operation_state
{
void start() BOOST_ASIO_NOEXCEPT
{
}
};
namespace boost {
namespace asio {
namespace traits {
#if !defined(BOOST_ASIO_HAS_DEDUCED_START_MEMBER_TRAIT)
template <>
struct start_member<operation_state>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
typedef void result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_START_MEMBER_TRAIT)
} // namespace traits
} // namespace asio
} // namespace boost
struct sender : exec::sender_base
{
sender()
{
}
template <typename R>
operation_state connect(BOOST_ASIO_MOVE_ARG(R) r) const
{
(void)r;
return operation_state();
}
};
namespace boost {
namespace asio {
namespace traits {
#if !defined(BOOST_ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT)
template <typename R>
struct connect_member<const sender, R>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
typedef operation_state result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT)
} // namespace traits
} // namespace asio
} // namespace boost
struct no_bulk_execute
{
};
struct const_member_bulk_execute
{
const_member_bulk_execute()
{
}
template <typename F>
sender bulk_execute(BOOST_ASIO_MOVE_ARG(F), std::size_t) const
{
++call_count;
return sender();
}
};
namespace boost {
namespace asio {
namespace traits {
#if !defined(BOOST_ASIO_HAS_DEDUCED_SUBMIT_MEMBER_TRAIT)
template <typename F, typename N>
struct bulk_execute_member<const const_member_bulk_execute, F, N>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
typedef sender result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SUBMIT_MEMBER_TRAIT)
} // namespace traits
} // namespace asio
} // namespace boost
struct free_bulk_execute
{
free_bulk_execute()
{
}
template <typename F>
friend sender bulk_execute(const free_bulk_execute&,
BOOST_ASIO_MOVE_ARG(F), std::size_t)
{
++call_count;
return sender();
}
};
namespace boost {
namespace asio {
namespace traits {
#if !defined(BOOST_ASIO_HAS_DEDUCED_SUBMIT_FREE_TRAIT)
template <typename F, typename N>
struct bulk_execute_free<const free_bulk_execute, F, N>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
typedef sender result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SUBMIT_FREE_TRAIT)
} // namespace traits
} // namespace asio
} // namespace boost
struct executor
{
executor()
{
}
executor(const executor&) BOOST_ASIO_NOEXCEPT
{
}
#if defined(BOOST_ASIO_HAS_MOVE)
executor(executor&&) BOOST_ASIO_NOEXCEPT
{
}
#endif // defined(BOOST_ASIO_HAS_MOVE)
template <typename F>
void execute(BOOST_ASIO_MOVE_ARG(F) f) const BOOST_ASIO_NOEXCEPT
{
typename boost::asio::decay<F>::type tmp(BOOST_ASIO_MOVE_CAST(F)(f));
tmp();
}
bool operator==(const executor&) const BOOST_ASIO_NOEXCEPT
{
return true;
}
bool operator!=(const executor&) const BOOST_ASIO_NOEXCEPT
{
return false;
}
};
namespace boost {
namespace asio {
namespace traits {
#if !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
template <typename F>
struct execute_member<executor, F>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
typedef void result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
#if !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
template <>
struct equality_comparable<executor>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
} // namespace traits
} // namespace asio
} // namespace boost
void test_can_bulk_execute()
{
BOOST_ASIO_CONSTEXPR bool b1 = exec::can_bulk_execute<
no_bulk_execute&, exec::invocable_archetype, std::size_t>::value;
BOOST_ASIO_CHECK(b1 == false);
BOOST_ASIO_CONSTEXPR bool b2 = exec::can_bulk_execute<
const no_bulk_execute&, exec::invocable_archetype, std::size_t>::value;
BOOST_ASIO_CHECK(b2 == false);
BOOST_ASIO_CONSTEXPR bool b3 = exec::can_bulk_execute<
const_member_bulk_execute&, exec::invocable_archetype, std::size_t>::value;
BOOST_ASIO_CHECK(b3 == true);
BOOST_ASIO_CONSTEXPR bool b4 = exec::can_bulk_execute<
const const_member_bulk_execute&,
exec::invocable_archetype, std::size_t>::value;
BOOST_ASIO_CHECK(b4 == true);
BOOST_ASIO_CONSTEXPR bool b5 = exec::can_bulk_execute<
free_bulk_execute&, exec::invocable_archetype, std::size_t>::value;
BOOST_ASIO_CHECK(b5 == true);
BOOST_ASIO_CONSTEXPR bool b6 = exec::can_bulk_execute<
const free_bulk_execute&, exec::invocable_archetype, std::size_t>::value;
BOOST_ASIO_CHECK(b6 == true);
BOOST_ASIO_CONSTEXPR bool b7 = exec::can_bulk_execute<
executor&, exec::invocable_archetype, std::size_t>::value;
BOOST_ASIO_CHECK(b7 == true);
BOOST_ASIO_CONSTEXPR bool b8 = exec::can_bulk_execute<
const executor&, exec::invocable_archetype, std::size_t>::value;
BOOST_ASIO_CHECK(b8 == true);
}
void handler(std::size_t)
{
}
void counting_handler(std::size_t)
{
++call_count;
}
void completion_handler()
{
++call_count;
}
void test_bulk_execute()
{
call_count = 0;
const_member_bulk_execute ex1;
exec::bulk_execute(ex1, handler, 2);
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
const const_member_bulk_execute ex2;
exec::bulk_execute(ex2, handler, 2);
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
exec::bulk_execute(const_member_bulk_execute(), handler, 2);
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
free_bulk_execute ex3;
exec::bulk_execute(ex3, handler, 2);
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
const free_bulk_execute ex4;
exec::bulk_execute(ex4, handler, 2);
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
exec::bulk_execute(free_bulk_execute(), handler, 2);
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
executor ex5;
exec::execute(
exec::bulk_execute(ex5, counting_handler, 10u),
completion_handler);
BOOST_ASIO_CHECK(call_count == 11);
call_count = 0;
const executor ex6;
exec::execute(
exec::bulk_execute(ex6, counting_handler, 10u),
completion_handler);
BOOST_ASIO_CHECK(call_count == 11);
call_count = 0;
exec::execute(
exec::bulk_execute(executor(), counting_handler, 10u),
completion_handler);
BOOST_ASIO_CHECK(call_count == 11);
}
BOOST_ASIO_TEST_SUITE
(
"bulk_execute",
BOOST_ASIO_TEST_CASE(test_can_bulk_execute)
BOOST_ASIO_TEST_CASE(test_bulk_execute)
)

View File

@@ -0,0 +1,497 @@
//
// connect.cpp
// ~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/execution/connect.hpp>
#include <boost/system/error_code.hpp>
#include "../unit_test.hpp"
namespace exec = boost::asio::execution;
static int call_count = 0;
struct operation_state
{
void start() BOOST_ASIO_NOEXCEPT
{
}
};
namespace boost {
namespace asio {
namespace traits {
#if !defined(BOOST_ASIO_HAS_DEDUCED_START_MEMBER_TRAIT)
template <>
struct start_member<operation_state>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
typedef void result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_START_MEMBER_TRAIT)
} // namespace traits
} // namespace asio
} // namespace boost
struct no_connect_1
{
};
struct no_connect_2 : exec::sender_base
{
};
struct no_connect_3
{
template <typename R>
operation_state connect(BOOST_ASIO_MOVE_ARG(R) r)
{
(void)r;
return operation_state();
}
};
#if !defined(BOOST_ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT)
namespace boost {
namespace asio {
namespace traits {
template <typename R>
struct connect_member<no_connect_3, R>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
typedef operation_state result_type;
};
} // namespace traits
} // namespace asio
} // namespace boost
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT)
struct const_member_connect : exec::sender_base
{
const_member_connect()
{
}
template <typename R>
operation_state connect(BOOST_ASIO_MOVE_ARG(R) r) const
{
(void)r;
++call_count;
return operation_state();
}
};
#if !defined(BOOST_ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT)
namespace boost {
namespace asio {
namespace traits {
template <typename R>
struct connect_member<const const_member_connect, R>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
typedef operation_state result_type;
};
} // namespace traits
} // namespace asio
} // namespace boost
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT)
struct free_connect_const_receiver : exec::sender_base
{
free_connect_const_receiver()
{
}
template <typename R>
friend operation_state connect(
const free_connect_const_receiver&, BOOST_ASIO_MOVE_ARG(R) r)
{
(void)r;
++call_count;
return operation_state();
}
};
#if !defined(BOOST_ASIO_HAS_DEDUCED_CONNECT_FREE_TRAIT)
namespace boost {
namespace asio {
namespace traits {
template <typename R>
struct connect_free<const free_connect_const_receiver, R>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
typedef operation_state result_type;
};
} // namespace traits
} // namespace asio
} // namespace boost
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_CONNECT_FREE_TRAIT)
struct non_const_member_connect : exec::sender_base
{
template <typename R>
operation_state connect(BOOST_ASIO_MOVE_ARG(R) r)
{
(void)r;
++call_count;
return operation_state();
}
};
#if !defined(BOOST_ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT)
namespace boost {
namespace asio {
namespace traits {
template <typename R>
struct connect_member<non_const_member_connect, R>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
typedef operation_state result_type;
};
} // namespace traits
} // namespace asio
} // namespace boost
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT)
struct free_connect_non_const_receiver : exec::sender_base
{
free_connect_non_const_receiver()
{
}
template <typename R>
friend operation_state connect(
free_connect_non_const_receiver&, BOOST_ASIO_MOVE_ARG(R) r)
{
(void)r;
++call_count;
return operation_state();
}
};
#if !defined(BOOST_ASIO_HAS_DEDUCED_CONNECT_FREE_TRAIT)
namespace boost {
namespace asio {
namespace traits {
template <typename R>
struct connect_free<free_connect_non_const_receiver, R>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
typedef operation_state result_type;
};
} // namespace traits
} // namespace asio
} // namespace boost
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_CONNECT_FREE_TRAIT)
struct receiver
{
receiver()
{
}
receiver(const receiver&)
{
}
#if defined(BOOST_ASIO_HAS_MOVE)
receiver(receiver&&) BOOST_ASIO_NOEXCEPT
{
}
#endif // defined(BOOST_ASIO_HAS_MOVE)
template <typename E>
void set_error(BOOST_ASIO_MOVE_ARG(E) e) BOOST_ASIO_NOEXCEPT
{
(void)e;
}
void set_done() BOOST_ASIO_NOEXCEPT
{
}
};
namespace boost {
namespace asio {
namespace traits {
#if !defined(BOOST_ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)
template <typename E>
struct set_error_member<receiver, E>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
typedef void result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)
#if !defined(BOOST_ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)
template <>
struct set_done_member<receiver>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
typedef void result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)
} // namespace traits
} // namespace asio
} // namespace boost
struct executor
{
executor()
{
}
executor(const executor&) BOOST_ASIO_NOEXCEPT
{
}
#if defined(BOOST_ASIO_HAS_MOVE)
executor(executor&&) BOOST_ASIO_NOEXCEPT
{
}
#endif // defined(BOOST_ASIO_HAS_MOVE)
template <typename F>
void execute(BOOST_ASIO_MOVE_ARG(F) f) const BOOST_ASIO_NOEXCEPT
{
(void)f;
}
bool operator==(const executor&) const BOOST_ASIO_NOEXCEPT
{
return true;
}
bool operator!=(const executor&) const BOOST_ASIO_NOEXCEPT
{
return false;
}
};
namespace boost {
namespace asio {
namespace traits {
#if !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
template <typename F>
struct execute_member<executor, F>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
typedef void result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)
#if !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
template <>
struct equality_comparable<executor>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
} // namespace traits
} // namespace asio
} // namespace boost
void test_can_connect()
{
BOOST_ASIO_CONSTEXPR bool b1 = exec::can_connect<
no_connect_1&, receiver>::value;
BOOST_ASIO_CHECK(b1 == false);
BOOST_ASIO_CONSTEXPR bool b2 = exec::can_connect<
const no_connect_1&, receiver>::value;
BOOST_ASIO_CHECK(b2 == false);
BOOST_ASIO_CONSTEXPR bool b3 = exec::can_connect<
no_connect_2&, receiver>::value;
BOOST_ASIO_CHECK(b3 == false);
BOOST_ASIO_CONSTEXPR bool b4 = exec::can_connect<
const no_connect_2&, receiver>::value;
BOOST_ASIO_CHECK(b4 == false);
BOOST_ASIO_CONSTEXPR bool b5 = exec::can_connect<
no_connect_3&, receiver>::value;
BOOST_ASIO_CHECK(b5 == false);
BOOST_ASIO_CONSTEXPR bool b6 = exec::can_connect<
const no_connect_3&, receiver>::value;
BOOST_ASIO_CHECK(b6 == false);
BOOST_ASIO_CONSTEXPR bool b7 = exec::can_connect<
const_member_connect&, receiver>::value;
BOOST_ASIO_CHECK(b7 == true);
BOOST_ASIO_CONSTEXPR bool b8 = exec::can_connect<
const const_member_connect&, receiver>::value;
BOOST_ASIO_CHECK(b8 == true);
BOOST_ASIO_CONSTEXPR bool b9 = exec::can_connect<
free_connect_const_receiver&, receiver>::value;
BOOST_ASIO_CHECK(b9 == true);
BOOST_ASIO_CONSTEXPR bool b10 = exec::can_connect<
const free_connect_const_receiver&, receiver>::value;
BOOST_ASIO_CHECK(b10 == true);
BOOST_ASIO_CONSTEXPR bool b11 = exec::can_connect<
non_const_member_connect&, receiver>::value;
BOOST_ASIO_CHECK(b11 == true);
BOOST_ASIO_CONSTEXPR bool b12 = exec::can_connect<
const non_const_member_connect&, receiver>::value;
BOOST_ASIO_CHECK(b12 == false);
BOOST_ASIO_CONSTEXPR bool b13 = exec::can_connect<
free_connect_non_const_receiver&, receiver>::value;
BOOST_ASIO_CHECK(b13 == true);
BOOST_ASIO_CONSTEXPR bool b14 = exec::can_connect<
const free_connect_non_const_receiver&, receiver>::value;
BOOST_ASIO_CHECK(b14 == false);
BOOST_ASIO_CONSTEXPR bool b15 = exec::can_connect<
executor&, receiver>::value;
BOOST_ASIO_CHECK(b15 == true);
BOOST_ASIO_CONSTEXPR bool b16 = exec::can_connect<
const executor&, receiver>::value;
BOOST_ASIO_CHECK(b16 == true);
}
void increment(int* count)
{
++(*count);
}
void test_connect()
{
receiver r;
call_count = 0;
const_member_connect s1;
operation_state o1 = exec::connect(s1, r);
BOOST_ASIO_CHECK(call_count == 1);
(void)o1;
call_count = 0;
const const_member_connect s2;
operation_state o2 = exec::connect(s2, r);
BOOST_ASIO_CHECK(call_count == 1);
(void)o2;
call_count = 0;
operation_state o3 = exec::connect(const_member_connect(), r);
BOOST_ASIO_CHECK(call_count == 1);
(void)o3;
call_count = 0;
free_connect_const_receiver s3;
operation_state o4 = exec::connect(s3, r);
BOOST_ASIO_CHECK(call_count == 1);
(void)o4;
call_count = 0;
const free_connect_const_receiver s4;
operation_state o5 = exec::connect(s4, r);
BOOST_ASIO_CHECK(call_count == 1);
(void)o5;
call_count = 0;
operation_state o6 = exec::connect(free_connect_const_receiver(), r);
BOOST_ASIO_CHECK(call_count == 1);
(void)o6;
call_count = 0;
non_const_member_connect s5;
operation_state o7 = exec::connect(s5, r);
BOOST_ASIO_CHECK(call_count == 1);
(void)o7;
call_count = 0;
free_connect_non_const_receiver s6;
operation_state o8 = exec::connect(s6, r);
BOOST_ASIO_CHECK(call_count == 1);
(void)o8;
executor s7;
exec::connect_result<executor&,
receiver&>::type o9 = exec::connect(s7, r);
BOOST_ASIO_CHECK((
exec::is_operation_state<
exec::connect_result<executor&, receiver&>::type
>::value));
(void)o9;
const executor s8;
exec::connect_result<const executor&,
receiver&>::type o10 = exec::connect(s8, r);
(void)exec::connect(s8, r);
BOOST_ASIO_CHECK((
exec::is_operation_state<
exec::connect_result<const executor&, receiver&>::type
>::value));
(void)o10;
}
BOOST_ASIO_TEST_SUITE
(
"connect",
BOOST_ASIO_TEST_CASE(test_can_connect)
BOOST_ASIO_TEST_CASE(test_connect)
)

View File

@@ -0,0 +1,157 @@
//
// context_as.cpp
// ~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/execution/context_as.hpp>
#include <boost/asio/execution/any_executor.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/static_thread_pool.hpp>
#include "../unit_test.hpp"
#if defined(BOOST_ASIO_HAS_BOOST_BIND)
# include <boost/bind/bind.hpp>
#else // defined(BOOST_ASIO_HAS_BOOST_BIND)
# include <functional>
#endif // defined(BOOST_ASIO_HAS_BOOST_BIND)
using namespace boost::asio;
#if defined(BOOST_ASIO_HAS_BOOST_BIND)
namespace bindns = boost;
#else // defined(BOOST_ASIO_HAS_BOOST_BIND)
namespace bindns = std;
#endif
void context_as_executor_query_test()
{
static_thread_pool pool(1);
BOOST_ASIO_CHECK(
&boost::asio::query(pool.executor(),
execution::context_as_t<static_thread_pool&>())
== &pool);
execution::any_executor<
execution::context_as_t<static_thread_pool&>
> ex1 = pool.executor();
BOOST_ASIO_CHECK(
&boost::asio::query(ex1,
execution::context_as_t<static_thread_pool&>())
== &pool);
BOOST_ASIO_CHECK(
&boost::asio::query(ex1, execution::context)
== &pool);
BOOST_ASIO_CHECK(
&boost::asio::query(pool.executor(),
execution::context_as_t<const static_thread_pool&>())
== &pool);
execution::any_executor<
execution::context_as_t<const static_thread_pool&>
> ex2 = pool.executor();
BOOST_ASIO_CHECK(
&boost::asio::query(ex2,
execution::context_as_t<const static_thread_pool&>())
== &pool);
BOOST_ASIO_CHECK(
&boost::asio::query(ex2, execution::context)
== &pool);
io_context io_ctx;
BOOST_ASIO_CHECK(
&boost::asio::query(io_ctx.get_executor(),
execution::context_as_t<io_context&>())
== &io_ctx);
execution::any_executor<
execution::context_as_t<io_context&>
> ex3 = io_ctx.get_executor();
BOOST_ASIO_CHECK(
&boost::asio::query(ex3,
execution::context_as_t<io_context&>())
== &io_ctx);
BOOST_ASIO_CHECK(
&boost::asio::query(ex3, execution::context)
== &io_ctx);
BOOST_ASIO_CHECK(
&boost::asio::query(io_ctx.get_executor(),
execution::context_as_t<const io_context&>())
== &io_ctx);
execution::any_executor<
execution::context_as_t<const io_context&>
> ex4 = io_ctx.get_executor();
BOOST_ASIO_CHECK(
&boost::asio::query(ex4,
execution::context_as_t<const io_context&>())
== &io_ctx);
BOOST_ASIO_CHECK(
&boost::asio::query(ex4, execution::context)
== &io_ctx);
BOOST_ASIO_CHECK(
&boost::asio::query(io_ctx.get_executor(),
execution::context_as_t<execution_context&>())
== &io_ctx);
execution::any_executor<
execution::context_as_t<execution_context&>
> ex5 = io_ctx.get_executor();
BOOST_ASIO_CHECK(
&boost::asio::query(ex5,
execution::context_as_t<execution_context&>())
== &io_ctx);
BOOST_ASIO_CHECK(
&boost::asio::query(ex5, execution::context)
== &io_ctx);
BOOST_ASIO_CHECK(
&boost::asio::query(io_ctx.get_executor(),
execution::context_as_t<const execution_context&>())
== &io_ctx);
execution::any_executor<
execution::context_as_t<const execution_context&>
> ex6 = io_ctx.get_executor();
BOOST_ASIO_CHECK(
&boost::asio::query(ex6,
execution::context_as_t<const execution_context&>())
== &io_ctx);
BOOST_ASIO_CHECK(
&boost::asio::query(ex6, execution::context)
== &io_ctx);
}
BOOST_ASIO_TEST_SUITE
(
"context_as",
BOOST_ASIO_TEST_CASE(context_as_executor_query_test)
)

View File

@@ -0,0 +1,400 @@
//
// execute.cpp
// ~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/execution/execute.hpp>
#include <boost/asio/execution/sender.hpp>
#include <boost/asio/execution/submit.hpp>
#include <boost/asio/execution/invocable_archetype.hpp>
#include "../unit_test.hpp"
#if defined(BOOST_ASIO_HAS_BOOST_BIND)
# include <boost/bind/bind.hpp>
#else // defined(BOOST_ASIO_HAS_BOOST_BIND)
# include <functional>
#endif // defined(BOOST_ASIO_HAS_BOOST_BIND)
namespace exec = boost::asio::execution;
struct no_execute
{
};
struct const_member_execute
{
template <typename F>
void execute(BOOST_ASIO_MOVE_ARG(F) f) const
{
typename boost::asio::decay<F>::type tmp(BOOST_ASIO_MOVE_CAST(F)(f));
tmp();
}
};
#if !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
namespace boost {
namespace asio {
namespace traits {
template <typename F>
struct execute_member<const_member_execute, F>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
typedef void result_type;
};
} // namespace traits
} // namespace asio
} // namespace boost
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
struct free_execute_const_executor
{
template <typename F>
friend void execute(const free_execute_const_executor&,
BOOST_ASIO_MOVE_ARG(F) f)
{
typename boost::asio::decay<F>::type tmp(BOOST_ASIO_MOVE_CAST(F)(f));
tmp();
}
};
#if !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_FREE_TRAIT)
namespace boost {
namespace asio {
namespace traits {
template <typename F>
struct execute_free<free_execute_const_executor, F>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
typedef void result_type;
};
} // namespace traits
} // namespace asio
} // namespace boost
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_FREE_TRAIT)
#if defined(BOOST_ASIO_HAS_MOVE)
// Support for rvalue references is required in order to use the execute
// customisation point with non-const member functions and free functions
// taking non-const arguments.
struct non_const_member_execute
{
template <typename F>
void execute(BOOST_ASIO_MOVE_ARG(F) f)
{
typename boost::asio::decay<F>::type tmp(BOOST_ASIO_MOVE_CAST(F)(f));
tmp();
}
};
#if !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
namespace boost {
namespace asio {
namespace traits {
template <typename F>
struct execute_member<non_const_member_execute, F>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
typedef void result_type;
};
template <typename F>
struct execute_member<const non_const_member_execute, F>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = false);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
typedef void result_type;
};
template <typename F>
struct execute_member<const non_const_member_execute&, F>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = false);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
typedef void result_type;
};
} // namespace traits
} // namespace asio
} // namespace boost
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
struct free_execute_non_const_executor
{
template <typename F>
friend void execute(free_execute_non_const_executor&,
BOOST_ASIO_MOVE_ARG(F) f)
{
typename boost::asio::decay<F>::type tmp(BOOST_ASIO_MOVE_CAST(F)(f));
tmp();
}
};
#if !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_FREE_TRAIT)
namespace boost {
namespace asio {
namespace traits {
template <typename F>
struct execute_free<free_execute_non_const_executor, F>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
typedef void result_type;
};
template <typename F>
struct execute_free<const free_execute_non_const_executor, F>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = false);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
typedef void result_type;
};
template <typename F>
struct execute_free<const free_execute_non_const_executor&, F>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = false);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
typedef void result_type;
};
} // namespace traits
} // namespace asio
} // namespace boost
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_FREE_TRAIT)
#endif // defined(BOOST_ASIO_HAS_MOVE)
struct operation_state
{
void start() BOOST_ASIO_NOEXCEPT
{
}
};
namespace boost {
namespace asio {
namespace traits {
#if !defined(BOOST_ASIO_HAS_DEDUCED_START_MEMBER_TRAIT)
template <>
struct start_member<operation_state>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
typedef void result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_START_MEMBER_TRAIT)
} // namespace traits
} // namespace asio
} // namespace boost
struct sender : exec::sender_base
{
sender()
{
}
template <typename R>
operation_state connect(BOOST_ASIO_MOVE_ARG(R) r) const
{
(void)r;
return operation_state();
}
template <typename R>
void submit(BOOST_ASIO_MOVE_ARG(R) r) const
{
exec::set_value(BOOST_ASIO_MOVE_CAST(R)(r));
}
};
namespace boost {
namespace asio {
namespace traits {
#if !defined(BOOST_ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT)
template <typename R>
struct connect_member<const sender, R>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
typedef operation_state result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT)
#if !defined(BOOST_ASIO_HAS_DEDUCED_SUBMIT_MEMBER_TRAIT)
template <typename R>
struct submit_member<const sender, R>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
typedef void result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SUBMIT_MEMBER_TRAIT)
} // namespace traits
} // namespace asio
} // namespace boost
void test_can_execute()
{
BOOST_ASIO_CONSTEXPR bool b1 = exec::can_execute<
no_execute&, exec::invocable_archetype>::value;
BOOST_ASIO_CHECK(b1 == false);
BOOST_ASIO_CONSTEXPR bool b2 = exec::can_execute<
const no_execute&, exec::invocable_archetype>::value;
BOOST_ASIO_CHECK(b2 == false);
BOOST_ASIO_CONSTEXPR bool b3 = exec::can_execute<
const_member_execute&, exec::invocable_archetype>::value;
BOOST_ASIO_CHECK(b3 == true);
BOOST_ASIO_CONSTEXPR bool b4 = exec::can_execute<
const const_member_execute&, exec::invocable_archetype>::value;
BOOST_ASIO_CHECK(b4 == true);
BOOST_ASIO_CONSTEXPR bool b5 = exec::can_execute<
free_execute_const_executor&, exec::invocable_archetype>::value;
BOOST_ASIO_CHECK(b5 == true);
BOOST_ASIO_CONSTEXPR bool b6 = exec::can_execute<
const free_execute_const_executor&, exec::invocable_archetype>::value;
BOOST_ASIO_CHECK(b6 == true);
#if defined(BOOST_ASIO_HAS_MOVE)
BOOST_ASIO_CONSTEXPR bool b7 = exec::can_execute<
non_const_member_execute&, exec::invocable_archetype>::value;
BOOST_ASIO_CHECK(b7 == true);
BOOST_ASIO_CONSTEXPR bool b8 = exec::can_execute<
const non_const_member_execute&, exec::invocable_archetype>::value;
BOOST_ASIO_CHECK(b8 == false);
BOOST_ASIO_CONSTEXPR bool b9 = exec::can_execute<
free_execute_non_const_executor&, exec::invocable_archetype>::value;
BOOST_ASIO_CHECK(b9 == true);
BOOST_ASIO_CONSTEXPR bool b10 = exec::can_execute<
const free_execute_non_const_executor&, exec::invocable_archetype>::value;
BOOST_ASIO_CHECK(b10 == false);
#endif // defined(BOOST_ASIO_HAS_MOVE)
BOOST_ASIO_CONSTEXPR bool b11 = exec::can_execute<
sender&, exec::invocable_archetype>::value;
BOOST_ASIO_CHECK(b11 == true);
BOOST_ASIO_CONSTEXPR bool b12 = exec::can_execute<
const sender&, exec::invocable_archetype>::value;
BOOST_ASIO_CHECK(b12 == true);
}
void increment(int* count)
{
++(*count);
}
void test_execute()
{
#if defined(BOOST_ASIO_HAS_BOOST_BIND)
namespace bindns = boost;
#else // defined(BOOST_ASIO_HAS_BOOST_BIND)
namespace bindns = std;
#endif // defined(BOOST_ASIO_HAS_BOOST_BIND)
int count = 0;
const_member_execute ex1 = {};
exec::execute(ex1, bindns::bind(&increment, &count));
BOOST_ASIO_CHECK(count == 1);
count = 0;
const const_member_execute ex2 = {};
exec::execute(ex2, bindns::bind(&increment, &count));
BOOST_ASIO_CHECK(count == 1);
count = 0;
exec::execute(const_member_execute(), bindns::bind(&increment, &count));
BOOST_ASIO_CHECK(count == 1);
count = 0;
free_execute_const_executor ex3 = {};
exec::execute(ex3, bindns::bind(&increment, &count));
BOOST_ASIO_CHECK(count == 1);
count = 0;
const free_execute_const_executor ex4 = {};
exec::execute(ex4, bindns::bind(&increment, &count));
BOOST_ASIO_CHECK(count == 1);
count = 0;
exec::execute(free_execute_const_executor(),
bindns::bind(&increment, &count));
BOOST_ASIO_CHECK(count == 1);
#if defined(BOOST_ASIO_HAS_MOVE)
count = 0;
non_const_member_execute ex5 = {};
exec::execute(ex5, bindns::bind(&increment, &count));
BOOST_ASIO_CHECK(count == 1);
count = 0;
free_execute_non_const_executor ex6 = {};
exec::execute(ex6, bindns::bind(&increment, &count));
BOOST_ASIO_CHECK(count == 1);
#endif // defined(BOOST_ASIO_HAS_MOVE)
count = 0;
sender ex7;
exec::execute(ex3, bindns::bind(&increment, &count));
BOOST_ASIO_CHECK(count == 1);
count = 0;
const sender ex8;
exec::execute(ex4, bindns::bind(&increment, &count));
BOOST_ASIO_CHECK(count == 1);
}
BOOST_ASIO_TEST_SUITE
(
"blocking",
BOOST_ASIO_TEST_CASE(test_can_execute)
BOOST_ASIO_TEST_CASE(test_execute)
)

View File

@@ -0,0 +1,186 @@
//
// executor.cpp
// ~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/execution/executor.hpp>
#include "../unit_test.hpp"
struct not_an_executor
{
};
struct executor
{
executor()
{
}
executor(const executor&) BOOST_ASIO_NOEXCEPT
{
}
#if defined(BOOST_ASIO_HAS_MOVE)
executor(executor&&) BOOST_ASIO_NOEXCEPT
{
}
#endif // defined(BOOST_ASIO_HAS_MOVE)
template <typename F>
void execute(BOOST_ASIO_MOVE_ARG(F) f) const BOOST_ASIO_NOEXCEPT
{
(void)f;
}
bool operator==(const executor&) const BOOST_ASIO_NOEXCEPT
{
return true;
}
bool operator!=(const executor&) const BOOST_ASIO_NOEXCEPT
{
return false;
}
};
namespace boost {
namespace asio {
namespace traits {
#if !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
template <typename F>
struct execute_member<executor, F>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
typedef void result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)
#if !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
template <>
struct equality_comparable<executor>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
} // namespace traits
} // namespace asio
} // namespace boost
void is_executor_test()
{
BOOST_ASIO_CHECK((
!boost::asio::execution::is_executor<
void
>::value));
BOOST_ASIO_CHECK((
!boost::asio::execution::is_executor<
not_an_executor
>::value));
BOOST_ASIO_CHECK((
boost::asio::execution::is_executor<
executor
>::value));
}
void is_executor_of_test()
{
BOOST_ASIO_CHECK((
!boost::asio::execution::is_executor_of<
void,
void(*)()
>::value));
BOOST_ASIO_CHECK((
!boost::asio::execution::is_executor_of<
not_an_executor,
void(*)()
>::value));
BOOST_ASIO_CHECK((
boost::asio::execution::is_executor_of<
executor,
void(*)()
>::value));
}
struct executor_with_other_shape_type
{
typedef double shape_type;
};
void executor_shape_test()
{
BOOST_ASIO_CHECK((
boost::asio::is_same<
boost::asio::execution::executor_shape<executor>::type,
std::size_t
>::value));
BOOST_ASIO_CHECK((
boost::asio::is_same<
boost::asio::execution::executor_shape<
executor_with_other_shape_type
>::type,
double
>::value));
}
struct executor_with_other_index_type
{
typedef unsigned char index_type;
};
void executor_index_test()
{
BOOST_ASIO_CHECK((
boost::asio::is_same<
boost::asio::execution::executor_index<executor>::type,
std::size_t
>::value));
BOOST_ASIO_CHECK((
boost::asio::is_same<
boost::asio::execution::executor_index<
executor_with_other_shape_type
>::type,
double
>::value));
BOOST_ASIO_CHECK((
boost::asio::is_same<
boost::asio::execution::executor_index<
executor_with_other_index_type
>::type,
unsigned char
>::value));
}
BOOST_ASIO_TEST_SUITE
(
"executor",
BOOST_ASIO_TEST_CASE(is_executor_test)
BOOST_ASIO_TEST_CASE(is_executor_of_test)
BOOST_ASIO_TEST_CASE(executor_shape_test)
BOOST_ASIO_TEST_CASE(executor_index_test)
)

View File

@@ -0,0 +1,25 @@
//
// invocable_archetype.cpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/execution/invocable_archetype.hpp>
#include "../unit_test.hpp"
BOOST_ASIO_TEST_SUITE
(
"invocable_archetype",
BOOST_ASIO_TEST_CASE(null_test)
)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,108 @@
//
// operation_state.cpp
// ~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/execution/operation_state.hpp>
#include <string>
#include <boost/system/error_code.hpp>
#include "../unit_test.hpp"
struct not_an_operation_state_1
{
};
struct not_an_operation_state_2
{
void start()
{
}
};
namespace boost {
namespace asio {
namespace traits {
#if !defined(BOOST_ASIO_HAS_DEDUCED_START_MEMBER_TRAIT)
template <>
struct start_member<not_an_operation_state_2>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
typedef void result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_START_MEMBER_TRAIT)
} // namespace traits
} // namespace asio
} // namespace boost
struct operation_state
{
void start() BOOST_ASIO_NOEXCEPT
{
}
};
namespace boost {
namespace asio {
namespace traits {
#if !defined(BOOST_ASIO_HAS_DEDUCED_START_MEMBER_TRAIT)
template <>
struct start_member<operation_state>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
typedef void result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_START_MEMBER_TRAIT)
} // namespace traits
} // namespace asio
} // namespace boost
void is_operation_state_test()
{
BOOST_ASIO_CHECK((
!boost::asio::execution::is_operation_state<
void
>::value));
BOOST_ASIO_CHECK((
!boost::asio::execution::is_operation_state<
not_an_operation_state_1
>::value));
BOOST_ASIO_CHECK((
!boost::asio::execution::is_operation_state<
not_an_operation_state_2
>::value));
BOOST_ASIO_CHECK((
boost::asio::execution::is_operation_state<
operation_state
>::value));
}
BOOST_ASIO_TEST_SUITE
(
"operation_state",
BOOST_ASIO_TEST_CASE(is_operation_state_test)
)

View File

@@ -0,0 +1,549 @@
//
// prefer_only.cpp
// ~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/execution/prefer_only.hpp>
#include <boost/asio/execution/any_executor.hpp>
#include "../unit_test.hpp"
#if defined(BOOST_ASIO_HAS_BOOST_BIND)
# include <boost/bind/bind.hpp>
#else // defined(BOOST_ASIO_HAS_BOOST_BIND)
# include <functional>
#endif // defined(BOOST_ASIO_HAS_BOOST_BIND)
using namespace boost::asio;
#if defined(BOOST_ASIO_HAS_BOOST_BIND)
namespace bindns = boost;
#else // defined(BOOST_ASIO_HAS_BOOST_BIND)
namespace bindns = std;
#endif
static int possibly_blocking_count = 0;
static int never_blocking_count = 0;
struct possibly_blocking_executor
{
template <typename F>
void execute(const F&) const
{
++possibly_blocking_count;
}
friend bool operator==(const possibly_blocking_executor&,
const possibly_blocking_executor&) BOOST_ASIO_NOEXCEPT
{
return true;
}
friend bool operator!=(const possibly_blocking_executor&,
const possibly_blocking_executor&) BOOST_ASIO_NOEXCEPT
{
return false;
}
};
namespace boost {
namespace asio {
namespace traits {
#if !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
template <typename F>
struct execute_member<possibly_blocking_executor, F>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
typedef void result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
#if !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
template <>
struct equality_comparable<possibly_blocking_executor>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
} // namespace traits
} // namespace asio
} // namespace boost
struct never_blocking_executor
{
static BOOST_ASIO_CONSTEXPR execution::blocking_t::never_t
query(execution::blocking_t) BOOST_ASIO_NOEXCEPT
{
return execution::blocking_t::never_t();
}
template <typename F>
void execute(const F&) const
{
++never_blocking_count;
}
friend bool operator==(const never_blocking_executor&,
const never_blocking_executor&) BOOST_ASIO_NOEXCEPT
{
return true;
}
friend bool operator!=(const never_blocking_executor&,
const never_blocking_executor&) BOOST_ASIO_NOEXCEPT
{
return false;
}
};
namespace boost {
namespace asio {
namespace traits {
#if !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
template <typename F>
struct execute_member<never_blocking_executor, F>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
typedef void result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
#if !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
template <>
struct equality_comparable<never_blocking_executor>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
#if !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)
template <typename Param>
struct query_static_constexpr_member<
never_blocking_executor, Param,
typename boost::asio::enable_if<
boost::asio::is_convertible<Param, execution::blocking_t>::value
>::type>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
typedef execution::blocking_t::never_t result_type;
static BOOST_ASIO_CONSTEXPR result_type value()
{
return result_type();
}
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)
} // namespace traits
} // namespace asio
} // namespace boost
struct either_blocking_executor
{
execution::blocking_t blocking_;
explicit either_blocking_executor(execution::blocking_t b)
: blocking_(b)
{
}
execution::blocking_t query(execution::blocking_t) const BOOST_ASIO_NOEXCEPT
{
return blocking_;
}
either_blocking_executor require(execution::blocking_t::possibly_t) const
{
return either_blocking_executor(execution::blocking.possibly);
}
either_blocking_executor require(execution::blocking_t::never_t) const
{
return either_blocking_executor(execution::blocking.never);
}
template <typename F>
void execute(const F&) const
{
if (blocking_ == execution::blocking.never)
++never_blocking_count;
else
++possibly_blocking_count;
}
friend bool operator==(const either_blocking_executor& a,
const either_blocking_executor& b) BOOST_ASIO_NOEXCEPT
{
return a.blocking_ == b.blocking_;
}
friend bool operator!=(const either_blocking_executor& a,
const either_blocking_executor& b) BOOST_ASIO_NOEXCEPT
{
return a.blocking_ != b.blocking_;
}
};
namespace boost {
namespace asio {
namespace traits {
#if !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
template <typename F>
struct execute_member<either_blocking_executor, F>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
typedef void result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
#if !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
template <>
struct equality_comparable<either_blocking_executor>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
#if !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)
template <typename Param>
struct query_member<
either_blocking_executor, Param,
typename boost::asio::enable_if<
boost::asio::is_convertible<Param, execution::blocking_t>::value
>::type>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
typedef execution::blocking_t result_type;
};
#if !defined(BOOST_ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)
template <typename Param>
struct require_member<
either_blocking_executor, Param,
typename boost::asio::enable_if<
boost::asio::is_convertible<Param, execution::blocking_t>::value
>::type>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
typedef either_blocking_executor result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)
} // namespace traits
} // namespace asio
} // namespace boost
void prefer_only_executor_query_test()
{
typedef execution::any_executor<
execution::blocking_t,
execution::prefer_only<execution::blocking_t::possibly_t>,
execution::prefer_only<execution::blocking_t::never_t>
> executor_type;
executor_type ex1 = possibly_blocking_executor();
BOOST_ASIO_CHECK(
boost::asio::query(ex1, execution::blocking)
== execution::blocking.possibly);
BOOST_ASIO_CHECK(
boost::asio::query(ex1, execution::blocking.possibly)
== execution::blocking.possibly);
BOOST_ASIO_CHECK(
boost::asio::query(ex1, execution::blocking.never)
== execution::blocking.possibly);
executor_type ex2 = boost::asio::prefer(ex1, execution::blocking.possibly);
BOOST_ASIO_CHECK(
boost::asio::query(ex2, execution::blocking)
== execution::blocking.possibly);
BOOST_ASIO_CHECK(
boost::asio::query(ex2, execution::blocking.possibly)
== execution::blocking.possibly);
BOOST_ASIO_CHECK(
boost::asio::query(ex2, execution::blocking.never)
== execution::blocking.possibly);
executor_type ex3 = boost::asio::prefer(ex1, execution::blocking.never);
BOOST_ASIO_CHECK(
boost::asio::query(ex3, execution::blocking)
== execution::blocking.possibly);
BOOST_ASIO_CHECK(
boost::asio::query(ex3, execution::blocking.possibly)
== execution::blocking.possibly);
BOOST_ASIO_CHECK(
boost::asio::query(ex3, execution::blocking.never)
== execution::blocking.possibly);
executor_type ex4 = never_blocking_executor();
BOOST_ASIO_CHECK(
boost::asio::query(ex4, execution::blocking)
== execution::blocking.never);
BOOST_ASIO_CHECK(
boost::asio::query(ex4, execution::blocking.possibly)
== execution::blocking.never);
BOOST_ASIO_CHECK(
boost::asio::query(ex4, execution::blocking.never)
== execution::blocking.never);
executor_type ex5 = boost::asio::prefer(ex4, execution::blocking.possibly);
BOOST_ASIO_CHECK(
boost::asio::query(ex5, execution::blocking)
== execution::blocking.never);
BOOST_ASIO_CHECK(
boost::asio::query(ex5, execution::blocking.possibly)
== execution::blocking.never);
BOOST_ASIO_CHECK(
boost::asio::query(ex5, execution::blocking.never)
== execution::blocking.never);
executor_type ex6 = boost::asio::prefer(ex4, execution::blocking.never);
BOOST_ASIO_CHECK(
boost::asio::query(ex6, execution::blocking)
== execution::blocking.never);
BOOST_ASIO_CHECK(
boost::asio::query(ex6, execution::blocking.possibly)
== execution::blocking.never);
BOOST_ASIO_CHECK(
boost::asio::query(ex6, execution::blocking.never)
== execution::blocking.never);
executor_type ex7 = either_blocking_executor(execution::blocking.possibly);
BOOST_ASIO_CHECK(
boost::asio::query(ex7, execution::blocking)
== execution::blocking.possibly);
BOOST_ASIO_CHECK(
boost::asio::query(ex7, execution::blocking.possibly)
== execution::blocking.possibly);
BOOST_ASIO_CHECK(
boost::asio::query(ex7, execution::blocking.never)
== execution::blocking.possibly);
executor_type ex8 = boost::asio::prefer(ex7, execution::blocking.possibly);
BOOST_ASIO_CHECK(
boost::asio::query(ex8, execution::blocking)
== execution::blocking.possibly);
BOOST_ASIO_CHECK(
boost::asio::query(ex8, execution::blocking.possibly)
== execution::blocking.possibly);
BOOST_ASIO_CHECK(
boost::asio::query(ex8, execution::blocking.never)
== execution::blocking.possibly);
executor_type ex9 = boost::asio::prefer(ex7, execution::blocking.never);
BOOST_ASIO_CHECK(
boost::asio::query(ex9, execution::blocking)
== execution::blocking.never);
BOOST_ASIO_CHECK(
boost::asio::query(ex9, execution::blocking.possibly)
== execution::blocking.never);
BOOST_ASIO_CHECK(
boost::asio::query(ex9, execution::blocking.never)
== execution::blocking.never);
executor_type ex10 = either_blocking_executor(execution::blocking.never);
BOOST_ASIO_CHECK(
boost::asio::query(ex10, execution::blocking)
== execution::blocking.never);
BOOST_ASIO_CHECK(
boost::asio::query(ex10, execution::blocking.possibly)
== execution::blocking.never);
BOOST_ASIO_CHECK(
boost::asio::query(ex10, execution::blocking.never)
== execution::blocking.never);
executor_type ex11 = boost::asio::prefer(ex7, execution::blocking.possibly);
BOOST_ASIO_CHECK(
boost::asio::query(ex11, execution::blocking)
== execution::blocking.possibly);
BOOST_ASIO_CHECK(
boost::asio::query(ex11, execution::blocking.possibly)
== execution::blocking.possibly);
BOOST_ASIO_CHECK(
boost::asio::query(ex11, execution::blocking.never)
== execution::blocking.possibly);
executor_type ex12 = boost::asio::prefer(ex7, execution::blocking.never);
BOOST_ASIO_CHECK(
boost::asio::query(ex12, execution::blocking)
== execution::blocking.never);
BOOST_ASIO_CHECK(
boost::asio::query(ex12, execution::blocking.possibly)
== execution::blocking.never);
BOOST_ASIO_CHECK(
boost::asio::query(ex12, execution::blocking.never)
== execution::blocking.never);
}
void do_nothing()
{
}
void prefer_only_executor_execute_test()
{
typedef execution::any_executor<
execution::blocking_t,
execution::prefer_only<execution::blocking_t::possibly_t>,
execution::prefer_only<execution::blocking_t::never_t>
> executor_type;
executor_type ex1 = possibly_blocking_executor();
execution::execute(ex1, &do_nothing);
BOOST_ASIO_CHECK(possibly_blocking_count == 1);
BOOST_ASIO_CHECK(never_blocking_count == 0);
executor_type ex2 = boost::asio::prefer(ex1, execution::blocking.possibly);
execution::execute(ex2, &do_nothing);
BOOST_ASIO_CHECK(possibly_blocking_count == 2);
BOOST_ASIO_CHECK(never_blocking_count == 0);
executor_type ex3 = boost::asio::prefer(ex1, execution::blocking.never);
execution::execute(ex3, &do_nothing);
BOOST_ASIO_CHECK(possibly_blocking_count == 3);
BOOST_ASIO_CHECK(never_blocking_count == 0);
executor_type ex4 = never_blocking_executor();
execution::execute(ex4, &do_nothing);
BOOST_ASIO_CHECK(possibly_blocking_count == 3);
BOOST_ASIO_CHECK(never_blocking_count == 1);
executor_type ex5 = boost::asio::prefer(ex4, execution::blocking.possibly);
execution::execute(ex5, &do_nothing);
BOOST_ASIO_CHECK(possibly_blocking_count == 3);
BOOST_ASIO_CHECK(never_blocking_count == 2);
executor_type ex6 = boost::asio::prefer(ex4, execution::blocking.never);
execution::execute(ex6, &do_nothing);
BOOST_ASIO_CHECK(possibly_blocking_count == 3);
BOOST_ASIO_CHECK(never_blocking_count == 3);
executor_type ex7 = either_blocking_executor(execution::blocking.possibly);
execution::execute(ex7, &do_nothing);
BOOST_ASIO_CHECK(possibly_blocking_count == 4);
BOOST_ASIO_CHECK(never_blocking_count == 3);
executor_type ex8 = boost::asio::prefer(ex7, execution::blocking.possibly);
execution::execute(ex8, &do_nothing);
BOOST_ASIO_CHECK(possibly_blocking_count == 5);
BOOST_ASIO_CHECK(never_blocking_count == 3);
executor_type ex9 = boost::asio::prefer(ex7, execution::blocking.never);
execution::execute(ex9, &do_nothing);
BOOST_ASIO_CHECK(possibly_blocking_count == 5);
BOOST_ASIO_CHECK(never_blocking_count == 4);
executor_type ex10 = either_blocking_executor(execution::blocking.never);
execution::execute(ex10, &do_nothing);
BOOST_ASIO_CHECK(possibly_blocking_count == 5);
BOOST_ASIO_CHECK(never_blocking_count == 5);
executor_type ex11 = boost::asio::prefer(ex7, execution::blocking.possibly);
execution::execute(ex11, &do_nothing);
BOOST_ASIO_CHECK(possibly_blocking_count == 6);
BOOST_ASIO_CHECK(never_blocking_count == 5);
executor_type ex12 = boost::asio::prefer(ex7, execution::blocking.never);
execution::execute(ex12, &do_nothing);
BOOST_ASIO_CHECK(possibly_blocking_count == 6);
BOOST_ASIO_CHECK(never_blocking_count == 6);
}
BOOST_ASIO_TEST_SUITE
(
"prefer_only",
BOOST_ASIO_TEST_CASE(prefer_only_executor_query_test)
BOOST_ASIO_TEST_CASE(prefer_only_executor_execute_test)
)

View File

@@ -0,0 +1,557 @@
//
// receiver.cpp
// ~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/execution/receiver.hpp>
#include <string>
#include <boost/system/error_code.hpp>
#include "../unit_test.hpp"
struct not_a_receiver
{
};
struct receiver
{
receiver()
{
}
receiver(const receiver&)
{
}
#if defined(BOOST_ASIO_HAS_MOVE)
receiver(receiver&&)
{
}
#endif // defined(BOOST_ASIO_HAS_MOVE)
template <typename E>
void set_error(BOOST_ASIO_MOVE_ARG(E) e) BOOST_ASIO_NOEXCEPT
{
(void)e;
}
void set_done() BOOST_ASIO_NOEXCEPT
{
}
};
namespace boost {
namespace asio {
namespace traits {
#if !defined(BOOST_ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)
template <typename E>
struct set_error_member<receiver, E>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
typedef void result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)
#if !defined(BOOST_ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)
template <>
struct set_done_member<receiver>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
typedef void result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)
} // namespace traits
} // namespace asio
} // namespace boost
struct receiver_of_0
{
receiver_of_0()
{
}
receiver_of_0(const receiver_of_0&)
{
}
#if defined(BOOST_ASIO_HAS_MOVE)
receiver_of_0(receiver_of_0&&)
{
}
#endif // defined(BOOST_ASIO_HAS_MOVE)
template <typename E>
void set_error(BOOST_ASIO_MOVE_ARG(E) e) BOOST_ASIO_NOEXCEPT
{
(void)e;
}
void set_done() BOOST_ASIO_NOEXCEPT
{
}
void set_value()
{
}
};
namespace boost {
namespace asio {
namespace traits {
#if !defined(BOOST_ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)
template <typename E>
struct set_error_member<receiver_of_0, E>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
typedef void result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)
#if !defined(BOOST_ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)
template <>
struct set_done_member<receiver_of_0>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
typedef void result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)
#if !defined(BOOST_ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)
template <>
struct set_value_member<receiver_of_0, void()>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
typedef void result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)
} // namespace traits
} // namespace asio
} // namespace boost
struct receiver_of_1
{
receiver_of_1()
{
}
receiver_of_1(const receiver_of_1&)
{
}
#if defined(BOOST_ASIO_HAS_MOVE)
receiver_of_1(receiver_of_1&&)
{
}
#endif // defined(BOOST_ASIO_HAS_MOVE)
template <typename E>
void set_error(BOOST_ASIO_MOVE_ARG(E) e) BOOST_ASIO_NOEXCEPT
{
(void)e;
}
void set_done() BOOST_ASIO_NOEXCEPT
{
}
void set_value(int) BOOST_ASIO_NOEXCEPT
{
}
};
namespace boost {
namespace asio {
namespace traits {
#if !defined(BOOST_ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)
template <typename E>
struct set_error_member<receiver_of_1, E>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
typedef void result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)
#if !defined(BOOST_ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)
template <>
struct set_done_member<receiver_of_1>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
typedef void result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)
#if !defined(BOOST_ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)
template <>
struct set_value_member<receiver_of_1, void(int)>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
typedef void result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)
} // namespace traits
} // namespace asio
} // namespace boost
struct receiver_of_2
{
receiver_of_2()
{
}
receiver_of_2(const receiver_of_2&)
{
}
#if defined(BOOST_ASIO_HAS_MOVE)
receiver_of_2(receiver_of_2&&)
{
}
#endif // defined(BOOST_ASIO_HAS_MOVE)
template <typename E>
void set_error(BOOST_ASIO_MOVE_ARG(E) e) BOOST_ASIO_NOEXCEPT
{
(void)e;
}
void set_done() BOOST_ASIO_NOEXCEPT
{
}
void set_value(int, std::string)
{
}
};
namespace boost {
namespace asio {
namespace traits {
#if !defined(BOOST_ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)
template <typename E>
struct set_error_member<receiver_of_2, E>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
typedef void result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)
#if !defined(BOOST_ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)
template <>
struct set_done_member<receiver_of_2>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
typedef void result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)
#if !defined(BOOST_ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)
template <>
struct set_value_member<receiver_of_2, void(int, std::string)>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
typedef void result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)
} // namespace traits
} // namespace asio
} // namespace boost
void is_receiver_test()
{
BOOST_ASIO_CHECK((
!boost::asio::execution::is_receiver<
void,
boost::system::error_code
>::value));
BOOST_ASIO_CHECK((
!boost::asio::execution::is_receiver<
not_a_receiver,
boost::system::error_code
>::value));
BOOST_ASIO_CHECK((
boost::asio::execution::is_receiver<
receiver,
boost::system::error_code
>::value));
BOOST_ASIO_CHECK((
boost::asio::execution::is_receiver<
receiver_of_0,
boost::system::error_code
>::value));
BOOST_ASIO_CHECK((
boost::asio::execution::is_receiver<
receiver_of_1,
boost::system::error_code
>::value));
BOOST_ASIO_CHECK((
boost::asio::execution::is_receiver<
receiver_of_2,
boost::system::error_code
>::value));
}
void is_receiver_of_test()
{
BOOST_ASIO_CHECK((
!boost::asio::execution::is_receiver_of<
void
>::value));
BOOST_ASIO_CHECK((
!boost::asio::execution::is_receiver_of<
void,
int
>::value));
BOOST_ASIO_CHECK((
!boost::asio::execution::is_receiver_of<
not_a_receiver
>::value));
BOOST_ASIO_CHECK((
!boost::asio::execution::is_receiver_of<
not_a_receiver,
int
>::value));
BOOST_ASIO_CHECK((
!boost::asio::execution::is_receiver_of<
not_a_receiver,
int,
std::string
>::value));
BOOST_ASIO_CHECK((
!boost::asio::execution::is_receiver_of<
receiver
>::value));
BOOST_ASIO_CHECK((
!boost::asio::execution::is_receiver_of<
receiver,
int
>::value));
BOOST_ASIO_CHECK((
!boost::asio::execution::is_receiver_of<
receiver,
int,
std::string
>::value));
BOOST_ASIO_CHECK((
boost::asio::execution::is_receiver_of<
receiver_of_0
>::value));
BOOST_ASIO_CHECK((
!boost::asio::execution::is_receiver_of<
receiver_of_0,
int
>::value));
BOOST_ASIO_CHECK((
!boost::asio::execution::is_receiver_of<
receiver_of_0,
int,
std::string
>::value));
BOOST_ASIO_CHECK((
!boost::asio::execution::is_receiver_of<
receiver_of_1
>::value));
BOOST_ASIO_CHECK((
boost::asio::execution::is_receiver_of<
receiver_of_1,
int
>::value));
BOOST_ASIO_CHECK((
!boost::asio::execution::is_receiver_of<
receiver_of_1,
int,
std::string
>::value));
BOOST_ASIO_CHECK((
!boost::asio::execution::is_receiver_of<
receiver_of_2
>::value));
BOOST_ASIO_CHECK((
!boost::asio::execution::is_receiver_of<
receiver_of_2,
int
>::value));
BOOST_ASIO_CHECK((
boost::asio::execution::is_receiver_of<
receiver_of_2,
int,
std::string
>::value));
}
void is_nothrow_receiver_of_test()
{
BOOST_ASIO_CHECK((
!boost::asio::execution::is_nothrow_receiver_of<
void
>::value));
BOOST_ASIO_CHECK((
!boost::asio::execution::is_nothrow_receiver_of<
void,
int
>::value));
BOOST_ASIO_CHECK((
!boost::asio::execution::is_nothrow_receiver_of<
not_a_receiver
>::value));
BOOST_ASIO_CHECK((
!boost::asio::execution::is_nothrow_receiver_of<
not_a_receiver,
int
>::value));
BOOST_ASIO_CHECK((
!boost::asio::execution::is_nothrow_receiver_of<
not_a_receiver,
int,
std::string
>::value));
BOOST_ASIO_CHECK((
!boost::asio::execution::is_nothrow_receiver_of<
receiver
>::value));
BOOST_ASIO_CHECK((
!boost::asio::execution::is_nothrow_receiver_of<
receiver,
int
>::value));
BOOST_ASIO_CHECK((
!boost::asio::execution::is_nothrow_receiver_of<
receiver,
int,
std::string
>::value));
BOOST_ASIO_CHECK((
!boost::asio::execution::is_nothrow_receiver_of<
receiver_of_0
>::value));
BOOST_ASIO_CHECK((
!boost::asio::execution::is_nothrow_receiver_of<
receiver_of_0,
int
>::value));
BOOST_ASIO_CHECK((
!boost::asio::execution::is_nothrow_receiver_of<
receiver_of_0,
int,
std::string
>::value));
BOOST_ASIO_CHECK((
!boost::asio::execution::is_nothrow_receiver_of<
receiver_of_1
>::value));
BOOST_ASIO_CHECK((
boost::asio::execution::is_nothrow_receiver_of<
receiver_of_1,
int
>::value));
BOOST_ASIO_CHECK((
!boost::asio::execution::is_nothrow_receiver_of<
receiver_of_1,
int,
std::string
>::value));
BOOST_ASIO_CHECK((
!boost::asio::execution::is_nothrow_receiver_of<
receiver_of_2
>::value));
BOOST_ASIO_CHECK((
!boost::asio::execution::is_nothrow_receiver_of<
receiver_of_2,
int
>::value));
BOOST_ASIO_CHECK((
!boost::asio::execution::is_nothrow_receiver_of<
receiver_of_2,
int,
std::string
>::value));
}
BOOST_ASIO_TEST_SUITE
(
"receiver",
BOOST_ASIO_TEST_CASE(is_receiver_test)
BOOST_ASIO_TEST_CASE(is_receiver_of_test)
BOOST_ASIO_TEST_CASE(is_nothrow_receiver_of_test)
)

View File

@@ -0,0 +1,506 @@
//
// schedule.cpp
// ~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/execution/schedule.hpp>
#include <boost/system/error_code.hpp>
#include <boost/asio/execution/sender.hpp>
#include <boost/asio/execution/submit.hpp>
#include <boost/asio/traits/connect_member.hpp>
#include <boost/asio/traits/start_member.hpp>
#include <boost/asio/traits/submit_member.hpp>
#include "../unit_test.hpp"
namespace exec = boost::asio::execution;
struct operation_state
{
void start() BOOST_ASIO_NOEXCEPT
{
}
};
namespace boost {
namespace asio {
namespace traits {
#if !defined(BOOST_ASIO_HAS_DEDUCED_START_MEMBER_TRAIT)
template <>
struct start_member<operation_state>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
typedef void result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_START_MEMBER_TRAIT)
} // namespace traits
} // namespace asio
} // namespace boost
struct sender : exec::sender_base
{
sender()
{
}
template <typename R>
operation_state connect(BOOST_ASIO_MOVE_ARG(R) r) const
{
(void)r;
return operation_state();
}
template <typename R>
void submit(BOOST_ASIO_MOVE_ARG(R) r) const
{
typename boost::asio::decay<R>::type tmp(BOOST_ASIO_MOVE_CAST(R)(r));
exec::set_value(tmp);
}
};
namespace boost {
namespace asio {
namespace traits {
#if !defined(BOOST_ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT)
template <typename R>
struct connect_member<const sender, R>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
typedef operation_state result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT)
#if !defined(BOOST_ASIO_HAS_DEDUCED_SUBMIT_MEMBER_TRAIT)
template <typename R>
struct submit_member<const sender, R>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
typedef void result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SUBMIT_MEMBER_TRAIT)
} // namespace traits
} // namespace asio
} // namespace boost
struct no_schedule
{
};
struct const_member_schedule
{
sender schedule() const BOOST_ASIO_NOEXCEPT
{
return sender();
}
};
#if !defined(BOOST_ASIO_HAS_DEDUCED_SCHEDULE_MEMBER_TRAIT)
namespace boost {
namespace asio {
namespace traits {
template <>
struct schedule_member<const const_member_schedule>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
typedef sender result_type;
};
} // namespace traits
} // namespace asio
} // namespace boost
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SCHEDULE_MEMBER_TRAIT)
struct free_schedule_const_receiver
{
friend sender schedule(
const free_schedule_const_receiver&) BOOST_ASIO_NOEXCEPT
{
return sender();
}
};
#if !defined(BOOST_ASIO_HAS_DEDUCED_SCHEDULE_FREE_TRAIT)
namespace boost {
namespace asio {
namespace traits {
template <>
struct schedule_free<const free_schedule_const_receiver>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
typedef sender result_type;
};
} // namespace traits
} // namespace asio
} // namespace boost
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SCHEDULE_FREE_TRAIT)
struct non_const_member_schedule
{
sender schedule() BOOST_ASIO_NOEXCEPT
{
return sender();
}
};
#if !defined(BOOST_ASIO_HAS_DEDUCED_SCHEDULE_MEMBER_TRAIT)
namespace boost {
namespace asio {
namespace traits {
template <>
struct schedule_member<non_const_member_schedule>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
typedef sender result_type;
};
} // namespace traits
} // namespace asio
} // namespace boost
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SCHEDULE_MEMBER_TRAIT)
struct free_schedule_non_const_receiver
{
friend sender schedule(
free_schedule_non_const_receiver&) BOOST_ASIO_NOEXCEPT
{
return sender();
}
};
#if !defined(BOOST_ASIO_HAS_DEDUCED_SCHEDULE_FREE_TRAIT)
namespace boost {
namespace asio {
namespace traits {
template <>
struct schedule_free<free_schedule_non_const_receiver>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
typedef sender result_type;
};
} // namespace traits
} // namespace asio
} // namespace boost
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SCHEDULE_FREE_TRAIT)
struct executor
{
executor()
{
}
executor(const executor&) BOOST_ASIO_NOEXCEPT
{
}
#if defined(BOOST_ASIO_HAS_MOVE)
executor(executor&&) BOOST_ASIO_NOEXCEPT
{
}
#endif // defined(BOOST_ASIO_HAS_MOVE)
template <typename F>
void execute(BOOST_ASIO_MOVE_ARG(F) f) const BOOST_ASIO_NOEXCEPT
{
typename boost::asio::decay<F>::type tmp(BOOST_ASIO_MOVE_CAST(F)(f));
tmp();
}
bool operator==(const executor&) const BOOST_ASIO_NOEXCEPT
{
return true;
}
bool operator!=(const executor&) const BOOST_ASIO_NOEXCEPT
{
return false;
}
};
namespace boost {
namespace asio {
namespace traits {
#if !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
template <typename F>
struct execute_member<executor, F>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
typedef void result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)
#if !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
template <>
struct equality_comparable<executor>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
} // namespace traits
} // namespace asio
} // namespace boost
void test_can_schedule()
{
BOOST_ASIO_CONSTEXPR bool b1 = exec::can_schedule<
no_schedule&>::value;
BOOST_ASIO_CHECK(b1 == false);
BOOST_ASIO_CONSTEXPR bool b2 = exec::can_schedule<
const no_schedule&>::value;
BOOST_ASIO_CHECK(b2 == false);
BOOST_ASIO_CONSTEXPR bool b3 = exec::can_schedule<
const_member_schedule&>::value;
BOOST_ASIO_CHECK(b3 == true);
BOOST_ASIO_CONSTEXPR bool b4 = exec::can_schedule<
const const_member_schedule&>::value;
BOOST_ASIO_CHECK(b4 == true);
BOOST_ASIO_CONSTEXPR bool b5 = exec::can_schedule<
free_schedule_const_receiver&>::value;
BOOST_ASIO_CHECK(b5 == true);
BOOST_ASIO_CONSTEXPR bool b6 = exec::can_schedule<
const free_schedule_const_receiver&>::value;
BOOST_ASIO_CHECK(b6 == true);
BOOST_ASIO_CONSTEXPR bool b7 = exec::can_schedule<
non_const_member_schedule&>::value;
BOOST_ASIO_CHECK(b7 == true);
BOOST_ASIO_CONSTEXPR bool b8 = exec::can_schedule<
const non_const_member_schedule&>::value;
BOOST_ASIO_CHECK(b8 == false);
BOOST_ASIO_CONSTEXPR bool b9 = exec::can_schedule<
free_schedule_non_const_receiver&>::value;
BOOST_ASIO_CHECK(b9 == true);
BOOST_ASIO_CONSTEXPR bool b10 = exec::can_schedule<
const free_schedule_non_const_receiver&>::value;
BOOST_ASIO_CHECK(b10 == false);
BOOST_ASIO_CONSTEXPR bool b11 = exec::can_schedule<
executor&>::value;
BOOST_ASIO_CHECK(b11 == true);
BOOST_ASIO_CONSTEXPR bool b12 = exec::can_schedule<
const executor&>::value;
BOOST_ASIO_CHECK(b12 == true);
}
struct receiver
{
int* count_;
receiver(int* count)
: count_(count)
{
}
receiver(const receiver& other) BOOST_ASIO_NOEXCEPT
: count_(other.count_)
{
}
#if defined(BOOST_ASIO_HAS_MOVE)
receiver(receiver&& other) BOOST_ASIO_NOEXCEPT
: count_(other.count_)
{
other.count_ = 0;
}
#endif // defined(BOOST_ASIO_HAS_MOVE)
void set_value() BOOST_ASIO_NOEXCEPT
{
++(*count_);
}
template <typename E>
void set_error(BOOST_ASIO_MOVE_ARG(E) e) BOOST_ASIO_NOEXCEPT
{
(void)e;
}
void set_done() BOOST_ASIO_NOEXCEPT
{
}
};
namespace boost {
namespace asio {
namespace traits {
#if !defined(BOOST_ASIO_HAS_DEDUCED_SET_VALUE_MEMBER_TRAIT)
template <>
struct set_value_member<receiver, void()>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
typedef void result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_VALUE_MEMBER_TRAIT)
#if !defined(BOOST_ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)
template <typename E>
struct set_error_member<receiver, E>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
typedef void result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)
#if !defined(BOOST_ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)
template <>
struct set_done_member<receiver>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
typedef void result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)
} // namespace traits
} // namespace asio
} // namespace boost
void test_schedule()
{
int count = 0;
const_member_schedule ex1 = {};
exec::submit(
exec::schedule(ex1),
receiver(&count));
BOOST_ASIO_CHECK(count == 1);
count = 0;
const const_member_schedule ex2 = {};
exec::submit(
exec::schedule(ex2),
receiver(&count));
BOOST_ASIO_CHECK(count == 1);
count = 0;
exec::submit(
exec::schedule(const_member_schedule()),
receiver(&count));
BOOST_ASIO_CHECK(count == 1);
count = 0;
free_schedule_const_receiver ex3 = {};
exec::submit(
exec::schedule(ex3),
receiver(&count));
BOOST_ASIO_CHECK(count == 1);
count = 0;
const free_schedule_const_receiver ex4 = {};
exec::submit(
exec::schedule(ex4),
receiver(&count));
BOOST_ASIO_CHECK(count == 1);
count = 0;
exec::submit(
exec::schedule(free_schedule_const_receiver()),
receiver(&count));
BOOST_ASIO_CHECK(count == 1);
count = 0;
non_const_member_schedule ex5 = {};
exec::submit(
exec::schedule(ex5),
receiver(&count));
BOOST_ASIO_CHECK(count == 1);
count = 0;
free_schedule_non_const_receiver ex6 = {};
exec::submit(
exec::schedule(ex6),
receiver(&count));
BOOST_ASIO_CHECK(count == 1);
count = 0;
executor ex7;
exec::submit(
exec::schedule(ex7),
receiver(&count));
BOOST_ASIO_CHECK(count == 1);
count = 0;
const executor ex8;
exec::submit(
exec::schedule(ex8),
receiver(&count));
BOOST_ASIO_CHECK(count == 1);
count = 0;
exec::submit(
exec::schedule(executor()),
receiver(&count));
BOOST_ASIO_CHECK(count == 1);
}
BOOST_ASIO_TEST_SUITE
(
"schedule",
BOOST_ASIO_TEST_CASE(test_can_schedule)
BOOST_ASIO_TEST_CASE(test_schedule)
)

View File

@@ -0,0 +1,101 @@
//
// scheduler.cpp
// ~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/execution/scheduler.hpp>
#include "../unit_test.hpp"
namespace exec = boost::asio::execution;
struct not_a_scheduler
{
};
struct executor
{
executor()
{
}
executor(const executor&) BOOST_ASIO_NOEXCEPT
{
}
#if defined(BOOST_ASIO_HAS_MOVE)
executor(executor&&) BOOST_ASIO_NOEXCEPT
{
}
#endif // defined(BOOST_ASIO_HAS_MOVE)
template <typename F>
void execute(BOOST_ASIO_MOVE_ARG(F) f) const BOOST_ASIO_NOEXCEPT
{
(void)f;
}
bool operator==(const executor&) const BOOST_ASIO_NOEXCEPT
{
return true;
}
bool operator!=(const executor&) const BOOST_ASIO_NOEXCEPT
{
return false;
}
};
namespace boost {
namespace asio {
namespace traits {
#if !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
template <typename F>
struct execute_member<executor, F>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
typedef void result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)
#if !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
template <>
struct equality_comparable<executor>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
} // namespace traits
} // namespace asio
} // namespace boost
void test_is_scheduler()
{
BOOST_ASIO_CHECK(!exec::is_scheduler<void>::value);
BOOST_ASIO_CHECK(!exec::is_scheduler<not_a_scheduler>::value);
BOOST_ASIO_CHECK(exec::is_scheduler<executor>::value);
}
BOOST_ASIO_TEST_SUITE
(
"scheduler",
BOOST_ASIO_TEST_CASE(test_is_scheduler)
)

View File

@@ -0,0 +1,237 @@
//
// sender.cpp
// ~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/execution/sender.hpp>
#include <boost/system/error_code.hpp>
#include "../unit_test.hpp"
namespace exec = boost::asio::execution;
struct not_a_sender
{
};
struct sender_using_base :
boost::asio::execution::sender_base
{
sender_using_base()
{
}
};
struct executor
{
executor()
{
}
executor(const executor&) BOOST_ASIO_NOEXCEPT
{
}
#if defined(BOOST_ASIO_HAS_MOVE)
executor(executor&&) BOOST_ASIO_NOEXCEPT
{
}
#endif // defined(BOOST_ASIO_HAS_MOVE)
template <typename F>
void execute(BOOST_ASIO_MOVE_ARG(F) f) const BOOST_ASIO_NOEXCEPT
{
(void)f;
}
bool operator==(const executor&) const BOOST_ASIO_NOEXCEPT
{
return true;
}
bool operator!=(const executor&) const BOOST_ASIO_NOEXCEPT
{
return false;
}
};
namespace boost {
namespace asio {
namespace traits {
#if !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
template <typename F>
struct execute_member<executor, F>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
typedef void result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)
#if !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
template <>
struct equality_comparable<executor>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
} // namespace traits
} // namespace asio
} // namespace boost
#if defined(BOOST_ASIO_HAS_DEDUCED_EXECUTION_IS_TYPED_SENDER_TRAIT)
struct operation_state
{
void start() BOOST_ASIO_NOEXCEPT
{
}
};
namespace boost {
namespace asio {
namespace traits {
#if !defined(BOOST_ASIO_HAS_DEDUCED_START_MEMBER_TRAIT)
template <>
struct start_member<operation_state>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
typedef void result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_START_MEMBER_TRAIT)
} // namespace traits
} // namespace asio
} // namespace boost
struct typed_sender
{
template <
template <typename...> class Tuple,
template <typename...> class Variant>
using value_types = Variant<Tuple<int>>;
template <template <typename...> class Variant>
using error_types = Variant<boost::system::error_code>;
BOOST_ASIO_STATIC_CONSTEXPR(bool, sends_done = true);
typed_sender()
{
}
template <typename R>
operation_state connect(BOOST_ASIO_MOVE_ARG(R) r) const
{
(void)r;
return operation_state();
}
};
namespace boost {
namespace asio {
namespace traits {
#if !defined(BOOST_ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT)
template <typename R>
struct connect_member<const typed_sender, R>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
typedef operation_state result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT)
} // namespace traits
} // namespace asio
} // namespace boost
#endif // defined(BOOST_ASIO_HAS_DEDUCED_EXECUTION_IS_TYPED_SENDER_TRAIT)
template <typename T>
bool is_unspecialised(T*, ...)
{
return false;
}
template <typename T>
bool is_unspecialised(T*,
typename boost::asio::void_type<
typename exec::sender_traits<
T>::asio_execution_sender_traits_base_is_unspecialised
>::type*)
{
return true;
}
void test_sender_traits()
{
not_a_sender s1;
BOOST_ASIO_CHECK(is_unspecialised(&s1, static_cast<void*>(0)));
sender_using_base s2;
BOOST_ASIO_CHECK(!is_unspecialised(&s2, static_cast<void*>(0)));
executor s3;
BOOST_ASIO_CHECK(!is_unspecialised(&s3, static_cast<void*>(0)));
#if defined(BOOST_ASIO_HAS_DEDUCED_EXECUTION_IS_TYPED_SENDER_TRAIT)
typed_sender s4;
BOOST_ASIO_CHECK(!is_unspecialised(&s4, static_cast<void*>(0)));
#endif // defined(BOOST_ASIO_HAS_DEDUCED_EXECUTION_IS_TYPED_SENDER_TRAIT)
}
void test_is_sender()
{
BOOST_ASIO_CHECK(!exec::is_sender<void>::value);
BOOST_ASIO_CHECK(!exec::is_sender<not_a_sender>::value);
BOOST_ASIO_CHECK(exec::is_sender<sender_using_base>::value);
BOOST_ASIO_CHECK(exec::is_sender<executor>::value);
#if defined(BOOST_ASIO_HAS_DEDUCED_EXECUTION_IS_TYPED_SENDER_TRAIT)
BOOST_ASIO_CHECK(exec::is_sender<typed_sender>::value);
#endif // defined(BOOST_ASIO_HAS_DEDUCED_EXECUTION_IS_TYPED_SENDER_TRAIT)
}
void test_is_typed_sender()
{
BOOST_ASIO_CHECK(!exec::is_typed_sender<void>::value);
BOOST_ASIO_CHECK(!exec::is_typed_sender<not_a_sender>::value);
BOOST_ASIO_CHECK(!exec::is_typed_sender<sender_using_base>::value);
#if defined(BOOST_ASIO_HAS_DEDUCED_EXECUTION_IS_TYPED_SENDER_TRAIT)
BOOST_ASIO_CHECK(exec::is_typed_sender<executor>::value);
BOOST_ASIO_CHECK(exec::is_typed_sender<typed_sender>::value);
#endif // defined(BOOST_ASIO_HAS_DEDUCED_EXECUTION_IS_TYPED_SENDER_TRAIT)
}
BOOST_ASIO_TEST_SUITE
(
"sender",
BOOST_ASIO_TEST_CASE(test_sender_traits)
BOOST_ASIO_TEST_CASE(test_is_sender)
BOOST_ASIO_TEST_CASE(test_is_typed_sender)
)

View File

@@ -0,0 +1,236 @@
//
// set_done.cpp
// ~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/execution/set_done.hpp>
#include <boost/system/error_code.hpp>
#include "../unit_test.hpp"
namespace exec = boost::asio::execution;
static int call_count = 0;
struct no_set_done
{
};
struct const_member_set_done
{
void set_done() const BOOST_ASIO_NOEXCEPT
{
++call_count;
}
};
#if !defined(BOOST_ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)
namespace boost {
namespace asio {
namespace traits {
template <>
struct set_done_member<const const_member_set_done>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
typedef void result_type;
};
} // namespace traits
} // namespace asio
} // namespace boost
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)
struct free_set_done_const_receiver
{
friend void set_done(const free_set_done_const_receiver&) BOOST_ASIO_NOEXCEPT
{
++call_count;
}
};
#if !defined(BOOST_ASIO_HAS_DEDUCED_SET_DONE_FREE_TRAIT)
namespace boost {
namespace asio {
namespace traits {
template <>
struct set_done_free<const free_set_done_const_receiver>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
typedef void result_type;
};
} // namespace traits
} // namespace asio
} // namespace boost
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_DONE_FREE_TRAIT)
struct non_const_member_set_done
{
void set_done() BOOST_ASIO_NOEXCEPT
{
++call_count;
}
};
#if !defined(BOOST_ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)
namespace boost {
namespace asio {
namespace traits {
template <>
struct set_done_member<non_const_member_set_done>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
typedef void result_type;
};
} // namespace traits
} // namespace asio
} // namespace boost
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)
struct free_set_done_non_const_receiver
{
friend void set_done(free_set_done_non_const_receiver&) BOOST_ASIO_NOEXCEPT
{
++call_count;
}
};
#if !defined(BOOST_ASIO_HAS_DEDUCED_SET_DONE_FREE_TRAIT)
namespace boost {
namespace asio {
namespace traits {
template <>
struct set_done_free<free_set_done_non_const_receiver>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
typedef void result_type;
};
} // namespace traits
} // namespace asio
} // namespace boost
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_DONE_FREE_TRAIT)
void test_can_set_done()
{
BOOST_ASIO_CONSTEXPR bool b1 = exec::can_set_done<
no_set_done&>::value;
BOOST_ASIO_CHECK(b1 == false);
BOOST_ASIO_CONSTEXPR bool b2 = exec::can_set_done<
const no_set_done&>::value;
BOOST_ASIO_CHECK(b2 == false);
BOOST_ASIO_CONSTEXPR bool b3 = exec::can_set_done<
const_member_set_done&>::value;
BOOST_ASIO_CHECK(b3 == true);
BOOST_ASIO_CONSTEXPR bool b4 = exec::can_set_done<
const const_member_set_done&>::value;
BOOST_ASIO_CHECK(b4 == true);
BOOST_ASIO_CONSTEXPR bool b5 = exec::can_set_done<
free_set_done_const_receiver&>::value;
BOOST_ASIO_CHECK(b5 == true);
BOOST_ASIO_CONSTEXPR bool b6 = exec::can_set_done<
const free_set_done_const_receiver&>::value;
BOOST_ASIO_CHECK(b6 == true);
BOOST_ASIO_CONSTEXPR bool b7 = exec::can_set_done<
non_const_member_set_done&>::value;
BOOST_ASIO_CHECK(b7 == true);
BOOST_ASIO_CONSTEXPR bool b8 = exec::can_set_done<
const non_const_member_set_done&>::value;
BOOST_ASIO_CHECK(b8 == false);
BOOST_ASIO_CONSTEXPR bool b9 = exec::can_set_done<
free_set_done_non_const_receiver&>::value;
BOOST_ASIO_CHECK(b9 == true);
BOOST_ASIO_CONSTEXPR bool b10 = exec::can_set_done<
const free_set_done_non_const_receiver&>::value;
BOOST_ASIO_CHECK(b10 == false);
}
void increment(int* count)
{
++(*count);
}
void test_set_done()
{
call_count = 0;
const_member_set_done ex1 = {};
exec::set_done(ex1);
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
const const_member_set_done ex2 = {};
exec::set_done(ex2);
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
exec::set_done(const_member_set_done());
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
free_set_done_const_receiver ex3 = {};
exec::set_done(ex3);
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
const free_set_done_const_receiver ex4 = {};
exec::set_done(ex4);
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
exec::set_done(free_set_done_const_receiver());
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
non_const_member_set_done ex5 = {};
exec::set_done(ex5);
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
free_set_done_non_const_receiver ex6 = {};
exec::set_done(ex6);
BOOST_ASIO_CHECK(call_count == 1);
}
BOOST_ASIO_TEST_SUITE
(
"set_done",
BOOST_ASIO_TEST_CASE(test_can_set_done)
BOOST_ASIO_TEST_CASE(test_set_done)
)

View File

@@ -0,0 +1,252 @@
//
// set_error.cpp
// ~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/execution/set_error.hpp>
#include <boost/system/error_code.hpp>
#include "../unit_test.hpp"
namespace exec = boost::asio::execution;
static int call_count = 0;
struct no_set_error
{
};
struct const_member_set_error
{
template <typename E>
void set_error(BOOST_ASIO_MOVE_ARG(E) e) const BOOST_ASIO_NOEXCEPT
{
typename boost::asio::decay<E>::type tmp(BOOST_ASIO_MOVE_CAST(E)(e));
(void)tmp;
++call_count;
}
};
#if !defined(BOOST_ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)
namespace boost {
namespace asio {
namespace traits {
template <typename E>
struct set_error_member<const const_member_set_error, E>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
typedef void result_type;
};
} // namespace traits
} // namespace asio
} // namespace boost
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)
struct free_set_error_const_receiver
{
template <typename E>
friend void set_error(const free_set_error_const_receiver&,
BOOST_ASIO_MOVE_ARG(E) e) BOOST_ASIO_NOEXCEPT
{
typename boost::asio::decay<E>::type tmp(BOOST_ASIO_MOVE_CAST(E)(e));
(void)tmp;
++call_count;
}
};
#if !defined(BOOST_ASIO_HAS_DEDUCED_SET_ERROR_FREE_TRAIT)
namespace boost {
namespace asio {
namespace traits {
template <typename E>
struct set_error_free<const free_set_error_const_receiver, E>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
typedef void result_type;
};
} // namespace traits
} // namespace asio
} // namespace boost
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_ERROR_FREE_TRAIT)
struct non_const_member_set_error
{
template <typename E>
void set_error(BOOST_ASIO_MOVE_ARG(E) e) BOOST_ASIO_NOEXCEPT
{
typename boost::asio::decay<E>::type tmp(BOOST_ASIO_MOVE_CAST(E)(e));
(void)tmp;
++call_count;
}
};
#if !defined(BOOST_ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)
namespace boost {
namespace asio {
namespace traits {
template <typename E>
struct set_error_member<non_const_member_set_error, E>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
typedef void result_type;
};
} // namespace traits
} // namespace asio
} // namespace boost
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)
struct free_set_error_non_const_receiver
{
template <typename E>
friend void set_error(free_set_error_non_const_receiver&,
BOOST_ASIO_MOVE_ARG(E) e) BOOST_ASIO_NOEXCEPT
{
typename boost::asio::decay<E>::type tmp(BOOST_ASIO_MOVE_CAST(E)(e));
(void)tmp;
++call_count;
}
};
#if !defined(BOOST_ASIO_HAS_DEDUCED_SET_ERROR_FREE_TRAIT)
namespace boost {
namespace asio {
namespace traits {
template <typename E>
struct set_error_free<free_set_error_non_const_receiver, E>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
typedef void result_type;
};
} // namespace traits
} // namespace asio
} // namespace boost
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_ERROR_FREE_TRAIT)
void test_can_set_error()
{
BOOST_ASIO_CONSTEXPR bool b1 = exec::can_set_error<
no_set_error&, boost::system::error_code>::value;
BOOST_ASIO_CHECK(b1 == false);
BOOST_ASIO_CONSTEXPR bool b2 = exec::can_set_error<
const no_set_error&, boost::system::error_code>::value;
BOOST_ASIO_CHECK(b2 == false);
BOOST_ASIO_CONSTEXPR bool b3 = exec::can_set_error<
const_member_set_error&, boost::system::error_code>::value;
BOOST_ASIO_CHECK(b3 == true);
BOOST_ASIO_CONSTEXPR bool b4 = exec::can_set_error<
const const_member_set_error&, boost::system::error_code>::value;
BOOST_ASIO_CHECK(b4 == true);
BOOST_ASIO_CONSTEXPR bool b5 = exec::can_set_error<
free_set_error_const_receiver&, boost::system::error_code>::value;
BOOST_ASIO_CHECK(b5 == true);
BOOST_ASIO_CONSTEXPR bool b6 = exec::can_set_error<
const free_set_error_const_receiver&, boost::system::error_code>::value;
BOOST_ASIO_CHECK(b6 == true);
BOOST_ASIO_CONSTEXPR bool b7 = exec::can_set_error<
non_const_member_set_error&, boost::system::error_code>::value;
BOOST_ASIO_CHECK(b7 == true);
BOOST_ASIO_CONSTEXPR bool b8 = exec::can_set_error<
const non_const_member_set_error&, boost::system::error_code>::value;
BOOST_ASIO_CHECK(b8 == false);
BOOST_ASIO_CONSTEXPR bool b9 = exec::can_set_error<
free_set_error_non_const_receiver&, boost::system::error_code>::value;
BOOST_ASIO_CHECK(b9 == true);
BOOST_ASIO_CONSTEXPR bool b10 = exec::can_set_error<
const free_set_error_non_const_receiver&, boost::system::error_code>::value;
BOOST_ASIO_CHECK(b10 == false);
}
void increment(int* count)
{
++(*count);
}
void test_set_error()
{
boost::system::error_code ec;
call_count = 0;
const_member_set_error ex1 = {};
exec::set_error(ex1, ec);
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
const const_member_set_error ex2 = {};
exec::set_error(ex2, ec);
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
exec::set_error(const_member_set_error(), ec);
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
free_set_error_const_receiver ex3 = {};
exec::set_error(ex3, ec);
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
const free_set_error_const_receiver ex4 = {};
exec::set_error(ex4, ec);
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
exec::set_error(free_set_error_const_receiver(), ec);
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
non_const_member_set_error ex5 = {};
exec::set_error(ex5, ec);
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
free_set_error_non_const_receiver ex6 = {};
exec::set_error(ex6, ec);
BOOST_ASIO_CHECK(call_count == 1);
}
BOOST_ASIO_TEST_SUITE
(
"set_error",
BOOST_ASIO_TEST_CASE(test_can_set_error)
BOOST_ASIO_TEST_CASE(test_set_error)
)

View File

@@ -0,0 +1,844 @@
//
// set_value.cpp
// ~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/execution/set_value.hpp>
#include <string>
#include "../unit_test.hpp"
namespace exec = boost::asio::execution;
static int call_count = 0;
struct no_set_value
{
};
struct const_member_set_value_0
{
void set_value() const
{
++call_count;
}
};
#if !defined(BOOST_ASIO_HAS_DEDUCED_SET_VALUE_MEMBER_TRAIT)
namespace boost {
namespace asio {
namespace traits {
template <>
struct set_value_member<const const_member_set_value_0, void()>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
typedef void result_type;
};
} // namespace traits
} // namespace asio
} // namespace boost
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_VALUE_MEMBER_TRAIT)
struct const_member_set_value_1
{
template <typename V1>
void set_value(BOOST_ASIO_MOVE_ARG(V1) v1) const
{
typename boost::asio::decay<V1>::type tmp(BOOST_ASIO_MOVE_CAST(V1)(v1));
(void)tmp;
++call_count;
}
};
#if !defined(BOOST_ASIO_HAS_DEDUCED_SET_VALUE_MEMBER_TRAIT)
namespace boost {
namespace asio {
namespace traits {
template <typename V1>
struct set_value_member<const const_member_set_value_1, void(V1)>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
typedef void result_type;
};
} // namespace traits
} // namespace asio
} // namespace boost
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_VALUE_MEMBER_TRAIT)
struct const_member_set_value_2
{
template <typename V1, typename V2>
void set_value(BOOST_ASIO_MOVE_ARG(V1) v1, BOOST_ASIO_MOVE_ARG(V2) v2) const
{
typename boost::asio::decay<V1>::type tmp1(BOOST_ASIO_MOVE_CAST(V1)(v1));
(void)tmp1;
typename boost::asio::decay<V2>::type tmp2(BOOST_ASIO_MOVE_CAST(V2)(v2));
(void)tmp2;
++call_count;
}
};
#if !defined(BOOST_ASIO_HAS_DEDUCED_SET_VALUE_MEMBER_TRAIT)
namespace boost {
namespace asio {
namespace traits {
template <typename V1, typename V2>
struct set_value_member<const const_member_set_value_2, void(V1, V2)>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
typedef void result_type;
};
} // namespace traits
} // namespace asio
} // namespace boost
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_VALUE_MEMBER_TRAIT)
struct free_set_value_const_receiver_0
{
friend void set_value(const free_set_value_const_receiver_0&)
{
++call_count;
}
};
#if !defined(BOOST_ASIO_HAS_DEDUCED_SET_VALUE_FREE_TRAIT)
namespace boost {
namespace asio {
namespace traits {
template <>
struct set_value_free<const free_set_value_const_receiver_0, void()>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
typedef void result_type;
};
} // namespace traits
} // namespace asio
} // namespace boost
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_VALUE_FREE_TRAIT)
struct free_set_value_const_receiver_1
{
template <typename V1>
friend void set_value(const free_set_value_const_receiver_1&,
BOOST_ASIO_MOVE_ARG(V1) v1)
{
typename boost::asio::decay<V1>::type tmp(BOOST_ASIO_MOVE_CAST(V1)(v1));
(void)tmp;
++call_count;
}
};
#if !defined(BOOST_ASIO_HAS_DEDUCED_SET_VALUE_FREE_TRAIT)
namespace boost {
namespace asio {
namespace traits {
template <typename V1>
struct set_value_free<const free_set_value_const_receiver_1, void(V1)>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
typedef void result_type;
};
} // namespace traits
} // namespace asio
} // namespace boost
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_VALUE_FREE_TRAIT)
struct free_set_value_const_receiver_2
{
template <typename V1, typename V2>
friend void set_value(const free_set_value_const_receiver_2&,
BOOST_ASIO_MOVE_ARG(V1) v1, BOOST_ASIO_MOVE_ARG(V2) v2)
{
typename boost::asio::decay<V1>::type tmp1(BOOST_ASIO_MOVE_CAST(V1)(v1));
(void)tmp1;
typename boost::asio::decay<V2>::type tmp2(BOOST_ASIO_MOVE_CAST(V2)(v2));
(void)tmp2;
++call_count;
}
};
#if !defined(BOOST_ASIO_HAS_DEDUCED_SET_VALUE_FREE_TRAIT)
namespace boost {
namespace asio {
namespace traits {
template <typename V1, typename V2>
struct set_value_free<const free_set_value_const_receiver_2, void(V1, V2)>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
typedef void result_type;
};
} // namespace traits
} // namespace asio
} // namespace boost
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_VALUE_FREE_TRAIT)
struct non_const_member_set_value_0
{
void set_value()
{
++call_count;
}
};
#if !defined(BOOST_ASIO_HAS_DEDUCED_SET_VALUE_MEMBER_TRAIT)
namespace boost {
namespace asio {
namespace traits {
template <>
struct set_value_member<non_const_member_set_value_0, void()>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
typedef void result_type;
};
} // namespace traits
} // namespace asio
} // namespace boost
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_VALUE_MEMBER_TRAIT)
struct non_const_member_set_value_1
{
template <typename V1>
void set_value(BOOST_ASIO_MOVE_ARG(V1) v1)
{
typename boost::asio::decay<V1>::type tmp(BOOST_ASIO_MOVE_CAST(V1)(v1));
(void)tmp;
++call_count;
}
};
#if !defined(BOOST_ASIO_HAS_DEDUCED_SET_VALUE_MEMBER_TRAIT)
namespace boost {
namespace asio {
namespace traits {
template <typename V1>
struct set_value_member<non_const_member_set_value_1, void(V1)>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
typedef void result_type;
};
} // namespace traits
} // namespace asio
} // namespace boost
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_VALUE_MEMBER_TRAIT)
struct non_const_member_set_value_2
{
template <typename V1, typename V2>
void set_value(BOOST_ASIO_MOVE_ARG(V1) v1, BOOST_ASIO_MOVE_ARG(V2) v2)
{
typename boost::asio::decay<V1>::type tmp1(BOOST_ASIO_MOVE_CAST(V1)(v1));
(void)tmp1;
typename boost::asio::decay<V2>::type tmp2(BOOST_ASIO_MOVE_CAST(V2)(v2));
(void)tmp2;
++call_count;
}
};
#if !defined(BOOST_ASIO_HAS_DEDUCED_SET_VALUE_MEMBER_TRAIT)
namespace boost {
namespace asio {
namespace traits {
template <typename V1, typename V2>
struct set_value_member<non_const_member_set_value_2, void(V1, V2)>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
typedef void result_type;
};
} // namespace traits
} // namespace asio
} // namespace boost
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_VALUE_MEMBER_TRAIT)
struct free_set_value_non_const_receiver_0
{
friend void set_value(free_set_value_non_const_receiver_0&)
{
++call_count;
}
};
#if !defined(BOOST_ASIO_HAS_DEDUCED_SET_VALUE_FREE_TRAIT)
namespace boost {
namespace asio {
namespace traits {
template <>
struct set_value_free<free_set_value_non_const_receiver_0, void()>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
typedef void result_type;
};
} // namespace traits
} // namespace asio
} // namespace boost
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_VALUE_FREE_TRAIT)
struct free_set_value_non_const_receiver_1
{
template <typename V1>
friend void set_value(free_set_value_non_const_receiver_1&,
BOOST_ASIO_MOVE_ARG(V1) v1)
{
typename boost::asio::decay<V1>::type tmp(BOOST_ASIO_MOVE_CAST(V1)(v1));
(void)tmp;
++call_count;
}
};
#if !defined(BOOST_ASIO_HAS_DEDUCED_SET_VALUE_FREE_TRAIT)
namespace boost {
namespace asio {
namespace traits {
template <typename V1>
struct set_value_free<free_set_value_non_const_receiver_1, void(V1)>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
typedef void result_type;
};
} // namespace traits
} // namespace asio
} // namespace boost
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_VALUE_FREE_TRAIT)
struct free_set_value_non_const_receiver_2
{
template <typename V1, typename V2>
friend void set_value(free_set_value_non_const_receiver_2&,
BOOST_ASIO_MOVE_ARG(V1) v1, BOOST_ASIO_MOVE_ARG(V2) v2)
{
typename boost::asio::decay<V1>::type tmp1(BOOST_ASIO_MOVE_CAST(V1)(v1));
(void)tmp1;
typename boost::asio::decay<V2>::type tmp2(BOOST_ASIO_MOVE_CAST(V2)(v2));
(void)tmp2;
++call_count;
}
};
#if !defined(BOOST_ASIO_HAS_DEDUCED_SET_VALUE_FREE_TRAIT)
namespace boost {
namespace asio {
namespace traits {
template <typename V1, typename V2>
struct set_value_free<free_set_value_non_const_receiver_2, void(V1, V2)>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
typedef void result_type;
};
} // namespace traits
} // namespace asio
} // namespace boost
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_VALUE_FREE_TRAIT)
void test_can_set_value()
{
BOOST_ASIO_CONSTEXPR bool b1 = exec::can_set_value<
no_set_value&>::value;
BOOST_ASIO_CHECK(b1 == false);
BOOST_ASIO_CONSTEXPR bool b2 = exec::can_set_value<
const no_set_value&>::value;
BOOST_ASIO_CHECK(b2 == false);
BOOST_ASIO_CONSTEXPR bool b3 = exec::can_set_value<
no_set_value&, int>::value;
BOOST_ASIO_CHECK(b3 == false);
BOOST_ASIO_CONSTEXPR bool b4 = exec::can_set_value<
const no_set_value&, int>::value;
BOOST_ASIO_CHECK(b4 == false);
BOOST_ASIO_CONSTEXPR bool b5 = exec::can_set_value<
no_set_value&, int, std::string>::value;
BOOST_ASIO_CHECK(b5 == false);
BOOST_ASIO_CONSTEXPR bool b6 = exec::can_set_value<
const no_set_value&, int, std::string>::value;
BOOST_ASIO_CHECK(b6 == false);
BOOST_ASIO_CONSTEXPR bool b7 = exec::can_set_value<
const_member_set_value_0&>::value;
BOOST_ASIO_CHECK(b7 == true);
BOOST_ASIO_CONSTEXPR bool b8 = exec::can_set_value<
const const_member_set_value_0&>::value;
BOOST_ASIO_CHECK(b8 == true);
BOOST_ASIO_CONSTEXPR bool b9 = exec::can_set_value<
const_member_set_value_0&, int>::value;
BOOST_ASIO_CHECK(b9 == false);
BOOST_ASIO_CONSTEXPR bool b10 = exec::can_set_value<
const const_member_set_value_0&, int>::value;
BOOST_ASIO_CHECK(b10 == false);
BOOST_ASIO_CONSTEXPR bool b11 = exec::can_set_value<
const_member_set_value_0&, int, std::string>::value;
BOOST_ASIO_CHECK(b11 == false);
BOOST_ASIO_CONSTEXPR bool b12 = exec::can_set_value<
const const_member_set_value_0&, int, std::string>::value;
BOOST_ASIO_CHECK(b12 == false);
BOOST_ASIO_CONSTEXPR bool b13 = exec::can_set_value<
const_member_set_value_1&>::value;
BOOST_ASIO_CHECK(b13 == false);
BOOST_ASIO_CONSTEXPR bool b14 = exec::can_set_value<
const const_member_set_value_1&>::value;
BOOST_ASIO_CHECK(b14 == false);
BOOST_ASIO_CONSTEXPR bool b15 = exec::can_set_value<
const_member_set_value_1&, int>::value;
BOOST_ASIO_CHECK(b15 == true);
BOOST_ASIO_CONSTEXPR bool b16 = exec::can_set_value<
const const_member_set_value_1&, int>::value;
BOOST_ASIO_CHECK(b16 == true);
BOOST_ASIO_CONSTEXPR bool b17 = exec::can_set_value<
const_member_set_value_1&, int, std::string>::value;
BOOST_ASIO_CHECK(b17 == false);
BOOST_ASIO_CONSTEXPR bool b18 = exec::can_set_value<
const const_member_set_value_1&, int, std::string>::value;
BOOST_ASIO_CHECK(b18 == false);
BOOST_ASIO_CONSTEXPR bool b19 = exec::can_set_value<
const_member_set_value_2&>::value;
BOOST_ASIO_CHECK(b19 == false);
BOOST_ASIO_CONSTEXPR bool b20 = exec::can_set_value<
const const_member_set_value_2&>::value;
BOOST_ASIO_CHECK(b20 == false);
BOOST_ASIO_CONSTEXPR bool b21 = exec::can_set_value<
const_member_set_value_2&, int>::value;
BOOST_ASIO_CHECK(b21 == false);
BOOST_ASIO_CONSTEXPR bool b22 = exec::can_set_value<
const const_member_set_value_2&, int>::value;
BOOST_ASIO_CHECK(b22 == false);
BOOST_ASIO_CONSTEXPR bool b23 = exec::can_set_value<
const_member_set_value_2&, int, std::string>::value;
BOOST_ASIO_CHECK(b23 == true);
BOOST_ASIO_CONSTEXPR bool b24 = exec::can_set_value<
const const_member_set_value_2&, int, std::string>::value;
BOOST_ASIO_CHECK(b24 == true);
BOOST_ASIO_CONSTEXPR bool b25 = exec::can_set_value<
free_set_value_const_receiver_0&>::value;
BOOST_ASIO_CHECK(b25 == true);
BOOST_ASIO_CONSTEXPR bool b26 = exec::can_set_value<
const free_set_value_const_receiver_0&>::value;
BOOST_ASIO_CHECK(b26 == true);
BOOST_ASIO_CONSTEXPR bool b27 = exec::can_set_value<
free_set_value_const_receiver_0&, int>::value;
BOOST_ASIO_CHECK(b27 == false);
BOOST_ASIO_CONSTEXPR bool b28 = exec::can_set_value<
const free_set_value_const_receiver_0&, int>::value;
BOOST_ASIO_CHECK(b28 == false);
BOOST_ASIO_CONSTEXPR bool b29 = exec::can_set_value<
free_set_value_const_receiver_0&, int, std::string>::value;
BOOST_ASIO_CHECK(b29 == false);
BOOST_ASIO_CONSTEXPR bool b30 = exec::can_set_value<
const free_set_value_const_receiver_0&, int, std::string>::value;
BOOST_ASIO_CHECK(b30 == false);
BOOST_ASIO_CONSTEXPR bool b31 = exec::can_set_value<
free_set_value_const_receiver_1&>::value;
BOOST_ASIO_CHECK(b31 == false);
BOOST_ASIO_CONSTEXPR bool b32 = exec::can_set_value<
const free_set_value_const_receiver_1&>::value;
BOOST_ASIO_CHECK(b32 == false);
BOOST_ASIO_CONSTEXPR bool b33 = exec::can_set_value<
free_set_value_const_receiver_1&, int>::value;
BOOST_ASIO_CHECK(b33 == true);
BOOST_ASIO_CONSTEXPR bool b34 = exec::can_set_value<
const free_set_value_const_receiver_1&, int>::value;
BOOST_ASIO_CHECK(b34 == true);
BOOST_ASIO_CONSTEXPR bool b35 = exec::can_set_value<
free_set_value_const_receiver_1&, int, std::string>::value;
BOOST_ASIO_CHECK(b35 == false);
BOOST_ASIO_CONSTEXPR bool b36 = exec::can_set_value<
const free_set_value_const_receiver_1&, int, std::string>::value;
BOOST_ASIO_CHECK(b36 == false);
BOOST_ASIO_CONSTEXPR bool b37 = exec::can_set_value<
free_set_value_const_receiver_2&>::value;
BOOST_ASIO_CHECK(b37 == false);
BOOST_ASIO_CONSTEXPR bool b38 = exec::can_set_value<
const free_set_value_const_receiver_2&>::value;
BOOST_ASIO_CHECK(b38 == false);
BOOST_ASIO_CONSTEXPR bool b39 = exec::can_set_value<
free_set_value_const_receiver_2&, int>::value;
BOOST_ASIO_CHECK(b39 == false);
BOOST_ASIO_CONSTEXPR bool b40 = exec::can_set_value<
const free_set_value_const_receiver_2&, int>::value;
BOOST_ASIO_CHECK(b40 == false);
BOOST_ASIO_CONSTEXPR bool b41 = exec::can_set_value<
free_set_value_const_receiver_2&, int, std::string>::value;
BOOST_ASIO_CHECK(b41 == true);
BOOST_ASIO_CONSTEXPR bool b42 = exec::can_set_value<
const free_set_value_const_receiver_2&, int, std::string>::value;
BOOST_ASIO_CHECK(b42 == true);
BOOST_ASIO_CONSTEXPR bool b43 = exec::can_set_value<
non_const_member_set_value_0&>::value;
BOOST_ASIO_CHECK(b43 == true);
BOOST_ASIO_CONSTEXPR bool b44 = exec::can_set_value<
const non_const_member_set_value_0&>::value;
BOOST_ASIO_CHECK(b44 == false);
BOOST_ASIO_CONSTEXPR bool b45 = exec::can_set_value<
non_const_member_set_value_0&, int>::value;
BOOST_ASIO_CHECK(b45 == false);
BOOST_ASIO_CONSTEXPR bool b46 = exec::can_set_value<
const non_const_member_set_value_0&, int>::value;
BOOST_ASIO_CHECK(b46 == false);
BOOST_ASIO_CONSTEXPR bool b47 = exec::can_set_value<
non_const_member_set_value_0&, int, std::string>::value;
BOOST_ASIO_CHECK(b47 == false);
BOOST_ASIO_CONSTEXPR bool b48 = exec::can_set_value<
const non_const_member_set_value_0&, int, std::string>::value;
BOOST_ASIO_CHECK(b48 == false);
BOOST_ASIO_CONSTEXPR bool b49 = exec::can_set_value<
non_const_member_set_value_1&>::value;
BOOST_ASIO_CHECK(b49 == false);
BOOST_ASIO_CONSTEXPR bool b50 = exec::can_set_value<
const non_const_member_set_value_1&>::value;
BOOST_ASIO_CHECK(b50 == false);
BOOST_ASIO_CONSTEXPR bool b51 = exec::can_set_value<
non_const_member_set_value_1&, int>::value;
BOOST_ASIO_CHECK(b51 == true);
BOOST_ASIO_CONSTEXPR bool b52 = exec::can_set_value<
const non_const_member_set_value_1&, int>::value;
BOOST_ASIO_CHECK(b52 == false);
BOOST_ASIO_CONSTEXPR bool b53 = exec::can_set_value<
non_const_member_set_value_1&, int, std::string>::value;
BOOST_ASIO_CHECK(b53 == false);
BOOST_ASIO_CONSTEXPR bool b54 = exec::can_set_value<
const non_const_member_set_value_1&, int, std::string>::value;
BOOST_ASIO_CHECK(b54 == false);
BOOST_ASIO_CONSTEXPR bool b55 = exec::can_set_value<
non_const_member_set_value_2&>::value;
BOOST_ASIO_CHECK(b55 == false);
BOOST_ASIO_CONSTEXPR bool b56 = exec::can_set_value<
const non_const_member_set_value_2&>::value;
BOOST_ASIO_CHECK(b56 == false);
BOOST_ASIO_CONSTEXPR bool b57 = exec::can_set_value<
non_const_member_set_value_2&, int>::value;
BOOST_ASIO_CHECK(b57 == false);
BOOST_ASIO_CONSTEXPR bool b58 = exec::can_set_value<
const non_const_member_set_value_2&, int>::value;
BOOST_ASIO_CHECK(b58 == false);
BOOST_ASIO_CONSTEXPR bool b59 = exec::can_set_value<
non_const_member_set_value_2&, int, std::string>::value;
BOOST_ASIO_CHECK(b59 == true);
BOOST_ASIO_CONSTEXPR bool b60 = exec::can_set_value<
const non_const_member_set_value_2&, int, std::string>::value;
BOOST_ASIO_CHECK(b60 == false);
BOOST_ASIO_CONSTEXPR bool b61 = exec::can_set_value<
free_set_value_non_const_receiver_0&>::value;
BOOST_ASIO_CHECK(b61 == true);
BOOST_ASIO_CONSTEXPR bool b62 = exec::can_set_value<
const free_set_value_non_const_receiver_0&>::value;
BOOST_ASIO_CHECK(b62 == false);
BOOST_ASIO_CONSTEXPR bool b63 = exec::can_set_value<
free_set_value_non_const_receiver_0&, int>::value;
BOOST_ASIO_CHECK(b63 == false);
BOOST_ASIO_CONSTEXPR bool b64 = exec::can_set_value<
const free_set_value_non_const_receiver_0&, int>::value;
BOOST_ASIO_CHECK(b64 == false);
BOOST_ASIO_CONSTEXPR bool b65 = exec::can_set_value<
free_set_value_non_const_receiver_0&, int, std::string>::value;
BOOST_ASIO_CHECK(b65 == false);
BOOST_ASIO_CONSTEXPR bool b66 = exec::can_set_value<
const free_set_value_non_const_receiver_0&, int, std::string>::value;
BOOST_ASIO_CHECK(b66 == false);
BOOST_ASIO_CONSTEXPR bool b67 = exec::can_set_value<
free_set_value_non_const_receiver_1&>::value;
BOOST_ASIO_CHECK(b67 == false);
BOOST_ASIO_CONSTEXPR bool b68 = exec::can_set_value<
const free_set_value_non_const_receiver_1&>::value;
BOOST_ASIO_CHECK(b68 == false);
BOOST_ASIO_CONSTEXPR bool b69 = exec::can_set_value<
free_set_value_non_const_receiver_1&, int>::value;
BOOST_ASIO_CHECK(b69 == true);
BOOST_ASIO_CONSTEXPR bool b70 = exec::can_set_value<
const free_set_value_non_const_receiver_1&, int>::value;
BOOST_ASIO_CHECK(b70 == false);
BOOST_ASIO_CONSTEXPR bool b71 = exec::can_set_value<
free_set_value_non_const_receiver_1&, int, std::string>::value;
BOOST_ASIO_CHECK(b71 == false);
BOOST_ASIO_CONSTEXPR bool b72 = exec::can_set_value<
const free_set_value_non_const_receiver_1&, int, std::string>::value;
BOOST_ASIO_CHECK(b72 == false);
BOOST_ASIO_CONSTEXPR bool b73 = exec::can_set_value<
free_set_value_non_const_receiver_2&>::value;
BOOST_ASIO_CHECK(b73 == false);
BOOST_ASIO_CONSTEXPR bool b74 = exec::can_set_value<
const free_set_value_non_const_receiver_2&>::value;
BOOST_ASIO_CHECK(b74 == false);
BOOST_ASIO_CONSTEXPR bool b75 = exec::can_set_value<
free_set_value_non_const_receiver_2&, int>::value;
BOOST_ASIO_CHECK(b75 == false);
BOOST_ASIO_CONSTEXPR bool b76 = exec::can_set_value<
const free_set_value_non_const_receiver_2&, int>::value;
BOOST_ASIO_CHECK(b76 == false);
BOOST_ASIO_CONSTEXPR bool b77 = exec::can_set_value<
free_set_value_non_const_receiver_2&, int, std::string>::value;
BOOST_ASIO_CHECK(b77 == true);
BOOST_ASIO_CONSTEXPR bool b78 = exec::can_set_value<
const free_set_value_non_const_receiver_2&, int, std::string>::value;
BOOST_ASIO_CHECK(b78 == false);
}
void increment(int* count)
{
++(*count);
}
void test_set_value()
{
call_count = 0;
const_member_set_value_0 ex1 = {};
exec::set_value(ex1);
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
const const_member_set_value_0 ex2 = {};
exec::set_value(ex2);
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
exec::set_value(const_member_set_value_0());
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
const_member_set_value_1 ex3 = {};
exec::set_value(ex3, 123);
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
const const_member_set_value_1 ex4 = {};
exec::set_value(ex4, 123);
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
exec::set_value(const_member_set_value_1(), 123);
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
const_member_set_value_2 ex5 = {};
exec::set_value(ex5, 123, std::string());
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
const const_member_set_value_2 ex6 = {};
exec::set_value(ex6, 123, std::string());
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
exec::set_value(const_member_set_value_2(), 123, std::string());
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
free_set_value_const_receiver_0 ex7 = {};
exec::set_value(ex7);
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
const free_set_value_const_receiver_0 ex8 = {};
exec::set_value(ex8);
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
exec::set_value(free_set_value_const_receiver_0());
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
free_set_value_const_receiver_1 ex9 = {};
exec::set_value(ex9, 123);
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
const free_set_value_const_receiver_1 ex10 = {};
exec::set_value(ex10, 123);
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
exec::set_value(free_set_value_const_receiver_1(), 123);
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
free_set_value_const_receiver_2 ex11 = {};
exec::set_value(ex11, 123, std::string());
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
const free_set_value_const_receiver_2 ex12 = {};
exec::set_value(ex12, 123, std::string());
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
exec::set_value(free_set_value_const_receiver_2(), 123, std::string());
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
non_const_member_set_value_0 ex13 = {};
exec::set_value(ex13);
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
non_const_member_set_value_1 ex14 = {};
exec::set_value(ex14, 123);
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
non_const_member_set_value_2 ex15 = {};
exec::set_value(ex15, 123, std::string());
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
free_set_value_non_const_receiver_0 ex16 = {};
exec::set_value(ex16);
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
free_set_value_non_const_receiver_1 ex17 = {};
exec::set_value(ex17, 123);
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
free_set_value_non_const_receiver_2 ex18 = {};
exec::set_value(ex18, 123, std::string());
BOOST_ASIO_CHECK(call_count == 1);
}
BOOST_ASIO_TEST_SUITE
(
"set_value",
BOOST_ASIO_TEST_CASE(test_can_set_value)
BOOST_ASIO_TEST_CASE(test_set_value)
)

View File

@@ -0,0 +1,236 @@
//
// start.cpp
// ~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/execution/start.hpp>
#include <boost/system/error_code.hpp>
#include "../unit_test.hpp"
namespace exec = boost::asio::execution;
static int call_count = 0;
struct no_start
{
};
struct const_member_start
{
void start() const BOOST_ASIO_NOEXCEPT
{
++call_count;
}
};
#if !defined(BOOST_ASIO_HAS_DEDUCED_START_MEMBER_TRAIT)
namespace boost {
namespace asio {
namespace traits {
template <>
struct start_member<const const_member_start>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
typedef void result_type;
};
} // namespace traits
} // namespace asio
} // namespace boost
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_START_MEMBER_TRAIT)
struct free_start_const_receiver
{
friend void start(const free_start_const_receiver&) BOOST_ASIO_NOEXCEPT
{
++call_count;
}
};
#if !defined(BOOST_ASIO_HAS_DEDUCED_START_FREE_TRAIT)
namespace boost {
namespace asio {
namespace traits {
template <>
struct start_free<const free_start_const_receiver>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
typedef void result_type;
};
} // namespace traits
} // namespace asio
} // namespace boost
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_START_FREE_TRAIT)
struct non_const_member_start
{
void start() BOOST_ASIO_NOEXCEPT
{
++call_count;
}
};
#if !defined(BOOST_ASIO_HAS_DEDUCED_START_MEMBER_TRAIT)
namespace boost {
namespace asio {
namespace traits {
template <>
struct start_member<non_const_member_start>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
typedef void result_type;
};
} // namespace traits
} // namespace asio
} // namespace boost
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_START_MEMBER_TRAIT)
struct free_start_non_const_receiver
{
friend void start(free_start_non_const_receiver&) BOOST_ASIO_NOEXCEPT
{
++call_count;
}
};
#if !defined(BOOST_ASIO_HAS_DEDUCED_START_FREE_TRAIT)
namespace boost {
namespace asio {
namespace traits {
template <>
struct start_free<free_start_non_const_receiver>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
typedef void result_type;
};
} // namespace traits
} // namespace asio
} // namespace boost
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_START_FREE_TRAIT)
void test_can_start()
{
BOOST_ASIO_CONSTEXPR bool b1 = exec::can_start<
no_start&>::value;
BOOST_ASIO_CHECK(b1 == false);
BOOST_ASIO_CONSTEXPR bool b2 = exec::can_start<
const no_start&>::value;
BOOST_ASIO_CHECK(b2 == false);
BOOST_ASIO_CONSTEXPR bool b3 = exec::can_start<
const_member_start&>::value;
BOOST_ASIO_CHECK(b3 == true);
BOOST_ASIO_CONSTEXPR bool b4 = exec::can_start<
const const_member_start&>::value;
BOOST_ASIO_CHECK(b4 == true);
BOOST_ASIO_CONSTEXPR bool b5 = exec::can_start<
free_start_const_receiver&>::value;
BOOST_ASIO_CHECK(b5 == true);
BOOST_ASIO_CONSTEXPR bool b6 = exec::can_start<
const free_start_const_receiver&>::value;
BOOST_ASIO_CHECK(b6 == true);
BOOST_ASIO_CONSTEXPR bool b7 = exec::can_start<
non_const_member_start&>::value;
BOOST_ASIO_CHECK(b7 == true);
BOOST_ASIO_CONSTEXPR bool b8 = exec::can_start<
const non_const_member_start&>::value;
BOOST_ASIO_CHECK(b8 == false);
BOOST_ASIO_CONSTEXPR bool b9 = exec::can_start<
free_start_non_const_receiver&>::value;
BOOST_ASIO_CHECK(b9 == true);
BOOST_ASIO_CONSTEXPR bool b10 = exec::can_start<
const free_start_non_const_receiver&>::value;
BOOST_ASIO_CHECK(b10 == false);
}
void increment(int* count)
{
++(*count);
}
void test_start()
{
call_count = 0;
const_member_start ex1 = {};
exec::start(ex1);
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
const const_member_start ex2 = {};
exec::start(ex2);
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
exec::start(const_member_start());
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
free_start_const_receiver ex3 = {};
exec::start(ex3);
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
const free_start_const_receiver ex4 = {};
exec::start(ex4);
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
exec::start(free_start_const_receiver());
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
non_const_member_start ex5 = {};
exec::start(ex5);
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
free_start_non_const_receiver ex6 = {};
exec::start(ex6);
BOOST_ASIO_CHECK(call_count == 1);
}
BOOST_ASIO_TEST_SUITE
(
"start",
BOOST_ASIO_TEST_CASE(test_can_start)
BOOST_ASIO_TEST_CASE(test_start)
)

View File

@@ -0,0 +1,562 @@
//
// submit.cpp
// ~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/execution/submit.hpp>
#include <boost/system/error_code.hpp>
#include "../unit_test.hpp"
namespace exec = boost::asio::execution;
static int call_count = 0;
struct operation_state
{
void start() BOOST_ASIO_NOEXCEPT
{
}
};
namespace boost {
namespace asio {
namespace traits {
#if !defined(BOOST_ASIO_HAS_DEDUCED_START_MEMBER_TRAIT)
template <>
struct start_member<operation_state>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
typedef void result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_START_MEMBER_TRAIT)
} // namespace traits
} // namespace asio
} // namespace boost
struct no_submit_1
{
};
struct no_submit_2 : exec::sender_base
{
};
struct no_submit_3
{
template <typename R>
void submit(BOOST_ASIO_MOVE_ARG(R) r)
{
(void)r;
}
};
#if !defined(BOOST_ASIO_HAS_DEDUCED_SUBMIT_MEMBER_TRAIT)
namespace boost {
namespace asio {
namespace traits {
template <typename R>
struct submit_member<no_submit_3, R>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
typedef void result_type;
};
} // namespace traits
} // namespace asio
} // namespace boost
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SUBMIT_MEMBER_TRAIT)
struct const_member_submit : exec::sender_base
{
const_member_submit()
{
}
template <typename R>
operation_state connect(BOOST_ASIO_MOVE_ARG(R) r) const
{
(void)r;
return operation_state();
}
template <typename R>
void submit(BOOST_ASIO_MOVE_ARG(R) r) const
{
(void)r;
++call_count;
}
};
namespace boost {
namespace asio {
namespace traits {
#if !defined(BOOST_ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT)
template <typename R>
struct connect_member<const const_member_submit, R>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
typedef operation_state result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT)
#if !defined(BOOST_ASIO_HAS_DEDUCED_SUBMIT_MEMBER_TRAIT)
template <typename R>
struct submit_member<const const_member_submit, R>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
typedef void result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SUBMIT_MEMBER_TRAIT)
} // namespace traits
} // namespace asio
} // namespace boost
struct free_submit_const_receiver : exec::sender_base
{
free_submit_const_receiver()
{
}
template <typename R>
friend operation_state connect(
const free_submit_const_receiver&, BOOST_ASIO_MOVE_ARG(R) r)
{
(void)r;
return operation_state();
}
template <typename R>
friend void submit(
const free_submit_const_receiver&, BOOST_ASIO_MOVE_ARG(R) r)
{
(void)r;
++call_count;
}
};
namespace boost {
namespace asio {
namespace traits {
#if !defined(BOOST_ASIO_HAS_DEDUCED_CONNECT_FREE_TRAIT)
template <typename R>
struct connect_free<const free_submit_const_receiver, R>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
typedef operation_state result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_CONNECT_FREE_TRAIT)
#if !defined(BOOST_ASIO_HAS_DEDUCED_SUBMIT_FREE_TRAIT)
template <typename R>
struct submit_free<const free_submit_const_receiver, R>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
typedef void result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SUBMIT_FREE_TRAIT)
} // namespace traits
} // namespace asio
} // namespace boost
struct non_const_member_submit : exec::sender_base
{
non_const_member_submit()
{
}
template <typename R>
operation_state connect(BOOST_ASIO_MOVE_ARG(R) r)
{
(void)r;
return operation_state();
}
template <typename R>
void submit(BOOST_ASIO_MOVE_ARG(R) r)
{
(void)r;
++call_count;
}
};
namespace boost {
namespace asio {
namespace traits {
#if !defined(BOOST_ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT)
template <typename R>
struct connect_member<non_const_member_submit, R>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
typedef operation_state result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT)
#if !defined(BOOST_ASIO_HAS_DEDUCED_SUBMIT_MEMBER_TRAIT)
template <typename R>
struct submit_member<non_const_member_submit, R>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
typedef void result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SUBMIT_MEMBER_TRAIT)
} // namespace traits
} // namespace asio
} // namespace boost
struct free_submit_non_const_receiver : exec::sender_base
{
free_submit_non_const_receiver()
{
}
template <typename R>
friend operation_state connect(
free_submit_non_const_receiver&, BOOST_ASIO_MOVE_ARG(R) r)
{
(void)r;
return operation_state();
}
template <typename R>
friend void submit(
free_submit_non_const_receiver&, BOOST_ASIO_MOVE_ARG(R) r)
{
(void)r;
++call_count;
}
};
namespace boost {
namespace asio {
namespace traits {
#if !defined(BOOST_ASIO_HAS_DEDUCED_CONNECT_FREE_TRAIT)
template <typename R>
struct connect_free<free_submit_non_const_receiver, R>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
typedef operation_state result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_CONNECT_FREE_TRAIT)
#if !defined(BOOST_ASIO_HAS_DEDUCED_SUBMIT_FREE_TRAIT)
template <typename R>
struct submit_free<free_submit_non_const_receiver, R>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
typedef void result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SUBMIT_FREE_TRAIT)
} // namespace traits
} // namespace asio
} // namespace boost
struct receiver
{
receiver()
{
}
receiver(const receiver&)
{
}
#if defined(BOOST_ASIO_HAS_MOVE)
receiver(receiver&&) BOOST_ASIO_NOEXCEPT
{
}
#endif // defined(BOOST_ASIO_HAS_MOVE)
template <typename E>
void set_error(BOOST_ASIO_MOVE_ARG(E) e) BOOST_ASIO_NOEXCEPT
{
(void)e;
}
void set_done() BOOST_ASIO_NOEXCEPT
{
}
};
namespace boost {
namespace asio {
namespace traits {
#if !defined(BOOST_ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)
template <typename E>
struct set_error_member<receiver, E>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
typedef void result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)
#if !defined(BOOST_ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)
template <>
struct set_done_member<receiver>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
typedef void result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)
} // namespace traits
} // namespace asio
} // namespace boost
struct executor
{
executor()
{
}
executor(const executor&) BOOST_ASIO_NOEXCEPT
{
}
#if defined(BOOST_ASIO_HAS_MOVE)
executor(executor&&) BOOST_ASIO_NOEXCEPT
{
}
#endif // defined(BOOST_ASIO_HAS_MOVE)
template <typename F>
void execute(BOOST_ASIO_MOVE_ARG(F) f) const BOOST_ASIO_NOEXCEPT
{
(void)f;
++call_count;
}
bool operator==(const executor&) const BOOST_ASIO_NOEXCEPT
{
return true;
}
bool operator!=(const executor&) const BOOST_ASIO_NOEXCEPT
{
return false;
}
};
namespace boost {
namespace asio {
namespace traits {
#if !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
template <typename F>
struct execute_member<executor, F>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
typedef void result_type;
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)
#if !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
template <>
struct equality_comparable<executor>
{
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
};
#endif // !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
} // namespace traits
} // namespace asio
} // namespace boost
void test_can_submit()
{
BOOST_ASIO_CONSTEXPR bool b1 = exec::can_submit<
no_submit_1&, receiver>::value;
BOOST_ASIO_CHECK(b1 == false);
BOOST_ASIO_CONSTEXPR bool b2 = exec::can_submit<
const no_submit_1&, receiver>::value;
BOOST_ASIO_CHECK(b2 == false);
BOOST_ASIO_CONSTEXPR bool b3 = exec::can_submit<
no_submit_2&, receiver>::value;
BOOST_ASIO_CHECK(b3 == false);
BOOST_ASIO_CONSTEXPR bool b4 = exec::can_submit<
const no_submit_2&, receiver>::value;
BOOST_ASIO_CHECK(b4 == false);
BOOST_ASIO_CONSTEXPR bool b5 = exec::can_submit<
no_submit_3&, receiver>::value;
BOOST_ASIO_CHECK(b5 == false);
BOOST_ASIO_CONSTEXPR bool b6 = exec::can_submit<
const no_submit_3&, receiver>::value;
BOOST_ASIO_CHECK(b6 == false);
BOOST_ASIO_CONSTEXPR bool b7 = exec::can_submit<
const_member_submit&, receiver>::value;
BOOST_ASIO_CHECK(b7 == true);
BOOST_ASIO_CONSTEXPR bool b8 = exec::can_submit<
const const_member_submit&, receiver>::value;
BOOST_ASIO_CHECK(b8 == true);
BOOST_ASIO_CONSTEXPR bool b9 = exec::can_submit<
free_submit_const_receiver&, receiver>::value;
BOOST_ASIO_CHECK(b9 == true);
BOOST_ASIO_CONSTEXPR bool b10 = exec::can_submit<
const free_submit_const_receiver&, receiver>::value;
BOOST_ASIO_CHECK(b10 == true);
BOOST_ASIO_CONSTEXPR bool b11 = exec::can_submit<
non_const_member_submit&, receiver>::value;
BOOST_ASIO_CHECK(b11 == true);
BOOST_ASIO_CONSTEXPR bool b12 = exec::can_submit<
const non_const_member_submit&, receiver>::value;
BOOST_ASIO_CHECK(b12 == false);
BOOST_ASIO_CONSTEXPR bool b13 = exec::can_submit<
free_submit_non_const_receiver&, receiver>::value;
BOOST_ASIO_CHECK(b13 == true);
BOOST_ASIO_CONSTEXPR bool b14 = exec::can_submit<
const free_submit_non_const_receiver&, receiver>::value;
BOOST_ASIO_CHECK(b14 == false);
BOOST_ASIO_CONSTEXPR bool b15 = exec::can_submit<
executor&, receiver>::value;
BOOST_ASIO_CHECK(b15 == true);
BOOST_ASIO_CONSTEXPR bool b16 = exec::can_submit<
const executor&, receiver>::value;
BOOST_ASIO_CHECK(b16 == true);
}
void increment(int* count)
{
++(*count);
}
void test_submit()
{
receiver r;
call_count = 0;
const_member_submit s1;
exec::submit(s1, r);
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
const const_member_submit s2;
exec::submit(s2, r);
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
exec::submit(const_member_submit(), r);
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
free_submit_const_receiver s3;
exec::submit(s3, r);
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
const free_submit_const_receiver s4;
exec::submit(s4, r);
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
exec::submit(free_submit_const_receiver(), r);
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
non_const_member_submit s5;
exec::submit(s5, r);
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
free_submit_non_const_receiver s6;
exec::submit(s6, r);
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
executor s7;
exec::submit(s7, r);
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
const executor s8;
exec::submit(s8, r);
BOOST_ASIO_CHECK(call_count == 1);
call_count = 0;
exec::submit(executor(), r);
BOOST_ASIO_CHECK(call_count == 1);
}
BOOST_ASIO_TEST_SUITE
(
"submit",
BOOST_ASIO_TEST_CASE(test_can_submit)
BOOST_ASIO_TEST_CASE(test_submit)
)

View File

@@ -0,0 +1,25 @@
//
// execution_context.cpp
// ~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/execution_context.hpp>
#include "unit_test.hpp"
BOOST_ASIO_TEST_SUITE
(
"execution_context",
BOOST_ASIO_TEST_CASE(null_test)
)

View File

@@ -0,0 +1,25 @@
//
// executor.cpp
// ~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/executor.hpp>
#include "unit_test.hpp"
BOOST_ASIO_TEST_SUITE
(
"executor",
BOOST_ASIO_TEST_CASE(null_test)
)

View File

@@ -0,0 +1,25 @@
//
// executor_work_guard.cpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/executor_work_guard.hpp>
#include "unit_test.hpp"
BOOST_ASIO_TEST_SUITE
(
"executor_work_guard",
BOOST_ASIO_TEST_CASE(null_test)
)

View File

@@ -0,0 +1,65 @@
#
# Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
#
# Distributed under the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#
import os ;
import feature ;
lib socket ; # SOLARIS
lib nsl ; # SOLARIS
lib ws2_32 ; # NT
lib mswsock ; # NT
lib ipv6 ; # HPUX
lib network ; # HAIKU
local USE_SELECT =
<define>BOOST_ASIO_DISABLE_EPOLL
<define>BOOST_ASIO_DISABLE_KQUEUE
<define>BOOST_ASIO_DISABLE_IOCP
;
project
: requirements
<library>/boost/date_time//boost_date_time
<library>/boost/system//boost_system
<library>/boost/chrono//boost_chrono
<define>BOOST_ALL_NO_LIB=1
<threading>multi
<target-os>solaris:<library>socket
<target-os>solaris:<library>nsl
<target-os>windows:<define>_WIN32_WINNT=0x0501
<target-os>windows,<toolset>gcc:<library>ws2_32
<target-os>windows,<toolset>gcc:<library>mswsock
<target-os>windows,<toolset>gcc-cygwin:<define>__USE_W32_SOCKETS
<target-os>hpux,<toolset>gcc:<define>_XOPEN_SOURCE_EXTENDED
<target-os>hpux:<library>ipv6
<target-os>haiku:<library>network
;
test-suite "asio-experimental" :
[ run append.cpp ]
[ run append.cpp : : : $(USE_SELECT) : append_select ]
[ run as_tuple.cpp ]
[ run as_tuple.cpp : : : $(USE_SELECT) : as_tuple_select ]
[ run awaitable_operators.cpp ]
[ run awaitable_operators.cpp : : : $(USE_SELECT) : awaitable_operators_select ]
[ run basic_channel.cpp ]
[ run basic_channel.cpp : : : $(USE_SELECT) : basic_channel_select ]
[ run basic_concurrent_channel.cpp ]
[ run basic_concurrent_channel.cpp : : : $(USE_SELECT) : basic_concurrent_channel_select ]
[ run channel.cpp ]
[ run channel.cpp : : : $(USE_SELECT) : channel_select ]
[ run channel_traits.cpp ]
[ run channel_traits.cpp : : : $(USE_SELECT) : channel_traits_select ]
[ run concurrent_channel.cpp ]
[ run concurrent_channel.cpp : : : $(USE_SELECT) : concurrent_channel_select ]
[ run deferred.cpp ]
[ run deferred.cpp : : : $(USE_SELECT) : deferred_select ]
[ run prepend.cpp ]
[ run prepend.cpp : : : $(USE_SELECT) : prepend_select ]
[ run promise.cpp ]
[ run promise.cpp : : : $(USE_SELECT) : promise_select ]
;

View File

@@ -0,0 +1,58 @@
//
// experimental/append.cpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/experimental/append.hpp>
#include <boost/asio/bind_executor.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/post.hpp>
#include <boost/asio/system_timer.hpp>
#include "../unit_test.hpp"
void append_test()
{
boost::asio::io_context io1;
boost::asio::io_context io2;
boost::asio::system_timer timer1(io1);
int count = 0;
timer1.expires_after(boost::asio::chrono::seconds(0));
timer1.async_wait(
boost::asio::experimental::append(
boost::asio::bind_executor(io2.get_executor(),
[&count](boost::system::error_code, int a, int b)
{
++count;
BOOST_ASIO_CHECK(a == 123);
BOOST_ASIO_CHECK(b == 321);
}), 123, 321));
BOOST_ASIO_CHECK(count == 0);
io1.run();
BOOST_ASIO_CHECK(count == 0);
io2.run();
BOOST_ASIO_CHECK(count == 1);
}
BOOST_ASIO_TEST_SUITE
(
"experimental/basic_channel",
BOOST_ASIO_TEST_CASE(append_test)
)

View File

@@ -0,0 +1,56 @@
//
// experimental/as_tuple.cpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/experimental/as_tuple.hpp>
#include <boost/asio/bind_executor.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/post.hpp>
#include <boost/asio/system_timer.hpp>
#include "../unit_test.hpp"
void as_tuple_test()
{
boost::asio::io_context io1;
boost::asio::io_context io2;
boost::asio::system_timer timer1(io1);
int count = 0;
timer1.expires_after(boost::asio::chrono::seconds(0));
timer1.async_wait(
boost::asio::experimental::as_tuple(
boost::asio::bind_executor(io2.get_executor(),
[&count](std::tuple<boost::system::error_code>)
{
++count;
})));
BOOST_ASIO_CHECK(count == 0);
io1.run();
BOOST_ASIO_CHECK(count == 0);
io2.run();
BOOST_ASIO_CHECK(count == 1);
}
BOOST_ASIO_TEST_SUITE
(
"experimental/basic_channel",
BOOST_ASIO_TEST_CASE(as_tuple_test)
)

View File

@@ -0,0 +1,297 @@
//
// experimental/awaitable_operators.cpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Prevent link dependency on the Boost.System library.
#if !defined(BOOST_SYSTEM_NO_DEPRECATED)
#define BOOST_SYSTEM_NO_DEPRECATED
#endif // !defined(BOOST_SYSTEM_NO_DEPRECATED)
// Test that header file is self-contained.
#include <boost/asio/experimental/awaitable_operators.hpp>
#include <boost/asio/co_spawn.hpp>
#include <boost/asio/detached.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/post.hpp>
#include "../unit_test.hpp"
using boost::asio::awaitable;
using namespace boost::asio::experimental::awaitable_operators;
struct move_only
{
move_only(int i) : value(i) {}
move_only(const move_only&) = delete;
move_only(move_only&&) {}
move_only& operator=(const move_only&) = delete;
move_only& operator=(move_only&&) { return *this; }
int value;
};
awaitable<void> void_ok()
{
co_return;
}
awaitable<void> void_ex()
{
throw std::runtime_error("exception");
co_return;
}
awaitable<void> void_post_loop()
{
for (;;)
co_await boost::asio::post(boost::asio::use_awaitable);
}
awaitable<int> int_0()
{
co_return 0;
}
awaitable<int> int_1()
{
co_return 1;
}
awaitable<int> int_2()
{
co_return 2;
}
awaitable<int> int_ex()
{
throw std::runtime_error("exception");
co_return -1;
}
awaitable<move_only> move_only_0()
{
co_return move_only(0);
}
awaitable<move_only> move_only_1()
{
co_return move_only(1);
}
awaitable<move_only> move_only_2()
{
co_return move_only(2);
}
awaitable<move_only> move_only_ex()
{
throw std::runtime_error("exception");
co_return move_only(-1);
}
awaitable<void> do_test_and_awaitable_operator()
{
int i;
std::tuple<int, int> ii;
std::tuple<int, int, int> iii;
co_await (void_ok() && void_ok());
co_await (void_ok() && void_ok() && void_ok());
try { co_await (void_ex() && void_ok()); } catch (...) {}
try { co_await (void_ex() && void_ok() && void_ok()); } catch (...) {}
try { co_await (void_ex() && void_post_loop()); } catch (...) {}
try { co_await (void_ex() && void_ok() && void_post_loop()); } catch (...) {}
i = co_await (void_ok() && int_0());
BOOST_ASIO_CHECK(i == 0);
i = co_await (void_ok() && int_1());
BOOST_ASIO_CHECK(i == 1);
i = co_await (int_0() && void_ok());
BOOST_ASIO_CHECK(i == 0);
ii = co_await (int_0() && int_1());
BOOST_ASIO_CHECK(std::get<0>(ii) == 0);
BOOST_ASIO_CHECK(std::get<1>(ii) == 1);
i = co_await (void_ok() && void_ok() && int_0());
BOOST_ASIO_CHECK(i == 0);
i = co_await (void_ok() && int_0() && void_ok());
BOOST_ASIO_CHECK(i == 0);
ii = co_await (void_ok() && int_0() && int_1());
BOOST_ASIO_CHECK(std::get<0>(ii) == 0);
BOOST_ASIO_CHECK(std::get<1>(ii) == 1);
ii = co_await (int_0() && void_ok() && int_1());
BOOST_ASIO_CHECK(std::get<0>(ii) == 0);
BOOST_ASIO_CHECK(std::get<1>(ii) == 1);
iii = co_await (int_0() && int_1() && int_2());
BOOST_ASIO_CHECK(std::get<0>(iii) == 0);
BOOST_ASIO_CHECK(std::get<1>(iii) == 1);
BOOST_ASIO_CHECK(std::get<2>(iii) == 2);
}
void test_and_awaitable_operator()
{
boost::asio::io_context ctx;
co_spawn(ctx, do_test_and_awaitable_operator(), boost::asio::detached);
ctx.run();
}
awaitable<void> do_test_or_awaitable_operator()
{
std::variant<int, int> ii;
std::variant<int, std::monostate> iv;
std::variant<std::monostate, int> vi;
std::variant<std::monostate, std::monostate> vv;
std::variant<int, int, int> iii;
std::variant<int, int, std::monostate> iiv;
std::variant<int, std::monostate, int> ivi;
std::variant<int, std::monostate, std::monostate> ivv;
std::variant<std::monostate, int, int> vii;
std::variant<std::monostate, int, std::monostate> viv;
std::variant<std::monostate, std::monostate, int> vvi;
std::variant<std::monostate, std::monostate, std::monostate> vvv;
vv = co_await (void_ok() || void_ok());
BOOST_ASIO_CHECK(vv.index() == 0);
vv = co_await (void_ex() || void_ok());
BOOST_ASIO_CHECK(vv.index() == 1);
vi = co_await (void_ok() || int_0());
BOOST_ASIO_CHECK(vi.index() == 0);
vi = co_await (void_ex() || int_0());
BOOST_ASIO_CHECK(vi.index() == 1);
iv = co_await (int_0() || void_ex());
BOOST_ASIO_CHECK(iv.index() == 0);
BOOST_ASIO_CHECK(std::get<0>(iv) == 0);
ii = co_await (int_0() || int_1());
BOOST_ASIO_CHECK(ii.index() == 0);
BOOST_ASIO_CHECK(std::get<0>(ii) == 0);
ii = co_await (int_ex() || int_1());
BOOST_ASIO_CHECK(ii.index() == 1);
BOOST_ASIO_CHECK(std::get<1>(ii) == 1);
vvv = co_await (void_ok() || void_ok() || void_ok());
BOOST_ASIO_CHECK(vvv.index() == 0);
vvv = co_await (void_ex() || void_ok() || void_ok());
BOOST_ASIO_CHECK(vvv.index() == 1);
vvv = co_await (void_ex() || void_ex() || void_ok());
BOOST_ASIO_CHECK(vvv.index() == 2);
vvi = co_await (void_ok() || void_ok() || int_0());
BOOST_ASIO_CHECK(vvi.index() == 0);
viv = co_await (void_ok() || int_0() || void_ok());
BOOST_ASIO_CHECK(viv.index() == 0);
viv = co_await (void_ex() || int_0() || void_ok());
BOOST_ASIO_CHECK(viv.index() == 1);
BOOST_ASIO_CHECK(std::get<1>(viv) == 0);
vii = co_await (void_ex() || int_0() || int_1());
BOOST_ASIO_CHECK(vii.index() == 1);
BOOST_ASIO_CHECK(std::get<1>(vii) == 0);
ivv = co_await (int_0() || void_ok() || void_ok());
BOOST_ASIO_CHECK(ivv.index() == 0);
BOOST_ASIO_CHECK(std::get<0>(ivv) == 0);
ivv = co_await (int_ex() || void_ok() || void_ok());
BOOST_ASIO_CHECK(ivv.index() == 1);
ivi = co_await (int_0() || void_ok() || int_1());
BOOST_ASIO_CHECK(ivi.index() == 0);
BOOST_ASIO_CHECK(std::get<0>(ivi) == 0);
ivi = co_await (int_ex() || void_ok() || int_1());
BOOST_ASIO_CHECK(ivi.index() == 1);
iiv = co_await (int_0() || int_1() || void_ok());
BOOST_ASIO_CHECK(iiv.index() == 0);
BOOST_ASIO_CHECK(std::get<0>(iiv) == 0);
iiv = co_await (int_ex() || int_1() || void_ok());
BOOST_ASIO_CHECK(iiv.index() == 1);
BOOST_ASIO_CHECK(std::get<0>(iiv) == 1);
iiv = co_await (int_ex() || int_ex() || void_ok());
BOOST_ASIO_CHECK(iiv.index() == 2);
iii = co_await (int_0() || int_1() || int_2());
BOOST_ASIO_CHECK(iii.index() == 0);
BOOST_ASIO_CHECK(std::get<0>(iii) == 0);
iii = co_await (int_ex() || int_1() || int_2());
BOOST_ASIO_CHECK(iii.index() == 1);
BOOST_ASIO_CHECK(std::get<1>(iii) == 1);
iii = co_await (int_ex() || int_ex() || int_2());
BOOST_ASIO_CHECK(iii.index() == 2);
BOOST_ASIO_CHECK(std::get<2>(iii) == 2);
std::variant<move_only, int> mi = co_await (move_only_0() || int_1());
BOOST_ASIO_CHECK(mi.index() == 0);
BOOST_ASIO_CHECK(std::get<0>(mi).value == 0);
mi = co_await (move_only_ex() || int_1());
BOOST_ASIO_CHECK(mi.index() == 1);
BOOST_ASIO_CHECK(std::get<1>(mi) == 1);
std::variant<move_only, move_only> mm =
co_await (move_only_0() || move_only_1());
BOOST_ASIO_CHECK(mm.index() == 0);
BOOST_ASIO_CHECK(std::get<0>(mm).value == 0);
mm = co_await (move_only_ex() || move_only_1());
BOOST_ASIO_CHECK(mm.index() == 1);
BOOST_ASIO_CHECK(std::get<1>(mm).value == 1);
std::variant<move_only, move_only, move_only> mmm =
co_await (move_only_0() || move_only_1() || move_only_2());
BOOST_ASIO_CHECK(mmm.index() == 0);
BOOST_ASIO_CHECK(std::get<0>(mmm).value == 0);
mmm = co_await (move_only_ex() || move_only_1() || move_only_2());
BOOST_ASIO_CHECK(mmm.index() == 1);
BOOST_ASIO_CHECK(std::get<1>(mmm).value == 1);
mmm = co_await (move_only_ex() || move_only_ex() || move_only_2());
BOOST_ASIO_CHECK(mmm.index() == 2);
BOOST_ASIO_CHECK(std::get<2>(mmm).value == 2);
}
void test_or_awaitable_operator()
{
boost::asio::io_context ctx;
co_spawn(ctx, do_test_or_awaitable_operator(), boost::asio::detached);
ctx.run();
}
BOOST_ASIO_TEST_SUITE
(
"experimental/awaitable_operators",
BOOST_ASIO_TEST_CASE(test_and_awaitable_operator)
BOOST_ASIO_TEST_CASE(test_or_awaitable_operator)
)

View File

@@ -0,0 +1,25 @@
//
// experimental/basic_channel.cpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/experimental/basic_channel.hpp>
#include "../unit_test.hpp"
BOOST_ASIO_TEST_SUITE
(
"experimental/basic_channel",
BOOST_ASIO_TEST_CASE(null_test)
)

View File

@@ -0,0 +1,25 @@
//
// experimental/basic_concurrent_channel.cpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/experimental/basic_concurrent_channel.hpp>
#include "../unit_test.hpp"
BOOST_ASIO_TEST_SUITE
(
"experimental/basic_concurrent_channel",
BOOST_ASIO_TEST_CASE(null_test)
)

View File

@@ -0,0 +1,165 @@
//
// experimental/channel.cpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/experimental/channel.hpp>
#include <utility>
#include <boost/asio/error.hpp>
#include <boost/asio/io_context.hpp>
#include "../unit_test.hpp"
using namespace boost::asio;
using namespace boost::asio::experimental;
void unbuffered_channel_test()
{
io_context ctx;
channel<void(boost::system::error_code, std::string)> ch1(ctx);
BOOST_ASIO_CHECK(ch1.is_open());
BOOST_ASIO_CHECK(!ch1.ready());
bool b1 = ch1.try_send(boost::asio::error::eof, "hello");
BOOST_ASIO_CHECK(!b1);
std::string s1 = "abcdefghijklmnopqrstuvwxyz";
bool b2 = ch1.try_send(boost::asio::error::eof, std::move(s1));
BOOST_ASIO_CHECK(!b2);
BOOST_ASIO_CHECK(!s1.empty());
boost::system::error_code ec1;
std::string s2;
ch1.async_receive(
[&](boost::system::error_code ec, std::string s)
{
ec1 = ec;
s2 = std::move(s);
});
bool b3 = ch1.try_send(boost::asio::error::eof, std::move(s1));
BOOST_ASIO_CHECK(b3);
BOOST_ASIO_CHECK(s1.empty());
ctx.run();
BOOST_ASIO_CHECK(ec1 == boost::asio::error::eof);
BOOST_ASIO_CHECK(s2 == "abcdefghijklmnopqrstuvwxyz");
bool b4 = ch1.try_receive([](boost::system::error_code, std::string){});
BOOST_ASIO_CHECK(!b4);
boost::system::error_code ec2 = boost::asio::error::would_block;
std::string s3 = "zyxwvutsrqponmlkjihgfedcba";
ch1.async_send(boost::asio::error::eof, std::move(s3),
[&](boost::system::error_code ec)
{
ec2 = ec;
});
boost::system::error_code ec3;
std::string s4;
bool b5 = ch1.try_receive(
[&](boost::system::error_code ec, std::string s)
{
ec3 = ec;
s4 = s;
});
BOOST_ASIO_CHECK(b5);
BOOST_ASIO_CHECK(ec3 == boost::asio::error::eof);
BOOST_ASIO_CHECK(s4 == "zyxwvutsrqponmlkjihgfedcba");
ctx.restart();
ctx.run();
BOOST_ASIO_CHECK(!ec2);
};
void buffered_channel_test()
{
io_context ctx;
channel<void(boost::system::error_code, std::string)> ch1(ctx, 1);
BOOST_ASIO_CHECK(ch1.is_open());
BOOST_ASIO_CHECK(!ch1.ready());
bool b1 = ch1.try_send(boost::asio::error::eof, "hello");
BOOST_ASIO_CHECK(b1);
std::string s1 = "abcdefghijklmnopqrstuvwxyz";
bool b2 = ch1.try_send(boost::asio::error::eof, std::move(s1));
BOOST_ASIO_CHECK(!b2);
BOOST_ASIO_CHECK(!s1.empty());
boost::system::error_code ec1;
std::string s2;
ch1.async_receive(
[&](boost::system::error_code ec, std::string s)
{
ec1 = ec;
s2 = std::move(s);
});
ctx.run();
BOOST_ASIO_CHECK(ec1 == boost::asio::error::eof);
BOOST_ASIO_CHECK(s2 == "hello");
bool b4 = ch1.try_receive([](boost::system::error_code, std::string){});
BOOST_ASIO_CHECK(!b4);
boost::system::error_code ec2 = boost::asio::error::would_block;
std::string s3 = "zyxwvutsrqponmlkjihgfedcba";
ch1.async_send(boost::asio::error::eof, std::move(s3),
[&](boost::system::error_code ec)
{
ec2 = ec;
});
boost::system::error_code ec3;
std::string s4;
bool b5 = ch1.try_receive(
[&](boost::system::error_code ec, std::string s)
{
ec3 = ec;
s4 = s;
});
BOOST_ASIO_CHECK(b5);
BOOST_ASIO_CHECK(ec3 == boost::asio::error::eof);
BOOST_ASIO_CHECK(s4 == "zyxwvutsrqponmlkjihgfedcba");
ctx.restart();
ctx.run();
BOOST_ASIO_CHECK(!ec2);
};
BOOST_ASIO_TEST_SUITE
(
"experimental/channel",
BOOST_ASIO_TEST_CASE(unbuffered_channel_test)
BOOST_ASIO_TEST_CASE(buffered_channel_test)
)

View File

@@ -0,0 +1,25 @@
//
// experimental/channel_traits.cpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/experimental/channel_traits.hpp>
#include "../unit_test.hpp"
BOOST_ASIO_TEST_SUITE
(
"experimental/channel_traits",
BOOST_ASIO_TEST_CASE(null_test)
)

View File

@@ -0,0 +1,165 @@
//
// experimental/concurrent_channel.cpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/experimental/concurrent_channel.hpp>
#include <utility>
#include <boost/asio/error.hpp>
#include <boost/asio/io_context.hpp>
#include "../unit_test.hpp"
using namespace boost::asio;
using namespace boost::asio::experimental;
void unbuffered_concurrent_channel_test()
{
io_context ctx;
concurrent_channel<void(boost::system::error_code, std::string)> ch1(ctx);
BOOST_ASIO_CHECK(ch1.is_open());
BOOST_ASIO_CHECK(!ch1.ready());
bool b1 = ch1.try_send(boost::asio::error::eof, "hello");
BOOST_ASIO_CHECK(!b1);
std::string s1 = "abcdefghijklmnopqrstuvwxyz";
bool b2 = ch1.try_send(boost::asio::error::eof, std::move(s1));
BOOST_ASIO_CHECK(!b2);
BOOST_ASIO_CHECK(!s1.empty());
boost::system::error_code ec1;
std::string s2;
ch1.async_receive(
[&](boost::system::error_code ec, std::string s)
{
ec1 = ec;
s2 = std::move(s);
});
bool b3 = ch1.try_send(boost::asio::error::eof, std::move(s1));
BOOST_ASIO_CHECK(b3);
BOOST_ASIO_CHECK(s1.empty());
ctx.run();
BOOST_ASIO_CHECK(ec1 == boost::asio::error::eof);
BOOST_ASIO_CHECK(s2 == "abcdefghijklmnopqrstuvwxyz");
bool b4 = ch1.try_receive([](boost::system::error_code, std::string){});
BOOST_ASIO_CHECK(!b4);
boost::system::error_code ec2 = boost::asio::error::would_block;
std::string s3 = "zyxwvutsrqponmlkjihgfedcba";
ch1.async_send(boost::asio::error::eof, std::move(s3),
[&](boost::system::error_code ec)
{
ec2 = ec;
});
boost::system::error_code ec3;
std::string s4;
bool b5 = ch1.try_receive(
[&](boost::system::error_code ec, std::string s)
{
ec3 = ec;
s4 = s;
});
BOOST_ASIO_CHECK(b5);
BOOST_ASIO_CHECK(ec3 == boost::asio::error::eof);
BOOST_ASIO_CHECK(s4 == "zyxwvutsrqponmlkjihgfedcba");
ctx.restart();
ctx.run();
BOOST_ASIO_CHECK(!ec2);
};
void buffered_concurrent_channel_test()
{
io_context ctx;
concurrent_channel<void(boost::system::error_code, std::string)> ch1(ctx, 1);
BOOST_ASIO_CHECK(ch1.is_open());
BOOST_ASIO_CHECK(!ch1.ready());
bool b1 = ch1.try_send(boost::asio::error::eof, "hello");
BOOST_ASIO_CHECK(b1);
std::string s1 = "abcdefghijklmnopqrstuvwxyz";
bool b2 = ch1.try_send(boost::asio::error::eof, std::move(s1));
BOOST_ASIO_CHECK(!b2);
BOOST_ASIO_CHECK(!s1.empty());
boost::system::error_code ec1;
std::string s2;
ch1.async_receive(
[&](boost::system::error_code ec, std::string s)
{
ec1 = ec;
s2 = std::move(s);
});
ctx.run();
BOOST_ASIO_CHECK(ec1 == boost::asio::error::eof);
BOOST_ASIO_CHECK(s2 == "hello");
bool b4 = ch1.try_receive([](boost::system::error_code, std::string){});
BOOST_ASIO_CHECK(!b4);
boost::system::error_code ec2 = boost::asio::error::would_block;
std::string s3 = "zyxwvutsrqponmlkjihgfedcba";
ch1.async_send(boost::asio::error::eof, std::move(s3),
[&](boost::system::error_code ec)
{
ec2 = ec;
});
boost::system::error_code ec3;
std::string s4;
bool b5 = ch1.try_receive(
[&](boost::system::error_code ec, std::string s)
{
ec3 = ec;
s4 = s;
});
BOOST_ASIO_CHECK(b5);
BOOST_ASIO_CHECK(ec3 == boost::asio::error::eof);
BOOST_ASIO_CHECK(s4 == "zyxwvutsrqponmlkjihgfedcba");
ctx.restart();
ctx.run();
BOOST_ASIO_CHECK(!ec2);
};
BOOST_ASIO_TEST_SUITE
(
"experimental/concurrent_channel",
BOOST_ASIO_TEST_CASE(unbuffered_concurrent_channel_test)
BOOST_ASIO_TEST_CASE(buffered_concurrent_channel_test)
)

View File

@@ -0,0 +1,59 @@
#
# Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
#
# Distributed under the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#
import os ;
import feature ;
lib socket ; # SOLARIS
lib nsl ; # SOLARIS
lib ws2_32 ; # NT
lib mswsock ; # NT
lib ipv6 ; # HPUX
lib network ; # HAIKU
local USE_SELECT =
<define>BOOST_ASIO_DISABLE_EPOLL
<define>BOOST_ASIO_DISABLE_KQUEUE
<define>BOOST_ASIO_DISABLE_IOCP
;
project
: requirements
<library>/boost/date_time//boost_date_time
<library>/boost/system//boost_system
<library>/boost/chrono//boost_chrono
<define>BOOST_ALL_NO_LIB=1
<threading>multi
<target-os>solaris:<library>socket
<target-os>solaris:<library>nsl
<target-os>windows:<define>_WIN32_WINNT=0x0501
<target-os>windows,<toolset>gcc:<library>ws2_32
<target-os>windows,<toolset>gcc:<library>mswsock
<target-os>windows,<toolset>gcc-cygwin:<define>__USE_W32_SOCKETS
<target-os>hpux,<toolset>gcc:<define>_XOPEN_SOURCE_EXTENDED
<target-os>hpux:<library>ipv6
<target-os>haiku:<library>network
;
test-suite "asio-experimental-coro" :
[ run cancel.cpp ]
[ run cancel.cpp : : : $(USE_SELECT) : cancel_select ]
[ run co_spawn.cpp ]
[ run co_spawn.cpp : : : $(USE_SELECT) : co_spawn_select ]
[ run exception.cpp ]
[ run exception.cpp : : : $(USE_SELECT) : exception_select ]
[ run executor.cpp ]
[ run executor.cpp : : : $(USE_SELECT) : executor_select ]
[ run partial.cpp ]
[ run partial.cpp : : : $(USE_SELECT) : partial_select ]
[ run simple_test.cpp ]
[ run simple_test.cpp : : : $(USE_SELECT) : simple_test_select ]
[ run stack_test.cpp ]
[ run stack_test.cpp : : : $(USE_SELECT) : stack_test_select ]
[ run use_coro.cpp ]
[ run use_coro.cpp : : : $(USE_SELECT) : use_coro_select ]
;

View File

@@ -0,0 +1,178 @@
//
// experimental/coro/cancel.cpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2021-2022 Klemens D. Morgenstern
// (klemens dot morgenstern at gmx dot net)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/experimental/coro.hpp>
#include <iostream>
#include <boost/asio/io_context.hpp>
#include <boost/asio/steady_timer.hpp>
#include <boost/asio/this_coro.hpp>
#include "../../unit_test.hpp"
using namespace boost::asio::experimental;
namespace this_coro = boost::asio::this_coro;
namespace coro {
auto coro_simple_cancel_impl(boost::asio::io_context& ) noexcept
-> boost::asio::experimental::coro<void() noexcept, boost::system::error_code>
{
BOOST_ASIO_CHECK(
!(co_await this_coro::cancellation_state).cancelled());
boost::asio::steady_timer timer{
co_await this_coro::executor,
std::chrono::seconds(1)};
BOOST_ASIO_CHECK(
!(co_await this_coro::cancellation_state).cancelled());
auto ec = co_await timer;
BOOST_ASIO_CHECK(
(co_await this_coro::cancellation_state).cancelled());
co_return ec;
}
void coro_simple_cancel()
{
boost::asio::io_context ctx;
boost::asio::cancellation_signal sig;
auto k = coro_simple_cancel_impl(ctx);
boost::system::error_code res_ec;
k.async_resume(
boost::asio::bind_cancellation_slot(sig.slot(),
[&](boost::system::error_code ec) {res_ec = ec;}));
boost::asio::post(ctx, [&]{sig.emit(boost::asio::cancellation_type::all);});
BOOST_ASIO_CHECK(!res_ec);
ctx.run();
BOOST_ASIO_CHECK(res_ec == boost::asio::error::operation_aborted);
}
auto coro_throw_cancel_impl(boost::asio::io_context& )
-> boost::asio::experimental::coro<void() , void>
{
boost::asio::steady_timer timer{
co_await this_coro::executor,
std::chrono::seconds(1)};
co_await timer;
}
void coro_throw_cancel()
{
boost::asio::io_context ctx;
boost::asio::cancellation_signal sig;
auto k = coro_throw_cancel_impl(ctx);
std::exception_ptr res_ex;
k.async_resume(
boost::asio::bind_cancellation_slot(sig.slot(),
[&](std::exception_ptr ex) {res_ex = ex;}));
boost::asio::post(ctx, [&]{sig.emit(boost::asio::cancellation_type::all);});
BOOST_ASIO_CHECK(!res_ex);
ctx.run();
BOOST_ASIO_CHECK(res_ex);
try
{
if (res_ex)
std::rethrow_exception(res_ex);
}
catch (boost::system::system_error& se)
{
BOOST_ASIO_CHECK(se.code() == boost::asio::error::operation_aborted);
}
}
auto coro_simple_cancel_nested_k(boost::asio::io_context&, int& cnt) noexcept
-> boost::asio::experimental::coro<
void() noexcept,
boost::system::error_code>
{
boost::asio::steady_timer timer{
co_await this_coro::executor,
std::chrono::milliseconds(100)};
BOOST_ASIO_CHECK(!(co_await this_coro::cancellation_state).cancelled());
auto ec = co_await timer;
cnt++;
BOOST_ASIO_CHECK((co_await this_coro::cancellation_state).cancelled());
co_return ec;
}
auto coro_simple_cancel_nested_kouter(
boost::asio::io_context& ctx, int& cnt) noexcept
-> boost::asio::experimental::coro<
boost::system::error_code() noexcept,
boost::system::error_code>
{
BOOST_ASIO_CHECK(cnt == 0);
co_yield co_await coro_simple_cancel_nested_k(ctx, cnt);
BOOST_ASIO_CHECK(cnt == 1);
auto ec = co_await coro_simple_cancel_nested_k(ctx, cnt);
BOOST_ASIO_CHECK(cnt == 2);
co_return ec;
}
void coro_simple_cancel_nested()
{
boost::asio::io_context ctx;
boost::asio::cancellation_signal sig;
int cnt = 0;
auto kouter = coro_simple_cancel_nested_kouter(ctx, cnt);
boost::system::error_code res_ec;
kouter.async_resume(
boost::asio::bind_cancellation_slot(sig.slot(),
[&](boost::system::error_code ec) {res_ec = ec;}));
boost::asio::post(ctx, [&]{sig.emit(boost::asio::cancellation_type::all);});
BOOST_ASIO_CHECK(!res_ec);
ctx.run();
BOOST_ASIO_CHECK(res_ec == boost::asio::error::operation_aborted);
ctx.restart();
res_ec = {};
kouter.async_resume(
boost::asio::bind_cancellation_slot(sig.slot(),
[&](boost::system::error_code ec) {res_ec = ec;}));
boost::asio::post(ctx, [&]{sig.emit(boost::asio::cancellation_type::all);});
BOOST_ASIO_CHECK(!res_ec);
ctx.run();
BOOST_ASIO_CHECK(res_ec == boost::asio::error::operation_aborted);
BOOST_ASIO_CHECK(cnt == 2);
}
} // namespace coro
BOOST_ASIO_TEST_SUITE
(
"coro/cancel",
BOOST_ASIO_TEST_CASE(::coro::coro_simple_cancel)
BOOST_ASIO_TEST_CASE(::coro::coro_throw_cancel)
BOOST_ASIO_TEST_CASE(::coro::coro_simple_cancel_nested)
)

View File

@@ -0,0 +1,67 @@
//
// experimental/coro/co_spawn.cpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2021-2022 Klemens D. Morgenstern
// (klemens dot morgenstern at gmx dot net)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/experimental/co_spawn.hpp>
#include <iostream>
#include <boost/asio/io_context.hpp>
#include <boost/asio/steady_timer.hpp>
#include <boost/asio/this_coro.hpp>
#include "../../unit_test.hpp"
using namespace boost::asio::experimental;
namespace this_coro = boost::asio::this_coro;
namespace coro {
auto coro_simple_co_spawn_impl(boost::asio::io_context& , bool &done) noexcept
-> boost::asio::experimental::coro<void() noexcept, int>
{
boost::asio::steady_timer timer(
co_await this_coro::executor,
std::chrono::milliseconds(10));
done = true;
co_return 42;
}
void coro_co_spawn()
{
boost::asio::io_context ctx;
bool done1 = false;
bool done2 = false;
int res = 0;
co_spawn(coro_simple_co_spawn_impl(ctx, done1),
[&](int r){done2= true; res = r;});
ctx.run();
BOOST_ASIO_CHECK(done1);
BOOST_ASIO_CHECK(done2);
BOOST_ASIO_CHECK(res == 42);
}
} // namespace coro
BOOST_ASIO_TEST_SUITE
(
"coro/co_spawn",
BOOST_ASIO_TEST_CASE(::coro::coro_co_spawn)
)

View File

@@ -0,0 +1,172 @@
//
// experimental/coro/exception.cpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2021-2022 Klemens D. Morgenstern
// (klemens dot morgenstern at gmx dot net)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/experimental/coro.hpp>
#include <boost/asio/co_spawn.hpp>
#include <boost/asio/detached.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/use_awaitable.hpp>
#include <boost/asio/awaitable.hpp>
#include "../../unit_test.hpp"
using namespace boost::asio::experimental;
namespace coro {
template <typename Func>
struct on_scope_exit
{
Func func;
static_assert(noexcept(func()));
on_scope_exit(const Func &f)
: func(static_cast< Func && >(f))
{
}
on_scope_exit(Func &&f)
: func(f)
{
}
on_scope_exit(const on_scope_exit &) = delete;
~on_scope_exit()
{
func();
}
};
boost::asio::experimental::coro<int> throwing_generator(
boost::asio::any_io_executor, int &last, bool &destroyed)
{
on_scope_exit x = [&]() noexcept { destroyed = true; };
(void)x;
int i = 0;
while (i < 3)
co_yield last = ++i;
throw std::runtime_error("throwing-generator");
}
boost::asio::awaitable<void> throwing_generator_test()
{
int val = 0;
bool destr = false;
{
auto gi = throwing_generator(
co_await boost::asio::this_coro::executor,
val, destr);
bool caught = false;
try
{
for (int i = 0; i < 10; i++)
{
BOOST_ASIO_CHECK(val == i);
const auto next = co_await gi.async_resume(boost::asio::use_awaitable);
BOOST_ASIO_CHECK(next);
BOOST_ASIO_CHECK(val == *next);
BOOST_ASIO_CHECK(val == i + 1);
}
}
catch (std::runtime_error &err)
{
caught = true;
using std::operator ""sv;
BOOST_ASIO_CHECK(err.what() == "throwing-generator"sv);
}
BOOST_ASIO_CHECK(val == 3);
BOOST_ASIO_CHECK(caught);
}
BOOST_ASIO_CHECK(destr);
};
void run_throwing_generator_test()
{
boost::asio::io_context ctx;
boost::asio::co_spawn(ctx, throwing_generator_test(), boost::asio::detached);
ctx.run();
}
boost::asio::experimental::coro<int(int)> throwing_stacked(
boost::asio::any_io_executor exec, int &val,
bool &destroyed_inner, bool &destroyed)
{
BOOST_ASIO_CHECK((co_await boost::asio::this_coro::throw_if_cancelled()));
on_scope_exit x = [&]() noexcept { destroyed = true; };
(void)x;
auto gen = throwing_generator(exec, val, destroyed_inner);
while (auto next = co_await gen) // 1, 2, 4, 8, ...
BOOST_ASIO_CHECK(42 ==(co_yield *next)); // offset is delayed by one cycle
}
boost::asio::awaitable<void> throwing_generator_stacked_test()
{
int val = 0;
bool destr = false, destr_inner = false;
{
auto gi = throwing_stacked(
co_await boost::asio::this_coro::executor,
val, destr, destr_inner);
bool caught = false;
try
{
for (int i = 0; i < 10; i++)
{
BOOST_ASIO_CHECK(val == i);
const auto next =
co_await gi.async_resume(42, boost::asio::use_awaitable);
BOOST_ASIO_CHECK(next);
BOOST_ASIO_CHECK(val == *next);
BOOST_ASIO_CHECK(val == i + 1);
}
}
catch (std::runtime_error &err)
{
caught = true;
using std::operator ""sv;
BOOST_ASIO_CHECK(err.what() == "throwing-generator"sv);
}
BOOST_ASIO_CHECK(val == 3);
BOOST_ASIO_CHECK(caught);
}
BOOST_ASIO_CHECK(destr);
BOOST_ASIO_CHECK(destr_inner);
};
void run_throwing_generator_stacked_test()
{
boost::asio::io_context ctx;
boost::asio::co_spawn(ctx,
throwing_generator_stacked_test,
boost::asio::detached);
ctx.run();
}
} // namespace coro
BOOST_ASIO_TEST_SUITE
(
"coro/exception",
BOOST_ASIO_TEST_CASE(::coro::run_throwing_generator_stacked_test)
BOOST_ASIO_TEST_CASE(::coro::run_throwing_generator_test)
)

View File

@@ -0,0 +1,116 @@
//
// experimental/coro/executor.cpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2021-2022 Klemens D. Morgenstern
// (klemens dot morgenstern at gmx dot net)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/experimental/coro.hpp>
#include <boost/asio/thread_pool.hpp>
#include <boost/asio/io_context.hpp>
#include "../../unit_test.hpp"
using namespace boost::asio::experimental;
namespace coro {
#define BOOST_ASIO_CHECKPOINT() \
BOOST_ASIO_TEST_IOSTREAM << __FILE__ << "(" << __LINE__ << "): " \
<< boost::asio::detail::test_name() << ": " \
<< "Checkpoint" << std::endl;
template <typename T>
void different_execs()
{
boost::asio::thread_pool th_ctx{1u};
boost::asio::io_context ctx;
auto o = std::make_optional(
boost::asio::prefer(th_ctx.get_executor(),
boost::asio::execution::outstanding_work.tracked));
static bool ran_inner = false, ran_outer = false;
struct c_inner_t
{
auto operator()(boost::asio::any_io_executor e) -> boost::asio::experimental::coro<T>
{
auto p = e.target<boost::asio::thread_pool::executor_type>();
BOOST_ASIO_CHECKPOINT();
BOOST_ASIO_CHECK(p);
BOOST_ASIO_CHECK(p->running_in_this_thread());
ran_inner = true;
co_return;
};
};
c_inner_t c_inner;
struct c_outer_t
{
auto operator()(boost::asio::any_io_executor e, int,
boost::asio::experimental::coro<T> tp)
-> boost::asio::experimental::coro<void>
{
auto p = e.target<boost::asio::io_context::executor_type>();
BOOST_ASIO_CHECK(p);
BOOST_ASIO_CHECK(p->running_in_this_thread());
BOOST_ASIO_CHECKPOINT();
co_await tp;
BOOST_ASIO_CHECKPOINT();
BOOST_ASIO_CHECK(p->running_in_this_thread());
ran_outer = true;
};
};
c_outer_t c_outer;
bool ran = false;
std::exception_ptr ex;
auto c = c_outer(ctx.get_executor(), 10, c_inner(th_ctx.get_executor()));
c.async_resume(
[&](std::exception_ptr e)
{
BOOST_ASIO_CHECK(!e);
BOOST_ASIO_CHECKPOINT();
ran = true;
});
BOOST_ASIO_CHECK(!ran);
ctx.run();
o.reset();
BOOST_ASIO_CHECK(ran);
BOOST_ASIO_CHECK(ran_inner);
BOOST_ASIO_CHECK(ran_outer);
BOOST_ASIO_CHECK(!ex);
th_ctx.stop();
th_ctx.join();
}
} // namespace coro
BOOST_ASIO_TEST_SUITE
(
"coro/partial",
BOOST_ASIO_TEST_CASE(::coro::different_execs<void>)
BOOST_ASIO_TEST_CASE(::coro::different_execs<int()>)
)

View File

@@ -0,0 +1,45 @@
//
// experimental/coro/partial.cpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2021-2022 Klemens D. Morgenstern
// (klemens dot morgenstern at gmx dot net)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/experimental/coro.hpp>
#include <boost/asio/io_context.hpp>
#include "../../unit_test.hpp"
using namespace boost::asio::experimental;
namespace coro {
void partial()
{
boost::asio::io_context ctx;
bool ran = false;
auto p = detail::post_coroutine(ctx, [&]{ran = true;});
BOOST_ASIO_CHECK(!ran);
p.resume();
BOOST_ASIO_CHECK(!ran);
ctx.run();
BOOST_ASIO_CHECK(ran);
}
} // namespace coro
BOOST_ASIO_TEST_SUITE
(
"coro/partial",
BOOST_ASIO_TEST_CASE(::coro::partial)
)

View File

@@ -0,0 +1,266 @@
//
// experimental/coro/simple_test.cpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2021-2022 Klemens D. Morgenstern
// (klemens dot morgenstern at gmx dot net)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/experimental/coro.hpp>
#include <boost/asio/co_spawn.hpp>
#include <boost/asio/detached.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/use_awaitable.hpp>
#include <iostream>
#include <vector>
#include "../../unit_test.hpp"
using namespace boost::asio::experimental;
namespace boost {
namespace asio {
namespace experimental {
template struct coro<void(), void, any_io_executor>;
template struct coro<int(), void, any_io_executor>;
template struct coro<void(), int, any_io_executor>;
template struct coro<int(int), void, any_io_executor>;
template struct coro<int(), int, any_io_executor>;
template struct coro<int(int), int, any_io_executor>;
template struct coro<void() noexcept, void, any_io_executor>;
template struct coro<int() noexcept, void, any_io_executor>;
template struct coro<void() noexcept, int, any_io_executor>;
template struct coro<int(int) noexcept, void, any_io_executor>;
template struct coro<int() noexcept, int, any_io_executor>;
template struct coro<int(int) noexcept, int, any_io_executor>;
} // namespace experimental
} // namespace asio
} // namespace boost
namespace coro {
template <typename Func>
struct on_scope_exit
{
Func func;
static_assert(noexcept(func()));
on_scope_exit(const Func &f)
: func(static_cast< Func && >(f))
{
}
on_scope_exit(Func &&f)
: func(f)
{
}
on_scope_exit(const on_scope_exit &) = delete;
~on_scope_exit()
{
func();
}
};
boost::asio::experimental::coro<int> generator_impl(
boost::asio::any_io_executor, int& last, bool& destroyed)
{
on_scope_exit x = [&]() noexcept { destroyed = true; };
(void)x;
int i = 0;
while (true)
co_yield last = ++i;
}
boost::asio::awaitable<void> generator_test()
{
int val = 0;
bool destr = false;
{
auto gi = generator_impl(
co_await boost::asio::this_coro::executor, val, destr);
for (int i = 0; i < 10; i++)
{
BOOST_ASIO_CHECK(val == i);
const auto next = co_await gi.async_resume(boost::asio::use_awaitable);
BOOST_ASIO_CHECK(next);
BOOST_ASIO_CHECK(val == *next);
BOOST_ASIO_CHECK(val == i + 1);
}
BOOST_ASIO_CHECK(!destr);
}
BOOST_ASIO_CHECK(destr);
};
void run_generator_test()
{
boost::asio::io_context ctx;
boost::asio::co_spawn(ctx, generator_test, boost::asio::detached);
ctx.run();
}
boost::asio::experimental::coro<void, int> task_test(boost::asio::io_context&)
{
co_return 42;
}
boost::asio::experimental::coro<void, int> task_throw(boost::asio::io_context&)
{
throw std::logic_error(__func__);
co_return 42;
}
void run_task_test()
{
boost::asio::io_context ctx;
bool tt1 = false;
bool tt2 = false;
bool tt3 = false;
bool tt4 = false;
auto tt = task_test(ctx);
tt.async_resume(
[&](std::exception_ptr pt, int i)
{
tt1 = true;
BOOST_ASIO_CHECK(!pt);
BOOST_ASIO_CHECK(i == 42);
tt.async_resume(
[&](std::exception_ptr pt, int)
{
tt2 = true;
BOOST_ASIO_CHECK(pt);
});
});
auto tt_2 = task_throw(ctx);
tt_2.async_resume(
[&](std::exception_ptr pt, int)
{
tt3 = true;
BOOST_ASIO_CHECK(pt);
tt.async_resume(
[&](std::exception_ptr pt, int)
{
tt4 = true;
BOOST_ASIO_CHECK(pt);
});
});
ctx.run();
BOOST_ASIO_CHECK(tt1);
BOOST_ASIO_CHECK(tt2);
BOOST_ASIO_CHECK(tt3);
BOOST_ASIO_CHECK(tt4);
}
boost::asio::experimental::coro<char> completion_generator_test_impl(
boost::asio::any_io_executor, int limit)
{
for (int i = 0; i < limit; i++)
co_yield i;
}
boost::asio::awaitable<void> completion_generator_test()
{
std::vector<int> res;
auto g = completion_generator_test_impl(
co_await boost::asio::this_coro::executor, 10);
BOOST_ASIO_CHECK(g.is_open());
while (auto val = co_await g.async_resume(boost::asio::use_awaitable))
res.push_back(*val);
BOOST_ASIO_CHECK(!g.is_open());
BOOST_ASIO_CHECK((res == std::vector{0,1,2,3,4,5,6,7,8,9}));
};
void run_completion_generator_test()
{
boost::asio::io_context ctx;
boost::asio::co_spawn(ctx, completion_generator_test, boost::asio::detached);
ctx.run();
}
boost::asio::experimental::coro<int(int)>
symmetrical_test_impl(boost::asio::any_io_executor)
{
int i = 0;
while (true)
i = (co_yield i) + i;
}
boost::asio::awaitable<void> symmetrical_test()
{
auto g = symmetrical_test_impl(co_await boost::asio::this_coro::executor);
BOOST_ASIO_CHECK(g.is_open());
BOOST_ASIO_CHECK(0 == (co_await g.async_resume(0,
boost::asio::use_awaitable)).value_or(-1));
BOOST_ASIO_CHECK(1 == (co_await g.async_resume(1,
boost::asio::use_awaitable)).value_or(-1));
BOOST_ASIO_CHECK(3 == (co_await g.async_resume(2,
boost::asio::use_awaitable)).value_or(-1));
BOOST_ASIO_CHECK(6 == (co_await g.async_resume(3,
boost::asio::use_awaitable)).value_or(-1));
BOOST_ASIO_CHECK(10 == (co_await g.async_resume(4,
boost::asio::use_awaitable)).value_or(-1));
BOOST_ASIO_CHECK(15 == (co_await g.async_resume(5,
boost::asio::use_awaitable)).value_or(-1));
BOOST_ASIO_CHECK(21 == (co_await g.async_resume(6,
boost::asio::use_awaitable)).value_or(-1));
BOOST_ASIO_CHECK(28 == (co_await g.async_resume(7,
boost::asio::use_awaitable)).value_or(-1));
BOOST_ASIO_CHECK(36 == (co_await g.async_resume(8,
boost::asio::use_awaitable)).value_or(-1));
BOOST_ASIO_CHECK(45 == (co_await g.async_resume(9,
boost::asio::use_awaitable)).value_or(-1));
};
void run_symmetrical_test()
{
boost::asio::io_context ctx;
boost::asio::co_spawn(ctx, symmetrical_test, boost::asio::detached);
ctx.run();
}
} // namespace coro
BOOST_ASIO_TEST_SUITE
(
"coro/simple_test",
BOOST_ASIO_TEST_CASE(::coro::run_generator_test)
BOOST_ASIO_TEST_CASE(::coro::run_task_test)
BOOST_ASIO_TEST_CASE(::coro::run_symmetrical_test)
BOOST_ASIO_TEST_CASE(::coro::run_completion_generator_test)
)

View File

@@ -0,0 +1,83 @@
//
// experimental/coro/stack_test.cpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2021-2022 Klemens D. Morgenstern
// (klemens dot morgenstern at gmx dot net)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/experimental/coro.hpp>
#include <boost/asio/detached.hpp>
#include <boost/asio/io_context.hpp>
#include <iostream>
#include "../../unit_test.hpp"
using namespace boost::asio::experimental;
namespace coro {
boost::asio::experimental::coro<int()>
stack_generator(boost::asio::any_io_executor, int i = 1)
{
for (;;)
{
co_yield i;
i *= 2;
}
}
boost::asio::experimental::coro<int(int)>
stack_accumulate(boost::asio::any_io_executor exec)
{
auto gen = stack_generator(exec);
int offset = 0;
while (auto next = co_await gen) // 1, 2, 4, 8, ...
offset = co_yield *next + offset; // offset is delayed by one cycle
}
boost::asio::experimental::coro<int>
main_stack_coro(boost::asio::io_context&, bool & done)
{
auto g = stack_accumulate(co_await boost::asio::this_coro::executor);
BOOST_ASIO_CHECK(g.is_open());
BOOST_ASIO_CHECK(1 == (co_await g(1000)).value_or(-1));
BOOST_ASIO_CHECK(2002 == (co_await g(2000)).value_or(-1));
BOOST_ASIO_CHECK(3004 == (co_await g(3000)).value_or(-1));
BOOST_ASIO_CHECK(4008 == (co_await g(4000)).value_or(-1));
BOOST_ASIO_CHECK(5016 == (co_await g(5000)).value_or(-1));
BOOST_ASIO_CHECK(6032 == (co_await g(6000)).value_or(-1));
BOOST_ASIO_CHECK(7064 == (co_await g(7000)).value_or(-1));
BOOST_ASIO_CHECK(8128 == (co_await g(8000)).value_or(-1));
BOOST_ASIO_CHECK(9256 == (co_await g(9000)).value_or(-1));
BOOST_ASIO_CHECK(511 == (co_await g(-1)).value_or(-1));
done = true;
}
void stack_test()
{
bool done = false;
boost::asio::io_context ctx;
auto k = main_stack_coro(ctx, done);
k.async_resume(boost::asio::detached);
ctx.run();
BOOST_ASIO_CHECK(done);
}
} // namespace coro
BOOST_ASIO_TEST_SUITE
(
"coro/stack_test",
BOOST_ASIO_TEST_CASE(::coro::stack_test)
)

View File

@@ -0,0 +1,77 @@
//
// experimental/coro/use_coro.cpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2021-2022 Klemens D. Morgenstern
// (klemens dot morgenstern at gmx dot net)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/experimental/use_coro.hpp>
#include <boost/asio/steady_timer.hpp>
#include <iostream>
#include "../../unit_test.hpp"
using namespace boost::asio::experimental;
namespace coro {
boost::asio::experimental::coro<void(), int>
awaiter(boost::asio::any_io_executor exec)
{
boost::asio::steady_timer timer{exec};
co_await timer.async_wait(use_coro);
co_return 42;
}
boost::asio::experimental::coro<void() noexcept, int>
awaiter_noexcept(boost::asio::any_io_executor exec)
{
boost::asio::steady_timer timer{exec};
auto ec = co_await timer.async_wait(use_coro);
BOOST_ASIO_CHECK(ec == boost::system::error_code{});
co_return 42;
}
void stack_test2()
{
bool done = false;
boost::asio::io_context ctx;
auto k = awaiter(ctx.get_executor());
auto k2 = awaiter_noexcept(ctx.get_executor());
k.async_resume(
[&](std::exception_ptr ex, int res)
{
BOOST_ASIO_CHECK(!ex);
BOOST_ASIO_CHECK(res == 42);
done = true;
});
k2.async_resume([&](int res)
{
BOOST_ASIO_CHECK(res == 42);
done = true;
});
ctx.run();
BOOST_ASIO_CHECK(done);
}
} // namespace coro
BOOST_ASIO_TEST_SUITE
(
"coro/use_coro",
BOOST_ASIO_TEST_CASE(::coro::stack_test2)
)

View File

@@ -0,0 +1,25 @@
//
// experimental/deferred.cpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/experimental/deferred.hpp>
#include "../unit_test.hpp"
BOOST_ASIO_TEST_SUITE
(
"experimental/deferred",
BOOST_ASIO_TEST_CASE(null_test)
)

View File

@@ -0,0 +1,58 @@
//
// experimental/prepend.cpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/experimental/prepend.hpp>
#include <boost/asio/bind_executor.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/post.hpp>
#include <boost/asio/system_timer.hpp>
#include "../unit_test.hpp"
void prepend_test()
{
boost::asio::io_context io1;
boost::asio::io_context io2;
boost::asio::system_timer timer1(io1);
int count = 0;
timer1.expires_after(boost::asio::chrono::seconds(0));
timer1.async_wait(
boost::asio::experimental::prepend(
boost::asio::bind_executor(io2.get_executor(),
[&count](int a, int b, boost::system::error_code)
{
++count;
BOOST_ASIO_CHECK(a == 123);
BOOST_ASIO_CHECK(b == 321);
}), 123, 321));
BOOST_ASIO_CHECK(count == 0);
io1.run();
BOOST_ASIO_CHECK(count == 0);
io2.run();
BOOST_ASIO_CHECK(count == 1);
}
BOOST_ASIO_TEST_SUITE
(
"experimental/basic_channel",
BOOST_ASIO_TEST_CASE(prepend_test)
)

View File

@@ -0,0 +1,322 @@
//
// promise.cpp
// ~~~~~~~~~~~
//
// Copyright (c) 2021-2022 Klemens D. Morgenstern
// (klemens dot morgenstern at gmx dot net)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include <boost/asio/experimental/promise.hpp>
#include <array>
#include <vector>
#include <boost/asio/steady_timer.hpp>
#include "../unit_test.hpp"
namespace promise {
void promise_tester()
{
using namespace boost::asio;
using boost::system::error_code;
using namespace std::chrono;
io_context ctx;
steady_timer timer1{ctx}, timer2{ctx};
const auto started_when = steady_clock::now();
timer1.expires_at(started_when + milliseconds(2000));
timer2.expires_at(started_when + milliseconds(1000));
auto p = timer1.async_wait(experimental::use_promise);
steady_clock::time_point completed_when;
error_code ec;
bool called = false;
p.async_wait(
[&](auto ec_)
{
ec = ec_;
called = true;
completed_when = steady_clock::now();
});
steady_clock::time_point timer2_done;
timer2.async_wait([&](auto) {
timer2_done = steady_clock::now();;
p.cancel();
});
ctx.run();
BOOST_ASIO_CHECK(timer2_done + milliseconds(1) > completed_when);
BOOST_ASIO_CHECK(called);
BOOST_ASIO_CHECK(ec == error::operation_aborted);
}
void promise_race_tester()
{
using namespace boost::asio;
using boost::system::error_code;
using namespace std::chrono;
io_context ctx;
steady_timer timer1{ctx}, timer2{ctx};
const auto started_when = steady_clock::now();
timer1.expires_at(started_when + milliseconds(2000));
timer2.expires_at(started_when + milliseconds(1000));
experimental::promise<void(std::variant<error_code, error_code>)> p =
experimental::promise<>::race(
timer1.async_wait(experimental::use_promise),
timer2.async_wait(experimental::use_promise));
auto called = false;
error_code ec;
steady_clock::time_point completed_when;
p.async_wait(
[&](auto v)
{
BOOST_ASIO_CHECK(v.index() == 1);
ec = get<1>(v);
called = true;
completed_when = steady_clock::now();
});
ctx.run();
BOOST_ASIO_CHECK(started_when + milliseconds(1000) <= completed_when);
BOOST_ASIO_CHECK(started_when + milliseconds(1500) > completed_when);
BOOST_ASIO_CHECK(called);
BOOST_ASIO_CHECK(!ec);
}
void promise_all_tester()
{
using namespace boost::asio;
using boost::system::error_code;
using namespace std::chrono;
io_context ctx;
steady_timer timer1{ctx},
timer2{ctx};
const auto started_when = steady_clock::now();
timer1.expires_at(started_when + milliseconds(2000));
timer2.expires_at(started_when + milliseconds(1000));
experimental::promise<void(error_code, error_code)> p =
experimental::promise<>::all(
timer1.async_wait(experimental::use_promise),
timer2.async_wait(experimental::use_promise));
bool called = false;
steady_clock::time_point completed_when;
p.async_wait(
[&](auto ec1, auto ec2)
{
BOOST_ASIO_CHECK(!ec1);
BOOST_ASIO_CHECK(!ec2);
called = true;
completed_when = steady_clock::now();
});
ctx.run();
BOOST_ASIO_CHECK(started_when + milliseconds(2000) <= completed_when);
BOOST_ASIO_CHECK(started_when + milliseconds(2500) > completed_when);
BOOST_ASIO_CHECK(called);
}
void promise_race_ranged_tester()
{
using namespace boost::asio;
using boost::system::error_code;
using namespace std::chrono;
io_context ctx;
steady_timer timer1{ctx}, timer2{ctx};
const auto started_when = steady_clock::now();
timer1.expires_at(started_when + milliseconds(2000));
timer2.expires_at(started_when + milliseconds(1000));
// promise<
// std::variant<
// tuple<error_code, std::size_t>,
// tuple<error_code, std::size_t>>>
experimental::promise<void(std::size_t, error_code)> p =
experimental::promise<>::race(
std::array{
timer1.async_wait(experimental::use_promise),
timer2.async_wait(experimental::use_promise)
});
auto called = false;
auto completed_when = steady_clock::time_point();
p.async_wait([&](auto idx, auto ec )
{
BOOST_ASIO_CHECK(idx == 1);
called = true;
completed_when = steady_clock::now();
BOOST_ASIO_CHECK(!ec);
});
std::vector<experimental::promise<void()>> arr;
experimental::promise<>::race(
ctx.get_executor(), std::move(arr)
).async_wait(
[](std::size_t idx) {BOOST_ASIO_CHECK(idx == std::size_t(-1));}
);
ctx.run();
BOOST_ASIO_CHECK(started_when + milliseconds(1000) <= completed_when);
BOOST_ASIO_CHECK(started_when + milliseconds(1500) > completed_when);
BOOST_ASIO_CHECK(called);
std::exception_ptr ex;
try
{
experimental::promise<>::race(std::move(arr));
}
catch (...)
{
ex = std::current_exception();
}
BOOST_ASIO_CHECK(ex);
}
void promise_all_ranged_tester()
{
using namespace boost::asio;
using boost::system::error_code;
using namespace std::chrono;
io_context ctx;
steady_timer timer1{ctx}, timer2{ctx};
const auto started_when = steady_clock::now();
timer1.expires_at(started_when + milliseconds(2000));
timer2.expires_at(started_when + milliseconds(1000));
// promise<
// std::variant<
// tuple<error_code, std::size_t>,
// tuple<error_code, std::size_t>>>
experimental::promise<void(std::vector<error_code>)> p =
experimental::promise<>::all(
std::array{
timer1.async_wait(experimental::use_promise),
timer2.async_wait(experimental::use_promise)
});
auto called = false;
auto completed_when = steady_clock::time_point();
p.async_wait(
[&](auto v){
BOOST_ASIO_CHECK(v.size() == 2u);
completed_when = steady_clock::now();
BOOST_ASIO_CHECK(!v[0]);
BOOST_ASIO_CHECK(!v[1]);
called = true;
});
std::vector<experimental::promise<void()>> arr;
experimental::promise<>::all(
ctx.get_executor(), std::move(arr)
).async_wait(
[](auto v) {BOOST_ASIO_CHECK(v.size() == 0);}
);
ctx.run();
BOOST_ASIO_CHECK(started_when + milliseconds(2000) <= completed_when);
BOOST_ASIO_CHECK(started_when + milliseconds(2500) > completed_when);
BOOST_ASIO_CHECK(called == true);
std::exception_ptr ex;
try
{
experimental::promise<>::all(std::move(arr));
}
catch (...)
{
ex = std::current_exception();
}
BOOST_ASIO_CHECK(ex);
}
void promise_cancel_tester()
{
using namespace boost::asio;
using boost::system::error_code;
using namespace std::chrono;
io_context ctx;
steady_timer timer1{ctx}, timer2{ctx};
const auto started_when = steady_clock::now();
timer1.expires_at(started_when + milliseconds(2000));
timer2.expires_at(started_when + milliseconds(1000));
// promise<
// std::variant<
// tuple<error_code, std::size_t>,
// tuple<error_code, std::size_t>>>
experimental::promise<void(error_code, error_code)> p =
experimental::promise<>::all(
timer1.async_wait(experimental::use_promise),
timer2.async_wait(experimental::use_promise));
bool called = false;
p.async_wait(
[&](auto ec1, auto ec2)
{
called = true;
BOOST_ASIO_CHECK(ec1 == error::operation_aborted);
BOOST_ASIO_CHECK(ec2 == error::operation_aborted);
});
post(ctx, [&]{p.cancel();});
ctx.run();
BOOST_ASIO_CHECK(called);
}
} // namespace promise
BOOST_ASIO_TEST_SUITE
(
"promise",
BOOST_ASIO_TEST_CASE(promise::promise_tester)
BOOST_ASIO_TEST_CASE(promise::promise_race_tester)
BOOST_ASIO_TEST_CASE(promise::promise_all_tester)
BOOST_ASIO_TEST_CASE(promise::promise_race_ranged_tester)
BOOST_ASIO_TEST_CASE(promise::promise_all_ranged_tester)
BOOST_ASIO_TEST_CASE(promise::promise_cancel_tester)
)

Some files were not shown because too many files have changed in this diff Show More