Thread overview | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
August 25, 2013 Error on recursive alias | ||||
---|---|---|---|---|
| ||||
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. |
August 25, 2013 Re: Error on recursive alias | ||||
---|---|---|---|---|
| ||||
Posted in reply to Johan Mollevik | 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
|
August 25, 2013 Re: Error on recursive alias | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | bearophile wrote:
> 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
x and y are the two dimensional indices into the 4x4 array block and v is the vallue at block[y][x]
|
August 25, 2013 Re: Error on recursive alias | ||||
---|---|---|---|---|
| ||||
Posted in reply to Johan Mollevik | 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
|
August 25, 2013 Re: Error on recursive alias | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | 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] > > 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 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 way |
August 25, 2013 Re: Error on recursive alias | ||||
---|---|---|---|---|
| ||||
Posted in reply to Johan Mollevik | Johan Mollevik wrote: > 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] >> >> 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 > > 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 way Hmm, your solution does not work with static arrays it seems, will se if I can sort that out |
August 25, 2013 Re: Error on recursive alias | ||||
---|---|---|---|---|
| ||||
Posted in reply to Johan Mollevik | 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 |
August 25, 2013 Re: Error on recursive alias | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | 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; } |
Copyright © 1999-2021 by the D Language Foundation