///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
 *	Contains simple stacks.
 *	\file		IceStack.h
 *	\author		Pierre Terdiman
 *	\date		February, 5, 2000
 */
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Include Guard
#ifndef __ICESTACK_H__
#define __ICESTACK_H__

	class ICECORE_API LIFOStack : public Container
	{
		public:
		// Constructor/Destructor
										LIFOStack()		{}
										~LIFOStack()	{}
		// Management
		__forceinline	LIFOStack&		Push(udword entry)			{	Add(entry);	return *this;	}
						bool			Pop(udword &entry);
	};

	class ICECORE_API FIFOStack : public Container
	{
		public:
		// Constructor/Destructor
										FIFOStack() : mCurIndex(0)		{}
										~FIFOStack()					{}
		// Management
		__forceinline	FIFOStack&		Push(udword entry)			{	Add(entry);	return *this;	}
						bool			Pop(udword &entry);
		private:
						udword			mCurIndex;			//!< Current index within the container
	};

	// Use that one instead of an array of bools. Takes less ram, nearly as fast [no bounds checkings and so on].
	#define BITSTOBYTES(x)				((udword(x)>>3)+ ((x&7) ? 1 : 0))

	static ubyte BitMasks[]		= { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
	static ubyte NegBitMasks[]	= { 0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F };

	class ICECORE_API ArrayOfBits
	{
		public:
		// Constructor / Destructor
										ArrayOfBits(udword n)		{ mBits = new ubyte[BITSTOBYTES(n)];						}			// Get ram for n bits
										~ArrayOfBits()				{ DELETEARRAY(mBits);										}			// Free used ram

		// Data management
		__forceinline	void			SetBit(udword bitnumber)	{ mBits[bitnumber>>3] |= BitMasks[bitnumber&7];				}			// Set bit bitnumber to 1
		__forceinline	void			ClearBit(udword bitnumber)	{ mBits[bitnumber>>3] &= NegBitMasks[bitnumber&7];			}			// Set bit bitnumber to 0

		// Data access
		__forceinline	bool			IsSet(udword bitnumber)		{ return (mBits[bitnumber>>3]&BitMasks[bitnumber&7])!=0;	}			// Returns true if bit bitnumber is 1

						ubyte*			mBits;																								// Array of bits
	};

#endif // __ICESTACK_H__
