#include <iostream>
using namespace std;
#ifndef STACK_H
#define STACK_H
#include <cassert> // для assert
#include <iostream>
#include <stdio.h>
#include <iomanip> // для setw
template <typename T>
class Stack
{
private:
T *stackPtr; // указатель на стек
int size; // максимальное количество элементов в стеке
int top; // номер текущего элемента стека
public:
Stack(int = 10); // по умолчанию размер стека равен 10 элементам
Stack( Stack<T> &); // конструктор копирования
~Stack(); // деструктор
// поместить элемент в вершину стека
// Stack<T> operator=(Stack<T>& a);
inline void push( int & value);
inline void push(Stack<int> &value);
inline T pop(); // удалить элемент из вершины стека и вернуть его
inline void printStack(); // вывод стека на экран
inline T &Peek(int ) ; // n-й элемент от вершины стека
inline int getStackSize() ; // получить размер стека
inline T *getPtr() ; // получить указатель на стек
inline int& getTop() ; // получить номер текущего элемента в стеке
};
// реализация методов шаблона класса STack
// конструктор Стека
template <typename T>
Stack<T>::Stack(int maxSize) :
size(maxSize) // инициализация константы
{
stackPtr = new T[size]; // выделить память под стек
printf("consctructor(int) %p\n",(void*)stackPtr );
top = 0; // инициализируем текущий элемент нулем;
}
// конструктор копирования
template <typename T>
Stack<T>::Stack( Stack<T> & otherStack) :
size(otherStack.getStackSize()) // инициализация константы
{
stackPtr = new T[size]; // выделить память под новый стек
printf("consctructor(stack) %p\n",(void*)stackPtr );
top = otherStack.getTop();
for(int ix = 0; ix < top; ix++)
stackPtr[ix] = otherStack.getPtr()[ix];
}
// функция деструктора Стека
template <typename T>
Stack<T>::~Stack()
{
printf("desctructor %p\n",(void*)stackPtr );
delete [] stackPtr; // удаляем стек
}
// функция добавления элемента в стек
/*
template <typename T>
Stack<T> Stack<T>::operator=(Stack<T>& a)
{
*this(a);
return *this;
}
*/
template <typename T>
inline void Stack<T>::push( int & value)
{
// проверяем размер стека
assert(top < size); // номер текущего элемента должен быть меньше размера стека
stackPtr[top++]=value;
// catch(Stack<int> T)
//{top++;
// stackPtr[top](value);
//stackPtr[top] value; // помещаем элемент в стек
// }
}
template <typename T>
inline void Stack<T>::push(Stack<int>& value)
{
assert(top < size);
//stackPtr[top++](value);
top++;
stackPtr[top].getTop()=value.getTop();
for(int ix = 0; ix < stackPtr[top].getTop(); ix++)
stackPtr[top].getPtr()[ix] = value.getPtr()[ix];
}
/*
template <typename T>
inline void Stack<T>::push( int & value)
{
// проверяем размер стека
assert(top < size); // номер текущего элемента должен быть меньше размера стека
stackPtr[top++]=value; // помещаем элемент в стек
}
*/
// функция удаления элемента из стека
template <typename T>
inline T Stack<T>::pop()
{
// проверяем размер стека
assert(top > 0); // номер текущего элемента должен быть больше 0
delete stackPtr[--top]; // удаляем элемент из стека
}
// функция возвращает n-й элемент от вершины стека
template <class T>
inline T &Stack<T>::Peek(int nom)
{
assert(nom <= top);
return stackPtr[top - nom]; // вернуть n-й элемент стека
}
// вывод стека на экран
template <typename T>
inline void Stack<T>::printStack()
{
for (int ix = top - 1; ix >= 0; ix--)
printf(" %d \n",stackPtr[ix]);//cout << "|" << setw(4) << stackPtr[ix] << endl;
}
// вернуть размер стека
template <typename T>
inline int Stack<T>::getStackSize()
{
return size;
}
// вернуть указатель на стек (для конструктора копирования)
template <typename T>
inline T *Stack<T>::getPtr()
{
return stackPtr;
}
// вернуть размер стека
template <typename T>
inline int& Stack<T>::getTop()
{
return top;
}
#endif // STACK_H
int main()
{
int ch, ct = 0;
Stack<int> a(10), b(10),c(10);
Stack<Stack<int> > d(4);
while (ct++ < 10)
{
cin >> ch;
a.push(ch);
ch++; // помещаем элементы в стек
b.push(ch);
ch++;
c.push(ch);
}
//printf("%d ", ct);
d.push(a);
//printf("%d ", ct);
d.push(b);
d.push(c);
d.Peek(2).printStack();
d.Peek(1).printStack();
d.Peek(0).printStack();
//d.~Stack();
// printf("%d ", ct);
return 0;
}