Skip to content

Add examples and update docs to match working code#127

Merged
MungoG merged 1 commit intocppalliance:developfrom
MungoG:add-examples
Feb 4, 2026
Merged

Add examples and update docs to match working code#127
MungoG merged 1 commit intocppalliance:developfrom
MungoG:add-examples

Conversation

@MungoG
Copy link
Contributor

@MungoG MungoG commented Feb 3, 2026

Summary by CodeRabbit

  • New Features

    • Added a comprehensive suite of runnable examples demonstrating async patterns (hello task, producer/consumer, buffer composition, custom dynamic buffer, type-erased echo, echo server, mock-stream tests, parallel fetch, stream pipeline, timeout/cancellation, and more).
  • Documentation

    • Added an examples guide with build instructions for CMake and B2.
  • Chores

    • Enabled building and inclusion of the examples in project builds (toggle-controlled).

@coderabbitai
Copy link

coderabbitai bot commented Feb 3, 2026

📝 Walkthrough

Walkthrough

Adds a new examples suite and enables building it: new example/ directory with many example projects, CMake/Jam build files, README, and multiple example source files; activates add_subdirectory(example) in the top-level CMakeLists.

Changes

Cohort / File(s) Summary
Top-level & aggregator
CMakeLists.txt, example/CMakeLists.txt, example/Jamfile, example/README.md
Enables building examples from the root and adds aggregator build manifests and documentation.
Per-example build files
example/*/CMakeLists.txt, example/*/Jamfile
Adds CMake and Boost.Jam files for each example (hello-task, producer-consumer, buffer-composition, mock-stream-testing, type-erased-echo, timeout-cancellation, parallel-fetch, custom-dynamic-buffer, echo-server-corosio, stream-pipeline).
Hello task
example/hello-task/hello_task.cpp
New simple async say_hello() coroutine and executable target.
Producer / Consumer
example/producer-consumer/producer_consumer.cpp
Producer/consumer coroutine example using thread_pool, strand, async_event and when_all coordination.
Buffer composition
example/buffer-composition/buffer_composition.cpp
Buffer demonstrations for single, pair, array, and mutable buffers; new example executable target.
Mock stream testing
example/mock-stream-testing/mock_stream_testing.cpp
Transport-agnostic mock-stream tests (happy path, partial reads, error injection) and executable.
Type-erased echo
example/type-erased-echo/echo.hpp, .../echo.cpp, .../main.cpp
Adds type-erased echo interface, implementation, and mock-stream test harness using any_stream.
Timeout / cancellation
example/timeout-cancellation/timeout_cancellation.cpp
Cooperative cancellation examples using stop tokens, run_async, and cancellation propagation.
Parallel fetch
example/parallel-fetch/parallel_fetch.cpp
Parallel async orchestration examples (when_all, side-effects, error propagation) and executable.
Custom dynamic buffer
example/custom-dynamic-buffer/custom_dynamic_buffer.cpp
Adds tracked_buffer class with prepare/commit/consume/compact, stats, and an async read demo; new example executable.
Echo server (Corosio)
example/echo-server-corosio/echo_server.cpp, example/echo-server-corosio/CMakeLists.txt
TCP echo server using Corosio; CMake conditionally adds target when Boost::corosio exists.
Stream pipeline
example/stream-pipeline/stream_pipeline.cpp
Adds composable transforms (uppercase, line-numbering), transfer coroutine, pipeline demo, and executable.

Sequence Diagram(s)

sequenceDiagram
    rect rgba(200,230,255,0.5)
    participant Client as Client
    participant IO as I/O_Context
    participant Acceptor as Acceptor
    participant Session as Echo_Session
    end
    IO->>Acceptor: bind/listen & start accept_loop
    Client->>Acceptor: TCP connect
    Acceptor->>IO: async_accept
    IO-->>Acceptor: accept complete
    Acceptor->>Session: spawn echo_session(any_stream)
    Client->>Session: write data
    Session->>Session: read_some (co_await)
    Session-->>Client: write (echo)
    Client->>Session: close (EOF)
    Session->>Session: detect EOF and terminate
Loading
sequenceDiagram
    rect rgba(230,255,220,0.5)
    participant Source as Buffer_Source
    participant LineNum as LineNumbering_Transform
    participant Upper as Uppercase_Transform
    participant Transfer as Transfer_Routine
    participant Sink as Write_Sink
    end
    Transfer->>Upper: pull()
    Upper->>LineNum: pull()
    LineNum->>Source: pull()
    Source-->>LineNum: buffer
    LineNum->>LineNum: prefix line numbers
    LineNum-->>Upper: transformed buffer
    Upper->>Upper: uppercase bytes
    Upper-->>Transfer: transformed buffer
    Transfer->>Sink: write(buffer)
    Sink-->>Transfer: io_result
    Transfer->>Upper: consume(n)
    loop until EOF
        Transfer->>Upper: pull()
    end
    Source-->>LineNum: EOF
    LineNum-->>Upper: EOF
    Upper-->>Transfer: EOF
    Transfer->>Sink: write_eof()
    Sink-->>Transfer: io_result
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related issues

Possibly related PRs

  • ongoing work #88 — Related (and potentially conflicting) because it concerns public type-erased interfaces which these examples consume (e.g., any_stream).

Poem

🐰 I hopped through code and found a trail,
Examples sprouted, demos set sail,
Coroutines hummed and buffers played,
Echoes bounced and pipelines swayed,
I nibble docs and dream in bytes. 🥕

🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding examples and updating documentation to match the working codebase.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@cppalliance-bot
Copy link

cppalliance-bot commented Feb 3, 2026

An automated preview of the documentation is available at https://127.capy.prtest3.cppalliance.org/index.html

If more commits are pushed to the pull request, the docs will rebuild at the same URL.

2026-02-04 19:50:22 UTC

@cppalliance-bot
Copy link

cppalliance-bot commented Feb 3, 2026

GCOVR code coverage report https://127.capy.prtest3.cppalliance.org/gcovr/index.html
LCOV code coverage report https://127.capy.prtest3.cppalliance.org/genhtml/index.html
Coverage Diff Report https://127.capy.prtest3.cppalliance.org/diff-report/index.html

Build time: 2026-02-04 19:53:39 UTC

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 10

🤖 Fix all issues with AI agents
In `@example/echo-server-corosio/echo_server.cpp`:
- Around line 10-13: Add a file-level /* */ overview comment immediately after
the includes that briefly describes the echo server's design: mention that the
program uses boost::corosio (and boost::capy) to accept TCP connections, spawns
a coroutine per client (e.g., main/accept loop hands off sockets to a
per-connection coroutine), implements a read-then-write echo loop with simple
framing/error handling and graceful shutdown behaviour, and note any important
invariants or thread/coroutine-safety assumptions; place this comment block
directly below the existing `#include` lines so reviewers can quickly understand
how echo_server.cpp is structured.

In `@example/hello-task/hello_task.cpp`:
- Around line 10-12: Add a high-level C-style block comment immediately after
the `#include` lines that gives an overview of the implementation in this
translation unit; describe the purpose of the file, main algorithmic flow, key
data structures or classes used, and any important invariants or dependencies so
reviewers can quickly understand the non-trivial logic in hello_task.cpp (place
the comment directly after the `#include` <...> lines).

In `@example/mock-stream-testing/mock_stream_testing.cpp`:
- Around line 10-18: Add a file-level overview block comment immediately after
the include section in mock_stream_testing.cpp describing the high-level purpose
and flow of the test/implementation (what the file tests or implements, key
components like boost::capy::test::stream, fuse, any_stream and any important
invariants or setup/teardown). Locate the include block (lines containing
`#include` <boost/capy.hpp>, <boost/capy/test/stream.hpp>,
<boost/capy/test/fuse.hpp>, <boost/capy/io/any_stream.hpp>,
<boost/capy/cond.hpp>, <iostream>, <cassert>, <cctype>) and insert a /* ... */
overview block right after those includes; keep it concise (2–4 sentences) and
focused on the high-level behavior and assumptions used by the rest of the file.
- Around line 49-53: The current code uses stream.write_some(...) which may
write only part of the buffer; replace it with a full-write operation so the
entire line is sent before returning. Change the destructuring of auto [wec, wn]
= co_await stream.write_some(...) to call the full write variant (e.g., co_await
stream.write(const_buffer(line.data(), line.size())) or an equivalent
async_write helper) and capture only the error code (wec), then keep co_return
!wec; so success is only returned when the whole buffer has been written; update
any references to wn accordingly.

In `@example/producer-consumer/producer_consumer.cpp`:
- Around line 15-37: The code has a data race on shared_value because
async_event is not thread-safe and producer() and consumer() run on different
threads; replace shared_value with std::atomic<int> and in producer() use
shared_value.store(42, std::memory_order_release) and in consumer() use int v =
shared_value.load(std::memory_order_acquire) (or otherwise eliminate shared
mutable state), keeping the signaling via async_event as-is to ensure correct
synchronization between producer() and consumer().

In `@example/stream-pipeline/stream_pipeline.cpp`:
- Around line 339-343: Wrap the call to demo_pipeline() inside main() in a
try-catch that catches std::system_error (and a generic std::exception fallback)
to prevent abrupt termination when transfer() throws; in the catch blocks log or
print a clear error message including the exception.what() and return a non-zero
exit code so main() signals failure while demo_pipeline() and transfer() remain
unchanged.

In `@example/timeout-cancellation/timeout_cancellation.cpp`:
- Around line 67-108: The demos create a local thread_pool that may be destroyed
before queued run_async tasks start; keep the pool alive until tasks complete by
moving the thread_pool to a longer-lived scope (e.g., construct it in main()) or
by synchronizing task completion (e.g., add a completion callback or future that
the demo functions wait on). Update demo_normal_completion and demo_cancellation
to not create a transient thread_pool: either accept a thread_pool& parameter or
rely on a main-level thread_pool instance, and use a completion signal
(promise/future or condition_variable) returned from run_async or invoked by the
task lambda so the demo waits for the async work (or cancellation) to finish
before returning.

In `@example/type-erased-echo/echo.cpp`:
- Around line 10-15: Add a /* ... */ overview block comment immediately after
the include section in echo.cpp that summarizes the file's high-level behavior
and design (what the file implements, key control flow, and how it interacts
with echo.hpp and Boost.Capy I/O operations such as the read/write/cond flows
and buffer handling). Keep it concise (3–6 sentences) and reference the primary
responsibilities implemented in this file (e.g., how incoming data is processed
and echoed back, any important invariants or concurrency assumptions) so future
readers can quickly understand the implementation without reading all functions.

In `@example/type-erased-echo/echo.hpp`:
- Around line 18-19: Add a Doxygen async/awaitable docstring for the public
function echo_session(boost::capy::any_stream& stream) that starts with a verb
(one-sentence brief), then an extended async description matching echo.cpp
behavior, document completion conditions (when it completes normally versus
errors), list parameters (stream) and return (boost::capy::task<>), document
thrown exceptions or error conditions, explain cancellation behavior, include a
small usage example and remarks, and add an `@see` reference to echo.cpp or
related helpers; place this comment immediately above the echo_session
declaration in the header.

In `@example/type-erased-echo/main.cpp`:
- Around line 10-15: Add a C-style block comment immediately after the includes
in main.cpp that provides a high-level overview of the file: describe the role
of main(), how it uses echo.hpp and the Boost Capy test utilities (boost::capy,
boost::capy::test::stream, fuse, run_blocking), the key control flow and
interactions (e.g., how input is received/echoed and how the test
harness/fuse/run_blocking are orchestrated), and any important invariants or
assumptions; place this /* ... */ overview directly after the `#include` lines so
readers can quickly understand the implementation before diving into main() and
other functions.
🧹 Nitpick comments (8)
example/producer-consumer/producer_consumer.cpp (1)

10-13: Add a brief file-level overview block after the includes.
This example has non-trivial logic but no high-level overview comment. Add a short /* ... */ summary after the includes.

✍️ Suggested addition
 `#include` <boost/capy.hpp>
 `#include` <iostream>
 
+/* Overview: Demonstrates a simple producer-consumer flow using async_event and when_all. */
+
 using namespace boost::capy;

As per coding guidelines: Files containing non-trivial implementation logic should include a /* */ block comment after the includes that provides a high-level overview of how the implementation works.

example/parallel-fetch/parallel_fetch.cpp (1)

10-14: Add a brief file-level overview block after the includes.
This file is non-trivial and would benefit from a short overview comment after the includes.

✍️ Suggested addition
 `#include` <boost/capy.hpp>
 `#include` <iostream>
 `#include` <string>
 
+/* Overview: Demonstrates parallel fetch workflows with when_all and basic error handling. */
+
 using namespace boost::capy;

As per coding guidelines: Files containing non-trivial implementation logic should include a /* */ block comment after the includes that provides a high-level overview of how the implementation works.

example/buffer-composition/buffer_composition.cpp (1)

10-16: Add a brief file-level overview block after the includes.
A short summary comment will help future readers understand the example’s intent.

✍️ Suggested addition
 `#include` <boost/capy.hpp>
 `#include` <iostream>
 `#include` <string>
 `#include` <array>
 `#include` <vector>
 
+/* Overview: Demonstrates composing Capy buffers into singles, pairs, arrays, and mutable pairs. */
+
 using namespace boost::capy;

As per coding guidelines: Files containing non-trivial implementation logic should include a /* */ block comment after the includes that provides a high-level overview of how the implementation works.

example/timeout-cancellation/timeout_cancellation.cpp (1)

10-17: Add a brief file-level overview block after the includes.
A short summary comment will document the intent of this example.

✍️ Suggested addition
 `#include` <boost/capy.hpp>
 `#include` <boost/capy/test/stream.hpp>
 `#include` <boost/capy/test/run_blocking.hpp>
 `#include` <iostream>
 `#include` <chrono>
 `#include` <thread>
 
+/* Overview: Demonstrates stop_token-driven cancellation and timeout-style flows with Capy tasks. */
+
 using namespace boost::capy;

As per coding guidelines: Files containing non-trivial implementation logic should include a /* */ block comment after the includes that provides a high-level overview of how the implementation works.

example/custom-dynamic-buffer/custom_dynamic_buffer.cpp (1)

10-20: Add a brief file-level overview block after the includes.
This is a substantial example; a short overview comment would help maintainers.

✍️ Suggested addition
 `#include` <boost/capy.hpp>
 `#include` <boost/capy/test/run_blocking.hpp>
 `#include` <boost/capy/test/stream.hpp>
 `#include` <boost/capy/test/fuse.hpp>
 `#include` <boost/capy/cond.hpp>
 `#include` <iostream>
 `#include` <vector>
 `#include` <cassert>
 `#include` <cstring>
 
+/* Overview: Implements a tracked dynamic buffer and a read-loop demo with stats. */
+
 using namespace boost::capy;

As per coding guidelines: Files containing non-trivial implementation logic should include a /* */ block comment after the includes that provides a high-level overview of how the implementation works.

example/producer-consumer/CMakeLists.txt (1)

10-16: Consider excluding build scripts from compilable sources.
Line 10–12 includes CMakeLists.txt and Jamfile in PFILES; if the intent is IDE visibility only, mark them as header-only or keep them out of the target sources.

♻️ Suggested tweak
-file(GLOB_RECURSE PFILES CONFIGURE_DEPENDS *.cpp *.hpp
-    CMakeLists.txt
-    Jamfile)
+file(GLOB_RECURSE PFILES CONFIGURE_DEPENDS *.cpp *.hpp)
+set(OTHER_FILES CMakeLists.txt Jamfile)
 
-source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} PREFIX "" FILES ${PFILES})
+source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} PREFIX "" FILES ${PFILES} ${OTHER_FILES})
 
-add_executable(capy_example_producer_consumer ${PFILES})
+add_executable(capy_example_producer_consumer ${PFILES} ${OTHER_FILES})
+set_source_files_properties(${OTHER_FILES} PROPERTIES HEADER_FILE_ONLY TRUE)
example/echo-server-corosio/echo_server.cpp (1)

17-58: Trim redundant inline // comments to reduce noise.

Several comments restate the obvious (e.g., “Read some data”, “Echo it back”). Consider removing or consolidating them.

As per coding guidelines: Single-line // comments within code should be used sparingly and judiciously, explaining the why (not the what or how) when it is non-obvious. Warn about comments that merely restate what the code does or excessive commenting that adds noise rather than clarity.

example/mock-stream-testing/mock_stream_testing.cpp (1)

21-47: Trim redundant inline // comments to reduce noise.

Many inline comments simply restate what the code already expresses. Consider removing or consolidating them.

As per coding guidelines: Single-line // comments within code should be used sparingly and judiciously, explaining the why (not the what or how) when it is non-obvious. Warn about comments that merely restate what the code does or excessive commenting that adds noise rather than clarity.

Comment on lines +10 to +13
#include <boost/capy.hpp>
#include <boost/corosio.hpp>
#include <iostream>

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add the required file-level overview block after the includes.

This is non-trivial implementation logic; please add a brief /* */ overview right after the includes to summarize how the server works.

✍️ Example of the required overview block
 `#include` <boost/corosio.hpp>
 `#include` <iostream>

+/* High-level overview:
+   - Accepts TCP connections and spawns an echo session per client.
+   - Each session reads bytes and writes them back until EOF or error.
+*/

As per coding guidelines: Files containing non-trivial implementation logic should include a /* */ block comment after the includes that provides a high-level overview of how the implementation works.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
#include <boost/capy.hpp>
#include <boost/corosio.hpp>
#include <iostream>
`#include` <boost/capy.hpp>
`#include` <boost/corosio.hpp>
`#include` <iostream>
/* High-level overview:
- Accepts TCP connections and spawns an echo session per client.
- Each session reads bytes and writes them back until EOF or error.
*/
🤖 Prompt for AI Agents
In `@example/echo-server-corosio/echo_server.cpp` around lines 10 - 13, Add a
file-level /* */ overview comment immediately after the includes that briefly
describes the echo server's design: mention that the program uses boost::corosio
(and boost::capy) to accept TCP connections, spawns a coroutine per client
(e.g., main/accept loop hands off sockets to a per-connection coroutine),
implements a read-then-write echo loop with simple framing/error handling and
graceful shutdown behaviour, and note any important invariants or
thread/coroutine-safety assumptions; place this comment block directly below the
existing `#include` lines so reviewers can quickly understand how echo_server.cpp
is structured.

Comment on lines +10 to +12
#include <boost/capy.hpp>
#include <iostream>

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add the required post-include overview block comment.
This file contains non-trivial logic but lacks the high-level /* */ overview after the includes.

📝 Suggested addition
 `#include` <boost/capy.hpp>
 `#include` <iostream>
+
+/*
+Overview:
+- Schedules a simple coroutine on a thread_pool executor to print a greeting.
+*/

As per coding guidelines: “Files containing non-trivial implementation logic should include a /* */ block comment after the includes that provides a high-level overview of how the implementation works.”

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
#include <boost/capy.hpp>
#include <iostream>
`#include` <boost/capy.hpp>
`#include` <iostream>
/*
Overview:
- Schedules a simple coroutine on a thread_pool executor to print a greeting.
*/
🤖 Prompt for AI Agents
In `@example/hello-task/hello_task.cpp` around lines 10 - 12, Add a high-level
C-style block comment immediately after the `#include` lines that gives an
overview of the implementation in this translation unit; describe the purpose of
the file, main algorithmic flow, key data structures or classes used, and any
important invariants or dependencies so reviewers can quickly understand the
non-trivial logic in hello_task.cpp (place the comment directly after the
`#include` <...> lines).

Comment on lines +10 to +18
#include <boost/capy.hpp>
#include <boost/capy/test/stream.hpp>
#include <boost/capy/test/fuse.hpp>
#include <boost/capy/io/any_stream.hpp>
#include <boost/capy/cond.hpp>
#include <iostream>
#include <cassert>
#include <cctype>

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add the required file-level overview block after the includes.

This file contains non-trivial implementation logic; please add a brief /* */ overview right after the includes.

✍️ Example of the required overview block
 `#include` <cctype>

+/* High-level overview:
+   - Implements an uppercase echo protocol over any_stream.
+   - Exercises protocol behavior with mock stream scenarios and fuse error injection.
+*/

As per coding guidelines: Files containing non-trivial implementation logic should include a /* */ block comment after the includes that provides a high-level overview of how the implementation works.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
#include <boost/capy.hpp>
#include <boost/capy/test/stream.hpp>
#include <boost/capy/test/fuse.hpp>
#include <boost/capy/io/any_stream.hpp>
#include <boost/capy/cond.hpp>
#include <iostream>
#include <cassert>
#include <cctype>
`#include` <boost/capy.hpp>
`#include` <boost/capy/test/stream.hpp>
`#include` <boost/capy/test/fuse.hpp>
`#include` <boost/capy/io/any_stream.hpp>
`#include` <boost/capy/cond.hpp>
`#include` <iostream>
`#include` <cassert>
`#include` <cctype>
/* High-level overview:
- Implements an uppercase echo protocol over any_stream.
- Exercises protocol behavior with mock stream scenarios and fuse error injection.
*/
🤖 Prompt for AI Agents
In `@example/mock-stream-testing/mock_stream_testing.cpp` around lines 10 - 18,
Add a file-level overview block comment immediately after the include section in
mock_stream_testing.cpp describing the high-level purpose and flow of the
test/implementation (what the file tests or implements, key components like
boost::capy::test::stream, fuse, any_stream and any important invariants or
setup/teardown). Locate the include block (lines containing `#include`
<boost/capy.hpp>, <boost/capy/test/stream.hpp>, <boost/capy/test/fuse.hpp>,
<boost/capy/io/any_stream.hpp>, <boost/capy/cond.hpp>, <iostream>, <cassert>,
<cctype>) and insert a /* ... */ overview block right after those includes; keep
it concise (2–4 sentences) and focused on the high-level behavior and
assumptions used by the rest of the file.

Comment on lines 49 to 53
// Echo uppercase
// wec: std::error_code, wn: std::size_t
auto [wec, wn] = co_await stream.write_some(const_buffer(line.data(), line.size()));

co_return !wec;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

Boost.Capy write_some partial write semantics documentation

💡 Result:

I couldn’t find any Boost library/module actually named “Boost.Capy”; the closest “write_some” APIs in Boost with partial semantics are in Boost.Asio (I/O) and Boost.Beast (HTTP writing).

Boost.Asio write_some (partial write semantics)

basic_stream_socket::write_some is a blocking call that returns once one or more bytes have been written (or an error occurs), and it may write only part of the provided buffers. The return value is the number of bytes actually written, so the caller must handle the remainder (e.g., loop) or use boost::asio::write to ensure everything is written before returning. [1]

Boost.Beast http::write_some (partial message write)

boost::beast::http::write_some(stream, serializer) writes part of an HTTP message using a serializer and blocks until (a) one or more bytes are transferred, (b) serializer::is_done() becomes true, or (c) an error occurs. It is implemented in terms of the underlying stream’s write_some, and the amount written can be bounded via serializer::limit(). [2]

Sources
[1] Boost.Asio (develop docs): basic_stream_socket::write_some remarks on partial writes and blocking behavior. (beta.boost.org)
[2] Boost.Beast: http::write_some description and completion conditions. (beta.boost.org)

Citations:


🏁 Script executed:

# Search for write() and write_some() declarations in the codebase
fd -e hpp -e h -e cpp | head -20

Repository: cppalliance/capy

Length of output: 881


🏁 Script executed:

# Look for the stream header files that might define write and write_some
find . -type f \( -name "*.hpp" -o -name "*.h" \) | xargs grep -l "write_some\|write(" | head -10

Repository: cppalliance/capy

Length of output: 487


🏁 Script executed:

# Search for write_some definition in the codebase
rg "write_some" --type hpp --type cpp -B 2 -A 5 | head -100

Repository: cppalliance/capy

Length of output: 87


🏁 Script executed:

# Look for write() function definition/declaration
rg "^\s*auto\s+write\s*\(" --type hpp --type cpp -B 2 -A 8 | head -150

Repository: cppalliance/capy

Length of output: 87


🏁 Script executed:

# Check the stream concept definition
cat -n include/boost/capy/concept/stream.hpp | head -100

Repository: cppalliance/capy

Length of output: 1906


🏁 Script executed:

cat -n include/boost/capy/concept/write_stream.hpp

Repository: cppalliance/capy

Length of output: 4222


🏁 Script executed:

# Search for write function (without type suffix)
rg "write\(" --type c -B 3 -A 10 include/boost/capy | head -200

Repository: cppalliance/capy

Length of output: 42


🏁 Script executed:

# Search for write function more broadly
rg "write\s*\(" include/boost/capy -A 8 | head -150

Repository: cppalliance/capy

Length of output: 8900


🏁 Script executed:

# Check what's in the io directory
fd . include/boost/capy/io -type f

Repository: cppalliance/capy

Length of output: 230


🏁 Script executed:

# Look at the specific file mentioned in the review
cat -n example/mock-stream-testing/mock_stream_testing.cpp | sed -n '40,65p'

Repository: cppalliance/capy

Length of output: 929


🏁 Script executed:

# Look at the write() function definition in detail
cat -n include/boost/capy/write.hpp | head -120

Repository: cppalliance/capy

Length of output: 3382


🏁 Script executed:

# Check the mock stream implementation to see if write_some can be partial
cat -n example/mock-stream-testing/mock_stream_testing.cpp | head -30

Repository: cppalliance/capy

Length of output: 1075


🏁 Script executed:

# Look for the test stream class definition
rg "class.*stream" example/mock-stream-testing -A 20 | head -80

Repository: cppalliance/capy

Length of output: 42


🏁 Script executed:

# Search for test stream class in the test headers
find . -name "*.hpp" -path "*/test/*" -exec grep -l "class stream" {} \;

Repository: cppalliance/capy

Length of output: 96


🏁 Script executed:

# Look at test stream header
cat -n include/boost/capy/test/stream.hpp | head -150

Repository: cppalliance/capy

Length of output: 5218


🏁 Script executed:

# Continue reading the stream implementation, focusing on write_some
cat -n include/boost/capy/test/stream.hpp | sed -n '150,250p'

Repository: cppalliance/capy

Length of output: 3729


🏁 Script executed:

# Continue reading the write_some implementation
cat -n include/boost/capy/test/stream.hpp | sed -n '248,320p'

Repository: cppalliance/capy

Length of output: 2616


Use write() instead of write_some() to guarantee full write completion.

write_some writes one or more bytes and returns the actual count written, which may be less than the total buffer size. The current code returns success even if only part of the line was written. Use write() to loop until all bytes are sent, ensuring complete output.

Proposed fix
-    auto [wec, wn] = co_await stream.write_some(const_buffer(line.data(), line.size()));
+    auto [wec, wn] = co_await write(stream, const_buffer(line.data(), line.size()));
🤖 Prompt for AI Agents
In `@example/mock-stream-testing/mock_stream_testing.cpp` around lines 49 - 53,
The current code uses stream.write_some(...) which may write only part of the
buffer; replace it with a full-write operation so the entire line is sent before
returning. Change the destructuring of auto [wec, wn] = co_await
stream.write_some(...) to call the full write variant (e.g., co_await
stream.write(const_buffer(line.data(), line.size())) or an equivalent
async_write helper) and capture only the error code (wec), then keep co_return
!wec; so success is only returned when the whole buffer has been written; update
any references to wn accordingly.

Comment on lines +10 to +15
#include "echo.hpp"
#include <boost/capy/read.hpp>
#include <boost/capy/write.hpp>
#include <boost/capy/cond.hpp>
#include <boost/capy/buffers/make_buffer.hpp>

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add the required post-include overview block comment.
This file contains non-trivial logic but lacks the high-level /* */ overview after the includes.

📝 Suggested addition
 `#include` "echo.hpp"
 `#include` <boost/capy/read.hpp>
 `#include` <boost/capy/write.hpp>
 `#include` <boost/capy/cond.hpp>
 `#include` <boost/capy/buffers/make_buffer.hpp>
+
+/*
+Overview:
+- Implements an echo loop that reads from any_stream and writes the same data back,
+  exiting on EOF and propagating errors as system_error.
+*/

As per coding guidelines: “Files containing non-trivial implementation logic should include a /* */ block comment after the includes that provides a high-level overview of how the implementation works.”

🤖 Prompt for AI Agents
In `@example/type-erased-echo/echo.cpp` around lines 10 - 15, Add a /* ... */
overview block comment immediately after the include section in echo.cpp that
summarizes the file's high-level behavior and design (what the file implements,
key control flow, and how it interacts with echo.hpp and Boost.Capy I/O
operations such as the read/write/cond flows and buffer handling). Keep it
concise (3–6 sentences) and reference the primary responsibilities implemented
in this file (e.g., how incoming data is processed and echoed back, any
important invariants or concurrency assumptions) so future readers can quickly
understand the implementation without reading all functions.

Comment on lines +18 to +19
// Type-erased interface: no template dependencies
boost::capy::task<> echo_session(boost::capy::any_stream& stream);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add a full async/awaitable docstring for echo_session.

This public header declaration lacks the required Doxygen comment. Please add documentation that follows the async/awaitable requirements (verb-starting brief, extended async description, completion conditions, params/return/throws, cancellation, examples, remarks, and @see) based on the actual behavior in echo.cpp.
As per coding guidelines, "Docstrings are required for all classes and functions in public headers in non-detail namespaces. Docstrings should include a brief description of purpose, document all parameters, return values, and any preconditions, postconditions, or exceptions." and "Write async/awaitable function javadoc with a one-sentence brief starting with a verb (e.g., 'Read data from the stream asynchronously.')."

🤖 Prompt for AI Agents
In `@example/type-erased-echo/echo.hpp` around lines 18 - 19, Add a Doxygen
async/awaitable docstring for the public function
echo_session(boost::capy::any_stream& stream) that starts with a verb
(one-sentence brief), then an extended async description matching echo.cpp
behavior, document completion conditions (when it completes normally versus
errors), list parameters (stream) and return (boost::capy::task<>), document
thrown exceptions or error conditions, explain cancellation behavior, include a
small usage example and remarks, and add an `@see` reference to echo.cpp or
related helpers; place this comment immediately above the echo_session
declaration in the header.

Comment on lines +10 to +15
#include "echo.hpp"
#include <boost/capy.hpp>
#include <boost/capy/test/stream.hpp>
#include <boost/capy/test/fuse.hpp>
#include <boost/capy/test/run_blocking.hpp>
#include <iostream>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add the required post-include overview block comment.
This file contains non-trivial logic but lacks the high-level /* */ overview after the includes.

📝 Suggested addition
 `#include` "echo.hpp"
 `#include` <boost/capy.hpp>
 `#include` <boost/capy/test/stream.hpp>
 `#include` <boost/capy/test/fuse.hpp>
 `#include` <boost/capy/test/run_blocking.hpp>
 `#include` <iostream>
+
+/*
+Overview:
+- Builds a mock stream, runs the echo session with run_blocking, and prints the echoed data.
+*/

As per coding guidelines: “Files containing non-trivial implementation logic should include a /* */ block comment after the includes that provides a high-level overview of how the implementation works.”

🤖 Prompt for AI Agents
In `@example/type-erased-echo/main.cpp` around lines 10 - 15, Add a C-style block
comment immediately after the includes in main.cpp that provides a high-level
overview of the file: describe the role of main(), how it uses echo.hpp and the
Boost Capy test utilities (boost::capy, boost::capy::test::stream, fuse,
run_blocking), the key control flow and interactions (e.g., how input is
received/echoed and how the test harness/fuse/run_blocking are orchestrated),
and any important invariants or assumptions; place this /* ... */ overview
directly after the `#include` lines so readers can quickly understand the
implementation before diving into main() and other functions.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In `@example/echo-server-corosio/echo_server.cpp`:
- Around line 122-125: The acceptor's reuse_address is already set by the
tcp::acceptor(ioc, endpoint) constructor so remove the redundant
acceptor.set_option(tcp::acceptor::reuse_address(true)); call (or alternatively
construct with an explicit third arg tcp::acceptor(ioc, endpoint, true)); edit
the code around tcp::acceptor acceptor(ioc, endpoint) to either delete the
set_option line or replace the constructor to include the explicit true.

In `@example/parallel-fetch/parallel_fetch.cpp`:
- Around line 131-140: The main function launches asynchronous work with
thread_pool and run_async but returns immediately, so tasks may be aborted;
modify main to capture the futures returned by run_async(pool.get_executor())
when calling fetch_user_dashboard("alice"), fetch_with_side_effects(), and
demonstrate_error_handling(), and then wait for their completion (e.g., call
.get() or .wait() on each future or use a provided thread_pool synchronization
method) before returning to ensure all async output completes.

In `@example/timeout-cancellation/timeout_cancellation.cpp`:
- Around line 10-16: Add a file-level /* */ comment block immediately after the
includes that gives a brief high-level overview of the example: describe the
demo structure (how boost::capy test/stream/run_blocking are used), the control
flow involving threads and chrono-based timeouts, how cancellation is triggered
and propagated, and any gotchas (race conditions, lifetime of objects, or
ordering assumptions). Keep it short (3–6 sentences) and reference the main
concepts shown in the file (use of boost::capy, test::stream and run_blocking,
thread/chrono usage, and cancellation semantics) so readers can quickly
understand the example before reading the code.
🧹 Nitpick comments (1)
example/custom-dynamic-buffer/custom_dynamic_buffer.cpp (1)

190-194: Add exception handling in main() for robustness.

The read_into_tracked_buffer() function throws std::system_error on I/O failures. While unlikely with mock streams, adding a try-catch demonstrates proper error handling.

🛡️ Proposed fix
 int main()
 {
-    demo_tracked_buffer();
-    return 0;
+    try
+    {
+        demo_tracked_buffer();
+        return 0;
+    }
+    catch (std::exception const& e)
+    {
+        std::cerr << "Error: " << e.what() << "\n";
+        return 1;
+    }
 }

Comment on lines +122 to +125
// Create acceptor
tcp::endpoint endpoint(tcp::v4(), port);
tcp::acceptor acceptor(ioc, endpoint);
acceptor.set_option(tcp::acceptor::reuse_address(true));
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🌐 Web query:

Boost.Asio tcp::acceptor constructor with endpoint behavior bind

💡 Result:

In Boost.Asio, the tcp::acceptor constructor that takes an endpoint does perform a bind (and more).

tcp::acceptor(io_context, endpoint, reuse_addr=true) behavior

This overload is documented/implemented as equivalent to doing all of the following, in order: open() → (optionally) set_option(reuse_address)bind()listen(). So the acceptor ends up already listening on that endpoint, and any bind-time errors (e.g., “address already in use”) will be thrown from the constructor. [1] [2]

boost::asio::ip::tcp::acceptor a(ioc, endpoint); // opens + binds + listens
  • reuse_addr defaults to true, and when true it sets socket_base::reuse_address(true) before binding. [2]
  • If you want to control options beyond reuse_address (or control when bind/listen happens), use the step-by-step form: acceptor.open(...), acceptor.set_option(...), acceptor.bind(...), acceptor.listen(...). [1] [3]

Sources: Boost.Asio ip::tcp::acceptor reference and basic_socket_acceptor constructor notes / implementation. [1] [2] [3]


🌐 Web query:

SO_REUSEADDR socket option must be set before bind

💡 Result:

SO_REUSEADDR affects the kernel’s address/port validation rules used by bind(), so it needs to be enabled before you call bind() for it to have any effect. On Linux, SO_REUSEADDR “indicates that the rules used in validating addresses supplied in a bind(2) call should allow reuse of local addresses” [1]. If you set it after bind(), you’ve already passed the point where those rules mattered.

Linux-specific gotcha: Linux will allow port reuse with SO_REUSEADDR only if it was set both by the previous program that bound the port and by the program trying to reuse it (behavior differs on some other OSes) [2]. This is one reason servers typically always set it on their listening sockets.

Windows: Microsoft’s docs likewise describe setting SO_REUSEADDR before bind(); Windows also warns that using it can make which socket receives traffic non-deterministic and recommends SO_EXCLUSIVEADDRUSE for exclusive binding when appropriate [3][4].

Typical pattern (POSIX):

  1. socket()
  2. setsockopt(SO_REUSEADDR)
  3. bind()
  4. listen()

Sources: [1] [2] [3] [4]


Remove redundant reuse_address option setting.

The tcp::acceptor(ioc, endpoint) constructor already sets reuse_address(true) by default before binding. The subsequent set_option() call is redundant and comes too late to influence the bind operation. Either remove it or, for explicitness, pass true as the third constructor argument:

Suggested fix
         // Create acceptor
         tcp::endpoint endpoint(tcp::v4(), port);
-        tcp::acceptor acceptor(ioc, endpoint);
-        acceptor.set_option(tcp::acceptor::reuse_address(true));
+        tcp::acceptor acceptor(ioc, endpoint, true);
🤖 Prompt for AI Agents
In `@example/echo-server-corosio/echo_server.cpp` around lines 122 - 125, The
acceptor's reuse_address is already set by the tcp::acceptor(ioc, endpoint)
constructor so remove the redundant
acceptor.set_option(tcp::acceptor::reuse_address(true)); call (or alternatively
construct with an explicit third arg tcp::acceptor(ioc, endpoint, true)); edit
the code around tcp::acceptor acceptor(ioc, endpoint) to either delete the
set_option line or replace the constructor to include the explicit true.

Comment on lines 10 to 17
#include <boost/capy.hpp>
#include <boost/capy/test/stream.hpp>
#include <boost/capy/test/run_blocking.hpp>
#include <iostream>
#include <chrono>
#include <thread>

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add a file-level implementation overview comment.

This example has non-trivial control flow and should include a short /* */ overview after the includes to explain the demo structure and any gotchas.

📝 Suggested addition
 `#include` <iostream>
 `#include` <chrono>
 `#include` <thread>
+
+/*
+    Demonstrates cooperative cancellation with stop tokens by running a slow
+    coroutine in a thread pool, showcasing normal completion and cancellation.
+*/

As per coding guidelines: Files containing non-trivial implementation logic should include a /* */ block comment after the includes that provides a high-level overview of how the implementation works.

🤖 Prompt for AI Agents
In `@example/timeout-cancellation/timeout_cancellation.cpp` around lines 10 - 16,
Add a file-level /* */ comment block immediately after the includes that gives a
brief high-level overview of the example: describe the demo structure (how
boost::capy test/stream/run_blocking are used), the control flow involving
threads and chrono-based timeouts, how cancellation is triggered and propagated,
and any gotchas (race conditions, lifetime of objects, or ordering assumptions).
Keep it short (3–6 sentences) and reference the main concepts shown in the file
(use of boost::capy, test::stream and run_blocking, thread/chrono usage, and
cancellation semantics) so readers can quickly understand the example before
reading the code.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🤖 Fix all issues with AI agents
In `@example/buffer-composition/buffer_composition.cpp`:
- Around line 10-15: Add a short C-style block comment immediately after the
includes in buffer_composition.cpp that gives a high-level overview of the file:
describe the purpose (buffer composition/demo), the main data structures used
(std::array, std::vector), key functions or flow (initialization,
composition/merging step, and output/logging), and any non-trivial algorithmic
steps readers should know (e.g., how buffers are combined or indexed). Keep it
concise (2–4 sentences) so someone scanning the file can quickly understand the
implementation and where to look (e.g., main or any compose/merge functions).

In `@example/custom-dynamic-buffer/custom_dynamic_buffer.cpp`:
- Around line 100-111: The consume() method can advance read_pos_ past
write_pos_ if called with n > size(); clamp the amount consumed by computing
actual = std::min(n, size()) (use the existing size() method), then update
total_consumed_ and read_pos_ using actual and preserve the reset logic that
sets read_pos_/write_pos_ to 0 when empty; ensure you update only
total_consumed_, read_pos_, and keep write_pos_ unchanged (referencing
consume(), size(), total_consumed_, read_pos_, write_pos_).
- Around line 10-19: Add a file-level /* ... */ overview comment immediately
after the includes in custom_dynamic_buffer.cpp that briefly describes the
custom dynamic buffer design and the demo flow; mention key concepts such as how
the buffer grows/shrinks, ownership/aliasing rules, thread/async expectations,
and how the demo exercises it via boost::capy test utilities (references:
boost/capy/test/run_blocking, boost/capy/test/stream, boost/capy/test/fuse).
Keep the comment concise (a few sentences) and focused on high-level
architecture and what readers should expect from the example.

In `@example/Jamfile`:
- Around line 10-18: The Jamfile currently lists example subprojects but omits
the README-referenced echo-server-corosio; either add the missing entry
"build-project echo-server-corosio ;" to the list (so the example is included)
or, if omission is intentional due to the Corosio dependency, add a short
comment in the Jamfile near the project list explaining why echo-server-corosio
is excluded (referencing the README entry for clarity). Ensure the change is
made in the same project-list block where build-project hello-task,
producer-consumer, etc. are declared.

In `@example/parallel-fetch/parallel_fetch.cpp`:
- Around line 10-13: Add a C-style block comment immediately after the include
section that gives a short high-level overview of the demo in
parallel_fetch.cpp: describe the purpose of the example, the main flow (how the
program initializes the parallel fetcher, spawns worker tasks/threads,
dispatches fetch jobs, and collects results), note key components and APIs used
(e.g., boost::capy usage, any ThreadPool/worker abstractions or main()), and
mention error handling and expected output so readers can quickly understand the
implementation before diving into code.
🧹 Nitpick comments (2)
example/mock-stream-testing/mock_stream_testing.cpp (1)

60-68: Trim redundant inline comments to reduce noise.

Several // comments restate types or obvious steps (e.g., // test::stream, // bool). Consider removing or keeping only the “why” comments.

As per coding guidelines: Single-line // comments within code should be used sparingly and judiciously, explaining the why (not the what or how) when it is non-obvious. Warn about comments that merely restate what the code does or excessive commenting that adds noise rather than clarity.

example/stream-pipeline/stream_pipeline.cpp (1)

10-35: Add the required post-include overview block.

The overview is currently before the includes and not in a /* */ block. Move/convert it to a block comment right after the includes.

📝 Suggested update
-//
-// Stream Pipeline Example
-//
-// This example demonstrates chaining buffer sources to create a data
-// processing pipeline. Data flows through transform stages:
-//
-//   input -> uppercase_transform -> line_numbering_transform -> output
-//
-// Each transform is a BufferSource that wraps an upstream any_buffer_source,
-// enabling type-erased composition of arbitrary transform chains.
-//
-// The transforms use task<> coroutines for their pull() methods, allowing
-// them to properly co_await the upstream source.
-//
-
 `#include` <boost/capy.hpp>
 `#include` <boost/capy/test/run_blocking.hpp>
 `#include` <boost/capy/test/buffer_source.hpp>
 `#include` <boost/capy/test/write_sink.hpp>
 `#include` <boost/capy/io/any_buffer_source.hpp>
 `#include` <boost/capy/io/any_write_sink.hpp>
 `#include` <iostream>
 `#include` <algorithm>
 `#include` <cctype>
 `#include` <system_error>
+
+/*
+Stream Pipeline Example
+
+Demonstrates chaining buffer sources:
+  input -> uppercase_transform -> line_numbering_transform -> output
+
+Each transform wraps an upstream any_buffer_source, and pull() is a coroutine
+so it can co_await the upstream source.
+*/

As per coding guidelines, Files containing non-trivial implementation logic should include a /* */ block comment after the includes that provides a high-level overview of how the implementation works.

Comment on lines +10 to +15
#include <boost/capy.hpp>
#include <iostream>
#include <string>
#include <array>
#include <vector>

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add a short file overview after the includes.
This example has non-trivial demonstration logic; a brief /* */ summary will help readers orient quickly.
As per coding guidelines: Files containing non-trivial implementation logic should include a /* */ block comment after the includes that provides a high-level overview of how the implementation works.

🤖 Prompt for AI Agents
In `@example/buffer-composition/buffer_composition.cpp` around lines 10 - 15, Add
a short C-style block comment immediately after the includes in
buffer_composition.cpp that gives a high-level overview of the file: describe
the purpose (buffer composition/demo), the main data structures used
(std::array, std::vector), key functions or flow (initialization,
composition/merging step, and output/logging), and any non-trivial algorithmic
steps readers should know (e.g., how buffers are combined or indexed). Keep it
concise (2–4 sentences) so someone scanning the file can quickly understand the
implementation and where to look (e.g., main or any compose/merge functions).

Comment on lines +10 to +19
#include <boost/capy.hpp>
#include <boost/capy/test/run_blocking.hpp>
#include <boost/capy/test/stream.hpp>
#include <boost/capy/test/fuse.hpp>
#include <boost/capy/cond.hpp>
#include <iostream>
#include <vector>
#include <cassert>
#include <cstring>

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add a file-level overview after the includes.
This file is non-trivial; a brief /* */ summary will help maintainers understand the buffer design and demo flow.
As per coding guidelines: Files containing non-trivial implementation logic should include a /* */ block comment after the includes that provides a high-level overview of how the implementation works.

🤖 Prompt for AI Agents
In `@example/custom-dynamic-buffer/custom_dynamic_buffer.cpp` around lines 10 -
19, Add a file-level /* ... */ overview comment immediately after the includes
in custom_dynamic_buffer.cpp that briefly describes the custom dynamic buffer
design and the demo flow; mention key concepts such as how the buffer
grows/shrinks, ownership/aliasing rules, thread/async expectations, and how the
demo exercises it via boost::capy test utilities (references:
boost/capy/test/run_blocking, boost/capy/test/stream, boost/capy/test/fuse).
Keep the comment concise (a few sentences) and focused on high-level
architecture and what readers should expect from the example.

Comment on lines +10 to +18
build-project hello-task ;
build-project producer-consumer ;
build-project buffer-composition ;
build-project mock-stream-testing ;
build-project type-erased-echo ;
build-project timeout-cancellation ;
build-project parallel-fetch ;
build-project custom-dynamic-buffer ;
build-project stream-pipeline ;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Missing echo-server-corosio subproject.

The README documents echo-server-corosio as an example, but it's not listed here. If this is intentional (due to the Corosio dependency), consider adding a comment explaining the omission. Otherwise, add the missing entry:

 build-project stream-pipeline ;
+build-project echo-server-corosio ;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
build-project hello-task ;
build-project producer-consumer ;
build-project buffer-composition ;
build-project mock-stream-testing ;
build-project type-erased-echo ;
build-project timeout-cancellation ;
build-project parallel-fetch ;
build-project custom-dynamic-buffer ;
build-project stream-pipeline ;
build-project hello-task ;
build-project producer-consumer ;
build-project buffer-composition ;
build-project mock-stream-testing ;
build-project type-erased-echo ;
build-project timeout-cancellation ;
build-project parallel-fetch ;
build-project custom-dynamic-buffer ;
build-project stream-pipeline ;
build-project echo-server-corosio ;
🤖 Prompt for AI Agents
In `@example/Jamfile` around lines 10 - 18, The Jamfile currently lists example
subprojects but omits the README-referenced echo-server-corosio; either add the
missing entry "build-project echo-server-corosio ;" to the list (so the example
is included) or, if omission is intentional due to the Corosio dependency, add a
short comment in the Jamfile near the project list explaining why
echo-server-corosio is excluded (referencing the README entry for clarity).
Ensure the change is made in the same project-list block where build-project
hello-task, producer-consumer, etc. are declared.

Comment on lines 10 to 14
#include <boost/capy.hpp>
#include <iostream>
#include <string>

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add a short file overview after the includes.
This example is non-trivial and benefits from a brief /* */ summary of the demo flow.
As per coding guidelines: Files containing non-trivial implementation logic should include a /* */ block comment after the includes that provides a high-level overview of how the implementation works.

🤖 Prompt for AI Agents
In `@example/parallel-fetch/parallel_fetch.cpp` around lines 10 - 13, Add a
C-style block comment immediately after the include section that gives a short
high-level overview of the demo in parallel_fetch.cpp: describe the purpose of
the example, the main flow (how the program initializes the parallel fetcher,
spawns worker tasks/threads, dispatches fetch jobs, and collects results), note
key components and APIs used (e.g., boost::capy usage, any ThreadPool/worker
abstractions or main()), and mention error handling and expected output so
readers can quickly understand the implementation before diving into code.

thread_pool pool(4);

// Create acceptor
tcp::endpoint endpoint(tcp::v4(), port);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are we still using the tcp:: namespace?


// Create acceptor
tcp::endpoint endpoint(tcp::v4(), port);
tcp::acceptor acceptor(ioc, endpoint);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this can't be right, I renamed it

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the one example not yet working- this is still the raw slop and I can't currently try to compile it. Even though it is a capy example I need to move it to the corosio examples folder to avoid a circular build dependency between capy and corosio.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@example/custom-dynamic-buffer/custom_dynamic_buffer.cpp`:
- Around line 10-103: The code uses std::min in tracked_buffer::consume but
doesn't include <algorithm>, so add `#include` <algorithm> alongside the other
includes at the top of the file so std::min is defined (this affects
tracked_buffer::consume and any other uses of std::min in this translation
unit); keep the include with the existing header block for consistency.
🧹 Nitpick comments (1)
example/echo-server-corosio/echo_server.cpp (1)

88-95: Consider handling potential exception from remote_endpoint().

If the socket disconnects between async_accept returning and calling remote_endpoint(), this can throw. While unlikely in practice, wrapping this in a try-catch would be more defensive.

💡 Suggested defensive handling
         // Build client info string
-        auto remote = socket.remote_endpoint();  // tcp::endpoint
-        std::string client_info = 
-            std::to_string(++connection_id) + ":" +
-            remote.address().to_string() + ":" +
-            std::to_string(remote.port());
+        std::string client_info;
+        try
+        {
+            auto remote = socket.remote_endpoint();
+            client_info = 
+                std::to_string(++connection_id) + ":" +
+                remote.address().to_string() + ":" +
+                std::to_string(remote.port());
+        }
+        catch (...)
+        {
+            client_info = std::to_string(++connection_id) + ":unknown";
+        }

Comment on lines +10 to +103
#include <boost/capy.hpp>
#include <boost/capy/test/run_blocking.hpp>
#include <boost/capy/test/stream.hpp>
#include <boost/capy/test/fuse.hpp>
#include <boost/capy/cond.hpp>
#include <iostream>
#include <vector>
#include <cassert>
#include <cstring>

using namespace boost::capy;

// Custom dynamic buffer with statistics tracking
class tracked_buffer
{
std::vector<char> storage_;
std::size_t read_pos_ = 0; // Start of readable data
std::size_t write_pos_ = 0; // End of readable data
std::size_t max_size_;

// Statistics
std::size_t total_prepared_ = 0;
std::size_t total_committed_ = 0;
std::size_t total_consumed_ = 0;

public:
explicit tracked_buffer(std::size_t max_size = 65536)
: max_size_(max_size)
{
storage_.reserve(1024);
}

// === DynamicBuffer interface ===

// Consumer: readable data
const_buffer data() const noexcept
{
return const_buffer(
storage_.data() + read_pos_,
write_pos_ - read_pos_);
}

// Capacity queries
std::size_t size() const noexcept
{
return write_pos_ - read_pos_;
}

std::size_t max_size() const noexcept
{
return max_size_;
}

std::size_t capacity() const noexcept
{
return storage_.capacity() - read_pos_;
}

// Producer: prepare space for writing
mutable_buffer prepare(std::size_t n)
{
total_prepared_ += n;

// Compact if needed
if (storage_.size() + n > storage_.capacity() && read_pos_ > 0)
{
compact();
}

// Grow if needed
std::size_t required = write_pos_ + n;
if (required > max_size_)
throw std::length_error("tracked_buffer: max_size exceeded");

if (required > storage_.size())
storage_.resize(required);

return mutable_buffer(
storage_.data() + write_pos_,
n);
}

// Producer: mark bytes as written
void commit(std::size_t n)
{
total_committed_ += n;
write_pos_ += n;
}

// Consumer: mark bytes as processed
void consume(std::size_t n)
{
std::size_t actual = std::min(n, size()); // std::size_t
total_consumed_ += actual;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# Check if the file exists and inspect the includes and the line with std::min
if [ -f "example/custom-dynamic-buffer/custom_dynamic_buffer.cpp" ]; then
  echo "=== File exists. First 15 lines (includes section) ==="
  head -n 15 "example/custom-dynamic-buffer/custom_dynamic_buffer.cpp"
  echo ""
  echo "=== Line 102 context (lines 100-105) ==="
  sed -n '100,105p' "example/custom-dynamic-buffer/custom_dynamic_buffer.cpp"
  echo ""
  echo "=== Checking for `#include` <algorithm> ==="
  grep -n "#include <algorithm>" "example/custom-dynamic-buffer/custom_dynamic_buffer.cpp" || echo "No direct include of <algorithm> found"
else
  echo "File does not exist at expected path"
  echo "Searching for the file..."
  find . -name "custom_dynamic_buffer.cpp" 2>/dev/null
fi

Repository: cppalliance/capy

Length of output: 869


Include <algorithm> for std::min.

Line 102 uses std::min, which requires <algorithm>. The current includes do not directly include this header, relying instead on transitive includes that may not be available on stricter toolchains.

Proposed fix
 `#include` <boost/capy/cond.hpp>
 `#include` <iostream>
 `#include` <vector>
 `#include` <cassert>
 `#include` <cstring>
+#include <algorithm>
🤖 Prompt for AI Agents
In `@example/custom-dynamic-buffer/custom_dynamic_buffer.cpp` around lines 10 -
103, The code uses std::min in tracked_buffer::consume but doesn't include
<algorithm>, so add `#include` <algorithm> alongside the other includes at the top
of the file so std::min is defined (this affects tracked_buffer::consume and any
other uses of std::min in this translation unit); keep the include with the
existing header block for consistency.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@example/custom-dynamic-buffer/custom_dynamic_buffer.cpp`:
- Around line 191-194: The program's main() currently calls
demo_tracked_buffer() without catching exceptions; wrap the
demo_tracked_buffer() invocation in a try/catch that catches std::length_error
and std::system_error (and a generic std::exception fallback), log or print the
error message including exception.what(), and return a non-zero exit code on
failure so buffer.prepare(...) and read_into_tracked_buffer() exceptions are
handled gracefully. Ensure you reference main() and demo_tracked_buffer() and
include explicit handling for std::length_error (from buffer.prepare) and
std::system_error (from read_into_tracked_buffer) plus a final catch-all.

In `@example/producer-consumer/producer_consumer.cpp`:
- Around line 17-21: Add a file-level overview block comment immediately after
the includes in producer_consumer.cpp that summarizes the producer-consumer
implementation, its threading/strand and synchronization approach (e.g., use of
boost::capy/ex::strand, std::latch), and the high-level flow of data between
producer and consumer; place this /* ... */ comment after the existing include
lines (including boost/capy.hpp, boost/capy/ex/strand.hpp, iostream, latch) so
readers get a concise explanation of the file's purpose and design.
🧹 Nitpick comments (2)
example/type-erased-echo/echo.cpp (1)

26-27: Inline comments describe "what" rather than "why".

The comments "Read some data" and "Echo it back" restate what the code does. Per guidelines, inline comments should explain the why when non-obvious. However, for example/tutorial code intended to teach library usage, these descriptive comments can aid readability for newcomers—so this is acceptable here.

Also applies to: 36-37

example/timeout-cancellation/timeout_cancellation.cpp (1)

121-139: Consider calling process_items() in a demo or adding a note.

This function demonstrates manual stop token checking but is never called. Consider either:

  • Adding a demo that exercises it, or
  • Adding a comment noting it's provided as a reference pattern for readers

Comment on lines +191 to +194
int main()
{
demo_tracked_buffer();
return 0;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

find . -name "custom_dynamic_buffer.cpp" -type f

Repository: cppalliance/capy

Length of output: 117


🏁 Script executed:

wc -l ./example/custom-dynamic-buffer/custom_dynamic_buffer.cpp

Repository: cppalliance/capy

Length of output: 121


🏁 Script executed:

cat -n ./example/custom-dynamic-buffer/custom_dynamic_buffer.cpp

Repository: cppalliance/capy

Length of output: 6469


Handle exceptions at the entry point to avoid std::terminate.

demo_tracked_buffer() can throw exceptions: buffer.prepare(256) may throw std::length_error (line 82), and read_into_tracked_buffer() throws std::system_error on read errors (line 153). Unhandled exceptions in main() cause program termination. Wrap the call in try/catch and return non-zero on failure.

🛡️ Suggested fix
 int main()
 {
-    demo_tracked_buffer();
-    return 0;
+    try
+    {
+        demo_tracked_buffer();
+        return 0;
+    }
+    catch (...)
+    {
+        std::cerr << "tracked_buffer demo failed\n";
+        return 1;
+    }
 }
🧰 Tools
🪛 Cppcheck (2.19.0)

[error] 193-193: Unhandled exception thrown in function that is an entry point.

(throwInEntryPoint)

🤖 Prompt for AI Agents
In `@example/custom-dynamic-buffer/custom_dynamic_buffer.cpp` around lines 191 -
194, The program's main() currently calls demo_tracked_buffer() without catching
exceptions; wrap the demo_tracked_buffer() invocation in a try/catch that
catches std::length_error and std::system_error (and a generic std::exception
fallback), log or print the error message including exception.what(), and return
a non-zero exit code on failure so buffer.prepare(...) and
read_into_tracked_buffer() exceptions are handled gracefully. Ensure you
reference main() and demo_tracked_buffer() and include explicit handling for
std::length_error (from buffer.prepare) and std::system_error (from
read_into_tracked_buffer) plus a final catch-all.

Comment on lines +17 to +21
#include <boost/capy.hpp>
#include <boost/capy/ex/strand.hpp>
#include <iostream>
#include <latch>

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add the required file-level overview block after the includes.

This file has non-trivial implementation logic and should include a brief /* */ overview immediately after the includes.

Suggested fix
 `#include` <boost/capy.hpp>
 `#include` <boost/capy/ex/strand.hpp>
 `#include` <iostream>
 `#include` <latch>

+/* High-level overview:
+   - Runs producer/consumer coroutines on a strand-backed thread_pool.
+   - Signals readiness via async_event and synchronizes completion with std::latch.
+*/

As per coding guidelines: Files containing non-trivial implementation logic should include a /* */ block comment after the includes that provides a high-level overview of how the implementation works.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
#include <boost/capy.hpp>
#include <boost/capy/ex/strand.hpp>
#include <iostream>
#include <latch>
`#include` <boost/capy.hpp>
`#include` <boost/capy/ex/strand.hpp>
`#include` <iostream>
`#include` <latch>
/* High-level overview:
- Runs producer/consumer coroutines on a strand-backed thread_pool.
- Signals readiness via async_event and synchronizes completion with std::latch.
*/
🤖 Prompt for AI Agents
In `@example/producer-consumer/producer_consumer.cpp` around lines 17 - 21, Add a
file-level overview block comment immediately after the includes in
producer_consumer.cpp that summarizes the producer-consumer implementation, its
threading/strand and synchronization approach (e.g., use of
boost::capy/ex::strand, std::latch), and the high-level flow of data between
producer and consumer; place this /* ... */ comment after the existing include
lines (including boost/capy.hpp, boost/capy/ex/strand.hpp, iostream, latch) so
readers get a concise explanation of the file's purpose and design.

@MungoG MungoG merged commit 18aa8a8 into cppalliance:develop Feb 4, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants