arrp 0.0.15
Auto returning resource pool for modern C++
Loading...
Searching...
No Matches
API Reference

Overview

Complete API reference for the ARRP (Auto Returning Resource Pool) library.

resource_pool Class

Thread-safe resource pool with automatic lifecycle management.

Template Parameters

template <typename T, typename SRT = scoped_resource<T>, uint8_t InitCapacity = DefaultCapacity>
class resource_pool
  • T: Resource type. Must be move-constructible and non-arithmetic.
  • SRT: Scoped resource wrapper type. Defaults to scoped_resource<T>.
  • InitCapacity: Initial capacity (max 255).

Constructors

Default Constructor

resource_pool(auto_add_policy add_policy = auto_add_policy::NoGrow);

Creates a pool with specified growth policy.

  • NoGrow: Throws when empty (default)
  • AutoGrow: Creates resources on demand

See auto_add_policy for available policies.

Custom Factory Constructor

resource_pool(std::function<SRT(resource_pool&)>&& new_resource_callback);

Creates a pool with custom resource factory callback.

Returns a scoped_resource wrapping the newly created resource.

Warning: Factory callbacks MUST NOT call any pool methods (would cause deadlock).

Methods

checkout()

[[nodiscard]] auto checkout() -> SRT;

Borrows a resource from the pool.

Returns: scoped_resource wrapper that automatically returns resource on destruction.

Throws: std::runtime_error if pool is at capacity and empty.

Thread Safety: Thread-safe. Resource creation happens outside lock.

Performance: O(1) amortized.

Exception Safety: Strong - if factory throws, checkout count is properly decremented.

See Also: scoped_resource for automatic resource management.

checkin()

void checkin(T&& raw_resource);

Returns a resource to the pool.

Note: Typically called automatically by scoped_resource destructor.

Thread Safety: Thread-safe.

Performance: O(1) amortized.

Exception Safety: noexcept.

size()

[[nodiscard]] size_t size() const noexcept;

Returns number of available resources in pool (excludes checked-out resources).

Thread Safety: Thread-safe.

Performance: O(1) with lock acquisition.

Exception Safety: noexcept.

clear()

void clear() noexcept;

Removes and destroys all resources in pool.

Note: Does not affect checked-out resources.

Thread Safety: Thread-safe.

Performance: O(n) where n is pool size.

Exception Safety: noexcept.

to_json()

nlohmann::json to_json() const;

Serializes pool state to JSON (requires nlohmann/json).

Returns: JSON object with:

  • capacity: Maximum resources
  • size: Available resources
  • load: Total resources (in pool + checked out)
  • checkedout: Currently checked out
  • counters: Operation statistics

Thread Safety: Thread-safe.

Performance: O(1) with lock acquisition.

scoped_resource Class

RAII wrapper for automatic resource return to pool. Implements the Resource Acquisition Is Initialization (RAII) pattern.

Template Parameters

  • T: Resource type. Must be move-constructible and non-arithmetic.

Constructors

Explicit Constructor

explicit scoped_resource(T&& src, std::function<void(T&&)>&& f = {});

Wraps resource with optional return callback.

Parameters:

  • src: R-value reference to the resource to wrap
  • f: Optional callback function invoked on destruction to return resource to pool

Note: Typically created by resource_pool::checkout().

Methods

operator*()

auto operator*() -> T&;

Dereferences wrapped resource.

Returns: Reference to the wrapped resource.

Example:

auto res = pool.checkout();
(*res).doSomething(); // Access via dereference

operator T&()

operator T&();

Implicit conversion to resource reference.

Example:

auto res = pool.checkout();
T& ref = res; // Implicit conversion

invalidate()

void invalidate();

Marks resource as invalid to prevent automatic return to pool.

Use Cases:

  • Resource has been moved out
  • Resource has been consumed
  • Custom resource management needed

Example:

auto res = pool.checkout();
auto extracted = std::move(*res);
res.invalidate(); // Don't return moved-out resource

Move Constructor

scoped_resource(scoped_resource&& src) noexcept;

Transfers ownership. Source becomes invalid.

Note: Ensures only one wrapper returns the resource to the pool.

Move Assignment

scoped_resource& operator=(scoped_resource&& src) noexcept;

Transfers ownership. Previous resource (if valid) is returned to pool.

Note: If this wrapper held a valid resource, it is returned to the pool before assignment.

Enumerations

auto_add_policy

enum class auto_add_policy {
NoGrow, // Throw when pool is empty
AutoGrow // Create resources on demand
};

Controls whether resource_pool automatically creates resources when empty.

Values:

  • NoGrow: Throws std::runtime_error when checkout() is called on empty pool
  • AutoGrow: Automatically creates new resources on demand up to capacity limit

Usage:

// NoGrow policy (default)
resource_pool<Resource> pool1;
// AutoGrow policy
resource_pool<Resource> pool2(auto_add_policy::AutoGrow);

Exceptions

All exceptions thrown by ARRP are of type std::runtime_error:

  • "No items in the pool; add something first." - checkout() on empty pool with NoGrow policy
  • "Pool Size:X checkedout:Y capacity:Z" - checkout() when at capacity and empty

Thread Safety

Guarantees:

  • All public methods of resource_pool are thread-safe
  • Multiple threads can safely call checkout() and checkin() concurrently
  • Internal mutexes protect shared state
  • Atomic counters for lock-free statistics
  • No external synchronization required

Performance:

  • Resource creation happens outside lock to minimize contention
  • Atomic operations for counters avoid lock overhead

Note: scoped_resource is not thread-safe by itself; thread safety is provided by resource_pool.

Performance Characteristics

Operation Complexity Notes
checkout() O(1) amortized Resource creation outside lock
checkin() O(1) amortized Simple push_back operation
size() O(1) With lock acquisition
clear() O(n) n = pool size
to_json() O(1) With lock acquisition

Memory Characteristics

  • Pool overhead: ~200 bytes (mutex, deque, counters, callback)
  • Per-resource overhead: ~40 bytes (deque node)
  • No dynamic allocations after initialization

Constraints

  • Capacity limited to 255 resources (uint8_t)
  • Factory callbacks must not call resource_pool methods
  • Resources must be move-constructible and non-arithmetic types
  • Counters wrap around after ~18 quintillion operations (uint64_t)

Exception Safety

  • checkout(): Strong - if factory throws, state remains consistent
  • checkin(): noexcept
  • clear(): noexcept
  • size(): noexcept
  • to_json(): Strong

Best Practices

  1. Always use RAII: Let scoped_resource handle resource return
  2. Factory callbacks: Only create and return resources, never call resource_pool methods
  3. Exception handling: Catch std::runtime_error from checkout()
  4. Resource types: Prefer shared_ptr or unique_ptr over raw pointers
  5. Monitoring: Use to_json() to track pool utilization
  6. Thread safety: No external synchronization needed
  7. Invalidation: Use invalidate() only when resource is moved out or consumed

Quick Links

  • resource_pool class - Main pool implementation
  • scoped_resource class - RAII wrapper
  • auto_add_policy enum - Growth policy control
  • Usage Guide - Practical examples and patterns