1 module artemisd.utils.bag; 2 3 final class Bag(E) 4 { 5 this() 6 { 7 this(64); 8 } 9 10 this(int capacity) 11 { 12 data = new E[capacity]; 13 } 14 15 E remove(size_t index) 16 { 17 assert(index >= 0 && index < size); 18 E e = data[index]; // make copy of element to remove so it can be returned 19 data[index] = data[--size_]; // overwrite item to remove with last element 20 return e; 21 } 22 23 E removeLast() 24 { 25 assert(size > 0); 26 E e = data[--size_]; 27 return e; 28 } 29 30 bool remove(E e) 31 { 32 for (size_t i = 0; i < size; i++) 33 { 34 E e2 = data[i]; 35 36 if (e == e2) 37 { 38 data[i] = data[--size_]; // overwrite item to remove with last element 39 return true; 40 } 41 } 42 43 return false; 44 } 45 46 bool contains(E e) 47 { 48 for(size_t i = 0; size > i; i++) 49 { 50 if(e == data[i]) 51 { 52 return true; 53 } 54 } 55 return false; 56 } 57 58 bool removeAll(Bag!E bag) 59 { 60 bool modified = false; 61 62 for (size_t i = 0; i < bag.size(); i++) 63 { 64 E e1 = bag.get(i); 65 66 for (size_t j = 0; j < size; j++) 67 { 68 E e2 = data[j]; 69 70 if (e1 == e2) 71 { 72 remove(j); 73 j--; 74 modified = true; 75 break; 76 } 77 } 78 } 79 80 return modified; 81 } 82 83 E get(size_t index) 84 { 85 assert(index >=0 && index < data.length); 86 return data[index]; 87 } 88 89 @property size_t size() 90 { 91 return size_; 92 } 93 94 @property void size(int size) 95 { 96 size_ = size; 97 } 98 99 size_t getCapacity() 100 { 101 return data.length; 102 } 103 104 bool isIndexWithinBounds(int index) 105 { 106 return index < getCapacity(); 107 } 108 109 bool isEmpty() 110 { 111 return size == 0; 112 } 113 114 void add(E e) 115 { 116 if (size == data.length) 117 { 118 grow(); 119 } 120 121 data[size_++] = e; 122 } 123 124 void set(int index, E e) 125 { 126 if(index >= data.length) 127 { 128 grow(index*2); 129 } 130 size = index+1; 131 data[index] = e; 132 } 133 134 void ensureCapacity(int index) 135 { 136 if(index >= data.length) 137 { 138 grow(index*2); 139 } 140 } 141 142 void clear() 143 { 144 data.length = 0; 145 size = 0; 146 } 147 148 void addAll(Bag!E items) 149 { 150 for(size_t i = 0; items.size() > i; i++) 151 { 152 add(items.get(i)); 153 } 154 } 155 156 override string toString() 157 { 158 import std.conv; 159 import std.array; 160 auto s = appender!string; 161 s.put("["); 162 for(size_t i = 0; size > i; i++) 163 { 164 if( i > 0 ) 165 s.put(","); 166 s.put(to!string(data[i])); 167 } 168 s.put("]"); 169 return s.data; 170 } 171 private: 172 173 void grow() 174 { 175 size_t newCapacity = (data.length * 3) / 2 + 1; 176 grow(newCapacity); 177 } 178 179 void grow(size_t newCapacity) 180 { 181 data.length = newCapacity; 182 } 183 184 E[] data; 185 int size_; 186 }