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()
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*()
Dereferences wrapped resource.
Returns: Reference to the wrapped resource.
Example:
auto res = pool.checkout();
(*res).doSomething();
operator T&()
Implicit conversion to resource reference.
Example:
auto res = pool.checkout();
T& ref = res;
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();
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,
AutoGrow
};
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:
resource_pool<Resource> pool1;
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
- Always use RAII: Let scoped_resource handle resource return
- Factory callbacks: Only create and return resources, never call resource_pool methods
- Exception handling: Catch std::runtime_error from checkout()
- Resource types: Prefer shared_ptr or unique_ptr over raw pointers
- Monitoring: Use to_json() to track pool utilization
- Thread safety: No external synchronization needed
- 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