Changeset 7d51ef8 for libcfa/src/containers/list2.hfa
- Timestamp:
- May 11, 2021, 9:52:18 PM (4 years ago)
- 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
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/containers/list2.hfa
r8d1ad36 r7d51ef8 18 18 #include <assert.h> 19 19 20 extern "C" { 21 void * memset ( void * ptr, int value, size_t num ); 22 } 23 24 trait embedded( tOuter &, tInner & ) { 25 tInner & ?`inner( tOuter & ); 20 forall( Decorator &, T & ) 21 struct tytagref { 22 inline T &; 26 23 }; 27 24 28 // embedded is reflexive 29 forall( tX & ) 30 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; } 31 32 32 33 // 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 ) \ 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) ) 35 48 36 49 … … 81 94 } 82 95 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) ) ) { 95 102 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; 97 104 ptrdiff_t link_offset = (ptrdiff_t) & link_from_null; 98 105 size_t origin_addr = ((size_t) & lst) - link_offset; … … 105 112 ( ( dlink(tE) & ) this ){ listOrigin, listOrigin } ; 106 113 } 107 108 // redundant109 // void ?{}( diref(tE, tLinks) & this, tE & target ) {110 // tE && ref = this;111 // &ref = ⌖112 // }113 114 } 114 115 … … 116 117 117 118 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) {119 forall( tE &, tLinks & | embedded( tE, tLinks, dlink(tE) ) ) { 120 121 static inline void insert_after(tE & list_pos, tE &to_insert) { 121 122 verify (&list_pos != 0p); 122 123 verify (&to_insert != 0p); 123 dlink(tE) & linkToInsert = to_insert`inner `inner;124 dlink(tE) & linkToInsert = to_insert`inner; 124 125 verify(linkToInsert.prev == 0p); 125 126 verify(linkToInsert.next == 0p); 126 127 tE & list_pos_raw = list_pos; 127 128 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; 130 132 tE & after_elem = * (tE *) ORIGIN_TAG_CLEAR( (size_t) & after_raw ); 131 133 linkToInsert.prev = & list_pos_raw; 132 134 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) { 139 142 verify (&list_pos != 0p); 140 143 verify (&to_insert != 0p); 141 dlink(tE) & linkToInsert = to_insert`inner `inner;144 dlink(tE) & linkToInsert = to_insert`inner; 142 145 verify(linkToInsert.next == 0p); 143 146 verify(linkToInsert.prev == 0p); 144 147 tE & list_pos_raw = list_pos; 145 148 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; 148 152 tE & before_elem = * (tE *) ORIGIN_TAG_CLEAR( (size_t) & before_raw ); 149 153 linkToInsert.next = & list_pos_raw; 150 154 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) { 157 162 verify (&list_pos != 0p); 158 163 tE & list_pos_elem = list_pos; 159 164 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; 161 166 tE & before_raw = * list_pos_links.prev; 162 167 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; 164 169 tE & after_raw = * list_pos_links.next; 165 170 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; 167 172 before_links.next = &after_raw; 168 173 after_links.prev = &before_raw; … … 174 179 } 175 180 176 static inline diref(tE, tLinks)?`first( dlist(tE, tLinks) &lst ) {181 static inline tE & ?`first( dlist(tE, tLinks) &lst ) { 177 182 tE * firstPtr = lst.next; 178 183 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 ) { 183 187 tE * lastPtr = lst.prev; 184 188 if (ORIGIN_TAG_QUERY((size_t)lastPtr)) lastPtr = 0p; 185 diref(tE, tLinks) ret = { *lastPtr }; 186 return ret; 189 return *lastPtr; 187 190 } 188 191 … … 193 196 } 194 197 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 ) { 212 199 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 ) { 218 204 tE && ref_inner = refx; 219 205 tE & oldReferent = * (tE*) ORIGIN_TAG_CLEAR( (size_t) & ref_inner ); 220 &ref_inner = oldReferent`inner `inner.next;206 &ref_inner = oldReferent`inner.next; 221 207 return &ref_inner != 0p && 222 208 ! ORIGIN_TAG_QUERY( (size_t) & ref_inner ); 223 209 } 224 210 225 static inline bool ?`movePrev( diref(tE, tLinks)& refx ) {211 static inline bool ?`movePrev( tE && refx ) { 226 212 tE && ref_inner = refx; 227 213 tE & oldReferent = * (tE*) ORIGIN_TAG_CLEAR( (size_t) & ref_inner ); 228 &ref_inner = oldReferent`inner `inner.prev;214 &ref_inner = oldReferent`inner.prev; 229 215 return &ref_inner != 0p && 230 216 ! ORIGIN_TAG_QUERY( (size_t) & ref_inner ); 231 217 } 232 218 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; 253 235 } 254 236 … … 262 244 263 245 static inline tE & try_pop_front( dlist(tE, tLinks) &lst ) { 264 diref(tE, tLinks)first_inlist = lst`first;246 tE & first_inlist = lst`first; 265 247 tE & first_item = first_inlist; 266 248 if (&first_item) remove(first_inlist); … … 269 251 270 252 static inline tE & try_pop_back( dlist(tE, tLinks) &lst ) { 271 diref(tE, tLinks)last_inlist = lst`last;253 tE & last_inlist = lst`last; 272 254 tE & last_item = last_inlist; 273 255 if (&last_item) remove(last_inlist); … … 282 264 tE & lagElem = *0p; 283 265 284 while ( diref(tE, tLinks)it = this`elems; it`moveNext ) {266 while ( tE & it = this`elems; it`moveNext ) { 285 267 if (& lagElem == 0p && &it != & this`first ) return false; 286 268 & lagElem = & it; … … 297 279 tE & lagElem = *0p; 298 280 299 while ( diref(tE, tLinks)it = this`elems; it`movePrev ) {281 while ( tE & it = this`elems; it`movePrev ) { 300 282 if (& lagElem == 0p && &it != & this`last ) return false; 301 283 & lagElem = & it; … … 314 296 } 315 297 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.