- Timestamp:
- May 12, 2021, 1:37:09 PM (3 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 8cd40bf
- Parents:
- 1680072 (diff), 7d51ef8 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/containers/list2.hfa
r1680072 r1e5cd9a 18 18 #include <assert.h> 19 19 20 forall( T & ) struct tag {}; 21 #define ttag(T) ((tag(T)){}) 22 #define ztag(n) ttag(Z(n)) 23 24 extern "C" { 25 void * memset ( void * ptr, int value, size_t num ); 26 } 27 28 trait embedded( tOuter &, tInner & ) { 29 tInner & ?`inner( tOuter & ); 20 forall( Decorator &, T & ) 21 struct tytagref { 22 inline T &; 30 23 }; 31 24 32 // embedded is reflexive 33 forall( tX & ) 34 static inline tX & ?`inner( tX & this ) { return this; } 25 trait embedded( tOuter &, tMid &, tInner & ) { 26 tytagref( tMid, tInner ) ?`inner( tOuter & ); 27 }; 28 29 // embedded is reflexive, with no info (void) as the type tag 30 forall (T &) 31 tytagref(void, T) ?`inner ( T & this ) { tytagref( void, T ) ret = {this}; return ret; } 35 32 36 33 // use this on every case of plan-9 inheritance, to make embedded a closure of plan-9 inheritance 37 #define P9_EMBEDDED( tOuter, tInner ) \ 38 static inline tInner & ?`inner( tOuter & this ) { return this; } 34 #define P9_EMBEDDED( derived, immedBase ) \ 35 forall( 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) ) 39 48 40 49 … … 85 94 } 86 95 87 forall( tLinks & = tE ) { 88 89 struct dlist { 90 inline dlink(tE); 91 }; 92 93 struct diref { 94 inline tE &; 95 }; 96 } 97 98 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) ) ) { 99 102 static inline tE * $get_list_origin_addr( dlist(tE, tLinks) & lst ) { 100 dlink(tE) & link_from_null = ( * (tE *) 0p )`inner `inner;103 dlink(tE) & link_from_null = ( * (tE *) 0p )`inner; 101 104 ptrdiff_t link_offset = (ptrdiff_t) & link_from_null; 102 105 size_t origin_addr = ((size_t) & lst) - link_offset; … … 109 112 ( ( dlink(tE) & ) this ){ listOrigin, listOrigin } ; 110 113 } 111 112 // redundant113 // void ?{}( diref(tE, tLinks) & this, tE & target ) {114 // tE && ref = this;115 // &ref = ⌖116 // }117 114 } 118 115 … … 120 117 121 118 122 forall( tE &, tLinks & | embedded( tE, tLinks ) | embedded( tLinks, dlink(tE) ) ) {123 124 static inline void insert_after( diref(tE, tLinks)list_pos, tE &to_insert) {119 forall( tE &, tLinks & | embedded( tE, tLinks, dlink(tE) ) ) { 120 121 static inline void insert_after(tE & list_pos, tE &to_insert) { 125 122 verify (&list_pos != 0p); 126 123 verify (&to_insert != 0p); 127 dlink(tE) & linkToInsert = to_insert`inner `inner;124 dlink(tE) & linkToInsert = to_insert`inner; 128 125 verify(linkToInsert.prev == 0p); 129 126 verify(linkToInsert.next == 0p); 130 127 tE & list_pos_raw = list_pos; 131 128 tE & list_pos_elem = * (tE *) ORIGIN_TAG_CLEAR( (size_t) & list_pos_raw ); 132 asm( "" : : : "memory" ); 133 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; 134 132 tE & after_elem = * (tE *) ORIGIN_TAG_CLEAR( (size_t) & after_raw ); 135 133 linkToInsert.prev = & list_pos_raw; 136 134 linkToInsert.next = & after_raw; 137 (after_elem`inner`inner).prev = &to_insert; 138 (list_pos_elem`inner`inner).next = &to_insert; 139 asm( "" : : : "memory" ); 140 } 141 142 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) { 143 142 verify (&list_pos != 0p); 144 143 verify (&to_insert != 0p); 145 dlink(tE) & linkToInsert = to_insert`inner `inner;144 dlink(tE) & linkToInsert = to_insert`inner; 146 145 verify(linkToInsert.next == 0p); 147 146 verify(linkToInsert.prev == 0p); 148 147 tE & list_pos_raw = list_pos; 149 148 tE & list_pos_elem = * (tE *) ORIGIN_TAG_CLEAR( (size_t) & list_pos_raw ); 150 asm( "" : : : "memory" ); 151 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; 152 152 tE & before_elem = * (tE *) ORIGIN_TAG_CLEAR( (size_t) & before_raw ); 153 153 linkToInsert.next = & list_pos_raw; 154 154 linkToInsert.prev = & before_raw; 155 (before_elem`inner`inner).next = &to_insert; 156 (list_pos_elem`inner`inner).prev = &to_insert; 157 asm( "" : : : "memory" ); 158 } 159 160 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) { 161 162 verify (&list_pos != 0p); 162 163 tE & list_pos_elem = list_pos; 163 164 verify( ! ORIGIN_TAG_QUERY((size_t) & list_pos_elem) ); 164 dlink(tE) & list_pos_links = list_pos_elem`inner `inner;165 dlink(tE) & list_pos_links = list_pos_elem`inner; 165 166 tE & before_raw = * list_pos_links.prev; 166 167 tE & before_elem = * (tE *) ORIGIN_TAG_CLEAR( (size_t) & before_raw ); 167 dlink(tE) & before_links = before_elem`inner `inner;168 dlink(tE) & before_links = before_elem`inner; 168 169 tE & after_raw = * list_pos_links.next; 169 170 tE & after_elem = * (tE *) ORIGIN_TAG_CLEAR( (size_t) & after_raw ); 170 dlink(tE) & after_links = after_elem`inner `inner;171 dlink(tE) & after_links = after_elem`inner; 171 172 before_links.next = &after_raw; 172 173 after_links.prev = &before_raw; … … 178 179 } 179 180 180 static inline diref(tE, tLinks)?`first( dlist(tE, tLinks) &lst ) {181 static inline tE & ?`first( dlist(tE, tLinks) &lst ) { 181 182 tE * firstPtr = lst.next; 182 183 if (ORIGIN_TAG_QUERY((size_t)firstPtr)) firstPtr = 0p; 183 diref(tE, tLinks) ret = { *firstPtr }; 184 return ret; 185 } 186 static inline diref(tE, tLinks) ?`last ( dlist(tE, tLinks) &lst ) { 184 return *firstPtr; 185 } 186 static inline tE & ?`last ( dlist(tE, tLinks) &lst ) { 187 187 tE * lastPtr = lst.prev; 188 188 if (ORIGIN_TAG_QUERY((size_t)lastPtr)) lastPtr = 0p; 189 diref(tE, tLinks) ret = { *lastPtr }; 190 return ret; 191 } 192 193 static inline int ?!=?( const diref(tE, tLinks) & list_pos, zero_t ) { 194 tE & list_pos_elem = list_pos; 195 if (ORIGIN_TAG_QUERY((size_t) & list_pos_elem)) return 0; 196 return & list_pos_elem != 0p; 197 } 198 199 static inline int DUMB_COMPARE( diref(tE, tLinks) list_pos, tE * elem ) { 200 tE & signifiedLhs = list_pos; 201 return &signifiedLhs == elem; 202 } 203 204 static inline diref(tE, tLinks) ?`from( tE & elem ) { 205 diref(tE, tLinks) ret = { elem }; 206 return ret; 207 } 208 209 static inline diref(tE, tLinks) ?`elems( dlist(tE, tLinks) & lst ) { 189 return *lastPtr; 190 } 191 192 static inline bool ?`isEmpty( dlist(tE, tLinks) & lst ) { 193 tE * firstPtr = lst.next; 194 if (ORIGIN_TAG_QUERY((size_t)firstPtr)) firstPtr = 0p; 195 return firstPtr == 0p; 196 } 197 198 static inline tE & ?`elems( dlist(tE, tLinks) & lst ) { 210 199 tE * origin = $get_list_origin_addr( lst ); 211 diref(tE, tLinks) ret = { *origin }; 212 return ret; 213 } 214 215 static inline bool ?`moveNext( diref(tE, tLinks) & refx ) { 200 return *origin; 201 } 202 203 static inline bool ?`moveNext( tE && refx ) { 216 204 tE && ref_inner = refx; 217 205 tE & oldReferent = * (tE*) ORIGIN_TAG_CLEAR( (size_t) & ref_inner ); 218 &ref_inner = oldReferent`inner `inner.next;206 &ref_inner = oldReferent`inner.next; 219 207 return &ref_inner != 0p && 220 208 ! ORIGIN_TAG_QUERY( (size_t) & ref_inner ); 221 209 } 222 210 223 static inline bool ?`movePrev( diref(tE, tLinks)& refx ) {211 static inline bool ?`movePrev( tE && refx ) { 224 212 tE && ref_inner = refx; 225 213 tE & oldReferent = * (tE*) ORIGIN_TAG_CLEAR( (size_t) & ref_inner ); 226 &ref_inner = oldReferent`inner `inner.prev;214 &ref_inner = oldReferent`inner.prev; 227 215 return &ref_inner != 0p && 228 216 ! ORIGIN_TAG_QUERY( (size_t) & ref_inner ); 229 217 } 230 218 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; 235 } 236 231 237 static inline void insert_first( dlist(tE, tLinks) &lst, tE & e ) { 232 238 insert_after(lst`elems, e); … … 235 241 static inline void insert_last( dlist(tE, tLinks) &lst, tE & e ) { 236 242 insert_before(lst`elems, e); 243 } 244 245 static inline tE & try_pop_front( dlist(tE, tLinks) &lst ) { 246 tE & first_inlist = lst`first; 247 tE & first_item = first_inlist; 248 if (&first_item) remove(first_inlist); 249 return first_item; 250 } 251 252 static inline tE & try_pop_back( dlist(tE, tLinks) &lst ) { 253 tE & last_inlist = lst`last; 254 tE & last_item = last_inlist; 255 if (&last_item) remove(last_inlist); 256 return last_item; 237 257 } 238 258 … … 244 264 tE & lagElem = *0p; 245 265 246 while ( diref(tE, tLinks)it = this`elems; it`moveNext ) {266 while ( tE & it = this`elems; it`moveNext ) { 247 267 if (& lagElem == 0p && &it != & this`first ) return false; 248 268 & lagElem = & it; … … 259 279 tE & lagElem = *0p; 260 280 261 while ( diref(tE, tLinks)it = this`elems; it`movePrev ) {281 while ( tE & it = this`elems; it`movePrev ) { 262 282 if (& lagElem == 0p && &it != & this`last ) return false; 263 283 & lagElem = & it; … … 276 296 } 277 297 278 forall( tE & | embedded( tE, dlink(tE) ) ) {279 static inline void insert_after(tE & list_pos, tE &to_insert ) {280 diref(tE, tE) list_pos_ref = list_pos`from;281 insert_after( list_pos_ref, to_insert );282 }283 static inline void insert_before(tE & list_pos, tE &to_insert ) {284 diref(tE, tE) list_pos_ref = list_pos`from;285 insert_before( list_pos_ref, to_insert );286 }287 static inline tE & remove(tE & list_pos ) {288 diref(tE, tE) list_pos_ref = list_pos`from;289 return remove( list_pos_ref );290 }291 static inline bool ?`moveNext( tE && ref ) {292 diref(tE, tE) & ref_dird = (diref(tE, tE) &) & ref;293 return ref_dird`moveNext;294 }295 static inline bool ?`movePrev( tE && ref ) {296 diref(tE, tE) & ref_dird = (diref(tE, tE) &) & ref;297 return ref_dird`movePrev;298 }299 300 }
Note: See TracChangeset
for help on using the changeset viewer.