Jamoma API  0.6.0.a19
mempool.h
1 #ifndef mempool___mempool_h
2 #define mempool___mempool_h
3 
4 
5 /*
6  * This is where you may alter options to give mempool++
7  */
8 
9 //#define MEMPOOL_DEBUGGING //Causes mempool++ to spit out what it's doing to the console
10 //#define MEMPOOL_ASSERTS //Causes mempool++ to check what it's doing and look for impossible cases
11 #define MEMPOOL_OVERFLOW 3.0f / 4.0f //Changes how full a pool is before going to fallbacks
12 //#define MEMPOOL_DETERMINE_DISTRIBUTION //Allows mempool++ to automatically give you the best distribution
13 #define MEMPOOL_DETERMINE_SCALAR 5.0f / 3.0f //Gives you this times the max number at any given time from distribution
14 #define MEMPOOL_FALLBACK_DEPTH 3
15 //#define MEMPOOL_PERFORMANCE_DEBUGGING
16 //#define private public
17 
18 
19 //version info
20 #define __MEMPOOL_MAJOR__ 1
21 #define __MEMPOOL_MINOR__ 2
22 #define __MEMPOOL_PATCH__ 0
23 #define __MEMPOOL_VERSION__ (__MEMPOOL_MAJOR__ * 10000 + __MEMPOOL_MINOR__ * 100 + __MEMPOOL_PATCH__)
24 
25 /*
26  * This is where special function / macro for special options are
27  */
28 
29 #ifdef MEMPOOL_DEBUGGING
30  #include <iostream>
31  #define MEMPOOL_DEBUG(x) std::cout << x << std::endl;
32 #else
33  #define MEMPOOL_DEBUG(x)
34 #endif
35 
36 #ifdef MEMPOOL_ASSERTS
37  #include <iostream>
38  #define MEMPOOL_ASSERT(condition) if (pool_unlikely(!(condition))){ std::cout << #condition << " isn't true" << std::endl; }
39  #define MEMPOOL_ASSERT2(condition, out) if (pool_unlikely(!(condition))){ std::cout << out << std::endl; }
40 #else
41  #define MEMPOOL_ASSERT(condition)
42  #define MEMPOOL_ASSERT2(condition, out)
43 #endif
44 
45 #ifdef MEMPOOL_PERFORMANCE_DEBUGGING
46  #include <iostream>
47  #include <sstream>
48  #include <string>
49  #define MEMPOOL_PERFORMANCE_DEBUG(x) std::cout << x << std::endl;
50 #else
51  #define MEMPOOL_PERFORMANCE_DEBUG(x)
52 #endif
53 
54 
55 
56 /*
57  * This is where compiler-specific code goes
58  */
59 #ifdef __GNUC__
60  #if (__GNUC__ >= 3)
61  #define POOL_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
62  #else
63  #define POOL_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100)
64  #endif
65 
66  #if (POOL_GCC_VERSION >= 40300)
67  #define pool_hot pool_nothrow __attribute__ ((hot))
68  #else
69  #define pool_hot pool_nothrow
70  #endif
71 
72  #if (POOL_GCC_VERSION >= 29600)
73  #define pool_likely(x) __builtin_expect((long)((bool)(x)),1)
74  #define pool_unlikely(x) __builtin_expect((long)((bool)(x)),0)
75  #else
76  #define pool_likely(x) x
77  #define pool_unlikely(x) x
78  #endif
79 
80  #define pool_nothrow throw()
81 #else
82  #define pool_hot pool_nothrow
83  #define pool_likely(x) x
84  #define pool_unlikely(x) x
85  #define pool_nothrow
86 #endif
87 
88 #include <cstring>
89 
90 /*
91  * This is where the classes are
92  */
93 
94 //Callbacks for fallback if the pool is out of space
95 class mempool_callbacks {
96 public:
97  typedef void * (*mallocer_t)(size_t);
98  typedef void(*freer_t)(void *);
99  typedef void * (*reallocer_t)(void *, size_t);
100 
101  //Allows the user to alter where the fallbacks point to
102  static inline void set(mallocer_t mallocer, reallocer_t reallocer, freer_t freer) pool_nothrow {
103  get_instance()._malloc = mallocer;
104  get_instance()._free = freer;
105  get_instance()._realloc = reallocer;
106  }
107 
108  //allocates memory
109  static inline void * allocate(size_t size) pool_nothrow {
110  MEMPOOL_DEBUG("Returing malloced memory:" << size << " bytes");
111  return get_instance()._malloc(size);
112  }
113 
114  //frees memory
115  static inline void deallocate(void * ptr) pool_nothrow {
116  MEMPOOL_DEBUG("Freeing malloced memory: " << ptr);
117  get_instance()._free(ptr);
118  }
119 
120  static inline void * reallocate(void * ptr, size_t size) pool_nothrow {
121  MEMPOOL_DEBUG("Reallocating memory: " << ptr << " to " << size << " bytes");
122  return get_instance()._realloc(ptr, size);
123  }
124 private:
125  //Retrieves a Meyers singleton
126  static inline mempool_callbacks & get_instance(void) pool_nothrow {
127  static mempool_callbacks _single(std::malloc, std::realloc, std::free);
128  return _single;
129  }
130 
131  //The constructor
132  inline mempool_callbacks(mallocer_t mallocer, reallocer_t reallocer, freer_t freer) :
133  _malloc(mallocer),
134  _free(freer),
135  _realloc(reallocer){
136  }
137 
138  //not copyable
139  mempool_callbacks & operator = (const mempool_callbacks & other);
140  mempool_callbacks(const mempool_callbacks & other);
141 
142  //member callbacks
143  mallocer_t _malloc;
144  reallocer_t _realloc;
145  freer_t _free;
146 };
147 
148 //The workhorse of the templates library, a class that holds a pool that it allocates memory from
149 template <typename T, size_t size>
150 class object_memory_pool; //forward declaration
151 
152 template <size_t bytes, size_t size>
153 class memory_pool_no_fullflag { //forward declaration
154 public:
155  memory_pool_no_fullflag<bytes, size>():
156  _link(NULL),
157  current(0),
158  depth(0),
159  threshold((size_t)((float)size * (MEMPOOL_OVERFLOW))),
160  memoryPool_end(memoryPool_start + (size * bytes)),
161  used_end(used_start + size),
162  runningPointer(used_start)
163  {
164  std::memset(used_start, 0, size * sizeof(bool));
165  }
166 
167  virtual ~memory_pool_no_fullflag(void){
168  if (_link){
169  _link -> ~memory_pool_no_fullflag();
170  mempool_callbacks::deallocate(_link);
171  }
172  }
173 
174  inline size_t load(void) const pool_nothrow {
175  return current;
176  }
177 
178  inline void * allocate(void) pool_hot {
179  if (void * res = allocate_nofallback()){
180  return res;
181  }
182  return _link_allocate();
183  }
184 
185  inline void deallocate(void * ptr) pool_hot {
186  if (memory_pool_no_fullflag<bytes, size> * container = contains(ptr)){
187  container -> deallocate_nofallback(ptr);
188  } else {
189  mempool_callbacks::deallocate(ptr);
190  }
191  }
192 
193  void * allocate_nofallback() pool_hot {
194  if (!(*runningPointer)) return _return_current();
195  if (++runningPointer >= used_end) runningPointer = used_start;
196  if (current < threshold){
197  //make sure it doesnt loop around infinity so point it to itself
198  const bool * position = runningPointer;
199  do {
200  if (!(*runningPointer)) return _return_current();
201  if (++runningPointer >= used_end) runningPointer = used_start;
202  } while (position != runningPointer);
203  MEMPOOL_ASSERT2(false, "Got to impossible code location");
204  }
205 
206  MEMPOOL_DEBUG("Returing null");
207  return NULL;
208  }
209 
210  void deallocate_nofallback(void * ptr) pool_hot {
211  MEMPOOL_ASSERT2(current, "current not positive");
212  --current;
213  MEMPOOL_DEBUG("Freeing slot " << ((char*)ptr - memoryPool_start) / bytes);
214  MEMPOOL_DEBUG(" pointer=" << ptr);
215  MEMPOOL_ASSERT2((((char*)ptr - memoryPool_start) / bytes) < size, "Freeing slot " << (((char*)ptr - memoryPool_start) / bytes) << " in a pool with only " << size << " items");
216  MEMPOOL_ASSERT2(used_start[((char*)ptr - memoryPool_start) / bytes], "Freeing " << ptr << " and it's already been freed");
217  used_start[(((char*)ptr - memoryPool_start) / bytes)] = false;
218  }
219 
220  inline memory_pool_no_fullflag<bytes, size> * contains(void * ptr) pool_hot {
221  if ((ptr >= memoryPool_start) && (ptr < memoryPool_end)) return this;
222  return (_link) ? _link -> contains(ptr) : NULL;
223  }
224 
225  #ifdef MEMPOOL_PERFORMANCE_DEBUGGING
226  const char * const getName(void){ return "memory_pool_no_fullflag"; }
227 
228  const char * getDepth(){
229  static const char * depths[15] = {
230  " ",
231  " ",
232  " ",
233  " ",
234  " ",
235  " ",
236  " ",
237  " ",
238  " ",
239  " ",
240  " ",
241  " ",
242  " ",
243  " ",
244  "- ",
245  };
246  if (depth > 14) return depths[14];
247  return depths[depth];
248  }
249 
250  std::string dump(void){
251  std::stringstream output;
252  output << getDepth() << getName() << "<" << bytes << ", " << size << ">: " << (void*)this << std::endl;
253  output << getDepth() << "Currently holding: " << current << " items." << std::endl;
254  //_____
255  output << getDepth() << "+";
256  for(int i = 0; i < 78; ++i){
257  output << "_";
258  }
259  output << "+" << std::endl << getDepth() << "|";
260 
261  //Fill in
262  int i;
263  for(i = 0; i < size; ++i){
264  if ((i % 80 == 0) && (i != 0)){
265  output << "|" << std::endl << getDepth() << "|";
266  }
267  if (i == (runningPointer - used_start)){
268  if (used_start[i]){
269  output << "R";
270  } else {
271  output << "P";
272  }
273  } else if (used_start[i]){
274  output << "X";
275  } else {
276  output << " ";
277  }
278  }
279 
280  for(; (i % 80) != 0; ++i){
281  output << "+";
282  }
283 
284  //-------
285  output << getDepth() << "+";
286  for(i = 0; i < 78; ++i){
287  output << "-";
288  }
289  output << "+";
290  if (_link){
291  output << "----+" << std::endl;
292  }
293  return output.str();
294  }
295  #endif
296 protected:
297  //copy ctors and assignment operator
298  memory_pool_no_fullflag & operator = (const memory_pool_no_fullflag & other);
299  memory_pool_no_fullflag(const memory_pool_no_fullflag & other);
300 
301  inline void * _return_current(void) pool_hot {
302  *runningPointer = true;
303  ++current;
304  MEMPOOL_DEBUG("Returning slot " << runningPointer - used_start << " at depth " << depth);
305  MEMPOOL_DEBUG(" memoryPool_start=" << (void*)memoryPool_start);
306  MEMPOOL_DEBUG(" memoryPool_end =" << (void*)memoryPool_end);
307  MEMPOOL_DEBUG(" return value =" << (void*)(memoryPool_start + ((runningPointer - used_start) * bytes)));
308  MEMPOOL_ASSERT2(((memoryPool_start + ((runningPointer - used_start) * bytes))) < memoryPool_end, "Returning pointer outside the high end of the pool");
309  MEMPOOL_ASSERT2(((memoryPool_start + ((runningPointer - used_start) * bytes))) >= memoryPool_start, "Returning pointer outside the low end of the pool");
310  const bool * const pre = runningPointer;
311  if (++runningPointer >= used_end) runningPointer = used_start;
312  return memoryPool_start + ((pre - used_start) * bytes);
313  }
314 
315  void * _link_allocate(void) pool_nothrow {
316  if (depth >= MEMPOOL_FALLBACK_DEPTH) return mempool_callbacks::allocate(bytes);
317  if (!_link){
318  _link = new(mempool_callbacks::allocate(sizeof(memory_pool_no_fullflag<bytes, size>))) memory_pool_no_fullflag<bytes, size>();
319  _link -> depth = depth + 1;
320  }
321  return _link -> allocate();
322  }
323 
324  size_t current; //The current number of items in the pool
325  size_t threshold; //The number of items in the pool before it starts using fallback
326  char memoryPool_start[size * bytes]; //The memory pool
327  char * memoryPool_end; //The end of the memory pool
328  bool used_start[size]; //A pool to know whether or not an item is currently used
329  bool * used_end; //The end of the boolean flags
330  bool * runningPointer; //A pointer that loops, keeping an eye on what is taken and what isn't
331  memory_pool_no_fullflag<bytes, size> * _link; //Creates a linked list when expanding
332  size_t depth;
333 };
334 
335 template <size_t bytes, size_t size>
336 class memory_pool : public memory_pool_no_fullflag<bytes, size> {
337 public:
338  memory_pool<bytes, size>() :
339  memory_pool_no_fullflag<bytes, size>(),
340  _full(false){}
341 
342  virtual ~memory_pool(void){}
343 
344  inline void * allocate(void) pool_hot {
345  if (_full) return mempool_callbacks::allocate(bytes);
346  return memory_pool_no_fullflag<bytes, size>::allocate();
347  }
348 
349  inline void deallocate(void * ptr) pool_hot {
350  _full = false;
351  return memory_pool_no_fullflag<bytes, size>::deallocate(ptr);
352  }
353 
354  #ifdef MEMPOOL_PERFORMANCE_DEBUGGING
355  const char * const getName(void){ return "memory_pool"; }
356  #endif
357 private:
358  //copy ctors and assignment operator
359  memory_pool & operator = (const memory_pool & other);
360  memory_pool(const memory_pool & other);
361 
362  bool _full;
363 
364  template <typename T, size_t s> friend class object_memory_pool;
365 };
366 
367 
368 //A memory pool for a specific type of object
369 #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)) ]
370 template <typename T, size_t size>
371 class object_memory_pool {
372 public:
373  inline size_t load(void) const pool_nothrow {
374  return _pool.load();
375  }
376 
377  virtual ~object_memory_pool() pool_nothrow { } //so that it can be overloaded
378 
379  inline T * allocate(void) pool_hot { return new (_pool.allocate()) T(); }
380  inline void * allocate_noctor(void) pool_nothrow { return _pool.allocate(); }
381 
382  inline void deallocate(T * ptr) pool_hot {
383  ptr -> ~T();
384  _pool.deallocate(ptr);
385  }
386 
387  inline memory_pool<sizeof(T), size> * contains(T * ptr) const pool_hot {
388  return _pool.contains((void*)ptr);
389  }
390 
391  inline T * alloc_nofallback() pool_hot {
392  if (void * res = _pool.allocate_nofallback()){
393  return new (res) T();
394  }
395  return NULL;
396  }
397 
398  inline void deallocate_nofallback(T * ptr) pool_hot {
399  ptr -> ~T();
400  _pool.deallocate_nofallback(ptr);
401  }
402  #ifdef MEMPOOL_PERFORMANCE_DEBUGGING
403  const std::string dump(void){ return _pool.dump(); }
404  #endif
405 private:
406  memory_pool<sizeof(T), size> _pool;
407 };
408 
409 
410 #define MEMPOOL_TEMPLATE_PAIR(x) size_t bytes ## x , size_t count ## x
411 #define MEMPOOL_ALLOC_CHECK(x) if (bytes <= bytes ## x ){ if (void * res = (_pool ## x).allocate_nofallback()) return res; }
412 #define MEMPOOL_DEALLOC_CHECK(x) if (memory_pool_no_fullflag< bytes ## x , count ## x > * container = (_pool ## x).contains(ptr)){ container -> deallocate_nofallback(ptr); return; }
413 #define MEMPOOL_MEMBER_POOL(x) memory_pool< bytes ## x , count ## x > _pool ## x;
414 
415 #define MEMPOOL_REALLOC_CHECK(x)\
416  if (memory_pool_no_fullflag< bytes ## x , count ## x > * container = (_pool ## x).contains(ptr)){\
417  if (bytes <= bytes ## x) return ptr;\
418  void * newvalue = allocate(bytes);\
419  std::memcpy(newvalue, ptr, bytes ## x);\
420  container -> deallocate_nofallback(ptr);\
421  return newvalue;\
422  }
423 
424 
425 #ifdef MEMPOOL_DETERMINE_DISTRIBUTION
426  #include <map>
427  #include <iostream>
428  #define MEMPOOL_ALLOC_METHOD(number, code)\
429  bucket_pool_ ## number (void) : _profile_on_delete(0) { }\
430  ~bucket_pool_ ## number (void) { \
431  if (_profile_on_delete){ \
432  dump_atonce(_profile_on_delete, _profile_on_delete / 40); \
433  dump_template(_profile_on_delete); \
434  } \
435  }\
436  void * allocate(size_t bytes) pool_hot {\
437  if (mapping.find(bytes) != mapping.end()){\
438  ++mapping[bytes];\
439  ++current_mapping[bytes];\
440  if (current_mapping[bytes] > max_mapping[bytes]) max_mapping[bytes] = current_mapping[bytes];\
441  } else {\
442  mapping[bytes] = 1;\
443  max_mapping[bytes] = 1;\
444  current_mapping[bytes] = 1;\
445  }\
446  void * res = mempool_callbacks::allocate(bytes);\
447  mem_mapping[res] = bytes;\
448  return res;\
449  }
450  #define MEMPOOL_DEALLOC_METHOD(code)\
451  void deallocate(void * ptr) pool_hot {\
452  --current_mapping[mem_mapping[ptr]];\
453  mem_mapping.erase(ptr);\
454  mempool_callbacks::deallocate(ptr);\
455  }
456 
457  #define MEMPOOL_ANALYZERS(macro_count)\
458  inline size_t _max(size_t one, size_t two){ return (one > two) ? one : two; }\
459  void dump_total(size_t max, size_t sep = 16, size_t tlen = 30){\
460  std::cout << "-------- Total --------" << std::endl;\
461  size_t max_amount = 0;\
462  for(size_t i = 0; i < max;){\
463  size_t amount = 0;\
464  for(size_t j = 0; j < sep; ++j, ++i){\
465  if (mapping.find(i) != mapping.end()){\
466  amount += mapping[i];\
467  }\
468  }\
469  if (amount > max_amount) max_amount = amount;\
470  }\
471  float scalar = ((float)max_amount) / ((float)tlen);\
472  \
473  for(size_t i = 0; i < max;){\
474  size_t amount = 0;\
475  for(size_t j = 0; j < sep; ++j, ++i){\
476  if (mapping.find(i) != mapping.end()){\
477  amount += mapping[i];\
478  }\
479  }\
480  \
481  if (i < 10) std::cout << ' ';\
482  if (i < 100) std::cout << ' ';\
483  if (i < 1000) std::cout << ' ';\
484  if (i < 10000) std::cout << ' ';\
485  std::cout << i << ':';\
486  \
487  for(size_t j = 0; j < (size_t)((float)amount / scalar); ++j){\
488  std::cout << '*';\
489  }\
490  std::cout << '(' << amount << ')' << std::endl;\
491  }\
492  }\
493  \
494  void dump_atonce(size_t max, size_t sep = 16, size_t tlen = 30){\
495  std::cout << "------ Distribution for \"" << _str << "\" ------" << std::endl;\
496  size_t max_amount = 0;\
497  for(size_t i = 0; i < max;){\
498  size_t amount = 0;\
499  for(size_t j = 0; j < sep; ++j, ++i){\
500  if (max_mapping.find(i) != max_mapping.end()){\
501  amount += max_mapping[i];\
502  }\
503  }\
504  if (amount > max_amount) max_amount = amount;\
505  }\
506  float scalar = ((float)max_amount) / ((float)tlen);\
507  \
508  for(size_t i = 0; i < max;){\
509  size_t amount = 0;\
510  for(size_t j = 0; j < sep; ++j, ++i){\
511  if (max_mapping.find(i) != max_mapping.end()){\
512  amount += max_mapping[i];\
513  }\
514  }\
515  \
516  if (i < 10) std::cout << ' ';\
517  if (i < 100) std::cout << ' ';\
518  if (i < 1000) std::cout << ' ';\
519  if (i < 10000) std::cout << ' ';\
520  std::cout << i << ':';\
521  \
522  for(size_t j = 0; j < (size_t)((float)amount / scalar); ++j){\
523  std::cout << '*';\
524  }\
525  std::cout << '(' << amount << ')' << std::endl;\
526  }\
527  }\
528  \
529  void dump_template(size_t max){\
530  std::cout << "Recommended Template for \"" << _str << "\" = ";\
531  size_t total_at_once = 0;\
532  size_t highest = 0;\
533  for(size_t i = 0; i < max; ++i){\
534  if (max_mapping.find(i) != max_mapping.end()){\
535  total_at_once += max_mapping[i];\
536  highest = i;\
537  }\
538  }\
539  \
540  size_t count = 0;\
541  size_t total_at_once_part = total_at_once / macro_count;\
542  size_t current = 0;\
543  size_t totalsofar = 0;\
544  std::cout << '<';\
545  for(size_t i = 0; ((i < max) && (count < (macro_count -1))); ++i){\
546  if (max_mapping.find(i) != max_mapping.end()){\
547  current += max_mapping[i];\
548  totalsofar += max_mapping[i];\
549  if (current > total_at_once_part){\
550  std::cout << (i - 1) << ", " << (size_t)(((float)current - max_mapping[i]) * (MEMPOOL_DETERMINE_SCALAR)) << ", ";\
551  current = max_mapping[i];\
552  ++count;\
553  }\
554  }\
555  }\
556  std::cout << max << ", " << _max((size_t)((float)(total_at_once - totalsofar) * (MEMPOOL_DETERMINE_SCALAR)), total_at_once_part / 2) << '>' << std::endl;\
557  }\
558  \
559  inline void profile_on_delete(size_t var, const std::string & str){ _profile_on_delete = var; _str = str; }
560 
561  #define MEMPOOL_MEMBERS(code)\
562  std::map<size_t, size_t> mapping;\
563  std::map<size_t, size_t> current_mapping;\
564  std::map<size_t, size_t> max_mapping;\
565  std::map<void *, size_t> mem_mapping;\
566  size_t _profile_on_delete;\
567  std::string _str;
568  #define MEMPOOL_LOAD(number, code) inline size_t * load(void) const pool_nothrow { static size_t _load[number] = {0}; return &_load[0]; }
569 #else
570  #define MEMPOOL_ALLOC_METHOD(number, code)\
571  void * allocate(size_t bytes) pool_hot {\
572  code\
573  return mempool_callbacks::allocate(bytes);\
574  }
575  #define MEMPOOL_DEALLOC_METHOD(code)\
576  void deallocate(void * ptr) pool_hot {\
577  code\
578  mempool_callbacks::deallocate(ptr);\
579  }
580  #define MEMPOOL_ANALYZERS(macro_count)
581  #define MEMPOOL_MEMBERS(code) code
582  #define MEMPOOL_LOAD(number, code) inline size_t * load(void) const pool_nothrow { static size_t _load[number]; code return &_load[0]; }
583 #endif
584 
585 template<
586 MEMPOOL_TEMPLATE_PAIR(1),
587 MEMPOOL_TEMPLATE_PAIR(2)>
588 class bucket_pool_2 {
589 public:
590  MEMPOOL_ALLOC_METHOD(
591  2,
592  MEMPOOL_ALLOC_CHECK(1)
593  MEMPOOL_ALLOC_CHECK(2)
594  )
595  void * reallocate(void * ptr, size_t bytes){
596  MEMPOOL_REALLOC_CHECK(1)
597  MEMPOOL_REALLOC_CHECK(2)
598  }
599  MEMPOOL_LOAD(
600  2,
601  _load[0] = _pool1.load();
602  _load[1] = _pool2.load();
603  )
604  MEMPOOL_DEALLOC_METHOD(
605  MEMPOOL_DEALLOC_CHECK(1)
606  MEMPOOL_DEALLOC_CHECK(2)
607  )
608  MEMPOOL_ANALYZERS(2)
609 private:
610  MEMPOOL_MEMBERS(
611  MEMPOOL_MEMBER_POOL(1)
612  MEMPOOL_MEMBER_POOL(2)
613  )
614 };
615 
616 template<
617 MEMPOOL_TEMPLATE_PAIR(1),
618 MEMPOOL_TEMPLATE_PAIR(2),
619 MEMPOOL_TEMPLATE_PAIR(3)>
620 class bucket_pool_3 {
621 public:
622  MEMPOOL_ALLOC_METHOD(
623  3,
624  MEMPOOL_ALLOC_CHECK(1)
625  MEMPOOL_ALLOC_CHECK(2)
626  MEMPOOL_ALLOC_CHECK(3)
627  )
628  void * reallocate(void * ptr, size_t bytes){
629  MEMPOOL_REALLOC_CHECK(1)
630  MEMPOOL_REALLOC_CHECK(2)
631  MEMPOOL_REALLOC_CHECK(3)
632  return mempool_callbacks::reallocate(ptr, bytes);
633  }
634  MEMPOOL_LOAD(
635  3,
636  _load[0] = _pool1.load();
637  _load[1] = _pool2.load();
638  _load[2] = _pool3.load();
639  )
640  MEMPOOL_DEALLOC_METHOD(
641  MEMPOOL_DEALLOC_CHECK(1)
642  MEMPOOL_DEALLOC_CHECK(2)
643  MEMPOOL_DEALLOC_CHECK(3)
644  )
645  MEMPOOL_ANALYZERS(3)
646 private:
647  MEMPOOL_MEMBERS(
648  MEMPOOL_MEMBER_POOL(1)
649  MEMPOOL_MEMBER_POOL(2)
650  MEMPOOL_MEMBER_POOL(3)
651  )
652 };
653 
654 template<
655 MEMPOOL_TEMPLATE_PAIR(1),
656 MEMPOOL_TEMPLATE_PAIR(2),
657 MEMPOOL_TEMPLATE_PAIR(3),
658 MEMPOOL_TEMPLATE_PAIR(4)>
659 class bucket_pool_4 {
660 public:
661  MEMPOOL_ALLOC_METHOD(
662  4,
663  MEMPOOL_ALLOC_CHECK(1)
664  MEMPOOL_ALLOC_CHECK(2)
665  MEMPOOL_ALLOC_CHECK(3)
666  MEMPOOL_ALLOC_CHECK(4)
667  )
668  void * reallocate(void * ptr, size_t bytes){
669  MEMPOOL_REALLOC_CHECK(1)
670  MEMPOOL_REALLOC_CHECK(2)
671  MEMPOOL_REALLOC_CHECK(3)
672  MEMPOOL_REALLOC_CHECK(4)
673  return mempool_callbacks::reallocate(ptr, bytes);
674  }
675  MEMPOOL_LOAD(
676  4,
677  _load[0] = _pool1.load();
678  _load[1] = _pool2.load();
679  _load[2] = _pool3.load();
680  _load[3] = _pool4.load();
681  )
682  MEMPOOL_DEALLOC_METHOD(
683  MEMPOOL_DEALLOC_CHECK(1)
684  MEMPOOL_DEALLOC_CHECK(2)
685  MEMPOOL_DEALLOC_CHECK(3)
686  MEMPOOL_DEALLOC_CHECK(4)
687  )
688  MEMPOOL_ANALYZERS(4)
689 private:
690  MEMPOOL_MEMBERS(
691  MEMPOOL_MEMBER_POOL(1)
692  MEMPOOL_MEMBER_POOL(2)
693  MEMPOOL_MEMBER_POOL(3)
694  MEMPOOL_MEMBER_POOL(4)
695  )
696 };
697 
698 template<
699 MEMPOOL_TEMPLATE_PAIR(1),
700 MEMPOOL_TEMPLATE_PAIR(2),
701 MEMPOOL_TEMPLATE_PAIR(3),
702 MEMPOOL_TEMPLATE_PAIR(4),
703 MEMPOOL_TEMPLATE_PAIR(5)>
704 class bucket_pool_5 {
705 public:
706  MEMPOOL_ALLOC_METHOD(
707  5,
708  MEMPOOL_ALLOC_CHECK(1)
709  MEMPOOL_ALLOC_CHECK(2)
710  MEMPOOL_ALLOC_CHECK(3)
711  MEMPOOL_ALLOC_CHECK(4)
712  MEMPOOL_ALLOC_CHECK(5)
713  )
714  void * reallocate(void * ptr, size_t bytes){
715  MEMPOOL_REALLOC_CHECK(1)
716  MEMPOOL_REALLOC_CHECK(2)
717  MEMPOOL_REALLOC_CHECK(3)
718  MEMPOOL_REALLOC_CHECK(4)
719  MEMPOOL_REALLOC_CHECK(5)
720  return mempool_callbacks::reallocate(ptr, bytes);
721  }
722  MEMPOOL_LOAD(
723  5,
724  _load[0] = _pool1.load();
725  _load[1] = _pool2.load();
726  _load[2] = _pool3.load();
727  _load[3] = _pool4.load();
728  _load[4] = _pool5.load();
729  )
730  MEMPOOL_DEALLOC_METHOD(
731  MEMPOOL_DEALLOC_CHECK(1)
732  MEMPOOL_DEALLOC_CHECK(2)
733  MEMPOOL_DEALLOC_CHECK(3)
734  MEMPOOL_DEALLOC_CHECK(4)
735  MEMPOOL_DEALLOC_CHECK(5)
736  )
737  MEMPOOL_ANALYZERS(5)
738 private:
739  MEMPOOL_MEMBERS(
740  MEMPOOL_MEMBER_POOL(1)
741  MEMPOOL_MEMBER_POOL(2)
742  MEMPOOL_MEMBER_POOL(3)
743  MEMPOOL_MEMBER_POOL(4)
744  MEMPOOL_MEMBER_POOL(5)
745  )
746 };
747 
748 template<
749 MEMPOOL_TEMPLATE_PAIR(1),
750 MEMPOOL_TEMPLATE_PAIR(2),
751 MEMPOOL_TEMPLATE_PAIR(3),
752 MEMPOOL_TEMPLATE_PAIR(4),
753 MEMPOOL_TEMPLATE_PAIR(5),
754 MEMPOOL_TEMPLATE_PAIR(6)>
755 class bucket_pool_6 {
756 public:
757  MEMPOOL_ALLOC_METHOD(
758  6,
759  MEMPOOL_ALLOC_CHECK(1)
760  MEMPOOL_ALLOC_CHECK(2)
761  MEMPOOL_ALLOC_CHECK(3)
762  MEMPOOL_ALLOC_CHECK(4)
763  MEMPOOL_ALLOC_CHECK(5)
764  MEMPOOL_ALLOC_CHECK(6)
765  )
766  void * reallocate(void * ptr, size_t bytes){
767  MEMPOOL_REALLOC_CHECK(1)
768  MEMPOOL_REALLOC_CHECK(2)
769  MEMPOOL_REALLOC_CHECK(3)
770  MEMPOOL_REALLOC_CHECK(4)
771  MEMPOOL_REALLOC_CHECK(5)
772  MEMPOOL_REALLOC_CHECK(6)
773  return mempool_callbacks::reallocate(ptr, bytes);
774  }
775  MEMPOOL_LOAD(
776  6,
777  _load[0] = _pool1.load();
778  _load[1] = _pool2.load();
779  _load[2] = _pool3.load();
780  _load[3] = _pool4.load();
781  _load[4] = _pool5.load();
782  _load[5] = _pool6.load();
783  )
784  MEMPOOL_DEALLOC_METHOD(
785  MEMPOOL_DEALLOC_CHECK(1)
786  MEMPOOL_DEALLOC_CHECK(2)
787  MEMPOOL_DEALLOC_CHECK(3)
788  MEMPOOL_DEALLOC_CHECK(4)
789  MEMPOOL_DEALLOC_CHECK(5)
790  MEMPOOL_DEALLOC_CHECK(6)
791  )
792  MEMPOOL_ANALYZERS(6)
793 private:
794  MEMPOOL_MEMBERS(
795  MEMPOOL_MEMBER_POOL(1)
796  MEMPOOL_MEMBER_POOL(2)
797  MEMPOOL_MEMBER_POOL(3)
798  MEMPOOL_MEMBER_POOL(4)
799  MEMPOOL_MEMBER_POOL(5)
800  MEMPOOL_MEMBER_POOL(6)
801  )
802 };
803 
804 template<
805 MEMPOOL_TEMPLATE_PAIR(1),
806 MEMPOOL_TEMPLATE_PAIR(2),
807 MEMPOOL_TEMPLATE_PAIR(3),
808 MEMPOOL_TEMPLATE_PAIR(4),
809 MEMPOOL_TEMPLATE_PAIR(5),
810 MEMPOOL_TEMPLATE_PAIR(6),
811 MEMPOOL_TEMPLATE_PAIR(7)>
812 class bucket_pool_7 {
813 public:
814  MEMPOOL_ALLOC_METHOD(
815  7,
816  MEMPOOL_ALLOC_CHECK(1)
817  MEMPOOL_ALLOC_CHECK(2)
818  MEMPOOL_ALLOC_CHECK(3)
819  MEMPOOL_ALLOC_CHECK(4)
820  MEMPOOL_ALLOC_CHECK(5)
821  MEMPOOL_ALLOC_CHECK(6)
822  MEMPOOL_ALLOC_CHECK(7)
823  )
824  void * reallocate(void * ptr, size_t bytes){
825  MEMPOOL_REALLOC_CHECK(1)
826  MEMPOOL_REALLOC_CHECK(2)
827  MEMPOOL_REALLOC_CHECK(3)
828  MEMPOOL_REALLOC_CHECK(4)
829  MEMPOOL_REALLOC_CHECK(5)
830  MEMPOOL_REALLOC_CHECK(6)
831  MEMPOOL_REALLOC_CHECK(7)
832  return mempool_callbacks::reallocate(ptr, bytes);
833  }
834  MEMPOOL_LOAD(
835  7,
836  _load[0] = _pool1.load();
837  _load[1] = _pool2.load();
838  _load[2] = _pool3.load();
839  _load[3] = _pool4.load();
840  _load[4] = _pool5.load();
841  _load[5] = _pool6.load();
842  _load[6] = _pool7.load();
843  )
844  MEMPOOL_DEALLOC_METHOD(
845  MEMPOOL_DEALLOC_CHECK(1)
846  MEMPOOL_DEALLOC_CHECK(2)
847  MEMPOOL_DEALLOC_CHECK(3)
848  MEMPOOL_DEALLOC_CHECK(4)
849  MEMPOOL_DEALLOC_CHECK(5)
850  MEMPOOL_DEALLOC_CHECK(6)
851  MEMPOOL_DEALLOC_CHECK(7)
852  )
853  MEMPOOL_ANALYZERS(7)
854 private:
855  MEMPOOL_MEMBERS(
856  MEMPOOL_MEMBER_POOL(1)
857  MEMPOOL_MEMBER_POOL(2)
858  MEMPOOL_MEMBER_POOL(3)
859  MEMPOOL_MEMBER_POOL(4)
860  MEMPOOL_MEMBER_POOL(5)
861  MEMPOOL_MEMBER_POOL(6)
862  MEMPOOL_MEMBER_POOL(7)
863  )
864 };
865 
866 template<
867 MEMPOOL_TEMPLATE_PAIR(1),
868 MEMPOOL_TEMPLATE_PAIR(2),
869 MEMPOOL_TEMPLATE_PAIR(3),
870 MEMPOOL_TEMPLATE_PAIR(4),
871 MEMPOOL_TEMPLATE_PAIR(5),
872 MEMPOOL_TEMPLATE_PAIR(6),
873 MEMPOOL_TEMPLATE_PAIR(7),
874 MEMPOOL_TEMPLATE_PAIR(8)>
875 class bucket_pool_8 {
876 public:
877  MEMPOOL_ALLOC_METHOD(
878  8,
879  MEMPOOL_ALLOC_CHECK(1)
880  MEMPOOL_ALLOC_CHECK(2)
881  MEMPOOL_ALLOC_CHECK(3)
882  MEMPOOL_ALLOC_CHECK(4)
883  MEMPOOL_ALLOC_CHECK(5)
884  MEMPOOL_ALLOC_CHECK(6)
885  MEMPOOL_ALLOC_CHECK(7)
886  MEMPOOL_ALLOC_CHECK(8)
887  )
888  void * reallocate(void * ptr, size_t bytes){
889  MEMPOOL_REALLOC_CHECK(1)
890  MEMPOOL_REALLOC_CHECK(2)
891  MEMPOOL_REALLOC_CHECK(3)
892  MEMPOOL_REALLOC_CHECK(4)
893  MEMPOOL_REALLOC_CHECK(5)
894  MEMPOOL_REALLOC_CHECK(6)
895  MEMPOOL_REALLOC_CHECK(7)
896  MEMPOOL_REALLOC_CHECK(8)
897  return mempool_callbacks::reallocate(ptr, bytes);
898  }
899  MEMPOOL_LOAD(
900  8,
901  _load[0] = _pool1.load();
902  _load[1] = _pool2.load();
903  _load[2] = _pool3.load();
904  _load[3] = _pool4.load();
905  _load[4] = _pool5.load();
906  _load[5] = _pool6.load();
907  _load[6] = _pool7.load();
908  _load[7] = _pool8.load();
909  )
910  MEMPOOL_DEALLOC_METHOD(
911  MEMPOOL_DEALLOC_CHECK(1)
912  MEMPOOL_DEALLOC_CHECK(2)
913  MEMPOOL_DEALLOC_CHECK(3)
914  MEMPOOL_DEALLOC_CHECK(4)
915  MEMPOOL_DEALLOC_CHECK(5)
916  MEMPOOL_DEALLOC_CHECK(6)
917  MEMPOOL_DEALLOC_CHECK(7)
918  MEMPOOL_DEALLOC_CHECK(8)
919  )
920  MEMPOOL_ANALYZERS(8)
921 private:
922  MEMPOOL_MEMBERS(
923  MEMPOOL_MEMBER_POOL(1)
924  MEMPOOL_MEMBER_POOL(2)
925  MEMPOOL_MEMBER_POOL(3)
926  MEMPOOL_MEMBER_POOL(4)
927  MEMPOOL_MEMBER_POOL(5)
928  MEMPOOL_MEMBER_POOL(6)
929  MEMPOOL_MEMBER_POOL(7)
930  MEMPOOL_MEMBER_POOL(8)
931  )
932 };
933 
934 template<
935 MEMPOOL_TEMPLATE_PAIR(1),
936 MEMPOOL_TEMPLATE_PAIR(2),
937 MEMPOOL_TEMPLATE_PAIR(3),
938 MEMPOOL_TEMPLATE_PAIR(4),
939 MEMPOOL_TEMPLATE_PAIR(5),
940 MEMPOOL_TEMPLATE_PAIR(6),
941 MEMPOOL_TEMPLATE_PAIR(7),
942 MEMPOOL_TEMPLATE_PAIR(8),
943 MEMPOOL_TEMPLATE_PAIR(9)>
944 class bucket_pool_9 {
945 public:
946  MEMPOOL_ALLOC_METHOD(
947  9,
948  MEMPOOL_ALLOC_CHECK(1)
949  MEMPOOL_ALLOC_CHECK(2)
950  MEMPOOL_ALLOC_CHECK(3)
951  MEMPOOL_ALLOC_CHECK(4)
952  MEMPOOL_ALLOC_CHECK(5)
953  MEMPOOL_ALLOC_CHECK(6)
954  MEMPOOL_ALLOC_CHECK(7)
955  MEMPOOL_ALLOC_CHECK(8)
956  MEMPOOL_ALLOC_CHECK(9)
957  )
958  void * reallocate(void * ptr, size_t bytes){
959  MEMPOOL_REALLOC_CHECK(1)
960  MEMPOOL_REALLOC_CHECK(2)
961  MEMPOOL_REALLOC_CHECK(3)
962  MEMPOOL_REALLOC_CHECK(4)
963  MEMPOOL_REALLOC_CHECK(5)
964  MEMPOOL_REALLOC_CHECK(6)
965  MEMPOOL_REALLOC_CHECK(7)
966  MEMPOOL_REALLOC_CHECK(8)
967  MEMPOOL_REALLOC_CHECK(9)
968  return mempool_callbacks::reallocate(ptr, bytes);
969  }
970  MEMPOOL_LOAD(
971  9,
972  _load[0] = _pool1.load();
973  _load[1] = _pool2.load();
974  _load[2] = _pool3.load();
975  _load[3] = _pool4.load();
976  _load[4] = _pool5.load();
977  _load[5] = _pool6.load();
978  _load[6] = _pool7.load();
979  _load[7] = _pool8.load();
980  _load[8] = _pool9.load();
981  )
982  MEMPOOL_DEALLOC_METHOD(
983  MEMPOOL_DEALLOC_CHECK(1)
984  MEMPOOL_DEALLOC_CHECK(2)
985  MEMPOOL_DEALLOC_CHECK(3)
986  MEMPOOL_DEALLOC_CHECK(4)
987  MEMPOOL_DEALLOC_CHECK(5)
988  MEMPOOL_DEALLOC_CHECK(6)
989  MEMPOOL_DEALLOC_CHECK(7)
990  MEMPOOL_DEALLOC_CHECK(8)
991  MEMPOOL_DEALLOC_CHECK(9)
992  )
993  MEMPOOL_ANALYZERS(9)
994 private:
995  MEMPOOL_MEMBERS(
996  MEMPOOL_MEMBER_POOL(1)
997  MEMPOOL_MEMBER_POOL(2)
998  MEMPOOL_MEMBER_POOL(3)
999  MEMPOOL_MEMBER_POOL(4)
1000  MEMPOOL_MEMBER_POOL(5)
1001  MEMPOOL_MEMBER_POOL(6)
1002  MEMPOOL_MEMBER_POOL(7)
1003  MEMPOOL_MEMBER_POOL(8)
1004  MEMPOOL_MEMBER_POOL(9)
1005  )
1006 };
1007 
1008 template<
1009 MEMPOOL_TEMPLATE_PAIR(1),
1010 MEMPOOL_TEMPLATE_PAIR(2),
1011 MEMPOOL_TEMPLATE_PAIR(3),
1012 MEMPOOL_TEMPLATE_PAIR(4),
1013 MEMPOOL_TEMPLATE_PAIR(5),
1014 MEMPOOL_TEMPLATE_PAIR(6),
1015 MEMPOOL_TEMPLATE_PAIR(7),
1016 MEMPOOL_TEMPLATE_PAIR(8),
1017 MEMPOOL_TEMPLATE_PAIR(9),
1018 MEMPOOL_TEMPLATE_PAIR(10)>
1019 class bucket_pool_10 {
1020 public:
1021  MEMPOOL_ALLOC_METHOD(
1022  10,
1023  MEMPOOL_ALLOC_CHECK(1)
1024  MEMPOOL_ALLOC_CHECK(2)
1025  MEMPOOL_ALLOC_CHECK(3)
1026  MEMPOOL_ALLOC_CHECK(4)
1027  MEMPOOL_ALLOC_CHECK(5)
1028  MEMPOOL_ALLOC_CHECK(6)
1029  MEMPOOL_ALLOC_CHECK(7)
1030  MEMPOOL_ALLOC_CHECK(8)
1031  MEMPOOL_ALLOC_CHECK(9)
1032  MEMPOOL_ALLOC_CHECK(10)
1033  )
1034  void * reallocate(void * ptr, size_t bytes){
1035  MEMPOOL_REALLOC_CHECK(1)
1036  MEMPOOL_REALLOC_CHECK(2)
1037  MEMPOOL_REALLOC_CHECK(3)
1038  MEMPOOL_REALLOC_CHECK(4)
1039  MEMPOOL_REALLOC_CHECK(5)
1040  MEMPOOL_REALLOC_CHECK(6)
1041  MEMPOOL_REALLOC_CHECK(7)
1042  MEMPOOL_REALLOC_CHECK(8)
1043  MEMPOOL_REALLOC_CHECK(9)
1044  MEMPOOL_REALLOC_CHECK(10)
1045  return mempool_callbacks::reallocate(ptr, bytes);
1046  }
1047  MEMPOOL_LOAD(
1048  10,
1049  _load[0] = _pool1.load();
1050  _load[1] = _pool2.load();
1051  _load[2] = _pool3.load();
1052  _load[3] = _pool4.load();
1053  _load[4] = _pool5.load();
1054  _load[5] = _pool6.load();
1055  _load[6] = _pool7.load();
1056  _load[7] = _pool8.load();
1057  _load[8] = _pool9.load();
1058  _load[9] = _pool10.load();
1059  )
1060  MEMPOOL_DEALLOC_METHOD(
1061  MEMPOOL_DEALLOC_CHECK(1)
1062  MEMPOOL_DEALLOC_CHECK(2)
1063  MEMPOOL_DEALLOC_CHECK(3)
1064  MEMPOOL_DEALLOC_CHECK(4)
1065  MEMPOOL_DEALLOC_CHECK(5)
1066  MEMPOOL_DEALLOC_CHECK(6)
1067  MEMPOOL_DEALLOC_CHECK(7)
1068  MEMPOOL_DEALLOC_CHECK(8)
1069  MEMPOOL_DEALLOC_CHECK(9)
1070  MEMPOOL_DEALLOC_CHECK(10)
1071  )
1072  MEMPOOL_ANALYZERS(10)
1073 private:
1074  MEMPOOL_MEMBERS(
1075  MEMPOOL_MEMBER_POOL(1)
1076  MEMPOOL_MEMBER_POOL(2)
1077  MEMPOOL_MEMBER_POOL(3)
1078  MEMPOOL_MEMBER_POOL(4)
1079  MEMPOOL_MEMBER_POOL(5)
1080  MEMPOOL_MEMBER_POOL(6)
1081  MEMPOOL_MEMBER_POOL(7)
1082  MEMPOOL_MEMBER_POOL(8)
1083  MEMPOOL_MEMBER_POOL(9)
1084  MEMPOOL_MEMBER_POOL(10)
1085  )
1086 };
1087 
1088 #endif