1 module m3.Stack; 2 3 private: 4 5 static import m3.m3; 6 7 debug(m3) { 8 static import core.stdc.stdio; 9 alias printf = core.stdc.stdio.printf; 10 } 11 12 static import std.traits; 13 alias isArray = std.traits.isArray; 14 15 public: 16 17 struct Stack(T) { 18 static assert(!isArray!(T), "Stack cannot be used with an array"); 19 20 static struct Node { 21 T value; 22 Node* previous = null; 23 } 24 25 private: 26 Node* _end; 27 size_t _length; 28 29 public: 30 @nogc 31 ~this() { 32 Node* cur = _end; 33 while (cur) { 34 debug(m3) printf("Destroy Stack\n"); 35 36 Node* tmp = cur; 37 cur = tmp.previous; 38 m3.m3.destruct(tmp); 39 } 40 } 41 42 @safe 43 @nogc 44 @property 45 size_t length() const pure nothrow { 46 return _length; 47 } 48 49 @nogc 50 @property 51 inout(Node*) top() inout pure nothrow { 52 return _end; 53 } 54 55 @nogc 56 void push(U : T)(auto ref U item) nothrow { 57 Node* newEnd = m3.m3.make!(Node); 58 newEnd.value = item; 59 newEnd.previous = _end; 60 61 _end = newEnd; 62 _length++; 63 } 64 65 @nogc 66 void pop() nothrow { 67 if (_end) { 68 Node* oldEnd = _end; 69 _end = _end.previous; 70 m3.m3.destruct(oldEnd); 71 72 _length--; 73 } 74 } 75 } 76 77 @nogc 78 unittest { 79 Stack!(char) stack; 80 81 stack.push('H'); 82 assert(stack.top.value == 'H'); 83 84 stack.push('a'); 85 assert(stack.top.value == 'a'); 86 87 stack.pop(); 88 assert(stack.top.value == 'H'); 89 90 stack.pop(); 91 assert(!stack.top); 92 }