1 /// \file Stack.d 2 3 module tagion.betterC.utils.Stack; 4 5 @nogc: 6 7 import tagion.betterC.utils.Memory; 8 9 //import core.stdc.stdio; 10 11 struct Stack(T) { 12 @nogc: 13 struct Element { 14 Element* next; 15 T value; 16 } 17 18 protected { 19 Element* root; 20 } 21 // this() { 22 // top=null; 23 // } 24 ~this() { 25 dispose; 26 } 27 28 void dispose() { 29 static void _dispose(ref Element* e) { 30 if (e !is null) { 31 _dispose(e.next); 32 33 34 35 .dispose!false(e); 36 } 37 } 38 39 _dispose(root); 40 } 41 42 void push(T x) { 43 auto new_e = create!Element; 44 new_e.value = x; 45 new_e.next = root; 46 root = new_e; 47 } 48 49 T pop() { 50 scope (exit) { 51 if (root !is null) { 52 auto temp_e = root; 53 root = root.next; 54 temp_e.dispose; 55 } 56 } 57 return root.value; 58 } 59 60 @property T top() { 61 return root.value; 62 } 63 64 @property bool empty() const pure { 65 return root is null; 66 } 67 68 @property size_t length() const pure { 69 size_t count; 70 for (Element* e = cast(Element*) root; e !is null; e = e.next) { 71 count++; 72 } 73 return count; 74 } 75 76 Range opSlice() { 77 return Range(root); 78 } 79 80 struct Range { 81 private Element* current; 82 bool empty() const pure { 83 return (current is null); 84 } 85 86 T front() pure { 87 return current.value; 88 } 89 90 void popFront() { 91 current = current.next; 92 } 93 } 94 95 } 96 97 unittest { 98 Stack!int q; 99 const(int[7]) table = [7, 6, 5, 4, 3, 2, 1]; 100 101 assert(q.empty); 102 foreach (t; table) { 103 q.push(t); 104 } 105 106 assert(!q.empty); 107 assert(table.length == q.length); 108 assert(q.top == table[table.length - 1]); 109 110 size_t i = table.length; 111 int[table.length] check = table; 112 foreach (b; q[]) { 113 i--; 114 assert(check[i] is b); 115 } 116 117 foreach_reverse (j; 0 .. table.length) { 118 assert(q.top == table[j]); 119 q.pop; 120 } 121 }