Ignore:
Timestamp:
May 11, 2021, 9:52:18 PM (4 years ago)
Author:
Michael Brooks <mlbrooks@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
1e5cd9a, 67b421c
Parents:
8d1ad36
Message:

Changing how the dlist API specifies which list direction you're working on.

New style is:
with( DLINK_VIA( request, request.priority ) ) remove( myItem );

This change eliminates the diref type from the public API. The diref type did not support intutive use of taking the address of its referent, as is needed to null-check or identity-compare a reference.

File:
1 edited

Legend:

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

    r8d1ad36 r7d51ef8  
    1818#include <assert.h>
    1919
    20 extern "C" {
    21     void * memset ( void * ptr, int value, size_t num );
    22 }
    23 
    24 trait embedded( tOuter &, tInner & ) {
    25     tInner & ?`inner( tOuter & );
     20forall( Decorator &, T & )
     21struct tytagref {
     22    inline T &;
    2623};
    2724
    28 // embedded is reflexive
    29 forall( tX & )
    30 static inline tX & ?`inner( tX & this ) { return this; }
     25trait embedded( tOuter &, tMid &, tInner & ) {
     26    tytagref( tMid, tInner ) ?`inner( tOuter & );
     27};
     28
     29// embedded is reflexive, with no info (void) as the type tag
     30forall (T &)
     31tytagref(void, T) ?`inner ( T & this ) { tytagref( void, T ) ret = {this}; return ret; }
    3132
    3233// use this on every case of plan-9 inheritance, to make embedded a closure of plan-9 inheritance
    33 #define P9_EMBEDDED( tOuter, tInner ) \
    34    static inline tInner & ?`inner( tOuter & this ) { return this; }
     34#define P9_EMBEDDED( derived, immedBase ) \
     35forall( Tbase &, TdiscardPath & | { tytagref( TdiscardPath, Tbase ) ?`inner( immedBase & ); } ) \
     36    static inline tytagref(immedBase, Tbase) ?`inner( derived & this ) { \
     37        immedBase & ib = this; \
     38        Tbase & b = ib`inner; \
     39        tytagref(immedBase, Tbase) result = { b }; \
     40        return result; \
     41    }
     42
     43#define EMBEDDED_VIA( OUTER, MID, INNER ) \
     44   (struct { tytagref(MID, INNER) ( * ?`inner ) ( OUTER & ); }){ ?`inner }
     45
     46#define DLINK_VIA( TE, TLINK ) \
     47   EMBEDDED_VIA( TE, TLINK, dlink(TE) )
    3548
    3649
     
    8194    }
    8295
    83     forall( tLinks & = tE ) {
    84 
    85         struct dlist {
    86             inline dlink(tE);
    87         };
    88 
    89         struct diref {
    90             inline tE &;
    91         };
    92     }
    93 
    94     forall( tLinks & = tE | embedded( tE, tLinks ) | embedded( tLinks, dlink(tE) ) ) {
     96    forall( tLinks & = dlink(tE) )
     97    struct dlist {
     98        inline dlink(tE);
     99    };
     100
     101    forall( tLinks & | embedded( tE, tLinks, dlink(tE) ) ) {
    95102        static inline tE * $get_list_origin_addr( dlist(tE, tLinks) & lst ) {
    96             dlink(tE) & link_from_null = ( * (tE *) 0p )`inner`inner;
     103            dlink(tE) & link_from_null = ( * (tE *) 0p )`inner;
    97104            ptrdiff_t link_offset = (ptrdiff_t) & link_from_null;
    98105            size_t origin_addr = ((size_t) & lst) - link_offset;
     
    105112            ( ( dlink(tE) & ) this ){ listOrigin, listOrigin } ;
    106113        }
    107 
    108         // redundant
    109         // void ?{}( diref(tE, tLinks) & this, tE & target ) {
    110         //     tE && ref = this;
    111         //     &ref = &target;
    112         // }
    113114    }
    114115
     
    116117
    117118
    118 forall( tE &, tLinks & | embedded( tE, tLinks ) | embedded( tLinks, dlink(tE) ) ) {
    119 
    120         static inline void insert_after(diref(tE, tLinks) list_pos, tE &to_insert) {
     119forall( tE &, tLinks & | embedded( tE, tLinks, dlink(tE) ) ) {
     120
     121        static inline void insert_after(tE & list_pos, tE &to_insert) {
    121122                verify (&list_pos != 0p);
    122123                verify (&to_insert != 0p);
    123         dlink(tE) & linkToInsert = to_insert`inner`inner;
     124        dlink(tE) & linkToInsert = to_insert`inner;
    124125                verify(linkToInsert.prev == 0p);
    125126                verify(linkToInsert.next == 0p);
    126127        tE & list_pos_raw = list_pos;
    127128        tE & list_pos_elem = * (tE *) ORIGIN_TAG_CLEAR( (size_t) & list_pos_raw );
    128         asm( "" : : : "memory" );
    129         tE & after_raw = * (list_pos_elem`inner`inner).next;
     129        dlink(tE) & list_pos_links = list_pos_elem`inner;
     130        asm( "" : : : "memory" );
     131        tE & after_raw = * list_pos_links.next;
    130132        tE & after_elem = * (tE *) ORIGIN_TAG_CLEAR( (size_t) & after_raw );
    131133                linkToInsert.prev = & list_pos_raw;
    132134                linkToInsert.next = & after_raw;
    133         (after_elem`inner`inner).prev = &to_insert;
    134                 (list_pos_elem`inner`inner).next = &to_insert;
    135         asm( "" : : : "memory" );
    136         }
    137 
    138         static inline void insert_before(diref(tE, tLinks) list_pos, tE &to_insert) {
     135        dlink(tE) & afterLinks = after_elem`inner;
     136        afterLinks.prev = &to_insert;
     137                list_pos_links.next = &to_insert;
     138        asm( "" : : : "memory" );
     139        }
     140
     141        static inline void insert_before(tE & list_pos, tE &to_insert) {
    139142                verify (&list_pos != 0p);
    140143                verify (&to_insert != 0p);
    141         dlink(tE) & linkToInsert = to_insert`inner`inner;
     144        dlink(tE) & linkToInsert = to_insert`inner;
    142145                verify(linkToInsert.next == 0p);
    143146                verify(linkToInsert.prev == 0p);
    144147        tE & list_pos_raw = list_pos;
    145148        tE & list_pos_elem = * (tE *) ORIGIN_TAG_CLEAR( (size_t) & list_pos_raw );
    146         asm( "" : : : "memory" );
    147         tE & before_raw = * (list_pos_elem`inner`inner).prev;
     149        dlink(tE) & list_pos_links = list_pos_elem`inner;
     150        asm( "" : : : "memory" );
     151        tE & before_raw = * (list_pos_links).prev;
    148152        tE & before_elem = * (tE *) ORIGIN_TAG_CLEAR( (size_t) & before_raw );
    149153                linkToInsert.next = & list_pos_raw;
    150154                linkToInsert.prev = & before_raw;
    151         (before_elem`inner`inner).next = &to_insert;
    152                 (list_pos_elem`inner`inner).prev = &to_insert;
    153         asm( "" : : : "memory" );
    154         }
    155 
    156         static inline tE & remove(diref(tE, tLinks) list_pos) {
     155        dlink(tE) & beforeLinks = before_elem`inner;
     156        beforeLinks.next = &to_insert;
     157                (list_pos_links).prev = &to_insert;
     158        asm( "" : : : "memory" );
     159        }
     160
     161        static inline tE & remove(tE & list_pos) {
    157162                verify (&list_pos != 0p);
    158163        tE & list_pos_elem = list_pos;
    159164        verify( ! ORIGIN_TAG_QUERY((size_t) & list_pos_elem) );
    160         dlink(tE) & list_pos_links = list_pos_elem`inner`inner;
     165        dlink(tE) & list_pos_links = list_pos_elem`inner;
    161166        tE & before_raw = * list_pos_links.prev;
    162167        tE & before_elem = * (tE *) ORIGIN_TAG_CLEAR( (size_t) & before_raw );
    163         dlink(tE) & before_links = before_elem`inner`inner;
     168        dlink(tE) & before_links = before_elem`inner;
    164169        tE & after_raw = * list_pos_links.next;
    165170        tE & after_elem = * (tE *) ORIGIN_TAG_CLEAR( (size_t) & after_raw );
    166         dlink(tE) & after_links = after_elem`inner`inner;
     171        dlink(tE) & after_links = after_elem`inner;
    167172        before_links.next = &after_raw;
    168173        after_links.prev = &before_raw;
     
    174179        }
    175180
    176     static inline diref(tE, tLinks) ?`first( dlist(tE, tLinks) &lst ) {
     181    static inline tE & ?`first( dlist(tE, tLinks) &lst ) {
    177182        tE * firstPtr = lst.next;
    178183        if (ORIGIN_TAG_QUERY((size_t)firstPtr)) firstPtr = 0p;
    179         diref(tE, tLinks) ret = { *firstPtr };
    180         return ret;
    181     }
    182     static inline diref(tE, tLinks) ?`last ( dlist(tE, tLinks) &lst ) {
     184        return *firstPtr;
     185    }
     186    static inline tE & ?`last ( dlist(tE, tLinks) &lst ) {
    183187        tE * lastPtr = lst.prev;
    184188        if (ORIGIN_TAG_QUERY((size_t)lastPtr)) lastPtr = 0p;
    185         diref(tE, tLinks) ret = { *lastPtr };
    186         return ret;
     189        return *lastPtr;
    187190    }
    188191
     
    193196    }
    194197
    195     static inline int ?!=?( const diref(tE, tLinks) & list_pos, zero_t ) {
    196         tE & list_pos_elem = list_pos;
    197         if (ORIGIN_TAG_QUERY((size_t) & list_pos_elem)) return 0;
    198         return & list_pos_elem != 0p;
    199     }
    200 
    201     static inline int DUMB_COMPARE( diref(tE, tLinks) list_pos, tE * elem ) {
    202         tE & signifiedLhs = list_pos;
    203         return &signifiedLhs == elem;
    204     }
    205 
    206     static inline diref(tE, tLinks) ?`from( tE & elem ) {
    207         diref(tE, tLinks) ret = { elem };
    208         return ret;
    209     }
    210 
    211     static inline diref(tE, tLinks) ?`elems( dlist(tE, tLinks) & lst ) {
     198    static inline tE & ?`elems( dlist(tE, tLinks) & lst ) {
    212199        tE * origin = $get_list_origin_addr( lst );
    213         diref(tE, tLinks) ret = { *origin };
    214         return ret;
    215     }
    216 
    217     static inline bool ?`moveNext( diref(tE, tLinks) & refx ) {
     200        return *origin;
     201    }
     202
     203    static inline bool ?`moveNext( tE && refx ) {
    218204        tE && ref_inner = refx;
    219205        tE & oldReferent = * (tE*) ORIGIN_TAG_CLEAR( (size_t) & ref_inner );
    220         &ref_inner = oldReferent`inner`inner.next;
     206        &ref_inner = oldReferent`inner.next;
    221207        return &ref_inner != 0p  &&
    222208            ! ORIGIN_TAG_QUERY( (size_t) & ref_inner );
    223209    }
    224210
    225     static inline bool ?`movePrev( diref(tE, tLinks) & refx ) {
     211    static inline bool ?`movePrev( tE && refx ) {
    226212        tE && ref_inner = refx;
    227213        tE & oldReferent = * (tE*) ORIGIN_TAG_CLEAR( (size_t) & ref_inner );
    228         &ref_inner = oldReferent`inner`inner.prev;
     214        &ref_inner = oldReferent`inner.prev;
    229215        return &ref_inner != 0p  &&
    230216            ! ORIGIN_TAG_QUERY( (size_t) & ref_inner );
    231217    }
    232218
    233     static inline bool ?`hasNext( diref(tE, tLinks) refx ) {
    234         return refx`moveNext;
    235     }
    236 
    237     static inline bool ?`hasPrev( diref(tE, tLinks) refx ) {
    238         return refx`movePrev;
    239     }
    240 
    241     static inline diref(tE, tLinks) ?`next( diref(tE, tLinks) refx ) {
    242         if( refx`moveNext ) return refx;
    243         tE && ref_inner = refx;
    244         & ref_inner = 0p;
    245         return refx;
    246     }
    247 
    248     static inline diref(tE, tLinks) ?`prev( diref(tE, tLinks) refx ) {
    249         if( refx`movePrev ) return refx;
    250         tE && ref_inner = refx;
    251         & ref_inner = 0p;
    252         return refx;
     219    static inline bool ?`hasNext( tE & e ) {
     220        return e`moveNext;
     221    }
     222
     223    static inline bool ?`hasPrev( tE & e ) {
     224        return e`movePrev;
     225    }
     226
     227    static inline tE & ?`next( tE & e ) {
     228        if( e`moveNext ) return e;
     229        return * 0p;
     230    }
     231
     232    static inline tE & ?`prev( tE & e ) {
     233        if( e`movePrev ) return e;
     234        return * 0p;
    253235    }
    254236
     
    262244
    263245    static inline tE & try_pop_front( dlist(tE, tLinks) &lst ) {
    264         diref(tE, tLinks) first_inlist = lst`first;
     246        tE & first_inlist = lst`first;
    265247        tE & first_item = first_inlist;
    266248        if (&first_item) remove(first_inlist);
     
    269251
    270252    static inline tE & try_pop_back( dlist(tE, tLinks) &lst ) {
    271         diref(tE, tLinks) last_inlist = lst`last;
     253        tE & last_inlist = lst`last;
    272254        tE & last_item = last_inlist;
    273255        if (&last_item) remove(last_inlist);
     
    282264        tE & lagElem = *0p;
    283265
    284         while ( diref(tE, tLinks) it = this`elems; it`moveNext ) {
     266        while ( tE & it = this`elems; it`moveNext ) {
    285267            if (& lagElem == 0p &&  &it != & this`first ) return false;
    286268            & lagElem = & it;
     
    297279        tE & lagElem = *0p;
    298280
    299         while ( diref(tE, tLinks) it = this`elems; it`movePrev ) {
     281        while ( tE & it = this`elems; it`movePrev ) {
    300282            if (& lagElem == 0p &&  &it != & this`last ) return false;
    301283            & lagElem = & it;
     
    314296}
    315297
    316 forall( tE & | embedded( tE, dlink(tE) ) ) {
    317         static inline void insert_after(tE & list_pos, tE &to_insert ) {
    318         diref(tE, tE) list_pos_ref = list_pos`from;
    319         insert_after( list_pos_ref, to_insert );
    320     }
    321         static inline void insert_before(tE & list_pos, tE &to_insert ) {
    322         diref(tE, tE) list_pos_ref = list_pos`from;
    323         insert_before( list_pos_ref, to_insert );
    324     }
    325         static inline tE & remove(tE & list_pos ) {
    326         diref(tE, tE) list_pos_ref = list_pos`from;
    327         return remove( list_pos_ref );
    328     }
    329     static inline bool ?`moveNext( tE && ref ) {
    330         diref(tE, tE) & ref_dird = (diref(tE, tE) &) & ref;
    331         return ref_dird`moveNext;
    332     }
    333     static inline bool ?`movePrev( tE && ref ) {
    334         diref(tE, tE) & ref_dird = (diref(tE, tE) &) & ref;
    335         return ref_dird`movePrev;
    336     }
    337     static inline bool ?`hasNext( tE & ref ) {
    338         diref(tE, tE) ref_dird = { ref };
    339         return ref_dird`hasNext;
    340     }
    341     static inline bool ?`hasPrev( tE & ref ) {
    342         diref(tE, tE) ref_dird = { ref };
    343         return ref_dird`hasPrev;
    344     }
    345     static inline tE & ?`next( tE & ref ) {
    346         diref(tE, tE) ref_dird = { ref };
    347         diref(tE, tE) rslt = ref_dird`next;
    348         return rslt;
    349     }
    350     static inline tE & ?`prev( tE & ref ) {
    351         diref(tE, tE) ref_dird = { ref };
    352         diref(tE, tE) rslt = ref_dird`prev;
    353         return rslt;
    354     }
    355 }
Note: See TracChangeset for help on using the changeset viewer.