15 #ifndef RAPIDJSON_INTERNAL_STACK_H_ 16 #define RAPIDJSON_INTERNAL_STACK_H_ 18 #include "../allocators.h" 22 #if defined(__clang__) 24 RAPIDJSON_DIAG_OFF(c++98-compat)
36 template <
typename Allocator>
41 Stack(Allocator* allocator,
size_t stackCapacity) : allocator_(allocator), ownAllocator_(0), stack_(0), stackTop_(0), stackEnd_(0), initialCapacity_(stackCapacity) {
44 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS 46 : allocator_(rhs.allocator_),
47 ownAllocator_(rhs.ownAllocator_),
49 stackTop_(rhs.stackTop_),
50 stackEnd_(rhs.stackEnd_),
51 initialCapacity_(rhs.initialCapacity_)
54 rhs.ownAllocator_ = 0;
58 rhs.initialCapacity_ = 0;
66 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS 72 allocator_ = rhs.allocator_;
73 ownAllocator_ = rhs.ownAllocator_;
75 stackTop_ = rhs.stackTop_;
76 stackEnd_ = rhs.stackEnd_;
77 initialCapacity_ = rhs.initialCapacity_;
80 rhs.ownAllocator_ = 0;
84 rhs.initialCapacity_ = 0;
90 void Swap(
Stack& rhs) RAPIDJSON_NOEXCEPT {
91 internal::Swap(allocator_, rhs.allocator_);
92 internal::Swap(ownAllocator_, rhs.ownAllocator_);
93 internal::Swap(stack_, rhs.stack_);
94 internal::Swap(stackTop_, rhs.stackTop_);
95 internal::Swap(stackEnd_, rhs.stackEnd_);
96 internal::Swap(initialCapacity_, rhs.initialCapacity_);
99 void Clear() { stackTop_ = stack_; }
104 Allocator::Free(stack_);
116 RAPIDJSON_FORCEINLINE
void Reserve(
size_t count = 1) {
118 if (
RAPIDJSON_UNLIKELY(static_cast<std::ptrdiff_t>(
sizeof(T) * count) > (stackEnd_ - stackTop_)))
123 RAPIDJSON_FORCEINLINE T* Push(
size_t count = 1) {
125 return PushUnsafe<T>(count);
129 RAPIDJSON_FORCEINLINE T* PushUnsafe(
size_t count = 1) {
131 RAPIDJSON_ASSERT(static_cast<std::ptrdiff_t>(
sizeof(T) * count) <= (stackEnd_ - stackTop_));
132 T* ret =
reinterpret_cast<T*
>(stackTop_);
133 stackTop_ +=
sizeof(T) * count;
138 T* Pop(
size_t count) {
140 stackTop_ -= count *
sizeof(T);
141 return reinterpret_cast<T*
>(stackTop_);
147 return reinterpret_cast<T*
>(stackTop_ -
sizeof(T));
151 const T* Top()
const {
153 return reinterpret_cast<T*
>(stackTop_ -
sizeof(T));
157 T* End() {
return reinterpret_cast<T*
>(stackTop_); }
160 const T* End()
const {
return reinterpret_cast<T*
>(stackTop_); }
163 T* Bottom() {
return reinterpret_cast<T*
>(stack_); }
166 const T* Bottom()
const {
return reinterpret_cast<T*
>(stack_); }
168 bool HasAllocator()
const {
169 return allocator_ != 0;
172 Allocator& GetAllocator() {
177 bool Empty()
const {
return stackTop_ == stack_; }
178 size_t GetSize()
const {
return static_cast<size_t>(stackTop_ - stack_); }
179 size_t GetCapacity()
const {
return static_cast<size_t>(stackEnd_ - stack_); }
183 void Expand(
size_t count) {
188 ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
189 newCapacity = initialCapacity_;
191 newCapacity = GetCapacity();
192 newCapacity += (newCapacity + 1) / 2;
194 size_t newSize = GetSize() +
sizeof(T) * count;
195 if (newCapacity < newSize)
196 newCapacity = newSize;
201 void Resize(
size_t newCapacity) {
202 const size_t size = GetSize();
203 stack_ =
static_cast<char*
>(allocator_->Realloc(stack_, GetCapacity(), newCapacity));
204 stackTop_ = stack_ + size;
205 stackEnd_ = stack_ + newCapacity;
209 Allocator::Free(stack_);
210 RAPIDJSON_DELETE(ownAllocator_);
217 Allocator* allocator_;
218 Allocator* ownAllocator_;
222 size_t initialCapacity_;
228 #if defined(__clang__) 232 #endif // RAPIDJSON_STACK_H_ #define RAPIDJSON_NAMESPACE_BEGIN
provide custom rapidjson namespace (opening expression)
Definition: rapidjson.h:121
#define RAPIDJSON_UNLIKELY(x)
Compiler branching hint for expression with low probability to be true.
Definition: rapidjson.h:507
#define RAPIDJSON_NAMESPACE_END
provide custom rapidjson namespace (closing expression)
Definition: rapidjson.h:124
A type-unsafe stack for storing different types of data.
Definition: stack.h:37
Definition: allocators.h:422
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:437