15#ifndef RAPIDJSON_INTERNAL_STACK_H_
16#define RAPIDJSON_INTERNAL_STACK_H_
18#include "../allocators.h"
23RAPIDJSON_DIAG_OFF(c++98-compat)
26RAPIDJSON_NAMESPACE_BEGIN
35template <
typename Allocator>
40 Stack(
Allocator* allocator,
size_t stackCapacity) : allocator_(allocator), ownAllocator_(0), stack_(0), stackTop_(0), stackEnd_(0), initialCapacity_(stackCapacity) {
43#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
45 : allocator_(rhs.allocator_),
46 ownAllocator_(rhs.ownAllocator_),
48 stackTop_(rhs.stackTop_),
49 stackEnd_(rhs.stackEnd_),
50 initialCapacity_(rhs.initialCapacity_)
53 rhs.ownAllocator_ = 0;
57 rhs.initialCapacity_ = 0;
65#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
66 Stack& operator=(Stack&& rhs) {
71 allocator_ = rhs.allocator_;
72 ownAllocator_ = rhs.ownAllocator_;
74 stackTop_ = rhs.stackTop_;
75 stackEnd_ = rhs.stackEnd_;
76 initialCapacity_ = rhs.initialCapacity_;
79 rhs.ownAllocator_ = 0;
83 rhs.initialCapacity_ = 0;
89 void Swap(Stack& rhs) RAPIDJSON_NOEXCEPT {
90 internal::Swap(allocator_, rhs.allocator_);
91 internal::Swap(ownAllocator_, rhs.ownAllocator_);
92 internal::Swap(stack_, rhs.stack_);
93 internal::Swap(stackTop_, rhs.stackTop_);
94 internal::Swap(stackEnd_, rhs.stackEnd_);
95 internal::Swap(initialCapacity_, rhs.initialCapacity_);
98 void Clear() { stackTop_ = stack_; }
103 Allocator::Free(stack_);
115 RAPIDJSON_FORCEINLINE
void Reserve(
size_t count = 1) {
122 RAPIDJSON_FORCEINLINE T* Push(
size_t count = 1) {
124 return PushUnsafe<T>(count);
128 RAPIDJSON_FORCEINLINE T* PushUnsafe(
size_t count = 1) {
131 T* ret =
reinterpret_cast<T*
>(stackTop_);
132 stackTop_ +=
sizeof(T) * count;
137 T* Pop(
size_t count) {
139 stackTop_ -= count *
sizeof(T);
140 return reinterpret_cast<T*
>(stackTop_);
146 return reinterpret_cast<T*
>(stackTop_ -
sizeof(T));
150 const T* Top()
const {
152 return reinterpret_cast<T*
>(stackTop_ -
sizeof(T));
156 T* End() {
return reinterpret_cast<T*
>(stackTop_); }
159 const T* End()
const {
return reinterpret_cast<T*
>(stackTop_); }
162 T* Bottom() {
return reinterpret_cast<T*
>(stack_); }
165 const T* Bottom()
const {
return reinterpret_cast<T*
>(stack_); }
167 bool HasAllocator()
const {
168 return allocator_ != 0;
176 bool Empty()
const {
return stackTop_ == stack_; }
177 size_t GetSize()
const {
return static_cast<size_t>(stackTop_ - stack_); }
178 size_t GetCapacity()
const {
return static_cast<size_t>(stackEnd_ - stack_); }
182 void Expand(
size_t count) {
188 newCapacity = initialCapacity_;
190 newCapacity = GetCapacity();
191 newCapacity += (newCapacity + 1) / 2;
193 size_t newSize = GetSize() +
sizeof(T) * count;
194 if (newCapacity < newSize)
195 newCapacity = newSize;
200 void Resize(
size_t newCapacity) {
201 const size_t size = GetSize();
202 stack_ =
static_cast<char*
>(allocator_->Realloc(stack_, GetCapacity(), newCapacity));
203 stackTop_ = stack_ + size;
204 stackEnd_ = stack_ + newCapacity;
208 Allocator::Free(stack_);
214 Stack& operator=(
const Stack&);
221 size_t initialCapacity_;
225RAPIDJSON_NAMESPACE_END
227#if defined(__clang__)
Concept for allocating, resizing and freeing memory block.
#define RAPIDJSON_UNLIKELY(x)
Compiler branching hint for expression with low probability to be true.
Definition rapidjson.h:481
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition rapidjson.h:411
#define RAPIDJSON_DELETE(x)
! customization point for global delete
Definition rapidjson.h:603
#define RAPIDJSON_NEW(TypeName)
! customization point for global new
Definition rapidjson.h:599