A cross-platform C++20 high-performance string builder with Small Buffer Optimization and efficient memory management
nfx-stringbuilder is a modern C++20 library providing efficient string building capabilities with zero heap allocations for small strings (≤256 bytes). Designed for applications requiring high-performance string concatenation with minimal allocations, it features Small Buffer Optimization (SBO), comprehensive type support, and C++20 std::format integration.
<<) for natural concatenationformat() method for modern formattingstd::format for StringBuilderstring_view access without allocation# --- Library build types ---
option(NFX_STRINGBUILDER_BUILD_STATIC "Build static library" ON )
option(NFX_STRINGBUILDER_BUILD_SHARED "Build shared library" OFF)
# --- Build components ---
option(NFX_STRINGBUILDER_BUILD_TESTS "Build tests" OFF)
option(NFX_STRINGBUILDER_BUILD_SAMPLES "Build samples" OFF)
option(NFX_STRINGBUILDER_BUILD_BENCHMARKS "Build benchmarks" OFF)
option(NFX_STRINGBUILDER_BUILD_COMPARATIVE_BENCHMARKS "Build comparative benchmarks" OFF)
option(NFX_STRINGBUILDER_BUILD_DOCUMENTATION "Build Doxygen documentation" OFF)
# --- Installation ---
option(NFX_STRINGBUILDER_INSTALL_PROJECT "Install project" OFF)
# --- Packaging ---
option(NFX_STRINGBUILDER_PACKAGE_SOURCE "Enable source package generation" OFF)
option(NFX_STRINGBUILDER_PACKAGE_ARCHIVE "Enable TGZ/ZIP package generation" OFF)
option(NFX_STRINGBUILDER_PACKAGE_DEB "Enable DEB package generation" OFF)
option(NFX_STRINGBUILDER_PACKAGE_RPM "Enable RPM package generation" OFF)
option(NFX_STRINGBUILDER_PACKAGE_WIX "Enable WiX Windows installer (MSI)" OFF)
include(FetchContent)
FetchContent_Declare(
nfx-stringbuilder
GIT_REPOSITORY https://github.com/nfx-libs/nfx-stringbuilder.git
GIT_TAG main # or use specific version tag like "0.1.0"
)
FetchContent_MakeAvailable(nfx-stringbuilder)
# Link with static library
target_link_libraries(your_target PRIVATE nfx-stringbuilder::static)
# Add as submodule
git submodule add https://github.com/nfx-libs/nfx-stringbuilder.git third-party/nfx-stringbuilder
# In your CMakeLists.txt
add_subdirectory(third-party/nfx-stringbuilder)
target_link_libraries(your_target PRIVATE nfx-stringbuilder::static)
find_package(nfx-stringbuilder REQUIRED)
target_link_libraries(your_target PRIVATE nfx-stringbuilder::static)
Build Commands:
# Clone the repository
git clone https://github.com/nfx-libs/nfx-stringbuilder.git
cd nfx-stringbuilder
# Create build directory
mkdir build && cd build
# Configure with CMake
cmake .. -DCMAKE_BUILD_TYPE=Release
# Build the library
cmake --build . --config Release --parallel
# Run tests (optional)
ctest -C Release --output-on-failure
# Run benchmarks (optional)
./bin/benchmarks/BM_StringBuilder
nfx-stringbuilder includes API documentation generated with Doxygen.
The complete API documentation is available online at: https://nfx-libs.github.io/nfx-stringbuilder
# Configure with documentation enabled
cmake .. -DCMAKE_BUILD_TYPE=Release -DNFX_STRINGBUILDER_BUILD_DOCUMENTATION=ON
# Build the documentation
cmake --build . --target nfx-stringbuilder-documentation
After building, open ./build/doc/html/index.html in your web browser.
#include <nfx/string/StringBuilder.h>
using namespace nfx::string;
int main()
{
// Create a StringBuilder instance
StringBuilder builder;
// Build strings with fluent interface
builder.append("Hello")
.append(", ")
.append("World")
.append("!");
// Convert to std::string
std::string result = builder.toString();
// Output: "Hello, World!"
return 0;
}
#include <nfx/string/StringBuilder.h>
#include <vector>
using namespace nfx::string;
std::string buildReport(const std::vector<std::string>& items)
{
StringBuilder builder;
// Reserve capacity for better performance
builder.reserve(1024);
// Build header
builder.append("=== Report ===\n");
// Add items
for (size_t i = 0; i < items.size(); ++i)
{
builder.append("Item ")
.append(std::to_string(i + 1))
.append(": ")
.append(items[i])
.append("\n");
}
// Add footer
builder.append("Total items: ")
.append(std::to_string(items.size()));
return builder.toString();
}
#include <nfx/string/StringBuilder.h>
using namespace nfx::string;
void demonstrateStringTypes()
{
StringBuilder builder;
// std::string
std::string stdStr = "from std::string";
builder.append(stdStr)
.append(" | ");
// string_view (zero-copy)
std::string_view sv = "from string_view";
builder.append(sv)
.append(" | ");
// C-string
builder.append("from C-string")
.append(" | ");
// Single characters
builder.append('A')
.append('B')
.append('C');
std::string result = builder.toString();
// Output: "from std::string | from string_view | from C-string | ABC"
}
#include <nfx/string/StringBuilder.h>
using namespace nfx::string;
void demonstrateNumericTypes()
{
StringBuilder builder;
// Integer types
int32_t i32 = -42;
uint32_t u32 = 42;
int64_t i64 = -9223372036854775807LL;
uint64_t u64 = 18446744073709551615ULL;
builder.append("int32_t: ")
.append(i32) // Direct numeric append
.append(", uint32_t: ")
.append(u32)
.append(", int64_t: ")
.append(i64)
.append(", uint64_t: ")
.append(u64);
// Floating-point types
float f = 3.14159f;
double d = 2.718281828459045;
builder.append("\nfloat: ")
.append(f) // Direct numeric append
.append(", double: ")
.append(d);
std::string result = builder.toString();
// Output: "int32_t: -42, uint32_t: 42, int64_t: -9223372036854775807, uint64_t: 18446744073709551615
// float: 3.14159, double: 2.71828"
}
void demonstrateStreamOperators()
{
StringBuilder builder;
// Stream operators work with all numeric types
int value = 42;
double price = 19.99;
builder << "Product #" << value << " costs $" << price;
std::string result = builder.toString();
// Output: "Product #42 costs $19.99"
}
void demonstrateVariadicAppend()
{
StringBuilder builder;
// Append multiple arguments at once
int userId = 12345;
const char* userName = "alice";
int64_t timestamp = 1672531200;
builder.append("User ", userId, " (", userName, ") logged in at ", timestamp);
std::string result = builder.toString();
// Output: "User 12345 (alice) logged in at 1672531200"
}
#include <nfx/string/StringBuilder.h>
using namespace nfx::string;
void demonstrateFormatMethod()
{
StringBuilder builder;
// Using StringBuilder's format() method directly
builder.append("User: ");
builder.format("{} (ID: {:08})", "Alice", 123);
builder.append("\n");
// Format with floating-point precision
builder.append("Price: ");
builder.format("${:.2f}", 19.99);
builder.append("\n");
// Format with hex and binary
builder.append("Value: ");
builder.format("hex=0x{:X}, bin=0b{:b}", 255, 15);
std::string result = builder.toString();
// Output: "User: Alice (ID: 00000123)
// Price: $19.99
// Value: hex=0xFF, bin=0b1111"
}
void demonstrateFormatChaining()
{
StringBuilder builder;
// format() returns reference for chaining
builder.format("Name: {}", "Bob")
.append(" | ")
.format("Age: {}", 30)
.append(" | ")
.format("Score: {:.1f}", 95.7);
std::string result = builder.toString();
// Output: "Name: Bob | Age: 30 | Score: 95.7"
}
#include <nfx/string/StringBuilder.h>
#include <format>
using namespace nfx::string;
void demonstrateStdFormatter()
{
StringBuilder builder;
builder.append("Hello, ")
.append("World!");
std::string formatted = std::format("Result: {}", builder);
std::string bufferFormatted = std::format("Buffer content: {}", builder);
}
#include <nfx/string/StringBuilder.h>
using namespace nfx::string;
void demonstrateCapacityHints()
{
// Pre-allocate 2048 bytes to avoid reallocations
StringBuilder builder(2048);
// Build large strings without reallocation
for (int i = 0; i < 100; ++i)
{
builder.append("Item ")
.append(std::to_string(i))
.append(": Some long description text here\n");
}
std::string result = builder.toString();
// No heap reallocations occurred during building
}
#include <nfx/string/StringBuilder.h>
using namespace nfx::string;
void directBufferAccess()
{
StringBuilder builder;
// Append methods with chaining
builder.append("Direct ")
.append("buffer ")
.append("access")
.append('!');
// Get size and capacity
size_t size = builder.size(); // Current content size
size_t capacity = builder.capacity(); // Allocated capacity
// Zero-copy string_view access
std::string_view view = builder.toStringView();
// Iterator support
for (char c : builder)
{
// Process each character
}
// Clear for reuse
builder.clear();
}
#include <nfx/string/StringBuilder.h>
#include <thread>
#include <vector>
using namespace nfx::string;
void threadWorker(int threadId)
{
// Each thread creates its own StringBuilder instance
for (int i = 0; i < 100; ++i)
{
StringBuilder builder;
builder.append("Thread ")
.append(std::to_string(threadId))
.append(" - Iteration ")
.append(std::to_string(i));
std::string result = builder.toString();
// Process result...
}
}
void demonstrateMultithreading()
{
std::vector<std::thread> threads;
// Spawn multiple threads
for (int i = 0; i < 4; ++i)
{
threads.emplace_back(threadWorker, i);
}
// Wait for completion
for (auto& t : threads)
{
t.join();
}
std::cout << "All threads completed successfully\n";
}
Sample Output:
[INFO] User logged in: username=john.doe, ip=192.168.1.100, timestamp=2025-10-31
[ERROR] Connection failed: timeout after 30s
nfx-stringbuilder provides comprehensive packaging options for distribution.
# Configure with packaging options
cmake .. -DCMAKE_BUILD_TYPE=Release \
-DNFX_STRINGBUILDER_BUILD_STATIC=ON \
-DNFX_STRINGBUILDER_BUILD_SHARED=ON \
-DNFX_STRINGBUILDER_PACKAGE_ARCHIVE=ON \
-DNFX_STRINGBUILDER_PACKAGE_DEB=ON \
-DNFX_STRINGBUILDER_PACKAGE_RPM=ON
# Generate binary packages
cmake --build . --target package
# or
cd build && cpack
# Generate source packages
cd build && cpack --config CPackSourceConfig.cmake
| Format | Platform | Description | Requirements |
|---|---|---|---|
| TGZ/ZIP | Cross-platform | Compressed archive packages | None |
| DEB | Debian/Ubuntu | Native Debian packages | dpkg-dev |
| RPM | RedHat/SUSE | Native RPM packages | rpm-build |
| WiX | Windows | Professional MSI installer | WiX 3.11+ |
| Source | Cross-platform | Source code distribution (TGZ+ZIP) | None |
# Linux (DEB-based systems)
sudo dpkg -i nfx-stringbuilder_*_amd64.deb
# Linux (RPM-based systems)
sudo rpm -ivh nfx-stringbuilder-*-Linux.rpm
# Windows (MSI installer)
nfx-stringbuilder-0.1.0-MSVC.msi
# Manual installation (extract archive)
tar -xzf nfx-stringbuilder-*-Linux.tar.gz -C /usr/local/
nfx-stringbuilder/
├── benchmark/ # Performance benchmarks with Google Benchmark
├── cmake/ # CMake modules and configuration
├── include/nfx/ # Public headers
├── samples/ # Example usage and demonstrations
├── src/ # Implementation files
└── test/ # Comprehensive unit tests with GoogleTest
For detailed performance metrics and benchmarks, see:
See TODO.md for upcoming features and project roadmap.
See the CHANGELOG.md for a detailed history of changes, new features, and bug fixes.
This project is licensed under the MIT License.
All dependencies are automatically fetched via CMake FetchContent when building the library, tests, or benchmarks.
Updated on January 06, 2026