37#ifndef RESOURCE_POOL_HPP
38#define RESOURCE_POOL_HPP
42#include <shared_mutex>
46#include "siddiqsoft/RunOnEnd.hpp"
103 template <
typename T>
104 requires std::move_constructible<T>
112 uint64_t
debugId {
static_cast<uint64_t
>(std::rand())};
142 :
rsrc(std::move(src))
147 if constexpr (std::is_pointer_v<T>) {
148 std::cerr << std::format(
" - resource_wrap: debugId:{} {:p}\n",
debugId,
static_cast<void*
>(
rsrc));
150 else if constexpr (std::is_integral_v<T>) {
151 std::cerr << std::format(
" - resource_wrap: debugId:{} {}\n",
debugId,
rsrc);
154 std::cerr << std::format(
" - resource_wrap: debugId:{}\n",
debugId);
176 std::cerr << std::format(
" - resource_wrap: move into debugId:{}\n",
debugId);
178 rsrc = std::move(src);
197 auto operator*() -> T& {
return rsrc; }
225 std::cerr << std::format(
" - ~resource_wrap: putback debugId:{} isValid:{}\n",
debugId,
isValid);
260 void invalidate() {
isValid =
false; }
337 template <
typename T, u
int16_t InitCapacity = sizeof(u
int8_t)>
338 requires((InitCapacity <=
sizeof(uint16_t))) && std::move_constructible<T>
344 std::deque<T> _pool {};
348 std::mutex _poolLock {};
385 std::scoped_lock<std::mutex> l(_poolLock);
404 std::scoped_lock<std::mutex> l(_poolLock);
448 std::scoped_lock<std::mutex> l(_poolLock);
450 if (!_pool.empty()) {
451 RunOnEnd roe([&]() { _pool.pop_front(); });
457 auto autoReturnResource = [
this](T&& rsrc) {
458 this->checkin(std::move(rsrc));
461 return {std::move(_pool.front()), autoReturnResource};
467 throw std::runtime_error(
"Empty pool; add something first!");
508 void checkin(T&& rsrc)
510 std::scoped_lock<std::mutex> l(_poolLock);
511 _pool.push_back(std::move(rsrc));
auto size()
Get the current size of the pool.
resource_pool(resource_pool &&src)=default
Move constructor (defaulted) Allows moving a pool to a new location.
auto checkout() -> resource_wrap< T >
resource_pool & operator=(resource_pool &)=delete
Copy assignment operator (deleted - pools are not copyable).
resource_pool & operator=(resource_pool &&src)=default
Move assignment operator (defaulted).
resource_pool()=default
Default constructor Creates an empty pool ready to accept resources.
void clear()
Clear all items from the pool.
resource_pool(resource_pool &)=delete
Copy constructor (deleted - pools are not copyable) Each pool manages its own resources independently...
~resource_pool()
Destructor - clears all resources from the pool All remaining resources are destroyed.
uint64_t debugId
Debug identifier for tracking (used in DEBUG builds).
resource_wrap()=delete
Default constructor is deleted Resources must be explicitly constructed with a valid resource.
~resource_wrap()
Destructor - automatically returns resource to pool if valid.
resource_wrap & operator=(T &&src)
Move assignment operator.
bool isValid
Tracks whether the resource is valid and should be returned to pool Prevents returning uninitialized ...
resource_wrap & operator=(const resource_wrap &)=delete
Copy assignment is deleted.
resource_wrap(T &&src, std::function< void(T &&)> &&f={})
Construct a resource_wrap with a resource and optional callback.
resource_wrap(const T &)=delete
Copy constructor is deleted Resources are move-only to maintain clear ownership semantics.
std::function< void(T &&)> putbackCallback
Callback function to return the resource to the pool Called by destructor when resource is valid.
T rsrc
The actual resource being wrapped.