2016-06-26 19:05:09 +00:00
|
|
|
#pragma once
|
|
|
|
#include <memory>
|
|
|
|
#include <functional>
|
|
|
|
#include <stack>
|
|
|
|
#include <mutex>
|
|
|
|
|
2019-01-02 19:00:34 +00:00
|
|
|
template<typename value_type, typename pointer_type = std::unique_ptr<value_type>>
|
2016-06-26 19:05:09 +00:00
|
|
|
class ObjectPool {
|
|
|
|
public:
|
2016-09-21 08:22:46 +00:00
|
|
|
using wrapper_type = lambda_unique_ptr<value_type>;
|
2016-06-26 19:05:09 +00:00
|
|
|
|
2016-09-21 08:22:46 +00:00
|
|
|
ObjectPool(std::function<pointer_type()> createObject) :
|
2016-06-26 19:05:09 +00:00
|
|
|
createObject(createObject)
|
|
|
|
{}
|
|
|
|
|
2016-09-21 08:22:46 +00:00
|
|
|
wrapper_type acquire() {
|
2016-06-26 19:05:09 +00:00
|
|
|
std::lock_guard<std::mutex> lock(poolMutex);
|
|
|
|
|
|
|
|
if (pool.empty()) {
|
2016-07-27 19:43:09 +00:00
|
|
|
pool.push(createObject());
|
2016-06-26 19:05:09 +00:00
|
|
|
}
|
|
|
|
|
2016-09-21 08:22:46 +00:00
|
|
|
auto pointer = pool.top();
|
|
|
|
pool.pop();
|
|
|
|
return wrapper_type(pointer.get(), [this, pointer](value_type*) {
|
2016-06-26 19:05:09 +00:00
|
|
|
std::lock_guard<std::mutex> lock(poolMutex);
|
2016-09-21 08:22:46 +00:00
|
|
|
this->pool.push(pointer);
|
2016-06-26 19:05:09 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
bool empty() const {
|
|
|
|
std::lock_guard<std::mutex> lock(poolMutex);
|
|
|
|
return pool.empty();
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t size() const {
|
|
|
|
std::lock_guard<std::mutex> lock(poolMutex);
|
|
|
|
return pool.size();
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2016-09-21 08:22:46 +00:00
|
|
|
std::function<pointer_type()> createObject;
|
|
|
|
std::stack<std::shared_ptr<value_type>> pool;
|
2016-06-26 19:05:09 +00:00
|
|
|
mutable std::mutex poolMutex;
|
|
|
|
};
|