Open64 (mfef90, whirl2f, and IR tools)
TAG: version-openad; SVN changeset: 916
|
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