Buffer Sequences

Every I/O operation ultimately comes down to moving bytes between your program and the outside world—​a socket, a file, a pipe. The question is: how do you describe where those bytes live in memory?

The obvious answer is a pointer and a size. And for a single contiguous buffer, that works. But real I/O is rarely that tidy. An HTTP response has headers in one buffer and a body in another. A message might be assembled from a protocol header, a payload, and a checksum. Each is produced by different parts of your code, and each sits in its own memory. The operating system even supports scatter/gather I/O specifically to handle this: a single system call that reads into or writes from multiple non-contiguous buffers.

Capy’s buffer model is designed for this reality. Instead of forcing you to copy data into a single contiguous allocation, Capy uses buffer sequences. These are lightweight, zero-copy abstractions that let you describe any arrangement of memory and pass it directly to the OS. The design is concept-driven, meaning the compiler verifies correctness at compile time with no runtime overhead.

What This Section Covers

  • Why Concepts, Not Spans — Why Capy models buffers with concepts instead of a single span type.

  • Buffer Types — const_buffer and mutable_buffer, the two concrete buffer types.

  • Buffer Sequences — Composing buffers into sequences for zero-allocation scatter/gather I/O.

  • System I/O Integration — How buffer sequences translate to platform iovec/WSABUF structures.

  • Buffer Algorithms — Measuring and copying buffer sequences with buffer_size, buffer_copy, and related algorithms.

Understanding buffers is essential for everything that follows—​streams, I/O operations, and protocol implementations all build on the abstractions introduced here.