LinkList.h (7327B)
1 /* 2 =========================================================================== 3 4 Doom 3 BFG Edition GPL Source Code 5 Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. 6 7 This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). 8 9 Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation, either version 3 of the License, or 12 (at your option) any later version. 13 14 Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>. 21 22 In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below. 23 24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA. 25 26 =========================================================================== 27 */ 28 29 #ifndef __LINKLIST_H__ 30 #define __LINKLIST_H__ 31 32 /* 33 ============================================================================== 34 35 idLinkList 36 37 Circular linked list template 38 39 ============================================================================== 40 */ 41 42 template< class type > 43 class idLinkList { 44 public: 45 idLinkList(); 46 ~idLinkList(); 47 48 bool IsListEmpty() const; 49 bool InList() const; 50 int Num() const; 51 void Clear(); 52 53 void InsertBefore( idLinkList &node ); 54 void InsertAfter( idLinkList &node ); 55 void AddToEnd( idLinkList &node ); 56 void AddToFront( idLinkList &node ); 57 58 void Remove(); 59 60 type * Next() const; 61 type * Prev() const; 62 63 type * Owner() const; 64 void SetOwner( type *object ); 65 66 idLinkList * ListHead() const; 67 idLinkList * NextNode() const; 68 idLinkList * PrevNode() const; 69 70 private: 71 idLinkList * head; 72 idLinkList * next; 73 idLinkList * prev; 74 type * owner; 75 }; 76 77 /* 78 ================ 79 idLinkList<type>::idLinkList 80 81 Node is initialized to be the head of an empty list 82 ================ 83 */ 84 template< class type > 85 idLinkList<type>::idLinkList() { 86 owner = NULL; 87 head = this; 88 next = this; 89 prev = this; 90 } 91 92 /* 93 ================ 94 idLinkList<type>::~idLinkList 95 96 Removes the node from the list, or if it's the head of a list, removes 97 all the nodes from the list. 98 ================ 99 */ 100 template< class type > 101 idLinkList<type>::~idLinkList() { 102 Clear(); 103 } 104 105 /* 106 ================ 107 idLinkList<type>::IsListEmpty 108 109 Returns true if the list is empty. 110 ================ 111 */ 112 template< class type > 113 bool idLinkList<type>::IsListEmpty() const { 114 return head->next == head; 115 } 116 117 /* 118 ================ 119 idLinkList<type>::InList 120 121 Returns true if the node is in a list. If called on the head of a list, will always return false. 122 ================ 123 */ 124 template< class type > 125 bool idLinkList<type>::InList() const { 126 return head != this; 127 } 128 129 /* 130 ================ 131 idLinkList<type>::Num 132 133 Returns the number of nodes in the list. 134 ================ 135 */ 136 template< class type > 137 int idLinkList<type>::Num() const { 138 idLinkList<type> *node; 139 int num; 140 141 num = 0; 142 for( node = head->next; node != head; node = node->next ) { 143 num++; 144 } 145 146 return num; 147 } 148 149 /* 150 ================ 151 idLinkList<type>::Clear 152 153 If node is the head of the list, clears the list. Otherwise it just removes the node from the list. 154 ================ 155 */ 156 template< class type > 157 void idLinkList<type>::Clear() { 158 if ( head == this ) { 159 while( next != this ) { 160 next->Remove(); 161 } 162 } else { 163 Remove(); 164 } 165 } 166 167 /* 168 ================ 169 idLinkList<type>::Remove 170 171 Removes node from list 172 ================ 173 */ 174 template< class type > 175 void idLinkList<type>::Remove() { 176 prev->next = next; 177 next->prev = prev; 178 179 next = this; 180 prev = this; 181 head = this; 182 } 183 184 /* 185 ================ 186 idLinkList<type>::InsertBefore 187 188 Places the node before the existing node in the list. If the existing node is the head, 189 then the new node is placed at the end of the list. 190 ================ 191 */ 192 template< class type > 193 void idLinkList<type>::InsertBefore( idLinkList &node ) { 194 Remove(); 195 196 next = &node; 197 prev = node.prev; 198 node.prev = this; 199 prev->next = this; 200 head = node.head; 201 } 202 203 /* 204 ================ 205 idLinkList<type>::InsertAfter 206 207 Places the node after the existing node in the list. If the existing node is the head, 208 then the new node is placed at the beginning of the list. 209 ================ 210 */ 211 template< class type > 212 void idLinkList<type>::InsertAfter( idLinkList &node ) { 213 Remove(); 214 215 prev = &node; 216 next = node.next; 217 node.next = this; 218 next->prev = this; 219 head = node.head; 220 } 221 222 /* 223 ================ 224 idLinkList<type>::AddToEnd 225 226 Adds node at the end of the list 227 ================ 228 */ 229 template< class type > 230 void idLinkList<type>::AddToEnd( idLinkList &node ) { 231 InsertBefore( *node.head ); 232 } 233 234 /* 235 ================ 236 idLinkList<type>::AddToFront 237 238 Adds node at the beginning of the list 239 ================ 240 */ 241 template< class type > 242 void idLinkList<type>::AddToFront( idLinkList &node ) { 243 InsertAfter( *node.head ); 244 } 245 246 /* 247 ================ 248 idLinkList<type>::ListHead 249 250 Returns the head of the list. If the node isn't in a list, it returns 251 a pointer to itself. 252 ================ 253 */ 254 template< class type > 255 idLinkList<type> *idLinkList<type>::ListHead() const { 256 return head; 257 } 258 259 /* 260 ================ 261 idLinkList<type>::Next 262 263 Returns the next object in the list, or NULL if at the end. 264 ================ 265 */ 266 template< class type > 267 type *idLinkList<type>::Next() const { 268 if ( !next || ( next == head ) ) { 269 return NULL; 270 } 271 return next->owner; 272 } 273 274 /* 275 ================ 276 idLinkList<type>::Prev 277 278 Returns the previous object in the list, or NULL if at the beginning. 279 ================ 280 */ 281 template< class type > 282 type *idLinkList<type>::Prev() const { 283 if ( !prev || ( prev == head ) ) { 284 return NULL; 285 } 286 return prev->owner; 287 } 288 289 /* 290 ================ 291 idLinkList<type>::NextNode 292 293 Returns the next node in the list, or NULL if at the end. 294 ================ 295 */ 296 template< class type > 297 idLinkList<type> *idLinkList<type>::NextNode() const { 298 if ( next == head ) { 299 return NULL; 300 } 301 return next; 302 } 303 304 /* 305 ================ 306 idLinkList<type>::PrevNode 307 308 Returns the previous node in the list, or NULL if at the beginning. 309 ================ 310 */ 311 template< class type > 312 idLinkList<type> *idLinkList<type>::PrevNode() const { 313 if ( prev == head ) { 314 return NULL; 315 } 316 return prev; 317 } 318 319 /* 320 ================ 321 idLinkList<type>::Owner 322 323 Gets the object that is associated with this node. 324 ================ 325 */ 326 template< class type > 327 type *idLinkList<type>::Owner() const { 328 return owner; 329 } 330 331 /* 332 ================ 333 idLinkList<type>::SetOwner 334 335 Sets the object that this node is associated with. 336 ================ 337 */ 338 template< class type > 339 void idLinkList<type>::SetOwner( type *object ) { 340 owner = object; 341 } 342 343 #endif /* !__LINKLIST_H__ */