arrp is a header-only C++23 resource pool. A resource_pool<T> owns available
resources, while a move-only resource_guard<T> returns each borrowed resource
when the guard is destroyed.
- A C++23 compiler.
- A move-constructible, move-assignable, non-arithmetic resource type.
nlohmann/json.hpp, included beforesiddiqsoft/arrp.hpp, only when JSON statistics are needed.
include(FetchContent)
FetchContent_Declare(arrp
GIT_REPOSITORY https://github.com/SiddiqSoft/arrp.git
GIT_TAG master
)
FetchContent_MakeAvailable(arrp)
target_link_libraries(your_target PRIVATE arrp::arrp)nuget install SiddiqSoft.aarpAdd include/ to your compiler's include path and include:
#include <siddiqsoft/arrp.hpp>Seed the pool before using try_borrow():
#include <siddiqsoft/arrp.hpp>
#include <string>
int main()
{
siddiqsoft::arrp::resource_pool<std::string> pool {8};
pool.seed("resource-1");
{
auto resource = pool.try_borrow();
if (!resource) {
return 1;
}
resource->append("-in-use");
} // The resource returns to the pool.
}Resources are borrowed and returned in FIFO order. try_borrow() returns an
invalid guard with pool_error::NoMoreResources when no resource is available.
Pass a positive std::chrono::nanoseconds timeout to wait for a returned
resource; expiry returns pool_error::Timeout.
Register a factory and use try_borrow_create():
siddiqsoft::arrp::resource_pool<std::string> pool {8};
pool.set_factory_callback([] {
return std::string {"created-on-demand"};
});
auto resource = pool.try_borrow_create();
if (resource) {
// Use *resource.
}The factory takes no arguments and must return T or the pool's scoped resource
type. It must not call methods on the same pool. try_borrow() never invokes the
factory.
Call invalidate() when a resource is no longer reusable:
auto resource = pool.try_borrow();
if (resource) {
// Detect application-specific corruption here.
resource.invalidate();
}An invalid guard is discarded rather than returned. Moving the value out through
static_cast<T>(std::move(guard)) also invalidates the guard.
Borrowing, seeding, clearing, sizing, setting the factory callback, and JSON
statistics synchronize pool storage. Individual resource_guard instances are
not thread-safe. Do not let a guard outlive the pool that created it.
clear() removes resources currently available in the pool. Borrowed resources
can still return when their guards are destroyed. An optional cleanup callback
runs under the pool lock for every resource removed by clear() or destruction,
so it must not call pool methods.
The constructor capacity is clamped to 1 through 255 and is reported in
statistics, but it is not a hard insertion limit: seed() and a factory can add
more resources than the configured value.
To enable JSON statistics, include nlohmann JSON first:
#include <nlohmann/json.hpp>
#include <siddiqsoft/arrp.hpp>
#include <iostream>
auto stats = pool.to_json();
std::cout << stats.dump(2) << '\n';The statistics include available size, configured capacity, borrows,
returns, abandons, loans, seeded resources, and factory-created resources.
The repository includes a Natvis file at SiddiqSoft.arrp.natvis for Visual Studio and VS Code debugging. It provides richer views for resource_pool and resource_guard so their state can be inspected directly in the debugger.
When consuming the NuGet package, the Natvis file is packaged under the native build folder so MSBuild-based tooling can discover it automatically.
Full runnable example applications demonstrating various resource management patterns are available in the repository's examples/ folder:
- scoped_file: Demonstrates managing C
FILE*file handles using an RAII wrapper (ScopedFile) and a seededresource_pool. - scoped_curl: Demonstrates multi-threaded asynchronous HTTP requests with
libcurl(CURL*), dynamic factory creation withtry_borrow_create(), timeouts, and JSON telemetry reporting.
See the online Examples Guide for build instructions and walkthroughs.
cmake --fresh --preset=Apple-Debug
cmake --build --preset=Apple-Debug
ctest --preset=Apple-DebugBSD 3-Clause License. See LICENSE.