Annotate std/bigint.d and std/internal/math/biguintcore.d to please dlang/dmd#12520 #8076

This commit is contained in:
nordlow 2021-05-17 00:10:48 +02:00
parent bc0a16273e
commit a44f71813f
2 changed files with 42 additions and 40 deletions

View file

@ -246,7 +246,7 @@ public:
* Implements assignment operators from built-in integers of the form * Implements assignment operators from built-in integers of the form
* `BigInt op= integer`. * `BigInt op= integer`.
*/ */
BigInt opOpAssign(string op, T)(T y) pure nothrow @safe BigInt opOpAssign(string op, T)(T y) pure nothrow @safe return
if ((op=="+" || op=="-" || op=="*" || op=="/" || op=="%" if ((op=="+" || op=="-" || op=="*" || op=="/" || op=="%"
|| op==">>" || op=="<<" || op=="^^" || op=="|" || op=="&" || op=="^") && isIntegral!T) || op==">>" || op=="<<" || op=="^^" || op=="|" || op=="&" || op=="^") && isIntegral!T)
{ {
@ -414,7 +414,7 @@ public:
/** /**
* Implements assignment operators of the form `BigInt op= BigInt`. * Implements assignment operators of the form `BigInt op= BigInt`.
*/ */
BigInt opOpAssign(string op, T)(T y) pure nothrow @safe BigInt opOpAssign(string op, T)(T y) pure nothrow @safe scope return
if ((op=="+" || op== "-" || op=="*" || op=="|" || op=="&" || op=="^" || op=="/" || op=="%") if ((op=="+" || op== "-" || op=="*" || op=="|" || op=="&" || op=="^" || op=="/" || op=="%")
&& is (T: BigInt)) && is (T: BigInt))
{ {
@ -472,7 +472,7 @@ public:
/** /**
* Implements binary operators between `BigInt`s. * Implements binary operators between `BigInt`s.
*/ */
BigInt opBinary(string op, T)(T y) pure nothrow @safe const BigInt opBinary(string op, T)(T y) pure nothrow @safe const return scope
if ((op=="+" || op == "*" || op=="-" || op=="|" || op=="&" || op=="^" || if ((op=="+" || op == "*" || op=="-" || op=="|" || op=="&" || op=="^" ||
op=="/" || op=="%") op=="/" || op=="%")
&& is (T: BigInt)) && is (T: BigInt))
@ -1454,19 +1454,19 @@ public:
} }
private: private:
void negate() @safe pure nothrow @nogc void negate() @safe pure nothrow @nogc scope
{ {
if (!data.isZero()) if (!data.isZero())
sign = !sign; sign = !sign;
} }
bool isZero() pure const nothrow @nogc @safe bool isZero() pure const nothrow @nogc @safe scope
{ {
return data.isZero(); return data.isZero();
} }
alias isNegative = sign; alias isNegative = sign;
// Generate a runtime error if division by zero occurs // Generate a runtime error if division by zero occurs
void checkDivByZero() pure const nothrow @safe void checkDivByZero() pure const nothrow @safe scope
{ {
assert(!isZero(), "BigInt division by zero"); assert(!isZero(), "BigInt division by zero");
} }

View file

@ -245,12 +245,12 @@ private:
immutable(BigDigit) [] data = ZERO; immutable(BigDigit) [] data = ZERO;
this(immutable(BigDigit) [] x) pure nothrow @nogc @safe this(immutable(BigDigit) [] x) pure nothrow @nogc @safe scope
{ {
data = x; data = x;
} }
package(std) // used from: std.bigint package(std) // used from: std.bigint
this(T)(T x) pure nothrow @safe if (isIntegral!T) this(T)(T x) pure nothrow @safe scope if (isIntegral!T)
{ {
opAssign(x); opAssign(x);
} }
@ -260,7 +260,7 @@ private:
}; };
public: public:
// Length in uints // Length in uints
@property size_t uintLength() pure nothrow const @safe @nogc @property size_t uintLength() pure nothrow const @safe @nogc scope
{ {
static if (BigDigit.sizeof == uint.sizeof) static if (BigDigit.sizeof == uint.sizeof)
{ {
@ -272,7 +272,7 @@ public:
((data[$-1] & 0xFFFF_FFFF_0000_0000L) ? 1 : 0); ((data[$-1] & 0xFFFF_FFFF_0000_0000L) ? 1 : 0);
} }
} }
@property size_t ulongLength() pure nothrow const @safe @nogc @property size_t ulongLength() pure nothrow const @safe @nogc scope
{ {
static if (BigDigit.sizeof == uint.sizeof) static if (BigDigit.sizeof == uint.sizeof)
{ {
@ -285,7 +285,7 @@ public:
} }
// The value at (cast(ulong[]) data)[n] // The value at (cast(ulong[]) data)[n]
ulong peekUlong(size_t n) pure nothrow const @safe @nogc ulong peekUlong(size_t n) pure nothrow const @safe @nogc scope
{ {
static if (BigDigit.sizeof == int.sizeof) static if (BigDigit.sizeof == int.sizeof)
{ {
@ -298,7 +298,7 @@ public:
} }
} }
uint peekUint(size_t n) pure nothrow const @safe @nogc uint peekUint(size_t n) pure nothrow const @safe @nogc scope
{ {
static if (BigDigit.sizeof == int.sizeof) static if (BigDigit.sizeof == int.sizeof)
{ {
@ -312,7 +312,7 @@ public:
} }
/// ///
void opAssign(Tulong)(Tulong u) pure nothrow @safe if (is (Tulong == ulong)) void opAssign(Tulong)(Tulong u) pure nothrow @safe scope if (is (Tulong == ulong))
{ {
if (u == 0) data = ZERO; if (u == 0) data = ZERO;
else if (u == 1) data = ONE; else if (u == 1) data = ONE;
@ -339,13 +339,13 @@ public:
} }
} }
} }
void opAssign(Tdummy = void)(BigUint y) pure nothrow @nogc @safe void opAssign(Tdummy = void)(BigUint y) pure nothrow @nogc @safe scope
{ {
this.data = y.data; this.data = y.data;
} }
/// ///
int opCmp(Tdummy = void)(const BigUint y) pure nothrow @nogc const @safe int opCmp(Tdummy = void)(const BigUint y) pure nothrow @nogc const @safe scope
{ {
if (data.length != y.data.length) if (data.length != y.data.length)
return (data.length > y.data.length) ? 1 : -1; return (data.length > y.data.length) ? 1 : -1;
@ -356,7 +356,7 @@ public:
} }
/// ///
int opCmp(Tulong)(Tulong y) pure nothrow @nogc const @safe if (is (Tulong == ulong)) int opCmp(Tulong)(Tulong y) pure nothrow @nogc const @safe scope if (is (Tulong == ulong))
{ {
if (data.length > maxBigDigits!Tulong) if (data.length > maxBigDigits!Tulong)
return 1; return 1;
@ -382,12 +382,12 @@ public:
return 0; return 0;
} }
bool opEquals(Tdummy = void)(ref const BigUint y) pure nothrow @nogc const @safe bool opEquals(Tdummy = void)(ref const BigUint y) pure nothrow @nogc const @safe scope
{ {
return y.data[] == data[]; return y.data[] == data[];
} }
bool opEquals(Tdummy = void)(ulong y) pure nothrow @nogc const @safe bool opEquals(Tdummy = void)(ulong y) pure nothrow @nogc const @safe scope
{ {
if (data.length > 2) if (data.length > 2)
return false; return false;
@ -400,18 +400,18 @@ public:
return (data[0] == ylo); return (data[0] == ylo);
} }
bool isZero() pure const nothrow @safe @nogc bool isZero() pure const nothrow @safe @nogc scope
{ {
return data.length == 1 && data[0] == 0; return data.length == 1 && data[0] == 0;
} }
size_t numBytes() pure nothrow const @safe @nogc size_t numBytes() pure nothrow const @safe @nogc scope
{ {
return data.length * BigDigit.sizeof; return data.length * BigDigit.sizeof;
} }
// the extra bytes are added to the start of the string // the extra bytes are added to the start of the string
char [] toDecimalString(int frontExtraBytes) const pure nothrow @safe char [] toDecimalString(int frontExtraBytes) const pure nothrow @safe scope
{ {
immutable predictlength = 20+20*(data.length/2); // just over 19 immutable predictlength = 20+20*(data.length/2); // just over 19
char [] buff = new char[frontExtraBytes + predictlength]; char [] buff = new char[frontExtraBytes + predictlength];
@ -428,7 +428,7 @@ public:
*/ */
char [] toHexString(int frontExtraBytes, char separator = 0, char [] toHexString(int frontExtraBytes, char separator = 0,
int minPadding=0, char padChar = '0', int minPadding=0, char padChar = '0',
LetterCase letterCase = LetterCase.upper) const pure nothrow @safe LetterCase letterCase = LetterCase.upper) const pure nothrow @safe scope
{ {
// Calculate number of extra padding bytes // Calculate number of extra padding bytes
size_t extraPad = (minPadding > data.length * 2 * BigDigit.sizeof) size_t extraPad = (minPadding > data.length * 2 * BigDigit.sizeof)
@ -492,7 +492,7 @@ public:
/** /**
* Convert to an octal string. * Convert to an octal string.
*/ */
char[] toOctalString() pure nothrow @safe const char[] toOctalString() pure nothrow @safe const scope
{ {
auto predictLength = 1 + data.length*BigDigitBits / 3; auto predictLength = 1 + data.length*BigDigitBits / 3;
char[] buff = new char[predictLength]; char[] buff = new char[predictLength];
@ -501,7 +501,7 @@ public:
} }
// return false if invalid character found // return false if invalid character found
bool fromHexString(Range)(Range s) if ( bool fromHexString(Range)(Range s) scope if (
isBidirectionalRange!Range && isSomeChar!(ElementType!Range)) isBidirectionalRange!Range && isSomeChar!(ElementType!Range))
{ {
import std.range : walkLength; import std.range : walkLength;
@ -570,7 +570,7 @@ public:
} }
// return true if OK; false if erroneous characters found // return true if OK; false if erroneous characters found
bool fromDecimalString(Range)(Range s) if ( bool fromDecimalString(Range)(Range s) scope if (
isForwardRange!Range && isSomeChar!(ElementType!Range)) isForwardRange!Range && isSomeChar!(ElementType!Range))
{ {
import std.range : walkLength; import std.range : walkLength;
@ -595,7 +595,7 @@ public:
return true; return true;
} }
void fromMagnitude(Range)(Range magnitude) void fromMagnitude(Range)(Range magnitude) scope
if (isInputRange!Range if (isInputRange!Range
&& (isForwardRange!Range || hasLength!Range) && (isForwardRange!Range || hasLength!Range)
&& isUnsigned!(ElementType!Range)) && isUnsigned!(ElementType!Range))
@ -734,7 +734,7 @@ public:
} }
// return x << y // return x << y
BigUint opBinary(string op, Tulong)(Tulong y) pure nothrow @safe const BigUint opBinary(string op, Tulong)(Tulong y) pure nothrow @safe const scope
if (op == "<<" && is (Tulong == ulong)) if (op == "<<" && is (Tulong == ulong))
{ {
assert(y > 0, "Can not left shift BigUint by 0"); assert(y > 0, "Can not left shift BigUint by 0");
@ -813,7 +813,7 @@ public:
// If wantSub is false, return x + y, leaving sign unchanged. // If wantSub is false, return x + y, leaving sign unchanged.
// If wantSub is true, return abs(x - y), negating sign if x<y // If wantSub is true, return abs(x - y), negating sign if x<y
static BigUint addOrSub(BigUint x, BigUint y, bool wantSub, bool *sign) static BigUint addOrSub(scope BigUint x, scope BigUint y, bool wantSub, bool *sign)
pure nothrow @safe pure nothrow @safe
{ {
BigUint r; BigUint r;
@ -858,7 +858,7 @@ public:
/* return x * y. /* return x * y.
*/ */
static BigUint mul(BigUint x, BigUint y) pure nothrow @safe static BigUint mul(scope BigUint x, scope BigUint y) pure nothrow @safe
{ {
if (y == 0 || x == 0) if (y == 0 || x == 0)
return BigUint(ZERO); return BigUint(ZERO);
@ -879,7 +879,7 @@ public:
} }
// return x / y // return x / y
static BigUint divInt(T)(BigUint x, T y_) pure nothrow @safe static BigUint divInt(T)(scope return BigUint x, T y_) pure nothrow @safe
if ( is(immutable T == immutable uint) ) if ( is(immutable T == immutable uint) )
{ {
uint y = y_; uint y = y_;
@ -905,7 +905,7 @@ public:
return BigUint(removeLeadingZeros(trustedAssumeUnique(result))); return BigUint(removeLeadingZeros(trustedAssumeUnique(result)));
} }
static BigUint divInt(T)(BigUint x, T y) pure nothrow @safe static BigUint divInt(T)(scope BigUint x, T y) pure nothrow @safe
if ( is(immutable T == immutable ulong) ) if ( is(immutable T == immutable ulong) )
{ {
if (y <= uint.max) if (y <= uint.max)
@ -921,7 +921,7 @@ public:
} }
// return x % y // return x % y
static uint modInt(T)(BigUint x, T y_) pure if ( is(immutable T == immutable uint) ) static uint modInt(T)(scope BigUint x, T y_) pure if ( is(immutable T == immutable uint) )
{ {
import core.memory : GC; import core.memory : GC;
uint y = y_; uint y = y_;
@ -942,7 +942,7 @@ public:
} }
// return x / y // return x / y
static BigUint div(BigUint x, BigUint y) pure nothrow @safe static BigUint div(scope return BigUint x, scope BigUint y) pure nothrow @safe
{ {
if (y.data.length > x.data.length) if (y.data.length > x.data.length)
return BigUint(ZERO); return BigUint(ZERO);
@ -954,7 +954,7 @@ public:
} }
// return x % y // return x % y
static BigUint mod(BigUint x, BigUint y) pure nothrow @safe static BigUint mod(scope return BigUint x, scope BigUint y) pure nothrow @safe
{ {
if (y.data.length > x.data.length) return x; if (y.data.length > x.data.length) return x;
if (y.data.length == 1) if (y.data.length == 1)
@ -968,8 +968,10 @@ public:
} }
// Return x / y in quotient, x % y in remainder // Return x / y in quotient, x % y in remainder
static void divMod(BigUint x, BigUint y, out BigUint quotient, out BigUint remainder) pure nothrow @safe static void divMod(BigUint x, scope BigUint y,
out BigUint quotient, out BigUint remainder) pure nothrow @safe
{ {
/* TODO Qualify parameter `x` as `return` when it applies to `out` parameters */
if (y.data.length > x.data.length) if (y.data.length > x.data.length)
{ {
quotient = 0uL; quotient = 0uL;
@ -991,7 +993,7 @@ public:
} }
// return x op y // return x op y
static BigUint bitwiseOp(string op)(BigUint x, BigUint y, bool xSign, bool ySign, ref bool resultSign) static BigUint bitwiseOp(string op)(scope BigUint x, scope BigUint y, bool xSign, bool ySign, ref bool resultSign)
pure nothrow @safe if (op == "|" || op == "^" || op == "&") pure nothrow @safe if (op == "|" || op == "^" || op == "&")
{ {
auto d1 = includeSign(x.data, y.uintLength, xSign); auto d1 = includeSign(x.data, y.uintLength, xSign);
@ -1018,7 +1020,7 @@ public:
* exponentiation is used. * exponentiation is used.
* Memory allocation is minimized: at most one temporary BigUint is used. * Memory allocation is minimized: at most one temporary BigUint is used.
*/ */
static BigUint pow(BigUint x, ulong y) pure nothrow @safe static BigUint pow(scope return BigUint x, ulong y) pure nothrow @safe
{ {
// Deal with the degenerate cases first. // Deal with the degenerate cases first.
if (y == 0) return BigUint(ONE); if (y == 0) return BigUint(ONE);
@ -1226,7 +1228,7 @@ public:
} }
// Implement toHash so that BigUint works properly as an AA key. // Implement toHash so that BigUint works properly as an AA key.
size_t toHash() const @nogc nothrow pure @safe size_t toHash() const @nogc nothrow pure @safe scope
{ {
return .hashOf(data); return .hashOf(data);
} }
@ -1257,7 +1259,7 @@ public:
} }
// Remove leading zeros from x, to restore the BigUint invariant // Remove leading zeros from x, to restore the BigUint invariant
inout(BigDigit) [] removeLeadingZeros(inout(BigDigit) [] x) pure nothrow @safe inout(BigDigit) [] removeLeadingZeros(scope return inout(BigDigit) [] x) pure nothrow @safe
{ {
size_t k = x.length; size_t k = x.length;
while (k>1 && x[k - 1]==0) --k; while (k>1 && x[k - 1]==0) --k;
@ -1915,7 +1917,7 @@ private:
// every 8 digits. // every 8 digits.
// buff.length must be data.length*8 if separator is zero, // buff.length must be data.length*8 if separator is zero,
// or data.length*9 if separator is non-zero. It will be completely filled. // or data.length*9 if separator is non-zero. It will be completely filled.
char [] biguintToHex(char [] buff, const BigDigit [] data, char separator=0, char [] biguintToHex(scope return char [] buff, const scope BigDigit [] data, char separator=0,
LetterCase letterCase = LetterCase.upper) pure nothrow @safe LetterCase letterCase = LetterCase.upper) pure nothrow @safe
{ {
int x=0; int x=0;