00001 //---------------------------------------------------------------------------- 00002 /** @file SgStack.h 00003 Stack class. */ 00004 //---------------------------------------------------------------------------- 00005 00006 #ifndef SG_STACK_H 00007 #define SG_STACK_H 00008 00009 #include <algorithm> 00010 00011 //---------------------------------------------------------------------------- 00012 00013 /** Stack with up to size objects of class T. Stack does not assume ownership. 00014 Memory management of objects on stack is the user's responsibility. */ 00015 template <class T, int SIZE> 00016 class SgStack 00017 { 00018 public: 00019 SgStack() 00020 : m_sp(0) 00021 { } 00022 00023 ~SgStack() {} 00024 00025 /** Empty the stack */ 00026 void Clear(); 00027 00028 /** Make this stack a copy of other*/ 00029 void CopyFrom(const SgStack<T,SIZE>& other); 00030 00031 bool IsEmpty() const; 00032 00033 bool NonEmpty() const; 00034 00035 /** remove and return top element. Must be NonEmpty. */ 00036 T Pop(); 00037 00038 void Push(T data); 00039 00040 /** Push all elements from other stack onto this stack */ 00041 void PushAll(const SgStack<T,SIZE>& other); 00042 00043 /** Number of elements on stack */ 00044 int Size() const; 00045 00046 /** Exchange contents of this and other stack */ 00047 void SwapWith(SgStack<T,SIZE>& other); 00048 00049 const T& Top() const; 00050 00051 const T& operator[](int index) const; 00052 00053 private: 00054 int m_sp; 00055 00056 T m_stack[SIZE]; 00057 00058 /** not implemented */ 00059 SgStack(const SgStack&); 00060 00061 /** not implemented */ 00062 SgStack& operator=(const SgStack&); 00063 }; 00064 00065 //---------------------------------------------------------------------------- 00066 00067 template<typename T, int SIZE> 00068 void SgStack<T,SIZE>::Clear() 00069 { 00070 m_sp = 0; 00071 } 00072 00073 template<typename T, int SIZE> 00074 void SgStack<T,SIZE>::CopyFrom(const SgStack<T,SIZE>& other) 00075 { 00076 for(int i=0; i < other.Size(); ++i) 00077 m_stack[i] = other.m_stack[i]; 00078 m_sp = other.m_sp; 00079 } 00080 00081 template<typename T, int SIZE> 00082 bool SgStack<T,SIZE>::IsEmpty() const 00083 { 00084 return m_sp == 0; 00085 } 00086 00087 template<typename T, int SIZE> 00088 bool SgStack<T,SIZE>::NonEmpty() const 00089 { 00090 return m_sp != 0; 00091 } 00092 00093 template<typename T, int SIZE> 00094 T SgStack<T,SIZE>::Pop() 00095 { 00096 SG_ASSERT(0 < m_sp); 00097 return m_stack[--m_sp]; 00098 } 00099 00100 template<typename T, int SIZE> 00101 void SgStack<T,SIZE>::Push(T data) 00102 { 00103 SG_ASSERT(m_sp < SIZE); 00104 m_stack[m_sp++] = data; 00105 } 00106 00107 template<typename T, int SIZE> 00108 void SgStack<T,SIZE>::PushAll(const SgStack<T,SIZE>& other) 00109 { 00110 for(int i=0; i < other.Size(); ++i) 00111 Push(other.m_stack[i]); 00112 } 00113 00114 template<typename T, int SIZE> 00115 int SgStack<T,SIZE>::Size() const 00116 { 00117 return m_sp; 00118 } 00119 00120 template<typename T, int SIZE> 00121 void SgStack<T,SIZE>::SwapWith(SgStack<T,SIZE>& other) 00122 { 00123 int nuSwap = std::min(Size(), other.Size()); 00124 for(int i = 0; i < nuSwap; ++i) 00125 std::swap(m_stack[i], other.m_stack[i]); 00126 if (Size() < other.Size()) 00127 for(int i = Size(); i < other.Size(); ++i) 00128 m_stack[i] = other.m_stack[i]; 00129 else if (other.Size() < Size()) 00130 for(int i = other.Size(); i < Size(); ++i) 00131 other.m_stack[i] = m_stack[i]; 00132 std::swap(m_sp, other.m_sp); 00133 } 00134 00135 template<typename T, int SIZE> 00136 const T& SgStack<T,SIZE>::Top() const 00137 { 00138 SG_ASSERT(0 < m_sp); 00139 return m_stack[m_sp-1]; 00140 } 00141 00142 template<typename T, int SIZE> 00143 const T& SgStack<T,SIZE>::operator[](int index) const 00144 { 00145 SG_ASSERT(index >= 0); 00146 SG_ASSERT(index < m_sp); 00147 return m_stack[index]; 00148 } 00149 00150 //---------------------------------------------------------------------------- 00151 00152 #endif // SG_STACK_H