nfx-stringbuilder

License: MIT GitHub release (latest by date) GitHub tag (latest by date)

C++20 CMake Cross Platform

Linux GCC Linux Clang Windows MinGW Windows MSVC CodeQL

A cross-platform C++20 high-performance string builder with Small Buffer Optimization and efficient memory management

Overview

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.

Key Features

🛠️ Rich String Building Interface

📊 Real-World Applications

⚡ Performance Optimized

🌍 Cross-Platform Support

Quick Start

Requirements

CMake Integration

# --- 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)

Using in Your Project

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)

Option 2: As a Git Submodule

# 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)

Option 3: Using find_package (After Installation)

find_package(nfx-stringbuilder REQUIRED)
target_link_libraries(your_target PRIVATE nfx-stringbuilder::static)

Building

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

Documentation

nfx-stringbuilder includes API documentation generated with Doxygen.

📚 Online Documentation

The complete API documentation is available online at: https://nfx-libs.github.io/nfx-stringbuilder

Building Documentation Locally

# Configure with documentation enabled
cmake .. -DCMAKE_BUILD_TYPE=Release -DNFX_STRINGBUILDER_BUILD_DOCUMENTATION=ON

# Build the documentation
cmake --build . --target nfx-stringbuilder-documentation

Requirements

Accessing Local Documentation

After building, open ./build/doc/html/index.html in your web browser.

Usage Examples

Basic String Building

#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;
}

Efficient String Concatenation

#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();
}

Working with Different String Types

#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"
}

Numeric Type Support

#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"
}

format() Method Integration

#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"
}

C++20 std::formatter Integration

#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);
}

Capacity Hints for Pre-allocation

#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
}

Direct Buffer Manipulation

#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();
}

Multi-threaded Usage

#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

Installation & Packaging

nfx-stringbuilder provides comprehensive packaging options for distribution.

Package Generation

# 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

Supported Package Formats

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

Installation

# 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/

Project Structure

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

Performance

For detailed performance metrics and benchmarks, see:

Roadmap

See TODO.md for upcoming features and project roadmap.

Changelog

See the CHANGELOG.md for a detailed history of changes, new features, and bug fixes.

License

This project is licensed under the MIT License.

Dependencies

Development Dependencies

All dependencies are automatically fetched via CMake FetchContent when building the library, tests, or benchmarks.


Updated on January 06, 2026