Ali Çehreli wrote: > On 08/25/2013 09:23 AM, Johan Mollevik wrote: > > > Hmm, your solution does not work with static arrays it seems, will se > > if I can sort that out > > Probably due to the fact that static arrays cannot be InputRanges > because they cannot lose elements by popFront(). A slice to the entire > array is an InputRange though: > > foreach (e; myStaticArray) // compilation error > > foreach (e; myStaticArray[]) // works > > Ali
I accutally got my original code to work just now. I made a mistake when translating typeof(T[0]) into more modern code. That caused supprising errors. Pasting the code bellow if anyone is interested (can probably be shortened), thanks for the help and quick response. import std.traits; import std.conv; import std.metastrings; template Tuple(T...) { alias T Tuple; } template opApplyType(T) { static if(isArray!T) alias Tuple!(size_t,ForeachType!T) opApplyType; else static if(isAssociativeArray!T) alias Tuple!(typeof(T.keys)[0],typeof(T.values)[0]) opApplyType; else static if(hasMember!(T,"opApply")) alias ParameterTypeTuple!(typeof(&T.opApply)) opApplyType; } template foreachType(T) { static if(is(opApplyType!(T) V)) { static if(is(opApplyType!(V[$-1]))) alias Tuple!(V[0..$-1],foreachType!(V[$-1])) foreachType; else alias V foreachType; } else { pragma(msg,"Failed to resolve type "); static assert(0,opApplyType!(T)); } } template DgArgs(T...) { static if(T.length) const char[] DgArgs="ref "~T[0].stringof~","~DgArgs! (T[1..$]); else const char[] DgArgs=""; } template DgType(T...) { mixin("alias int delegate("~DgArgs!(T)~") Type;"); } template opApplyParams(int i) { static if(i==0) const char[] opApplyParams=""; else const char[] opApplyParams=",p"~to!string(i)~opApplyParams!(i-1); } template opApplyRest(int i) { const char[] opApplyRest="foreach(p"~opApplyParams! (i)~";opApplyN(v))" ~"\n\tif(auto r=dg(i,p"~opApplyParams! (i)~"))" ~"\n\t\treturn r;"; } struct opApplyContext(T) { alias foreachType!(T) FT; mixin DgType!(FT) DG; T* a; int opApply(DG.Type dg) { //consider recursive mixin of delegate function //writefln("Begin opApplyN: ",DG.Type.stringof); static if(isArray!T) { //pragma(msg,"array"); static if(is(opApplyType!(typeof((*a)[0])) V)) { //pragma(msg,"branch"); foreach(i,v;*a) { //pragma(msg,V.stringof); //pragma(msg,DG.Type.stringof); //pragma(msg,typeof(&opApplyN(v).opApply).stringof); //pragma(msg,opApplyRest! (FT.length-2)); mixin(opApplyRest! (FT.length-2)); } } else { //pragma(msg,"leaf"); foreach(i,v;*a) if(auto r=dg(i,v)) return r; } } else static if(isAssociativeArray!(T)) { pragma(msg,"hash"); static assert(0,"Not Implemented"); } else static if(hasMember!(T,"opApply")) { pragma(msg,"opApply"); static assert(0,"Not Implemented"); } else { pragma(msg,"else"); static assert(0,"Not Implemented"); } return 0; } } opApplyContext!(T) opApplyN(T)(T c) { opApplyContext!(T) t; t.a=&c; return t; } opApplyContext!(T) opApplyN(T:T*)(T* c) { opApplyContext!(T) t; t.a=c; return t; }