digitalmars.D - a case where static foreach dosn't work "correctly"
- BCS (66/66) Dec 06 2006 If a static foreach is given a tuple of const ints, the ints don't
- Alexander Panek (3/81) Dec 06 2006 Have you tried to do the same with DMD 0.176 ?
- BCS (76/88) Dec 07 2006 It wasn't, but I fond a work around (and a few typos), here's the latest...
If a static foreach is given a tuple of const ints, the ints don't behave like consts inside of the foreach body. I havent checked other cases but you can't use them for array indexes in ASM operations: voif fn(V...)() { const int i = 0 int[3] array; foreach(j, V) { asm { mov EAX, array[i]; // works mov EAX, array[j]; // fails } } } Why does this matter you ask? It would allow this to work: /***** unsigned big int with "size" words of precision */ template BigNum(uint size) { static if(size == 0) static assert(false, "BigNum!(1) is not valid"); else static if(size == 1) static assert(false, "BigNum!(1) is not implemented"); else static if(size == 2) alias use!(1, 1) start; else alias build!(size, size-2, size-1) start; } template build(uint size, uint i, V...) { static if(i==1) alias use!(size, 1, V) build; else alias build!(size, i-1, i, V) build; } template use(uint size, V...) { struct use { uint[size] valuse; use!(size, V).use opAdd(use!(size, V).use to) { uint[size] mine, other; mine[] = valuse; other[] = to.valuse[]; asm { mov EAX, mine[0]; add other[0], EAX; } foreach(i; V) { asm { mov EAX, mine[i]; // this fails adc other[i], EAX; } } use!(size, V).use ret; ret.valuse[] = other; return ret; } } } DMD 0.174
Dec 06 2006
Have you tried to do the same with DMD 0.176 ? Maybe the bug is already solved in one of the two big massacres! BCS wrote:If a static foreach is given a tuple of const ints, the ints don't behave like consts inside of the foreach body. I havent checked other cases but you can't use them for array indexes in ASM operations: voif fn(V...)() { const int i = 0 int[3] array; foreach(j, V) { asm { mov EAX, array[i]; // works mov EAX, array[j]; // fails } } } Why does this matter you ask? It would allow this to work: /***** unsigned big int with "size" words of precision */ template BigNum(uint size) { static if(size == 0) static assert(false, "BigNum!(1) is not valid"); else static if(size == 1) static assert(false, "BigNum!(1) is not implemented"); else static if(size == 2) alias use!(1, 1) start; else alias build!(size, size-2, size-1) start; } template build(uint size, uint i, V...) { static if(i==1) alias use!(size, 1, V) build; else alias build!(size, i-1, i, V) build; } template use(uint size, V...) { struct use { uint[size] valuse; use!(size, V).use opAdd(use!(size, V).use to) { uint[size] mine, other; mine[] = valuse; other[] = to.valuse[]; asm { mov EAX, mine[0]; add other[0], EAX; } foreach(i; V) { asm { mov EAX, mine[i]; // this fails adc other[i], EAX; } } use!(size, V).use ret; ret.valuse[] = other; return ret; } } } DMD 0.174
Dec 06 2006
Alexander Panek wrote:Have you tried to do the same with DMD 0.176 ? Maybe the bug is already solved in one of the two big massacres!It wasn't, but I fond a work around (and a few typos), here's the latest: /***** unsigned big int with "size" words of precision */ alias BigNum(4) uCent; template BigNum(uint size) { static if(size == 0) static assert(false, "BigNum!(1) is not valid"); else static if(size == 1) static assert(false, "BigNum!(1) is not implemented"); else static if(size == 2) alias use!(1, 1) BigNum; else alias build!(size, size-2, size-1) BigNum; } template build(uint size, uint i, V...) { static if(i==1) alias use!(size, 1, V) build; else alias build!(size, i-1, i, V) build; } template use(uint size, V...) { struct use { uint[size] valuse; use!(size, V) opAdd(use!(size, V) to) { uint[size] mine, other; mine[] = valuse; other[] = to.valuse[]; asm { mov EAX, mine[0]; add other[0], EAX; } foreach(j,i; V) { const uint off = V[j]; // this is a work-around asm { mov EAX, mine[off]; adc other[off], EAX; } } use!(size, V) ret; ret.valuse[] = other; return ret; } use!(size, V) opSub(use!(size, V) to) { uint[size] mine, other; mine[] = valuse; other[] = to.valuse[]; asm { mov EAX, mine[0]; sub other[0], EAX; } foreach(j,i; V) { const uint off = V[j]; asm { mov EAX, mine[off]; sbb other[off], EAX; } } use!(size, V) ret; ret.valuse[] = other; return ret; } } }BCS wrote:[...]If a static foreach is given a tuple of const ints, the ints don't behave like consts inside of the foreach body. I havent checked other cases but you can't use them for array indexes in ASM operations:Why does this matter you ask? It would allow this to work:
Dec 07 2006