#ifndef STACK_H #define STACK_H /////////////////////////////////////////////////////////////////////// // Stack.h - stack class derived from Effective C++, Scott Meyers // // // // Note: inclusion model for templates requires all template // // implementations be placed in header file. // // // // Jim Fawcett, CSE687 - Object Oriented Design, Spring 2004 // /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////// // template class template class stack { template friend class stack; private: struct stacknode { T data; stacknode *next; stacknode(const T& newdata, stacknode *nextnode) : data(newdata), next(nextnode) { } }; stacknode *top; public: stack(); ~stack(); void push(const T& object); T pop(void); void flush(); int size() const; // member templates template stack(const stack&); template stack& operator=(const stack&); }; // //----< void constructor >--------------------------------------------- template stack::stack() : top(0) { } //----< destructor >--------------------------------------------------- template stack::~stack(void) { while (top) { stacknode *next_to_die = top; top = top->next; delete next_to_die; } } //----< push data onto stack >----------------------------------------- template void stack::push(const T &object) { top = new stacknode(object, top); } //----< pop data from stack >------------------------------------------ template T stack::pop(void) { if (!top) { throw std::out_of_range("\n attempt to pop empty stack\n"); } stacknode *save = top; top = top->next; T data = save->data; delete save; return data; } //----< empty stack >-------------------------------------------------- template void stack::flush() { stacknode* node = top; while(node) { stacknode *next_to_die = node; node = node->next; delete next_to_die; } } //----< return number of elements on stack >--------------------------- template int stack::size() const { stacknode* node = top; int count = 0; while(node) { count++; node = node->next; } return count; } // //----< copy and promotion constructor, a member template >------------ template template stack::stack(const stack& s) : top(0) { stack::stacknode* node = const_cast::stacknode*>(s.top); while(node) { this->push(node->data); node = node->next; } } //----< assignment from stack of possibly a compatible type >---------- template template stack& stack::operator=(const stack& s) { if((void*)this == (void*)&s) return *this; flush(); stack::stacknode* node2 = const_cast::stacknode*>(s.top); while(node2) { this->push(static_cast(node2->data)); node2 = node2->next; } return *this; } #endif