#ifndef STACK_H
#define STACK_H
#include <iostream>
template <class T>
class stack
{
friend std::ostream &operator<< <> ( std::ostream &os, stack s);
public:
// class Error { };
// class Empty : public Error { };
// class Full : public Error { };
stack( int size = 128);
stack( const stack &rhs);
~stack();
const stack& operator=( const stack &rhs);
void push( T d);
T pop();
bool is_empty() const;
bool is_full() const;
private:
int capacity;
int sp;
T *v;
void copy( const stack &other);
};
template <class T>
stack<T>::stack( int size)
{
v = new T[capacity = size];
sp = 0;
}
template <class T>
stack<T>::stack( const stack &other)
{
copy(other);
}
template <class T>
stack<T>::~stack()
{
delete [] v;
}
template <class T>
const stack<T>& stack<T>::operator=( const stack &other)
{
if ( this != &other )
{
delete [] v;
copy(other);
}
return *this;
}
template <class T>
void stack<T>::copy( const stack &other)
{
v = new T[capacity = other.capacity];
sp = other.sp;
for ( int i = 0 ; i < sp; ++i)
v[i] = other.v[i];
}
template <class T>
void stack<T>::push( T d) // throws (Full)
{
if ( ! is_full() )
v[sp++] = d;
// else
// throw Full();
}
template <class T>
T stack<T>::pop() // throws (Empty)
{
if ( ! is_empty() )
v[--sp];
else
return T();
// else
// throw Empty();
}
template <class T>
bool stack<T>::is_empty() const
{
return 0 == sp;
}
template <class T>
bool stack<T>::is_full() const
{
return capacity == sp;
}
template <class T>
std::ostream &operator<<( std::ostream &os, stack<T> ds)
{
os << "[ ";
for ( int i = 0; i < ds.sp-1; ++i )
os << ds.v[i] << ", ";
if ( ds.sp > 0 )
os << ds.v[ds.sp-1];
os << " ]";
return os;
}
#endif /* STACK_H */