#include <iostream> 
#include <cstdlib>

using namespace std;

#ifndef _STACK_H
#define _STACK_H

template <class T, int n>
class stack
{
private:
T * data;//use a dynamic array
int top;
int size;
int max;

public :

stack();
//constructor : creats an empty stack


stack(const stack & x);
// copy constructor

~stack();
//destructor

void push(const T & x);
// precondition : none
//postcondition : x is top item on the stack
//size of the stack it incremented

T pop();
//precondition : stack is not empty
//postcondition : top item is removed
//returns : top item

bool isempty() const;
//precondition : none
//postcondition : none
//Returns : true if no item are on the stack

int getsize() const;
//precondition : none
//postconditione : none
//Returns the number of items on the stack

T stacktop() const;
//precondition : stack is not empty
//postcondition : none
//returns top item on stack

};


template <class T, int n>
stack<T,n>::stack()
{
data = new T[n];
top = -1;
size = 0;
max = n;
}

template <class T, int n>
stack<T,n>::stack(const stack & x)
{

data = new T[x.max];
size = x.size;
top = x.top;
for(int i = 0; i < size; i++) 
data[i] = x.data[i];
}



template <class T, int n>
stack<T,n>::~stack()
{
delete [] data;
}

template <class T, int n>
void stack<T,n>::push(const T & x)
{
if (size == max)
{
cout<<"Stack overflow";
exit(1);
}
top++;
data[top] = x;
size++;
}

template <class T, int n>
T stack<T,n>::pop()
{
if (size == 0)
{
cout<<"Error : stack underflow ";
exit(1);
}
T x = data[top];
top--;
size--;
return x;
}

template <class T, int n>
bool stack<T,n>::isempty() const
{
return size == 0;
}

template <class T, int n>
int stack<T,n>::getsize() const
{
return size;
}

template <class T, int n>
T stack<T,n>::stacktop() const
{
if (size == 0)
{
cout<<"Error : stack underflow ";
exit(1);
}
return data[top];
}


#endif