/*********************************************************************
 * This file is part of the cpplibs suite.
 *
 * Copyright (C) 2001 Topi Mäenpää
 * All rights reserved.
 *
 * This program is free software. You can redistribute and/or modify
 * it under the terms of the free software licence found in the
 * accompanying file "COPYING". The licence terms must always be
 * redistributed with this source file. The above copyright notice
 * must be reproduced in all modified and unmodified copies of this
 * source file.
 *
 * $Revision: 1.2 $
 *********************************************************************/

#ifndef _STACK_H
#define _STACK_H

namespace util
{
	/**
	 * Stack is a data structure that is accessed from one end. Items
	 * are "pushed" on the top of the stack and "popped" out of it. In
	 * other words, stack is a FILO (first-in-last-out) buffer.
	 **/
	template <class T> class Stack : public List<T>
	{
	public:
		/**
		 * Create a stack with the given initial capacity and block size.
		 **/
		Stack(int capacity=16, int blockSize=16) : List<T>(capacity,blockSize) {}
		/**
		 * Create a copy of any list as a stack.
		 **/
		Stack(const List<T>& other) : List<T>(other) {}

		/**
		 * Copy any list to a stack.
		 **/
		Stack& operator= (const List<T>& other) { List<T>::operator=(other); return *this; }

		/**
		 * Push an element on the top of the stack.
		 **/
		void push(T element) { addElement(element); }
		/**
		 * Pop the element on the top of the stack. The stack will shrink
		 * by one element, thus there must be at least one element in the
		 * stack before calling this method.
		 **/
		T pop() { return _internalArray[-1+_iCurrentItems--]; }
		/**
		 * See what's on the top of the stack without popping an element.
		 *
		 * @return the most recently added element
		 **/
		T& peek() { return _internalArray[_iCurrentItems-1]; }
		/**
		 * See what's on the top of the stack without popping an element.
		 * Const version.
		 *
		 * @return the most recently added element
		 **/
		const T& peek() const { return _internalArray[_iCurrentItems-1]; }
	};
}

#endif
