Fixes Issue 8837 - BigInt needs better operator constraints.

This commit is contained in:
Andrej Mitrovic 2013-02-04 22:06:20 +01:00
parent 705f1a9bdf
commit 7c616db71a

View file

@ -27,6 +27,7 @@ module std.bigint;
private import std.internal.math.biguintcore; private import std.internal.math.biguintcore;
private import std.format : FormatSpec, FormatException; private import std.format : FormatSpec, FormatException;
private import std.traits;
/** A struct representing an arbitrary precision integer /** A struct representing an arbitrary precision integer
* *
@ -105,14 +106,14 @@ public:
} }
/// ///
this(T: long) (T x) this(T)(T x) if (isIntegral!T)
{ {
data = data.init; // @@@: Workaround for compiler bug data = data.init; // @@@: Workaround for compiler bug
opAssign(x); opAssign(x);
} }
/// ///
BigInt opAssign(T: long)(T x) BigInt opAssign(T)(T x) if (isIntegral!T)
{ {
data = cast(ulong)((x < 0) ? -x : x); data = cast(ulong)((x < 0) ? -x : x);
sign = (x < 0); sign = (x < 0);
@ -130,7 +131,7 @@ public:
// BigInt op= integer // BigInt op= integer
BigInt opOpAssign(string op, T)(T y) BigInt opOpAssign(string op, T)(T y)
if ((op=="+" || op=="-" || op=="*" || op=="/" || op=="%" if ((op=="+" || op=="-" || op=="*" || op=="/" || op=="%"
|| op==">>" || op=="<<" || op=="^^") && is (T: long)) || op==">>" || op=="<<" || op=="^^") && isIntegral!T)
{ {
ulong u = cast(ulong)(y < 0 ? -y : y); ulong u = cast(ulong)(y < 0 ? -y : y);
@ -252,7 +253,7 @@ public:
// BigInt op integer // BigInt op integer
BigInt opBinary(string op, T)(T y) BigInt opBinary(string op, T)(T y)
if ((op=="+" || op == "*" || op=="-" || op=="/" if ((op=="+" || op == "*" || op=="-" || op=="/"
|| op==">>" || op=="<<" || op=="^^") && is (T: long)) || op==">>" || op=="<<" || op=="^^") && isIntegral!T)
{ {
BigInt r = this; BigInt r = this;
return r.opOpAssign!(op)(y); return r.opOpAssign!(op)(y);
@ -260,7 +261,7 @@ public:
// //
int opBinary(string op, T : int)(T y) int opBinary(string op, T : int)(T y)
if (op == "%") if (op == "%" && isIntegral!T)
{ {
assert(y!=0); assert(y!=0);
uint u = y < 0 ? -y : y; uint u = y < 0 ? -y : y;
@ -272,14 +273,14 @@ public:
// Commutative operators // Commutative operators
BigInt opBinaryRight(string op, T)(T y) BigInt opBinaryRight(string op, T)(T y)
if ((op=="+" || op=="*") && !is(T: BigInt)) if ((op=="+" || op=="*") && isIntegral!T)
{ {
return opBinary!(op)(y); return opBinary!(op)(y);
} }
// BigInt = integer op BigInt // BigInt = integer op BigInt
BigInt opBinaryRight(string op, T)(T y) BigInt opBinaryRight(string op, T)(T y)
if (op == "-" && is(T: long)) if (op == "-" && isIntegral!T)
{ {
ulong u = cast(ulong)(y < 0 ? -y : y); ulong u = cast(ulong)(y < 0 ? -y : y);
BigInt r; BigInt r;
@ -294,7 +295,7 @@ public:
// integer = integer op BigInt // integer = integer op BigInt
T opBinaryRight(string op, T)(T x) T opBinaryRight(string op, T)(T x)
if ((op=="%" || op=="/") && is(T: long)) if ((op=="%" || op=="/") && isIntegral!T)
{ {
static if (op == "%") static if (op == "%")
{ {
@ -350,7 +351,7 @@ public:
} }
/// ///
bool opEquals(T: long)(T y) const bool opEquals(T)(T y) const if (isIntegral!T)
{ {
if (sign != (y<0)) if (sign != (y<0))
return 0; return 0;
@ -358,7 +359,7 @@ public:
} }
/// ///
int opCmp(T:long)(T y) int opCmp(T)(T y) if (isIntegral!T)
{ {
if (sign != (y<0) ) if (sign != (y<0) )
return sign ? -1 : 1; return sign ? -1 : 1;