home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / vc98 / include / utlist.h < prev    next >
C/C++ Source or Header  |  1998-04-25  |  65KB  |  2,109 lines

  1. #ifndef __UTLIST_H__
  2. #define __UTLIST_H__
  3. /******************************************************************************
  4. Microsoft D.T.C. (Distributed Transaction Coordinator)
  5.  
  6. Copyright 1995 Microsoft Corporation.  All Rights Reserved.
  7.  
  8. @doc
  9.  
  10. @module UTList.h  |
  11.  
  12.     Contains list ADT. 
  13.  
  14. @devnote None
  15. -------------------------------------------------------------------------------
  16.     @rev 1 | 12th Apr,95 | GaganC | Added StaticList & StaticListIterator    
  17.     @rev 0 | 24th Jan,95 | GaganC | Created
  18. *******************************************************************************/
  19.  
  20.  
  21. typedef enum {
  22.                 EXCEPT_MEMORY=0,
  23.                  EXCEPT_UNKNOWN,
  24.                  EXCEPT_LOCKFAILED,
  25.                 EXCEPT_TROUBLE
  26.              }    EXCEPT;  
  27.  
  28.  
  29. //---------- Forward Declarations -------------------------------------------
  30. template <class T> class UTLink;
  31. template <class T> class UTList;
  32. template <class T> class UTListIterator;
  33. template <class T> class UTStaticList;
  34. template <class T> class UTStaticListIterator;
  35.  
  36. //-----**************************************************************-----
  37. // @class template class
  38. //        The UTIterator is an ABSTRACT BASE CLASS for ALL iterators. This
  39. //        class defines the basic operation that all iterators must support
  40. //        regardless of what type of collection it operates upon.
  41. //
  42. //-----**************************************************************-----
  43. template <class T> class UTIterator
  44. {
  45. // @access Public members
  46.  
  47. public:
  48.  
  49.     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  50.     // initialize iterator
  51.     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  52.     // @cmember Initializes the iterator to the first position
  53.     virtual BOOL    Init    (void) =0;
  54.  
  55.     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  56.     // operators
  57.     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  58.     // @cmember Retrieves the current element (pointed to by iterator)
  59.     virtual T        operator()    (void) const =0;
  60.     // @cmember Checks to see if iterator is in a valid position
  61.     virtual BOOL    operator !    (void) const =0;
  62.     // @cmember Moves the iterator forward
  63.     virtual BOOL    operator ++ (int dummy) =0;
  64.     // @cmember Assigns the current element a new value
  65.     virtual void    operator =    (T    newValue) =0;
  66. };
  67.  
  68. //-----**************************************************************-----
  69. // @class Template class
  70. //        The UTLink class is the backbone of a linked list. It holds the
  71. //        actual data of type T (which is the list's data type) and points
  72. //        to the next and previous elements in the list.
  73. //        The class is entirely private to hide all functions and data from
  74. //        everyone but it's friends - which are the UTList and UTListIterator.
  75. //
  76. // @tcarg class | T | data type to store in the link
  77. //-----**************************************************************-----
  78. template <class T> class UTLink
  79. {
  80. // @access Public members
  81. public:
  82.  
  83.     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  84.     // constructors/destructor
  85.     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  86.     // @cmember Constructor
  87.     UTLink (void);
  88.     // @cmember Constructor
  89.     UTLink (const T& LinkValue,UTLink< T > * Prev = NULL,UTLink< T > * Next = NULL);
  90.     // @cmember Copy Constructor
  91.     UTLink (const UTLink< T >&    CopyLink);
  92.     // @cmember Destructor
  93.     virtual ~UTLink (void);
  94.  
  95.     void Init (const T& LinkValue,UTLink< T > * Prev = NULL,UTLink< T > * Next = NULL);
  96.  
  97.     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  98.     // operators
  99.     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  100.     // @cmember Assignment operator
  101.     virtual UTLink< T >& operator =    (const UTLink< T >&    AssignLink);
  102.  
  103.     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  104.     // action protocol
  105.     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  106.     // @cmember Adds a new element before this object
  107.     UTLink< T > * AddBefore    (const T& newValue);
  108.     // @cmember Adds a new element after this object
  109.     UTLink< T > * AddAfter    (const T& newValue);
  110.  
  111.     // @cmember Remove this link from the specified list
  112.     void        RemoveFromList (UTStaticList < T > * pStaticList);
  113.  
  114. public:
  115.     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  116.     // friends
  117.     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  118.     friend class UTList< T >;
  119.     friend class UTStaticList < T >;
  120.     friend class UTListIterator< T >;
  121.     friend class UTStaticListIterator <T>;
  122.  
  123.     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  124.     // data members
  125.     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  126.     // @cmember Value held in the link of type T
  127.     T                m_Value;
  128.     // @cmember Pointer to next link (in list)
  129.     UTLink< T > *    m_pNextLink;
  130.     // @cmember Pointer to previous link (in list)
  131.     UTLink< T > *    m_pPrevLink;
  132. };
  133.  
  134. //-----**************************************************************-----
  135. // @class Template class
  136. //        The UTList class consists of a pointer to the first and last
  137. //        links along with a count of the number of elements in the list.
  138. //        The Add method simply appends to the end of the list.
  139. //        To add elements to a specific location in the list other than
  140. //        the first or last positions, use the UTListIterator methods.
  141. //        To create an ordered list, a user could inherit from the UTList
  142. //        class and override Add to add elements in the correct order.
  143. //        Of course, you would want to do something about the other
  144. //        methods of adding members to the list.
  145. //
  146. // @tcarg class | T | data type to store in the list
  147. //-----**************************************************************-----
  148.  
  149. template <class T> class UTList
  150. {
  151. // @access Public members
  152. public:
  153.  
  154.     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  155.     // constructors/destructor
  156.     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  157.     // @cmember Consructor
  158.     UTList    (void);
  159.     // @cmember Copy Constructor
  160.     UTList    (const UTList< T >& CopyList);
  161.     // @cmember Destructor
  162.     virtual ~UTList (void);
  163.  
  164.     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  165.     // operators
  166.     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  167.     // @cmember Assignment operator
  168.     virtual UTList< T >&        operator =    (const UTList< T >& AssignList);
  169.  
  170.     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  171.     // action protocol
  172.     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  173.     // @cmember Add new value to the list
  174.     virtual void            Add            (const T& newValue);
  175.     // @cmember Insert new value at the front of the list
  176.     virtual void            InsertFirst (const T& newValue);
  177.     // @cmember Insert new value at the end of the list
  178.     virtual void            InsertLast    (const T& newValue);
  179.     // @cmember Remove all elements from the list
  180.     virtual void            RemoveAll    (void);
  181.     // @cmember Remove first element from the list
  182.     virtual BOOL            RemoveFirst (T* pType);
  183.     // @cmember Remove last element from the list
  184.     virtual BOOL            RemoveLast    (T* pType);
  185.     // @cmember Duplicate contents of entire list
  186.     virtual UTList< T > *    Duplicate    (void);
  187.  
  188.     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  189.     // state protocol
  190.     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  191.     // @cmember Retrieve the first value via the out parameter
  192.     virtual BOOL    FirstElement(T* pType) const;
  193.     // @cmember Retrieve the last value via the out parameter
  194.     virtual BOOL    LastElement (T* pType) const;
  195.     // @cmember Does the list include this value?
  196.     virtual BOOL    Includes    (const T& value);
  197.     // @cmember Is the list empty?
  198.     virtual BOOL    IsEmpty        (void) const;
  199.     // @cmember Return the count of elements in the list
  200.     virtual ULONG    GetCount    (void) const;
  201.  
  202.     virtual void    Init (void);
  203. // @access Protected members
  204. protected:
  205.  
  206.     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  207.     // friends
  208.     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  209.     friend class UTListIterator< T >;
  210.  
  211.     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  212.     // data members
  213.     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  214.     // @cmember Count of elements in the list
  215.     ULONG            m_ulCount;
  216.     // @cmember Pointer to the first link in the list
  217.     UTLink< T > *    m_pFirstLink;
  218.     // @cmember Pointer to the last link in the list
  219.     UTLink< T > *    m_pLastLink;
  220. };
  221.  
  222. //-----**************************************************************-----
  223. // @class Template class
  224. //        The UTStaticList class. This is similar to the UTList class except 
  225. //        that it in this the links are all static. Links are provided, to
  226. //        the various methods, they are never created or destroyed as they
  227. //        have been preallocated.
  228. //
  229. // @tcarg class | T | data type to store in the list
  230. //-----**************************************************************-----
  231. template <class T> class UTStaticList
  232. {
  233. // @access Public members
  234. public:
  235.  
  236.     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  237.     // constructors/destructor
  238.     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  239.     // @cmember Consructor
  240.     UTStaticList    (void);
  241.     // @cmember Copy Constructor
  242. //    UTStaticList    (const UTStaticList< T >& CopyList);
  243.     // @cmember Destructor
  244.     virtual ~UTStaticList (void);
  245.  
  246.     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  247.     // operators
  248.     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  249.     // @cmember Assignment operator
  250. //    virtual UTStaticList< T >&        operator =    (const UTStaticList< T >& AssignList);
  251.  
  252.     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  253.     // action protocol
  254.     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  255.     // @cmember Add new link to the list
  256.     virtual void            Add            (UTLink <T> * pLink);
  257.     // @cmember Insert new link at the front of the list
  258.     virtual void            InsertFirst (UTLink <T> * pLink);
  259.     // @cmember Insert new link at the end of the list
  260.     virtual void            InsertLast    (UTLink <T> * pLink);
  261.     // @cmember Remove all elements from the list
  262.     virtual void            RemoveAll    (void);
  263.     // @cmember Remove first element from the list
  264.     virtual BOOL            RemoveFirst (UTLink <T> ** ppLink);
  265.     // @cmember Remove last element from the list
  266.     virtual BOOL            RemoveLast    (UTLink <T> ** ppLink);
  267.     // @cmember Duplicate contents of entire list
  268. //    virtual UTStaticList< T > *    Duplicate    (void);
  269.  
  270.     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  271.     // state protocol
  272.     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  273.     // @cmember Retrieve the first link via the out parameter
  274.     virtual BOOL    FirstElement(UTLink <T> ** ppLink);
  275.     // @cmember Retrieve the last link via the out parameter
  276.     virtual BOOL    LastElement (UTLink <T> ** ppLink);
  277.     // @cmember Does the list include this value?
  278. //    virtual BOOL    Includes    (const UTLink <T> * pLink);
  279.     // @cmember Is the list empty?
  280.     virtual BOOL    IsEmpty        (void) const;
  281.     // @cmember Return the count of elements in the list
  282.     virtual ULONG    GetCount    (void) const;
  283.  
  284.  
  285.     virtual void    Init (void);
  286.  
  287. // @access Protected members
  288. public:
  289.  
  290.     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  291.     // friends
  292.     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  293.     friend class UTStaticListIterator <T>;
  294.  
  295.     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  296.     // data members
  297.     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  298.     // @cmember Count of elements in the list
  299.     ULONG            m_ulCount;
  300.     // @cmember Pointer to the first link in the list
  301.     UTLink< T > *    m_pFirstLink;
  302.     // @cmember Pointer to the last link in the list
  303.     UTLink< T > *    m_pLastLink;
  304. }; //End class UTStaticList
  305.  
  306.  
  307.  
  308.  
  309.  
  310. //-----**************************************************************-----
  311. // @class Template class
  312. //        The UTListIterator class implements the operations that an
  313. //        iterator must support and includes some additional operations
  314. //        that are useful in the context of a linked list.
  315. //        Use AddBefore & AddAfter to add elements to a list based on the
  316. //        iterator's current position within the list.
  317. //
  318. // @tcarg class | T | data type stored in list and type for iterator
  319. // @base public | UTIterator
  320. //-----**************************************************************-----
  321. template <class T> class UTListIterator : public UTIterator< T >
  322. {
  323. // @access Public members
  324. public:
  325.  
  326.     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  327.     // constructors/destructor
  328.     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  329.     // @cmember Constructor
  330.     UTListIterator (UTList< T >&    List);
  331.     // @cmember Copy constructor
  332.     UTListIterator (const UTListIterator< T >&    CopyListItr);
  333.     // @cmember Destructor
  334.     virtual ~UTListIterator(void);
  335.  
  336.     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  337.     // iterator protocol
  338.     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  339.     // @cmember Initialize the iterator to the first link in list
  340.     virtual BOOL    Init        (void);
  341.     // @cmember Retrieve the value from the current link
  342.     virtual T        operator () (void) const;
  343.     // @cmember Does the iterator point to a valid link
  344.     virtual BOOL    operator !    (void) const;
  345.     // @cmember Move the iterator to the next link
  346.     virtual BOOL    operator ++ (int dummy);
  347.     // @cmember Assign the current link a new value
  348.     virtual void    operator =    (T newValue);
  349.  
  350.     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  351.     // additional protocol for list iterator
  352.     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  353.     // @cmember Assignment operator
  354.     virtual UTListIterator< T >& operator =    (const UTListIterator< T >& AssignListItr);
  355.     // @cmember Move the iterator to the previous link
  356.     virtual BOOL    operator --        (int dummy);
  357.     // @cmember Remove the current link from the list
  358.     virtual BOOL    RemoveCurrent    (T* pType);
  359.     // @cmember Insert a new value before the iterator
  360.     virtual void    InsertBefore    (const T& newValue);
  361.     // @cmember Insert a new value after the iterator
  362.     virtual void    InsertAfter        (const T& newValue);
  363.     // @cmember Set the iterator at the first element of this value
  364.     virtual BOOL    SetPosAt        (const T& value);
  365.  
  366. // @access Protected members
  367. public:
  368.  
  369.     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  370.     // data members
  371.     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  372.     // @cmember Position of iterator in list
  373.     UTLink< T > *    m_pCurrentLink;
  374.     // @cmember One position before the current position
  375.     UTLink< T > *    m_pPreviousLink;
  376.     // @cmember List that is being iterated upon
  377.     UTList< T >&        m_List;
  378. };
  379.  
  380. //-----**************************************************************-----
  381. // @class Template class
  382. //        The UTStaticListIterator class implements the operations that an
  383. //        iterator must support and includes some additional operations
  384. //        that are useful in the context of a static linked list.
  385. //        Use AddBefore & AddAfter to add elements to a list based on the
  386. //        iterator's current position within the list.
  387. //
  388. // @tcarg class | T | data type stored in list and type for iterator
  389. // @base public | UTIterator
  390. //-----**************************************************************-----
  391. template <class T> class UTStaticListIterator : public UTIterator< T >
  392. {
  393. // @access Public members
  394. public:
  395.  
  396.     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  397.     // constructors/destructor
  398.     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  399.     // @cmember Constructor
  400.     UTStaticListIterator (UTStaticList< T >&    StaticList);
  401.     // @cmember Copy constructor
  402. //    UTStaticListIterator (const UTStaticListIterator< T >&    CopyListItr);
  403.     // @cmember Destructor
  404.     virtual ~UTStaticListIterator(void);
  405.  
  406.     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  407.     // iterator protocol
  408.     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  409.     // @cmember Initialize the iterator to the first link in list
  410.     virtual BOOL    Init        (void);
  411.     // @cmember Retrieve the value from the current link
  412.     virtual T        operator () (void) const;
  413.     // @cmember Does the iterator point to a valid link
  414.     virtual BOOL    operator !    (void) const;
  415.     // @cmember Move the iterator to the next link
  416.     virtual BOOL    operator ++ (int dummy);
  417.     // @cmember Assign the current link a new value
  418.     virtual void    operator =    (T newValue);
  419.  
  420.     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  421.     // additional protocol for list iterator
  422.     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  423.     // @cmember Assignment operator
  424. //    virtual UTListIterator< T >& operator =    (const UTListIterator< T >& AssignListItr);
  425.     // @cmember Move the iterator to the previous link
  426.     virtual BOOL    operator --        (int dummy);
  427.     // @cmember Remove the current link from the list
  428.     virtual BOOL    RemoveCurrent    (UTLink<T> ** ppLink);
  429.     // @cmember Insert a new value before the iterator
  430. //    virtual void    InsertBefore    (UTLink<T> * pLink);
  431.     // @cmember Insert a new value after the iterator
  432. //    virtual void    InsertAfter        (UTLink<T> * pLink);
  433.     // @cmember Set the iterator at the first element of this value
  434.     virtual BOOL    SetPosAt        (const T& Value);
  435.  
  436. // @access Protected members
  437. public:
  438.  
  439.     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  440.     // data members
  441.     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  442.     // @cmember Position of iterator in list
  443.     UTLink< T > *    m_pCurrentLink;
  444.     // @cmember One position before the current position
  445.     UTLink< T > *    m_pPreviousLink;
  446.     // @cmember List that is being iterated upon
  447.     UTStaticList< T >&        m_StaticList;
  448. };    //End UTStaticListIterator
  449.  
  450.  
  451. //---------- Inline Functions -----------------------------------------------
  452.  
  453. //---------------------------------------------------------------------------
  454. // @mfunc    Constructors
  455. //
  456. // @tcarg None.
  457. //
  458. //
  459. // @rdesc None.
  460. //
  461. //---------------------------------------------------------------------------
  462.  
  463. template <class T> UTLink< T >::UTLink
  464.     (
  465.         void
  466.     )
  467.     {
  468.     // do nothing
  469.     m_pPrevLink = NULL;
  470.     m_pNextLink = NULL;
  471.     }
  472.  
  473.  
  474.  
  475. //---------------------------------------------------------------------------
  476. // @mfunc    Constructors
  477. //
  478. // @tcarg class | T | data type to store in the link
  479. //
  480. //
  481. // @rdesc None.
  482. //
  483. //---------------------------------------------------------------------------
  484.  
  485. template <class T> UTLink< T >::UTLink(
  486.         const T&        LinkValue,    // @parm [in] Value to be stored with link
  487.         UTLink< T > *    Prev,        // @parm [in] pointer to previous link
  488.         UTLink< T > *    Next        // @parm [in] pointer to next link
  489.         )
  490. : m_Value(LinkValue),
  491.     m_pPrevLink(Prev),
  492.     m_pNextLink(Next)
  493.     {
  494.     // do nothing
  495.     }
  496.  
  497. //---------------------------------------------------------------------------
  498. // @tcarg class | T | data type to store in the link
  499. //
  500. // @rdesc None.
  501. //
  502. //---------------------------------------------------------------------------
  503.  
  504. template <class T> UTLink< T >::UTLink(
  505.         const UTLink< T >&    CopyLink    // @parm [in] value to copy into this object
  506.         )
  507.     {
  508.     m_Value        = CopyLink.m_Value;
  509.     m_pPrevLink = CopyLink.m_pPrevLink;
  510.     m_pNextLink = CopyLink.m_pNextLink;
  511.     }
  512.  
  513. //---------------------------------------------------------------------------
  514. // @mfunc    This is the destructor. Currently, it does nothing.
  515. //
  516. // @tcarg class | T | data type to store in the link
  517. //
  518. // @rdesc None.
  519. //
  520. //---------------------------------------------------------------------------
  521.  
  522. template <class T> UTLink< T >::~UTLink(
  523.         void
  524.         )
  525.     {
  526.     // do nothing
  527.     }
  528.  
  529.  
  530. //---------------------------------------------------------------------------
  531. // @mfunc    This is the assignment operator for <c UTLink>.
  532. //
  533. // @tcarg class | T | data type to store in the link
  534. //
  535. // @rdesc    Returns a reference to the newly assigned object
  536. //
  537. //---------------------------------------------------------------------------
  538. template <class T> void UTLink<T>::Init
  539.      (
  540.          const T& LinkValue,UTLink< T > * Prev, UTLink< T > * Next
  541.      )
  542. {
  543.     m_Value     = LinkValue;
  544.     m_pPrevLink = Prev;
  545.     m_pNextLink = Next;
  546. }
  547.  
  548.  
  549.  
  550. //---------------------------------------------------------------------------
  551. // @mfunc    This is the assignment operator for <c UTLink>.
  552. //
  553. // @tcarg class | T | data type to store in the link
  554. //
  555. // @rdesc    Returns a reference to the newly assigned object
  556. //
  557. //---------------------------------------------------------------------------
  558.  
  559. template <class T> UTLink< T >& UTLink< T >::operator =(
  560.         const UTLink< T >&    AssignLink    // @parm [in] value to assign into this object
  561.         )
  562.     {
  563.     m_Value        = AssignLink.m_Value;
  564.     m_pPrevLink = AssignLink.m_pPrevLink;
  565.     m_pNextLink = AssignLink.m_pNextLink;
  566.     return *this;
  567.     }
  568.  
  569. //---------------------------------------------------------------------------
  570. // @mfunc    This method takes a value of type T and creates a new link
  571. //            containing that value. It fixes all pointers surrounding the
  572. //            current link so that it assumes the position just before the
  573. //            current link. It then returns the new link pointer.
  574. //
  575. // @tcarg class | T | data type to store in the link
  576. //
  577. // @rdesc Pointer to the newly added link
  578. //
  579. //---------------------------------------------------------------------------
  580.  
  581. template <class T> UTLink< T > * UTLink< T >::AddBefore(
  582.         const T&    newValue    // @parm [in] Value for new link just after the current link
  583.         )
  584.     {
  585.     // allocate memory for new link
  586.     UTLink< T > * newLink;
  587.  
  588.     newLink = new UTLink< T >(newValue, m_pPrevLink, this);
  589.     if (newLink)
  590.     {
  591.         // if this isn't front of list, have old prev link point to new link
  592.         if (m_pPrevLink)
  593.             {
  594.             m_pPrevLink->m_pNextLink = newLink;
  595.             }
  596.  
  597.         // make sure this link points back to new link added just before it
  598.         m_pPrevLink = newLink;
  599.     }
  600.     else
  601.         throw ( EXCEPT_MEMORY );
  602.  
  603.     return (newLink);
  604.     }
  605.  
  606. //---------------------------------------------------------------------------
  607. // @mfunc    This method takes a value of type T and creates a new link
  608. //            containing that value. It fixes all pointers surrounding the
  609. //            current link so that it assumes the position just after the
  610. //            current link. It then returns the new link pointer.
  611. //
  612. // @tcarg class | T | data type to store in the link
  613. //
  614. // @rdesc Pointer to the newly added link
  615. //
  616. //---------------------------------------------------------------------------
  617.  
  618. template <class T> UTLink< T > * UTLink< T >::AddAfter(
  619.         const T&    newValue    // @parm [in] Value for new link just after the current link
  620.         )
  621.     {
  622.     // allocate memory for new link
  623.     UTLink< T > * newLink;
  624.     newLink = new UTLink< T >(newValue, this, m_pNextLink);
  625.  
  626.     if (newLink)
  627.     {
  628.         // if this isn't end of list, have old next link point back to new link
  629.         if (m_pNextLink)
  630.             {
  631.             m_pNextLink->m_pPrevLink = newLink;
  632.             }
  633.  
  634.         // make sure this link points forward to new link added just after it
  635.         m_pNextLink = newLink;
  636.     }
  637.     else
  638.         throw (EXCEPT_MEMORY);
  639.  
  640.     return (newLink);
  641.     }
  642.  
  643.  
  644.  
  645. //---------------------------------------------------------------------------
  646. // @mfunc    This method takes a pointer to a static list and removes this
  647. //            link from the list.
  648. //
  649. // @tcarg class | T | data type stored in the link
  650. //
  651. // @rdesc    none
  652. //
  653. //---------------------------------------------------------------------------
  654. template <class T> void        UTLink< T >::RemoveFromList (
  655.                                             UTStaticList < T > * pStaticList)
  656. {
  657.     if ((m_pPrevLink == 0x0 ) && (m_pNextLink == 0x0)) 
  658.     {
  659.         pStaticList->m_pLastLink    = 0x0;
  660.         pStaticList->m_pFirstLink    = 0x0;
  661.     }
  662.     else if (m_pPrevLink == 0x0 )
  663.     {
  664.         pStaticList->m_pFirstLink    = m_pNextLink;
  665.     }
  666.     else if (m_pNextLink == 0x0 )
  667.     {
  668.         pStaticList->m_pLastLink    = m_pPrevLink;
  669.     }
  670.     else
  671.     {
  672.         m_pNextLink->m_pPrevLink    = m_pPrevLink; 
  673.         m_pPrevLink->m_pNextLink    = m_pNextLink; 
  674.     }
  675.     
  676.     m_pNextLink = 0x0;
  677.     m_pPrevLink = 0x0;
  678.  
  679.  
  680.     // Update the number of link objects in the list 
  681.     pStaticList->m_ulCount--;
  682.  
  683. }    // End    RemoveFromList
  684.  
  685.  
  686.  
  687.  
  688. //---------------------------------------------------------------------------
  689. // @mfunc    Constructors
  690. //
  691. // @tcarg class | T | data type to store in the list
  692. //
  693. // @syntax    UTList< T >::UTList()
  694. //
  695. // @rdesc    None.
  696. //
  697. //---------------------------------------------------------------------------
  698.  
  699. template <class T> UTList< T >::UTList(
  700.         void
  701.         )
  702. : m_ulCount(0), m_pFirstLink(NULL), m_pLastLink(NULL)
  703.     {
  704.     // do nothing
  705.     }
  706.  
  707. //---------------------------------------------------------------------------
  708. // @tcarg class | T | data type to store in the list
  709. //
  710. // @syntax    UTList< T >::UTList(const UTList< T >&)
  711. //
  712. // @rdesc    None.
  713. //
  714. //---------------------------------------------------------------------------
  715.  
  716. template <class T> UTList< T >::UTList(
  717.         const UTList< T >&    CopyList    // @parm [in] list to be copied
  718.         )
  719.     {
  720.     UTListIterator< T >    itr((UTList< T >&)CopyList);
  721.  
  722.     m_pFirstLink = NULL;
  723.     m_pLastLink = NULL;
  724.     m_ulCount = 0;
  725.     for (itr.Init(); !itr; itr++)
  726.         InsertLast(itr());
  727.     }
  728.  
  729. //---------------------------------------------------------------------------
  730. // @mfunc    This destructor calls <mf UTList::RemoveAll> on the list to
  731. //            delete all links and the memory associated with them.
  732. //
  733. // @tcarg class | T | data type to store in the list
  734. //
  735. //---------------------------------------------------------------------------
  736.  
  737. template <class T> UTList< T >::~UTList(
  738.         void
  739.         )
  740.     {
  741.     RemoveAll();
  742.     }
  743.  
  744.  
  745.  
  746. //---------------------------------------------------------------------------
  747. // @mfunc    Reinitializes the list
  748. //
  749. // @tcarg class | T | data type to store in the list
  750. //
  751. //---------------------------------------------------------------------------
  752. template <class T> void UTList< T >::Init (void)
  753. {
  754.     m_ulCount        = 0x0;    
  755.     m_pFirstLink    = 0x0; 
  756.     m_pLastLink        = 0x0;      
  757. }
  758.  
  759. //---------------------------------------------------------------------------
  760. // @mfunc    This is the assignment operator for <c UTList>. All elements
  761. //            are first removed from this list and then the list is generated
  762. //            by copying the assigned list. Assignment to self is prevented.
  763. //
  764. // @tcarg class | T | data type to store in the list
  765. //
  766. // @rdesc    Returns a reference to the newly assigned object
  767. //---------------------------------------------------------------------------
  768.  
  769. template <class T> UTList< T >& UTList< T >::operator =(
  770.         const UTList< T >&    AssignList    // @parm [in] list to be copied (assigned from)
  771.         )
  772.     {
  773.     UTListIterator< T >    itr((UTList< T >&)AssignList);
  774.  
  775.     // make sure we're not assigning list to itself first
  776.     if (m_pFirstLink != AssignList.m_pFirstLink)
  777.         {
  778.         RemoveAll();    // remove all from this list first
  779.         for (itr.Init(); !itr; itr++)
  780.             InsertLast(itr());
  781.         }
  782.     return *this;
  783.     }
  784.     
  785. //---------------------------------------------------------------------------
  786. // @mfunc    This method duplicates the list into an entirely new list and
  787. //            returns a pointer to the new list.
  788. //
  789. // @tcarg class | T | data type to store in the list
  790. //
  791. // @rdesc Pointer to the newly createe list
  792. //---------------------------------------------------------------------------
  793.  
  794. template <class T> UTList< T > * UTList< T >::Duplicate(
  795.         void
  796.         )
  797. {
  798.     UTListIterator< T >    itr((UTList< T >&) *this);
  799.     UTList< T > *        pNewList = new UTList();
  800.     if (pNewList)
  801.     {
  802.         for (itr.Init(); !itr; itr++)
  803.             pNewList->InsertLast(itr());
  804.     }
  805.     else
  806.         throw (EXCEPT_MEMORY);
  807.  
  808.     return pNewList;
  809. }
  810.     
  811. //---------------------------------------------------------------------------
  812. // @mfunc    This method adds the value to the end of the list by calling
  813. //            <mf UTList::InsertLast>.
  814. //
  815. // @tcarg class | T | data type to store in the list
  816. //
  817. // @rdesc    None.
  818. //---------------------------------------------------------------------------
  819.  
  820. template <class T> void UTList< T >::Add(
  821.         const T& newValue    // @parm [in] value to be added to list
  822.         )
  823.     {
  824.     InsertLast(newValue);
  825.     }
  826.  
  827. //---------------------------------------------------------------------------
  828. // @mfunc    This method inserts the new value at the beginning of the
  829. //            list.
  830. //
  831. // @tcarg class | T | data type to store in the list
  832. //
  833. // @rdesc    None.
  834. //---------------------------------------------------------------------------
  835.  
  836. template <class T> void UTList< T >::InsertFirst(
  837.         const T& newValue    // @parm [in] value to be inserted at beginning of list
  838.         )
  839. {
  840.     UTLink< T > * pLink = m_pFirstLink;        // save ptr to link
  841.     if (pLink)    // list is not empty
  842.         {
  843.         m_pFirstLink = pLink->AddBefore(newValue);
  844.         }
  845.     else        // list is empty
  846.     {
  847.         m_pLastLink = new UTLink< T >(newValue, NULL, NULL);
  848.         if (m_pLastLink)
  849.         {
  850.             m_pFirstLink = m_pLastLink;
  851.         }
  852.         else
  853.             throw (EXCEPT_MEMORY);
  854.     }
  855.     m_ulCount++;
  856. }
  857.  
  858. //---------------------------------------------------------------------------
  859. // @mfunc    This method inserts the new value at the end of the list.
  860. //
  861. // @tcarg class | T | data type to store in the list
  862. //
  863. // @rdesc    None.
  864. //---------------------------------------------------------------------------
  865.  
  866. template <class T> void UTList< T >::InsertLast(
  867.         const T& newValue    // @parm [in] value to be inserted at end of list
  868.         )
  869. {
  870.     UTLink< T > * pLink = m_pLastLink;    // save ptr to link
  871.     if (pLink)    // list is not empty
  872.         m_pLastLink = pLink->AddAfter(newValue);
  873.     else        // list is empty
  874.     {
  875.         m_pLastLink = new UTLink< T >(newValue, NULL, NULL);
  876.         if (m_pLastLink)
  877.         {
  878.             m_pFirstLink = m_pLastLink;
  879.         }
  880.         else
  881.             throw (EXCEPT_MEMORY);
  882.     }
  883.     m_ulCount++;
  884. }
  885.  
  886. //---------------------------------------------------------------------------
  887. // @mfunc    This method moves through the list and deletes each link and
  888. //            then resets the list count and pointers as they were set in
  889. //            the constructor.
  890. //
  891. // @tcarg class | T | data type to store in the list
  892. //
  893. // @rdesc    None.
  894. //---------------------------------------------------------------------------
  895.  
  896. template <class T> void UTList< T >::RemoveAll(
  897.         void
  898.         )
  899.     {
  900.     UTListIterator< T >    itr((UTList< T >&) *this);
  901.     T                    tValue;            // required for RemoveCurrent()
  902.  
  903.     while (!itr)
  904.         itr.RemoveCurrent(&tValue);        // this will reset itr to valid pos
  905.     }
  906.  
  907. //---------------------------------------------------------------------------
  908. // @mfunc    This method removes the first element from the list and fixes
  909. //            the pointer to the first element according to what remains
  910. //            of the list. The former first element is returned through a
  911. //            CALLER allocated variable.
  912. //
  913. // @tcarg class | T | data type to store in the list
  914. //
  915. // @rdesc    Returns a BOOL
  916. // @flag TRUE    | if first element exists and is deleted
  917. // @flag FALSE    | otherwise
  918. //---------------------------------------------------------------------------
  919.  
  920. template <class T> BOOL UTList< T >::RemoveFirst(
  921.         T*    pType    // @parm [out] location to put first element if available
  922.         )
  923.     {
  924.     BOOL            bReturn = FALSE;
  925.     UTLink< T > *    pLink = m_pFirstLink;
  926.  
  927.     if (pLink)
  928.         {
  929.         // isolate the link that is about to be deleted
  930.         m_pFirstLink = m_pFirstLink->m_pNextLink;
  931.         if (m_pFirstLink)
  932.             m_pFirstLink->m_pPrevLink = NULL;
  933.         if (m_pLastLink == pLink)
  934.             m_pLastLink = NULL;
  935.  
  936.         // prepare return value and delete node
  937.         *pType = pLink->m_Value;
  938.         bReturn = TRUE;
  939.         delete pLink;
  940.         m_ulCount--;
  941.         }
  942.     return bReturn;
  943.     }
  944.  
  945. //---------------------------------------------------------------------------
  946. // @mfunc    This method removes the last element from the list and fixes
  947. //            the pointer to the last element according to what remains
  948. //            of the list. The former last element is returned through a
  949. //            CALLER allocated variable.
  950. //
  951. // @tcarg class | T | data type to store in the list
  952. //
  953. // @rdesc    Returns a BOOL
  954. // @flag TRUE    | if last element exists and is deleted
  955. // @flag FALSE    | otherwise
  956. //
  957. //---------------------------------------------------------------------------
  958.  
  959. template <class T> BOOL UTList< T >::RemoveLast(
  960.         T*    pType    // @parm [out] location to put first element if available
  961.         )
  962.     {
  963.     BOOL            bReturn = FALSE;
  964.     UTLink< T > * pLink = m_pLastLink;
  965.  
  966.     if (pLink)
  967.         {
  968.         // isolate the link that is about to be deleted
  969.         m_pLastLink = m_pLastLink->m_pPrevLink;
  970.         if (m_pLastLink)
  971.             m_pLastLink->m_pNextLink = NULL;
  972.         if (m_pFirstLink == pLink)
  973.             m_pFirstLink = NULL;
  974.  
  975.         // prepare return value and delete node
  976.         *pType = pLink->m_Value;
  977.         bReturn = TRUE;
  978.         delete pLink;
  979.         m_ulCount--;
  980.         }
  981.     return bReturn;
  982.     }
  983.  
  984. //---------------------------------------------------------------------------
  985. // @mfunc    This method returns TRUE if there is a first element in the
  986. //            list and fills the out argument (CALLER allocated) with that
  987. //            first element value.
  988. //
  989. // @tcarg class | T | data type to store in the list
  990. //
  991. // @rdesc    Returns a BOOL
  992. // @flag TRUE    | if first element exists
  993. // @flag FALSE    | otherwise
  994. //
  995. //---------------------------------------------------------------------------
  996.  
  997. template <class T> BOOL UTList< T >::FirstElement(
  998.         T*    pType    // @parm [out] location to put first element if available
  999.         ) const
  1000.     {
  1001.     BOOL    bReturn = FALSE;
  1002.     if (m_pFirstLink)
  1003.         {
  1004.         *pType = m_pFirstLink->m_Value;
  1005.         bReturn = TRUE;
  1006.         }
  1007.     return bReturn;
  1008.     }
  1009.  
  1010. //---------------------------------------------------------------------------
  1011. // @mfunc    This method returns TRUE if there is a last element in the
  1012. //            list and fills the out argument (CALLER allocated) with that
  1013. //            last element value.
  1014. //
  1015. // @tcarg class | T | data type to store in the list
  1016. //
  1017. // @rdesc    Returns a BOOL
  1018. // @flag TRUE    | if last element exists
  1019. // @flag FALSE    | otherwise
  1020. //
  1021. //---------------------------------------------------------------------------
  1022.  
  1023. template <class T> BOOL UTList< T >::LastElement(
  1024.         T*    pType    // @parm [out] location to put last element if available
  1025.         ) const
  1026.     {
  1027.     BOOL    bReturn = FALSE;
  1028.     if (m_pLastLink)
  1029.         {
  1030.         *pType = m_pLastLink->m_Value;
  1031.         bReturn = TRUE;
  1032.         }
  1033.     return bReturn;
  1034.     }
  1035.  
  1036. //---------------------------------------------------------------------------
  1037. // @mfunc    This method checks the list for the given value and returns
  1038. //            TRUE if that value is in the list.
  1039. //
  1040. // @tcarg class | T | data type to store in the list
  1041. //
  1042. // @rdesc    Returns a BOOL
  1043. // @flag TRUE    | if element exists in list
  1044. // @flag FALSE    | otherwise
  1045. //
  1046. //---------------------------------------------------------------------------
  1047.  
  1048. template <class T> BOOL UTList< T >::Includes(
  1049.         const T& value    // @parm [in] does list include this value?
  1050.         )
  1051.     {
  1052.     UTListIterator< T >    itr((UTList< T >&) *this);
  1053.  
  1054.     while (!itr && (itr() != value))
  1055.         itr++;
  1056.     return (!itr);
  1057.     }
  1058.  
  1059. //---------------------------------------------------------------------------
  1060. // @mfunc    This method returns TRUE if the count of elements in the list
  1061. //            is ZERO.
  1062. //
  1063. // @tcarg class | T | data type to store in the list
  1064. //
  1065. // @rdesc    Returns a BOOL
  1066. // @flag TRUE    | if list is empty
  1067. // @flag FALSE    | list is not empty
  1068. //---------------------------------------------------------------------------
  1069.  
  1070. template <class T> BOOL UTList< T >::IsEmpty(
  1071.         void
  1072.         ) const
  1073.     {
  1074.     return (m_ulCount == 0);
  1075.     }
  1076.  
  1077. //---------------------------------------------------------------------------
  1078. // @mfunc    This method returns the member variable that indicates the
  1079. //            count of elements. It is incremented whenever values are added
  1080. //            and decremented whenever values are removed.
  1081. //
  1082. // @tcarg class | T | data type to store in the list
  1083. //
  1084. // @rdesc    ULONG
  1085. //---------------------------------------------------------------------------
  1086.  
  1087. template <class T> ULONG UTList< T >::GetCount(
  1088.         void
  1089.         ) const
  1090.     {
  1091.     return (m_ulCount);
  1092.     }
  1093.  
  1094.  
  1095. //---------------------------------------------------------------------------
  1096. // @mfunc    Constructors
  1097. //
  1098. // @tcarg class | T | data type to iterate over
  1099. //
  1100. // @syntax UTListIterator< T >::UTListIterator(UTList< T >&)
  1101. //
  1102. // @rdesc    None.
  1103. //---------------------------------------------------------------------------
  1104.  
  1105. template <class T> UTListIterator< T >::UTListIterator(
  1106.         UTList< T >& List    // @parm [in] list reference for list to be iterated upon
  1107.         )
  1108. : m_List(List)
  1109.     {
  1110.     Init();
  1111.     }
  1112.  
  1113. //---------------------------------------------------------------------------
  1114. // @tcarg class | T | data type to iterate over
  1115. //
  1116. // @syntax UTListIterator< T >::UTListIterator(const UTListIterator< T >&)
  1117. //
  1118. // @rdesc    None.
  1119. //---------------------------------------------------------------------------
  1120.  
  1121. template <class T> UTListIterator< T >::UTListIterator(
  1122.         const UTListIterator< T >&    CopyListItr    // @parm [in] value to copy into this obj
  1123.         )
  1124. : m_List(CopyListItr.m_List),
  1125.     m_pPreviousLink(CopyListItr.m_pPreviousLink),
  1126.     m_pCurrentLink(CopyListItr.m_pCurrentLink)
  1127.     {
  1128.     }
  1129.  
  1130. //---------------------------------------------------------------------------
  1131. // @mfunc    This destruct does nothing because no memory needs to be deleted.
  1132. //
  1133. // @tcarg class | T | data type to iterate over
  1134. //
  1135. // @rdesc    None.
  1136. //---------------------------------------------------------------------------
  1137.  
  1138. template <class T> UTListIterator< T >::~UTListIterator(
  1139.         void
  1140.         )
  1141.     {
  1142.     // do nothing
  1143.     }
  1144.  
  1145. //---------------------------------------------------------------------------
  1146. // @mfunc    This is the assignment operator.
  1147. //
  1148. // @tcarg class | T | data type to iterate over
  1149. //
  1150. // @syntax    UTListIterator< T >& UTListIterator< T >::operator =(const UTListIterator< T >&)
  1151. //
  1152. // @rdesc    Returns a reference to the newly assigned object
  1153. //---------------------------------------------------------------------------
  1154.  
  1155. template <class T> UTListIterator< T >& UTListIterator< T >::operator =(
  1156.         const UTListIterator< T >&    AssignListItr // @parm [in] value to copy into this obj
  1157.         )
  1158.     {
  1159.     // make sure iterators don't already point to the same thing
  1160.     if (m_pCurrentLink != AssignListItr.m_pCurrentLink)
  1161.         {
  1162.         m_List = AssignListItr.m_List;
  1163.         m_pPreviousLink = AssignListItr.m_pPreviousLink;
  1164.         m_pCurrentLink = AssignListItr.m_pCurrentLink;
  1165.         }
  1166.     return *this;
  1167.     }
  1168.  
  1169. //---------------------------------------------------------------------------
  1170. // @tcarg class | T | data type to iterate over
  1171. //
  1172. // @syntax    UTListIterator< T >& UTListIterator< T >::operator =(T)
  1173. //
  1174. // @rdesc    None.
  1175. //---------------------------------------------------------------------------
  1176.  
  1177. template <class T> void UTListIterator< T >::operator =(
  1178.         T    newValue    // @parm [in] value to place in link at current position
  1179.         )
  1180.     {
  1181.     if (m_pCurrentLink)
  1182.         m_pCurrentLink->m_Value = newValue;
  1183.     }
  1184.  
  1185. //---------------------------------------------------------------------------
  1186. // @mfunc    This method sets up the iterator by making its internal state
  1187. //            point to the first element in the list.
  1188. //
  1189. // @tcarg class | T | data type to iterate over
  1190. //
  1191. // @rdesc    Returns a BOOL
  1192. // @flag TRUE    | if there is at least on element in the list which means
  1193. //                    there is something to iterate over
  1194. // @flag FALSE    | if no elements are to be iterated upon
  1195. //---------------------------------------------------------------------------
  1196.  
  1197. template <class T> BOOL UTListIterator< T >::Init(
  1198.         void
  1199.         )
  1200.     {
  1201.     m_pPreviousLink = NULL;
  1202.     m_pCurrentLink = m_List.m_pFirstLink;
  1203.     return (m_pCurrentLink != NULL);
  1204.     }
  1205.  
  1206. //---------------------------------------------------------------------------
  1207. // @mfunc    This operator retrieves the element from the current position
  1208. //            of the iterator.
  1209. //
  1210. // @tcarg class | T | data type to iterate over
  1211. //
  1212. // @rdesc    T    - current value where iterator is located
  1213. //---------------------------------------------------------------------------
  1214.  
  1215. template <class T> T UTListIterator< T >::operator ()(
  1216.         void
  1217.         ) const
  1218.     {
  1219.     //UNDONE:
  1220.     //assert(m_pCurrentLink != NULL);
  1221.     if (m_pCurrentLink)
  1222.         return (m_pCurrentLink->m_Value);
  1223.     else    // incorrect use of iterator, return "bogus" default value
  1224.         {
  1225.         T    tBogusDefault = (T) 0;
  1226.         return tBogusDefault;
  1227.         }
  1228.     }
  1229.  
  1230. //---------------------------------------------------------------------------
  1231. // @mfunc    This operator determines if the current position is valid.
  1232. //
  1233. // @tcarg class | T | data type to iterate over
  1234. //
  1235. // @rdesc    Returns a BOOL
  1236. // @flag TRUE    | if iterator is in a valid position
  1237. // @flag FALSE    | if iterator is NOT in a valid position
  1238. //---------------------------------------------------------------------------
  1239.  
  1240. template <class T> BOOL UTListIterator< T >::operator !(
  1241.         void
  1242.         ) const
  1243.     {
  1244.     return (m_pCurrentLink != NULL);
  1245.     }
  1246.  
  1247. //---------------------------------------------------------------------------
  1248. // @mfunc    This operator increments the iterator to the next element in the
  1249. //            list and returns an indication of whether or not the end of the
  1250. //            list has been passed.
  1251. //
  1252. // @tcarg class | T | data type to iterate over
  1253. //
  1254. // @rdesc    Returns a BOOL
  1255. // @flag TRUE    | if new position is valid
  1256. // @flag FALSE    | if new position is NOT valid (i.e. end of the list)
  1257. //---------------------------------------------------------------------------
  1258.  
  1259. template <class T> BOOL UTListIterator< T >::operator ++(
  1260.         int dummy    // @parm [in] dummy so that operator is on right hand side
  1261.         )
  1262.     {
  1263.     if (m_pCurrentLink)
  1264.         {
  1265.         m_pPreviousLink = m_pCurrentLink;
  1266.         m_pCurrentLink = m_pCurrentLink->m_pNextLink;
  1267.         }
  1268.     return (m_pCurrentLink != NULL);
  1269.     }
  1270.  
  1271. //---------------------------------------------------------------------------
  1272. // @mfunc    This operator decrements the iterator to the prev element in the
  1273. //            list and returns an indication of whether or not the front of the
  1274. //            list has been passed.
  1275. //
  1276. // @tcarg class | T | data type to iterate over
  1277. //
  1278. // @rdesc    Returns a BOOL
  1279. // @flag TRUE    | if new position is valid
  1280. // @flag FALSE    | if new position is NOT valid
  1281. //---------------------------------------------------------------------------
  1282.  
  1283. template <class T> BOOL UTListIterator< T >::operator --(
  1284.         int dummy    // @parm [in] dummy so that operator is on right hand side
  1285.         )
  1286.     {
  1287.     m_pCurrentLink = m_pPreviousLink;
  1288.     if (m_pCurrentLink)
  1289.         {
  1290.         m_pPreviousLink = m_pCurrentLink->m_pPrevLink;
  1291.         }
  1292.     return (m_pCurrentLink != NULL);
  1293.     }
  1294.  
  1295. //---------------------------------------------------------------------------
  1296. // @mfunc    RemoveCurrent deletes the element at the position of the
  1297. //            iterator returning the deleted value through a CALLER
  1298. //            allocated parameter. <nl>
  1299. //            It then fixes the current position to the following: <nl><nl>
  1300. //        If we...                            The we... <nl>
  1301. //        1) removed any link but 1st one        old previous position->next <nl>
  1302. //        2) removed first link(links remain) new first position <nl>
  1303. //        3) removed only link                NULL (no current position) <nl>
  1304. //
  1305. // @tcarg class | T | data type to iterate over
  1306. //
  1307. // @rdesc    Returns a BOOL
  1308. // @flag TRUE    | if current element exists and was removed
  1309. // @flag FALSE    | otherwise
  1310. //---------------------------------------------------------------------------
  1311.  
  1312. template <class T> BOOL UTListIterator< T >::RemoveCurrent(
  1313.         T*    pType    // @parm [out] location to put current element if available
  1314.         )
  1315.     {
  1316.     BOOL    bReturn = FALSE;
  1317.  
  1318.     if (m_pCurrentLink) // remove ONLY if iterator is still in valid position
  1319.         {
  1320.         if (m_pPreviousLink == NULL)    // removing first element
  1321.             {
  1322.             if (m_pCurrentLink->m_pNextLink == NULL)    // ONLY element
  1323.                 {
  1324.                 m_List.m_pFirstLink = m_List.m_pLastLink = NULL;
  1325.                 }
  1326.             else    // first, but not last element
  1327.                 {
  1328.                 m_List.m_pFirstLink = m_pCurrentLink->m_pNextLink;
  1329.                 m_pCurrentLink->m_pNextLink->m_pPrevLink = NULL;
  1330.                 }
  1331.             }
  1332.         else        // not removing first element
  1333.             {
  1334.             if (m_pCurrentLink->m_pNextLink == NULL)    // last element
  1335.                 {
  1336.                 m_List.m_pLastLink = m_pPreviousLink;
  1337.                 m_pPreviousLink->m_pNextLink = NULL;
  1338.                 }
  1339.             else    // neither first nor last element
  1340.                 {
  1341.                 m_pPreviousLink->m_pNextLink = m_pCurrentLink->m_pNextLink;
  1342.                 m_pCurrentLink->m_pNextLink->m_pPrevLink = m_pPreviousLink;
  1343.                 }
  1344.             }
  1345.         *pType = m_pCurrentLink->m_Value;
  1346.         bReturn = TRUE;
  1347.         delete m_pCurrentLink;
  1348.         m_List.m_ulCount--;
  1349.  
  1350.         // now fix up the current iterator pointer
  1351.         if (m_pPreviousLink)
  1352.             m_pCurrentLink = m_pPreviousLink->m_pNextLink;
  1353.         else if (m_List.m_pFirstLink)
  1354.             m_pCurrentLink = m_List.m_pFirstLink;
  1355.         else
  1356.             m_pCurrentLink = NULL;
  1357.         }
  1358.     return bReturn;
  1359.     }
  1360.  
  1361. //---------------------------------------------------------------------------
  1362. // @mfunc    This method adds a new link to the list (using data passed as
  1363. //            an argument) in a position just before the current position
  1364. //            of the iterator.
  1365. //
  1366. // @tcarg class | T | data type to iterate over
  1367. //
  1368. // @rdesc    None.
  1369. //---------------------------------------------------------------------------
  1370.  
  1371. template <class T> void UTListIterator< T >::InsertBefore(
  1372.         const T& newValue    // @parm [in] new data to be added before the current position
  1373.         )
  1374.     {
  1375.     if (m_pCurrentLink)        // add ONLY if iterator is still in valid position
  1376.         {
  1377.         if (m_pPreviousLink)    // not at beginning
  1378.             {
  1379.             m_pCurrentLink->AddBefore(newValue);
  1380.             }
  1381.         else    // at beginning of list
  1382.             {
  1383.             m_List.m_pFirstLink = m_pCurrentLink->AddBefore(newValue);
  1384.             }
  1385.         m_List.m_ulCount++;
  1386.         // fix prev pointer which is now two links away
  1387.         m_pPreviousLink = m_pCurrentLink->m_pPrevLink;
  1388.         }
  1389.     }
  1390.  
  1391. //---------------------------------------------------------------------------
  1392. // @mfunc    This method adds a new link to the list (using data passed as
  1393. //            an argument) in a position immediately following the current
  1394. //            position of the iterator.
  1395. //
  1396. // @tcarg class | T | data type to iterate over
  1397. //
  1398. // @rdesc    None.
  1399. //---------------------------------------------------------------------------
  1400.  
  1401. template <class T> void UTListIterator< T >::InsertAfter(
  1402.         const T& newValue    // @parm [in] new data to be added after the current position
  1403.         )
  1404.     {
  1405.     if (m_pCurrentLink)        // add ONLY if iterator is still in valid position
  1406.         {
  1407.         if (m_pCurrentLink->m_pNextLink)    // not at end
  1408.             {
  1409.             m_pCurrentLink->AddAfter(newValue);
  1410.             }
  1411.         else    // at end of list
  1412.             {
  1413.             m_List.m_pLastLink = m_pCurrentLink->AddAfter(newValue);
  1414.             }
  1415.         m_List.m_ulCount++;
  1416.         }
  1417.     }
  1418.  
  1419. //---------------------------------------------------------------------------
  1420. // @mfunc    This method resets the iterator at the value passed
  1421. //            in as an argument if it exists in the list and returns
  1422. //            TRUE in that case indicating that it did change position.
  1423. //            If the value does not exist, the position remains
  1424. //            unchanged, and FALSE is returned to indicate this.
  1425. //
  1426. // @tcarg class | T | data type to iterate over
  1427. //
  1428. // @rdesc    Returns a BOOL
  1429. // @flag TRUE    | if posistion has changed
  1430. // @flag FALSE    | otherwise
  1431. //---------------------------------------------------------------------------
  1432.  
  1433. template <class T> BOOL UTListIterator< T >::SetPosAt(
  1434.         const T& value    //@parm [in] if this value is in list, set up iterator at its location
  1435.         )
  1436.     {
  1437.     BOOL bReturn = FALSE;
  1438.     UTLink< T > *    pLink = m_List.m_pFirstLink;
  1439.     
  1440.     while (pLink && pLink->m_Value != value)
  1441.         pLink = pLink->m_pNextLink;
  1442.     if (pLink)    // found value in list
  1443.         {
  1444.         m_pCurrentLink = pLink;
  1445.         m_pPreviousLink = pLink->m_pPrevLink;
  1446.         bReturn = TRUE;
  1447.         }
  1448.     return bReturn;
  1449.     }
  1450.  
  1451.  
  1452.  
  1453. //---------------------------------------------------------------------------
  1454. // @mfunc    Constructors
  1455. //
  1456. // @tcarg class | T | data type to store in the list
  1457. //
  1458. // @syntax    UTStaticList< T >::UTStaticList()
  1459. //
  1460. // @rdesc    None.
  1461. //
  1462. //---------------------------------------------------------------------------
  1463.  
  1464. template <class T> UTStaticList< T >::UTStaticList(
  1465.         void
  1466.         )
  1467. : m_ulCount(0), m_pFirstLink(NULL), m_pLastLink(NULL)
  1468.     {
  1469.     // do nothing
  1470.     }
  1471.  
  1472.  
  1473. //---------------------------------------------------------------------------
  1474. // @mfunc    This destructor does nothing
  1475. //
  1476. // @tcarg class | T | data type to store in the list
  1477. //
  1478. //---------------------------------------------------------------------------
  1479.  
  1480. template <class T> UTStaticList< T >::~UTStaticList(
  1481.         void
  1482.         )
  1483.     {
  1484.         //Do nothing
  1485.     }
  1486.  
  1487. //---------------------------------------------------------------------------
  1488. // @mfunc    Reinitializes the list
  1489. //
  1490. // @tcarg class | T | data type to store in the list
  1491. //
  1492. //---------------------------------------------------------------------------
  1493. template <class T> void UTStaticList< T >::Init (void)
  1494. {
  1495.     m_ulCount        = 0x0;    
  1496.     m_pFirstLink    = 0x0; 
  1497.     m_pLastLink        = 0x0;      
  1498. }
  1499.  
  1500.  
  1501. //---------------------------------------------------------------------------
  1502. // @mfunc    This method adds the link to the end of the list by calling
  1503. //            <mf UTStaticList::InsertLast>.
  1504. //
  1505. // @tcarg class | T | data type to store in the list
  1506. //
  1507. // @rdesc    None.
  1508. //---------------------------------------------------------------------------
  1509.  
  1510. template <class T> void UTStaticList< T >::Add(
  1511.          UTLink <T> * pLink    // @parm [in] Link to be added to list
  1512.         )
  1513.     {
  1514.     InsertLast(pLink);
  1515.     }
  1516.  
  1517.  
  1518. //---------------------------------------------------------------------------
  1519. // @mfunc    This method inserts the new value at the beginning of the
  1520. //            list.
  1521. //
  1522. // @tcarg class | T | data type to store in the list
  1523. //
  1524. // @rdesc    None.
  1525. //---------------------------------------------------------------------------
  1526.  
  1527. template <class T> void UTStaticList< T >::InsertFirst(
  1528.          UTLink <T> * pLink    // @parm [in] link to be inserted at beginning of list
  1529.         )
  1530. {
  1531.     if (m_pFirstLink)    // list is not empty
  1532.     {
  1533.         pLink->m_pPrevLink             = (UTLink<T> *) 0;
  1534.         pLink->m_pNextLink             = m_pFirstLink;
  1535.         m_pFirstLink->m_pPrevLink     = pLink;
  1536.         m_pFirstLink                = pLink;
  1537.     }
  1538.     else        // list is empty
  1539.     {
  1540.         m_pFirstLink = pLink;
  1541.         m_pLastLink = pLink;
  1542.     }
  1543.  
  1544.     m_ulCount++;
  1545. } //End UTStaticList::InsertFirst
  1546.  
  1547.  
  1548. //---------------------------------------------------------------------------
  1549. // @mfunc    This method inserts the new link at the end of the list.
  1550. //
  1551. // @tcarg class | T | data type to store in the list
  1552. //
  1553. // @rdesc    None.
  1554. //---------------------------------------------------------------------------
  1555.  
  1556. template <class T> void UTStaticList< T >::InsertLast(
  1557.          UTLink <T> * pLink    // @parm [in] link to be inserted at end of list
  1558.         )
  1559. {
  1560.     if (m_pLastLink)    // list is not empty
  1561.     {
  1562.         pLink->m_pNextLink             = (UTLink<T> *) 0;
  1563.         pLink->m_pPrevLink             = m_pLastLink;
  1564.         m_pLastLink->m_pNextLink     = pLink;
  1565.         m_pLastLink                    = pLink;
  1566.     }
  1567.     else        // list is empty
  1568.     {
  1569.         m_pFirstLink = pLink;
  1570.         m_pLastLink = pLink;
  1571.     }
  1572.     
  1573.     //Increment the count
  1574.     m_ulCount++;
  1575.  
  1576. } //End UTStaticList::InsertLast
  1577.  
  1578.  
  1579.  
  1580.  
  1581.  
  1582. //---------------------------------------------------------------------------
  1583. // @mfunc    This method  resets the list count and pointers as they were set in
  1584. //            the constructor.
  1585. //
  1586. // @tcarg class | T | data type to store in the list
  1587. //
  1588. // @rdesc    None.
  1589. //---------------------------------------------------------------------------
  1590.  
  1591. template <class T> void UTStaticList< T >::RemoveAll
  1592.     (
  1593.         void
  1594.     )
  1595. {
  1596.     //UNDONE - gaganc Need to reset the pointers of all the links to NULL
  1597.         m_pFirstLink     = NULL;
  1598.         m_pLastLink      = NULL;
  1599.         m_ulCount         = 0;
  1600.  
  1601. } //End UTStaticList::RemoveAll
  1602.  
  1603.  
  1604. //---------------------------------------------------------------------------
  1605. // @mfunc    This method removes the first element from the list and fixes
  1606. //            the pointer to the first element according to what remains
  1607. //            of the list. The former first element is returned through a
  1608. //            CALLER allocated variable.
  1609. //
  1610. // @tcarg class | T | data type to store in the list
  1611. //
  1612. // @rdesc    Returns a BOOL
  1613. // @flag TRUE    | if first element exists and is deleted
  1614. // @flag FALSE    | otherwise
  1615. //---------------------------------------------------------------------------
  1616.  
  1617. template <class T> BOOL UTStaticList< T >::RemoveFirst(
  1618.         UTLink<T> **    ppLink    // @parm [out] location to put first element if available
  1619.         )
  1620. {
  1621.     BOOL            bReturn = FALSE;
  1622.  
  1623.     //Assign the out param the first link
  1624.     *ppLink     = m_pFirstLink;
  1625.  
  1626.     if (m_pFirstLink)
  1627.     {
  1628.         // Reset the first link
  1629.         m_pFirstLink = m_pFirstLink->m_pNextLink;
  1630.  
  1631.         if (m_pFirstLink)
  1632.             m_pFirstLink->m_pPrevLink = NULL;
  1633.  
  1634.         if (m_pLastLink == *ppLink)
  1635.             m_pLastLink = NULL;
  1636.  
  1637.         bReturn = TRUE;
  1638.  
  1639.         m_ulCount--;
  1640.     }
  1641.  
  1642.     //Remember to clear previous and the next pointers in the link
  1643.     if (*ppLink)
  1644.     {
  1645.         (*ppLink)->m_pNextLink = NULL;
  1646.         (*ppLink)->m_pPrevLink = NULL;
  1647.     }
  1648.  
  1649.     return bReturn;
  1650. } //End UTStaticList::RemoveFirst
  1651.  
  1652. //---------------------------------------------------------------------------
  1653. // @mfunc    This method removes the last element from the list and fixes
  1654. //            the pointer to the last element according to what remains
  1655. //            of the list. The former last element is returned through a
  1656. //            CALLER allocated variable.
  1657. //
  1658. // @tcarg class | T | data type to store in the list
  1659. //
  1660. // @rdesc    Returns a BOOL
  1661. // @flag TRUE    | if last element exists and is deleted
  1662. // @flag FALSE    | otherwise
  1663. //
  1664. //---------------------------------------------------------------------------
  1665.  
  1666. template <class T> BOOL UTStaticList< T >::RemoveLast(
  1667.         UTLink<T> **    ppLink    // @parm [out] location to put first element if available
  1668.         )
  1669. {
  1670.     BOOL            bReturn = FALSE;
  1671.  
  1672.     *ppLink = m_pLastLink;
  1673.  
  1674.     if (m_pLastLink)
  1675.     {
  1676.         // isolate the link that is about to be deleted
  1677.         m_pLastLink = m_pLastLink->m_pPrevLink;
  1678.  
  1679.         if (m_pLastLink)
  1680.             m_pLastLink->m_pNextLink = NULL;
  1681.  
  1682.         if (m_pFirstLink == *ppLink)
  1683.             m_pFirstLink = NULL;
  1684.  
  1685.         bReturn = TRUE;
  1686.         m_ulCount--;
  1687.     }
  1688.  
  1689.     //Remember to clear previous and the next pointers in the link
  1690.     if (*ppLink)
  1691.     {
  1692.         (*ppLink)->m_pNextLink = NULL;
  1693.         (*ppLink)->m_pPrevLink = NULL;
  1694.     }
  1695.  
  1696.     return bReturn;
  1697. } //End UTStaticList::RemoveLast
  1698.  
  1699. //---------------------------------------------------------------------------
  1700. // @mfunc    This method returns TRUE if there is a first element in the
  1701. //            list and fills the out argument (CALLER allocated) with that
  1702. //            first element value.
  1703. //
  1704. // @tcarg class | T | data type to store in the list
  1705. //
  1706. // @rdesc    Returns a BOOL
  1707. // @flag TRUE    | if first element exists
  1708. // @flag FALSE    | otherwise
  1709. //
  1710. //---------------------------------------------------------------------------
  1711.  
  1712. template <class T> BOOL UTStaticList< T >::FirstElement
  1713.     (
  1714.         UTLink <T> **    ppLink    // @parm [out] location to put first element if available
  1715.     )
  1716. {
  1717.     BOOL    bReturn = FALSE;
  1718.  
  1719.     //If the first elment exists then return TRUE else FALSE
  1720.     if (m_pFirstLink)
  1721.         {
  1722.             *ppLink = m_pFirstLink;
  1723.             bReturn = TRUE;
  1724.         }
  1725.  
  1726.     return bReturn;
  1727. }
  1728.  
  1729.  
  1730. //---------------------------------------------------------------------------
  1731. // @mfunc    This method returns TRUE if there is a last element in the
  1732. //            list and fills the out argument (CALLER allocated) with that
  1733. //            last element value.
  1734. //
  1735. // @tcarg class | T | data type to store in the list
  1736. //
  1737. // @rdesc    Returns a BOOL
  1738. // @flag TRUE    | if last element exists
  1739. // @flag FALSE    | otherwise
  1740. //
  1741. //---------------------------------------------------------------------------
  1742.  
  1743. template <class T> BOOL UTStaticList< T >::LastElement
  1744.     (
  1745.         UTLink<T> **    ppLink    // @parm [out] location to put last element if available
  1746.     ) 
  1747. {
  1748.     BOOL    bReturn = FALSE;
  1749.  
  1750.     if (m_pLastLink)
  1751.     {
  1752.         *ppLink = m_pLastLink;
  1753.         bReturn = TRUE;
  1754.     }
  1755.     return bReturn;
  1756. }
  1757.  
  1758.  
  1759. //---------------------------------------------------------------------------
  1760. // @mfunc    This method returns TRUE if the count of elements in the list
  1761. //            is ZERO.
  1762. //
  1763. // @tcarg class | T | data type to store in the list
  1764. //
  1765. // @rdesc    Returns a BOOL
  1766. // @flag TRUE    | if list is empty
  1767. // @flag FALSE    | list is not empty
  1768. //---------------------------------------------------------------------------
  1769.  
  1770. template <class T> BOOL UTStaticList< T >::IsEmpty
  1771.     (
  1772.         void
  1773.     ) const
  1774. {
  1775.     return (m_ulCount == 0);
  1776. } //End UTStaticList::IsEmpty
  1777.  
  1778. //---------------------------------------------------------------------------
  1779. // @mfunc    This method returns the member variable that indicates the
  1780. //            count of elements. It is incremented whenever values are added
  1781. //            and decremented whenever values are removed.
  1782. //
  1783. // @tcarg class | T | data type to store in the list
  1784. //
  1785. // @rdesc    ULONG
  1786. //---------------------------------------------------------------------------
  1787.  
  1788. template <class T> ULONG UTStaticList< T >::GetCount
  1789.     (
  1790.         void
  1791.     ) const
  1792. {
  1793.     return (m_ulCount);
  1794. } //End UTStaticList::GetCount
  1795.  
  1796.  
  1797.  
  1798.  
  1799.  
  1800.  
  1801. //---------------------------------------------------------------------------
  1802. // @mfunc    Constructors
  1803. //
  1804. // @tcarg class | T | data type to iterate over
  1805. //
  1806. // @syntax UTStaticListIterator< T >::UTStaticListIterator(UTStaticList< T >&)
  1807. //
  1808. // @rdesc    None.
  1809. //---------------------------------------------------------------------------
  1810.  
  1811. template <class T> UTStaticListIterator< T >::UTStaticListIterator
  1812.     (
  1813.         UTStaticList< T >& StaticList    // @parm [in] list reference for list to be iterated upon
  1814.     )
  1815.     : m_StaticList(StaticList)
  1816. {
  1817.     Init();
  1818. }
  1819.  
  1820.  
  1821. //---------------------------------------------------------------------------
  1822. // @mfunc    This destruct does nothing because no memory needs to be deleted.
  1823. //
  1824. // @tcarg class | T | data type to iterate over
  1825. //
  1826. // @rdesc    None.
  1827. //---------------------------------------------------------------------------
  1828.  
  1829. template <class T> UTStaticListIterator< T >::~UTStaticListIterator
  1830.     (
  1831.         void
  1832.     )
  1833. {
  1834.     // do nothing
  1835. }
  1836.  
  1837. //---------------------------------------------------------------------------
  1838. // @mfunc    This is the assignment operator.
  1839. //
  1840. // @tcarg class | T | data type to iterate over
  1841. //
  1842. // @syntax    UTStaticListIterator< T >& UTStaticListIterator< T >
  1843. //                ::operator =(const UTListIterator< T >&)
  1844. //
  1845. // @rdesc    Returns a reference to the newly assigned object
  1846. //---------------------------------------------------------------------------
  1847.  
  1848. template <class T> UTStaticListIterator< T >& UTStaticListIterator< T >::operator =
  1849.     (
  1850.         const UTStaticListIterator< T >&    AssignListItr 
  1851.                                     // @parm [in] value to copy into this obj
  1852.     )
  1853. {
  1854.     // make sure iterators don't already point to the same thing
  1855.     if (m_pCurrentLink != AssignListItr.m_pCurrentLink)
  1856.     {
  1857.         m_StaticList     = AssignListItr.m_StaticList;
  1858.         m_pPreviousLink = AssignListItr.m_pPreviousLink;
  1859.         m_pCurrentLink     = AssignListItr.m_pCurrentLink;
  1860.     }
  1861.     return *this;
  1862. } //End UTStaticListIterator
  1863.  
  1864. //---------------------------------------------------------------------------
  1865. // @tcarg class | T | data type to iterate over
  1866. //
  1867. // @syntax    UTStaticListIterator< T >& UTStaticListIterator< T >::operator =(T)
  1868. //
  1869. // @rdesc    None.
  1870. //---------------------------------------------------------------------------
  1871.  
  1872. template <class T> void UTStaticListIterator< T >::operator =(
  1873.         T    newValue    // @parm [in] value to place in link at current position
  1874.         )
  1875. {
  1876.     //CAUTION : -- Don't use this THIS WILL CRASH
  1877.     UTLink <short> * pLink = 0;
  1878.     
  1879.     pLink->m_Value;
  1880. }
  1881.  
  1882. //---------------------------------------------------------------------------
  1883. // @mfunc    This method sets up the iterator by making its internal state
  1884. //            point to the first element in the list.
  1885. //
  1886. // @tcarg class | T | data type to iterate over
  1887. //
  1888. // @rdesc    Returns a BOOL
  1889. // @flag TRUE    | if there is at least on element in the list which means
  1890. //                    there is something to iterate over
  1891. // @flag FALSE    | if no elements are to be iterated upon
  1892. //---------------------------------------------------------------------------
  1893.  
  1894. template <class T> BOOL UTStaticListIterator< T >::Init
  1895.     (
  1896.         void
  1897.     )
  1898. {
  1899.     m_pPreviousLink = NULL;
  1900.     m_pCurrentLink = m_StaticList.m_pFirstLink;
  1901.  
  1902.     return (m_pCurrentLink != NULL);
  1903. }
  1904.  
  1905. //---------------------------------------------------------------------------
  1906. // @mfunc    This operator retrieves the element from the current position
  1907. //            of the iterator.
  1908. //
  1909. // @tcarg class | T | data type to iterate over
  1910. //
  1911. // @rdesc    T    - current value where iterator is located
  1912. //---------------------------------------------------------------------------
  1913.  
  1914. template <class T> T UTStaticListIterator< T >::operator ()
  1915.     (
  1916.         void
  1917.     ) const
  1918. {
  1919.     if (m_pCurrentLink)
  1920.         return (m_pCurrentLink->m_Value);
  1921.     else    // incorrect use of iterator, return "bogus" default value
  1922.     {
  1923.         T tBogusDefault = (T) 0;
  1924.         return tBogusDefault;
  1925.     }
  1926. }
  1927.  
  1928. //---------------------------------------------------------------------------
  1929. // @mfunc    This operator determines if the current position is valid.
  1930. //
  1931. // @tcarg class | T | data type to iterate over
  1932. //
  1933. // @rdesc    Returns a BOOL
  1934. // @flag TRUE    | if iterator is in a valid position
  1935. // @flag FALSE    | if iterator is NOT in a valid position
  1936. //---------------------------------------------------------------------------
  1937.  
  1938. template <class T> BOOL UTStaticListIterator< T >::operator !
  1939.     (
  1940.         void
  1941.     ) const
  1942. {
  1943.     return (m_pCurrentLink != NULL);
  1944. }
  1945.  
  1946. //---------------------------------------------------------------------------
  1947. // @mfunc    This operator increments the iterator to the next element in the
  1948. //            list and returns an indication of whether or not the end of the
  1949. //            list has been passed.
  1950. //
  1951. // @tcarg class | T | data type to iterate over
  1952. //
  1953. // @rdesc    Returns a BOOL
  1954. // @flag TRUE    | if new position is valid
  1955. // @flag FALSE    | if new position is NOT valid (i.e. end of the list)
  1956. //---------------------------------------------------------------------------
  1957.  
  1958. template <class T> BOOL UTStaticListIterator< T >::operator ++
  1959.     (
  1960.         int dummy    // @parm [in] dummy so that operator is on right hand side
  1961.     )
  1962. {
  1963.     if (m_pCurrentLink)
  1964.     {
  1965.         m_pPreviousLink = m_pCurrentLink;
  1966.         m_pCurrentLink = m_pCurrentLink->m_pNextLink;
  1967.     }
  1968.     return (m_pCurrentLink != NULL);
  1969. }
  1970.  
  1971. //---------------------------------------------------------------------------
  1972. // @mfunc    This operator decrements the iterator to the prev element in the
  1973. //            list and returns an indication of whether or not the front of the
  1974. //            list has been passed.
  1975. //
  1976. // @tcarg class | T | data type to iterate over
  1977. //
  1978. // @rdesc    Returns a BOOL
  1979. // @flag TRUE    | if new position is valid
  1980. // @flag FALSE    | if new position is NOT valid
  1981. //---------------------------------------------------------------------------
  1982.  
  1983. template <class T> BOOL UTStaticListIterator< T >::operator --
  1984.     (
  1985.         int dummy    // @parm [in] dummy so that operator is on right hand side
  1986.     )
  1987. {
  1988.     m_pCurrentLink = m_pPreviousLink;
  1989.     if (m_pCurrentLink)
  1990.     {
  1991.         m_pPreviousLink = m_pCurrentLink->m_pPrevLink;
  1992.     }
  1993.     return (m_pCurrentLink != NULL);
  1994. }
  1995.  
  1996.  
  1997. //---------------------------------------------------------------------------
  1998. // @mfunc    RemoveCurrent deletes the element at the position of the
  1999. //            iterator returning the deleted value through a CALLER
  2000. //            allocated parameter. <nl>
  2001. //            It then fixes the current position to the following: <nl><nl>
  2002. //        If we...                            The we... <nl>
  2003. //        1) removed any link but 1st one        old previous position->next <nl>
  2004. //        2) removed first link(links remain) new first position <nl>
  2005. //        3) removed only link                NULL (no current position) <nl>
  2006. //
  2007. // @tcarg class | T | data type to iterate over
  2008. //
  2009. // @rdesc    Returns a BOOL
  2010. // @flag TRUE    | if current element exists and was removed
  2011. // @flag FALSE    | otherwise
  2012. //---------------------------------------------------------------------------
  2013.  
  2014. template <class T> BOOL UTStaticListIterator< T >::RemoveCurrent
  2015.     (
  2016.         UTLink <T> ** ppLink // @parm [out] location to put current element if available
  2017.     )
  2018. {
  2019.     BOOL    bReturn = FALSE;
  2020.  
  2021.     if (m_pCurrentLink) // remove ONLY if iterator is still in valid position
  2022.         {
  2023.         if (m_pPreviousLink == NULL)    // removing first element
  2024.         {
  2025.             if (m_pCurrentLink->m_pNextLink == NULL)    // ONLY element
  2026.             {
  2027.                 m_StaticList.m_pFirstLink = m_StaticList.m_pLastLink = NULL;
  2028.             }
  2029.             else    // first, but not last element
  2030.             {
  2031.                 m_StaticList.m_pFirstLink = m_pCurrentLink->m_pNextLink;
  2032.                 m_pCurrentLink->m_pNextLink->m_pPrevLink = NULL;
  2033.             }
  2034.         }
  2035.         else        // not removing first element
  2036.         {
  2037.             if (m_pCurrentLink->m_pNextLink == NULL)    // last element
  2038.             {
  2039.                 m_StaticList.m_pLastLink = m_pPreviousLink;
  2040.                 m_pPreviousLink->m_pNextLink = NULL;
  2041.             }
  2042.             else    // neither first nor last element
  2043.             {
  2044.                 m_pPreviousLink->m_pNextLink = m_pCurrentLink->m_pNextLink;
  2045.                 m_pCurrentLink->m_pNextLink->m_pPrevLink = m_pPreviousLink;
  2046.             }
  2047.         }
  2048.         *ppLink = m_pCurrentLink;
  2049.         (*ppLink)->m_pNextLink = 0;
  2050.         (*ppLink)->m_pPrevLink = 0;
  2051.  
  2052.         bReturn = TRUE;
  2053.  
  2054.         m_StaticList.m_ulCount--;
  2055.  
  2056.         // now fix up the current iterator pointer
  2057.         if (m_pPreviousLink)
  2058.         {
  2059.             m_pCurrentLink = m_pPreviousLink->m_pNextLink;
  2060.         }
  2061.         else if (m_StaticList.m_pFirstLink)
  2062.         {
  2063.             m_pCurrentLink = m_StaticList.m_pFirstLink;
  2064.         }
  2065.         else
  2066.         {
  2067.             m_pCurrentLink = NULL;
  2068.         }
  2069.     }
  2070.     return bReturn;
  2071. } //End RemoveCurrent
  2072.  
  2073. //---------------------------------------------------------------------------
  2074. // @mfunc    This method resets the iterator at the value passed
  2075. //            in as an argument if it exists in the list and returns
  2076. //            TRUE in that case indicating that it did change position.
  2077. //            If the value does not exist, the position remains
  2078. //            unchanged, and FALSE is returned to indicate this.
  2079. //
  2080. // @tcarg class | T | data type to iterate over
  2081. //
  2082. // @rdesc    Returns a BOOL
  2083. // @flag TRUE    | if posistion has changed
  2084. // @flag FALSE    | otherwise
  2085. //---------------------------------------------------------------------------
  2086.  
  2087. template <class T> BOOL UTStaticListIterator< T >::SetPosAt
  2088.     (
  2089.         const T& value    //@parm [in] if this value is in list, set up iterator at its location
  2090.     )
  2091. {
  2092.     BOOL bReturn = FALSE;
  2093.     UTLink< T > *    pLink = m_StaticList.m_pFirstLink;
  2094.     
  2095.     while (pLink && pLink->m_Value != value)
  2096.         pLink = pLink->m_pNextLink;
  2097.     if (pLink)    // found value in list
  2098.         {
  2099.         m_pCurrentLink = pLink;
  2100.         m_pPreviousLink = pLink->m_pPrevLink;
  2101.         bReturn = TRUE;
  2102.         }
  2103.     return bReturn;
  2104. } //End SetPosAt
  2105.  
  2106.  
  2107.  
  2108. #endif    // __UTLIST_H__
  2109.