1 module ggeD.indexVec; 2 import ggeD; 3 import std; 4 5 6 private alias MakeSerialIndex(X) = SerialIndex!X; 7 8 package(ggeD): 9 struct IndexVec(IndexTypes...) 10 { 11 12 alias SrialIndexes = staticMap!(MakeSerialIndex,IndexTypes); 13 SrialIndexes idx; 14 alias Dim = Alias!(IndexTypes.length); 15 alias Rank = Dim; 16 alias idx this; 17 @nogc typeof(this) unit(ulong n) 18 { 19 IndexVec!(IndexTypes) vec; 20 static foreach(i;0..Dim) 21 { 22 vec[i] = i == n ? 1 : 0; 23 } 24 return vec; 25 } 26 27 alias tupleof = idx; 28 @nogc auto opBinary(string op,OtherIndexTypes...)(IndexVec!(OtherIndexTypes) rhs) if(OtherIndexTypes.length == Dim) 29 { 30 SrialIndexes result = idx; 31 static foreach(i; 0 .. Dim) 32 { 33 result[i] = mixin("idx[i]" ~ op ~ "rhs[i]"); 34 } 35 return IndexVec!(IndexTypes)(result); 36 } 37 @nogc auto opBinary(string op,N)(N rhs) if(isNumeric!N && (op=="/" || op=="*")) 38 { 39 SrialIndexes result = idx; 40 static foreach(i; 0 .. Dim) 41 { 42 result[i] = mixin("idx[i]" ~ op ~ "rhs"); 43 } 44 return IndexVec!(IndexTypes)(result); 45 } 46 @nogc auto opBinary(string op,N)(N[Dim] rhs) 47 { 48 SrialIndexes result = idx; 49 static foreach(i; 0 .. Dim) 50 { 51 result[i] = mixin("idx[i]" ~ op ~ "rhs[i]"); 52 } 53 return IndexVec!(IndexTypes)(result); 54 } 55 @nogc auto opBinaryRight(string op,N)(N[Dim] lhs) 56 { 57 SrialIndexes result = idx; 58 static foreach(i; 0 .. Dim) 59 { 60 result[i] = mixin("lhs[i]" ~ op ~ "idx[i]"); 61 } 62 return IndexVec!(IndexTypes)(result); 63 } 64 string toString() 65 { 66 string instantWrite(string sep="",Arg...)(Arg arg) 67 { 68 string result; 69 foreach(i,v;arg) 70 { 71 result ~= v.to!string; 72 if(i!=arg.length-1) result~= sep; 73 } 74 return result; 75 } 76 return "["~instantWrite!", "(idx)~"]"; 77 } 78 @nogc auto clamp() 79 { 80 SrialIndexes result = idx; 81 static foreach(i;0..Dim) 82 { 83 result[i] = idx[i].clamp; 84 } 85 return IndexVec!(IndexTypes)(result); 86 } 87 @nogc auto loop() 88 { 89 SrialIndexes result = idx; 90 static foreach(i;0..Dim) 91 { 92 result[i] = idx[i].loop; 93 } 94 return IndexVec!(IndexTypes)(result); 95 } 96 } 97 98 struct SerialIndex(IndexType = int) 99 { 100 this(T)(T f,size_t len_,IndexType offset = 0) 101 { 102 _idx = cast(IndexType)f; 103 _len = len_; 104 } 105 @nogc const IndexType max() 106 { 107 return cast(IndexType)(_len+_offset); 108 } 109 @nogc const size_t len() 110 { 111 return _len; 112 } 113 114 IndexType _idx ; 115 size_t _len; 116 IndexType _offset = 0; 117 alias _idx this; 118 @nogc void idx(IndexType i){ 119 _idx = i; 120 } 121 @nogc auto idx() 122 { 123 return _idx; 124 } 125 @nogc auto opAssign(T)(T value) 126 { 127 _idx = cast(IndexType)value; 128 } 129 @nogc SerialIndex opUnary(string op)() 130 { 131 auto r = SerialIndex(mixin(op~"_idx"),_len,_offset); 132 return r; 133 } 134 @nogc SerialIndex opBinary(string op,T)(T value) 135 { 136 auto r = SerialIndex(mixin("_idx"~op~"value"),_len,_offset); 137 return r; 138 } 139 @nogc SerialIndex opBinaryRight(string op,T)(T value) 140 { 141 auto r = SerialIndex(mixin("value"~op~"_idx"),_len,_offset); 142 return r; 143 } 144 @nogc SerialIndex clamp() 145 { 146 auto r = SerialIndex(_idx < 0 ? 0 : _idx > max ? max : _idx,_len,_offset); 147 return r; 148 } 149 @nogc SerialIndex loop() 150 { 151 auto r = SerialIndex(_idx < 0 ? _len+_idx : _idx > max ? _idx-_len : _idx,_len,_offset); 152 return r; 153 } 154 string toString() 155 { 156 return _idx.to!string; 157 } 158 159 }