diff options
author | Iain Buclaw <ibuclaw@gdcproject.org> | 2023-01-29 21:06:59 +0100 |
---|---|---|
committer | Iain Buclaw <ibuclaw@gdcproject.org> | 2023-02-21 15:33:38 +0100 |
commit | f99303eb4aafef70075951731b3ad99266fe6225 (patch) | |
tree | 582ebb6e3e8fd966732bc3b92da1a63caad1aca7 /libphobos/src/std | |
parent | 7e9dd9de169034810b92d47bf78284db731fa5da (diff) | |
download | gcc-f99303eb4aafef70075951731b3ad99266fe6225.zip gcc-f99303eb4aafef70075951731b3ad99266fe6225.tar.gz gcc-f99303eb4aafef70075951731b3ad99266fe6225.tar.bz2 |
d: Merge upstream dmd, druntime 09faa4eacd, phobos 13ef27a56.
D front-end changes:
- Import dmd v2.102.0-beta.1
- `static assert' now supports multiple message arguments.
D runtime changes:
- Import druntime v2.102.0-beta.1
- The default `Throwable.TraceInfo' generation now is `@nogc'.
- `Object.factory' method has now been deprecated.
Phobos changes:
- Import phobos v2.102.0-beta.1
- Added float- and double-precision implementations for log
function families in std.math.
- `std.typecons.Unique' now calls `destroy` on struct types
gcc/d/ChangeLog:
* Make-lang.in (D_FRONTEND_OBJS): Add d/location.o.
* d-lang.cc (d_init_options): Update for new front-end interface.
(d_post_options): Call Loc::set after handling options.
* dmd/MERGE: Merge upstream dmd 09faa4eacd.
* dmd/VERSION: Bump version to v2.102.0-beta.1.
libphobos/ChangeLog:
* libdruntime/MERGE: Merge upstream druntime 09faa4eacd.
* src/MERGE: Merge upstream phobos 13ef27a56.
* testsuite/libphobos.exceptions/refcounted.d: Add test for chained
reference counted exceptions.
* testsuite/libphobos.shared/finalize.d: Add dg-warning for deprecated
factory interfaces.
* testsuite/libphobos.gc/issue22843.d: New test.
gcc/testsuite/ChangeLog:
* gdc.dg/simd2a.d: Update.
* gdc.dg/simd2b.d: Update.
* gdc.dg/simd2c.d: Update.
* gdc.dg/simd2d.d: Update.
* gdc.dg/simd2e.d: Update.
* gdc.dg/simd2f.d: Update.
* gdc.dg/simd2g.d: Update.
* gdc.dg/simd2h.d: Update.
* gdc.dg/simd2i.d: Update.
* gdc.dg/simd2j.d: Update.
Diffstat (limited to 'libphobos/src/std')
-rw-r--r-- | libphobos/src/std/algorithm/iteration.d | 5 | ||||
-rw-r--r-- | libphobos/src/std/conv.d | 6 | ||||
-rw-r--r-- | libphobos/src/std/math/exponential.d | 399 | ||||
-rw-r--r-- | libphobos/src/std/math/operations.d | 2 | ||||
-rw-r--r-- | libphobos/src/std/numeric.d | 2 | ||||
-rw-r--r-- | libphobos/src/std/parallelism.d | 13 | ||||
-rw-r--r-- | libphobos/src/std/random.d | 14 | ||||
-rw-r--r-- | libphobos/src/std/regex/package.d | 2 | ||||
-rw-r--r-- | libphobos/src/std/typecons.d | 26 |
9 files changed, 374 insertions, 95 deletions
diff --git a/libphobos/src/std/algorithm/iteration.d b/libphobos/src/std/algorithm/iteration.d index 9a365d5..967d2a6 100644 --- a/libphobos/src/std/algorithm/iteration.d +++ b/libphobos/src/std/algorithm/iteration.d @@ -7737,8 +7737,9 @@ if (isInputRange!R && // uniq /** -Lazily iterates unique consecutive elements of the given range (functionality -akin to the $(HTTP wikipedia.org/wiki/_Uniq, _uniq) system +Lazily iterates unique consecutive elements of the given range, which is +assumed to be sorted (functionality akin to the +$(HTTP wikipedia.org/wiki/_Uniq, _uniq) system utility). Equivalence of elements is assessed by using the predicate `pred`, by default `"a == b"`. The predicate is passed to $(REF binaryFun, std,functional), and can either accept a string, or any callable diff --git a/libphobos/src/std/conv.d b/libphobos/src/std/conv.d index d1b6421..aef2365 100644 --- a/libphobos/src/std/conv.d +++ b/libphobos/src/std/conv.d @@ -1891,9 +1891,7 @@ if (!is(S : T) && isAssociativeArray!S && } // test conversions floating => integral { - // AllInts[0 .. $ - 1] should be AllInts - // @@@ BUG IN COMPILER @@@ - foreach (Integral; AllInts[0 .. $ - 1]) + foreach (Integral; AllInts) { foreach (Floating; AllFloats) { @@ -1903,7 +1901,7 @@ if (!is(S : T) && isAssociativeArray!S && } // test conversion integral => floating { - foreach (Integral; AllInts[0 .. $ - 1]) + foreach (Integral; AllInts) { foreach (Floating; AllFloats) { diff --git a/libphobos/src/std/math/exponential.d b/libphobos/src/std/math/exponential.d index e32330f..66f4b8a 100644 --- a/libphobos/src/std/math/exponential.d +++ b/libphobos/src/std/math/exponential.d @@ -2910,7 +2910,7 @@ private alias log10P = logP; alias log10Q = logQ; - // Coefficients for log(x) = z + z^^3 P(z^^2)/Q(z^^2) + // Coefficients for log(x) = z + z^^3 R(z^^2)/S(z^^2) // where z = 2(x-1)/(x+1) // Theoretical peak relative error = 1.1e-35 static immutable real[6] logR = [ @@ -2931,7 +2931,8 @@ private 1.0 ]; } - else + else static if (floatTraits!T.realFormat == RealFormat.ieeeExtended || + floatTraits!T.realFormat == RealFormat.ieeeExtended53) { // Coefficients for log(1 + x) = x - x^^2/2 + x^^3 P(x)/Q(x) // Theoretical peak relative error = 2.32e-20 @@ -2980,7 +2981,7 @@ private alias log10P = log2P; alias log10Q = log2Q; - // Coefficients for log(x) = z + z^^3 P(z^^2)/Q(z^^2) + // Coefficients for log(x) = z + z^^3 R(z^^2)/S(z^^2) // where z = 2(x-1)/(x+1) // Theoretical peak relative error = 6.16e-22 static immutable real[4] logR = [ @@ -2996,6 +2997,85 @@ private 1.0000000000000000000000E0L, ]; } + else static if (floatTraits!T.realFormat == RealFormat.ieeeDouble) + { + // Coefficients for log(1 + x) = x - x^^2/2 + x^^3 P(x)/Q(x) + static immutable double[6] logP = [ + 7.70838733755885391666E0, + 1.79368678507819816313E1, + 1.44989225341610930846E1, + 4.70579119878881725854E0, + 4.97494994976747001425E-1, + 1.01875663804580931796E-4, + ]; + static immutable double[6] logQ = [ + 2.31251620126765340583E1, + 7.11544750618563894466E1, + 8.29875266912776603211E1, + 4.52279145837532221105E1, + 1.12873587189167450590E1, + 1.00000000000000000000E0, + ]; + + // log2 uses the same coefficients as log. + alias log2P = logP; + alias log2Q = logQ; + + // Coefficients for log(1 + x) = x - x^^2/2 + x^^3 P(x)/Q(x) + static immutable double[7] log10P = [ + 1.98892446572874072159E1, + 5.67349287391754285487E1, + 6.06127134467767258030E1, + 2.97877425097986925891E1, + 6.56312093769992875930E0, + 4.98531067254050724270E-1, + 4.58482948458143443514E-5, + ]; + static immutable double[7] log10Q = [ + 5.96677339718622216300E1, + 2.14955586696422947765E2, + 3.07254189979530058263E2, + 2.20664384982121929218E2, + 8.27410449222435217021E1, + 1.50314182634250003249E1, + 1.00000000000000000000E0, + ]; + + // Coefficients for log(x) = z + z^^3 R(z)/S(z) + // where z = 2(x-1)/(x+1) + static immutable double[3] logR = [ + -6.41409952958715622951E1, + 1.63866645699558079767E1, + -7.89580278884799154124E-1, + ]; + static immutable double[4] logS = [ + -7.69691943550460008604E2, + 3.12093766372244180303E2, + -3.56722798256324312549E1, + 1.00000000000000000000E0, + ]; + } + else static if (floatTraits!T.realFormat == RealFormat.ieeeSingle) + { + // Coefficients for log(1 + x) = x - x^^2/2 + x^^3 P(x) + static immutable float[9] logP = [ + 3.3333331174E-1, + -2.4999993993E-1, + 2.0000714765E-1, + -1.6668057665E-1, + 1.4249322787E-1, + -1.2420140846E-1, + 1.1676998740E-1, + -1.1514610310E-1, + 7.0376836292E-2, + ]; + + // log2 and log10 uses the same coefficients as log. + alias log2P = logP; + alias log10P = logP; + } + else + static assert(0, "no coefficients for log()"); } } @@ -3009,6 +3089,7 @@ private * $(TR $(TD +$(INFIN)) $(TD +$(INFIN)) $(TD no) $(TD no)) * ) */ +pragma(inline, true) real log(real x) @safe pure nothrow @nogc { version (INLINE_YL2X) @@ -3020,6 +3101,31 @@ real log(real x) @safe pure nothrow @nogc return logImpl(x); } +/// ditto +pragma(inline, true) +double log(double x) @safe pure nothrow @nogc { return __ctfe ? cast(double) log(cast(real) x) : logImpl(x); } + +/// ditto +pragma(inline, true) +float log(float x) @safe pure nothrow @nogc { return __ctfe ? cast(float) log(cast(real) x) : logImpl(x); } + +// @@@DEPRECATED_[2.112.0]@@@ +deprecated("`std.math.exponential.log` called with argument types `(int)` matches both " + ~ "`log(real)`, `log(double)`, and `log(float)`. Cast argument to floating point type instead.") +real log(int x) @safe pure nothrow @nogc { return log(cast(real) x); } +// @@@DEPRECATED_[2.112.0]@@@ +deprecated("`std.math.exponential.log` called with argument types `(uint)` matches both " + ~ "`log(real)`, `log(double)`, and `log(float)`. Cast argument to floating point type instead.") +real log(uint x) @safe pure nothrow @nogc { return log(cast(real) x); } +// @@@DEPRECATED_[2.112.0]@@@ +deprecated("`std.math.exponential.log` called with argument types `(long)` matches both " + ~ "`log(real)`, `log(double)`, and `log(float)`. Cast argument to floating point type instead.") +real log(long x) @safe pure nothrow @nogc { return log(cast(real) x); } +// @@@DEPRECATED_[2.112.0]@@@ +deprecated("`std.math.exponential.log` called with argument types `(ulong)` matches both " + ~ "`log(real)`, `log(double)`, and `log(float)`. Cast argument to floating point type instead.") +real log(ulong x) @safe pure nothrow @nogc { return log(cast(real) x); } + /// @safe pure nothrow @nogc unittest { @@ -3034,12 +3140,31 @@ private T logImpl(T)(T x) @safe pure nothrow @nogc import std.math.constants : SQRT1_2; import std.math.algebraic : poly; import std.math.traits : isInfinity, isNaN, signbit; + import std.math : floatTraits, RealFormat; alias coeffs = LogCoeffs!T; + alias F = floatTraits!T; - // C1 + C2 = LN2. - enum T C1 = 6.93145751953125E-1L; - enum T C2 = 1.428606820309417232121458176568075500134E-6L; + static if (F.realFormat == RealFormat.ieeeExtended || + F.realFormat == RealFormat.ieeeExtended53 || + F.realFormat == RealFormat.ieeeQuadruple) + { + // C1 + C2 = LN2. + enum T C1 = 6.93145751953125E-1L; + enum T C2 = 1.428606820309417232121458176568075500134E-6L; + } + else static if (F.realFormat == RealFormat.ieeeDouble) + { + enum T C1 = 0.693359375; + enum T C2 = -2.121944400546905827679e-4; + } + else static if (F.realFormat == RealFormat.ieeeSingle) + { + enum T C1 = 0.693359375; + enum T C2 = -2.12194440e-4; + } + else + static assert(0, "Not implemented for this architecture"); // Special cases. if (isNaN(x)) @@ -3058,30 +3183,36 @@ private T logImpl(T)(T x) @safe pure nothrow @nogc x = frexp(x, exp); - // Logarithm using log(x) = z + z^^3 R(z) / S(z), - // where z = 2(x - 1)/(x + 1) - if ((exp > 2) || (exp < -2)) + static if (F.realFormat == RealFormat.ieeeDouble || + F.realFormat == RealFormat.ieeeExtended || + F.realFormat == RealFormat.ieeeExtended53 || + F.realFormat == RealFormat.ieeeQuadruple) { - if (x < SQRT1_2) - { // 2(2x - 1)/(2x + 1) - exp -= 1; - z = x - 0.5; - y = 0.5 * z + 0.5; - } - else - { // 2(x - 1)/(x + 1) - z = x - 0.5; - z -= 0.5; - y = 0.5 * x + 0.5; - } - x = z / y; - z = x * x; - z = x * (z * poly(z, coeffs.logR) / poly(z, coeffs.logS)); - z += exp * C2; - z += x; - z += exp * C1; + // Logarithm using log(x) = z + z^^3 R(z) / S(z), + // where z = 2(x - 1)/(x + 1) + if ((exp > 2) || (exp < -2)) + { + if (x < SQRT1_2) + { // 2(2x - 1)/(2x + 1) + exp -= 1; + z = x - 0.5; + y = 0.5 * z + 0.5; + } + else + { // 2(x - 1)/(x + 1) + z = x - 0.5; + z -= 0.5; + y = 0.5 * x + 0.5; + } + x = z / y; + z = x * x; + z = x * (z * poly(z, coeffs.logR) / poly(z, coeffs.logS)); + z += exp * C2; + z += x; + z += exp * C1; - return z; + return z; + } } // Logarithm using log(1 + x) = x - .5x^^2 + x^^3 P(x) / Q(x) @@ -3095,7 +3226,10 @@ private T logImpl(T)(T x) @safe pure nothrow @nogc x = x - 1.0; } z = x * x; - y = x * (z * poly(x, coeffs.logP) / poly(x, coeffs.logQ)); + static if (F.realFormat == RealFormat.ieeeSingle) + y = x * (z * poly(x, coeffs.logP)); + else + y = x * (z * poly(x, coeffs.logP) / poly(x, coeffs.logQ)); y += exp * C2; z = y - 0.5 * z; @@ -3117,6 +3251,7 @@ private T logImpl(T)(T x) @safe pure nothrow @nogc * $(TR $(TD +$(INFIN)) $(TD +$(INFIN)) $(TD no) $(TD no)) * ) */ +pragma(inline, true) real log10(real x) @safe pure nothrow @nogc { version (INLINE_YL2X) @@ -3128,12 +3263,37 @@ real log10(real x) @safe pure nothrow @nogc return log10Impl(x); } +/// ditto +pragma(inline, true) +double log10(double x) @safe pure nothrow @nogc { return __ctfe ? cast(double) log10(cast(real) x) : log10Impl(x); } + +/// ditto +pragma(inline, true) +float log10(float x) @safe pure nothrow @nogc { return __ctfe ? cast(float) log10(cast(real) x) : log10Impl(x); } + +// @@@DEPRECATED_[2.112.0]@@@ +deprecated("`std.math.exponential.log10` called with argument types `(int)` matches both " + ~ "`log10(real)`, `log10(double)`, and `log10(float)`. Cast argument to floating point type instead.") +real log10(int x) @safe pure nothrow @nogc { return log10(cast(real) x); } +// @@@DEPRECATED_[2.112.0]@@@ +deprecated("`std.math.exponential.log10` called with argument types `(uint)` matches both " + ~ "`log10(real)`, `log10(double)`, and `log10(float)`. Cast argument to floating point type instead.") +real log10(uint x) @safe pure nothrow @nogc { return log10(cast(real) x); } +// @@@DEPRECATED_[2.112.0]@@@ +deprecated("`std.math.exponential.log10` called with argument types `(long)` matches both " + ~ "`log10(real)`, `log10(double)`, and `log10(float)`. Cast argument to floating point type instead.") +real log10(long x) @safe pure nothrow @nogc { return log10(cast(real) x); } +// @@@DEPRECATED_[2.112.0]@@@ +deprecated("`std.math.exponential.log10` called with argument types `(ulong)` matches both " + ~ "`log10(real)`, `log10(double)`, and `log10(float)`. Cast argument to floating point type instead.") +real log10(ulong x) @safe pure nothrow @nogc { return log10(cast(real) x); } + /// @safe pure nothrow @nogc unittest { import std.math.algebraic : fabs; - assert(fabs(log10(1000) - 3) < .000001); + assert(fabs(log10(1000.0L) - 3) < .000001); } private T log10Impl(T)(T x) @safe pure nothrow @nogc @@ -3141,16 +3301,34 @@ private T log10Impl(T)(T x) @safe pure nothrow @nogc import std.math.constants : SQRT1_2; import std.math.algebraic : poly; import std.math.traits : isNaN, isInfinity, signbit; + import std.math : floatTraits, RealFormat; alias coeffs = LogCoeffs!T; + alias F = floatTraits!T; - // log10(2) split into two parts. - enum T L102A = 0.3125L; - enum T L102B = -1.14700043360188047862611052755069732318101185E-2L; + static if (F.realFormat == RealFormat.ieeeExtended || + F.realFormat == RealFormat.ieeeExtended53 || + F.realFormat == RealFormat.ieeeQuadruple) + { + // log10(2) split into two parts. + enum T L102A = 0.3125L; + enum T L102B = -1.14700043360188047862611052755069732318101185E-2L; - // log10(e) split into two parts. - enum T L10EA = 0.5L; - enum T L10EB = -6.570551809674817234887108108339491770560299E-2L; + // log10(e) split into two parts. + enum T L10EA = 0.5L; + enum T L10EB = -6.570551809674817234887108108339491770560299E-2L; + } + else static if (F.realFormat == RealFormat.ieeeDouble || + F.realFormat == RealFormat.ieeeSingle) + { + enum T L102A = 3.0078125E-1; + enum T L102B = 2.48745663981195213739E-4; + + enum T L10EA = 4.3359375E-1; + enum T L10EB = 7.00731903251827651129E-4; + } + else + static assert(0, "Not implemented for this architecture"); // Special cases are the same as for log. if (isNaN(x)) @@ -3169,26 +3347,31 @@ private T log10Impl(T)(T x) @safe pure nothrow @nogc x = frexp(x, exp); - // Logarithm using log(x) = z + z^^3 R(z) / S(z), - // where z = 2(x - 1)/(x + 1) - if ((exp > 2) || (exp < -2)) - { - if (x < SQRT1_2) - { // 2(2x - 1)/(2x + 1) - exp -= 1; - z = x - 0.5; - y = 0.5 * z + 0.5; - } - else - { // 2(x - 1)/(x + 1) - z = x - 0.5; - z -= 0.5; - y = 0.5 * x + 0.5; + static if (F.realFormat == RealFormat.ieeeExtended || + F.realFormat == RealFormat.ieeeExtended53 || + F.realFormat == RealFormat.ieeeQuadruple) + { + // Logarithm using log(x) = z + z^^3 R(z) / S(z), + // where z = 2(x - 1)/(x + 1) + if ((exp > 2) || (exp < -2)) + { + if (x < SQRT1_2) + { // 2(2x - 1)/(2x + 1) + exp -= 1; + z = x - 0.5; + y = 0.5 * z + 0.5; + } + else + { // 2(x - 1)/(x + 1) + z = x - 0.5; + z -= 0.5; + y = 0.5 * x + 0.5; + } + x = z / y; + z = x * x; + y = x * (z * poly(z, coeffs.logR) / poly(z, coeffs.logS)); + goto Ldone; } - x = z / y; - z = x * x; - y = x * (z * poly(z, coeffs.logR) / poly(z, coeffs.logS)); - goto Ldone; } // Logarithm using log(1 + x) = x - .5x^^2 + x^^3 P(x) / Q(x) @@ -3201,7 +3384,10 @@ private T log10Impl(T)(T x) @safe pure nothrow @nogc x = x - 1.0; z = x * x; - y = x * (z * poly(x, coeffs.log10P) / poly(x, coeffs.log10Q)); + static if (F.realFormat == RealFormat.ieeeSingle) + y = x * (z * poly(x, coeffs.log10P)); + else + y = x * (z * poly(x, coeffs.log10P) / poly(x, coeffs.log10Q)); y = y - 0.5 * z; // Multiply log of fraction by log10(e) and base 2 exponent by log10(2). @@ -3232,6 +3418,7 @@ Ldone: * $(TR $(TD +$(INFIN)) $(TD +$(INFIN)) $(TD no) $(TD no)) * ) */ +pragma(inline, true) real log1p(real x) @safe pure nothrow @nogc { version (INLINE_YL2X) @@ -3245,6 +3432,31 @@ real log1p(real x) @safe pure nothrow @nogc return log1pImpl(x); } +/// ditto +pragma(inline, true) +double log1p(double x) @safe pure nothrow @nogc { return __ctfe ? cast(double) log1p(cast(real) x) : log1pImpl(x); } + +/// ditto +pragma(inline, true) +float log1p(float x) @safe pure nothrow @nogc { return __ctfe ? cast(float) log1p(cast(real) x) : log1pImpl(x); } + +// @@@DEPRECATED_[2.112.0]@@@ +deprecated("`std.math.exponential.log1p` called with argument types `(int)` matches both " + ~ "`log1p(real)`, `log1p(double)`, and `log1p(float)`. Cast argument to floating point type instead.") +real log1p(int x) @safe pure nothrow @nogc { return log1p(cast(real) x); } +// @@@DEPRECATED_[2.112.0]@@@ +deprecated("`std.math.exponential.log1p` called with argument types `(uint)` matches both " + ~ "`log1p(real)`, `log1p(double)`, and `log1p(float)`. Cast argument to floating point type instead.") +real log1p(uint x) @safe pure nothrow @nogc { return log1p(cast(real) x); } +// @@@DEPRECATED_[2.112.0]@@@ +deprecated("`std.math.exponential.log1p` called with argument types `(long)` matches both " + ~ "`log1p(real)`, `log1p(double)`, and `log1p(float)`. Cast argument to floating point type instead.") +real log1p(long x) @safe pure nothrow @nogc { return log1p(cast(real) x); } +// @@@DEPRECATED_[2.112.0]@@@ +deprecated("`std.math.exponential.log1p` called with argument types `(ulong)` matches both " + ~ "`log1p(real)`, `log1p(double)`, and `log1p(float)`. Cast argument to floating point type instead.") +real log1p(ulong x) @safe pure nothrow @nogc { return log1p(cast(real) x); } + /// @safe pure unittest { @@ -3289,6 +3501,7 @@ private T log1pImpl(T)(T x) @safe pure nothrow @nogc * $(TR $(TD +$(INFIN)) $(TD +$(INFIN)) $(TD no) $(TD no) ) * ) */ +pragma(inline, true) real log2(real x) @safe pure nothrow @nogc { version (INLINE_YL2X) @@ -3297,6 +3510,31 @@ real log2(real x) @safe pure nothrow @nogc return log2Impl(x); } +/// ditto +pragma(inline, true) +double log2(double x) @safe pure nothrow @nogc { return __ctfe ? cast(double) log2(cast(real) x) : log2Impl(x); } + +/// ditto +pragma(inline, true) +float log2(float x) @safe pure nothrow @nogc { return __ctfe ? cast(float) log2(cast(real) x) : log2Impl(x); } + +// @@@DEPRECATED_[2.112.0]@@@ +deprecated("`std.math.exponential.log2` called with argument types `(int)` matches both " + ~ "`log2(real)`, `log2(double)`, and `log2(float)`. Cast argument to floating point type instead.") +real log2(int x) @safe pure nothrow @nogc { return log2(cast(real) x); } +// @@@DEPRECATED_[2.112.0]@@@ +deprecated("`std.math.exponential.log2` called with argument types `(uint)` matches both " + ~ "`log2(real)`, `log2(double)`, and `log2(float)`. Cast argument to floating point type instead.") +real log2(uint x) @safe pure nothrow @nogc { return log2(cast(real) x); } +// @@@DEPRECATED_[2.112.0]@@@ +deprecated("`std.math.exponential.log2` called with argument types `(long)` matches both " + ~ "`log2(real)`, `log2(double)`, and `log2(float)`. Cast argument to floating point type instead.") +real log2(long x) @safe pure nothrow @nogc { return log2(cast(real) x); } +// @@@DEPRECATED_[2.112.0]@@@ +deprecated("`std.math.exponential.log2` called with argument types `(ulong)` matches both " + ~ "`log2(real)`, `log2(double)`, and `log2(float)`. Cast argument to floating point type instead.") +real log2(ulong x) @safe pure nothrow @nogc { return log2(cast(real) x); } + /// @safe unittest { @@ -3318,8 +3556,10 @@ private T log2Impl(T)(T x) @safe pure nothrow @nogc import std.math.traits : isNaN, isInfinity, signbit; import std.math.constants : SQRT1_2, LOG2E; import std.math.algebraic : poly; + import std.math : floatTraits, RealFormat; alias coeffs = LogCoeffs!T; + alias F = floatTraits!T; // Special cases are the same as for log. if (isNaN(x)) @@ -3338,26 +3578,32 @@ private T log2Impl(T)(T x) @safe pure nothrow @nogc x = frexp(x, exp); - // Logarithm using log(x) = z + z^^3 R(z) / S(z), - // where z = 2(x - 1)/(x + 1) - if ((exp > 2) || (exp < -2)) + static if (F.realFormat == RealFormat.ieeeDouble || + F.realFormat == RealFormat.ieeeExtended || + F.realFormat == RealFormat.ieeeExtended53 || + F.realFormat == RealFormat.ieeeQuadruple) { - if (x < SQRT1_2) - { // 2(2x - 1)/(2x + 1) - exp -= 1; - z = x - 0.5; - y = 0.5 * z + 0.5; - } - else - { // 2(x - 1)/(x + 1) - z = x - 0.5; - z -= 0.5; - y = 0.5 * x + 0.5; + // Logarithm using log(x) = z + z^^3 R(z) / S(z), + // where z = 2(x - 1)/(x + 1) + if ((exp > 2) || (exp < -2)) + { + if (x < SQRT1_2) + { // 2(2x - 1)/(2x + 1) + exp -= 1; + z = x - 0.5; + y = 0.5 * z + 0.5; + } + else + { // 2(x - 1)/(x + 1) + z = x - 0.5; + z -= 0.5; + y = 0.5 * x + 0.5; + } + x = z / y; + z = x * x; + y = x * (z * poly(z, coeffs.logR) / poly(z, coeffs.logS)); + goto Ldone; } - x = z / y; - z = x * x; - y = x * (z * poly(z, coeffs.logR) / poly(z, coeffs.logS)); - goto Ldone; } // Logarithm using log(1 + x) = x - .5x^^2 + x^^3 P(x) / Q(x) @@ -3370,7 +3616,10 @@ private T log2Impl(T)(T x) @safe pure nothrow @nogc x = x - 1.0; z = x * x; - y = x * (z * poly(x, coeffs.log2P) / poly(x, coeffs.log2Q)); + static if (F.realFormat == RealFormat.ieeeSingle) + y = x * (z * poly(x, coeffs.log2P)); + else + y = x * (z * poly(x, coeffs.log2P) / poly(x, coeffs.log2Q)); y = y - 0.5 * z; // Multiply log of fraction by log10(e) and base 2 exponent by log10(2). diff --git a/libphobos/src/std/math/operations.d b/libphobos/src/std/math/operations.d index cb3c805..f2e1800 100644 --- a/libphobos/src/std/math/operations.d +++ b/libphobos/src/std/math/operations.d @@ -1793,7 +1793,7 @@ if (isFloatingPoint!T) } import std.math.exponential : log2; - enum log2_max_exp = cast(int) log2(T.max_exp); + enum log2_max_exp = cast(int) log2(T(T.max_exp)); ret.mantissa = ival & ((1L << (T.mant_dig - 1)) - 1); ret.exponent = (ival >> (T.mant_dig - 1)) & ((1L << (log2_max_exp + 1)) - 1); diff --git a/libphobos/src/std/numeric.d b/libphobos/src/std/numeric.d index df7ac39..648b70e 100644 --- a/libphobos/src/std/numeric.d +++ b/libphobos/src/std/numeric.d @@ -436,7 +436,7 @@ public: static @property size_t dig() { auto shiftcnt = precision - ((flags&Flags.storeNormalized) == 0); - return shiftcnt == 64 ? 19 : cast(size_t) log10(1uL << shiftcnt); + return shiftcnt == 64 ? 19 : cast(size_t) log10(real(1uL << shiftcnt)); } /// Returns: smallest increment to the value 1 diff --git a/libphobos/src/std/parallelism.d b/libphobos/src/std/parallelism.d index 2c97638..9b231f3 100644 --- a/libphobos/src/std/parallelism.d +++ b/libphobos/src/std/parallelism.d @@ -1508,7 +1508,7 @@ public: if (this.size == 0) { - return rangeLen; + return max(rangeLen, 1); } immutable size_t eightSize = 4 * (this.size + 1); @@ -3644,6 +3644,15 @@ ParallelForeach!R parallel(R)(R range, size_t workUnitSize) assert(arrIndex.sum == 10.iota.sum); } +// https://issues.dlang.org/show_bug.cgi?id=22745 +@system unittest +{ + auto pool = new TaskPool(0); + int[] empty; + foreach (i; pool.parallel(empty)) {} + pool.finish(); +} + // Thrown when a parallel foreach loop is broken from. class ParallelForeachError : Error { @@ -4339,7 +4348,7 @@ version (StdUnittest) foreach (i, elem; logs) { - assert(isClose(elem, cast(double) log(i + 1))); + assert(isClose(elem, log(double(i + 1)))); } assert(poolInstance.amap!"a * a"([1,2,3,4,5]) == [1,4,9,16,25]); diff --git a/libphobos/src/std/random.d b/libphobos/src/std/random.d index 9b3c5ed..93be764 100644 --- a/libphobos/src/std/random.d +++ b/libphobos/src/std/random.d @@ -2516,7 +2516,7 @@ if (!is(T == enum) && (isIntegral!T || isSomeChar!T)) assert(rnd.uniform!ulong == 4838462006927449017); enum Fruit { apple, mango, pear } - version (X86_64) // https://issues.dlang.org/show_bug.cgi?id=15147 + version (D_LP64) // https://issues.dlang.org/show_bug.cgi?id=15147 assert(rnd.uniform!Fruit == Fruit.mango); } @@ -2798,7 +2798,7 @@ auto ref choice(Range)(ref Range range) auto rnd = MinstdRand0(42); auto elem = [1, 2, 3, 4, 5].choice(rnd); - version (X86_64) // https://issues.dlang.org/show_bug.cgi?id=15147 + version (D_LP64) // https://issues.dlang.org/show_bug.cgi?id=15147 assert(elem == 3); } @@ -2913,7 +2913,7 @@ if (isRandomAccessRange!Range) auto rnd = MinstdRand0(42); auto arr = [1, 2, 3, 4, 5].randomShuffle(rnd); - version (X86_64) // https://issues.dlang.org/show_bug.cgi?id=15147 + version (D_LP64) // https://issues.dlang.org/show_bug.cgi?id=15147 assert(arr == [3, 5, 2, 4, 1]); } @@ -3003,15 +3003,15 @@ if (isRandomAccessRange!Range) auto arr = [1, 2, 3, 4, 5, 6]; arr = arr.dup.partialShuffle(1, rnd); - version (X86_64) // https://issues.dlang.org/show_bug.cgi?id=15147 + version (D_LP64) // https://issues.dlang.org/show_bug.cgi?id=15147 assert(arr == [2, 1, 3, 4, 5, 6]); // 1<->2 arr = arr.dup.partialShuffle(2, rnd); - version (X86_64) // https://issues.dlang.org/show_bug.cgi?id=15147 + version (D_LP64) // https://issues.dlang.org/show_bug.cgi?id=15147 assert(arr == [1, 4, 3, 2, 5, 6]); // 1<->2, 2<->4 arr = arr.dup.partialShuffle(3, rnd); - version (X86_64) // https://issues.dlang.org/show_bug.cgi?id=15147 + version (D_LP64) // https://issues.dlang.org/show_bug.cgi?id=15147 assert(arr == [5, 4, 6, 2, 1, 3]); // 1<->5, 2<->4, 3<->6 } @@ -3428,7 +3428,7 @@ if (isRandomAccessRange!Range) import std.range : iota; auto rnd = MinstdRand0(42); - version (X86_64) // https://issues.dlang.org/show_bug.cgi?id=15147 + version (D_LP64) // https://issues.dlang.org/show_bug.cgi?id=15147 assert(10.iota.randomCover(rnd).equal([7, 4, 2, 0, 1, 6, 8, 3, 9, 5])); } diff --git a/libphobos/src/std/regex/package.d b/libphobos/src/std/regex/package.d index 1562d79..d6a01e2 100644 --- a/libphobos/src/std/regex/package.d +++ b/libphobos/src/std/regex/package.d @@ -212,7 +212,7 @@ They met on 24/01/1970. names work like aliases in addition to direct numbers. ) $(REG_TITLE Assertions, Match position rather than character ) - $(REG_ROW ^, Matches at the begining of input or line (in multiline mode).) + $(REG_ROW ^, Matches at the beginning of input or line (in multiline mode).) $(REG_ROW $, Matches at the end of input or line (in multiline mode). ) $(REG_ROW \b, Matches at word boundary. ) $(REG_ROW \B, Matches when $(U not) at word boundary. ) diff --git a/libphobos/src/std/typecons.d b/libphobos/src/std/typecons.d index e83b6171..25cf9e0 100644 --- a/libphobos/src/std/typecons.d +++ b/libphobos/src/std/typecons.d @@ -225,7 +225,10 @@ public: { if (_p !is null) { - destroy(_p); + static if (is(T == class) || is(T == interface)) + destroy(_p); + else + destroy(*_p); _p = null; } } @@ -259,7 +262,7 @@ private: /// @safe unittest { - static struct S + struct S { int i; this(int i){this.i = i;} @@ -284,6 +287,7 @@ private: Unique!S u1; assert(u1.isEmpty); u1 = produce(); + assert(u1.i == 5); increment(u1); assert(u1.i == 6); //consume(u1); // Error: u1 is not copyable @@ -292,6 +296,24 @@ private: assert(u1.isEmpty); } +@safe unittest +{ + int i; + struct S + { + ~this() + { + // check context pointer still exists - dtor also called before GC frees struct + if (this.tupleof[0]) + i++; + } + } + { + Unique!S u = new S; + } + assert(i == 1); +} + @system unittest { // test conversion to base ref |