Changes in libcfa/src/collections/list.hfa [6b33e89:65b0402]
- File:
-
- 1 edited
-
libcfa/src/collections/list.hfa (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/collections/list.hfa
r6b33e89 r65b0402 10 10 // Created On : Wed Apr 22 18:00:00 2020 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Apr 24 18:12:59202513 // Update Count : 7212 // Last Modified On : Sun Apr 20 19:04:50 2025 13 // Update Count : 51 14 14 // 15 15 … … 72 72 73 73 // The origin is the position encountered at the start of iteration, signifying, "need to advance to the first element," 74 // and at the end of iteration, signifying, "no more elements." Normal comsumption of an iterator runs "advance"as75 // the first step, and uses the return of "advance"as a guard, before dereferencing the iterator. So normal74 // and at the end of iteration, signifying, "no more elements." Normal comsumption of an iterator runs ?`moveNext as 75 // the first step, and uses the return of ?`moveNext as a guard, before dereferencing the iterator. So normal 76 76 // consumption of an iterator does not dereference an iterator in origin position. The value of a pointer (underlying a 77 77 // refence) that is exposed publicly as an iteraor, and also a pointer stored internally in a link field, is tagged, to … … 128 128 129 129 static inline forall( tE &, tLinks & | embedded( tE, tLinks, dlink( tE ) ) ) { 130 bool isListed( tE & node ) {131 verify( &node != 0p );132 dlink( tE ) & node_links = node`inner;133 return (node_links.prev != 0p) || (node_links.next != 0p);134 }135 136 bool isEmpty( dlist( tE, tLinks ) & list ) {137 tE * firstPtr = list.next;138 if ( ORIGIN_TAG_QUERY(( size_t)firstPtr) ) firstPtr = 0p;139 return firstPtr == 0p;140 }141 142 tE & first( dlist( tE, tLinks ) & list ) {143 tE * firstPtr = list.next;144 if ( ORIGIN_TAG_QUERY( (size_t)firstPtr ) ) firstPtr = 0p;145 return *firstPtr;146 }147 148 tE & last( dlist( tE, tLinks ) & list ) {149 tE * lastPtr = list.prev;150 if ( ORIGIN_TAG_QUERY( (size_t)lastPtr) ) lastPtr = 0p;151 return *lastPtr;152 }153 154 130 tE & insert_before( tE & before, tE & node ) { 155 131 verify( &before != 0p ); … … 218 194 } 219 195 220 tE & iter( dlist( tE, tLinks ) & list ) { 196 tE & ?`first( dlist( tE, tLinks ) & list ) { 197 tE * firstPtr = list.next; 198 if ( ORIGIN_TAG_QUERY( (size_t)firstPtr ) ) firstPtr = 0p; 199 return *firstPtr; 200 } 201 202 tE & ?`last( dlist( tE, tLinks ) & list ) { 203 tE * lastPtr = list.prev; 204 if ( ORIGIN_TAG_QUERY( (size_t)lastPtr) ) lastPtr = 0p; 205 return *lastPtr; 206 } 207 208 bool ?`isEmpty( dlist( tE, tLinks ) & list ) { 209 tE * firstPtr = list.next; 210 if ( ORIGIN_TAG_QUERY(( size_t)firstPtr) ) firstPtr = 0p; 211 return firstPtr == 0p; 212 } 213 214 bool ?`isListed( tE & node ) { 215 verify( &node != 0p ); 216 dlink( tE ) & node_links = node`inner; 217 return (node_links.prev != 0p) || (node_links.next != 0p); 218 } 219 220 tE & ?`elems( dlist( tE, tLinks ) & list ) { 221 221 tE * origin = $get_list_origin_addr( list ); 222 222 return *origin; 223 223 } 224 225 bool recede( tE && refx ) { 224 tE & ?`head( dlist( tE, tLinks ) & list ) { 225 return list`elems; 226 } 227 228 bool ?`moveNext( tE && refx ) { 229 tE && ref_inner = refx; 230 tE & oldReferent = *(tE*)ORIGIN_TAG_CLEAR( (size_t)&ref_inner ); 231 &ref_inner = oldReferent`inner.next; 232 return &ref_inner != 0p && ! ORIGIN_TAG_QUERY( (size_t)&ref_inner ); 233 } 234 bool ?`next( tE && refx ) { // alternate name 235 return refx`moveNext; 236 } 237 238 bool ?`movePrev( tE && refx ) { 226 239 tE && ref_inner = refx; 227 240 tE & oldReferent = *(tE*)ORIGIN_TAG_CLEAR( (size_t)&ref_inner ); … … 229 242 return &ref_inner != 0p && ! ORIGIN_TAG_QUERY( (size_t)&ref_inner ); 230 243 } 231 232 bool advance( tE && refx ) { 233 tE && ref_inner = refx; 234 tE & oldReferent = *(tE*)ORIGIN_TAG_CLEAR( (size_t)&ref_inner ); 235 &ref_inner = oldReferent`inner.next; 236 return &ref_inner != 0p && ! ORIGIN_TAG_QUERY( (size_t)&ref_inner ); 237 } 238 239 bool isFirst( tE & node ) { 240 return recede( node ); 241 } 242 243 bool isLast( tE & node ) { 244 return advance( node ); 245 } 246 247 tE & prev( tE & node ) { 248 if ( recede( node ) ) return node; 244 bool ?`prev( tE && refx ) { // alternate name 245 return refx`movePrev; 246 } 247 248 bool ?`hasNext( tE & node ) { 249 return node`moveNext; 250 } 251 252 bool ?`hasPrev( tE & node ) { 253 return node`movePrev; 254 } 255 256 tE & ?`next( tE & node ) { 257 if ( node`moveNext ) return node; 249 258 return *0p; 250 259 } 251 260 252 tE & next( tE & node ) {253 if ( advance( node )) return node;261 tE & ?`prev( tE & node ) { 262 if ( node`movePrev ) return node; 254 263 return *0p; 255 264 } 256 265 257 266 tE & insert_first( dlist( tE, tLinks ) & list, tE & node ) { 258 insert_after( iter( list ), node );267 insert_after( list`elems, node ); 259 268 return node; 260 269 } 261 270 262 271 tE & insert_last( dlist( tE, tLinks ) & list, tE & node ) { 263 insert_before( iter( list ), node );264 return node; 265 } 266 tE & insert( dlist( tE, tLinks ) & list, tE & node ) { // synonym for insert_last272 insert_before( list`elems, node ); 273 return node; 274 } 275 tE & insert( dlist( tE, tLinks ) & list, tE & node ) { // alternate name 267 276 insert_last( list, node ); 268 277 return node; … … 270 279 271 280 tE & remove_first( dlist( tE, tLinks ) & list ) { 272 tE & first_node = first( list ); 273 if ( &first_node ) return remove( first_node ); 274 return first_node; 281 return remove( list`first ); 275 282 } 276 283 277 284 tE & remove_last( dlist( tE, tLinks ) & list ) { 278 tE & last_node = last( list ); 279 if ( &last_node ) return remove( last_node ); 280 return last_node; 285 return remove( list`last ); 281 286 } 282 287 … … 317 322 // } 318 323 324 tE & try_pop_front( dlist( tE, tLinks ) & list ) { 325 tE & first_inlist = list`first; 326 tE & first_item = first_inlist; 327 if ( &first_item ) remove( first_inlist ); 328 return first_item; 329 } 330 331 tE & try_pop_back( dlist( tE, tLinks ) & list ) { 332 tE & last_inlist = list`last; 333 tE & last_item = last_inlist; 334 if ( &last_item ) remove( last_inlist ); 335 return last_item; 336 } 337 338 319 339 #if ! defined(NDEBUG) && (defined(__CFA_DEBUG__) || defined(__CFA_VERIFY__)) 320 340 bool $validate_fwd( dlist( tE, tLinks ) & this ) { 321 if ( ! & first( this ) ) return &last( this )== 0p;341 if ( ! & this`first ) return &this`last == 0p; 322 342 323 343 tE & lagElem = *0p; 324 while ( tE & it = iter( this ); advance( it )) {325 if ( & lagElem == 0p && &it != & first( this )) return false;344 while ( tE & it = this`elems; it`moveNext ) { 345 if ( & lagElem == 0p && &it != & this`first ) return false; 326 346 &lagElem = ⁢ 327 347 } 328 348 329 if ( &lagElem != & last( this )) return false;330 331 // TODO: verify that it is back at iter( this );349 if ( &lagElem != &this`last ) return false; 350 351 // TODO: verify that it is back at this`elems; 332 352 return true; 333 353 } 334 354 335 355 bool $validate_rev( dlist( tE, tLinks ) & this ) { 336 if ( ! & last( this ) ) return &first( this )== 0p;356 if ( ! & this`last ) return &this`first == 0p; 337 357 338 358 tE & lagElem = *0p; 339 while ( tE & it = iter( this ); recede( it )) {340 if ( &lagElem == 0p && &it != & last( this )) return false;359 while ( tE & it = this`elems; it`movePrev ) { 360 if ( &lagElem == 0p && &it != & this`last ) return false; 341 361 &lagElem = ⁢ 342 362 } 343 363 344 if ( &lagElem != & first( this )) return false;345 346 // TODO: verify that it is back at iter( this );364 if ( &lagElem != &this`first ) return false; 365 366 // TODO: verify that it is back at this`elems; 347 367 return true; 348 368 } … … 355 375 356 376 // TEMPORARY, until foreach statement created. 357 #define FOREACH( list, index ) for ( typeof( iter( list )) & (index) = iter( list ); advance( index ); )358 #define FOREACH_REV( list, index ) for ( typeof( iter( list )) & (index) = iter( list ); recede( index ); )359 #define FOREACH_COND( list, index, expr ) for ( typeof( iter( list )) & (index) = iter( list ); advance( index )&& !(expr); )360 #define FOREACH_REV_COND( list, index, expr ) for ( typeof( iter( list )) & (index) = iter( list ); recede( index )&& !(expr); )377 #define FOREACH( list, index ) for ( typeof((list)`head) & (index) = (list)`head; (index)`next; ) 378 #define FOREACH_REV( list, index ) for ( typeof((list)`head) & (index) = (list)`head; (index)`prev; ) 379 #define FOREACH_COND( list, index, expr ) for ( typeof((list)`head) & (index) = (list)`head; (index)`next && !(expr); ) 380 #define FOREACH_REV_COND( list, index, expr ) for ( typeof((list)`head) & (index) = (list)`head; (index)`prev && !(expr); )
Note:
See TracChangeset
for help on using the changeset viewer.