stack.h

Engine/source/persistence/rapidjson/internal/stack.h

More...

Classes:

class

A type-unsafe stack for storing different types of data.

Namespaces:

Detailed Description

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