#include "allocPool.hpp" template requires std::default_initializable && resetable allocPool::allocPool(size_t defaultAllocNumbers) : vec(defaultAllocNumbers), pivot{defaultAllocNumbers} { memset(&(vec[0]), 0, sizeof(vec[0]) * vec.size()); initArray(defaultAllocNumbers); } template requires std::default_initializable && resetable T *allocPool::getPtr() { if (pivot == 0) resizeVec(); auto *ptrToReturn{vec[0]}; std::swap(vec[0], vec[pivot - 1]); positionMap[vec[0]] = 0; positionMap[vec[pivot - 1]] = pivot - 1; pivot--; return ptrToReturn; } template requires std::default_initializable && resetable void allocPool::returnPtr(T *ptr) { size_t pos = positionMap[ptr]; vec[pos].reset(); std::swap(vec[pos], vec[pivot]); pivot++; } template requires std::default_initializable && resetable void allocPool::initArray(size_t amount) { const auto amountOfThreads{std::thread::hardware_concurrency()}; assert(amountOfThreads); const auto amountPerThreads{amount / amountOfThreads}; std::vector threads; threads.reserve(amountOfThreads); for (size_t i{}; i < amountOfThreads; i++) threads.emplace_back(&allocPool::initObjects, this, i, amountPerThreads); for (auto &t: threads) t.join(); // Remainder initObjects(vec[vec.size() - (amount % amountOfThreads)], amount % amountOfThreads); } template requires std::default_initializable && resetable void allocPool::initObjects(size_t startIdx, size_t amount) { for (size_t i{}; i < amount; i++) { // TODO: Be more cache friendly by making a vector per thread, then doing memcpy into the original vector. vec[startIdx + i] = new T; positionMap[startIdx + i] = i; } } template requires std::default_initializable && resetable void allocPool::resizeVec() { size_t size{vec.size()}; vec.resize(2 * size); memcpy(&(vec[size]), &(vec[0]), size); initArray(size); }