Arcane  v3.16.8.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
allocators.h
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2// Tencent is pleased to support the open source community by making RapidJSON available.
3//
4// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
5//
6// Licensed under the MIT License (the "License"); you may not use this file except
7// in compliance with the License. You may obtain a copy of the License at
8//
9// http://opensource.org/licenses/MIT
10//
11// Unless required by applicable law or agreed to in writing, software distributed
12// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
13// CONDITIONS OF ANY KIND, either express or implied. See the License for the
14// specific language governing permissions and limitations under the License.
15
16#ifndef RAPIDJSON_ALLOCATORS_H_
17#define RAPIDJSON_ALLOCATORS_H_
18
19#include "rapidjson.h"
20#include "internal/meta.h"
21
22#include <memory>
23#include <limits>
24
25#if RAPIDJSON_HAS_CXX11
26#include <type_traits>
27#endif
28
30
32// Allocator
33
63
64
71
72#ifndef RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY
73#define RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY (64 * 1024)
74#endif
75
76
78// CrtAllocator
79
81
85public:
86 static const bool kNeedFree = true;
87 void* Malloc(size_t size) {
88 if (size) // behavior of malloc(0) is implementation defined.
89 return RAPIDJSON_MALLOC(size);
90 else
91 return NULL; // standardize to returning NULL.
92 }
93 void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) {
94 (void)originalSize;
95 if (newSize == 0) {
96 RAPIDJSON_FREE(originalPtr);
97 return NULL;
98 }
99 return RAPIDJSON_REALLOC(originalPtr, newSize);
100 }
101 static void Free(void *ptr) RAPIDJSON_NOEXCEPT { RAPIDJSON_FREE(ptr); }
102
103 bool operator==(const CrtAllocator&) const RAPIDJSON_NOEXCEPT {
104 return true;
105 }
106 bool operator!=(const CrtAllocator&) const RAPIDJSON_NOEXCEPT {
107 return false;
108 }
109};
110
112// MemoryPoolAllocator
113
115
130template <typename BaseAllocator = CrtAllocator>
133
135 struct ChunkHeader {
136 size_t capacity;
137 size_t size;
139 };
140
141 struct SharedData {
143 BaseAllocator* ownBaseAllocator;
144 size_t refcount;
145 bool ownBuffer;
146 };
147
148 static const size_t SIZEOF_SHARED_DATA = RAPIDJSON_ALIGN(sizeof(SharedData));
149 static const size_t SIZEOF_CHUNK_HEADER = RAPIDJSON_ALIGN(sizeof(ChunkHeader));
150
151 static inline ChunkHeader *GetChunkHead(SharedData *shared)
152 {
153 return reinterpret_cast<ChunkHeader*>(reinterpret_cast<uint8_t*>(shared) + SIZEOF_SHARED_DATA);
154 }
155 static inline uint8_t *GetChunkBuffer(SharedData *shared)
156 {
157 return reinterpret_cast<uint8_t*>(shared->chunkHead) + SIZEOF_CHUNK_HEADER;
158 }
159
161
162public:
163 static const bool kNeedFree = false;
164 static const bool kRefCounted = true;
165
167
170 explicit
171 MemoryPoolAllocator(size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) :
172 chunk_capacity_(chunkSize),
173 baseAllocator_(baseAllocator ? baseAllocator : RAPIDJSON_NEW(BaseAllocator)()),
174 shared_(static_cast<SharedData*>(baseAllocator_ ? baseAllocator_->Malloc(SIZEOF_SHARED_DATA + SIZEOF_CHUNK_HEADER) : 0))
175 {
178 if (baseAllocator) {
179 shared_->ownBaseAllocator = 0;
180 }
181 else {
182 shared_->ownBaseAllocator = baseAllocator_;
183 }
184 shared_->chunkHead = GetChunkHead(shared_);
185 shared_->chunkHead->capacity = 0;
186 shared_->chunkHead->size = 0;
187 shared_->chunkHead->next = 0;
188 shared_->ownBuffer = true;
189 shared_->refcount = 1;
190 }
191
193
202 MemoryPoolAllocator(void *buffer, size_t size, size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) :
203 chunk_capacity_(chunkSize),
204 baseAllocator_(baseAllocator),
205 shared_(static_cast<SharedData*>(AlignBuffer(buffer, size)))
206 {
207 RAPIDJSON_ASSERT(size >= SIZEOF_SHARED_DATA + SIZEOF_CHUNK_HEADER);
208 shared_->chunkHead = GetChunkHead(shared_);
209 shared_->chunkHead->capacity = size - SIZEOF_SHARED_DATA - SIZEOF_CHUNK_HEADER;
210 shared_->chunkHead->size = 0;
211 shared_->chunkHead->next = 0;
212 shared_->ownBaseAllocator = 0;
213 shared_->ownBuffer = false;
214 shared_->refcount = 1;
215 }
216
217 MemoryPoolAllocator(const MemoryPoolAllocator& rhs) RAPIDJSON_NOEXCEPT :
218 chunk_capacity_(rhs.chunk_capacity_),
219 baseAllocator_(rhs.baseAllocator_),
220 shared_(rhs.shared_)
221 {
222 RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0);
223 ++shared_->refcount;
224 }
225 MemoryPoolAllocator& operator=(const MemoryPoolAllocator& rhs) RAPIDJSON_NOEXCEPT
226 {
227 RAPIDJSON_NOEXCEPT_ASSERT(rhs.shared_->refcount > 0);
228 ++rhs.shared_->refcount;
229 this->~MemoryPoolAllocator();
230 baseAllocator_ = rhs.baseAllocator_;
231 chunk_capacity_ = rhs.chunk_capacity_;
232 shared_ = rhs.shared_;
233 return *this;
234 }
235
236#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
237 MemoryPoolAllocator(MemoryPoolAllocator&& rhs) RAPIDJSON_NOEXCEPT :
238 chunk_capacity_(rhs.chunk_capacity_),
239 baseAllocator_(rhs.baseAllocator_),
240 shared_(rhs.shared_)
241 {
242 RAPIDJSON_NOEXCEPT_ASSERT(rhs.shared_->refcount > 0);
243 rhs.shared_ = 0;
244 }
245 MemoryPoolAllocator& operator=(MemoryPoolAllocator&& rhs) RAPIDJSON_NOEXCEPT
246 {
247 RAPIDJSON_NOEXCEPT_ASSERT(rhs.shared_->refcount > 0);
248 this->~MemoryPoolAllocator();
249 baseAllocator_ = rhs.baseAllocator_;
250 chunk_capacity_ = rhs.chunk_capacity_;
251 shared_ = rhs.shared_;
252 rhs.shared_ = 0;
253 return *this;
254 }
255#endif
256
258
260 ~MemoryPoolAllocator() RAPIDJSON_NOEXCEPT {
261 if (!shared_) {
262 // do nothing if moved
263 return;
264 }
265 if (shared_->refcount > 1) {
266 --shared_->refcount;
267 return;
268 }
269 Clear();
270 BaseAllocator *a = shared_->ownBaseAllocator;
271 if (shared_->ownBuffer) {
272 baseAllocator_->Free(shared_);
273 }
275 }
276
278 void Clear() RAPIDJSON_NOEXCEPT {
279 RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0);
280 for (;;) {
281 ChunkHeader* c = shared_->chunkHead;
282 if (!c->next) {
283 break;
284 }
285 shared_->chunkHead = c->next;
286 baseAllocator_->Free(c);
287 }
288 shared_->chunkHead->size = 0;
289 }
290
292
294 size_t Capacity() const RAPIDJSON_NOEXCEPT {
295 RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0);
296 size_t capacity = 0;
297 for (ChunkHeader* c = shared_->chunkHead; c != 0; c = c->next)
298 capacity += c->capacity;
299 return capacity;
300 }
301
303
305 size_t Size() const RAPIDJSON_NOEXCEPT {
306 RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0);
307 size_t size = 0;
308 for (ChunkHeader* c = shared_->chunkHead; c != 0; c = c->next)
309 size += c->size;
310 return size;
311 }
312
314
316 bool Shared() const RAPIDJSON_NOEXCEPT {
317 RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0);
318 return shared_->refcount > 1;
319 }
320
322 void* Malloc(size_t size) {
323 RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0);
324 if (!size)
325 return NULL;
326
327 size = RAPIDJSON_ALIGN(size);
328 if (RAPIDJSON_UNLIKELY(shared_->chunkHead->size + size > shared_->chunkHead->capacity))
329 if (!AddChunk(chunk_capacity_ > size ? chunk_capacity_ : size))
330 return NULL;
331
332 void *buffer = GetChunkBuffer(shared_) + shared_->chunkHead->size;
333 shared_->chunkHead->size += size;
334 return buffer;
335 }
336
338 void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) {
339 if (originalPtr == 0)
340 return Malloc(newSize);
341
342 RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0);
343 if (newSize == 0)
344 return NULL;
345
346 originalSize = RAPIDJSON_ALIGN(originalSize);
347 newSize = RAPIDJSON_ALIGN(newSize);
348
349 // Do not shrink if new size is smaller than original
350 if (originalSize >= newSize)
351 return originalPtr;
352
353 // Simply expand it if it is the last allocation and there is sufficient space
354 if (originalPtr == GetChunkBuffer(shared_) + shared_->chunkHead->size - originalSize) {
355 size_t increment = static_cast<size_t>(newSize - originalSize);
356 if (shared_->chunkHead->size + increment <= shared_->chunkHead->capacity) {
357 shared_->chunkHead->size += increment;
358 return originalPtr;
359 }
360 }
361
362 // Realloc process: allocate and copy memory, do not free original buffer.
363 if (void* newBuffer = Malloc(newSize)) {
364 if (originalSize)
365 std::memcpy(newBuffer, originalPtr, originalSize);
366 return newBuffer;
367 }
368 else
369 return NULL;
370 }
371
373 static void Free(void *ptr) RAPIDJSON_NOEXCEPT { (void)ptr; } // Do nothing
374
376 bool operator==(const MemoryPoolAllocator& rhs) const RAPIDJSON_NOEXCEPT {
377 RAPIDJSON_NOEXCEPT_ASSERT(shared_->refcount > 0);
378 RAPIDJSON_NOEXCEPT_ASSERT(rhs.shared_->refcount > 0);
379 return shared_ == rhs.shared_;
380 }
381
382 bool operator!=(const MemoryPoolAllocator& rhs) const RAPIDJSON_NOEXCEPT {
383 return !operator==(rhs);
384 }
385
386private:
388
391 bool AddChunk(size_t capacity) {
392 if (!baseAllocator_)
393 shared_->ownBaseAllocator = baseAllocator_ = RAPIDJSON_NEW(BaseAllocator)();
394 if (ChunkHeader* chunk = static_cast<ChunkHeader*>(baseAllocator_->Malloc(SIZEOF_CHUNK_HEADER + capacity))) {
395 chunk->capacity = capacity;
396 chunk->size = 0;
397 chunk->next = shared_->chunkHead;
398 shared_->chunkHead = chunk;
399 return true;
400 }
401 else
402 return false;
403 }
404
405 static inline void* AlignBuffer(void* buf, size_t &size)
406 {
408 const uintptr_t mask = sizeof(void*) - 1;
409 const uintptr_t ubuf = reinterpret_cast<uintptr_t>(buf);
410 if (RAPIDJSON_UNLIKELY(ubuf & mask)) {
411 const uintptr_t abuf = (ubuf + mask) & ~mask;
412 RAPIDJSON_ASSERT(size >= abuf - ubuf);
413 buf = reinterpret_cast<void*>(abuf);
414 size -= abuf - ubuf;
415 }
416 return buf;
417 }
418
420 BaseAllocator* baseAllocator_;
422};
423
424namespace internal {
425 template<typename, typename = void>
427 public FalseType
428 { };
429 template<typename T>
430 struct IsRefCounted<T, typename internal::EnableIfCond<T::kRefCounted>::Type> :
431 public TrueType
432 { };
433}
434
435template<typename T, typename A>
436inline T* Realloc(A& a, T* old_p, size_t old_n, size_t new_n)
437{
438 RAPIDJSON_NOEXCEPT_ASSERT(old_n <= (std::numeric_limits<size_t>::max)() / sizeof(T) && new_n <= (std::numeric_limits<size_t>::max)() / sizeof(T));
439 return static_cast<T*>(a.Realloc(old_p, old_n * sizeof(T), new_n * sizeof(T)));
440}
441
442template<typename T, typename A>
443inline T *Malloc(A& a, size_t n = 1)
444{
445 return Realloc<T, A>(a, NULL, 0, n);
446}
447
448template<typename T, typename A>
449inline void Free(A& a, T *p, size_t n = 1)
450{
451 static_cast<void>(Realloc<T, A>(a, p, n, 0));
452}
453
454#ifdef __GNUC__
455RAPIDJSON_DIAG_PUSH
456RAPIDJSON_DIAG_OFF(effc++) // std::allocator can safely be inherited
457#endif
458
459template <typename T, typename BaseAllocator = CrtAllocator>
460class StdAllocator :
461 public std::allocator<T>
462{
463 typedef std::allocator<T> allocator_type;
464#if RAPIDJSON_HAS_CXX11
465 typedef std::allocator_traits<allocator_type> traits_type;
466#else
467 typedef allocator_type traits_type;
468#endif
469
470public:
471 typedef BaseAllocator BaseAllocatorType;
472
473 StdAllocator() RAPIDJSON_NOEXCEPT :
474 allocator_type(),
475 baseAllocator_()
476 { }
477
478 StdAllocator(const StdAllocator& rhs) RAPIDJSON_NOEXCEPT :
479 allocator_type(rhs),
480 baseAllocator_(rhs.baseAllocator_)
481 { }
482
483 template<typename U>
484 StdAllocator(const StdAllocator<U, BaseAllocator>& rhs) RAPIDJSON_NOEXCEPT :
485 allocator_type(rhs),
486 baseAllocator_(rhs.baseAllocator_)
487 { }
488
489#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
490 StdAllocator(StdAllocator&& rhs) RAPIDJSON_NOEXCEPT :
491 allocator_type(std::move(rhs)),
492 baseAllocator_(std::move(rhs.baseAllocator_))
493 { }
494#endif
495#if RAPIDJSON_HAS_CXX11
496 using propagate_on_container_move_assignment = std::true_type;
497 using propagate_on_container_swap = std::true_type;
498#endif
499
500 /* implicit */
501 StdAllocator(const BaseAllocator& baseAllocator) RAPIDJSON_NOEXCEPT :
502 allocator_type(),
503 baseAllocator_(baseAllocator)
504 { }
505
506 ~StdAllocator() RAPIDJSON_NOEXCEPT
507 { }
508
509 template<typename U>
510 struct rebind {
511 typedef StdAllocator<U, BaseAllocator> other;
512 };
513
514 typedef typename traits_type::size_type size_type;
515 typedef typename traits_type::difference_type difference_type;
516
517 typedef typename traits_type::value_type value_type;
518 typedef typename traits_type::pointer pointer;
519 typedef typename traits_type::const_pointer const_pointer;
520
521#if RAPIDJSON_HAS_CXX11
522
523 typedef typename std::add_lvalue_reference<value_type>::type &reference;
524 typedef typename std::add_lvalue_reference<typename std::add_const<value_type>::type>::type &const_reference;
525
526 pointer address(reference r) const RAPIDJSON_NOEXCEPT
527 {
528 return std::addressof(r);
529 }
530 const_pointer address(const_reference r) const RAPIDJSON_NOEXCEPT
531 {
532 return std::addressof(r);
533 }
534
535 size_type max_size() const RAPIDJSON_NOEXCEPT
536 {
537 return traits_type::max_size(*this);
538 }
539
540 template <typename ...Args>
541 void construct(pointer p, Args&&... args)
542 {
543 traits_type::construct(*this, p, std::forward<Args>(args)...);
544 }
545 void destroy(pointer p)
546 {
547 traits_type::destroy(*this, p);
548 }
549
550#else // !RAPIDJSON_HAS_CXX11
551
552 typedef typename allocator_type::reference reference;
553 typedef typename allocator_type::const_reference const_reference;
554
555 pointer address(reference r) const RAPIDJSON_NOEXCEPT
556 {
557 return allocator_type::address(r);
558 }
559 const_pointer address(const_reference r) const RAPIDJSON_NOEXCEPT
560 {
561 return allocator_type::address(r);
562 }
563
564 size_type max_size() const RAPIDJSON_NOEXCEPT
565 {
566 return allocator_type::max_size();
567 }
568
569 void construct(pointer p, const_reference r)
570 {
571 allocator_type::construct(p, r);
572 }
573 void destroy(pointer p)
574 {
575 allocator_type::destroy(p);
576 }
577
578#endif // !RAPIDJSON_HAS_CXX11
579
580 template <typename U>
581 U* allocate(size_type n = 1, const void* = 0)
582 {
583 return RAPIDJSON_NAMESPACE::Malloc<U>(baseAllocator_, n);
584 }
585 template <typename U>
586 void deallocate(U* p, size_type n = 1)
587 {
588 RAPIDJSON_NAMESPACE::Free<U>(baseAllocator_, p, n);
589 }
590
591 pointer allocate(size_type n = 1, const void* = 0)
592 {
593 return allocate<value_type>(n);
594 }
595 void deallocate(pointer p, size_type n = 1)
596 {
597 deallocate<value_type>(p, n);
598 }
599
600#if RAPIDJSON_HAS_CXX11
601 using is_always_equal = std::is_empty<BaseAllocator>;
602#endif
603
604 template<typename U>
605 bool operator==(const StdAllocator<U, BaseAllocator>& rhs) const RAPIDJSON_NOEXCEPT
606 {
607 return baseAllocator_ == rhs.baseAllocator_;
608 }
609 template<typename U>
610 bool operator!=(const StdAllocator<U, BaseAllocator>& rhs) const RAPIDJSON_NOEXCEPT
611 {
612 return !operator==(rhs);
613 }
614
616 static const bool kNeedFree = BaseAllocator::kNeedFree;
617 static const bool kRefCounted = internal::IsRefCounted<BaseAllocator>::Value;
618 void* Malloc(size_t size)
619 {
620 return baseAllocator_.Malloc(size);
621 }
622 void* Realloc(void* originalPtr, size_t originalSize, size_t newSize)
623 {
624 return baseAllocator_.Realloc(originalPtr, originalSize, newSize);
625 }
626 static void Free(void *ptr) RAPIDJSON_NOEXCEPT
627 {
628 BaseAllocator::Free(ptr);
629 }
630
631private:
632 template <typename, typename>
633 friend class StdAllocator; // access to StdAllocator<!T>.*
634
635 BaseAllocator baseAllocator_;
636};
637
638#if !RAPIDJSON_HAS_CXX17 // std::allocator<void> deprecated in C++17
639template <typename BaseAllocator>
640class StdAllocator<void, BaseAllocator> :
641 public std::allocator<void>
642{
643 typedef std::allocator<void> allocator_type;
644
645public:
646 typedef BaseAllocator BaseAllocatorType;
647
648 StdAllocator() RAPIDJSON_NOEXCEPT :
649 allocator_type(),
650 baseAllocator_()
651 { }
652
653 StdAllocator(const StdAllocator& rhs) RAPIDJSON_NOEXCEPT :
654 allocator_type(rhs),
655 baseAllocator_(rhs.baseAllocator_)
656 { }
657
658 template<typename U>
659 StdAllocator(const StdAllocator<U, BaseAllocator>& rhs) RAPIDJSON_NOEXCEPT :
660 allocator_type(rhs),
661 baseAllocator_(rhs.baseAllocator_)
662 { }
663
664 /* implicit */
665 StdAllocator(const BaseAllocator& baseAllocator) RAPIDJSON_NOEXCEPT :
666 allocator_type(),
667 baseAllocator_(baseAllocator)
668 { }
669
670 ~StdAllocator() RAPIDJSON_NOEXCEPT
671 { }
672
673 template<typename U>
674 struct rebind {
675 typedef StdAllocator<U, BaseAllocator> other;
676 };
677
678 typedef typename allocator_type::value_type value_type;
679
680private:
681 template <typename, typename>
682 friend class StdAllocator; // access to StdAllocator<!T>.*
683
684 BaseAllocator baseAllocator_;
685};
686#endif
687
688#ifdef __GNUC__
689RAPIDJSON_DIAG_POP
690#endif
691
693
694#endif // RAPIDJSON_ENCODINGS_H_
C-runtime library allocator.
Definition allocators.h:84
Default memory allocator used by the parser and DOM.
Definition allocators.h:131
SharedData * shared_
The shared data of the allocator.
Definition allocators.h:421
MemoryPoolAllocator(void *buffer, size_t size, size_t chunkSize=kDefaultChunkCapacity, BaseAllocator *baseAllocator=0)
Constructor with user-supplied buffer.
Definition allocators.h:202
static const bool kRefCounted
Tell users that this allocator is reference counted on copy.
Definition allocators.h:164
bool AddChunk(size_t capacity)
Creates a new chunk.
Definition allocators.h:391
size_t Size() const RAPIDJSON_NOEXCEPT
Computes the memory blocks allocated.
Definition allocators.h:305
size_t Capacity() const RAPIDJSON_NOEXCEPT
Computes the total capacity of allocated memory chunks.
Definition allocators.h:294
BaseAllocator * baseAllocator_
base allocator for allocating memory chunks.
Definition allocators.h:420
size_t chunk_capacity_
The minimum capacity of chunk when they are allocated.
Definition allocators.h:419
void Clear() RAPIDJSON_NOEXCEPT
Deallocates all memory chunks, excluding the first/user one.
Definition allocators.h:278
void * Realloc(void *originalPtr, size_t originalSize, size_t newSize)
Resizes a memory block (concept Allocator)
Definition allocators.h:338
void * Malloc(size_t size)
Allocates a memory block. (concept Allocator)
Definition allocators.h:322
static const size_t kDefaultChunkCapacity
Default chunk capacity.
Definition allocators.h:160
bool operator==(const MemoryPoolAllocator &rhs) const RAPIDJSON_NOEXCEPT
Compare (equality) with another MemoryPoolAllocator.
Definition allocators.h:376
static void Free(void *ptr) RAPIDJSON_NOEXCEPT
Frees a memory block (concept Allocator)
Definition allocators.h:373
static const bool kNeedFree
Tell users that no need to call Free() with this allocator. (concept Allocator)
Definition allocators.h:163
bool operator!=(const MemoryPoolAllocator &rhs) const RAPIDJSON_NOEXCEPT
Compare (inequality) with another MemoryPoolAllocator.
Definition allocators.h:382
bool Shared() const RAPIDJSON_NOEXCEPT
Whether the allocator is shared.
Definition allocators.h:316
MemoryPoolAllocator(size_t chunkSize=kDefaultChunkCapacity, BaseAllocator *baseAllocator=0)
Constructor with chunkSize.
Definition allocators.h:171
~MemoryPoolAllocator() RAPIDJSON_NOEXCEPT
Destructor.
Definition allocators.h:260
#define RAPIDJSON_NOEXCEPT_ASSERT(x)
Assertion (in non-throwing contexts).
Definition rapidjson.h:688
#define RAPIDJSON_ALIGN(x)
Data alignment of the machine.
Definition rapidjson.h:308
#define RAPIDJSON_UNLIKELY(x)
Compiler branching hint for expression with low probability to be true.
Definition rapidjson.h:508
#define RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY
User-defined kDefaultChunkCapacity definition.
Definition allocators.h:73
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition rapidjson.h:438
#define RAPIDJSON_NAMESPACE_BEGIN
provide custom rapidjson namespace (opening expression)
Definition rapidjson.h:122
#define RAPIDJSON_NAMESPACE_END
provide custom rapidjson namespace (closing expression)
Definition rapidjson.h:125
common definitions and configuration
#define RAPIDJSON_MALLOC(size)
! customization point for global malloc
Definition rapidjson.h:697
Type
Type of JSON value.
Definition rapidjson.h:730
#define RAPIDJSON_DELETE(x)
! customization point for global delete
Definition rapidjson.h:717
#define RAPIDJSON_REALLOC(ptr, new_size)
! customization point for global realloc
Definition rapidjson.h:701
#define RAPIDJSON_FREE(ptr)
! customization point for global free
Definition rapidjson.h:705
#define RAPIDJSON_NEW(TypeName)
! customization point for global new
Definition rapidjson.h:713
Chunk header for perpending to each chunk.
Definition allocators.h:135
ChunkHeader * next
Next chunk in the linked list.
Definition allocators.h:138
size_t size
Current size of allocated memory in bytes.
Definition allocators.h:137
size_t capacity
Capacity of the chunk in bytes (excluding the header itself).
Definition allocators.h:136
ChunkHeader * chunkHead
Head of the chunk linked-list. Only the head chunk serves allocation.
Definition allocators.h:142
BaseAllocator * ownBaseAllocator
base allocator created by this object.
Definition allocators.h:143