15 #ifndef RAPIDJSON_ALLOCATORS_H_
16 #define RAPIDJSON_ALLOCATORS_H_
20 RAPIDJSON_NAMESPACE_BEGIN
64 static const bool kNeedFree =
true;
65 void* Malloc(
size_t size) {
67 return std::malloc(size);
71 void* Realloc(
void* originalPtr,
size_t originalSize,
size_t newSize) {
74 std::free(originalPtr);
77 return std::realloc(originalPtr, newSize);
79 static void Free(
void *ptr) { std::free(ptr); }
101 template <
typename BaseAllocator = CrtAllocator>
104 static const bool kNeedFree =
false;
111 chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(0), baseAllocator_(baseAllocator), ownBaseAllocator_(0)
125 MemoryPoolAllocator(
void *buffer,
size_t size,
size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) :
126 chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(buffer), baseAllocator_(baseAllocator), ownBaseAllocator_(0)
130 chunkHead_ =
reinterpret_cast<ChunkHeader*
>(buffer);
131 chunkHead_->capacity = size -
sizeof(ChunkHeader);
132 chunkHead_->size = 0;
133 chunkHead_->next = 0;
146 while (chunkHead_ && chunkHead_ != userBuffer_) {
147 ChunkHeader* next = chunkHead_->next;
148 baseAllocator_->Free(chunkHead_);
151 if (chunkHead_ && chunkHead_ == userBuffer_)
152 chunkHead_->size = 0;
160 for (ChunkHeader* c = chunkHead_; c != 0; c = c->next)
161 capacity += c->capacity;
170 for (ChunkHeader* c = chunkHead_; c != 0; c = c->next)
181 if (chunkHead_ == 0 || chunkHead_->size + size > chunkHead_->capacity)
182 if (!AddChunk(chunk_capacity_ > size ? chunk_capacity_ : size))
185 void *buffer =
reinterpret_cast<char *
>(chunkHead_) +
RAPIDJSON_ALIGN(
sizeof(ChunkHeader)) + chunkHead_->size;
186 chunkHead_->size += size;
191 void*
Realloc(
void* originalPtr,
size_t originalSize,
size_t newSize) {
192 if (originalPtr == 0)
193 return Malloc(newSize);
202 if (originalSize >= newSize)
206 if (originalPtr ==
reinterpret_cast<char *
>(chunkHead_) +
RAPIDJSON_ALIGN(
sizeof(ChunkHeader)) + chunkHead_->size - originalSize) {
207 size_t increment =
static_cast<size_t>(newSize - originalSize);
208 if (chunkHead_->size + increment <= chunkHead_->capacity) {
209 chunkHead_->size += increment;
215 if (
void* newBuffer = Malloc(newSize)) {
217 std::memcpy(newBuffer, originalPtr, originalSize);
225 static void Free(
void *ptr) { (void)ptr; }
237 bool AddChunk(
size_t capacity) {
239 ownBaseAllocator_ = baseAllocator_ =
RAPIDJSON_NEW(BaseAllocator());
240 if (ChunkHeader* chunk =
reinterpret_cast<ChunkHeader*
>(baseAllocator_->Malloc(
RAPIDJSON_ALIGN(
sizeof(ChunkHeader)) + capacity))) {
241 chunk->capacity = capacity;
243 chunk->next = chunkHead_;
251 static const int kDefaultChunkCapacity = 64 * 1024;
262 ChunkHeader *chunkHead_;
263 size_t chunk_capacity_;
265 BaseAllocator* baseAllocator_;
266 BaseAllocator* ownBaseAllocator_;
269 RAPIDJSON_NAMESPACE_END
271 #endif // RAPIDJSON_ENCODINGS_H_