February 2025 Update Blog Post
Containers
Re-writing Containers
...what could be going wrong?
Sane C++ Libraries tag-line is "Platform Abstraction Libraries".
The main reason for that is that the project doesn't try or want to be a STL replacement.
There is an hard requirement not to depend on the Standard C++ Library because the standard totally disrespects one of the fundamental pillars of the project, namely Fast Compile Times.
In general STL-like containers may not be the best or most efficient abstraction in many cases.
Using them (or not) it's really an application choice that should not dictated by a Platform Abstraction library.
A lot of effort is often spent avoiding or at least reducing Containers usage in other Sane C++ Libraries API.
The problem is that Vector<T>
containers were used both by Strings
library and just as Buffers for File
and other libraries.
For this reason I've decided to re-write the entire set of Containers
with a few objectives
- Cleaning-up the quite messy and verbose code for
Vector<T>
andSmallVector<T>
andArray<T,N>
- Provide a base implementation that works for
char
buffers but concise enough to be included inFoundations
library. - Share as much code as possible to implement
Vector<T>
andSmallVector<T>
that are still inContainers
- Create a byte buffer implementation that should not leak in the headers
The results are quite satisfying, there is now a Buffer
and SmallBuffer<N>
that replace all Vector<char>
usages and are implemented in Foundation.cpp
file.
All the other Vector-like containers share most of the code and they're delivered as header only library as one can expect from a templated library.
Probably a next step could be evolving them to use custom memory allocators and arenas, but that will happen maybe in some future update.
This is the detailed list of commits:
- Containers: Handle edge case in copy insert
- Containers: Replace contains and find in Vector and Array using Span
- Containers: Rewrite Vector and Array using Segment
- DebugVisualizers: Add Buffer and SmallBuffer visualizers for lldb and natvis
- DebugVisualizers: Update String and SmallString visualizers
- DebugVisualizers: Update Vector and SmallVector visualizers for lldb and natvis
An these are the commits were some dependencies from Containers
have been removed
- File: Remove dependency from Containers library
- SerializationBinary: Replace Vector usages with Buffer
- Strings: Remove dependency from Containers library
- Http: Use Buffer instead of Vector in test
SC::Foundation
Changes in SC::Foundation
are connected to the ones just described in Containers, because Segment
class and Buffer
plus SmallBuffer
are all defined there.
Two classes, specifically TaggedUnion
and TaggedMap
have been moved to SC::FoundationExtra
.
The reason is that they're not used by any other library and feel a little bit too Modern C++
to deserve a place in Sane C++ Libraries.
- Foundation: Add Buffer and SmallBuffer
- Foundation: Add Segment::append overload for types convertible to T
- Foundation: Add function to register Memory globals
- Foundation: Move Assert code to a dedicated Internal file
- FoundationExtra: Move TaggedUnion and TaggedMap to FoundationExtra
SC::Build
SC::Build
is the self-hosted build system used by Sane C++ Libraries to generate test and example projects.
It's not needed to use the libraries, as they need no build system at all, but it's used when developing the libraries.
It's not ready for general use (yet!), but it's progressing towards getting there someday.
In this month the build definition API has been cleaned up a little bit, with preference towards using methods to configure the build rather than filling the data structure.
A new more precise flags resolution / merging system properly allows to override compile or link flags in configuration, so that they have priority over the ones set per-project.
It's also possible to set a compile flags for a specific set of files, including disabling warnings for them.
Result buildTestProject(const Parameters& parameters, Project& project)
{
project = {TargetType::ConsoleExecutable, TEST_PROJECT_NAME};
// All relative paths are evaluated from this project root directory.
project.setRootDirectory(parameters.directories.libraryDirectory.view());
// Project Configurations
project.addPresetConfiguration(Configuration::Preset::Debug, parameters);
project.addPresetConfiguration(Configuration::Preset::Release, parameters);
project.addPresetConfiguration(Configuration::Preset::DebugCoverage, parameters);
// Defines
// $(PROJECT_ROOT) expands to Project::setRootDirectory expressed relative to $(PROJECT_DIR)
project.addDefines({"SC_LIBRARY_PATH=$(PROJECT_ROOT)", "SC_COMPILER_ENABLE_CONFIG=1"});
// Includes
project.addIncludePaths({
".", // Libraries path (for PluginTest)
"Tests/SCTest", // SCConfig.h path (enabled by SC_COMPILER_ENABLE_CONFIG == 1)
});
addSaneCppLibraries(project, parameters);
project.addFiles("Tests/SCTest", "*.cpp"); // add all .cpp from SCTest directory
project.addFiles("Tests/SCTest", "*.h"); // add all .h from SCTest directory
project.addFiles("Tools", "SC-*.cpp"); // add all tools
project.addFiles("Tools", "*.h"); // add tools headers
project.addFiles("Tools", "*Test.cpp"); // add tools tests
// This is a totally useless per-file define to test "per-file" flags SC::Build feature.
SourceFiles specificFiles;
// For testing purposes let's create a needlessly complex selection filter for "SC Spaces.cpp"
specificFiles.addSelection("Tests/SCTest", "*.cpp");
specificFiles.removeSelection("Tests/SCTest", "SCTest.cpp");
// Add an useless define to be checked inside "SC Spaces.cpp" and "SCTest.cpp"
specificFiles.compile.addDefines({"SC_SPACES_SPECIFIC_DEFINE=1"});
specificFiles.compile.addIncludePaths({"../Directory With Spaces"});
// For testing purposes disable some warnings caused in "SC Spaces.cpp"
specificFiles.compile.disableWarnings({4100}); // MSVC only
specificFiles.compile.disableWarnings({"unused-parameter"}); // GCC and Clang
specificFiles.compile.disableClangWarnings({"reserved-user-defined-literal"}); // Clang Only
project.addSpecificFileFlags(specificFiles);
return Result(true);
}
This is the detailed list of commits:
- Build: Add basic support for disabling warnings on specific file
- Build: Basic support of "per-file" compile flags
- Build: Improve build definition API
- Build: Refactor Makefile backend
- Build: Refactor Xcode writer
- Build: Resolve compile / link options in project if not set on configuration
- Build: Simplify defining compile and link settings getting rid of TaggedUnion
- Build: Use TargetType to configure console executables or graphical application
Minor Changes
And as always here is the list of random fixes scattered around the library!
This is the detailed list of commits for all minor changes:
- Async: Remove variable length array in Linux backend
- AsyncStreams: Disable tests requiring ZLib on Windows ARM64
- CI: Compile also SCExample
- Everywhere: Fix some spelling errors
- Plugin: Add close method to PluginRegistry
- Plugin: Move StringHashFNV to PluginHash
- SCTest: More properly group tests by library they belong to
- Strings: Move implementations to internal
Full Changelog: release/2025/01...release/2025/02