#ifndef mempool___mempool_h #define mempool___mempool_h /* * This is where you may alter options to give mempool++ */ //#define MEMPOOL_DEBUGGING //Causes mempool++ to spit out what it's doing to the console //#define MEMPOOL_ASSERTS //Causes mempool++ to check what it's doing and look for impossible cases #define MEMPOOL_OVERFLOW 3.0f / 4.0f //Changes how full a pool is before going to fallbacks //#define MEMPOOL_DETERMINE_DISTRIBUTION //Allows mempool++ to automatically give you the best distribution #define MEMPOOL_DETERMINE_SCALAR 5.0f / 3.0f //Gives you this times the max number at any given time from distribution #define MEMPOOL_FALLBACK_DEPTH 3 //#define MEMPOOL_PERFORMANCE_DEBUGGING //#define private public //version info #define __MEMPOOL_MAJOR__ 1 #define __MEMPOOL_MINOR__ 2 #define __MEMPOOL_PATCH__ 0 #define __MEMPOOL_VERSION__ (__MEMPOOL_MAJOR__ * 10000 + __MEMPOOL_MINOR__ * 100 + __MEMPOOL_PATCH__) /* * This is where special function / macro for special options are */ #ifdef MEMPOOL_DEBUGGING #include #define MEMPOOL_DEBUG(x) std::cout << x << std::endl; #else #define MEMPOOL_DEBUG(x) #endif #ifdef MEMPOOL_ASSERTS #include #define MEMPOOL_ASSERT(condition) if (pool_unlikely(!(condition))){ std::cout << #condition << " isn't true" << std::endl; } #define MEMPOOL_ASSERT2(condition, out) if (pool_unlikely(!(condition))){ std::cout << out << std::endl; } #else #define MEMPOOL_ASSERT(condition) #define MEMPOOL_ASSERT2(condition, out) #endif #ifdef MEMPOOL_PERFORMANCE_DEBUGGING #include #include #include #define MEMPOOL_PERFORMANCE_DEBUG(x) std::cout << x << std::endl; #else #define MEMPOOL_PERFORMANCE_DEBUG(x) #endif /* * This is where compiler-specific code goes */ #ifdef __GNUC__ #if (__GNUC__ >= 3) #define POOL_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) #else #define POOL_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100) #endif #if (POOL_GCC_VERSION >= 40300) #define pool_hot pool_nothrow __attribute__ ((hot)) #else #define pool_hot pool_nothrow #endif #if (POOL_GCC_VERSION >= 29600) #define pool_likely(x) __builtin_expect((long)((bool)(x)),1) #define pool_unlikely(x) __builtin_expect((long)((bool)(x)),0) #else #define pool_likely(x) x #define pool_unlikely(x) x #endif #define pool_nothrow throw() #else #define pool_hot pool_nothrow #define pool_likely(x) x #define pool_unlikely(x) x #define pool_nothrow #endif #include /* * This is where the classes are */ //Callbacks for fallback if the pool is out of space class mempool_callbacks { public: typedef void * (*mallocer_t)(size_t); typedef void(*freer_t)(void *); typedef void * (*reallocer_t)(void *, size_t); //Allows the user to alter where the fallbacks point to static inline void set(mallocer_t mallocer, reallocer_t reallocer, freer_t freer) pool_nothrow { get_instance()._malloc = mallocer; get_instance()._free = freer; get_instance()._realloc = reallocer; } //allocates memory static inline void * allocate(size_t size) pool_nothrow { MEMPOOL_DEBUG("Returing malloced memory:" << size << " bytes"); return get_instance()._malloc(size); } //frees memory static inline void deallocate(void * ptr) pool_nothrow { MEMPOOL_DEBUG("Freeing malloced memory: " << ptr); get_instance()._free(ptr); } static inline void * reallocate(void * ptr, size_t size) pool_nothrow { MEMPOOL_DEBUG("Reallocating memory: " << ptr << " to " << size << " bytes"); return get_instance()._realloc(ptr, size); } private: //Retrieves a Meyers singleton static inline mempool_callbacks & get_instance(void) pool_nothrow { static mempool_callbacks _single(std::malloc, std::realloc, std::free); return _single; } //The constructor inline mempool_callbacks(mallocer_t mallocer, reallocer_t reallocer, freer_t freer) : _malloc(mallocer), _free(freer), _realloc(reallocer){ } //not copyable mempool_callbacks & operator = (const mempool_callbacks & other); mempool_callbacks(const mempool_callbacks & other); //member callbacks mallocer_t _malloc; reallocer_t _realloc; freer_t _free; }; //The workhorse of the templates library, a class that holds a pool that it allocates memory from template class object_memory_pool; //forward declaration template class memory_pool_no_fullflag { //forward declaration public: memory_pool_no_fullflag(): _link(NULL), current(0), depth(0), threshold((size_t)((float)size * (MEMPOOL_OVERFLOW))), memoryPool_end(memoryPool_start + (size * bytes)), used_end(used_start + size), runningPointer(used_start) { std::memset(used_start, 0, size * sizeof(bool)); } virtual ~memory_pool_no_fullflag(void){ if (_link){ _link -> ~memory_pool_no_fullflag(); mempool_callbacks::deallocate(_link); } } inline size_t load(void) const pool_nothrow { return current; } inline void * allocate(void) pool_hot { if (void * res = allocate_nofallback()){ return res; } return _link_allocate(); } inline void deallocate(void * ptr) pool_hot { if (memory_pool_no_fullflag * container = contains(ptr)){ container -> deallocate_nofallback(ptr); } else { mempool_callbacks::deallocate(ptr); } } void * allocate_nofallback() pool_hot { if (!(*runningPointer)) return _return_current(); if (++runningPointer >= used_end) runningPointer = used_start; if (current < threshold){ //make sure it doesnt loop around infinity so point it to itself const bool * position = runningPointer; do { if (!(*runningPointer)) return _return_current(); if (++runningPointer >= used_end) runningPointer = used_start; } while (position != runningPointer); MEMPOOL_ASSERT2(false, "Got to impossible code location"); } MEMPOOL_DEBUG("Returing null"); return NULL; } void deallocate_nofallback(void * ptr) pool_hot { MEMPOOL_ASSERT2(current, "current not positive"); --current; MEMPOOL_DEBUG("Freeing slot " << ((char*)ptr - memoryPool_start) / bytes); MEMPOOL_DEBUG(" pointer=" << ptr); MEMPOOL_ASSERT2((((char*)ptr - memoryPool_start) / bytes) < size, "Freeing slot " << (((char*)ptr - memoryPool_start) / bytes) << " in a pool with only " << size << " items"); MEMPOOL_ASSERT2(used_start[((char*)ptr - memoryPool_start) / bytes], "Freeing " << ptr << " and it's already been freed"); used_start[(((char*)ptr - memoryPool_start) / bytes)] = false; } inline memory_pool_no_fullflag * contains(void * ptr) pool_hot { if ((ptr >= memoryPool_start) && (ptr < memoryPool_end)) return this; return (_link) ? _link -> contains(ptr) : NULL; } #ifdef MEMPOOL_PERFORMANCE_DEBUGGING const char * const getName(void){ return "memory_pool_no_fullflag"; } const char * getDepth(){ static const char * depths[15] = { " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "- ", }; if (depth > 14) return depths[14]; return depths[depth]; } std::string dump(void){ std::stringstream output; output << getDepth() << getName() << "<" << bytes << ", " << size << ">: " << (void*)this << std::endl; output << getDepth() << "Currently holding: " << current << " items." << std::endl; //_____ output << getDepth() << "+"; for(int i = 0; i < 78; ++i){ output << "_"; } output << "+" << std::endl << getDepth() << "|"; //Fill in int i; for(i = 0; i < size; ++i){ if ((i % 80 == 0) && (i != 0)){ output << "|" << std::endl << getDepth() << "|"; } if (i == (runningPointer - used_start)){ if (used_start[i]){ output << "R"; } else { output << "P"; } } else if (used_start[i]){ output << "X"; } else { output << " "; } } for(; (i % 80) != 0; ++i){ output << "+"; } //------- output << getDepth() << "+"; for(i = 0; i < 78; ++i){ output << "-"; } output << "+"; if (_link){ output << "----+" << std::endl; } return output.str(); } #endif protected: //copy ctors and assignment operator memory_pool_no_fullflag & operator = (const memory_pool_no_fullflag & other); memory_pool_no_fullflag(const memory_pool_no_fullflag & other); inline void * _return_current(void) pool_hot { *runningPointer = true; ++current; MEMPOOL_DEBUG("Returning slot " << runningPointer - used_start << " at depth " << depth); MEMPOOL_DEBUG(" memoryPool_start=" << (void*)memoryPool_start); MEMPOOL_DEBUG(" memoryPool_end =" << (void*)memoryPool_end); MEMPOOL_DEBUG(" return value =" << (void*)(memoryPool_start + ((runningPointer - used_start) * bytes))); MEMPOOL_ASSERT2(((memoryPool_start + ((runningPointer - used_start) * bytes))) < memoryPool_end, "Returning pointer outside the high end of the pool"); MEMPOOL_ASSERT2(((memoryPool_start + ((runningPointer - used_start) * bytes))) >= memoryPool_start, "Returning pointer outside the low end of the pool"); const bool * const pre = runningPointer; if (++runningPointer >= used_end) runningPointer = used_start; return memoryPool_start + ((pre - used_start) * bytes); } void * _link_allocate(void) pool_nothrow { if (depth >= MEMPOOL_FALLBACK_DEPTH) return mempool_callbacks::allocate(bytes); if (!_link){ _link = new(mempool_callbacks::allocate(sizeof(memory_pool_no_fullflag))) memory_pool_no_fullflag(); _link -> depth = depth + 1; } return _link -> allocate(); } size_t current; //The current number of items in the pool size_t threshold; //The number of items in the pool before it starts using fallback char memoryPool_start[size * bytes]; //The memory pool char * memoryPool_end; //The end of the memory pool bool used_start[size]; //A pool to know whether or not an item is currently used bool * used_end; //The end of the boolean flags bool * runningPointer; //A pointer that loops, keeping an eye on what is taken and what isn't memory_pool_no_fullflag * _link; //Creates a linked list when expanding size_t depth; }; template class memory_pool : public memory_pool_no_fullflag { public: memory_pool() : memory_pool_no_fullflag(), _full(false){} virtual ~memory_pool(void){} inline void * allocate(void) pool_hot { if (_full) return mempool_callbacks::allocate(bytes); return memory_pool_no_fullflag::allocate(); } inline void deallocate(void * ptr) pool_hot { _full = false; return memory_pool_no_fullflag::deallocate(ptr); } #ifdef MEMPOOL_PERFORMANCE_DEBUGGING const char * const getName(void){ return "memory_pool"; } #endif private: //copy ctors and assignment operator memory_pool & operator = (const memory_pool & other); memory_pool(const memory_pool & other); bool _full; template friend class object_memory_pool; }; //A memory pool for a specific type of object #define new_object(pool, ctor) new (pool.allocate_noctor()) ctor //allows user to call a specific ctor on the object [ new_object(mypool, T(x, y)) ] template class object_memory_pool { public: inline size_t load(void) const pool_nothrow { return _pool.load(); } virtual ~object_memory_pool() pool_nothrow { } //so that it can be overloaded inline T * allocate(void) pool_hot { return new (_pool.allocate()) T(); } inline void * allocate_noctor(void) pool_nothrow { return _pool.allocate(); } inline void deallocate(T * ptr) pool_hot { ptr -> ~T(); _pool.deallocate(ptr); } inline memory_pool * contains(T * ptr) const pool_hot { return _pool.contains((void*)ptr); } inline T * alloc_nofallback() pool_hot { if (void * res = _pool.allocate_nofallback()){ return new (res) T(); } return NULL; } inline void deallocate_nofallback(T * ptr) pool_hot { ptr -> ~T(); _pool.deallocate_nofallback(ptr); } #ifdef MEMPOOL_PERFORMANCE_DEBUGGING const std::string dump(void){ return _pool.dump(); } #endif private: memory_pool _pool; }; #define MEMPOOL_TEMPLATE_PAIR(x) size_t bytes ## x , size_t count ## x #define MEMPOOL_ALLOC_CHECK(x) if (bytes <= bytes ## x ){ if (void * res = (_pool ## x).allocate_nofallback()) return res; } #define MEMPOOL_DEALLOC_CHECK(x) if (memory_pool_no_fullflag< bytes ## x , count ## x > * container = (_pool ## x).contains(ptr)){ container -> deallocate_nofallback(ptr); return; } #define MEMPOOL_MEMBER_POOL(x) memory_pool< bytes ## x , count ## x > _pool ## x; #define MEMPOOL_REALLOC_CHECK(x)\ if (memory_pool_no_fullflag< bytes ## x , count ## x > * container = (_pool ## x).contains(ptr)){\ if (bytes <= bytes ## x) return ptr;\ void * newvalue = allocate(bytes);\ std::memcpy(newvalue, ptr, bytes ## x);\ container -> deallocate_nofallback(ptr);\ return newvalue;\ } #ifdef MEMPOOL_DETERMINE_DISTRIBUTION #include #include #define MEMPOOL_ALLOC_METHOD(number, code)\ bucket_pool_ ## number (void) : _profile_on_delete(0) { }\ ~bucket_pool_ ## number (void) { \ if (_profile_on_delete){ \ dump_atonce(_profile_on_delete, _profile_on_delete / 40); \ dump_template(_profile_on_delete); \ } \ }\ void * allocate(size_t bytes) pool_hot {\ if (mapping.find(bytes) != mapping.end()){\ ++mapping[bytes];\ ++current_mapping[bytes];\ if (current_mapping[bytes] > max_mapping[bytes]) max_mapping[bytes] = current_mapping[bytes];\ } else {\ mapping[bytes] = 1;\ max_mapping[bytes] = 1;\ current_mapping[bytes] = 1;\ }\ void * res = mempool_callbacks::allocate(bytes);\ mem_mapping[res] = bytes;\ return res;\ } #define MEMPOOL_DEALLOC_METHOD(code)\ void deallocate(void * ptr) pool_hot {\ --current_mapping[mem_mapping[ptr]];\ mem_mapping.erase(ptr);\ mempool_callbacks::deallocate(ptr);\ } #define MEMPOOL_ANALYZERS(macro_count)\ inline size_t _max(size_t one, size_t two){ return (one > two) ? one : two; }\ void dump_total(size_t max, size_t sep = 16, size_t tlen = 30){\ std::cout << "-------- Total --------" << std::endl;\ size_t max_amount = 0;\ for(size_t i = 0; i < max;){\ size_t amount = 0;\ for(size_t j = 0; j < sep; ++j, ++i){\ if (mapping.find(i) != mapping.end()){\ amount += mapping[i];\ }\ }\ if (amount > max_amount) max_amount = amount;\ }\ float scalar = ((float)max_amount) / ((float)tlen);\ \ for(size_t i = 0; i < max;){\ size_t amount = 0;\ for(size_t j = 0; j < sep; ++j, ++i){\ if (mapping.find(i) != mapping.end()){\ amount += mapping[i];\ }\ }\ \ if (i < 10) std::cout << ' ';\ if (i < 100) std::cout << ' ';\ if (i < 1000) std::cout << ' ';\ if (i < 10000) std::cout << ' ';\ std::cout << i << ':';\ \ for(size_t j = 0; j < (size_t)((float)amount / scalar); ++j){\ std::cout << '*';\ }\ std::cout << '(' << amount << ')' << std::endl;\ }\ }\ \ void dump_atonce(size_t max, size_t sep = 16, size_t tlen = 30){\ std::cout << "------ Distribution for \"" << _str << "\" ------" << std::endl;\ size_t max_amount = 0;\ for(size_t i = 0; i < max;){\ size_t amount = 0;\ for(size_t j = 0; j < sep; ++j, ++i){\ if (max_mapping.find(i) != max_mapping.end()){\ amount += max_mapping[i];\ }\ }\ if (amount > max_amount) max_amount = amount;\ }\ float scalar = ((float)max_amount) / ((float)tlen);\ \ for(size_t i = 0; i < max;){\ size_t amount = 0;\ for(size_t j = 0; j < sep; ++j, ++i){\ if (max_mapping.find(i) != max_mapping.end()){\ amount += max_mapping[i];\ }\ }\ \ if (i < 10) std::cout << ' ';\ if (i < 100) std::cout << ' ';\ if (i < 1000) std::cout << ' ';\ if (i < 10000) std::cout << ' ';\ std::cout << i << ':';\ \ for(size_t j = 0; j < (size_t)((float)amount / scalar); ++j){\ std::cout << '*';\ }\ std::cout << '(' << amount << ')' << std::endl;\ }\ }\ \ void dump_template(size_t max){\ std::cout << "Recommended Template for \"" << _str << "\" = ";\ size_t total_at_once = 0;\ size_t highest = 0;\ for(size_t i = 0; i < max; ++i){\ if (max_mapping.find(i) != max_mapping.end()){\ total_at_once += max_mapping[i];\ highest = i;\ }\ }\ \ size_t count = 0;\ size_t total_at_once_part = total_at_once / macro_count;\ size_t current = 0;\ size_t totalsofar = 0;\ std::cout << '<';\ for(size_t i = 0; ((i < max) && (count < (macro_count -1))); ++i){\ if (max_mapping.find(i) != max_mapping.end()){\ current += max_mapping[i];\ totalsofar += max_mapping[i];\ if (current > total_at_once_part){\ std::cout << (i - 1) << ", " << (size_t)(((float)current - max_mapping[i]) * (MEMPOOL_DETERMINE_SCALAR)) << ", ";\ current = max_mapping[i];\ ++count;\ }\ }\ }\ std::cout << max << ", " << _max((size_t)((float)(total_at_once - totalsofar) * (MEMPOOL_DETERMINE_SCALAR)), total_at_once_part / 2) << '>' << std::endl;\ }\ \ inline void profile_on_delete(size_t var, const std::string & str){ _profile_on_delete = var; _str = str; } #define MEMPOOL_MEMBERS(code)\ std::map mapping;\ std::map current_mapping;\ std::map max_mapping;\ std::map mem_mapping;\ size_t _profile_on_delete;\ std::string _str; #define MEMPOOL_LOAD(number, code) inline size_t * load(void) const pool_nothrow { static size_t _load[number] = {0}; return &_load[0]; } #else #define MEMPOOL_ALLOC_METHOD(number, code)\ void * allocate(size_t bytes) pool_hot {\ code\ return mempool_callbacks::allocate(bytes);\ } #define MEMPOOL_DEALLOC_METHOD(code)\ void deallocate(void * ptr) pool_hot {\ code\ mempool_callbacks::deallocate(ptr);\ } #define MEMPOOL_ANALYZERS(macro_count) #define MEMPOOL_MEMBERS(code) code #define MEMPOOL_LOAD(number, code) inline size_t * load(void) const pool_nothrow { static size_t _load[number]; code return &_load[0]; } #endif template< MEMPOOL_TEMPLATE_PAIR(1), MEMPOOL_TEMPLATE_PAIR(2)> class bucket_pool_2 { public: MEMPOOL_ALLOC_METHOD( 2, MEMPOOL_ALLOC_CHECK(1) MEMPOOL_ALLOC_CHECK(2) ) void * reallocate(void * ptr, size_t bytes){ MEMPOOL_REALLOC_CHECK(1) MEMPOOL_REALLOC_CHECK(2) } MEMPOOL_LOAD( 2, _load[0] = _pool1.load(); _load[1] = _pool2.load(); ) MEMPOOL_DEALLOC_METHOD( MEMPOOL_DEALLOC_CHECK(1) MEMPOOL_DEALLOC_CHECK(2) ) MEMPOOL_ANALYZERS(2) private: MEMPOOL_MEMBERS( MEMPOOL_MEMBER_POOL(1) MEMPOOL_MEMBER_POOL(2) ) }; template< MEMPOOL_TEMPLATE_PAIR(1), MEMPOOL_TEMPLATE_PAIR(2), MEMPOOL_TEMPLATE_PAIR(3)> class bucket_pool_3 { public: MEMPOOL_ALLOC_METHOD( 3, MEMPOOL_ALLOC_CHECK(1) MEMPOOL_ALLOC_CHECK(2) MEMPOOL_ALLOC_CHECK(3) ) void * reallocate(void * ptr, size_t bytes){ MEMPOOL_REALLOC_CHECK(1) MEMPOOL_REALLOC_CHECK(2) MEMPOOL_REALLOC_CHECK(3) return mempool_callbacks::reallocate(ptr, bytes); } MEMPOOL_LOAD( 3, _load[0] = _pool1.load(); _load[1] = _pool2.load(); _load[2] = _pool3.load(); ) MEMPOOL_DEALLOC_METHOD( MEMPOOL_DEALLOC_CHECK(1) MEMPOOL_DEALLOC_CHECK(2) MEMPOOL_DEALLOC_CHECK(3) ) MEMPOOL_ANALYZERS(3) private: MEMPOOL_MEMBERS( MEMPOOL_MEMBER_POOL(1) MEMPOOL_MEMBER_POOL(2) MEMPOOL_MEMBER_POOL(3) ) }; template< MEMPOOL_TEMPLATE_PAIR(1), MEMPOOL_TEMPLATE_PAIR(2), MEMPOOL_TEMPLATE_PAIR(3), MEMPOOL_TEMPLATE_PAIR(4)> class bucket_pool_4 { public: MEMPOOL_ALLOC_METHOD( 4, MEMPOOL_ALLOC_CHECK(1) MEMPOOL_ALLOC_CHECK(2) MEMPOOL_ALLOC_CHECK(3) MEMPOOL_ALLOC_CHECK(4) ) void * reallocate(void * ptr, size_t bytes){ MEMPOOL_REALLOC_CHECK(1) MEMPOOL_REALLOC_CHECK(2) MEMPOOL_REALLOC_CHECK(3) MEMPOOL_REALLOC_CHECK(4) return mempool_callbacks::reallocate(ptr, bytes); } MEMPOOL_LOAD( 4, _load[0] = _pool1.load(); _load[1] = _pool2.load(); _load[2] = _pool3.load(); _load[3] = _pool4.load(); ) MEMPOOL_DEALLOC_METHOD( MEMPOOL_DEALLOC_CHECK(1) MEMPOOL_DEALLOC_CHECK(2) MEMPOOL_DEALLOC_CHECK(3) MEMPOOL_DEALLOC_CHECK(4) ) MEMPOOL_ANALYZERS(4) private: MEMPOOL_MEMBERS( MEMPOOL_MEMBER_POOL(1) MEMPOOL_MEMBER_POOL(2) MEMPOOL_MEMBER_POOL(3) MEMPOOL_MEMBER_POOL(4) ) }; template< MEMPOOL_TEMPLATE_PAIR(1), MEMPOOL_TEMPLATE_PAIR(2), MEMPOOL_TEMPLATE_PAIR(3), MEMPOOL_TEMPLATE_PAIR(4), MEMPOOL_TEMPLATE_PAIR(5)> class bucket_pool_5 { public: MEMPOOL_ALLOC_METHOD( 5, MEMPOOL_ALLOC_CHECK(1) MEMPOOL_ALLOC_CHECK(2) MEMPOOL_ALLOC_CHECK(3) MEMPOOL_ALLOC_CHECK(4) MEMPOOL_ALLOC_CHECK(5) ) void * reallocate(void * ptr, size_t bytes){ MEMPOOL_REALLOC_CHECK(1) MEMPOOL_REALLOC_CHECK(2) MEMPOOL_REALLOC_CHECK(3) MEMPOOL_REALLOC_CHECK(4) MEMPOOL_REALLOC_CHECK(5) return mempool_callbacks::reallocate(ptr, bytes); } MEMPOOL_LOAD( 5, _load[0] = _pool1.load(); _load[1] = _pool2.load(); _load[2] = _pool3.load(); _load[3] = _pool4.load(); _load[4] = _pool5.load(); ) MEMPOOL_DEALLOC_METHOD( MEMPOOL_DEALLOC_CHECK(1) MEMPOOL_DEALLOC_CHECK(2) MEMPOOL_DEALLOC_CHECK(3) MEMPOOL_DEALLOC_CHECK(4) MEMPOOL_DEALLOC_CHECK(5) ) MEMPOOL_ANALYZERS(5) private: MEMPOOL_MEMBERS( MEMPOOL_MEMBER_POOL(1) MEMPOOL_MEMBER_POOL(2) MEMPOOL_MEMBER_POOL(3) MEMPOOL_MEMBER_POOL(4) MEMPOOL_MEMBER_POOL(5) ) }; template< MEMPOOL_TEMPLATE_PAIR(1), MEMPOOL_TEMPLATE_PAIR(2), MEMPOOL_TEMPLATE_PAIR(3), MEMPOOL_TEMPLATE_PAIR(4), MEMPOOL_TEMPLATE_PAIR(5), MEMPOOL_TEMPLATE_PAIR(6)> class bucket_pool_6 { public: MEMPOOL_ALLOC_METHOD( 6, MEMPOOL_ALLOC_CHECK(1) MEMPOOL_ALLOC_CHECK(2) MEMPOOL_ALLOC_CHECK(3) MEMPOOL_ALLOC_CHECK(4) MEMPOOL_ALLOC_CHECK(5) MEMPOOL_ALLOC_CHECK(6) ) void * reallocate(void * ptr, size_t bytes){ MEMPOOL_REALLOC_CHECK(1) MEMPOOL_REALLOC_CHECK(2) MEMPOOL_REALLOC_CHECK(3) MEMPOOL_REALLOC_CHECK(4) MEMPOOL_REALLOC_CHECK(5) MEMPOOL_REALLOC_CHECK(6) return mempool_callbacks::reallocate(ptr, bytes); } MEMPOOL_LOAD( 6, _load[0] = _pool1.load(); _load[1] = _pool2.load(); _load[2] = _pool3.load(); _load[3] = _pool4.load(); _load[4] = _pool5.load(); _load[5] = _pool6.load(); ) MEMPOOL_DEALLOC_METHOD( MEMPOOL_DEALLOC_CHECK(1) MEMPOOL_DEALLOC_CHECK(2) MEMPOOL_DEALLOC_CHECK(3) MEMPOOL_DEALLOC_CHECK(4) MEMPOOL_DEALLOC_CHECK(5) MEMPOOL_DEALLOC_CHECK(6) ) MEMPOOL_ANALYZERS(6) private: MEMPOOL_MEMBERS( MEMPOOL_MEMBER_POOL(1) MEMPOOL_MEMBER_POOL(2) MEMPOOL_MEMBER_POOL(3) MEMPOOL_MEMBER_POOL(4) MEMPOOL_MEMBER_POOL(5) MEMPOOL_MEMBER_POOL(6) ) }; template< MEMPOOL_TEMPLATE_PAIR(1), MEMPOOL_TEMPLATE_PAIR(2), MEMPOOL_TEMPLATE_PAIR(3), MEMPOOL_TEMPLATE_PAIR(4), MEMPOOL_TEMPLATE_PAIR(5), MEMPOOL_TEMPLATE_PAIR(6), MEMPOOL_TEMPLATE_PAIR(7)> class bucket_pool_7 { public: MEMPOOL_ALLOC_METHOD( 7, MEMPOOL_ALLOC_CHECK(1) MEMPOOL_ALLOC_CHECK(2) MEMPOOL_ALLOC_CHECK(3) MEMPOOL_ALLOC_CHECK(4) MEMPOOL_ALLOC_CHECK(5) MEMPOOL_ALLOC_CHECK(6) MEMPOOL_ALLOC_CHECK(7) ) void * reallocate(void * ptr, size_t bytes){ MEMPOOL_REALLOC_CHECK(1) MEMPOOL_REALLOC_CHECK(2) MEMPOOL_REALLOC_CHECK(3) MEMPOOL_REALLOC_CHECK(4) MEMPOOL_REALLOC_CHECK(5) MEMPOOL_REALLOC_CHECK(6) MEMPOOL_REALLOC_CHECK(7) return mempool_callbacks::reallocate(ptr, bytes); } MEMPOOL_LOAD( 7, _load[0] = _pool1.load(); _load[1] = _pool2.load(); _load[2] = _pool3.load(); _load[3] = _pool4.load(); _load[4] = _pool5.load(); _load[5] = _pool6.load(); _load[6] = _pool7.load(); ) MEMPOOL_DEALLOC_METHOD( MEMPOOL_DEALLOC_CHECK(1) MEMPOOL_DEALLOC_CHECK(2) MEMPOOL_DEALLOC_CHECK(3) MEMPOOL_DEALLOC_CHECK(4) MEMPOOL_DEALLOC_CHECK(5) MEMPOOL_DEALLOC_CHECK(6) MEMPOOL_DEALLOC_CHECK(7) ) MEMPOOL_ANALYZERS(7) private: MEMPOOL_MEMBERS( MEMPOOL_MEMBER_POOL(1) MEMPOOL_MEMBER_POOL(2) MEMPOOL_MEMBER_POOL(3) MEMPOOL_MEMBER_POOL(4) MEMPOOL_MEMBER_POOL(5) MEMPOOL_MEMBER_POOL(6) MEMPOOL_MEMBER_POOL(7) ) }; template< MEMPOOL_TEMPLATE_PAIR(1), MEMPOOL_TEMPLATE_PAIR(2), MEMPOOL_TEMPLATE_PAIR(3), MEMPOOL_TEMPLATE_PAIR(4), MEMPOOL_TEMPLATE_PAIR(5), MEMPOOL_TEMPLATE_PAIR(6), MEMPOOL_TEMPLATE_PAIR(7), MEMPOOL_TEMPLATE_PAIR(8)> class bucket_pool_8 { public: MEMPOOL_ALLOC_METHOD( 8, MEMPOOL_ALLOC_CHECK(1) MEMPOOL_ALLOC_CHECK(2) MEMPOOL_ALLOC_CHECK(3) MEMPOOL_ALLOC_CHECK(4) MEMPOOL_ALLOC_CHECK(5) MEMPOOL_ALLOC_CHECK(6) MEMPOOL_ALLOC_CHECK(7) MEMPOOL_ALLOC_CHECK(8) ) void * reallocate(void * ptr, size_t bytes){ MEMPOOL_REALLOC_CHECK(1) MEMPOOL_REALLOC_CHECK(2) MEMPOOL_REALLOC_CHECK(3) MEMPOOL_REALLOC_CHECK(4) MEMPOOL_REALLOC_CHECK(5) MEMPOOL_REALLOC_CHECK(6) MEMPOOL_REALLOC_CHECK(7) MEMPOOL_REALLOC_CHECK(8) return mempool_callbacks::reallocate(ptr, bytes); } MEMPOOL_LOAD( 8, _load[0] = _pool1.load(); _load[1] = _pool2.load(); _load[2] = _pool3.load(); _load[3] = _pool4.load(); _load[4] = _pool5.load(); _load[5] = _pool6.load(); _load[6] = _pool7.load(); _load[7] = _pool8.load(); ) MEMPOOL_DEALLOC_METHOD( MEMPOOL_DEALLOC_CHECK(1) MEMPOOL_DEALLOC_CHECK(2) MEMPOOL_DEALLOC_CHECK(3) MEMPOOL_DEALLOC_CHECK(4) MEMPOOL_DEALLOC_CHECK(5) MEMPOOL_DEALLOC_CHECK(6) MEMPOOL_DEALLOC_CHECK(7) MEMPOOL_DEALLOC_CHECK(8) ) MEMPOOL_ANALYZERS(8) private: MEMPOOL_MEMBERS( MEMPOOL_MEMBER_POOL(1) MEMPOOL_MEMBER_POOL(2) MEMPOOL_MEMBER_POOL(3) MEMPOOL_MEMBER_POOL(4) MEMPOOL_MEMBER_POOL(5) MEMPOOL_MEMBER_POOL(6) MEMPOOL_MEMBER_POOL(7) MEMPOOL_MEMBER_POOL(8) ) }; template< MEMPOOL_TEMPLATE_PAIR(1), MEMPOOL_TEMPLATE_PAIR(2), MEMPOOL_TEMPLATE_PAIR(3), MEMPOOL_TEMPLATE_PAIR(4), MEMPOOL_TEMPLATE_PAIR(5), MEMPOOL_TEMPLATE_PAIR(6), MEMPOOL_TEMPLATE_PAIR(7), MEMPOOL_TEMPLATE_PAIR(8), MEMPOOL_TEMPLATE_PAIR(9)> class bucket_pool_9 { public: MEMPOOL_ALLOC_METHOD( 9, MEMPOOL_ALLOC_CHECK(1) MEMPOOL_ALLOC_CHECK(2) MEMPOOL_ALLOC_CHECK(3) MEMPOOL_ALLOC_CHECK(4) MEMPOOL_ALLOC_CHECK(5) MEMPOOL_ALLOC_CHECK(6) MEMPOOL_ALLOC_CHECK(7) MEMPOOL_ALLOC_CHECK(8) MEMPOOL_ALLOC_CHECK(9) ) void * reallocate(void * ptr, size_t bytes){ MEMPOOL_REALLOC_CHECK(1) MEMPOOL_REALLOC_CHECK(2) MEMPOOL_REALLOC_CHECK(3) MEMPOOL_REALLOC_CHECK(4) MEMPOOL_REALLOC_CHECK(5) MEMPOOL_REALLOC_CHECK(6) MEMPOOL_REALLOC_CHECK(7) MEMPOOL_REALLOC_CHECK(8) MEMPOOL_REALLOC_CHECK(9) return mempool_callbacks::reallocate(ptr, bytes); } MEMPOOL_LOAD( 9, _load[0] = _pool1.load(); _load[1] = _pool2.load(); _load[2] = _pool3.load(); _load[3] = _pool4.load(); _load[4] = _pool5.load(); _load[5] = _pool6.load(); _load[6] = _pool7.load(); _load[7] = _pool8.load(); _load[8] = _pool9.load(); ) MEMPOOL_DEALLOC_METHOD( MEMPOOL_DEALLOC_CHECK(1) MEMPOOL_DEALLOC_CHECK(2) MEMPOOL_DEALLOC_CHECK(3) MEMPOOL_DEALLOC_CHECK(4) MEMPOOL_DEALLOC_CHECK(5) MEMPOOL_DEALLOC_CHECK(6) MEMPOOL_DEALLOC_CHECK(7) MEMPOOL_DEALLOC_CHECK(8) MEMPOOL_DEALLOC_CHECK(9) ) MEMPOOL_ANALYZERS(9) private: MEMPOOL_MEMBERS( MEMPOOL_MEMBER_POOL(1) MEMPOOL_MEMBER_POOL(2) MEMPOOL_MEMBER_POOL(3) MEMPOOL_MEMBER_POOL(4) MEMPOOL_MEMBER_POOL(5) MEMPOOL_MEMBER_POOL(6) MEMPOOL_MEMBER_POOL(7) MEMPOOL_MEMBER_POOL(8) MEMPOOL_MEMBER_POOL(9) ) }; template< MEMPOOL_TEMPLATE_PAIR(1), MEMPOOL_TEMPLATE_PAIR(2), MEMPOOL_TEMPLATE_PAIR(3), MEMPOOL_TEMPLATE_PAIR(4), MEMPOOL_TEMPLATE_PAIR(5), MEMPOOL_TEMPLATE_PAIR(6), MEMPOOL_TEMPLATE_PAIR(7), MEMPOOL_TEMPLATE_PAIR(8), MEMPOOL_TEMPLATE_PAIR(9), MEMPOOL_TEMPLATE_PAIR(10)> class bucket_pool_10 { public: MEMPOOL_ALLOC_METHOD( 10, MEMPOOL_ALLOC_CHECK(1) MEMPOOL_ALLOC_CHECK(2) MEMPOOL_ALLOC_CHECK(3) MEMPOOL_ALLOC_CHECK(4) MEMPOOL_ALLOC_CHECK(5) MEMPOOL_ALLOC_CHECK(6) MEMPOOL_ALLOC_CHECK(7) MEMPOOL_ALLOC_CHECK(8) MEMPOOL_ALLOC_CHECK(9) MEMPOOL_ALLOC_CHECK(10) ) void * reallocate(void * ptr, size_t bytes){ MEMPOOL_REALLOC_CHECK(1) MEMPOOL_REALLOC_CHECK(2) MEMPOOL_REALLOC_CHECK(3) MEMPOOL_REALLOC_CHECK(4) MEMPOOL_REALLOC_CHECK(5) MEMPOOL_REALLOC_CHECK(6) MEMPOOL_REALLOC_CHECK(7) MEMPOOL_REALLOC_CHECK(8) MEMPOOL_REALLOC_CHECK(9) MEMPOOL_REALLOC_CHECK(10) return mempool_callbacks::reallocate(ptr, bytes); } MEMPOOL_LOAD( 10, _load[0] = _pool1.load(); _load[1] = _pool2.load(); _load[2] = _pool3.load(); _load[3] = _pool4.load(); _load[4] = _pool5.load(); _load[5] = _pool6.load(); _load[6] = _pool7.load(); _load[7] = _pool8.load(); _load[8] = _pool9.load(); _load[9] = _pool10.load(); ) MEMPOOL_DEALLOC_METHOD( MEMPOOL_DEALLOC_CHECK(1) MEMPOOL_DEALLOC_CHECK(2) MEMPOOL_DEALLOC_CHECK(3) MEMPOOL_DEALLOC_CHECK(4) MEMPOOL_DEALLOC_CHECK(5) MEMPOOL_DEALLOC_CHECK(6) MEMPOOL_DEALLOC_CHECK(7) MEMPOOL_DEALLOC_CHECK(8) MEMPOOL_DEALLOC_CHECK(9) MEMPOOL_DEALLOC_CHECK(10) ) MEMPOOL_ANALYZERS(10) private: MEMPOOL_MEMBERS( MEMPOOL_MEMBER_POOL(1) MEMPOOL_MEMBER_POOL(2) MEMPOOL_MEMBER_POOL(3) MEMPOOL_MEMBER_POOL(4) MEMPOOL_MEMBER_POOL(5) MEMPOOL_MEMBER_POOL(6) MEMPOOL_MEMBER_POOL(7) MEMPOOL_MEMBER_POOL(8) MEMPOOL_MEMBER_POOL(9) MEMPOOL_MEMBER_POOL(10) ) }; #endif