Changeset 6b33e89 for libcfa/src/collections/list.hfa
- Timestamp:
- Apr 25, 2025, 7:39:09 AM (6 months ago)
- Branches:
- master
- Children:
- 65bd3c2
- Parents:
- b195498
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/collections/list.hfa
rb195498 r6b33e89 10 10 // Created On : Wed Apr 22 18:00:00 2020 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Apr 20 19:04:50202513 // Update Count : 5112 // Last Modified On : Thu Apr 24 18:12:59 2025 13 // Update Count : 72 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 ?`moveNextas75 // the first step, and uses the return of ?`moveNextas a guard, before dereferencing the iterator. So normal74 // and at the end of iteration, signifying, "no more elements." Normal comsumption of an iterator runs "advance" as 75 // the first step, and uses the return of "advance" 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 130 154 tE & insert_before( tE & before, tE & node ) { 131 155 verify( &before != 0p ); … … 194 218 } 195 219 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 ) { 220 tE & iter( dlist( tE, tLinks ) & list ) { 221 221 tE * origin = $get_list_origin_addr( list ); 222 222 return *origin; 223 223 } 224 tE & ?`head( dlist( tE, tLinks ) & list ) { 225 return list`elems; 226 } 227 228 bool ?`moveNext( tE && refx ) { 224 225 bool recede( tE && refx ) { 226 tE && ref_inner = refx; 227 tE & oldReferent = *(tE*)ORIGIN_TAG_CLEAR( (size_t)&ref_inner ); 228 &ref_inner = oldReferent`inner.prev; 229 return &ref_inner != 0p && ! ORIGIN_TAG_QUERY( (size_t)&ref_inner ); 230 } 231 232 bool advance( tE && refx ) { 229 233 tE && ref_inner = refx; 230 234 tE & oldReferent = *(tE*)ORIGIN_TAG_CLEAR( (size_t)&ref_inner ); … … 232 236 return &ref_inner != 0p && ! ORIGIN_TAG_QUERY( (size_t)&ref_inner ); 233 237 } 234 bool ?`next( tE && refx ) { // alternate name 235 return refx`moveNext; 236 } 237 238 bool ?`movePrev( tE && refx ) { 239 tE && ref_inner = refx; 240 tE & oldReferent = *(tE*)ORIGIN_TAG_CLEAR( (size_t)&ref_inner ); 241 &ref_inner = oldReferent`inner.prev; 242 return &ref_inner != 0p && ! ORIGIN_TAG_QUERY( (size_t)&ref_inner ); 243 } 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; 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; 258 249 return *0p; 259 250 } 260 251 261 tE & ?`prev( tE & node ) {262 if ( node`movePrev) return node;252 tE & next( tE & node ) { 253 if ( advance( node ) ) return node; 263 254 return *0p; 264 255 } 265 256 266 257 tE & insert_first( dlist( tE, tLinks ) & list, tE & node ) { 267 insert_after( list`elems, node );258 insert_after( iter( list ), node ); 268 259 return node; 269 260 } 270 261 271 262 tE & insert_last( dlist( tE, tLinks ) & list, tE & node ) { 272 insert_before( list`elems, node );273 return node; 274 } 275 tE & insert( dlist( tE, tLinks ) & list, tE & node ) { // alternate name263 insert_before( iter( list ), node ); 264 return node; 265 } 266 tE & insert( dlist( tE, tLinks ) & list, tE & node ) { // synonym for insert_last 276 267 insert_last( list, node ); 277 268 return node; … … 279 270 280 271 tE & remove_first( dlist( tE, tLinks ) & list ) { 281 return remove( list`first ); 272 tE & first_node = first( list ); 273 if ( &first_node ) return remove( first_node ); 274 return first_node; 282 275 } 283 276 284 277 tE & remove_last( dlist( tE, tLinks ) & list ) { 285 return remove( list`last ); 278 tE & last_node = last( list ); 279 if ( &last_node ) return remove( last_node ); 280 return last_node; 286 281 } 287 282 … … 322 317 // } 323 318 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 339 319 #if ! defined(NDEBUG) && (defined(__CFA_DEBUG__) || defined(__CFA_VERIFY__)) 340 320 bool $validate_fwd( dlist( tE, tLinks ) & this ) { 341 if ( ! & this`first ) return &this`last== 0p;321 if ( ! & first( this ) ) return &last( this ) == 0p; 342 322 343 323 tE & lagElem = *0p; 344 while ( tE & it = this`elems; it`moveNext) {345 if ( & lagElem == 0p && &it != & this`first) return false;324 while ( tE & it = iter( this ); advance( it ) ) { 325 if ( & lagElem == 0p && &it != & first( this ) ) return false; 346 326 &lagElem = ⁢ 347 327 } 348 328 349 if ( &lagElem != & this`last) return false;350 351 // TODO: verify that it is back at this`elems;329 if ( &lagElem != &last( this ) ) return false; 330 331 // TODO: verify that it is back at iter( this ); 352 332 return true; 353 333 } 354 334 355 335 bool $validate_rev( dlist( tE, tLinks ) & this ) { 356 if ( ! & this`last ) return &this`first== 0p;336 if ( ! & last( this ) ) return &first( this ) == 0p; 357 337 358 338 tE & lagElem = *0p; 359 while ( tE & it = this`elems; it`movePrev) {360 if ( &lagElem == 0p && &it != & this`last) return false;339 while ( tE & it = iter( this ); recede( it ) ) { 340 if ( &lagElem == 0p && &it != & last( this ) ) return false; 361 341 &lagElem = ⁢ 362 342 } 363 343 364 if ( &lagElem != & this`first) return false;365 366 // TODO: verify that it is back at this`elems;344 if ( &lagElem != &first( this ) ) return false; 345 346 // TODO: verify that it is back at iter( this ); 367 347 return true; 368 348 } … … 375 355 376 356 // TEMPORARY, until foreach statement created. 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); )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); )
Note:
See TracChangeset
for help on using the changeset viewer.