Sun 30 November 2025

🌫️ Sane C++ November 25

SC

Welcome to the November 2025 update!
This month, focus is bringing the long neglected Http library out of its initial Draft state!

Http

The Http library was initially put together in a hurry for the first release of Sane C++ Libraries almost two years ago. Since then, it has remained largely unchanged, a simple Draft that was just enough to demonstrate a basic asynchronous web server.

While useful, its minimal implementation and lack of comprehensive tests meant it was often fragile, breaking as other parts of the ecosystem evolved. The time has come to give Http the attention it deserves and begin the long process of elevating it to a more robust state.

The first steps on this journey involve reducing its footprint by removing now-unnecessary dependencies on Containers and Time. Concurrently, Http is being refactored to leverage the AsyncStreams abstraction instead of dealing with raw socket operations. The next step is to remove the Memory dependency, leaving AsyncStreams as its sole dependency and solidifying its foundation.

Detailed list of commits:

AsyncStreams

As is often the case, improvements in one library drive the evolution of another. The work on Http exposed some limitations in AsyncStreams.

Previously, AsyncStreams was strict, only allowing data from its own pre-allocated buffers. This is great for managing memory with a fixed budget, but Http needed more flexibility. It required the ability to handle data from other subsystems without forcing a copy.

To accommodate this, the buffer system in AsyncStreams is now a hybrid model. It now supports read-only buffers and IGrowableBuffer-based views, where the memory lifetime is managed by the caller. This change, along with several bug fixes to the stream's state machine, makes AsyncStreams more powerful and flexible, ready for the more complex scenarios that the evolving Http library will demand.

Detailed list of commits:

Async

Stress-testing the new Http and AsyncStreams integration revealed some subtle edge cases in the core Async library.

For instance, on Windows, IOCP cancellations can return ERROR_NOT_FOUND if no cancellation was queued, which shouldn't be treated as a critical error by higher-level abstractions.

More critically, a re-entrancy bug was discovered. Calling the event loop's runOnce method from within a callback could cause the same callback to be invoked again before it had been fully torn down. A new internal flag, Flag_NeedsTeardown, now prevents the same completion from being incorrectly called multiple times.

Detailed list of commits:

Tools

The ToolsBootstrap utility, which replaces the old bootstrap Makefiles, has received some bug fixes and feature enhancements.

This tool was largely coded with AI assistance, and in an interesting experiment, it was automatically translated from C++ to C. Why? To get even faster compilation times. While the C++ version was already quick, the C version is faster, and the translation was surprisingly low-effort. So... here it is!

Detailed list of commits:

Build

SC::Build is steadily maturing. This month, it gained the ability to specify coverage exclusion regexes directly in the SC-Build.cpp file. Additionally, the generated Makefile targets are now smarter, automatically attempting a clean rebuild if a No rule to make target error occurs.

Detailed list of commits:

Others

As with every month, there are numerous small fixes and improvements that don't need their own section but are worth mentioning.

A fix for pipe reads on Windows was added to File, and the Function template now has a user-configurable LAMBDA_SIZE to help avoid heap allocations for closures. Console gained methods for printing to stderr, and the limitations of FileSystemWatcher are now better documented thanks to a community-filed issue.

All these small changes are great indicators of the libraries maturing and hardening over time!

Detailed list of commits: