00001
00002
00003
00004
00005 #ifndef STACK_H
00006 #define STACK_H
00007
00008 #include <stdexcept>
00009 #include <new>
00010 #include <string>
00011 #include "node.h"
00012
00013 using namespace std;
00014
00015
00016
00024 class StackEmpty : public runtime_error {
00025 public:
00026 StackEmpty() : runtime_error( "stack empty" ) {}
00027 StackEmpty( const string &what ) : runtime_error( what ) {}
00028 };
00029
00030
00031
00040 template <typename T>
00041 class Stack {
00042
00043 public:
00044 Stack();
00045 Stack( const Stack & ) throw ( bad_alloc );
00046 ~Stack();
00047 bool empty() const;
00048 unsigned size() const;
00049 void clear();
00050 void push( const T & ) throw ( bad_alloc );
00051 T pop() throw ( StackEmpty );
00052 T &top() const throw ( StackEmpty );
00053 const Stack<T> &operator=( const Stack<T> & ) throw ( bad_alloc );
00054
00055 private:
00056 unsigned sz;
00057 Node<T> *contents;
00058
00059 };
00060
00065 template <typename T>
00066 Stack<T>::Stack()
00067 {
00068 sz = 0;
00069 contents = 0;
00070 }
00071
00079 template <typename T>
00080 Stack<T>::Stack( const Stack<T> &s ) throw ( bad_alloc )
00081 {
00082 sz = 0;
00083 contents = 0;
00084 *this = s;
00085 }
00086
00091 template <typename T>
00092 Stack<T>::~Stack()
00093 {
00094 clear();
00095 }
00096
00103 template <typename T>
00104 bool Stack<T>::empty() const
00105 {
00106 return (contents == 0);
00107 }
00108
00115 template <typename T>
00116 unsigned Stack<T>::size() const
00117 {
00118 return sz;
00119 }
00120
00125 template <typename T>
00126 void Stack<T>::clear()
00127 {
00128 Node<T> *current = contents;
00129 while (contents != 0) {
00130 contents = contents->getNextPtr();
00131 delete current;
00132 current = contents;
00133 }
00134 sz = 0;
00135 contents = 0;
00136 }
00137
00145 template <typename T>
00146 void Stack<T>::push( const T &item ) throw ( bad_alloc )
00147 {
00148 Node<T> *newNode = new Node<T>( item );
00149 newNode->setNextPtr( contents );
00150 contents = newNode;
00151 sz++;
00152 }
00153
00161 template <typename T>
00162 T Stack<T>::pop() throw ( StackEmpty )
00163 {
00164 if ( empty() )
00165 throw StackEmpty( "pop: stack empty" );
00166 Node<T> *ptr = contents;
00167 contents = contents->getNextPtr();
00168 T value = ptr->getObject();
00169 delete ptr;
00170 sz--;
00171 return value;
00172 }
00173
00181 template <typename T>
00182 T &Stack<T>::top() const throw ( StackEmpty )
00183 {
00184 if ( empty() )
00185 throw StackEmpty( "top: stack empty" );
00186 return contents->getObject();
00187 }
00188
00197
00198
00199
00200
00201
00202 template <typename T>
00203 const Stack<T> &Stack<T>::operator=( const Stack<T> &s ) throw ( bad_alloc )
00204 {
00205 if ( this != &s ) {
00206 if ( !empty() )
00207 clear();
00208 sz = s.sz;
00209 Node<T> *meptr = 0, *sptr = s.contents;
00210 while ( sptr != 0 ) {
00211 if ( meptr == 0 )
00212 contents = meptr = new Node<T>( *sptr );
00213 else {
00214 meptr->setNextPtr( new Node<T>( *sptr ) );
00215 meptr = meptr->getNextPtr();
00216 }
00217 sptr = sptr->getNextPtr();
00218 }
00219 }
00220 return *this;
00221 }
00222
00223 #endif // STACK_H
00224