This change adds a new set of type requirements for dynamic buffers,
DynamicBuffer_v2, which supports copy construction. These new type
requirements enable dynamic buffers to be used as arguments to
user-defined composed operations, where the same dynamic buffer object
is used repeatedly for multiple underlying operations. For example:
template <typename DynamicBuffer>
void echo_line(tcp::socket& sock, DynamicBuffer buf)
{
n = boost::asio::read_until(sock, buf, '\n');
boost::asio::write(sock, buf, boost::asio::transfer_exactly(n));
}
The original DynamicBuffer type requirements have been renamed to
DynamicBuffer_v1.
New type traits is_dynamic_buffer_v1 and is_dynamic_buffer_v2 have been
added to test for conformance to DynamicBuffer_v1 and DynamicBuffer_v2
respectively. The existing is_dynamic_buffer trait has been retained and
delegates to is_dynamic_buffer_v1, unless BOOST_ASIO_NO_DYNAMIC_BUFFER_V1
is defined, in which case it delegates to is_dynamic_buffer_v2.
The dynamic_string_buffer and dynamic_vector buffer classes conform to
both DynamicBuffer_v1 and DynamicBuffer_v2 requirements.
When BOOST_ASIO_NO_DYNAMIC_BUFFER_V1 is defined, all support for
DynamicBuffer_v1 types and functions is #ifdef-ed out. Support for using
basic_streambuf with the read, async_read, read_until, async_read_until,
write, and async_write functions is also disabled as a consequence.
This change should have no impact on existing source code that simply
uses dynamic buffers in conjunction with asio's composed operations,
such as:
string data;
// ...
size_t n = boost::asio::read_until(my_socket
boost::asio::dynamic_buffer(data, MY_MAX),
'\n');
This change addresses an issue where a call to buffer_sequence_begin or
buffer_sequence_end could trigger an implicit conversion to const_buffer
or mutable_buffer. Whenever this implicit conversion occurred, the
return value of buffer_sequence_begin/end would point to a temporary
object.
The awaitable<>, co_spawn(), this_coro, detached, and redirect_error
facilities have been moved from the asio::experimental namespace to
namespace asio. As part of this change, the this_coro::token() awaitable
has been superseded by the asio::use_awaitable completion token.
Please note that the use_awaitable and redirect_error completion tokens
work only with asynchronous operations that use the new form of
async_result with member function initiate(). Furthermore, when using
use_awaitable, please be aware that the asynchronous operation is not
initiated until co_await is applied to the awaitable<>.
The `async_result` template now supports a new form:
template <typename CompletionToken, typename Signature>
struct async_result
{
typedef /* ... */ return_type;
template <typename Initiation,
typename RawCompletionToken,
typename... Args>
static return_type initiate(
Initiation&& initiation,
RawCompletionToken&& token,
Args&&... args);
};
The `initiate()` function must:
* Transform the token into a completion handler object `handler`.
* Cause the invocation of the function object `initiation` as if
by calling:
std::forward<Initiation>(initiation)(
std::move(handler),
std::forward<Args>(args)...);
The invocation of `initiation` may be deferred (e.g. lazily evaluated),
in which case `initiation` and `args` must be decay-copied and moved
as required.
A helper function template `async_initiate` has also been added as a
wrapper for the invocation of `async_result<>::initiate`. For backward
compatibility, this function supports both the old and new async_result
forms.
N.B. The Windows-specific tick_count_timer example has been removed as
it has been superseded by timers based on the standard steady_clock.
It's also not clear how to map a wrapping time source to the standard
chrono concepts.