#pragma once #include "ncx_slab.h" #include template class mempool { public: mempool(size_t pool_size = 1024000) { // 1024KB const auto space = static_cast(malloc(pool_size)); mem_pool_ = reinterpret_cast(space); mem_pool_->addr = space; mem_pool_->min_shift = 3; mem_pool_->end = space + pool_size; ncx_slab_init(mem_pool_); } ~mempool() { free(mem_pool_->addr); } [[nodiscard]] void* alloc(size_t size) const { return ncx_slab_alloc(mem_pool_, size); } template [[nodiscard]] T* alloc(Args&&... args) const { T* out = (T*)alloc(sizeof(T)); new (out) T(std::forward(args)...); return out; } template [[nodiscard]] T* alloc() const { T* out = (T*)alloc(sizeof(T)); new (out) T(); return out; } template void free(T* p) const { p->~T(); free((void*)p); } void free(void* p) const { ncx_slab_free(mem_pool_, p); } [[nodiscard]] ncx_slab_stat_t stat() const { ncx_slab_stat_t out; ncx_slab_stat(mem_pool_, &out); return out; } private: ncx_slab_pool_t* mem_pool_ = nullptr; }; template class obj_mempool { public: template static T* alloc(Args&&... args) { auto obj = pool_.template alloc(std::forward(args)...); objs_.push_back(obj); return obj; } static T* alloc() { auto obj = pool_.template alloc(); objs_.push_back(obj); return obj; } static void free(T* p) { pool_.template free(p); objs_.erase(std::remove(objs_.begin(), objs_.end(), p), objs_.end()); } static void free_all() { for (auto obj : objs_) { pool_.template free(obj); } objs_.clear(); } static const std::vector& objs() { return objs_; } static bool has_obj(T* p) { return std::find(objs_.begin(), objs_.end(), p) != objs_.end(); } static bool safe_free(T* p) { if (has_obj(p)) { free(p); return true; } return false; } private: static mempool pool_; static std::vector objs_; };