Ignore:
Timestamp:
Jan 7, 2021, 5:06:22 PM (5 years ago)
Author:
Thierry Delisle <tdelisle@…>
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.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/bits/sequence.hfa

    r42f6e07 r2b4daf2  
    22
    33#include "bits/collection.hfa"
     4#include "bits/defs.hfa"
    45
    56struct Seqable {
    6         inline Colable;
    7         Seqable * back;                                                                         // pointer to previous node in the list
     7        __cfa_anonymous_object(Colable);
     8        struct Seqable * back;                                                                          // pointer to previous node in the list
    89};
    910
    10 inline {
     11#ifdef __cforall
     12static inline {
    1113        // PUBLIC
    1214
     
    2628        }
    2729
    28         // wrappers to make Collection have T
    29         forall( dtype T ) {
    30                 T *& Back( T * n ) {
    31                         return (T *)Back( (Seqable *)n );
    32                 }
    33         } // distribution
     30        // // wrappers to make Collection have T
     31        // forall( dtype T ) {
     32        //      T *& Back( T * n ) {
     33        //              return (T *)Back( (Seqable *)n );
     34        //      }
     35        // } // distribution
    3436} // distribution
    3537
    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
     45forall( dtype T | { T *& Back ( T * ); T *& Next ( T * ); } ) {
    3746        struct Sequence {
    3847                inline Collection;                                                              // Plan 9 inheritance
    3948        };
    4049
    41         inline {
     50        static inline {
    4251                // wrappers to make Collection have T
    4352                T & head( Sequence(T) & s ) with( s ) {
     
    5059                void ?{}( Sequence(T) & s ) with( s ) {
    5160                        ((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.
    5564                T & tail( Sequence(T) & s ) with( s ) {
    5665                        return root ? (T &)*Back( &head( s ) ) : *0p;
     
    6574                } // post: n == tail() & succ(n) == 0 | n != tail() & *succ(n) in *s
    6675
    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.
    6877                T * pred( Sequence(T) & s, T * n ) with( s ) {  // pre: *n in *s
    6978                        #ifdef __CFA_DEBUG__
     
    7180                        #endif // __CFA_DEBUG__
    7281                        return n == &head( s ) ? 0p : Back( n );
    73                 }       // post: n == head() & head(n) == 0 | n != head() & *pred(n) in *s
    74 
    75 
    76                 // Insert *n into the sequence before *bef, or at the end if bef == 0.
    77                 void insertBef( Sequence(T) & s, T & n, T & bef ) with( s ) { // pre: !n->listed() & *bef in *s
     82                } // 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
    7887                        #ifdef __CFA_DEBUG__
    7988                        if ( listed( &n ) ) abort( "(Sequence &)%p.insertBef( %p, %p ) : Node is already on another list.", &s, n, &bef );
     
    103112                                Next( Back( &n ) ) = &n;
    104113                        } // if
     114                        return n;
    105115                }       // post: n->listed() & *n in *s & succ(n) == bef
    106116
    107117
    108118                // Insert *n into the sequence after *aft, or at the beginning if aft == 0.
    109                 void insertAft( Sequence(T) & s, T & aft, T & n ) with( s ) {   // pre: !n->listed() & *aft in *s
     119                T & insertAft( Sequence(T) & s, T & aft, T & n ) with( s ) {    // pre: !n->listed() & *aft in *s
    110120                        #ifdef __CFA_DEBUG__
    111121                        if ( listed( &n ) ) abort( "(Sequence &)%p.insertAft( %p, %p ) : Node is already on another list.", &s, &aft, &n );
     
    133143                                Next( &aft ) = &n;
    134144                        } // if
    135                 }         // post: n->listed() & *n in *s & succ(n) == bef
     145                        return n;
     146                } // post: n->listed() & *n in *s & succ(n) == bef
    136147               
    137148                // pre: n->listed() & *n in *s
    138                 void remove( Sequence(T) & s, T & n ) with( s ) { // O(1)
     149                T & remove( Sequence(T) & s, T & n ) with( s ) { // O(1)
    139150                        #ifdef __CFA_DEBUG__
    140151                        if ( ! listed( &n ) ) abort( "(Sequence &)%p.remove( %p ) : Node is not on a list.", &s, &n );
     
    147158                        Next( Back( &n ) ) = Next( &n );
    148159                        Next( &n ) = Back( &n ) = 0p;
    149                 }                                                       // post: !n->listed().
     160                        return n;
     161                } // post: !n->listed()
    150162
    151163                // 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
    155168                // 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
    159173                // 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
    163178                // Remove and return the head element in the sequence.
    164179                T & dropHead( Sequence(T) & s ) {
     
    166181                        return &n ? remove( s, n ), n : *0p;
    167182                }
     183
    168184                // Remove and return the head element in the sequence.
    169185                T & drop( Sequence(T) & s ) {
    170186                        return dropHead( s );
    171187                }
     188
    172189                // Remove and return the tail element in the sequence.
    173190                T & dropTail( Sequence(T) & s ) {
     
    184201                                T * toEnd = Back( &head( s ) );
    185202                                T * fromEnd = Back( &head( from ) );
    186                                 Back( root ) = fromEnd;
     203                                Back( (T *)root ) = fromEnd;
    187204                                Next( fromEnd ) = &head( s );
    188                                 Back( from.root ) = toEnd;
     205                                Back( (T *)from.root ) = toEnd;
    189206                                Next( toEnd ) = &head( from );
    190207                        } // if
     
    214231} // distribution
    215232
    216 forall( dtype T ) {
     233forall( dtype T | { T *& Back ( T * ); T *& Next ( T * ); } ) {
    217234        // SeqIter(T) is used to iterate over a Sequence(T) in head-to-tail order.
    218235        struct SeqIter {
     
    224241        };
    225242
    226         inline {
     243        static inline {
    227244                void ?{}( SeqIter(T) & si ) with( si ) {
    228245                        ((ColIter &)si){};
    229246                        seq = 0p;
    230                 } // post: elts = null.
    231 
     247                } // post: elts = null
     248
     249                // Create a iterator active in sequence s.
    232250                void ?{}( SeqIter(T) & si, Sequence(T) & s ) with( si ) {
    233251                        ((ColIter &)si){};
    234252                        seq = &s;
    235253                        curr = &head( s );
    236                 } // post: elts = null.
     254                } // post: elts = null
    237255
    238256                void ?{}( SeqIter(T) & si, Sequence(T) & s, T & start ) with( si ) {
     
    240258                        seq = &s;
    241259                        curr = &start;
    242                 } // post: elts = null.
    243 
     260                } // post: elts = null
     261
     262                // Make the iterator active in sequence s.
    244263                void over( SeqIter(T) & si, Sequence(T) & s ) with( si ) {
    245264                        seq = &s;
    246265                        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 ) {
    250269                        if ( curr ) {
    251270                                &tp = Curr( si );
     
    265284        };
    266285
    267         inline {
     286        static inline {
    268287                void ?{}( SeqIterRev(T) & si ) with( si ) {     
    269288                        ((ColIter &)si){};
    270289                        seq = 0p;
    271                 } // post: elts = null.
    272 
     290                } // post: elts = null
     291
     292                // Create a iterator active in sequence s.
    273293                void ?{}( SeqIterRev(T) & si, Sequence(T) & s ) with( si ) {   
    274294                        ((ColIter &)si){};
    275295                        seq = &s;
    276296                        curr = &tail( s );
    277                 } // post: elts = null.
     297                } // post: elts = null
    278298
    279299                void ?{}( SeqIterRev(T) & si, Sequence(T) & s, T & start ) with( si ) {
     
    281301                        seq = &s;
    282302                        curr = &start;
    283                 } // post: elts = null.
    284 
     303                } // post: elts = null
     304
     305                // Make the iterator active in sequence s.
    285306                void over( SeqIterRev(T) & si, Sequence(T) & s ) with( si ) {
    286307                        seq = &s;
    287308                        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 ) {
    291312                        if ( curr ) {
    292313                                &tp = Curr( si );
     
    298319        } // distribution
    299320} // distribution
     321
     322#endif
Note: See TracChangeset for help on using the changeset viewer.