// Section 2.2:

#include "utility.h"
#include <cstdlib>
const int maxstack = 10;   //  small value for testing


typedef double Stack_entry;

template< class T >
class Stack {
public:
   Stack();
   bool empty() const;
   Error_code pop();
   Error_code top(T &item ) const;
   Error_code push(const T &item);
   void clear(); //  Reset the stack to be empty.
   bool full() const ; //  If the stack is full, return true; else return false.
   int size() const;   //  Return the number of entries in the stack.


private:
   int count;
   T entry[maxstack];
};

template< class T >
Error_code Stack<T>::push(const T &item)
/*
Pre:  None.
Post: If the Stack is not full, item is added to the top
      of the Stack.  If the Stack is full,
      an Error_code of overflow is returned and the Stack is left unchanged.
*/

{
   Error_code outcome = success;
   if (count >= maxstack)
      outcome = overflow;
   else
      entry[count++] = item;
   return outcome;
}

template< class T >
Error_code Stack<T>::pop()
/*
Pre:  None.
Post: If the Stack is not empty, the top of
      the Stack is removed.  If the Stack
      is empty, an Error_code of underflow is returned.
*/

{
   Error_code outcome = success;
   if (count == 0)
      outcome = underflow;
   else --count;
   return outcome;
}

template< class T >
Error_code Stack<T>::top(T &item) const
/*
Pre:  None.
Post: If the Stack is not empty, the top of
      the Stack is returned in item.  If the Stack
      is empty an Error_code of underflow is returned.
*/

{
   Error_code outcome = success;
   if (count == 0)
      outcome = underflow;
   else
      item = entry[count - 1];
   return outcome;
}

template< class T >
bool Stack<T>::empty() const
/*
Pre:  None.
Post: If the Stack is empty, true is returned.
      Otherwise false is returned.
*/

{
   bool outcome = true;
   if (count > 0) outcome = false;
   return outcome;
}

template< class T >
void Stack<T>::clear()
/*
Pre:  None.
Post: If the Stack is empty, true is returned.
      Otherwise false is returned.
*/

{
   count = 0;
   for(int i = 0; i < maxstack; i++)
	   entry[i] = NULL;
}


template< class T >
bool Stack<T>::full() const
/*
Pre:  None.
Post: Return true if the stack is full, false otherwise

*/

{
   return count;  
}

template< class T >
int Stack<T>::size() const
/*
Pre:  None.
Post: If the Stack is empty, true is returned.
      Otherwise false is returned.
*/

{
   return (count == maxstack);
	  
}
template< class T >
Stack<T>::Stack()
/*
Pre:  None.
Post: The stack is initialized to be empty.
*/
{
   count = 0;
}


class Extended_stack {
public:
   Extended_stack();
   Error_code pop();
   Error_code push(Stack_entry item);
   Error_code top(Stack_entry &item) const;
   bool empty() const;
   void clear(); //  Reset the stack to be empty.
   bool full() const ; //  If the stack is full, return true; else return false.
   int size() const;   //  Return the number of entries in the stack.

private:
   int count;
   Stack_entry entry[maxstack];
};

