Convert explicit template arguments to dummy arguments to try to make older gcc
[bigint/bigint.git] / BigInteger.cc
index 2651ab7..dac50d9 100644 (file)
@@ -13,11 +13,18 @@ void BigInteger::operator =(const BigInteger &x) {
 BigInteger::BigInteger(const Blk *b, Index blen, Sign s) : mag(b, blen) {
        switch (s) {
        case zero:
+               if (!mag.isZero())
+                       throw "BigInteger::BigInteger(const Blk *, Index, Sign): Cannot use a sign of zero with a nonzero magnitude";
+               sign = zero;
+               break;
        case positive:
        case negative:
+               // If the magnitude is zero, force the sign to zero.
                sign = mag.isZero() ? zero : s;
                break;
        default:
+               /* g++ seems to be optimizing out this case on the assumption
+                * that the sign is a valid member of the enumeration.  Oh well. */
                throw "BigInteger::BigInteger(const Blk *, Index, Sign): Invalid sign";
        }
 }
@@ -25,12 +32,19 @@ BigInteger::BigInteger(const Blk *b, Index blen, Sign s) : mag(b, blen) {
 BigInteger::BigInteger(const BigUnsigned &x, Sign s) : mag(x) {
        switch (s) {
        case zero:
+               if (!mag.isZero())
+                       throw "BigInteger::BigInteger(const BigUnsigned &, Sign): Cannot use a sign of zero with a nonzero magnitude";
+               sign = zero;
+               break;
        case positive:
        case negative:
+               // If the magnitude is zero, force the sign to zero.
                sign = mag.isZero() ? zero : s;
                break;
        default:
-               throw "BigInteger::BigInteger(Blk *, Index, Sign): Invalid sign";
+               /* g++ seems to be optimizing out this case on the assumption
+                * that the sign is a valid member of the enumeration.  Oh well. */
+               throw "BigInteger::BigInteger(const BigUnsigned &, Sign): Invalid sign";
        }
 }
 
@@ -39,15 +53,9 @@ BigInteger::BigInteger(const BigUnsigned &x, Sign s) : mag(x) {
  * negative BigInteger instead of an exception. */
 
 // Done longhand to let us use initialization.
-BigInteger::BigInteger(unsigned long x) : mag(x) {
-       sign = mag.isZero() ? zero : positive;
-}
-BigInteger::BigInteger(unsigned int x) : mag(x) {
-       sign = mag.isZero() ? zero : positive;
-}
-BigInteger::BigInteger(unsigned short x) : mag(x) {
-       sign = mag.isZero() ? zero : positive;
-}
+BigInteger::BigInteger(unsigned long  x) : mag(x) { sign = mag.isZero() ? zero : positive; }
+BigInteger::BigInteger(unsigned int   x) : mag(x) { sign = mag.isZero() ? zero : positive; }
+BigInteger::BigInteger(unsigned short x) : mag(x) { sign = mag.isZero() ? zero : positive; }
 
 // For signed input, determine the desired magnitude and sign separately.
 
@@ -66,12 +74,9 @@ namespace {
        }
 }
 
-BigInteger::BigInteger(long x) : sign(signOf(x)),
-       mag(magOf<long, unsigned long>(x)) {}
-BigInteger::BigInteger(int x) : sign(signOf(x)),
-       mag(magOf<int, unsigned int>(x)) {}
-BigInteger::BigInteger(short x) : sign(signOf(x)),
-       mag(magOf<short, unsigned short>(x)) {}
+BigInteger::BigInteger(long  x) : sign(signOf(x)), mag(magOf<long , unsigned long >(x)) {}
+BigInteger::BigInteger(int   x) : sign(signOf(x)), mag(magOf<int  , unsigned int  >(x)) {}
+BigInteger::BigInteger(short x) : sign(signOf(x)), mag(magOf<short, unsigned short>(x)) {}
 
 // CONVERSION TO PRIMITIVE INTEGERS
 
@@ -80,23 +85,23 @@ BigInteger::BigInteger(short x) : sign(signOf(x)),
  * BigInteger::convertToUnsignedPrimitive to avoid requiring BigUnsigned to
  * declare BigInteger. */
 template <class X>
-inline X convertBigUnsignedToPrimitiveAccess(const BigUnsigned &a) {
-       return a.convertToPrimitive<X>();
+inline X convertBigUnsignedToPrimitiveAccess(const BigUnsigned &a, X dummyX) {
+       return a.convertToPrimitive(dummyX);
 }
 
 template <class X>
-X BigInteger::convertToUnsignedPrimitive() const {
+X BigInteger::convertToUnsignedPrimitive(X dummyX) const {
        if (sign == negative)
                throw "BigInteger::to<Primitive>: "
                        "Cannot convert a negative integer to an unsigned type";
        else
-               return convertBigUnsignedToPrimitiveAccess<X>(mag);
+               return convertBigUnsignedToPrimitiveAccess(mag, dummyX);
 }
 
 /* Similar to BigUnsigned::convertToPrimitive, but split into two cases for
  * nonnegative and negative numbers. */
 template <class X, class UX>
-X BigInteger::convertToSignedPrimitive() const {
+X BigInteger::convertToSignedPrimitive(X /*dummyX*/, UX /*dummyUX*/) const {
        if (sign == zero)
                return 0;
        else if (mag.getLength() == 1) {
@@ -119,24 +124,12 @@ X BigInteger::convertToSignedPrimitive() const {
                "Value is too big to fit in the requested type";
 }
 
-unsigned long BigInteger::toUnsignedLong() const {
-       return convertToUnsignedPrimitive<unsigned long>();
-}
-unsigned int BigInteger::toUnsignedInt() const {
-       return convertToUnsignedPrimitive<unsigned int>();
-}
-unsigned short BigInteger::toUnsignedShort() const {
-       return convertToUnsignedPrimitive<unsigned short>();
-}
-long BigInteger::toLong() const {
-       return convertToSignedPrimitive<long, unsigned long>();
-}
-int BigInteger::toInt() const {
-       return convertToSignedPrimitive<int, unsigned int>();
-}
-short BigInteger::toShort() const {
-       return convertToSignedPrimitive<short, unsigned short>();
-}
+unsigned long  BigInteger::toUnsignedLong () const { return convertToUnsignedPrimitive((unsigned long )0)          ; }
+unsigned int   BigInteger::toUnsignedInt  () const { return convertToUnsignedPrimitive((unsigned int  )0)          ; }
+unsigned short BigInteger::toUnsignedShort() const { return convertToUnsignedPrimitive((unsigned short)0)          ; }
+long           BigInteger::toLong         () const { return convertToSignedPrimitive  ((long )0, (unsigned long )0); }
+int            BigInteger::toInt          () const { return convertToSignedPrimitive  ((int  )0, (unsigned int  )0); }
+short          BigInteger::toShort        () const { return convertToSignedPrimitive  ((short)0, (unsigned short)0); }
 
 // COMPARISON
 BigInteger::CmpRes BigInteger::compareTo(const BigInteger &x) const {