71 lines
1.9 KiB
C++
71 lines
1.9 KiB
C++
#pragma once
|
|
|
|
#include <cstddef>
|
|
#include <list>
|
|
#include <deque>
|
|
#ifdef WITH_BOOST
|
|
#include <boost/container/pmr/memory_resource.hpp>
|
|
#include <boost/container/pmr/polymorphic_allocator.hpp>
|
|
#include <boost/container/pmr/synchronized_pool_resource.hpp>
|
|
#include <boost/container/vector.hpp>
|
|
using boost::container::pmr::synchronized_pool_resource;
|
|
using boost::container::pmr::polymorphic_allocator;
|
|
using boost::container::vector;
|
|
#else
|
|
#include <memory_resource>
|
|
using std::pmr::synchronized_pool_resource;
|
|
using std::pmr::polymorphic_allocator;
|
|
#endif
|
|
#include <unordered_set>
|
|
#ifdef WITH_BOOST
|
|
template <class Key,
|
|
class Hash = std::hash<Key>,
|
|
class Pred = std::equal_to<Key>>
|
|
using unordered_set = std::unordered_set<Key, Hash, Pred, polymorphic_allocator<Key>>;
|
|
#else
|
|
using std::pmr::unordered_set;
|
|
using std::vector;
|
|
#endif
|
|
namespace Xybrid::Util {
|
|
extern synchronized_pool_resource rpool;
|
|
extern polymorphic_allocator<std::max_align_t> ralloc;
|
|
|
|
void reserveInitialPool();
|
|
|
|
template<typename T, size_t PSIZE = 16>
|
|
class ResourcePool {
|
|
typedef char slot[sizeof(T)];
|
|
std::list<slot[PSIZE]> pages;
|
|
|
|
std::deque<T*> avail;
|
|
unordered_set<T*> used = {rpool};
|
|
|
|
void newPage() {
|
|
auto p = pages.emplace_back();
|
|
for (size_t i = 0; i < PSIZE; i++) avail.push_back(&p[i]);
|
|
//avail.res
|
|
}
|
|
|
|
public:
|
|
typedef T type;
|
|
static const constexpr size_t pageSize = PSIZE;
|
|
|
|
template<typename... Arg>
|
|
T* getNew(Arg... args) {
|
|
if (avail.empty()) newPage();
|
|
T* n = avail.pop_back();
|
|
new (n) T(args...);
|
|
used.insert(n);
|
|
return n;
|
|
}
|
|
|
|
void del(T* n) {
|
|
if (!used.contains(n)) return; // not mine
|
|
n->~T(); // destroy object
|
|
used.erase(n);
|
|
avail.push_back(n);
|
|
}
|
|
|
|
};
|
|
}
|