1#ifndef INTNS_MEMORY_OBJECTPOOL_HPP
2#define INTNS_MEMORY_OBJECTPOOL_HPP
13namespace intns::memory {
19template <
typename Policy,
typename T>
21 { Policy::on_acquire(obj) }
noexcept;
29template <
typename Policy,
typename T>
31 { Policy::on_release(obj) }
noexcept;
45 static void on_acquire(U&)
noexcept {}
46 static void on_release(U&)
noexcept {}
71template <
typename T,
typename AcquirePolicy = NoOpPoolPolicy<T>,
72 typename ReleasePolicy = AcquirePolicy>
75 static_assert(std::is_default_constructible_v<T>,
76 "T must be default constructible");
77 static_assert(std::is_move_constructible_v<T>,
78 "T must be move constructible");
81 using queue_type = std::deque<T>;
82 using size_type = size_t;
94 ObjectPool(queue_type&& src) : objects_(std::move(src)) {}
111 std::optional<size_type> limit = std::nullopt);
119 [[nodiscard]] value_type
take();
127 [[nodiscard]] std::optional<value_type>
try_take();
135 void add(value_type&& back);
144 [[nodiscard]]
bool try_add(value_type&& back);
153 void reserve(size_type target_size) { reserve_impl<true>(target_size); }
163 return reserve_impl<false>(target_size);
171 std::scoped_lock<std::mutex> lock(mutex_);
172 objects_.shrink_to_fit();
180 std::scoped_lock<std::mutex> lock(mutex_);
181 return objects_.capacity();
188 [[nodiscard]] size_type
size()
const {
189 std::scoped_lock<std::mutex> lock(mutex_);
190 return objects_.size();
198 std::scoped_lock<std::mutex> lock(mutex_);
199 return objects_.empty();
207 [[nodiscard]] std::optional<size_type>
size_limit() const noexcept {
208 std::scoped_lock<std::mutex> lock(mutex_);
217 std::scoped_lock<std::mutex> lock(mutex_);
234 template <
bool ThrowOnError>
235 [[nodiscard]]
bool reserve_impl(size_type target_size);
241 mutable std::mutex mutex_;
244 std::optional<size_type> size_limit_ = std::nullopt;
256template <
typename Pool>
258 using value_type =
typename Pool::value_type;
274 : pool_(o.pool_), obj_(std::move(o.obj_)), active_(o.active_) {
286 pool_->add(std::move(obj_));
294 [[nodiscard]]
auto&
get() noexcept {
return obj_; }
300 [[nodiscard]] value_type*
operator->() noexcept {
return &obj_; }
306 [[nodiscard]]
const auto&
get() const noexcept {
return obj_; }
312 [[nodiscard]]
const value_type*
operator->() const noexcept {
return &obj_; }
325 return std::move(obj_);
341#include "ObjectPool.tpp"
A thread-safe object pool for managing reusable objects of type T.
Definition ObjectPool.hpp:74
void add(value_type &&back)
Adds a new object to the pool.
ObjectPool(size_type init_size, std::optional< size_type > limit=std::nullopt)
Creates an ObjectPool with a set initial size and optional max limit. Objects are default-constructed...
value_type take()
Removes and returns an object from the pool.
ObjectPool(queue_type &&src)
Constructs an ObjectPool by moving the given queue of objects.
Definition ObjectPool.hpp:94
size_type size() const
Returns the number of objects currently managed.
Definition ObjectPool.hpp:188
std::optional< value_type > try_take()
Attempts to take an object from the container.
void set_size_limit(std::optional< size_type > limit) noexcept
Sets the max pool size; nullopt makes it unlimited.
Definition ObjectPool.hpp:216
size_type capacity() const
Returns the pool's maximum capacity without reallocation.
Definition ObjectPool.hpp:179
void shrink_to_fit()
Reduces the memory usage of the internal object storage to fit its current size. This may free unused...
Definition ObjectPool.hpp:170
bool try_reserve(size_type target_size)
Reserves space for a minimum number of objects in the pool without throwing exceptions.
Definition ObjectPool.hpp:162
bool empty() const
Checks if the object pool is empty.
Definition ObjectPool.hpp:197
std::optional< size_type > size_limit() const noexcept
Returns the maximum allowed size for the container.
Definition ObjectPool.hpp:207
bool try_add(value_type &&back)
Attempts to add a new object to the container.
void reserve(size_type target_size)
Reserves space for a minimum number of objects in the pool.
Definition ObjectPool.hpp:153
RAII wrapper for managing leased ObjectPool objects.
Definition ObjectPool.hpp:257
~PoolLease()
Destructor for the PoolLease class.
Definition ObjectPool.hpp:284
const auto & get() const noexcept
Returns a constant reference to the managed object.
Definition ObjectPool.hpp:306
value_type release() noexcept
Releases ownership of the managed object.
Definition ObjectPool.hpp:323
value_type * operator->() noexcept
Provides pointer-like access to the underlying object.
Definition ObjectPool.hpp:300
PoolLease(Pool &p)
Creates a PoolLease and acquires an object from the given pool.
Definition ObjectPool.hpp:265
PoolLease(PoolLease &&o) noexcept
Move constructor for PoolLease. Transfers ownership and deactivates the source to prevent double rele...
Definition ObjectPool.hpp:273
auto & get() noexcept
Returns a reference to the internal object.
Definition ObjectPool.hpp:294
const value_type * operator->() const noexcept
Provides pointer-like access to the underlying object.
Definition ObjectPool.hpp:312
Concept to check if a type supports the acquire hook. Type T must implement Policy::on_acquire(T&),...
Definition ObjectPool.hpp:20
Concept to check if a type supports the release hook. Type T must implement Policy::on_release(T&),...
Definition ObjectPool.hpp:30
A no-operation pool policy for resource management.
Definition ObjectPool.hpp:44