www.pudn.com > RCApp-src.zip > List.h


/* 
	RedEye Project (http://members.ozemail.com.au/~ndmcevoy/) 
	Copyright (C) 2003  Nick McEvoy 
 
	This library is free software; you can redistribute it and/or 
	modify it under the terms of the GNU Library General Public 
	License as published by the Free Software Foundation; either 
	version 2 of the License, or (at your option) any later version. 
 
	This library is distributed in the hope that it will be useful, 
	but WITHOUT ANY WARRANTY; without even the implied warranty of 
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
	Library General Public License for more details. 
 
	You should have received a copy of the GNU Library General Public 
	License along with this library; if not, write to the Free 
	Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
 
	----------------------------------------------------------------- 
 
		Commented for use with Doxygen (http://www.doxygen.org) 
 
	----------------------------------------------------------------- 
*/ 
 
/*! \file List.h 
 *	\brief Template class for a doubly linked list. 
 * 
 *		This file contains a template class for a doubly linked list. 
 */ 
 
#ifndef _RE_LIST_H_
#define _RE_LIST_H_
 
// System includes 
#include  
 
//! Used for abstract iteration position. 
struct __LISTPOSITION { }; 
//! Abstract iteration position. 
typedef __LISTPOSITION* LISTPOSITION; 
 
// Forward declare reList. 
template  
class reList; 
 
//!	A list node used to store pointers to a  object. 
/*! 
 *		reListNode is a list node used to store pointers to a  object, 
 *		and to the next and previous reListNode structs in the list. 
 */ 
template  
struct reListNode 
{ 
private: 
	//! The node element. 
	Type* mpItem; 
 
	//! The next node. 
	reListNode* mpNext; 
 
	//! The previous node. 
	reListNode* mpPrevious; 
 
	friend class reList; 
}; 
 
//!	A template class for a doubly linked list. 
/*! 
 *		reList is a template of a doubly linked list. 
 *		The list stores * pointers. 
 */ 
template  
class reList   
{ 
public: 
	//! Constructor. 
	/*! 
	 *		The constructor initialises data. 
	 * 
	 *	\param bDeleteOn - if true added items will be deleted on removal. 
	 */ 
	reList(bool bDeleteOn = true) 
		{ 
			mpFirst = NULL; 
			mpLast = NULL; 
			miCount = 0; 
			mbDeleteItems = bDeleteOn; 
		}; 
 
	//! Destructor. 
	/*! 
	 *		The destructor cleans up. 
	 */ 
	virtual ~reList(void) 
		{RemoveAll();}; 
 
	//! Add an element to the head of the list. 
	/*! 
	 *	\param pData - a pointer to the element to be added. 
	 *	\return none. 
	 */ 
	void 
	AddHead(Type* pData); 
 
	//! Add an element to the tail of the list. 
	/*! 
	 *	\param pData - a pointer to the element to be added. 
	 *	\return none. 
	 */ 
	void 
	AddTail(Type* pData); 
 
	//! Removes an element from the list. 
	/*! 
	 *		Find an element by pointer reference and remove it from the list. 
	 * 
	 *	\param pData - a pointer to the element to be removed. 
	 *	\return none. 
	 */ 
	void 
	Remove(Type* pData); 
 
	//! Removes an element from the list. 
	/*! 
	 *		Removes an element from the list, specified by Pos, 
	 *		then sets Pos to the LISTPOSITION value of the next 
	 *		entry in the list. 
	 * 
	 *	\param Pos - a list position of the element to be removed. 
	 *	\return none. 
	 */ 
	void 
	RemoveAt(LISTPOSITION& Pos); 
 
	//! Removes an element from the head of the list. 
	/*! 
	 *	\param none. 
	 *	\return none. 
	 */ 
	void 
	RemoveHead(); 
 
	//! Removes an element from the tail of the list. 
	/*! 
	 *	\param none. 
	 *	\return none. 
	 */ 
	void 
	RemoveTail(); 
 
	//! Removes all the elements from the list. 
	/*! 
	 *	\param none. 
	 *	\return none. 
	 */ 
	void 
	RemoveAll(); 
 
	//! Returns the head element of the list (can be null). 
	/*! 
	 *	\param none. 
	 *	\return a pointer to the head element of the list (can be null). 
	 */ 
	Type* 
	GetHead() const; 
 
	//! Returns the tail element of the list (can be null). 
	/*! 
	 *	\param none. 
	 *	\return a pointer to the tail element of the list (can be null). 
	 */ 
	Type* 
	GetTail() const; 
 
	//! Returns the position of the head element of the list. 
	/*! 
	 *	\param none. 
	 *	\return a list position of the head element. 
	 */ 
	const LISTPOSITION 
	GetHeadPosition() const; 
 
	//! Returns the position of the tail element of the list. 
	/*! 
	 *	\param none. 
	 *	\return a list position of the tail element. 
	 */ 
	const LISTPOSITION 
	GetTailPosition() const; 
 
	//! Gets the list element identified by Pos, then Pos is set to next element. 
	/*! 
	 *		Gets the list element identified by Pos, then sets Pos 
	 *		to the LISTPOSITION value of the next entry in the list. 
	 *		You can use GetNext() in a forward iteration loop if you 
	 *		establish the initial position with a call to GetHeadPosition(). 
	 * 
	 *	\param Pos - a list position of element to get, Pos is then set to 
	 *	             the next entry in the list. 
	 *	\return a pointer to the list element. 
	 */ 
	Type* 
	GetNext(LISTPOSITION& Pos) const; 
 
	//! Gets the list element identified by Pos, then Pos is set to previous element. 
	/*! 
	 *		Gets the list element identified by Pos, then sets Pos 
	 *		to the LISTPOSITION value of the previous entry in the list. 
	 *		You can use GetPrev() in a reverse iteration loop if you 
	 *		establish the initial position with a call to GetTailPosition(). 
	 * 
	 *	\param Pos - a list position of element to get, Pos is then set to 
	 *	             the previous entry in the list. 
	 *	\return a pointer to the list element. 
	 */ 
	Type* 
	GetPrev(LISTPOSITION& Pos) const; 
 
	//! Gets the list element identified by Pos. 
	/*! 
	 *	\param Pos - a list position of element to get. 
	 *	\return a pointer to the list element. 
	 */ 
	Type* 
	GetAt(LISTPOSITION& Pos) const; 
 
	//! Returns the number of elements in the list. 
	/*! 
	 *	\param none. 
	 *	\return the number of elements in the list. 
	 */ 
	int 
	GetCount() const 
		{return miCount;}; 
 
	//! Return if the list is empty or not. 
	/*! 
	 *	\param none. 
	 *	\return TRUE if the list is empty, otherwise FALSE. 
	 */ 
	bool 
	IsEmpty() const; 
 
private: 
	//! Copy constructor. 
	/*! 
	 *		The copy constructor is disallowed (ie. private). 
	 */ 
	reList(const reList &); 
 
	//! Assignment operator. 
	/*! 
	 *		The assignment operator is disallowed (ie. private). 
	 */ 
	reList& operator=(const reList &); 
 
	//! The first node in the list. 
	reListNode* mpFirst; 
 
	//! The last node in the list. 
	reListNode* mpLast; 
 
	//! The number of elements in the list. 
	int miCount; 
 
	//! A flag to indicate if items added to the list should be deleted. 
	bool mbDeleteItems; 
}; 
 
 
 
 
template  
void reList::AddHead(Type* pData) 
{ 
	reListNode* pNewNode = new reListNode; 
 
	if (!mpFirst) // First and only item in the list. 
	{ 
		pNewNode->mpNext     = NULL; 
		pNewNode->mpPrevious = NULL; 
 
		mpFirst = pNewNode; 
		mpLast  = pNewNode; 
	} 
	else 
	{ 
		pNewNode->mpPrevious = NULL; 
		pNewNode->mpNext = mpFirst; 
 
		mpFirst->mpPrevious = pNewNode; 
		mpFirst = pNewNode; 
	} 
 
	miCount++; 
 
	pNewNode->mpItem = pData; 
} 
 
 
 
 
template  
void reList::AddTail(Type* pData) 
{ 
	reListNode* pNewNode = new reListNode; 
 
	if (!mpFirst) // First and only item in the list. 
	{ 
		pNewNode->mpNext     = NULL; 
		pNewNode->mpPrevious = NULL; 
 
		mpFirst = pNewNode; 
		mpLast  = pNewNode; 
	} 
	else 
	{ 
		pNewNode->mpPrevious = mpLast; 
		pNewNode->mpNext = NULL; 
 
		mpLast->mpNext = pNewNode; 
		mpLast = pNewNode; 
	} 
 
	miCount++; 
 
	pNewNode->mpItem = pData; 
} 
 
 
 
 
template  
void reList::Remove(Type* pData) 
{ 
	reListNode* pNode = mpFirst; 
	while (pNode) 
	{ 
		if (pData == pNode->mpItem) 
		{ 
			if (mbDeleteItems) 
				delete pNode->mpItem; 
			pNode->mpItem = NULL; 
 
			delete pNode; 
			pNode = NULL; 
 
			miCount--; 
			break; 
		} 
 
		pNode = pNode->mpNext; 
	} 
} 
 
 
 
 
template  
void reList::RemoveAt(LISTPOSITION& Pos) 
{ 
	reListNode* pDeleteNode = (reListNode*)Pos; 
 
	if (pDeleteNode) 
	{ 
		Pos = (LISTPOSITION)pDeleteNode->mpNext; 
 
		if (pDeleteNode == mpFirst) 
			RemoveHead(); 
		else if (pDeleteNode == mpLast) 
			RemoveTail(); 
		else 
		{ 
			if (pDeleteNode->mpPrevious) 
				pDeleteNode->mpPrevious->mpNext = pDeleteNode->mpNext; 
 
			if (pDeleteNode->mpNext) 
				pDeleteNode->mpNext->mpPrevious = pDeleteNode->mpPrevious; 
 
			if (pDeleteNode->mpItem) 
			{ 
				if (mbDeleteItems) 
					delete pDeleteNode->mpItem; 
				pDeleteNode->mpItem = NULL; 
			} 
 
			delete pDeleteNode; 
			pDeleteNode = NULL; 
 
			miCount--; 
		} 
	} 
} 
 
 
 
 
template  
void reList::RemoveHead() 
{ 
	reListNode* pDeleteNode = mpFirst; 
 
	if (pDeleteNode) 
	{ 
		mpFirst = mpFirst->mpNext; 
 
		if (mpFirst) 
			mpFirst->mpPrevious = NULL; 
 
		if (pDeleteNode->mpItem) 
		{ 
			if (mbDeleteItems) 
				delete pDeleteNode->mpItem; 
			pDeleteNode->mpItem = NULL; 
		} 
 
		delete pDeleteNode; 
		pDeleteNode = NULL; 
 
		miCount--; 
	} 
} 
 
 
 
 
template  
void reList::RemoveTail() 
{ 
	reListNode* pDeleteNode = mpLast; 
 
	if (pDeleteNode) 
	{ 
		mpLast = mpLast->mpPrevious; 
 
		if (mpLast) 
			mpLast->mpNext = NULL; 
 
		if (pDeleteNode->mpItem) 
		{ 
			if (mbDeleteItems) 
				delete pDeleteNode->mpItem; 
			pDeleteNode->mpItem = NULL; 
		} 
 
		delete pDeleteNode; 
		pDeleteNode = NULL; 
 
		miCount--; 
	} 
} 
 
 
 
 
template  
void reList::RemoveAll() 
{ 
	while (mpFirst) 
		RemoveHead(); 
} 
 
 
 
 
template  
Type* reList::GetHead() const 
{ 
	if (mpFirst) 
		return mpFirst->mpItem; 
	else 
		return NULL; 
} 
 
 
 
 
template  
Type* reList::GetTail() const 
{ 
	if (mpLast) 
		return mpLast->mpItem; 
	else 
		return NULL; 
} 
 
 
 
 
template  
const LISTPOSITION reList::GetHeadPosition() const 
{ 
	return (LISTPOSITION)mpFirst; 
} 
 
 
 
 
template  
const LISTPOSITION reList::GetTailPosition() const 
{ 
	return (LISTPOSITION)mpLast; 
} 
 
 
 
 
template  
Type* reList::GetNext(LISTPOSITION& Pos) const 
{ 
	reListNode* pNode = (reListNode*)Pos; 
 
	if (!pNode) 
		return NULL; 
 
	Pos = (LISTPOSITION)pNode->mpNext; 
 
	return pNode->mpItem; 
} 
 
 
 
 
template  
Type* reList::GetPrev(LISTPOSITION& Pos) const 
{ 
	reListNode* pNode = (reListNode*)Pos; 
 
	if (!pNode) 
		return NULL; 
 
	Pos = (LISTPOSITION)pNode->mpPrevious; 
 
	return pNode->mpItem; 
} 
 
 
 
 
template  
Type* reList::GetAt(LISTPOSITION& Pos) const 
{ 
	reListNode* pNode = (reListNode*)Pos; 
 
	if (!pNode) 
		return NULL; 
 
	return pNode->mpItem; 
} 
 
 
 
 
template  
bool reList::IsEmpty() const 
{ 
	if (mpFirst) 
		return false; 
	else 
		return true; 
}

#endif // _RE_LIST_H_