boost::capy::WriteStream

Requires write_some to return an IoAwaitable decomposing to an error code and a size.

Synopsis

template<typename T>
concept WriteStream = requires(T& stream, const_buffer_archetype buffers)
    {
        { stream.write_some(buffers) } ‐> IoAwaitable;
        requires awaitable_decomposes_to<
            decltype(stream.write_some(buffers)),
            std::error_code, std::size_t>;
    };

Description

A type satisfies WriteStream if it provides a write_some member function template that accepts any ConstBufferSequence and await‐returns (error_code, std::size_t).

Syntactic Requirements

  • T must provide a write_some member function template accepting any ConstBufferSequence.

  • The return type of write_some must satisfy IoAwaitable.

  • The awaitable's result must decompose to (error_code,std::size_t) via structured bindings.

Semantic Requirements

Attempts to write up to buffer_size( buffers ) bytes from the buffer sequence to the stream.

If buffer_size( buffers ) > 0:

  • If !ec, then n >= 1 && n <= buffer_size( buffers ). n bytes were written from the buffer sequence.

  • If ec, then n >= 0 && n < buffer_size( buffers ). n is the number of bytes written before the I/O contingency arose.

Equivalently, n == buffer_size( buffers ) implies !ec. A completion that writes the entire buffer sequence is a success, even when the underlying operation also signals a contingency. That contingency is reported on a subsequent write. This lets generic composition algorithms such as when_all and when_any distinguish a completed transfer from a failure.

If buffer_empty( buffers ) is true, n is 0. The empty buffer is not itself a cause for error, but ec may reflect the state of the stream.

Buffers in the sequence are consumed in order.

After an Error

A subsequent write_some call is permitted. A conforming stream may report the same contingency, report a different one, or resume delivering data.

Error Reporting

I/O contingencies arising from the underlying I/O system are reported via the error_code component of the return value. Examples are EOF, connection reset, and broken pipe. Failures in the library wrapper itself (such as memory allocation failure) are reported via exceptions.

Buffer Lifetime

The caller must ensure that the memory referenced by buffers remains valid until the co_await expression returns.

Conforming Signatures

template< ConstBufferSequence Buffers >
IoAwaitable auto write_some( Buffers buffers );

Pass buffer sequences by value. A by‐value parameter is copied into the coroutine frame, or into the awaitable's state. The returned awaitable is therefore self‐contained. A caller may store it, move it across threads, or wrap it into a sender without lifetime concerns. A by‐const‐reference parameter binds to caller storage. It is safe only when co_await consumes the awaitable immediately, in the same scope. Storing such an awaitable produces a dangling reference.

Callers who want to avoid copying an expensive buffer sequence (for example, a std::vector<const_buffer> with many entries) can pass std::views::all(seq) at the call site. The resulting ref_view satisfies the buffer‐sequence concepts and copies in O(1). See doc/buffers‐passing‐rationale.md.

Example

template< WriteStream Stream >
task<> write_all( Stream& s, char const* buf, std::size_t size )
{
    std::size_t total = 0;
    while( total < size )
    {
        auto [ec, n] = co_await s.write_some(
            const_buffer( buf + total, size - total ) );
        total += n;
        if( ec )
            co_return;
    }
}

Exceptions

Name

Thrown on

std::bad_alloc

If coroutine frame allocation fails.

Template Parameters

Name

Description

T

The stream type.

See Also

IoAwaitable, ConstBufferSequence, awaitable_decomposes_to

Created with MrDocs