#ifndef SMART_STACK_H #define SMART_STACK_H #include #include #include #include using namespace std; /** * A stack implementation based upon use of a singly-linked list. * Elements are inserted and removed according to the last-in * first-out principle. * * This implementation is (very) loosely based on the Singly-Linked * List from Section 3.2.4 of the text, but customized directly as a * stack implementations. */ template class SmartStack { protected: struct Node { // a node in the stack Object elem; // element Node* next; // next pointer Node(const Object& e = Object(), Node* n = NULL) : elem(e), next(n) { SmartStack::total++; // please leave this command here } ~Node() { SmartStack::total--; // please leave this command here } }; private: Node* head; // pointer to stack top int n; // number of items in stack public: /* Standard constructor creates an empty stack. */ SmartStack() : head(NULL), n(0) { } /* Return the number of objects in the stack. */ int size() const { return n; } /* Determine if the stack is currently empty. */ bool empty() const { return n == 0; } /* Return a const reference to the top object in the stack. */ const Object& top() const { if (empty()) throw std::runtime_error("Access to empty stack"); return head->elem; } /* Insert an object at the top of the stack. */ void push(const Object& e) { head = new Node(e, head); // new node points to old head n++; } /** Removes the top object from the stack. */ void pop() { if (empty()) throw std::runtime_error("Access to empty stack"); Node* old = head; // node to remove head = old->next; delete old; n--; } protected: // protected utilities void removeAll() { // remove entire stack contents while (!empty()) pop(); } void copyFrom(const SmartStack& other) { // copy from other n = other.n; head = NULL; Node* walk(other.head); // walk the other list Node* prev(NULL); for (int j=0; j < n; j++) { Node* v = new Node(walk->elem, NULL); // make copy of model if (prev == NULL) head = v; // first node else prev->next = v; // else link after prev prev = v; walk = walk->next; } } public: /* Copy constructor */ SmartStack(const SmartStack& other) { copyFrom(other); } /* Assignment operator */ SmartStack& operator=(const SmartStack& other) { if (this != &other) { // avoid self copy (x = x) removeAll(); // remove old contents copyFrom(other); // copy new contents } return *this; } /* Destructor */ ~SmartStack() { removeAll(); } public: //----------------------------------------------------------- // used for diagnostic purposes to count number of live nodes static int total; static int getTotalNumNodes() { return total; } std::string dump() const { std::stringstream temp; for (Node* walk=head; walk!=NULL; walk=walk->next) temp << walk->elem << " "; return temp.str(); } //----------------------------------------------------------- }; // end of SmartStack class #endif