Changeset 8f448e0


Ignore:
Timestamp:
Nov 12, 2025, 1:27:30 PM (3 months ago)
Author:
Michael Brooks <mlbrooks@…>
Branches:
master
Children:
5e0b6657
Parents:
1b4e5a8
git-author:
Michael Brooks <mlbrooks@…> (10/15/25 18:05:26)
git-committer:
Michael Brooks <mlbrooks@…> (11/12/25 13:27:30)
Message:

Make dlist2 pass the original dlist test. Now, there is one common test for both.

Files:
2 added
2 edited

Legend:

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

    r1b4e5a8 r8f448e0  
    239239}
    240240
     241forall( tE & ) {
     242#ifdef __EXPERIMENTAL_DISABLE_OTAG__ // Perf experimention alt mode
     243    static inline size_t origin_tag_query_arith$( tE & raw ) {
     244        return 0;
     245    }
     246    static inline tE & nullif$( tE & val, size_t arith_ctrl ) {
     247        verify( arith_ctrl == 0 );  (void) arith_ctrl;
     248        return val;
     249    }
     250#else // Normal
     251    // like ORIGIN_TAG_QUERY, but return is arithmetic number 0 or 1 (rather than 0 or non-0)
     252    static inline size_t origin_tag_query_arith$( tE & raw ) {
     253        size_t ret = (((size_t) & raw) >> ORIGIN_TAG_BITNO) & 1;
     254        verify( ORIGIN_TAG_QUERY( (size_t) & raw ) ? ret == 1 : ret == 0 );
     255        return ret;
     256    }
     257    // Requires arith_ctrl being 0 or 1.
     258    // When 0, passes val through; when 1, returns null reference.
     259    // Importantly, implemented without jumps or tests.
     260    static inline tE & nullif$( tE & val, size_t arith_ctrl ) {
     261        verify( ! ORIGIN_TAG_QUERY( (size_t) & val ) );
     262        verify( arith_ctrl == 0 || arith_ctrl == 1 );
     263        size_t mask_ctrl = ~ - arith_ctrl;
     264        verify( arith_ctrl == 0 && mask_ctrl == -1 || arith_ctrl == 1 && mask_ctrl ==0 );
     265        tE & ret = * (tE*) ( ((size_t) & val) & mask_ctrl);
     266        verify( arith_ctrl == 0 && &ret == &val || arith_ctrl == 1 && &ret == 0p );
     267        return ret;
     268    }
     269#endif
     270}
    241271
    242272forall( tE &, tLinks & | embedded( tE, tLinks, dlink(tE) ) ) {
     
    496526                verify (&lst != 0p);
    497527        dlink(tE) & list_links = lst;
    498         verify (! ORIGIN_TAG_QUERY( (size_t) (list_links.next) ) );
    499 
    500         dlink(tE) & fst_links = * list_links.next;
     528        verify (! ORIGIN_TAG_QUERY( (size_t) (& list_links) ) );
     529        // call is valid on empty list; when so, list_links.next and after_links.prev have otags set
     530
     531        dlink(tE) & fst_raw = * list_links.next;
     532        dlink(tE) & fst_links = * (dlink(tE) *) ORIGIN_TAG_CLEAR( (size_t) & fst_raw );
     533        size_t fst_tagval = origin_tag_query_arith$( fst_raw );
    501534
    502535        dlink(tE) & after_raw = * fst_links.next;
    503536        dlink(tE) & after_links = * (dlink(tE) *) ORIGIN_TAG_CLEAR( (size_t) & after_raw );
    504         verify( ! ORIGIN_TAG_QUERY( (size_t) (after_links.prev) ) );
    505537
    506538        size_t before_links_next_rslt = ((size_t) & after_raw);
     
    515547        asm( "" : : : "memory" );
    516548
    517         tytagref( tLinks, dlink(tE) ) lpLnkTagged = {fst_links};
    518         return downcast$( lpLnkTagged );
     549        tytagref( tLinks, dlink(tE) ) retExt = { fst_links };
     550        return nullif$( downcast$( retExt ), fst_tagval );
    519551    }
    520552
     
    522554                verify (&lst != 0p);
    523555        dlink(tE) & list_links = lst;
    524         verify (! ORIGIN_TAG_QUERY( (size_t) (list_links.prev) ) );
    525 
    526         dlink(tE) & last_links = * list_links.prev;
     556        // call is valid on empty list; when so, list_links.prev and before_links.next have otags set
     557
     558        dlink(tE) & last_raw = * list_links.prev;
     559        dlink(tE) & last_links = * (dlink(tE) *) ORIGIN_TAG_CLEAR( (size_t) & last_raw );
     560        size_t last_tagval = origin_tag_query_arith$( last_raw );
    527561
    528562        dlink(tE) & before_raw = * last_links.prev;
    529563        dlink(tE) & before_links = * (dlink(tE) *) ORIGIN_TAG_CLEAR( (size_t) & before_raw );
    530         verify( ! ORIGIN_TAG_QUERY( (size_t) (before_links.next) ) );
    531564
    532565        size_t after_links_prev_rslt = ((size_t) & before_raw);
     
    541574        asm( "" : : : "memory" );
    542575
    543         tytagref( tLinks, dlink(tE) ) lpLnkTagged = {last_links};
    544         return downcast$( lpLnkTagged );
     576        tytagref( tLinks, dlink(tE) ) lpLnkTagged = { last_links };
     577        return nullif$( downcast$( lpLnkTagged ), last_tagval );
    545578    }
    546579
  • tests/list/dlist-insert-remove.cfa

    r1b4e5a8 r8f448e0  
     1#ifdef __TEMP_DLIST_V2__
     2#include <collections/list2.hfa>
     3#else
    14#include <collections/list.hfa>
     5#endif
    26#include <assert.h>
    37// NO including fstream.hfa (use printf, not sout)
Note: See TracChangeset for help on using the changeset viewer.