Skip to content

arrp - Auto Returning Resource Pool

arrp (Auto Returning Resource Pool) is a lightweight, thread-safe, header-only C++23 resource pool library. It allows applications to manage and reuse scarce, expensive, or moveable resources seamlessly using RAII semantics.

  • Uses std::deque to store objects of type T.
  • Uses std::mutex to implement thread-safe access to the resources.
  • Uses lambdas to return the underlying resource to the std::deque.
  • A resource_pool<T> owns available resources, while borrowing returns a move-only resource_guard<T>.
  • Uses RAII via a helper class. When the guard goes out of scope or is destroyed, the borrowed resource is automatically returned to the pool for immediate reuse by other components or threads.

Key Features & Design Goals

RAII Resource Management

Resources return to the pool automatically when their resource_guard<T> is destroyed, eliminating leak vectors and manual cleanup logic.

Thread-Safe Pool Storage

Borrowing, seeding, clearing, capacity adjustments, and statistics gathering are thread-safe and internally synchronized via mutex locks.

On-Demand Factory Fallback

Register a factory callback to create resources on demand via try_borrow_create() whenever the pool runs dry.

JSON Diagnostics & Natvis

Integrates with nlohmann/json for detailed runtime pool statistics and includes native Natvis visualizers for Visual Studio and VS Code debugging.


Quick Start Examples

#include <siddiqsoft/arrp.hpp>
#include <string>
#include <iostream>

int main()
{
    // Construct a pool with an initial capacity of 8
    siddiqsoft::arrp::resource_pool<std::string> pool {8};

    // Seed available resources into the pool
    pool.seed("connection-1");
    pool.seed("connection-2");

    {
        // Borrow a resource from the pool (FIFO order)
        auto resource = pool.try_borrow();
        if (resource) {
            resource->append(" [active]");
            std::cout << "Using resource: " << *resource << '\n';
        }
    } // 'resource' goes out of scope here; connection-1 returns to the pool automatically!

    return 0;
}
#include <siddiqsoft/arrp.hpp>
#include <memory>

struct DatabaseConnection {
    void query(const char* sql) {}
};

int main()
{
    siddiqsoft::arrp::resource_pool<std::unique_ptr<DatabaseConnection>> pool {4};

    // Register a factory callback for creating resources when pool is empty
    pool.set_factory_callback([]() {
        return std::make_unique<DatabaseConnection>();
    });

    // Tries to borrow existing resource, or creates a new one via factory
    auto conn = pool.try_borrow_create();
    if (conn) {
        conn->get()->query("SELECT 1;");
    }

    return 0;
}
#include <siddiqsoft/arrp.hpp>
#include <chrono>

using namespace std::chrono_literals;

void process(siddiqsoft::arrp::resource_pool<std::string>& pool)
{
    // Wait up to 250 milliseconds for a resource to become available
    auto guard = pool.try_borrow(250ms);
    if (!guard) {
        if (guard.error() == siddiqsoft::arrp::pool_error::Timeout) {
            // Handle timeout gracefully
        }
    }
}

System Requirements

Requirement Details
C++ Standard C++23 compiler (MSVC 2022+, GCC 13+, Clang 16+)
Resource Type (T) Must satisfy NonNumericMoveConstructible: move-constructible, move-assignable, non-arithmetic type.
Optional Dependencies nlohmann/json (required only when JSON statistics are enabled via to_json()).

Documentation Navigation

  • Features Overview: Explore resource lifecycle management, thread-safety, and JSON diagnostics.
  • Integration Guide: Learn how to add arrp using CMake FetchContent, NuGet, or direct headers.
  • Examples Overview: Explore complete runnable examples in the repository examples/ directory.
  • API Reference: Complete detailed documentation of all classes, methods, enums, and concept constraints.
  • License: Project license details (BSD 3-Clause).