Changeset 2b4daf2 for libcfa/src/bits/sequence.hfa
- Timestamp:
- Jan 7, 2021, 5:06:22 PM (5 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 5ad381b
- Parents:
- 42f6e07 (diff), 58fe85a (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/bits/sequence.hfa
r42f6e07 r2b4daf2 2 2 3 3 #include "bits/collection.hfa" 4 #include "bits/defs.hfa" 4 5 5 6 struct Seqable { 6 inline Colable;7 Seqable * back; // pointer to previous node in the list7 __cfa_anonymous_object(Colable); 8 struct Seqable * back; // pointer to previous node in the list 8 9 }; 9 10 10 inline { 11 #ifdef __cforall 12 static inline { 11 13 // PUBLIC 12 14 … … 26 28 } 27 29 28 // wrappers to make Collection have T29 forall( dtype T ) {30 T *& Back( T * n ) {31 return (T *)Back( (Seqable *)n );32 }33 } // distribution30 // // wrappers to make Collection have T 31 // forall( dtype T ) { 32 // T *& Back( T * n ) { 33 // return (T *)Back( (Seqable *)n ); 34 // } 35 // } // distribution 34 36 } // distribution 35 37 36 forall( dtype T ) { 38 39 // A Sequence(T) is a Collection(T) defining the ordering of a uStack and uQueue, and to insert and remove elements 40 // anywhere in the sequence. T must be a public descendant of uSeqable. 41 42 // The implementation is a typical doubly-linked list, except the next field of the last node points at the first node 43 // and the back field of the last node points at the first node (circular). 44 45 forall( dtype T | { T *& Back ( T * ); T *& Next ( T * ); } ) { 37 46 struct Sequence { 38 47 inline Collection; // Plan 9 inheritance 39 48 }; 40 49 41 inline {50 static inline { 42 51 // wrappers to make Collection have T 43 52 T & head( Sequence(T) & s ) with( s ) { … … 50 59 void ?{}( Sequence(T) & s ) with( s ) { 51 60 ((Collection &)s){}; 52 } // post: isEmpty() .53 54 // Return a pointer to the last sequence element, without removing it. 61 } // post: isEmpty() 62 63 // Return a pointer to the last sequence element, without removing it. 55 64 T & tail( Sequence(T) & s ) with( s ) { 56 65 return root ? (T &)*Back( &head( s ) ) : *0p; … … 65 74 } // post: n == tail() & succ(n) == 0 | n != tail() & *succ(n) in *s 66 75 67 // Return a pointer to the element before *n, or 0p if there isn't one.76 // Return a pointer to the element before *n, or 0p if list empty. 68 77 T * pred( Sequence(T) & s, T * n ) with( s ) { // pre: *n in *s 69 78 #ifdef __CFA_DEBUG__ … … 71 80 #endif // __CFA_DEBUG__ 72 81 return n == &head( s ) ? 0p : Back( n ); 73 } 74 75 76 // Insert *n into the sequence before *bef, or at the end if bef == 0 .77 voidinsertBef( Sequence(T) & s, T & n, T & bef ) with( s ) { // pre: !n->listed() & *bef in *s82 } // post: n == head() & head(n) == 0 | n != head() & *pred(n) in *s 83 84 85 // Insert *n into the sequence before *bef, or at the end if bef == 0p. 86 T & insertBef( Sequence(T) & s, T & n, T & bef ) with( s ) { // pre: !n->listed() & *bef in *s 78 87 #ifdef __CFA_DEBUG__ 79 88 if ( listed( &n ) ) abort( "(Sequence &)%p.insertBef( %p, %p ) : Node is already on another list.", &s, n, &bef ); … … 103 112 Next( Back( &n ) ) = &n; 104 113 } // if 114 return n; 105 115 } // post: n->listed() & *n in *s & succ(n) == bef 106 116 107 117 108 118 // Insert *n into the sequence after *aft, or at the beginning if aft == 0. 109 voidinsertAft( Sequence(T) & s, T & aft, T & n ) with( s ) { // pre: !n->listed() & *aft in *s119 T & insertAft( Sequence(T) & s, T & aft, T & n ) with( s ) { // pre: !n->listed() & *aft in *s 110 120 #ifdef __CFA_DEBUG__ 111 121 if ( listed( &n ) ) abort( "(Sequence &)%p.insertAft( %p, %p ) : Node is already on another list.", &s, &aft, &n ); … … 133 143 Next( &aft ) = &n; 134 144 } // if 135 } // post: n->listed() & *n in *s & succ(n) == bef 145 return n; 146 } // post: n->listed() & *n in *s & succ(n) == bef 136 147 137 148 // pre: n->listed() & *n in *s 138 voidremove( Sequence(T) & s, T & n ) with( s ) { // O(1)149 T & remove( Sequence(T) & s, T & n ) with( s ) { // O(1) 139 150 #ifdef __CFA_DEBUG__ 140 151 if ( ! listed( &n ) ) abort( "(Sequence &)%p.remove( %p ) : Node is not on a list.", &s, &n ); … … 147 158 Next( Back( &n ) ) = Next( &n ); 148 159 Next( &n ) = Back( &n ) = 0p; 149 } // post: !n->listed(). 160 return n; 161 } // post: !n->listed() 150 162 151 163 // Add an element to the head of the sequence. 152 void addHead( Sequence(T) & s, T & n ) { // pre: !n->listed(); post: n->listed() & head() == n 153 insertAft( s, *0p, n ); 154 } 164 T & addHead( Sequence(T) & s, T & n ) { // pre: !n->listed(); post: n->listed() & head() == n 165 return insertAft( s, *0p, n ); 166 } 167 155 168 // Add an element to the tail of the sequence. 156 void addTail( Sequence(T) & s, T & n ) { // pre: !n->listed(); post: n->listed() & head() == n 157 insertBef( s, n, *0p ); 158 } 169 T & addTail( Sequence(T) & s, T & n ) { // pre: !n->listed(); post: n->listed() & head() == n 170 return insertBef( s, n, *0p ); 171 } 172 159 173 // Add an element to the tail of the sequence. 160 void add( Sequence(T) & s, T & n ) { // pre: !n->listed(); post: n->listed() & head() == n 161 addTail( s, n ); 162 } 174 T & add( Sequence(T) & s, T & n ) { // pre: !n->listed(); post: n->listed() & head() == n 175 return addTail( s, n ); 176 } 177 163 178 // Remove and return the head element in the sequence. 164 179 T & dropHead( Sequence(T) & s ) { … … 166 181 return &n ? remove( s, n ), n : *0p; 167 182 } 183 168 184 // Remove and return the head element in the sequence. 169 185 T & drop( Sequence(T) & s ) { 170 186 return dropHead( s ); 171 187 } 188 172 189 // Remove and return the tail element in the sequence. 173 190 T & dropTail( Sequence(T) & s ) { … … 184 201 T * toEnd = Back( &head( s ) ); 185 202 T * fromEnd = Back( &head( from ) ); 186 Back( root ) = fromEnd;203 Back( (T *)root ) = fromEnd; 187 204 Next( fromEnd ) = &head( s ); 188 Back( from.root ) = toEnd;205 Back( (T *)from.root ) = toEnd; 189 206 Next( toEnd ) = &head( from ); 190 207 } // if … … 214 231 } // distribution 215 232 216 forall( dtype T ) {233 forall( dtype T | { T *& Back ( T * ); T *& Next ( T * ); } ) { 217 234 // SeqIter(T) is used to iterate over a Sequence(T) in head-to-tail order. 218 235 struct SeqIter { … … 224 241 }; 225 242 226 inline {243 static inline { 227 244 void ?{}( SeqIter(T) & si ) with( si ) { 228 245 ((ColIter &)si){}; 229 246 seq = 0p; 230 } // post: elts = null. 231 247 } // post: elts = null 248 249 // Create a iterator active in sequence s. 232 250 void ?{}( SeqIter(T) & si, Sequence(T) & s ) with( si ) { 233 251 ((ColIter &)si){}; 234 252 seq = &s; 235 253 curr = &head( s ); 236 } // post: elts = null .254 } // post: elts = null 237 255 238 256 void ?{}( SeqIter(T) & si, Sequence(T) & s, T & start ) with( si ) { … … 240 258 seq = &s; 241 259 curr = &start; 242 } // post: elts = null. 243 260 } // post: elts = null 261 262 // Make the iterator active in sequence s. 244 263 void over( SeqIter(T) & si, Sequence(T) & s ) with( si ) { 245 264 seq = &s; 246 265 curr = &head( s ); 247 } // post: elts = {e in s} .248 249 bool ? >>?( SeqIter(T) & si, T && tp ) with( si ) {266 } // post: elts = {e in s} 267 268 bool ?|?( SeqIter(T) & si, T && tp ) with( si ) { 250 269 if ( curr ) { 251 270 &tp = Curr( si ); … … 265 284 }; 266 285 267 inline {286 static inline { 268 287 void ?{}( SeqIterRev(T) & si ) with( si ) { 269 288 ((ColIter &)si){}; 270 289 seq = 0p; 271 } // post: elts = null. 272 290 } // post: elts = null 291 292 // Create a iterator active in sequence s. 273 293 void ?{}( SeqIterRev(T) & si, Sequence(T) & s ) with( si ) { 274 294 ((ColIter &)si){}; 275 295 seq = &s; 276 296 curr = &tail( s ); 277 } // post: elts = null .297 } // post: elts = null 278 298 279 299 void ?{}( SeqIterRev(T) & si, Sequence(T) & s, T & start ) with( si ) { … … 281 301 seq = &s; 282 302 curr = &start; 283 } // post: elts = null. 284 303 } // post: elts = null 304 305 // Make the iterator active in sequence s. 285 306 void over( SeqIterRev(T) & si, Sequence(T) & s ) with( si ) { 286 307 seq = &s; 287 308 curr = &tail( s ); 288 } // post: elts = {e in s} .289 290 bool ? >>?( SeqIterRev(T) & si, T && tp ) with( si ) {309 } // post: elts = {e in s} 310 311 bool ?|?( SeqIterRev(T) & si, T && tp ) with( si ) { 291 312 if ( curr ) { 292 313 &tp = Curr( si ); … … 298 319 } // distribution 299 320 } // distribution 321 322 #endif
Note:
See TracChangeset
for help on using the changeset viewer.