Skip to content

Instantly share code, notes, and snippets.

@Delaunay
Last active April 11, 2018 11:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Delaunay/8695f1e965ab3fc76c9d82a9eda555d8 to your computer and use it in GitHub Desktop.
Save Delaunay/8695f1e965ab3fc76c9d82a9eda555d8 to your computer and use it in GitHub Desktop.
Simple Pool Implementation (gcc 8, C++2a)
#include <thread>
#include <mutex>
#include <tuple>
#include <list>
#include <memory>
namespace pool{
namespace internal {
template<typename T>
struct PoolObjectWrapper{
/*PoolObjectWrapper(bool f, T& obj):
free(f), object(obj)
{}*/
bool free = false;
T object;
};
template<typename T>
struct Deleter
{
Deleter() {}
static void deleter(internal::PoolObjectWrapper<T>* t) {
t->free = true;
}
void operator () (internal::PoolObjectWrapper<T>* t) {
deleter(t);
}
};
}
template<typename T>
struct PooledObjectTrait{
static T make(){ return T(); }
};
template<typename T, typename PtrType>
class PooledObject{
public:
PooledObject(internal::PoolObjectWrapper<T>* object):
_ptr(object)
{}
PooledObject(internal::PoolObjectWrapper<T>* object, void(*deleter)(internal::PoolObjectWrapper<T>*)):
_ptr(object, deleter)
{}
inline T& operator* () { return (*_ptr).object; }
inline T* operator->() { return _ptr->object; }
inline operator bool() const { return _ptr; }
private:
PtrType _ptr;
};
template<typename T>
using UniquePooledObject = PooledObject<T, std::unique_ptr<internal::PoolObjectWrapper<T>, internal::Deleter<T>>>;
template<typename T>
using SharedPooledObject = PooledObject<T, std::shared_ptr<internal::PoolObjectWrapper<T>>>;
template<typename T>
class DynamicPool{
public:
DynamicPool(std::size_t initial_size){
//_pool.reserve(initial_size);
for(std::size_t i = 0; i < initial_size; ++i){
_pool.push_back({true, PooledObjectTrait<T>::make()});
}
}
UniquePooledObject<T> get_unique(){
return UniquePooledObject<T>(get_free_or_make());
}
SharedPooledObject<T> get_shared(){
void(*deleter)(internal::PoolObjectWrapper<T>*) = &internal::Deleter<T>::deleter;
return SharedPooledObject<T>(get_free_or_make(), deleter);
}
std::size_t size() const { return _pool.size(); }
private:
internal::PoolObjectWrapper<T>* get_free_or_make(){
std::lock_guard<std::mutex> lock(_mutex);
for(auto& elem: _pool){
if (elem.free){
elem.free = false;
return &elem;
}
}
_pool.push_back({false, PooledObjectTrait<T>::make()});
return &_pool.back();
}
private:
std::list<internal::PoolObjectWrapper<T>> _pool;
std::mutex _mutex;
};
}
#include <iostream>
int main(){
pool::DynamicPool<int> pool(20);
{
auto a = pool.get_unique();
auto b = pool.get_shared();
(*a) = 10;
(*b) = 20;
}
{
auto a = pool.get_unique();
auto b = pool.get_shared();
std::cout << (*a) << std::endl;
std::cout << (*b) << std::endl;
}
auto a = pool.get_shared();
std::cout << (*a) << std::endl;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment