Update boost to 1.71

This commit is contained in:
FearlessTobi 2019-09-07 17:55:51 +02:00
parent 502437b2ae
commit a7826d8f57
843 changed files with 32812 additions and 23388 deletions

View File

@ -1,7 +1,7 @@
Boost libraries - trimmed down for Citra Boost libraries - trimmed down for Citra
======================================== ========================================
This is a subset of Boost v1.67.0 generated using the bcp tool. To get a list of boost modules guaranteed to exist, check the build script. This is a subset of Boost v1.71.0 generated using the bcp tool. To get a list of boost modules guaranteed to exist, check the build script.
Updating this repo (on Windows) Updating this repo (on Windows)
=============================== ===============================

View File

@ -43,7 +43,6 @@ namespace boost {
The result is given as an \c iterator_range delimiting the match. The result is given as an \c iterator_range delimiting the match.
\param Search A substring to be searched for. \param Search A substring to be searched for.
\param Comp An element comparison predicate
\return An instance of the \c first_finder object \return An instance of the \c first_finder object
*/ */
template<typename RangeT> template<typename RangeT>
@ -84,7 +83,6 @@ namespace boost {
The result is given as an \c iterator_range delimiting the match. The result is given as an \c iterator_range delimiting the match.
\param Search A substring to be searched for. \param Search A substring to be searched for.
\param Comp An element comparison predicate
\return An instance of the \c last_finder object \return An instance of the \c last_finder object
*/ */
template<typename RangeT> template<typename RangeT>
@ -124,7 +122,6 @@ namespace boost {
\param Search A substring to be searched for. \param Search A substring to be searched for.
\param Nth An index of the match to be find \param Nth An index of the match to be find
\param Comp An element comparison predicate
\return An instance of the \c nth_finder object \return An instance of the \c nth_finder object
*/ */
template<typename RangeT> template<typename RangeT>
@ -230,7 +227,6 @@ namespace boost {
\param Begin Beginning of the range \param Begin Beginning of the range
\param End End of the range \param End End of the range
\param Range The range.
\return An instance of the \c range_finger object \return An instance of the \c range_finger object
*/ */
template< typename ForwardIteratorT > template< typename ForwardIteratorT >

View File

@ -183,7 +183,7 @@ namespace boost {
// check range (may be private because it is static) // check range (may be private because it is static)
static BOOST_CONSTEXPR bool rangecheck (size_type i) { static BOOST_CONSTEXPR bool rangecheck (size_type i) {
return i > size() ? boost::throw_exception(std::out_of_range ("array<>: index out of range")), true : true; return i >= size() ? boost::throw_exception(std::out_of_range ("array<>: index out of range")), true : true;
} }
}; };

View File

@ -2,7 +2,7 @@
// asio.hpp // asio.hpp
// ~~~~~~~~ // ~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -20,6 +20,7 @@
#include <boost/asio/associated_allocator.hpp> #include <boost/asio/associated_allocator.hpp>
#include <boost/asio/associated_executor.hpp> #include <boost/asio/associated_executor.hpp>
#include <boost/asio/async_result.hpp> #include <boost/asio/async_result.hpp>
#include <boost/asio/awaitable.hpp>
#include <boost/asio/basic_datagram_socket.hpp> #include <boost/asio/basic_datagram_socket.hpp>
#include <boost/asio/basic_deadline_timer.hpp> #include <boost/asio/basic_deadline_timer.hpp>
#include <boost/asio/basic_io_object.hpp> #include <boost/asio/basic_io_object.hpp>
@ -27,6 +28,7 @@
#include <boost/asio/basic_seq_packet_socket.hpp> #include <boost/asio/basic_seq_packet_socket.hpp>
#include <boost/asio/basic_serial_port.hpp> #include <boost/asio/basic_serial_port.hpp>
#include <boost/asio/basic_signal_set.hpp> #include <boost/asio/basic_signal_set.hpp>
#include <boost/asio/basic_socket.hpp>
#include <boost/asio/basic_socket_acceptor.hpp> #include <boost/asio/basic_socket_acceptor.hpp>
#include <boost/asio/basic_socket_iostream.hpp> #include <boost/asio/basic_socket_iostream.hpp>
#include <boost/asio/basic_socket_streambuf.hpp> #include <boost/asio/basic_socket_streambuf.hpp>
@ -42,13 +44,14 @@
#include <boost/asio/buffered_write_stream_fwd.hpp> #include <boost/asio/buffered_write_stream_fwd.hpp>
#include <boost/asio/buffered_write_stream.hpp> #include <boost/asio/buffered_write_stream.hpp>
#include <boost/asio/buffers_iterator.hpp> #include <boost/asio/buffers_iterator.hpp>
#include <boost/asio/co_spawn.hpp>
#include <boost/asio/completion_condition.hpp> #include <boost/asio/completion_condition.hpp>
#include <boost/asio/compose.hpp>
#include <boost/asio/connect.hpp> #include <boost/asio/connect.hpp>
#include <boost/asio/coroutine.hpp> #include <boost/asio/coroutine.hpp>
#include <boost/asio/datagram_socket_service.hpp>
#include <boost/asio/deadline_timer_service.hpp>
#include <boost/asio/deadline_timer.hpp> #include <boost/asio/deadline_timer.hpp>
#include <boost/asio/defer.hpp> #include <boost/asio/defer.hpp>
#include <boost/asio/detached.hpp>
#include <boost/asio/dispatch.hpp> #include <boost/asio/dispatch.hpp>
#include <boost/asio/error.hpp> #include <boost/asio/error.hpp>
#include <boost/asio/execution_context.hpp> #include <boost/asio/execution_context.hpp>
@ -62,7 +65,6 @@
#include <boost/asio/handler_alloc_hook.hpp> #include <boost/asio/handler_alloc_hook.hpp>
#include <boost/asio/handler_continuation_hook.hpp> #include <boost/asio/handler_continuation_hook.hpp>
#include <boost/asio/handler_invoke_hook.hpp> #include <boost/asio/handler_invoke_hook.hpp>
#include <boost/asio/handler_type.hpp>
#include <boost/asio/high_resolution_timer.hpp> #include <boost/asio/high_resolution_timer.hpp>
#include <boost/asio/io_context.hpp> #include <boost/asio/io_context.hpp>
#include <boost/asio/io_context_strand.hpp> #include <boost/asio/io_context_strand.hpp>
@ -75,6 +77,8 @@
#include <boost/asio/ip/address_v6.hpp> #include <boost/asio/ip/address_v6.hpp>
#include <boost/asio/ip/address_v6_iterator.hpp> #include <boost/asio/ip/address_v6_iterator.hpp>
#include <boost/asio/ip/address_v6_range.hpp> #include <boost/asio/ip/address_v6_range.hpp>
#include <boost/asio/ip/network_v4.hpp>
#include <boost/asio/ip/network_v6.hpp>
#include <boost/asio/ip/bad_address_cast.hpp> #include <boost/asio/ip/bad_address_cast.hpp>
#include <boost/asio/ip/basic_endpoint.hpp> #include <boost/asio/ip/basic_endpoint.hpp>
#include <boost/asio/ip/basic_resolver.hpp> #include <boost/asio/ip/basic_resolver.hpp>
@ -86,7 +90,6 @@
#include <boost/asio/ip/multicast.hpp> #include <boost/asio/ip/multicast.hpp>
#include <boost/asio/ip/resolver_base.hpp> #include <boost/asio/ip/resolver_base.hpp>
#include <boost/asio/ip/resolver_query_base.hpp> #include <boost/asio/ip/resolver_query_base.hpp>
#include <boost/asio/ip/resolver_service.hpp>
#include <boost/asio/ip/tcp.hpp> #include <boost/asio/ip/tcp.hpp>
#include <boost/asio/ip/udp.hpp> #include <boost/asio/ip/udp.hpp>
#include <boost/asio/ip/unicast.hpp> #include <boost/asio/ip/unicast.hpp>
@ -105,46 +108,38 @@
#include <boost/asio/posix/descriptor.hpp> #include <boost/asio/posix/descriptor.hpp>
#include <boost/asio/posix/descriptor_base.hpp> #include <boost/asio/posix/descriptor_base.hpp>
#include <boost/asio/posix/stream_descriptor.hpp> #include <boost/asio/posix/stream_descriptor.hpp>
#include <boost/asio/posix/stream_descriptor_service.hpp>
#include <boost/asio/post.hpp> #include <boost/asio/post.hpp>
#include <boost/asio/raw_socket_service.hpp>
#include <boost/asio/read.hpp> #include <boost/asio/read.hpp>
#include <boost/asio/read_at.hpp> #include <boost/asio/read_at.hpp>
#include <boost/asio/read_until.hpp> #include <boost/asio/read_until.hpp>
#include <boost/asio/seq_packet_socket_service.hpp> #include <boost/asio/redirect_error.hpp>
#include <boost/asio/serial_port.hpp> #include <boost/asio/serial_port.hpp>
#include <boost/asio/serial_port_base.hpp> #include <boost/asio/serial_port_base.hpp>
#include <boost/asio/serial_port_service.hpp>
#include <boost/asio/signal_set.hpp> #include <boost/asio/signal_set.hpp>
#include <boost/asio/signal_set_service.hpp>
#include <boost/asio/socket_acceptor_service.hpp>
#include <boost/asio/socket_base.hpp> #include <boost/asio/socket_base.hpp>
#include <boost/asio/steady_timer.hpp> #include <boost/asio/steady_timer.hpp>
#include <boost/asio/strand.hpp> #include <boost/asio/strand.hpp>
#include <boost/asio/stream_socket_service.hpp>
#include <boost/asio/streambuf.hpp> #include <boost/asio/streambuf.hpp>
#include <boost/asio/system_context.hpp> #include <boost/asio/system_context.hpp>
#include <boost/asio/system_executor.hpp> #include <boost/asio/system_executor.hpp>
#include <boost/asio/system_timer.hpp> #include <boost/asio/system_timer.hpp>
#include <boost/asio/this_coro.hpp>
#include <boost/asio/thread_pool.hpp> #include <boost/asio/thread_pool.hpp>
#include <boost/asio/time_traits.hpp> #include <boost/asio/time_traits.hpp>
#include <boost/asio/use_awaitable.hpp>
#include <boost/asio/use_future.hpp> #include <boost/asio/use_future.hpp>
#include <boost/asio/uses_executor.hpp> #include <boost/asio/uses_executor.hpp>
#include <boost/asio/version.hpp> #include <boost/asio/version.hpp>
#include <boost/asio/wait_traits.hpp> #include <boost/asio/wait_traits.hpp>
#include <boost/asio/waitable_timer_service.hpp>
#include <boost/asio/windows/basic_handle.hpp>
#include <boost/asio/windows/basic_object_handle.hpp> #include <boost/asio/windows/basic_object_handle.hpp>
#include <boost/asio/windows/basic_overlapped_handle.hpp>
#include <boost/asio/windows/basic_random_access_handle.hpp> #include <boost/asio/windows/basic_random_access_handle.hpp>
#include <boost/asio/windows/basic_stream_handle.hpp> #include <boost/asio/windows/basic_stream_handle.hpp>
#include <boost/asio/windows/object_handle.hpp> #include <boost/asio/windows/object_handle.hpp>
#include <boost/asio/windows/object_handle_service.hpp>
#include <boost/asio/windows/overlapped_handle.hpp> #include <boost/asio/windows/overlapped_handle.hpp>
#include <boost/asio/windows/overlapped_ptr.hpp> #include <boost/asio/windows/overlapped_ptr.hpp>
#include <boost/asio/windows/random_access_handle.hpp> #include <boost/asio/windows/random_access_handle.hpp>
#include <boost/asio/windows/random_access_handle_service.hpp>
#include <boost/asio/windows/stream_handle.hpp> #include <boost/asio/windows/stream_handle.hpp>
#include <boost/asio/windows/stream_handle_service.hpp>
#include <boost/asio/write.hpp> #include <boost/asio/write.hpp>
#include <boost/asio/write_at.hpp> #include <boost/asio/write_at.hpp>

View File

@ -2,7 +2,7 @@
// associated_allocator.hpp // associated_allocator.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// associated_executor.hpp // associated_executor.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// async_result.hpp // async_result.hpp
// ~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -17,7 +17,7 @@
#include <boost/asio/detail/config.hpp> #include <boost/asio/detail/config.hpp>
#include <boost/asio/detail/type_traits.hpp> #include <boost/asio/detail/type_traits.hpp>
#include <boost/asio/handler_type.hpp> #include <boost/asio/detail/variadic_templates.hpp>
#include <boost/asio/detail/push_options.hpp> #include <boost/asio/detail/push_options.hpp>
@ -42,30 +42,15 @@ namespace asio {
* The primary template assumes that the CompletionToken is the completion * The primary template assumes that the CompletionToken is the completion
* handler. * handler.
*/ */
#if defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
template <typename CompletionToken, typename Signature> template <typename CompletionToken, typename Signature>
#else // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
template <typename CompletionToken, typename Signature = void>
#endif // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
class async_result class async_result
{ {
public: public:
#if defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
/// The concrete completion handler type for the specific signature. /// The concrete completion handler type for the specific signature.
typedef CompletionToken completion_handler_type; typedef CompletionToken completion_handler_type;
/// The return type of the initiating function. /// The return type of the initiating function.
typedef void return_type; typedef void return_type;
#else // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
// For backward compatibility, determine the concrete completion handler type
// by using the legacy handler_type trait.
typedef typename handler_type<CompletionToken, Signature>::type
completion_handler_type;
// For backward compatibility, determine the initiating function return type
// using the legacy single-parameter version of async_result.
typedef typename async_result<completion_handler_type>::type return_type;
#endif // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
/// Construct an async result from a given handler. /// Construct an async result from a given handler.
/** /**
@ -74,11 +59,6 @@ public:
* then returned from the initiating function. * then returned from the initiating function.
*/ */
explicit async_result(completion_handler_type& h) explicit async_result(completion_handler_type& h)
#if defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
// No data members to initialise.
#else // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
: legacy_result_(h)
#endif // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
{ {
(void)h; (void)h;
} }
@ -86,56 +66,60 @@ public:
/// Obtain the value to be returned from the initiating function. /// Obtain the value to be returned from the initiating function.
return_type get() return_type get()
{ {
#if defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
// Nothing to do.
#else // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
return legacy_result_.get();
#endif // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
} }
#if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) \
|| defined(GENERATING_DOCUMENTATION)
/// Initiate the asynchronous operation that will produce the result, and
/// obtain the value to be returned from the initiating function.
template <typename Initiation, typename RawCompletionToken, typename... Args>
static return_type initiate(
BOOST_ASIO_MOVE_ARG(Initiation) initiation,
BOOST_ASIO_MOVE_ARG(RawCompletionToken) token,
BOOST_ASIO_MOVE_ARG(Args)... args)
{
BOOST_ASIO_MOVE_CAST(Initiation)(initiation)(
BOOST_ASIO_MOVE_CAST(RawCompletionToken)(token),
BOOST_ASIO_MOVE_CAST(Args)(args)...);
}
#else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
// || defined(GENERATING_DOCUMENTATION)
template <typename Initiation, typename RawCompletionToken>
static return_type initiate(
BOOST_ASIO_MOVE_ARG(Initiation) initiation,
BOOST_ASIO_MOVE_ARG(RawCompletionToken) token)
{
BOOST_ASIO_MOVE_CAST(Initiation)(initiation)(
BOOST_ASIO_MOVE_CAST(RawCompletionToken)(token));
}
#define BOOST_ASIO_PRIVATE_INITIATE_DEF(n) \
template <typename Initiation, typename RawCompletionToken, \
BOOST_ASIO_VARIADIC_TPARAMS(n)> \
static return_type initiate( \
BOOST_ASIO_MOVE_ARG(Initiation) initiation, \
BOOST_ASIO_MOVE_ARG(RawCompletionToken) token, \
BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
{ \
BOOST_ASIO_MOVE_CAST(Initiation)(initiation)( \
BOOST_ASIO_MOVE_CAST(RawCompletionToken)(token), \
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)
// || defined(GENERATING_DOCUMENTATION)
private: private:
async_result(const async_result&) BOOST_ASIO_DELETED; async_result(const async_result&) BOOST_ASIO_DELETED;
async_result& operator=(const async_result&) BOOST_ASIO_DELETED; async_result& operator=(const async_result&) BOOST_ASIO_DELETED;
#if defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
// No data members.
#else // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
async_result<completion_handler_type> legacy_result_;
#endif // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
}; };
#if !defined(BOOST_ASIO_NO_DEPRECATED)
/// (Deprecated: Use two-parameter version of async_result.) An interface for
/// customising the behaviour of an initiating function.
/**
* This template may be specialised for user-defined handler types.
*/
template <typename Handler>
class async_result<Handler>
{
public:
/// The return type of the initiating function.
typedef void type;
/// Construct an async result from a given handler.
/**
* When using a specalised async_result, the constructor has an opportunity
* to initialise some state associated with the handler, which is then
* returned from the initiating function.
*/
explicit async_result(Handler&)
{
}
/// Obtain the value to be returned from the initiating function.
type get()
{
}
};
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
/// Helper template to deduce the handler type from a CompletionToken, capture /// Helper template to deduce the handler type from a CompletionToken, capture
/// a local copy of the handler, and then create an async_result for the /// a local copy of the handler, and then create an async_result for the
/// handler. /// handler.
@ -195,11 +179,40 @@ struct async_result_helper
{ {
}; };
} // namespace detail struct async_result_memfns_base
} // namespace asio {
} // namespace boost void initiate();
};
#include <boost/asio/detail/pop_options.hpp> template <typename T>
struct async_result_memfns_derived
: T, async_result_memfns_base
{
};
template <typename T, T>
struct async_result_memfns_check
{
};
template <typename>
char (&async_result_initiate_memfn_helper(...))[2];
template <typename T>
char async_result_initiate_memfn_helper(
async_result_memfns_check<
void (async_result_memfns_base::*)(),
&async_result_memfns_derived<T>::initiate>*);
template <typename CompletionToken, typename Signature>
struct async_result_has_initiate_memfn
: integral_constant<bool, sizeof(async_result_initiate_memfn_helper<
async_result<typename decay<CompletionToken>::type, Signature>
>(0)) != 1>
{
};
} // namespace detail
#if defined(GENERATING_DOCUMENTATION) #if defined(GENERATING_DOCUMENTATION)
# define BOOST_ASIO_INITFN_RESULT_TYPE(ct, sig) \ # define BOOST_ASIO_INITFN_RESULT_TYPE(ct, sig) \
@ -220,4 +233,126 @@ struct async_result_helper
typename ::boost::asio::decay<ct>::type, sig>::completion_handler_type typename ::boost::asio::decay<ct>::type, sig>::completion_handler_type
#endif #endif
#if defined(GENERATING_DOCUMENTATION)
template <typename CompletionToken, typename Signature,
typename Initiation, typename... Args>
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)
async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation,
BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken),
BOOST_ASIO_MOVE_ARG(Args)... args);
#elif defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
template <typename CompletionToken, typename Signature,
typename Initiation, typename... Args>
inline typename enable_if<
detail::async_result_has_initiate_memfn<CompletionToken, Signature>::value,
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type
async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation,
BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token,
BOOST_ASIO_MOVE_ARG(Args)... args)
{
return async_result<typename decay<CompletionToken>::type,
Signature>::initiate(BOOST_ASIO_MOVE_CAST(Initiation)(initiation),
BOOST_ASIO_MOVE_CAST(CompletionToken)(token),
BOOST_ASIO_MOVE_CAST(Args)(args)...);
}
template <typename CompletionToken, typename Signature,
typename Initiation, typename... Args>
inline typename enable_if<
!detail::async_result_has_initiate_memfn<CompletionToken, Signature>::value,
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type
async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation,
BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token,
BOOST_ASIO_MOVE_ARG(Args)... args)
{
async_completion<CompletionToken, Signature> completion(token);
BOOST_ASIO_MOVE_CAST(Initiation)(initiation)(
BOOST_ASIO_MOVE_CAST(BOOST_ASIO_HANDLER_TYPE(CompletionToken,
Signature))(completion.completion_handler),
BOOST_ASIO_MOVE_CAST(Args)(args)...);
return completion.result.get();
}
#else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
template <typename CompletionToken, typename Signature, typename Initiation>
inline typename enable_if<
detail::async_result_has_initiate_memfn<CompletionToken, Signature>::value,
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type
async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation,
BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token)
{
return async_result<typename decay<CompletionToken>::type,
Signature>::initiate(BOOST_ASIO_MOVE_CAST(Initiation)(initiation),
BOOST_ASIO_MOVE_CAST(CompletionToken)(token));
}
template <typename CompletionToken, typename Signature, typename Initiation>
inline typename enable_if<
!detail::async_result_has_initiate_memfn<CompletionToken, Signature>::value,
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type
async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation,
BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token)
{
async_completion<CompletionToken, Signature> completion(token);
BOOST_ASIO_MOVE_CAST(Initiation)(initiation)(
BOOST_ASIO_MOVE_CAST(BOOST_ASIO_HANDLER_TYPE(CompletionToken,
Signature))(completion.completion_handler));
return completion.result.get();
}
#define BOOST_ASIO_PRIVATE_INITIATE_DEF(n) \
template <typename CompletionToken, typename Signature, \
typename Initiation, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
inline typename enable_if< \
detail::async_result_has_initiate_memfn< \
CompletionToken, Signature>::value, \
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type \
async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation, \
BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \
BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
{ \
return async_result<typename decay<CompletionToken>::type, \
Signature>::initiate(BOOST_ASIO_MOVE_CAST(Initiation)(initiation), \
BOOST_ASIO_MOVE_CAST(CompletionToken)(token), \
BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
} \
\
template <typename CompletionToken, typename Signature, \
typename Initiation, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
inline typename enable_if< \
!detail::async_result_has_initiate_memfn< \
CompletionToken, Signature>::value, \
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type \
async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation, \
BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \
BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
{ \
async_completion<CompletionToken, Signature> completion(token); \
\
BOOST_ASIO_MOVE_CAST(Initiation)(initiation)( \
BOOST_ASIO_MOVE_CAST(BOOST_ASIO_HANDLER_TYPE(CompletionToken, \
Signature))(completion.completion_handler), \
BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
\
return completion.result.get(); \
} \
/**/
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
#include <boost/asio/detail/pop_options.hpp>
#endif // BOOST_ASIO_ASYNC_RESULT_HPP #endif // BOOST_ASIO_ASYNC_RESULT_HPP

125
boost/asio/awaitable.hpp Normal file
View File

@ -0,0 +1,125 @@
//
// awaitable.hpp
// ~~~~~~~~~~~~~
//
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASIO_AWAITABLE_HPP
#define BOOST_ASIO_AWAITABLE_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
#if defined(BOOST_ASIO_HAS_CO_AWAIT) || defined(GENERATING_DOCUMENTATION)
#include <experimental/coroutine>
#include <boost/asio/executor.hpp>
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
namespace detail {
using std::experimental::coroutine_handle;
using std::experimental::suspend_always;
template <typename> class awaitable_thread;
template <typename, typename> class awaitable_frame;
} // namespace detail
/// The return type of a coroutine or asynchronous operation.
template <typename T, typename Executor = executor>
class awaitable
{
public:
/// The type of the awaited value.
typedef T value_type;
/// The executor type that will be used for the coroutine.
typedef Executor executor_type;
/// Default constructor.
constexpr awaitable() noexcept
: frame_(nullptr)
{
}
/// Move constructor.
awaitable(awaitable&& other) noexcept
: frame_(std::exchange(other.frame_, nullptr))
{
}
/// Destructor
~awaitable()
{
if (frame_)
frame_->destroy();
}
/// Checks if the awaitable refers to a future result.
bool valid() const noexcept
{
return !!frame_;
}
#if !defined(GENERATING_DOCUMENTATION)
// Support for co_await keyword.
bool await_ready() const noexcept
{
return false;
}
// Support for co_await keyword.
template <class U>
void await_suspend(
detail::coroutine_handle<detail::awaitable_frame<U, Executor>> h)
{
frame_->push_frame(&h.promise());
}
// Support for co_await keyword.
T await_resume()
{
return frame_->get();
}
#endif // !defined(GENERATING_DOCUMENTATION)
private:
template <typename> friend class detail::awaitable_thread;
template <typename, typename> friend class detail::awaitable_frame;
// Not copy constructible or copy assignable.
awaitable(const awaitable&) = delete;
awaitable& operator=(const awaitable&) = delete;
// Construct the awaitable from a coroutine's frame object.
explicit awaitable(detail::awaitable_frame<T, Executor>* a)
: frame_(a)
{
}
detail::awaitable_frame<T, Executor>* frame_;
};
} // namespace asio
} // namespace boost
#include <boost/asio/detail/pop_options.hpp>
#include <boost/asio/impl/awaitable.hpp>
#endif // defined(BOOST_ASIO_HAS_CO_AWAIT) || defined(GENERATING_DOCUMENTATION)
#endif // BOOST_ASIO_AWAITABLE_HPP

View File

@ -2,7 +2,7 @@
// basic_datagram_socket.hpp // basic_datagram_socket.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -19,19 +19,25 @@
#include <cstddef> #include <cstddef>
#include <boost/asio/basic_socket.hpp> #include <boost/asio/basic_socket.hpp>
#include <boost/asio/detail/handler_type_requirements.hpp> #include <boost/asio/detail/handler_type_requirements.hpp>
#include <boost/asio/detail/non_const_lvalue.hpp>
#include <boost/asio/detail/throw_error.hpp> #include <boost/asio/detail/throw_error.hpp>
#include <boost/asio/detail/type_traits.hpp> #include <boost/asio/detail/type_traits.hpp>
#include <boost/asio/error.hpp> #include <boost/asio/error.hpp>
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
# include <boost/asio/datagram_socket_service.hpp>
#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
#include <boost/asio/detail/push_options.hpp> #include <boost/asio/detail/push_options.hpp>
namespace boost { namespace boost {
namespace asio { namespace asio {
#if !defined(BOOST_ASIO_BASIC_DATAGRAM_SOCKET_FWD_DECL)
#define BOOST_ASIO_BASIC_DATAGRAM_SOCKET_FWD_DECL
// Forward declaration with defaulted arguments.
template <typename Protocol, typename Executor = executor>
class basic_datagram_socket;
#endif // !defined(BOOST_ASIO_BASIC_DATAGRAM_SOCKET_FWD_DECL)
/// Provides datagram-oriented socket functionality. /// Provides datagram-oriented socket functionality.
/** /**
* The basic_datagram_socket class template provides asynchronous and blocking * The basic_datagram_socket class template provides asynchronous and blocking
@ -41,18 +47,28 @@ namespace asio {
* @e Distinct @e objects: Safe.@n * @e Distinct @e objects: Safe.@n
* @e Shared @e objects: Unsafe. * @e Shared @e objects: Unsafe.
*/ */
template <typename Protocol template <typename Protocol, typename Executor>
BOOST_ASIO_SVC_TPARAM_DEF1(= datagram_socket_service<Protocol>)>
class basic_datagram_socket class basic_datagram_socket
: public basic_socket<Protocol BOOST_ASIO_SVC_TARG> : public basic_socket<Protocol, Executor>
{ {
public: public:
/// The type of the executor associated with the object.
typedef Executor executor_type;
/// Rebinds the socket type to another executor.
template <typename Executor1>
struct rebind_executor
{
/// The socket type when rebound to the specified executor.
typedef basic_datagram_socket<Protocol, Executor1> other;
};
/// The native representation of a socket. /// The native representation of a socket.
#if defined(GENERATING_DOCUMENTATION) #if defined(GENERATING_DOCUMENTATION)
typedef implementation_defined native_handle_type; typedef implementation_defined native_handle_type;
#else #else
typedef typename basic_socket< typedef typename basic_socket<Protocol,
Protocol BOOST_ASIO_SVC_TARG>::native_handle_type native_handle_type; Executor>::native_handle_type native_handle_type;
#endif #endif
/// The protocol type. /// The protocol type.
@ -66,12 +82,29 @@ public:
* This constructor creates a datagram socket without opening it. The open() * This constructor creates a datagram socket without opening it. The open()
* function must be called before data can be sent or received on the socket. * function must be called before data can be sent or received on the socket.
* *
* @param io_context The io_context object that the datagram socket will use * @param ex The I/O executor that the socket will use, by default, to
* to dispatch handlers for any asynchronous operations performed on the * dispatch handlers for any asynchronous operations performed on the socket.
* socket.
*/ */
explicit basic_datagram_socket(boost::asio::io_context& io_context) explicit basic_datagram_socket(const executor_type& ex)
: basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context) : basic_socket<Protocol, Executor>(ex)
{
}
/// Construct a basic_datagram_socket without opening it.
/**
* This constructor creates a datagram socket without opening it. The open()
* function must be called before data can be sent or received on the socket.
*
* @param context An execution context which provides the I/O executor that
* the socket will use, by default, to dispatch handlers for any asynchronous
* operations performed on the socket.
*/
template <typename ExecutionContext>
explicit basic_datagram_socket(ExecutionContext& context,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: basic_socket<Protocol, Executor>(context)
{ {
} }
@ -79,17 +112,37 @@ public:
/** /**
* This constructor creates and opens a datagram socket. * This constructor creates and opens a datagram socket.
* *
* @param io_context The io_context object that the datagram socket will use * @param ex The I/O executor that the socket will use, by default, to
* to dispatch handlers for any asynchronous operations performed on the * dispatch handlers for any asynchronous operations performed on the socket.
* socket.
* *
* @param protocol An object specifying protocol parameters to be used. * @param protocol An object specifying protocol parameters to be used.
* *
* @throws boost::system::system_error Thrown on failure. * @throws boost::system::system_error Thrown on failure.
*/ */
basic_datagram_socket(boost::asio::io_context& io_context, basic_datagram_socket(const executor_type& ex, const protocol_type& protocol)
const protocol_type& protocol) : basic_socket<Protocol, Executor>(ex, protocol)
: basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context, protocol) {
}
/// Construct and open a basic_datagram_socket.
/**
* This constructor creates and opens a datagram socket.
*
* @param context An execution context which provides the I/O executor that
* the socket will use, by default, to dispatch handlers for any asynchronous
* operations performed on the socket.
*
* @param protocol An object specifying protocol parameters to be used.
*
* @throws boost::system::system_error Thrown on failure.
*/
template <typename ExecutionContext>
basic_datagram_socket(ExecutionContext& context,
const protocol_type& protocol,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: basic_socket<Protocol, Executor>(context, protocol)
{ {
} }
@ -100,18 +153,42 @@ public:
* to the specified endpoint on the local machine. The protocol used is the * to the specified endpoint on the local machine. The protocol used is the
* protocol associated with the given endpoint. * protocol associated with the given endpoint.
* *
* @param io_context The io_context object that the datagram socket will use * @param ex The I/O executor that the socket will use, by default, to
* to dispatch handlers for any asynchronous operations performed on the * dispatch handlers for any asynchronous operations performed on the socket.
* socket.
* *
* @param endpoint An endpoint on the local machine to which the datagram * @param endpoint An endpoint on the local machine to which the datagram
* socket will be bound. * socket will be bound.
* *
* @throws boost::system::system_error Thrown on failure. * @throws boost::system::system_error Thrown on failure.
*/ */
basic_datagram_socket(boost::asio::io_context& io_context, basic_datagram_socket(const executor_type& ex, const endpoint_type& endpoint)
const endpoint_type& endpoint) : basic_socket<Protocol, Executor>(ex, endpoint)
: basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context, endpoint) {
}
/// Construct a basic_datagram_socket, opening it and binding it to the given
/// local endpoint.
/**
* This constructor creates a datagram socket and automatically opens it bound
* to the specified endpoint on the local machine. The protocol used is the
* protocol associated with the given endpoint.
*
* @param context An execution context which provides the I/O executor that
* the socket will use, by default, to dispatch handlers for any asynchronous
* operations performed on the socket.
*
* @param endpoint An endpoint on the local machine to which the datagram
* socket will be bound.
*
* @throws boost::system::system_error Thrown on failure.
*/
template <typename ExecutionContext>
basic_datagram_socket(ExecutionContext& context,
const endpoint_type& endpoint,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: basic_socket<Protocol, Executor>(context, endpoint)
{ {
} }
@ -120,9 +197,8 @@ public:
* This constructor creates a datagram socket object to hold an existing * This constructor creates a datagram socket object to hold an existing
* native socket. * native socket.
* *
* @param io_context The io_context object that the datagram socket will use * @param ex The I/O executor that the socket will use, by default, to
* to dispatch handlers for any asynchronous operations performed on the * dispatch handlers for any asynchronous operations performed on the socket.
* socket.
* *
* @param protocol An object specifying protocol parameters to be used. * @param protocol An object specifying protocol parameters to be used.
* *
@ -130,10 +206,34 @@ public:
* *
* @throws boost::system::system_error Thrown on failure. * @throws boost::system::system_error Thrown on failure.
*/ */
basic_datagram_socket(boost::asio::io_context& io_context, basic_datagram_socket(const executor_type& ex,
const protocol_type& protocol, const native_handle_type& native_socket) const protocol_type& protocol, const native_handle_type& native_socket)
: basic_socket<Protocol BOOST_ASIO_SVC_TARG>( : basic_socket<Protocol, Executor>(ex, protocol, native_socket)
io_context, protocol, native_socket) {
}
/// Construct a basic_datagram_socket on an existing native socket.
/**
* This constructor creates a datagram socket object to hold an existing
* native socket.
*
* @param context An execution context which provides the I/O executor that
* the socket will use, by default, to dispatch handlers for any asynchronous
* operations performed on the socket.
*
* @param protocol An object specifying protocol parameters to be used.
*
* @param native_socket The new underlying socket implementation.
*
* @throws boost::system::system_error Thrown on failure.
*/
template <typename ExecutionContext>
basic_datagram_socket(ExecutionContext& context,
const protocol_type& protocol, const native_handle_type& native_socket,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: basic_socket<Protocol, Executor>(context, protocol, native_socket)
{ {
} }
@ -146,10 +246,11 @@ public:
* will occur. * will occur.
* *
* @note Following the move, the moved-from object is in the same state as if * @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_datagram_socket(io_context&) constructor. * constructed using the @c basic_datagram_socket(const executor_type&)
* constructor.
*/ */
basic_datagram_socket(basic_datagram_socket&& other) basic_datagram_socket(basic_datagram_socket&& other)
: basic_socket<Protocol BOOST_ASIO_SVC_TARG>(std::move(other)) : basic_socket<Protocol, Executor>(std::move(other))
{ {
} }
@ -162,11 +263,12 @@ public:
* will occur. * will occur.
* *
* @note Following the move, the moved-from object is in the same state as if * @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_datagram_socket(io_context&) constructor. * constructed using the @c basic_datagram_socket(const executor_type&)
* constructor.
*/ */
basic_datagram_socket& operator=(basic_datagram_socket&& other) basic_datagram_socket& operator=(basic_datagram_socket&& other)
{ {
basic_socket<Protocol BOOST_ASIO_SVC_TARG>::operator=(std::move(other)); basic_socket<Protocol, Executor>::operator=(std::move(other));
return *this; return *this;
} }
@ -179,13 +281,16 @@ public:
* will occur. * will occur.
* *
* @note Following the move, the moved-from object is in the same state as if * @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_datagram_socket(io_context&) constructor. * constructed using the @c basic_datagram_socket(const executor_type&)
* constructor.
*/ */
template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1> template <typename Protocol1, typename Executor1>
basic_datagram_socket( basic_datagram_socket(basic_datagram_socket<Protocol1, Executor1>&& other,
basic_datagram_socket<Protocol1 BOOST_ASIO_SVC_TARG1>&& other, typename enable_if<
typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0) is_convertible<Protocol1, Protocol>::value
: basic_socket<Protocol BOOST_ASIO_SVC_TARG>(std::move(other)) && is_convertible<Executor1, Executor>::value
>::type* = 0)
: basic_socket<Protocol, Executor>(std::move(other))
{ {
} }
@ -199,14 +304,17 @@ public:
* will occur. * will occur.
* *
* @note Following the move, the moved-from object is in the same state as if * @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_datagram_socket(io_context&) constructor. * constructed using the @c basic_datagram_socket(const executor_type&)
* constructor.
*/ */
template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1> template <typename Protocol1, typename Executor1>
typename enable_if<is_convertible<Protocol1, Protocol>::value, typename enable_if<
basic_datagram_socket>::type& operator=( is_convertible<Protocol1, Protocol>::value
basic_datagram_socket<Protocol1 BOOST_ASIO_SVC_TARG1>&& other) && is_convertible<Executor1, Executor>::value,
basic_datagram_socket&
>::type operator=(basic_datagram_socket<Protocol1, Executor1>&& other)
{ {
basic_socket<Protocol BOOST_ASIO_SVC_TARG>::operator=(std::move(other)); basic_socket<Protocol, Executor>::operator=(std::move(other));
return *this; return *this;
} }
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
@ -246,8 +354,8 @@ public:
std::size_t send(const ConstBufferSequence& buffers) std::size_t send(const ConstBufferSequence& buffers)
{ {
boost::system::error_code ec; boost::system::error_code ec;
std::size_t s = this->get_service().send( std::size_t s = this->impl_.get_service().send(
this->get_implementation(), buffers, 0, ec); this->impl_.get_implementation(), buffers, 0, ec);
boost::asio::detail::throw_error(ec, "send"); boost::asio::detail::throw_error(ec, "send");
return s; return s;
} }
@ -274,8 +382,8 @@ public:
socket_base::message_flags flags) socket_base::message_flags flags)
{ {
boost::system::error_code ec; boost::system::error_code ec;
std::size_t s = this->get_service().send( std::size_t s = this->impl_.get_service().send(
this->get_implementation(), buffers, flags, ec); this->impl_.get_implementation(), buffers, flags, ec);
boost::asio::detail::throw_error(ec, "send"); boost::asio::detail::throw_error(ec, "send");
return s; return s;
} }
@ -301,8 +409,8 @@ public:
std::size_t send(const ConstBufferSequence& buffers, std::size_t send(const ConstBufferSequence& buffers,
socket_base::message_flags flags, boost::system::error_code& ec) socket_base::message_flags flags, boost::system::error_code& ec)
{ {
return this->get_service().send( return this->impl_.get_service().send(
this->get_implementation(), buffers, flags, ec); this->impl_.get_implementation(), buffers, flags, ec);
} }
/// Start an asynchronous send on a connected socket. /// Start an asynchronous send on a connected socket.
@ -323,9 +431,9 @@ public:
* std::size_t bytes_transferred // Number of bytes sent. * std::size_t bytes_transferred // Number of bytes sent.
* ); @endcode * ); @endcode
* Regardless of whether the asynchronous operation completes immediately or * Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation * not, the handler will not be invoked from within this function. On
* of the handler will be performed in a manner equivalent to using * immediate completion, invocation of the handler will be performed in a
* boost::asio::io_context::post(). * manner equivalent to using boost::asio::post().
* *
* @note The async_send operation can only be used with a connected socket. * @note The async_send operation can only be used with a connected socket.
* Use the async_send_to function to send data on an unconnected datagram * Use the async_send_to function to send data on an unconnected datagram
@ -346,22 +454,10 @@ public:
async_send(const ConstBufferSequence& buffers, async_send(const ConstBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler) BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{ {
// If you get an error on the following line it means that your handler does return async_initiate<WriteHandler,
// not meet the documented type requirements for a WriteHandler. void (boost::system::error_code, std::size_t)>(
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; initiate_async_send(), handler, this,
buffers, socket_base::message_flags(0));
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_send(this->get_implementation(),
buffers, 0, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
async_completion<WriteHandler,
void (boost::system::error_code, std::size_t)> init(handler);
this->get_service().async_send(this->get_implementation(),
buffers, 0, init.completion_handler);
return init.result.get();
#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
} }
/// Start an asynchronous send on a connected socket. /// Start an asynchronous send on a connected socket.
@ -384,9 +480,9 @@ public:
* std::size_t bytes_transferred // Number of bytes sent. * std::size_t bytes_transferred // Number of bytes sent.
* ); @endcode * ); @endcode
* Regardless of whether the asynchronous operation completes immediately or * Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation * not, the handler will not be invoked from within this function. On
* of the handler will be performed in a manner equivalent to using * immediate completion, invocation of the handler will be performed in a
* boost::asio::io_context::post(). * manner equivalent to using boost::asio::post().
* *
* @note The async_send operation can only be used with a connected socket. * @note The async_send operation can only be used with a connected socket.
* Use the async_send_to function to send data on an unconnected datagram * Use the async_send_to function to send data on an unconnected datagram
@ -399,22 +495,9 @@ public:
socket_base::message_flags flags, socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler) BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{ {
// If you get an error on the following line it means that your handler does return async_initiate<WriteHandler,
// not meet the documented type requirements for a WriteHandler. void (boost::system::error_code, std::size_t)>(
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; initiate_async_send(), handler, this, buffers, flags);
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_send(this->get_implementation(),
buffers, flags, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
async_completion<WriteHandler,
void (boost::system::error_code, std::size_t)> init(handler);
this->get_service().async_send(this->get_implementation(),
buffers, flags, init.completion_handler);
return init.result.get();
#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
} }
/// Send a datagram to the specified endpoint. /// Send a datagram to the specified endpoint.
@ -447,8 +530,8 @@ public:
const endpoint_type& destination) const endpoint_type& destination)
{ {
boost::system::error_code ec; boost::system::error_code ec;
std::size_t s = this->get_service().send_to( std::size_t s = this->impl_.get_service().send_to(
this->get_implementation(), buffers, destination, 0, ec); this->impl_.get_implementation(), buffers, destination, 0, ec);
boost::asio::detail::throw_error(ec, "send_to"); boost::asio::detail::throw_error(ec, "send_to");
return s; return s;
} }
@ -474,8 +557,8 @@ public:
const endpoint_type& destination, socket_base::message_flags flags) const endpoint_type& destination, socket_base::message_flags flags)
{ {
boost::system::error_code ec; boost::system::error_code ec;
std::size_t s = this->get_service().send_to( std::size_t s = this->impl_.get_service().send_to(
this->get_implementation(), buffers, destination, flags, ec); this->impl_.get_implementation(), buffers, destination, flags, ec);
boost::asio::detail::throw_error(ec, "send_to"); boost::asio::detail::throw_error(ec, "send_to");
return s; return s;
} }
@ -501,7 +584,7 @@ public:
const endpoint_type& destination, socket_base::message_flags flags, const endpoint_type& destination, socket_base::message_flags flags,
boost::system::error_code& ec) boost::system::error_code& ec)
{ {
return this->get_service().send_to(this->get_implementation(), return this->impl_.get_service().send_to(this->impl_.get_implementation(),
buffers, destination, flags, ec); buffers, destination, flags, ec);
} }
@ -526,9 +609,9 @@ public:
* std::size_t bytes_transferred // Number of bytes sent. * std::size_t bytes_transferred // Number of bytes sent.
* ); @endcode * ); @endcode
* Regardless of whether the asynchronous operation completes immediately or * Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation * not, the handler will not be invoked from within this function. On
* of the handler will be performed in a manner equivalent to using * immediate completion, invocation of the handler will be performed in a
* boost::asio::io_context::post(). * manner equivalent to using boost::asio::post().
* *
* @par Example * @par Example
* To send a single data buffer use the @ref buffer function as follows: * To send a single data buffer use the @ref buffer function as follows:
@ -549,24 +632,10 @@ public:
const endpoint_type& destination, const endpoint_type& destination,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler) BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{ {
// If you get an error on the following line it means that your handler does return async_initiate<WriteHandler,
// not meet the documented type requirements for a WriteHandler. void (boost::system::error_code, std::size_t)>(
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; initiate_async_send_to(), handler, this, buffers,
destination, socket_base::message_flags(0));
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_send_to(
this->get_implementation(), buffers, destination, 0,
BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
async_completion<WriteHandler,
void (boost::system::error_code, std::size_t)> init(handler);
this->get_service().async_send_to(
this->get_implementation(), buffers, destination, 0,
init.completion_handler);
return init.result.get();
#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
} }
/// Start an asynchronous send. /// Start an asynchronous send.
@ -592,9 +661,9 @@ public:
* std::size_t bytes_transferred // Number of bytes sent. * std::size_t bytes_transferred // Number of bytes sent.
* ); @endcode * ); @endcode
* Regardless of whether the asynchronous operation completes immediately or * Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation * not, the handler will not be invoked from within this function. On
* of the handler will be performed in a manner equivalent to using * immediate completion, invocation of the handler will be performed in a
* boost::asio::io_context::post(). * manner equivalent to using boost::asio::post().
*/ */
template <typename ConstBufferSequence, typename WriteHandler> template <typename ConstBufferSequence, typename WriteHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
@ -603,24 +672,9 @@ public:
const endpoint_type& destination, socket_base::message_flags flags, const endpoint_type& destination, socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler) BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{ {
// If you get an error on the following line it means that your handler does return async_initiate<WriteHandler,
// not meet the documented type requirements for a WriteHandler. void (boost::system::error_code, std::size_t)>(
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; initiate_async_send_to(), handler, this, buffers, destination, flags);
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_send_to(
this->get_implementation(), buffers, destination, flags,
BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
async_completion<WriteHandler,
void (boost::system::error_code, std::size_t)> init(handler);
this->get_service().async_send_to(
this->get_implementation(), buffers, destination, flags,
init.completion_handler);
return init.result.get();
#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
} }
/// Receive some data on a connected socket. /// Receive some data on a connected socket.
@ -651,8 +705,8 @@ public:
std::size_t receive(const MutableBufferSequence& buffers) std::size_t receive(const MutableBufferSequence& buffers)
{ {
boost::system::error_code ec; boost::system::error_code ec;
std::size_t s = this->get_service().receive( std::size_t s = this->impl_.get_service().receive(
this->get_implementation(), buffers, 0, ec); this->impl_.get_implementation(), buffers, 0, ec);
boost::asio::detail::throw_error(ec, "receive"); boost::asio::detail::throw_error(ec, "receive");
return s; return s;
} }
@ -680,8 +734,8 @@ public:
socket_base::message_flags flags) socket_base::message_flags flags)
{ {
boost::system::error_code ec; boost::system::error_code ec;
std::size_t s = this->get_service().receive( std::size_t s = this->impl_.get_service().receive(
this->get_implementation(), buffers, flags, ec); this->impl_.get_implementation(), buffers, flags, ec);
boost::asio::detail::throw_error(ec, "receive"); boost::asio::detail::throw_error(ec, "receive");
return s; return s;
} }
@ -708,8 +762,8 @@ public:
std::size_t receive(const MutableBufferSequence& buffers, std::size_t receive(const MutableBufferSequence& buffers,
socket_base::message_flags flags, boost::system::error_code& ec) socket_base::message_flags flags, boost::system::error_code& ec)
{ {
return this->get_service().receive( return this->impl_.get_service().receive(
this->get_implementation(), buffers, flags, ec); this->impl_.get_implementation(), buffers, flags, ec);
} }
/// Start an asynchronous receive on a connected socket. /// Start an asynchronous receive on a connected socket.
@ -730,9 +784,9 @@ public:
* std::size_t bytes_transferred // Number of bytes received. * std::size_t bytes_transferred // Number of bytes received.
* ); @endcode * ); @endcode
* Regardless of whether the asynchronous operation completes immediately or * Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation * not, the handler will not be invoked from within this function. On
* of the handler will be performed in a manner equivalent to using * immediate completion, invocation of the handler will be performed in a
* boost::asio::io_context::post(). * manner equivalent to using boost::asio::post().
* *
* @note The async_receive operation can only be used with a connected socket. * @note The async_receive operation can only be used with a connected socket.
* Use the async_receive_from function to receive data on an unconnected * Use the async_receive_from function to receive data on an unconnected
@ -754,22 +808,10 @@ public:
async_receive(const MutableBufferSequence& buffers, async_receive(const MutableBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler) BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{ {
// If you get an error on the following line it means that your handler does return async_initiate<ReadHandler,
// not meet the documented type requirements for a ReadHandler. void (boost::system::error_code, std::size_t)>(
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; initiate_async_receive(), handler, this,
buffers, socket_base::message_flags(0));
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_receive(this->get_implementation(),
buffers, 0, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
async_completion<ReadHandler,
void (boost::system::error_code, std::size_t)> init(handler);
this->get_service().async_receive(this->get_implementation(),
buffers, 0, init.completion_handler);
return init.result.get();
#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
} }
/// Start an asynchronous receive on a connected socket. /// Start an asynchronous receive on a connected socket.
@ -792,9 +834,9 @@ public:
* std::size_t bytes_transferred // Number of bytes received. * std::size_t bytes_transferred // Number of bytes received.
* ); @endcode * ); @endcode
* Regardless of whether the asynchronous operation completes immediately or * Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation * not, the handler will not be invoked from within this function. On
* of the handler will be performed in a manner equivalent to using * immediate completion, invocation of the handler will be performed in a
* boost::asio::io_context::post(). * manner equivalent to using boost::asio::post().
* *
* @note The async_receive operation can only be used with a connected socket. * @note The async_receive operation can only be used with a connected socket.
* Use the async_receive_from function to receive data on an unconnected * Use the async_receive_from function to receive data on an unconnected
@ -807,22 +849,9 @@ public:
socket_base::message_flags flags, socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler) BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{ {
// If you get an error on the following line it means that your handler does return async_initiate<ReadHandler,
// not meet the documented type requirements for a ReadHandler. void (boost::system::error_code, std::size_t)>(
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; initiate_async_receive(), handler, this, buffers, flags);
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_receive(this->get_implementation(),
buffers, flags, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
async_completion<ReadHandler,
void (boost::system::error_code, std::size_t)> init(handler);
this->get_service().async_receive(this->get_implementation(),
buffers, flags, init.completion_handler);
return init.result.get();
#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
} }
/// Receive a datagram with the endpoint of the sender. /// Receive a datagram with the endpoint of the sender.
@ -856,8 +885,8 @@ public:
endpoint_type& sender_endpoint) endpoint_type& sender_endpoint)
{ {
boost::system::error_code ec; boost::system::error_code ec;
std::size_t s = this->get_service().receive_from( std::size_t s = this->impl_.get_service().receive_from(
this->get_implementation(), buffers, sender_endpoint, 0, ec); this->impl_.get_implementation(), buffers, sender_endpoint, 0, ec);
boost::asio::detail::throw_error(ec, "receive_from"); boost::asio::detail::throw_error(ec, "receive_from");
return s; return s;
} }
@ -883,8 +912,8 @@ public:
endpoint_type& sender_endpoint, socket_base::message_flags flags) endpoint_type& sender_endpoint, socket_base::message_flags flags)
{ {
boost::system::error_code ec; boost::system::error_code ec;
std::size_t s = this->get_service().receive_from( std::size_t s = this->impl_.get_service().receive_from(
this->get_implementation(), buffers, sender_endpoint, flags, ec); this->impl_.get_implementation(), buffers, sender_endpoint, flags, ec);
boost::asio::detail::throw_error(ec, "receive_from"); boost::asio::detail::throw_error(ec, "receive_from");
return s; return s;
} }
@ -910,8 +939,8 @@ public:
endpoint_type& sender_endpoint, socket_base::message_flags flags, endpoint_type& sender_endpoint, socket_base::message_flags flags,
boost::system::error_code& ec) boost::system::error_code& ec)
{ {
return this->get_service().receive_from(this->get_implementation(), return this->impl_.get_service().receive_from(
buffers, sender_endpoint, flags, ec); this->impl_.get_implementation(), buffers, sender_endpoint, flags, ec);
} }
/// Start an asynchronous receive. /// Start an asynchronous receive.
@ -937,9 +966,9 @@ public:
* std::size_t bytes_transferred // Number of bytes received. * std::size_t bytes_transferred // Number of bytes received.
* ); @endcode * ); @endcode
* Regardless of whether the asynchronous operation completes immediately or * Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation * not, the handler will not be invoked from within this function. On
* of the handler will be performed in a manner equivalent to using * immediate completion, invocation of the handler will be performed in a
* boost::asio::io_context::post(). * manner equivalent to using boost::asio::post().
* *
* @par Example * @par Example
* To receive into a single data buffer use the @ref buffer function as * To receive into a single data buffer use the @ref buffer function as
@ -957,24 +986,10 @@ public:
endpoint_type& sender_endpoint, endpoint_type& sender_endpoint,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler) BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{ {
// If you get an error on the following line it means that your handler does return async_initiate<ReadHandler,
// not meet the documented type requirements for a ReadHandler. void (boost::system::error_code, std::size_t)>(
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; initiate_async_receive_from(), handler, this, buffers,
&sender_endpoint, socket_base::message_flags(0));
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_receive_from(
this->get_implementation(), buffers, sender_endpoint, 0,
BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
async_completion<ReadHandler,
void (boost::system::error_code, std::size_t)> init(handler);
this->get_service().async_receive_from(
this->get_implementation(), buffers, sender_endpoint, 0,
init.completion_handler);
return init.result.get();
#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
} }
/// Start an asynchronous receive. /// Start an asynchronous receive.
@ -1002,9 +1017,9 @@ public:
* std::size_t bytes_transferred // Number of bytes received. * std::size_t bytes_transferred // Number of bytes received.
* ); @endcode * ); @endcode
* Regardless of whether the asynchronous operation completes immediately or * Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation * not, the handler will not be invoked from within this function. On
* of the handler will be performed in a manner equivalent to using * immediate completion, invocation of the handler will be performed in a
* boost::asio::io_context::post(). * manner equivalent to using boost::asio::post().
*/ */
template <typename MutableBufferSequence, typename ReadHandler> template <typename MutableBufferSequence, typename ReadHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
@ -1013,25 +1028,85 @@ public:
endpoint_type& sender_endpoint, socket_base::message_flags flags, endpoint_type& sender_endpoint, socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler) BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{ {
// If you get an error on the following line it means that your handler does return async_initiate<ReadHandler,
// not meet the documented type requirements for a ReadHandler. void (boost::system::error_code, std::size_t)>(
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; initiate_async_receive_from(), handler,
this, buffers, &sender_endpoint, flags);
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_receive_from(
this->get_implementation(), buffers, sender_endpoint, flags,
BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
async_completion<ReadHandler,
void (boost::system::error_code, std::size_t)> init(handler);
this->get_service().async_receive_from(
this->get_implementation(), buffers, sender_endpoint, flags,
init.completion_handler);
return init.result.get();
#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
} }
private:
struct initiate_async_send
{
template <typename WriteHandler, typename ConstBufferSequence>
void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
basic_datagram_socket* self, const ConstBufferSequence& buffers,
socket_base::message_flags flags) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a WriteHandler.
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
detail::non_const_lvalue<WriteHandler> handler2(handler);
self->impl_.get_service().async_send(
self->impl_.get_implementation(), buffers, flags,
handler2.value, self->impl_.get_implementation_executor());
}
};
struct initiate_async_send_to
{
template <typename WriteHandler, typename ConstBufferSequence>
void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
basic_datagram_socket* self, const ConstBufferSequence& buffers,
const endpoint_type& destination,
socket_base::message_flags flags) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a WriteHandler.
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
detail::non_const_lvalue<WriteHandler> handler2(handler);
self->impl_.get_service().async_send_to(
self->impl_.get_implementation(), buffers, destination, flags,
handler2.value, self->impl_.get_implementation_executor());
}
};
struct initiate_async_receive
{
template <typename ReadHandler, typename MutableBufferSequence>
void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
basic_datagram_socket* self, const MutableBufferSequence& buffers,
socket_base::message_flags flags) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a ReadHandler.
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
detail::non_const_lvalue<ReadHandler> handler2(handler);
self->impl_.get_service().async_receive(
self->impl_.get_implementation(), buffers, flags,
handler2.value, self->impl_.get_implementation_executor());
}
};
struct initiate_async_receive_from
{
template <typename ReadHandler, typename MutableBufferSequence>
void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
basic_datagram_socket* self, const MutableBufferSequence& buffers,
endpoint_type* sender_endpoint, socket_base::message_flags flags) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a ReadHandler.
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
detail::non_const_lvalue<ReadHandler> handler2(handler);
self->impl_.get_service().async_receive_from(
self->impl_.get_implementation(), buffers, *sender_endpoint, flags,
handler2.value, self->impl_.get_implementation_executor());
}
};
}; };
} // namespace asio } // namespace asio

View File

@ -2,7 +2,7 @@
// basic_deadline_timer.hpp // basic_deadline_timer.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -21,19 +21,16 @@
|| defined(GENERATING_DOCUMENTATION) || defined(GENERATING_DOCUMENTATION)
#include <cstddef> #include <cstddef>
#include <boost/asio/basic_io_object.hpp> #include <boost/asio/detail/deadline_timer_service.hpp>
#include <boost/asio/detail/handler_type_requirements.hpp> #include <boost/asio/detail/handler_type_requirements.hpp>
#include <boost/asio/detail/io_object_impl.hpp>
#include <boost/asio/detail/non_const_lvalue.hpp>
#include <boost/asio/detail/throw_error.hpp> #include <boost/asio/detail/throw_error.hpp>
#include <boost/asio/error.hpp> #include <boost/asio/error.hpp>
#include <boost/asio/execution_context.hpp>
#include <boost/asio/executor.hpp>
#include <boost/asio/time_traits.hpp> #include <boost/asio/time_traits.hpp>
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
# include <boost/asio/deadline_timer_service.hpp>
#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
# include <boost/asio/detail/deadline_timer_service.hpp>
# define BOOST_ASIO_SVC_T detail::deadline_timer_service<TimeTraits>
#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
#include <boost/asio/detail/push_options.hpp> #include <boost/asio/detail/push_options.hpp>
namespace boost { namespace boost {
@ -58,7 +55,7 @@ namespace asio {
* Performing a blocking wait: * Performing a blocking wait:
* @code * @code
* // Construct a timer without setting an expiry time. * // Construct a timer without setting an expiry time.
* boost::asio::deadline_timer timer(io_context); * boost::asio::deadline_timer timer(my_context);
* *
* // Set an expiry time relative to now. * // Set an expiry time relative to now.
* timer.expires_from_now(boost::posix_time::seconds(5)); * timer.expires_from_now(boost::posix_time::seconds(5));
@ -81,7 +78,7 @@ namespace asio {
* ... * ...
* *
* // Construct a timer with an absolute expiry time. * // Construct a timer with an absolute expiry time.
* boost::asio::deadline_timer timer(io_context, * boost::asio::deadline_timer timer(my_context,
* boost::posix_time::time_from_string("2005-12-07 23:59:59.000")); * boost::posix_time::time_from_string("2005-12-07 23:59:59.000"));
* *
* // Start an asynchronous wait. * // Start an asynchronous wait.
@ -128,14 +125,13 @@ namespace asio {
* it contains the value boost::asio::error::operation_aborted. * it contains the value boost::asio::error::operation_aborted.
*/ */
template <typename Time, template <typename Time,
typename TimeTraits = boost::asio::time_traits<Time> typename TimeTraits = boost::asio::time_traits<Time>,
BOOST_ASIO_SVC_TPARAM_DEF2(= deadline_timer_service<Time, TimeTraits>)> typename Executor = executor>
class basic_deadline_timer class basic_deadline_timer
: BOOST_ASIO_SVC_ACCESS basic_io_object<BOOST_ASIO_SVC_T>
{ {
public: public:
/// The type of the executor associated with the object. /// The type of the executor associated with the object.
typedef io_context::executor_type executor_type; typedef Executor executor_type;
/// The time traits type. /// The time traits type.
typedef TimeTraits traits_type; typedef TimeTraits traits_type;
@ -152,11 +148,30 @@ public:
* expires_at() or expires_from_now() functions must be called to set an * expires_at() or expires_from_now() functions must be called to set an
* expiry time before the timer can be waited on. * expiry time before the timer can be waited on.
* *
* @param io_context The io_context object that the timer will use to dispatch * @param ex The I/O executor that the timer will use, by default, to
* handlers for any asynchronous operations performed on the timer. * dispatch handlers for any asynchronous operations performed on the timer.
*/ */
explicit basic_deadline_timer(boost::asio::io_context& io_context) explicit basic_deadline_timer(const executor_type& ex)
: basic_io_object<BOOST_ASIO_SVC_T>(io_context) : impl_(ex)
{
}
/// Constructor.
/**
* This constructor creates a timer without setting an expiry time. The
* expires_at() or expires_from_now() functions must be called to set an
* expiry time before the timer can be waited on.
*
* @param context An execution context which provides the I/O executor that
* the timer will use, by default, to dispatch handlers for any asynchronous
* operations performed on the timer.
*/
template <typename ExecutionContext>
explicit basic_deadline_timer(ExecutionContext& context,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: impl_(context)
{ {
} }
@ -164,18 +179,40 @@ public:
/** /**
* This constructor creates a timer and sets the expiry time. * This constructor creates a timer and sets the expiry time.
* *
* @param io_context The io_context object that the timer will use to dispatch * @param ex The I/O executor that the timer will use, by default, to
* handlers for any asynchronous operations performed on the timer. * dispatch handlers for any asynchronous operations performed on the timer.
* *
* @param expiry_time The expiry time to be used for the timer, expressed * @param expiry_time The expiry time to be used for the timer, expressed
* as an absolute time. * as an absolute time.
*/ */
basic_deadline_timer(boost::asio::io_context& io_context, basic_deadline_timer(const executor_type& ex, const time_type& expiry_time)
const time_type& expiry_time) : impl_(ex)
: basic_io_object<BOOST_ASIO_SVC_T>(io_context)
{ {
boost::system::error_code ec; boost::system::error_code ec;
this->get_service().expires_at(this->get_implementation(), expiry_time, ec); impl_.get_service().expires_at(impl_.get_implementation(), expiry_time, ec);
boost::asio::detail::throw_error(ec, "expires_at");
}
/// Constructor to set a particular expiry time as an absolute time.
/**
* This constructor creates a timer and sets the expiry time.
*
* @param context An execution context which provides the I/O executor that
* the timer will use, by default, to dispatch handlers for any asynchronous
* operations performed on the timer.
*
* @param expiry_time The expiry time to be used for the timer, expressed
* as an absolute time.
*/
template <typename ExecutionContext>
basic_deadline_timer(ExecutionContext& context, const time_type& expiry_time,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: impl_(context)
{
boost::system::error_code ec;
impl_.get_service().expires_at(impl_.get_implementation(), expiry_time, ec);
boost::asio::detail::throw_error(ec, "expires_at"); boost::asio::detail::throw_error(ec, "expires_at");
} }
@ -183,19 +220,44 @@ public:
/** /**
* This constructor creates a timer and sets the expiry time. * This constructor creates a timer and sets the expiry time.
* *
* @param io_context The io_context object that the timer will use to dispatch * @param ex The I/O executor that the timer will use, by default, to
* handlers for any asynchronous operations performed on the timer. * dispatch handlers for any asynchronous operations performed on the timer.
* *
* @param expiry_time The expiry time to be used for the timer, relative to * @param expiry_time The expiry time to be used for the timer, relative to
* now. * now.
*/ */
basic_deadline_timer(boost::asio::io_context& io_context, basic_deadline_timer(const executor_type& ex,
const duration_type& expiry_time) const duration_type& expiry_time)
: basic_io_object<BOOST_ASIO_SVC_T>(io_context) : impl_(ex)
{ {
boost::system::error_code ec; boost::system::error_code ec;
this->get_service().expires_from_now( impl_.get_service().expires_from_now(
this->get_implementation(), expiry_time, ec); impl_.get_implementation(), expiry_time, ec);
boost::asio::detail::throw_error(ec, "expires_from_now");
}
/// Constructor to set a particular expiry time relative to now.
/**
* This constructor creates a timer and sets the expiry time.
*
* @param context An execution context which provides the I/O executor that
* the timer will use, by default, to dispatch handlers for any asynchronous
* operations performed on the timer.
*
* @param expiry_time The expiry time to be used for the timer, relative to
* now.
*/
template <typename ExecutionContext>
basic_deadline_timer(ExecutionContext& context,
const duration_type& expiry_time,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: impl_(context)
{
boost::system::error_code ec;
impl_.get_service().expires_from_now(
impl_.get_implementation(), expiry_time, ec);
boost::asio::detail::throw_error(ec, "expires_from_now"); boost::asio::detail::throw_error(ec, "expires_from_now");
} }
@ -208,10 +270,11 @@ public:
* occur. * occur.
* *
* @note Following the move, the moved-from object is in the same state as if * @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_deadline_timer(io_context&) constructor. * constructed using the @c basic_deadline_timer(const executor_type&)
* constructor.
*/ */
basic_deadline_timer(basic_deadline_timer&& other) basic_deadline_timer(basic_deadline_timer&& other)
: basic_io_object<BOOST_ASIO_SVC_T>(std::move(other)) : impl_(std::move(other.impl_))
{ {
} }
@ -224,11 +287,12 @@ public:
* occur. * occur.
* *
* @note Following the move, the moved-from object is in the same state as if * @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_deadline_timer(io_context&) constructor. * constructed using the @c basic_deadline_timer(const executor_type&)
* constructor.
*/ */
basic_deadline_timer& operator=(basic_deadline_timer&& other) basic_deadline_timer& operator=(basic_deadline_timer&& other)
{ {
basic_io_object<BOOST_ASIO_SVC_T>::operator=(std::move(other)); impl_ = std::move(other.impl_);
return *this; return *this;
} }
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
@ -242,45 +306,11 @@ public:
{ {
} }
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
// These functions are provided by basic_io_object<>.
#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
#if !defined(BOOST_ASIO_NO_DEPRECATED)
/// (Deprecated: Use get_executor().) Get the io_context associated with the
/// object.
/**
* This function may be used to obtain the io_context object that the I/O
* object uses to dispatch handlers for asynchronous operations.
*
* @return A reference to the io_context object that the I/O object will use
* to dispatch handlers. Ownership is not transferred to the caller.
*/
boost::asio::io_context& get_io_context()
{
return basic_io_object<BOOST_ASIO_SVC_T>::get_io_context();
}
/// (Deprecated: Use get_executor().) Get the io_context associated with the
/// object.
/**
* This function may be used to obtain the io_context object that the I/O
* object uses to dispatch handlers for asynchronous operations.
*
* @return A reference to the io_context object that the I/O object will use
* to dispatch handlers. Ownership is not transferred to the caller.
*/
boost::asio::io_context& get_io_service()
{
return basic_io_object<BOOST_ASIO_SVC_T>::get_io_service();
}
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
/// Get the executor associated with the object. /// Get the executor associated with the object.
executor_type get_executor() BOOST_ASIO_NOEXCEPT executor_type get_executor() BOOST_ASIO_NOEXCEPT
{ {
return basic_io_object<BOOST_ASIO_SVC_T>::get_executor(); return impl_.get_executor();
} }
#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
/// Cancel any asynchronous operations that are waiting on the timer. /// Cancel any asynchronous operations that are waiting on the timer.
/** /**
@ -307,7 +337,7 @@ public:
std::size_t cancel() std::size_t cancel()
{ {
boost::system::error_code ec; boost::system::error_code ec;
std::size_t s = this->get_service().cancel(this->get_implementation(), ec); std::size_t s = impl_.get_service().cancel(impl_.get_implementation(), ec);
boost::asio::detail::throw_error(ec, "cancel"); boost::asio::detail::throw_error(ec, "cancel");
return s; return s;
} }
@ -336,7 +366,7 @@ public:
*/ */
std::size_t cancel(boost::system::error_code& ec) std::size_t cancel(boost::system::error_code& ec)
{ {
return this->get_service().cancel(this->get_implementation(), ec); return impl_.get_service().cancel(impl_.get_implementation(), ec);
} }
/// Cancels one asynchronous operation that is waiting on the timer. /// Cancels one asynchronous operation that is waiting on the timer.
@ -366,8 +396,8 @@ public:
std::size_t cancel_one() std::size_t cancel_one()
{ {
boost::system::error_code ec; boost::system::error_code ec;
std::size_t s = this->get_service().cancel_one( std::size_t s = impl_.get_service().cancel_one(
this->get_implementation(), ec); impl_.get_implementation(), ec);
boost::asio::detail::throw_error(ec, "cancel_one"); boost::asio::detail::throw_error(ec, "cancel_one");
return s; return s;
} }
@ -398,7 +428,7 @@ public:
*/ */
std::size_t cancel_one(boost::system::error_code& ec) std::size_t cancel_one(boost::system::error_code& ec)
{ {
return this->get_service().cancel_one(this->get_implementation(), ec); return impl_.get_service().cancel_one(impl_.get_implementation(), ec);
} }
/// Get the timer's expiry time as an absolute time. /// Get the timer's expiry time as an absolute time.
@ -408,7 +438,7 @@ public:
*/ */
time_type expires_at() const time_type expires_at() const
{ {
return this->get_service().expires_at(this->get_implementation()); return impl_.get_service().expires_at(impl_.get_implementation());
} }
/// Set the timer's expiry time as an absolute time. /// Set the timer's expiry time as an absolute time.
@ -436,8 +466,8 @@ public:
std::size_t expires_at(const time_type& expiry_time) std::size_t expires_at(const time_type& expiry_time)
{ {
boost::system::error_code ec; boost::system::error_code ec;
std::size_t s = this->get_service().expires_at( std::size_t s = impl_.get_service().expires_at(
this->get_implementation(), expiry_time, ec); impl_.get_implementation(), expiry_time, ec);
boost::asio::detail::throw_error(ec, "expires_at"); boost::asio::detail::throw_error(ec, "expires_at");
return s; return s;
} }
@ -467,8 +497,8 @@ public:
std::size_t expires_at(const time_type& expiry_time, std::size_t expires_at(const time_type& expiry_time,
boost::system::error_code& ec) boost::system::error_code& ec)
{ {
return this->get_service().expires_at( return impl_.get_service().expires_at(
this->get_implementation(), expiry_time, ec); impl_.get_implementation(), expiry_time, ec);
} }
/// Get the timer's expiry time relative to now. /// Get the timer's expiry time relative to now.
@ -478,7 +508,7 @@ public:
*/ */
duration_type expires_from_now() const duration_type expires_from_now() const
{ {
return this->get_service().expires_from_now(this->get_implementation()); return impl_.get_service().expires_from_now(impl_.get_implementation());
} }
/// Set the timer's expiry time relative to now. /// Set the timer's expiry time relative to now.
@ -506,8 +536,8 @@ public:
std::size_t expires_from_now(const duration_type& expiry_time) std::size_t expires_from_now(const duration_type& expiry_time)
{ {
boost::system::error_code ec; boost::system::error_code ec;
std::size_t s = this->get_service().expires_from_now( std::size_t s = impl_.get_service().expires_from_now(
this->get_implementation(), expiry_time, ec); impl_.get_implementation(), expiry_time, ec);
boost::asio::detail::throw_error(ec, "expires_from_now"); boost::asio::detail::throw_error(ec, "expires_from_now");
return s; return s;
} }
@ -537,8 +567,8 @@ public:
std::size_t expires_from_now(const duration_type& expiry_time, std::size_t expires_from_now(const duration_type& expiry_time,
boost::system::error_code& ec) boost::system::error_code& ec)
{ {
return this->get_service().expires_from_now( return impl_.get_service().expires_from_now(
this->get_implementation(), expiry_time, ec); impl_.get_implementation(), expiry_time, ec);
} }
/// Perform a blocking wait on the timer. /// Perform a blocking wait on the timer.
@ -551,7 +581,7 @@ public:
void wait() void wait()
{ {
boost::system::error_code ec; boost::system::error_code ec;
this->get_service().wait(this->get_implementation(), ec); impl_.get_service().wait(impl_.get_implementation(), ec);
boost::asio::detail::throw_error(ec, "wait"); boost::asio::detail::throw_error(ec, "wait");
} }
@ -564,7 +594,7 @@ public:
*/ */
void wait(boost::system::error_code& ec) void wait(boost::system::error_code& ec)
{ {
this->get_service().wait(this->get_implementation(), ec); impl_.get_service().wait(impl_.get_implementation(), ec);
} }
/// Start an asynchronous wait on the timer. /// Start an asynchronous wait on the timer.
@ -587,32 +617,44 @@ public:
* const boost::system::error_code& error // Result of operation. * const boost::system::error_code& error // Result of operation.
* ); @endcode * ); @endcode
* Regardless of whether the asynchronous operation completes immediately or * Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation * not, the handler will not be invoked from within this function. On
* of the handler will be performed in a manner equivalent to using * immediate completion, invocation of the handler will be performed in a
* boost::asio::io_context::post(). * manner equivalent to using boost::asio::post().
*/ */
template <typename WaitHandler> template <typename WaitHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler, BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler,
void (boost::system::error_code)) void (boost::system::error_code))
async_wait(BOOST_ASIO_MOVE_ARG(WaitHandler) handler) async_wait(BOOST_ASIO_MOVE_ARG(WaitHandler) handler)
{ {
// If you get an error on the following line it means that your handler does return async_initiate<WaitHandler, void (boost::system::error_code)>(
// not meet the documented type requirements for a WaitHandler. initiate_async_wait(), handler, this);
BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_wait(this->get_implementation(),
BOOST_ASIO_MOVE_CAST(WaitHandler)(handler));
#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
async_completion<WaitHandler,
void (boost::system::error_code)> init(handler);
this->get_service().async_wait(this->get_implementation(),
init.completion_handler);
return init.result.get();
#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
} }
private:
// Disallow copying and assignment.
basic_deadline_timer(const basic_deadline_timer&) BOOST_ASIO_DELETED;
basic_deadline_timer& operator=(
const basic_deadline_timer&) BOOST_ASIO_DELETED;
struct initiate_async_wait
{
template <typename WaitHandler>
void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler,
basic_deadline_timer* self) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a WaitHandler.
BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
detail::non_const_lvalue<WaitHandler> handler2(handler);
self->impl_.get_service().async_wait(
self->impl_.get_implementation(), handler2.value,
self->impl_.get_implementation_executor());
}
};
detail::io_object_impl<
detail::deadline_timer_service<TimeTraits>, Executor> impl_;
}; };
} // namespace asio } // namespace asio
@ -620,10 +662,6 @@ public:
#include <boost/asio/detail/pop_options.hpp> #include <boost/asio/detail/pop_options.hpp>
#if !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
# undef BOOST_ASIO_SVC_T
#endif // !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
#endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) #endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
// || defined(GENERATING_DOCUMENTATION) // || defined(GENERATING_DOCUMENTATION)

View File

@ -2,7 +2,7 @@
// basic_io_object.hpp // basic_io_object.hpp
// ~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// basic_raw_socket.hpp // basic_raw_socket.hpp
// ~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -19,19 +19,25 @@
#include <cstddef> #include <cstddef>
#include <boost/asio/basic_socket.hpp> #include <boost/asio/basic_socket.hpp>
#include <boost/asio/detail/handler_type_requirements.hpp> #include <boost/asio/detail/handler_type_requirements.hpp>
#include <boost/asio/detail/non_const_lvalue.hpp>
#include <boost/asio/detail/throw_error.hpp> #include <boost/asio/detail/throw_error.hpp>
#include <boost/asio/detail/type_traits.hpp> #include <boost/asio/detail/type_traits.hpp>
#include <boost/asio/error.hpp> #include <boost/asio/error.hpp>
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
# include <boost/asio/raw_socket_service.hpp>
#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
#include <boost/asio/detail/push_options.hpp> #include <boost/asio/detail/push_options.hpp>
namespace boost { namespace boost {
namespace asio { namespace asio {
#if !defined(BOOST_ASIO_BASIC_RAW_SOCKET_FWD_DECL)
#define BOOST_ASIO_BASIC_RAW_SOCKET_FWD_DECL
// Forward declaration with defaulted arguments.
template <typename Protocol, typename Executor = executor>
class basic_raw_socket;
#endif // !defined(BOOST_ASIO_BASIC_RAW_SOCKET_FWD_DECL)
/// Provides raw-oriented socket functionality. /// Provides raw-oriented socket functionality.
/** /**
* The basic_raw_socket class template provides asynchronous and blocking * The basic_raw_socket class template provides asynchronous and blocking
@ -41,18 +47,28 @@ namespace asio {
* @e Distinct @e objects: Safe.@n * @e Distinct @e objects: Safe.@n
* @e Shared @e objects: Unsafe. * @e Shared @e objects: Unsafe.
*/ */
template <typename Protocol template <typename Protocol, typename Executor>
BOOST_ASIO_SVC_TPARAM_DEF1(= raw_socket_service<Protocol>)>
class basic_raw_socket class basic_raw_socket
: public basic_socket<Protocol BOOST_ASIO_SVC_TARG> : public basic_socket<Protocol, Executor>
{ {
public: public:
/// The type of the executor associated with the object.
typedef Executor executor_type;
/// Rebinds the socket type to another executor.
template <typename Executor1>
struct rebind_executor
{
/// The socket type when rebound to the specified executor.
typedef basic_raw_socket<Protocol, Executor1> other;
};
/// The native representation of a socket. /// The native representation of a socket.
#if defined(GENERATING_DOCUMENTATION) #if defined(GENERATING_DOCUMENTATION)
typedef implementation_defined native_handle_type; typedef implementation_defined native_handle_type;
#else #else
typedef typename basic_socket< typedef typename basic_socket<Protocol,
Protocol BOOST_ASIO_SVC_TARG>::native_handle_type native_handle_type; Executor>::native_handle_type native_handle_type;
#endif #endif
/// The protocol type. /// The protocol type.
@ -66,12 +82,29 @@ public:
* This constructor creates a raw socket without opening it. The open() * This constructor creates a raw socket without opening it. The open()
* function must be called before data can be sent or received on the socket. * function must be called before data can be sent or received on the socket.
* *
* @param io_context The io_context object that the raw socket will use * @param ex The I/O executor that the socket will use, by default, to
* to dispatch handlers for any asynchronous operations performed on the * dispatch handlers for any asynchronous operations performed on the socket.
* socket.
*/ */
explicit basic_raw_socket(boost::asio::io_context& io_context) explicit basic_raw_socket(const executor_type& ex)
: basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context) : basic_socket<Protocol, Executor>(ex)
{
}
/// Construct a basic_raw_socket without opening it.
/**
* This constructor creates a raw socket without opening it. The open()
* function must be called before data can be sent or received on the socket.
*
* @param context An execution context which provides the I/O executor that
* the socket will use, by default, to dispatch handlers for any asynchronous
* operations performed on the socket.
*/
template <typename ExecutionContext>
explicit basic_raw_socket(ExecutionContext& context,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: basic_socket<Protocol, Executor>(context)
{ {
} }
@ -79,17 +112,36 @@ public:
/** /**
* This constructor creates and opens a raw socket. * This constructor creates and opens a raw socket.
* *
* @param io_context The io_context object that the raw socket will use * @param ex The I/O executor that the socket will use, by default, to
* to dispatch handlers for any asynchronous operations performed on the * dispatch handlers for any asynchronous operations performed on the socket.
* socket.
* *
* @param protocol An object specifying protocol parameters to be used. * @param protocol An object specifying protocol parameters to be used.
* *
* @throws boost::system::system_error Thrown on failure. * @throws boost::system::system_error Thrown on failure.
*/ */
basic_raw_socket(boost::asio::io_context& io_context, basic_raw_socket(const executor_type& ex, const protocol_type& protocol)
const protocol_type& protocol) : basic_socket<Protocol, Executor>(ex, protocol)
: basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context, protocol) {
}
/// Construct and open a basic_raw_socket.
/**
* This constructor creates and opens a raw socket.
*
* @param context An execution context which provides the I/O executor that
* the socket will use, by default, to dispatch handlers for any asynchronous
* operations performed on the socket.
*
* @param protocol An object specifying protocol parameters to be used.
*
* @throws boost::system::system_error Thrown on failure.
*/
template <typename ExecutionContext>
basic_raw_socket(ExecutionContext& context, const protocol_type& protocol,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: basic_socket<Protocol, Executor>(context, protocol)
{ {
} }
@ -100,18 +152,41 @@ public:
* to the specified endpoint on the local machine. The protocol used is the * to the specified endpoint on the local machine. The protocol used is the
* protocol associated with the given endpoint. * protocol associated with the given endpoint.
* *
* @param io_context The io_context object that the raw socket will use * @param ex The I/O executor that the socket will use, by default, to
* to dispatch handlers for any asynchronous operations performed on the * dispatch handlers for any asynchronous operations performed on the socket.
* socket.
* *
* @param endpoint An endpoint on the local machine to which the raw * @param endpoint An endpoint on the local machine to which the raw
* socket will be bound. * socket will be bound.
* *
* @throws boost::system::system_error Thrown on failure. * @throws boost::system::system_error Thrown on failure.
*/ */
basic_raw_socket(boost::asio::io_context& io_context, basic_raw_socket(const executor_type& ex, const endpoint_type& endpoint)
const endpoint_type& endpoint) : basic_socket<Protocol, Executor>(ex, endpoint)
: basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context, endpoint) {
}
/// Construct a basic_raw_socket, opening it and binding it to the given
/// local endpoint.
/**
* This constructor creates a raw socket and automatically opens it bound
* to the specified endpoint on the local machine. The protocol used is the
* protocol associated with the given endpoint.
*
* @param context An execution context which provides the I/O executor that
* the socket will use, by default, to dispatch handlers for any asynchronous
* operations performed on the socket.
*
* @param endpoint An endpoint on the local machine to which the raw
* socket will be bound.
*
* @throws boost::system::system_error Thrown on failure.
*/
template <typename ExecutionContext>
basic_raw_socket(ExecutionContext& context, const endpoint_type& endpoint,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: basic_socket<Protocol, Executor>(context, endpoint)
{ {
} }
@ -120,9 +195,8 @@ public:
* This constructor creates a raw socket object to hold an existing * This constructor creates a raw socket object to hold an existing
* native socket. * native socket.
* *
* @param io_context The io_context object that the raw socket will use * @param ex The I/O executor that the socket will use, by default, to
* to dispatch handlers for any asynchronous operations performed on the * dispatch handlers for any asynchronous operations performed on the socket.
* socket.
* *
* @param protocol An object specifying protocol parameters to be used. * @param protocol An object specifying protocol parameters to be used.
* *
@ -130,10 +204,34 @@ public:
* *
* @throws boost::system::system_error Thrown on failure. * @throws boost::system::system_error Thrown on failure.
*/ */
basic_raw_socket(boost::asio::io_context& io_context, basic_raw_socket(const executor_type& ex,
const protocol_type& protocol, const native_handle_type& native_socket) const protocol_type& protocol, const native_handle_type& native_socket)
: basic_socket<Protocol BOOST_ASIO_SVC_TARG>( : basic_socket<Protocol, Executor>(ex, protocol, native_socket)
io_context, protocol, native_socket) {
}
/// Construct a basic_raw_socket on an existing native socket.
/**
* This constructor creates a raw socket object to hold an existing
* native socket.
*
* @param context An execution context which provides the I/O executor that
* the socket will use, by default, to dispatch handlers for any asynchronous
* operations performed on the socket.
*
* @param protocol An object specifying protocol parameters to be used.
*
* @param native_socket The new underlying socket implementation.
*
* @throws boost::system::system_error Thrown on failure.
*/
template <typename ExecutionContext>
basic_raw_socket(ExecutionContext& context,
const protocol_type& protocol, const native_handle_type& native_socket,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: basic_socket<Protocol, Executor>(context, protocol, native_socket)
{ {
} }
@ -146,10 +244,11 @@ public:
* will occur. * will occur.
* *
* @note Following the move, the moved-from object is in the same state as if * @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_raw_socket(io_context&) constructor. * constructed using the @c basic_raw_socket(const executor_type&)
* constructor.
*/ */
basic_raw_socket(basic_raw_socket&& other) basic_raw_socket(basic_raw_socket&& other)
: basic_socket<Protocol BOOST_ASIO_SVC_TARG>(std::move(other)) : basic_socket<Protocol, Executor>(std::move(other))
{ {
} }
@ -161,28 +260,34 @@ public:
* will occur. * will occur.
* *
* @note Following the move, the moved-from object is in the same state as if * @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_raw_socket(io_context&) constructor. * constructed using the @c basic_raw_socket(const executor_type&)
* constructor.
*/ */
basic_raw_socket& operator=(basic_raw_socket&& other) basic_raw_socket& operator=(basic_raw_socket&& other)
{ {
basic_socket<Protocol BOOST_ASIO_SVC_TARG>::operator=(std::move(other)); basic_socket<Protocol, Executor>::operator=(std::move(other));
return *this; return *this;
} }
/// Move-construct a basic_raw_socket from a socket of another protocol type. /// Move-construct a basic_raw_socket from a socket of another protocol
/// type.
/** /**
* This constructor moves a raw socket from one object to another. * This constructor moves a raw socket from one object to another.
* *
* @param other The other basic_raw_socket object from which the move will * @param other The other basic_raw_socket object from which the move
* occur. * will occur.
* *
* @note Following the move, the moved-from object is in the same state as if * @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_raw_socket(io_context&) constructor. * constructed using the @c basic_raw_socket(const executor_type&)
* constructor.
*/ */
template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1> template <typename Protocol1, typename Executor1>
basic_raw_socket(basic_raw_socket<Protocol1 BOOST_ASIO_SVC_TARG1>&& other, basic_raw_socket(basic_raw_socket<Protocol1, Executor1>&& other,
typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0) typename enable_if<
: basic_socket<Protocol BOOST_ASIO_SVC_TARG>(std::move(other)) is_convertible<Protocol1, Protocol>::value
&& is_convertible<Executor1, Executor>::value
>::type* = 0)
: basic_socket<Protocol, Executor>(std::move(other))
{ {
} }
@ -194,14 +299,17 @@ public:
* will occur. * will occur.
* *
* @note Following the move, the moved-from object is in the same state as if * @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_raw_socket(io_context&) constructor. * constructed using the @c basic_raw_socket(const executor_type&)
* constructor.
*/ */
template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1> template <typename Protocol1, typename Executor1>
typename enable_if<is_convertible<Protocol1, Protocol>::value, typename enable_if<
basic_raw_socket>::type& operator=( is_convertible<Protocol1, Protocol>::value
basic_raw_socket<Protocol1 BOOST_ASIO_SVC_TARG1>&& other) && is_convertible<Executor1, Executor>::value,
basic_raw_socket&
>::type operator=(basic_raw_socket<Protocol1, Executor1>&& other)
{ {
basic_socket<Protocol BOOST_ASIO_SVC_TARG>::operator=(std::move(other)); basic_socket<Protocol, Executor>::operator=(std::move(other));
return *this; return *this;
} }
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
@ -240,8 +348,8 @@ public:
std::size_t send(const ConstBufferSequence& buffers) std::size_t send(const ConstBufferSequence& buffers)
{ {
boost::system::error_code ec; boost::system::error_code ec;
std::size_t s = this->get_service().send( std::size_t s = this->impl_.get_service().send(
this->get_implementation(), buffers, 0, ec); this->impl_.get_implementation(), buffers, 0, ec);
boost::asio::detail::throw_error(ec, "send"); boost::asio::detail::throw_error(ec, "send");
return s; return s;
} }
@ -267,8 +375,8 @@ public:
socket_base::message_flags flags) socket_base::message_flags flags)
{ {
boost::system::error_code ec; boost::system::error_code ec;
std::size_t s = this->get_service().send( std::size_t s = this->impl_.get_service().send(
this->get_implementation(), buffers, flags, ec); this->impl_.get_implementation(), buffers, flags, ec);
boost::asio::detail::throw_error(ec, "send"); boost::asio::detail::throw_error(ec, "send");
return s; return s;
} }
@ -293,8 +401,8 @@ public:
std::size_t send(const ConstBufferSequence& buffers, std::size_t send(const ConstBufferSequence& buffers,
socket_base::message_flags flags, boost::system::error_code& ec) socket_base::message_flags flags, boost::system::error_code& ec)
{ {
return this->get_service().send( return this->impl_.get_service().send(
this->get_implementation(), buffers, flags, ec); this->impl_.get_implementation(), buffers, flags, ec);
} }
/// Start an asynchronous send on a connected socket. /// Start an asynchronous send on a connected socket.
@ -315,9 +423,9 @@ public:
* std::size_t bytes_transferred // Number of bytes sent. * std::size_t bytes_transferred // Number of bytes sent.
* ); @endcode * ); @endcode
* Regardless of whether the asynchronous operation completes immediately or * Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation * not, the handler will not be invoked from within this function. On
* of the handler will be performed in a manner equivalent to using * immediate completion, invocation of the handler will be performed in a
* boost::asio::io_context::post(). * manner equivalent to using boost::asio::post().
* *
* @note The async_send operation can only be used with a connected socket. * @note The async_send operation can only be used with a connected socket.
* Use the async_send_to function to send data on an unconnected raw * Use the async_send_to function to send data on an unconnected raw
@ -338,22 +446,10 @@ public:
async_send(const ConstBufferSequence& buffers, async_send(const ConstBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler) BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{ {
// If you get an error on the following line it means that your handler does return async_initiate<WriteHandler,
// not meet the documented type requirements for a WriteHandler. void (boost::system::error_code, std::size_t)>(
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; initiate_async_send(), handler, this,
buffers, socket_base::message_flags(0));
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_send(this->get_implementation(),
buffers, 0, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
async_completion<WriteHandler,
void (boost::system::error_code, std::size_t)> init(handler);
this->get_service().async_send(this->get_implementation(),
buffers, 0, init.completion_handler);
return init.result.get();
#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
} }
/// Start an asynchronous send on a connected socket. /// Start an asynchronous send on a connected socket.
@ -376,9 +472,9 @@ public:
* std::size_t bytes_transferred // Number of bytes sent. * std::size_t bytes_transferred // Number of bytes sent.
* ); @endcode * ); @endcode
* Regardless of whether the asynchronous operation completes immediately or * Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation * not, the handler will not be invoked from within this function. On
* of the handler will be performed in a manner equivalent to using * immediate completion, invocation of the handler will be performed in a
* boost::asio::io_context::post(). * manner equivalent to using boost::asio::post().
* *
* @note The async_send operation can only be used with a connected socket. * @note The async_send operation can only be used with a connected socket.
* Use the async_send_to function to send data on an unconnected raw * Use the async_send_to function to send data on an unconnected raw
@ -391,22 +487,9 @@ public:
socket_base::message_flags flags, socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler) BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{ {
// If you get an error on the following line it means that your handler does return async_initiate<WriteHandler,
// not meet the documented type requirements for a WriteHandler. void (boost::system::error_code, std::size_t)>(
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; initiate_async_send(), handler, this, buffers, flags);
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_send(this->get_implementation(),
buffers, flags, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
async_completion<WriteHandler,
void (boost::system::error_code, std::size_t)> init(handler);
this->get_service().async_send(this->get_implementation(),
buffers, flags, init.completion_handler);
return init.result.get();
#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
} }
/// Send raw data to the specified endpoint. /// Send raw data to the specified endpoint.
@ -439,8 +522,8 @@ public:
const endpoint_type& destination) const endpoint_type& destination)
{ {
boost::system::error_code ec; boost::system::error_code ec;
std::size_t s = this->get_service().send_to( std::size_t s = this->impl_.get_service().send_to(
this->get_implementation(), buffers, destination, 0, ec); this->impl_.get_implementation(), buffers, destination, 0, ec);
boost::asio::detail::throw_error(ec, "send_to"); boost::asio::detail::throw_error(ec, "send_to");
return s; return s;
} }
@ -466,8 +549,8 @@ public:
const endpoint_type& destination, socket_base::message_flags flags) const endpoint_type& destination, socket_base::message_flags flags)
{ {
boost::system::error_code ec; boost::system::error_code ec;
std::size_t s = this->get_service().send_to( std::size_t s = this->impl_.get_service().send_to(
this->get_implementation(), buffers, destination, flags, ec); this->impl_.get_implementation(), buffers, destination, flags, ec);
boost::asio::detail::throw_error(ec, "send_to"); boost::asio::detail::throw_error(ec, "send_to");
return s; return s;
} }
@ -493,7 +576,7 @@ public:
const endpoint_type& destination, socket_base::message_flags flags, const endpoint_type& destination, socket_base::message_flags flags,
boost::system::error_code& ec) boost::system::error_code& ec)
{ {
return this->get_service().send_to(this->get_implementation(), return this->impl_.get_service().send_to(this->impl_.get_implementation(),
buffers, destination, flags, ec); buffers, destination, flags, ec);
} }
@ -518,9 +601,9 @@ public:
* std::size_t bytes_transferred // Number of bytes sent. * std::size_t bytes_transferred // Number of bytes sent.
* ); @endcode * ); @endcode
* Regardless of whether the asynchronous operation completes immediately or * Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation * not, the handler will not be invoked from within this function. On
* of the handler will be performed in a manner equivalent to using * immediate completion, invocation of the handler will be performed in a
* boost::asio::io_context::post(). * manner equivalent to using boost::asio::post().
* *
* @par Example * @par Example
* To send a single data buffer use the @ref buffer function as follows: * To send a single data buffer use the @ref buffer function as follows:
@ -541,22 +624,10 @@ public:
const endpoint_type& destination, const endpoint_type& destination,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler) BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{ {
// If you get an error on the following line it means that your handler does return async_initiate<WriteHandler,
// not meet the documented type requirements for a WriteHandler. void (boost::system::error_code, std::size_t)>(
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; initiate_async_send_to(), handler, this, buffers,
destination, socket_base::message_flags(0));
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_send_to(this->get_implementation(),
buffers, destination, 0, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
async_completion<WriteHandler,
void (boost::system::error_code, std::size_t)> init(handler);
this->get_service().async_send_to(this->get_implementation(),
buffers, destination, 0, init.completion_handler);
return init.result.get();
#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
} }
/// Start an asynchronous send. /// Start an asynchronous send.
@ -582,9 +653,9 @@ public:
* std::size_t bytes_transferred // Number of bytes sent. * std::size_t bytes_transferred // Number of bytes sent.
* ); @endcode * ); @endcode
* Regardless of whether the asynchronous operation completes immediately or * Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation * not, the handler will not be invoked from within this function. On
* of the handler will be performed in a manner equivalent to using * immediate completion, invocation of the handler will be performed in a
* boost::asio::io_context::post(). * manner equivalent to using boost::asio::post().
*/ */
template <typename ConstBufferSequence, typename WriteHandler> template <typename ConstBufferSequence, typename WriteHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
@ -593,24 +664,9 @@ public:
const endpoint_type& destination, socket_base::message_flags flags, const endpoint_type& destination, socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler) BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{ {
// If you get an error on the following line it means that your handler does return async_initiate<WriteHandler,
// not meet the documented type requirements for a WriteHandler. void (boost::system::error_code, std::size_t)>(
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; initiate_async_send_to(), handler, this, buffers, destination, flags);
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_send_to(
this->get_implementation(), buffers, destination, flags,
BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
async_completion<WriteHandler,
void (boost::system::error_code, std::size_t)> init(handler);
this->get_service().async_send_to(
this->get_implementation(), buffers, destination, flags,
init.completion_handler);
return init.result.get();
#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
} }
/// Receive some data on a connected socket. /// Receive some data on a connected socket.
@ -641,8 +697,8 @@ public:
std::size_t receive(const MutableBufferSequence& buffers) std::size_t receive(const MutableBufferSequence& buffers)
{ {
boost::system::error_code ec; boost::system::error_code ec;
std::size_t s = this->get_service().receive( std::size_t s = this->impl_.get_service().receive(
this->get_implementation(), buffers, 0, ec); this->impl_.get_implementation(), buffers, 0, ec);
boost::asio::detail::throw_error(ec, "receive"); boost::asio::detail::throw_error(ec, "receive");
return s; return s;
} }
@ -670,8 +726,8 @@ public:
socket_base::message_flags flags) socket_base::message_flags flags)
{ {
boost::system::error_code ec; boost::system::error_code ec;
std::size_t s = this->get_service().receive( std::size_t s = this->impl_.get_service().receive(
this->get_implementation(), buffers, flags, ec); this->impl_.get_implementation(), buffers, flags, ec);
boost::asio::detail::throw_error(ec, "receive"); boost::asio::detail::throw_error(ec, "receive");
return s; return s;
} }
@ -698,8 +754,8 @@ public:
std::size_t receive(const MutableBufferSequence& buffers, std::size_t receive(const MutableBufferSequence& buffers,
socket_base::message_flags flags, boost::system::error_code& ec) socket_base::message_flags flags, boost::system::error_code& ec)
{ {
return this->get_service().receive( return this->impl_.get_service().receive(
this->get_implementation(), buffers, flags, ec); this->impl_.get_implementation(), buffers, flags, ec);
} }
/// Start an asynchronous receive on a connected socket. /// Start an asynchronous receive on a connected socket.
@ -720,9 +776,9 @@ public:
* std::size_t bytes_transferred // Number of bytes received. * std::size_t bytes_transferred // Number of bytes received.
* ); @endcode * ); @endcode
* Regardless of whether the asynchronous operation completes immediately or * Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation * not, the handler will not be invoked from within this function. On
* of the handler will be performed in a manner equivalent to using * immediate completion, invocation of the handler will be performed in a
* boost::asio::io_context::post(). * manner equivalent to using boost::asio::post().
* *
* @note The async_receive operation can only be used with a connected socket. * @note The async_receive operation can only be used with a connected socket.
* Use the async_receive_from function to receive data on an unconnected * Use the async_receive_from function to receive data on an unconnected
@ -744,22 +800,10 @@ public:
async_receive(const MutableBufferSequence& buffers, async_receive(const MutableBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler) BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{ {
// If you get an error on the following line it means that your handler does return async_initiate<ReadHandler,
// not meet the documented type requirements for a ReadHandler. void (boost::system::error_code, std::size_t)>(
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; initiate_async_receive(), handler, this,
buffers, socket_base::message_flags(0));
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_receive(this->get_implementation(),
buffers, 0, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
async_completion<ReadHandler,
void (boost::system::error_code, std::size_t)> init(handler);
this->get_service().async_receive(this->get_implementation(),
buffers, 0, init.completion_handler);
return init.result.get();
#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
} }
/// Start an asynchronous receive on a connected socket. /// Start an asynchronous receive on a connected socket.
@ -782,9 +826,9 @@ public:
* std::size_t bytes_transferred // Number of bytes received. * std::size_t bytes_transferred // Number of bytes received.
* ); @endcode * ); @endcode
* Regardless of whether the asynchronous operation completes immediately or * Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation * not, the handler will not be invoked from within this function. On
* of the handler will be performed in a manner equivalent to using * immediate completion, invocation of the handler will be performed in a
* boost::asio::io_context::post(). * manner equivalent to using boost::asio::post().
* *
* @note The async_receive operation can only be used with a connected socket. * @note The async_receive operation can only be used with a connected socket.
* Use the async_receive_from function to receive data on an unconnected * Use the async_receive_from function to receive data on an unconnected
@ -797,22 +841,9 @@ public:
socket_base::message_flags flags, socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler) BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{ {
// If you get an error on the following line it means that your handler does return async_initiate<ReadHandler,
// not meet the documented type requirements for a ReadHandler. void (boost::system::error_code, std::size_t)>(
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; initiate_async_receive(), handler, this, buffers, flags);
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_receive(this->get_implementation(),
buffers, flags, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
async_completion<ReadHandler,
void (boost::system::error_code, std::size_t)> init(handler);
this->get_service().async_receive(this->get_implementation(),
buffers, flags, init.completion_handler);
return init.result.get();
#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
} }
/// Receive raw data with the endpoint of the sender. /// Receive raw data with the endpoint of the sender.
@ -846,8 +877,8 @@ public:
endpoint_type& sender_endpoint) endpoint_type& sender_endpoint)
{ {
boost::system::error_code ec; boost::system::error_code ec;
std::size_t s = this->get_service().receive_from( std::size_t s = this->impl_.get_service().receive_from(
this->get_implementation(), buffers, sender_endpoint, 0, ec); this->impl_.get_implementation(), buffers, sender_endpoint, 0, ec);
boost::asio::detail::throw_error(ec, "receive_from"); boost::asio::detail::throw_error(ec, "receive_from");
return s; return s;
} }
@ -873,8 +904,8 @@ public:
endpoint_type& sender_endpoint, socket_base::message_flags flags) endpoint_type& sender_endpoint, socket_base::message_flags flags)
{ {
boost::system::error_code ec; boost::system::error_code ec;
std::size_t s = this->get_service().receive_from( std::size_t s = this->impl_.get_service().receive_from(
this->get_implementation(), buffers, sender_endpoint, flags, ec); this->impl_.get_implementation(), buffers, sender_endpoint, flags, ec);
boost::asio::detail::throw_error(ec, "receive_from"); boost::asio::detail::throw_error(ec, "receive_from");
return s; return s;
} }
@ -900,8 +931,8 @@ public:
endpoint_type& sender_endpoint, socket_base::message_flags flags, endpoint_type& sender_endpoint, socket_base::message_flags flags,
boost::system::error_code& ec) boost::system::error_code& ec)
{ {
return this->get_service().receive_from(this->get_implementation(), return this->impl_.get_service().receive_from(
buffers, sender_endpoint, flags, ec); this->impl_.get_implementation(), buffers, sender_endpoint, flags, ec);
} }
/// Start an asynchronous receive. /// Start an asynchronous receive.
@ -927,9 +958,9 @@ public:
* std::size_t bytes_transferred // Number of bytes received. * std::size_t bytes_transferred // Number of bytes received.
* ); @endcode * ); @endcode
* Regardless of whether the asynchronous operation completes immediately or * Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation * not, the handler will not be invoked from within this function. On
* of the handler will be performed in a manner equivalent to using * immediate completion, invocation of the handler will be performed in a
* boost::asio::io_context::post(). * manner equivalent to using boost::asio::post().
* *
* @par Example * @par Example
* To receive into a single data buffer use the @ref buffer function as * To receive into a single data buffer use the @ref buffer function as
@ -947,24 +978,10 @@ public:
endpoint_type& sender_endpoint, endpoint_type& sender_endpoint,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler) BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{ {
// If you get an error on the following line it means that your handler does return async_initiate<ReadHandler,
// not meet the documented type requirements for a ReadHandler. void (boost::system::error_code, std::size_t)>(
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; initiate_async_receive_from(), handler, this, buffers,
&sender_endpoint, socket_base::message_flags(0));
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_receive_from(
this->get_implementation(), buffers, sender_endpoint, 0,
BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
async_completion<ReadHandler,
void (boost::system::error_code, std::size_t)> init(handler);
this->get_service().async_receive_from(
this->get_implementation(), buffers, sender_endpoint, 0,
init.completion_handler);
return init.result.get();
#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
} }
/// Start an asynchronous receive. /// Start an asynchronous receive.
@ -992,9 +1009,9 @@ public:
* std::size_t bytes_transferred // Number of bytes received. * std::size_t bytes_transferred // Number of bytes received.
* ); @endcode * ); @endcode
* Regardless of whether the asynchronous operation completes immediately or * Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation * not, the handler will not be invoked from within this function. On
* of the handler will be performed in a manner equivalent to using * immediate completion, invocation of the handler will be performed in a
* boost::asio::io_context::post(). * manner equivalent to using boost::asio::post().
*/ */
template <typename MutableBufferSequence, typename ReadHandler> template <typename MutableBufferSequence, typename ReadHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
@ -1003,25 +1020,85 @@ public:
endpoint_type& sender_endpoint, socket_base::message_flags flags, endpoint_type& sender_endpoint, socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler) BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{ {
// If you get an error on the following line it means that your handler does return async_initiate<ReadHandler,
// not meet the documented type requirements for a ReadHandler. void (boost::system::error_code, std::size_t)>(
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; initiate_async_receive_from(), handler,
this, buffers, &sender_endpoint, flags);
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_receive_from(
this->get_implementation(), buffers, sender_endpoint, flags,
BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
async_completion<ReadHandler,
void (boost::system::error_code, std::size_t)> init(handler);
this->get_service().async_receive_from(
this->get_implementation(), buffers, sender_endpoint, flags,
init.completion_handler);
return init.result.get();
#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
} }
private:
struct initiate_async_send
{
template <typename WriteHandler, typename ConstBufferSequence>
void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
basic_raw_socket* self, const ConstBufferSequence& buffers,
socket_base::message_flags flags) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a WriteHandler.
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
detail::non_const_lvalue<WriteHandler> handler2(handler);
self->impl_.get_service().async_send(
self->impl_.get_implementation(), buffers, flags,
handler2.value, self->impl_.get_implementation_executor());
}
};
struct initiate_async_send_to
{
template <typename WriteHandler, typename ConstBufferSequence>
void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
basic_raw_socket* self, const ConstBufferSequence& buffers,
const endpoint_type& destination,
socket_base::message_flags flags) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a WriteHandler.
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
detail::non_const_lvalue<WriteHandler> handler2(handler);
self->impl_.get_service().async_send_to(
self->impl_.get_implementation(), buffers, destination, flags,
handler2.value, self->impl_.get_implementation_executor());
}
};
struct initiate_async_receive
{
template <typename ReadHandler, typename MutableBufferSequence>
void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
basic_raw_socket* self, const MutableBufferSequence& buffers,
socket_base::message_flags flags) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a ReadHandler.
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
detail::non_const_lvalue<ReadHandler> handler2(handler);
self->impl_.get_service().async_receive(
self->impl_.get_implementation(), buffers, flags,
handler2.value, self->impl_.get_implementation_executor());
}
};
struct initiate_async_receive_from
{
template <typename ReadHandler, typename MutableBufferSequence>
void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
basic_raw_socket* self, const MutableBufferSequence& buffers,
endpoint_type* sender_endpoint, socket_base::message_flags flags) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a ReadHandler.
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
detail::non_const_lvalue<ReadHandler> handler2(handler);
self->impl_.get_service().async_receive_from(
self->impl_.get_implementation(), buffers, *sender_endpoint, flags,
handler2.value, self->impl_.get_implementation_executor());
}
};
}; };
} // namespace asio } // namespace asio

View File

@ -2,7 +2,7 @@
// basic_seq_packet_socket.hpp // basic_seq_packet_socket.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -22,15 +22,20 @@
#include <boost/asio/detail/throw_error.hpp> #include <boost/asio/detail/throw_error.hpp>
#include <boost/asio/error.hpp> #include <boost/asio/error.hpp>
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
# include <boost/asio/seq_packet_socket_service.hpp>
#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
#include <boost/asio/detail/push_options.hpp> #include <boost/asio/detail/push_options.hpp>
namespace boost { namespace boost {
namespace asio { namespace asio {
#if !defined(BOOST_ASIO_BASIC_SEQ_PACKET_SOCKET_FWD_DECL)
#define BOOST_ASIO_BASIC_SEQ_PACKET_SOCKET_FWD_DECL
// Forward declaration with defaulted arguments.
template <typename Protocol, typename Executor = executor>
class basic_seq_packet_socket;
#endif // !defined(BOOST_ASIO_BASIC_SEQ_PACKET_SOCKET_FWD_DECL)
/// Provides sequenced packet socket functionality. /// Provides sequenced packet socket functionality.
/** /**
* The basic_seq_packet_socket class template provides asynchronous and blocking * The basic_seq_packet_socket class template provides asynchronous and blocking
@ -40,18 +45,28 @@ namespace asio {
* @e Distinct @e objects: Safe.@n * @e Distinct @e objects: Safe.@n
* @e Shared @e objects: Unsafe. * @e Shared @e objects: Unsafe.
*/ */
template <typename Protocol template <typename Protocol, typename Executor>
BOOST_ASIO_SVC_TPARAM_DEF1(= seq_packet_socket_service<Protocol>)>
class basic_seq_packet_socket class basic_seq_packet_socket
: public basic_socket<Protocol BOOST_ASIO_SVC_TARG> : public basic_socket<Protocol, Executor>
{ {
public: public:
/// The type of the executor associated with the object.
typedef Executor executor_type;
/// Rebinds the socket type to another executor.
template <typename Executor1>
struct rebind_executor
{
/// The socket type when rebound to the specified executor.
typedef basic_seq_packet_socket<Protocol, Executor1> other;
};
/// The native representation of a socket. /// The native representation of a socket.
#if defined(GENERATING_DOCUMENTATION) #if defined(GENERATING_DOCUMENTATION)
typedef implementation_defined native_handle_type; typedef implementation_defined native_handle_type;
#else #else
typedef typename basic_socket< typedef typename basic_socket<Protocol,
Protocol BOOST_ASIO_SVC_TARG>::native_handle_type native_handle_type; Executor>::native_handle_type native_handle_type;
#endif #endif
/// The protocol type. /// The protocol type.
@ -66,12 +81,30 @@ public:
* socket needs to be opened and then connected or accepted before data can * socket needs to be opened and then connected or accepted before data can
* be sent or received on it. * be sent or received on it.
* *
* @param io_context The io_context object that the sequenced packet socket * @param ex The I/O executor that the socket will use, by default, to
* will use to dispatch handlers for any asynchronous operations performed on * dispatch handlers for any asynchronous operations performed on the socket.
* the socket.
*/ */
explicit basic_seq_packet_socket(boost::asio::io_context& io_context) explicit basic_seq_packet_socket(const executor_type& ex)
: basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context) : basic_socket<Protocol, Executor>(ex)
{
}
/// Construct a basic_seq_packet_socket without opening it.
/**
* This constructor creates a sequenced packet socket without opening it. The
* socket needs to be opened and then connected or accepted before data can
* be sent or received on it.
*
* @param context An execution context which provides the I/O executor that
* the socket will use, by default, to dispatch handlers for any asynchronous
* operations performed on the socket.
*/
template <typename ExecutionContext>
explicit basic_seq_packet_socket(ExecutionContext& context,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: basic_socket<Protocol, Executor>(context)
{ {
} }
@ -81,17 +114,40 @@ public:
* needs to be connected or accepted before data can be sent or received on * needs to be connected or accepted before data can be sent or received on
* it. * it.
* *
* @param io_context The io_context object that the sequenced packet socket * @param ex The I/O executor that the socket will use, by default, to
* will use to dispatch handlers for any asynchronous operations performed on * dispatch handlers for any asynchronous operations performed on the socket.
* the socket.
* *
* @param protocol An object specifying protocol parameters to be used. * @param protocol An object specifying protocol parameters to be used.
* *
* @throws boost::system::system_error Thrown on failure. * @throws boost::system::system_error Thrown on failure.
*/ */
basic_seq_packet_socket(boost::asio::io_context& io_context, basic_seq_packet_socket(const executor_type& ex,
const protocol_type& protocol) const protocol_type& protocol)
: basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context, protocol) : basic_socket<Protocol, Executor>(ex, protocol)
{
}
/// Construct and open a basic_seq_packet_socket.
/**
* This constructor creates and opens a sequenced_packet socket. The socket
* needs to be connected or accepted before data can be sent or received on
* it.
*
* @param context An execution context which provides the I/O executor that
* the socket will use, by default, to dispatch handlers for any asynchronous
* operations performed on the socket.
*
* @param protocol An object specifying protocol parameters to be used.
*
* @throws boost::system::system_error Thrown on failure.
*/
template <typename ExecutionContext>
basic_seq_packet_socket(ExecutionContext& context,
const protocol_type& protocol,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: basic_socket<Protocol, Executor>(context, protocol)
{ {
} }
@ -102,18 +158,43 @@ public:
* it bound to the specified endpoint on the local machine. The protocol used * it bound to the specified endpoint on the local machine. The protocol used
* is the protocol associated with the given endpoint. * is the protocol associated with the given endpoint.
* *
* @param io_context The io_context object that the sequenced packet socket * @param ex The I/O executor that the socket will use, by default, to
* will use to dispatch handlers for any asynchronous operations performed on * dispatch handlers for any asynchronous operations performed on the socket.
* the socket.
* *
* @param endpoint An endpoint on the local machine to which the sequenced * @param endpoint An endpoint on the local machine to which the sequenced
* packet socket will be bound. * packet socket will be bound.
* *
* @throws boost::system::system_error Thrown on failure. * @throws boost::system::system_error Thrown on failure.
*/ */
basic_seq_packet_socket(boost::asio::io_context& io_context, basic_seq_packet_socket(const executor_type& ex,
const endpoint_type& endpoint) const endpoint_type& endpoint)
: basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context, endpoint) : basic_socket<Protocol, Executor>(ex, endpoint)
{
}
/// Construct a basic_seq_packet_socket, opening it and binding it to the
/// given local endpoint.
/**
* This constructor creates a sequenced packet socket and automatically opens
* it bound to the specified endpoint on the local machine. The protocol used
* is the protocol associated with the given endpoint.
*
* @param context An execution context which provides the I/O executor that
* the socket will use, by default, to dispatch handlers for any asynchronous
* operations performed on the socket.
*
* @param endpoint An endpoint on the local machine to which the sequenced
* packet socket will be bound.
*
* @throws boost::system::system_error Thrown on failure.
*/
template <typename ExecutionContext>
basic_seq_packet_socket(ExecutionContext& context,
const endpoint_type& endpoint,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: basic_socket<Protocol, Executor>(context, endpoint)
{ {
} }
@ -122,9 +203,8 @@ public:
* This constructor creates a sequenced packet socket object to hold an * This constructor creates a sequenced packet socket object to hold an
* existing native socket. * existing native socket.
* *
* @param io_context The io_context object that the sequenced packet socket * @param ex The I/O executor that the socket will use, by default, to
* will use to dispatch handlers for any asynchronous operations performed on * dispatch handlers for any asynchronous operations performed on the socket.
* the socket.
* *
* @param protocol An object specifying protocol parameters to be used. * @param protocol An object specifying protocol parameters to be used.
* *
@ -132,10 +212,34 @@ public:
* *
* @throws boost::system::system_error Thrown on failure. * @throws boost::system::system_error Thrown on failure.
*/ */
basic_seq_packet_socket(boost::asio::io_context& io_context, basic_seq_packet_socket(const executor_type& ex,
const protocol_type& protocol, const native_handle_type& native_socket) const protocol_type& protocol, const native_handle_type& native_socket)
: basic_socket<Protocol BOOST_ASIO_SVC_TARG>( : basic_socket<Protocol, Executor>(ex, protocol, native_socket)
io_context, protocol, native_socket) {
}
/// Construct a basic_seq_packet_socket on an existing native socket.
/**
* This constructor creates a sequenced packet socket object to hold an
* existing native socket.
*
* @param context An execution context which provides the I/O executor that
* the socket will use, by default, to dispatch handlers for any asynchronous
* operations performed on the socket.
*
* @param protocol An object specifying protocol parameters to be used.
*
* @param native_socket The new underlying socket implementation.
*
* @throws boost::system::system_error Thrown on failure.
*/
template <typename ExecutionContext>
basic_seq_packet_socket(ExecutionContext& context,
const protocol_type& protocol, const native_handle_type& native_socket,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: basic_socket<Protocol, Executor>(context, protocol, native_socket)
{ {
} }
@ -149,10 +253,11 @@ public:
* will occur. * will occur.
* *
* @note Following the move, the moved-from object is in the same state as if * @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_seq_packet_socket(io_context&) constructor. * constructed using the @c basic_seq_packet_socket(const executor_type&)
* constructor.
*/ */
basic_seq_packet_socket(basic_seq_packet_socket&& other) basic_seq_packet_socket(basic_seq_packet_socket&& other)
: basic_socket<Protocol BOOST_ASIO_SVC_TARG>(std::move(other)) : basic_socket<Protocol, Executor>(std::move(other))
{ {
} }
@ -165,11 +270,12 @@ public:
* will occur. * will occur.
* *
* @note Following the move, the moved-from object is in the same state as if * @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_seq_packet_socket(io_context&) constructor. * constructed using the @c basic_seq_packet_socket(const executor_type&)
* constructor.
*/ */
basic_seq_packet_socket& operator=(basic_seq_packet_socket&& other) basic_seq_packet_socket& operator=(basic_seq_packet_socket&& other)
{ {
basic_socket<Protocol BOOST_ASIO_SVC_TARG>::operator=(std::move(other)); basic_socket<Protocol, Executor>::operator=(std::move(other));
return *this; return *this;
} }
@ -183,13 +289,16 @@ public:
* will occur. * will occur.
* *
* @note Following the move, the moved-from object is in the same state as if * @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_seq_packet_socket(io_context&) constructor. * constructed using the @c basic_seq_packet_socket(const executor_type&)
* constructor.
*/ */
template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1> template <typename Protocol1, typename Executor1>
basic_seq_packet_socket( basic_seq_packet_socket(basic_seq_packet_socket<Protocol1, Executor1>&& other,
basic_seq_packet_socket<Protocol1 BOOST_ASIO_SVC_TARG1>&& other, typename enable_if<
typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0) is_convertible<Protocol1, Protocol>::value
: basic_socket<Protocol BOOST_ASIO_SVC_TARG>(std::move(other)) && is_convertible<Executor1, Executor>::value
>::type* = 0)
: basic_socket<Protocol, Executor>(std::move(other))
{ {
} }
@ -203,14 +312,17 @@ public:
* will occur. * will occur.
* *
* @note Following the move, the moved-from object is in the same state as if * @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_seq_packet_socket(io_context&) constructor. * constructed using the @c basic_seq_packet_socket(const executor_type&)
* constructor.
*/ */
template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1> template <typename Protocol1, typename Executor1>
typename enable_if<is_convertible<Protocol1, Protocol>::value, typename enable_if<
basic_seq_packet_socket>::type& operator=( is_convertible<Protocol1, Protocol>::value
basic_seq_packet_socket<Protocol1 BOOST_ASIO_SVC_TARG1>&& other) && is_convertible<Executor1, Executor>::value,
basic_seq_packet_socket&
>::type operator=(basic_seq_packet_socket<Protocol1, Executor1>&& other)
{ {
basic_socket<Protocol BOOST_ASIO_SVC_TARG>::operator=(std::move(other)); basic_socket<Protocol, Executor>::operator=(std::move(other));
return *this; return *this;
} }
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
@ -252,8 +364,8 @@ public:
socket_base::message_flags flags) socket_base::message_flags flags)
{ {
boost::system::error_code ec; boost::system::error_code ec;
std::size_t s = this->get_service().send( std::size_t s = this->impl_.get_service().send(
this->get_implementation(), buffers, flags, ec); this->impl_.get_implementation(), buffers, flags, ec);
boost::asio::detail::throw_error(ec, "send"); boost::asio::detail::throw_error(ec, "send");
return s; return s;
} }
@ -280,8 +392,8 @@ public:
std::size_t send(const ConstBufferSequence& buffers, std::size_t send(const ConstBufferSequence& buffers,
socket_base::message_flags flags, boost::system::error_code& ec) socket_base::message_flags flags, boost::system::error_code& ec)
{ {
return this->get_service().send( return this->impl_.get_service().send(
this->get_implementation(), buffers, flags, ec); this->impl_.get_implementation(), buffers, flags, ec);
} }
/// Start an asynchronous send. /// Start an asynchronous send.
@ -304,9 +416,9 @@ public:
* std::size_t bytes_transferred // Number of bytes sent. * std::size_t bytes_transferred // Number of bytes sent.
* ); @endcode * ); @endcode
* Regardless of whether the asynchronous operation completes immediately or * Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation * not, the handler will not be invoked from within this function. On
* of the handler will be performed in a manner equivalent to using * immediate completion, invocation of the handler will be performed in a
* boost::asio::io_context::post(). * manner equivalent to using boost::asio::post().
* *
* @par Example * @par Example
* To send a single data buffer use the @ref buffer function as follows: * To send a single data buffer use the @ref buffer function as follows:
@ -324,22 +436,9 @@ public:
socket_base::message_flags flags, socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler) BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{ {
// If you get an error on the following line it means that your handler does return async_initiate<WriteHandler,
// not meet the documented type requirements for a WriteHandler. void (boost::system::error_code, std::size_t)>(
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; initiate_async_send(), handler, this, buffers, flags);
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_send(this->get_implementation(),
buffers, flags, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
async_completion<WriteHandler,
void (boost::system::error_code, std::size_t)> init(handler);
this->get_service().async_send(this->get_implementation(),
buffers, flags, init.completion_handler);
return init.result.get();
#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
} }
/// Receive some data on the socket. /// Receive some data on the socket.
@ -376,13 +475,8 @@ public:
socket_base::message_flags& out_flags) socket_base::message_flags& out_flags)
{ {
boost::system::error_code ec; boost::system::error_code ec;
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) std::size_t s = this->impl_.get_service().receive_with_flags(
std::size_t s = this->get_service().receive( this->impl_.get_implementation(), buffers, 0, out_flags, ec);
this->get_implementation(), buffers, 0, out_flags, ec);
#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
std::size_t s = this->get_service().receive_with_flags(
this->get_implementation(), buffers, 0, out_flags, ec);
#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
boost::asio::detail::throw_error(ec, "receive"); boost::asio::detail::throw_error(ec, "receive");
return s; return s;
} }
@ -428,13 +522,8 @@ public:
socket_base::message_flags& out_flags) socket_base::message_flags& out_flags)
{ {
boost::system::error_code ec; boost::system::error_code ec;
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) std::size_t s = this->impl_.get_service().receive_with_flags(
std::size_t s = this->get_service().receive( this->impl_.get_implementation(), buffers, in_flags, out_flags, ec);
this->get_implementation(), buffers, in_flags, out_flags, ec);
#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
std::size_t s = this->get_service().receive_with_flags(
this->get_implementation(), buffers, in_flags, out_flags, ec);
#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
boost::asio::detail::throw_error(ec, "receive"); boost::asio::detail::throw_error(ec, "receive");
return s; return s;
} }
@ -467,13 +556,8 @@ public:
socket_base::message_flags in_flags, socket_base::message_flags in_flags,
socket_base::message_flags& out_flags, boost::system::error_code& ec) socket_base::message_flags& out_flags, boost::system::error_code& ec)
{ {
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) return this->impl_.get_service().receive_with_flags(
return this->get_service().receive(this->get_implementation(), this->impl_.get_implementation(), buffers, in_flags, out_flags, ec);
buffers, in_flags, out_flags, ec);
#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().receive_with_flags(this->get_implementation(),
buffers, in_flags, out_flags, ec);
#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
} }
/// Start an asynchronous receive. /// Start an asynchronous receive.
@ -500,9 +584,9 @@ public:
* std::size_t bytes_transferred // Number of bytes received. * std::size_t bytes_transferred // Number of bytes received.
* ); @endcode * ); @endcode
* Regardless of whether the asynchronous operation completes immediately or * Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation * not, the handler will not be invoked from within this function. On
* of the handler will be performed in a manner equivalent to using * immediate completion, invocation of the handler will be performed in a
* boost::asio::io_context::post(). * manner equivalent to using boost::asio::post().
* *
* @par Example * @par Example
* To receive into a single data buffer use the @ref buffer function as * To receive into a single data buffer use the @ref buffer function as
@ -521,24 +605,10 @@ public:
socket_base::message_flags& out_flags, socket_base::message_flags& out_flags,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler) BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{ {
// If you get an error on the following line it means that your handler does return async_initiate<ReadHandler,
// not meet the documented type requirements for a ReadHandler. void (boost::system::error_code, std::size_t)>(
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; initiate_async_receive_with_flags(), handler, this,
buffers, socket_base::message_flags(0), &out_flags);
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_receive(
this->get_implementation(), buffers, 0, out_flags,
BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
async_completion<ReadHandler,
void (boost::system::error_code, std::size_t)> init(handler);
this->get_service().async_receive_with_flags(
this->get_implementation(), buffers, 0, out_flags,
init.completion_handler);
return init.result.get();
#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
} }
/// Start an asynchronous receive. /// Start an asynchronous receive.
@ -567,9 +637,9 @@ public:
* std::size_t bytes_transferred // Number of bytes received. * std::size_t bytes_transferred // Number of bytes received.
* ); @endcode * ); @endcode
* Regardless of whether the asynchronous operation completes immediately or * Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation * not, the handler will not be invoked from within this function. On
* of the handler will be performed in a manner equivalent to using * immediate completion, invocation of the handler will be performed in a
* boost::asio::io_context::post(). * manner equivalent to using boost::asio::post().
* *
* @par Example * @par Example
* To receive into a single data buffer use the @ref buffer function as * To receive into a single data buffer use the @ref buffer function as
@ -591,25 +661,49 @@ public:
socket_base::message_flags& out_flags, socket_base::message_flags& out_flags,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler) BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{ {
// If you get an error on the following line it means that your handler does return async_initiate<ReadHandler,
// not meet the documented type requirements for a ReadHandler. void (boost::system::error_code, std::size_t)>(
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; initiate_async_receive_with_flags(), handler,
this, buffers, in_flags, &out_flags);
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_receive(
this->get_implementation(), buffers, in_flags, out_flags,
BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
async_completion<ReadHandler,
void (boost::system::error_code, std::size_t)> init(handler);
this->get_service().async_receive_with_flags(
this->get_implementation(), buffers, in_flags, out_flags,
init.completion_handler);
return init.result.get();
#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
} }
private:
struct initiate_async_send
{
template <typename WriteHandler, typename ConstBufferSequence>
void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
basic_seq_packet_socket* self, const ConstBufferSequence& buffers,
socket_base::message_flags flags) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a WriteHandler.
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
detail::non_const_lvalue<WriteHandler> handler2(handler);
self->impl_.get_service().async_send(
self->impl_.get_implementation(), buffers, flags,
handler2.value, self->impl_.get_implementation_executor());
}
};
struct initiate_async_receive_with_flags
{
template <typename ReadHandler, typename MutableBufferSequence>
void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
basic_seq_packet_socket* self, const MutableBufferSequence& buffers,
socket_base::message_flags in_flags,
socket_base::message_flags* out_flags) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a ReadHandler.
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
detail::non_const_lvalue<ReadHandler> handler2(handler);
self->impl_.get_service().async_receive_with_flags(
self->impl_.get_implementation(), buffers, in_flags, *out_flags,
handler2.value, self->impl_.get_implementation_executor());
}
};
}; };
} // namespace asio } // namespace asio

View File

@ -2,7 +2,7 @@
// basic_serial_port.hpp // basic_serial_port.hpp
// ~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
@ -18,18 +18,29 @@
#include <boost/asio/detail/config.hpp> #include <boost/asio/detail/config.hpp>
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
#if defined(BOOST_ASIO_HAS_SERIAL_PORT) \ #if defined(BOOST_ASIO_HAS_SERIAL_PORT) \
|| defined(GENERATING_DOCUMENTATION) || defined(GENERATING_DOCUMENTATION)
#include <string> #include <string>
#include <boost/asio/basic_io_object.hpp> #include <boost/asio/async_result.hpp>
#include <boost/asio/detail/handler_type_requirements.hpp> #include <boost/asio/detail/handler_type_requirements.hpp>
#include <boost/asio/detail/io_object_impl.hpp>
#include <boost/asio/detail/non_const_lvalue.hpp>
#include <boost/asio/detail/throw_error.hpp> #include <boost/asio/detail/throw_error.hpp>
#include <boost/asio/detail/type_traits.hpp>
#include <boost/asio/error.hpp> #include <boost/asio/error.hpp>
#include <boost/asio/execution_context.hpp>
#include <boost/asio/executor.hpp>
#include <boost/asio/serial_port_base.hpp> #include <boost/asio/serial_port_base.hpp>
#include <boost/asio/serial_port_service.hpp> #if defined(BOOST_ASIO_HAS_IOCP)
# include <boost/asio/detail/win_iocp_serial_port_service.hpp>
#else
# include <boost/asio/detail/reactive_serial_port_service.hpp>
#endif
#if defined(BOOST_ASIO_HAS_MOVE)
# include <utility>
#endif // defined(BOOST_ASIO_HAS_MOVE)
#include <boost/asio/detail/push_options.hpp> #include <boost/asio/detail/push_options.hpp>
@ -38,34 +49,63 @@ namespace asio {
/// Provides serial port functionality. /// Provides serial port functionality.
/** /**
* The basic_serial_port class template provides functionality that is common * The basic_serial_port class provides a wrapper over serial port
* to all serial ports. * functionality.
* *
* @par Thread Safety * @par Thread Safety
* @e Distinct @e objects: Safe.@n * @e Distinct @e objects: Safe.@n
* @e Shared @e objects: Unsafe. * @e Shared @e objects: Unsafe.
*/ */
template <typename SerialPortService = serial_port_service> template <typename Executor = executor>
class basic_serial_port class basic_serial_port
: public basic_io_object<SerialPortService>, : public serial_port_base
public serial_port_base
{ {
public: public:
/// The native representation of a serial port. /// The type of the executor associated with the object.
typedef typename SerialPortService::native_handle_type native_handle_type; typedef Executor executor_type;
/// A basic_serial_port is always the lowest layer. /// The native representation of a serial port.
typedef basic_serial_port<SerialPortService> lowest_layer_type; #if defined(GENERATING_DOCUMENTATION)
typedef implementation_defined native_handle_type;
#elif defined(BOOST_ASIO_HAS_IOCP)
typedef detail::win_iocp_serial_port_service::native_handle_type
native_handle_type;
#else
typedef detail::reactive_serial_port_service::native_handle_type
native_handle_type;
#endif
/// A basic_basic_serial_port is always the lowest layer.
typedef basic_serial_port lowest_layer_type;
/// Construct a basic_serial_port without opening it. /// Construct a basic_serial_port without opening it.
/** /**
* This constructor creates a serial port without opening it. * This constructor creates a serial port without opening it.
* *
* @param io_context The io_context object that the serial port will use to * @param ex The I/O executor that the serial port will use, by default, to
* dispatch handlers for any asynchronous operations performed on the port. * dispatch handlers for any asynchronous operations performed on the
* serial port.
*/ */
explicit basic_serial_port(boost::asio::io_context& io_context) explicit basic_serial_port(const executor_type& ex)
: basic_io_object<SerialPortService>(io_context) : impl_(ex)
{
}
/// Construct a basic_serial_port without opening it.
/**
* This constructor creates a serial port without opening it.
*
* @param context An execution context which provides the I/O executor that
* the serial port will use, by default, to dispatch handlers for any
* asynchronous operations performed on the serial port.
*/
template <typename ExecutionContext>
explicit basic_serial_port(ExecutionContext& context,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value,
basic_serial_port
>::type* = 0)
: impl_(context)
{ {
} }
@ -74,18 +114,18 @@ public:
* This constructor creates and opens a serial port for the specified device * This constructor creates and opens a serial port for the specified device
* name. * name.
* *
* @param io_context The io_context object that the serial port will use to * @param ex The I/O executor that the serial port will use, by default, to
* dispatch handlers for any asynchronous operations performed on the port. * dispatch handlers for any asynchronous operations performed on the
* serial port.
* *
* @param device The platform-specific device name for this serial * @param device The platform-specific device name for this serial
* port. * port.
*/ */
explicit basic_serial_port(boost::asio::io_context& io_context, basic_serial_port(const executor_type& ex, const char* device)
const char* device) : impl_(ex)
: basic_io_object<SerialPortService>(io_context)
{ {
boost::system::error_code ec; boost::system::error_code ec;
this->get_service().open(this->get_implementation(), device, ec); impl_.get_service().open(impl_.get_implementation(), device, ec);
boost::asio::detail::throw_error(ec, "open"); boost::asio::detail::throw_error(ec, "open");
} }
@ -94,18 +134,66 @@ public:
* This constructor creates and opens a serial port for the specified device * This constructor creates and opens a serial port for the specified device
* name. * name.
* *
* @param io_context The io_context object that the serial port will use to * @param context An execution context which provides the I/O executor that
* dispatch handlers for any asynchronous operations performed on the port. * the serial port will use, by default, to dispatch handlers for any
* asynchronous operations performed on the serial port.
* *
* @param device The platform-specific device name for this serial * @param device The platform-specific device name for this serial
* port. * port.
*/ */
explicit basic_serial_port(boost::asio::io_context& io_context, template <typename ExecutionContext>
const std::string& device) basic_serial_port(ExecutionContext& context, const char* device,
: basic_io_object<SerialPortService>(io_context) typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: impl_(context)
{ {
boost::system::error_code ec; boost::system::error_code ec;
this->get_service().open(this->get_implementation(), device, ec); impl_.get_service().open(impl_.get_implementation(), device, ec);
boost::asio::detail::throw_error(ec, "open");
}
/// Construct and open a basic_serial_port.
/**
* This constructor creates and opens a serial port for the specified device
* name.
*
* @param ex The I/O executor that the serial port will use, by default, to
* dispatch handlers for any asynchronous operations performed on the
* serial port.
*
* @param device The platform-specific device name for this serial
* port.
*/
basic_serial_port(const executor_type& ex, const std::string& device)
: impl_(ex)
{
boost::system::error_code ec;
impl_.get_service().open(impl_.get_implementation(), device, ec);
boost::asio::detail::throw_error(ec, "open");
}
/// Construct and open a basic_serial_port.
/**
* This constructor creates and opens a serial port for the specified device
* name.
*
* @param context An execution context which provides the I/O executor that
* the serial port will use, by default, to dispatch handlers for any
* asynchronous operations performed on the serial port.
*
* @param device The platform-specific device name for this serial
* port.
*/
template <typename ExecutionContext>
basic_serial_port(ExecutionContext& context, const std::string& device,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: impl_(context)
{
boost::system::error_code ec;
impl_.get_service().open(impl_.get_implementation(), device, ec);
boost::asio::detail::throw_error(ec, "open"); boost::asio::detail::throw_error(ec, "open");
} }
@ -114,19 +202,47 @@ public:
* This constructor creates a serial port object to hold an existing native * This constructor creates a serial port object to hold an existing native
* serial port. * serial port.
* *
* @param io_context The io_context object that the serial port will use to * @param ex The I/O executor that the serial port will use, by default, to
* dispatch handlers for any asynchronous operations performed on the port. * dispatch handlers for any asynchronous operations performed on the
* serial port.
* *
* @param native_serial_port A native serial port. * @param native_serial_port A native serial port.
* *
* @throws boost::system::system_error Thrown on failure. * @throws boost::system::system_error Thrown on failure.
*/ */
basic_serial_port(boost::asio::io_context& io_context, basic_serial_port(const executor_type& ex,
const native_handle_type& native_serial_port) const native_handle_type& native_serial_port)
: basic_io_object<SerialPortService>(io_context) : impl_(ex)
{ {
boost::system::error_code ec; boost::system::error_code ec;
this->get_service().assign(this->get_implementation(), impl_.get_service().assign(impl_.get_implementation(),
native_serial_port, ec);
boost::asio::detail::throw_error(ec, "assign");
}
/// Construct a basic_serial_port on an existing native serial port.
/**
* This constructor creates a serial port object to hold an existing native
* serial port.
*
* @param context An execution context which provides the I/O executor that
* the serial port will use, by default, to dispatch handlers for any
* asynchronous operations performed on the serial port.
*
* @param native_serial_port A native serial port.
*
* @throws boost::system::system_error Thrown on failure.
*/
template <typename ExecutionContext>
basic_serial_port(ExecutionContext& context,
const native_handle_type& native_serial_port,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: impl_(context)
{
boost::system::error_code ec;
impl_.get_service().assign(impl_.get_implementation(),
native_serial_port, ec); native_serial_port, ec);
boost::asio::detail::throw_error(ec, "assign"); boost::asio::detail::throw_error(ec, "assign");
} }
@ -140,11 +256,11 @@ public:
* occur. * occur.
* *
* @note Following the move, the moved-from object is in the same state as if * @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_serial_port(io_context&) constructor. * constructed using the @c basic_serial_port(const executor_type&)
* constructor.
*/ */
basic_serial_port(basic_serial_port&& other) basic_serial_port(basic_serial_port&& other)
: basic_io_object<SerialPortService>( : impl_(std::move(other.impl_))
BOOST_ASIO_MOVE_CAST(basic_serial_port)(other))
{ {
} }
@ -156,16 +272,32 @@ public:
* occur. * occur.
* *
* @note Following the move, the moved-from object is in the same state as if * @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_serial_port(io_context&) constructor. * constructed using the @c basic_serial_port(const executor_type&)
* constructor.
*/ */
basic_serial_port& operator=(basic_serial_port&& other) basic_serial_port& operator=(basic_serial_port&& other)
{ {
basic_io_object<SerialPortService>::operator=( impl_ = std::move(other.impl_);
BOOST_ASIO_MOVE_CAST(basic_serial_port)(other));
return *this; return *this;
} }
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
/// Destroys the serial port.
/**
* This function destroys the serial port, cancelling any outstanding
* asynchronous wait operations associated with the serial port as if by
* calling @c cancel.
*/
~basic_serial_port()
{
}
/// Get the executor associated with the object.
executor_type get_executor() BOOST_ASIO_NOEXCEPT
{
return impl_.get_executor();
}
/// Get a reference to the lowest layer. /// Get a reference to the lowest layer.
/** /**
* This function returns a reference to the lowest layer in a stack of * This function returns a reference to the lowest layer in a stack of
@ -205,7 +337,7 @@ public:
void open(const std::string& device) void open(const std::string& device)
{ {
boost::system::error_code ec; boost::system::error_code ec;
this->get_service().open(this->get_implementation(), device, ec); impl_.get_service().open(impl_.get_implementation(), device, ec);
boost::asio::detail::throw_error(ec, "open"); boost::asio::detail::throw_error(ec, "open");
} }
@ -221,7 +353,7 @@ public:
BOOST_ASIO_SYNC_OP_VOID open(const std::string& device, BOOST_ASIO_SYNC_OP_VOID open(const std::string& device,
boost::system::error_code& ec) boost::system::error_code& ec)
{ {
this->get_service().open(this->get_implementation(), device, ec); impl_.get_service().open(impl_.get_implementation(), device, ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
} }
@ -236,7 +368,7 @@ public:
void assign(const native_handle_type& native_serial_port) void assign(const native_handle_type& native_serial_port)
{ {
boost::system::error_code ec; boost::system::error_code ec;
this->get_service().assign(this->get_implementation(), impl_.get_service().assign(impl_.get_implementation(),
native_serial_port, ec); native_serial_port, ec);
boost::asio::detail::throw_error(ec, "assign"); boost::asio::detail::throw_error(ec, "assign");
} }
@ -252,7 +384,7 @@ public:
BOOST_ASIO_SYNC_OP_VOID assign(const native_handle_type& native_serial_port, BOOST_ASIO_SYNC_OP_VOID assign(const native_handle_type& native_serial_port,
boost::system::error_code& ec) boost::system::error_code& ec)
{ {
this->get_service().assign(this->get_implementation(), impl_.get_service().assign(impl_.get_implementation(),
native_serial_port, ec); native_serial_port, ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
} }
@ -260,7 +392,7 @@ public:
/// Determine whether the serial port is open. /// Determine whether the serial port is open.
bool is_open() const bool is_open() const
{ {
return this->get_service().is_open(this->get_implementation()); return impl_.get_service().is_open(impl_.get_implementation());
} }
/// Close the serial port. /// Close the serial port.
@ -274,7 +406,7 @@ public:
void close() void close()
{ {
boost::system::error_code ec; boost::system::error_code ec;
this->get_service().close(this->get_implementation(), ec); impl_.get_service().close(impl_.get_implementation(), ec);
boost::asio::detail::throw_error(ec, "close"); boost::asio::detail::throw_error(ec, "close");
} }
@ -288,7 +420,7 @@ public:
*/ */
BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec) BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec)
{ {
this->get_service().close(this->get_implementation(), ec); impl_.get_service().close(impl_.get_implementation(), ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
} }
@ -300,7 +432,7 @@ public:
*/ */
native_handle_type native_handle() native_handle_type native_handle()
{ {
return this->get_service().native_handle(this->get_implementation()); return impl_.get_service().native_handle(impl_.get_implementation());
} }
/// Cancel all asynchronous operations associated with the serial port. /// Cancel all asynchronous operations associated with the serial port.
@ -314,7 +446,7 @@ public:
void cancel() void cancel()
{ {
boost::system::error_code ec; boost::system::error_code ec;
this->get_service().cancel(this->get_implementation(), ec); impl_.get_service().cancel(impl_.get_implementation(), ec);
boost::asio::detail::throw_error(ec, "cancel"); boost::asio::detail::throw_error(ec, "cancel");
} }
@ -328,7 +460,7 @@ public:
*/ */
BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec) BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec)
{ {
this->get_service().cancel(this->get_implementation(), ec); impl_.get_service().cancel(impl_.get_implementation(), ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
} }
@ -342,7 +474,7 @@ public:
void send_break() void send_break()
{ {
boost::system::error_code ec; boost::system::error_code ec;
this->get_service().send_break(this->get_implementation(), ec); impl_.get_service().send_break(impl_.get_implementation(), ec);
boost::asio::detail::throw_error(ec, "send_break"); boost::asio::detail::throw_error(ec, "send_break");
} }
@ -355,7 +487,7 @@ public:
*/ */
BOOST_ASIO_SYNC_OP_VOID send_break(boost::system::error_code& ec) BOOST_ASIO_SYNC_OP_VOID send_break(boost::system::error_code& ec)
{ {
this->get_service().send_break(this->get_implementation(), ec); impl_.get_service().send_break(impl_.get_implementation(), ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
} }
@ -378,7 +510,7 @@ public:
void set_option(const SettableSerialPortOption& option) void set_option(const SettableSerialPortOption& option)
{ {
boost::system::error_code ec; boost::system::error_code ec;
this->get_service().set_option(this->get_implementation(), option, ec); impl_.get_service().set_option(impl_.get_implementation(), option, ec);
boost::asio::detail::throw_error(ec, "set_option"); boost::asio::detail::throw_error(ec, "set_option");
} }
@ -401,7 +533,7 @@ public:
BOOST_ASIO_SYNC_OP_VOID set_option(const SettableSerialPortOption& option, BOOST_ASIO_SYNC_OP_VOID set_option(const SettableSerialPortOption& option,
boost::system::error_code& ec) boost::system::error_code& ec)
{ {
this->get_service().set_option(this->get_implementation(), option, ec); impl_.get_service().set_option(impl_.get_implementation(), option, ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
} }
@ -422,10 +554,10 @@ public:
* boost::asio::serial_port_base::character_size * boost::asio::serial_port_base::character_size
*/ */
template <typename GettableSerialPortOption> template <typename GettableSerialPortOption>
void get_option(GettableSerialPortOption& option) void get_option(GettableSerialPortOption& option) const
{ {
boost::system::error_code ec; boost::system::error_code ec;
this->get_service().get_option(this->get_implementation(), option, ec); impl_.get_service().get_option(impl_.get_implementation(), option, ec);
boost::asio::detail::throw_error(ec, "get_option"); boost::asio::detail::throw_error(ec, "get_option");
} }
@ -447,9 +579,9 @@ public:
*/ */
template <typename GettableSerialPortOption> template <typename GettableSerialPortOption>
BOOST_ASIO_SYNC_OP_VOID get_option(GettableSerialPortOption& option, BOOST_ASIO_SYNC_OP_VOID get_option(GettableSerialPortOption& option,
boost::system::error_code& ec) boost::system::error_code& ec) const
{ {
this->get_service().get_option(this->get_implementation(), option, ec); impl_.get_service().get_option(impl_.get_implementation(), option, ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
} }
@ -474,7 +606,7 @@ public:
* @par Example * @par Example
* To write a single data buffer use the @ref buffer function as follows: * To write a single data buffer use the @ref buffer function as follows:
* @code * @code
* serial_port.write_some(boost::asio::buffer(data, size)); * basic_serial_port.write_some(boost::asio::buffer(data, size));
* @endcode * @endcode
* See the @ref buffer documentation for information on writing multiple * See the @ref buffer documentation for information on writing multiple
* buffers in one go, and how to use it with arrays, boost::array or * buffers in one go, and how to use it with arrays, boost::array or
@ -484,8 +616,8 @@ public:
std::size_t write_some(const ConstBufferSequence& buffers) std::size_t write_some(const ConstBufferSequence& buffers)
{ {
boost::system::error_code ec; boost::system::error_code ec;
std::size_t s = this->get_service().write_some( std::size_t s = impl_.get_service().write_some(
this->get_implementation(), buffers, ec); impl_.get_implementation(), buffers, ec);
boost::asio::detail::throw_error(ec, "write_some"); boost::asio::detail::throw_error(ec, "write_some");
return s; return s;
} }
@ -510,8 +642,8 @@ public:
std::size_t write_some(const ConstBufferSequence& buffers, std::size_t write_some(const ConstBufferSequence& buffers,
boost::system::error_code& ec) boost::system::error_code& ec)
{ {
return this->get_service().write_some( return impl_.get_service().write_some(
this->get_implementation(), buffers, ec); impl_.get_implementation(), buffers, ec);
} }
/// Start an asynchronous write. /// Start an asynchronous write.
@ -532,9 +664,9 @@ public:
* std::size_t bytes_transferred // Number of bytes written. * std::size_t bytes_transferred // Number of bytes written.
* ); @endcode * ); @endcode
* Regardless of whether the asynchronous operation completes immediately or * Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation * not, the handler will not be invoked from within this function. On
* of the handler will be performed in a manner equivalent to using * immediate completion, invocation of the handler will be performed in a
* boost::asio::io_context::post(). * manner equivalent to using boost::asio::post().
* *
* @note The write operation may not transmit all of the data to the peer. * @note The write operation may not transmit all of the data to the peer.
* Consider using the @ref async_write function if you need to ensure that all * Consider using the @ref async_write function if you need to ensure that all
@ -543,7 +675,8 @@ public:
* @par Example * @par Example
* To write a single data buffer use the @ref buffer function as follows: * To write a single data buffer use the @ref buffer function as follows:
* @code * @code
* serial_port.async_write_some(boost::asio::buffer(data, size), handler); * basic_serial_port.async_write_some(
* boost::asio::buffer(data, size), handler);
* @endcode * @endcode
* See the @ref buffer documentation for information on writing multiple * See the @ref buffer documentation for information on writing multiple
* buffers in one go, and how to use it with arrays, boost::array or * buffers in one go, and how to use it with arrays, boost::array or
@ -555,12 +688,9 @@ public:
async_write_some(const ConstBufferSequence& buffers, async_write_some(const ConstBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler) BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{ {
// If you get an error on the following line it means that your handler does return async_initiate<WriteHandler,
// not meet the documented type requirements for a WriteHandler. void (boost::system::error_code, std::size_t)>(
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; initiate_async_write_some(), handler, this, buffers);
return this->get_service().async_write_some(this->get_implementation(),
buffers, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
} }
/// Read some data from the serial port. /// Read some data from the serial port.
@ -585,7 +715,7 @@ public:
* @par Example * @par Example
* To read into a single data buffer use the @ref buffer function as follows: * To read into a single data buffer use the @ref buffer function as follows:
* @code * @code
* serial_port.read_some(boost::asio::buffer(data, size)); * basic_serial_port.read_some(boost::asio::buffer(data, size));
* @endcode * @endcode
* See the @ref buffer documentation for information on reading into multiple * See the @ref buffer documentation for information on reading into multiple
* buffers in one go, and how to use it with arrays, boost::array or * buffers in one go, and how to use it with arrays, boost::array or
@ -595,8 +725,8 @@ public:
std::size_t read_some(const MutableBufferSequence& buffers) std::size_t read_some(const MutableBufferSequence& buffers)
{ {
boost::system::error_code ec; boost::system::error_code ec;
std::size_t s = this->get_service().read_some( std::size_t s = impl_.get_service().read_some(
this->get_implementation(), buffers, ec); impl_.get_implementation(), buffers, ec);
boost::asio::detail::throw_error(ec, "read_some"); boost::asio::detail::throw_error(ec, "read_some");
return s; return s;
} }
@ -622,8 +752,8 @@ public:
std::size_t read_some(const MutableBufferSequence& buffers, std::size_t read_some(const MutableBufferSequence& buffers,
boost::system::error_code& ec) boost::system::error_code& ec)
{ {
return this->get_service().read_some( return impl_.get_service().read_some(
this->get_implementation(), buffers, ec); impl_.get_implementation(), buffers, ec);
} }
/// Start an asynchronous read. /// Start an asynchronous read.
@ -644,9 +774,9 @@ public:
* std::size_t bytes_transferred // Number of bytes read. * std::size_t bytes_transferred // Number of bytes read.
* ); @endcode * ); @endcode
* Regardless of whether the asynchronous operation completes immediately or * Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation * not, the handler will not be invoked from within this function. On
* of the handler will be performed in a manner equivalent to using * immediate completion, invocation of the handler will be performed in a
* boost::asio::io_context::post(). * manner equivalent to using boost::asio::post().
* *
* @note The read operation may not read all of the requested number of bytes. * @note The read operation may not read all of the requested number of bytes.
* Consider using the @ref async_read function if you need to ensure that the * Consider using the @ref async_read function if you need to ensure that the
@ -656,7 +786,8 @@ public:
* @par Example * @par Example
* To read into a single data buffer use the @ref buffer function as follows: * To read into a single data buffer use the @ref buffer function as follows:
* @code * @code
* serial_port.async_read_some(boost::asio::buffer(data, size), handler); * basic_serial_port.async_read_some(
* boost::asio::buffer(data, size), handler);
* @endcode * @endcode
* See the @ref buffer documentation for information on reading into multiple * See the @ref buffer documentation for information on reading into multiple
* buffers in one go, and how to use it with arrays, boost::array or * buffers in one go, and how to use it with arrays, boost::array or
@ -668,13 +799,55 @@ public:
async_read_some(const MutableBufferSequence& buffers, async_read_some(const MutableBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler) BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{ {
// If you get an error on the following line it means that your handler does return async_initiate<ReadHandler,
// not meet the documented type requirements for a ReadHandler. void (boost::system::error_code, std::size_t)>(
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; initiate_async_read_some(), handler, this, buffers);
return this->get_service().async_read_some(this->get_implementation(),
buffers, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
} }
private:
// Disallow copying and assignment.
basic_serial_port(const basic_serial_port&) BOOST_ASIO_DELETED;
basic_serial_port& operator=(const basic_serial_port&) BOOST_ASIO_DELETED;
struct initiate_async_write_some
{
template <typename WriteHandler, typename ConstBufferSequence>
void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
basic_serial_port* self, const ConstBufferSequence& buffers) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a WriteHandler.
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
detail::non_const_lvalue<WriteHandler> handler2(handler);
self->impl_.get_service().async_write_some(
self->impl_.get_implementation(), buffers, handler2.value,
self->impl_.get_implementation_executor());
}
};
struct initiate_async_read_some
{
template <typename ReadHandler, typename MutableBufferSequence>
void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
basic_serial_port* self, const MutableBufferSequence& buffers) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a ReadHandler.
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
detail::non_const_lvalue<ReadHandler> handler2(handler);
self->impl_.get_service().async_read_some(
self->impl_.get_implementation(), buffers, handler2.value,
self->impl_.get_implementation_executor());
}
};
#if defined(BOOST_ASIO_HAS_IOCP)
detail::io_object_impl<detail::win_iocp_serial_port_service, Executor> impl_;
#else
detail::io_object_impl<detail::reactive_serial_port_service, Executor> impl_;
#endif
}; };
} // namespace asio } // namespace asio
@ -685,6 +858,4 @@ public:
#endif // defined(BOOST_ASIO_HAS_SERIAL_PORT) #endif // defined(BOOST_ASIO_HAS_SERIAL_PORT)
// || defined(GENERATING_DOCUMENTATION) // || defined(GENERATING_DOCUMENTATION)
#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
#endif // BOOST_ASIO_BASIC_SERIAL_PORT_HPP #endif // BOOST_ASIO_BASIC_SERIAL_PORT_HPP

View File

@ -2,7 +2,7 @@
// basic_signal_set.hpp // basic_signal_set.hpp
// ~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -17,25 +17,24 @@
#include <boost/asio/detail/config.hpp> #include <boost/asio/detail/config.hpp>
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) #include <boost/asio/async_result.hpp>
#include <boost/asio/basic_io_object.hpp>
#include <boost/asio/detail/handler_type_requirements.hpp> #include <boost/asio/detail/handler_type_requirements.hpp>
#include <boost/asio/detail/io_object_impl.hpp>
#include <boost/asio/detail/non_const_lvalue.hpp>
#include <boost/asio/detail/signal_set_service.hpp>
#include <boost/asio/detail/throw_error.hpp> #include <boost/asio/detail/throw_error.hpp>
#include <boost/asio/detail/type_traits.hpp>
#include <boost/asio/error.hpp> #include <boost/asio/error.hpp>
#include <boost/asio/signal_set_service.hpp> #include <boost/asio/execution_context.hpp>
#include <boost/asio/executor.hpp>
#include <boost/asio/detail/push_options.hpp>
namespace boost { namespace boost {
namespace asio { namespace asio {
/// Provides signal functionality. /// Provides signal functionality.
/** /**
* The basic_signal_set class template provides the ability to perform an * The basic_signal_set class provides the ability to perform an asynchronous
* asynchronous wait for one or more signals to occur. * wait for one or more signals to occur.
*
* Most applications will use the boost::asio::signal_set typedef.
* *
* @par Thread Safety * @par Thread Safety
* @e Distinct @e objects: Safe.@n * @e Distinct @e objects: Safe.@n
@ -57,7 +56,7 @@ namespace asio {
* ... * ...
* *
* // Construct a signal set registered for process termination. * // Construct a signal set registered for process termination.
* boost::asio::signal_set signals(io_context, SIGINT, SIGTERM); * boost::asio::signal_set signals(my_context, SIGINT, SIGTERM);
* *
* // Start an asynchronous wait for one of the signals to occur. * // Start an asynchronous wait for one of the signals to occur.
* signals.async_wait(handler); * signals.async_wait(handler);
@ -92,20 +91,40 @@ namespace asio {
* that any signals registered using signal_set objects are unblocked in at * that any signals registered using signal_set objects are unblocked in at
* least one thread. * least one thread.
*/ */
template <typename SignalSetService = signal_set_service> template <typename Executor = executor>
class basic_signal_set class basic_signal_set
: public basic_io_object<SignalSetService>
{ {
public: public:
/// The type of the executor associated with the object.
typedef Executor executor_type;
/// Construct a signal set without adding any signals. /// Construct a signal set without adding any signals.
/** /**
* This constructor creates a signal set without registering for any signals. * This constructor creates a signal set without registering for any signals.
* *
* @param io_context The io_context object that the signal set will use to * @param ex The I/O executor that the signal set will use, by default, to
* dispatch handlers for any asynchronous operations performed on the set. * dispatch handlers for any asynchronous operations performed on the
* signal set.
*/ */
explicit basic_signal_set(boost::asio::io_context& io_context) explicit basic_signal_set(const executor_type& ex)
: basic_io_object<SignalSetService>(io_context) : impl_(ex)
{
}
/// Construct a signal set without adding any signals.
/**
* This constructor creates a signal set without registering for any signals.
*
* @param context An execution context which provides the I/O executor that
* the signal set will use, by default, to dispatch handlers for any
* asynchronous operations performed on the signal set.
*/
template <typename ExecutionContext>
explicit basic_signal_set(ExecutionContext& context,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: impl_(context)
{ {
} }
@ -113,20 +132,47 @@ public:
/** /**
* This constructor creates a signal set and registers for one signal. * This constructor creates a signal set and registers for one signal.
* *
* @param io_context The io_context object that the signal set will use to * @param ex The I/O executor that the signal set will use, by default, to
* dispatch handlers for any asynchronous operations performed on the set. * dispatch handlers for any asynchronous operations performed on the
* signal set.
* *
* @param signal_number_1 The signal number to be added. * @param signal_number_1 The signal number to be added.
* *
* @note This constructor is equivalent to performing: * @note This constructor is equivalent to performing:
* @code boost::asio::signal_set signals(io_context); * @code boost::asio::signal_set signals(ex);
* signals.add(signal_number_1); @endcode * signals.add(signal_number_1); @endcode
*/ */
basic_signal_set(boost::asio::io_context& io_context, int signal_number_1) basic_signal_set(const executor_type& ex, int signal_number_1)
: basic_io_object<SignalSetService>(io_context) : impl_(ex)
{ {
boost::system::error_code ec; boost::system::error_code ec;
this->get_service().add(this->get_implementation(), signal_number_1, ec); impl_.get_service().add(impl_.get_implementation(), signal_number_1, ec);
boost::asio::detail::throw_error(ec, "add");
}
/// Construct a signal set and add one signal.
/**
* This constructor creates a signal set and registers for one signal.
*
* @param context An execution context which provides the I/O executor that
* the signal set will use, by default, to dispatch handlers for any
* asynchronous operations performed on the signal set.
*
* @param signal_number_1 The signal number to be added.
*
* @note This constructor is equivalent to performing:
* @code boost::asio::signal_set signals(context);
* signals.add(signal_number_1); @endcode
*/
template <typename ExecutionContext>
basic_signal_set(ExecutionContext& context, int signal_number_1,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: impl_(context)
{
boost::system::error_code ec;
impl_.get_service().add(impl_.get_implementation(), signal_number_1, ec);
boost::asio::detail::throw_error(ec, "add"); boost::asio::detail::throw_error(ec, "add");
} }
@ -134,26 +180,59 @@ public:
/** /**
* This constructor creates a signal set and registers for two signals. * This constructor creates a signal set and registers for two signals.
* *
* @param io_context The io_context object that the signal set will use to * @param ex The I/O executor that the signal set will use, by default, to
* dispatch handlers for any asynchronous operations performed on the set. * dispatch handlers for any asynchronous operations performed on the
* signal set.
* *
* @param signal_number_1 The first signal number to be added. * @param signal_number_1 The first signal number to be added.
* *
* @param signal_number_2 The second signal number to be added. * @param signal_number_2 The second signal number to be added.
* *
* @note This constructor is equivalent to performing: * @note This constructor is equivalent to performing:
* @code boost::asio::signal_set signals(io_context); * @code boost::asio::signal_set signals(ex);
* signals.add(signal_number_1); * signals.add(signal_number_1);
* signals.add(signal_number_2); @endcode * signals.add(signal_number_2); @endcode
*/ */
basic_signal_set(boost::asio::io_context& io_context, int signal_number_1, basic_signal_set(const executor_type& ex, int signal_number_1,
int signal_number_2) int signal_number_2)
: basic_io_object<SignalSetService>(io_context) : impl_(ex)
{ {
boost::system::error_code ec; boost::system::error_code ec;
this->get_service().add(this->get_implementation(), signal_number_1, ec); impl_.get_service().add(impl_.get_implementation(), signal_number_1, ec);
boost::asio::detail::throw_error(ec, "add"); boost::asio::detail::throw_error(ec, "add");
this->get_service().add(this->get_implementation(), signal_number_2, ec); impl_.get_service().add(impl_.get_implementation(), signal_number_2, ec);
boost::asio::detail::throw_error(ec, "add");
}
/// Construct a signal set and add two signals.
/**
* This constructor creates a signal set and registers for two signals.
*
* @param context An execution context which provides the I/O executor that
* the signal set will use, by default, to dispatch handlers for any
* asynchronous operations performed on the signal set.
*
* @param signal_number_1 The first signal number to be added.
*
* @param signal_number_2 The second signal number to be added.
*
* @note This constructor is equivalent to performing:
* @code boost::asio::signal_set signals(context);
* signals.add(signal_number_1);
* signals.add(signal_number_2); @endcode
*/
template <typename ExecutionContext>
basic_signal_set(ExecutionContext& context, int signal_number_1,
int signal_number_2,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: impl_(context)
{
boost::system::error_code ec;
impl_.get_service().add(impl_.get_implementation(), signal_number_1, ec);
boost::asio::detail::throw_error(ec, "add");
impl_.get_service().add(impl_.get_implementation(), signal_number_2, ec);
boost::asio::detail::throw_error(ec, "add"); boost::asio::detail::throw_error(ec, "add");
} }
@ -161,8 +240,9 @@ public:
/** /**
* This constructor creates a signal set and registers for three signals. * This constructor creates a signal set and registers for three signals.
* *
* @param io_context The io_context object that the signal set will use to * @param ex The I/O executor that the signal set will use, by default, to
* dispatch handlers for any asynchronous operations performed on the set. * dispatch handlers for any asynchronous operations performed on the
* signal set.
* *
* @param signal_number_1 The first signal number to be added. * @param signal_number_1 The first signal number to be added.
* *
@ -171,24 +251,77 @@ public:
* @param signal_number_3 The third signal number to be added. * @param signal_number_3 The third signal number to be added.
* *
* @note This constructor is equivalent to performing: * @note This constructor is equivalent to performing:
* @code boost::asio::signal_set signals(io_context); * @code boost::asio::signal_set signals(ex);
* signals.add(signal_number_1); * signals.add(signal_number_1);
* signals.add(signal_number_2); * signals.add(signal_number_2);
* signals.add(signal_number_3); @endcode * signals.add(signal_number_3); @endcode
*/ */
basic_signal_set(boost::asio::io_context& io_context, int signal_number_1, basic_signal_set(const executor_type& ex, int signal_number_1,
int signal_number_2, int signal_number_3) int signal_number_2, int signal_number_3)
: basic_io_object<SignalSetService>(io_context) : impl_(ex)
{ {
boost::system::error_code ec; boost::system::error_code ec;
this->get_service().add(this->get_implementation(), signal_number_1, ec); impl_.get_service().add(impl_.get_implementation(), signal_number_1, ec);
boost::asio::detail::throw_error(ec, "add"); boost::asio::detail::throw_error(ec, "add");
this->get_service().add(this->get_implementation(), signal_number_2, ec); impl_.get_service().add(impl_.get_implementation(), signal_number_2, ec);
boost::asio::detail::throw_error(ec, "add"); boost::asio::detail::throw_error(ec, "add");
this->get_service().add(this->get_implementation(), signal_number_3, ec); impl_.get_service().add(impl_.get_implementation(), signal_number_3, ec);
boost::asio::detail::throw_error(ec, "add"); boost::asio::detail::throw_error(ec, "add");
} }
/// Construct a signal set and add three signals.
/**
* This constructor creates a signal set and registers for three signals.
*
* @param context An execution context which provides the I/O executor that
* the signal set will use, by default, to dispatch handlers for any
* asynchronous operations performed on the signal set.
*
* @param signal_number_1 The first signal number to be added.
*
* @param signal_number_2 The second signal number to be added.
*
* @param signal_number_3 The third signal number to be added.
*
* @note This constructor is equivalent to performing:
* @code boost::asio::signal_set signals(context);
* signals.add(signal_number_1);
* signals.add(signal_number_2);
* signals.add(signal_number_3); @endcode
*/
template <typename ExecutionContext>
basic_signal_set(ExecutionContext& context, int signal_number_1,
int signal_number_2, int signal_number_3,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: impl_(context)
{
boost::system::error_code ec;
impl_.get_service().add(impl_.get_implementation(), signal_number_1, ec);
boost::asio::detail::throw_error(ec, "add");
impl_.get_service().add(impl_.get_implementation(), signal_number_2, ec);
boost::asio::detail::throw_error(ec, "add");
impl_.get_service().add(impl_.get_implementation(), signal_number_3, ec);
boost::asio::detail::throw_error(ec, "add");
}
/// Destroys the signal set.
/**
* This function destroys the signal set, cancelling any outstanding
* asynchronous wait operations associated with the signal set as if by
* calling @c cancel.
*/
~basic_signal_set()
{
}
/// Get the executor associated with the object.
executor_type get_executor() BOOST_ASIO_NOEXCEPT
{
return impl_.get_executor();
}
/// Add a signal to a signal_set. /// Add a signal to a signal_set.
/** /**
* This function adds the specified signal to the set. It has no effect if the * This function adds the specified signal to the set. It has no effect if the
@ -201,7 +334,7 @@ public:
void add(int signal_number) void add(int signal_number)
{ {
boost::system::error_code ec; boost::system::error_code ec;
this->get_service().add(this->get_implementation(), signal_number, ec); impl_.get_service().add(impl_.get_implementation(), signal_number, ec);
boost::asio::detail::throw_error(ec, "add"); boost::asio::detail::throw_error(ec, "add");
} }
@ -214,9 +347,10 @@ public:
* *
* @param ec Set to indicate what error occurred, if any. * @param ec Set to indicate what error occurred, if any.
*/ */
BOOST_ASIO_SYNC_OP_VOID add(int signal_number, boost::system::error_code& ec) BOOST_ASIO_SYNC_OP_VOID add(int signal_number,
boost::system::error_code& ec)
{ {
this->get_service().add(this->get_implementation(), signal_number, ec); impl_.get_service().add(impl_.get_implementation(), signal_number, ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
} }
@ -235,7 +369,7 @@ public:
void remove(int signal_number) void remove(int signal_number)
{ {
boost::system::error_code ec; boost::system::error_code ec;
this->get_service().remove(this->get_implementation(), signal_number, ec); impl_.get_service().remove(impl_.get_implementation(), signal_number, ec);
boost::asio::detail::throw_error(ec, "remove"); boost::asio::detail::throw_error(ec, "remove");
} }
@ -254,7 +388,7 @@ public:
BOOST_ASIO_SYNC_OP_VOID remove(int signal_number, BOOST_ASIO_SYNC_OP_VOID remove(int signal_number,
boost::system::error_code& ec) boost::system::error_code& ec)
{ {
this->get_service().remove(this->get_implementation(), signal_number, ec); impl_.get_service().remove(impl_.get_implementation(), signal_number, ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
} }
@ -270,7 +404,7 @@ public:
void clear() void clear()
{ {
boost::system::error_code ec; boost::system::error_code ec;
this->get_service().clear(this->get_implementation(), ec); impl_.get_service().clear(impl_.get_implementation(), ec);
boost::asio::detail::throw_error(ec, "clear"); boost::asio::detail::throw_error(ec, "clear");
} }
@ -285,7 +419,7 @@ public:
*/ */
BOOST_ASIO_SYNC_OP_VOID clear(boost::system::error_code& ec) BOOST_ASIO_SYNC_OP_VOID clear(boost::system::error_code& ec)
{ {
this->get_service().clear(this->get_implementation(), ec); impl_.get_service().clear(impl_.get_implementation(), ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
} }
@ -313,7 +447,7 @@ public:
void cancel() void cancel()
{ {
boost::system::error_code ec; boost::system::error_code ec;
this->get_service().cancel(this->get_implementation(), ec); impl_.get_service().cancel(impl_.get_implementation(), ec);
boost::asio::detail::throw_error(ec, "cancel"); boost::asio::detail::throw_error(ec, "cancel");
} }
@ -340,7 +474,7 @@ public:
*/ */
BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec) BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec)
{ {
this->get_service().cancel(this->get_implementation(), ec); impl_.get_service().cancel(impl_.get_implementation(), ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
} }
@ -365,29 +499,45 @@ public:
* int signal_number // Indicates which signal occurred. * int signal_number // Indicates which signal occurred.
* ); @endcode * ); @endcode
* Regardless of whether the asynchronous operation completes immediately or * Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation * not, the handler will not be invoked from within this function. On
* of the handler will be performed in a manner equivalent to using * immediate completion, invocation of the handler will be performed in a
* boost::asio::io_context::post(). * manner equivalent to using boost::asio::post().
*/ */
template <typename SignalHandler> template <typename SignalHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(SignalHandler, BOOST_ASIO_INITFN_RESULT_TYPE(SignalHandler,
void (boost::system::error_code, int)) void (boost::system::error_code, int))
async_wait(BOOST_ASIO_MOVE_ARG(SignalHandler) handler) async_wait(BOOST_ASIO_MOVE_ARG(SignalHandler) handler)
{ {
// If you get an error on the following line it means that your handler does return async_initiate<SignalHandler, void (boost::system::error_code, int)>(
// not meet the documented type requirements for a SignalHandler. initiate_async_wait(), handler, this);
BOOST_ASIO_SIGNAL_HANDLER_CHECK(SignalHandler, handler) type_check;
return this->get_service().async_wait(this->get_implementation(),
BOOST_ASIO_MOVE_CAST(SignalHandler)(handler));
} }
private:
// Disallow copying and assignment.
basic_signal_set(const basic_signal_set&) BOOST_ASIO_DELETED;
basic_signal_set& operator=(const basic_signal_set&) BOOST_ASIO_DELETED;
struct initiate_async_wait
{
template <typename SignalHandler>
void operator()(BOOST_ASIO_MOVE_ARG(SignalHandler) handler,
basic_signal_set* self) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a SignalHandler.
BOOST_ASIO_SIGNAL_HANDLER_CHECK(SignalHandler, handler) type_check;
detail::non_const_lvalue<SignalHandler> handler2(handler);
self->impl_.get_service().async_wait(
self->impl_.get_implementation(), handler2.value,
self->impl_.get_implementation_executor());
}
};
detail::io_object_impl<detail::signal_set_service, Executor> impl_;
}; };
} // namespace asio } // namespace asio
} // namespace boost } // namespace boost
#include <boost/asio/detail/pop_options.hpp>
#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
#endif // BOOST_ASIO_BASIC_SIGNAL_SET_HPP #endif // BOOST_ASIO_BASIC_SIGNAL_SET_HPP

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@
// basic_socket_iostream.hpp // basic_socket_iostream.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -23,10 +23,6 @@
#include <ostream> #include <ostream>
#include <boost/asio/basic_socket_streambuf.hpp> #include <boost/asio/basic_socket_streambuf.hpp>
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
# include <boost/asio/stream_socket_service.hpp>
#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
#if !defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) #if !defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
# include <boost/asio/detail/variadic_templates.hpp> # include <boost/asio/detail/variadic_templates.hpp>
@ -36,8 +32,7 @@
// explicit basic_socket_iostream(T1 x1, ..., Tn xn) // explicit basic_socket_iostream(T1 x1, ..., Tn xn)
// : std::basic_iostream<char>( // : std::basic_iostream<char>(
// &this->detail::socket_iostream_base< // &this->detail::socket_iostream_base<
// Protocol BOOST_ASIO_SVC_TARG, Clock, // Protocol, Clock, WaitTraits>::streambuf_)
// WaitTraits BOOST_ASIO_SVC_TARG1>::streambuf_)
// { // {
// if (rdbuf()->connect(x1, ..., xn) == 0) // if (rdbuf()->connect(x1, ..., xn) == 0)
// this->setstate(std::ios_base::failbit); // this->setstate(std::ios_base::failbit);
@ -49,8 +44,7 @@
explicit basic_socket_iostream(BOOST_ASIO_VARIADIC_BYVAL_PARAMS(n)) \ explicit basic_socket_iostream(BOOST_ASIO_VARIADIC_BYVAL_PARAMS(n)) \
: std::basic_iostream<char>( \ : std::basic_iostream<char>( \
&this->detail::socket_iostream_base< \ &this->detail::socket_iostream_base< \
Protocol BOOST_ASIO_SVC_TARG, Clock, \ Protocol, Clock, WaitTraits>::streambuf_) \
WaitTraits BOOST_ASIO_SVC_TARG1>::streambuf_) \
{ \ { \
this->setf(std::ios_base::unitbuf); \ this->setf(std::ios_base::unitbuf); \
if (rdbuf()->connect(BOOST_ASIO_VARIADIC_BYVAL_ARGS(n)) == 0) \ if (rdbuf()->connect(BOOST_ASIO_VARIADIC_BYVAL_ARGS(n)) == 0) \
@ -86,8 +80,7 @@ namespace detail {
// A separate base class is used to ensure that the streambuf is initialised // A separate base class is used to ensure that the streambuf is initialised
// prior to the basic_socket_iostream's basic_iostream base class. // prior to the basic_socket_iostream's basic_iostream base class.
template <typename Protocol BOOST_ASIO_SVC_TPARAM, template <typename Protocol, typename Clock, typename WaitTraits>
typename Clock, typename WaitTraits BOOST_ASIO_SVC_TPARAM1>
class socket_iostream_base class socket_iostream_base
{ {
protected: protected:
@ -113,8 +106,7 @@ protected:
} }
#endif // defined(BOOST_ASIO_HAS_MOVE) #endif // defined(BOOST_ASIO_HAS_MOVE)
basic_socket_streambuf<Protocol BOOST_ASIO_SVC_TARG, basic_socket_streambuf<Protocol, Clock, WaitTraits> streambuf_;
Clock, WaitTraits BOOST_ASIO_SVC_TARG1> streambuf_;
}; };
} // namespace detail } // namespace detail
@ -123,18 +115,15 @@ protected:
#define BOOST_ASIO_BASIC_SOCKET_IOSTREAM_FWD_DECL #define BOOST_ASIO_BASIC_SOCKET_IOSTREAM_FWD_DECL
// Forward declaration with defaulted arguments. // Forward declaration with defaulted arguments.
template <typename Protocol template <typename Protocol,
BOOST_ASIO_SVC_TPARAM_DEF1(= stream_socket_service<Protocol>),
#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) \ #if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) \
&& defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
typename Clock = boost::posix_time::ptime, typename Clock = boost::posix_time::ptime,
typename WaitTraits = time_traits<Clock> typename WaitTraits = time_traits<Clock> >
BOOST_ASIO_SVC_TPARAM1_DEF2(= deadline_timer_service<Clock, WaitTraits>)>
#else // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) #else // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
// && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) // && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
typename Clock = chrono::steady_clock, typename Clock = chrono::steady_clock,
typename WaitTraits = wait_traits<Clock> typename WaitTraits = wait_traits<Clock> >
BOOST_ASIO_SVC_TPARAM1_DEF1(= steady_timer::service_type)>
#endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) #endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
// && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) // && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
class basic_socket_iostream; class basic_socket_iostream;
@ -147,12 +136,10 @@ template <typename Protocol,
typename Clock = chrono::steady_clock, typename Clock = chrono::steady_clock,
typename WaitTraits = wait_traits<Clock> > typename WaitTraits = wait_traits<Clock> >
#else // defined(GENERATING_DOCUMENTATION) #else // defined(GENERATING_DOCUMENTATION)
template <typename Protocol BOOST_ASIO_SVC_TPARAM, template <typename Protocol, typename Clock, typename WaitTraits>
typename Clock, typename WaitTraits BOOST_ASIO_SVC_TPARAM1>
#endif // defined(GENERATING_DOCUMENTATION) #endif // defined(GENERATING_DOCUMENTATION)
class basic_socket_iostream class basic_socket_iostream
: private detail::socket_iostream_base<Protocol : private detail::socket_iostream_base<Protocol, Clock, WaitTraits>,
BOOST_ASIO_SVC_TARG, Clock, WaitTraits BOOST_ASIO_SVC_TARG1>,
public std::basic_iostream<char> public std::basic_iostream<char>
{ {
private: private:
@ -202,8 +189,7 @@ public:
basic_socket_iostream() basic_socket_iostream()
: std::basic_iostream<char>( : std::basic_iostream<char>(
&this->detail::socket_iostream_base< &this->detail::socket_iostream_base<
Protocol BOOST_ASIO_SVC_TARG, Clock, Protocol, Clock, WaitTraits>::streambuf_)
WaitTraits BOOST_ASIO_SVC_TARG1>::streambuf_)
{ {
this->setf(std::ios_base::unitbuf); this->setf(std::ios_base::unitbuf);
} }
@ -212,12 +198,10 @@ public:
/// Construct a basic_socket_iostream from the supplied socket. /// Construct a basic_socket_iostream from the supplied socket.
explicit basic_socket_iostream(basic_stream_socket<protocol_type> s) explicit basic_socket_iostream(basic_stream_socket<protocol_type> s)
: detail::socket_iostream_base< : detail::socket_iostream_base<
Protocol BOOST_ASIO_SVC_TARG, Clock, Protocol, Clock, WaitTraits>(std::move(s)),
WaitTraits BOOST_ASIO_SVC_TARG1>(std::move(s)),
std::basic_iostream<char>( std::basic_iostream<char>(
&this->detail::socket_iostream_base< &this->detail::socket_iostream_base<
Protocol BOOST_ASIO_SVC_TARG, Clock, Protocol, Clock, WaitTraits>::streambuf_)
WaitTraits BOOST_ASIO_SVC_TARG1>::streambuf_)
{ {
this->setf(std::ios_base::unitbuf); this->setf(std::ios_base::unitbuf);
} }
@ -227,13 +211,11 @@ public:
/// Move-construct a basic_socket_iostream from another. /// Move-construct a basic_socket_iostream from another.
basic_socket_iostream(basic_socket_iostream&& other) basic_socket_iostream(basic_socket_iostream&& other)
: detail::socket_iostream_base< : detail::socket_iostream_base<
Protocol BOOST_ASIO_SVC_TARG, Clock, Protocol, Clock, WaitTraits>(std::move(other)),
WaitTraits BOOST_ASIO_SVC_TARG1>(std::move(other)),
std::basic_iostream<char>(std::move(other)) std::basic_iostream<char>(std::move(other))
{ {
this->set_rdbuf(&this->detail::socket_iostream_base< this->set_rdbuf(&this->detail::socket_iostream_base<
Protocol BOOST_ASIO_SVC_TARG, Clock, Protocol, Clock, WaitTraits>::streambuf_);
WaitTraits BOOST_ASIO_SVC_TARG1>::streambuf_);
} }
/// Move-assign a basic_socket_iostream from another. /// Move-assign a basic_socket_iostream from another.
@ -241,8 +223,7 @@ public:
{ {
std::basic_iostream<char>::operator=(std::move(other)); std::basic_iostream<char>::operator=(std::move(other));
detail::socket_iostream_base< detail::socket_iostream_base<
Protocol BOOST_ASIO_SVC_TARG, Clock, Protocol, Clock, WaitTraits>::operator=(std::move(other));
WaitTraits BOOST_ASIO_SVC_TARG1>::operator=(std::move(other));
return *this; return *this;
} }
#endif // defined(BOOST_ASIO_HAS_STD_IOSTREAM_MOVE) #endif // defined(BOOST_ASIO_HAS_STD_IOSTREAM_MOVE)
@ -263,8 +244,7 @@ public:
explicit basic_socket_iostream(T... x) explicit basic_socket_iostream(T... x)
: std::basic_iostream<char>( : std::basic_iostream<char>(
&this->detail::socket_iostream_base< &this->detail::socket_iostream_base<
Protocol BOOST_ASIO_SVC_TARG, Clock, Protocol, Clock, WaitTraits>::streambuf_)
WaitTraits BOOST_ASIO_SVC_TARG1>::streambuf_)
{ {
this->setf(std::ios_base::unitbuf); this->setf(std::ios_base::unitbuf);
if (rdbuf()->connect(x...) == 0) if (rdbuf()->connect(x...) == 0)
@ -302,18 +282,15 @@ public:
} }
/// Return a pointer to the underlying streambuf. /// Return a pointer to the underlying streambuf.
basic_socket_streambuf<Protocol BOOST_ASIO_SVC_TARG, basic_socket_streambuf<Protocol, Clock, WaitTraits>* rdbuf() const
Clock, WaitTraits BOOST_ASIO_SVC_TARG1>* rdbuf() const
{ {
return const_cast<basic_socket_streambuf<Protocol BOOST_ASIO_SVC_TARG, return const_cast<basic_socket_streambuf<Protocol, Clock, WaitTraits>*>(
Clock, WaitTraits BOOST_ASIO_SVC_TARG1>*>(
&this->detail::socket_iostream_base< &this->detail::socket_iostream_base<
Protocol BOOST_ASIO_SVC_TARG, Clock, Protocol, Clock, WaitTraits>::streambuf_);
WaitTraits BOOST_ASIO_SVC_TARG1>::streambuf_);
} }
/// Get a reference to the underlying socket. /// Get a reference to the underlying socket.
basic_socket<Protocol BOOST_ASIO_SVC_TARG>& socket() basic_socket<Protocol>& socket()
{ {
return rdbuf()->socket(); return rdbuf()->socket();
} }

View File

@ -2,7 +2,7 @@
// basic_socket_streambuf.hpp // basic_socket_streambuf.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -28,17 +28,9 @@
#include <boost/asio/detail/throw_error.hpp> #include <boost/asio/detail/throw_error.hpp>
#include <boost/asio/io_context.hpp> #include <boost/asio/io_context.hpp>
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
# include <boost/asio/stream_socket_service.hpp>
#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) \ #if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) \
&& defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
# if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) # include <boost/asio/detail/deadline_timer_service.hpp>
# include <boost/asio/deadline_timer_service.hpp>
# else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
# include <boost/asio/detail/deadline_timer_service.hpp>
# endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
#else // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) #else // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
// && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) // && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
# include <boost/asio/steady_timer.hpp> # include <boost/asio/steady_timer.hpp>
@ -55,7 +47,7 @@
// { // {
// init_buffers(); // init_buffers();
// typedef typename Protocol::resolver resolver_type; // typedef typename Protocol::resolver resolver_type;
// resolver_type resolver(socket().get_executor().context()); // resolver_type resolver(socket().get_executor());
// connect_to_endpoints( // connect_to_endpoints(
// resolver.resolve(x1, ..., xn, ec_)); // resolver.resolve(x1, ..., xn, ec_));
// return !ec_ ? this : 0; // return !ec_ ? this : 0;
@ -68,7 +60,7 @@
{ \ { \
init_buffers(); \ init_buffers(); \
typedef typename Protocol::resolver resolver_type; \ typedef typename Protocol::resolver resolver_type; \
resolver_type resolver(socket().get_executor().context()); \ resolver_type resolver(socket().get_executor()); \
connect_to_endpoints( \ connect_to_endpoints( \
resolver.resolve(BOOST_ASIO_VARIADIC_BYVAL_ARGS(n), ec_)); \ resolver.resolve(BOOST_ASIO_VARIADIC_BYVAL_ARGS(n), ec_)); \
return !ec_ ? this : 0; \ return !ec_ ? this : 0; \
@ -77,10 +69,6 @@
#endif // !defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) #endif // !defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
#if !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
# define BOOST_ASIO_SVC_T1 detail::deadline_timer_service<traits_helper>
#endif // !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
#include <boost/asio/detail/push_options.hpp> #include <boost/asio/detail/push_options.hpp>
namespace boost { namespace boost {
@ -125,18 +113,15 @@ protected:
#define BOOST_ASIO_BASIC_SOCKET_STREAMBUF_FWD_DECL #define BOOST_ASIO_BASIC_SOCKET_STREAMBUF_FWD_DECL
// Forward declaration with defaulted arguments. // Forward declaration with defaulted arguments.
template <typename Protocol template <typename Protocol,
BOOST_ASIO_SVC_TPARAM_DEF1(= stream_socket_service<Protocol>),
#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) \ #if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) \
&& defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
typename Clock = boost::posix_time::ptime, typename Clock = boost::posix_time::ptime,
typename WaitTraits = time_traits<Clock> typename WaitTraits = time_traits<Clock> >
BOOST_ASIO_SVC_TPARAM1_DEF2(= deadline_timer_service<Clock, WaitTraits>)>
#else // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) #else // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
// && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) // && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
typename Clock = chrono::steady_clock, typename Clock = chrono::steady_clock,
typename WaitTraits = wait_traits<Clock> typename WaitTraits = wait_traits<Clock> >
BOOST_ASIO_SVC_TPARAM1_DEF1(= steady_timer::service_type)>
#endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) #endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
// && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) // && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
class basic_socket_streambuf; class basic_socket_streambuf;
@ -149,17 +134,16 @@ template <typename Protocol,
typename Clock = chrono::steady_clock, typename Clock = chrono::steady_clock,
typename WaitTraits = wait_traits<Clock> > typename WaitTraits = wait_traits<Clock> >
#else // defined(GENERATING_DOCUMENTATION) #else // defined(GENERATING_DOCUMENTATION)
template <typename Protocol BOOST_ASIO_SVC_TPARAM, template <typename Protocol, typename Clock, typename WaitTraits>
typename Clock, typename WaitTraits BOOST_ASIO_SVC_TPARAM1>
#endif // defined(GENERATING_DOCUMENTATION) #endif // defined(GENERATING_DOCUMENTATION)
class basic_socket_streambuf class basic_socket_streambuf
: public std::streambuf, : public std::streambuf,
private detail::socket_streambuf_io_context, private detail::socket_streambuf_io_context,
private detail::socket_streambuf_buffers, private detail::socket_streambuf_buffers,
#if defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION) #if defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
private basic_socket<Protocol BOOST_ASIO_SVC_TARG> private basic_socket<Protocol>
#else // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION) #else // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
public basic_socket<Protocol BOOST_ASIO_SVC_TARG> public basic_socket<Protocol>
#endif // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION) #endif // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
{ {
private: private:
@ -208,7 +192,7 @@ public:
/// Construct a basic_socket_streambuf without establishing a connection. /// Construct a basic_socket_streambuf without establishing a connection.
basic_socket_streambuf() basic_socket_streambuf()
: detail::socket_streambuf_io_context(new io_context), : detail::socket_streambuf_io_context(new io_context),
basic_socket<Protocol BOOST_ASIO_SVC_TARG>(*default_io_context_), basic_socket<Protocol>(*default_io_context_),
expiry_time_(max_expiry_time()) expiry_time_(max_expiry_time())
{ {
init_buffers(); init_buffers();
@ -218,7 +202,7 @@ public:
/// Construct a basic_socket_streambuf from the supplied socket. /// Construct a basic_socket_streambuf from the supplied socket.
explicit basic_socket_streambuf(basic_stream_socket<protocol_type> s) explicit basic_socket_streambuf(basic_stream_socket<protocol_type> s)
: detail::socket_streambuf_io_context(0), : detail::socket_streambuf_io_context(0),
basic_socket<Protocol BOOST_ASIO_SVC_TARG>(std::move(s)), basic_socket<Protocol>(std::move(s)),
expiry_time_(max_expiry_time()) expiry_time_(max_expiry_time())
{ {
init_buffers(); init_buffers();
@ -227,7 +211,7 @@ public:
/// Move-construct a basic_socket_streambuf from another. /// Move-construct a basic_socket_streambuf from another.
basic_socket_streambuf(basic_socket_streambuf&& other) basic_socket_streambuf(basic_socket_streambuf&& other)
: detail::socket_streambuf_io_context(other), : detail::socket_streambuf_io_context(other),
basic_socket<Protocol BOOST_ASIO_SVC_TARG>(std::move(other.socket())), basic_socket<Protocol>(std::move(other.socket())),
ec_(other.ec_), ec_(other.ec_),
expiry_time_(other.expiry_time_) expiry_time_(other.expiry_time_)
{ {
@ -300,7 +284,7 @@ public:
{ {
init_buffers(); init_buffers();
typedef typename Protocol::resolver resolver_type; typedef typename Protocol::resolver resolver_type;
resolver_type resolver(socket().get_executor().context()); resolver_type resolver(socket().get_executor());
connect_to_endpoints(resolver.resolve(x..., ec_)); connect_to_endpoints(resolver.resolve(x..., ec_));
return !ec_ ? this : 0; return !ec_ ? this : 0;
} }
@ -323,7 +307,7 @@ public:
} }
/// Get a reference to the underlying socket. /// Get a reference to the underlying socket.
basic_socket<Protocol BOOST_ASIO_SVC_TARG>& socket() basic_socket<Protocol>& socket()
{ {
return *this; return *this;
} }
@ -696,10 +680,6 @@ private:
#include <boost/asio/detail/pop_options.hpp> #include <boost/asio/detail/pop_options.hpp>
#if !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
# undef BOOST_ASIO_SVC_T1
#endif // !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
#if !defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) #if !defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
# undef BOOST_ASIO_PRIVATE_CONNECT_DEF # undef BOOST_ASIO_PRIVATE_CONNECT_DEF
#endif // !defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) #endif // !defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)

View File

@ -2,7 +2,7 @@
// basic_stream_socket.hpp // basic_stream_socket.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -20,18 +20,24 @@
#include <boost/asio/async_result.hpp> #include <boost/asio/async_result.hpp>
#include <boost/asio/basic_socket.hpp> #include <boost/asio/basic_socket.hpp>
#include <boost/asio/detail/handler_type_requirements.hpp> #include <boost/asio/detail/handler_type_requirements.hpp>
#include <boost/asio/detail/non_const_lvalue.hpp>
#include <boost/asio/detail/throw_error.hpp> #include <boost/asio/detail/throw_error.hpp>
#include <boost/asio/error.hpp> #include <boost/asio/error.hpp>
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
# include <boost/asio/stream_socket_service.hpp>
#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
#include <boost/asio/detail/push_options.hpp> #include <boost/asio/detail/push_options.hpp>
namespace boost { namespace boost {
namespace asio { namespace asio {
#if !defined(BOOST_ASIO_BASIC_STREAM_SOCKET_FWD_DECL)
#define BOOST_ASIO_BASIC_STREAM_SOCKET_FWD_DECL
// Forward declaration with defaulted arguments.
template <typename Protocol, typename Executor = executor>
class basic_stream_socket;
#endif // !defined(BOOST_ASIO_BASIC_STREAM_SOCKET_FWD_DECL)
/// Provides stream-oriented socket functionality. /// Provides stream-oriented socket functionality.
/** /**
* The basic_stream_socket class template provides asynchronous and blocking * The basic_stream_socket class template provides asynchronous and blocking
@ -44,18 +50,28 @@ namespace asio {
* @par Concepts: * @par Concepts:
* AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream. * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream.
*/ */
template <typename Protocol template <typename Protocol, typename Executor>
BOOST_ASIO_SVC_TPARAM_DEF1(= stream_socket_service<Protocol>)>
class basic_stream_socket class basic_stream_socket
: public basic_socket<Protocol BOOST_ASIO_SVC_TARG> : public basic_socket<Protocol, Executor>
{ {
public: public:
/// The type of the executor associated with the object.
typedef Executor executor_type;
/// Rebinds the socket type to another executor.
template <typename Executor1>
struct rebind_executor
{
/// The socket type when rebound to the specified executor.
typedef basic_stream_socket<Protocol, Executor1> other;
};
/// The native representation of a socket. /// The native representation of a socket.
#if defined(GENERATING_DOCUMENTATION) #if defined(GENERATING_DOCUMENTATION)
typedef implementation_defined native_handle_type; typedef implementation_defined native_handle_type;
#else #else
typedef typename basic_socket< typedef typename basic_socket<Protocol,
Protocol BOOST_ASIO_SVC_TARG>::native_handle_type native_handle_type; Executor>::native_handle_type native_handle_type;
#endif #endif
/// The protocol type. /// The protocol type.
@ -70,11 +86,30 @@ public:
* needs to be opened and then connected or accepted before data can be sent * needs to be opened and then connected or accepted before data can be sent
* or received on it. * or received on it.
* *
* @param io_context The io_context object that the stream socket will use to * @param ex The I/O executor that the socket will use, by default, to
* dispatch handlers for any asynchronous operations performed on the socket. * dispatch handlers for any asynchronous operations performed on the socket.
*/ */
explicit basic_stream_socket(boost::asio::io_context& io_context) explicit basic_stream_socket(const executor_type& ex)
: basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context) : basic_socket<Protocol, Executor>(ex)
{
}
/// Construct a basic_stream_socket without opening it.
/**
* This constructor creates a stream socket without opening it. The socket
* needs to be opened and then connected or accepted before data can be sent
* or received on it.
*
* @param context An execution context which provides the I/O executor that
* the socket will use, by default, to dispatch handlers for any asynchronous
* operations performed on the socket.
*/
template <typename ExecutionContext>
explicit basic_stream_socket(ExecutionContext& context,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: basic_socket<Protocol, Executor>(context)
{ {
} }
@ -83,16 +118,37 @@ public:
* This constructor creates and opens a stream socket. The socket needs to be * This constructor creates and opens a stream socket. The socket needs to be
* connected or accepted before data can be sent or received on it. * connected or accepted before data can be sent or received on it.
* *
* @param io_context The io_context object that the stream socket will use to * @param ex The I/O executor that the socket will use, by default, to
* dispatch handlers for any asynchronous operations performed on the socket. * dispatch handlers for any asynchronous operations performed on the socket.
* *
* @param protocol An object specifying protocol parameters to be used. * @param protocol An object specifying protocol parameters to be used.
* *
* @throws boost::system::system_error Thrown on failure. * @throws boost::system::system_error Thrown on failure.
*/ */
basic_stream_socket(boost::asio::io_context& io_context, basic_stream_socket(const executor_type& ex, const protocol_type& protocol)
const protocol_type& protocol) : basic_socket<Protocol, Executor>(ex, protocol)
: basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context, protocol) {
}
/// Construct and open a basic_stream_socket.
/**
* This constructor creates and opens a stream socket. The socket needs to be
* connected or accepted before data can be sent or received on it.
*
* @param context An execution context which provides the I/O executor that
* the socket will use, by default, to dispatch handlers for any asynchronous
* operations performed on the socket.
*
* @param protocol An object specifying protocol parameters to be used.
*
* @throws boost::system::system_error Thrown on failure.
*/
template <typename ExecutionContext>
basic_stream_socket(ExecutionContext& context, const protocol_type& protocol,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: basic_socket<Protocol, Executor>(context, protocol)
{ {
} }
@ -103,7 +159,7 @@ public:
* to the specified endpoint on the local machine. The protocol used is the * to the specified endpoint on the local machine. The protocol used is the
* protocol associated with the given endpoint. * protocol associated with the given endpoint.
* *
* @param io_context The io_context object that the stream socket will use to * @param ex The I/O executor that the socket will use, by default, to
* dispatch handlers for any asynchronous operations performed on the socket. * dispatch handlers for any asynchronous operations performed on the socket.
* *
* @param endpoint An endpoint on the local machine to which the stream * @param endpoint An endpoint on the local machine to which the stream
@ -111,9 +167,33 @@ public:
* *
* @throws boost::system::system_error Thrown on failure. * @throws boost::system::system_error Thrown on failure.
*/ */
basic_stream_socket(boost::asio::io_context& io_context, basic_stream_socket(const executor_type& ex, const endpoint_type& endpoint)
const endpoint_type& endpoint) : basic_socket<Protocol, Executor>(ex, endpoint)
: basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context, endpoint) {
}
/// Construct a basic_stream_socket, opening it and binding it to the given
/// local endpoint.
/**
* This constructor creates a stream socket and automatically opens it bound
* to the specified endpoint on the local machine. The protocol used is the
* protocol associated with the given endpoint.
*
* @param context An execution context which provides the I/O executor that
* the socket will use, by default, to dispatch handlers for any asynchronous
* operations performed on the socket.
*
* @param endpoint An endpoint on the local machine to which the stream
* socket will be bound.
*
* @throws boost::system::system_error Thrown on failure.
*/
template <typename ExecutionContext>
basic_stream_socket(ExecutionContext& context, const endpoint_type& endpoint,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: basic_socket<Protocol, Executor>(context, endpoint)
{ {
} }
@ -122,7 +202,7 @@ public:
* This constructor creates a stream socket object to hold an existing native * This constructor creates a stream socket object to hold an existing native
* socket. * socket.
* *
* @param io_context The io_context object that the stream socket will use to * @param ex The I/O executor that the socket will use, by default, to
* dispatch handlers for any asynchronous operations performed on the socket. * dispatch handlers for any asynchronous operations performed on the socket.
* *
* @param protocol An object specifying protocol parameters to be used. * @param protocol An object specifying protocol parameters to be used.
@ -131,10 +211,34 @@ public:
* *
* @throws boost::system::system_error Thrown on failure. * @throws boost::system::system_error Thrown on failure.
*/ */
basic_stream_socket(boost::asio::io_context& io_context, basic_stream_socket(const executor_type& ex,
const protocol_type& protocol, const native_handle_type& native_socket) const protocol_type& protocol, const native_handle_type& native_socket)
: basic_socket<Protocol BOOST_ASIO_SVC_TARG>( : basic_socket<Protocol, Executor>(ex, protocol, native_socket)
io_context, protocol, native_socket) {
}
/// Construct a basic_stream_socket on an existing native socket.
/**
* This constructor creates a stream socket object to hold an existing native
* socket.
*
* @param context An execution context which provides the I/O executor that
* the socket will use, by default, to dispatch handlers for any asynchronous
* operations performed on the socket.
*
* @param protocol An object specifying protocol parameters to be used.
*
* @param native_socket The new underlying socket implementation.
*
* @throws boost::system::system_error Thrown on failure.
*/
template <typename ExecutionContext>
basic_stream_socket(ExecutionContext& context,
const protocol_type& protocol, const native_handle_type& native_socket,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: basic_socket<Protocol, Executor>(context, protocol, native_socket)
{ {
} }
@ -147,10 +251,11 @@ public:
* will occur. * will occur.
* *
* @note Following the move, the moved-from object is in the same state as if * @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_stream_socket(io_context&) constructor. * constructed using the @c basic_stream_socket(const executor_type&)
* constructor.
*/ */
basic_stream_socket(basic_stream_socket&& other) basic_stream_socket(basic_stream_socket&& other)
: basic_socket<Protocol BOOST_ASIO_SVC_TARG>(std::move(other)) : basic_socket<Protocol, Executor>(std::move(other))
{ {
} }
@ -162,11 +267,12 @@ public:
* will occur. * will occur.
* *
* @note Following the move, the moved-from object is in the same state as if * @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_stream_socket(io_context&) constructor. * constructed using the @c basic_stream_socket(const executor_type&)
* constructor.
*/ */
basic_stream_socket& operator=(basic_stream_socket&& other) basic_stream_socket& operator=(basic_stream_socket&& other)
{ {
basic_socket<Protocol BOOST_ASIO_SVC_TARG>::operator=(std::move(other)); basic_socket<Protocol, Executor>::operator=(std::move(other));
return *this; return *this;
} }
@ -179,13 +285,16 @@ public:
* will occur. * will occur.
* *
* @note Following the move, the moved-from object is in the same state as if * @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_stream_socket(io_context&) constructor. * constructed using the @c basic_stream_socket(const executor_type&)
* constructor.
*/ */
template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1> template <typename Protocol1, typename Executor1>
basic_stream_socket( basic_stream_socket(basic_stream_socket<Protocol1, Executor1>&& other,
basic_stream_socket<Protocol1 BOOST_ASIO_SVC_TARG1>&& other, typename enable_if<
typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0) is_convertible<Protocol1, Protocol>::value
: basic_socket<Protocol BOOST_ASIO_SVC_TARG>(std::move(other)) && is_convertible<Executor1, Executor>::value
>::type* = 0)
: basic_socket<Protocol, Executor>(std::move(other))
{ {
} }
@ -197,14 +306,17 @@ public:
* will occur. * will occur.
* *
* @note Following the move, the moved-from object is in the same state as if * @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_stream_socket(io_context&) constructor. * constructed using the @c basic_stream_socket(const executor_type&)
* constructor.
*/ */
template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1> template <typename Protocol1, typename Executor1>
typename enable_if<is_convertible<Protocol1, Protocol>::value, typename enable_if<
basic_stream_socket>::type& operator=( is_convertible<Protocol1, Protocol>::value
basic_stream_socket<Protocol1 BOOST_ASIO_SVC_TARG1>&& other) && is_convertible<Executor1, Executor>::value,
basic_stream_socket&
>::type operator=(basic_stream_socket<Protocol1, Executor1>&& other)
{ {
basic_socket<Protocol BOOST_ASIO_SVC_TARG>::operator=(std::move(other)); basic_socket<Protocol, Executor>::operator=(std::move(other));
return *this; return *this;
} }
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
@ -247,8 +359,8 @@ public:
std::size_t send(const ConstBufferSequence& buffers) std::size_t send(const ConstBufferSequence& buffers)
{ {
boost::system::error_code ec; boost::system::error_code ec;
std::size_t s = this->get_service().send( std::size_t s = this->impl_.get_service().send(
this->get_implementation(), buffers, 0, ec); this->impl_.get_implementation(), buffers, 0, ec);
boost::asio::detail::throw_error(ec, "send"); boost::asio::detail::throw_error(ec, "send");
return s; return s;
} }
@ -285,8 +397,8 @@ public:
socket_base::message_flags flags) socket_base::message_flags flags)
{ {
boost::system::error_code ec; boost::system::error_code ec;
std::size_t s = this->get_service().send( std::size_t s = this->impl_.get_service().send(
this->get_implementation(), buffers, flags, ec); this->impl_.get_implementation(), buffers, flags, ec);
boost::asio::detail::throw_error(ec, "send"); boost::asio::detail::throw_error(ec, "send");
return s; return s;
} }
@ -313,8 +425,8 @@ public:
std::size_t send(const ConstBufferSequence& buffers, std::size_t send(const ConstBufferSequence& buffers,
socket_base::message_flags flags, boost::system::error_code& ec) socket_base::message_flags flags, boost::system::error_code& ec)
{ {
return this->get_service().send( return this->impl_.get_service().send(
this->get_implementation(), buffers, flags, ec); this->impl_.get_implementation(), buffers, flags, ec);
} }
/// Start an asynchronous send. /// Start an asynchronous send.
@ -335,9 +447,9 @@ public:
* std::size_t bytes_transferred // Number of bytes sent. * std::size_t bytes_transferred // Number of bytes sent.
* ); @endcode * ); @endcode
* Regardless of whether the asynchronous operation completes immediately or * Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation * not, the handler will not be invoked from within this function. On
* of the handler will be performed in a manner equivalent to using * immediate completion, invocation of the handler will be performed in a
* boost::asio::io_context::post(). * manner equivalent to using boost::asio::post().
* *
* @note The send operation may not transmit all of the data to the peer. * @note The send operation may not transmit all of the data to the peer.
* Consider using the @ref async_write function if you need to ensure that all * Consider using the @ref async_write function if you need to ensure that all
@ -358,24 +470,10 @@ public:
async_send(const ConstBufferSequence& buffers, async_send(const ConstBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler) BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{ {
// If you get an error on the following line it means that your handler does return async_initiate<WriteHandler,
// not meet the documented type requirements for a WriteHandler. void (boost::system::error_code, std::size_t)>(
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; initiate_async_send(), handler, this,
buffers, socket_base::message_flags(0));
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_send(
this->get_implementation(), buffers, 0,
BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
async_completion<WriteHandler,
void (boost::system::error_code, std::size_t)> init(handler);
this->get_service().async_send(
this->get_implementation(), buffers, 0,
init.completion_handler);
return init.result.get();
#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
} }
/// Start an asynchronous send. /// Start an asynchronous send.
@ -398,9 +496,9 @@ public:
* std::size_t bytes_transferred // Number of bytes sent. * std::size_t bytes_transferred // Number of bytes sent.
* ); @endcode * ); @endcode
* Regardless of whether the asynchronous operation completes immediately or * Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation * not, the handler will not be invoked from within this function. On
* of the handler will be performed in a manner equivalent to using * immediate completion, invocation of the handler will be performed in a
* boost::asio::io_context::post(). * manner equivalent to using boost::asio::post().
* *
* @note The send operation may not transmit all of the data to the peer. * @note The send operation may not transmit all of the data to the peer.
* Consider using the @ref async_write function if you need to ensure that all * Consider using the @ref async_write function if you need to ensure that all
@ -422,24 +520,9 @@ public:
socket_base::message_flags flags, socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler) BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{ {
// If you get an error on the following line it means that your handler does return async_initiate<WriteHandler,
// not meet the documented type requirements for a WriteHandler. void (boost::system::error_code, std::size_t)>(
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; initiate_async_send(), handler, this, buffers, flags);
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_send(
this->get_implementation(), buffers, flags,
BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
async_completion<WriteHandler,
void (boost::system::error_code, std::size_t)> init(handler);
this->get_service().async_send(
this->get_implementation(), buffers, flags,
init.completion_handler);
return init.result.get();
#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
} }
/// Receive some data on the socket. /// Receive some data on the socket.
@ -474,8 +557,8 @@ public:
std::size_t receive(const MutableBufferSequence& buffers) std::size_t receive(const MutableBufferSequence& buffers)
{ {
boost::system::error_code ec; boost::system::error_code ec;
std::size_t s = this->get_service().receive( std::size_t s = this->impl_.get_service().receive(
this->get_implementation(), buffers, 0, ec); this->impl_.get_implementation(), buffers, 0, ec);
boost::asio::detail::throw_error(ec, "receive"); boost::asio::detail::throw_error(ec, "receive");
return s; return s;
} }
@ -515,8 +598,8 @@ public:
socket_base::message_flags flags) socket_base::message_flags flags)
{ {
boost::system::error_code ec; boost::system::error_code ec;
std::size_t s = this->get_service().receive( std::size_t s = this->impl_.get_service().receive(
this->get_implementation(), buffers, flags, ec); this->impl_.get_implementation(), buffers, flags, ec);
boost::asio::detail::throw_error(ec, "receive"); boost::asio::detail::throw_error(ec, "receive");
return s; return s;
} }
@ -543,8 +626,8 @@ public:
std::size_t receive(const MutableBufferSequence& buffers, std::size_t receive(const MutableBufferSequence& buffers,
socket_base::message_flags flags, boost::system::error_code& ec) socket_base::message_flags flags, boost::system::error_code& ec)
{ {
return this->get_service().receive( return this->impl_.get_service().receive(
this->get_implementation(), buffers, flags, ec); this->impl_.get_implementation(), buffers, flags, ec);
} }
/// Start an asynchronous receive. /// Start an asynchronous receive.
@ -565,9 +648,9 @@ public:
* std::size_t bytes_transferred // Number of bytes received. * std::size_t bytes_transferred // Number of bytes received.
* ); @endcode * ); @endcode
* Regardless of whether the asynchronous operation completes immediately or * Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation * not, the handler will not be invoked from within this function. On
* of the handler will be performed in a manner equivalent to using * immediate completion, invocation of the handler will be performed in a
* boost::asio::io_context::post(). * manner equivalent to using boost::asio::post().
* *
* @note The receive operation may not receive all of the requested number of * @note The receive operation may not receive all of the requested number of
* bytes. Consider using the @ref async_read function if you need to ensure * bytes. Consider using the @ref async_read function if you need to ensure
@ -590,22 +673,10 @@ public:
async_receive(const MutableBufferSequence& buffers, async_receive(const MutableBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler) BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{ {
// If you get an error on the following line it means that your handler does return async_initiate<ReadHandler,
// not meet the documented type requirements for a ReadHandler. void (boost::system::error_code, std::size_t)>(
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; initiate_async_receive(), handler, this,
buffers, socket_base::message_flags(0));
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_receive(this->get_implementation(),
buffers, 0, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
async_completion<ReadHandler,
void (boost::system::error_code, std::size_t)> init(handler);
this->get_service().async_receive(this->get_implementation(),
buffers, 0, init.completion_handler);
return init.result.get();
#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
} }
/// Start an asynchronous receive. /// Start an asynchronous receive.
@ -628,9 +699,9 @@ public:
* std::size_t bytes_transferred // Number of bytes received. * std::size_t bytes_transferred // Number of bytes received.
* ); @endcode * ); @endcode
* Regardless of whether the asynchronous operation completes immediately or * Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation * not, the handler will not be invoked from within this function. On
* of the handler will be performed in a manner equivalent to using * immediate completion, invocation of the handler will be performed in a
* boost::asio::io_context::post(). * manner equivalent to using boost::asio::post().
* *
* @note The receive operation may not receive all of the requested number of * @note The receive operation may not receive all of the requested number of
* bytes. Consider using the @ref async_read function if you need to ensure * bytes. Consider using the @ref async_read function if you need to ensure
@ -654,22 +725,9 @@ public:
socket_base::message_flags flags, socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler) BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{ {
// If you get an error on the following line it means that your handler does return async_initiate<ReadHandler,
// not meet the documented type requirements for a ReadHandler. void (boost::system::error_code, std::size_t)>(
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; initiate_async_receive(), handler, this, buffers, flags);
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_receive(this->get_implementation(),
buffers, flags, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
async_completion<ReadHandler,
void (boost::system::error_code, std::size_t)> init(handler);
this->get_service().async_receive(this->get_implementation(),
buffers, flags, init.completion_handler);
return init.result.get();
#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
} }
/// Write some data to the socket. /// Write some data to the socket.
@ -703,8 +761,8 @@ public:
std::size_t write_some(const ConstBufferSequence& buffers) std::size_t write_some(const ConstBufferSequence& buffers)
{ {
boost::system::error_code ec; boost::system::error_code ec;
std::size_t s = this->get_service().send( std::size_t s = this->impl_.get_service().send(
this->get_implementation(), buffers, 0, ec); this->impl_.get_implementation(), buffers, 0, ec);
boost::asio::detail::throw_error(ec, "write_some"); boost::asio::detail::throw_error(ec, "write_some");
return s; return s;
} }
@ -729,7 +787,8 @@ public:
std::size_t write_some(const ConstBufferSequence& buffers, std::size_t write_some(const ConstBufferSequence& buffers,
boost::system::error_code& ec) boost::system::error_code& ec)
{ {
return this->get_service().send(this->get_implementation(), buffers, 0, ec); return this->impl_.get_service().send(
this->impl_.get_implementation(), buffers, 0, ec);
} }
/// Start an asynchronous write. /// Start an asynchronous write.
@ -750,9 +809,9 @@ public:
* std::size_t bytes_transferred // Number of bytes written. * std::size_t bytes_transferred // Number of bytes written.
* ); @endcode * ); @endcode
* Regardless of whether the asynchronous operation completes immediately or * Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation * not, the handler will not be invoked from within this function. On
* of the handler will be performed in a manner equivalent to using * immediate completion, invocation of the handler will be performed in a
* boost::asio::io_context::post(). * manner equivalent to using boost::asio::post().
* *
* @note The write operation may not transmit all of the data to the peer. * @note The write operation may not transmit all of the data to the peer.
* Consider using the @ref async_write function if you need to ensure that all * Consider using the @ref async_write function if you need to ensure that all
@ -773,22 +832,10 @@ public:
async_write_some(const ConstBufferSequence& buffers, async_write_some(const ConstBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler) BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{ {
// If you get an error on the following line it means that your handler does return async_initiate<WriteHandler,
// not meet the documented type requirements for a WriteHandler. void (boost::system::error_code, std::size_t)>(
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; initiate_async_send(), handler, this,
buffers, socket_base::message_flags(0));
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_send(this->get_implementation(),
buffers, 0, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
async_completion<WriteHandler,
void (boost::system::error_code, std::size_t)> init(handler);
this->get_service().async_send(this->get_implementation(),
buffers, 0, init.completion_handler);
return init.result.get();
#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
} }
/// Read some data from the socket. /// Read some data from the socket.
@ -823,8 +870,8 @@ public:
std::size_t read_some(const MutableBufferSequence& buffers) std::size_t read_some(const MutableBufferSequence& buffers)
{ {
boost::system::error_code ec; boost::system::error_code ec;
std::size_t s = this->get_service().receive( std::size_t s = this->impl_.get_service().receive(
this->get_implementation(), buffers, 0, ec); this->impl_.get_implementation(), buffers, 0, ec);
boost::asio::detail::throw_error(ec, "read_some"); boost::asio::detail::throw_error(ec, "read_some");
return s; return s;
} }
@ -850,8 +897,8 @@ public:
std::size_t read_some(const MutableBufferSequence& buffers, std::size_t read_some(const MutableBufferSequence& buffers,
boost::system::error_code& ec) boost::system::error_code& ec)
{ {
return this->get_service().receive( return this->impl_.get_service().receive(
this->get_implementation(), buffers, 0, ec); this->impl_.get_implementation(), buffers, 0, ec);
} }
/// Start an asynchronous read. /// Start an asynchronous read.
@ -872,9 +919,9 @@ public:
* std::size_t bytes_transferred // Number of bytes read. * std::size_t bytes_transferred // Number of bytes read.
* ); @endcode * ); @endcode
* Regardless of whether the asynchronous operation completes immediately or * Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation * not, the handler will not be invoked from within this function. On
* of the handler will be performed in a manner equivalent to using * immediate completion, invocation of the handler will be performed in a
* boost::asio::io_context::post(). * manner equivalent to using boost::asio::post().
* *
* @note The read operation may not read all of the requested number of bytes. * @note The read operation may not read all of the requested number of bytes.
* Consider using the @ref async_read function if you need to ensure that the * Consider using the @ref async_read function if you need to ensure that the
@ -896,23 +943,48 @@ public:
async_read_some(const MutableBufferSequence& buffers, async_read_some(const MutableBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler) BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{ {
// If you get an error on the following line it means that your handler does return async_initiate<ReadHandler,
// not meet the documented type requirements for a ReadHandler. void (boost::system::error_code, std::size_t)>(
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; initiate_async_receive(), handler, this,
buffers, socket_base::message_flags(0));
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_receive(this->get_implementation(),
buffers, 0, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
async_completion<ReadHandler,
void (boost::system::error_code, std::size_t)> init(handler);
this->get_service().async_receive(this->get_implementation(),
buffers, 0, init.completion_handler);
return init.result.get();
#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
} }
private:
struct initiate_async_send
{
template <typename WriteHandler, typename ConstBufferSequence>
void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
basic_stream_socket* self, const ConstBufferSequence& buffers,
socket_base::message_flags flags) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a WriteHandler.
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
detail::non_const_lvalue<WriteHandler> handler2(handler);
self->impl_.get_service().async_send(
self->impl_.get_implementation(), buffers, flags,
handler2.value, self->impl_.get_implementation_executor());
}
};
struct initiate_async_receive
{
template <typename ReadHandler, typename MutableBufferSequence>
void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
basic_stream_socket* self, const MutableBufferSequence& buffers,
socket_base::message_flags flags) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a ReadHandler.
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
detail::non_const_lvalue<ReadHandler> handler2(handler);
self->impl_.get_service().async_receive(
self->impl_.get_implementation(), buffers, flags,
handler2.value, self->impl_.get_implementation_executor());
}
};
}; };
} // namespace asio } // namespace asio

View File

@ -2,7 +2,7 @@
// basic_streambuf.hpp // basic_streambuf.hpp
// ~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// basic_streambuf_fwd.hpp // basic_streambuf_fwd.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// basic_waitable_timer.hpp // basic_waitable_timer.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -17,26 +17,20 @@
#include <boost/asio/detail/config.hpp> #include <boost/asio/detail/config.hpp>
#include <cstddef> #include <cstddef>
#include <boost/asio/basic_io_object.hpp> #include <boost/asio/detail/chrono_time_traits.hpp>
#include <boost/asio/detail/deadline_timer_service.hpp>
#include <boost/asio/detail/handler_type_requirements.hpp> #include <boost/asio/detail/handler_type_requirements.hpp>
#include <boost/asio/detail/io_object_impl.hpp>
#include <boost/asio/detail/non_const_lvalue.hpp>
#include <boost/asio/detail/throw_error.hpp> #include <boost/asio/detail/throw_error.hpp>
#include <boost/asio/error.hpp> #include <boost/asio/error.hpp>
#include <boost/asio/executor.hpp>
#include <boost/asio/wait_traits.hpp> #include <boost/asio/wait_traits.hpp>
#if defined(BOOST_ASIO_HAS_MOVE) #if defined(BOOST_ASIO_HAS_MOVE)
# include <utility> # include <utility>
#endif // defined(BOOST_ASIO_HAS_MOVE) #endif // defined(BOOST_ASIO_HAS_MOVE)
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
# include <boost/asio/waitable_timer_service.hpp>
#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
# include <boost/asio/detail/chrono_time_traits.hpp>
# include <boost/asio/detail/deadline_timer_service.hpp>
# define BOOST_ASIO_SVC_T \
detail::deadline_timer_service< \
detail::chrono_time_traits<Clock, WaitTraits> >
#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
#include <boost/asio/detail/push_options.hpp> #include <boost/asio/detail/push_options.hpp>
namespace boost { namespace boost {
@ -47,8 +41,8 @@ namespace asio {
// Forward declaration with defaulted arguments. // Forward declaration with defaulted arguments.
template <typename Clock, template <typename Clock,
typename WaitTraits = boost::asio::wait_traits<Clock> typename WaitTraits = boost::asio::wait_traits<Clock>,
BOOST_ASIO_SVC_TPARAM_DEF2(= waitable_timer_service<Clock, WaitTraits>)> typename Executor = executor>
class basic_waitable_timer; class basic_waitable_timer;
#endif // !defined(BOOST_ASIO_BASIC_WAITABLE_TIMER_FWD_DECL) #endif // !defined(BOOST_ASIO_BASIC_WAITABLE_TIMER_FWD_DECL)
@ -76,7 +70,7 @@ class basic_waitable_timer;
* Performing a blocking wait (C++11): * Performing a blocking wait (C++11):
* @code * @code
* // Construct a timer without setting an expiry time. * // Construct a timer without setting an expiry time.
* boost::asio::steady_timer timer(io_context); * boost::asio::steady_timer timer(my_context);
* *
* // Set an expiry time relative to now. * // Set an expiry time relative to now.
* timer.expires_after(std::chrono::seconds(5)); * timer.expires_after(std::chrono::seconds(5));
@ -99,7 +93,7 @@ class basic_waitable_timer;
* ... * ...
* *
* // Construct a timer with an absolute expiry time. * // Construct a timer with an absolute expiry time.
* boost::asio::steady_timer timer(io_context, * boost::asio::steady_timer timer(my_context,
* std::chrono::steady_clock::now() + std::chrono::seconds(60)); * std::chrono::steady_clock::now() + std::chrono::seconds(60));
* *
* // Start an asynchronous wait. * // Start an asynchronous wait.
@ -145,13 +139,12 @@ class basic_waitable_timer;
* @li If a wait handler is cancelled, the boost::system::error_code passed to * @li If a wait handler is cancelled, the boost::system::error_code passed to
* it contains the value boost::asio::error::operation_aborted. * it contains the value boost::asio::error::operation_aborted.
*/ */
template <typename Clock, typename WaitTraits BOOST_ASIO_SVC_TPARAM> template <typename Clock, typename WaitTraits, typename Executor>
class basic_waitable_timer class basic_waitable_timer
: BOOST_ASIO_SVC_ACCESS basic_io_object<BOOST_ASIO_SVC_T>
{ {
public: public:
/// The type of the executor associated with the object. /// The type of the executor associated with the object.
typedef io_context::executor_type executor_type; typedef Executor executor_type;
/// The clock type. /// The clock type.
typedef Clock clock_type; typedef Clock clock_type;
@ -171,11 +164,30 @@ public:
* expires_at() or expires_after() functions must be called to set an expiry * expires_at() or expires_after() functions must be called to set an expiry
* time before the timer can be waited on. * time before the timer can be waited on.
* *
* @param io_context The io_context object that the timer will use to dispatch * @param ex The I/O executor that the timer will use, by default, to
* handlers for any asynchronous operations performed on the timer. * dispatch handlers for any asynchronous operations performed on the timer.
*/ */
explicit basic_waitable_timer(boost::asio::io_context& io_context) explicit basic_waitable_timer(const executor_type& ex)
: basic_io_object<BOOST_ASIO_SVC_T>(io_context) : impl_(ex)
{
}
/// Constructor.
/**
* This constructor creates a timer without setting an expiry time. The
* expires_at() or expires_after() functions must be called to set an expiry
* time before the timer can be waited on.
*
* @param context An execution context which provides the I/O executor that
* the timer will use, by default, to dispatch handlers for any asynchronous
* operations performed on the timer.
*/
template <typename ExecutionContext>
explicit basic_waitable_timer(ExecutionContext& context,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: impl_(context)
{ {
} }
@ -183,18 +195,41 @@ public:
/** /**
* This constructor creates a timer and sets the expiry time. * This constructor creates a timer and sets the expiry time.
* *
* @param io_context The io_context object that the timer will use to dispatch * @param ex The I/O executor object that the timer will use, by default, to
* handlers for any asynchronous operations performed on the timer. * dispatch handlers for any asynchronous operations performed on the timer.
* *
* @param expiry_time The expiry time to be used for the timer, expressed * @param expiry_time The expiry time to be used for the timer, expressed
* as an absolute time. * as an absolute time.
*/ */
basic_waitable_timer(boost::asio::io_context& io_context, basic_waitable_timer(const executor_type& ex, const time_point& expiry_time)
const time_point& expiry_time) : impl_(ex)
: basic_io_object<BOOST_ASIO_SVC_T>(io_context)
{ {
boost::system::error_code ec; boost::system::error_code ec;
this->get_service().expires_at(this->get_implementation(), expiry_time, ec); impl_.get_service().expires_at(impl_.get_implementation(), expiry_time, ec);
boost::asio::detail::throw_error(ec, "expires_at");
}
/// Constructor to set a particular expiry time as an absolute time.
/**
* This constructor creates a timer and sets the expiry time.
*
* @param context An execution context which provides the I/O executor that
* the timer will use, by default, to dispatch handlers for any asynchronous
* operations performed on the timer.
*
* @param expiry_time The expiry time to be used for the timer, expressed
* as an absolute time.
*/
template <typename ExecutionContext>
explicit basic_waitable_timer(ExecutionContext& context,
const time_point& expiry_time,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: impl_(context)
{
boost::system::error_code ec;
impl_.get_service().expires_at(impl_.get_implementation(), expiry_time, ec);
boost::asio::detail::throw_error(ec, "expires_at"); boost::asio::detail::throw_error(ec, "expires_at");
} }
@ -202,19 +237,43 @@ public:
/** /**
* This constructor creates a timer and sets the expiry time. * This constructor creates a timer and sets the expiry time.
* *
* @param io_context The io_context object that the timer will use to dispatch * @param ex The I/O executor that the timer will use, by default, to
* handlers for any asynchronous operations performed on the timer. * dispatch handlers for any asynchronous operations performed on the timer.
* *
* @param expiry_time The expiry time to be used for the timer, relative to * @param expiry_time The expiry time to be used for the timer, relative to
* now. * now.
*/ */
basic_waitable_timer(boost::asio::io_context& io_context, basic_waitable_timer(const executor_type& ex, const duration& expiry_time)
const duration& expiry_time) : impl_(ex)
: basic_io_object<BOOST_ASIO_SVC_T>(io_context)
{ {
boost::system::error_code ec; boost::system::error_code ec;
this->get_service().expires_after( impl_.get_service().expires_after(
this->get_implementation(), expiry_time, ec); impl_.get_implementation(), expiry_time, ec);
boost::asio::detail::throw_error(ec, "expires_after");
}
/// Constructor to set a particular expiry time relative to now.
/**
* This constructor creates a timer and sets the expiry time.
*
* @param context An execution context which provides the I/O executor that
* the timer will use, by default, to dispatch handlers for any asynchronous
* operations performed on the timer.
*
* @param expiry_time The expiry time to be used for the timer, relative to
* now.
*/
template <typename ExecutionContext>
explicit basic_waitable_timer(ExecutionContext& context,
const duration& expiry_time,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: impl_(context)
{
boost::system::error_code ec;
impl_.get_service().expires_after(
impl_.get_implementation(), expiry_time, ec);
boost::asio::detail::throw_error(ec, "expires_after"); boost::asio::detail::throw_error(ec, "expires_after");
} }
@ -227,10 +286,11 @@ public:
* occur. * occur.
* *
* @note Following the move, the moved-from object is in the same state as if * @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_waitable_timer(io_context&) constructor. * constructed using the @c basic_waitable_timer(const executor_type&)
* constructor.
*/ */
basic_waitable_timer(basic_waitable_timer&& other) basic_waitable_timer(basic_waitable_timer&& other)
: basic_io_object<BOOST_ASIO_SVC_T>(std::move(other)) : impl_(std::move(other.impl_))
{ {
} }
@ -243,11 +303,12 @@ public:
* occur. * occur.
* *
* @note Following the move, the moved-from object is in the same state as if * @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_waitable_timer(io_context&) constructor. * constructed using the @c basic_waitable_timer(const executor_type&)
* constructor.
*/ */
basic_waitable_timer& operator=(basic_waitable_timer&& other) basic_waitable_timer& operator=(basic_waitable_timer&& other)
{ {
basic_io_object<BOOST_ASIO_SVC_T>::operator=(std::move(other)); impl_ = std::move(other.impl_);
return *this; return *this;
} }
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
@ -261,45 +322,11 @@ public:
{ {
} }
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
// These functions are provided by basic_io_object<>.
#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
#if !defined(BOOST_ASIO_NO_DEPRECATED)
/// (Deprecated: Use get_executor().) Get the io_context associated with the
/// object.
/**
* This function may be used to obtain the io_context object that the I/O
* object uses to dispatch handlers for asynchronous operations.
*
* @return A reference to the io_context object that the I/O object will use
* to dispatch handlers. Ownership is not transferred to the caller.
*/
boost::asio::io_context& get_io_context()
{
return basic_io_object<BOOST_ASIO_SVC_T>::get_io_context();
}
/// (Deprecated: Use get_executor().) Get the io_context associated with the
/// object.
/**
* This function may be used to obtain the io_context object that the I/O
* object uses to dispatch handlers for asynchronous operations.
*
* @return A reference to the io_context object that the I/O object will use
* to dispatch handlers. Ownership is not transferred to the caller.
*/
boost::asio::io_context& get_io_service()
{
return basic_io_object<BOOST_ASIO_SVC_T>::get_io_service();
}
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
/// Get the executor associated with the object. /// Get the executor associated with the object.
executor_type get_executor() BOOST_ASIO_NOEXCEPT executor_type get_executor() BOOST_ASIO_NOEXCEPT
{ {
return basic_io_object<BOOST_ASIO_SVC_T>::get_executor(); return impl_.get_executor();
} }
#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
/// Cancel any asynchronous operations that are waiting on the timer. /// Cancel any asynchronous operations that are waiting on the timer.
/** /**
@ -326,7 +353,7 @@ public:
std::size_t cancel() std::size_t cancel()
{ {
boost::system::error_code ec; boost::system::error_code ec;
std::size_t s = this->get_service().cancel(this->get_implementation(), ec); std::size_t s = impl_.get_service().cancel(impl_.get_implementation(), ec);
boost::asio::detail::throw_error(ec, "cancel"); boost::asio::detail::throw_error(ec, "cancel");
return s; return s;
} }
@ -357,7 +384,7 @@ public:
*/ */
std::size_t cancel(boost::system::error_code& ec) std::size_t cancel(boost::system::error_code& ec)
{ {
return this->get_service().cancel(this->get_implementation(), ec); return impl_.get_service().cancel(impl_.get_implementation(), ec);
} }
#endif // !defined(BOOST_ASIO_NO_DEPRECATED) #endif // !defined(BOOST_ASIO_NO_DEPRECATED)
@ -388,8 +415,8 @@ public:
std::size_t cancel_one() std::size_t cancel_one()
{ {
boost::system::error_code ec; boost::system::error_code ec;
std::size_t s = this->get_service().cancel_one( std::size_t s = impl_.get_service().cancel_one(
this->get_implementation(), ec); impl_.get_implementation(), ec);
boost::asio::detail::throw_error(ec, "cancel_one"); boost::asio::detail::throw_error(ec, "cancel_one");
return s; return s;
} }
@ -422,7 +449,7 @@ public:
*/ */
std::size_t cancel_one(boost::system::error_code& ec) std::size_t cancel_one(boost::system::error_code& ec)
{ {
return this->get_service().cancel_one(this->get_implementation(), ec); return impl_.get_service().cancel_one(impl_.get_implementation(), ec);
} }
/// (Deprecated: Use expiry().) Get the timer's expiry time as an absolute /// (Deprecated: Use expiry().) Get the timer's expiry time as an absolute
@ -433,7 +460,7 @@ public:
*/ */
time_point expires_at() const time_point expires_at() const
{ {
return this->get_service().expires_at(this->get_implementation()); return impl_.get_service().expires_at(impl_.get_implementation());
} }
#endif // !defined(BOOST_ASIO_NO_DEPRECATED) #endif // !defined(BOOST_ASIO_NO_DEPRECATED)
@ -444,7 +471,7 @@ public:
*/ */
time_point expiry() const time_point expiry() const
{ {
return this->get_service().expiry(this->get_implementation()); return impl_.get_service().expiry(impl_.get_implementation());
} }
/// Set the timer's expiry time as an absolute time. /// Set the timer's expiry time as an absolute time.
@ -472,8 +499,8 @@ public:
std::size_t expires_at(const time_point& expiry_time) std::size_t expires_at(const time_point& expiry_time)
{ {
boost::system::error_code ec; boost::system::error_code ec;
std::size_t s = this->get_service().expires_at( std::size_t s = impl_.get_service().expires_at(
this->get_implementation(), expiry_time, ec); impl_.get_implementation(), expiry_time, ec);
boost::asio::detail::throw_error(ec, "expires_at"); boost::asio::detail::throw_error(ec, "expires_at");
return s; return s;
} }
@ -505,8 +532,8 @@ public:
std::size_t expires_at(const time_point& expiry_time, std::size_t expires_at(const time_point& expiry_time,
boost::system::error_code& ec) boost::system::error_code& ec)
{ {
return this->get_service().expires_at( return impl_.get_service().expires_at(
this->get_implementation(), expiry_time, ec); impl_.get_implementation(), expiry_time, ec);
} }
#endif // !defined(BOOST_ASIO_NO_DEPRECATED) #endif // !defined(BOOST_ASIO_NO_DEPRECATED)
@ -535,8 +562,8 @@ public:
std::size_t expires_after(const duration& expiry_time) std::size_t expires_after(const duration& expiry_time)
{ {
boost::system::error_code ec; boost::system::error_code ec;
std::size_t s = this->get_service().expires_after( std::size_t s = impl_.get_service().expires_after(
this->get_implementation(), expiry_time, ec); impl_.get_implementation(), expiry_time, ec);
boost::asio::detail::throw_error(ec, "expires_after"); boost::asio::detail::throw_error(ec, "expires_after");
return s; return s;
} }
@ -549,7 +576,7 @@ public:
*/ */
duration expires_from_now() const duration expires_from_now() const
{ {
return this->get_service().expires_from_now(this->get_implementation()); return impl_.get_service().expires_from_now(impl_.get_implementation());
} }
/// (Deprecated: Use expires_after().) Set the timer's expiry time relative /// (Deprecated: Use expires_after().) Set the timer's expiry time relative
@ -578,8 +605,8 @@ public:
std::size_t expires_from_now(const duration& expiry_time) std::size_t expires_from_now(const duration& expiry_time)
{ {
boost::system::error_code ec; boost::system::error_code ec;
std::size_t s = this->get_service().expires_from_now( std::size_t s = impl_.get_service().expires_from_now(
this->get_implementation(), expiry_time, ec); impl_.get_implementation(), expiry_time, ec);
boost::asio::detail::throw_error(ec, "expires_from_now"); boost::asio::detail::throw_error(ec, "expires_from_now");
return s; return s;
} }
@ -610,8 +637,8 @@ public:
std::size_t expires_from_now(const duration& expiry_time, std::size_t expires_from_now(const duration& expiry_time,
boost::system::error_code& ec) boost::system::error_code& ec)
{ {
return this->get_service().expires_from_now( return impl_.get_service().expires_from_now(
this->get_implementation(), expiry_time, ec); impl_.get_implementation(), expiry_time, ec);
} }
#endif // !defined(BOOST_ASIO_NO_DEPRECATED) #endif // !defined(BOOST_ASIO_NO_DEPRECATED)
@ -625,7 +652,7 @@ public:
void wait() void wait()
{ {
boost::system::error_code ec; boost::system::error_code ec;
this->get_service().wait(this->get_implementation(), ec); impl_.get_service().wait(impl_.get_implementation(), ec);
boost::asio::detail::throw_error(ec, "wait"); boost::asio::detail::throw_error(ec, "wait");
} }
@ -638,7 +665,7 @@ public:
*/ */
void wait(boost::system::error_code& ec) void wait(boost::system::error_code& ec)
{ {
this->get_service().wait(this->get_implementation(), ec); impl_.get_service().wait(impl_.get_implementation(), ec);
} }
/// Start an asynchronous wait on the timer. /// Start an asynchronous wait on the timer.
@ -661,31 +688,17 @@ public:
* const boost::system::error_code& error // Result of operation. * const boost::system::error_code& error // Result of operation.
* ); @endcode * ); @endcode
* Regardless of whether the asynchronous operation completes immediately or * Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation * not, the handler will not be invoked from within this function. On
* of the handler will be performed in a manner equivalent to using * immediate completion, invocation of the handler will be performed in a
* boost::asio::io_context::post(). * manner equivalent to using boost::asio::post().
*/ */
template <typename WaitHandler> template <typename WaitHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler, BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler,
void (boost::system::error_code)) void (boost::system::error_code))
async_wait(BOOST_ASIO_MOVE_ARG(WaitHandler) handler) async_wait(BOOST_ASIO_MOVE_ARG(WaitHandler) handler)
{ {
// If you get an error on the following line it means that your handler does return async_initiate<WaitHandler, void (boost::system::error_code)>(
// not meet the documented type requirements for a WaitHandler. initiate_async_wait(), handler, this);
BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_wait(this->get_implementation(),
BOOST_ASIO_MOVE_CAST(WaitHandler)(handler));
#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
async_completion<WaitHandler,
void (boost::system::error_code)> init(handler);
this->get_service().async_wait(this->get_implementation(),
init.completion_handler);
return init.result.get();
#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
} }
private: private:
@ -693,6 +706,28 @@ private:
basic_waitable_timer(const basic_waitable_timer&) BOOST_ASIO_DELETED; basic_waitable_timer(const basic_waitable_timer&) BOOST_ASIO_DELETED;
basic_waitable_timer& operator=( basic_waitable_timer& operator=(
const basic_waitable_timer&) BOOST_ASIO_DELETED; const basic_waitable_timer&) BOOST_ASIO_DELETED;
struct initiate_async_wait
{
template <typename WaitHandler>
void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler,
basic_waitable_timer* self) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a WaitHandler.
BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
detail::non_const_lvalue<WaitHandler> handler2(handler);
self->impl_.get_service().async_wait(
self->impl_.get_implementation(), handler2.value,
self->impl_.get_implementation_executor());
}
};
detail::io_object_impl<
detail::deadline_timer_service<
detail::chrono_time_traits<Clock, WaitTraits> >,
executor_type > impl_;
}; };
} // namespace asio } // namespace asio
@ -700,8 +735,4 @@ private:
#include <boost/asio/detail/pop_options.hpp> #include <boost/asio/detail/pop_options.hpp>
#if !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
# undef BOOST_ASIO_SVC_T
#endif // !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
#endif // BOOST_ASIO_BASIC_WAITABLE_TIMER_HPP #endif // BOOST_ASIO_BASIC_WAITABLE_TIMER_HPP

View File

@ -2,7 +2,7 @@
// bind_executor.hpp // bind_executor.hpp
// ~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -548,37 +548,6 @@ private:
async_result<T, Signature> target_; async_result<T, Signature> target_;
}; };
#if !defined(BOOST_ASIO_NO_DEPRECATED)
template <typename T, typename Executor, typename Signature>
struct handler_type<executor_binder<T, Executor>, Signature>
{
typedef executor_binder<
typename handler_type<T, Signature>::type, Executor> type;
};
template <typename T, typename Executor>
class async_result<executor_binder<T, Executor> >
{
public:
typedef typename async_result<T>::type type;
explicit async_result(executor_binder<T, Executor>& b)
: target_(b.get())
{
}
type get()
{
return target_.get();
}
private:
async_result<T> target_;
};
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
template <typename T, typename Executor, typename Allocator> template <typename T, typename Executor, typename Allocator>
struct associated_allocator<executor_binder<T, Executor>, Allocator> struct associated_allocator<executor_binder<T, Executor>, Allocator>
{ {

View File

@ -2,7 +2,7 @@
// buffer.hpp // buffer.hpp
// ~~~~~~~~~~ // ~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -23,7 +23,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <boost/asio/detail/array_fwd.hpp> #include <boost/asio/detail/array_fwd.hpp>
#include <boost/asio/detail/is_buffer_sequence.hpp> #include <boost/asio/detail/memory.hpp>
#include <boost/asio/detail/string_view.hpp> #include <boost/asio/detail/string_view.hpp>
#include <boost/asio/detail/throw_exception.hpp> #include <boost/asio/detail/throw_exception.hpp>
#include <boost/asio/detail/type_traits.hpp> #include <boost/asio/detail/type_traits.hpp>
@ -347,41 +347,6 @@ public:
#endif // !defined(BOOST_ASIO_NO_DEPRECATED) #endif // !defined(BOOST_ASIO_NO_DEPRECATED)
/// Trait to determine whether a type satisfies the MutableBufferSequence
/// requirements.
template <typename T>
struct is_mutable_buffer_sequence
#if defined(GENERATING_DOCUMENTATION)
: integral_constant<bool, automatically_determined>
#else // defined(GENERATING_DOCUMENTATION)
: boost::asio::detail::is_buffer_sequence<T, mutable_buffer>
#endif // defined(GENERATING_DOCUMENTATION)
{
};
/// Trait to determine whether a type satisfies the ConstBufferSequence
/// requirements.
template <typename T>
struct is_const_buffer_sequence
#if defined(GENERATING_DOCUMENTATION)
: integral_constant<bool, automatically_determined>
#else // defined(GENERATING_DOCUMENTATION)
: boost::asio::detail::is_buffer_sequence<T, const_buffer>
#endif // defined(GENERATING_DOCUMENTATION)
{
};
/// Trait to determine whether a type satisfies the DynamicBuffer requirements.
template <typename T>
struct is_dynamic_buffer
#if defined(GENERATING_DOCUMENTATION)
: integral_constant<bool, automatically_determined>
#else // defined(GENERATING_DOCUMENTATION)
: boost::asio::detail::is_dynamic_buffer<T>
#endif // defined(GENERATING_DOCUMENTATION)
{
};
/// (Deprecated: Use the socket/descriptor wait() and async_wait() member /// (Deprecated: Use the socket/descriptor wait() and async_wait() member
/// functions.) An implementation of both the ConstBufferSequence and /// functions.) An implementation of both the ConstBufferSequence and
/// MutableBufferSequence concepts to represent a null buffer sequence. /// MutableBufferSequence concepts to represent a null buffer sequence.
@ -418,29 +383,45 @@ private:
/*@{*/ /*@{*/
/// Get an iterator to the first element in a buffer sequence. /// Get an iterator to the first element in a buffer sequence.
inline const mutable_buffer* buffer_sequence_begin(const mutable_buffer& b) template <typename MutableBuffer>
inline const mutable_buffer* buffer_sequence_begin(const MutableBuffer& b,
typename enable_if<
is_convertible<const MutableBuffer*, const mutable_buffer*>::value
>::type* = 0) BOOST_ASIO_NOEXCEPT
{ {
return &b; return static_cast<const mutable_buffer*>(detail::addressof(b));
} }
/// Get an iterator to the first element in a buffer sequence. /// Get an iterator to the first element in a buffer sequence.
inline const const_buffer* buffer_sequence_begin(const const_buffer& b) template <typename ConstBuffer>
inline const const_buffer* buffer_sequence_begin(const ConstBuffer& b,
typename enable_if<
is_convertible<const ConstBuffer*, const const_buffer*>::value
>::type* = 0) BOOST_ASIO_NOEXCEPT
{ {
return &b; return static_cast<const const_buffer*>(detail::addressof(b));
} }
#if defined(BOOST_ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION) #if defined(BOOST_ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION)
/// Get an iterator to the first element in a buffer sequence. /// Get an iterator to the first element in a buffer sequence.
template <typename C> template <typename C>
inline auto buffer_sequence_begin(C& c) -> decltype(c.begin()) inline auto buffer_sequence_begin(C& c,
typename enable_if<
!is_convertible<const C*, const mutable_buffer*>::value
&& !is_convertible<const C*, const const_buffer*>::value
>::type* = 0) BOOST_ASIO_NOEXCEPT -> decltype(c.begin())
{ {
return c.begin(); return c.begin();
} }
/// Get an iterator to the first element in a buffer sequence. /// Get an iterator to the first element in a buffer sequence.
template <typename C> template <typename C>
inline auto buffer_sequence_begin(const C& c) -> decltype(c.begin()) inline auto buffer_sequence_begin(const C& c,
typename enable_if<
!is_convertible<const C*, const mutable_buffer*>::value
&& !is_convertible<const C*, const const_buffer*>::value
>::type* = 0) BOOST_ASIO_NOEXCEPT -> decltype(c.begin())
{ {
return c.begin(); return c.begin();
} }
@ -448,13 +429,21 @@ inline auto buffer_sequence_begin(const C& c) -> decltype(c.begin())
#else // defined(BOOST_ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION) #else // defined(BOOST_ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION)
template <typename C> template <typename C>
inline typename C::iterator buffer_sequence_begin(C& c) inline typename C::iterator buffer_sequence_begin(C& c,
typename enable_if<
!is_convertible<const C*, const mutable_buffer*>::value
&& !is_convertible<const C*, const const_buffer*>::value
>::type* = 0) BOOST_ASIO_NOEXCEPT
{ {
return c.begin(); return c.begin();
} }
template <typename C> template <typename C>
inline typename C::const_iterator buffer_sequence_begin(const C& c) inline typename C::const_iterator buffer_sequence_begin(const C& c,
typename enable_if<
!is_convertible<const C*, const mutable_buffer*>::value
&& !is_convertible<const C*, const const_buffer*>::value
>::type* = 0) BOOST_ASIO_NOEXCEPT
{ {
return c.begin(); return c.begin();
} }
@ -471,29 +460,45 @@ inline typename C::const_iterator buffer_sequence_begin(const C& c)
/*@{*/ /*@{*/
/// Get an iterator to one past the end element in a buffer sequence. /// Get an iterator to one past the end element in a buffer sequence.
inline const mutable_buffer* buffer_sequence_end(const mutable_buffer& b) template <typename MutableBuffer>
inline const mutable_buffer* buffer_sequence_end(const MutableBuffer& b,
typename enable_if<
is_convertible<const MutableBuffer*, const mutable_buffer*>::value
>::type* = 0) BOOST_ASIO_NOEXCEPT
{ {
return &b + 1; return static_cast<const mutable_buffer*>(detail::addressof(b)) + 1;
} }
/// Get an iterator to one past the end element in a buffer sequence. /// Get an iterator to one past the end element in a buffer sequence.
inline const const_buffer* buffer_sequence_end(const const_buffer& b) template <typename ConstBuffer>
inline const const_buffer* buffer_sequence_end(const ConstBuffer& b,
typename enable_if<
is_convertible<const ConstBuffer*, const const_buffer*>::value
>::type* = 0) BOOST_ASIO_NOEXCEPT
{ {
return &b + 1; return static_cast<const const_buffer*>(detail::addressof(b)) + 1;
} }
#if defined(BOOST_ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION) #if defined(BOOST_ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION)
/// Get an iterator to one past the end element in a buffer sequence. /// Get an iterator to one past the end element in a buffer sequence.
template <typename C> template <typename C>
inline auto buffer_sequence_end(C& c) -> decltype(c.end()) inline auto buffer_sequence_end(C& c,
typename enable_if<
!is_convertible<const C*, const mutable_buffer*>::value
&& !is_convertible<const C*, const const_buffer*>::value
>::type* = 0) BOOST_ASIO_NOEXCEPT -> decltype(c.end())
{ {
return c.end(); return c.end();
} }
/// Get an iterator to one past the end element in a buffer sequence. /// Get an iterator to one past the end element in a buffer sequence.
template <typename C> template <typename C>
inline auto buffer_sequence_end(const C& c) -> decltype(c.end()) inline auto buffer_sequence_end(const C& c,
typename enable_if<
!is_convertible<const C*, const mutable_buffer*>::value
&& !is_convertible<const C*, const const_buffer*>::value
>::type* = 0) BOOST_ASIO_NOEXCEPT -> decltype(c.end())
{ {
return c.end(); return c.end();
} }
@ -501,13 +506,21 @@ inline auto buffer_sequence_end(const C& c) -> decltype(c.end())
#else // defined(BOOST_ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION) #else // defined(BOOST_ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION)
template <typename C> template <typename C>
inline typename C::iterator buffer_sequence_end(C& c) inline typename C::iterator buffer_sequence_end(C& c,
typename enable_if<
!is_convertible<const C*, const mutable_buffer*>::value
&& !is_convertible<const C*, const const_buffer*>::value
>::type* = 0) BOOST_ASIO_NOEXCEPT
{ {
return c.end(); return c.end();
} }
template <typename C> template <typename C>
inline typename C::const_iterator buffer_sequence_end(const C& c) inline typename C::const_iterator buffer_sequence_end(const C& c,
typename enable_if<
!is_convertible<const C*, const mutable_buffer*>::value
&& !is_convertible<const C*, const const_buffer*>::value
>::type* = 0) BOOST_ASIO_NOEXCEPT
{ {
return c.end(); return c.end();
} }
@ -1404,7 +1417,7 @@ inline BOOST_ASIO_MUTABLE_BUFFER buffer(
); );
} }
/// Create a new non-modifiable buffer that represents the given string. /// Create a new modifiable buffer that represents the given string.
/** /**
* @returns A mutable_buffer value equivalent to: * @returns A mutable_buffer value equivalent to:
* @code mutable_buffer( * @code mutable_buffer(
@ -1534,19 +1547,23 @@ template <typename Elem, typename Traits, typename Allocator>
class dynamic_string_buffer class dynamic_string_buffer
{ {
public: public:
/// The type used to represent the input sequence as a list of buffers. /// The type used to represent a sequence of constant buffers that refers to
/// the underlying memory.
typedef BOOST_ASIO_CONST_BUFFER const_buffers_type; typedef BOOST_ASIO_CONST_BUFFER const_buffers_type;
/// The type used to represent the output sequence as a list of buffers. /// The type used to represent a sequence of mutable buffers that refers to
/// the underlying memory.
typedef BOOST_ASIO_MUTABLE_BUFFER mutable_buffers_type; typedef BOOST_ASIO_MUTABLE_BUFFER mutable_buffers_type;
/// Construct a dynamic buffer from a string. /// Construct a dynamic buffer from a string.
/** /**
* @param s The string to be used as backing storage for the dynamic buffer. * @param s The string to be used as backing storage for the dynamic buffer.
* Any existing data in the string is treated as the dynamic buffer's input * The object stores a reference to the string and the user is responsible
* sequence. The object stores a reference to the string and the user is * for ensuring that the string object remains valid while the
* responsible for ensuring that the string object remains valid until the * dynamic_string_buffer object, and copies of the object, are in use.
* dynamic_string_buffer object is destroyed. *
* @b DynamicBuffer_v1: Any existing data in the string is treated as the
* dynamic buffer's input sequence.
* *
* @param maximum_size Specifies a maximum size for the buffer, in bytes. * @param maximum_size Specifies a maximum size for the buffer, in bytes.
*/ */
@ -1554,64 +1571,131 @@ public:
std::size_t maximum_size = std::size_t maximum_size =
(std::numeric_limits<std::size_t>::max)()) BOOST_ASIO_NOEXCEPT (std::numeric_limits<std::size_t>::max)()) BOOST_ASIO_NOEXCEPT
: string_(s), : string_(s),
size_(string_.size()), #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
size_((std::numeric_limits<std::size_t>::max)()),
#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
max_size_(maximum_size) max_size_(maximum_size)
{ {
} }
/// @b DynamicBuffer_v2: Copy construct a dynamic buffer.
dynamic_string_buffer(const dynamic_string_buffer& other) BOOST_ASIO_NOEXCEPT
: string_(other.string_),
#if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
size_(other.size_),
#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
max_size_(other.max_size_)
{
}
#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
/// Move construct a dynamic buffer. /// Move construct a dynamic buffer.
dynamic_string_buffer(dynamic_string_buffer&& other) BOOST_ASIO_NOEXCEPT dynamic_string_buffer(dynamic_string_buffer&& other) BOOST_ASIO_NOEXCEPT
: string_(other.string_), : string_(other.string_),
#if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
size_(other.size_), size_(other.size_),
#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
max_size_(other.max_size_) max_size_(other.max_size_)
{ {
} }
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
/// Get the size of the input sequence. /// @b DynamicBuffer_v1: Get the size of the input sequence.
/// @b DynamicBuffer_v2: Get the current size of the underlying memory.
/**
* @returns @b DynamicBuffer_v1 The current size of the input sequence.
* @b DynamicBuffer_v2: The current size of the underlying string if less than
* max_size(). Otherwise returns max_size().
*/
std::size_t size() const BOOST_ASIO_NOEXCEPT std::size_t size() const BOOST_ASIO_NOEXCEPT
{ {
return size_; #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
if (size_ != (std::numeric_limits<std::size_t>::max)())
return size_;
#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
return (std::min)(string_.size(), max_size());
} }
/// Get the maximum size of the dynamic buffer. /// Get the maximum size of the dynamic buffer.
/** /**
* @returns The allowed maximum of the sum of the sizes of the input sequence * @returns The allowed maximum size of the underlying memory.
* and output sequence.
*/ */
std::size_t max_size() const BOOST_ASIO_NOEXCEPT std::size_t max_size() const BOOST_ASIO_NOEXCEPT
{ {
return max_size_; return max_size_;
} }
/// Get the current capacity of the dynamic buffer. /// Get the maximum size that the buffer may grow to without triggering
/// reallocation.
/** /**
* @returns The current total capacity of the buffer, i.e. for both the input * @returns The current capacity of the underlying string if less than
* sequence and output sequence. * max_size(). Otherwise returns max_size().
*/ */
std::size_t capacity() const BOOST_ASIO_NOEXCEPT std::size_t capacity() const BOOST_ASIO_NOEXCEPT
{ {
return string_.capacity(); return (std::min)(string_.capacity(), max_size());
} }
/// Get a list of buffers that represents the input sequence. #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
/// @b DynamicBuffer_v1: Get a list of buffers that represents the input
/// sequence.
/** /**
* @returns An object of type @c const_buffers_type that satisfies * @returns An object of type @c const_buffers_type that satisfies
* ConstBufferSequence requirements, representing the basic_string memory in * ConstBufferSequence requirements, representing the basic_string memory in
* input sequence. * the input sequence.
* *
* @note The returned object is invalidated by any @c dynamic_string_buffer * @note The returned object is invalidated by any @c dynamic_string_buffer
* or @c basic_string member function that modifies the input sequence or * or @c basic_string member function that resizes or erases the string.
* output sequence.
*/ */
const_buffers_type data() const BOOST_ASIO_NOEXCEPT const_buffers_type data() const BOOST_ASIO_NOEXCEPT
{ {
return const_buffers_type(boost::asio::buffer(string_, size_)); return const_buffers_type(boost::asio::buffer(string_, size_));
} }
#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
/// Get a list of buffers that represents the output sequence, with the given /// @b DynamicBuffer_v2: Get a sequence of buffers that represents the
/// size. /// underlying memory.
/**
* @param pos Position of the first byte to represent in the buffer sequence
*
* @param n The number of bytes to return in the buffer sequence. If the
* underlying memory is shorter, the buffer sequence represents as many bytes
* as are available.
*
* @returns An object of type @c mutable_buffers_type that satisfies
* MutableBufferSequence requirements, representing the basic_string memory.
*
* @note The returned object is invalidated by any @c dynamic_string_buffer
* or @c basic_string member function that resizes or erases the string.
*/
mutable_buffers_type data(std::size_t pos, std::size_t n) BOOST_ASIO_NOEXCEPT
{
return mutable_buffers_type(boost::asio::buffer(
boost::asio::buffer(string_, max_size_) + pos, n));
}
/// @b DynamicBuffer_v2: Get a sequence of buffers that represents the
/// underlying memory.
/**
* @param pos Position of the first byte to represent in the buffer sequence
*
* @param n The number of bytes to return in the buffer sequence. If the
* underlying memory is shorter, the buffer sequence represents as many bytes
* as are available.
*
* @note The returned object is invalidated by any @c dynamic_string_buffer
* or @c basic_string member function that resizes or erases the string.
*/
const_buffers_type data(std::size_t pos,
std::size_t n) const BOOST_ASIO_NOEXCEPT
{
return const_buffers_type(boost::asio::buffer(
boost::asio::buffer(string_, max_size_) + pos, n));
}
#if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
/// @b DynamicBuffer_v1: Get a list of buffers that represents the output
/// sequence, with the given size.
/** /**
* Ensures that the output sequence can accommodate @c n bytes, resizing the * Ensures that the output sequence can accommodate @c n bytes, resizing the
* basic_string object as necessary. * basic_string object as necessary.
@ -1628,18 +1712,22 @@ public:
*/ */
mutable_buffers_type prepare(std::size_t n) mutable_buffers_type prepare(std::size_t n)
{ {
if (size () > max_size() || max_size() - size() < n) if (size() > max_size() || max_size() - size() < n)
{ {
std::length_error ex("dynamic_string_buffer too long"); std::length_error ex("dynamic_string_buffer too long");
boost::asio::detail::throw_exception(ex); boost::asio::detail::throw_exception(ex);
} }
if (size_ == (std::numeric_limits<std::size_t>::max)())
size_ = string_.size(); // Enable v1 behaviour.
string_.resize(size_ + n); string_.resize(size_ + n);
return boost::asio::buffer(boost::asio::buffer(string_) + size_, n); return boost::asio::buffer(boost::asio::buffer(string_) + size_, n);
} }
/// Move bytes from the output sequence to the input sequence. /// @b DynamicBuffer_v1: Move bytes from the output sequence to the input
/// sequence.
/** /**
* @param n The number of bytes to append from the start of the output * @param n The number of bytes to append from the start of the output
* sequence to the end of the input sequence. The remainder of the output * sequence to the end of the input sequence. The remainder of the output
@ -1656,24 +1744,69 @@ public:
size_ += (std::min)(n, string_.size() - size_); size_ += (std::min)(n, string_.size() - size_);
string_.resize(size_); string_.resize(size_);
} }
#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
/// Remove characters from the input sequence. /// @b DynamicBuffer_v2: Grow the underlying memory by the specified number of
/// bytes.
/** /**
* Removes @c n characters from the beginning of the input sequence. * Resizes the string to accommodate an additional @c n bytes at the end.
* *
* @note If @c n is greater than the size of the input sequence, the entire * @throws std::length_error If <tt>size() + n > max_size()</tt>.
* input sequence is consumed and no error is issued. */
void grow(std::size_t n)
{
if (size() > max_size() || max_size() - size() < n)
{
std::length_error ex("dynamic_string_buffer too long");
boost::asio::detail::throw_exception(ex);
}
string_.resize(size() + n);
}
/// @b DynamicBuffer_v2: Shrink the underlying memory by the specified number
/// of bytes.
/**
* Erases @c n bytes from the end of the string by resizing the basic_string
* object. If @c n is greater than the current size of the string, the string
* is emptied.
*/
void shrink(std::size_t n)
{
string_.resize(n > size() ? 0 : size() - n);
}
/// @b DynamicBuffer_v1: Remove characters from the input sequence.
/// @b DynamicBuffer_v2: Consume the specified number of bytes from the
/// beginning of the underlying memory.
/**
* @b DynamicBuffer_v1: Removes @c n characters from the beginning of the
* input sequence. @note If @c n is greater than the size of the input
* sequence, the entire input sequence is consumed and no error is issued.
*
* @b DynamicBuffer_v2: Erases @c n bytes from the beginning of the string.
* If @c n is greater than the current size of the string, the string is
* emptied.
*/ */
void consume(std::size_t n) void consume(std::size_t n)
{ {
std::size_t consume_length = (std::min)(n, size_); #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
string_.erase(0, consume_length); if (size_ != (std::numeric_limits<std::size_t>::max)())
size_ -= consume_length; {
std::size_t consume_length = (std::min)(n, size_);
string_.erase(0, consume_length);
size_ -= consume_length;
return;
}
#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
string_.erase(0, n);
} }
private: private:
std::basic_string<Elem, Traits, Allocator>& string_; std::basic_string<Elem, Traits, Allocator>& string_;
#if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
std::size_t size_; std::size_t size_;
#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
const std::size_t max_size_; const std::size_t max_size_;
}; };
@ -1685,19 +1818,20 @@ template <typename Elem, typename Allocator>
class dynamic_vector_buffer class dynamic_vector_buffer
{ {
public: public:
/// The type used to represent the input sequence as a list of buffers. /// The type used to represent a sequence of constant buffers that refers to
/// the underlying memory.
typedef BOOST_ASIO_CONST_BUFFER const_buffers_type; typedef BOOST_ASIO_CONST_BUFFER const_buffers_type;
/// The type used to represent the output sequence as a list of buffers. /// The type used to represent a sequence of mutable buffers that refers to
/// the underlying memory.
typedef BOOST_ASIO_MUTABLE_BUFFER mutable_buffers_type; typedef BOOST_ASIO_MUTABLE_BUFFER mutable_buffers_type;
/// Construct a dynamic buffer from a string. /// Construct a dynamic buffer from a vector.
/** /**
* @param v The vector to be used as backing storage for the dynamic buffer. * @param v The vector to be used as backing storage for the dynamic buffer.
* Any existing data in the vector is treated as the dynamic buffer's input * The object stores a reference to the vector and the user is responsible
* sequence. The object stores a reference to the vector and the user is * for ensuring that the vector object remains valid while the
* responsible for ensuring that the vector object remains valid until the * dynamic_vector_buffer object, and copies of the object, are in use.
* dynamic_vector_buffer object is destroyed.
* *
* @param maximum_size Specifies a maximum size for the buffer, in bytes. * @param maximum_size Specifies a maximum size for the buffer, in bytes.
*/ */
@ -1705,77 +1839,149 @@ public:
std::size_t maximum_size = std::size_t maximum_size =
(std::numeric_limits<std::size_t>::max)()) BOOST_ASIO_NOEXCEPT (std::numeric_limits<std::size_t>::max)()) BOOST_ASIO_NOEXCEPT
: vector_(v), : vector_(v),
size_(vector_.size()), #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
size_((std::numeric_limits<std::size_t>::max)()),
#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
max_size_(maximum_size) max_size_(maximum_size)
{ {
} }
/// @b DynamicBuffer_v2: Copy construct a dynamic buffer.
dynamic_vector_buffer(const dynamic_vector_buffer& other) BOOST_ASIO_NOEXCEPT
: vector_(other.vector_),
#if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
size_(other.size_),
#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
max_size_(other.max_size_)
{
}
#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
/// Move construct a dynamic buffer. /// Move construct a dynamic buffer.
dynamic_vector_buffer(dynamic_vector_buffer&& other) BOOST_ASIO_NOEXCEPT dynamic_vector_buffer(dynamic_vector_buffer&& other) BOOST_ASIO_NOEXCEPT
: vector_(other.vector_), : vector_(other.vector_),
#if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
size_(other.size_), size_(other.size_),
#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
max_size_(other.max_size_) max_size_(other.max_size_)
{ {
} }
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
/// Get the size of the input sequence. /// @b DynamicBuffer_v1: Get the size of the input sequence.
/// @b DynamicBuffer_v2: Get the current size of the underlying memory.
/**
* @returns @b DynamicBuffer_v1 The current size of the input sequence.
* @b DynamicBuffer_v2: The current size of the underlying vector if less than
* max_size(). Otherwise returns max_size().
*/
std::size_t size() const BOOST_ASIO_NOEXCEPT std::size_t size() const BOOST_ASIO_NOEXCEPT
{ {
return size_; #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
if (size_ != (std::numeric_limits<std::size_t>::max)())
return size_;
#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
return (std::min)(vector_.size(), max_size());
} }
/// Get the maximum size of the dynamic buffer. /// Get the maximum size of the dynamic buffer.
/** /**
* @returns The allowed maximum of the sum of the sizes of the input sequence * @returns @b DynamicBuffer_v1: The allowed maximum of the sum of the sizes
* and output sequence. * of the input sequence and output sequence. @b DynamicBuffer_v2: The allowed
* maximum size of the underlying memory.
*/ */
std::size_t max_size() const BOOST_ASIO_NOEXCEPT std::size_t max_size() const BOOST_ASIO_NOEXCEPT
{ {
return max_size_; return max_size_;
} }
/// Get the current capacity of the dynamic buffer. /// Get the maximum size that the buffer may grow to without triggering
/// reallocation.
/** /**
* @returns The current total capacity of the buffer, i.e. for both the input * @returns @b DynamicBuffer_v1: The current total capacity of the buffer,
* sequence and output sequence. * i.e. for both the input sequence and output sequence. @b DynamicBuffer_v2:
* The current capacity of the underlying vector if less than max_size().
* Otherwise returns max_size().
*/ */
std::size_t capacity() const BOOST_ASIO_NOEXCEPT std::size_t capacity() const BOOST_ASIO_NOEXCEPT
{ {
return vector_.capacity(); return (std::min)(vector_.capacity(), max_size());
} }
/// Get a list of buffers that represents the input sequence. #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
/// @b DynamicBuffer_v1: Get a list of buffers that represents the input
/// sequence.
/** /**
* @returns An object of type @c const_buffers_type that satisfies * @returns An object of type @c const_buffers_type that satisfies
* ConstBufferSequence requirements, representing the basic_string memory in * ConstBufferSequence requirements, representing the vector memory in the
* input sequence. * input sequence.
* *
* @note The returned object is invalidated by any @c dynamic_vector_buffer * @note The returned object is invalidated by any @c dynamic_vector_buffer
* or @c basic_string member function that modifies the input sequence or * or @c vector member function that modifies the input sequence or output
* output sequence. * sequence.
*/ */
const_buffers_type data() const BOOST_ASIO_NOEXCEPT const_buffers_type data() const BOOST_ASIO_NOEXCEPT
{ {
return const_buffers_type(boost::asio::buffer(vector_, size_)); return const_buffers_type(boost::asio::buffer(vector_, size_));
} }
#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
/// Get a list of buffers that represents the output sequence, with the given /// @b DynamicBuffer_v2: Get a sequence of buffers that represents the
/// size. /// underlying memory.
/** /**
* Ensures that the output sequence can accommodate @c n bytes, resizing the * @param pos Position of the first byte to represent in the buffer sequence
* basic_string object as necessary. *
* @param n The number of bytes to return in the buffer sequence. If the
* underlying memory is shorter, the buffer sequence represents as many bytes
* as are available.
* *
* @returns An object of type @c mutable_buffers_type that satisfies * @returns An object of type @c mutable_buffers_type that satisfies
* MutableBufferSequence requirements, representing basic_string memory * MutableBufferSequence requirements, representing the vector memory.
* at the start of the output sequence of size @c n. *
* @note The returned object is invalidated by any @c dynamic_vector_buffer
* or @c vector member function that resizes or erases the vector.
*/
mutable_buffers_type data(std::size_t pos, std::size_t n) BOOST_ASIO_NOEXCEPT
{
return mutable_buffers_type(boost::asio::buffer(
boost::asio::buffer(vector_, max_size_) + pos, n));
}
/// @b DynamicBuffer_v2: Get a sequence of buffers that represents the
/// underlying memory.
/**
* @param pos Position of the first byte to represent in the buffer sequence
*
* @param n The number of bytes to return in the buffer sequence. If the
* underlying memory is shorter, the buffer sequence represents as many bytes
* as are available.
*
* @note The returned object is invalidated by any @c dynamic_vector_buffer
* or @c vector member function that resizes or erases the vector.
*/
const_buffers_type data(std::size_t pos,
std::size_t n) const BOOST_ASIO_NOEXCEPT
{
return const_buffers_type(boost::asio::buffer(
boost::asio::buffer(vector_, max_size_) + pos, n));
}
#if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
/// @b DynamicBuffer_v1: Get a list of buffers that represents the output
/// sequence, with the given size.
/**
* Ensures that the output sequence can accommodate @c n bytes, resizing the
* vector object as necessary.
*
* @returns An object of type @c mutable_buffers_type that satisfies
* MutableBufferSequence requirements, representing vector memory at the
* start of the output sequence of size @c n.
* *
* @throws std::length_error If <tt>size() + n > max_size()</tt>. * @throws std::length_error If <tt>size() + n > max_size()</tt>.
* *
* @note The returned object is invalidated by any @c dynamic_vector_buffer * @note The returned object is invalidated by any @c dynamic_vector_buffer
* or @c basic_string member function that modifies the input sequence or * or @c vector member function that modifies the input sequence or output
* output sequence. * sequence.
*/ */
mutable_buffers_type prepare(std::size_t n) mutable_buffers_type prepare(std::size_t n)
{ {
@ -1785,12 +1991,16 @@ public:
boost::asio::detail::throw_exception(ex); boost::asio::detail::throw_exception(ex);
} }
if (size_ == (std::numeric_limits<std::size_t>::max)())
size_ = vector_.size(); // Enable v1 behaviour.
vector_.resize(size_ + n); vector_.resize(size_ + n);
return boost::asio::buffer(boost::asio::buffer(vector_) + size_, n); return boost::asio::buffer(boost::asio::buffer(vector_) + size_, n);
} }
/// Move bytes from the output sequence to the input sequence. /// @b DynamicBuffer_v1: Move bytes from the output sequence to the input
/// sequence.
/** /**
* @param n The number of bytes to append from the start of the output * @param n The number of bytes to append from the start of the output
* sequence to the end of the input sequence. The remainder of the output * sequence to the end of the input sequence. The remainder of the output
@ -1807,24 +2017,69 @@ public:
size_ += (std::min)(n, vector_.size() - size_); size_ += (std::min)(n, vector_.size() - size_);
vector_.resize(size_); vector_.resize(size_);
} }
#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
/// Remove characters from the input sequence. /// @b DynamicBuffer_v2: Grow the underlying memory by the specified number of
/// bytes.
/** /**
* Removes @c n characters from the beginning of the input sequence. * Resizes the vector to accommodate an additional @c n bytes at the end.
* *
* @note If @c n is greater than the size of the input sequence, the entire * @throws std::length_error If <tt>size() + n > max_size()</tt>.
* input sequence is consumed and no error is issued. */
void grow(std::size_t n)
{
if (size() > max_size() || max_size() - size() < n)
{
std::length_error ex("dynamic_vector_buffer too long");
boost::asio::detail::throw_exception(ex);
}
vector_.resize(size() + n);
}
/// @b DynamicBuffer_v2: Shrink the underlying memory by the specified number
/// of bytes.
/**
* Erases @c n bytes from the end of the vector by resizing the vector
* object. If @c n is greater than the current size of the vector, the vector
* is emptied.
*/
void shrink(std::size_t n)
{
vector_.resize(n > size() ? 0 : size() - n);
}
/// @b DynamicBuffer_v1: Remove characters from the input sequence.
/// @b DynamicBuffer_v2: Consume the specified number of bytes from the
/// beginning of the underlying memory.
/**
* @b DynamicBuffer_v1: Removes @c n characters from the beginning of the
* input sequence. @note If @c n is greater than the size of the input
* sequence, the entire input sequence is consumed and no error is issued.
*
* @b DynamicBuffer_v2: Erases @c n bytes from the beginning of the vector.
* If @c n is greater than the current size of the vector, the vector is
* emptied.
*/ */
void consume(std::size_t n) void consume(std::size_t n)
{ {
std::size_t consume_length = (std::min)(n, size_); #if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
vector_.erase(vector_.begin(), vector_.begin() + consume_length); if (size_ != (std::numeric_limits<std::size_t>::max)())
size_ -= consume_length; {
std::size_t consume_length = (std::min)(n, size_);
vector_.erase(vector_.begin(), vector_.begin() + consume_length);
size_ -= consume_length;
return;
}
#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
vector_.erase(vector_.begin(), vector_.begin() + (std::min)(size(), n));
} }
private: private:
std::vector<Elem, Allocator>& vector_; std::vector<Elem, Allocator>& vector_;
#if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
std::size_t size_; std::size_t size_;
#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
const std::size_t max_size_; const std::size_t max_size_;
}; };
@ -2159,6 +2414,85 @@ inline std::size_t buffer_copy(const MutableBufferSequence& target,
} // namespace asio } // namespace asio
} // namespace boost } // namespace boost
#include <boost/asio/detail/pop_options.hpp>
#include <boost/asio/detail/is_buffer_sequence.hpp>
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
/// Trait to determine whether a type satisfies the MutableBufferSequence
/// requirements.
template <typename T>
struct is_mutable_buffer_sequence
#if defined(GENERATING_DOCUMENTATION)
: integral_constant<bool, automatically_determined>
#else // defined(GENERATING_DOCUMENTATION)
: boost::asio::detail::is_buffer_sequence<T, mutable_buffer>
#endif // defined(GENERATING_DOCUMENTATION)
{
};
/// Trait to determine whether a type satisfies the ConstBufferSequence
/// requirements.
template <typename T>
struct is_const_buffer_sequence
#if defined(GENERATING_DOCUMENTATION)
: integral_constant<bool, automatically_determined>
#else // defined(GENERATING_DOCUMENTATION)
: boost::asio::detail::is_buffer_sequence<T, const_buffer>
#endif // defined(GENERATING_DOCUMENTATION)
{
};
#if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
/// Trait to determine whether a type satisfies the DynamicBuffer_v1
/// requirements.
template <typename T>
struct is_dynamic_buffer_v1
#if defined(GENERATING_DOCUMENTATION)
: integral_constant<bool, automatically_determined>
#else // defined(GENERATING_DOCUMENTATION)
: boost::asio::detail::is_dynamic_buffer_v1<T>
#endif // defined(GENERATING_DOCUMENTATION)
{
};
#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
/// Trait to determine whether a type satisfies the DynamicBuffer_v2
/// requirements.
template <typename T>
struct is_dynamic_buffer_v2
#if defined(GENERATING_DOCUMENTATION)
: integral_constant<bool, automatically_determined>
#else // defined(GENERATING_DOCUMENTATION)
: boost::asio::detail::is_dynamic_buffer_v2<T>
#endif // defined(GENERATING_DOCUMENTATION)
{
};
/// Trait to determine whether a type satisfies the DynamicBuffer requirements.
/**
* If @c BOOST_ASIO_NO_DYNAMIC_BUFFER_V1 is not defined, determines whether the
* type satisfies the DynamicBuffer_v1 requirements. Otherwise, if @c
* BOOST_ASIO_NO_DYNAMIC_BUFFER_V1 is defined, determines whether the type
* satisfies the DynamicBuffer_v2 requirements.
*/
template <typename T>
struct is_dynamic_buffer
#if defined(GENERATING_DOCUMENTATION)
: integral_constant<bool, automatically_determined>
#elif defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
: boost::asio::is_dynamic_buffer_v2<T>
#else // defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
: boost::asio::is_dynamic_buffer_v1<T>
#endif // defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
{
};
} // namespace asio
} // namespace boost
#include <boost/asio/detail/pop_options.hpp> #include <boost/asio/detail/pop_options.hpp>
#endif // BOOST_ASIO_BUFFER_HPP #endif // BOOST_ASIO_BUFFER_HPP

View File

@ -2,7 +2,7 @@
// buffered_read_stream.hpp // buffered_read_stream.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -26,7 +26,6 @@
#include <boost/asio/detail/noncopyable.hpp> #include <boost/asio/detail/noncopyable.hpp>
#include <boost/asio/detail/type_traits.hpp> #include <boost/asio/detail/type_traits.hpp>
#include <boost/asio/error.hpp> #include <boost/asio/error.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/detail/push_options.hpp> #include <boost/asio/detail/push_options.hpp>
@ -106,22 +105,6 @@ public:
return next_layer_.lowest_layer().get_executor(); return next_layer_.lowest_layer().get_executor();
} }
#if !defined(BOOST_ASIO_NO_DEPRECATED)
/// (Deprecated: Use get_executor().) Get the io_context associated with the
/// object.
boost::asio::io_context& get_io_context()
{
return next_layer_.get_io_context();
}
/// (Deprecated: Use get_executor().) Get the io_context associated with the
/// object.
boost::asio::io_context& get_io_service()
{
return next_layer_.get_io_service();
}
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
/// Close the stream. /// Close the stream.
void close() void close()
{ {

View File

@ -2,7 +2,7 @@
// buffered_read_stream_fwd.hpp // buffered_read_stream_fwd.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// buffered_stream.hpp // buffered_stream.hpp
// ~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -23,7 +23,6 @@
#include <boost/asio/buffered_stream_fwd.hpp> #include <boost/asio/buffered_stream_fwd.hpp>
#include <boost/asio/detail/noncopyable.hpp> #include <boost/asio/detail/noncopyable.hpp>
#include <boost/asio/error.hpp> #include <boost/asio/error.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/detail/push_options.hpp> #include <boost/asio/detail/push_options.hpp>
@ -97,22 +96,6 @@ public:
return stream_impl_.lowest_layer().get_executor(); return stream_impl_.lowest_layer().get_executor();
} }
#if !defined(BOOST_ASIO_NO_DEPRECATED)
/// (Deprecated: Use get_executor().) Get the io_context associated with the
/// object.
boost::asio::io_context& get_io_context()
{
return stream_impl_.get_io_context();
}
/// (Deprecated: Use get_executor().) Get the io_context associated with the
/// object.
boost::asio::io_context& get_io_service()
{
return stream_impl_.get_io_service();
}
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
/// Close the stream. /// Close the stream.
void close() void close()
{ {

View File

@ -2,7 +2,7 @@
// buffered_stream_fwd.hpp // buffered_stream_fwd.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// buffered_write_stream.hpp // buffered_write_stream.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -25,7 +25,6 @@
#include <boost/asio/detail/noncopyable.hpp> #include <boost/asio/detail/noncopyable.hpp>
#include <boost/asio/detail/type_traits.hpp> #include <boost/asio/detail/type_traits.hpp>
#include <boost/asio/error.hpp> #include <boost/asio/error.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/write.hpp> #include <boost/asio/write.hpp>
#include <boost/asio/detail/push_options.hpp> #include <boost/asio/detail/push_options.hpp>
@ -106,22 +105,6 @@ public:
return next_layer_.lowest_layer().get_executor(); return next_layer_.lowest_layer().get_executor();
} }
#if !defined(BOOST_ASIO_NO_DEPRECATED)
/// (Deprecated: Use get_executor().) Get the io_context associated with the
/// object.
boost::asio::io_context& get_io_context()
{
return next_layer_.get_io_context();
}
/// (Deprecated: Use get_executor().) Get the io_context associated with the
/// object.
boost::asio::io_context& get_io_service()
{
return next_layer_.get_io_service();
}
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
/// Close the stream. /// Close the stream.
void close() void close()
{ {

View File

@ -2,7 +2,7 @@
// buffered_write_stream_fwd.hpp // buffered_write_stream_fwd.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// buffers_iterator.hpp // buffers_iterator.hpp
// ~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

90
boost/asio/co_spawn.hpp Normal file
View File

@ -0,0 +1,90 @@
//
// co_spawn.hpp
// ~~~~~~~~~~~~
//
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASIO_CO_SPAWN_HPP
#define BOOST_ASIO_CO_SPAWN_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
#if defined(BOOST_ASIO_HAS_CO_AWAIT) || defined(GENERATING_DOCUMENTATION)
#include <boost/asio/awaitable.hpp>
#include <boost/asio/execution_context.hpp>
#include <boost/asio/is_executor.hpp>
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
namespace detail {
template <typename T>
struct awaitable_signature;
template <typename T, typename Executor>
struct awaitable_signature<awaitable<T, Executor>>
{
typedef void type(std::exception_ptr, T);
};
template <typename Executor>
struct awaitable_signature<awaitable<void, Executor>>
{
typedef void type(std::exception_ptr);
};
} // namespace detail
/// Spawn a new thread of execution.
/**
* The entry point function object @c f must have the signature:
*
* @code awaitable<void, E> f(); @endcode
*
* where @c E is convertible from @c Executor.
*/
template <typename Executor, typename F, typename CompletionToken>
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken,
typename detail::awaitable_signature<typename result_of<F()>::type>::type)
co_spawn(const Executor& ex, F&& f, CompletionToken&& token,
typename enable_if<
is_executor<Executor>::value
>::type* = 0);
/// Spawn a new thread of execution.
/**
* The entry point function object @c f must have the signature:
*
* @code awaitable<void, E> f(); @endcode
*
* where @c E is convertible from @c ExecutionContext::executor_type.
*/
template <typename ExecutionContext, typename F, typename CompletionToken>
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken,
typename detail::awaitable_signature<typename result_of<F()>::type>::type)
co_spawn(ExecutionContext& ctx, F&& f, CompletionToken&& token,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0);
} // namespace asio
} // namespace boost
#include <boost/asio/detail/pop_options.hpp>
#include <boost/asio/impl/co_spawn.hpp>
#endif // defined(BOOST_ASIO_HAS_CO_AWAIT) || defined(GENERATING_DOCUMENTATION)
#endif // BOOST_ASIO_CO_SPAWN_HPP

View File

@ -2,7 +2,7 @@
// completion_condition.hpp // completion_condition.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

138
boost/asio/compose.hpp Normal file
View File

@ -0,0 +1,138 @@
//
// compose.hpp
// ~~~~~~~~~~~
//
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASIO_COMPOSE_HPP
#define BOOST_ASIO_COMPOSE_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
#include <boost/asio/async_result.hpp>
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
#if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) \
|| defined(GENERATING_DOCUMENTATION)
/// Launch an asynchronous operation with a stateful implementation.
/**
* The async_compose function simplifies the implementation of composed
* asynchronous operations automatically wrapping a stateful function object
* with a conforming intermediate completion handler.
*
* @param implementation A function object that contains the implementation of
* the composed asynchronous operation. The first argument to the function
* object is a non-const reference to the enclosing intermediate completion
* handler. The remaining arguments are any arguments that originate from the
* completion handlers of any asynchronous operations performed by the
* implementation.
* @param token The completion token.
*
* @param io_objects_or_executors Zero or more I/O objects or I/O executors for
* which outstanding work must be maintained.
*
* @par Example:
*
* @code struct async_echo_implementation
* {
* tcp::socket& socket_;
* boost::asio::mutable_buffer buffer_;
* enum { starting, reading, writing } state_;
*
* template <typename Self>
* void operator()(Self& self,
* boost::system::error_code error = {},
* std::size_t n = 0)
* {
* switch (state_)
* {
* case starting:
* state_ = reading;
* socket_.async_read_some(
* buffer_, std::move(self));
* break;
* case reading:
* if (error)
* {
* self.complete(error, 0);
* }
* else
* {
* state_ = writing;
* boost::asio::async_write(socket_, buffer_,
* boost::asio::transfer_exactly(n),
* std::move(self));
* }
* break;
* case writing:
* self.complete(error, n);
* break;
* }
* }
* };
*
* template <typename CompletionToken>
* auto async_echo(tcp::socket& socket,
* boost::asio::mutable_buffer buffer,
* CompletionToken&& token) ->
* typename boost::asio::async_result<
* typename std::decay<CompletionToken>::type,
* void(boost::system::error_code, std::size_t)>::return_type
* {
* return boost::asio::async_compose<CompletionToken,
* void(boost::system::error_code, std::size_t)>(
* async_echo_implementation{socket, buffer,
* async_echo_implementation::starting},
* token, socket);
* } @endcode
*/
template <typename CompletionToken, typename Signature,
typename Implementation, typename... IoObjectsOrExecutors>
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)
async_compose(BOOST_ASIO_MOVE_ARG(Implementation) implementation,
BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token,
BOOST_ASIO_MOVE_ARG(IoObjectsOrExecutors)... io_objects_or_executors);
#else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
// || defined(GENERATING_DOCUMENTATION)
template <typename CompletionToken, typename Signature, typename Implementation>
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)
async_compose(BOOST_ASIO_MOVE_ARG(Implementation) implementation,
BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token);
#define BOOST_ASIO_PRIVATE_ASYNC_COMPOSE_DEF(n) \
template <typename CompletionToken, typename Signature, \
typename Implementation, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature) \
async_compose(BOOST_ASIO_MOVE_ARG(Implementation) implementation, \
BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \
BOOST_ASIO_VARIADIC_MOVE_PARAMS(n));
/**/
BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_ASYNC_COMPOSE_DEF)
#undef BOOST_ASIO_PRIVATE_ASYNC_COMPOSE_DEF
#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
// || defined(GENERATING_DOCUMENTATION)
} // namespace asio
} // namespace boost
#include <boost/asio/detail/pop_options.hpp>
#include <boost/asio/impl/compose.hpp>
#endif // BOOST_ASIO_COMPOSE_HPP

View File

@ -2,7 +2,7 @@
// connect.hpp // connect.hpp
// ~~~~~~~~~~~ // ~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -59,7 +59,8 @@ struct is_endpoint_sequence
/** /**
* @defgroup connect boost::asio::connect * @defgroup connect boost::asio::connect
* *
* @brief Establishes a socket connection by trying each endpoint in a sequence. * @brief The @c connect function is a composed operation that establishes a
* socket connection by trying each endpoint in a sequence.
*/ */
/*@{*/ /*@{*/
@ -82,14 +83,13 @@ struct is_endpoint_sequence
* Otherwise, contains the error from the last connection attempt. * Otherwise, contains the error from the last connection attempt.
* *
* @par Example * @par Example
* @code tcp::resolver r(io_context); * @code tcp::resolver r(my_context);
* tcp::resolver::query q("host", "service"); * tcp::resolver::query q("host", "service");
* tcp::socket s(io_context); * tcp::socket s(my_context);
* boost::asio::connect(s, r.resolve(q)); @endcode * boost::asio::connect(s, r.resolve(q)); @endcode
*/ */
template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename EndpointSequence> template <typename Protocol, typename Executor, typename EndpointSequence>
typename Protocol::endpoint connect( typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,
basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
const EndpointSequence& endpoints, const EndpointSequence& endpoints,
typename enable_if<is_endpoint_sequence< typename enable_if<is_endpoint_sequence<
EndpointSequence>::value>::type* = 0); EndpointSequence>::value>::type* = 0);
@ -114,9 +114,9 @@ typename Protocol::endpoint connect(
* default-constructed endpoint. * default-constructed endpoint.
* *
* @par Example * @par Example
* @code tcp::resolver r(io_context); * @code tcp::resolver r(my_context);
* tcp::resolver::query q("host", "service"); * tcp::resolver::query q("host", "service");
* tcp::socket s(io_context); * tcp::socket s(my_context);
* boost::system::error_code ec; * boost::system::error_code ec;
* boost::asio::connect(s, r.resolve(q), ec); * boost::asio::connect(s, r.resolve(q), ec);
* if (ec) * if (ec)
@ -124,16 +124,15 @@ typename Protocol::endpoint connect(
* // An error occurred. * // An error occurred.
* } @endcode * } @endcode
*/ */
template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename EndpointSequence> template <typename Protocol, typename Executor, typename EndpointSequence>
typename Protocol::endpoint connect( typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,
basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
const EndpointSequence& endpoints, boost::system::error_code& ec, const EndpointSequence& endpoints, boost::system::error_code& ec,
typename enable_if<is_endpoint_sequence< typename enable_if<is_endpoint_sequence<
EndpointSequence>::value>::type* = 0); EndpointSequence>::value>::type* = 0);
#if !defined(BOOST_ASIO_NO_DEPRECATED) #if !defined(BOOST_ASIO_NO_DEPRECATED)
/// (Deprecated.) Establishes a socket connection by trying each endpoint in a /// (Deprecated: Use range overload.) Establishes a socket connection by trying
/// sequence. /// each endpoint in a sequence.
/** /**
* This function attempts to connect a socket to one of a sequence of * This function attempts to connect a socket to one of a sequence of
* endpoints. It does this by repeated calls to the socket's @c connect member * endpoints. It does this by repeated calls to the socket's @c connect member
@ -156,12 +155,12 @@ typename Protocol::endpoint connect(
* Iterator represents the end of the sequence. This is a valid assumption for * Iterator represents the end of the sequence. This is a valid assumption for
* iterator types such as @c boost::asio::ip::tcp::resolver::iterator. * iterator types such as @c boost::asio::ip::tcp::resolver::iterator.
*/ */
template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename Iterator> template <typename Protocol, typename Executor, typename Iterator>
Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s, Iterator begin, Iterator connect(basic_socket<Protocol, Executor>& s, Iterator begin,
typename enable_if<!is_endpoint_sequence<Iterator>::value>::type* = 0); typename enable_if<!is_endpoint_sequence<Iterator>::value>::type* = 0);
/// (Deprecated.) Establishes a socket connection by trying each endpoint in a /// (Deprecated: Use range overload.) Establishes a socket connection by trying
/// sequence. /// each endpoint in a sequence.
/** /**
* This function attempts to connect a socket to one of a sequence of * This function attempts to connect a socket to one of a sequence of
* endpoints. It does this by repeated calls to the socket's @c connect member * endpoints. It does this by repeated calls to the socket's @c connect member
@ -184,8 +183,8 @@ Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s, Iterator begin,
* Iterator represents the end of the sequence. This is a valid assumption for * Iterator represents the end of the sequence. This is a valid assumption for
* iterator types such as @c boost::asio::ip::tcp::resolver::iterator. * iterator types such as @c boost::asio::ip::tcp::resolver::iterator.
*/ */
template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename Iterator> template <typename Protocol, typename Executor, typename Iterator>
Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s, Iterator connect(basic_socket<Protocol, Executor>& s,
Iterator begin, boost::system::error_code& ec, Iterator begin, boost::system::error_code& ec,
typename enable_if<!is_endpoint_sequence<Iterator>::value>::type* = 0); typename enable_if<!is_endpoint_sequence<Iterator>::value>::type* = 0);
#endif // !defined(BOOST_ASIO_NO_DEPRECATED) #endif // !defined(BOOST_ASIO_NO_DEPRECATED)
@ -211,14 +210,14 @@ Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
* Otherwise, contains the error from the last connection attempt. * Otherwise, contains the error from the last connection attempt.
* *
* @par Example * @par Example
* @code tcp::resolver r(io_context); * @code tcp::resolver r(my_context);
* tcp::resolver::query q("host", "service"); * tcp::resolver::query q("host", "service");
* tcp::resolver::results_type e = r.resolve(q); * tcp::resolver::results_type e = r.resolve(q);
* tcp::socket s(io_context); * tcp::socket s(my_context);
* boost::asio::connect(s, e.begin(), e.end()); @endcode * boost::asio::connect(s, e.begin(), e.end()); @endcode
*/ */
template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename Iterator> template <typename Protocol, typename Executor, typename Iterator>
Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s, Iterator connect(basic_socket<Protocol, Executor>& s,
Iterator begin, Iterator end); Iterator begin, Iterator end);
/// Establishes a socket connection by trying each endpoint in a sequence. /// Establishes a socket connection by trying each endpoint in a sequence.
@ -243,10 +242,10 @@ Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
* endpoint. Otherwise, the end iterator. * endpoint. Otherwise, the end iterator.
* *
* @par Example * @par Example
* @code tcp::resolver r(io_context); * @code tcp::resolver r(my_context);
* tcp::resolver::query q("host", "service"); * tcp::resolver::query q("host", "service");
* tcp::resolver::results_type e = r.resolve(q); * tcp::resolver::results_type e = r.resolve(q);
* tcp::socket s(io_context); * tcp::socket s(my_context);
* boost::system::error_code ec; * boost::system::error_code ec;
* boost::asio::connect(s, e.begin(), e.end(), ec); * boost::asio::connect(s, e.begin(), e.end(), ec);
* if (ec) * if (ec)
@ -254,8 +253,8 @@ Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
* // An error occurred. * // An error occurred.
* } @endcode * } @endcode
*/ */
template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename Iterator> template <typename Protocol, typename Executor, typename Iterator>
Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s, Iterator connect(basic_socket<Protocol, Executor>& s,
Iterator begin, Iterator end, boost::system::error_code& ec); Iterator begin, Iterator end, boost::system::error_code& ec);
/// Establishes a socket connection by trying each endpoint in a sequence. /// Establishes a socket connection by trying each endpoint in a sequence.
@ -302,17 +301,16 @@ Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
* } * }
* }; @endcode * }; @endcode
* It would be used with the boost::asio::connect function as follows: * It would be used with the boost::asio::connect function as follows:
* @code tcp::resolver r(io_context); * @code tcp::resolver r(my_context);
* tcp::resolver::query q("host", "service"); * tcp::resolver::query q("host", "service");
* tcp::socket s(io_context); * tcp::socket s(my_context);
* tcp::endpoint e = boost::asio::connect(s, * tcp::endpoint e = boost::asio::connect(s,
* r.resolve(q), my_connect_condition()); * r.resolve(q), my_connect_condition());
* std::cout << "Connected to: " << e << std::endl; @endcode * std::cout << "Connected to: " << e << std::endl; @endcode
*/ */
template <typename Protocol BOOST_ASIO_SVC_TPARAM, template <typename Protocol, typename Executor,
typename EndpointSequence, typename ConnectCondition> typename EndpointSequence, typename ConnectCondition>
typename Protocol::endpoint connect( typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,
basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
const EndpointSequence& endpoints, ConnectCondition connect_condition, const EndpointSequence& endpoints, ConnectCondition connect_condition,
typename enable_if<is_endpoint_sequence< typename enable_if<is_endpoint_sequence<
EndpointSequence>::value>::type* = 0); EndpointSequence>::value>::type* = 0);
@ -362,9 +360,9 @@ typename Protocol::endpoint connect(
* } * }
* }; @endcode * }; @endcode
* It would be used with the boost::asio::connect function as follows: * It would be used with the boost::asio::connect function as follows:
* @code tcp::resolver r(io_context); * @code tcp::resolver r(my_context);
* tcp::resolver::query q("host", "service"); * tcp::resolver::query q("host", "service");
* tcp::socket s(io_context); * tcp::socket s(my_context);
* boost::system::error_code ec; * boost::system::error_code ec;
* tcp::endpoint e = boost::asio::connect(s, * tcp::endpoint e = boost::asio::connect(s,
* r.resolve(q), my_connect_condition(), ec); * r.resolve(q), my_connect_condition(), ec);
@ -377,18 +375,17 @@ typename Protocol::endpoint connect(
* std::cout << "Connected to: " << e << std::endl; * std::cout << "Connected to: " << e << std::endl;
* } @endcode * } @endcode
*/ */
template <typename Protocol BOOST_ASIO_SVC_TPARAM, template <typename Protocol, typename Executor,
typename EndpointSequence, typename ConnectCondition> typename EndpointSequence, typename ConnectCondition>
typename Protocol::endpoint connect( typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,
basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
const EndpointSequence& endpoints, ConnectCondition connect_condition, const EndpointSequence& endpoints, ConnectCondition connect_condition,
boost::system::error_code& ec, boost::system::error_code& ec,
typename enable_if<is_endpoint_sequence< typename enable_if<is_endpoint_sequence<
EndpointSequence>::value>::type* = 0); EndpointSequence>::value>::type* = 0);
#if !defined(BOOST_ASIO_NO_DEPRECATED) #if !defined(BOOST_ASIO_NO_DEPRECATED)
/// (Deprecated.) Establishes a socket connection by trying each endpoint in a /// (Deprecated: Use range overload.) Establishes a socket connection by trying
/// sequence. /// each endpoint in a sequence.
/** /**
* This function attempts to connect a socket to one of a sequence of * This function attempts to connect a socket to one of a sequence of
* endpoints. It does this by repeated calls to the socket's @c connect member * endpoints. It does this by repeated calls to the socket's @c connect member
@ -422,14 +419,14 @@ typename Protocol::endpoint connect(
* Iterator represents the end of the sequence. This is a valid assumption for * Iterator represents the end of the sequence. This is a valid assumption for
* iterator types such as @c boost::asio::ip::tcp::resolver::iterator. * iterator types such as @c boost::asio::ip::tcp::resolver::iterator.
*/ */
template <typename Protocol BOOST_ASIO_SVC_TPARAM, template <typename Protocol, typename Executor,
typename Iterator, typename ConnectCondition> typename Iterator, typename ConnectCondition>
Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s, Iterator connect(basic_socket<Protocol, Executor>& s,
Iterator begin, ConnectCondition connect_condition, Iterator begin, ConnectCondition connect_condition,
typename enable_if<!is_endpoint_sequence<Iterator>::value>::type* = 0); typename enable_if<!is_endpoint_sequence<Iterator>::value>::type* = 0);
/// (Deprecated.) Establishes a socket connection by trying each endpoint in a /// (Deprecated: Use range overload.) Establishes a socket connection by trying
/// sequence. /// each endpoint in a sequence.
/** /**
* This function attempts to connect a socket to one of a sequence of * This function attempts to connect a socket to one of a sequence of
* endpoints. It does this by repeated calls to the socket's @c connect member * endpoints. It does this by repeated calls to the socket's @c connect member
@ -463,9 +460,9 @@ Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
* Iterator represents the end of the sequence. This is a valid assumption for * Iterator represents the end of the sequence. This is a valid assumption for
* iterator types such as @c boost::asio::ip::tcp::resolver::iterator. * iterator types such as @c boost::asio::ip::tcp::resolver::iterator.
*/ */
template <typename Protocol BOOST_ASIO_SVC_TPARAM, template <typename Protocol, typename Executor,
typename Iterator, typename ConnectCondition> typename Iterator, typename ConnectCondition>
Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s, Iterator begin, Iterator connect(basic_socket<Protocol, Executor>& s, Iterator begin,
ConnectCondition connect_condition, boost::system::error_code& ec, ConnectCondition connect_condition, boost::system::error_code& ec,
typename enable_if<!is_endpoint_sequence<Iterator>::value>::type* = 0); typename enable_if<!is_endpoint_sequence<Iterator>::value>::type* = 0);
#endif // !defined(BOOST_ASIO_NO_DEPRECATED) #endif // !defined(BOOST_ASIO_NO_DEPRECATED)
@ -516,17 +513,17 @@ Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s, Iterator begin,
* } * }
* }; @endcode * }; @endcode
* It would be used with the boost::asio::connect function as follows: * It would be used with the boost::asio::connect function as follows:
* @code tcp::resolver r(io_context); * @code tcp::resolver r(my_context);
* tcp::resolver::query q("host", "service"); * tcp::resolver::query q("host", "service");
* tcp::resolver::results_type e = r.resolve(q); * tcp::resolver::results_type e = r.resolve(q);
* tcp::socket s(io_context); * tcp::socket s(my_context);
* tcp::resolver::results_type::iterator i = boost::asio::connect( * tcp::resolver::results_type::iterator i = boost::asio::connect(
* s, e.begin(), e.end(), my_connect_condition()); * s, e.begin(), e.end(), my_connect_condition());
* std::cout << "Connected to: " << i->endpoint() << std::endl; @endcode * std::cout << "Connected to: " << i->endpoint() << std::endl; @endcode
*/ */
template <typename Protocol BOOST_ASIO_SVC_TPARAM, template <typename Protocol, typename Executor,
typename Iterator, typename ConnectCondition> typename Iterator, typename ConnectCondition>
Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s, Iterator begin, Iterator connect(basic_socket<Protocol, Executor>& s, Iterator begin,
Iterator end, ConnectCondition connect_condition); Iterator end, ConnectCondition connect_condition);
/// Establishes a socket connection by trying each endpoint in a sequence. /// Establishes a socket connection by trying each endpoint in a sequence.
@ -576,10 +573,10 @@ Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s, Iterator begin,
* } * }
* }; @endcode * }; @endcode
* It would be used with the boost::asio::connect function as follows: * It would be used with the boost::asio::connect function as follows:
* @code tcp::resolver r(io_context); * @code tcp::resolver r(my_context);
* tcp::resolver::query q("host", "service"); * tcp::resolver::query q("host", "service");
* tcp::resolver::results_type e = r.resolve(q); * tcp::resolver::results_type e = r.resolve(q);
* tcp::socket s(io_context); * tcp::socket s(my_context);
* boost::system::error_code ec; * boost::system::error_code ec;
* tcp::resolver::results_type::iterator i = boost::asio::connect( * tcp::resolver::results_type::iterator i = boost::asio::connect(
* s, e.begin(), e.end(), my_connect_condition()); * s, e.begin(), e.end(), my_connect_condition());
@ -592,9 +589,9 @@ Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s, Iterator begin,
* std::cout << "Connected to: " << i->endpoint() << std::endl; * std::cout << "Connected to: " << i->endpoint() << std::endl;
* } @endcode * } @endcode
*/ */
template <typename Protocol BOOST_ASIO_SVC_TPARAM, template <typename Protocol, typename Executor,
typename Iterator, typename ConnectCondition> typename Iterator, typename ConnectCondition>
Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s, Iterator connect(basic_socket<Protocol, Executor>& s,
Iterator begin, Iterator end, ConnectCondition connect_condition, Iterator begin, Iterator end, ConnectCondition connect_condition,
boost::system::error_code& ec); boost::system::error_code& ec);
@ -603,8 +600,8 @@ Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
/** /**
* @defgroup async_connect boost::asio::async_connect * @defgroup async_connect boost::asio::async_connect
* *
* @brief Asynchronously establishes a socket connection by trying each * @brief The @c async_connect function is a composed asynchronous operation
* endpoint in a sequence. * that establishes a socket connection by trying each endpoint in a sequence.
*/ */
/*@{*/ /*@{*/
@ -635,14 +632,14 @@ Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
* const typename Protocol::endpoint& endpoint * const typename Protocol::endpoint& endpoint
* ); @endcode * ); @endcode
* Regardless of whether the asynchronous operation completes immediately or * Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation * not, the handler will not be invoked from within this function. On
* of the handler will be performed in a manner equivalent to using * immediate completion, invocation of the handler will be performed in a
* boost::asio::io_context::post(). * manner equivalent to using boost::asio::post().
* *
* @par Example * @par Example
* @code tcp::resolver r(io_context); * @code tcp::resolver r(my_context);
* tcp::resolver::query q("host", "service"); * tcp::resolver::query q("host", "service");
* tcp::socket s(io_context); * tcp::socket s(my_context);
* *
* // ... * // ...
* *
@ -669,19 +666,19 @@ Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
* // ... * // ...
* } @endcode * } @endcode
*/ */
template <typename Protocol BOOST_ASIO_SVC_TPARAM, template <typename Protocol, typename Executor,
typename EndpointSequence, typename RangeConnectHandler> typename EndpointSequence, typename RangeConnectHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(RangeConnectHandler, BOOST_ASIO_INITFN_RESULT_TYPE(RangeConnectHandler,
void (boost::system::error_code, typename Protocol::endpoint)) void (boost::system::error_code, typename Protocol::endpoint))
async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s, async_connect(basic_socket<Protocol, Executor>& s,
const EndpointSequence& endpoints, const EndpointSequence& endpoints,
BOOST_ASIO_MOVE_ARG(RangeConnectHandler) handler, BOOST_ASIO_MOVE_ARG(RangeConnectHandler) handler,
typename enable_if<is_endpoint_sequence< typename enable_if<is_endpoint_sequence<
EndpointSequence>::value>::type* = 0); EndpointSequence>::value>::type* = 0);
#if !defined(BOOST_ASIO_NO_DEPRECATED) #if !defined(BOOST_ASIO_NO_DEPRECATED)
/// (Deprecated.) Asynchronously establishes a socket connection by trying each /// (Deprecated: Use range overload.) Asynchronously establishes a socket
/// endpoint in a sequence. /// connection by trying each endpoint in a sequence.
/** /**
* This function attempts to connect a socket to one of a sequence of * This function attempts to connect a socket to one of a sequence of
* endpoints. It does this by repeated calls to the socket's @c async_connect * endpoints. It does this by repeated calls to the socket's @c async_connect
@ -707,20 +704,20 @@ async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
* Iterator iterator * Iterator iterator
* ); @endcode * ); @endcode
* Regardless of whether the asynchronous operation completes immediately or * Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation * not, the handler will not be invoked from within this function. On
* of the handler will be performed in a manner equivalent to using * immediate completion, invocation of the handler will be performed in a
* boost::asio::io_context::post(). * manner equivalent to using boost::asio::post().
* *
* @note This overload assumes that a default constructed object of type @c * @note This overload assumes that a default constructed object of type @c
* Iterator represents the end of the sequence. This is a valid assumption for * Iterator represents the end of the sequence. This is a valid assumption for
* iterator types such as @c boost::asio::ip::tcp::resolver::iterator. * iterator types such as @c boost::asio::ip::tcp::resolver::iterator.
*/ */
template <typename Protocol BOOST_ASIO_SVC_TPARAM, template <typename Protocol, typename Executor,
typename Iterator, typename IteratorConnectHandler> typename Iterator, typename IteratorConnectHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler, BOOST_ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler,
void (boost::system::error_code, Iterator)) void (boost::system::error_code, Iterator))
async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s, async_connect(basic_socket<Protocol, Executor>& s, Iterator begin,
Iterator begin, BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler, BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler,
typename enable_if<!is_endpoint_sequence<Iterator>::value>::type* = 0); typename enable_if<!is_endpoint_sequence<Iterator>::value>::type* = 0);
#endif // !defined(BOOST_ASIO_NO_DEPRECATED) #endif // !defined(BOOST_ASIO_NO_DEPRECATED)
@ -753,13 +750,13 @@ async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
* Iterator iterator * Iterator iterator
* ); @endcode * ); @endcode
* Regardless of whether the asynchronous operation completes immediately or * Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation * not, the handler will not be invoked from within this function. On
* of the handler will be performed in a manner equivalent to using * immediate completion, invocation of the handler will be performed in a
* boost::asio::io_context::post(). * manner equivalent to using boost::asio::post().
* *
* @par Example * @par Example
* @code std::vector<tcp::endpoint> endpoints = ...; * @code std::vector<tcp::endpoint> endpoints = ...;
* tcp::socket s(io_context); * tcp::socket s(my_context);
* boost::asio::async_connect(s, * boost::asio::async_connect(s,
* endpoints.begin(), endpoints.end(), * endpoints.begin(), endpoints.end(),
* connect_handler); * connect_handler);
@ -773,12 +770,11 @@ async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
* // ... * // ...
* } @endcode * } @endcode
*/ */
template <typename Protocol BOOST_ASIO_SVC_TPARAM, template <typename Protocol, typename Executor,
typename Iterator, typename IteratorConnectHandler> typename Iterator, typename IteratorConnectHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler, BOOST_ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler,
void (boost::system::error_code, Iterator)) void (boost::system::error_code, Iterator))
async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s, async_connect(basic_socket<Protocol, Executor>& s, Iterator begin, Iterator end,
Iterator begin, Iterator end,
BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler); BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler);
/// Asynchronously establishes a socket connection by trying each endpoint in a /// Asynchronously establishes a socket connection by trying each endpoint in a
@ -819,9 +815,9 @@ async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
* Iterator iterator * Iterator iterator
* ); @endcode * ); @endcode
* Regardless of whether the asynchronous operation completes immediately or * Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation * not, the handler will not be invoked from within this function. On
* of the handler will be performed in a manner equivalent to using * immediate completion, invocation of the handler will be performed in a
* boost::asio::io_context::post(). * manner equivalent to using boost::asio::post().
* *
* @par Example * @par Example
* The following connect condition function object can be used to output * The following connect condition function object can be used to output
@ -838,9 +834,9 @@ async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
* } * }
* }; @endcode * }; @endcode
* It would be used with the boost::asio::connect function as follows: * It would be used with the boost::asio::connect function as follows:
* @code tcp::resolver r(io_context); * @code tcp::resolver r(my_context);
* tcp::resolver::query q("host", "service"); * tcp::resolver::query q("host", "service");
* tcp::socket s(io_context); * tcp::socket s(my_context);
* *
* // ... * // ...
* *
@ -876,19 +872,19 @@ async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
* } * }
* } @endcode * } @endcode
*/ */
template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename EndpointSequence, template <typename Protocol, typename Executor, typename EndpointSequence,
typename ConnectCondition, typename RangeConnectHandler> typename ConnectCondition, typename RangeConnectHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(RangeConnectHandler, BOOST_ASIO_INITFN_RESULT_TYPE(RangeConnectHandler,
void (boost::system::error_code, typename Protocol::endpoint)) void (boost::system::error_code, typename Protocol::endpoint))
async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s, async_connect(basic_socket<Protocol, Executor>& s,
const EndpointSequence& endpoints, ConnectCondition connect_condition, const EndpointSequence& endpoints, ConnectCondition connect_condition,
BOOST_ASIO_MOVE_ARG(RangeConnectHandler) handler, BOOST_ASIO_MOVE_ARG(RangeConnectHandler) handler,
typename enable_if<is_endpoint_sequence< typename enable_if<is_endpoint_sequence<
EndpointSequence>::value>::type* = 0); EndpointSequence>::value>::type* = 0);
#if !defined(BOOST_ASIO_NO_DEPRECATED) #if !defined(BOOST_ASIO_NO_DEPRECATED)
/// (Deprecated.) Asynchronously establishes a socket connection by trying each /// (Deprecated: Use range overload.) Asynchronously establishes a socket
/// endpoint in a sequence. /// connection by trying each endpoint in a sequence.
/** /**
* This function attempts to connect a socket to one of a sequence of * This function attempts to connect a socket to one of a sequence of
* endpoints. It does this by repeated calls to the socket's @c async_connect * endpoints. It does this by repeated calls to the socket's @c async_connect
@ -925,19 +921,19 @@ async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
* Iterator iterator * Iterator iterator
* ); @endcode * ); @endcode
* Regardless of whether the asynchronous operation completes immediately or * Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation * not, the handler will not be invoked from within this function. On
* of the handler will be performed in a manner equivalent to using * immediate completion, invocation of the handler will be performed in a
* boost::asio::io_context::post(). * manner equivalent to using boost::asio::post().
* *
* @note This overload assumes that a default constructed object of type @c * @note This overload assumes that a default constructed object of type @c
* Iterator represents the end of the sequence. This is a valid assumption for * Iterator represents the end of the sequence. This is a valid assumption for
* iterator types such as @c boost::asio::ip::tcp::resolver::iterator. * iterator types such as @c boost::asio::ip::tcp::resolver::iterator.
*/ */
template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename Iterator, template <typename Protocol, typename Executor, typename Iterator,
typename ConnectCondition, typename IteratorConnectHandler> typename ConnectCondition, typename IteratorConnectHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler, BOOST_ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler,
void (boost::system::error_code, Iterator)) void (boost::system::error_code, Iterator))
async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s, Iterator begin, async_connect(basic_socket<Protocol, Executor>& s, Iterator begin,
ConnectCondition connect_condition, ConnectCondition connect_condition,
BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler, BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler,
typename enable_if<!is_endpoint_sequence<Iterator>::value>::type* = 0); typename enable_if<!is_endpoint_sequence<Iterator>::value>::type* = 0);
@ -983,9 +979,9 @@ async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s, Iterator begin,
* Iterator iterator * Iterator iterator
* ); @endcode * ); @endcode
* Regardless of whether the asynchronous operation completes immediately or * Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation * not, the handler will not be invoked from within this function. On
* of the handler will be performed in a manner equivalent to using * immediate completion, invocation of the handler will be performed in a
* boost::asio::io_context::post(). * manner equivalent to using boost::asio::post().
* *
* @par Example * @par Example
* The following connect condition function object can be used to output * The following connect condition function object can be used to output
@ -1002,9 +998,9 @@ async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s, Iterator begin,
* } * }
* }; @endcode * }; @endcode
* It would be used with the boost::asio::connect function as follows: * It would be used with the boost::asio::connect function as follows:
* @code tcp::resolver r(io_context); * @code tcp::resolver r(my_context);
* tcp::resolver::query q("host", "service"); * tcp::resolver::query q("host", "service");
* tcp::socket s(io_context); * tcp::socket s(my_context);
* *
* // ... * // ...
* *
@ -1041,12 +1037,12 @@ async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s, Iterator begin,
* } * }
* } @endcode * } @endcode
*/ */
template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename Iterator, template <typename Protocol, typename Executor, typename Iterator,
typename ConnectCondition, typename IteratorConnectHandler> typename ConnectCondition, typename IteratorConnectHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler, BOOST_ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler,
void (boost::system::error_code, Iterator)) void (boost::system::error_code, Iterator))
async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s, async_connect(basic_socket<Protocol, Executor>& s, Iterator begin,
Iterator begin, Iterator end, ConnectCondition connect_condition, Iterator end, ConnectCondition connect_condition,
BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler); BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler);
/*@}*/ /*@}*/

View File

@ -2,7 +2,7 @@
// coroutine.hpp // coroutine.hpp
// ~~~~~~~~~~~~~ // ~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -206,7 +206,7 @@ class coroutine_ref;
* { * {
* do * do
* { * {
* socket_.reset(new tcp::socket(io_context_)); * socket_.reset(new tcp::socket(my_context_));
* yield acceptor->async_accept(*socket_, *this); * yield acceptor->async_accept(*socket_, *this);
* fork server(*this)(); * fork server(*this)();
* } while (is_parent()); * } while (is_parent());
@ -228,7 +228,7 @@ class coroutine_ref;
* Note that @c fork doesn't do the actual forking by itself. It is the * Note that @c fork doesn't do the actual forking by itself. It is the
* application's responsibility to create a clone of the coroutine and call it. * application's responsibility to create a clone of the coroutine and call it.
* The clone can be called immediately, as above, or scheduled for delayed * The clone can be called immediately, as above, or scheduled for delayed
* execution using something like io_context::post(). * execution using something like boost::asio::post().
* *
* @par Alternate macro names * @par Alternate macro names
* *

View File

@ -1,468 +0,0 @@
//
// datagram_socket_service.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASIO_DATAGRAM_SOCKET_SERVICE_HPP
#define BOOST_ASIO_DATAGRAM_SOCKET_SERVICE_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
#include <cstddef>
#include <boost/asio/async_result.hpp>
#include <boost/asio/detail/type_traits.hpp>
#include <boost/asio/error.hpp>
#include <boost/asio/io_context.hpp>
#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
# include <boost/asio/detail/null_socket_service.hpp>
#elif defined(BOOST_ASIO_HAS_IOCP)
# include <boost/asio/detail/win_iocp_socket_service.hpp>
#else
# include <boost/asio/detail/reactive_socket_service.hpp>
#endif
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
/// Default service implementation for a datagram socket.
template <typename Protocol>
class datagram_socket_service
#if defined(GENERATING_DOCUMENTATION)
: public boost::asio::io_context::service
#else
: public boost::asio::detail::service_base<datagram_socket_service<Protocol> >
#endif
{
public:
#if defined(GENERATING_DOCUMENTATION)
/// The unique service identifier.
static boost::asio::io_context::id id;
#endif
/// The protocol type.
typedef Protocol protocol_type;
/// The endpoint type.
typedef typename Protocol::endpoint endpoint_type;
private:
// The type of the platform-specific implementation.
#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
typedef detail::null_socket_service<Protocol> service_impl_type;
#elif defined(BOOST_ASIO_HAS_IOCP)
typedef detail::win_iocp_socket_service<Protocol> service_impl_type;
#else
typedef detail::reactive_socket_service<Protocol> service_impl_type;
#endif
public:
/// The type of a datagram socket.
#if defined(GENERATING_DOCUMENTATION)
typedef implementation_defined implementation_type;
#else
typedef typename service_impl_type::implementation_type implementation_type;
#endif
/// The native socket type.
#if defined(GENERATING_DOCUMENTATION)
typedef implementation_defined native_handle_type;
#else
typedef typename service_impl_type::native_handle_type native_handle_type;
#endif
/// Construct a new datagram socket service for the specified io_context.
explicit datagram_socket_service(boost::asio::io_context& io_context)
: boost::asio::detail::service_base<
datagram_socket_service<Protocol> >(io_context),
service_impl_(io_context)
{
}
/// Construct a new datagram socket implementation.
void construct(implementation_type& impl)
{
service_impl_.construct(impl);
}
#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
/// Move-construct a new datagram socket implementation.
void move_construct(implementation_type& impl,
implementation_type& other_impl)
{
service_impl_.move_construct(impl, other_impl);
}
/// Move-assign from another datagram socket implementation.
void move_assign(implementation_type& impl,
datagram_socket_service& other_service,
implementation_type& other_impl)
{
service_impl_.move_assign(impl, other_service.service_impl_, other_impl);
}
// All socket services have access to each other's implementations.
template <typename Protocol1> friend class datagram_socket_service;
/// Move-construct a new datagram socket implementation from another protocol
/// type.
template <typename Protocol1>
void converting_move_construct(implementation_type& impl,
datagram_socket_service<Protocol1>& other_service,
typename datagram_socket_service<
Protocol1>::implementation_type& other_impl,
typename enable_if<is_convertible<
Protocol1, Protocol>::value>::type* = 0)
{
service_impl_.template converting_move_construct<Protocol1>(
impl, other_service.service_impl_, other_impl);
}
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
/// Destroy a datagram socket implementation.
void destroy(implementation_type& impl)
{
service_impl_.destroy(impl);
}
// Open a new datagram socket implementation.
BOOST_ASIO_SYNC_OP_VOID open(implementation_type& impl,
const protocol_type& protocol, boost::system::error_code& ec)
{
if (protocol.type() == BOOST_ASIO_OS_DEF(SOCK_DGRAM))
service_impl_.open(impl, protocol, ec);
else
ec = boost::asio::error::invalid_argument;
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Assign an existing native socket to a datagram socket.
BOOST_ASIO_SYNC_OP_VOID assign(implementation_type& impl,
const protocol_type& protocol, const native_handle_type& native_socket,
boost::system::error_code& ec)
{
service_impl_.assign(impl, protocol, native_socket, ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Determine whether the socket is open.
bool is_open(const implementation_type& impl) const
{
return service_impl_.is_open(impl);
}
/// Close a datagram socket implementation.
BOOST_ASIO_SYNC_OP_VOID close(implementation_type& impl,
boost::system::error_code& ec)
{
service_impl_.close(impl, ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Release ownership of the underlying socket.
native_handle_type release(implementation_type& impl,
boost::system::error_code& ec)
{
return service_impl_.release(impl, ec);
}
/// Get the native socket implementation.
native_handle_type native_handle(implementation_type& impl)
{
return service_impl_.native_handle(impl);
}
/// Cancel all asynchronous operations associated with the socket.
BOOST_ASIO_SYNC_OP_VOID cancel(implementation_type& impl,
boost::system::error_code& ec)
{
service_impl_.cancel(impl, ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Determine whether the socket is at the out-of-band data mark.
bool at_mark(const implementation_type& impl,
boost::system::error_code& ec) const
{
return service_impl_.at_mark(impl, ec);
}
/// Determine the number of bytes available for reading.
std::size_t available(const implementation_type& impl,
boost::system::error_code& ec) const
{
return service_impl_.available(impl, ec);
}
// Bind the datagram socket to the specified local endpoint.
BOOST_ASIO_SYNC_OP_VOID bind(implementation_type& impl,
const endpoint_type& endpoint, boost::system::error_code& ec)
{
service_impl_.bind(impl, endpoint, ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Connect the datagram socket to the specified endpoint.
BOOST_ASIO_SYNC_OP_VOID connect(implementation_type& impl,
const endpoint_type& peer_endpoint, boost::system::error_code& ec)
{
service_impl_.connect(impl, peer_endpoint, ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Start an asynchronous connect.
template <typename ConnectHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(ConnectHandler,
void (boost::system::error_code))
async_connect(implementation_type& impl,
const endpoint_type& peer_endpoint,
BOOST_ASIO_MOVE_ARG(ConnectHandler) handler)
{
async_completion<ConnectHandler,
void (boost::system::error_code)> init(handler);
service_impl_.async_connect(impl, peer_endpoint, init.completion_handler);
return init.result.get();
}
/// Set a socket option.
template <typename SettableSocketOption>
BOOST_ASIO_SYNC_OP_VOID set_option(implementation_type& impl,
const SettableSocketOption& option, boost::system::error_code& ec)
{
service_impl_.set_option(impl, option, ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Get a socket option.
template <typename GettableSocketOption>
BOOST_ASIO_SYNC_OP_VOID get_option(const implementation_type& impl,
GettableSocketOption& option, boost::system::error_code& ec) const
{
service_impl_.get_option(impl, option, ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Perform an IO control command on the socket.
template <typename IoControlCommand>
BOOST_ASIO_SYNC_OP_VOID io_control(implementation_type& impl,
IoControlCommand& command, boost::system::error_code& ec)
{
service_impl_.io_control(impl, command, ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Gets the non-blocking mode of the socket.
bool non_blocking(const implementation_type& impl) const
{
return service_impl_.non_blocking(impl);
}
/// Sets the non-blocking mode of the socket.
BOOST_ASIO_SYNC_OP_VOID non_blocking(implementation_type& impl,
bool mode, boost::system::error_code& ec)
{
service_impl_.non_blocking(impl, mode, ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Gets the non-blocking mode of the native socket implementation.
bool native_non_blocking(const implementation_type& impl) const
{
return service_impl_.native_non_blocking(impl);
}
/// Sets the non-blocking mode of the native socket implementation.
BOOST_ASIO_SYNC_OP_VOID native_non_blocking(implementation_type& impl,
bool mode, boost::system::error_code& ec)
{
service_impl_.native_non_blocking(impl, mode, ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Get the local endpoint.
endpoint_type local_endpoint(const implementation_type& impl,
boost::system::error_code& ec) const
{
return service_impl_.local_endpoint(impl, ec);
}
/// Get the remote endpoint.
endpoint_type remote_endpoint(const implementation_type& impl,
boost::system::error_code& ec) const
{
return service_impl_.remote_endpoint(impl, ec);
}
/// Disable sends or receives on the socket.
BOOST_ASIO_SYNC_OP_VOID shutdown(implementation_type& impl,
socket_base::shutdown_type what, boost::system::error_code& ec)
{
service_impl_.shutdown(impl, what, ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Wait for the socket to become ready to read, ready to write, or to have
/// pending error conditions.
BOOST_ASIO_SYNC_OP_VOID wait(implementation_type& impl,
socket_base::wait_type w, boost::system::error_code& ec)
{
service_impl_.wait(impl, w, ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Asynchronously wait for the socket to become ready to read, ready to
/// write, or to have pending error conditions.
template <typename WaitHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler,
void (boost::system::error_code))
async_wait(implementation_type& impl, socket_base::wait_type w,
BOOST_ASIO_MOVE_ARG(WaitHandler) handler)
{
async_completion<WaitHandler,
void (boost::system::error_code)> init(handler);
service_impl_.async_wait(impl, w, init.completion_handler);
return init.result.get();
}
/// Send the given data to the peer.
template <typename ConstBufferSequence>
std::size_t send(implementation_type& impl,
const ConstBufferSequence& buffers,
socket_base::message_flags flags, boost::system::error_code& ec)
{
return service_impl_.send(impl, buffers, flags, ec);
}
/// Start an asynchronous send.
template <typename ConstBufferSequence, typename WriteHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
void (boost::system::error_code, std::size_t))
async_send(implementation_type& impl, const ConstBufferSequence& buffers,
socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{
async_completion<WriteHandler,
void (boost::system::error_code, std::size_t)> init(handler);
service_impl_.async_send(impl, buffers, flags, init.completion_handler);
return init.result.get();
}
/// Send a datagram to the specified endpoint.
template <typename ConstBufferSequence>
std::size_t send_to(implementation_type& impl,
const ConstBufferSequence& buffers, const endpoint_type& destination,
socket_base::message_flags flags, boost::system::error_code& ec)
{
return service_impl_.send_to(impl, buffers, destination, flags, ec);
}
/// Start an asynchronous send.
template <typename ConstBufferSequence, typename WriteHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
void (boost::system::error_code, std::size_t))
async_send_to(implementation_type& impl,
const ConstBufferSequence& buffers, const endpoint_type& destination,
socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{
async_completion<WriteHandler,
void (boost::system::error_code, std::size_t)> init(handler);
service_impl_.async_send_to(impl, buffers,
destination, flags, init.completion_handler);
return init.result.get();
}
/// Receive some data from the peer.
template <typename MutableBufferSequence>
std::size_t receive(implementation_type& impl,
const MutableBufferSequence& buffers,
socket_base::message_flags flags, boost::system::error_code& ec)
{
return service_impl_.receive(impl, buffers, flags, ec);
}
/// Start an asynchronous receive.
template <typename MutableBufferSequence, typename ReadHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t))
async_receive(implementation_type& impl,
const MutableBufferSequence& buffers,
socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{
async_completion<ReadHandler,
void (boost::system::error_code, std::size_t)> init(handler);
service_impl_.async_receive(impl, buffers, flags, init.completion_handler);
return init.result.get();
}
/// Receive a datagram with the endpoint of the sender.
template <typename MutableBufferSequence>
std::size_t receive_from(implementation_type& impl,
const MutableBufferSequence& buffers, endpoint_type& sender_endpoint,
socket_base::message_flags flags, boost::system::error_code& ec)
{
return service_impl_.receive_from(impl, buffers, sender_endpoint, flags,
ec);
}
/// Start an asynchronous receive that will get the endpoint of the sender.
template <typename MutableBufferSequence, typename ReadHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t))
async_receive_from(implementation_type& impl,
const MutableBufferSequence& buffers, endpoint_type& sender_endpoint,
socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{
async_completion<ReadHandler,
void (boost::system::error_code, std::size_t)> init(handler);
service_impl_.async_receive_from(impl, buffers,
sender_endpoint, flags, init.completion_handler);
return init.result.get();
}
private:
// Destroy all user-defined handler objects owned by the service.
void shutdown()
{
service_impl_.shutdown();
}
// The platform-specific implementation.
service_impl_type service_impl_;
};
} // namespace asio
} // namespace boost
#include <boost/asio/detail/pop_options.hpp>
#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
#endif // BOOST_ASIO_DATAGRAM_SOCKET_SERVICE_HPP

View File

@ -2,7 +2,7 @@
// deadline_timer.hpp // deadline_timer.hpp
// ~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -1,175 +0,0 @@
//
// deadline_timer_service.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASIO_DEADLINE_TIMER_SERVICE_HPP
#define BOOST_ASIO_DEADLINE_TIMER_SERVICE_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) \
|| defined(GENERATING_DOCUMENTATION)
#include <cstddef>
#include <boost/asio/async_result.hpp>
#include <boost/asio/detail/deadline_timer_service.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/time_traits.hpp>
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
/// Default service implementation for a timer.
template <typename TimeType,
typename TimeTraits = boost::asio::time_traits<TimeType> >
class deadline_timer_service
#if defined(GENERATING_DOCUMENTATION)
: public boost::asio::io_context::service
#else
: public boost::asio::detail::service_base<
deadline_timer_service<TimeType, TimeTraits> >
#endif
{
public:
#if defined(GENERATING_DOCUMENTATION)
/// The unique service identifier.
static boost::asio::io_context::id id;
#endif
/// The time traits type.
typedef TimeTraits traits_type;
/// The time type.
typedef typename traits_type::time_type time_type;
/// The duration type.
typedef typename traits_type::duration_type duration_type;
private:
// The type of the platform-specific implementation.
typedef detail::deadline_timer_service<traits_type> service_impl_type;
public:
/// The implementation type of the deadline timer.
#if defined(GENERATING_DOCUMENTATION)
typedef implementation_defined implementation_type;
#else
typedef typename service_impl_type::implementation_type implementation_type;
#endif
/// Construct a new timer service for the specified io_context.
explicit deadline_timer_service(boost::asio::io_context& io_context)
: boost::asio::detail::service_base<
deadline_timer_service<TimeType, TimeTraits> >(io_context),
service_impl_(io_context)
{
}
/// Construct a new timer implementation.
void construct(implementation_type& impl)
{
service_impl_.construct(impl);
}
/// Destroy a timer implementation.
void destroy(implementation_type& impl)
{
service_impl_.destroy(impl);
}
/// Cancel any asynchronous wait operations associated with the timer.
std::size_t cancel(implementation_type& impl, boost::system::error_code& ec)
{
return service_impl_.cancel(impl, ec);
}
/// Cancels one asynchronous wait operation associated with the timer.
std::size_t cancel_one(implementation_type& impl,
boost::system::error_code& ec)
{
return service_impl_.cancel_one(impl, ec);
}
/// Get the expiry time for the timer as an absolute time.
time_type expires_at(const implementation_type& impl) const
{
return service_impl_.expiry(impl);
}
/// Set the expiry time for the timer as an absolute time.
std::size_t expires_at(implementation_type& impl,
const time_type& expiry_time, boost::system::error_code& ec)
{
return service_impl_.expires_at(impl, expiry_time, ec);
}
/// Get the expiry time for the timer relative to now.
duration_type expires_from_now(const implementation_type& impl) const
{
return TimeTraits::subtract(service_impl_.expiry(impl), TimeTraits::now());
}
/// Set the expiry time for the timer relative to now.
std::size_t expires_from_now(implementation_type& impl,
const duration_type& expiry_time, boost::system::error_code& ec)
{
return service_impl_.expires_after(impl, expiry_time, ec);
}
// Perform a blocking wait on the timer.
void wait(implementation_type& impl, boost::system::error_code& ec)
{
service_impl_.wait(impl, ec);
}
// Start an asynchronous wait on the timer.
template <typename WaitHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler,
void (boost::system::error_code))
async_wait(implementation_type& impl,
BOOST_ASIO_MOVE_ARG(WaitHandler) handler)
{
async_completion<WaitHandler,
void (boost::system::error_code)> init(handler);
service_impl_.async_wait(impl, init.completion_handler);
return init.result.get();
}
private:
// Destroy all user-defined handler objects owned by the service.
void shutdown()
{
service_impl_.shutdown();
}
// The platform-specific implementation.
service_impl_type service_impl_;
};
} // namespace asio
} // namespace boost
#include <boost/asio/detail/pop_options.hpp>
#endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
// || defined(GENERATING_DOCUMENTATION)
#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
#endif // BOOST_ASIO_DEADLINE_TIMER_SERVICE_HPP

View File

@ -2,7 +2,7 @@
// defer.hpp // defer.hpp
// ~~~~~~~~~ // ~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -32,6 +32,11 @@ namespace asio {
* executor. The function object is queued for execution, and is never called * executor. The function object is queued for execution, and is never called
* from the current thread prior to returning from <tt>defer()</tt>. * from the current thread prior to returning from <tt>defer()</tt>.
* *
* The use of @c defer(), rather than @ref post(), indicates the caller's
* preference that the executor defer the queueing of the function object. This
* may allow the executor to optimise queueing for cases when the function
* object represents a continuation of the current call context.
*
* This function has the following effects: * This function has the following effects:
* *
* @li Constructs a function object handler of type @c Handler, initialized * @li Constructs a function object handler of type @c Handler, initialized
@ -60,6 +65,11 @@ BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) defer(
* The function object is queued for execution, and is never called from the * The function object is queued for execution, and is never called from the
* current thread prior to returning from <tt>defer()</tt>. * current thread prior to returning from <tt>defer()</tt>.
* *
* The use of @c defer(), rather than @ref post(), indicates the caller's
* preference that the executor defer the queueing of the function object. This
* may allow the executor to optimise queueing for cases when the function
* object represents a continuation of the current call context.
*
* This function has the following effects: * This function has the following effects:
* *
* @li Constructs a function object handler of type @c Handler, initialized * @li Constructs a function object handler of type @c Handler, initialized

64
boost/asio/detached.hpp Normal file
View File

@ -0,0 +1,64 @@
//
// detached.hpp
// ~~~~~~~~~~~~
//
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASIO_DETACHED_HPP
#define BOOST_ASIO_DETACHED_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
#include <memory>
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
/// Class used to specify that an asynchronous operation is detached.
/**
* The detached_t class is used to indicate that an asynchronous operation is
* detached. That is, there is no completion handler waiting for the
* operation's result. A detached_t object may be passed as a handler to an
* asynchronous operation, typically using the special value
* @c boost::asio::detached. For example:
* @code my_socket.async_send(my_buffer, boost::asio::detached);
* @endcode
*/
class detached_t
{
public:
/// Constructor.
BOOST_ASIO_CONSTEXPR detached_t()
{
}
};
/// A special value, similar to std::nothrow.
/**
* See the documentation for boost::asio::detached_t for a usage example.
*/
#if defined(BOOST_ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)
constexpr detached_t detached;
#elif defined(BOOST_ASIO_MSVC)
__declspec(selectany) detached_t detached;
#endif
} // namespace asio
} // namespace boost
#include <boost/asio/detail/pop_options.hpp>
#include <boost/asio/impl/detached.hpp>
#endif // BOOST_ASIO_DETACHED_HPP

View File

@ -2,7 +2,7 @@
// detail/array.hpp // detail/array.hpp
// ~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/array_fwd.hpp // detail/array_fwd.hpp
// ~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/assert.hpp // detail/assert.hpp
// ~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/atomic_count.hpp // detail/atomic_count.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/base_from_completion_cond.hpp // detail/base_from_completion_cond.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -28,8 +28,9 @@ template <typename CompletionCondition>
class base_from_completion_cond class base_from_completion_cond
{ {
protected: protected:
explicit base_from_completion_cond(CompletionCondition completion_condition) explicit base_from_completion_cond(CompletionCondition& completion_condition)
: completion_condition_(completion_condition) : completion_condition_(
BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition))
{ {
} }

View File

@ -2,7 +2,7 @@
// detail/bind_handler.hpp // detail/bind_handler.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/buffer_resize_guard.hpp // detail/buffer_resize_guard.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/buffer_sequence_adapter.hpp // detail/buffer_sequence_adapter.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/buffered_stream_storage.hpp // detail/buffered_stream_storage.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/call_stack.hpp // detail/call_stack.hpp
// ~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/chrono.hpp // detail/chrono.hpp
// ~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/chrono_time_traits.hpp // detail/chrono_time_traits.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/completion_handler.hpp // detail/completion_handler.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/concurrency_hint.hpp // detail/concurrency_hint.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/conditionally_enabled_event.hpp // detail/conditionally_enabled_event.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/conditionally_enabled_mutex.hpp // detail/conditionally_enabled_mutex.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/config.hpp // detail/config.hpp
// ~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -70,9 +70,6 @@
# define BOOST_ASIO_MSVC _MSC_VER # define BOOST_ASIO_MSVC _MSC_VER
# endif // defined(BOOST_ASIO_HAS_BOOST_CONFIG) && defined(BOOST_MSVC) # endif // defined(BOOST_ASIO_HAS_BOOST_CONFIG) && defined(BOOST_MSVC)
#endif // !defined(BOOST_ASIO_MSVC) #endif // !defined(BOOST_ASIO_MSVC)
#if defined(BOOST_ASIO_MSVC)
# include <ciso646> // Needed for _HAS_CXX17.
#endif // defined(BOOST_ASIO_MSVC)
// Clang / libc++ detection. // Clang / libc++ detection.
#if defined(__clang__) #if defined(__clang__)
@ -111,15 +108,26 @@
# define BOOST_ASIO_HAS_MOVE 1 # define BOOST_ASIO_HAS_MOVE 1
# endif // (_MSC_VER >= 1700) # endif // (_MSC_VER >= 1700)
# endif // defined(BOOST_ASIO_MSVC) # endif // defined(BOOST_ASIO_MSVC)
# if defined(__INTEL_CXX11_MODE__)
# if defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1500)
# define BOOST_ASIO_HAS_MOVE 1
# endif // defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1500)
# if defined(__ICL) && (__ICL >= 1500)
# define BOOST_ASIO_HAS_MOVE 1
# endif // defined(__ICL) && (__ICL >= 1500)
# endif // defined(__INTEL_CXX11_MODE__)
# endif // !defined(BOOST_ASIO_DISABLE_MOVE) # endif // !defined(BOOST_ASIO_DISABLE_MOVE)
#endif // !defined(BOOST_ASIO_HAS_MOVE) #endif // !defined(BOOST_ASIO_HAS_MOVE)
// If BOOST_ASIO_MOVE_CAST isn't defined, and move support is available, define // If BOOST_ASIO_MOVE_CAST isn't defined, and move support is available, define
// BOOST_ASIO_MOVE_ARG and BOOST_ASIO_MOVE_CAST to take advantage of rvalue // * BOOST_ASIO_MOVE_ARG,
// references and perfect forwarding. // * BOOST_ASIO_NONDEDUCED_MOVE_ARG, and
// * BOOST_ASIO_MOVE_CAST
// to take advantage of rvalue references and perfect forwarding.
#if defined(BOOST_ASIO_HAS_MOVE) && !defined(BOOST_ASIO_MOVE_CAST) #if defined(BOOST_ASIO_HAS_MOVE) && !defined(BOOST_ASIO_MOVE_CAST)
# define BOOST_ASIO_MOVE_ARG(type) type&& # define BOOST_ASIO_MOVE_ARG(type) type&&
# define BOOST_ASIO_MOVE_ARG2(type1, type2) type1, type2&& # define BOOST_ASIO_MOVE_ARG2(type1, type2) type1, type2&&
# define BOOST_ASIO_NONDEDUCED_MOVE_ARG(type) type&
# define BOOST_ASIO_MOVE_CAST(type) static_cast<type&&> # define BOOST_ASIO_MOVE_CAST(type) static_cast<type&&>
# define BOOST_ASIO_MOVE_CAST2(type1, type2) static_cast<type1, type2&&> # define BOOST_ASIO_MOVE_CAST2(type1, type2) static_cast<type1, type2&&>
#endif // defined(BOOST_ASIO_HAS_MOVE) && !defined(BOOST_ASIO_MOVE_CAST) #endif // defined(BOOST_ASIO_HAS_MOVE) && !defined(BOOST_ASIO_MOVE_CAST)
@ -145,6 +153,7 @@
# else # else
# define BOOST_ASIO_MOVE_ARG(type) type # define BOOST_ASIO_MOVE_ARG(type) type
# endif # endif
# define BOOST_ASIO_NONDEDUCED_MOVE_ARG(type) const type&
# define BOOST_ASIO_MOVE_CAST(type) static_cast<const type&> # define BOOST_ASIO_MOVE_CAST(type) static_cast<const type&>
# define BOOST_ASIO_MOVE_CAST2(type1, type2) static_cast<const type1, type2&> # define BOOST_ASIO_MOVE_CAST2(type1, type2) static_cast<const type1, type2&>
#endif // !defined(BOOST_ASIO_MOVE_CAST) #endif // !defined(BOOST_ASIO_MOVE_CAST)
@ -229,7 +238,7 @@
// Support noexcept on compilers known to allow it. // Support noexcept on compilers known to allow it.
#if !defined(BOOST_ASIO_NOEXCEPT) #if !defined(BOOST_ASIO_NOEXCEPT)
# if !defined(BOOST_ASIO_DISABLE_NOEXCEPT) # if !defined(BOOST_ASIO_DISABLE_NOEXCEPT)
# if (BOOST_VERSION >= 105300) # if defined(BOOST_ASIO_HAS_BOOST_CONFIG) && (BOOST_VERSION >= 105300)
# define BOOST_ASIO_NOEXCEPT BOOST_NOEXCEPT # define BOOST_ASIO_NOEXCEPT BOOST_NOEXCEPT
# define BOOST_ASIO_NOEXCEPT_OR_NOTHROW BOOST_NOEXCEPT_OR_NOTHROW # define BOOST_ASIO_NOEXCEPT_OR_NOTHROW BOOST_NOEXCEPT_OR_NOTHROW
# elif defined(__clang__) # elif defined(__clang__)
@ -275,9 +284,9 @@
# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4) # endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4)
# endif // defined(__GNUC__) # endif // defined(__GNUC__)
# if defined(BOOST_ASIO_MSVC) # if defined(BOOST_ASIO_MSVC)
# if (_MSC_VER >= 1700) # if (_MSC_VER >= 1800)
# define BOOST_ASIO_HAS_DECLTYPE 1 # define BOOST_ASIO_HAS_DECLTYPE 1
# endif // (_MSC_VER >= 1700) # endif // (_MSC_VER >= 1800)
# endif // defined(BOOST_ASIO_MSVC) # endif // defined(BOOST_ASIO_MSVC)
# endif // !defined(BOOST_ASIO_DISABLE_DECLTYPE) # endif // !defined(BOOST_ASIO_DISABLE_DECLTYPE)
#endif // !defined(BOOST_ASIO_HAS_DECLTYPE) #endif // !defined(BOOST_ASIO_HAS_DECLTYPE)
@ -332,7 +341,7 @@
// Compliant C++11 compilers put noexcept specifiers on error_category members. // Compliant C++11 compilers put noexcept specifiers on error_category members.
#if !defined(BOOST_ASIO_ERROR_CATEGORY_NOEXCEPT) #if !defined(BOOST_ASIO_ERROR_CATEGORY_NOEXCEPT)
# if (BOOST_VERSION >= 105300) # if defined(BOOST_ASIO_HAS_BOOST_CONFIG) && (BOOST_VERSION >= 105300)
# define BOOST_ASIO_ERROR_CATEGORY_NOEXCEPT BOOST_NOEXCEPT # define BOOST_ASIO_ERROR_CATEGORY_NOEXCEPT BOOST_NOEXCEPT
# elif defined(__clang__) # elif defined(__clang__)
# if __has_feature(__cxx_noexcept__) # if __has_feature(__cxx_noexcept__)
@ -441,7 +450,13 @@
# if __has_include(<atomic>) # if __has_include(<atomic>)
# define BOOST_ASIO_HAS_STD_ATOMIC 1 # define BOOST_ASIO_HAS_STD_ATOMIC 1
# endif // __has_include(<atomic>) # endif // __has_include(<atomic>)
# endif // (__cplusplus >= 201103) # elif defined(__apple_build_version__) && defined(_LIBCPP_VERSION)
# if (__clang_major__ >= 10)
# if __has_include(<atomic>)
# define BOOST_ASIO_HAS_STD_ATOMIC 1
# endif // __has_include(<atomic>)
# endif // (__clang_major__ >= 10)
# endif /// defined(__apple_build_version__) && defined(_LIBCPP_VERSION)
# endif // defined(__clang__) # endif // defined(__clang__)
# if defined(__GNUC__) # if defined(__GNUC__)
# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4) # if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)
@ -493,9 +508,9 @@
// Boost support for chrono. // Boost support for chrono.
#if !defined(BOOST_ASIO_HAS_BOOST_CHRONO) #if !defined(BOOST_ASIO_HAS_BOOST_CHRONO)
# if !defined(BOOST_ASIO_DISABLE_BOOST_CHRONO) # if !defined(BOOST_ASIO_DISABLE_BOOST_CHRONO)
# if (BOOST_VERSION >= 104700) # if defined(BOOST_ASIO_HAS_BOOST_CONFIG) && (BOOST_VERSION >= 104700)
# define BOOST_ASIO_HAS_BOOST_CHRONO 1 # define BOOST_ASIO_HAS_BOOST_CHRONO 1
# endif // (BOOST_VERSION >= 104700) # endif // defined(BOOST_ASIO_HAS_BOOST_CONFIG) && (BOOST_VERSION >= 104700)
# endif // !defined(BOOST_ASIO_DISABLE_BOOST_CHRONO) # endif // !defined(BOOST_ASIO_DISABLE_BOOST_CHRONO)
#endif // !defined(BOOST_ASIO_HAS_BOOST_CHRONO) #endif // !defined(BOOST_ASIO_HAS_BOOST_CHRONO)
@ -759,9 +774,7 @@
# if defined(__GNUC__) # if defined(__GNUC__)
# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4) # if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)
# if defined(__GXX_EXPERIMENTAL_CXX0X__) # if defined(__GXX_EXPERIMENTAL_CXX0X__)
# if defined(_GLIBCXX_HAS_GTHREADS) # define BOOST_ASIO_HAS_STD_FUTURE 1
# define BOOST_ASIO_HAS_STD_FUTURE 1
# endif // defined(_GLIBCXX_HAS_GTHREADS)
# endif // defined(__GXX_EXPERIMENTAL_CXX0X__) # endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4) # endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)
# endif // defined(__GNUC__) # endif // defined(__GNUC__)
@ -777,23 +790,29 @@
#if !defined(BOOST_ASIO_HAS_STD_STRING_VIEW) #if !defined(BOOST_ASIO_HAS_STD_STRING_VIEW)
# if !defined(BOOST_ASIO_DISABLE_STD_STRING_VIEW) # if !defined(BOOST_ASIO_DISABLE_STD_STRING_VIEW)
# if defined(__clang__) # if defined(__clang__)
# if (__cplusplus >= 201703) # if defined(BOOST_ASIO_HAS_CLANG_LIBCXX)
# if __has_include(<string_view>) # if (__cplusplus >= 201402)
# define BOOST_ASIO_HAS_STD_STRING_VIEW 1 # if __has_include(<string_view>)
# endif // __has_include(<string_view>) # define BOOST_ASIO_HAS_STD_STRING_VIEW 1
# endif // (__cplusplus >= 201703) # endif // __has_include(<string_view>)
# endif // defined(__clang__) # endif // (__cplusplus >= 201402)
# if defined(__GNUC__) # else // defined(BOOST_ASIO_HAS_CLANG_LIBCXX)
# if (__cplusplus >= 201703)
# if __has_include(<string_view>)
# define BOOST_ASIO_HAS_STD_STRING_VIEW 1
# endif // __has_include(<string_view>)
# endif // (__cplusplus >= 201703)
# endif // defined(BOOST_ASIO_HAS_CLANG_LIBCXX)
# elif defined(__GNUC__)
# if (__GNUC__ >= 7) # if (__GNUC__ >= 7)
# if (__cplusplus >= 201703) # if (__cplusplus >= 201703)
# define BOOST_ASIO_HAS_STD_STRING_VIEW 1 # define BOOST_ASIO_HAS_STD_STRING_VIEW 1
# endif // (__cplusplus >= 201703) # endif // (__cplusplus >= 201703)
# endif // (__GNUC__ >= 7) # endif // (__GNUC__ >= 7)
# endif // defined(__GNUC__) # elif defined(BOOST_ASIO_MSVC)
# if defined(BOOST_ASIO_MSVC) # if (_MSC_VER >= 1910 && _MSVC_LANG >= 201703)
# if (_MSC_VER >= 1910 && _HAS_CXX17) # define BOOST_ASIO_HAS_STD_STRING_VIEW 1
# define BOOST_ASIO_HAS_STD_STRING_VIEW # endif // (_MSC_VER >= 1910 && _MSVC_LANG >= 201703)
# endif // (_MSC_VER >= 1910 && _HAS_CXX17)
# endif // defined(BOOST_ASIO_MSVC) # endif // defined(BOOST_ASIO_MSVC)
# endif // !defined(BOOST_ASIO_DISABLE_STD_STRING_VIEW) # endif // !defined(BOOST_ASIO_DISABLE_STD_STRING_VIEW)
#endif // !defined(BOOST_ASIO_HAS_STD_STRING_VIEW) #endif // !defined(BOOST_ASIO_HAS_STD_STRING_VIEW)
@ -802,11 +821,21 @@
#if !defined(BOOST_ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW) #if !defined(BOOST_ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW)
# if !defined(BOOST_ASIO_DISABLE_STD_EXPERIMENTAL_STRING_VIEW) # if !defined(BOOST_ASIO_DISABLE_STD_EXPERIMENTAL_STRING_VIEW)
# if defined(__clang__) # if defined(__clang__)
# if (__cplusplus >= 201402) # if defined(BOOST_ASIO_HAS_CLANG_LIBCXX)
# if __has_include(<experimental/string_view>) # if (_LIBCPP_VERSION < 7000)
# define BOOST_ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW 1 # if (__cplusplus >= 201402)
# endif // __has_include(<experimental/string_view>) # if __has_include(<experimental/string_view>)
# endif // (__cplusplus >= 201402) # define BOOST_ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW 1
# endif // __has_include(<experimental/string_view>)
# endif // (__cplusplus >= 201402)
# endif // (_LIBCPP_VERSION < 7000)
# else // defined(BOOST_ASIO_HAS_CLANG_LIBCXX)
# if (__cplusplus >= 201402)
# if __has_include(<experimental/string_view>)
# define BOOST_ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW 1
# endif // __has_include(<experimental/string_view>)
# endif // (__cplusplus >= 201402)
# endif // // defined(BOOST_ASIO_HAS_CLANG_LIBCXX)
# endif // defined(__clang__) # endif // defined(__clang__)
# if defined(__GNUC__) # if defined(__GNUC__)
# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)) || (__GNUC__ > 4) # if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)) || (__GNUC__ > 4)
@ -851,9 +880,9 @@
#if !defined(BOOST_ASIO_HAS_STD_INVOKE_RESULT) #if !defined(BOOST_ASIO_HAS_STD_INVOKE_RESULT)
# if !defined(BOOST_ASIO_DISABLE_STD_INVOKE_RESULT) # if !defined(BOOST_ASIO_DISABLE_STD_INVOKE_RESULT)
# if defined(BOOST_ASIO_MSVC) # if defined(BOOST_ASIO_MSVC)
# if (_MSC_VER >= 1910 && _HAS_CXX17) # if (_MSC_VER >= 1911 && _MSVC_LANG >= 201703)
# define BOOST_ASIO_HAS_STD_INVOKE_RESULT 1 # define BOOST_ASIO_HAS_STD_INVOKE_RESULT 1
# endif // (_MSC_VER >= 1910 && _HAS_CXX17) # endif // (_MSC_VER >= 1911 && _MSVC_LANG >= 201703)
# endif // defined(BOOST_ASIO_MSVC) # endif // defined(BOOST_ASIO_MSVC)
# endif // !defined(BOOST_ASIO_DISABLE_STD_INVOKE_RESULT) # endif // !defined(BOOST_ASIO_DISABLE_STD_INVOKE_RESULT)
#endif // !defined(BOOST_ASIO_HAS_STD_INVOKE_RESULT) #endif // !defined(BOOST_ASIO_HAS_STD_INVOKE_RESULT)
@ -903,15 +932,15 @@
# if defined(_MSC_VER) || defined(__BORLANDC__) # if defined(_MSC_VER) || defined(__BORLANDC__)
# pragma message( \ # pragma message( \
"Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately. For example:\n"\ "Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately. For example:\n"\
"- add -D_WIN32_WINNT=0x0501 to the compiler command line; or\n"\ "- add -D_WIN32_WINNT=0x0601 to the compiler command line; or\n"\
"- add _WIN32_WINNT=0x0501 to your project's Preprocessor Definitions.\n"\ "- add _WIN32_WINNT=0x0601 to your project's Preprocessor Definitions.\n"\
"Assuming _WIN32_WINNT=0x0501 (i.e. Windows XP target).") "Assuming _WIN32_WINNT=0x0601 (i.e. Windows 7 target).")
# else // defined(_MSC_VER) || defined(__BORLANDC__) # else // defined(_MSC_VER) || defined(__BORLANDC__)
# warning Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately. # warning Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately.
# warning For example, add -D_WIN32_WINNT=0x0501 to the compiler command line. # warning For example, add -D_WIN32_WINNT=0x0601 to the compiler command line.
# warning Assuming _WIN32_WINNT=0x0501 (i.e. Windows XP target). # warning Assuming _WIN32_WINNT=0x0601 (i.e. Windows 7 target).
# endif // defined(_MSC_VER) || defined(__BORLANDC__) # endif // defined(_MSC_VER) || defined(__BORLANDC__)
# define _WIN32_WINNT 0x0501 # define _WIN32_WINNT 0x0601
# endif // !defined(_WIN32_WINNT) && !defined(_WIN32_WINDOWS) # endif // !defined(_WIN32_WINNT) && !defined(_WIN32_WINDOWS)
# if defined(_MSC_VER) # if defined(_MSC_VER)
# if defined(_WIN32) && !defined(WIN32) # if defined(_WIN32) && !defined(WIN32)
@ -982,7 +1011,8 @@
|| defined(__FreeBSD__) \ || defined(__FreeBSD__) \
|| defined(__NetBSD__) \ || defined(__NetBSD__) \
|| defined(__OpenBSD__) \ || defined(__OpenBSD__) \
|| defined(__linux__) || defined(__linux__) \
|| defined(__HAIKU__)
# define BOOST_ASIO_HAS_UNISTD_H 1 # define BOOST_ASIO_HAS_UNISTD_H 1
# endif # endif
# endif // !defined(BOOST_ASIO_HAS_BOOST_CONFIG) # endif // !defined(BOOST_ASIO_HAS_BOOST_CONFIG)
@ -1202,6 +1232,8 @@
# define BOOST_ASIO_HAS_THREADS 1 # define BOOST_ASIO_HAS_THREADS 1
# elif defined(__APPLE__) # elif defined(__APPLE__)
# define BOOST_ASIO_HAS_THREADS 1 # define BOOST_ASIO_HAS_THREADS 1
# elif defined(__HAIKU__)
# define BOOST_ASIO_HAS_THREADS 1
# elif defined(_POSIX_THREADS) && (_POSIX_THREADS + 0 >= 0) # elif defined(_POSIX_THREADS) && (_POSIX_THREADS + 0 >= 0)
# define BOOST_ASIO_HAS_THREADS 1 # define BOOST_ASIO_HAS_THREADS 1
# elif defined(_PTHREADS) # elif defined(_PTHREADS)
@ -1217,6 +1249,8 @@
# define BOOST_ASIO_HAS_PTHREADS 1 # define BOOST_ASIO_HAS_PTHREADS 1
# elif defined(_POSIX_THREADS) && (_POSIX_THREADS + 0 >= 0) # elif defined(_POSIX_THREADS) && (_POSIX_THREADS + 0 >= 0)
# define BOOST_ASIO_HAS_PTHREADS 1 # define BOOST_ASIO_HAS_PTHREADS 1
# elif defined(__HAIKU__)
# define BOOST_ASIO_HAS_PTHREADS 1
# endif // defined(BOOST_ASIO_HAS_BOOST_CONFIG) && defined(BOOST_HAS_PTHREADS) # endif // defined(BOOST_ASIO_HAS_BOOST_CONFIG) && defined(BOOST_HAS_PTHREADS)
# endif // defined(BOOST_ASIO_HAS_THREADS) # endif // defined(BOOST_ASIO_HAS_THREADS)
#endif // !defined(BOOST_ASIO_HAS_PTHREADS) #endif // !defined(BOOST_ASIO_HAS_PTHREADS)
@ -1346,33 +1380,6 @@
// || (defined(__MACH__) && defined(__APPLE__)) // || (defined(__MACH__) && defined(__APPLE__))
#endif // !defined(BOOST_ASIO_DISABLE_SSIZE_T) #endif // !defined(BOOST_ASIO_DISABLE_SSIZE_T)
// Helper macros to manage the transition away from the old services-based API.
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
# define BOOST_ASIO_SVC_TPARAM , typename Service
# define BOOST_ASIO_SVC_TPARAM_DEF1(d1) , typename Service d1
# define BOOST_ASIO_SVC_TPARAM_DEF2(d1, d2) , typename Service d1, d2
# define BOOST_ASIO_SVC_TARG , Service
# define BOOST_ASIO_SVC_T Service
# define BOOST_ASIO_SVC_TPARAM1 , typename Service1
# define BOOST_ASIO_SVC_TPARAM1_DEF1(d1) , typename Service1 d1
# define BOOST_ASIO_SVC_TPARAM1_DEF2(d1, d2) , typename Service1 d1, d2
# define BOOST_ASIO_SVC_TARG1 , Service1
# define BOOST_ASIO_SVC_T1 Service1
# define BOOST_ASIO_SVC_ACCESS public
#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
# define BOOST_ASIO_SVC_TPARAM
# define BOOST_ASIO_SVC_TPARAM_DEF1(d1)
# define BOOST_ASIO_SVC_TPARAM_DEF2(d1, d2)
# define BOOST_ASIO_SVC_TARG
// BOOST_ASIO_SVC_T is defined at each point of use.
# define BOOST_ASIO_SVC_TPARAM1
# define BOOST_ASIO_SVC_TPARAM1_DEF1(d1)
# define BOOST_ASIO_SVC_TPARAM1_DEF2(d1, d2)
# define BOOST_ASIO_SVC_TARG1
// BOOST_ASIO_SVC_T1 is defined at each point of use.
# define BOOST_ASIO_SVC_ACCESS protected
#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
// Helper macros to manage transition away from error_code return values. // Helper macros to manage transition away from error_code return values.
#if defined(BOOST_ASIO_NO_DEPRECATED) #if defined(BOOST_ASIO_NO_DEPRECATED)
# define BOOST_ASIO_SYNC_OP_VOID void # define BOOST_ASIO_SYNC_OP_VOID void
@ -1424,11 +1431,11 @@
# endif // defined(BOOST_ASIO_MSVC) # endif // defined(BOOST_ASIO_MSVC)
# endif // !defined(BOOST_ASIO_DISABLE_CO_AWAIT) # endif // !defined(BOOST_ASIO_DISABLE_CO_AWAIT)
# if defined(__clang__) # if defined(__clang__)
# if (__cpp_coroutines >= 201703) # if (__cplusplus >= 201703) && (__cpp_coroutines >= 201703)
# if __has_include(<experimental/coroutine>) # if __has_include(<experimental/coroutine>)
# define BOOST_ASIO_HAS_CO_AWAIT 1 # define BOOST_ASIO_HAS_CO_AWAIT 1
# endif // __has_include(<experimental/coroutine>) # endif // __has_include(<experimental/coroutine>)
# endif // (__cpp_coroutines >= 201703) # endif // (__cplusplus >= 201703) && (__cpp_coroutines >= 201703)
# endif // defined(__clang__) # endif // defined(__clang__)
#endif // !defined(BOOST_ASIO_HAS_CO_AWAIT) #endif // !defined(BOOST_ASIO_HAS_CO_AWAIT)

View File

@ -2,7 +2,7 @@
// detail/consuming_buffers.hpp // detail/consuming_buffers.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/cstddef.hpp // detail/cstddef.hpp
// ~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/cstdint.hpp // detail/cstdint.hpp
// ~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/date_time_fwd.hpp // detail/date_time_fwd.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/deadline_timer_service.hpp // detail/deadline_timer_service.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -18,7 +18,7 @@
#include <boost/asio/detail/config.hpp> #include <boost/asio/detail/config.hpp>
#include <cstddef> #include <cstddef>
#include <boost/asio/error.hpp> #include <boost/asio/error.hpp>
#include <boost/asio/io_context.hpp> #include <boost/asio/execution_context.hpp>
#include <boost/asio/detail/bind_handler.hpp> #include <boost/asio/detail/bind_handler.hpp>
#include <boost/asio/detail/fenced_block.hpp> #include <boost/asio/detail/fenced_block.hpp>
#include <boost/asio/detail/memory.hpp> #include <boost/asio/detail/memory.hpp>
@ -44,7 +44,7 @@ namespace detail {
template <typename Time_Traits> template <typename Time_Traits>
class deadline_timer_service class deadline_timer_service
: public service_base<deadline_timer_service<Time_Traits> > : public execution_context_service_base<deadline_timer_service<Time_Traits> >
{ {
public: public:
// The time type. // The time type.
@ -64,9 +64,10 @@ public:
}; };
// Constructor. // Constructor.
deadline_timer_service(boost::asio::io_context& io_context) deadline_timer_service(execution_context& context)
: service_base<deadline_timer_service<Time_Traits> >(io_context), : execution_context_service_base<
scheduler_(boost::asio::use_service<timer_scheduler>(io_context)) deadline_timer_service<Time_Traits> >(context),
scheduler_(boost::asio::use_service<timer_scheduler>(context))
{ {
scheduler_.init_task(); scheduler_.init_task();
scheduler_.add_timer_queue(timer_queue_); scheduler_.add_timer_queue(timer_queue_);
@ -226,14 +227,15 @@ public:
} }
// Start an asynchronous wait on the timer. // Start an asynchronous wait on the timer.
template <typename Handler> template <typename Handler, typename IoExecutor>
void async_wait(implementation_type& impl, Handler& handler) void async_wait(implementation_type& impl,
Handler& handler, const IoExecutor& io_ex)
{ {
// Allocate and construct an operation to wrap the handler. // Allocate and construct an operation to wrap the handler.
typedef wait_handler<Handler> op; typedef wait_handler<Handler, IoExecutor> op;
typename op::ptr p = { boost::asio::detail::addressof(handler), typename op::ptr p = { boost::asio::detail::addressof(handler),
op::ptr::allocate(handler), 0 }; op::ptr::allocate(handler), 0 };
p.p = new (p.v) op(handler); p.p = new (p.v) op(handler, io_ex);
impl.might_have_pending_waits = true; impl.might_have_pending_waits = true;

View File

@ -2,7 +2,7 @@
// detail/dependent_type.hpp // detail/dependent_type.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/descriptor_ops.hpp // detail/descriptor_ops.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/descriptor_read_op.hpp // detail/descriptor_read_op.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -67,20 +67,21 @@ private:
MutableBufferSequence buffers_; MutableBufferSequence buffers_;
}; };
template <typename MutableBufferSequence, typename Handler> template <typename MutableBufferSequence, typename Handler, typename IoExecutor>
class descriptor_read_op class descriptor_read_op
: public descriptor_read_op_base<MutableBufferSequence> : public descriptor_read_op_base<MutableBufferSequence>
{ {
public: public:
BOOST_ASIO_DEFINE_HANDLER_PTR(descriptor_read_op); BOOST_ASIO_DEFINE_HANDLER_PTR(descriptor_read_op);
descriptor_read_op(int descriptor, descriptor_read_op(int descriptor, const MutableBufferSequence& buffers,
const MutableBufferSequence& buffers, Handler& handler) Handler& handler, const IoExecutor& io_ex)
: descriptor_read_op_base<MutableBufferSequence>( : descriptor_read_op_base<MutableBufferSequence>(
descriptor, buffers, &descriptor_read_op::do_complete), descriptor, buffers, &descriptor_read_op::do_complete),
handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)) handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
io_executor_(io_ex)
{ {
handler_work<Handler>::start(handler_); handler_work<Handler, IoExecutor>::start(handler_, io_executor_);
} }
static void do_complete(void* owner, operation* base, static void do_complete(void* owner, operation* base,
@ -90,7 +91,7 @@ public:
// Take ownership of the handler object. // Take ownership of the handler object.
descriptor_read_op* o(static_cast<descriptor_read_op*>(base)); descriptor_read_op* o(static_cast<descriptor_read_op*>(base));
ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
handler_work<Handler> w(o->handler_); handler_work<Handler, IoExecutor> w(o->handler_, o->io_executor_);
BOOST_ASIO_HANDLER_COMPLETION((*o)); BOOST_ASIO_HANDLER_COMPLETION((*o));
@ -117,6 +118,7 @@ public:
private: private:
Handler handler_; Handler handler_;
IoExecutor io_executor_;
}; };
} // namespace detail } // namespace detail

View File

@ -2,7 +2,7 @@
// detail/descriptor_write_op.hpp // detail/descriptor_write_op.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -67,20 +67,21 @@ private:
ConstBufferSequence buffers_; ConstBufferSequence buffers_;
}; };
template <typename ConstBufferSequence, typename Handler> template <typename ConstBufferSequence, typename Handler, typename IoExecutor>
class descriptor_write_op class descriptor_write_op
: public descriptor_write_op_base<ConstBufferSequence> : public descriptor_write_op_base<ConstBufferSequence>
{ {
public: public:
BOOST_ASIO_DEFINE_HANDLER_PTR(descriptor_write_op); BOOST_ASIO_DEFINE_HANDLER_PTR(descriptor_write_op);
descriptor_write_op(int descriptor, descriptor_write_op(int descriptor, const ConstBufferSequence& buffers,
const ConstBufferSequence& buffers, Handler& handler) Handler& handler, const IoExecutor& io_ex)
: descriptor_write_op_base<ConstBufferSequence>( : descriptor_write_op_base<ConstBufferSequence>(
descriptor, buffers, &descriptor_write_op::do_complete), descriptor, buffers, &descriptor_write_op::do_complete),
handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)) handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
io_executor_(io_ex)
{ {
handler_work<Handler>::start(handler_); handler_work<Handler, IoExecutor>::start(handler_, io_executor_);
} }
static void do_complete(void* owner, operation* base, static void do_complete(void* owner, operation* base,
@ -90,7 +91,7 @@ public:
// Take ownership of the handler object. // Take ownership of the handler object.
descriptor_write_op* o(static_cast<descriptor_write_op*>(base)); descriptor_write_op* o(static_cast<descriptor_write_op*>(base));
ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
handler_work<Handler> w(o->handler_); handler_work<Handler, IoExecutor> w(o->handler_, o->io_executor_);
BOOST_ASIO_HANDLER_COMPLETION((*o)); BOOST_ASIO_HANDLER_COMPLETION((*o));
@ -117,6 +118,7 @@ public:
private: private:
Handler handler_; Handler handler_;
IoExecutor io_executor_;
}; };
} // namespace detail } // namespace detail

View File

@ -2,7 +2,7 @@
// detail/dev_poll_reactor.hpp // detail/dev_poll_reactor.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/epoll_reactor.hpp // detail/epoll_reactor.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/event.hpp // detail/event.hpp
// ~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/eventfd_select_interrupter.hpp // detail/eventfd_select_interrupter.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2008 Roelof Naude (roelof.naude at gmail dot com) // Copyright (c) 2008 Roelof Naude (roelof.naude at gmail dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying

View File

@ -0,0 +1,106 @@
//
// detail/executor_function.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASIO_DETAIL_EXECUTOR_FUNCTION_HPP
#define BOOST_ASIO_DETAIL_EXECUTOR_FUNCTION_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
#include <boost/asio/detail/handler_alloc_helpers.hpp>
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
namespace detail {
class executor_function_base
{
public:
void complete()
{
func_(this, true);
}
void destroy()
{
func_(this, false);
}
protected:
typedef void (*func_type)(executor_function_base*, bool);
executor_function_base(func_type func)
: func_(func)
{
}
// Prevents deletion through this type.
~executor_function_base()
{
}
private:
func_type func_;
};
template <typename Function, typename Alloc>
class executor_function : public executor_function_base
{
public:
BOOST_ASIO_DEFINE_TAGGED_HANDLER_ALLOCATOR_PTR(
thread_info_base::executor_function_tag, executor_function);
template <typename F>
executor_function(BOOST_ASIO_MOVE_ARG(F) f, const Alloc& allocator)
: executor_function_base(&executor_function::do_complete),
function_(BOOST_ASIO_MOVE_CAST(F)(f)),
allocator_(allocator)
{
}
static void do_complete(executor_function_base* base, bool call)
{
// Take ownership of the function object.
executor_function* o(static_cast<executor_function*>(base));
Alloc allocator(o->allocator_);
ptr p = { detail::addressof(allocator), o, o };
// Make a copy of the function so that the memory can be deallocated before
// the upcall is made. Even if we're not about to make an upcall, a
// sub-object of the function may be the true owner of the memory
// associated with the function. Consequently, a local copy of the function
// is required to ensure that any owning sub-object remains valid until
// after we have deallocated the memory here.
Function function(BOOST_ASIO_MOVE_CAST(Function)(o->function_));
p.reset();
// Make the upcall if required.
if (call)
{
function();
}
}
private:
Function function_;
Alloc allocator_;
};
} // namespace detail
} // namespace asio
} // namespace boost
#include <boost/asio/detail/pop_options.hpp>
#endif // BOOST_ASIO_DETAIL_EXECUTOR_FUNCTION_HPP

View File

@ -2,7 +2,7 @@
// detail/executor_op.hpp // detail/executor_op.hpp
// ~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/fd_set_adapter.hpp // detail/fd_set_adapter.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/fenced_block.hpp // detail/fenced_block.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/functional.hpp // detail/functional.hpp
// ~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -0,0 +1,33 @@
//
// detail/future.hpp
// ~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_ASIO_DETAIL_FUTURE_HPP
#define BOOST_ASIO_DETAIL_FUTURE_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
#if defined(BOOST_ASIO_HAS_STD_FUTURE)
# include <future>
// Even though the future header is available, libstdc++ may not implement the
// std::future class itself. However, we need to have already included the
// future header to reliably test for _GLIBCXX_HAS_GTHREADS.
# if defined(__GNUC__) && !defined(BOOST_ASIO_HAS_CLANG_LIBCXX)
# if defined(_GLIBCXX_HAS_GTHREADS)
# define BOOST_ASIO_HAS_STD_FUTURE_CLASS 1
# endif // defined(_GLIBCXX_HAS_GTHREADS)
# else // defined(__GNUC__) && !defined(BOOST_ASIO_HAS_CLANG_LIBCXX)
# define BOOST_ASIO_HAS_STD_FUTURE_CLASS 1
# endif // defined(__GNUC__) && !defined(BOOST_ASIO_HAS_CLANG_LIBCXX)
#endif // defined(BOOST_ASIO_HAS_STD_FUTURE)
#endif // BOOST_ASIO_DETAIL_FUTURE_HPP

View File

@ -2,7 +2,7 @@
// detail/gcc_arm_fenced_block.hpp // detail/gcc_arm_fenced_block.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/gcc_hppa_fenced_block.hpp // detail/gcc_hppa_fenced_block.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/gcc_sync_fenced_block.hpp // detail/gcc_sync_fenced_block.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/gcc_x86_fenced_block.hpp // detail/gcc_x86_fenced_block.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/global.hpp // detail/global.hpp
// ~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/handler_alloc_helpers.hpp // detail/handler_alloc_helpers.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -194,7 +194,7 @@ struct get_hook_allocator<Handler, std::allocator<T> >
} \ } \
/**/ /**/
#define BOOST_ASIO_DEFINE_HANDLER_ALLOCATOR_PTR(op) \ #define BOOST_ASIO_DEFINE_TAGGED_HANDLER_ALLOCATOR_PTR(purpose, op) \
struct ptr \ struct ptr \
{ \ { \
const Alloc* a; \ const Alloc* a; \
@ -207,9 +207,10 @@ struct get_hook_allocator<Handler, std::allocator<T> >
static op* allocate(const Alloc& a) \ static op* allocate(const Alloc& a) \
{ \ { \
typedef typename ::boost::asio::detail::get_recycling_allocator< \ typedef typename ::boost::asio::detail::get_recycling_allocator< \
Alloc>::type recycling_allocator_type; \ Alloc, purpose>::type recycling_allocator_type; \
BOOST_ASIO_REBIND_ALLOC(recycling_allocator_type, op) a1( \ BOOST_ASIO_REBIND_ALLOC(recycling_allocator_type, op) a1( \
::boost::asio::detail::get_recycling_allocator<Alloc>::get(a)); \ ::boost::asio::detail::get_recycling_allocator< \
Alloc, purpose>::get(a)); \
return a1.allocate(1); \ return a1.allocate(1); \
} \ } \
void reset() \ void reset() \
@ -222,9 +223,10 @@ struct get_hook_allocator<Handler, std::allocator<T> >
if (v) \ if (v) \
{ \ { \
typedef typename ::boost::asio::detail::get_recycling_allocator< \ typedef typename ::boost::asio::detail::get_recycling_allocator< \
Alloc>::type recycling_allocator_type; \ Alloc, purpose>::type recycling_allocator_type; \
BOOST_ASIO_REBIND_ALLOC(recycling_allocator_type, op) a1( \ BOOST_ASIO_REBIND_ALLOC(recycling_allocator_type, op) a1( \
::boost::asio::detail::get_recycling_allocator<Alloc>::get(*a)); \ ::boost::asio::detail::get_recycling_allocator< \
Alloc, purpose>::get(*a)); \
a1.deallocate(static_cast<op*>(v), 1); \ a1.deallocate(static_cast<op*>(v), 1); \
v = 0; \ v = 0; \
} \ } \
@ -232,6 +234,11 @@ struct get_hook_allocator<Handler, std::allocator<T> >
} \ } \
/**/ /**/
#define BOOST_ASIO_DEFINE_HANDLER_ALLOCATOR_PTR(op) \
BOOST_ASIO_DEFINE_TAGGED_HANDLER_ALLOCATOR_PTR( \
::boost::asio::detail::thread_info_base::default_tag, op ) \
/**/
#include <boost/asio/detail/pop_options.hpp> #include <boost/asio/detail/pop_options.hpp>
#endif // BOOST_ASIO_DETAIL_HANDLER_ALLOC_HELPERS_HPP #endif // BOOST_ASIO_DETAIL_HANDLER_ALLOC_HELPERS_HPP

View File

@ -2,7 +2,7 @@
// detail/handler_cont_helpers.hpp // detail/handler_cont_helpers.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/handler_invoke_helpers.hpp // detail/handler_invoke_helpers.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/handler_tracking.hpp // detail/handler_tracking.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/handler_type_requirements.hpp // detail/handler_type_requirements.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/handler_work.hpp // detail/handler_work.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -28,24 +28,41 @@ namespace detail {
// A helper class template to allow completion handlers to be dispatched // A helper class template to allow completion handlers to be dispatched
// through either the new executors framework or the old invocaton hook. The // through either the new executors framework or the old invocaton hook. The
// primary template uses the new executors framework. // primary template uses the new executors framework.
template <typename Handler, typename Executor template <typename Handler,
= typename associated_executor<Handler>::type> typename IoExecutor = system_executor, typename HandlerExecutor
= typename associated_executor<Handler, IoExecutor>::type>
class handler_work class handler_work
{ {
public: public:
explicit handler_work(Handler& handler) BOOST_ASIO_NOEXCEPT explicit handler_work(Handler& handler) BOOST_ASIO_NOEXCEPT
: executor_(associated_executor<Handler>::get(handler)) : io_executor_(),
executor_(boost::asio::get_associated_executor(handler, io_executor_))
{
}
handler_work(Handler& handler, const IoExecutor& io_ex) BOOST_ASIO_NOEXCEPT
: io_executor_(io_ex),
executor_(boost::asio::get_associated_executor(handler, io_executor_))
{ {
} }
static void start(Handler& handler) BOOST_ASIO_NOEXCEPT static void start(Handler& handler) BOOST_ASIO_NOEXCEPT
{ {
Executor ex(associated_executor<Handler>::get(handler)); HandlerExecutor ex(boost::asio::get_associated_executor(handler));
ex.on_work_started(); ex.on_work_started();
} }
static void start(Handler& handler,
const IoExecutor& io_ex) BOOST_ASIO_NOEXCEPT
{
HandlerExecutor ex(boost::asio::get_associated_executor(handler, io_ex));
ex.on_work_started();
io_ex.on_work_started();
}
~handler_work() ~handler_work()
{ {
io_executor_.on_work_finished();
executor_.on_work_finished(); executor_.on_work_finished();
} }
@ -53,7 +70,7 @@ public:
void complete(Function& function, Handler& handler) void complete(Function& function, Handler& handler)
{ {
executor_.dispatch(BOOST_ASIO_MOVE_CAST(Function)(function), executor_.dispatch(BOOST_ASIO_MOVE_CAST(Function)(function),
associated_allocator<Handler>::get(handler)); boost::asio::get_associated_allocator(handler));
} }
private: private:
@ -61,7 +78,8 @@ private:
handler_work(const handler_work&); handler_work(const handler_work&);
handler_work& operator=(const handler_work&); handler_work& operator=(const handler_work&);
typename associated_executor<Handler>::type executor_; IoExecutor io_executor_;
HandlerExecutor executor_;
}; };
// This specialisation dispatches a handler through the old invocation hook. // This specialisation dispatches a handler through the old invocation hook.
@ -69,7 +87,7 @@ private:
// system_executor will dispatch through the hook anyway. However, by doing // system_executor will dispatch through the hook anyway. However, by doing
// this we avoid an extra copy of the handler. // this we avoid an extra copy of the handler.
template <typename Handler> template <typename Handler>
class handler_work<Handler, system_executor> class handler_work<Handler, system_executor, system_executor>
{ {
public: public:
explicit handler_work(Handler&) BOOST_ASIO_NOEXCEPT {} explicit handler_work(Handler&) BOOST_ASIO_NOEXCEPT {}

View File

@ -2,7 +2,7 @@
// detail/hash_map.hpp // detail/hash_map.hpp
// ~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/impl/buffer_sequence_adapter.ipp // detail/impl/buffer_sequence_adapter.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/impl/descriptor_ops.ipp // detail/impl/descriptor_ops.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/impl/dev_poll_reactor.hpp // detail/impl/dev_poll_reactor.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/impl/dev_poll_reactor.ipp // detail/impl/dev_poll_reactor.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/impl/epoll_reactor.hpp // detail/impl/epoll_reactor.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/impl/epoll_reactor.ipp // detail/impl/epoll_reactor.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/impl/eventfd_select_interrupter.ipp // detail/impl/eventfd_select_interrupter.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2008 Roelof Naude (roelof.naude at gmail dot com) // Copyright (c) 2008 Roelof Naude (roelof.naude at gmail dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying

View File

@ -2,7 +2,7 @@
// detail/impl/handler_tracking.ipp // detail/impl/handler_tracking.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -2,7 +2,7 @@
// detail/impl/kqueue_reactor.hpp // detail/impl/kqueue_reactor.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2005 Stefan Arentz (stefan at soze dot com) // Copyright (c) 2005 Stefan Arentz (stefan at soze dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying

View File

@ -2,7 +2,7 @@
// detail/impl/kqueue_reactor.ipp // detail/impl/kqueue_reactor.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2005 Stefan Arentz (stefan at soze dot com) // Copyright (c) 2005 Stefan Arentz (stefan at soze dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying

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