Blame | Last modification | View Log | Download | RSS feed
#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 <iostream>#define MEMPOOL_DEBUG(x) std::cout << x << std::endl;#else#define MEMPOOL_DEBUG(x)#endif#ifdef MEMPOOL_ASSERTS#include <iostream>#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 <iostream>#include <sstream>#include <string>#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 <cstring>/** This is where the classes are*///Callbacks for fallback if the pool is out of spaceclass 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 tostatic 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 memorystatic inline void * allocate(size_t size) pool_nothrow {MEMPOOL_DEBUG("Returing malloced memory:" << size << " bytes");return get_instance()._malloc(size);}//frees memorystatic 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 singletonstatic inline mempool_callbacks & get_instance(void) pool_nothrow {static mempool_callbacks _single(std::malloc, std::realloc, std::free);return _single;}//The constructorinline mempool_callbacks(mallocer_t mallocer, reallocer_t reallocer, freer_t freer) :_malloc(mallocer),_free(freer),_realloc(reallocer){}//not copyablemempool_callbacks & operator = (const mempool_callbacks & other);mempool_callbacks(const mempool_callbacks & other);//member callbacksmallocer_t _malloc;reallocer_t _realloc;freer_t _free;};//The workhorse of the templates library, a class that holds a pool that it allocates memory fromtemplate <typename T, size_t size>class object_memory_pool; //forward declarationtemplate <size_t bytes, size_t size>class memory_pool_no_fullflag { //forward declarationpublic:memory_pool_no_fullflag<bytes, size>():_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<bytes, size> * 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 itselfconst 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<bytes, size> * contains(void * ptr) pool_hot {if ((ptr >= memoryPool_start) && (ptr < memoryPool_end)) return this;return (_link) ? _link -> contains(ptr) : NULL;}#ifdef MEMPOOL_PERFORMANCE_DEBUGGINGconst 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 inint 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();}#endifprotected://copy ctors and assignment operatormemory_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<bytes, size>))) memory_pool_no_fullflag<bytes, size>();_link -> depth = depth + 1;}return _link -> allocate();}size_t current; //The current number of items in the poolsize_t threshold; //The number of items in the pool before it starts using fallbackchar memoryPool_start[size * bytes]; //The memory poolchar * memoryPool_end; //The end of the memory poolbool used_start[size]; //A pool to know whether or not an item is currently usedbool * used_end; //The end of the boolean flagsbool * runningPointer; //A pointer that loops, keeping an eye on what is taken and what isn'tmemory_pool_no_fullflag<bytes, size> * _link; //Creates a linked list when expandingsize_t depth;};template <size_t bytes, size_t size>class memory_pool : public memory_pool_no_fullflag<bytes, size> {public:memory_pool<bytes, size>() :memory_pool_no_fullflag<bytes, size>(),_full(false){}virtual ~memory_pool(void){}inline void * allocate(void) pool_hot {if (_full) return mempool_callbacks::allocate(bytes);return memory_pool_no_fullflag<bytes, size>::allocate();}inline void deallocate(void * ptr) pool_hot {_full = false;return memory_pool_no_fullflag<bytes, size>::deallocate(ptr);}#ifdef MEMPOOL_PERFORMANCE_DEBUGGINGconst char * const getName(void){ return "memory_pool"; }#endifprivate://copy ctors and assignment operatormemory_pool & operator = (const memory_pool & other);memory_pool(const memory_pool & other);bool _full;template <typename T, size_t s> 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 <typename T, size_t size>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 overloadedinline 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<sizeof(T), size> * 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_DEBUGGINGconst std::string dump(void){ return _pool.dump(); }#endifprivate:memory_pool<sizeof(T), size> _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 <map>#include <iostream>#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<size_t, size_t> mapping;\std::map<size_t, size_t> current_mapping;\std::map<size_t, size_t> max_mapping;\std::map<void *, size_t> 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]; }#endiftemplate<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