1 // SemiTwist Library 2 // Written in the D programming language. 3 4 module semitwist.util.container; 5 6 import semitwist.util.all; 7 8 final class Stack(T) 9 { 10 private T[] data; 11 @property size_t capacity() 12 { 13 return data.length; 14 } 15 private size_t _length=0; 16 @property size_t length() 17 { 18 return _length; 19 } 20 21 this(size_t initialCapacity=1024) 22 { 23 data.length = initialCapacity; 24 } 25 26 private this(Stack!T s) 27 { 28 data = s.data.dup; 29 _length = s._length; 30 } 31 32 ref T opIndex(size_t i) 33 { 34 debug if(i >= _length) 35 throw new Exception("Invalid index"); 36 37 return data[i]; 38 } 39 40 T[] opSlice(size_t a, size_t b) 41 { 42 debug if(a >= _length || b > _length) 43 throw new Exception("Invalid index"); 44 45 return data[a..b]; 46 } 47 48 private void expand() 49 { 50 size_t numMore = data.length; 51 if(numMore == 0) 52 numMore = 1; 53 data.length += numMore; 54 } 55 56 void clear() 57 { 58 _length = 0; 59 data.clear(); 60 } 61 62 void opOpAssign(string op)(T item) if(op=="~") 63 { 64 if(_length == data.length) 65 expand(); 66 67 data[_length] = item; 68 _length++; 69 } 70 71 void opOpAssign(string op)(T[] items) if(op=="~") 72 { 73 while(_length + items.length >= data.length) 74 expand(); 75 76 data[ _length .. _length + items.length ] = items; 77 _length += items.length; 78 } 79 80 void pop(size_t num=1) 81 { 82 debug if(num > _length) 83 throw new Exception("Invalid index"); 84 85 _length -= num; 86 } 87 88 @property ref T top() 89 { 90 return data[_length-1]; 91 } 92 93 @property bool empty() 94 { 95 return _length == 0; 96 } 97 98 void compact() 99 { 100 data.length = _length; 101 } 102 103 @property Stack!T dup() 104 { 105 return new Stack!T(this); 106 } 107 108 int opApply(int delegate(ref T) dg) 109 { 110 int result = 0; 111 foreach(ref T item; data[0.._length]) 112 { 113 result = dg(item); 114 if(result) 115 break; 116 } 117 return result; 118 } 119 120 int opApply(int delegate(ref size_t, ref T) dg) 121 { 122 int result = 0; 123 foreach(size_t i, ref T item; data[0.._length]) 124 { 125 result = dg(i, item); 126 if(result) 127 break; 128 } 129 return result; 130 } 131 }