15#ifndef RAPIDJSON_INTERNAL_STACK_H_
16#define RAPIDJSON_INTERNAL_STACK_H_
24RAPIDJSON_DIAG_OFF(c++98-compat)
36template <
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;
99 void Clear() { stackTop_ = stack_; }
104 Allocator::Free(stack_);
132 T*
ret =
reinterpret_cast<T*
>(stackTop_);
133 stackTop_ +=
sizeof(
T) *
count;
140 stackTop_ -=
count *
sizeof(
T);
141 return reinterpret_cast<T*
>(stackTop_);
147 return reinterpret_cast<T*
>(stackTop_ -
sizeof(
T));
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_); }
169 return allocator_ != 0;
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) {
189 newCapacity = initialCapacity_;
192 newCapacity += (newCapacity + 1) / 2;
195 if (newCapacity < newSize)
196 newCapacity = newSize;
201 void Resize(
size_t newCapacity) {
203 stack_ =
static_cast<char*
>(allocator_->Realloc(stack_,
GetCapacity(), newCapacity));
204 stackTop_ = stack_ + size;
205 stackEnd_ = stack_ + newCapacity;
209 Allocator::Free(stack_);
222 size_t initialCapacity_;
228#if defined(__clang__)
A type-unsafe stack for storing different types of data.
RAPIDJSON_FORCEINLINE T * Push(size_t count=1)
void Swap(Stack &rhs) RAPIDJSON_NOEXCEPT
bool HasAllocator() const
size_t GetCapacity() const
RAPIDJSON_FORCEINLINE void Reserve(size_t count=1)
RAPIDJSON_FORCEINLINE T * PushUnsafe(size_t count=1)
Allocator & GetAllocator()
Stack(Allocator *allocator, size_t stackCapacity)
Concept for allocating, resizing and freeing memory block.
#define RAPIDJSON_UNLIKELY(x)
Compiler branching hint for expression with low probability to be true.
#define RAPIDJSON_ASSERT(x)
Assertion.
#define RAPIDJSON_NAMESPACE_BEGIN
provide custom rapidjson namespace (opening expression)
#define RAPIDJSON_NAMESPACE_END
provide custom rapidjson namespace (closing expression)
void Swap(T &a, T &b) RAPIDJSON_NOEXCEPT
Custom swap() to avoid dependency on C++ <algorithm> header.
#define T(meth, val, expected)
#define RAPIDJSON_DELETE(x)
! customization point for global delete
#define RAPIDJSON_NEW(TypeName)
! customization point for global new