Skip to content

Commit

Permalink
Add any_completion_handler to the overview.
Browse files Browse the repository at this point in the history
  • Loading branch information
chriskohlhoff committed Apr 5, 2023
1 parent 7aac2ff commit fa9e66e
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 0 deletions.
3 changes: 3 additions & 0 deletions asio/src/doc/overview.qbk
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
* [link asio.overview.composition.parallel_group Co-ordinating Parallel Operations (experimental)]
* [link asio.overview.composition.compose Compositions as Asynchronous Operations]
* [link asio.overview.composition.token_adapters Completion Token Adapters]
* [link asio.overview.composition.type_erasure Type Erasure, Separate Compilation and Virtual Functions]
* [link asio.overview.networking Networking]
* [link asio.overview.networking.protocols TCP, UDP and ICMP]
* [link asio.overview.networking.other_protocols Support for Other Protocols]
Expand Down Expand Up @@ -117,6 +118,7 @@
* [link asio.overview.composition.parallel_group Co-ordinating Parallel Operations (experimental)]
* [link asio.overview.composition.compose Compositions as Asynchronous Operations]
* [link asio.overview.composition.token_adapters Completion Token Adapters]
* [link asio.overview.composition.type_erasure Type Erasure, Separate Compilation and Virtual Functions]

[include overview/coroutine.qbk]
[include overview/spawn.qbk]
Expand All @@ -128,6 +130,7 @@
[include overview/parallel_group.qbk]
[include overview/compose.qbk]
[include overview/token_adapters.qbk]
[include overview/type_erasure.qbk]

[endsect]

Expand Down
91 changes: 91 additions & 0 deletions asio/src/doc/overview/type_erasure.qbk
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
[/
/ Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]

[section:type_erasure Type Erasure, Separate Compilation and Virtual Functions]

The `any_completion_handler<>` class template can be used to type-erase
completion handlers. This template stores a completion handler in a
runtime-polymorphic wrapper, and forwards the function call operator,
associated executor, associated allocator, and associated cancellation slot to
the target handler.

One use case is to enable separate compilation of asynchronous operation
implementations. For example, we can declare our implementation function in a
header file, and provide a thin asynchronous operation wrapper:

void async_sleep_impl(
asio::any_completion_handler<void(asio::error_code)> handler,
asio::any_io_executor ex, std::chrono::nanoseconds duration);

template <typename CompletionToken>
inline auto async_sleep(asio::any_io_executor ex,
std::chrono::nanoseconds duration, CompletionToken&& token)
{
return asio::async_initiate<
CompletionToken, void(asio::error_code)>(
async_sleep_impl, token, std::move(ex), duration);
}

By wrapping a call to `async_initiate`, the `async_sleep` template function
adds full support for completion tokens. The definition of `async_sleep_impl`
is then put into a separately compiled source file:

void async_sleep_impl(
asio::any_completion_handler<void(asio::error_code)> handler,
asio::any_io_executor ex, std::chrono::nanoseconds duration)
{
auto timer = std::make_shared<asio::steady_timer>(ex, duration);
timer->async_wait(asio::consign(std::move(handler), timer));
}

Another use for `any_completion_handler<>` is to vary the implementation behind
an asynchronous operation at runtime, by using virtual functions:

class line_reader
{
public:
// ...

template <typename CompletionToken>
auto async_read_line(std::string prompt, CompletionToken&& token)
{
return asio::async_initiate<
CompletionToken, void(asio::error_code, std::string)>(
[](auto handler, line_reader* self, std::string prompt)
{
self->async_read_line_impl(std::move(prompt), std::move(handler));
}, token, this, prompt);
}

private:
virtual void async_read_line_impl(std::string prompt,
asio::any_completion_handler<
void(asio::error_code, std::string)> handler) = 0;
};

A derived class provides the implementation of the operation:

class stdin_line_reader : public line_reader
{
private:
// ...

void async_read_line_impl(std::string prompt,
asio::any_completion_handler<
void(asio::error_code, std::string)> handler) override
{
// ...
}
};

[heading See Also]

[link asio.reference.any_completion_handler any_completion_handler],
[link asio.examples.cpp11_examples.type_erasure type erasure examples (C++11)],
[link asio.examples.cpp20_examples.type_erasure type erasure examples (C++20)].

[endsect]

0 comments on commit fa9e66e

Please sign in to comment.