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