Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/collections/list.hfa

    r6b33e89 r65b0402  
    1010// Created On       : Wed Apr 22 18:00:00 2020
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Apr 24 18:12:59 2025
    13 // Update Count     : 72
     12// Last Modified On : Sun Apr 20 19:04:50 2025
     13// Update Count     : 51
    1414//
    1515
     
    7272
    7373// 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" as
    75 // the first step, and uses the return of "advance" as a guard, before dereferencing the iterator.  So normal
     74// 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
    7676// consumption of an iterator does not dereference an iterator in origin position.  The value of a pointer (underlying a
    7777// refence) that is exposed publicly as an iteraor, and also a pointer stored internally in a link field, is tagged, to
     
    128128
    129129static 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 
    154130        tE & insert_before( tE & before, tE & node ) {
    155131                verify( &before != 0p );
     
    218194        }
    219195
    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 ) {
    221221                tE * origin = $get_list_origin_addr( list );
    222222                return *origin;
    223223        }
    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 ) {
    226239                tE && ref_inner = refx;
    227240                tE & oldReferent = *(tE*)ORIGIN_TAG_CLEAR( (size_t)&ref_inner );
     
    229242                return &ref_inner != 0p && ! ORIGIN_TAG_QUERY( (size_t)&ref_inner );
    230243        }
    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;
    249258                return *0p;
    250259        }
    251260
    252         tE & next( tE & node ) {
    253                 if ( advance( node ) ) return node;
     261        tE & ?`prev( tE & node ) {
     262                if ( node`movePrev ) return node;
    254263                return *0p;
    255264        }
    256265
    257266        tE & insert_first( dlist( tE, tLinks ) & list, tE & node ) {
    258                 insert_after( iter( list ), node );
     267                insert_after( list`elems, node );
    259268                return node;
    260269        }
    261270
    262271        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_last
     272                insert_before( list`elems, node );
     273                return node;
     274        }
     275        tE &  insert( dlist( tE, tLinks ) & list, tE & node ) { // alternate name
    267276                insert_last( list, node );
    268277                return node;
     
    270279
    271280        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 );
    275282        }
    276283
    277284        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 );
    281286        }
    282287
     
    317322//      }
    318323
     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
    319339        #if ! defined(NDEBUG) && (defined(__CFA_DEBUG__) || defined(__CFA_VERIFY__))
    320340        bool $validate_fwd( dlist( tE, tLinks ) & this ) {
    321                 if ( ! & first( this ) ) return &last( this ) == 0p;
     341                if ( ! & this`first ) return &this`last == 0p;
    322342
    323343                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;
    326346                        &lagElem = ⁢
    327347                }
    328348
    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;
    332352                return true;
    333353        }
    334354
    335355        bool $validate_rev( dlist( tE, tLinks ) & this ) {
    336                 if ( ! & last( this ) ) return &first( this ) == 0p;
     356                if ( ! & this`last ) return &this`first == 0p;
    337357
    338358                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;
    341361                        &lagElem = ⁢
    342362                }
    343363
    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;
    347367                return true;
    348368        }
     
    355375
    356376// 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.