source: libcfa/src/bits/stack.hfa @ 7b2c8c3c

ADTast-experimentalenumforall-pointer-decaypthread-emulationqualifiedEnum
Last change on this file since 7b2c8c3c was fd54fef, checked in by Michael Brooks <mlbrooks@…>, 4 years ago

Converting the project to use the new syntax for otype, dtype and ttytpe.

Changed prelude (gen), libcfa and test suite to use it. Added a simple deprecation rule of the old syntax to the parser; we might wish to support both syntaxes "officially," like with an extra CLI switch, but this measure should serve as a simple reminder for our team to try the new syntax.

  • Property mode set to 100644
File size: 2.7 KB
RevLine 
[5e82d56]1#pragma once
2
[7d4ce2a]3#include "bits/collection.hfa"
[5e82d56]4
[9536761]5// A Stack(T) is a Collection(T) defining the ordering that nodes are returned by drop() in the reverse order from those
6// added by add(). T must be a public descendant of uColable.
7
8// The implementation is a typical singly-linked list, except the next field of the last element points to itself
9// instead of being null.
10
[fd54fef]11forall( T & | { T *& Next ( T * ); } ) {
[5e82d56]12        struct Stack {
13                inline Collection;                                                              // Plan 9 inheritance
14        };
15
16        inline {
17                // wrappers to make Collection have T
[a5a67ab8]18                T & head( Stack(T) & s ) with( s ) {
19                        return *(T *)head( (Collection &)s );
[5e82d56]20                } // post: empty() & head() == 0 | !empty() & head() in *this
21
22                void ?{}( Stack(T) &, const Stack(T) & ) = void; // no copy
23                Stack(T) & ?=?( const Stack(T) & ) = void;              // no assignment
24
25                void ?{}( Stack(T) & s ) with( s ) {
26                        ((Collection &)s){};
27                } // post: empty()
28
[636d3715]29                T & top( Stack(T) & s ) with( s ) {
[a5a67ab8]30                        return head( s );
[5e82d56]31                }
32
[a3a76ea]33                T & addHead( Stack(T) & s, T & n ) with( s ) {
[7c1144b]34                        #ifdef __CFA_DEBUG__
[636d3715]35                        if ( listed( (Colable &)(n) ) ) abort( "(Stack &)%p.addHead( %p ) : Node is already on another list.", &s, n );
[7c1144b]36                        #endif // __CFA_DEBUG__
[58870e6b]37                        Next( &n ) = &head( s ) ? &head( s ) : &n;
[636d3715]38                        root = &n;
[a3a76ea]39                        return n;
[5e82d56]40                }
41
[a3a76ea]42                T & add( Stack(T) & s, T & n ) with( s ) {
43                        return addHead( s, n );
[5e82d56]44                }
45
[a3a76ea]46                T & push( Stack(T) & s, T & n ) with( s ) {
47                        return addHead( s, n );
[5e82d56]48                }
49
[636d3715]50                T & drop( Stack(T) & s ) with( s ) {
[a5a67ab8]51                        T & t = head( s );
[5e82d56]52                        if ( root ) {
[accc5dbb]53                                root = ( T *)Next( (T *)root );
[a5a67ab8]54                                if ( &head( s ) == &t ) root = 0p;              // only one element ?
[58870e6b]55                                Next( &t ) = 0p;
[5e82d56]56                        } // if
57                        return t;
58                }
59
[636d3715]60                T & pop( Stack(T) & s ) with( s ) {
[5e82d56]61                        return drop( s );
62                }
63        } // distribution
64} // distribution
65
[9536761]66// A StackIter(T) is a subclass of ColIter(T) that generates the elements of a Stack(T).  It returns the elements in the
67// order returned by drop().
[5e82d56]68
[fd54fef]69forall( T & | { T *& Next ( T * ); } ) {
[5e82d56]70        struct StackIter {
71                inline ColIter;                                                                 // Plan 9 inheritance
72        };     
73
74        inline {
75                void ?{}( StackIter(T) & si ) with( si ) {
76                        ((ColIter &)si){};
77                } // post: curr == 0p
78
[9536761]79                // create an iterator active in stack s
[5e82d56]80                void ?{}( StackIter(T) & si, Stack(T) & s ) with( si ) {
[a5a67ab8]81                        curr = &head( s );
[5e82d56]82                } // post: curr = {e in s}
83
[636d3715]84                void ?{}( StackIter(T) & si, T & start ) with( si ) {
85                        curr = &start;
[5e82d56]86                } // post: curr = {e in s}
87
[9536761]88                // make existing iterator active in stack s
[5e82d56]89                void over( StackIter(T) & si, Stack(T) & s ) with( si ) {
[a5a67ab8]90                        curr = &head( s );
[5e82d56]91                } // post: curr = {e in s}
92
[9536761]93                bool ?|?( StackIter(T) & si, T && tp ) with( si ) {
[5e82d56]94                        if ( curr ) {
[3d0560d]95                                &tp = Curr( si );
[58870e6b]96                                T * n = Next( Curr( si ) );
[636d3715]97                                curr = n == Curr( si ) ? 0p : n;
[3d0560d]98                        } else &tp = 0p;
99                        return &tp != 0p;
[5e82d56]100                }
101        } // distribution
102} // distribution
Note: See TracBrowser for help on using the repository browser.