#pragma once #include #include #include #include #if defined(_WIN32) #include #endif namespace util { struct AlignedDeleter { void operator()(void* p) const { #if defined(_WIN32) _aligned_free(p); #else std::free(p); #endif } }; template class ObjectsPool { public: ObjectsPool(size_t preallocated = 0) { for (size_t i = 0; i < preallocated; i++) { allocateNew(); } } template std::shared_ptr create(Args&&... args) { std::lock_guard lock(mutex); if (freeObjects.empty()) { allocateNew(); } auto ptr = freeObjects.front(); freeObjects.pop(); new (ptr)T(std::forward(args)...); return std::shared_ptr(reinterpret_cast(ptr), [this](T* ptr) { ptr->~T(); std::lock_guard lock(mutex); freeObjects.push(ptr); }); } private: std::vector> objects; std::queue freeObjects; std::mutex mutex; void allocateNew() { std::unique_ptr ptr( #if defined(_WIN32) _aligned_malloc(sizeof(T), alignof(T)) #else std::aligned_alloc(alignof(T), sizeof(T)) #endif ); freeObjects.push(ptr.get()); objects.push_back(std::move(ptr)); } }; }