std.math.abs and shared/const/immutable BigInts
Joseph Rushton Wakeling
joseph.wakeling at webdrake.net
Mon Oct 7 07:56:33 PDT 2013
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
More information about the Digitalmars-d-learn
mailing list