22 template <
class T, std::
size_t growSize = 1024>
29 static const std::size_t blockSize =
sizeof(T) >
sizeof(Block)
32 uint8_t data[blockSize * growSize];
37 Buffer(Buffer *next) : next(next) {}
39 T *getBlock(std::size_t index) {
40 return reinterpret_cast<T *
>(&data[blockSize * index]);
44 Block *firstFreeBlock =
nullptr;
45 Buffer *firstBuffer =
nullptr;
46 std::size_t bufferedBlocks = growSize;
57 Buffer *buffer = firstBuffer;
58 firstBuffer = buffer->next;
65 Block *block = firstFreeBlock;
66 firstFreeBlock = block->next;
67 return reinterpret_cast<T *
>(block);
70 if (bufferedBlocks >= growSize) {
71 firstBuffer =
new Buffer(firstBuffer);
75 return firstBuffer->getBlock(bufferedBlocks++);
78 void deallocate(T *pointer) {
79 Block *block =
reinterpret_cast<Block *
>(pointer);
80 block->next = firstFreeBlock;
81 firstFreeBlock = block;
85 template <
class T, std::
size_t growSize = 1024>
89 std::allocator<T> *rebindAllocator =
nullptr;
93 typedef std::size_t size_type;
94 typedef std::ptrdiff_t difference_type;
96 typedef const T *const_pointer;
98 typedef const T &const_reference;
113 if (!std::is_same<T, U>::value) rebindAllocator =
new std::allocator<T>();
116 ~Allocator() {
delete rebindAllocator; }
119 pointer allocate(size_type n,
const void *hint = 0) {
121 if (copyAllocator)
return copyAllocator->allocate(n, hint);
123 if (rebindAllocator)
return rebindAllocator->allocate(n, hint);
126 if (n != 1 || hint)
throw std::bad_alloc();
128 return MemoryPool<T, growSize>::allocate();
131 void deallocate(pointer p, size_type n) {
134 copyAllocator->deallocate(p, n);
138 if (rebindAllocator) {
139 rebindAllocator->deallocate(p, n);
144 MemoryPool<T, growSize>::deallocate(p);
147 void construct(pointer p, const_reference val) {
new (p) T(val); }
149 void destroy(pointer p) { p->~T(); }