Single File Libraries
One of the core principles of this project is to be "Easy to Integrate".
I'm always looking for ways to lower the barrier to entry for using these libraries in your own projects.
To that end, I'm happy to announce that all Sane Cpp Libraries are now available as single-file libraries!
This means you can now get the power of a library like SC::Async
or SC::Process
by simply dropping a single .h
file into your project.
No complex build system integration, no scripts to runβjust include the header and build the source file. It's that simple.
There are two amalgamator tools written in Python and Javascript, that you can use to generate the single file libs locally on a checked out copy of the repo. Alternatively you can use the browser-based JavaScript amalgamator available at single_file_libs.html.
Detailed list of commits:
- SingleFileLibs/Javascript: Add javascript single file libs amalgamator (in-browser + cli)
- SingleFileLibs/Python: Add python single file libs amalgamator
- SingleFileLibs/Python: Print total lines of code at the end of library tables
Threading
The Threading
library received some love this month and has now been promoted to Usable status!
Here are some of the key additions:
SC::Semaphore
: A classic semaphore for controlling access to a resource.SC::Barrier
: A synchronization primitive that allows a set of threads to wait for each other to reach a certain point before continuing.SC::RWLock
: A reader-writer lock that allows concurrent access for read-only operations, but exclusive access for write operations.Atomic<T>
improvements: The atomic types have been improved with more operations and better memory ordering support for MSVC.
I also fixed a tricky "lost wake-up" bug in EventObject
's condition variable signaling, which improves the robustness of thread synchronization.
Detailed list of commits:
- Threading: Add Barrier
- Threading: Add RWLock
- Threading: Add Semaphore
- Threading: Improve Atomic
and Atomic - Threading: Prevent EventObject lost wake-up and fix Mutex destructor
- Threading: Promote Threading to Usable
Async
The Async
library received several important fixes, particularly for the io_uring
backend on Linux and the IOCP backend on Windows.
These changes improve the reliability and prevent potential hangs or asserts when dealing with asynchronous file and pipe operations.
Detailed list of commits:
- Async: Allow re-using AsyncProcessExit on Linux under io_uring
- Async: Do not expect IOCP cancellation packet if AsyncFilePoll handle is already closed
- Async: Do not process AsyncFilePoll cancellations on io_uring backend
- Async: Handle file descriptor read or write succeeding synchronously on Windows
- Async: Re-organize files for more effective unity build
- Async: Support async pipe non-blocking reads
- Async: Test synchronous pipe reads from ThreadPool
AsyncStreams
AsyncStreams
has been promoted to MVP (Minimum Viable Product), meaning its core feature set is in place for concurrently reading, writing, and transforming byte streams.
Detailed list of commits:
- AsyncStreams: Add async request test variation for blocking and non-blocking pipes
- AsyncStreams: Process leftover input bytes before finalizing zlib stream
- AsyncStreams: Promote AsyncStreams to MVP
Algorithms
The Algorithms library has been removed, or to be more precise it has been merged to Containers.
The reason is pretty simple, I am not a great fan of using std-like algorithms aside from very simple usages.
I find that any non-trivial usage of std C++ <algorithm>
make code more difficult to read and reason about.
For this reason Sane C++ Algorithms
library was only bringing 3 functions (removeIf
, sort
and find
) so it made really little sense.
If you need std-like algorithms, just include <algorithm>
or add some other library providing them to your project.
Detailed list of commits:
Process
Process library has been improved with arguments quoting on Windows. There's now better support for redirecting standard I/O and better support for ipc pipes in general, that has also involved the File library.
Detailed list of commits:
- Process: Automatically set child process standard IO inherit flags
- Process: Check the correct variable before assigning environmentMemory
- Process: Increment environment storage to 16K chars
- Process: Quote arguments on Windows with any UTF encoding
- Process: Validate external pipes used to redirect child process IO
Strings
The Path
and StringBuilder
classes now have better support for to handle UTF8 and UTF16 encodings.
Throughout the libraries the philosophy is to keep strings in whatever encoding they've been given.
Strings are lazy converted only when required by some OS API and in some cases this could lead to hitting asserts due to unsupported encodings.
Detailed list of commits:
- Strings: Check for null iterator before calling memchr
- Strings: Remove StringView::slice methods using bytes
- Strings: Support mixed encodings in Path
- Strings: Support mixed encodings in StringBuilder::appendReplaceAll
- Strings: Support mixed encodings in StringView::split{Before | After}
Build
The self-hosted C++ build system can now generate workspace files that group multiple projects. This has been done to support testing compilation of the Single File Libs in the CI, but it can be useful in general.
If absolute paths are used when adding files to a project, they will be automatically made relative to the project root directory.
Some better checking in makefile generation has been added, to avoid trying to build non-existing configurations.
Detailed list of commits:
- Build: Automatically compute relative paths when required for files
- Build: Generate workspace files grouping multiple projects
- Build: Print error when an unsupported configuration is requested
File
The file library gains methods to open stdin / stderr and stdout cross-platform.
Also the API for Pipe has been changed to make sure properly setting inheritable and blocking flags during creation, as in some platforms (Windows) some of these behaviors cannot be changed later (mainly setting OVERLAPPED_IO flags).
Detailed list of commits:
- File: Add methods to open stdin / stderr / stdout
- File: Enforce setting inheritable and blocking flags during pipe creation
Other Improvements
Beyond these major updates, August included a bunch of other fixes:
- CI: The continuous integration pipeline now automatically generates and builds the single-file libraries to ensure they are always up-to-date and working correctly.
- Dependencies: The LOC update is handled by the Python amalgamator script and the dependency .json generator is a separate script
- Everywhere: Fix some warnings under clang-cl and ASAN warning about using out of scope stack memory for FileSystemIterator
- Tools: Generate PDBs on windows so that tools can be debugged
Detailed list of commits:
- CI: Add single file libs generation and build
- CI: Always apt-get update before apt-get install
- Dependencies: Add script to just update library dependencies
- Documentation: Update LOC for all libraries
- Everywhere: Declare FileSystemIterator::FolderState before FileSystemIterator
- Everywhere: Fix clang-cl warnings and unity build issues
- Everywhere: Remove nodiscard when used with Result
- FileSystem: Fix conversion of precise error messages
- Plugin: Propagate host executable sanitization flags
- Testing: Enforce TestReport not printing anything under quiet mode
- Tools: Generate PDB when building tools on Windows
- Tools: Run SC-format with default event loop backend
- Tools: Update 7zr to 25.01