Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
cxx_base.h
Go to the documentation of this file.
00001 /*
00002 
00003   Copyright (C) 2000, 2001 Silicon Graphics, Inc.  All Rights Reserved.
00004 
00005   This program is free software; you can redistribute it and/or modify it
00006   under the terms of version 2 of the GNU General Public License as
00007   published by the Free Software Foundation.
00008 
00009   This program is distributed in the hope that it would be useful, but
00010   WITHOUT ANY WARRANTY; without even the implied warranty of
00011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
00012 
00013   Further, this software is distributed without any warranty that it is
00014   free of the rightful claim of any third person regarding infringement 
00015   or the like.  Any license provided herein, whether implied or 
00016   otherwise, applies only to this software file.  Patent licenses, if 
00017   any, provided herein do not apply to combinations of this program with 
00018   other software, or any other product whatsoever.  
00019 
00020   You should have received a copy of the GNU General Public License along
00021   with this program; if not, write the Free Software Foundation, Inc., 59
00022   Temple Place - Suite 330, Boston MA 02111-1307, USA.
00023 
00024   Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
00025   Mountain View, CA 94043, or:
00026 
00027   http://www.sgi.com
00028 
00029   For further information regarding this notice, see:
00030 
00031   http://oss.sgi.com/projects/GenInfo/NoticeExplan
00032 
00033 */
00034 
00035 
00036 //-*-c++-*-
00037 /* ====================================================================
00038  * ====================================================================
00039  *
00040  *
00041  * Revision history:
00042  *  18-SEP-94 shin - Original Version
00043  *  30-SEP-94 dkchen - Added doubly linked list
00044  *
00045  * Description:
00046  *
00047  * ====================================================================
00048  * ====================================================================
00049  */
00050 
00051 #ifndef cxx_base_INCLUDED
00052 #define cxx_base_INCLUDED
00053 
00054 #include "errors.h"
00055 
00056 #ifdef _KEEP_RCS_ID
00057 #endif /* _KEEP_RCS_ID */
00058 
00059 // NOTE:  FOLLOW THESE CODING CONVENTIONS:
00060 //
00061 //        All classes defined in this file are base classes.  Please
00062 //        follow these conventions:
00063 //
00064 //        To avoid undesirable effect of default assignment operator
00065 //        and default copy constructor, please create a "private"
00066 //        operator= and copy constructor for all classes.
00067 
00068 // Singly Linked List
00069 //
00070 //      Here's how to make and use a singly linked list.  Suppose you would
00071 //      like to use a list containing pairs of integers.  You would do this:
00072 //
00073 //      class II_NODE : public SLIST_NODE {
00074 //        DECLARE_SLIST_NODE_CLASS(II_NODE);
00075 //       public:
00076 //         INT int1;
00077 //         INT int2;
00078 //         II_NODE(INT i1, INT i2) : int1(i1), int2(i2) {}
00079 //         ~II_NODE() {}
00080 //       };
00081 //
00082 //      class II_LIST : public SLIST {
00083 //        DECLARE_SLIST_CLASS(II_LIST, II_NODE);
00084 //       public:
00085 //         // --> YOU MUST SUPPLY THIS, AND YOU MUST SUPPLY IT YOURSELF <--
00086 //         ~II_LIST();
00087 //      };
00088 //
00089 //      class II_ITER : public SLIST_ITER {
00090 //        DECLARE_SLIST_ITER_CLASS(II_ITER, II_NODE, II_LIST);
00091 //      };
00092 //
00093 //      class II_CONST_ITER : public SLIST_ITER {
00094 //        DECLARE_SLIST_CONST_ITER_CLASS(II_CONST_ITER, II_NODE, II_LIST);
00095 //      };
00096 //
00097 // Doing that supplies you with the following public functions
00098 // and classes.  Here I'm using II_NODE, etc as an example ...
00099 // obviously you will have different names for your classes.  The
00100 // member functions retain their names.
00101 //
00102 //
00103 //
00104 // II_NODE: defines the basic element of singly linked list.  It
00105 //             contains the pointer to the next node.
00106 //
00107 //      Exported Functions:
00108 //
00109 //          II_NODE(void)
00110 //
00111 //              Construct a singly linked list node, initialize next
00112 //              field to NULL. This does not initialize any of your
00113 //              fields!!! 
00114 //
00115 //          II_NODE             *Next()
00116 //          const II_NODE       *Next() const
00117 //
00118 //              The item on the list following this one
00119 //
00120 //          void Insert_After(II_NODE *nd)
00121 //
00122 //              Inserts a node "nd" after "this" node.
00123 //
00124 //          II_NODE* Insert_Before(II_NODE *nd)
00125 //
00126 //              Inserts a node "nd" before "this" node.
00127 //              WARNING: does not fix the previous pointer's pointer to this,
00128 //              so must be used with extreme caution!!
00129 //
00130 //          II_NODE*    Remove(II_NODE *prev)
00131 //
00132 //              Removes the "this" node from the list, returning it.  Note
00133 //              that the list's head and tail pointers are not updated,
00134 //              so this must be used with extreme caution.  TODO Michael
00135 //              Wolf says get rid of this function, or at least change its
00136 //              name so that people don't use it accidentally.
00137 //
00138 //
00139 //          void        Set_Next(II_NODE *)
00140 //
00141 //             Reset's the next pointer.  Be careful.
00142 //
00143 //          INT         Len() const
00144 //
00145 //             How many items are on the list from this out, including this.
00146 //
00147 //          INT         Pos(II_NODE *) const
00148 //
00149 //             Returns the position of the parameter in the linked list.
00150 //             0 is the first position, and so on.
00151 //             Returns -1 if the parameter doesn't belong to the list.
00152 //
00153 //  II_LIST is the container class is that holds a list of II_NODES.
00154 //  It maintains the head and the tail of the singly linked list.
00155 //
00156 //       Exported Functions:
00157 //
00158 //         II_LIST()
00159 //         II_LIST(II_NODE*)
00160 //
00161 //             Construct a an empty list or a list containing the one element.
00162 //
00163 //              NOTE THAT NO DESTRUCTORS ARE SUPPLIED.  IN ORDER TO DELETE
00164 //              DATA, YOU MUST SUPPLY YOUR OWN!  For example, you might want
00165 //              have the II_LIST contain a memory pool from which all the
00166 //              II_NODES are allocated, and then the destructor would iterate
00167 //              down the list deleting nodes.  Another possibility is to store
00168 //              a memory pool with each node.  Since there are so many choices,
00169 //              a destructor cannot be supplied here.
00170 //
00171 //         void Append( II_NODE *nd )
00172 //         BOOL SLIST::Append( SLIST_NODE *nd, SLIST_NODE *od)
00173 //
00174 //             Appends node "nd" to the end of the list, or after od.
00175 //             Returns TRUE if the append is successful.
00176 //
00177 //         void Prepend( II_NODE *nd )
00178 //         BOOL Prepend( II_NODE *nd, II_NODE *od )
00179 //
00180 //              Inserts node "nd" at the head of the list, or
00181 //              before the node "od" in the list.  Returns TRUE if the
00182 //              insertion is successful.
00183 //
00184 //         void Append_List(II_LIST *new_list)
00185 //
00186 //             Appends the "new_list" to the end of this one.
00187 //
00188 //         void Prepend_List(II_LIST *new_list)
00189 //
00190 //             Prepends the "new_list" at the front of this one.
00191 //
00192 //         II_NODE* Remove_Headnode(void)
00193 //
00194 //             Removes the current head node from this list, returning it.
00195 //
00196 //         II_NODE* Remove(II_NODE *prev, II_NODE *cur)
00197 //
00198 //             Removes cur from the list, returning it.  prev must point to
00199 //              cur.  If prev is NULL, this has same effect as
00200 //              Remove_Headnode() -- and cur must be the head.  _head and _tail
00201 //              of the list are updated appropriately.
00202 //
00203 //         II_NODE *Head(void)
00204 //         const II_NODE *Head(void) const
00205 //
00206 //             Returns the first node of the list
00207 //
00208 //         II_NODE *Tail(void)
00209 //         const II_NODE *Tail(void) const
00210 //
00211 //             Returns the last node of the list
00212 //
00213 //         BOOL Is_Empty(void) const
00214 //
00215 //             Returns TRUE if head node is NULL, or FALSE otherwise
00216 //
00217 //         INT32 Len(void) const
00218 //
00219 //             Returns the length of the list in the container
00220 //
00221 //         INT Pos(SLIST_NODE *) const
00222 //        
00223 //             Returns the position of the parameter in the linked list.
00224 //             0 is the first position, and so on.
00225 //             Returns -1 if the parameter doesn't belong to the list.
00226 //
00227 //
00228 // II_ITER: the iterator class is typically used to iterate through
00229 //             a singly linked list that is based on the base class
00230 //             SLIST_NODE, to perform certain operation.  Iteration does not
00231 //             change the list content.
00232 //
00233 // II_CONST_ITER: the same as iter, but returns constant pointers to nodes,
00234 //      and is initialized with constant pointers.  The interfaces for the
00235 //      two are identical, except for those differences.  [const] is used
00236 //      to signify where II_ITER does not have a const but II_CONST_ITER does.
00237 //
00238 //       Exported Functions:
00239 //
00240 //         II_ITER(void)
00241 //         II_CONST_ITER(void)
00242 //
00243 //             Construct a singly linked list iter but don't associate
00244 //             it with a list.
00245 //
00246 //         II_ITER(II_NODE *nd)
00247 //         II_CONST_ITER(const II_NODE *nd)
00248 //
00249 //             Construct so that when First is called, it will return nd and
00250 //             continue from there.
00251 //
00252 //         II_ITER(SLIST *sl)
00253 //         II_CONST_ITER(const SLIST *sl)
00254 //
00255 //             Construct so that when First is called, it will return the
00256 //             head of the list and continue from there.
00257 //
00258 //         ~II_ITER()
00259 //         ~II_CONST_ITER()
00260 //
00261 //             Destruct the iterator.
00262 //
00263 //         void Init([const] SLIST_NODE *nd)
00264 //         void Init([const] SLIST_NODE *nd)
00265 //
00266 //              Reinitialize.
00267 //
00268 //         void Set([const] SLIST_NODE *nd)
00269 //
00270 //              Sets the current to nd, len/idx to -1.
00271 //
00272 //         void SLIST_ITER::Clear(void)
00273 //
00274 //             Set head/tail to NULL, len/idx to -1.
00275 //
00276 //         [const] II_NODE* Nth(INT n)
00277 //
00278 //             Gets the n-th element in the list
00279 //
00280 //         [const] II_NODE* First(void)
00281 //
00282 //             Gets the first element "_head" and set "_cur" pointer
00283 //
00284 //         [const] II_NODE* Next(void)
00285 //
00286 //             Gets the _next element and bump the "_cur" pointer
00287 //
00288 //         [const] II_NODE* Peek_Next(void)
00289 //
00290 //             Gets the _next element in the list, doesn't change the iterator
00291 //
00292 //         [const] II_NODE* Head(void)
00293 //
00294 //             Gets the "_head" in the list, doesn't change the iterator
00295 //
00296 //         [const] II_NODE* Cur(void)
00297 //
00298 //             Gets the "_cur" element in the list
00299 //
00300 //         BOOL Is_Empty(void)
00301 //
00302 //             Returns TRUE is the current element, "_cur", a NULL pointer.
00303 //
00304 // Example usage of iterator:
00305 // II_ITER  foo_iter(list);
00306 // for (II_NODE *n=foo_iter.First(); !foo_iter.Is_Empty(); n=foo_iter.Next()) {
00307 //   // do whatever
00308 // }
00309 //
00310 // Substitute CHAIN for SLIST and you get a doubly linked list, with the
00311 // following additional functionality:
00312 //
00313 // CC_NODE: defines the basic element of doubly linked list, with the
00314 //          additional functions than II_NODE(SLIST):
00315 //
00316 //      Exported Functions:
00317 //
00318 //          CC_NODE*    Prev(void)
00319 //
00320 //              Gets the _prev element of this one
00321 //
00322 //          void        Set_Prev(CC_NODE *)
00323 //
00324 //              Resets the _prev pointer.  Be careful.
00325 //
00326 // CC_LIST is the container class that holds a chain of CC_NODES.
00327 // It maintains the head and tail of the doubly linked list.  In
00328 // addition to what II_LIST provide, here are the extra:
00329 //
00330 //      Exported Functions:
00331 //
00332 //          void        Insert_After(CC_NODE *nd, CC_NODE *after_nd)
00333 //
00334 //              Insert the node 'nd' after the node 'after_nd'
00335 //
00336 //          void        Insert_Before(CC_NODE *nd, CC_NODE *before_nd)
00337 //
00338 //              Insert the node 'nd' before the node 'before_nd'
00339 //
00340 //          void        Remove(CC_NODE *nd)
00341 //
00342 //              Remove the node 'nd' from the chain.  NOTE: different
00343 //              interface from the II_LIST.
00344 //
00345 // CC_ITER: the iterator class is typically used to iterate through
00346 //             a doubly linked list that is based on the base class
00347 //             CHAIN_NODE, to perform certain operation.  Iteration does not
00348 //             change the list content.
00349 //          Becaue the nature of chain, the chain iterator allows use
00350 //          to traverse the list backward by using the set of
00351 //          functions: (Last(), Is_Empty_Reverse(), Prev())
00352 //
00353 //          The additional function compare with II_ITER(SLIST_ITER):
00354 //
00355 //      Exported Functions:
00356 //
00357 //          CC_NODE*    Last(void)
00358 //
00359 //              Gets the last element of this list and set the index=len
00360 //
00361 //          CC_NODE*    Prev(void)
00362 //
00363 //              Gets the previous element of this list and decrment
00364 //              the current pointer.
00365 //
00366 //          CC_NODE*    Last_Nth(INT n)
00367 //
00368 //              Gets the last nth element of this list and set the
00369 //              pointer/index accordingly.
00370 //
00371 //          BOOL        Is_Empty_Reverse(void)
00372 //
00373 //              The mirror function for traversing the list backward.
00374 //
00375 
00376 class SLIST_NODE {
00377 friend class SLIST;
00378 friend class SLIST_ITER;
00379 private:
00380   SLIST_NODE *_next;   // point to the next node in the singly linked list
00381 
00382   SLIST_NODE& operator= (const SLIST_NODE& sl);
00383   SLIST_NODE(const SLIST_NODE&);
00384 
00385 protected:
00386   SLIST_NODE(void)                       { _next = NULL; }
00387   ~SLIST_NODE(void)                      {}
00388 
00389   void        Insert_After(SLIST_NODE *nd)  { nd->_next = _next; _next = nd; }
00390   SLIST_NODE *Insert_Before(SLIST_NODE *nd) { nd->_next = this; return nd; }
00391   SLIST_NODE *Remove(SLIST_NODE *prev);
00392   void        Set_Next(SLIST_NODE *n)       { _next = n; }
00393   INT32       Len(void) const;
00394   INT         Pos(SLIST_NODE *) const;
00395 public:
00396   SLIST_NODE *Next(void) const              { return _next;}
00397 };
00398 
00399 class SLIST {
00400 private:
00401   SLIST_NODE *_head;
00402   SLIST_NODE *_tail;
00403 
00404   SLIST& operator= (const SLIST& sl);
00405   SLIST(const SLIST&);
00406 
00407 protected:
00408   SLIST(void)                  { _head = _tail = NULL; }
00409 public:
00410   SLIST(SLIST_NODE *list);
00411   ~SLIST(void)                 {}
00412 
00413   void Set_Head(SLIST_NODE *h)      { _head = h; }
00414   void Set_Tail(SLIST_NODE *t)      { _tail = t; }
00415 
00416   void        Init(SLIST_NODE *list);   // same as constructor
00417   void        Init_Head(SLIST_NODE *list)      { _head = list; _tail = NULL; }
00418   void        Clear(void)                      { _head = _tail = NULL; }
00419 
00420   BOOL        Append( SLIST_NODE *nd, SLIST_NODE *od);
00421   BOOL        Prepend( SLIST_NODE *nd, SLIST_NODE *od );
00422   void        Append_List(SLIST *new_list);
00423   void        Prepend_List(SLIST *new_list);
00424   SLIST_NODE *Remove_Headnode(void);
00425   SLIST_NODE *Remove(SLIST_NODE *prev, SLIST_NODE *cur);
00426   void        Remove_node(SLIST_NODE *slist_node);
00427 
00428   SLIST_NODE            *Head(void)            { return _head; }
00429   const SLIST_NODE      *Head(void) const      { return _head; }
00430   SLIST_NODE            *Tail(void)            { return _tail; }
00431   const SLIST_NODE      *Tail(void) const      { return _tail; }
00432   BOOL        Is_Empty(void) const             { return _head == NULL; }
00433   INT32       Len(void) const;
00434   INT         Pos(SLIST_NODE *nd) const        { return _head->Pos(nd); }
00435 
00436   void Append( SLIST_NODE *nd )
00437     {
00438       if (nd == NULL) return;
00439       if (_head == NULL)
00440         _head = _tail = nd;
00441       else {
00442         _tail->Insert_After(nd);
00443         _tail = _tail->Next();
00444       }
00445     }
00446   
00447   void Prepend( SLIST_NODE *nd )
00448     {
00449       if (nd == NULL) return;
00450       // insert nd to beginning of list
00451       if (_head == NULL)
00452         _head = _tail = nd;
00453       else {
00454         _head = _head->Insert_Before(nd);
00455       }
00456     }
00457 
00458 };
00459 
00460 class SLIST_ITER {
00461 private:
00462   SLIST_NODE  *_head;
00463   SLIST_NODE  *_cur;
00464   mINT16       _len;
00465   mINT16       _idx;          // simulate indexing, default to -1
00466 
00467   SLIST_ITER& operator= (const SLIST_ITER& sl);
00468   SLIST_ITER(const SLIST_ITER&);
00469 
00470 protected:
00471   SLIST_ITER(void) { _head = NULL; _cur = NULL; _len = -1; _idx = -1;}
00472   void Set_Cur(SLIST_NODE* cur) { _cur = cur;}
00473   void Set_Idx(mINT16 idx) {_idx = idx;}
00474 
00475 public:
00476   SLIST_ITER(SLIST_NODE *nd)
00477                    { _head = nd; _cur = _head; _len = -1; _idx = -1; }
00478   SLIST_ITER(SLIST *sl)
00479                    { _head=sl->Head(); _cur=_head; _len=-1; _idx=-1; }
00480   ~SLIST_ITER(void) {}
00481 
00482   void         Init(SLIST_NODE *nd) { _head = nd; _cur = _head;}
00483   void         Init(SLIST *sl)      { _head = (sl ? sl->Head() : NULL);
00484                                                         _cur = _head;}
00485   void         Init(void)           { _head = NULL; _cur = _head;}
00486   void         Clear(void) { _head = NULL; _cur = NULL; _len = -1; _idx = -1;}
00487   void         Set(SLIST_NODE *nd)  {_cur = nd; _idx = -1;}
00488   SLIST_NODE  *First(void) {  // get the first element, and reset the pointer
00489     if (this == NULL)
00490       return NULL;
00491     if (_head)
00492       _cur = _head;
00493     else
00494       _cur = NULL;
00495     _idx = 0;
00496     return _cur;
00497   }
00498   SLIST_NODE  *Next(void) {   // get the next element, and bump the pointer.
00499     if (this == NULL)
00500       return NULL;
00501     if (_cur != NULL) {
00502       _cur = _cur->Next();
00503       _idx++;
00504     }
00505     return _cur;
00506   }
00507   SLIST_NODE  *Nth(INT n);// get the nth element
00508 
00509   SLIST_NODE  *Peek_Next(void) const {return _cur->Next();} 
00510   SLIST_NODE  *Head(void) const         {return _head;}
00511   SLIST_NODE  *Cur(void) const          {return _cur;}
00512   INT          Idx(void) const          {return _idx;}
00513   INT32        Len(void);               // get the length of the list
00514   BOOL         Is_Empty(void) const     { return _cur == NULL; }
00515 };
00516 
00517 // DECLARE_SLIST_NODE_CLASS: a macro to define the body of a derived
00518 //                           class "NAME_LIST" of SLIST_NODE
00519 //                   Example:
00520 //                           class NAME_LIST : public SLIST_NODE {
00521 //                           DECLARE_SLIST_NODE_CLASS( NAME_LIST )
00522 //                           ~NAME_LIST(void);
00523 //                           };
00524 //                   Note:   Create your own destructor!
00525 
00526 #define DECLARE_SLIST_NODE_CLASS( NAME_NODE )                         \
00527                                                                       \
00528 public:                                                               \
00529   NAME_NODE *Next(void) {                                             \
00530     return (NAME_NODE *) SLIST_NODE::Next();                          \
00531   }                                                                   \
00532   const NAME_NODE *Next(void) const {                                 \
00533     return (NAME_NODE *) SLIST_NODE::Next();                          \
00534   }                                                                   \
00535   void Insert_After(NAME_NODE *nd) {                                  \
00536     SLIST_NODE::Insert_After(nd);                                     \
00537   }                                                                   \
00538   void Insert_Before(NAME_NODE *nd) {                                 \
00539     SLIST_NODE::Insert_Before(nd);                                    \
00540   }                                                                   \
00541   NAME_NODE *Remove(NAME_NODE *prev) {                                \
00542     return (NAME_NODE*) SLIST_NODE::Remove(prev);                     \
00543   }                                                                   \
00544   void Set_Next(NAME_NODE *nd) {                                      \
00545     SLIST_NODE::Set_Next(nd);                                         \
00546   }                                                                   \
00547   INT32  Len(void) const    { return SLIST_NODE::Len(); }             \
00548   INT    Pos(NAME_NODE *od) { return SLIST_NODE::Pos(od); }           \
00549 
00550 // DECLARE_SLIST_CLASS: a macro to define the body of a derived
00551 //                      class "NAME_LIST" of SLIST.
00552 //              Example:
00553 //                      class NAME_LIST : public SLIST {
00554 //                      DECLARE_SLIST_CLASS( NAME_LIST, NODE_T )
00555 //                      };
00556 
00557 #define DECLARE_SLIST_CLASS( NAME_LIST, NAME_NODE)                      \
00558 public:                                                                 \
00559   typedef NAME_NODE CONTAINER_NODE;                                     \
00560   NAME_LIST(NAME_NODE *nd) { SLIST::Init(nd); }                         \
00561   NAME_LIST() : SLIST() {}                                              \
00562   void Append(NAME_NODE *nd) { SLIST::Append(nd); }                     \
00563   BOOL Append(NAME_NODE *nd, NAME_NODE *od) {                           \
00564     return SLIST::Append(nd, od);                                       \
00565   }                                                                     \
00566   void Prepend(NAME_NODE *nd) { SLIST::Prepend(nd); }                   \
00567   BOOL Prepend(NAME_NODE *nd, NAME_NODE *od) {                          \
00568     return SLIST::Prepend(nd, od);                                      \
00569   }                                                                     \
00570   void Append_List(NAME_LIST *nl) { SLIST::Append_List(nl); }           \
00571   void Prepend_List(NAME_LIST *nl) { SLIST::Prepend_List(nl); }         \
00572   NAME_NODE *Remove_Headnode(void) {                                    \
00573     return (NAME_NODE*) SLIST::Remove_Headnode();                       \
00574   }                                                                     \
00575   NAME_NODE *Remove(NAME_NODE *prev, NAME_NODE *cur) {                  \
00576     return (NAME_NODE*) SLIST::Remove(prev, cur);                       \
00577   }                                                                     \
00578   NAME_NODE *Head(void) { return (NAME_NODE *) SLIST::Head(); }         \
00579   const NAME_NODE *Head(void) const                                     \
00580                 { return (const NAME_NODE *) SLIST::Head(); }           \
00581   NAME_NODE *Tail(void) { return (NAME_NODE *) SLIST::Tail(); }         \
00582   const NAME_NODE *Tail(void) const                                     \
00583                 { return (const NAME_NODE *) SLIST::Tail(); }           \
00584   BOOL       Is_Empty(void) const { return SLIST::Is_Empty(); }         \
00585   INT32      Len(void) const { return SLIST::Len(); }                   \
00586   INT        Pos(NAME_NODE *od) { return SLIST::Pos(od); }              \
00587 
00588 
00589 // DECLARE_SLIST_ITER_CLASS: a macro to define the body of a derived
00590 //                           class "NAME_LIST" of SLIST_ITER
00591 //                   Example:
00592 //                           class NAME_LIST : public SLIST_ITER {
00593 //                           DECLARE_SLIST_ITER_CLASS( NAME_LIST, NODE_T )
00594 //                           };
00595 
00596 #define DECLARE_SLIST_ITER_CLASS( NAME_ITER, NAME_NODE, NAME_LIST)      \
00597 public:                                                                 \
00598   NAME_ITER(NAME_NODE *nd) { SLIST_ITER::Init(nd); }                    \
00599   NAME_ITER(NAME_LIST *nl) { SLIST_ITER::Init(nl); }                    \
00600   NAME_ITER(void)          { SLIST_ITER::Init();   }                    \
00601   void Init(NAME_NODE *nd) { SLIST_ITER::Init(nd); }                    \
00602   void Init(NAME_LIST *nl) { SLIST_ITER::Init(nl); }                    \
00603   void Set(NAME_NODE *nd) { SLIST_ITER::Set(nd); }                      \
00604   NAME_NODE *First(void) { return (NAME_NODE *) SLIST_ITER::First(); }  \
00605   NAME_NODE *Next(void) { return (NAME_NODE *) SLIST_ITER::Next(); }    \
00606   NAME_NODE *Nth(INT n) { return (NAME_NODE *) SLIST_ITER::Nth(n); }    \
00607   NAME_NODE *Peek_Next(void) { return (NAME_NODE *) SLIST_ITER::Peek_Next(); }\
00608   NAME_NODE *Head(void) { return (NAME_NODE *) SLIST_ITER::Head(); }    \
00609   NAME_NODE *Cur(void) { return (NAME_NODE *) SLIST_ITER::Cur(); }      \
00610   BOOL Is_Empty(void) { return SLIST_ITER::Is_Empty(); }                \
00611 
00612 #define DECLARE_SLIST_CONST_ITER_CLASS( NAME_ITER, NAME_NODE, NAME_LIST) \
00613 public:                                                                 \
00614   NAME_ITER(const NAME_NODE *nd) { SLIST_ITER::Init((NAME_NODE*)nd); } \
00615   NAME_ITER(const NAME_LIST *nl) { SLIST_ITER::Init((NAME_LIST*)nl); } \
00616   NAME_ITER(void)          { SLIST_ITER::Init();   }                    \
00617   void Init(NAME_NODE *nd) { SLIST_ITER::Init(nd); }                    \
00618   void Init(NAME_LIST *nl) { SLIST_ITER::Init(nl); }                    \
00619   void Set(NAME_NODE *nd) { SLIST_ITER::Set(nd); }                      \
00620   const NAME_NODE *First(void) { return (NAME_NODE *) SLIST_ITER::First(); } \
00621   const NAME_NODE *Next(void) { return (NAME_NODE *) SLIST_ITER::Next(); }   \
00622   const NAME_NODE *Nth(INT n) { return (NAME_NODE *) SLIST_ITER::Nth(n); }   \
00623   const NAME_NODE *Peek_Next(void) { return (NAME_NODE *) SLIST_ITER::Peek_Next(); }   \
00624   const NAME_NODE *Head(void) { return (NAME_NODE *) SLIST_ITER::Head(); }   \
00625   const NAME_NODE *Cur(void) { return (NAME_NODE *) SLIST_ITER::Cur(); }     \
00626   BOOL Is_Empty(void) { return SLIST_ITER::Is_Empty(); }                     \
00627 
00628 
00629 // CHAIN_NODE: defines the basic element of doubly linked list.  It
00630 //             contains the pointer to the prev and the next node.
00631 //
00632 //       Exported Functions:
00633 //
00634 //         CHAIN_NODE::CHAIN_NODE(void)
00635 //
00636 //             Construct a doubly linked list node, 
00637 //             initialize next field to NULL.
00638 //
00639 //         CHAIN_NODE::~CHAIN_NODE(void)
00640 //
00641 //             Destruct a doubly linked list node, 
00642 //             initialize next field to NULL.
00643 //
00644 //         CHAIN_NODE* CHAIN_NODE::Insert_After(CHAIN_NODE *nd)
00645 //
00646 //             Inserts a node "nd" after "this" node, returns "nd".
00647 //
00648 //         CHAIN_NODE* CHAIN_NODE::Insert_Before(CHAIN_NODE *nd)
00649 //
00650 //             Inserts a node "nd" before "this" node, returns "nd".
00651 //
00652 //         CHAIN_NODE* CHAIN_NODE::Remove(void)
00653 //
00654 //             Removes the "this" node from the list, returning it.
00655 //
00656 //         CHAIN_NODE* CHAIN_NODE::Next(void)
00657 //
00658 //             Returns the "next" node
00659 //
00660 //         CHAIN_NODE* CHAIN_NODE::Next(void)
00661 //
00662 //             Returns the "prev" node
00663 //
00664 //         void CHAIN_NODE::Set_Next(CHAIN_NODE *nd)
00665 //
00666 //             Sets the "next" field of "this" node.
00667 //
00668 //         void CHAIN_NODE::Set_Prev(CHAIN_NODE *nd)
00669 //
00670 //             Sets the "prev" field of "this" node.
00671 //
00672 
00673 class CHAIN_NODE {
00674 friend class CHAIN;
00675 friend class CHAIN_ITER;
00676 private:
00677   CHAIN_NODE *_next;   // point to the next node in the doubly linked list
00678   CHAIN_NODE *_prev;   // point to the prev node in the doubly linked list
00679 
00680   CHAIN_NODE& operator= (const CHAIN_NODE& sl);
00681   CHAIN_NODE(const CHAIN_NODE&);
00682 
00683 protected:
00684   CHAIN_NODE(void)                       { _next = _prev = NULL; }
00685   ~CHAIN_NODE(void)                      {}
00686 
00687   CHAIN_NODE *Insert_After(CHAIN_NODE *nd);
00688   CHAIN_NODE *Insert_Before(CHAIN_NODE *nd);
00689   CHAIN_NODE *Remove(void);
00690 
00691   CHAIN_NODE *Next(void)                    { return _next;}
00692   const CHAIN_NODE *Next(void) const        { return _next;}
00693   CHAIN_NODE *Prev(void)                    { return _prev;}
00694   const CHAIN_NODE *Prev(void) const        { return _prev;}
00695   void        Set_Next(CHAIN_NODE *n)       { _next = n; }
00696   void        Set_Prev(CHAIN_NODE *n)       { _prev = n; }
00697 };
00698 
00699 // CHAIN     : the container class is typically used to construct a
00700 //             doubly linked list that is based on the base class,
00701 //             CHAIN_NODE.  It maintains the head and the tail of the
00702 //             doubly linked list for fast update.
00703 //
00704 //       Exported Functions:
00705 //
00706 //         CHAIN::CHAIN(void)
00707 //
00708 //             Construct a doubly linked list container, initialize head and
00709 //             tail to NULL
00710 //
00711 //         CHAIN::CHAIN(CHAIN_NODE *nd)
00712 //
00713 //             Construct a doubly linked list container, initialize head and
00714 //             tail to nd.
00715 //
00716 //         CHAIN::~CHAIN(void)
00717 //
00718 //             Destruct a doubly linked list container, reset head and tail
00719 //             to NULL.
00720 //
00721 //         void CHAIN::Init(CHAIN_NODE *node)
00722 //
00723 //             Initializes head and tail with node
00724 //
00725 //         void CHAIN::Init(CHAIN *list)
00726 //
00727 //             Initializes head and tail to those of the "list"
00728 //
00729 //         void CHAIN::Clear(void)
00730 //
00731 //             Clear the CHAIN content, ie set head and tail to NULL.
00732 //
00733 //         void CHAIN::Append( CHAIN_NODE *nd )
00734 //
00735 //             Appends node "nd" to the "tail" of the list
00736 //
00737 //         void CHAIN::Prepend( CHAIN_NODE *nd )
00738 //
00739 //             Inserts node "nd" at the "head" of the list
00740 //
00741 //         void CHAIN::Insert_After( CHAIN_NODE *nd, CHAIN_NODE *after_nd )
00742 //
00743 //             Inserts node "nd" after the "after_nd" node.
00744 //
00745 //         void CHAIN::Insert_before( CHAIN_NODE *nd, CHAIN_NODE *before_nd )
00746 //
00747 //             Inserts node "nd" before the "before_nd" node.
00748 //
00749 //         BOOL CHAIN::Is_Member( CHAIN_NODE *nd ) const
00750 //
00751 //             Returns TRUE if "nd" is in the current list, or FALSE otherwise
00752 //
00753 //         void CHAIN::Append_List(CHAIN *new_list)
00754 //
00755 //             Appends the "new_list" at the "tail" of the list
00756 //
00757 //         void CHAIN::Prepend_List(CHAIN *new_list)
00758 //
00759 //             Prepends the "new_list" at the "head" of the list
00760 //
00761 //         void CHAIN::Remove(CHAIN_NODE *nd)
00762 //
00763 //             Remove the node from the chain
00764 //
00765 //         CHAIN_NODE* CHAIN::Remove_Head(void)
00766 //
00767 //             Remove the current head node from the chain, and return it
00768 //
00769 //         CHAIN_NODE* CHAIN::Remove_Tail(void)
00770 //
00771 //             Removes the current tail node from the chain, returning it
00772 //
00773 //         CHAIN_NODE * CHAIN::Head(void)
00774 //         const CHAIN_NODE * CHAIN::Head(void) const
00775 //
00776 //             Returns the "head" node of the list
00777 //
00778 //         CHAIN_NODE * CHAIN::Tail(void)
00779 //         const CHAIN_NODE * CHAIN::Tail(void) const
00780 //
00781 //             Returns the "tail" node of the list
00782 //
00783 //         BOOL CHAIN::Is_Empty(void) const
00784 //
00785 //             Returns TRUE if head node is NULL, or FALSE otherwise
00786 //
00787 //         INT32 CHAIN::Len(void) const
00788 //
00789 //             Returns the length of the list in the container
00790 //
00791 
00792 class CHAIN {
00793 private:
00794   CHAIN_NODE *_head;
00795   CHAIN_NODE *_tail;
00796 
00797   CHAIN& operator= (const CHAIN& sl);
00798   CHAIN(const CHAIN&);
00799 
00800 protected:
00801   CHAIN(void)                  { _head = _tail = NULL; }
00802 
00803 public:
00804   CHAIN(CHAIN_NODE *nd)        { _head = _tail = nd; }
00805   ~CHAIN(void)                 {}
00806 
00807                                         // same as constructor
00808   void        Init(void)                { _head = _tail = NULL; }
00809   void        Init(CHAIN_NODE *nd)      { _head = _tail = nd; }
00810   void        Init(CHAIN *list)         
00811                                { _head = list->Head(); _tail = list->Tail();}
00812   void        Clear(void)               { _head = _tail = NULL; }
00813 
00814   void        Append( CHAIN_NODE *nd );
00815   void        Prepend( CHAIN_NODE *nd );
00816   void        Insert_After(CHAIN_NODE *nd, CHAIN_NODE *after_nd);
00817   void        Insert_Before(CHAIN_NODE *nd, CHAIN_NODE *before_nd);
00818   BOOL        Is_Member(CHAIN_NODE *nd) const;
00819 
00820   void        Append_List(CHAIN *new_list);
00821   void        Prepend_List(CHAIN *new_list);
00822   void        Remove(CHAIN_NODE *);
00823   CHAIN_NODE *Remove_Head(void);
00824   CHAIN_NODE *Remove_Tail(void);
00825 
00826   CHAIN_NODE       *Head(void)                 { return _head; }
00827   const CHAIN_NODE *Head(void) const           { return _head; }
00828   CHAIN_NODE       *Tail(void)                       { return _tail; }
00829   const CHAIN_NODE *Tail(void) const                 { return _tail; }
00830   BOOL        Is_Empty(void) const             { return _head == NULL; }
00831   INT32       Len(void) const;
00832 
00833 };
00834 
00835 // CHAIN_ITER: the iterator class is typically used to iterate through
00836 //             a doubly linked list that is based on the base class
00837 //             CHAIN_NODE, to perform certain operation.  It does not
00838 //             change the list content.
00839 //
00840 //       Exported Functions:
00841 //
00842 //         CHAIN_ITER::CHAIN_ITER(void)
00843 //
00844 //             Construct a doubly linked list iter.  Initialize list/cur to
00845 //             NULL and len/idx to -1.
00846 //
00847 //         CHAIN_ITER::Set_Cur(CHAIN_NODE *cur)
00848 //
00849 //             Sets the _cur node to the specified 'cur' node.  This allow
00850 //             caller to visit part of the chain starting from 'cur' node.
00851 //             NOTE: Since this function currently does not set the _idx,
00852 //                   please refrain from using it for indexing access.
00853 //
00854 //         CHAIN_ITER::CHAIN_ITER(CHAIN *sl)
00855 //
00856 //             Construct a doubly linked list iter.  It takes a doubly
00857 //             linked list container and use it to initialize this
00858 //             iterator's list pointer.  It also set cur node to NULL
00859 //             and len/idx to -1.
00860 //
00861 //         CHAIN_ITER::~CHAIN_ITER(void)
00862 //
00863 //             Destruct a doubly linked list iter.
00864 //
00865 //         void CHAIN_ITER::Init(CHAIN *sl)
00866 //
00867 //             Uses the doubly linked list container to initialize the
00868 //             list of this iterator.
00869 //
00870 //         void CHAIN_ITER::Clear(void)
00871 //
00872 //             Set list/tail to NULL, len/idx to -1.
00873 //
00874 //         CHAIN_NODE* CHAIN_ITER::First(void)
00875 //
00876 //             Gets the first element and set "cur" pointer
00877 //
00878 //         CHAIN_NODE* CHAIN_ITER::Last(void)
00879 //
00880 //             Gets the last element and set "cur" pointer
00881 //
00882 //         CHAIN_NODE* CHAIN_ITER::Next(void)
00883 //
00884 //             Gets the next element and increment the "cur" pointer
00885 //
00886 //         CHAIN_NODE* CHAIN_ITER::Prev(void)
00887 //
00888 //             Gets the next element and decrement the "cur" pointer
00889 //
00890 //         CHAIN_NODE* CHAIN_ITER::Nth(INT n)
00891 //
00892 //             Gets the n-th element in the list
00893 //             Note: Head()==Nth(0)
00894 //
00895 //         CHAIN_NODE* CHAIN_ITER::Last_Nth(INT n)
00896 //
00897 //             Gets the last n-th element in the list
00898 //             Note: Tail()==Last_Nth(0)
00899 //
00900 //         CHAIN *CHAIN_ITER::List(void)
00901 //
00902 //             Gets the pointer to the container list
00903 //
00904 //         CHAIN_NODE* CHAIN_ITER::Peek_Next(void)
00905 //
00906 //             Gets the next element in the list
00907 //
00908 //         CHAIN_NODE* CHAIN_ITER::Cur(void)
00909 //
00910 //             Gets the "cur" element in the list
00911 //
00912 //         INT CHAIN_ITER::Idx(void)
00913 //
00914 //             Gets the current index "idx"
00915 //
00916 //         INT32 CHAIN_ITER::Len(void)
00917 //
00918 //             Gets the length "len" of the list
00919 //
00920 //         BOOL CHAIN_ITER::Is_Empty(void)
00921 //
00922 //             Returns TRUE if the current element, "cur", is a NULL pointer.
00923 //
00924 //         BOOL CHAIN_ITER::Is_Empty_Reverse(void)
00925 //
00926 //             Returns TRUE if the current element, "cur", is a NULL pointer.
00927 //
00928 // Example:
00929 // CHAIN_ITER  foo_iter( list );
00930 //
00931 // for (foo_iter.First(); !foo_iter.Is_Empty(); foo_iter.Next()) {
00932 //   // do whatever
00933 // }
00934 //
00935 
00936 class CHAIN_ITER {
00937 private:
00938   CHAIN_NODE  *_cur;
00939   CHAIN       *_list;
00940   mINT16       _len;
00941   mINT16       _idx;          // simulate indexing, default to -1
00942 
00943   CHAIN_ITER& operator= (const CHAIN_ITER& sl);
00944   CHAIN_ITER(const CHAIN_ITER&);
00945 
00946 protected:
00947   CHAIN_ITER(void)   { _list = NULL; _cur = NULL; _len = -1; _idx = -1;}
00948   void Set_Cur(CHAIN_NODE *cur) { _cur = cur; }
00949 
00950 public:
00951   CHAIN_ITER(CHAIN *sl)
00952                    { _list = sl; _cur=_list->Head(); 
00953                                         _len = -1; _idx = -1; }
00954   ~CHAIN_ITER(void) {}
00955 
00956   void         Init(CHAIN *sl) { _list = sl; _len=_idx=-1; _cur=_list->Head();}
00957   void         Clear(void) { _list = NULL; _cur = NULL; _len = -1; _idx = -1;}
00958   CHAIN_NODE  *First(void);  // get the first element, and reset the index.
00959   CHAIN_NODE  *Last(void);   // get the last element, and set index=len.
00960   CHAIN_NODE  *Next(void);   // get the next element, and incr. the pointer.
00961   CHAIN_NODE  *Prev(void);   // get the prev element, and decr. the pointer.
00962   CHAIN_NODE  *Nth(INT n);   // get the nth element
00963   CHAIN_NODE  *Last_Nth(INT n);// get the last nth element
00964 
00965   CHAIN       *List(void)            {return _list;} 
00966   CHAIN_NODE  *Peek_Next(void)       {return _cur->Next();} 
00967   CHAIN_NODE  *Cur(void)             {return _cur;}
00968   INT          Idx(void)             {return _idx;}
00969   INT32        Len(void);            // get the length of the list
00970   BOOL         Is_Empty(void)        { return _cur == NULL; }
00971   BOOL         Is_Empty_Reverse(void){ return _cur == NULL; }
00972 };
00973 
00974 // DECLARE_CHAIN_NODE_CLASS: a macro to define the body of a derived
00975 //                           class "NAME_LIST" of CHAIN_NODE
00976 //                   Example:
00977 //                           class NAME_LIST : public CHAIN_NODE {
00978 //                           DECLARE_CHAIN_NODE_CLASS( NAME_LIST )
00979 //                           ~NAME_LIST(void);
00980 //                           };
00981 //                   Note:   Create your own destructor!
00982 
00983 #define DECLARE_CHAIN_NODE_CLASS( NAME_NODE )                           \
00984 public:                                                                 \
00985   NAME_NODE *Next(void)                                                 \
00986                 {return (NAME_NODE *)CHAIN_NODE::Next();}               \
00987   NAME_NODE *Prev(void)                                                 \
00988                 {return (NAME_NODE *)CHAIN_NODE::Prev();}               \
00989   const NAME_NODE *Next(void) const                                     \
00990                 {return (const NAME_NODE *)CHAIN_NODE::Next();}         \
00991   const NAME_NODE *Prev(void) const                                     \
00992                 {return (const NAME_NODE *)CHAIN_NODE::Prev();}         \
00993   NAME_NODE *Insert_Before(NAME_NODE *nd) {                             \
00994     return (NAME_NODE*) CHAIN_NODE::Insert_Before(nd);                  \
00995   }                                                                     \
00996   NAME_NODE *Insert_After(NAME_NODE *nd) {                              \
00997     return (NAME_NODE*) CHAIN_NODE::Insert_After(nd);                   \
00998   }                                                                     \
00999   NAME_NODE *Remove() {                                                 \
01000     return (NAME_NODE*) CHAIN_NODE::Remove();                           \
01001   }                                                                     \
01002 
01003 // DECLARE_CHAIN_CLASS: a macro to define the body of a derived
01004 //                      class "NAME_LIST" of CHAIN.
01005 //              Example:
01006 //                      class NAME_LIST : public CHAIN {
01007 //                      DECLARE_CHAIN_CLASS( NAME_LIST, NAME_NODE )
01008 //                      };
01009 
01010 #define DECLARE_CHAIN_CLASS( NAME_LIST, NAME_NODE)                      \
01011 public:                                                                 \
01012   NAME_LIST(NAME_NODE *nd) { CHAIN::Init((CHAIN_NODE*)nd); }            \
01013   NAME_LIST(void)          { CHAIN::Init();   }                         \
01014   void          Clear() {CHAIN::Clear();}                               \
01015   void          Append(NAME_NODE* nd) {CHAIN::Append((CHAIN_NODE*)nd);} \
01016   void          Prepend(NAME_NODE* nd) {CHAIN::Prepend((CHAIN_NODE*)nd);}\
01017   void          Insert_After(NAME_NODE* a, NAME_NODE* b)                \
01018                  {CHAIN::Insert_After((CHAIN_NODE*)a,(CHAIN_NODE*)b);}  \
01019   void          Insert_Before(NAME_NODE* a, NAME_NODE* b)               \
01020                  {CHAIN::Insert_Before((CHAIN_NODE*)a,(CHAIN_NODE*)b);} \
01021   void          Append_List(NAME_LIST* l) {CHAIN::Append_List(l);}      \
01022   void          Prepend_List(NAME_LIST* l) {CHAIN::Prepend_List(l);}    \
01023                                                                         \
01024   BOOL       Is_Member(NAME_NODE *nd) const { return CHAIN::Is_Member((CHAIN_NODE*)nd); }  \
01025   NAME_NODE *Head(void) { return (NAME_NODE *) CHAIN::Head(); }         \
01026   const NAME_NODE *Head(void) const                                     \
01027                 { return (const NAME_NODE *) CHAIN::Head(); }           \
01028   NAME_NODE *Tail(void) { return (NAME_NODE *) CHAIN::Tail(); }         \
01029   const NAME_NODE *Tail(void) const                                     \
01030                 { return (const NAME_NODE *) CHAIN::Tail(); }           \
01031   void       Remove(NAME_NODE *nd) {                                    \
01032     CHAIN::Remove((CHAIN_NODE*)nd);                                     \
01033   }                                                                     \
01034   NAME_NODE  *Remove_Head(void) {                                       \
01035     return (NAME_NODE*) CHAIN::Remove_Head();                           \
01036   }                                                                     \
01037   NAME_NODE  *Remove_Tail(void) {                                       \
01038     return (NAME_NODE*) CHAIN::Remove_Tail();                           \
01039   }                                                                     \
01040   BOOL       Is_Empty(void) const { return CHAIN::Is_Empty(); }         \
01041   BOOL       Is_Empty_Reverse(void) const { return CHAIN::Is_Empty(); } \
01042   INT32      Len(void) const { return CHAIN::Len(); }                   \
01043 
01044 
01045 // DECLARE_CHAIN_ITER_CLASS: a macro to define the body of a derived
01046 //                           class "NAME_LIST" of CHAIN_ITER
01047 //                   Example:
01048 //                           class NAME_LIST : public CHAIN_ITER {
01049 //                           DECLARE_CHAIN_ITER_CLASS( NAME_LIST, NODE_T )
01050 //                           };
01051 
01052 #define DECLARE_CHAIN_ITER_CLASS( NAME_ITER, NAME_NODE, NAME_LIST)      \
01053 public:                                                                 \
01054   NAME_ITER(NAME_LIST *nl) { CHAIN_ITER::Init(nl); }                    \
01055   NAME_NODE *First(void) { return (NAME_NODE *) CHAIN_ITER::First(); }  \
01056   NAME_NODE *Last(void) { return (NAME_NODE *) CHAIN_ITER::Last(); }    \
01057   NAME_NODE *Next(void) { return (NAME_NODE *) CHAIN_ITER::Next(); }    \
01058   NAME_NODE *Prev(void) { return (NAME_NODE *) CHAIN_ITER::Prev(); }    \
01059   NAME_NODE *List(void) { return (NAME_NODE *) CHAIN_ITER::List(); }    \
01060   NAME_NODE *Nth(INT n) { return (NAME_NODE *) CHAIN_ITER::Nth(n); }    \
01061   NAME_NODE *Last_Nth(INT n)                                            \
01062                     { return (NAME_NODE *) CHAIN_ITER::Last_Nth(n); }   \
01063   NAME_NODE *Peek_Next(void) { return (NAME_NODE *) CHAIN_ITER::Peek_Next(); }\
01064   NAME_NODE *Head(void) { return (NAME_NODE *) CHAIN_ITER::List(); }    \
01065   NAME_NODE *Cur(void) { return (NAME_NODE *) CHAIN_ITER::Cur(); }      \
01066   BOOL Is_Empty(void) { return CHAIN_ITER::Is_Empty(); }                \
01067   BOOL Is_Empty_Reverse(void) { return CHAIN_ITER::Is_Empty(); }        \
01068 
01069 
01070 #define DECLARE_CHAIN_CONST_ITER_CLASS( NAME_ITER, NAME_NODE, NAME_LIST) \
01071 public:                                                                 \
01072   NAME_ITER(const NAME_LIST *nl)                                        \
01073               { CHAIN_ITER::Init((NAME_LIST *)nl); }                    \
01074   const NAME_NODE *First(void)                                          \
01075               { return (const NAME_NODE *) CHAIN_ITER::First(); }       \
01076   const NAME_NODE *Last(void)                                           \
01077               { return (const NAME_NODE *) CHAIN_ITER::Last(); }        \
01078   const NAME_NODE *Next(void)                                           \
01079               { return (const NAME_NODE *) CHAIN_ITER::Next(); }        \
01080   const NAME_NODE *Prev(void)                                           \
01081               { return (const NAME_NODE *) CHAIN_ITER::Prev(); }        \
01082   const NAME_NODE *List(void)                                           \
01083               { return (const NAME_NODE *) CHAIN_ITER::List(); }        \
01084   const NAME_NODE *Nth(INT n)                                           \
01085               { return (const NAME_NODE *) CHAIN_ITER::Nth(n); }        \
01086   const NAME_NODE *Last_Nth(INT n)                                      \
01087               { return (const NAME_NODE *) CHAIN_ITER::Last_Nth(n); }   \
01088   const NAME_NODE *Peek_Next(void)                                      \
01089               { return (const NAME_NODE *) CHAIN_ITER::Peek_Next(); }   \
01090   const NAME_NODE *Head(void)                                           \
01091               { return (const NAME_NODE *) CHAIN_ITER::List(); }        \
01092   const NAME_NODE *Cur(void)                                            \
01093               { return (const NAME_NODE *) CHAIN_ITER::Cur(); }         \
01094   BOOL Is_Empty(void) { return CHAIN_ITER::Is_Empty(); }                \
01095   BOOL Is_Empty_Reverse(void) { return CHAIN_ITER::Is_Empty(); }        \
01096 
01097 
01098 
01099 // ==================================================================
01100 // Circularly Linked List
01101 //
01102 // CLIST_NODE: defines the basic element of circularly linked list.  It
01103 //             contains the pointer to the next node.
01104 //
01105 //       Exported Functions:
01106 //
01107 //         CLIST_NODE::CLIST_NODE(void)
01108 //
01109 //             Construct a circular list node, initialize next field 
01110 //              to NULL.
01111 //
01112 //         CLIST_NODE::~CLIST_NODE(void)
01113 //
01114 //             Destruct a circular list node, initialize next field to 
01115 //              NULL.
01116 //
01117 //         void CLIST_NODE::Insert_After(CLIST_NODE *nd)
01118 //
01119 //             Inserts a node "nd" after "this" node.
01120 //
01121 //         CLIST_NODE* CLIST_NODE::Insert_Before(CLIST_NODE *nd)
01122 //
01123 //              Inserts a node "nd" before "this" node.  Please NOTE 
01124 //              that this method is inefficient time-wise because of 
01125 //              the need to search for the node that has "this" as its 
01126 //              "next" node.
01127 //
01128 //         CLIST_NODE* CLIST_NODE::Remove(CLIST_NODE *prev)
01129 //
01130 //             Removes the "this" node from the list, returning it
01131 //
01132 //         CLIST_NODE* CLIST_NODE::Next(void)
01133 //
01134 //             Returns the "_next" node
01135 //
01136 //         void CLIST_NODE::Set_Next(CLIST_NODE *n)
01137 //
01138 //             Sets the "_next" node of "this" node.
01139 //
01140 //         INT32 CLIST_NODE::Len(void) const
01141 //
01142 //              Returns the number of elements in the list
01143 //
01144 
01145 class CLIST_NODE {
01146 friend class CLIST;
01147 friend class CLIST_ITER;
01148 private:
01149   CLIST_NODE *_next;   // point to the next node in the circularly linked list
01150 
01151   CLIST_NODE& operator= (const CLIST_NODE& cl);
01152   CLIST_NODE(const CLIST_NODE&);
01153 
01154   // access function only used by non-private methods
01155   CLIST_NODE *Find_Next( void ) const;
01156 
01157 protected:
01158   CLIST_NODE(void)                       { _next = this; }
01159   ~CLIST_NODE(void)                      { _next = NULL; }
01160 
01161   void        Insert_After(CLIST_NODE *nd)  { nd->_next = _next; _next = nd; }
01162   CLIST_NODE *Insert_Before(CLIST_NODE *nd);
01163   CLIST_NODE *Remove(CLIST_NODE *prev);
01164 
01165   CLIST_NODE *Next(void) const          { return _next;}
01166   void        Set_Next(CLIST_NODE *n)   { _next = n; }
01167   INT32       Len(void) const;
01168 };
01169 
01170 // CLIST     : the container class is typically used to construct a
01171 //              circularly linked list that is based on the base class,
01172 //              CLIST_NODE.  It maintains the head of the circularly linked 
01173 //              list for fast update.
01174 //
01175 //       Exported Functions:
01176 //
01177 //         CLIST::CLIST(void)
01178 //
01179 //             Construct a circular list container, initialize head to NULL
01180 //
01181 //         CLIST::CLIST(CLIST_NODE *list)
01182 //
01183 //             Construct a circular list container, initialize head with list.
01184 //
01185 //         CLIST::~CLIST(void)
01186 //
01187 //             Destruct a circular list container, reset head to NULL.
01188 //
01189 //         void CLIST::Init(CLIST_NODE *list)
01190 //
01191 //             Initializes head with list
01192 //
01193 //         void CLIST::Clear(void)
01194 //
01195 //             Clear the CLIST content, ie set head to NULL.
01196 //
01197 //         void CLIST::Append( CLIST_NODE *nd )
01198 //
01199 //             Appends node "nd" to the list so it is at the "end" of
01200 //              the list, and therefore precedes the head
01201 //
01202 //         BOOL CLIST::Append( CLIST_NODE *nd, CLIST_NODE *od)
01203 //
01204 //             Appends node "nd" after the node "od" in the list
01205 //
01206 //         void CLIST::Prepend( CLIST_NODE *nd )
01207 //
01208 //             Inserts node "nd" at the "_head" of the list
01209 //
01210 //         BOOL CLIST::Prepend( CLIST_NODE *nd, CLIST_NODE *od )
01211 //
01212 //             Inserts node "nd" before the node "od" in the list
01213 //
01214 //         void CLIST::Append_List(CLIST *new_list)
01215 //
01216 //             Appends the "new_list" so it precedes the head
01217 //
01218 //         void CLIST::Prepend_List(CLIST *new_list)
01219 //
01220 //             Prepends the "new_list" at the "_head" of the list
01221 //
01222 //         CLIST_NODE * CLIST::Remove_Headnode(void)
01223 //
01224 //             Removes the current head node
01225 //
01226 //         CLIST_NODE * CLIST::Head(void)
01227 //
01228 //             Returns the "_head" node of the list
01229 //
01230 //         BOOL CLIST::Is_Empty(void) const
01231 //
01232 //             Returns TRUE if head node is NULL, or FALSE otherwise
01233 //
01234 //         INT32 CLIST::Len(void) const
01235 //
01236 //             Returns the length of the list in the container
01237 //
01238 //
01239 
01240 class CLIST {
01241 private:
01242   CLIST_NODE *_head;
01243   CLIST_NODE *_tail;
01244 
01245   CLIST& operator = (const CLIST& cl);
01246   CLIST(const CLIST&);
01247 
01248 protected:
01249   CLIST(void)                   { _head = _tail = NULL; }
01250 
01251 public:
01252   void        Init(CLIST_NODE *list);
01253   CLIST(CLIST_NODE *list)               { Init(list); }
01254   ~CLIST(void)                          { _head = _tail = NULL; }
01255 
01256   void        Clear(void)               { _head = _tail = NULL; }
01257 
01258   void        Append( CLIST_NODE *nd );
01259   BOOL        Append( CLIST_NODE *nd, CLIST_NODE *od);
01260   void        Prepend( CLIST_NODE *nd );
01261   BOOL        Prepend( CLIST_NODE *nd, CLIST_NODE *od );
01262 
01263   void        Append_List(CLIST *new_list);
01264   void        Prepend_List(CLIST *new_list);
01265   CLIST_NODE *Remove_Headnode(void);
01266 
01267   CLIST_NODE *Head(void) const                 { return _head; }
01268   CLIST_NODE *Tail(void) const                 { return _tail; }
01269   BOOL        Is_Empty(void) const             { return _head == NULL; }
01270   INT32       Len(void) const;
01271 
01272 };
01273 
01274 // CLIST_ITER: the iterator class is typically used to iterate through
01275 //             a circularly linked list that is based on the base class
01276 //             CLIST_NODE, to perform certain operation.  It does not
01277 //             change the list content.
01278 //
01279 //       Exported Functions:
01280 //
01281 //         CLIST_ITER::CLIST_ITER(void)
01282 //
01283 //             Construct a circular list iter.  Initialize head/cur to NULL
01284 //
01285 //         CLIST_ITER::CLIST_ITER(CLIST_NODE *nd)
01286 //
01287 //             Construct a circular list iter.  Initialize head with nd,
01288 //             cur with NULL
01289 //
01290 //         CLIST_ITER::CLIST_ITER(CLIST *cl)
01291 //
01292 //             Construct a circular list iter.  It takes a circular list
01293 //             container and use its head to initialize this
01294 //             iterator's head pointer.  It also set cur node to NULL
01295 //
01296 //         CLIST_ITER::~CLIST_ITER(void)
01297 //
01298 //             Destruct a circular list iter.  It sets head to NULL
01299 //
01300 //         void CLIST_ITER::Init(CLIST_NODE *nd)
01301 //
01302 //             Initializes "_head" with node "nd"
01303 //
01304 //         void CLIST_ITER::Init(CLIST *cl)
01305 //
01306 //             Uses the circular list container's head to initialize the
01307 //             head node of this iterator.
01308 //
01309 //         void CLIST_ITER::Clear(void)
01310 //
01311 //             Set head to NULL
01312 //
01313 //         void CLIST_ITER:: Set(CLIST_NODE *nd)
01314 //
01315 //             Sets the current node "_cur" with node "nd"
01316 //
01317 //         CLIST_NODE* CLIST_ITER::First(void)
01318 //
01319 //             Gets the first element "_head" and set "_cur" pointer
01320 //
01321 //         CLIST_NODE* CLIST_ITER::Next(void)
01322 //
01323 //             Gets the _next element and bump the "_cur" pointer
01324 //
01325 //         CLIST_NODE* CLIST_ITER::Peek_Next(void)
01326 //
01327 //             Gets the _next element in the list
01328 //
01329 //         CLIST_NODE* CLIST_ITER::Head(void)
01330 //
01331 //             Gets the "_head" in the list
01332 //
01333 //         CLIST_NODE* CLIST_ITER::Cur(void)
01334 //
01335 //             Gets the "_cur" element in the list
01336 //
01337 //         INT32 CLIST_ITER::Len(void)
01338 //
01339 //             Gets the length of the list
01340 //
01341 //         BOOL CLIST_ITER::Is_Empty(void)
01342 //
01343 //             Returns TRUE if the current element, "_cur", is a NULL pointer.
01344 //
01345 // Example:
01346 // CLIST_ITER  foo_iter( list );
01347 //
01348 // for (foo_iter.First(); !foo_iter.Is_empty(); foo_iter.Next()) {
01349 //   // do whatever
01350 // }
01351 //
01352 
01353 class CLIST_ITER {
01354 private:
01355   CLIST_NODE *_head;
01356   CLIST_NODE *_cur;
01357   BOOL        _saw_head;
01358 
01359   CLIST_ITER& operator= (const CLIST_ITER& cl);
01360   CLIST_ITER(const CLIST_ITER&);
01361 
01362 protected:
01363   CLIST_ITER(void)              { _head = NULL; 
01364                                   _cur = NULL; 
01365                                   _saw_head = FALSE;
01366                                 }
01367 
01368 public:
01369   CLIST_ITER(CLIST_NODE *nd)    { _head = nd;
01370                                   _cur = _head; 
01371                                   _saw_head = FALSE;
01372                                 }
01373   CLIST_ITER(CLIST *cl)         { _head = cl->Head(); 
01374                                   _cur = _head; 
01375                                   _saw_head = FALSE;
01376                                 }
01377   ~CLIST_ITER(void)             { _head = NULL; 
01378                                   _cur = NULL;
01379                                   _saw_head = FALSE;
01380                                 }
01381 
01382   void         Init(CLIST_NODE *nd) 
01383                                 { _head = nd; 
01384                                   _cur = _head;
01385                                   _saw_head = FALSE;
01386                                 }
01387   void         Init(CLIST *cl)  { _head = cl->Head();
01388                                   _cur = _head;
01389                                   _saw_head = FALSE;
01390                                 }
01391   void         Init(void)       { _head = NULL; 
01392                                   _cur = NULL;
01393                                   _saw_head = FALSE;
01394                                 }
01395 
01396   void         Clear(void) { Init(); }
01397   void         Set(CLIST_NODE *nd)  {_cur = nd; }
01398   CLIST_NODE  *First(void);  // get the first element, and reset the pointer
01399   CLIST_NODE  *Next(void);   // get the next element, and bump the pointer.
01400 
01401   CLIST_NODE  *Peek_Next(void) const {return _cur->Next();} 
01402   CLIST_NODE  *Head(void) const   {return _head;}
01403   CLIST_NODE  *Cur(void)  const   {return _cur;}
01404   BOOL         Saw_Head(void) const {return _saw_head;}
01405   INT32        Len(void) const;    // get the length of the list
01406 
01407   // for circular list, if we've already seen the head, we're done
01408   BOOL         Is_Empty(void){ return ( _cur == NULL    ||
01409                                         (_cur == _head && _saw_head) );
01410                              }
01411 };
01412 
01413 // DECLARE_CLIST_NODE_CLASS: a macro to define the body of a derived
01414 //                           class "NAME_LIST" of CLIST_NODE
01415 //                   Example:
01416 //                           class NAME_LIST : public CLIST_NODE {
01417 //                           DECLARE_CLIST_NODE_CLASS( NAME_LIST )
01418 //                           ~NAME_LIST(void);
01419 //                           };
01420 //                   Note:   Create your own destructor!
01421 
01422 #define DECLARE_CLIST_NODE_CLASS( NAME_LIST )                         \
01423                                                                       \
01424 public:                                                               \
01425   NAME_LIST *Next(void) {return (NAME_LIST *) CLIST_NODE::Next();}    \
01426   void Insert_After(NAME_LIST *nd) {                                  \
01427     CLIST_NODE::Insert_After(nd);                                     \
01428   }                                                                   \
01429   void Insert_Before(NAME_LIST *nd) {                                 \
01430     CLIST_NODE::Insert_Before(nd);                                    \
01431   }                                                                   \
01432   NAME_NODE* Remove(NAME_LIST *prev) {                                \
01433     return (NAME_NODE*)CLIST_NODE::Remove(prev);                      \
01434   }                                                                   \
01435   void Set_Next(NAME_LIST *nd) {                                      \
01436     CLIST_NODE::Set_Next(nd);                                         \
01437   }                                                                   \
01438   INT32 Len(void)  { return CLIST_NODE::Len(); }                      \
01439 
01440 
01441 // DECLARE_CLIST_CLASS: a macro to define the body of a derived
01442 //                      class "NAME_LIST" of CLIST.
01443 //              Example:
01444 //                      class NAME_LIST : public CLIST {
01445 //                      DECLARE_CLIST_CLASS( NAME_LIST, NODE_T )
01446 //                      };
01447 
01448 #define DECLARE_CLIST_CLASS( NAME_LIST, NAME_NODE)                      \
01449 public:                                                                 \
01450   NAME_LIST(NAME_NODE *nd) { CLIST::Init(nd); }                         \
01451   void Append(NAME_NODE *nd) { CLIST::Append(nd); }                     \
01452   void Append(NAME_NODE *nd, NAME_NODE *od) {                           \
01453     CLIST::Append(nd, od);                                              \
01454   }                                                                     \
01455   void Prepend(NAME_NODE *nd) { CLIST::Prepend(nd); }                   \
01456   void Prepend(NAME_NODE *nd, NAME_NODE *od) {                          \
01457     CLIST::Prepend(nd, od);                                             \
01458   }                                                                     \
01459   void Append_List(NAME_LIST *nl) { CLIST::Append_List(nl); }           \
01460   void Prepend_List(NAME_LIST *nl) { CLIST::Prepend_List(nl); }         \
01461   NAME_NODE *Remove_Headnode(void) {                                    \
01462     return (NAME_NODE*)CLIST::Remove_Headnode();                        \
01463   }                                                                     \
01464   NAME_NODE *Head(void) { return (NAME_NODE *) CLIST::Head(); }         \
01465   NAME_NODE *Tail(void) { return (NAME_NODE *) CLIST::Tail(); }         \
01466   BOOL       Is_Empty(void) const { return CLIST::Is_Empty(); }         \
01467   INT32      Len(void) const { return CLIST::Len(); }                   \
01468 
01469 
01470 
01471 // DECLARE_CLIST_ITER_CLASS: a macro to define the body of a derived
01472 //                           class "NAME_LIST" of CLIST_ITER
01473 //                   Example:
01474 //                           class NAME_LIST : public CLIST_ITER {
01475 //                           DECLARE_CLIST_ITER_CLASS( NAME_LIST, NODE_T )
01476 //                           };
01477 
01478 #define DECLARE_CLIST_ITER_CLASS( NAME_ITER, NAME_NODE, NAME_LIST)      \
01479 public:                                                                 \
01480   NAME_ITER(NAME_NODE *nd) { CLIST_ITER::Init(nd); }                    \
01481   NAME_ITER(NAME_LIST *nl) { CLIST_ITER::Init(nl); }                    \
01482   NAME_ITER(void)          { CLIST_ITER::Init();   }                    \
01483   void Init(NAME_NODE *nd) { CLIST_ITER::Init(nd); }                    \
01484   void Init(NAME_LIST *nl) { CLIST_ITER::Init(nl); }                    \
01485   void Set(NAME_NODE *nd) { CLIST_ITER::Set(nd); }                      \
01486   NAME_NODE *First(void) { return (NAME_NODE *) CLIST_ITER::First(); }  \
01487   NAME_NODE *Next(void) { return (NAME_NODE *) CLIST_ITER::Next(); }    \
01488   NAME_NODE *Peek_Next(void){ return (NAME_NODE *) CLIST_ITER::Peek_Next(); }\
01489   NAME_NODE *Head(void) { return (NAME_NODE *) CLIST_ITER::Head(); }    \
01490   NAME_NODE *Cur(void) { return (NAME_NODE *) CLIST_ITER::Cur(); }      \
01491   BOOL       Saw_Head(void) { return CLIST_ITER::Saw_Head(); }          \
01492 
01493 
01494 
01495 #endif  // cxx_base_INCLUDED
01496 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines