home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 1999 September
/
CHIPCD_9_99.iso
/
software
/
uaktualnienia
/
OptionPackPL
/
msmqocm.cab
/
utlist.h
< prev
next >
Wrap
C/C++ Source or Header
|
1998-04-07
|
65KB
|
2,109 lines
#ifndef __UTLIST_H__
#define __UTLIST_H__
/******************************************************************************
Microsoft D.T.C. (Distributed Transaction Coordinator)
Copyright 1995 Microsoft Corporation. All Rights Reserved.
@doc
@module UTList.h |
Contains list ADT.
@devnote None
-------------------------------------------------------------------------------
@rev 1 | 12th Apr,95 | GaganC | Added StaticList & StaticListIterator
@rev 0 | 24th Jan,95 | GaganC | Created
*******************************************************************************/
typedef enum {
EXCEPT_MEMORY=0,
EXCEPT_UNKNOWN,
EXCEPT_LOCKFAILED,
EXCEPT_TROUBLE
} EXCEPT;
//---------- Forward Declarations -------------------------------------------
template <class T> class UTLink;
template <class T> class UTList;
template <class T> class UTListIterator;
template <class T> class UTStaticList;
template <class T> class UTStaticListIterator;
//-----**************************************************************-----
// @class template class
// The UTIterator is an ABSTRACT BASE CLASS for ALL iterators. This
// class defines the basic operation that all iterators must support
// regardless of what type of collection it operates upon.
//
//-----**************************************************************-----
template <class T> class UTIterator
{
// @access Public members
public:
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// initialize iterator
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @cmember Initializes the iterator to the first position
virtual BOOL Init (void) =0;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// operators
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @cmember Retrieves the current element (pointed to by iterator)
virtual T operator() (void) const =0;
// @cmember Checks to see if iterator is in a valid position
virtual BOOL operator ! (void) const =0;
// @cmember Moves the iterator forward
virtual BOOL operator ++ (int dummy) =0;
// @cmember Assigns the current element a new value
virtual void operator = (T newValue) =0;
};
//-----**************************************************************-----
// @class Template class
// The UTLink class is the backbone of a linked list. It holds the
// actual data of type T (which is the list's data type) and points
// to the next and previous elements in the list.
// The class is entirely private to hide all functions and data from
// everyone but it's friends - which are the UTList and UTListIterator.
//
// @tcarg class | T | data type to store in the link
//-----**************************************************************-----
template <class T> class UTLink
{
// @access Public members
public:
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// constructors/destructor
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @cmember Constructor
UTLink (void);
// @cmember Constructor
UTLink (const T& LinkValue,UTLink< T > * Prev = NULL,UTLink< T > * Next = NULL);
// @cmember Copy Constructor
UTLink (const UTLink< T >& CopyLink);
// @cmember Destructor
virtual ~UTLink (void);
void Init (const T& LinkValue,UTLink< T > * Prev = NULL,UTLink< T > * Next = NULL);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// operators
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @cmember Assignment operator
virtual UTLink< T >& operator = (const UTLink< T >& AssignLink);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// action protocol
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @cmember Adds a new element before this object
UTLink< T > * AddBefore (const T& newValue);
// @cmember Adds a new element after this object
UTLink< T > * AddAfter (const T& newValue);
// @cmember Remove this link from the specified list
void RemoveFromList (UTStaticList < T > * pStaticList);
public:
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// friends
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
friend class UTList< T >;
friend class UTStaticList < T >;
friend class UTListIterator< T >;
friend class UTStaticListIterator <T>;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// data members
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @cmember Value held in the link of type T
T m_Value;
// @cmember Pointer to next link (in list)
UTLink< T > * m_pNextLink;
// @cmember Pointer to previous link (in list)
UTLink< T > * m_pPrevLink;
};
//-----**************************************************************-----
// @class Template class
// The UTList class consists of a pointer to the first and last
// links along with a count of the number of elements in the list.
// The Add method simply appends to the end of the list.
// To add elements to a specific location in the list other than
// the first or last positions, use the UTListIterator methods.
// To create an ordered list, a user could inherit from the UTList
// class and override Add to add elements in the correct order.
// Of course, you would want to do something about the other
// methods of adding members to the list.
//
// @tcarg class | T | data type to store in the list
//-----**************************************************************-----
template <class T> class UTList
{
// @access Public members
public:
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// constructors/destructor
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @cmember Consructor
UTList (void);
// @cmember Copy Constructor
UTList (const UTList< T >& CopyList);
// @cmember Destructor
virtual ~UTList (void);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// operators
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @cmember Assignment operator
virtual UTList< T >& operator = (const UTList< T >& AssignList);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// action protocol
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @cmember Add new value to the list
virtual void Add (const T& newValue);
// @cmember Insert new value at the front of the list
virtual void InsertFirst (const T& newValue);
// @cmember Insert new value at the end of the list
virtual void InsertLast (const T& newValue);
// @cmember Remove all elements from the list
virtual void RemoveAll (void);
// @cmember Remove first element from the list
virtual BOOL RemoveFirst (T* pType);
// @cmember Remove last element from the list
virtual BOOL RemoveLast (T* pType);
// @cmember Duplicate contents of entire list
virtual UTList< T > * Duplicate (void);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// state protocol
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @cmember Retrieve the first value via the out parameter
virtual BOOL FirstElement(T* pType) const;
// @cmember Retrieve the last value via the out parameter
virtual BOOL LastElement (T* pType) const;
// @cmember Does the list include this value?
virtual BOOL Includes (const T& value);
// @cmember Is the list empty?
virtual BOOL IsEmpty (void) const;
// @cmember Return the count of elements in the list
virtual ULONG GetCount (void) const;
virtual void Init (void);
// @access Protected members
protected:
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// friends
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
friend class UTListIterator< T >;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// data members
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @cmember Count of elements in the list
ULONG m_ulCount;
// @cmember Pointer to the first link in the list
UTLink< T > * m_pFirstLink;
// @cmember Pointer to the last link in the list
UTLink< T > * m_pLastLink;
};
//-----**************************************************************-----
// @class Template class
// The UTStaticList class. This is similar to the UTList class except
// that it in this the links are all static. Links are provided, to
// the various methods, they are never created or destroyed as they
// have been preallocated.
//
// @tcarg class | T | data type to store in the list
//-----**************************************************************-----
template <class T> class UTStaticList
{
// @access Public members
public:
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// constructors/destructor
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @cmember Consructor
UTStaticList (void);
// @cmember Copy Constructor
// UTStaticList (const UTStaticList< T >& CopyList);
// @cmember Destructor
virtual ~UTStaticList (void);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// operators
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @cmember Assignment operator
// virtual UTStaticList< T >& operator = (const UTStaticList< T >& AssignList);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// action protocol
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @cmember Add new link to the list
virtual void Add (UTLink <T> * pLink);
// @cmember Insert new link at the front of the list
virtual void InsertFirst (UTLink <T> * pLink);
// @cmember Insert new link at the end of the list
virtual void InsertLast (UTLink <T> * pLink);
// @cmember Remove all elements from the list
virtual void RemoveAll (void);
// @cmember Remove first element from the list
virtual BOOL RemoveFirst (UTLink <T> ** ppLink);
// @cmember Remove last element from the list
virtual BOOL RemoveLast (UTLink <T> ** ppLink);
// @cmember Duplicate contents of entire list
// virtual UTStaticList< T > * Duplicate (void);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// state protocol
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @cmember Retrieve the first link via the out parameter
virtual BOOL FirstElement(UTLink <T> ** ppLink);
// @cmember Retrieve the last link via the out parameter
virtual BOOL LastElement (UTLink <T> ** ppLink);
// @cmember Does the list include this value?
// virtual BOOL Includes (const UTLink <T> * pLink);
// @cmember Is the list empty?
virtual BOOL IsEmpty (void) const;
// @cmember Return the count of elements in the list
virtual ULONG GetCount (void) const;
virtual void Init (void);
// @access Protected members
public:
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// friends
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
friend class UTStaticListIterator <T>;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// data members
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @cmember Count of elements in the list
ULONG m_ulCount;
// @cmember Pointer to the first link in the list
UTLink< T > * m_pFirstLink;
// @cmember Pointer to the last link in the list
UTLink< T > * m_pLastLink;
}; //End class UTStaticList
//-----**************************************************************-----
// @class Template class
// The UTListIterator class implements the operations that an
// iterator must support and includes some additional operations
// that are useful in the context of a linked list.
// Use AddBefore & AddAfter to add elements to a list based on the
// iterator's current position within the list.
//
// @tcarg class | T | data type stored in list and type for iterator
// @base public | UTIterator
//-----**************************************************************-----
template <class T> class UTListIterator : public UTIterator< T >
{
// @access Public members
public:
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// constructors/destructor
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @cmember Constructor
UTListIterator (UTList< T >& List);
// @cmember Copy constructor
UTListIterator (const UTListIterator< T >& CopyListItr);
// @cmember Destructor
virtual ~UTListIterator(void);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// iterator protocol
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @cmember Initialize the iterator to the first link in list
virtual BOOL Init (void);
// @cmember Retrieve the value from the current link
virtual T operator () (void) const;
// @cmember Does the iterator point to a valid link
virtual BOOL operator ! (void) const;
// @cmember Move the iterator to the next link
virtual BOOL operator ++ (int dummy);
// @cmember Assign the current link a new value
virtual void operator = (T newValue);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// additional protocol for list iterator
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @cmember Assignment operator
virtual UTListIterator< T >& operator = (const UTListIterator< T >& AssignListItr);
// @cmember Move the iterator to the previous link
virtual BOOL operator -- (int dummy);
// @cmember Remove the current link from the list
virtual BOOL RemoveCurrent (T* pType);
// @cmember Insert a new value before the iterator
virtual void InsertBefore (const T& newValue);
// @cmember Insert a new value after the iterator
virtual void InsertAfter (const T& newValue);
// @cmember Set the iterator at the first element of this value
virtual BOOL SetPosAt (const T& value);
// @access Protected members
public:
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// data members
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @cmember Position of iterator in list
UTLink< T > * m_pCurrentLink;
// @cmember One position before the current position
UTLink< T > * m_pPreviousLink;
// @cmember List that is being iterated upon
UTList< T >& m_List;
};
//-----**************************************************************-----
// @class Template class
// The UTStaticListIterator class implements the operations that an
// iterator must support and includes some additional operations
// that are useful in the context of a static linked list.
// Use AddBefore & AddAfter to add elements to a list based on the
// iterator's current position within the list.
//
// @tcarg class | T | data type stored in list and type for iterator
// @base public | UTIterator
//-----**************************************************************-----
template <class T> class UTStaticListIterator : public UTIterator< T >
{
// @access Public members
public:
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// constructors/destructor
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @cmember Constructor
UTStaticListIterator (UTStaticList< T >& StaticList);
// @cmember Copy constructor
// UTStaticListIterator (const UTStaticListIterator< T >& CopyListItr);
// @cmember Destructor
virtual ~UTStaticListIterator(void);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// iterator protocol
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @cmember Initialize the iterator to the first link in list
virtual BOOL Init (void);
// @cmember Retrieve the value from the current link
virtual T operator () (void) const;
// @cmember Does the iterator point to a valid link
virtual BOOL operator ! (void) const;
// @cmember Move the iterator to the next link
virtual BOOL operator ++ (int dummy);
// @cmember Assign the current link a new value
virtual void operator = (T newValue);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// additional protocol for list iterator
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @cmember Assignment operator
// virtual UTListIterator< T >& operator = (const UTListIterator< T >& AssignListItr);
// @cmember Move the iterator to the previous link
virtual BOOL operator -- (int dummy);
// @cmember Remove the current link from the list
virtual BOOL RemoveCurrent (UTLink<T> ** ppLink);
// @cmember Insert a new value before the iterator
// virtual void InsertBefore (UTLink<T> * pLink);
// @cmember Insert a new value after the iterator
// virtual void InsertAfter (UTLink<T> * pLink);
// @cmember Set the iterator at the first element of this value
virtual BOOL SetPosAt (const T& Value);
// @access Protected members
public:
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// data members
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @cmember Position of iterator in list
UTLink< T > * m_pCurrentLink;
// @cmember One position before the current position
UTLink< T > * m_pPreviousLink;
// @cmember List that is being iterated upon
UTStaticList< T >& m_StaticList;
}; //End UTStaticListIterator
//---------- Inline Functions -----------------------------------------------
//---------------------------------------------------------------------------
// @mfunc Constructors
//
// @tcarg None.
//
//
// @rdesc None.
//
//---------------------------------------------------------------------------
template <class T> UTLink< T >::UTLink
(
void
)
{
// do nothing
m_pPrevLink = NULL;
m_pNextLink = NULL;
}
//---------------------------------------------------------------------------
// @mfunc Constructors
//
// @tcarg class | T | data type to store in the link
//
//
// @rdesc None.
//
//---------------------------------------------------------------------------
template <class T> UTLink< T >::UTLink(
const T& LinkValue, // @parm [in] Value to be stored with link
UTLink< T > * Prev, // @parm [in] pointer to previous link
UTLink< T > * Next // @parm [in] pointer to next link
)
: m_Value(LinkValue),
m_pPrevLink(Prev),
m_pNextLink(Next)
{
// do nothing
}
//---------------------------------------------------------------------------
// @tcarg class | T | data type to store in the link
//
// @rdesc None.
//
//---------------------------------------------------------------------------
template <class T> UTLink< T >::UTLink(
const UTLink< T >& CopyLink // @parm [in] value to copy into this object
)
{
m_Value = CopyLink.m_Value;
m_pPrevLink = CopyLink.m_pPrevLink;
m_pNextLink = CopyLink.m_pNextLink;
}
//---------------------------------------------------------------------------
// @mfunc This is the destructor. Currently, it does nothing.
//
// @tcarg class | T | data type to store in the link
//
// @rdesc None.
//
//---------------------------------------------------------------------------
template <class T> UTLink< T >::~UTLink(
void
)
{
// do nothing
}
//---------------------------------------------------------------------------
// @mfunc This is the assignment operator for <c UTLink>.
//
// @tcarg class | T | data type to store in the link
//
// @rdesc Returns a reference to the newly assigned object
//
//---------------------------------------------------------------------------
template <class T> void UTLink<T>::Init
(
const T& LinkValue,UTLink< T > * Prev, UTLink< T > * Next
)
{
m_Value = LinkValue;
m_pPrevLink = Prev;
m_pNextLink = Next;
}
//---------------------------------------------------------------------------
// @mfunc This is the assignment operator for <c UTLink>.
//
// @tcarg class | T | data type to store in the link
//
// @rdesc Returns a reference to the newly assigned object
//
//---------------------------------------------------------------------------
template <class T> UTLink< T >& UTLink< T >::operator =(
const UTLink< T >& AssignLink // @parm [in] value to assign into this object
)
{
m_Value = AssignLink.m_Value;
m_pPrevLink = AssignLink.m_pPrevLink;
m_pNextLink = AssignLink.m_pNextLink;
return *this;
}
//---------------------------------------------------------------------------
// @mfunc This method takes a value of type T and creates a new link
// containing that value. It fixes all pointers surrounding the
// current link so that it assumes the position just before the
// current link. It then returns the new link pointer.
//
// @tcarg class | T | data type to store in the link
//
// @rdesc Pointer to the newly added link
//
//---------------------------------------------------------------------------
template <class T> UTLink< T > * UTLink< T >::AddBefore(
const T& newValue // @parm [in] Value for new link just after the current link
)
{
// allocate memory for new link
UTLink< T > * newLink;
newLink = new UTLink< T >(newValue, m_pPrevLink, this);
if (newLink)
{
// if this isn't front of list, have old prev link point to new link
if (m_pPrevLink)
{
m_pPrevLink->m_pNextLink = newLink;
}
// make sure this link points back to new link added just before it
m_pPrevLink = newLink;
}
else
throw ( EXCEPT_MEMORY );
return (newLink);
}
//---------------------------------------------------------------------------
// @mfunc This method takes a value of type T and creates a new link
// containing that value. It fixes all pointers surrounding the
// current link so that it assumes the position just after the
// current link. It then returns the new link pointer.
//
// @tcarg class | T | data type to store in the link
//
// @rdesc Pointer to the newly added link
//
//---------------------------------------------------------------------------
template <class T> UTLink< T > * UTLink< T >::AddAfter(
const T& newValue // @parm [in] Value for new link just after the current link
)
{
// allocate memory for new link
UTLink< T > * newLink;
newLink = new UTLink< T >(newValue, this, m_pNextLink);
if (newLink)
{
// if this isn't end of list, have old next link point back to new link
if (m_pNextLink)
{
m_pNextLink->m_pPrevLink = newLink;
}
// make sure this link points forward to new link added just after it
m_pNextLink = newLink;
}
else
throw (EXCEPT_MEMORY);
return (newLink);
}
//---------------------------------------------------------------------------
// @mfunc This method takes a pointer to a static list and removes this
// link from the list.
//
// @tcarg class | T | data type stored in the link
//
// @rdesc none
//
//---------------------------------------------------------------------------
template <class T> void UTLink< T >::RemoveFromList (
UTStaticList < T > * pStaticList)
{
if ((m_pPrevLink == 0x0 ) && (m_pNextLink == 0x0))
{
pStaticList->m_pLastLink = 0x0;
pStaticList->m_pFirstLink = 0x0;
}
else if (m_pPrevLink == 0x0 )
{
pStaticList->m_pFirstLink = m_pNextLink;
}
else if (m_pNextLink == 0x0 )
{
pStaticList->m_pLastLink = m_pPrevLink;
}
else
{
m_pNextLink->m_pPrevLink = m_pPrevLink;
m_pPrevLink->m_pNextLink = m_pNextLink;
}
m_pNextLink = 0x0;
m_pPrevLink = 0x0;
// Update the number of link objects in the list
pStaticList->m_ulCount--;
} // End RemoveFromList
//---------------------------------------------------------------------------
// @mfunc Constructors
//
// @tcarg class | T | data type to store in the list
//
// @syntax UTList< T >::UTList()
//
// @rdesc None.
//
//---------------------------------------------------------------------------
template <class T> UTList< T >::UTList(
void
)
: m_ulCount(0), m_pFirstLink(NULL), m_pLastLink(NULL)
{
// do nothing
}
//---------------------------------------------------------------------------
// @tcarg class | T | data type to store in the list
//
// @syntax UTList< T >::UTList(const UTList< T >&)
//
// @rdesc None.
//
//---------------------------------------------------------------------------
template <class T> UTList< T >::UTList(
const UTList< T >& CopyList // @parm [in] list to be copied
)
{
UTListIterator< T > itr((UTList< T >&)CopyList);
m_pFirstLink = NULL;
m_pLastLink = NULL;
m_ulCount = 0;
for (itr.Init(); !itr; itr++)
InsertLast(itr());
}
//---------------------------------------------------------------------------
// @mfunc This destructor calls <mf UTList::RemoveAll> on the list to
// delete all links and the memory associated with them.
//
// @tcarg class | T | data type to store in the list
//
//---------------------------------------------------------------------------
template <class T> UTList< T >::~UTList(
void
)
{
RemoveAll();
}
//---------------------------------------------------------------------------
// @mfunc Reinitializes the list
//
// @tcarg class | T | data type to store in the list
//
//---------------------------------------------------------------------------
template <class T> void UTList< T >::Init (void)
{
m_ulCount = 0x0;
m_pFirstLink = 0x0;
m_pLastLink = 0x0;
}
//---------------------------------------------------------------------------
// @mfunc This is the assignment operator for <c UTList>. All elements
// are first removed from this list and then the list is generated
// by copying the assigned list. Assignment to self is prevented.
//
// @tcarg class | T | data type to store in the list
//
// @rdesc Returns a reference to the newly assigned object
//---------------------------------------------------------------------------
template <class T> UTList< T >& UTList< T >::operator =(
const UTList< T >& AssignList // @parm [in] list to be copied (assigned from)
)
{
UTListIterator< T > itr((UTList< T >&)AssignList);
// make sure we're not assigning list to itself first
if (m_pFirstLink != AssignList.m_pFirstLink)
{
RemoveAll(); // remove all from this list first
for (itr.Init(); !itr; itr++)
InsertLast(itr());
}
return *this;
}
//---------------------------------------------------------------------------
// @mfunc This method duplicates the list into an entirely new list and
// returns a pointer to the new list.
//
// @tcarg class | T | data type to store in the list
//
// @rdesc Pointer to the newly createe list
//---------------------------------------------------------------------------
template <class T> UTList< T > * UTList< T >::Duplicate(
void
)
{
UTListIterator< T > itr((UTList< T >&) *this);
UTList< T > * pNewList = new UTList();
if (pNewList)
{
for (itr.Init(); !itr; itr++)
pNewList->InsertLast(itr());
}
else
throw (EXCEPT_MEMORY);
return pNewList;
}
//---------------------------------------------------------------------------
// @mfunc This method adds the value to the end of the list by calling
// <mf UTList::InsertLast>.
//
// @tcarg class | T | data type to store in the list
//
// @rdesc None.
//---------------------------------------------------------------------------
template <class T> void UTList< T >::Add(
const T& newValue // @parm [in] value to be added to list
)
{
InsertLast(newValue);
}
//---------------------------------------------------------------------------
// @mfunc This method inserts the new value at the beginning of the
// list.
//
// @tcarg class | T | data type to store in the list
//
// @rdesc None.
//---------------------------------------------------------------------------
template <class T> void UTList< T >::InsertFirst(
const T& newValue // @parm [in] value to be inserted at beginning of list
)
{
UTLink< T > * pLink = m_pFirstLink; // save ptr to link
if (pLink) // list is not empty
{
m_pFirstLink = pLink->AddBefore(newValue);
}
else // list is empty
{
m_pLastLink = new UTLink< T >(newValue, NULL, NULL);
if (m_pLastLink)
{
m_pFirstLink = m_pLastLink;
}
else
throw (EXCEPT_MEMORY);
}
m_ulCount++;
}
//---------------------------------------------------------------------------
// @mfunc This method inserts the new value at the end of the list.
//
// @tcarg class | T | data type to store in the list
//
// @rdesc None.
//---------------------------------------------------------------------------
template <class T> void UTList< T >::InsertLast(
const T& newValue // @parm [in] value to be inserted at end of list
)
{
UTLink< T > * pLink = m_pLastLink; // save ptr to link
if (pLink) // list is not empty
m_pLastLink = pLink->AddAfter(newValue);
else // list is empty
{
m_pLastLink = new UTLink< T >(newValue, NULL, NULL);
if (m_pLastLink)
{
m_pFirstLink = m_pLastLink;
}
else
throw (EXCEPT_MEMORY);
}
m_ulCount++;
}
//---------------------------------------------------------------------------
// @mfunc This method moves through the list and deletes each link and
// then resets the list count and pointers as they were set in
// the constructor.
//
// @tcarg class | T | data type to store in the list
//
// @rdesc None.
//---------------------------------------------------------------------------
template <class T> void UTList< T >::RemoveAll(
void
)
{
UTListIterator< T > itr((UTList< T >&) *this);
T tValue; // required for RemoveCurrent()
while (!itr)
itr.RemoveCurrent(&tValue); // this will reset itr to valid pos
}
//---------------------------------------------------------------------------
// @mfunc This method removes the first element from the list and fixes
// the pointer to the first element according to what remains
// of the list. The former first element is returned through a
// CALLER allocated variable.
//
// @tcarg class | T | data type to store in the list
//
// @rdesc Returns a BOOL
// @flag TRUE | if first element exists and is deleted
// @flag FALSE | otherwise
//---------------------------------------------------------------------------
template <class T> BOOL UTList< T >::RemoveFirst(
T* pType // @parm [out] location to put first element if available
)
{
BOOL bReturn = FALSE;
UTLink< T > * pLink = m_pFirstLink;
if (pLink)
{
// isolate the link that is about to be deleted
m_pFirstLink = m_pFirstLink->m_pNextLink;
if (m_pFirstLink)
m_pFirstLink->m_pPrevLink = NULL;
if (m_pLastLink == pLink)
m_pLastLink = NULL;
// prepare return value and delete node
*pType = pLink->m_Value;
bReturn = TRUE;
delete pLink;
m_ulCount--;
}
return bReturn;
}
//---------------------------------------------------------------------------
// @mfunc This method removes the last element from the list and fixes
// the pointer to the last element according to what remains
// of the list. The former last element is returned through a
// CALLER allocated variable.
//
// @tcarg class | T | data type to store in the list
//
// @rdesc Returns a BOOL
// @flag TRUE | if last element exists and is deleted
// @flag FALSE | otherwise
//
//---------------------------------------------------------------------------
template <class T> BOOL UTList< T >::RemoveLast(
T* pType // @parm [out] location to put first element if available
)
{
BOOL bReturn = FALSE;
UTLink< T > * pLink = m_pLastLink;
if (pLink)
{
// isolate the link that is about to be deleted
m_pLastLink = m_pLastLink->m_pPrevLink;
if (m_pLastLink)
m_pLastLink->m_pNextLink = NULL;
if (m_pFirstLink == pLink)
m_pFirstLink = NULL;
// prepare return value and delete node
*pType = pLink->m_Value;
bReturn = TRUE;
delete pLink;
m_ulCount--;
}
return bReturn;
}
//---------------------------------------------------------------------------
// @mfunc This method returns TRUE if there is a first element in the
// list and fills the out argument (CALLER allocated) with that
// first element value.
//
// @tcarg class | T | data type to store in the list
//
// @rdesc Returns a BOOL
// @flag TRUE | if first element exists
// @flag FALSE | otherwise
//
//---------------------------------------------------------------------------
template <class T> BOOL UTList< T >::FirstElement(
T* pType // @parm [out] location to put first element if available
) const
{
BOOL bReturn = FALSE;
if (m_pFirstLink)
{
*pType = m_pFirstLink->m_Value;
bReturn = TRUE;
}
return bReturn;
}
//---------------------------------------------------------------------------
// @mfunc This method returns TRUE if there is a last element in the
// list and fills the out argument (CALLER allocated) with that
// last element value.
//
// @tcarg class | T | data type to store in the list
//
// @rdesc Returns a BOOL
// @flag TRUE | if last element exists
// @flag FALSE | otherwise
//
//---------------------------------------------------------------------------
template <class T> BOOL UTList< T >::LastElement(
T* pType // @parm [out] location to put last element if available
) const
{
BOOL bReturn = FALSE;
if (m_pLastLink)
{
*pType = m_pLastLink->m_Value;
bReturn = TRUE;
}
return bReturn;
}
//---------------------------------------------------------------------------
// @mfunc This method checks the list for the given value and returns
// TRUE if that value is in the list.
//
// @tcarg class | T | data type to store in the list
//
// @rdesc Returns a BOOL
// @flag TRUE | if element exists in list
// @flag FALSE | otherwise
//
//---------------------------------------------------------------------------
template <class T> BOOL UTList< T >::Includes(
const T& value // @parm [in] does list include this value?
)
{
UTListIterator< T > itr((UTList< T >&) *this);
while (!itr && (itr() != value))
itr++;
return (!itr);
}
//---------------------------------------------------------------------------
// @mfunc This method returns TRUE if the count of elements in the list
// is ZERO.
//
// @tcarg class | T | data type to store in the list
//
// @rdesc Returns a BOOL
// @flag TRUE | if list is empty
// @flag FALSE | list is not empty
//---------------------------------------------------------------------------
template <class T> BOOL UTList< T >::IsEmpty(
void
) const
{
return (m_ulCount == 0);
}
//---------------------------------------------------------------------------
// @mfunc This method returns the member variable that indicates the
// count of elements. It is incremented whenever values are added
// and decremented whenever values are removed.
//
// @tcarg class | T | data type to store in the list
//
// @rdesc ULONG
//---------------------------------------------------------------------------
template <class T> ULONG UTList< T >::GetCount(
void
) const
{
return (m_ulCount);
}
//---------------------------------------------------------------------------
// @mfunc Constructors
//
// @tcarg class | T | data type to iterate over
//
// @syntax UTListIterator< T >::UTListIterator(UTList< T >&)
//
// @rdesc None.
//---------------------------------------------------------------------------
template <class T> UTListIterator< T >::UTListIterator(
UTList< T >& List // @parm [in] list reference for list to be iterated upon
)
: m_List(List)
{
Init();
}
//---------------------------------------------------------------------------
// @tcarg class | T | data type to iterate over
//
// @syntax UTListIterator< T >::UTListIterator(const UTListIterator< T >&)
//
// @rdesc None.
//---------------------------------------------------------------------------
template <class T> UTListIterator< T >::UTListIterator(
const UTListIterator< T >& CopyListItr // @parm [in] value to copy into this obj
)
: m_List(CopyListItr.m_List),
m_pPreviousLink(CopyListItr.m_pPreviousLink),
m_pCurrentLink(CopyListItr.m_pCurrentLink)
{
}
//---------------------------------------------------------------------------
// @mfunc This destruct does nothing because no memory needs to be deleted.
//
// @tcarg class | T | data type to iterate over
//
// @rdesc None.
//---------------------------------------------------------------------------
template <class T> UTListIterator< T >::~UTListIterator(
void
)
{
// do nothing
}
//---------------------------------------------------------------------------
// @mfunc This is the assignment operator.
//
// @tcarg class | T | data type to iterate over
//
// @syntax UTListIterator< T >& UTListIterator< T >::operator =(const UTListIterator< T >&)
//
// @rdesc Returns a reference to the newly assigned object
//---------------------------------------------------------------------------
template <class T> UTListIterator< T >& UTListIterator< T >::operator =(
const UTListIterator< T >& AssignListItr // @parm [in] value to copy into this obj
)
{
// make sure iterators don't already point to the same thing
if (m_pCurrentLink != AssignListItr.m_pCurrentLink)
{
m_List = AssignListItr.m_List;
m_pPreviousLink = AssignListItr.m_pPreviousLink;
m_pCurrentLink = AssignListItr.m_pCurrentLink;
}
return *this;
}
//---------------------------------------------------------------------------
// @tcarg class | T | data type to iterate over
//
// @syntax UTListIterator< T >& UTListIterator< T >::operator =(T)
//
// @rdesc None.
//---------------------------------------------------------------------------
template <class T> void UTListIterator< T >::operator =(
T newValue // @parm [in] value to place in link at current position
)
{
if (m_pCurrentLink)
m_pCurrentLink->m_Value = newValue;
}
//---------------------------------------------------------------------------
// @mfunc This method sets up the iterator by making its internal state
// point to the first element in the list.
//
// @tcarg class | T | data type to iterate over
//
// @rdesc Returns a BOOL
// @flag TRUE | if there is at least on element in the list which means
// there is something to iterate over
// @flag FALSE | if no elements are to be iterated upon
//---------------------------------------------------------------------------
template <class T> BOOL UTListIterator< T >::Init(
void
)
{
m_pPreviousLink = NULL;
m_pCurrentLink = m_List.m_pFirstLink;
return (m_pCurrentLink != NULL);
}
//---------------------------------------------------------------------------
// @mfunc This operator retrieves the element from the current position
// of the iterator.
//
// @tcarg class | T | data type to iterate over
//
// @rdesc T - current value where iterator is located
//---------------------------------------------------------------------------
template <class T> T UTListIterator< T >::operator ()(
void
) const
{
//UNDONE:
//assert(m_pCurrentLink != NULL);
if (m_pCurrentLink)
return (m_pCurrentLink->m_Value);
else // incorrect use of iterator, return "bogus" default value
{
T tBogusDefault = (T) 0;
return tBogusDefault;
}
}
//---------------------------------------------------------------------------
// @mfunc This operator determines if the current position is valid.
//
// @tcarg class | T | data type to iterate over
//
// @rdesc Returns a BOOL
// @flag TRUE | if iterator is in a valid position
// @flag FALSE | if iterator is NOT in a valid position
//---------------------------------------------------------------------------
template <class T> BOOL UTListIterator< T >::operator !(
void
) const
{
return (m_pCurrentLink != NULL);
}
//---------------------------------------------------------------------------
// @mfunc This operator increments the iterator to the next element in the
// list and returns an indication of whether or not the end of the
// list has been passed.
//
// @tcarg class | T | data type to iterate over
//
// @rdesc Returns a BOOL
// @flag TRUE | if new position is valid
// @flag FALSE | if new position is NOT valid (i.e. end of the list)
//---------------------------------------------------------------------------
template <class T> BOOL UTListIterator< T >::operator ++(
int dummy // @parm [in] dummy so that operator is on right hand side
)
{
if (m_pCurrentLink)
{
m_pPreviousLink = m_pCurrentLink;
m_pCurrentLink = m_pCurrentLink->m_pNextLink;
}
return (m_pCurrentLink != NULL);
}
//---------------------------------------------------------------------------
// @mfunc This operator decrements the iterator to the prev element in the
// list and returns an indication of whether or not the front of the
// list has been passed.
//
// @tcarg class | T | data type to iterate over
//
// @rdesc Returns a BOOL
// @flag TRUE | if new position is valid
// @flag FALSE | if new position is NOT valid
//---------------------------------------------------------------------------
template <class T> BOOL UTListIterator< T >::operator --(
int dummy // @parm [in] dummy so that operator is on right hand side
)
{
m_pCurrentLink = m_pPreviousLink;
if (m_pCurrentLink)
{
m_pPreviousLink = m_pCurrentLink->m_pPrevLink;
}
return (m_pCurrentLink != NULL);
}
//---------------------------------------------------------------------------
// @mfunc RemoveCurrent deletes the element at the position of the
// iterator returning the deleted value through a CALLER
// allocated parameter. <nl>
// It then fixes the current position to the following: <nl><nl>
// If we... The we... <nl>
// 1) removed any link but 1st one old previous position->next <nl>
// 2) removed first link(links remain) new first position <nl>
// 3) removed only link NULL (no current position) <nl>
//
// @tcarg class | T | data type to iterate over
//
// @rdesc Returns a BOOL
// @flag TRUE | if current element exists and was removed
// @flag FALSE | otherwise
//---------------------------------------------------------------------------
template <class T> BOOL UTListIterator< T >::RemoveCurrent(
T* pType // @parm [out] location to put current element if available
)
{
BOOL bReturn = FALSE;
if (m_pCurrentLink) // remove ONLY if iterator is still in valid position
{
if (m_pPreviousLink == NULL) // removing first element
{
if (m_pCurrentLink->m_pNextLink == NULL) // ONLY element
{
m_List.m_pFirstLink = m_List.m_pLastLink = NULL;
}
else // first, but not last element
{
m_List.m_pFirstLink = m_pCurrentLink->m_pNextLink;
m_pCurrentLink->m_pNextLink->m_pPrevLink = NULL;
}
}
else // not removing first element
{
if (m_pCurrentLink->m_pNextLink == NULL) // last element
{
m_List.m_pLastLink = m_pPreviousLink;
m_pPreviousLink->m_pNextLink = NULL;
}
else // neither first nor last element
{
m_pPreviousLink->m_pNextLink = m_pCurrentLink->m_pNextLink;
m_pCurrentLink->m_pNextLink->m_pPrevLink = m_pPreviousLink;
}
}
*pType = m_pCurrentLink->m_Value;
bReturn = TRUE;
delete m_pCurrentLink;
m_List.m_ulCount--;
// now fix up the current iterator pointer
if (m_pPreviousLink)
m_pCurrentLink = m_pPreviousLink->m_pNextLink;
else if (m_List.m_pFirstLink)
m_pCurrentLink = m_List.m_pFirstLink;
else
m_pCurrentLink = NULL;
}
return bReturn;
}
//---------------------------------------------------------------------------
// @mfunc This method adds a new link to the list (using data passed as
// an argument) in a position just before the current position
// of the iterator.
//
// @tcarg class | T | data type to iterate over
//
// @rdesc None.
//---------------------------------------------------------------------------
template <class T> void UTListIterator< T >::InsertBefore(
const T& newValue // @parm [in] new data to be added before the current position
)
{
if (m_pCurrentLink) // add ONLY if iterator is still in valid position
{
if (m_pPreviousLink) // not at beginning
{
m_pCurrentLink->AddBefore(newValue);
}
else // at beginning of list
{
m_List.m_pFirstLink = m_pCurrentLink->AddBefore(newValue);
}
m_List.m_ulCount++;
// fix prev pointer which is now two links away
m_pPreviousLink = m_pCurrentLink->m_pPrevLink;
}
}
//---------------------------------------------------------------------------
// @mfunc This method adds a new link to the list (using data passed as
// an argument) in a position immediately following the current
// position of the iterator.
//
// @tcarg class | T | data type to iterate over
//
// @rdesc None.
//---------------------------------------------------------------------------
template <class T> void UTListIterator< T >::InsertAfter(
const T& newValue // @parm [in] new data to be added after the current position
)
{
if (m_pCurrentLink) // add ONLY if iterator is still in valid position
{
if (m_pCurrentLink->m_pNextLink) // not at end
{
m_pCurrentLink->AddAfter(newValue);
}
else // at end of list
{
m_List.m_pLastLink = m_pCurrentLink->AddAfter(newValue);
}
m_List.m_ulCount++;
}
}
//---------------------------------------------------------------------------
// @mfunc This method resets the iterator at the value passed
// in as an argument if it exists in the list and returns
// TRUE in that case indicating that it did change position.
// If the value does not exist, the position remains
// unchanged, and FALSE is returned to indicate this.
//
// @tcarg class | T | data type to iterate over
//
// @rdesc Returns a BOOL
// @flag TRUE | if posistion has changed
// @flag FALSE | otherwise
//---------------------------------------------------------------------------
template <class T> BOOL UTListIterator< T >::SetPosAt(
const T& value //@parm [in] if this value is in list, set up iterator at its location
)
{
BOOL bReturn = FALSE;
UTLink< T > * pLink = m_List.m_pFirstLink;
while (pLink && pLink->m_Value != value)
pLink = pLink->m_pNextLink;
if (pLink) // found value in list
{
m_pCurrentLink = pLink;
m_pPreviousLink = pLink->m_pPrevLink;
bReturn = TRUE;
}
return bReturn;
}
//---------------------------------------------------------------------------
// @mfunc Constructors
//
// @tcarg class | T | data type to store in the list
//
// @syntax UTStaticList< T >::UTStaticList()
//
// @rdesc None.
//
//---------------------------------------------------------------------------
template <class T> UTStaticList< T >::UTStaticList(
void
)
: m_ulCount(0), m_pFirstLink(NULL), m_pLastLink(NULL)
{
// do nothing
}
//---------------------------------------------------------------------------
// @mfunc This destructor does nothing
//
// @tcarg class | T | data type to store in the list
//
//---------------------------------------------------------------------------
template <class T> UTStaticList< T >::~UTStaticList(
void
)
{
//Do nothing
}
//---------------------------------------------------------------------------
// @mfunc Reinitializes the list
//
// @tcarg class | T | data type to store in the list
//
//---------------------------------------------------------------------------
template <class T> void UTStaticList< T >::Init (void)
{
m_ulCount = 0x0;
m_pFirstLink = 0x0;
m_pLastLink = 0x0;
}
//---------------------------------------------------------------------------
// @mfunc This method adds the link to the end of the list by calling
// <mf UTStaticList::InsertLast>.
//
// @tcarg class | T | data type to store in the list
//
// @rdesc None.
//---------------------------------------------------------------------------
template <class T> void UTStaticList< T >::Add(
UTLink <T> * pLink // @parm [in] Link to be added to list
)
{
InsertLast(pLink);
}
//---------------------------------------------------------------------------
// @mfunc This method inserts the new value at the beginning of the
// list.
//
// @tcarg class | T | data type to store in the list
//
// @rdesc None.
//---------------------------------------------------------------------------
template <class T> void UTStaticList< T >::InsertFirst(
UTLink <T> * pLink // @parm [in] link to be inserted at beginning of list
)
{
if (m_pFirstLink) // list is not empty
{
pLink->m_pPrevLink = (UTLink<T> *) 0;
pLink->m_pNextLink = m_pFirstLink;
m_pFirstLink->m_pPrevLink = pLink;
m_pFirstLink = pLink;
}
else // list is empty
{
m_pFirstLink = pLink;
m_pLastLink = pLink;
}
m_ulCount++;
} //End UTStaticList::InsertFirst
//---------------------------------------------------------------------------
// @mfunc This method inserts the new link at the end of the list.
//
// @tcarg class | T | data type to store in the list
//
// @rdesc None.
//---------------------------------------------------------------------------
template <class T> void UTStaticList< T >::InsertLast(
UTLink <T> * pLink // @parm [in] link to be inserted at end of list
)
{
if (m_pLastLink) // list is not empty
{
pLink->m_pNextLink = (UTLink<T> *) 0;
pLink->m_pPrevLink = m_pLastLink;
m_pLastLink->m_pNextLink = pLink;
m_pLastLink = pLink;
}
else // list is empty
{
m_pFirstLink = pLink;
m_pLastLink = pLink;
}
//Increment the count
m_ulCount++;
} //End UTStaticList::InsertLast
//---------------------------------------------------------------------------
// @mfunc This method resets the list count and pointers as they were set in
// the constructor.
//
// @tcarg class | T | data type to store in the list
//
// @rdesc None.
//---------------------------------------------------------------------------
template <class T> void UTStaticList< T >::RemoveAll
(
void
)
{
//UNDONE - gaganc Need to reset the pointers of all the links to NULL
m_pFirstLink = NULL;
m_pLastLink = NULL;
m_ulCount = 0;
} //End UTStaticList::RemoveAll
//---------------------------------------------------------------------------
// @mfunc This method removes the first element from the list and fixes
// the pointer to the first element according to what remains
// of the list. The former first element is returned through a
// CALLER allocated variable.
//
// @tcarg class | T | data type to store in the list
//
// @rdesc Returns a BOOL
// @flag TRUE | if first element exists and is deleted
// @flag FALSE | otherwise
//---------------------------------------------------------------------------
template <class T> BOOL UTStaticList< T >::RemoveFirst(
UTLink<T> ** ppLink // @parm [out] location to put first element if available
)
{
BOOL bReturn = FALSE;
//Assign the out param the first link
*ppLink = m_pFirstLink;
if (m_pFirstLink)
{
// Reset the first link
m_pFirstLink = m_pFirstLink->m_pNextLink;
if (m_pFirstLink)
m_pFirstLink->m_pPrevLink = NULL;
if (m_pLastLink == *ppLink)
m_pLastLink = NULL;
bReturn = TRUE;
m_ulCount--;
}
//Remember to clear previous and the next pointers in the link
if (*ppLink)
{
(*ppLink)->m_pNextLink = NULL;
(*ppLink)->m_pPrevLink = NULL;
}
return bReturn;
} //End UTStaticList::RemoveFirst
//---------------------------------------------------------------------------
// @mfunc This method removes the last element from the list and fixes
// the pointer to the last element according to what remains
// of the list. The former last element is returned through a
// CALLER allocated variable.
//
// @tcarg class | T | data type to store in the list
//
// @rdesc Returns a BOOL
// @flag TRUE | if last element exists and is deleted
// @flag FALSE | otherwise
//
//---------------------------------------------------------------------------
template <class T> BOOL UTStaticList< T >::RemoveLast(
UTLink<T> ** ppLink // @parm [out] location to put first element if available
)
{
BOOL bReturn = FALSE;
*ppLink = m_pLastLink;
if (m_pLastLink)
{
// isolate the link that is about to be deleted
m_pLastLink = m_pLastLink->m_pPrevLink;
if (m_pLastLink)
m_pLastLink->m_pNextLink = NULL;
if (m_pFirstLink == *ppLink)
m_pFirstLink = NULL;
bReturn = TRUE;
m_ulCount--;
}
//Remember to clear previous and the next pointers in the link
if (*ppLink)
{
(*ppLink)->m_pNextLink = NULL;
(*ppLink)->m_pPrevLink = NULL;
}
return bReturn;
} //End UTStaticList::RemoveLast
//---------------------------------------------------------------------------
// @mfunc This method returns TRUE if there is a first element in the
// list and fills the out argument (CALLER allocated) with that
// first element value.
//
// @tcarg class | T | data type to store in the list
//
// @rdesc Returns a BOOL
// @flag TRUE | if first element exists
// @flag FALSE | otherwise
//
//---------------------------------------------------------------------------
template <class T> BOOL UTStaticList< T >::FirstElement
(
UTLink <T> ** ppLink // @parm [out] location to put first element if available
)
{
BOOL bReturn = FALSE;
//If the first elment exists then return TRUE else FALSE
if (m_pFirstLink)
{
*ppLink = m_pFirstLink;
bReturn = TRUE;
}
return bReturn;
}
//---------------------------------------------------------------------------
// @mfunc This method returns TRUE if there is a last element in the
// list and fills the out argument (CALLER allocated) with that
// last element value.
//
// @tcarg class | T | data type to store in the list
//
// @rdesc Returns a BOOL
// @flag TRUE | if last element exists
// @flag FALSE | otherwise
//
//---------------------------------------------------------------------------
template <class T> BOOL UTStaticList< T >::LastElement
(
UTLink<T> ** ppLink // @parm [out] location to put last element if available
)
{
BOOL bReturn = FALSE;
if (m_pLastLink)
{
*ppLink = m_pLastLink;
bReturn = TRUE;
}
return bReturn;
}
//---------------------------------------------------------------------------
// @mfunc This method returns TRUE if the count of elements in the list
// is ZERO.
//
// @tcarg class | T | data type to store in the list
//
// @rdesc Returns a BOOL
// @flag TRUE | if list is empty
// @flag FALSE | list is not empty
//---------------------------------------------------------------------------
template <class T> BOOL UTStaticList< T >::IsEmpty
(
void
) const
{
return (m_ulCount == 0);
} //End UTStaticList::IsEmpty
//---------------------------------------------------------------------------
// @mfunc This method returns the member variable that indicates the
// count of elements. It is incremented whenever values are added
// and decremented whenever values are removed.
//
// @tcarg class | T | data type to store in the list
//
// @rdesc ULONG
//---------------------------------------------------------------------------
template <class T> ULONG UTStaticList< T >::GetCount
(
void
) const
{
return (m_ulCount);
} //End UTStaticList::GetCount
//---------------------------------------------------------------------------
// @mfunc Constructors
//
// @tcarg class | T | data type to iterate over
//
// @syntax UTStaticListIterator< T >::UTStaticListIterator(UTStaticList< T >&)
//
// @rdesc None.
//---------------------------------------------------------------------------
template <class T> UTStaticListIterator< T >::UTStaticListIterator
(
UTStaticList< T >& StaticList // @parm [in] list reference for list to be iterated upon
)
: m_StaticList(StaticList)
{
Init();
}
//---------------------------------------------------------------------------
// @mfunc This destruct does nothing because no memory needs to be deleted.
//
// @tcarg class | T | data type to iterate over
//
// @rdesc None.
//---------------------------------------------------------------------------
template <class T> UTStaticListIterator< T >::~UTStaticListIterator
(
void
)
{
// do nothing
}
//---------------------------------------------------------------------------
// @mfunc This is the assignment operator.
//
// @tcarg class | T | data type to iterate over
//
// @syntax UTStaticListIterator< T >& UTStaticListIterator< T >
// ::operator =(const UTListIterator< T >&)
//
// @rdesc Returns a reference to the newly assigned object
//---------------------------------------------------------------------------
template <class T> UTStaticListIterator< T >& UTStaticListIterator< T >::operator =
(
const UTStaticListIterator< T >& AssignListItr
// @parm [in] value to copy into this obj
)
{
// make sure iterators don't already point to the same thing
if (m_pCurrentLink != AssignListItr.m_pCurrentLink)
{
m_StaticList = AssignListItr.m_StaticList;
m_pPreviousLink = AssignListItr.m_pPreviousLink;
m_pCurrentLink = AssignListItr.m_pCurrentLink;
}
return *this;
} //End UTStaticListIterator
//---------------------------------------------------------------------------
// @tcarg class | T | data type to iterate over
//
// @syntax UTStaticListIterator< T >& UTStaticListIterator< T >::operator =(T)
//
// @rdesc None.
//---------------------------------------------------------------------------
template <class T> void UTStaticListIterator< T >::operator =(
T newValue // @parm [in] value to place in link at current position
)
{
//CAUTION : -- Don't use this THIS WILL CRASH
UTLink <short> * pLink = 0;
pLink->m_Value;
}
//---------------------------------------------------------------------------
// @mfunc This method sets up the iterator by making its internal state
// point to the first element in the list.
//
// @tcarg class | T | data type to iterate over
//
// @rdesc Returns a BOOL
// @flag TRUE | if there is at least on element in the list which means
// there is something to iterate over
// @flag FALSE | if no elements are to be iterated upon
//---------------------------------------------------------------------------
template <class T> BOOL UTStaticListIterator< T >::Init
(
void
)
{
m_pPreviousLink = NULL;
m_pCurrentLink = m_StaticList.m_pFirstLink;
return (m_pCurrentLink != NULL);
}
//---------------------------------------------------------------------------
// @mfunc This operator retrieves the element from the current position
// of the iterator.
//
// @tcarg class | T | data type to iterate over
//
// @rdesc T - current value where iterator is located
//---------------------------------------------------------------------------
template <class T> T UTStaticListIterator< T >::operator ()
(
void
) const
{
if (m_pCurrentLink)
return (m_pCurrentLink->m_Value);
else // incorrect use of iterator, return "bogus" default value
{
T tBogusDefault = (T) 0;
return tBogusDefault;
}
}
//---------------------------------------------------------------------------
// @mfunc This operator determines if the current position is valid.
//
// @tcarg class | T | data type to iterate over
//
// @rdesc Returns a BOOL
// @flag TRUE | if iterator is in a valid position
// @flag FALSE | if iterator is NOT in a valid position
//---------------------------------------------------------------------------
template <class T> BOOL UTStaticListIterator< T >::operator !
(
void
) const
{
return (m_pCurrentLink != NULL);
}
//---------------------------------------------------------------------------
// @mfunc This operator increments the iterator to the next element in the
// list and returns an indication of whether or not the end of the
// list has been passed.
//
// @tcarg class | T | data type to iterate over
//
// @rdesc Returns a BOOL
// @flag TRUE | if new position is valid
// @flag FALSE | if new position is NOT valid (i.e. end of the list)
//---------------------------------------------------------------------------
template <class T> BOOL UTStaticListIterator< T >::operator ++
(
int dummy // @parm [in] dummy so that operator is on right hand side
)
{
if (m_pCurrentLink)
{
m_pPreviousLink = m_pCurrentLink;
m_pCurrentLink = m_pCurrentLink->m_pNextLink;
}
return (m_pCurrentLink != NULL);
}
//---------------------------------------------------------------------------
// @mfunc This operator decrements the iterator to the prev element in the
// list and returns an indication of whether or not the front of the
// list has been passed.
//
// @tcarg class | T | data type to iterate over
//
// @rdesc Returns a BOOL
// @flag TRUE | if new position is valid
// @flag FALSE | if new position is NOT valid
//---------------------------------------------------------------------------
template <class T> BOOL UTStaticListIterator< T >::operator --
(
int dummy // @parm [in] dummy so that operator is on right hand side
)
{
m_pCurrentLink = m_pPreviousLink;
if (m_pCurrentLink)
{
m_pPreviousLink = m_pCurrentLink->m_pPrevLink;
}
return (m_pCurrentLink != NULL);
}
//---------------------------------------------------------------------------
// @mfunc RemoveCurrent deletes the element at the position of the
// iterator returning the deleted value through a CALLER
// allocated parameter. <nl>
// It then fixes the current position to the following: <nl><nl>
// If we... The we... <nl>
// 1) removed any link but 1st one old previous position->next <nl>
// 2) removed first link(links remain) new first position <nl>
// 3) removed only link NULL (no current position) <nl>
//
// @tcarg class | T | data type to iterate over
//
// @rdesc Returns a BOOL
// @flag TRUE | if current element exists and was removed
// @flag FALSE | otherwise
//---------------------------------------------------------------------------
template <class T> BOOL UTStaticListIterator< T >::RemoveCurrent
(
UTLink <T> ** ppLink // @parm [out] location to put current element if available
)
{
BOOL bReturn = FALSE;
if (m_pCurrentLink) // remove ONLY if iterator is still in valid position
{
if (m_pPreviousLink == NULL) // removing first element
{
if (m_pCurrentLink->m_pNextLink == NULL) // ONLY element
{
m_StaticList.m_pFirstLink = m_StaticList.m_pLastLink = NULL;
}
else // first, but not last element
{
m_StaticList.m_pFirstLink = m_pCurrentLink->m_pNextLink;
m_pCurrentLink->m_pNextLink->m_pPrevLink = NULL;
}
}
else // not removing first element
{
if (m_pCurrentLink->m_pNextLink == NULL) // last element
{
m_StaticList.m_pLastLink = m_pPreviousLink;
m_pPreviousLink->m_pNextLink = NULL;
}
else // neither first nor last element
{
m_pPreviousLink->m_pNextLink = m_pCurrentLink->m_pNextLink;
m_pCurrentLink->m_pNextLink->m_pPrevLink = m_pPreviousLink;
}
}
*ppLink = m_pCurrentLink;
(*ppLink)->m_pNextLink = 0;
(*ppLink)->m_pPrevLink = 0;
bReturn = TRUE;
m_StaticList.m_ulCount--;
// now fix up the current iterator pointer
if (m_pPreviousLink)
{
m_pCurrentLink = m_pPreviousLink->m_pNextLink;
}
else if (m_StaticList.m_pFirstLink)
{
m_pCurrentLink = m_StaticList.m_pFirstLink;
}
else
{
m_pCurrentLink = NULL;
}
}
return bReturn;
} //End RemoveCurrent
//---------------------------------------------------------------------------
// @mfunc This method resets the iterator at the value passed
// in as an argument if it exists in the list and returns
// TRUE in that case indicating that it did change position.
// If the value does not exist, the position remains
// unchanged, and FALSE is returned to indicate this.
//
// @tcarg class | T | data type to iterate over
//
// @rdesc Returns a BOOL
// @flag TRUE | if posistion has changed
// @flag FALSE | otherwise
//---------------------------------------------------------------------------
template <class T> BOOL UTStaticListIterator< T >::SetPosAt
(
const T& value //@parm [in] if this value is in list, set up iterator at its location
)
{
BOOL bReturn = FALSE;
UTLink< T > * pLink = m_StaticList.m_pFirstLink;
while (pLink && pLink->m_Value != value)
pLink = pLink->m_pNextLink;
if (pLink) // found value in list
{
m_pCurrentLink = pLink;
m_pPreviousLink = pLink->m_pPrevLink;
bReturn = TRUE;
}
return bReturn;
} //End SetPosAt
#endif // __UTLIST_H__