// ==============================
// excdemo.cpp
//
// C++ exception demo
//
// Created with: Borland C++ 4.52
// ==============================

#include <iostream.h>

class Stack
{
   int size, top, *values;

   class Parent
   {
      int index, value;

      public:

      Parent (int index, int value)
      {
              this->index = index;
              this->value = value;
      }

      int getIndex ()
      {
              return index;
      }

      int getValue ()
      {
              return value;
      }
   };

   public:

   class Empty : public Parent
   {
      public:

      Empty (int index) : Parent (index, 0)
      {
      }
   };

   class Full : public Parent
   {
      public:

      Full (int index, int value) : Parent (index, value)
      {
      }
   };

   Stack (int size)
   {
      this->size = size;        // Maximum number of integer values in stack.
      top = -1;                 // Stack defaults to empty.
      values = new int [size];  // Create stack to hold size integer values.
   }

   ~Stack ()
   {
      delete [] values;         // Destroy constructor-created integer array.
   }

   int isEmpty ()
   {
      return (top == -1) ? 1 : 0;
   }

   void push (int value)
   {
      if (top >= size-1)        // When top equals size-1, the stack is full.
              throw Full (top, value); // When full, throw Stack::Full exception.

      values [++top] = value;
   }

   int pop ()
   {
      if (top < 0)              // When top less than 0, the stack is empty.
               throw Empty (top);    // When empty, throw Stack::Empty exception.

      return values [top--];
   }
};

void main ()
{
   Stack s (5); // Create a stack that holds 5 integer values (maximum).

   cout << "Stack object created. Stack holds a maximum of 5 integer values.\n";

   int values [6] = { 52, -32, 468, 345, 42, 91 };

   try
   {
       // Attempt to push 6 integer values onto the stack. The last push attempt
       // results in a Stack::Full exception.

       for (int i = 0; i < 6; i++)
       {
                cout << "Attempting to push integer value " << values [i] << ".\n";
                s.push (values [i]);
       }
   }
   catch (Stack::Full f)
   {
       cout << "Stack is full. Could not push integer value " << f.getValue ()
                 << ". Top index equals " << f.getIndex () << ".\n";
   }

   try
   {
       // Attempt to pop 6 values from the stack. The last pop attempt results
       // in a Stack::Empty exception.

       for (int i = 0; i < 6; i++)
                cout << "Popping integer value " << s.pop () << ".\n";
   }
   catch (Stack::Empty e)
   {
       cout << "Stack is empty. Could not pop integer value. Top index equals "
                 << e.getIndex () << ".\n";
   }
}