#ifndef OPENMW_COMPONENTS_MISC_OBJECTPOOL_H #define OPENMW_COMPONENTS_MISC_OBJECTPOOL_H #include #include #include namespace Misc { template class ObjectPool; template class ObjectPtrDeleter { public: ObjectPtrDeleter(std::nullptr_t) : mPool(nullptr) { } ObjectPtrDeleter(ObjectPool& pool) : mPool(&pool) { } void operator()(T* object) const { mPool->recycle(object); } private: ObjectPool* mPool; }; template struct ObjectPtr final : std::unique_ptr> { using std::unique_ptr>::unique_ptr; using std::unique_ptr>::operator=; ObjectPtr() : ObjectPtr(nullptr) { } ObjectPtr(std::nullptr_t) : std::unique_ptr>(nullptr, nullptr) { } }; template class ObjectPool { friend class ObjectPtrDeleter; public: ObjectPool() : mObjects(std::make_unique>()) { } ObjectPtr get() { T* object; if (!mUnused.empty()) { object = mUnused.back(); mUnused.pop_back(); } else { mObjects->emplace_back(); object = &mObjects->back(); } return ObjectPtr(object, ObjectPtrDeleter(*this)); } private: std::unique_ptr> mObjects; std::vector mUnused; void recycle(T* object) { mUnused.push_back(object); } }; } #endif