15 #ifndef RAPIDJSON_ALLOCATORS_H_
16 #define RAPIDJSON_ALLOCATORS_H_
24 #if RAPIDJSON_HAS_CXX11
25 #include <type_traits>
71 #ifndef RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY
72 #define RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY (64 * 1024)
93 void*
Realloc(
void* originalPtr,
size_t originalSize,
size_t newSize)
128 template <
typename BaseAllocator = CrtAllocator>
145 BaseAllocator* ownBaseAllocator;
150 static const size_t SIZEOF_SHARED_DATA =
RAPIDJSON_ALIGN(
sizeof(SharedData));
151 static const size_t SIZEOF_CHUNK_HEADER =
RAPIDJSON_ALIGN(
sizeof(ChunkHeader));
153 static inline ChunkHeader* GetChunkHead(SharedData* shared)
155 return reinterpret_cast<ChunkHeader*
>(
reinterpret_cast<uint8_t*
>(shared) +
158 static inline uint8_t* GetChunkBuffer(SharedData* shared)
160 return reinterpret_cast<uint8_t*
>(shared->chunkHead) + SIZEOF_CHUNK_HEADER;
163 static const size_t kDefaultChunkCapacity =
177 BaseAllocator* baseAllocator = 0)
178 : chunk_capacity_(chunkSize),
179 baseAllocator_(baseAllocator ? baseAllocator :
RAPIDJSON_NEW(BaseAllocator)()),
180 shared_(static_cast<SharedData*>(
181 baseAllocator_ ? baseAllocator_->
Malloc(SIZEOF_SHARED_DATA + SIZEOF_CHUNK_HEADER)
188 shared_->ownBaseAllocator = 0;
192 shared_->ownBaseAllocator = baseAllocator_;
194 shared_->chunkHead = GetChunkHead(shared_);
195 shared_->chunkHead->capacity = 0;
196 shared_->chunkHead->size = 0;
197 shared_->chunkHead->next = 0;
198 shared_->ownBuffer =
true;
199 shared_->refcount = 1;
215 size_t chunkSize = kDefaultChunkCapacity,
216 BaseAllocator* baseAllocator = 0)
217 : chunk_capacity_(chunkSize),
218 baseAllocator_(baseAllocator),
219 shared_(static_cast<SharedData*>(AlignBuffer(buffer, size)))
222 shared_->chunkHead = GetChunkHead(shared_);
223 shared_->chunkHead->capacity = size - SIZEOF_SHARED_DATA - SIZEOF_CHUNK_HEADER;
224 shared_->chunkHead->size = 0;
225 shared_->chunkHead->next = 0;
226 shared_->ownBaseAllocator = 0;
227 shared_->ownBuffer =
false;
228 shared_->refcount = 1;
232 : chunk_capacity_(rhs.chunk_capacity_),
233 baseAllocator_(rhs.baseAllocator_),
242 ++rhs.shared_->refcount;
244 baseAllocator_ = rhs.baseAllocator_;
245 chunk_capacity_ = rhs.chunk_capacity_;
246 shared_ = rhs.shared_;
250 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
252 : chunk_capacity_(rhs.chunk_capacity_),
253 baseAllocator_(rhs.baseAllocator_),
263 baseAllocator_ = rhs.baseAllocator_;
264 chunk_capacity_ = rhs.chunk_capacity_;
265 shared_ = rhs.shared_;
281 if(shared_->refcount > 1)
287 BaseAllocator*
a = shared_->ownBaseAllocator;
288 if(shared_->ownBuffer)
290 baseAllocator_->Free(shared_);
301 ChunkHeader* c = shared_->chunkHead;
306 shared_->chunkHead = c->next;
307 baseAllocator_->Free(c);
309 shared_->chunkHead->size = 0;
319 for(ChunkHeader* c = shared_->chunkHead; c != 0; c = c->next)
320 capacity += c->capacity;
327 size_t Size() const RAPIDJSON_NOEXCEPT
331 for(ChunkHeader* c = shared_->chunkHead; c != 0; c = c->next)
342 return shared_->refcount > 1;
353 if(
RAPIDJSON_UNLIKELY(shared_->chunkHead->size + size > shared_->chunkHead->capacity))
354 if(!AddChunk(chunk_capacity_ > size ? chunk_capacity_ : size))
357 void* buffer = GetChunkBuffer(shared_) + shared_->chunkHead->size;
358 shared_->chunkHead->size += size;
363 void*
Realloc(
void* originalPtr,
size_t originalSize,
size_t newSize)
376 if(originalSize >= newSize)
380 if(originalPtr == GetChunkBuffer(shared_) + shared_->chunkHead->size - originalSize)
382 size_t increment =
static_cast<size_t>(newSize - originalSize);
383 if(shared_->chunkHead->size + increment <= shared_->chunkHead->capacity)
385 shared_->chunkHead->size += increment;
391 if(
void* newBuffer =
Malloc(newSize))
394 std::memcpy(newBuffer, originalPtr, originalSize);
402 static void Free(
void* ptr) RAPIDJSON_NOEXCEPT { (void)ptr; }
409 return shared_ == rhs.shared_;
422 bool AddChunk(
size_t capacity)
425 shared_->ownBaseAllocator = baseAllocator_ =
RAPIDJSON_NEW(BaseAllocator)();
426 if(ChunkHeader* chunk =
427 static_cast<ChunkHeader*
>(baseAllocator_->Malloc(SIZEOF_CHUNK_HEADER + capacity)))
429 chunk->capacity = capacity;
431 chunk->next = shared_->chunkHead;
432 shared_->chunkHead = chunk;
439 static inline void* AlignBuffer(
void* buf,
size_t& size)
442 const uintptr_t mask =
sizeof(
void*) - 1;
446 const uintptr_t abuf = (ubuf + mask) & ~mask;
448 buf =
reinterpret_cast<void*
>(abuf);
454 size_t chunk_capacity_;
455 BaseAllocator* baseAllocator_;
460 template <
typename,
typename =
void>
464 template <
typename T>
470 template <
typename T,
typename A>
471 inline T*
Realloc(A&
a, T* old_p,
size_t old_n,
size_t new_n)
475 return static_cast<T*
>(
a.Realloc(old_p, old_n *
sizeof(T), new_n *
sizeof(T)));
478 template <
typename T,
typename A>
481 return Realloc<T, A>(
a, NULL, 0, n);
484 template <
typename T,
typename A>
485 inline void Free(A&
a, T* p,
size_t n = 1)
487 static_cast<void>(Realloc<T, A>(
a, p, n, 0));
492 RAPIDJSON_DIAG_OFF(effc++)
495 template <
typename T,
typename BaseAllocator = CrtAllocator>
498 typedef std::allocator<T> allocator_type;
499 #if RAPIDJSON_HAS_CXX11
500 typedef std::allocator_traits<allocator_type> traits_type;
502 typedef allocator_type traits_type;
508 StdAllocator() RAPIDJSON_NOEXCEPT : allocator_type(), baseAllocator_() {}
511 baseAllocator_(rhs.baseAllocator_)
515 template <
typename U>
517 : allocator_type(rhs),
518 baseAllocator_(rhs.baseAllocator_)
522 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
524 : allocator_type(std::move(rhs)),
525 baseAllocator_(std::move(rhs.baseAllocator_))
529 #if RAPIDJSON_HAS_CXX11
537 baseAllocator_(baseAllocator)
543 template <
typename U>
556 #if RAPIDJSON_HAS_CXX11
558 typedef typename std::add_lvalue_reference<value_type>::type&
reference;
559 typedef typename std::add_lvalue_reference<typename std::add_const<value_type>::type>::type&
565 size_type max_size() const RAPIDJSON_NOEXCEPT {
return traits_type::max_size(*
this); }
567 template <
typename... Args>
570 traits_type::construct(*
this, p, std::forward<Args>(args)...);
582 return allocator_type::address(r);
592 template <
typename U>
595 return RAPIDJSON_NAMESPACE::Malloc<U>(baseAllocator_, n);
597 template <
typename U>
600 RAPIDJSON_NAMESPACE::Free<U>(baseAllocator_, p, n);
606 #if RAPIDJSON_HAS_CXX11
607 using is_always_equal = std::is_empty<BaseAllocator>;
610 template <
typename U>
613 return baseAllocator_ == rhs.baseAllocator_;
615 template <
typename U>
624 void*
Malloc(
size_t size) {
return baseAllocator_.Malloc(size); }
625 void*
Realloc(
void* originalPtr,
size_t originalSize,
size_t newSize)
627 return baseAllocator_.Realloc(originalPtr, originalSize, newSize);
632 template <
typename,
typename>
635 BaseAllocator baseAllocator_;
638 #if !RAPIDJSON_HAS_CXX17
639 template <
typename BaseAllocator>
642 typedef std::allocator<void> allocator_type;
647 StdAllocator() RAPIDJSON_NOEXCEPT : allocator_type(), baseAllocator_() {}
650 baseAllocator_(rhs.baseAllocator_)
654 template <
typename U>
656 : allocator_type(rhs),
657 baseAllocator_(rhs.baseAllocator_)
664 baseAllocator_(baseAllocator)
670 template <
typename U>
679 template <
typename,
typename>
682 BaseAllocator baseAllocator_;
T * Realloc(A &a, T *old_p, size_t old_n, size_t new_n)
Definition: allocators.h:471
void Free(A &a, T *p, size_t n=1)
Definition: allocators.h:485
T * Malloc(A &a, size_t n=1)
Definition: allocators.h:479
C-runtime library allocator.
Definition: allocators.h:83
bool operator!=(const CrtAllocator &) const RAPIDJSON_NOEXCEPT
Definition: allocators.h:106
void * Realloc(void *originalPtr, size_t originalSize, size_t newSize)
Definition: allocators.h:93
static void Free(void *ptr) RAPIDJSON_NOEXCEPT
Definition: allocators.h:103
static const bool kNeedFree
Definition: allocators.h:85
void * Malloc(size_t size)
Definition: allocators.h:86
bool operator==(const CrtAllocator &) const RAPIDJSON_NOEXCEPT
Definition: allocators.h:105
Default memory allocator used by the parser and DOM.
Definition: allocators.h:130
void * Malloc(size_t size)
Allocates a memory block. (concept Allocator)
Definition: allocators.h:346
MemoryPoolAllocator(void *buffer, size_t size, size_t chunkSize=kDefaultChunkCapacity, BaseAllocator *baseAllocator=0)
Constructor with user-supplied buffer.
Definition: allocators.h:213
MemoryPoolAllocator & operator=(const MemoryPoolAllocator &rhs) RAPIDJSON_NOEXCEPT
Definition: allocators.h:239
static const bool kRefCounted
Tell users that this allocator is reference counted on copy.
Definition: allocators.h:169
size_t Size() const RAPIDJSON_NOEXCEPT
Computes the memory blocks allocated.
Definition: allocators.h:327
size_t Capacity() const RAPIDJSON_NOEXCEPT
Computes the total capacity of allocated memory chunks.
Definition: allocators.h:315
void Clear() RAPIDJSON_NOEXCEPT
Deallocates all memory chunks, excluding the first/user one.
Definition: allocators.h:296
bool operator==(const MemoryPoolAllocator &rhs) const RAPIDJSON_NOEXCEPT
Compare (equality) with another MemoryPoolAllocator.
Definition: allocators.h:405
static void Free(void *ptr) RAPIDJSON_NOEXCEPT
Frees a memory block (concept Allocator)
Definition: allocators.h:402
static const bool kNeedFree
Tell users that no need to call Free() with this allocator. (concept Allocator)
Definition: allocators.h:167
bool operator!=(const MemoryPoolAllocator &rhs) const RAPIDJSON_NOEXCEPT
Compare (inequality) with another MemoryPoolAllocator.
Definition: allocators.h:412
void * Realloc(void *originalPtr, size_t originalSize, size_t newSize)
Resizes a memory block (concept Allocator)
Definition: allocators.h:363
bool Shared() const RAPIDJSON_NOEXCEPT
Whether the allocator is shared.
Definition: allocators.h:339
MemoryPoolAllocator(size_t chunkSize=kDefaultChunkCapacity, BaseAllocator *baseAllocator=0)
Constructor with chunkSize.
Definition: allocators.h:176
MemoryPoolAllocator(const MemoryPoolAllocator &rhs) RAPIDJSON_NOEXCEPT
Definition: allocators.h:231
~MemoryPoolAllocator() RAPIDJSON_NOEXCEPT
Destructor.
Definition: allocators.h:274
allocator_type::value_type value_type
Definition: allocators.h:676
~StdAllocator() RAPIDJSON_NOEXCEPT
Definition: allocators.h:668
StdAllocator(const StdAllocator< U, BaseAllocator > &rhs) RAPIDJSON_NOEXCEPT
Definition: allocators.h:655
BaseAllocator BaseAllocatorType
Definition: allocators.h:645
StdAllocator(const BaseAllocator &baseAllocator) RAPIDJSON_NOEXCEPT
Definition: allocators.h:662
StdAllocator(const StdAllocator &rhs) RAPIDJSON_NOEXCEPT
Definition: allocators.h:649
StdAllocator() RAPIDJSON_NOEXCEPT
Definition: allocators.h:647
Definition: allocators.h:497
BaseAllocator BaseAllocatorType
Definition: allocators.h:506
traits_type::pointer pointer
Definition: allocators.h:553
allocator_type::reference reference
Definition: allocators.h:576
size_type max_size() const RAPIDJSON_NOEXCEPT
Definition: allocators.h:585
void construct(pointer p, const_reference r)
Definition: allocators.h:587
void destroy(pointer p)
Definition: allocators.h:588
allocator_type::const_reference const_reference
Definition: allocators.h:577
~StdAllocator() RAPIDJSON_NOEXCEPT
Definition: allocators.h:541
traits_type::difference_type difference_type
Definition: allocators.h:550
const_pointer address(const_reference r) const RAPIDJSON_NOEXCEPT
Definition: allocators.h:580
bool operator!=(const StdAllocator< U, BaseAllocator > &rhs) const RAPIDJSON_NOEXCEPT
Definition: allocators.h:616
static const bool kNeedFree
rapidjson Allocator concept
Definition: allocators.h:622
void deallocate(U *p, size_type n=1)
Definition: allocators.h:598
void deallocate(pointer p, size_type n=1)
Definition: allocators.h:604
void * Realloc(void *originalPtr, size_t originalSize, size_t newSize)
Definition: allocators.h:625
pointer allocate(size_type n=1, const void *=0)
Definition: allocators.h:603
traits_type::value_type value_type
Definition: allocators.h:552
StdAllocator(const BaseAllocator &baseAllocator) RAPIDJSON_NOEXCEPT
Definition: allocators.h:535
StdAllocator(const StdAllocator< U, BaseAllocator > &rhs) RAPIDJSON_NOEXCEPT
Definition: allocators.h:516
StdAllocator(const StdAllocator &rhs) RAPIDJSON_NOEXCEPT
Definition: allocators.h:510
void * Malloc(size_t size)
Definition: allocators.h:624
bool operator==(const StdAllocator< U, BaseAllocator > &rhs) const RAPIDJSON_NOEXCEPT
Definition: allocators.h:611
traits_type::const_pointer const_pointer
Definition: allocators.h:554
static void Free(void *ptr) RAPIDJSON_NOEXCEPT
Definition: allocators.h:629
traits_type::size_type size_type
Definition: allocators.h:549
U * allocate(size_type n=1, const void *=0)
Definition: allocators.h:593
friend class StdAllocator
Definition: allocators.h:633
pointer address(reference r) const RAPIDJSON_NOEXCEPT
Definition: allocators.h:579
static const bool kRefCounted
Definition: allocators.h:623
StdAllocator() RAPIDJSON_NOEXCEPT
Definition: allocators.h:508
#define RAPIDJSON_NOEXCEPT_ASSERT(x)
Assertion (in non-throwing contexts).
Definition: rapidjson.h:717
#define RAPIDJSON_ALIGN(x)
Data alignment of the machine.
Definition: rapidjson.h:313
#define RAPIDJSON_UNLIKELY(x)
Compiler branching hint for expression with low probability to be true.
Definition: rapidjson.h:531
#define RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY
User-defined kDefaultChunkCapacity definition.
Definition: allocators.h:72
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:451
#define RAPIDJSON_NAMESPACE_BEGIN
provide custom rapidjson namespace (opening expression)
Definition: rapidjson.h:121
#define RAPIDJSON_NAMESPACE_END
provide custom rapidjson namespace (closing expression)
Definition: rapidjson.h:124
__host__ constexpr __device__ T max(T x)
Definition: math.hpp:84
bool_constant< true > true_type
Definition: integral_constant.hpp:62
Definition: allocators.h:459
const GenericPointer< typename T::ValueType > & pointer
Definition: pointer.h:1514
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition: pointer.h:1517
common definitions and configuration
#define RAPIDJSON_MALLOC(size)
! customization point for global malloc
Definition: rapidjson.h:726
Type
Type of JSON value.
Definition: rapidjson.h:760
#define RAPIDJSON_DELETE(x)
! customization point for global delete
Definition: rapidjson.h:746
#define RAPIDJSON_REALLOC(ptr, new_size)
! customization point for global realloc
Definition: rapidjson.h:730
#define RAPIDJSON_FREE(ptr)
! customization point for global free
Definition: rapidjson.h:734
#define RAPIDJSON_NEW(TypeName)
! customization point for global new
Definition: rapidjson.h:742
_W64 unsigned int uintptr_t
Definition: stdint.h:164
unsigned char uint8_t
Definition: stdint.h:124
Definition: allocators.h:545
StdAllocator< U, BaseAllocator > other
Definition: allocators.h:546
StdAllocator< U, BaseAllocator > other
Definition: allocators.h:673
Definition: allocators.h:462