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