digitalmars.D.learn - std.math.abs and shared/const/immutable BigInts
- Joseph Rushton Wakeling (42/42) Oct 07 2013 Hello all,
Hello all, I recently discovered this issue with std.bigint.BigInt and std.math.abs: http://d.puremagic.com/issues/show_bug.cgi?id=11188 In short, the following code: import std.bigint, std.math, std.typetuple; auto foo(T)() { T n = -3; return std.math.abs(n); } void main() { foreach (T; TypeTuple!(byte, short, int, long, BigInt)) { assert(foo!T() == 3); // works assert(foo!(shared(T)) == 3); // fails for BigInt assert(foo!(const(T)) == 3); // fails for BigInt assert(foo!(immutable(T)) == 3); // fails for BigInt } } ... will fail to compile for the shared, const and immutable variants of BigInt, with the compiler error message being: /opt/dmd/include/d2/std/math.d(303): std.math.abs(Num)(Num x) if (is(typeof(Num.init >= 0)) && is(typeof(-Num.init)) && !(is(Num* : const(ifloat*)) || is(Num* : const(idouble*)) || is(Num* : const(ireal*)))) /opt/dmd/include/d2/std/math.d(314): std.math.abs(Num)(Num z) if (is(Num* : const(cfloat*)) || is(Num* : const(cdouble*)) || is(Num* : const(creal*))) /opt/dmd/include/d2/std/math.d(322): std.math.abs(Num)(Num y) if (is(Num* : const(ifloat*)) || is(Num* : const(idouble*)) || is(Num* : const(ireal*))) bigabs.d(6): Error: template std.math.abs(Num)(Num x) if (is(typeof(Num.init >= 0)) && is(typeof(-Num.init)) && !(is(Num* : const(ifloat*)) || is(Num* : const(idouble*)) || is(Num* : const(ireal*)))) cannot deduce template function from argument types !()(shared(BigInt)) ... and similarly for const and immutable. What I can't see is why there is a failure to deduce the template function. In fact some checks show that it's the very first of these conditions: is(typeof(Num.init >= 0)) ... that fails. This is rather unintuitive. Doesn't a BigInt -- even an immutable one -- default to 0? Advice very much appreciated, as I'm feeling stumped. Thanks & best wishes, -- Joe
Oct 07 2013