/* * stack.hpp * * Created on: Nov 15, 2010 * Author: Michael Fischer * for use in Yale course CPSC 427a, Fall 2010 * * Derived from "Exception Handling: A False Sense of Security", by * Tom Cargill, C++ Report, Volume 6, Number 9, November-December * 1994, available at * http://ptgmedia.pearsoncmg.com/images/020163371x/supplements/Exception_Handling_Article.html * * Tom's code in turn was derived from David Reed, Exceptions: * Pragmatic issues with a new language feature", C++ Report, * October 1993, page 42. * */ #pragma once // Stack template class that throws exceptions on errors // bad_alloc thrown for out of memory // empty_stack_error thrown for attempting to pop an empty stack #include // ------------------------------------------------------------------ // Exception class class empty_stack_error { const std::string msg; public: empty_stack_error(std::string s) : msg(s) { } const std::string& what() const { return msg; } }; // ------------------------------------------------------------------ template class Stack { private: unsigned nelems; // allocation size unsigned size; // number of elements in stack T* v; // array of stack elements void grow(); // increases stack allocation public: unsigned getSize() const; void push(T); T pop(); Stack(); ~Stack(); Stack(const Stack&); Stack& operator=(const Stack&); }; // Default constructor template Stack::Stack() { size = 0; v = new T[nelems = 10]; } // Copy constructor template Stack::Stack(const Stack& s) { size = s.size; v = new T[nelems = s.nelems]; for (unsigned k = 0; k < size; k++) v[k] = s.v[k]; } // Destructor template Stack::~Stack() { delete[] v; } // Grow template void Stack::grow() { T* newBuffer = new T[nelems *= 2]; for (unsigned k = 0; k < size; k++) newBuffer[k] = v[k]; delete[] v; v = newBuffer; } // Push template void Stack::push(T element) { if (size == nelems) grow(); v[size++] = element; } // Pop stack template T Stack::pop() { if (size == 0) throw empty_stack_error("pop on empty stack"); return v[--size]; } // Size of stack template unsigned Stack::getSize() const { return size; } // Assignment template Stack& Stack::operator=(const Stack& s) { delete[] v; size = s.size; v = new T[nelems = s.nelems]; for (unsigned k = 0; k < size; k++) v[k] = s.v[k]; return *this; }