Skip to content

Commit f12f876

Browse files
committed
Overhaul type-erased I/O wrappers, design docs, and test coverage
Redesign the any_read_source and any_write_sink type-erasing wrappers to use a split vtable architecture with per-operation awaitable_ops dispatch, enabling zero-allocation steady-state I/O across multiple heterogeneous async operations. Restructure any_read_stream and any_write_stream flat vtables for optimal cache line coherence by ordering function pointers according to call sequence. Introduce buffer_array iterator-range constructors (truncating and throwing variants) for efficient buffer sequence materialization. Add buffer_param::more() to detect whether additional buffers remain beyond the current window. Convert buffer_param internal storage to use a union with placement-new construction, eliminating default initialization of buffer descriptors. Rewrite the ReadStream design document with a rigorous derivation of the errors-exclude-data contract, reconstructing Kohlhoff's reasoning from the Asio source code, POSIX/Windows system call semantics, and composed operation requirements. Add post-error preconditions across all read and write operations. Add two new design documents: Run API Design (two-phase invocation pattern, allocator timing constraints, C++17 postfix evaluation order, comparison with std::execution) and Type-Erasing Awaitables (flat vs split vtable layouts, cache line analysis, construct-in-await_ready vs construct-in-await_suspend strategies). Work around GCC 14 internal compiler error in write_now::operator() by replacing abbreviated function template syntax with explicit template parameter, avoiding an ICE in expand_expr_real_1 during RTL expansion of coroutine code on MinGW. Add comprehensive unit tests for any_read_source, any_read_stream, any_write_sink, any_write_stream, buffer_array, buffer_param, buffer_sink, buffer_source, read_source, write_sink, and stream test utilities, bringing total new test coverage to ~2,300 lines.
1 parent e320b5a commit f12f876

33 files changed

Lines changed: 4034 additions & 562 deletions

doc/modules/ROOT/nav.adoc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,6 @@
5050
** xref:design/ReadSource.adoc[ReadSource]
5151
** xref:design/WriteStream.adoc[WriteStream]
5252
** xref:design/WriteSink.adoc[WriteSink]
53+
** xref:design/RunApi.adoc[Run API]
54+
** xref:design/TypeEraseAwaitable.adoc[Type-Erasing Awaitables]
5355
* xref:reference:boost/capy.adoc[Reference]

doc/modules/ROOT/pages/design/ReadSource.adoc

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ read. May return fewer bytes than the buffer can hold.
3939
- On error: `ec`, `n == 0`.
4040
- If `buffer_empty(buffers)`: completes immediately, `!ec`, `n == 0`.
4141

42+
Once `read_some` returns an error (including EOF), the caller must
43+
not call `read_some` again. The stream is done. Not all
44+
implementations can reproduce a prior error on subsequent calls, so
45+
the behavior after an error is undefined.
46+
4247
=== `read(buffers)` -- Complete Read
4348

4449
Reads data into the buffer sequence. Either fills the entire buffer
@@ -58,6 +63,11 @@ Successful partial reads are not permitted. Either the entire buffer
5863
is filled, or the operation returns with an error. This is the
5964
defining property of a complete-read primitive.
6065

66+
Once `read` returns an error (including EOF), the caller must not
67+
call `read` or `read_some` again. The source is done. Not all
68+
implementations can reproduce a prior error on subsequent calls, so
69+
the behavior after an error is undefined.
70+
6171
When the buffer sequence contains multiple buffers, each buffer is
6272
filled completely before proceeding to the next.
6373

@@ -400,7 +410,7 @@ Examples of types that satisfy `ReadSource`:
400410

401411
The `read_some` contract (inherited from `ReadStream`) requires that
402412
when `ec == cond::eof`, `n` is always 0. Data and EOF are delivered
403-
in separate calls. See xref:ReadStream.adoc#_why_read_some_returns_no_data_on_eof[ReadStream: Why `read_some` Returns No Data on EOF]
413+
in separate calls. See xref:ReadStream.adoc#_design_foundations_why_errors_exclude_data[ReadStream: Why Errors Exclude Data]
404414
for the full rationale. The key points:
405415

406416
- The clean trichotomy (success/EOF/error, where data implies success)

0 commit comments

Comments
 (0)