rapidjson A fast JSON parser/generator for C++ with both SAX/DOM style API

- Main Page
- Related Pages
- Classes
- Files

- File List

All Classes Functions Variables Typedefs Pages
stack.h
1 #ifndef RAPIDJSON_INTERNAL_STACK_H_
2 #define RAPIDJSON_INTERNAL_STACK_H_
3
4 namespace rapidjson {
5 namespace internal {
6
7 ///////////////////////////////////////////////////////////////////////////////
8 // Stack
9
10 //! A type-unsafe stack for storing different types of data.
11 /*! \tparam Allocator Allocator for allocating stack memory.
12 */
13 template <typename Allocator>
14 class Stack {
15 public:
16 Stack(Allocator* allocator, size_t stack_capacity) : allocator_(allocator), own_allocator_(0), stack_(0), stack_top_(0), stack_end_(0), stack_capacity_(stack_capacity) {
17 RAPIDJSON_ASSERT(stack_capacity_ > 0);
18 if (!allocator_)
19 own_allocator_ = allocator_ = new Allocator();
20 stack_top_ = stack_ = (char*)allocator_->Malloc(stack_capacity_);
21 stack_end_ = stack_ + stack_capacity_;
22 }
23
24 ~Stack() {
25 Allocator::Free(stack_);
26 delete own_allocator_; // Only delete if it is owned by the stack
27 }
28
29 void Clear() { /*stack_top_ = 0;*/ stack_top_ = stack_; }
30
31 template<typename T>
32 T* Push(size_t count = 1) {
33 // Expand the stack if needed
34 if (stack_top_ + sizeof(T) * count >= stack_end_) {
35 size_t new_capacity = stack_capacity_ * 2;
36 size_t size = GetSize();
37 size_t new_size = GetSize() + sizeof(T) * count;
38 if (new_capacity < new_size)
39 new_capacity = new_size;
40 stack_ = (char*)allocator_->Realloc(stack_, stack_capacity_, new_capacity);
41 stack_capacity_ = new_capacity;
42 stack_top_ = stack_ + size;
43 stack_end_ = stack_ + stack_capacity_;
44 }
45 T* ret = (T*)stack_top_;
46 stack_top_ += sizeof(T) * count;
47 return ret;
48 }
49
50 template<typename T>
51 T* Pop(size_t count) {
52 RAPIDJSON_ASSERT(GetSize() >= count * sizeof(T));
53 stack_top_ -= count * sizeof(T);
54 return (T*)stack_top_;
55 }
56
57 template<typename T>
58 T* Top() {
59 RAPIDJSON_ASSERT(GetSize() >= sizeof(T));
60 return (T*)(stack_top_ - sizeof(T));
61 }
62
63 template<typename T>
64 T* Bottom() { return (T*)stack_; }
65
66 Allocator& GetAllocator() { return *allocator_; }
67 size_t GetSize() const { return stack_top_ - stack_; }
68 size_t GetCapacity() const { return stack_capacity_; }
69
70 private:
71 Allocator* allocator_;
72 Allocator* own_allocator_;
73 char *stack_;
74 char *stack_top_;
75 char *stack_end_;
76 size_t stack_capacity_;
77 };
78
79 } // namespace internal
80 } // namespace rapidjson
81
82 #endif // RAPIDJSON_STACK_H_