digitalmars.D.learn - Error on recursive alias
- Johan Mollevik (34/34) Aug 25 2013 I have some code from a couple of years ago that I'm trying to update
- bearophile (4/10) Aug 25 2013 What are x y and v?
- Johan Mollevik (3/17) Aug 25 2013 x and y are the two dimensional indices into the 4x4 array block and v
- bearophile (29/32) Aug 25 2013 OK. Something like this?
- Johan Mollevik (21/65) Aug 25 2013 That looks like it might work for 2 dimensions and as that is the use
- Johan Mollevik (4/81) Aug 25 2013 Hmm, your solution does not work with static arrays it seems, will se
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (7/9) Aug 25 2013 Probably due to the fact that static arrays cannot be InputRanges
- Johan Mollevik (134/148) Aug 25 2013 entire
I have some code from a couple of years ago that I'm trying to update to modern D. I was first using the gdc compiler in debian stable which seems based on DMD 2.055 but that caused somthing that looks like memmory coruption. Using the newer gdc compiler in debian sid (based on DMD 2.062 i think) I run into this error instead. util.d:23: Error: alias util.foreachType!(uint[4LU][4LU]).foreachType recursive alias declaration This is for code that have worked previously looking like this 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)); } } I can post all the source code if anyone is interested What my ultimate goal is is to resurect my opApplyN function allowing me to do things like this uint[4][4] block; foreach(x,y,v;opApplyN(block)) printf("%d %d %d\n",x,y,v); If anyone know a more convinient way to achive that that would be helpfull as well.
Aug 25 2013
Johan Mollevik:What my ultimate goal is is to resurect my opApplyN function allowing me to do things like this uint[4][4] block; foreach(x,y,v;opApplyN(block)) printf("%d %d %d\n",x,y,v);What are x y and v? Bye, bearophile
Aug 25 2013
bearophile wrote:Johan Mollevik:x and y are the two dimensional indices into the 4x4 array block and v is the vallue at block[y][x]What my ultimate goal is is to resurect my opApplyN function allowing me to do things like this uint[4][4] block; foreach(x,y,v;opApplyN(block)) printf("%d %d %d\n",x,y,v);What are x y and v? Bye, bearophile
Aug 25 2013
Johan Mollevik:x and y are the two dimensional indices into the 4x4 array block and v is the vallue at block[y][x]OK. Something like this? import std.stdio, std.typecons; struct NaturalScan(T) { T[][] data; size_t r, c; property bool empty() const pure nothrow { return r == data.length; } property Tuple!(size_t, size_t, T) front() const pure nothrow { return typeof(return)(r, c, data[r][c]); } void popFront() pure nothrow { c = (c + 1) % data[r].length; if (c == 0) r++; } } NaturalScan!T naturalScan(T)(T[][] m) { return typeof(return)(m); } void main() { auto mat = [[10, 20], [30, 40, 50], [60, 70]]; foreach (r, c, v; mat.naturalScan) writefln("%d %d %d", r, c, v); } Bye, bearophile
Aug 25 2013
bearophile wrote:Johan Mollevik:That looks like it might work for 2 dimensions and as that is the use case I have right now I might settle for that. (and I can add more overloads manually if needed) The original code was genereal enough to handle any number of dimensions thou. Bassically this would work like this uint[][][] array=... foreach(x,v;opApplyN(array)){//using only one index (x) //v has type uint[][] } foreach(x,y,v;opApplyN(array)){//using two indeces (x,y) //v has type uint[] } foreach(x,y,z,v;opApplyN(array)){//using three index (x,y,z) //v has type uint } So if someone know anything of why I get the error on recursive aliases I might try to get that working again otherwise I might try your code as it is enough for now Thnks for the help by the wayx and y are the two dimensional indices into the 4x4 array block and v is the vallue at block[y][x]OK. Something like this? import std.stdio, std.typecons; struct NaturalScan(T) { T[][] data; size_t r, c; property bool empty() const pure nothrow { return r == data.length; } property Tuple!(size_t, size_t, T) front() const pure nothrow { return typeof(return)(r, c, data[r][c]); } void popFront() pure nothrow { c = (c + 1) % data[r].length; if (c == 0) r++; } } NaturalScan!T naturalScan(T)(T[][] m) { return typeof(return)(m); } void main() { auto mat = [[10, 20], [30, 40, 50], [60, 70]]; foreach (r, c, v; mat.naturalScan) writefln("%d %d %d", r, c, v); } Bye, bearophile
Aug 25 2013
Johan Mollevik wrote:bearophile wrote:aliasesJohan Mollevik:That looks like it might work for 2 dimensions and as that is the use case I have right now I might settle for that. (and I can add more overloads manually if needed) The original code was genereal enough to handle any number of dimensions thou. Bassically this would work like this uint[][][] array=... foreach(x,v;opApplyN(array)){//using only one index (x) //v has type uint[][] } foreach(x,y,v;opApplyN(array)){//using two indeces (x,y) //v has type uint[] } foreach(x,y,z,v;opApplyN(array)){//using three index (x,y,z) //v has type uint } So if someone know anything of why I get the error on recursivex and y are the two dimensional indices into the 4x4 array block and v is the vallue at block[y][x]OK. Something like this? import std.stdio, std.typecons; struct NaturalScan(T) { T[][] data; size_t r, c; property bool empty() const pure nothrow { return r == data.length; } property Tuple!(size_t, size_t, T) front() const pure nothrow { return typeof(return)(r, c, data[r][c]); } void popFront() pure nothrow { c = (c + 1) % data[r].length; if (c == 0) r++; } } NaturalScan!T naturalScan(T)(T[][] m) { return typeof(return)(m); } void main() { auto mat = [[10, 20], [30, 40, 50], [60, 70]]; foreach (r, c, v; mat.naturalScan) writefln("%d %d %d", r, c, v); } Bye, bearophileI might try to get that working again otherwise I might try your code as it is enough for now Thnks for the help by the wayHmm, your solution does not work with static arrays it seems, will se if I can sort that out
Aug 25 2013
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 outProbably 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
Aug 25 2013
Ali Çehreli wrote:On 08/25/2013 09:23 AM, Johan Mollevik wrote: > Hmm, your solution does not work with static arrays it seems, willse> 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 theentirearray is an InputRange though: foreach (e; myStaticArray) // compilation error foreach (e; myStaticArray[]) // works AliI 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; }
Aug 25 2013