boost::capy::WriteSink

Concept for types providing complete writes with EOF signaling.

Synopsis

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

Description

A type satisfies WriteSink if it satisfies WriteStream and additionally provides write, write_eof(buffers), and write_eof() member functions that are IoAwaitable.

WriteSink refines WriteStream. Every WriteSink is a WriteStream. Algorithms constrained on WriteStream accept both raw streams and sinks.

Syntactic Requirements

  • `T` must satisfy WriteStream (provides `write_some`)

  • `T` must provide a `write` member function template accepting any ConstBufferSequence, returning an awaitable that decomposes to `(error_code,std::size_t)`

  • `T` must provide a `write_eof` member function template accepting any ConstBufferSequence, returning an awaitable that decomposes to `(error_code,std::size_t)`

  • `T` must provide a `write_eof` member function taking no arguments, returning an awaitable that decomposes to `(error_code)`

  • All return types must satisfy IoAwaitable

Semantic Requirements

The inherited write_some operation writes one or more bytes (partial write). See WriteStream.

The write operation consumes the entire buffer sequence:

  • On success: `!ec`, and `n` equals `buffer_size( buffers )`.

  • On error: `ec`, and `n` indicates the number of bytes written before the error.

The write_eof(buffers) operation writes the entire buffer sequence and signals end‐of‐stream atomically:

  • On success: `!ec`, `n` equals `buffer_size( buffers )`, and the sink is finalized.

  • On error: `ec`, and `n` indicates the number of bytes written before the error.

The write_eof() operation signals end‐of‐stream with no data:

  • On success: `!ec`, and the sink is finalized.

  • On error: `ec`.

After write_eof (either overload) returns successfully, no further writes or EOF signals are permitted.

Buffer Lifetime

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

Conforming Signatures

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

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

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

IoAwaitable auto write_eof();

Coroutine Buffer Lifetime: When implementing coroutine member functions, prefer accepting buffer sequences by value rather than by reference. Buffer sequences passed by reference may become dangling if the caller's stack frame is destroyed before the coroutine completes. Passing by value ensures the buffer sequence is copied into the coroutine frame and remains valid across suspension points.

Example

template< WriteSink Sink >
task<> send_body( Sink& sink, std::string_view data )
{
    // Atomic: write all data and signal EOF
    auto [ec, n] = co_await sink.write_eof(
        make_buffer( data ) );
}

// Or separately:
template< WriteSink Sink >
task<> send_body2( Sink& sink, std::string_view data )
{
    auto [ec, n] = co_await sink.write(
        make_buffer( data ) );
    if( ec )
        co_return;
    auto [ec2] = co_await sink.write_eof();
}

Template Parameters

Name Description

T

The sink type.

See Also

WriteStream, IoAwaitable, ConstBufferSequence, awaitable_decomposes_to

Created with MrDocs