Thanks! I thought about the idea of just creating the code and mix it in, but now I can see why I failed at that: Your code is kind of read-only to me, for now, because I need to change it a bit to accept an array instead of seperat indices.
Wouldn't it be nice if it worked like this: int[] index = (1,2,3); array(index) = -1; > > Here's one. > > module test144; > > import std.stdio, std.metastrings; > > struct PointerAssign(T) { > T* ptr; > T opAssign(T t) { *ptr = t; return t; } > static PointerAssign opCall(T* p) { PointerAssign res; res.ptr = p; > return res; } > } > > template isArray(T: T[]) { const bool isArray = true; } > template isArray(T) { const bool isArray = false; } > > template Init(T) { const T Init; } > template ElemType(T) { alias typeof(Init!(T)[0]) ElemType; } > > template BaseType(T) { > static if (isArray!(T)) alias BaseType!(ElemType!(T)) BaseType; > else alias T BaseType; > } > > template Depth(T) { > static if (isArray!(T)) const int Depth = 1 + Depth!(ElemType!(T)); > else const int Depth = 0; > } > > string ctToString(int i) { > if (!i) return "0"; > string res; > while (i) { > res = "0123456789"[i%10] ~ res; > i /= 10; > } > return res; > } > > string index(int len) { > string res; > for (int i = 0; i < len; ++i) > res ~= "[indices["~ctToString(i)~"]] "; > return res; > } > > PointerAssign!(BaseType!(T)) IndexArray(T)(T array, int[] indices...) { > return PointerAssign!(BaseType!(T)) (mixin("&array"~index(Depth!(T)))); > } > > void main() { > int[][][] array; > array.length = 10; > array[1].length = 3; > array[1][2].length = 4; > array[1][2][1] = 99; > writefln(array); > IndexArray(array, 1, 2, 3) = -1; > writefln(array); > }