#pragma once
#include "m3derror.h"
#include <stdlib.h>
namespace M3D
{

/**
 * Реализует стек с фиксированной глубиной. Память выделяется на этапе создания объекта.
 * Объект должен поддерживать оператор "="
 * Доступ к элементу стека O(1)
 * @author Denis A. Biryukov
 */

template <class T> class fixed_stack
{
	public:
		fixed_stack(int size)
		{
			_object_ = new T[size]();
			_top_ = 0;
			_size_ = size;
		}
		~fixed_stack()
		{
			delete[] _object_;
		};
		
		/**
		 * Помещает объект на верх стека.
		 * @param obj помещаемый объект
		 * @author Denis A. Biryukov
		 */
		void push(const T &obj)
		{
			if ( _object_ + _size_ <= _top_ + 1) THROW("Stack overflow");
			if (!_top_)
			{
				_top_ = _object_;
				*_top_ = obj;
			}
			else
			{
				*(++_top_) = obj;
			}
		}
		/**
		 * Получает объект с верхушки стека. После данной операции получить объект еще раз невозможно
		 * @return объект с верхушки стека
		 * @author Denis A. Biryukov\
		 */
		T& pop()
		{
			if (!_top_)THROW("Stack underflow");
			T *tmp = _top_--;
			if (_top_ < _object_) _top_ = 0;
			return *tmp;
		}
	private:
		T *_object_;
		T *_top_;
		int _size_;
};

}

