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
========================================
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)
===============================

View File

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

View File

@ -183,7 +183,7 @@ namespace boost {
// check range (may be private because it is static)
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
// ~~~~~~~~
//
// 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
// 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_executor.hpp>
#include <boost/asio/async_result.hpp>
#include <boost/asio/awaitable.hpp>
#include <boost/asio/basic_datagram_socket.hpp>
#include <boost/asio/basic_deadline_timer.hpp>
#include <boost/asio/basic_io_object.hpp>
@ -27,6 +28,7 @@
#include <boost/asio/basic_seq_packet_socket.hpp>
#include <boost/asio/basic_serial_port.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_iostream.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.hpp>
#include <boost/asio/buffers_iterator.hpp>
#include <boost/asio/co_spawn.hpp>
#include <boost/asio/completion_condition.hpp>
#include <boost/asio/compose.hpp>
#include <boost/asio/connect.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/defer.hpp>
#include <boost/asio/detached.hpp>
#include <boost/asio/dispatch.hpp>
#include <boost/asio/error.hpp>
#include <boost/asio/execution_context.hpp>
@ -62,7 +65,6 @@
#include <boost/asio/handler_alloc_hook.hpp>
#include <boost/asio/handler_continuation_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/io_context.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_iterator.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/basic_endpoint.hpp>
#include <boost/asio/ip/basic_resolver.hpp>
@ -86,7 +90,6 @@
#include <boost/asio/ip/multicast.hpp>
#include <boost/asio/ip/resolver_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/udp.hpp>
#include <boost/asio/ip/unicast.hpp>
@ -105,46 +108,38 @@
#include <boost/asio/posix/descriptor.hpp>
#include <boost/asio/posix/descriptor_base.hpp>
#include <boost/asio/posix/stream_descriptor.hpp>
#include <boost/asio/posix/stream_descriptor_service.hpp>
#include <boost/asio/post.hpp>
#include <boost/asio/raw_socket_service.hpp>
#include <boost/asio/read.hpp>
#include <boost/asio/read_at.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_base.hpp>
#include <boost/asio/serial_port_service.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/steady_timer.hpp>
#include <boost/asio/strand.hpp>
#include <boost/asio/stream_socket_service.hpp>
#include <boost/asio/streambuf.hpp>
#include <boost/asio/system_context.hpp>
#include <boost/asio/system_executor.hpp>
#include <boost/asio/system_timer.hpp>
#include <boost/asio/this_coro.hpp>
#include <boost/asio/thread_pool.hpp>
#include <boost/asio/time_traits.hpp>
#include <boost/asio/use_awaitable.hpp>
#include <boost/asio/use_future.hpp>
#include <boost/asio/uses_executor.hpp>
#include <boost/asio/version.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_overlapped_handle.hpp>
#include <boost/asio/windows/basic_random_access_handle.hpp>
#include <boost/asio/windows/basic_stream_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_ptr.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_service.hpp>
#include <boost/asio/write.hpp>
#include <boost/asio/write_at.hpp>

View File

@ -2,7 +2,7 @@
// 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
// 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
// ~~~~~~~~~~~~~~~~~~~~~~~
//
// 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
// 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
// ~~~~~~~~~~~~~~~~
//
// 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
// 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/type_traits.hpp>
#include <boost/asio/handler_type.hpp>
#include <boost/asio/detail/variadic_templates.hpp>
#include <boost/asio/detail/push_options.hpp>
@ -42,30 +42,15 @@ namespace asio {
* The primary template assumes that the CompletionToken is the completion
* handler.
*/
#if defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
template <typename CompletionToken, typename Signature>
#else // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
template <typename CompletionToken, typename Signature = void>
#endif // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
class async_result
{
public:
#if defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
/// The concrete completion handler type for the specific signature.
typedef CompletionToken completion_handler_type;
/// The return type of the initiating function.
typedef void return_type;
#else // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
// For backward compatibility, determine the concrete completion handler type
// by using the legacy handler_type trait.
typedef typename handler_type<CompletionToken, Signature>::type
completion_handler_type;
// For backward compatibility, determine the initiating function return type
// using the legacy single-parameter version of async_result.
typedef typename async_result<completion_handler_type>::type return_type;
#endif // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
/// Construct an async result from a given handler.
/**
@ -74,11 +59,6 @@ public:
* then returned from the initiating function.
*/
explicit async_result(completion_handler_type& h)
#if defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
// No data members to initialise.
#else // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
: legacy_result_(h)
#endif // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
{
(void)h;
}
@ -86,56 +66,60 @@ public:
/// Obtain the value to be returned from the initiating function.
return_type get()
{
#if defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
// Nothing to do.
#else // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
return legacy_result_.get();
#endif // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
}
#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:
async_result(const async_result&) BOOST_ASIO_DELETED;
async_result& operator=(const async_result&) BOOST_ASIO_DELETED;
#if defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
// No data members.
#else // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
async_result<completion_handler_type> legacy_result_;
#endif // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
};
#if !defined(BOOST_ASIO_NO_DEPRECATED)
/// (Deprecated: Use two-parameter version of async_result.) An interface for
/// customising the behaviour of an initiating function.
/**
* This template may be specialised for user-defined handler types.
*/
template <typename Handler>
class async_result<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
/// a local copy of the handler, and then create an async_result for the
/// handler.
@ -195,11 +179,40 @@ struct async_result_helper
{
};
} // namespace detail
} // namespace asio
} // namespace boost
struct async_result_memfns_base
{
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)
# 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
#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

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
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
// 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
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -19,19 +19,25 @@
#include <cstddef>
#include <boost/asio/basic_socket.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/type_traits.hpp>
#include <boost/asio/error.hpp>
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
# include <boost/asio/datagram_socket_service.hpp>
#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
#include <boost/asio/detail/push_options.hpp>
namespace boost {
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.
/**
* The basic_datagram_socket class template provides asynchronous and blocking
@ -41,18 +47,28 @@ namespace asio {
* @e Distinct @e objects: Safe.@n
* @e Shared @e objects: Unsafe.
*/
template <typename Protocol
BOOST_ASIO_SVC_TPARAM_DEF1(= datagram_socket_service<Protocol>)>
template <typename Protocol, typename Executor>
class basic_datagram_socket
: public basic_socket<Protocol BOOST_ASIO_SVC_TARG>
: public basic_socket<Protocol, Executor>
{
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.
#if defined(GENERATING_DOCUMENTATION)
typedef implementation_defined native_handle_type;
#else
typedef typename basic_socket<
Protocol BOOST_ASIO_SVC_TARG>::native_handle_type native_handle_type;
typedef typename basic_socket<Protocol,
Executor>::native_handle_type native_handle_type;
#endif
/// The protocol type.
@ -66,12 +82,29 @@ public:
* This constructor creates a datagram socket without opening it. The open()
* function must be called before data can be sent or received on the socket.
*
* @param io_context The io_context object that the datagram socket will use
* to dispatch handlers for any asynchronous operations performed on the
* socket.
* @param ex The I/O executor that the socket will use, by default, to
* dispatch handlers for any asynchronous operations performed on the socket.
*/
explicit basic_datagram_socket(boost::asio::io_context& io_context)
: basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context)
explicit basic_datagram_socket(const executor_type& ex)
: 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.
*
* @param io_context The io_context object that the datagram socket will use
* to dispatch handlers for any asynchronous operations performed on the
* socket.
* @param ex 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.
*/
basic_datagram_socket(boost::asio::io_context& io_context,
const protocol_type& protocol)
: basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context, protocol)
basic_datagram_socket(const executor_type& ex, const protocol_type& protocol)
: basic_socket<Protocol, Executor>(ex, 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
* protocol associated with the given endpoint.
*
* @param io_context The io_context object that the datagram socket will use
* to dispatch handlers for any asynchronous operations performed on the
* socket.
* @param ex 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.
*/
basic_datagram_socket(boost::asio::io_context& io_context,
const endpoint_type& endpoint)
: basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context, endpoint)
basic_datagram_socket(const executor_type& ex, const endpoint_type& endpoint)
: basic_socket<Protocol, Executor>(ex, 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
* native socket.
*
* @param io_context The io_context object that the datagram socket will use
* to dispatch handlers for any asynchronous operations performed on the
* socket.
* @param ex 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.
*
@ -130,10 +206,34 @@ public:
*
* @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)
: basic_socket<Protocol BOOST_ASIO_SVC_TARG>(
io_context, protocol, native_socket)
: basic_socket<Protocol, Executor>(ex, 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.
*
* @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_socket<Protocol BOOST_ASIO_SVC_TARG>(std::move(other))
: basic_socket<Protocol, Executor>(std::move(other))
{
}
@ -162,11 +263,12 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_datagram_socket(io_context&) constructor.
* constructed using the @c basic_datagram_socket(const executor_type&)
* constructor.
*/
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;
}
@ -179,13 +281,16 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_datagram_socket(io_context&) constructor.
* constructed using the @c basic_datagram_socket(const executor_type&)
* constructor.
*/
template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
basic_datagram_socket(
basic_datagram_socket<Protocol1 BOOST_ASIO_SVC_TARG1>&& other,
typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0)
: basic_socket<Protocol BOOST_ASIO_SVC_TARG>(std::move(other))
template <typename Protocol1, typename Executor1>
basic_datagram_socket(basic_datagram_socket<Protocol1, Executor1>&& other,
typename enable_if<
is_convertible<Protocol1, Protocol>::value
&& is_convertible<Executor1, Executor>::value
>::type* = 0)
: basic_socket<Protocol, Executor>(std::move(other))
{
}
@ -199,14 +304,17 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_datagram_socket(io_context&) constructor.
* constructed using the @c basic_datagram_socket(const executor_type&)
* constructor.
*/
template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
typename enable_if<is_convertible<Protocol1, Protocol>::value,
basic_datagram_socket>::type& operator=(
basic_datagram_socket<Protocol1 BOOST_ASIO_SVC_TARG1>&& other)
template <typename Protocol1, typename Executor1>
typename enable_if<
is_convertible<Protocol1, Protocol>::value
&& 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;
}
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
@ -246,8 +354,8 @@ public:
std::size_t send(const ConstBufferSequence& buffers)
{
boost::system::error_code ec;
std::size_t s = this->get_service().send(
this->get_implementation(), buffers, 0, ec);
std::size_t s = this->impl_.get_service().send(
this->impl_.get_implementation(), buffers, 0, ec);
boost::asio::detail::throw_error(ec, "send");
return s;
}
@ -274,8 +382,8 @@ public:
socket_base::message_flags flags)
{
boost::system::error_code ec;
std::size_t s = this->get_service().send(
this->get_implementation(), buffers, flags, ec);
std::size_t s = this->impl_.get_service().send(
this->impl_.get_implementation(), buffers, flags, ec);
boost::asio::detail::throw_error(ec, "send");
return s;
}
@ -301,8 +409,8 @@ public:
std::size_t send(const ConstBufferSequence& buffers,
socket_base::message_flags flags, boost::system::error_code& ec)
{
return this->get_service().send(
this->get_implementation(), buffers, flags, ec);
return this->impl_.get_service().send(
this->impl_.get_implementation(), buffers, flags, ec);
}
/// Start an asynchronous send on a connected socket.
@ -323,9 +431,9 @@ public:
* std::size_t bytes_transferred // Number of bytes sent.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* boost::asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post().
*
* @note The async_send operation can only be used with a connected socket.
* Use the async_send_to function to send data on an unconnected datagram
@ -346,22 +454,10 @@ public:
async_send(const ConstBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{
// 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;
#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)
return async_initiate<WriteHandler,
void (boost::system::error_code, std::size_t)>(
initiate_async_send(), handler, this,
buffers, socket_base::message_flags(0));
}
/// Start an asynchronous send on a connected socket.
@ -384,9 +480,9 @@ public:
* std::size_t bytes_transferred // Number of bytes sent.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* boost::asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post().
*
* @note The async_send operation can only be used with a connected socket.
* Use the async_send_to function to send data on an unconnected datagram
@ -399,22 +495,9 @@ public:
socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{
// 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;
#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)
return async_initiate<WriteHandler,
void (boost::system::error_code, std::size_t)>(
initiate_async_send(), handler, this, buffers, flags);
}
/// Send a datagram to the specified endpoint.
@ -447,8 +530,8 @@ public:
const endpoint_type& destination)
{
boost::system::error_code ec;
std::size_t s = this->get_service().send_to(
this->get_implementation(), buffers, destination, 0, ec);
std::size_t s = this->impl_.get_service().send_to(
this->impl_.get_implementation(), buffers, destination, 0, ec);
boost::asio::detail::throw_error(ec, "send_to");
return s;
}
@ -474,8 +557,8 @@ public:
const endpoint_type& destination, socket_base::message_flags flags)
{
boost::system::error_code ec;
std::size_t s = this->get_service().send_to(
this->get_implementation(), buffers, destination, flags, ec);
std::size_t s = this->impl_.get_service().send_to(
this->impl_.get_implementation(), buffers, destination, flags, ec);
boost::asio::detail::throw_error(ec, "send_to");
return s;
}
@ -501,7 +584,7 @@ public:
const endpoint_type& destination, socket_base::message_flags flags,
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);
}
@ -526,9 +609,9 @@ public:
* std::size_t bytes_transferred // Number of bytes sent.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* boost::asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post().
*
* @par Example
* To send a single data buffer use the @ref buffer function as follows:
@ -549,24 +632,10 @@ public:
const endpoint_type& destination,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{
// 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;
#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)
return async_initiate<WriteHandler,
void (boost::system::error_code, std::size_t)>(
initiate_async_send_to(), handler, this, buffers,
destination, socket_base::message_flags(0));
}
/// Start an asynchronous send.
@ -592,9 +661,9 @@ public:
* std::size_t bytes_transferred // Number of bytes sent.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* boost::asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post().
*/
template <typename ConstBufferSequence, typename WriteHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
@ -603,24 +672,9 @@ public:
const endpoint_type& destination, socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{
// 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;
#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)
return async_initiate<WriteHandler,
void (boost::system::error_code, std::size_t)>(
initiate_async_send_to(), handler, this, buffers, destination, flags);
}
/// Receive some data on a connected socket.
@ -651,8 +705,8 @@ public:
std::size_t receive(const MutableBufferSequence& buffers)
{
boost::system::error_code ec;
std::size_t s = this->get_service().receive(
this->get_implementation(), buffers, 0, ec);
std::size_t s = this->impl_.get_service().receive(
this->impl_.get_implementation(), buffers, 0, ec);
boost::asio::detail::throw_error(ec, "receive");
return s;
}
@ -680,8 +734,8 @@ public:
socket_base::message_flags flags)
{
boost::system::error_code ec;
std::size_t s = this->get_service().receive(
this->get_implementation(), buffers, flags, ec);
std::size_t s = this->impl_.get_service().receive(
this->impl_.get_implementation(), buffers, flags, ec);
boost::asio::detail::throw_error(ec, "receive");
return s;
}
@ -708,8 +762,8 @@ public:
std::size_t receive(const MutableBufferSequence& buffers,
socket_base::message_flags flags, boost::system::error_code& ec)
{
return this->get_service().receive(
this->get_implementation(), buffers, flags, ec);
return this->impl_.get_service().receive(
this->impl_.get_implementation(), buffers, flags, ec);
}
/// Start an asynchronous receive on a connected socket.
@ -730,9 +784,9 @@ public:
* std::size_t bytes_transferred // Number of bytes received.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* boost::asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post().
*
* @note The async_receive operation can only be used with a connected socket.
* Use the async_receive_from function to receive data on an unconnected
@ -754,22 +808,10 @@ public:
async_receive(const MutableBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{
// 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;
#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)
return async_initiate<ReadHandler,
void (boost::system::error_code, std::size_t)>(
initiate_async_receive(), handler, this,
buffers, socket_base::message_flags(0));
}
/// Start an asynchronous receive on a connected socket.
@ -792,9 +834,9 @@ public:
* std::size_t bytes_transferred // Number of bytes received.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* boost::asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post().
*
* @note The async_receive operation can only be used with a connected socket.
* Use the async_receive_from function to receive data on an unconnected
@ -807,22 +849,9 @@ public:
socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{
// 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;
#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)
return async_initiate<ReadHandler,
void (boost::system::error_code, std::size_t)>(
initiate_async_receive(), handler, this, buffers, flags);
}
/// Receive a datagram with the endpoint of the sender.
@ -856,8 +885,8 @@ public:
endpoint_type& sender_endpoint)
{
boost::system::error_code ec;
std::size_t s = this->get_service().receive_from(
this->get_implementation(), buffers, sender_endpoint, 0, ec);
std::size_t s = this->impl_.get_service().receive_from(
this->impl_.get_implementation(), buffers, sender_endpoint, 0, ec);
boost::asio::detail::throw_error(ec, "receive_from");
return s;
}
@ -883,8 +912,8 @@ public:
endpoint_type& sender_endpoint, socket_base::message_flags flags)
{
boost::system::error_code ec;
std::size_t s = this->get_service().receive_from(
this->get_implementation(), buffers, sender_endpoint, flags, ec);
std::size_t s = this->impl_.get_service().receive_from(
this->impl_.get_implementation(), buffers, sender_endpoint, flags, ec);
boost::asio::detail::throw_error(ec, "receive_from");
return s;
}
@ -910,8 +939,8 @@ public:
endpoint_type& sender_endpoint, socket_base::message_flags flags,
boost::system::error_code& ec)
{
return this->get_service().receive_from(this->get_implementation(),
buffers, sender_endpoint, flags, ec);
return this->impl_.get_service().receive_from(
this->impl_.get_implementation(), buffers, sender_endpoint, flags, ec);
}
/// Start an asynchronous receive.
@ -937,9 +966,9 @@ public:
* std::size_t bytes_transferred // Number of bytes received.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* boost::asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post().
*
* @par Example
* To receive into a single data buffer use the @ref buffer function as
@ -957,24 +986,10 @@ public:
endpoint_type& sender_endpoint,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{
// 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;
#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)
return async_initiate<ReadHandler,
void (boost::system::error_code, std::size_t)>(
initiate_async_receive_from(), handler, this, buffers,
&sender_endpoint, socket_base::message_flags(0));
}
/// Start an asynchronous receive.
@ -1002,9 +1017,9 @@ public:
* std::size_t bytes_transferred // Number of bytes received.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* boost::asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post().
*/
template <typename MutableBufferSequence, typename ReadHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
@ -1013,25 +1028,85 @@ public:
endpoint_type& sender_endpoint, socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
return async_initiate<ReadHandler,
void (boost::system::error_code, std::size_t)>(
initiate_async_receive_from(), handler,
this, buffers, &sender_endpoint, flags);
}
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;
#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)
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

View File

@ -2,7 +2,7 @@
// 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
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -21,19 +21,16 @@
|| defined(GENERATING_DOCUMENTATION)
#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/io_object_impl.hpp>
#include <boost/asio/detail/non_const_lvalue.hpp>
#include <boost/asio/detail/throw_error.hpp>
#include <boost/asio/error.hpp>
#include <boost/asio/execution_context.hpp>
#include <boost/asio/executor.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>
namespace boost {
@ -58,7 +55,7 @@ namespace asio {
* Performing a blocking wait:
* @code
* // 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.
* timer.expires_from_now(boost::posix_time::seconds(5));
@ -81,7 +78,7 @@ namespace asio {
* ...
*
* // 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"));
*
* // Start an asynchronous wait.
@ -128,14 +125,13 @@ namespace asio {
* it contains the value boost::asio::error::operation_aborted.
*/
template <typename Time,
typename TimeTraits = boost::asio::time_traits<Time>
BOOST_ASIO_SVC_TPARAM_DEF2(= deadline_timer_service<Time, TimeTraits>)>
typename TimeTraits = boost::asio::time_traits<Time>,
typename Executor = executor>
class basic_deadline_timer
: BOOST_ASIO_SVC_ACCESS basic_io_object<BOOST_ASIO_SVC_T>
{
public:
/// The type of the executor associated with the object.
typedef io_context::executor_type executor_type;
typedef Executor executor_type;
/// The time traits type.
typedef TimeTraits traits_type;
@ -152,11 +148,30 @@ public:
* expires_at() or expires_from_now() functions must be called to set an
* expiry time before the timer can be waited on.
*
* @param io_context The io_context object that the timer will use to dispatch
* handlers for any asynchronous operations performed on the timer.
* @param ex The I/O executor that the timer will use, by default, to
* dispatch handlers for any asynchronous operations performed on the timer.
*/
explicit basic_deadline_timer(boost::asio::io_context& io_context)
: basic_io_object<BOOST_ASIO_SVC_T>(io_context)
explicit basic_deadline_timer(const executor_type& ex)
: 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.
*
* @param io_context The io_context object that the timer will use to dispatch
* handlers for any asynchronous operations performed on the timer.
* @param ex 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.
*/
basic_deadline_timer(boost::asio::io_context& io_context,
const time_type& expiry_time)
: basic_io_object<BOOST_ASIO_SVC_T>(io_context)
basic_deadline_timer(const executor_type& ex, const time_type& expiry_time)
: impl_(ex)
{
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");
}
@ -183,19 +220,44 @@ public:
/**
* This constructor creates a timer and sets the expiry time.
*
* @param io_context The io_context object that the timer will use to dispatch
* handlers for any asynchronous operations performed on the timer.
* @param ex 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.
*/
basic_deadline_timer(boost::asio::io_context& io_context,
basic_deadline_timer(const executor_type& ex,
const duration_type& expiry_time)
: basic_io_object<BOOST_ASIO_SVC_T>(io_context)
: impl_(ex)
{
boost::system::error_code ec;
this->get_service().expires_from_now(
this->get_implementation(), expiry_time, ec);
impl_.get_service().expires_from_now(
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");
}
@ -208,10 +270,11 @@ public:
* occur.
*
* @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_deadline_timer(io_context&) constructor.
* constructed using the @c basic_deadline_timer(const executor_type&)
* constructor.
*/
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.
*
* @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_io_object<BOOST_ASIO_SVC_T>::operator=(std::move(other));
impl_ = std::move(other.impl_);
return *this;
}
#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.
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.
/**
@ -307,7 +337,7 @@ public:
std::size_t cancel()
{
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");
return s;
}
@ -336,7 +366,7 @@ public:
*/
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.
@ -366,8 +396,8 @@ public:
std::size_t cancel_one()
{
boost::system::error_code ec;
std::size_t s = this->get_service().cancel_one(
this->get_implementation(), ec);
std::size_t s = impl_.get_service().cancel_one(
impl_.get_implementation(), ec);
boost::asio::detail::throw_error(ec, "cancel_one");
return s;
}
@ -398,7 +428,7 @@ public:
*/
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.
@ -408,7 +438,7 @@ public:
*/
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.
@ -436,8 +466,8 @@ public:
std::size_t expires_at(const time_type& expiry_time)
{
boost::system::error_code ec;
std::size_t s = this->get_service().expires_at(
this->get_implementation(), expiry_time, ec);
std::size_t s = impl_.get_service().expires_at(
impl_.get_implementation(), expiry_time, ec);
boost::asio::detail::throw_error(ec, "expires_at");
return s;
}
@ -467,8 +497,8 @@ public:
std::size_t expires_at(const time_type& expiry_time,
boost::system::error_code& ec)
{
return this->get_service().expires_at(
this->get_implementation(), expiry_time, ec);
return impl_.get_service().expires_at(
impl_.get_implementation(), expiry_time, ec);
}
/// Get the timer's expiry time relative to now.
@ -478,7 +508,7 @@ public:
*/
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.
@ -506,8 +536,8 @@ public:
std::size_t expires_from_now(const duration_type& expiry_time)
{
boost::system::error_code ec;
std::size_t s = this->get_service().expires_from_now(
this->get_implementation(), expiry_time, ec);
std::size_t s = impl_.get_service().expires_from_now(
impl_.get_implementation(), expiry_time, ec);
boost::asio::detail::throw_error(ec, "expires_from_now");
return s;
}
@ -537,8 +567,8 @@ public:
std::size_t expires_from_now(const duration_type& expiry_time,
boost::system::error_code& ec)
{
return this->get_service().expires_from_now(
this->get_implementation(), expiry_time, ec);
return impl_.get_service().expires_from_now(
impl_.get_implementation(), expiry_time, ec);
}
/// Perform a blocking wait on the timer.
@ -551,7 +581,7 @@ public:
void wait()
{
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");
}
@ -564,7 +594,7 @@ public:
*/
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.
@ -587,32 +617,44 @@ public:
* const boost::system::error_code& error // Result of operation.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* boost::asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post().
*/
template <typename WaitHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler,
void (boost::system::error_code))
async_wait(BOOST_ASIO_MOVE_ARG(WaitHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WaitHandler.
return async_initiate<WaitHandler, void (boost::system::error_code)>(
initiate_async_wait(), handler, this);
}
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;
#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)
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
@ -620,10 +662,6 @@ public:
#include <boost/asio/detail/pop_options.hpp>
#if !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
# undef BOOST_ASIO_SVC_T
#endif // !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
#endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
// || defined(GENERATING_DOCUMENTATION)

View File

@ -2,7 +2,7 @@
// 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
// 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
// ~~~~~~~~~~~~~~~~~~~~
//
// 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
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -19,19 +19,25 @@
#include <cstddef>
#include <boost/asio/basic_socket.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/type_traits.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>
namespace boost {
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.
/**
* The basic_raw_socket class template provides asynchronous and blocking
@ -41,18 +47,28 @@ namespace asio {
* @e Distinct @e objects: Safe.@n
* @e Shared @e objects: Unsafe.
*/
template <typename Protocol
BOOST_ASIO_SVC_TPARAM_DEF1(= raw_socket_service<Protocol>)>
template <typename Protocol, typename Executor>
class basic_raw_socket
: public basic_socket<Protocol BOOST_ASIO_SVC_TARG>
: public basic_socket<Protocol, Executor>
{
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.
#if defined(GENERATING_DOCUMENTATION)
typedef implementation_defined native_handle_type;
#else
typedef typename basic_socket<
Protocol BOOST_ASIO_SVC_TARG>::native_handle_type native_handle_type;
typedef typename basic_socket<Protocol,
Executor>::native_handle_type native_handle_type;
#endif
/// The protocol type.
@ -66,12 +82,29 @@ public:
* This constructor creates a raw socket without opening it. The open()
* function must be called before data can be sent or received on the socket.
*
* @param io_context The io_context object that the raw socket will use
* to dispatch handlers for any asynchronous operations performed on the
* socket.
* @param ex The I/O executor that the socket will use, by default, to
* dispatch handlers for any asynchronous operations performed on the socket.
*/
explicit basic_raw_socket(boost::asio::io_context& io_context)
: basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context)
explicit basic_raw_socket(const executor_type& ex)
: 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.
*
* @param io_context The io_context object that the raw socket will use
* to dispatch handlers for any asynchronous operations performed on the
* socket.
* @param ex 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.
*/
basic_raw_socket(boost::asio::io_context& io_context,
const protocol_type& protocol)
: basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context, protocol)
basic_raw_socket(const executor_type& ex, const protocol_type& protocol)
: basic_socket<Protocol, Executor>(ex, 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
* protocol associated with the given endpoint.
*
* @param io_context The io_context object that the raw socket will use
* to dispatch handlers for any asynchronous operations performed on the
* socket.
* @param ex 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.
*/
basic_raw_socket(boost::asio::io_context& io_context,
const endpoint_type& endpoint)
: basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context, endpoint)
basic_raw_socket(const executor_type& ex, const endpoint_type& endpoint)
: basic_socket<Protocol, Executor>(ex, 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
* native socket.
*
* @param io_context The io_context object that the raw socket will use
* to dispatch handlers for any asynchronous operations performed on the
* socket.
* @param ex 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.
*
@ -130,10 +204,34 @@ public:
*
* @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)
: basic_socket<Protocol BOOST_ASIO_SVC_TARG>(
io_context, protocol, native_socket)
: basic_socket<Protocol, Executor>(ex, 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.
*
* @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_socket<Protocol BOOST_ASIO_SVC_TARG>(std::move(other))
: basic_socket<Protocol, Executor>(std::move(other))
{
}
@ -161,28 +260,34 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_raw_socket(io_context&) constructor.
* constructed using the @c basic_raw_socket(const executor_type&)
* constructor.
*/
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;
}
/// 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.
*
* @param other The other basic_raw_socket object from which the move will
* occur.
* @param other The other basic_raw_socket object from which the move
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_raw_socket(io_context&) constructor.
* constructed using the @c basic_raw_socket(const executor_type&)
* constructor.
*/
template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
basic_raw_socket(basic_raw_socket<Protocol1 BOOST_ASIO_SVC_TARG1>&& other,
typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0)
: basic_socket<Protocol BOOST_ASIO_SVC_TARG>(std::move(other))
template <typename Protocol1, typename Executor1>
basic_raw_socket(basic_raw_socket<Protocol1, Executor1>&& other,
typename enable_if<
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.
*
* @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>
typename enable_if<is_convertible<Protocol1, Protocol>::value,
basic_raw_socket>::type& operator=(
basic_raw_socket<Protocol1 BOOST_ASIO_SVC_TARG1>&& other)
template <typename Protocol1, typename Executor1>
typename enable_if<
is_convertible<Protocol1, Protocol>::value
&& 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;
}
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
@ -240,8 +348,8 @@ public:
std::size_t send(const ConstBufferSequence& buffers)
{
boost::system::error_code ec;
std::size_t s = this->get_service().send(
this->get_implementation(), buffers, 0, ec);
std::size_t s = this->impl_.get_service().send(
this->impl_.get_implementation(), buffers, 0, ec);
boost::asio::detail::throw_error(ec, "send");
return s;
}
@ -267,8 +375,8 @@ public:
socket_base::message_flags flags)
{
boost::system::error_code ec;
std::size_t s = this->get_service().send(
this->get_implementation(), buffers, flags, ec);
std::size_t s = this->impl_.get_service().send(
this->impl_.get_implementation(), buffers, flags, ec);
boost::asio::detail::throw_error(ec, "send");
return s;
}
@ -293,8 +401,8 @@ public:
std::size_t send(const ConstBufferSequence& buffers,
socket_base::message_flags flags, boost::system::error_code& ec)
{
return this->get_service().send(
this->get_implementation(), buffers, flags, ec);
return this->impl_.get_service().send(
this->impl_.get_implementation(), buffers, flags, ec);
}
/// Start an asynchronous send on a connected socket.
@ -315,9 +423,9 @@ public:
* std::size_t bytes_transferred // Number of bytes sent.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* boost::asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post().
*
* @note The async_send operation can only be used with a connected socket.
* Use the async_send_to function to send data on an unconnected raw
@ -338,22 +446,10 @@ public:
async_send(const ConstBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{
// 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;
#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)
return async_initiate<WriteHandler,
void (boost::system::error_code, std::size_t)>(
initiate_async_send(), handler, this,
buffers, socket_base::message_flags(0));
}
/// Start an asynchronous send on a connected socket.
@ -376,9 +472,9 @@ public:
* std::size_t bytes_transferred // Number of bytes sent.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* boost::asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post().
*
* @note The async_send operation can only be used with a connected socket.
* Use the async_send_to function to send data on an unconnected raw
@ -391,22 +487,9 @@ public:
socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{
// 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;
#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)
return async_initiate<WriteHandler,
void (boost::system::error_code, std::size_t)>(
initiate_async_send(), handler, this, buffers, flags);
}
/// Send raw data to the specified endpoint.
@ -439,8 +522,8 @@ public:
const endpoint_type& destination)
{
boost::system::error_code ec;
std::size_t s = this->get_service().send_to(
this->get_implementation(), buffers, destination, 0, ec);
std::size_t s = this->impl_.get_service().send_to(
this->impl_.get_implementation(), buffers, destination, 0, ec);
boost::asio::detail::throw_error(ec, "send_to");
return s;
}
@ -466,8 +549,8 @@ public:
const endpoint_type& destination, socket_base::message_flags flags)
{
boost::system::error_code ec;
std::size_t s = this->get_service().send_to(
this->get_implementation(), buffers, destination, flags, ec);
std::size_t s = this->impl_.get_service().send_to(
this->impl_.get_implementation(), buffers, destination, flags, ec);
boost::asio::detail::throw_error(ec, "send_to");
return s;
}
@ -493,7 +576,7 @@ public:
const endpoint_type& destination, socket_base::message_flags flags,
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);
}
@ -518,9 +601,9 @@ public:
* std::size_t bytes_transferred // Number of bytes sent.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* boost::asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post().
*
* @par Example
* To send a single data buffer use the @ref buffer function as follows:
@ -541,22 +624,10 @@ public:
const endpoint_type& destination,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{
// 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;
#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)
return async_initiate<WriteHandler,
void (boost::system::error_code, std::size_t)>(
initiate_async_send_to(), handler, this, buffers,
destination, socket_base::message_flags(0));
}
/// Start an asynchronous send.
@ -582,9 +653,9 @@ public:
* std::size_t bytes_transferred // Number of bytes sent.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* boost::asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post().
*/
template <typename ConstBufferSequence, typename WriteHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
@ -593,24 +664,9 @@ public:
const endpoint_type& destination, socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{
// 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;
#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)
return async_initiate<WriteHandler,
void (boost::system::error_code, std::size_t)>(
initiate_async_send_to(), handler, this, buffers, destination, flags);
}
/// Receive some data on a connected socket.
@ -641,8 +697,8 @@ public:
std::size_t receive(const MutableBufferSequence& buffers)
{
boost::system::error_code ec;
std::size_t s = this->get_service().receive(
this->get_implementation(), buffers, 0, ec);
std::size_t s = this->impl_.get_service().receive(
this->impl_.get_implementation(), buffers, 0, ec);
boost::asio::detail::throw_error(ec, "receive");
return s;
}
@ -670,8 +726,8 @@ public:
socket_base::message_flags flags)
{
boost::system::error_code ec;
std::size_t s = this->get_service().receive(
this->get_implementation(), buffers, flags, ec);
std::size_t s = this->impl_.get_service().receive(
this->impl_.get_implementation(), buffers, flags, ec);
boost::asio::detail::throw_error(ec, "receive");
return s;
}
@ -698,8 +754,8 @@ public:
std::size_t receive(const MutableBufferSequence& buffers,
socket_base::message_flags flags, boost::system::error_code& ec)
{
return this->get_service().receive(
this->get_implementation(), buffers, flags, ec);
return this->impl_.get_service().receive(
this->impl_.get_implementation(), buffers, flags, ec);
}
/// Start an asynchronous receive on a connected socket.
@ -720,9 +776,9 @@ public:
* std::size_t bytes_transferred // Number of bytes received.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* boost::asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post().
*
* @note The async_receive operation can only be used with a connected socket.
* Use the async_receive_from function to receive data on an unconnected
@ -744,22 +800,10 @@ public:
async_receive(const MutableBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{
// 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;
#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)
return async_initiate<ReadHandler,
void (boost::system::error_code, std::size_t)>(
initiate_async_receive(), handler, this,
buffers, socket_base::message_flags(0));
}
/// Start an asynchronous receive on a connected socket.
@ -782,9 +826,9 @@ public:
* std::size_t bytes_transferred // Number of bytes received.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* boost::asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post().
*
* @note The async_receive operation can only be used with a connected socket.
* Use the async_receive_from function to receive data on an unconnected
@ -797,22 +841,9 @@ public:
socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{
// 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;
#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)
return async_initiate<ReadHandler,
void (boost::system::error_code, std::size_t)>(
initiate_async_receive(), handler, this, buffers, flags);
}
/// Receive raw data with the endpoint of the sender.
@ -846,8 +877,8 @@ public:
endpoint_type& sender_endpoint)
{
boost::system::error_code ec;
std::size_t s = this->get_service().receive_from(
this->get_implementation(), buffers, sender_endpoint, 0, ec);
std::size_t s = this->impl_.get_service().receive_from(
this->impl_.get_implementation(), buffers, sender_endpoint, 0, ec);
boost::asio::detail::throw_error(ec, "receive_from");
return s;
}
@ -873,8 +904,8 @@ public:
endpoint_type& sender_endpoint, socket_base::message_flags flags)
{
boost::system::error_code ec;
std::size_t s = this->get_service().receive_from(
this->get_implementation(), buffers, sender_endpoint, flags, ec);
std::size_t s = this->impl_.get_service().receive_from(
this->impl_.get_implementation(), buffers, sender_endpoint, flags, ec);
boost::asio::detail::throw_error(ec, "receive_from");
return s;
}
@ -900,8 +931,8 @@ public:
endpoint_type& sender_endpoint, socket_base::message_flags flags,
boost::system::error_code& ec)
{
return this->get_service().receive_from(this->get_implementation(),
buffers, sender_endpoint, flags, ec);
return this->impl_.get_service().receive_from(
this->impl_.get_implementation(), buffers, sender_endpoint, flags, ec);
}
/// Start an asynchronous receive.
@ -927,9 +958,9 @@ public:
* std::size_t bytes_transferred // Number of bytes received.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* boost::asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post().
*
* @par Example
* To receive into a single data buffer use the @ref buffer function as
@ -947,24 +978,10 @@ public:
endpoint_type& sender_endpoint,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{
// 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;
#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)
return async_initiate<ReadHandler,
void (boost::system::error_code, std::size_t)>(
initiate_async_receive_from(), handler, this, buffers,
&sender_endpoint, socket_base::message_flags(0));
}
/// Start an asynchronous receive.
@ -992,9 +1009,9 @@ public:
* std::size_t bytes_transferred // Number of bytes received.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* boost::asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post().
*/
template <typename MutableBufferSequence, typename ReadHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
@ -1003,25 +1020,85 @@ public:
endpoint_type& sender_endpoint, socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
return async_initiate<ReadHandler,
void (boost::system::error_code, std::size_t)>(
initiate_async_receive_from(), handler,
this, buffers, &sender_endpoint, flags);
}
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;
#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)
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

View File

@ -2,7 +2,7 @@
// 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
// 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/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>
namespace boost {
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.
/**
* The basic_seq_packet_socket class template provides asynchronous and blocking
@ -40,18 +45,28 @@ namespace asio {
* @e Distinct @e objects: Safe.@n
* @e Shared @e objects: Unsafe.
*/
template <typename Protocol
BOOST_ASIO_SVC_TPARAM_DEF1(= seq_packet_socket_service<Protocol>)>
template <typename Protocol, typename Executor>
class basic_seq_packet_socket
: public basic_socket<Protocol BOOST_ASIO_SVC_TARG>
: public basic_socket<Protocol, Executor>
{
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.
#if defined(GENERATING_DOCUMENTATION)
typedef implementation_defined native_handle_type;
#else
typedef typename basic_socket<
Protocol BOOST_ASIO_SVC_TARG>::native_handle_type native_handle_type;
typedef typename basic_socket<Protocol,
Executor>::native_handle_type native_handle_type;
#endif
/// The protocol type.
@ -66,12 +81,30 @@ public:
* socket needs to be opened and then connected or accepted before data can
* be sent or received on it.
*
* @param io_context The io_context object that the sequenced packet socket
* will use to dispatch handlers for any asynchronous operations performed on
* the socket.
* @param ex The I/O executor that the socket will use, by default, to
* dispatch handlers for any asynchronous operations performed on the socket.
*/
explicit basic_seq_packet_socket(boost::asio::io_context& io_context)
: basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context)
explicit basic_seq_packet_socket(const executor_type& ex)
: 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
* it.
*
* @param io_context The io_context object that the sequenced packet socket
* will use to dispatch handlers for any asynchronous operations performed on
* the socket.
* @param ex 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.
*/
basic_seq_packet_socket(boost::asio::io_context& io_context,
basic_seq_packet_socket(const executor_type& ex,
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
* is the protocol associated with the given endpoint.
*
* @param io_context The io_context object that the sequenced packet socket
* will use to dispatch handlers for any asynchronous operations performed on
* the socket.
* @param ex 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.
*/
basic_seq_packet_socket(boost::asio::io_context& io_context,
basic_seq_packet_socket(const executor_type& ex,
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
* existing native socket.
*
* @param io_context The io_context object that the sequenced packet socket
* will use to dispatch handlers for any asynchronous operations performed on
* the socket.
* @param ex 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.
*
@ -132,10 +212,34 @@ public:
*
* @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)
: basic_socket<Protocol BOOST_ASIO_SVC_TARG>(
io_context, protocol, native_socket)
: basic_socket<Protocol, Executor>(ex, 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.
*
* @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_socket<Protocol BOOST_ASIO_SVC_TARG>(std::move(other))
: basic_socket<Protocol, Executor>(std::move(other))
{
}
@ -165,11 +270,12 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_seq_packet_socket(io_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_socket<Protocol BOOST_ASIO_SVC_TARG>::operator=(std::move(other));
basic_socket<Protocol, Executor>::operator=(std::move(other));
return *this;
}
@ -183,13 +289,16 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_seq_packet_socket(io_context&) constructor.
* constructed using the @c basic_seq_packet_socket(const executor_type&)
* constructor.
*/
template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
basic_seq_packet_socket(
basic_seq_packet_socket<Protocol1 BOOST_ASIO_SVC_TARG1>&& other,
typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0)
: basic_socket<Protocol BOOST_ASIO_SVC_TARG>(std::move(other))
template <typename Protocol1, typename Executor1>
basic_seq_packet_socket(basic_seq_packet_socket<Protocol1, Executor1>&& other,
typename enable_if<
is_convertible<Protocol1, Protocol>::value
&& is_convertible<Executor1, Executor>::value
>::type* = 0)
: basic_socket<Protocol, Executor>(std::move(other))
{
}
@ -203,14 +312,17 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_seq_packet_socket(io_context&) constructor.
* constructed using the @c basic_seq_packet_socket(const executor_type&)
* constructor.
*/
template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
typename enable_if<is_convertible<Protocol1, Protocol>::value,
basic_seq_packet_socket>::type& operator=(
basic_seq_packet_socket<Protocol1 BOOST_ASIO_SVC_TARG1>&& other)
template <typename Protocol1, typename Executor1>
typename enable_if<
is_convertible<Protocol1, Protocol>::value
&& 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;
}
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
@ -252,8 +364,8 @@ public:
socket_base::message_flags flags)
{
boost::system::error_code ec;
std::size_t s = this->get_service().send(
this->get_implementation(), buffers, flags, ec);
std::size_t s = this->impl_.get_service().send(
this->impl_.get_implementation(), buffers, flags, ec);
boost::asio::detail::throw_error(ec, "send");
return s;
}
@ -280,8 +392,8 @@ public:
std::size_t send(const ConstBufferSequence& buffers,
socket_base::message_flags flags, boost::system::error_code& ec)
{
return this->get_service().send(
this->get_implementation(), buffers, flags, ec);
return this->impl_.get_service().send(
this->impl_.get_implementation(), buffers, flags, ec);
}
/// Start an asynchronous send.
@ -304,9 +416,9 @@ public:
* std::size_t bytes_transferred // Number of bytes sent.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* boost::asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post().
*
* @par Example
* To send a single data buffer use the @ref buffer function as follows:
@ -324,22 +436,9 @@ public:
socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{
// 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;
#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)
return async_initiate<WriteHandler,
void (boost::system::error_code, std::size_t)>(
initiate_async_send(), handler, this, buffers, flags);
}
/// Receive some data on the socket.
@ -376,13 +475,8 @@ public:
socket_base::message_flags& out_flags)
{
boost::system::error_code ec;
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
std::size_t s = this->get_service().receive(
this->get_implementation(), buffers, 0, out_flags, ec);
#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
std::size_t s = this->get_service().receive_with_flags(
this->get_implementation(), buffers, 0, out_flags, ec);
#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
std::size_t s = this->impl_.get_service().receive_with_flags(
this->impl_.get_implementation(), buffers, 0, out_flags, ec);
boost::asio::detail::throw_error(ec, "receive");
return s;
}
@ -428,13 +522,8 @@ public:
socket_base::message_flags& out_flags)
{
boost::system::error_code ec;
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
std::size_t s = this->get_service().receive(
this->get_implementation(), buffers, in_flags, out_flags, ec);
#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
std::size_t s = this->get_service().receive_with_flags(
this->get_implementation(), buffers, in_flags, out_flags, ec);
#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
std::size_t s = this->impl_.get_service().receive_with_flags(
this->impl_.get_implementation(), buffers, in_flags, out_flags, ec);
boost::asio::detail::throw_error(ec, "receive");
return s;
}
@ -467,13 +556,8 @@ public:
socket_base::message_flags in_flags,
socket_base::message_flags& out_flags, boost::system::error_code& ec)
{
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().receive(this->get_implementation(),
buffers, in_flags, out_flags, ec);
#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().receive_with_flags(this->get_implementation(),
buffers, in_flags, out_flags, ec);
#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->impl_.get_service().receive_with_flags(
this->impl_.get_implementation(), buffers, in_flags, out_flags, ec);
}
/// Start an asynchronous receive.
@ -500,9 +584,9 @@ public:
* std::size_t bytes_transferred // Number of bytes received.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* boost::asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post().
*
* @par Example
* To receive into a single data buffer use the @ref buffer function as
@ -521,24 +605,10 @@ public:
socket_base::message_flags& out_flags,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{
// 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;
#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)
return async_initiate<ReadHandler,
void (boost::system::error_code, std::size_t)>(
initiate_async_receive_with_flags(), handler, this,
buffers, socket_base::message_flags(0), &out_flags);
}
/// Start an asynchronous receive.
@ -567,9 +637,9 @@ public:
* std::size_t bytes_transferred // Number of bytes received.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* boost::asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post().
*
* @par Example
* To receive into a single data buffer use the @ref buffer function as
@ -591,25 +661,49 @@ public:
socket_base::message_flags& out_flags,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
return async_initiate<ReadHandler,
void (boost::system::error_code, std::size_t)>(
initiate_async_receive_with_flags(), handler,
this, buffers, in_flags, &out_flags);
}
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;
#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)
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

View File

@ -2,7 +2,7 @@
// 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)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
@ -18,18 +18,29 @@
#include <boost/asio/detail/config.hpp>
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
#if defined(BOOST_ASIO_HAS_SERIAL_PORT) \
|| defined(GENERATING_DOCUMENTATION)
#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/io_object_impl.hpp>
#include <boost/asio/detail/non_const_lvalue.hpp>
#include <boost/asio/detail/throw_error.hpp>
#include <boost/asio/detail/type_traits.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_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>
@ -38,34 +49,63 @@ namespace asio {
/// Provides serial port functionality.
/**
* The basic_serial_port class template provides functionality that is common
* to all serial ports.
* The basic_serial_port class provides a wrapper over serial port
* functionality.
*
* @par Thread Safety
* @e Distinct @e objects: Safe.@n
* @e Shared @e objects: Unsafe.
*/
template <typename SerialPortService = serial_port_service>
template <typename Executor = executor>
class basic_serial_port
: public basic_io_object<SerialPortService>,
public serial_port_base
: public serial_port_base
{
public:
/// The native representation of a serial port.
typedef typename SerialPortService::native_handle_type native_handle_type;
/// The type of the executor associated with the object.
typedef Executor executor_type;
/// A basic_serial_port is always the lowest layer.
typedef basic_serial_port<SerialPortService> lowest_layer_type;
/// The native representation of a serial port.
#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.
/**
* This constructor creates a serial port without opening it.
*
* @param io_context The io_context object that the serial port will use to
* dispatch handlers for any asynchronous operations performed on the port.
* @param 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.
*/
explicit basic_serial_port(boost::asio::io_context& io_context)
: basic_io_object<SerialPortService>(io_context)
explicit basic_serial_port(const executor_type& ex)
: 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
* name.
*
* @param io_context The io_context object that the serial port will use to
* dispatch handlers for any asynchronous operations performed on the port.
* @param 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.
*/
explicit basic_serial_port(boost::asio::io_context& io_context,
const char* device)
: basic_io_object<SerialPortService>(io_context)
basic_serial_port(const executor_type& ex, const char* device)
: impl_(ex)
{
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");
}
@ -94,18 +134,66 @@ public:
* This constructor creates and opens a serial port for the specified device
* name.
*
* @param io_context The io_context object that the serial port will use to
* dispatch handlers for any asynchronous operations performed on the port.
* @param 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.
*/
explicit basic_serial_port(boost::asio::io_context& io_context,
const std::string& device)
: basic_io_object<SerialPortService>(io_context)
template <typename ExecutionContext>
basic_serial_port(ExecutionContext& context, const char* device,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: impl_(context)
{
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");
}
@ -114,19 +202,47 @@ public:
* This constructor creates a serial port object to hold an existing native
* serial port.
*
* @param io_context The io_context object that the serial port will use to
* dispatch handlers for any asynchronous operations performed on the port.
* @param 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 native_serial_port A native serial port.
*
* @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)
: basic_io_object<SerialPortService>(io_context)
: impl_(ex)
{
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);
boost::asio::detail::throw_error(ec, "assign");
}
@ -140,11 +256,11 @@ public:
* occur.
*
* @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_serial_port(io_context&) constructor.
* constructed using the @c basic_serial_port(const executor_type&)
* constructor.
*/
basic_serial_port(basic_serial_port&& other)
: basic_io_object<SerialPortService>(
BOOST_ASIO_MOVE_CAST(basic_serial_port)(other))
: impl_(std::move(other.impl_))
{
}
@ -156,16 +272,32 @@ public:
* occur.
*
* @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_serial_port(io_context&) constructor.
* constructed using the @c basic_serial_port(const executor_type&)
* constructor.
*/
basic_serial_port& operator=(basic_serial_port&& other)
{
basic_io_object<SerialPortService>::operator=(
BOOST_ASIO_MOVE_CAST(basic_serial_port)(other));
impl_ = std::move(other.impl_);
return *this;
}
#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.
/**
* This function returns a reference to the lowest layer in a stack of
@ -205,7 +337,7 @@ public:
void open(const std::string& device)
{
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");
}
@ -221,7 +353,7 @@ public:
BOOST_ASIO_SYNC_OP_VOID open(const std::string& device,
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);
}
@ -236,7 +368,7 @@ public:
void assign(const native_handle_type& native_serial_port)
{
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");
}
@ -252,7 +384,7 @@ public:
BOOST_ASIO_SYNC_OP_VOID assign(const native_handle_type& native_serial_port,
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_SYNC_OP_VOID_RETURN(ec);
}
@ -260,7 +392,7 @@ public:
/// Determine whether the serial port is open.
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.
@ -274,7 +406,7 @@ public:
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::detail::throw_error(ec, "close");
}
@ -288,7 +420,7 @@ public:
*/
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);
}
@ -300,7 +432,7 @@ public:
*/
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.
@ -314,7 +446,7 @@ public:
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::detail::throw_error(ec, "cancel");
}
@ -328,7 +460,7 @@ public:
*/
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);
}
@ -342,7 +474,7 @@ public:
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::detail::throw_error(ec, "send_break");
}
@ -355,7 +487,7 @@ public:
*/
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);
}
@ -378,7 +510,7 @@ public:
void set_option(const SettableSerialPortOption& option)
{
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");
}
@ -401,7 +533,7 @@ public:
BOOST_ASIO_SYNC_OP_VOID set_option(const SettableSerialPortOption& option,
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);
}
@ -422,10 +554,10 @@ public:
* boost::asio::serial_port_base::character_size
*/
template <typename GettableSerialPortOption>
void get_option(GettableSerialPortOption& option)
void get_option(GettableSerialPortOption& option) const
{
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");
}
@ -447,9 +579,9 @@ public:
*/
template <typename GettableSerialPortOption>
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);
}
@ -474,7 +606,7 @@ public:
* @par Example
* To write a single data buffer use the @ref buffer function as follows:
* @code
* serial_port.write_some(boost::asio::buffer(data, size));
* basic_serial_port.write_some(boost::asio::buffer(data, size));
* @endcode
* See the @ref buffer documentation for information on writing multiple
* 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)
{
boost::system::error_code ec;
std::size_t s = this->get_service().write_some(
this->get_implementation(), buffers, ec);
std::size_t s = impl_.get_service().write_some(
impl_.get_implementation(), buffers, ec);
boost::asio::detail::throw_error(ec, "write_some");
return s;
}
@ -510,8 +642,8 @@ public:
std::size_t write_some(const ConstBufferSequence& buffers,
boost::system::error_code& ec)
{
return this->get_service().write_some(
this->get_implementation(), buffers, ec);
return impl_.get_service().write_some(
impl_.get_implementation(), buffers, ec);
}
/// Start an asynchronous write.
@ -532,9 +664,9 @@ public:
* std::size_t bytes_transferred // Number of bytes written.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* boost::asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post().
*
* @note The write operation may not transmit all of the data to the peer.
* Consider using the @ref async_write function if you need to ensure that all
@ -543,7 +675,8 @@ public:
* @par Example
* To write a single data buffer use the @ref buffer function as follows:
* @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
* See the @ref buffer documentation for information on writing multiple
* 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,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{
// 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;
return this->get_service().async_write_some(this->get_implementation(),
buffers, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
return async_initiate<WriteHandler,
void (boost::system::error_code, std::size_t)>(
initiate_async_write_some(), handler, this, buffers);
}
/// Read some data from the serial port.
@ -585,7 +715,7 @@ public:
* @par Example
* To read into a single data buffer use the @ref buffer function as follows:
* @code
* serial_port.read_some(boost::asio::buffer(data, size));
* basic_serial_port.read_some(boost::asio::buffer(data, size));
* @endcode
* 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
@ -595,8 +725,8 @@ public:
std::size_t read_some(const MutableBufferSequence& buffers)
{
boost::system::error_code ec;
std::size_t s = this->get_service().read_some(
this->get_implementation(), buffers, ec);
std::size_t s = impl_.get_service().read_some(
impl_.get_implementation(), buffers, ec);
boost::asio::detail::throw_error(ec, "read_some");
return s;
}
@ -622,8 +752,8 @@ public:
std::size_t read_some(const MutableBufferSequence& buffers,
boost::system::error_code& ec)
{
return this->get_service().read_some(
this->get_implementation(), buffers, ec);
return impl_.get_service().read_some(
impl_.get_implementation(), buffers, ec);
}
/// Start an asynchronous read.
@ -644,9 +774,9 @@ public:
* std::size_t bytes_transferred // Number of bytes read.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* boost::asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post().
*
* @note The read operation may not read all of the requested number of bytes.
* Consider using the @ref async_read function if you need to ensure that the
@ -656,7 +786,8 @@ public:
* @par Example
* To read into a single data buffer use the @ref buffer function as follows:
* @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
* 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
@ -668,13 +799,55 @@ public:
async_read_some(const MutableBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
return async_initiate<ReadHandler,
void (boost::system::error_code, std::size_t)>(
initiate_async_read_some(), handler, this, buffers);
}
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;
return this->get_service().async_read_some(this->get_implementation(),
buffers, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
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
@ -685,6 +858,4 @@ public:
#endif // defined(BOOST_ASIO_HAS_SERIAL_PORT)
// || defined(GENERATING_DOCUMENTATION)
#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
#endif // BOOST_ASIO_BASIC_SERIAL_PORT_HPP

View File

@ -2,7 +2,7 @@
// 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
// 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>
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
#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/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/type_traits.hpp>
#include <boost/asio/error.hpp>
#include <boost/asio/signal_set_service.hpp>
#include <boost/asio/detail/push_options.hpp>
#include <boost/asio/execution_context.hpp>
#include <boost/asio/executor.hpp>
namespace boost {
namespace asio {
/// Provides signal functionality.
/**
* The basic_signal_set class template provides the ability to perform an
* asynchronous wait for one or more signals to occur.
*
* Most applications will use the boost::asio::signal_set typedef.
* The basic_signal_set class provides the ability to perform an asynchronous
* wait for one or more signals to occur.
*
* @par Thread Safety
* @e Distinct @e objects: Safe.@n
@ -57,7 +56,7 @@ namespace asio {
* ...
*
* // 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.
* signals.async_wait(handler);
@ -92,20 +91,40 @@ namespace asio {
* that any signals registered using signal_set objects are unblocked in at
* least one thread.
*/
template <typename SignalSetService = signal_set_service>
template <typename Executor = executor>
class basic_signal_set
: public basic_io_object<SignalSetService>
{
public:
/// The type of the executor associated with the object.
typedef Executor executor_type;
/// Construct a signal set without adding 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
* dispatch handlers for any asynchronous operations performed on the set.
* @param ex The I/O executor that the signal set will use, by default, to
* dispatch handlers for any asynchronous operations performed on the
* signal set.
*/
explicit basic_signal_set(boost::asio::io_context& io_context)
: basic_io_object<SignalSetService>(io_context)
explicit basic_signal_set(const executor_type& ex)
: 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.
*
* @param io_context The io_context object that the signal set will use to
* dispatch handlers for any asynchronous operations performed on the set.
* @param ex 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(io_context);
* @code boost::asio::signal_set signals(ex);
* signals.add(signal_number_1); @endcode
*/
basic_signal_set(boost::asio::io_context& io_context, int signal_number_1)
: basic_io_object<SignalSetService>(io_context)
basic_signal_set(const executor_type& ex, int signal_number_1)
: impl_(ex)
{
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");
}
@ -134,26 +180,59 @@ public:
/**
* 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
* dispatch handlers for any asynchronous operations performed on the set.
* @param ex 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(io_context);
* @code boost::asio::signal_set signals(ex);
* signals.add(signal_number_1);
* 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)
: basic_io_object<SignalSetService>(io_context)
: impl_(ex)
{
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");
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");
}
@ -161,8 +240,9 @@ public:
/**
* 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
* dispatch handlers for any asynchronous operations performed on the set.
* @param ex 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.
*
@ -171,24 +251,77 @@ public:
* @param signal_number_3 The third signal number to be added.
*
* @note This constructor is equivalent to performing:
* @code boost::asio::signal_set signals(io_context);
* @code boost::asio::signal_set signals(ex);
* signals.add(signal_number_1);
* signals.add(signal_number_2);
* 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)
: basic_io_object<SignalSetService>(io_context)
: impl_(ex)
{
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");
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");
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");
}
/// 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.
/**
* 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)
{
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");
}
@ -214,9 +347,10 @@ public:
*
* @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);
}
@ -235,7 +369,7 @@ public:
void remove(int signal_number)
{
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");
}
@ -254,7 +388,7 @@ public:
BOOST_ASIO_SYNC_OP_VOID remove(int signal_number,
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);
}
@ -270,7 +404,7 @@ public:
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::detail::throw_error(ec, "clear");
}
@ -285,7 +419,7 @@ public:
*/
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);
}
@ -313,7 +447,7 @@ public:
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::detail::throw_error(ec, "cancel");
}
@ -340,7 +474,7 @@ public:
*/
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);
}
@ -365,29 +499,45 @@ public:
* int signal_number // Indicates which signal occurred.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* boost::asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post().
*/
template <typename SignalHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(SignalHandler,
void (boost::system::error_code, int))
async_wait(BOOST_ASIO_MOVE_ARG(SignalHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a SignalHandler.
return async_initiate<SignalHandler, void (boost::system::error_code, int)>(
initiate_async_wait(), handler, this);
}
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;
return this->get_service().async_wait(this->get_implementation(),
BOOST_ASIO_MOVE_CAST(SignalHandler)(handler));
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 boost
#include <boost/asio/detail/pop_options.hpp>
#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
#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
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
// 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
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -23,10 +23,6 @@
#include <ostream>
#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)
# include <boost/asio/detail/variadic_templates.hpp>
@ -36,8 +32,7 @@
// explicit basic_socket_iostream(T1 x1, ..., Tn xn)
// : std::basic_iostream<char>(
// &this->detail::socket_iostream_base<
// Protocol BOOST_ASIO_SVC_TARG, Clock,
// WaitTraits BOOST_ASIO_SVC_TARG1>::streambuf_)
// Protocol, Clock, WaitTraits>::streambuf_)
// {
// if (rdbuf()->connect(x1, ..., xn) == 0)
// this->setstate(std::ios_base::failbit);
@ -49,8 +44,7 @@
explicit basic_socket_iostream(BOOST_ASIO_VARIADIC_BYVAL_PARAMS(n)) \
: std::basic_iostream<char>( \
&this->detail::socket_iostream_base< \
Protocol BOOST_ASIO_SVC_TARG, Clock, \
WaitTraits BOOST_ASIO_SVC_TARG1>::streambuf_) \
Protocol, Clock, WaitTraits>::streambuf_) \
{ \
this->setf(std::ios_base::unitbuf); \
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
// prior to the basic_socket_iostream's basic_iostream base class.
template <typename Protocol BOOST_ASIO_SVC_TPARAM,
typename Clock, typename WaitTraits BOOST_ASIO_SVC_TPARAM1>
template <typename Protocol, typename Clock, typename WaitTraits>
class socket_iostream_base
{
protected:
@ -113,8 +106,7 @@ protected:
}
#endif // defined(BOOST_ASIO_HAS_MOVE)
basic_socket_streambuf<Protocol BOOST_ASIO_SVC_TARG,
Clock, WaitTraits BOOST_ASIO_SVC_TARG1> streambuf_;
basic_socket_streambuf<Protocol, Clock, WaitTraits> streambuf_;
};
} // namespace detail
@ -123,18 +115,15 @@ protected:
#define BOOST_ASIO_BASIC_SOCKET_IOSTREAM_FWD_DECL
// Forward declaration with defaulted arguments.
template <typename Protocol
BOOST_ASIO_SVC_TPARAM_DEF1(= stream_socket_service<Protocol>),
template <typename Protocol,
#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) \
&& defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
typename Clock = boost::posix_time::ptime,
typename WaitTraits = time_traits<Clock>
BOOST_ASIO_SVC_TPARAM1_DEF2(= deadline_timer_service<Clock, WaitTraits>)>
typename WaitTraits = time_traits<Clock> >
#else // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
// && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
typename Clock = chrono::steady_clock,
typename WaitTraits = wait_traits<Clock>
BOOST_ASIO_SVC_TPARAM1_DEF1(= steady_timer::service_type)>
typename WaitTraits = wait_traits<Clock> >
#endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
// && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
class basic_socket_iostream;
@ -147,12 +136,10 @@ template <typename Protocol,
typename Clock = chrono::steady_clock,
typename WaitTraits = wait_traits<Clock> >
#else // defined(GENERATING_DOCUMENTATION)
template <typename Protocol BOOST_ASIO_SVC_TPARAM,
typename Clock, typename WaitTraits BOOST_ASIO_SVC_TPARAM1>
template <typename Protocol, typename Clock, typename WaitTraits>
#endif // defined(GENERATING_DOCUMENTATION)
class basic_socket_iostream
: private detail::socket_iostream_base<Protocol
BOOST_ASIO_SVC_TARG, Clock, WaitTraits BOOST_ASIO_SVC_TARG1>,
: private detail::socket_iostream_base<Protocol, Clock, WaitTraits>,
public std::basic_iostream<char>
{
private:
@ -202,8 +189,7 @@ public:
basic_socket_iostream()
: std::basic_iostream<char>(
&this->detail::socket_iostream_base<
Protocol BOOST_ASIO_SVC_TARG, Clock,
WaitTraits BOOST_ASIO_SVC_TARG1>::streambuf_)
Protocol, Clock, WaitTraits>::streambuf_)
{
this->setf(std::ios_base::unitbuf);
}
@ -212,12 +198,10 @@ public:
/// Construct a basic_socket_iostream from the supplied socket.
explicit basic_socket_iostream(basic_stream_socket<protocol_type> s)
: detail::socket_iostream_base<
Protocol BOOST_ASIO_SVC_TARG, Clock,
WaitTraits BOOST_ASIO_SVC_TARG1>(std::move(s)),
Protocol, Clock, WaitTraits>(std::move(s)),
std::basic_iostream<char>(
&this->detail::socket_iostream_base<
Protocol BOOST_ASIO_SVC_TARG, Clock,
WaitTraits BOOST_ASIO_SVC_TARG1>::streambuf_)
Protocol, Clock, WaitTraits>::streambuf_)
{
this->setf(std::ios_base::unitbuf);
}
@ -227,13 +211,11 @@ public:
/// Move-construct a basic_socket_iostream from another.
basic_socket_iostream(basic_socket_iostream&& other)
: detail::socket_iostream_base<
Protocol BOOST_ASIO_SVC_TARG, Clock,
WaitTraits BOOST_ASIO_SVC_TARG1>(std::move(other)),
Protocol, Clock, WaitTraits>(std::move(other)),
std::basic_iostream<char>(std::move(other))
{
this->set_rdbuf(&this->detail::socket_iostream_base<
Protocol BOOST_ASIO_SVC_TARG, Clock,
WaitTraits BOOST_ASIO_SVC_TARG1>::streambuf_);
Protocol, Clock, WaitTraits>::streambuf_);
}
/// Move-assign a basic_socket_iostream from another.
@ -241,8 +223,7 @@ public:
{
std::basic_iostream<char>::operator=(std::move(other));
detail::socket_iostream_base<
Protocol BOOST_ASIO_SVC_TARG, Clock,
WaitTraits BOOST_ASIO_SVC_TARG1>::operator=(std::move(other));
Protocol, Clock, WaitTraits>::operator=(std::move(other));
return *this;
}
#endif // defined(BOOST_ASIO_HAS_STD_IOSTREAM_MOVE)
@ -263,8 +244,7 @@ public:
explicit basic_socket_iostream(T... x)
: std::basic_iostream<char>(
&this->detail::socket_iostream_base<
Protocol BOOST_ASIO_SVC_TARG, Clock,
WaitTraits BOOST_ASIO_SVC_TARG1>::streambuf_)
Protocol, Clock, WaitTraits>::streambuf_)
{
this->setf(std::ios_base::unitbuf);
if (rdbuf()->connect(x...) == 0)
@ -302,18 +282,15 @@ public:
}
/// Return a pointer to the underlying streambuf.
basic_socket_streambuf<Protocol BOOST_ASIO_SVC_TARG,
Clock, WaitTraits BOOST_ASIO_SVC_TARG1>* rdbuf() const
basic_socket_streambuf<Protocol, Clock, WaitTraits>* rdbuf() const
{
return const_cast<basic_socket_streambuf<Protocol BOOST_ASIO_SVC_TARG,
Clock, WaitTraits BOOST_ASIO_SVC_TARG1>*>(
return const_cast<basic_socket_streambuf<Protocol, Clock, WaitTraits>*>(
&this->detail::socket_iostream_base<
Protocol BOOST_ASIO_SVC_TARG, Clock,
WaitTraits BOOST_ASIO_SVC_TARG1>::streambuf_);
Protocol, Clock, WaitTraits>::streambuf_);
}
/// Get a reference to the underlying socket.
basic_socket<Protocol BOOST_ASIO_SVC_TARG>& socket()
basic_socket<Protocol>& socket()
{
return rdbuf()->socket();
}

View File

@ -2,7 +2,7 @@
// 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
// 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/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) \
&& defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
# if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
# include <boost/asio/deadline_timer_service.hpp>
# else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
# include <boost/asio/detail/deadline_timer_service.hpp>
# endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
#else // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
// && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
# include <boost/asio/steady_timer.hpp>
@ -55,7 +47,7 @@
// {
// init_buffers();
// typedef typename Protocol::resolver resolver_type;
// resolver_type resolver(socket().get_executor().context());
// resolver_type resolver(socket().get_executor());
// connect_to_endpoints(
// resolver.resolve(x1, ..., xn, ec_));
// return !ec_ ? this : 0;
@ -68,7 +60,7 @@
{ \
init_buffers(); \
typedef typename Protocol::resolver resolver_type; \
resolver_type resolver(socket().get_executor().context()); \
resolver_type resolver(socket().get_executor()); \
connect_to_endpoints( \
resolver.resolve(BOOST_ASIO_VARIADIC_BYVAL_ARGS(n), ec_)); \
return !ec_ ? this : 0; \
@ -77,10 +69,6 @@
#endif // !defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
#if !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
# define BOOST_ASIO_SVC_T1 detail::deadline_timer_service<traits_helper>
#endif // !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
#include <boost/asio/detail/push_options.hpp>
namespace boost {
@ -125,18 +113,15 @@ protected:
#define BOOST_ASIO_BASIC_SOCKET_STREAMBUF_FWD_DECL
// Forward declaration with defaulted arguments.
template <typename Protocol
BOOST_ASIO_SVC_TPARAM_DEF1(= stream_socket_service<Protocol>),
template <typename Protocol,
#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) \
&& defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
typename Clock = boost::posix_time::ptime,
typename WaitTraits = time_traits<Clock>
BOOST_ASIO_SVC_TPARAM1_DEF2(= deadline_timer_service<Clock, WaitTraits>)>
typename WaitTraits = time_traits<Clock> >
#else // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
// && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
typename Clock = chrono::steady_clock,
typename WaitTraits = wait_traits<Clock>
BOOST_ASIO_SVC_TPARAM1_DEF1(= steady_timer::service_type)>
typename WaitTraits = wait_traits<Clock> >
#endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
// && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
class basic_socket_streambuf;
@ -149,17 +134,16 @@ template <typename Protocol,
typename Clock = chrono::steady_clock,
typename WaitTraits = wait_traits<Clock> >
#else // defined(GENERATING_DOCUMENTATION)
template <typename Protocol BOOST_ASIO_SVC_TPARAM,
typename Clock, typename WaitTraits BOOST_ASIO_SVC_TPARAM1>
template <typename Protocol, typename Clock, typename WaitTraits>
#endif // defined(GENERATING_DOCUMENTATION)
class basic_socket_streambuf
: public std::streambuf,
private detail::socket_streambuf_io_context,
private detail::socket_streambuf_buffers,
#if defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
private basic_socket<Protocol BOOST_ASIO_SVC_TARG>
private basic_socket<Protocol>
#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)
{
private:
@ -208,7 +192,7 @@ public:
/// Construct a basic_socket_streambuf without establishing a connection.
basic_socket_streambuf()
: 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())
{
init_buffers();
@ -218,7 +202,7 @@ public:
/// Construct a basic_socket_streambuf from the supplied socket.
explicit basic_socket_streambuf(basic_stream_socket<protocol_type> s)
: detail::socket_streambuf_io_context(0),
basic_socket<Protocol BOOST_ASIO_SVC_TARG>(std::move(s)),
basic_socket<Protocol>(std::move(s)),
expiry_time_(max_expiry_time())
{
init_buffers();
@ -227,7 +211,7 @@ public:
/// Move-construct a basic_socket_streambuf from another.
basic_socket_streambuf(basic_socket_streambuf&& other)
: detail::socket_streambuf_io_context(other),
basic_socket<Protocol BOOST_ASIO_SVC_TARG>(std::move(other.socket())),
basic_socket<Protocol>(std::move(other.socket())),
ec_(other.ec_),
expiry_time_(other.expiry_time_)
{
@ -300,7 +284,7 @@ public:
{
init_buffers();
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_));
return !ec_ ? this : 0;
}
@ -323,7 +307,7 @@ public:
}
/// Get a reference to the underlying socket.
basic_socket<Protocol BOOST_ASIO_SVC_TARG>& socket()
basic_socket<Protocol>& socket()
{
return *this;
}
@ -696,10 +680,6 @@ private:
#include <boost/asio/detail/pop_options.hpp>
#if !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
# undef BOOST_ASIO_SVC_T1
#endif // !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
#if !defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
# undef BOOST_ASIO_PRIVATE_CONNECT_DEF
#endif // !defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)

View File

@ -2,7 +2,7 @@
// 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
// 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/basic_socket.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/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>
namespace boost {
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.
/**
* The basic_stream_socket class template provides asynchronous and blocking
@ -44,18 +50,28 @@ namespace asio {
* @par Concepts:
* AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream.
*/
template <typename Protocol
BOOST_ASIO_SVC_TPARAM_DEF1(= stream_socket_service<Protocol>)>
template <typename Protocol, typename Executor>
class basic_stream_socket
: public basic_socket<Protocol BOOST_ASIO_SVC_TARG>
: public basic_socket<Protocol, Executor>
{
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.
#if defined(GENERATING_DOCUMENTATION)
typedef implementation_defined native_handle_type;
#else
typedef typename basic_socket<
Protocol BOOST_ASIO_SVC_TARG>::native_handle_type native_handle_type;
typedef typename basic_socket<Protocol,
Executor>::native_handle_type native_handle_type;
#endif
/// The protocol type.
@ -70,11 +86,30 @@ public:
* needs to be opened and then 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.
*/
explicit basic_stream_socket(boost::asio::io_context& io_context)
: basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context)
explicit basic_stream_socket(const executor_type& ex)
: 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
* 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.
*
* @param protocol An object specifying protocol parameters to be used.
*
* @throws boost::system::system_error Thrown on failure.
*/
basic_stream_socket(boost::asio::io_context& io_context,
const protocol_type& protocol)
: basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context, protocol)
basic_stream_socket(const executor_type& ex, const protocol_type& protocol)
: basic_socket<Protocol, Executor>(ex, 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
* 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.
*
* @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.
*/
basic_stream_socket(boost::asio::io_context& io_context,
const endpoint_type& endpoint)
: basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context, endpoint)
basic_stream_socket(const executor_type& ex, const endpoint_type& endpoint)
: basic_socket<Protocol, Executor>(ex, 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
* 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.
*
* @param protocol An object specifying protocol parameters to be used.
@ -131,10 +211,34 @@ public:
*
* @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)
: basic_socket<Protocol BOOST_ASIO_SVC_TARG>(
io_context, protocol, native_socket)
: basic_socket<Protocol, Executor>(ex, 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.
*
* @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_socket<Protocol BOOST_ASIO_SVC_TARG>(std::move(other))
: basic_socket<Protocol, Executor>(std::move(other))
{
}
@ -162,11 +267,12 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_stream_socket(io_context&) constructor.
* constructed using the @c basic_stream_socket(const executor_type&)
* constructor.
*/
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;
}
@ -179,13 +285,16 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_stream_socket(io_context&) constructor.
* constructed using the @c basic_stream_socket(const executor_type&)
* constructor.
*/
template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
basic_stream_socket(
basic_stream_socket<Protocol1 BOOST_ASIO_SVC_TARG1>&& other,
typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0)
: basic_socket<Protocol BOOST_ASIO_SVC_TARG>(std::move(other))
template <typename Protocol1, typename Executor1>
basic_stream_socket(basic_stream_socket<Protocol1, Executor1>&& other,
typename enable_if<
is_convertible<Protocol1, Protocol>::value
&& is_convertible<Executor1, Executor>::value
>::type* = 0)
: basic_socket<Protocol, Executor>(std::move(other))
{
}
@ -197,14 +306,17 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_stream_socket(io_context&) constructor.
* constructed using the @c basic_stream_socket(const executor_type&)
* constructor.
*/
template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
typename enable_if<is_convertible<Protocol1, Protocol>::value,
basic_stream_socket>::type& operator=(
basic_stream_socket<Protocol1 BOOST_ASIO_SVC_TARG1>&& other)
template <typename Protocol1, typename Executor1>
typename enable_if<
is_convertible<Protocol1, Protocol>::value
&& 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;
}
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
@ -247,8 +359,8 @@ public:
std::size_t send(const ConstBufferSequence& buffers)
{
boost::system::error_code ec;
std::size_t s = this->get_service().send(
this->get_implementation(), buffers, 0, ec);
std::size_t s = this->impl_.get_service().send(
this->impl_.get_implementation(), buffers, 0, ec);
boost::asio::detail::throw_error(ec, "send");
return s;
}
@ -285,8 +397,8 @@ public:
socket_base::message_flags flags)
{
boost::system::error_code ec;
std::size_t s = this->get_service().send(
this->get_implementation(), buffers, flags, ec);
std::size_t s = this->impl_.get_service().send(
this->impl_.get_implementation(), buffers, flags, ec);
boost::asio::detail::throw_error(ec, "send");
return s;
}
@ -313,8 +425,8 @@ public:
std::size_t send(const ConstBufferSequence& buffers,
socket_base::message_flags flags, boost::system::error_code& ec)
{
return this->get_service().send(
this->get_implementation(), buffers, flags, ec);
return this->impl_.get_service().send(
this->impl_.get_implementation(), buffers, flags, ec);
}
/// Start an asynchronous send.
@ -335,9 +447,9 @@ public:
* std::size_t bytes_transferred // Number of bytes sent.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* boost::asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post().
*
* @note The send operation may not transmit all of the data to the peer.
* Consider using the @ref async_write function if you need to ensure that all
@ -358,24 +470,10 @@ public:
async_send(const ConstBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{
// 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;
#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)
return async_initiate<WriteHandler,
void (boost::system::error_code, std::size_t)>(
initiate_async_send(), handler, this,
buffers, socket_base::message_flags(0));
}
/// Start an asynchronous send.
@ -398,9 +496,9 @@ public:
* std::size_t bytes_transferred // Number of bytes sent.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* boost::asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post().
*
* @note The send operation may not transmit all of the data to the peer.
* Consider using the @ref async_write function if you need to ensure that all
@ -422,24 +520,9 @@ public:
socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{
// 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;
#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)
return async_initiate<WriteHandler,
void (boost::system::error_code, std::size_t)>(
initiate_async_send(), handler, this, buffers, flags);
}
/// Receive some data on the socket.
@ -474,8 +557,8 @@ public:
std::size_t receive(const MutableBufferSequence& buffers)
{
boost::system::error_code ec;
std::size_t s = this->get_service().receive(
this->get_implementation(), buffers, 0, ec);
std::size_t s = this->impl_.get_service().receive(
this->impl_.get_implementation(), buffers, 0, ec);
boost::asio::detail::throw_error(ec, "receive");
return s;
}
@ -515,8 +598,8 @@ public:
socket_base::message_flags flags)
{
boost::system::error_code ec;
std::size_t s = this->get_service().receive(
this->get_implementation(), buffers, flags, ec);
std::size_t s = this->impl_.get_service().receive(
this->impl_.get_implementation(), buffers, flags, ec);
boost::asio::detail::throw_error(ec, "receive");
return s;
}
@ -543,8 +626,8 @@ public:
std::size_t receive(const MutableBufferSequence& buffers,
socket_base::message_flags flags, boost::system::error_code& ec)
{
return this->get_service().receive(
this->get_implementation(), buffers, flags, ec);
return this->impl_.get_service().receive(
this->impl_.get_implementation(), buffers, flags, ec);
}
/// Start an asynchronous receive.
@ -565,9 +648,9 @@ public:
* std::size_t bytes_transferred // Number of bytes received.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* boost::asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post().
*
* @note The receive operation may not receive all of the requested number of
* bytes. Consider using the @ref async_read function if you need to ensure
@ -590,22 +673,10 @@ public:
async_receive(const MutableBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{
// 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;
#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)
return async_initiate<ReadHandler,
void (boost::system::error_code, std::size_t)>(
initiate_async_receive(), handler, this,
buffers, socket_base::message_flags(0));
}
/// Start an asynchronous receive.
@ -628,9 +699,9 @@ public:
* std::size_t bytes_transferred // Number of bytes received.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* boost::asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post().
*
* @note The receive operation may not receive all of the requested number of
* bytes. Consider using the @ref async_read function if you need to ensure
@ -654,22 +725,9 @@ public:
socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{
// 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;
#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)
return async_initiate<ReadHandler,
void (boost::system::error_code, std::size_t)>(
initiate_async_receive(), handler, this, buffers, flags);
}
/// Write some data to the socket.
@ -703,8 +761,8 @@ public:
std::size_t write_some(const ConstBufferSequence& buffers)
{
boost::system::error_code ec;
std::size_t s = this->get_service().send(
this->get_implementation(), buffers, 0, ec);
std::size_t s = this->impl_.get_service().send(
this->impl_.get_implementation(), buffers, 0, ec);
boost::asio::detail::throw_error(ec, "write_some");
return s;
}
@ -729,7 +787,8 @@ public:
std::size_t write_some(const ConstBufferSequence& buffers,
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.
@ -750,9 +809,9 @@ public:
* std::size_t bytes_transferred // Number of bytes written.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* boost::asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post().
*
* @note The write operation may not transmit all of the data to the peer.
* Consider using the @ref async_write function if you need to ensure that all
@ -773,22 +832,10 @@ public:
async_write_some(const ConstBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{
// 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;
#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)
return async_initiate<WriteHandler,
void (boost::system::error_code, std::size_t)>(
initiate_async_send(), handler, this,
buffers, socket_base::message_flags(0));
}
/// Read some data from the socket.
@ -823,8 +870,8 @@ public:
std::size_t read_some(const MutableBufferSequence& buffers)
{
boost::system::error_code ec;
std::size_t s = this->get_service().receive(
this->get_implementation(), buffers, 0, ec);
std::size_t s = this->impl_.get_service().receive(
this->impl_.get_implementation(), buffers, 0, ec);
boost::asio::detail::throw_error(ec, "read_some");
return s;
}
@ -850,8 +897,8 @@ public:
std::size_t read_some(const MutableBufferSequence& buffers,
boost::system::error_code& ec)
{
return this->get_service().receive(
this->get_implementation(), buffers, 0, ec);
return this->impl_.get_service().receive(
this->impl_.get_implementation(), buffers, 0, ec);
}
/// Start an asynchronous read.
@ -872,9 +919,9 @@ public:
* std::size_t bytes_transferred // Number of bytes read.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* boost::asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post().
*
* @note The read operation may not read all of the requested number of bytes.
* Consider using the @ref async_read function if you need to ensure that the
@ -896,23 +943,48 @@ public:
async_read_some(const MutableBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
return async_initiate<ReadHandler,
void (boost::system::error_code, std::size_t)>(
initiate_async_receive(), handler, this,
buffers, socket_base::message_flags(0));
}
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;
#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)
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

View File

@ -2,7 +2,7 @@
// 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
// 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
// ~~~~~~~~~~~~~~~~~~~~~~~
//
// 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
// 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
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
// 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
// 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 <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/io_object_impl.hpp>
#include <boost/asio/detail/non_const_lvalue.hpp>
#include <boost/asio/detail/throw_error.hpp>
#include <boost/asio/error.hpp>
#include <boost/asio/executor.hpp>
#include <boost/asio/wait_traits.hpp>
#if defined(BOOST_ASIO_HAS_MOVE)
# include <utility>
#endif // defined(BOOST_ASIO_HAS_MOVE)
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
# include <boost/asio/waitable_timer_service.hpp>
#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
# include <boost/asio/detail/chrono_time_traits.hpp>
# include <boost/asio/detail/deadline_timer_service.hpp>
# define BOOST_ASIO_SVC_T \
detail::deadline_timer_service< \
detail::chrono_time_traits<Clock, WaitTraits> >
#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
#include <boost/asio/detail/push_options.hpp>
namespace boost {
@ -47,8 +41,8 @@ namespace asio {
// Forward declaration with defaulted arguments.
template <typename Clock,
typename WaitTraits = boost::asio::wait_traits<Clock>
BOOST_ASIO_SVC_TPARAM_DEF2(= waitable_timer_service<Clock, WaitTraits>)>
typename WaitTraits = boost::asio::wait_traits<Clock>,
typename Executor = executor>
class basic_waitable_timer;
#endif // !defined(BOOST_ASIO_BASIC_WAITABLE_TIMER_FWD_DECL)
@ -76,7 +70,7 @@ class basic_waitable_timer;
* Performing a blocking wait (C++11):
* @code
* // 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.
* timer.expires_after(std::chrono::seconds(5));
@ -99,7 +93,7 @@ class basic_waitable_timer;
* ...
*
* // 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));
*
* // 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
* 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
: BOOST_ASIO_SVC_ACCESS basic_io_object<BOOST_ASIO_SVC_T>
{
public:
/// The type of the executor associated with the object.
typedef io_context::executor_type executor_type;
typedef Executor executor_type;
/// The clock type.
typedef Clock clock_type;
@ -171,11 +164,30 @@ public:
* expires_at() or expires_after() functions must be called to set an expiry
* time before the timer can be waited on.
*
* @param io_context The io_context object that the timer will use to dispatch
* handlers for any asynchronous operations performed on the timer.
* @param ex The I/O executor that the timer will use, by default, to
* dispatch handlers for any asynchronous operations performed on the timer.
*/
explicit basic_waitable_timer(boost::asio::io_context& io_context)
: basic_io_object<BOOST_ASIO_SVC_T>(io_context)
explicit basic_waitable_timer(const executor_type& ex)
: 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.
*
* @param io_context The io_context object that the timer will use to dispatch
* handlers for any asynchronous operations performed on the timer.
* @param ex The I/O executor object 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.
*/
basic_waitable_timer(boost::asio::io_context& io_context,
const time_point& expiry_time)
: basic_io_object<BOOST_ASIO_SVC_T>(io_context)
basic_waitable_timer(const executor_type& ex, const time_point& expiry_time)
: impl_(ex)
{
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");
}
@ -202,19 +237,43 @@ public:
/**
* This constructor creates a timer and sets the expiry time.
*
* @param io_context The io_context object that the timer will use to dispatch
* handlers for any asynchronous operations performed on the timer.
* @param ex 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.
*/
basic_waitable_timer(boost::asio::io_context& io_context,
const duration& expiry_time)
: basic_io_object<BOOST_ASIO_SVC_T>(io_context)
basic_waitable_timer(const executor_type& ex, const duration& expiry_time)
: impl_(ex)
{
boost::system::error_code ec;
this->get_service().expires_after(
this->get_implementation(), expiry_time, ec);
impl_.get_service().expires_after(
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");
}
@ -227,10 +286,11 @@ public:
* occur.
*
* @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_waitable_timer(io_context&) constructor.
* constructed using the @c basic_waitable_timer(const executor_type&)
* constructor.
*/
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.
*
* @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_io_object<BOOST_ASIO_SVC_T>::operator=(std::move(other));
impl_ = std::move(other.impl_);
return *this;
}
#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.
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.
/**
@ -326,7 +353,7 @@ public:
std::size_t cancel()
{
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");
return s;
}
@ -357,7 +384,7 @@ public:
*/
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)
@ -388,8 +415,8 @@ public:
std::size_t cancel_one()
{
boost::system::error_code ec;
std::size_t s = this->get_service().cancel_one(
this->get_implementation(), ec);
std::size_t s = impl_.get_service().cancel_one(
impl_.get_implementation(), ec);
boost::asio::detail::throw_error(ec, "cancel_one");
return s;
}
@ -422,7 +449,7 @@ public:
*/
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
@ -433,7 +460,7 @@ public:
*/
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)
@ -444,7 +471,7 @@ public:
*/
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.
@ -472,8 +499,8 @@ public:
std::size_t expires_at(const time_point& expiry_time)
{
boost::system::error_code ec;
std::size_t s = this->get_service().expires_at(
this->get_implementation(), expiry_time, ec);
std::size_t s = impl_.get_service().expires_at(
impl_.get_implementation(), expiry_time, ec);
boost::asio::detail::throw_error(ec, "expires_at");
return s;
}
@ -505,8 +532,8 @@ public:
std::size_t expires_at(const time_point& expiry_time,
boost::system::error_code& ec)
{
return this->get_service().expires_at(
this->get_implementation(), expiry_time, ec);
return impl_.get_service().expires_at(
impl_.get_implementation(), expiry_time, ec);
}
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
@ -535,8 +562,8 @@ public:
std::size_t expires_after(const duration& expiry_time)
{
boost::system::error_code ec;
std::size_t s = this->get_service().expires_after(
this->get_implementation(), expiry_time, ec);
std::size_t s = impl_.get_service().expires_after(
impl_.get_implementation(), expiry_time, ec);
boost::asio::detail::throw_error(ec, "expires_after");
return s;
}
@ -549,7 +576,7 @@ public:
*/
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
@ -578,8 +605,8 @@ public:
std::size_t expires_from_now(const duration& expiry_time)
{
boost::system::error_code ec;
std::size_t s = this->get_service().expires_from_now(
this->get_implementation(), expiry_time, ec);
std::size_t s = impl_.get_service().expires_from_now(
impl_.get_implementation(), expiry_time, ec);
boost::asio::detail::throw_error(ec, "expires_from_now");
return s;
}
@ -610,8 +637,8 @@ public:
std::size_t expires_from_now(const duration& expiry_time,
boost::system::error_code& ec)
{
return this->get_service().expires_from_now(
this->get_implementation(), expiry_time, ec);
return impl_.get_service().expires_from_now(
impl_.get_implementation(), expiry_time, ec);
}
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
@ -625,7 +652,7 @@ public:
void wait()
{
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");
}
@ -638,7 +665,7 @@ public:
*/
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.
@ -661,31 +688,17 @@ public:
* const boost::system::error_code& error // Result of operation.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* boost::asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post().
*/
template <typename WaitHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler,
void (boost::system::error_code))
async_wait(BOOST_ASIO_MOVE_ARG(WaitHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WaitHandler.
BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_wait(this->get_implementation(),
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)
return async_initiate<WaitHandler, void (boost::system::error_code)>(
initiate_async_wait(), handler, this);
}
private:
@ -693,6 +706,28 @@ private:
basic_waitable_timer(const basic_waitable_timer&) BOOST_ASIO_DELETED;
basic_waitable_timer& operator=(
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
@ -700,8 +735,4 @@ private:
#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

View File

@ -2,7 +2,7 @@
// 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
// 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_;
};
#if !defined(BOOST_ASIO_NO_DEPRECATED)
template <typename T, typename Executor, typename Signature>
struct handler_type<executor_binder<T, Executor>, Signature>
{
typedef executor_binder<
typename handler_type<T, Signature>::type, Executor> type;
};
template <typename T, typename Executor>
class async_result<executor_binder<T, Executor> >
{
public:
typedef typename async_result<T>::type type;
explicit async_result(executor_binder<T, Executor>& b)
: target_(b.get())
{
}
type get()
{
return target_.get();
}
private:
async_result<T> target_;
};
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
template <typename T, typename Executor, typename Allocator>
struct associated_allocator<executor_binder<T, Executor>, Allocator>
{

View File

@ -2,7 +2,7 @@
// 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
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -23,7 +23,7 @@
#include <string>
#include <vector>
#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/throw_exception.hpp>
#include <boost/asio/detail/type_traits.hpp>
@ -347,41 +347,6 @@ public:
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
/// Trait to determine whether a type satisfies the MutableBufferSequence
/// requirements.
template <typename T>
struct is_mutable_buffer_sequence
#if defined(GENERATING_DOCUMENTATION)
: integral_constant<bool, automatically_determined>
#else // defined(GENERATING_DOCUMENTATION)
: boost::asio::detail::is_buffer_sequence<T, mutable_buffer>
#endif // defined(GENERATING_DOCUMENTATION)
{
};
/// Trait to determine whether a type satisfies the ConstBufferSequence
/// requirements.
template <typename T>
struct is_const_buffer_sequence
#if defined(GENERATING_DOCUMENTATION)
: integral_constant<bool, automatically_determined>
#else // defined(GENERATING_DOCUMENTATION)
: boost::asio::detail::is_buffer_sequence<T, const_buffer>
#endif // defined(GENERATING_DOCUMENTATION)
{
};
/// Trait to determine whether a type satisfies the DynamicBuffer requirements.
template <typename T>
struct is_dynamic_buffer
#if defined(GENERATING_DOCUMENTATION)
: integral_constant<bool, automatically_determined>
#else // defined(GENERATING_DOCUMENTATION)
: boost::asio::detail::is_dynamic_buffer<T>
#endif // defined(GENERATING_DOCUMENTATION)
{
};
/// (Deprecated: Use the socket/descriptor wait() and async_wait() member
/// functions.) An implementation of both the ConstBufferSequence and
/// MutableBufferSequence concepts to represent a null buffer sequence.
@ -418,29 +383,45 @@ private:
/*@{*/
/// 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.
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)
/// Get an iterator to the first element in a buffer sequence.
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();
}
/// Get an iterator to the first element in a buffer sequence.
template <typename C>
inline auto buffer_sequence_begin(const C& c) -> decltype(c.begin())
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();
}
@ -448,13 +429,21 @@ inline auto buffer_sequence_begin(const C& c) -> decltype(c.begin())
#else // defined(BOOST_ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION)
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();
}
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();
}
@ -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.
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.
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)
/// Get an iterator to one past the end element in a buffer sequence.
template <typename C>
inline auto buffer_sequence_end(C& c) -> decltype(c.end())
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();
}
/// Get an iterator to one past the end element in a buffer sequence.
template <typename C>
inline auto buffer_sequence_end(const C& c) -> decltype(c.end())
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();
}
@ -501,13 +506,21 @@ inline auto buffer_sequence_end(const C& c) -> decltype(c.end())
#else // defined(BOOST_ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION)
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();
}
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();
}
@ -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:
* @code mutable_buffer(
@ -1534,19 +1547,23 @@ template <typename Elem, typename Traits, typename Allocator>
class dynamic_string_buffer
{
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;
/// 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;
/// Construct a dynamic buffer from a string.
/**
* @param s The string to be used as backing storage for the dynamic buffer.
* Any existing data in the string is treated as the dynamic buffer's input
* sequence. The object stores a reference to the string and the user is
* responsible for ensuring that the string object remains valid until the
* dynamic_string_buffer object is destroyed.
* The object stores a reference to the string and the user is responsible
* for ensuring that the string object remains valid while the
* dynamic_string_buffer object, and copies of the object, are in use.
*
* @b DynamicBuffer_v1: Any existing data in the string is treated as the
* dynamic buffer's input sequence.
*
* @param maximum_size Specifies a maximum size for the buffer, in bytes.
*/
@ -1554,64 +1571,131 @@ public:
std::size_t maximum_size =
(std::numeric_limits<std::size_t>::max)()) BOOST_ASIO_NOEXCEPT
: 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)
{
}
/// @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)
/// Move construct a dynamic buffer.
dynamic_string_buffer(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_)
{
}
#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
{
#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.
/**
* @returns The allowed maximum of the sum of the sizes of the input sequence
* and output sequence.
* @returns The allowed maximum size of the underlying memory.
*/
std::size_t max_size() const BOOST_ASIO_NOEXCEPT
{
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
* sequence and output sequence.
* @returns The current capacity of the underlying string if less than
* max_size(). Otherwise returns max_size().
*/
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
* 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
* or @c basic_string member function that modifies the input sequence or
* output sequence.
* or @c basic_string member function that resizes or erases the string.
*/
const_buffers_type data() const BOOST_ASIO_NOEXCEPT
{
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
/// size.
/// @b DynamicBuffer_v2: Get a sequence of buffers that represents the
/// underlying memory.
/**
* @param pos Position of the first byte to represent in the buffer sequence
*
* @param n The number of bytes to return in the buffer sequence. If the
* underlying memory is shorter, the buffer sequence represents as many bytes
* as are available.
*
* @returns An object of type @c mutable_buffers_type that satisfies
* MutableBufferSequence requirements, representing the basic_string memory.
*
* @note The returned object is invalidated by any @c dynamic_string_buffer
* or @c basic_string member function that resizes or erases the string.
*/
mutable_buffers_type data(std::size_t pos, std::size_t n) 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
* basic_string object as necessary.
@ -1628,18 +1712,22 @@ public:
*/
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");
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);
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
* 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_);
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
* input sequence is consumed and no error is issued.
* @throws std::length_error If <tt>size() + n > max_size()</tt>.
*/
void grow(std::size_t n)
{
if (size() > max_size() || max_size() - size() < n)
{
std::length_error ex("dynamic_string_buffer too long");
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)
{
#if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
if (size_ != (std::numeric_limits<std::size_t>::max)())
{
std::size_t consume_length = (std::min)(n, size_);
string_.erase(0, consume_length);
size_ -= consume_length;
return;
}
#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
string_.erase(0, n);
}
private:
std::basic_string<Elem, Traits, Allocator>& string_;
#if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
std::size_t size_;
#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
const std::size_t max_size_;
};
@ -1685,19 +1818,20 @@ template <typename Elem, typename Allocator>
class dynamic_vector_buffer
{
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;
/// 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;
/// 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.
* Any existing data in the vector is treated as the dynamic buffer's input
* sequence. The object stores a reference to the vector and the user is
* responsible for ensuring that the vector object remains valid until the
* dynamic_vector_buffer object is destroyed.
* The object stores a reference to the vector and the user is responsible
* for ensuring that the vector object remains valid while the
* dynamic_vector_buffer object, and copies of the object, are in use.
*
* @param maximum_size Specifies a maximum size for the buffer, in bytes.
*/
@ -1705,77 +1839,149 @@ public:
std::size_t maximum_size =
(std::numeric_limits<std::size_t>::max)()) BOOST_ASIO_NOEXCEPT
: 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)
{
}
/// @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)
/// Move construct a dynamic buffer.
dynamic_vector_buffer(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_)
{
}
#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
{
#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.
/**
* @returns The allowed maximum of the sum of the sizes of the input sequence
* and output sequence.
* @returns @b DynamicBuffer_v1: The allowed maximum of the sum of the sizes
* of the input sequence and output sequence. @b DynamicBuffer_v2: The allowed
* maximum size of the underlying memory.
*/
std::size_t max_size() const BOOST_ASIO_NOEXCEPT
{
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
* sequence and output sequence.
* @returns @b DynamicBuffer_v1: The current total capacity of the buffer,
* i.e. for both the input sequence and output sequence. @b DynamicBuffer_v2:
* The current capacity of the underlying vector if less than max_size().
* Otherwise returns max_size().
*/
std::size_t capacity() const 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
* ConstBufferSequence requirements, representing the basic_string memory in
* ConstBufferSequence requirements, representing the vector memory in the
* input sequence.
*
* @note The returned object is invalidated by any @c dynamic_vector_buffer
* or @c basic_string member function that modifies the input sequence or
* output sequence.
* or @c vector member function that modifies the input sequence or output
* sequence.
*/
const_buffers_type data() const BOOST_ASIO_NOEXCEPT
{
return const_buffers_type(boost::asio::buffer(vector_, size_));
}
#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
/// Get a list of buffers that represents the output sequence, with the given
/// size.
/// @b DynamicBuffer_v2: Get a sequence of buffers that represents the
/// underlying memory.
/**
* Ensures that the output sequence can accommodate @c n bytes, resizing the
* basic_string object as necessary.
* @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 basic_string memory
* at the start of the output sequence of size @c n.
* MutableBufferSequence requirements, representing the vector memory.
*
* @note The returned object is invalidated by any @c dynamic_vector_buffer
* or @c vector member function that resizes or erases the vector.
*/
mutable_buffers_type data(std::size_t pos, std::size_t n) 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>.
*
* @note The returned object is invalidated by any @c dynamic_vector_buffer
* or @c basic_string member function that modifies the input sequence or
* output sequence.
* or @c vector member function that modifies the input sequence or output
* sequence.
*/
mutable_buffers_type prepare(std::size_t n)
{
@ -1785,12 +1991,16 @@ public:
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);
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
* 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_);
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
* input sequence is consumed and no error is issued.
* @throws std::length_error If <tt>size() + n > max_size()</tt>.
*/
void grow(std::size_t n)
{
if (size() > max_size() || max_size() - size() < n)
{
std::length_error ex("dynamic_vector_buffer too long");
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)
{
#if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
if (size_ != (std::numeric_limits<std::size_t>::max)())
{
std::size_t consume_length = (std::min)(n, size_);
vector_.erase(vector_.begin(), vector_.begin() + consume_length);
size_ -= consume_length;
return;
}
#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
vector_.erase(vector_.begin(), vector_.begin() + (std::min)(size(), n));
}
private:
std::vector<Elem, Allocator>& vector_;
#if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
std::size_t size_;
#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
const std::size_t max_size_;
};
@ -2159,6 +2414,85 @@ inline std::size_t buffer_copy(const MutableBufferSequence& target,
} // namespace asio
} // 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>
#endif // BOOST_ASIO_BUFFER_HPP

View File

@ -2,7 +2,7 @@
// 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
// 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/type_traits.hpp>
#include <boost/asio/error.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/detail/push_options.hpp>
@ -106,22 +105,6 @@ public:
return next_layer_.lowest_layer().get_executor();
}
#if !defined(BOOST_ASIO_NO_DEPRECATED)
/// (Deprecated: Use get_executor().) Get the io_context associated with the
/// object.
boost::asio::io_context& get_io_context()
{
return next_layer_.get_io_context();
}
/// (Deprecated: Use get_executor().) Get the io_context associated with the
/// object.
boost::asio::io_context& get_io_service()
{
return next_layer_.get_io_service();
}
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
/// Close the stream.
void close()
{

View File

@ -2,7 +2,7 @@
// 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
// 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
// ~~~~~~~~~~~~~~~~~~~
//
// 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
// 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/detail/noncopyable.hpp>
#include <boost/asio/error.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/detail/push_options.hpp>
@ -97,22 +96,6 @@ public:
return stream_impl_.lowest_layer().get_executor();
}
#if !defined(BOOST_ASIO_NO_DEPRECATED)
/// (Deprecated: Use get_executor().) Get the io_context associated with the
/// object.
boost::asio::io_context& get_io_context()
{
return stream_impl_.get_io_context();
}
/// (Deprecated: Use get_executor().) Get the io_context associated with the
/// object.
boost::asio::io_context& get_io_service()
{
return stream_impl_.get_io_service();
}
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
/// Close the stream.
void close()
{

View File

@ -2,7 +2,7 @@
// 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
// 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
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
// 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
// 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/type_traits.hpp>
#include <boost/asio/error.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/write.hpp>
#include <boost/asio/detail/push_options.hpp>
@ -106,22 +105,6 @@ public:
return next_layer_.lowest_layer().get_executor();
}
#if !defined(BOOST_ASIO_NO_DEPRECATED)
/// (Deprecated: Use get_executor().) Get the io_context associated with the
/// object.
boost::asio::io_context& get_io_context()
{
return next_layer_.get_io_context();
}
/// (Deprecated: Use get_executor().) Get the io_context associated with the
/// object.
boost::asio::io_context& get_io_service()
{
return next_layer_.get_io_service();
}
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
/// Close the stream.
void close()
{

View File

@ -2,7 +2,7 @@
// 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
// 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
// ~~~~~~~~~~~~~~~~~~~~
//
// 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
// 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
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
// 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
// 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
// ~~~~~~~~~~~
//
// 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
// 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
*
* @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.
*
* @par Example
* @code tcp::resolver r(io_context);
* @code tcp::resolver r(my_context);
* tcp::resolver::query q("host", "service");
* tcp::socket s(io_context);
* tcp::socket s(my_context);
* boost::asio::connect(s, r.resolve(q)); @endcode
*/
template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename EndpointSequence>
typename Protocol::endpoint connect(
basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
template <typename Protocol, typename Executor, typename EndpointSequence>
typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,
const EndpointSequence& endpoints,
typename enable_if<is_endpoint_sequence<
EndpointSequence>::value>::type* = 0);
@ -114,9 +114,9 @@ typename Protocol::endpoint connect(
* default-constructed endpoint.
*
* @par Example
* @code tcp::resolver r(io_context);
* @code tcp::resolver r(my_context);
* tcp::resolver::query q("host", "service");
* tcp::socket s(io_context);
* tcp::socket s(my_context);
* boost::system::error_code ec;
* boost::asio::connect(s, r.resolve(q), ec);
* if (ec)
@ -124,16 +124,15 @@ typename Protocol::endpoint connect(
* // An error occurred.
* } @endcode
*/
template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename EndpointSequence>
typename Protocol::endpoint connect(
basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
template <typename Protocol, typename Executor, typename EndpointSequence>
typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,
const EndpointSequence& endpoints, boost::system::error_code& ec,
typename enable_if<is_endpoint_sequence<
EndpointSequence>::value>::type* = 0);
#if !defined(BOOST_ASIO_NO_DEPRECATED)
/// (Deprecated.) Establishes a socket connection by trying each endpoint in a
/// sequence.
/// (Deprecated: Use range overload.) Establishes a socket connection by trying
/// each endpoint in a sequence.
/**
* This function attempts to connect a socket to one of a sequence of
* endpoints. It does this by repeated calls to the socket's @c connect member
@ -156,12 +155,12 @@ typename Protocol::endpoint connect(
* Iterator represents the end of the sequence. This is a valid assumption for
* iterator types such as @c boost::asio::ip::tcp::resolver::iterator.
*/
template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename Iterator>
Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s, Iterator begin,
template <typename Protocol, typename Executor, typename Iterator>
Iterator connect(basic_socket<Protocol, Executor>& s, Iterator begin,
typename enable_if<!is_endpoint_sequence<Iterator>::value>::type* = 0);
/// (Deprecated.) Establishes a socket connection by trying each endpoint in a
/// sequence.
/// (Deprecated: Use range overload.) Establishes a socket connection by trying
/// each endpoint in a sequence.
/**
* This function attempts to connect a socket to one of a sequence of
* endpoints. It does this by repeated calls to the socket's @c connect member
@ -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 types such as @c boost::asio::ip::tcp::resolver::iterator.
*/
template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename Iterator>
Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
template <typename Protocol, typename Executor, typename Iterator>
Iterator connect(basic_socket<Protocol, Executor>& s,
Iterator begin, boost::system::error_code& ec,
typename enable_if<!is_endpoint_sequence<Iterator>::value>::type* = 0);
#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.
*
* @par Example
* @code tcp::resolver r(io_context);
* @code tcp::resolver r(my_context);
* tcp::resolver::query q("host", "service");
* 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
*/
template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename Iterator>
Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
template <typename Protocol, typename Executor, typename Iterator>
Iterator connect(basic_socket<Protocol, Executor>& s,
Iterator begin, Iterator end);
/// 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.
*
* @par Example
* @code tcp::resolver r(io_context);
* @code tcp::resolver r(my_context);
* tcp::resolver::query q("host", "service");
* tcp::resolver::results_type e = r.resolve(q);
* tcp::socket s(io_context);
* tcp::socket s(my_context);
* boost::system::error_code ec;
* boost::asio::connect(s, e.begin(), e.end(), ec);
* if (ec)
@ -254,8 +253,8 @@ Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
* // An error occurred.
* } @endcode
*/
template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename Iterator>
Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
template <typename Protocol, typename Executor, typename Iterator>
Iterator connect(basic_socket<Protocol, Executor>& s,
Iterator begin, Iterator end, boost::system::error_code& ec);
/// 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
* 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::socket s(io_context);
* tcp::socket s(my_context);
* tcp::endpoint e = boost::asio::connect(s,
* r.resolve(q), my_connect_condition());
* std::cout << "Connected to: " << e << std::endl; @endcode
*/
template <typename Protocol BOOST_ASIO_SVC_TPARAM,
template <typename Protocol, typename Executor,
typename EndpointSequence, typename ConnectCondition>
typename Protocol::endpoint connect(
basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,
const EndpointSequence& endpoints, ConnectCondition connect_condition,
typename enable_if<is_endpoint_sequence<
EndpointSequence>::value>::type* = 0);
@ -362,9 +360,9 @@ typename Protocol::endpoint connect(
* }
* }; @endcode
* 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::socket s(io_context);
* tcp::socket s(my_context);
* boost::system::error_code ec;
* tcp::endpoint e = boost::asio::connect(s,
* r.resolve(q), my_connect_condition(), ec);
@ -377,18 +375,17 @@ typename Protocol::endpoint connect(
* 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 Protocol::endpoint connect(
basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,
const EndpointSequence& endpoints, ConnectCondition connect_condition,
boost::system::error_code& ec,
typename enable_if<is_endpoint_sequence<
EndpointSequence>::value>::type* = 0);
#if !defined(BOOST_ASIO_NO_DEPRECATED)
/// (Deprecated.) Establishes a socket connection by trying each endpoint in a
/// sequence.
/// (Deprecated: Use range overload.) Establishes a socket connection by trying
/// each endpoint in a sequence.
/**
* This function attempts to connect a socket to one of a sequence of
* endpoints. It does this by repeated calls to the socket's @c connect member
@ -422,14 +419,14 @@ typename Protocol::endpoint connect(
* Iterator represents the end of the sequence. This is a valid assumption for
* iterator types such as @c boost::asio::ip::tcp::resolver::iterator.
*/
template <typename Protocol BOOST_ASIO_SVC_TPARAM,
template <typename Protocol, typename Executor,
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,
typename enable_if<!is_endpoint_sequence<Iterator>::value>::type* = 0);
/// (Deprecated.) Establishes a socket connection by trying each endpoint in a
/// sequence.
/// (Deprecated: Use range overload.) Establishes a socket connection by trying
/// each endpoint in a sequence.
/**
* This function attempts to connect a socket to one of a sequence of
* endpoints. It does this by repeated calls to the socket's @c connect member
@ -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 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>
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,
typename enable_if<!is_endpoint_sequence<Iterator>::value>::type* = 0);
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
@ -516,17 +513,17 @@ Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s, Iterator begin,
* }
* }; @endcode
* 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::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(
* s, e.begin(), e.end(), my_connect_condition());
* 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>
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);
/// 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
* 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::results_type e = r.resolve(q);
* tcp::socket s(io_context);
* tcp::socket s(my_context);
* boost::system::error_code ec;
* tcp::resolver::results_type::iterator i = boost::asio::connect(
* 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;
* } @endcode
*/
template <typename Protocol BOOST_ASIO_SVC_TPARAM,
template <typename Protocol, typename Executor,
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,
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
*
* @brief Asynchronously establishes a socket connection by trying each
* endpoint in a sequence.
* @brief The @c async_connect function is a composed asynchronous operation
* 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
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* boost::asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post().
*
* @par Example
* @code tcp::resolver r(io_context);
* @code tcp::resolver r(my_context);
* 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
*/
template <typename Protocol BOOST_ASIO_SVC_TPARAM,
template <typename Protocol, typename Executor,
typename EndpointSequence, typename RangeConnectHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(RangeConnectHandler,
void (boost::system::error_code, typename Protocol::endpoint))
async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
async_connect(basic_socket<Protocol, Executor>& s,
const EndpointSequence& endpoints,
BOOST_ASIO_MOVE_ARG(RangeConnectHandler) handler,
typename enable_if<is_endpoint_sequence<
EndpointSequence>::value>::type* = 0);
#if !defined(BOOST_ASIO_NO_DEPRECATED)
/// (Deprecated.) Asynchronously establishes a socket connection by trying each
/// endpoint in a sequence.
/// (Deprecated: Use range overload.) Asynchronously establishes a socket
/// connection by trying each endpoint in a sequence.
/**
* This function attempts to connect a socket to one of a sequence of
* endpoints. It does this by repeated calls to the socket's @c async_connect
@ -707,20 +704,20 @@ async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
* Iterator iterator
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* boost::asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post().
*
* @note This overload assumes that a default constructed object of type @c
* Iterator represents the end of the sequence. This is a valid assumption for
* iterator types such as @c boost::asio::ip::tcp::resolver::iterator.
*/
template <typename Protocol BOOST_ASIO_SVC_TPARAM,
template <typename Protocol, typename Executor,
typename Iterator, typename IteratorConnectHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler,
void (boost::system::error_code, Iterator))
async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
Iterator begin, BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler,
async_connect(basic_socket<Protocol, Executor>& s, Iterator begin,
BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler,
typename enable_if<!is_endpoint_sequence<Iterator>::value>::type* = 0);
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
@ -753,13 +750,13 @@ async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
* Iterator iterator
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* boost::asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post().
*
* @par Example
* @code std::vector<tcp::endpoint> endpoints = ...;
* tcp::socket s(io_context);
* tcp::socket s(my_context);
* boost::asio::async_connect(s,
* endpoints.begin(), endpoints.end(),
* connect_handler);
@ -773,12 +770,11 @@ async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
* // ...
* } @endcode
*/
template <typename Protocol BOOST_ASIO_SVC_TPARAM,
template <typename Protocol, typename Executor,
typename Iterator, typename IteratorConnectHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler,
void (boost::system::error_code, Iterator))
async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
Iterator begin, Iterator end,
async_connect(basic_socket<Protocol, Executor>& s, Iterator begin, Iterator end,
BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler);
/// 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
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* boost::asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post().
*
* @par Example
* 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
* 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::socket s(io_context);
* tcp::socket s(my_context);
*
* // ...
*
@ -876,19 +872,19 @@ async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
* }
* } @endcode
*/
template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename EndpointSequence,
template <typename Protocol, typename Executor, typename EndpointSequence,
typename ConnectCondition, typename RangeConnectHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(RangeConnectHandler,
void (boost::system::error_code, typename Protocol::endpoint))
async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
async_connect(basic_socket<Protocol, Executor>& s,
const EndpointSequence& endpoints, ConnectCondition connect_condition,
BOOST_ASIO_MOVE_ARG(RangeConnectHandler) handler,
typename enable_if<is_endpoint_sequence<
EndpointSequence>::value>::type* = 0);
#if !defined(BOOST_ASIO_NO_DEPRECATED)
/// (Deprecated.) Asynchronously establishes a socket connection by trying each
/// endpoint in a sequence.
/// (Deprecated: Use range overload.) Asynchronously establishes a socket
/// connection by trying each endpoint in a sequence.
/**
* This function attempts to connect a socket to one of a sequence of
* endpoints. It does this by repeated calls to the socket's @c async_connect
@ -925,19 +921,19 @@ async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
* Iterator iterator
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* boost::asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post().
*
* @note This overload assumes that a default constructed object of type @c
* Iterator represents the end of the sequence. This is a valid assumption for
* iterator types such as @c boost::asio::ip::tcp::resolver::iterator.
*/
template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename Iterator,
template <typename Protocol, typename Executor, typename Iterator,
typename ConnectCondition, typename IteratorConnectHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler,
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,
BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler,
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
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* boost::asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using boost::asio::post().
*
* @par Example
* 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
* 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::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
*/
template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename Iterator,
template <typename Protocol, typename Executor, typename Iterator,
typename ConnectCondition, typename IteratorConnectHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler,
void (boost::system::error_code, Iterator))
async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
Iterator begin, Iterator end, ConnectCondition connect_condition,
async_connect(basic_socket<Protocol, Executor>& s, Iterator begin,
Iterator end, ConnectCondition connect_condition,
BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler);
/*@}*/

View File

@ -2,7 +2,7 @@
// 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
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -206,7 +206,7 @@ class coroutine_ref;
* {
* do
* {
* socket_.reset(new tcp::socket(io_context_));
* socket_.reset(new tcp::socket(my_context_));
* yield acceptor->async_accept(*socket_, *this);
* fork server(*this)();
* } while (is_parent());
@ -228,7 +228,7 @@ class coroutine_ref;
* Note that @c fork doesn't do the actual forking by itself. It is the
* application's responsibility to create a clone of the coroutine and call it.
* The clone can be called immediately, as above, or scheduled for delayed
* execution using something like io_context::post().
* execution using something like boost::asio::post().
*
* @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
// ~~~~~~~~~~~~~~~~~~
//
// 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
// 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
// ~~~~~~~~~
//
// 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
// 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
* 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:
*
* @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
* 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:
*
* @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
// ~~~~~~~~~~~~~~~~
//
// 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
// 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
// ~~~~~~~~~~~~~~~~~~~~
//
// 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
// 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
// ~~~~~~~~~~~~~~~~~
//
// 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
// 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
// ~~~~~~~~~~~~~~~~~~~~~~~
//
// 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
// 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
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// 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
// 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
{
protected:
explicit base_from_completion_cond(CompletionCondition completion_condition)
: completion_condition_(completion_condition)
explicit base_from_completion_cond(CompletionCondition& completion_condition)
: completion_condition_(
BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition))
{
}

View File

@ -2,7 +2,7 @@
// 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
// 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
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// 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
// 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
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// 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
// 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
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// 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
// 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
// ~~~~~~~~~~~~~~~~~~~~~
//
// 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
// 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
// ~~~~~~~~~~~~~~~~~
//
// 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
// 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
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// 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
// 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
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// 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
// 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
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// 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
// 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
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// 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
// 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
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// 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
// 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
// ~~~~~~~~~~~~~~~~~
//
// 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
// 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
# endif // defined(BOOST_ASIO_HAS_BOOST_CONFIG) && defined(BOOST_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.
#if defined(__clang__)
@ -111,15 +108,26 @@
# define BOOST_ASIO_HAS_MOVE 1
# endif // (_MSC_VER >= 1700)
# 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_HAS_MOVE)
// 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
// references and perfect forwarding.
// * BOOST_ASIO_MOVE_ARG,
// * 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)
# define BOOST_ASIO_MOVE_ARG(type) type&&
# 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_CAST2(type1, type2) static_cast<type1, type2&&>
#endif // defined(BOOST_ASIO_HAS_MOVE) && !defined(BOOST_ASIO_MOVE_CAST)
@ -145,6 +153,7 @@
# else
# define BOOST_ASIO_MOVE_ARG(type) type
# endif
# define BOOST_ASIO_NONDEDUCED_MOVE_ARG(type) const type&
# define BOOST_ASIO_MOVE_CAST(type) static_cast<const type&>
# define BOOST_ASIO_MOVE_CAST2(type1, type2) static_cast<const type1, type2&>
#endif // !defined(BOOST_ASIO_MOVE_CAST)
@ -229,7 +238,7 @@
// Support noexcept on compilers known to allow it.
#if !defined(BOOST_ASIO_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_OR_NOTHROW BOOST_NOEXCEPT_OR_NOTHROW
# elif defined(__clang__)
@ -275,9 +284,9 @@
# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4)
# endif // defined(__GNUC__)
# if defined(BOOST_ASIO_MSVC)
# if (_MSC_VER >= 1700)
# if (_MSC_VER >= 1800)
# define BOOST_ASIO_HAS_DECLTYPE 1
# endif // (_MSC_VER >= 1700)
# endif // (_MSC_VER >= 1800)
# endif // defined(BOOST_ASIO_MSVC)
# endif // !defined(BOOST_ASIO_DISABLE_DECLTYPE)
#endif // !defined(BOOST_ASIO_HAS_DECLTYPE)
@ -332,7 +341,7 @@
// Compliant C++11 compilers put noexcept specifiers on error_category members.
#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
# elif defined(__clang__)
# if __has_feature(__cxx_noexcept__)
@ -441,7 +450,13 @@
# if __has_include(<atomic>)
# define BOOST_ASIO_HAS_STD_ATOMIC 1
# 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__)
# if defined(__GNUC__)
# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)
@ -493,9 +508,9 @@
// Boost support for chrono.
#if !defined(BOOST_ASIO_HAS_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
# 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_HAS_BOOST_CHRONO)
@ -759,9 +774,7 @@
# if defined(__GNUC__)
# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)
# if defined(__GXX_EXPERIMENTAL_CXX0X__)
# if defined(_GLIBCXX_HAS_GTHREADS)
# define BOOST_ASIO_HAS_STD_FUTURE 1
# endif // defined(_GLIBCXX_HAS_GTHREADS)
# endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)
# endif // defined(__GNUC__)
@ -777,23 +790,29 @@
#if !defined(BOOST_ASIO_HAS_STD_STRING_VIEW)
# if !defined(BOOST_ASIO_DISABLE_STD_STRING_VIEW)
# if defined(__clang__)
# if defined(BOOST_ASIO_HAS_CLANG_LIBCXX)
# if (__cplusplus >= 201402)
# if __has_include(<string_view>)
# define BOOST_ASIO_HAS_STD_STRING_VIEW 1
# endif // __has_include(<string_view>)
# endif // (__cplusplus >= 201402)
# 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(__clang__)
# if defined(__GNUC__)
# endif // defined(BOOST_ASIO_HAS_CLANG_LIBCXX)
# elif defined(__GNUC__)
# if (__GNUC__ >= 7)
# if (__cplusplus >= 201703)
# define BOOST_ASIO_HAS_STD_STRING_VIEW 1
# endif // (__cplusplus >= 201703)
# endif // (__GNUC__ >= 7)
# endif // defined(__GNUC__)
# if defined(BOOST_ASIO_MSVC)
# if (_MSC_VER >= 1910 && _HAS_CXX17)
# define BOOST_ASIO_HAS_STD_STRING_VIEW
# endif // (_MSC_VER >= 1910 && _HAS_CXX17)
# elif defined(BOOST_ASIO_MSVC)
# if (_MSC_VER >= 1910 && _MSVC_LANG >= 201703)
# define BOOST_ASIO_HAS_STD_STRING_VIEW 1
# endif // (_MSC_VER >= 1910 && _MSVC_LANG >= 201703)
# endif // defined(BOOST_ASIO_MSVC)
# endif // !defined(BOOST_ASIO_DISABLE_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_DISABLE_STD_EXPERIMENTAL_STRING_VIEW)
# if defined(__clang__)
# if defined(BOOST_ASIO_HAS_CLANG_LIBCXX)
# if (_LIBCPP_VERSION < 7000)
# 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 // (_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__)
# if defined(__GNUC__)
# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)) || (__GNUC__ > 4)
@ -851,9 +880,9 @@
#if !defined(BOOST_ASIO_HAS_STD_INVOKE_RESULT)
# if !defined(BOOST_ASIO_DISABLE_STD_INVOKE_RESULT)
# 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
# endif // (_MSC_VER >= 1910 && _HAS_CXX17)
# endif // (_MSC_VER >= 1911 && _MSVC_LANG >= 201703)
# endif // defined(BOOST_ASIO_MSVC)
# endif // !defined(BOOST_ASIO_DISABLE_STD_INVOKE_RESULT)
#endif // !defined(BOOST_ASIO_HAS_STD_INVOKE_RESULT)
@ -903,15 +932,15 @@
# if defined(_MSC_VER) || defined(__BORLANDC__)
# pragma message( \
"Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately. For example:\n"\
"- add -D_WIN32_WINNT=0x0501 to the compiler command line; or\n"\
"- add _WIN32_WINNT=0x0501 to your project's Preprocessor Definitions.\n"\
"Assuming _WIN32_WINNT=0x0501 (i.e. Windows XP target).")
"- add -D_WIN32_WINNT=0x0601 to the compiler command line; or\n"\
"- add _WIN32_WINNT=0x0601 to your project's Preprocessor Definitions.\n"\
"Assuming _WIN32_WINNT=0x0601 (i.e. Windows 7 target).")
# else // defined(_MSC_VER) || defined(__BORLANDC__)
# warning Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately.
# warning For example, add -D_WIN32_WINNT=0x0501 to the compiler command line.
# warning Assuming _WIN32_WINNT=0x0501 (i.e. Windows XP target).
# warning For example, add -D_WIN32_WINNT=0x0601 to the compiler command line.
# warning Assuming _WIN32_WINNT=0x0601 (i.e. Windows 7 target).
# endif // defined(_MSC_VER) || defined(__BORLANDC__)
# define _WIN32_WINNT 0x0501
# define _WIN32_WINNT 0x0601
# endif // !defined(_WIN32_WINNT) && !defined(_WIN32_WINDOWS)
# if defined(_MSC_VER)
# if defined(_WIN32) && !defined(WIN32)
@ -982,7 +1011,8 @@
|| defined(__FreeBSD__) \
|| defined(__NetBSD__) \
|| defined(__OpenBSD__) \
|| defined(__linux__)
|| defined(__linux__) \
|| defined(__HAIKU__)
# define BOOST_ASIO_HAS_UNISTD_H 1
# endif
# endif // !defined(BOOST_ASIO_HAS_BOOST_CONFIG)
@ -1202,6 +1232,8 @@
# define BOOST_ASIO_HAS_THREADS 1
# elif defined(__APPLE__)
# define BOOST_ASIO_HAS_THREADS 1
# elif defined(__HAIKU__)
# define BOOST_ASIO_HAS_THREADS 1
# elif defined(_POSIX_THREADS) && (_POSIX_THREADS + 0 >= 0)
# define BOOST_ASIO_HAS_THREADS 1
# elif defined(_PTHREADS)
@ -1217,6 +1249,8 @@
# define BOOST_ASIO_HAS_PTHREADS 1
# elif defined(_POSIX_THREADS) && (_POSIX_THREADS + 0 >= 0)
# 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_THREADS)
#endif // !defined(BOOST_ASIO_HAS_PTHREADS)
@ -1346,33 +1380,6 @@
// || (defined(__MACH__) && defined(__APPLE__))
#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.
#if defined(BOOST_ASIO_NO_DEPRECATED)
# define BOOST_ASIO_SYNC_OP_VOID void
@ -1424,11 +1431,11 @@
# endif // defined(BOOST_ASIO_MSVC)
# endif // !defined(BOOST_ASIO_DISABLE_CO_AWAIT)
# if defined(__clang__)
# if (__cpp_coroutines >= 201703)
# if (__cplusplus >= 201703) && (__cpp_coroutines >= 201703)
# if __has_include(<experimental/coroutine>)
# define BOOST_ASIO_HAS_CO_AWAIT 1
# endif // __has_include(<experimental/coroutine>)
# endif // (__cpp_coroutines >= 201703)
# endif // (__cplusplus >= 201703) && (__cpp_coroutines >= 201703)
# endif // defined(__clang__)
#endif // !defined(BOOST_ASIO_HAS_CO_AWAIT)

View File

@ -2,7 +2,7 @@
// 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
// 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
// ~~~~~~~~~~~~~~~~~~
//
// 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
// 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
// ~~~~~~~~~~~~~~~~~~
//
// 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
// 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
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
// 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
// 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
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// 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
// 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 <cstddef>
#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/fenced_block.hpp>
#include <boost/asio/detail/memory.hpp>
@ -44,7 +44,7 @@ namespace detail {
template <typename Time_Traits>
class deadline_timer_service
: public service_base<deadline_timer_service<Time_Traits> >
: public execution_context_service_base<deadline_timer_service<Time_Traits> >
{
public:
// The time type.
@ -64,9 +64,10 @@ public:
};
// Constructor.
deadline_timer_service(boost::asio::io_context& io_context)
: service_base<deadline_timer_service<Time_Traits> >(io_context),
scheduler_(boost::asio::use_service<timer_scheduler>(io_context))
deadline_timer_service(execution_context& context)
: execution_context_service_base<
deadline_timer_service<Time_Traits> >(context),
scheduler_(boost::asio::use_service<timer_scheduler>(context))
{
scheduler_.init_task();
scheduler_.add_timer_queue(timer_queue_);
@ -226,14 +227,15 @@ public:
}
// Start an asynchronous wait on the timer.
template <typename Handler>
void async_wait(implementation_type& impl, Handler& handler)
template <typename Handler, typename IoExecutor>
void async_wait(implementation_type& impl,
Handler& handler, const IoExecutor& io_ex)
{
// 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),
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;

View File

@ -2,7 +2,7 @@
// 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
// 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
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
// 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
// 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
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// 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
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -67,20 +67,21 @@ private:
MutableBufferSequence buffers_;
};
template <typename MutableBufferSequence, typename Handler>
template <typename MutableBufferSequence, typename Handler, typename IoExecutor>
class descriptor_read_op
: public descriptor_read_op_base<MutableBufferSequence>
{
public:
BOOST_ASIO_DEFINE_HANDLER_PTR(descriptor_read_op);
descriptor_read_op(int descriptor,
const MutableBufferSequence& buffers, Handler& handler)
descriptor_read_op(int descriptor, const MutableBufferSequence& buffers,
Handler& handler, const IoExecutor& io_ex)
: descriptor_read_op_base<MutableBufferSequence>(
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,
@ -90,7 +91,7 @@ public:
// Take ownership of the handler object.
descriptor_read_op* o(static_cast<descriptor_read_op*>(base));
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));
@ -117,6 +118,7 @@ public:
private:
Handler handler_;
IoExecutor io_executor_;
};
} // namespace detail

View File

@ -2,7 +2,7 @@
// 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
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -67,20 +67,21 @@ private:
ConstBufferSequence buffers_;
};
template <typename ConstBufferSequence, typename Handler>
template <typename ConstBufferSequence, typename Handler, typename IoExecutor>
class descriptor_write_op
: public descriptor_write_op_base<ConstBufferSequence>
{
public:
BOOST_ASIO_DEFINE_HANDLER_PTR(descriptor_write_op);
descriptor_write_op(int descriptor,
const ConstBufferSequence& buffers, Handler& handler)
descriptor_write_op(int descriptor, const ConstBufferSequence& buffers,
Handler& handler, const IoExecutor& io_ex)
: descriptor_write_op_base<ConstBufferSequence>(
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,
@ -90,7 +91,7 @@ public:
// Take ownership of the handler object.
descriptor_write_op* o(static_cast<descriptor_write_op*>(base));
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));
@ -117,6 +118,7 @@ public:
private:
Handler handler_;
IoExecutor io_executor_;
};
} // namespace detail

View File

@ -2,7 +2,7 @@
// 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
// 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
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
// 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
// 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
// ~~~~~~~~~~~~~~~~
//
// 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
// 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
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// 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)
//
// 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
// ~~~~~~~~~~~~~~~~~~~~~~
//
// 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
// 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
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
// 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
// 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
// ~~~~~~~~~~~~~~~~~~~~~~~
//
// 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
// 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
// ~~~~~~~~~~~~~~~~~~~~~
//
// 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
// 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
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// 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
// 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
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// 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
// 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
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// 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
// 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
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// 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
// 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
// ~~~~~~~~~~~~~~~~~
//
// 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
// 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
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// 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
// 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 \
{ \
const Alloc* a; \
@ -207,9 +207,10 @@ struct get_hook_allocator<Handler, std::allocator<T> >
static op* allocate(const Alloc& a) \
{ \
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::detail::get_recycling_allocator<Alloc>::get(a)); \
::boost::asio::detail::get_recycling_allocator< \
Alloc, purpose>::get(a)); \
return a1.allocate(1); \
} \
void reset() \
@ -222,9 +223,10 @@ struct get_hook_allocator<Handler, std::allocator<T> >
if (v) \
{ \
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::detail::get_recycling_allocator<Alloc>::get(*a)); \
::boost::asio::detail::get_recycling_allocator< \
Alloc, purpose>::get(*a)); \
a1.deallocate(static_cast<op*>(v), 1); \
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>
#endif // BOOST_ASIO_DETAIL_HANDLER_ALLOC_HELPERS_HPP

View File

@ -2,7 +2,7 @@
// 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
// 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
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// 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
// 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
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// 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
// 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
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// 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
// 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
// ~~~~~~~~~~~~~~~~~~~~~~~
//
// 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
// 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
// through either the new executors framework or the old invocaton hook. The
// primary template uses the new executors framework.
template <typename Handler, typename Executor
= typename associated_executor<Handler>::type>
template <typename Handler,
typename IoExecutor = system_executor, typename HandlerExecutor
= typename associated_executor<Handler, IoExecutor>::type>
class handler_work
{
public:
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
{
Executor ex(associated_executor<Handler>::get(handler));
HandlerExecutor ex(boost::asio::get_associated_executor(handler));
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()
{
io_executor_.on_work_finished();
executor_.on_work_finished();
}
@ -53,7 +70,7 @@ public:
void complete(Function& function, Handler& handler)
{
executor_.dispatch(BOOST_ASIO_MOVE_CAST(Function)(function),
associated_allocator<Handler>::get(handler));
boost::asio::get_associated_allocator(handler));
}
private:
@ -61,7 +78,8 @@ private:
handler_work(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.
@ -69,7 +87,7 @@ private:
// system_executor will dispatch through the hook anyway. However, by doing
// this we avoid an extra copy of the handler.
template <typename Handler>
class handler_work<Handler, system_executor>
class handler_work<Handler, system_executor, system_executor>
{
public:
explicit handler_work(Handler&) BOOST_ASIO_NOEXCEPT {}

View File

@ -2,7 +2,7 @@
// 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
// 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
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// 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
// 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
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// 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
// 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
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// 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
// 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
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// 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
// 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
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// 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
// 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
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// 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
// 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
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// 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)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying

View File

@ -2,7 +2,7 @@
// 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
// 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
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// 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)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying

View File

@ -2,7 +2,7 @@
// 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)
//
// 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