1 module mutils.container.vector_allocator; 2 3 import std.experimental.allocator; 4 import std.traits; 5 6 /** 7 * Vector backed by given allocator 8 **/ 9 struct VectorAllocator(T, Allocator){ 10 static if(hasStaticMember!(Allocator,"instance")){ 11 alias allocator=Allocator.instance; 12 }else{ 13 Allocator allocator; 14 } 15 16 17 T[] array; 18 public: 19 20 this(size_t numElements){ 21 assert(numElements>0); 22 setLenght(numElements); 23 } 24 25 void clear(){ 26 removeAll(); 27 } 28 29 void removeAll(){ 30 if(array !is null){ 31 freeData(cast(void[])array); 32 } 33 array=T[].init; 34 } 35 36 bool empty(){ 37 return (array.length==0); 38 } 39 40 size_t length(){ 41 return array.length; 42 } 43 44 void reset(){ 45 clear(); 46 } 47 48 void setLenght(size_t newNumOfElements){ 49 if( array is null){ 50 array=allocator.makeArray!(T)(newNumOfElements); 51 }else{ 52 if(array.length<newNumOfElements){ 53 allocator.expandArray(array, newNumOfElements-array.length); 54 }else if(array.length>newNumOfElements){ 55 allocator.shrinkArray(array, array.length-newNumOfElements); 56 } 57 } 58 } 59 60 void freeData(void[] data){ 61 allocator.dispose(array); 62 } 63 64 void add( T t ) { 65 setLenght(array.length+1); 66 array[$-1]=t; 67 } 68 69 void add( T[] t ) { 70 size_t sizeBefore=array.length; 71 setLenght(array.length+t.length); 72 foreach(i;0..t.length){ 73 array[sizeBefore+i]=t[i]; 74 } 75 } 76 77 78 void remove(size_t elemNum){ 79 array[elemNum]=array[$-1]; 80 setLenght(array.length-1); 81 } 82 83 void removeElement(T elem){ 84 foreach(i,ref el;array){ 85 if(el==elem){ 86 remove(i); 87 return; 88 } 89 } 90 } 91 92 T opIndex(size_t elemNum){ 93 return array[elemNum]; 94 } 95 96 auto opSlice(){ 97 return array; 98 } 99 100 T[] opSlice(size_t x, size_t y){ 101 return array[x..y]; 102 } 103 104 size_t opDollar(){ 105 return array.length; 106 } 107 108 void opOpAssign(string op)(T obj){ 109 static assert(op=="~"); 110 add(obj); 111 } 112 113 void opOpAssign(string op)(T[] obj){ 114 static assert(op=="~"); 115 add(obj); 116 } 117 118 void opIndexAssign(T obj,size_t elemNum){ 119 array[elemNum]=obj; 120 121 } 122 123 } 124 unittest{ 125 import std.experimental.allocator.mallocator; 126 VectorAllocator!(int, Mallocator) vec; 127 assert(vec.empty); 128 vec.add(0); 129 vec.add(1); 130 vec.add(2); 131 vec.add(3); 132 vec.add(4); 133 vec.add(5); 134 assert(vec.length==6); 135 assert(vec[3]==3); 136 assert(vec[5]==5); 137 assert(vec[]==[0,1,2,3,4,5]); 138 assert(!vec.empty); 139 vec.remove(3); 140 assert(vec.length==5); 141 assert(vec[]==[0,1,2,5,4]);//unstable remove 142 }