Boost C++ Libraries of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

This is the documentation for a snapshot of the master branch, built from commit c0b072b354.


Base class to assist writing composed operations.


Defined in header <boost/beast/core/async_base.hpp>

    class Handler,
    class Executor1,
    class Allocator = std::allocator<void>>
class async_base




The type of allocator associated with this object.


The type of executor associated with this object.

Member Functions



async_base [constructor]


Move Constructor.


Invoke the final completion handler, maybe using post.


Invoke the final completion handler.


Returns the allocator associated with this object.


Returns the executor associated with this object.


Returns the handler associated with this object.



Returns ownership of the handler associated with this object.

~async_base [destructor]


A function object submitted to intermediate initiating functions during a composed operation may derive from this type to inherit all of the boilerplate to forward the executor, allocator, and legacy customization points associated with the completion handler invoked at the end of the composed operation. The composed operation must be typical; that is, associated with one executor of an I/O object, and invoking a caller-provided completion handler when the operation is finished. Classes derived from async_base will acquire these properties:


The following code demonstrates how async_base may be be used to assist authoring an asynchronous initiating function, by providing all of the boilerplate to manage the final completion handler in a way that maintains the allocator and executor associations:

// Asynchronously read into a buffer until the buffer is full, or an error occurs
template<class AsyncReadStream, class ReadHandler>
typename net::async_result<ReadHandler, void(error_code, std::size_t)>::return_type
async_read(AsyncReadStream& stream, net::mutable_buffer buffer, ReadHandler&& handler)
    using handler_type = BOOST_ASIO_HANDLER_TYPE(ReadHandler, void(error_code, std::size_t));
    using base_type = async_base<handler_type, typename AsyncReadStream::executor_type>;

    struct op : base_type
        AsyncReadStream& stream_;
        net::mutable_buffer buffer_;
        std::size_t total_bytes_transferred_;

            AsyncReadStream& stream,
            net::mutable_buffer buffer,
            handler_type& handler)
            : base_type(std::move(handler), stream.get_executor())
            , stream_(stream)
            , buffer_(buffer)
            , total_bytes_transferred_(0)
            (*this)({}, 0, false); // start the operation

        void operator()(error_code ec, std::size_t bytes_transferred, bool is_continuation = true)
            // Adjust the count of bytes and advance our buffer
            total_bytes_transferred_ += bytes_transferred;
            buffer_ = buffer_ + bytes_transferred;

            // Keep reading until buffer is full or an error occurs
            if(! ec && buffer_.size() > 0)
                return stream_.async_read_some(buffer_, std::move(*this));

            // Call the completion handler with the result. If `is_continuation` is
            // false, which happens on the first time through this function, then
            // `net::post` will be used to call the completion handler, otherwise
            // the completion handler will be invoked directly.

            this->complete(is_continuation, ec, total_bytes_transferred_);

    net::async_completion<ReadHandler, void(error_code, std::size_t)> init{handler};
    op(stream, buffer, init.completion_handler);
    return init.result.get();

Data members of composed operations implemented as completion handlers do not have stable addresses, as the composed operation object is move constructed upon each call to an initiating function. For most operations this is not a problem. For complex operations requiring stable temporary storage, the class stable_async_base is provided which offers additional functionality:

Temporary Storage Example

The following example demonstrates how a composed operation may store a temporary object.

Template Parameters




The type of the completion handler to store. This type must meet the requirements of CompletionHandler.


The type of the executor used when the handler has no associated executor. An instance of this type must be provided upon construction. The implementation will maintain an executor work guard and a copy of this instance.


The allocator type to use if the handler does not have an associated allocator. If this parameter is omitted, then std::allocator<void> will be used. If the specified allocator is not default constructible, an instance of the type must be provided upon construction.

See Also