aboutsummaryrefslogtreecommitdiff
path: root/libphobos/src/std
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2023-01-29 21:06:59 +0100
committerIain Buclaw <ibuclaw@gdcproject.org>2023-02-21 15:33:38 +0100
commitf99303eb4aafef70075951731b3ad99266fe6225 (patch)
tree582ebb6e3e8fd966732bc3b92da1a63caad1aca7 /libphobos/src/std
parent7e9dd9de169034810b92d47bf78284db731fa5da (diff)
downloadgcc-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.d5
-rw-r--r--libphobos/src/std/conv.d6
-rw-r--r--libphobos/src/std/math/exponential.d399
-rw-r--r--libphobos/src/std/math/operations.d2
-rw-r--r--libphobos/src/std/numeric.d2
-rw-r--r--libphobos/src/std/parallelism.d13
-rw-r--r--libphobos/src/std/random.d14
-rw-r--r--libphobos/src/std/regex/package.d2
-rw-r--r--libphobos/src/std/typecons.d26
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