DOOM-3-BFG

DOOM 3 BFG Edition
Log | Files | Refs

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__ */