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)
92 void*
Realloc(
void* originalPtr,
size_t originalSize,
size_t newSize) {
129 template <
typename BaseAllocator = CrtAllocator>
141 ChunkHeader *chunkHead;
142 BaseAllocator* ownBaseAllocator;
147 static const size_t SIZEOF_SHARED_DATA =
RAPIDJSON_ALIGN(
sizeof(SharedData));
148 static const size_t SIZEOF_CHUNK_HEADER =
RAPIDJSON_ALIGN(
sizeof(ChunkHeader));
150 static inline ChunkHeader *GetChunkHead(SharedData *shared)
152 return reinterpret_cast<ChunkHeader*
>(
reinterpret_cast<uint8_t*
>(shared) + SIZEOF_SHARED_DATA);
154 static inline uint8_t *GetChunkBuffer(SharedData *shared)
156 return reinterpret_cast<uint8_t*
>(shared->chunkHead) + SIZEOF_CHUNK_HEADER;
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))
178 shared_->ownBaseAllocator = 0;
181 shared_->ownBaseAllocator = baseAllocator_;
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;
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)))
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;
217 chunk_capacity_(rhs.chunk_capacity_),
218 baseAllocator_(rhs.baseAllocator_),
227 ++rhs.shared_->refcount;
229 baseAllocator_ = rhs.baseAllocator_;
230 chunk_capacity_ = rhs.chunk_capacity_;
231 shared_ = rhs.shared_;
235 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
237 chunk_capacity_(rhs.chunk_capacity_),
238 baseAllocator_(rhs.baseAllocator_),
248 baseAllocator_ = rhs.baseAllocator_;
249 chunk_capacity_ = rhs.chunk_capacity_;
250 shared_ = rhs.shared_;
264 if (shared_->refcount > 1) {
269 BaseAllocator *
a = shared_->ownBaseAllocator;
270 if (shared_->ownBuffer) {
271 baseAllocator_->Free(shared_);
280 ChunkHeader* c = shared_->chunkHead;
284 shared_->chunkHead = c->next;
285 baseAllocator_->Free(c);
287 shared_->chunkHead->size = 0;
296 for (ChunkHeader* c = shared_->chunkHead; c != 0; c = c->next)
297 capacity += c->capacity;
304 size_t Size() const RAPIDJSON_NOEXCEPT {
307 for (ChunkHeader* c = shared_->chunkHead; c != 0; c = c->next)
317 return shared_->refcount > 1;
327 if (
RAPIDJSON_UNLIKELY(shared_->chunkHead->size + size > shared_->chunkHead->capacity))
328 if (!AddChunk(chunk_capacity_ > size ? chunk_capacity_ : size))
331 void *buffer = GetChunkBuffer(shared_) + shared_->chunkHead->size;
332 shared_->chunkHead->size += size;
337 void*
Realloc(
void* originalPtr,
size_t originalSize,
size_t newSize) {
338 if (originalPtr == 0)
349 if (originalSize >= newSize)
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;
362 if (
void* newBuffer =
Malloc(newSize)) {
364 std::memcpy(newBuffer, originalPtr, originalSize);
372 static void Free(
void *ptr) RAPIDJSON_NOEXCEPT { (void)ptr; }
378 return shared_ == rhs.shared_;
390 bool AddChunk(
size_t capacity) {
392 shared_->ownBaseAllocator = baseAllocator_ =
RAPIDJSON_NEW(BaseAllocator)();
393 if (ChunkHeader* chunk =
static_cast<ChunkHeader*
>(baseAllocator_->Malloc(SIZEOF_CHUNK_HEADER + capacity))) {
394 chunk->capacity = capacity;
396 chunk->next = shared_->chunkHead;
397 shared_->chunkHead = chunk;
404 static inline void* AlignBuffer(
void* buf,
size_t &size)
407 const uintptr_t mask =
sizeof(
void*) - 1;
410 const uintptr_t abuf = (ubuf + mask) & ~mask;
412 buf =
reinterpret_cast<void*
>(abuf);
418 size_t chunk_capacity_;
419 BaseAllocator* baseAllocator_;
424 template<
typename,
typename =
void>
434 template<
typename T,
typename A>
435 inline T*
Realloc(A&
a, T* old_p,
size_t old_n,
size_t new_n)
438 return static_cast<T*
>(
a.Realloc(old_p, old_n *
sizeof(T), new_n *
sizeof(T)));
441 template<
typename T,
typename A>
444 return Realloc<T, A>(
a, NULL, 0, n);
447 template<
typename T,
typename A>
448 inline void Free(A&
a, T *p,
size_t n = 1)
450 static_cast<void>(Realloc<T, A>(
a, p, n, 0));
455 RAPIDJSON_DIAG_OFF(effc++)
458 template <
typename T,
typename BaseAllocator = CrtAllocator>
460 public std::allocator<T>
462 typedef std::allocator<T> allocator_type;
463 #if RAPIDJSON_HAS_CXX11
464 typedef std::allocator_traits<allocator_type> traits_type;
466 typedef allocator_type traits_type;
479 baseAllocator_(rhs.baseAllocator_)
485 baseAllocator_(rhs.baseAllocator_)
488 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
490 allocator_type(std::move(rhs)),
491 baseAllocator_(std::move(rhs.baseAllocator_))
494 #if RAPIDJSON_HAS_CXX11
502 baseAllocator_(baseAllocator)
520 #if RAPIDJSON_HAS_CXX11
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;
527 return std::addressof(r);
531 return std::addressof(r);
536 return traits_type::max_size(*
this);
539 template <
typename ...Args>
542 traits_type::construct(*
this, p, std::forward<Args>(args)...);
546 traits_type::destroy(*
this, p);
556 return allocator_type::address(r);
560 return allocator_type::address(r);
565 return allocator_type::max_size();
570 allocator_type::construct(p, r);
574 allocator_type::destroy(p);
579 template <
typename U>
582 return RAPIDJSON_NAMESPACE::Malloc<U>(baseAllocator_, n);
584 template <
typename U>
587 RAPIDJSON_NAMESPACE::Free<U>(baseAllocator_, p, n);
592 return allocate<value_type>(n);
596 deallocate<value_type>(p, n);
599 #if RAPIDJSON_HAS_CXX11
600 using is_always_equal = std::is_empty<BaseAllocator>;
606 return baseAllocator_ == rhs.baseAllocator_;
619 return baseAllocator_.Malloc(size);
621 void*
Realloc(
void* originalPtr,
size_t originalSize,
size_t newSize)
623 return baseAllocator_.Realloc(originalPtr, originalSize, newSize);
625 static void Free(
void *ptr) RAPIDJSON_NOEXCEPT
631 template <
typename,
typename>
634 BaseAllocator baseAllocator_;
637 #if !RAPIDJSON_HAS_CXX17
638 template <
typename BaseAllocator>
640 public std::allocator<void>
642 typedef std::allocator<void> allocator_type;
654 baseAllocator_(rhs.baseAllocator_)
660 baseAllocator_(rhs.baseAllocator_)
666 baseAllocator_(baseAllocator)
680 template <
typename,
typename>
683 BaseAllocator baseAllocator_;
T * Realloc(A &a, T *old_p, size_t old_n, size_t new_n)
Definition: allocators.h:435
void Free(A &a, T *p, size_t n=1)
Definition: allocators.h:448
T * Malloc(A &a, size_t n=1)
Definition: allocators.h:442
C-runtime library allocator.
Definition: allocators.h:83
bool operator!=(const CrtAllocator &) const RAPIDJSON_NOEXCEPT
Definition: allocators.h:105
void * Realloc(void *originalPtr, size_t originalSize, size_t newSize)
Definition: allocators.h:92
static void Free(void *ptr) RAPIDJSON_NOEXCEPT
Definition: allocators.h:100
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:102
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:321
MemoryPoolAllocator(void *buffer, size_t size, size_t chunkSize=kDefaultChunkCapacity, BaseAllocator *baseAllocator=0)
Constructor with user-supplied buffer.
Definition: allocators.h:201
MemoryPoolAllocator & operator=(const MemoryPoolAllocator &rhs) RAPIDJSON_NOEXCEPT
Definition: allocators.h:224
static const bool kRefCounted
Tell users that this allocator is reference counted on copy.
Definition: allocators.h:163
size_t Size() const RAPIDJSON_NOEXCEPT
Computes the memory blocks allocated.
Definition: allocators.h:304
size_t Capacity() const RAPIDJSON_NOEXCEPT
Computes the total capacity of allocated memory chunks.
Definition: allocators.h:293
void Clear() RAPIDJSON_NOEXCEPT
Deallocates all memory chunks, excluding the first/user one.
Definition: allocators.h:277
bool operator==(const MemoryPoolAllocator &rhs) const RAPIDJSON_NOEXCEPT
Compare (equality) with another MemoryPoolAllocator.
Definition: allocators.h:375
static void Free(void *ptr) RAPIDJSON_NOEXCEPT
Frees a memory block (concept Allocator)
Definition: allocators.h:372
static const bool kNeedFree
Tell users that no need to call Free() with this allocator. (concept Allocator)
Definition: allocators.h:162
bool operator!=(const MemoryPoolAllocator &rhs) const RAPIDJSON_NOEXCEPT
Compare (inequality) with another MemoryPoolAllocator.
Definition: allocators.h:381
void * Realloc(void *originalPtr, size_t originalSize, size_t newSize)
Resizes a memory block (concept Allocator)
Definition: allocators.h:337
bool Shared() const RAPIDJSON_NOEXCEPT
Whether the allocator is shared.
Definition: allocators.h:315
MemoryPoolAllocator(size_t chunkSize=kDefaultChunkCapacity, BaseAllocator *baseAllocator=0)
Constructor with chunkSize.
Definition: allocators.h:170
MemoryPoolAllocator(const MemoryPoolAllocator &rhs) RAPIDJSON_NOEXCEPT
Definition: allocators.h:216
~MemoryPoolAllocator() RAPIDJSON_NOEXCEPT
Destructor.
Definition: allocators.h:259
allocator_type::value_type value_type
Definition: allocators.h:677
~StdAllocator() RAPIDJSON_NOEXCEPT
Definition: allocators.h:669
StdAllocator(const StdAllocator< U, BaseAllocator > &rhs) RAPIDJSON_NOEXCEPT
Definition: allocators.h:658
BaseAllocator BaseAllocatorType
Definition: allocators.h:645
StdAllocator(const BaseAllocator &baseAllocator) RAPIDJSON_NOEXCEPT
Definition: allocators.h:664
StdAllocator(const StdAllocator &rhs) RAPIDJSON_NOEXCEPT
Definition: allocators.h:652
StdAllocator() RAPIDJSON_NOEXCEPT
Definition: allocators.h:647
Definition: allocators.h:461
BaseAllocator BaseAllocatorType
Definition: allocators.h:470
traits_type::pointer pointer
Definition: allocators.h:517
allocator_type::reference reference
Definition: allocators.h:551
size_type max_size() const RAPIDJSON_NOEXCEPT
Definition: allocators.h:563
void construct(pointer p, const_reference r)
Definition: allocators.h:568
void destroy(pointer p)
Definition: allocators.h:572
allocator_type::const_reference const_reference
Definition: allocators.h:552
~StdAllocator() RAPIDJSON_NOEXCEPT
Definition: allocators.h:505
traits_type::difference_type difference_type
Definition: allocators.h:514
const_pointer address(const_reference r) const RAPIDJSON_NOEXCEPT
Definition: allocators.h:558
bool operator!=(const StdAllocator< U, BaseAllocator > &rhs) const RAPIDJSON_NOEXCEPT
Definition: allocators.h:609
static const bool kNeedFree
rapidjson Allocator concept
Definition: allocators.h:615
void deallocate(U *p, size_type n=1)
Definition: allocators.h:585
void deallocate(pointer p, size_type n=1)
Definition: allocators.h:594
void * Realloc(void *originalPtr, size_t originalSize, size_t newSize)
Definition: allocators.h:621
pointer allocate(size_type n=1, const void *=0)
Definition: allocators.h:590
traits_type::value_type value_type
Definition: allocators.h:516
StdAllocator(const BaseAllocator &baseAllocator) RAPIDJSON_NOEXCEPT
Definition: allocators.h:500
StdAllocator(const StdAllocator< U, BaseAllocator > &rhs) RAPIDJSON_NOEXCEPT
Definition: allocators.h:483
StdAllocator(const StdAllocator &rhs) RAPIDJSON_NOEXCEPT
Definition: allocators.h:477
void * Malloc(size_t size)
Definition: allocators.h:617
bool operator==(const StdAllocator< U, BaseAllocator > &rhs) const RAPIDJSON_NOEXCEPT
Definition: allocators.h:604
traits_type::const_pointer const_pointer
Definition: allocators.h:518
static void Free(void *ptr) RAPIDJSON_NOEXCEPT
Definition: allocators.h:625
traits_type::size_type size_type
Definition: allocators.h:513
U * allocate(size_type n=1, const void *=0)
Definition: allocators.h:580
friend class StdAllocator
Definition: allocators.h:632
pointer address(reference r) const RAPIDJSON_NOEXCEPT
Definition: allocators.h:554
static const bool kRefCounted
Definition: allocators.h:616
StdAllocator() RAPIDJSON_NOEXCEPT
Definition: allocators.h:472
#define RAPIDJSON_NOEXCEPT_ASSERT(x)
Assertion (in non-throwing contexts).
Definition: rapidjson.h:687
#define RAPIDJSON_ALIGN(x)
Data alignment of the machine.
Definition: rapidjson.h:307
#define RAPIDJSON_UNLIKELY(x)
Compiler branching hint for expression with low probability to be true.
Definition: rapidjson.h:507
#define RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY
User-defined kDefaultChunkCapacity definition.
Definition: allocators.h:72
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:437
#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:423
const GenericPointer< typename T::ValueType > & pointer
Definition: pointer.h:1249
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition: pointer.h:1249
common definitions and configuration
#define RAPIDJSON_MALLOC(size)
! customization point for global malloc
Definition: rapidjson.h:696
Type
Type of JSON value.
Definition: rapidjson.h:729
#define RAPIDJSON_DELETE(x)
! customization point for global delete
Definition: rapidjson.h:716
#define RAPIDJSON_REALLOC(ptr, new_size)
! customization point for global realloc
Definition: rapidjson.h:700
#define RAPIDJSON_FREE(ptr)
! customization point for global free
Definition: rapidjson.h:704
#define RAPIDJSON_NEW(TypeName)
! customization point for global new
Definition: rapidjson.h:712
_W64 unsigned int uintptr_t
Definition: stdint.h:165
unsigned char uint8_t
Definition: stdint.h:124
Definition: allocators.h:509
StdAllocator< U, BaseAllocator > other
Definition: allocators.h:510
StdAllocator< U, BaseAllocator > other
Definition: allocators.h:674
Definition: allocators.h:427