source: libcfa/src/bits/stack.hfa@ d9b7b66

Last change on this file since d9b7b66 was fd54fef, checked in by Michael Brooks <mlbrooks@…>, 5 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
Line 
1#pragma once
2
3#include "bits/collection.hfa"
4
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
11forall( T & | { T *& Next ( T * ); } ) {
12 struct Stack {
13 inline Collection; // Plan 9 inheritance
14 };
15
16 inline {
17 // wrappers to make Collection have T
18 T & head( Stack(T) & s ) with( s ) {
19 return *(T *)head( (Collection &)s );
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
29 T & top( Stack(T) & s ) with( s ) {
30 return head( s );
31 }
32
33 T & addHead( Stack(T) & s, T & n ) with( s ) {
34 #ifdef __CFA_DEBUG__
35 if ( listed( (Colable &)(n) ) ) abort( "(Stack &)%p.addHead( %p ) : Node is already on another list.", &s, n );
36 #endif // __CFA_DEBUG__
37 Next( &n ) = &head( s ) ? &head( s ) : &n;
38 root = &n;
39 return n;
40 }
41
42 T & add( Stack(T) & s, T & n ) with( s ) {
43 return addHead( s, n );
44 }
45
46 T & push( Stack(T) & s, T & n ) with( s ) {
47 return addHead( s, n );
48 }
49
50 T & drop( Stack(T) & s ) with( s ) {
51 T & t = head( s );
52 if ( root ) {
53 root = ( T *)Next( (T *)root );
54 if ( &head( s ) == &t ) root = 0p; // only one element ?
55 Next( &t ) = 0p;
56 } // if
57 return t;
58 }
59
60 T & pop( Stack(T) & s ) with( s ) {
61 return drop( s );
62 }
63 } // distribution
64} // distribution
65
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().
68
69forall( T & | { T *& Next ( T * ); } ) {
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
79 // create an iterator active in stack s
80 void ?{}( StackIter(T) & si, Stack(T) & s ) with( si ) {
81 curr = &head( s );
82 } // post: curr = {e in s}
83
84 void ?{}( StackIter(T) & si, T & start ) with( si ) {
85 curr = &start;
86 } // post: curr = {e in s}
87
88 // make existing iterator active in stack s
89 void over( StackIter(T) & si, Stack(T) & s ) with( si ) {
90 curr = &head( s );
91 } // post: curr = {e in s}
92
93 bool ?|?( StackIter(T) & si, T && tp ) with( si ) {
94 if ( curr ) {
95 &tp = Curr( si );
96 T * n = Next( Curr( si ) );
97 curr = n == Curr( si ) ? 0p : n;
98 } else &tp = 0p;
99 return &tp != 0p;
100 }
101 } // distribution
102} // distribution
Note: See TracBrowser for help on using the repository browser.