1 module mutils.container.vecor_queue; 2 3 import core.bitop; 4 import core.stdc.stdlib : free, malloc; 5 import core.stdc..string : memcpy, memset; 6 import std.stdio; 7 8 @nogc @safe nothrow pure size_t nextPow2()(size_t num) { 9 return 1 << bsr(num) + 1; 10 } 11 12 struct VectorQueue(T) { 13 T[] array; 14 size_t begin; 15 size_t end; 16 17 ~this() { 18 clear(); 19 } 20 21 void clear() { 22 removeAll(); 23 } 24 25 void removeAll() { 26 if (array !is null) { 27 freeData(cast(void[]) array); 28 } 29 array = null; 30 end = 0; 31 begin = 0; 32 } 33 34 void reserve(size_t numElements) { 35 if (numElements > array.length) { 36 extend(numElements); 37 } 38 } 39 40 void extend(size_t newNumOfElements) { 41 auto oldArray = manualExtend(array, newNumOfElements); 42 if (oldArray !is null) { 43 freeData(oldArray); 44 } 45 } 46 47 @nogc void freeData(void[] data) { 48 // 0x0F probably invalid value for pointers and other types 49 memset(data.ptr, 0x0F, data.length); // Makes bugs show up xD 50 free(data.ptr); 51 } 52 53 size_t length() { 54 if (end >= begin) { 55 return end - begin; 56 } 57 return array.length + end - begin; 58 } 59 60 void[] manualExtend(T[] oldArray, size_t newNumOfElements = 0) { 61 if (newNumOfElements == 0) 62 newNumOfElements = 2; 63 size_t oldSize = oldArray.length * T.sizeof; 64 size_t newSize = newNumOfElements * T.sizeof; 65 T* memory = cast(T*) malloc(newSize); 66 array = memory[0 .. newNumOfElements]; 67 68 size_t bbbbb = begin; 69 size_t eeeee = end; 70 size_t lll = length; 71 size_t iterator = begin; 72 size_t i = 0; 73 if (oldArray) { 74 do { 75 if (iterator == end) { 76 break; 77 } 78 array[i] = oldArray[iterator]; 79 80 iterator++; 81 82 if (iterator == oldArray.length) { 83 iterator = 0; 84 } 85 i++; 86 } 87 while (1); 88 } 89 end = i; 90 begin = 0; 91 92 return cast(void[]) oldArray; 93 } 94 95 void add()(auto ref T el) { 96 if (array.length - length <= 1) { 97 extend(nextPow2(array.length + 1)); 98 } 99 array[end] = el; 100 end++; 101 if (end == array.length) { 102 end = 0; 103 } 104 105 } 106 107 T pop() { 108 109 assert(begin != end); 110 auto el = array[begin]; 111 begin++; 112 if (begin == array.length) { 113 begin = 0; 114 } 115 return el; 116 } 117 } 118 119 unittest { 120 VectorQueue!int queue; 121 122 queue.add(1); 123 queue.add(2); 124 queue.add(3); 125 126 assert(queue.length == 3); 127 128 assert(queue.pop() == 1); 129 assert(queue.pop() == 2); 130 131 assert(queue.length == 1); 132 assert(queue.array.length == 4); 133 134 queue.add(5); 135 queue.add(6); 136 assert(queue.array.length == 4); 137 assert(queue.pop() == 3); 138 139 assert(queue.length == 2); 140 141 assert(queue.pop() == 5); 142 assert(queue.pop() == 6); 143 assert(queue.length == 0); 144 assert(queue.array.length == 4); 145 146 foreach (int i; 0 .. 128) { 147 queue.add(i); 148 } 149 150 foreach (int i; 0 .. 128) { 151 assert(queue.pop() == i); 152 } 153 154 }