Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #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;
- }
Add Comment
Please, Sign In to add comment