aboutsummaryrefslogtreecommitdiff
path: root/libphobos/src/std
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2024-01-18 02:39:20 +0100
committerIain Buclaw <ibuclaw@gdcproject.org>2024-02-03 00:49:46 +0100
commitf204359931866b917856fc959c70dbf55f28c14d (patch)
treeba1c671045e384fa49a6381f79abf7c1b84a55ea /libphobos/src/std
parent5470a9b176c2b3030ff3891c7e9403db2b0685b8 (diff)
downloadgcc-f204359931866b917856fc959c70dbf55f28c14d.zip
gcc-f204359931866b917856fc959c70dbf55f28c14d.tar.gz
gcc-f204359931866b917856fc959c70dbf55f28c14d.tar.bz2
d: Merge dmd, druntime bce5c1f7b5, phobos e4d0dd513.
D front-end changes: - Import latest changes from dmd v2.107.0-beta.1. - Keywords like `__FILE__' are now always evaluated at the callsite. D runtime changes: - Import latest changes from druntime v2.107.0-beta.1. - Added `nameSig' field to TypeInfo_Class in object.d. Phobos changes: - Import latest changes from phobos v2.107.0-beta.1. gcc/d/ChangeLog: * dmd/MERGE: Merge upstream dmd bce5c1f7b5. * d-attribs.cc (build_attributes): Update for new front-end interface. * d-lang.cc (d_parse_file): Likewise. * decl.cc (DeclVisitor::visit (VarDeclaration *)): Likewise. * expr.cc (build_lambda_tree): New function. (ExprVisitor::visit (FuncExp *)): Use build_lambda_tree. (ExprVisitor::visit (SymOffExp *)): Likewise. (ExprVisitor::visit (VarExp *)): Likewise. * typeinfo.cc (create_tinfo_types): Add two ulong fields to internal TypeInfo representation. (TypeInfoVisitor::visit (TypeInfoClassDeclaration *)): Emit stub data for TypeInfo_Class.nameSig. (TypeInfoVisitor::visit (TypeInfoStructDeclaration *)): Update for new front-end interface. libphobos/ChangeLog: * libdruntime/MERGE: Merge upstream druntime bce5c1f7b5. * src/MERGE: Merge upstream phobos e4d0dd513.
Diffstat (limited to 'libphobos/src/std')
-rw-r--r--libphobos/src/std/bitmanip.d4
-rw-r--r--libphobos/src/std/complex.d2
-rw-r--r--libphobos/src/std/conv.d8
-rw-r--r--libphobos/src/std/exception.d6
-rw-r--r--libphobos/src/std/format/internal/floats.d14
-rw-r--r--libphobos/src/std/format/internal/write.d7
-rw-r--r--libphobos/src/std/math/algebraic.d2
-rw-r--r--libphobos/src/std/math/exponential.d44
-rw-r--r--libphobos/src/std/math/hardware.d8
-rw-r--r--libphobos/src/std/math/operations.d21
-rw-r--r--libphobos/src/std/math/package.d166
-rw-r--r--libphobos/src/std/math/rounding.d4
-rw-r--r--libphobos/src/std/math/traits.d179
-rw-r--r--libphobos/src/std/math/trigonometry.d5
-rw-r--r--libphobos/src/std/mmfile.d68
-rw-r--r--libphobos/src/std/regex/internal/backtracking.d2
-rw-r--r--libphobos/src/std/regex/internal/ir.d4
-rw-r--r--libphobos/src/std/typecons.d56
18 files changed, 322 insertions, 278 deletions
diff --git a/libphobos/src/std/bitmanip.d b/libphobos/src/std/bitmanip.d
index b84a676..e9f6191 100644
--- a/libphobos/src/std/bitmanip.d
+++ b/libphobos/src/std/bitmanip.d
@@ -279,10 +279,8 @@ See_Also: $(REF BitFlags, std,typecons)
*/
string bitfields(T...)()
{
- import std.conv : to;
-
static assert(T.length % 3 == 0,
- "Wrong number of arguments (" ~ to!string(T.length) ~ "): Must be a multiple of 3");
+ "Wrong number of arguments (" ~ T.length.stringof ~ "): Must be a multiple of 3");
static foreach (i, ARG; T)
{
diff --git a/libphobos/src/std/complex.d b/libphobos/src/std/complex.d
index 347e351..60746f9 100644
--- a/libphobos/src/std/complex.d
+++ b/libphobos/src/std/complex.d
@@ -1892,7 +1892,7 @@ Complex!T pow(T)(const T x, Complex!T n) @trusted pure nothrow @nogc
@safe pure nothrow @nogc unittest
{
import std.meta : AliasSeq;
- import std.math : RealFormat, floatTraits;
+ import std.math.traits : floatTraits, RealFormat;
static foreach (T; AliasSeq!(float, double, real))
{{
static if (floatTraits!T.realFormat == RealFormat.ibmExtended)
diff --git a/libphobos/src/std/conv.d b/libphobos/src/std/conv.d
index 23b33c4..5d02df0 100644
--- a/libphobos/src/std/conv.d
+++ b/libphobos/src/std/conv.d
@@ -1804,7 +1804,7 @@ if (!is(S : T) && isAssociativeArray!S &&
}
static void testFloatingToIntegral(Floating, Integral)()
{
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
bool convFails(Source, Target, E)(Source src)
{
@@ -3430,7 +3430,7 @@ if (isFloatingPoint!Target && !is(Target == enum) &&
Target result = cast(Target) (sign ? -ldval : ldval);
// if overflow occurred
- import std.math : isFinite;
+ import std.math.traits : isFinite;
enforce(isFinite(result), new ConvException("Range error"));
advanceSource();
@@ -3598,7 +3598,7 @@ if (isFloatingPoint!Target && !is(Target == enum) &&
@system unittest
{
// @system because strtod is not @safe.
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
static if (floatTraits!real.realFormat == RealFormat.ieeeDouble)
{
@@ -3682,7 +3682,7 @@ if (isFloatingPoint!Target && !is(Target == enum) &&
{
import core.stdc.errno;
import core.stdc.stdlib;
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
errno = 0; // In case it was set by another unittest in a different module.
struct longdouble
diff --git a/libphobos/src/std/exception.d b/libphobos/src/std/exception.d
index 5c78685..58a667c 100644
--- a/libphobos/src/std/exception.d
+++ b/libphobos/src/std/exception.d
@@ -1632,6 +1632,9 @@ class ErrnoException : Exception
/// Operating system error code.
final @property uint errno() nothrow pure scope @nogc @safe { return _errno; }
private uint _errno;
+ /// Localized error message generated through $(REF strerror_r, core,stdc,string) or $(REF strerror, core,stdc,string).
+ final @property string errnoMsg() nothrow pure scope @nogc @safe { return _errnoMsg; }
+ private string _errnoMsg;
/// Constructor which takes an error message. The current global $(REF errno, core,stdc,errno) value is used as error code.
this(string msg, string file = null, size_t line = 0) @safe
{
@@ -1642,7 +1645,8 @@ class ErrnoException : Exception
this(string msg, int errno, string file = null, size_t line = 0) @safe
{
_errno = errno;
- super(msg ~ " (" ~ errnoString(errno) ~ ")", file, line);
+ _errnoMsg = errnoString(errno);
+ super(msg ~ " (" ~ errnoMsg ~ ")", file, line);
}
}
diff --git a/libphobos/src/std/format/internal/floats.d b/libphobos/src/std/format/internal/floats.d
index afe0bfa..88b9d22 100644
--- a/libphobos/src/std/format/internal/floats.d
+++ b/libphobos/src/std/format/internal/floats.d
@@ -28,6 +28,15 @@ if (is(T == float) || is(T == double)
return w.data;
}
+/// Returns: whether `c` is a supported format specifier for floats
+package(std.format) bool isFloatSpec(char c) nothrow @nogc pure @safe
+{
+ return c == 'a' || c == 'A'
+ || c == 'e' || c == 'E'
+ || c == 'f' || c == 'F'
+ || c == 'g' || c == 'G';
+}
+
package(std.format) void printFloat(Writer, T, Char)(auto ref Writer w, const(T) val, FormatSpec!Char f)
if (is(T == float) || is(T == double)
|| (is(T == real) && (T.mant_dig == double.mant_dig || T.mant_dig == 64)))
@@ -43,10 +52,7 @@ if (is(T == float) || is(T == double)
if (sgn == "" && f.flPlus) sgn = "+";
if (sgn == "" && f.flSpace) sgn = " ";
- assert(f.spec == 'a' || f.spec == 'A'
- || f.spec == 'e' || f.spec == 'E'
- || f.spec == 'f' || f.spec == 'F'
- || f.spec == 'g' || f.spec == 'G', "unsupported format specifier");
+ assert(isFloatSpec(f.spec), "unsupported format specifier");
bool is_upper = f.spec == 'A' || f.spec == 'E' || f.spec=='F' || f.spec=='G';
// special treatment for nan and inf
diff --git a/libphobos/src/std/format/internal/write.d b/libphobos/src/std/format/internal/write.d
index 85954fa..16c7a51 100644
--- a/libphobos/src/std/format/internal/write.d
+++ b/libphobos/src/std/format/internal/write.d
@@ -570,9 +570,9 @@ void formatValueImpl(Writer, T, Char)(auto ref Writer w, const(T) obj,
scope const ref FormatSpec!Char f)
if (is(FloatingPointTypeOf!T) && !is(T == enum) && !hasToString!(T, Char))
{
- import std.algorithm.searching : find;
import std.format : enforceFmt;
import std.range.primitives : put;
+ import std.format.internal.floats : printFloat, isFloatSpec;
FloatingPointTypeOf!T val = obj;
const char spec = f.spec;
@@ -597,11 +597,9 @@ if (is(FloatingPointTypeOf!T) && !is(T == enum) && !hasToString!(T, Char))
return;
}
- enforceFmt(find("fgFGaAeEs", spec).length,
- "incompatible format character for floating point argument: %" ~ spec);
-
FormatSpec!Char fs = f; // fs is copy for change its values.
fs.spec = spec == 's' ? 'g' : spec;
+ enforceFmt(isFloatSpec(fs.spec), "incompatible format character for floating point argument: %" ~ spec);
static if (is(T == float) || is(T == double)
|| (is(T == real) && (T.mant_dig == double.mant_dig || T.mant_dig == 64)))
@@ -631,7 +629,6 @@ if (is(FloatingPointTypeOf!T) && !is(T == enum) && !hasToString!(T, Char))
tval = -doubleLowest;
}
- import std.format.internal.floats : printFloat;
printFloat(w, tval, fs);
}
diff --git a/libphobos/src/std/math/algebraic.d b/libphobos/src/std/math/algebraic.d
index 9999071..fd30523 100644
--- a/libphobos/src/std/math/algebraic.d
+++ b/libphobos/src/std/math/algebraic.d
@@ -308,7 +308,7 @@ if (isFloatingPoint!T)
// If both are huge, avoid overflow by scaling by 2^^-N.
// If both are tiny, avoid underflow by scaling by 2^^N.
import core.math : fabs, sqrt;
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
alias F = floatTraits!T;
diff --git a/libphobos/src/std/math/exponential.d b/libphobos/src/std/math/exponential.d
index 8290479..5e90f0d 100644
--- a/libphobos/src/std/math/exponential.d
+++ b/libphobos/src/std/math/exponential.d
@@ -1002,8 +1002,7 @@ float exp(float x) @safe pure nothrow @nogc { return __ctfe ? cast(float) exp(ca
private T expImpl(T)(T x) @safe pure nothrow @nogc
{
- import std.math : floatTraits, RealFormat;
- import std.math.traits : isNaN;
+ import std.math.traits : floatTraits, RealFormat, isNaN;
import std.math.rounding : floor;
import std.math.algebraic : poly;
import std.math.constants : LOG2E;
@@ -1143,7 +1142,7 @@ private T expImpl(T)(T x) @safe pure nothrow @nogc
@safe @nogc nothrow unittest
{
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
import std.math.operations : NaN, feqrel, isClose;
import std.math.constants : E;
import std.math.traits : isIdentical;
@@ -1517,7 +1516,7 @@ L_largenegative:
private T expm1Impl(T)(T x) @safe pure nothrow @nogc
{
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
import std.math.rounding : floor;
import std.math.algebraic : poly;
import std.math.constants : LN2;
@@ -1909,8 +1908,7 @@ L_was_nan:
private T exp2Impl(T)(T x) @nogc @safe pure nothrow
{
- import std.math : floatTraits, RealFormat;
- import std.math.traits : isNaN;
+ import std.math.traits : floatTraits, RealFormat, isNaN;
import std.math.rounding : floor;
import std.math.algebraic : poly;
@@ -2098,8 +2096,7 @@ private T exp2Impl(T)(T x) @nogc @safe pure nothrow
T frexp(T)(const T value, out int exp) @trusted pure nothrow @nogc
if (isFloatingPoint!T)
{
- import std.math : floatTraits, RealFormat, MANTISSA_MSB, MANTISSA_LSB;
- import std.math.traits : isSubnormal;
+ import std.math.traits : floatTraits, RealFormat, MANTISSA_MSB, MANTISSA_LSB, isSubnormal;
if (__ctfe)
{
@@ -2353,8 +2350,7 @@ if (isFloatingPoint!T)
@safe unittest
{
- import std.math : floatTraits, RealFormat;
- import std.math.traits : isIdentical;
+ import std.math.traits : floatTraits, RealFormat, isIdentical;
import std.meta : AliasSeq;
import std.typecons : tuple, Tuple;
@@ -2486,7 +2482,7 @@ if (isFloatingPoint!T)
int ilogb(T)(const T x) @trusted pure nothrow @nogc
if (isFloatingPoint!T)
{
- import std.math : floatTraits, RealFormat, MANTISSA_MSB, MANTISSA_LSB;
+ import std.math.traits : floatTraits, RealFormat, MANTISSA_MSB, MANTISSA_LSB;
import core.bitop : bsr;
alias F = floatTraits!T;
@@ -2681,7 +2677,7 @@ alias FP_ILOGBNAN = core.stdc.math.FP_ILOGBNAN;
@safe nothrow @nogc unittest
{
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
import std.math.operations : nextUp;
import std.meta : AliasSeq;
import std.typecons : Tuple;
@@ -2778,7 +2774,7 @@ float ldexp(float n, int exp) @safe pure nothrow @nogc { return core.math.ldex
@safe pure nothrow @nogc unittest
{
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
static if (floatTraits!(real).realFormat == RealFormat.ieeeExtended ||
floatTraits!(real).realFormat == RealFormat.ieeeExtended53 ||
@@ -2866,7 +2862,7 @@ private
// Coefficients shared across log(), log2(), log10(), log1p().
template LogCoeffs(T)
{
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
static if (floatTraits!T.realFormat == RealFormat.ieeeQuadruple)
{
@@ -3179,8 +3175,7 @@ private T logImpl(T, bool LOG1P = false)(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;
+ import std.math.traits : isInfinity, isNaN, signbit, floatTraits, RealFormat;
alias coeffs = LogCoeffs!T;
alias F = floatTraits!T;
@@ -3306,7 +3301,7 @@ private T logImpl(T, bool LOG1P = false)(T x) @safe pure nothrow @nogc
@safe @nogc nothrow unittest
{
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
import std.meta : AliasSeq;
static void testLog(T)(T[2][] vals)
@@ -3452,8 +3447,7 @@ 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;
+ import std.math.traits : isNaN, isInfinity, signbit, floatTraits, RealFormat;
alias coeffs = LogCoeffs!T;
alias F = floatTraits!T;
@@ -3558,7 +3552,7 @@ Ldone:
@safe @nogc nothrow unittest
{
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
import std.meta : AliasSeq;
static void testLog10(T)(T[2][] vals)
@@ -3710,7 +3704,7 @@ private T log1pImpl(T)(T x) @safe pure nothrow @nogc
import std.math.traits : isNaN, isInfinity, signbit;
import std.math.algebraic : poly;
import std.math.constants : SQRT1_2, SQRT2;
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
// Special cases.
if (isNaN(x) || x == 0.0)
@@ -3746,7 +3740,7 @@ private T log1pImpl(T)(T x) @safe pure nothrow @nogc
@safe @nogc nothrow unittest
{
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
import std.meta : AliasSeq;
static void testLog1p(T)(T[2][] vals)
@@ -3891,7 +3885,7 @@ 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;
+ import std.math.traits : floatTraits, RealFormat;
alias coeffs = LogCoeffs!T;
alias F = floatTraits!T;
@@ -3972,7 +3966,7 @@ Ldone:
@safe @nogc nothrow unittest
{
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
import std.meta : AliasSeq;
static void testLog2(T)(T[2][] vals)
@@ -4172,7 +4166,7 @@ private T logbImpl(T)(T x) @trusted pure nothrow @nogc
@safe @nogc nothrow unittest
{
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
import std.meta : AliasSeq;
static void testLogb(T)(T[2][] vals)
diff --git a/libphobos/src/std/math/hardware.d b/libphobos/src/std/math/hardware.d
index cb6cb87..c7c5d6e 100644
--- a/libphobos/src/std/math/hardware.d
+++ b/libphobos/src/std/math/hardware.d
@@ -210,14 +210,12 @@ private:
}
else version (RISCV_Any)
{
- mixin(`
uint result = void;
asm pure nothrow @nogc
{
"frflags %0" : "=r" (result);
}
return result;
- `);
}
else version (LoongArch_Any)
{
@@ -307,13 +305,11 @@ private:
}
else version (RISCV_Any)
{
- mixin(`
uint newValues = 0x0;
asm pure nothrow @nogc
{
"fsflags %0" : : "r" (newValues);
}
- `);
}
else version (LoongArch_Any)
{
@@ -1039,14 +1035,12 @@ private:
}
else version (RISCV_Any)
{
- mixin(`
ControlState cont;
asm pure nothrow @nogc
{
"frcsr %0" : "=r" (cont);
}
return cont;
- `);
}
else version (LoongArch_Any)
{
@@ -1163,12 +1157,10 @@ private:
}
else version (RISCV_Any)
{
- mixin(`
asm pure nothrow @nogc
{
"fscsr %0" : : "r" (newState);
}
- `);
}
else version (LoongArch_Any)
{
diff --git a/libphobos/src/std/math/operations.d b/libphobos/src/std/math/operations.d
index 4bf19ee..d456e29 100644
--- a/libphobos/src/std/math/operations.d
+++ b/libphobos/src/std/math/operations.d
@@ -44,7 +44,7 @@ import std.traits : CommonType, isFloatingPoint, isIntegral, Unqual;
*/
real NaN(ulong payload) @trusted pure nothrow @nogc
{
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
alias F = floatTraits!(real);
static if (F.realFormat == RealFormat.ieeeExtended ||
@@ -136,7 +136,7 @@ real NaN(ulong payload) @trusted pure nothrow @nogc
@system pure nothrow @nogc unittest // not @safe because taking address of local.
{
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
static if (floatTraits!(real).realFormat == RealFormat.ieeeDouble)
{
@@ -159,7 +159,7 @@ real NaN(ulong payload) @trusted pure nothrow @nogc
*/
ulong getNaNPayload(real x) @trusted pure nothrow @nogc
{
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
// assert(isNaN(x));
alias F = floatTraits!(real);
@@ -283,7 +283,7 @@ debug(UnitTest)
*/
real nextUp(real x) @trusted pure nothrow @nogc
{
- import std.math : floatTraits, RealFormat, MANTISSA_MSB, MANTISSA_LSB;
+ import std.math.traits : floatTraits, RealFormat, MANTISSA_MSB, MANTISSA_LSB;
alias F = floatTraits!(real);
static if (F.realFormat != RealFormat.ieeeDouble)
@@ -522,8 +522,7 @@ float nextDown(float x) @safe pure nothrow @nogc
@safe pure nothrow @nogc unittest
{
- import std.math : floatTraits, RealFormat;
- import std.math.traits : isIdentical;
+ import std.math.traits : floatTraits, RealFormat, isIdentical;
static if (floatTraits!(real).realFormat == RealFormat.ieeeExtended ||
floatTraits!(real).realFormat == RealFormat.ieeeDouble ||
@@ -865,7 +864,7 @@ real fma(real x, real y, real z) @safe pure nothrow @nogc { return (x * y) + z;
int feqrel(X)(const X x, const X y) @trusted pure nothrow @nogc
if (isFloatingPoint!(X))
{
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
import core.math : fabs;
/* Public Domain. Author: Don Clugston, 18 Aug 2005.
@@ -1495,7 +1494,7 @@ private template FloatingPointBaseType(T)
int cmp(T)(const(T) x, const(T) y) @nogc @trusted pure nothrow
if (isFloatingPoint!T)
{
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
alias F = floatTraits!T;
@@ -1723,7 +1722,7 @@ if (isFloatingPoint!T)
FloatingPointBitpattern!T extractBitpattern(T)(const(T) value) @trusted
if (isFloatingPoint!T)
{
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
T val = value;
FloatingPointBitpattern!T ret;
@@ -1895,7 +1894,7 @@ if (isFloatingPoint!T)
@safe pure unittest
{
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
alias F = floatTraits!real;
static if (F.realFormat == RealFormat.ieeeExtended)
@@ -1946,7 +1945,7 @@ if (isFloatingPoint!T)
@safe pure unittest
{
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
import std.math.exponential : log2;
alias F = floatTraits!real;
diff --git a/libphobos/src/std/math/package.d b/libphobos/src/std/math/package.d
index 614f4d3..0d1ecc3 100644
--- a/libphobos/src/std/math/package.d
+++ b/libphobos/src/std/math/package.d
@@ -321,169 +321,3 @@ else
static assert(real.mant_dig == 53 || real.mant_dig == 113,
"Only 64-bit and 128-bit reals are supported for BigEndian CPUs.");
}
-
-// Underlying format exposed through floatTraits
-enum RealFormat
-{
- ieeeHalf,
- ieeeSingle,
- ieeeDouble,
- ieeeExtended, // x87 80-bit real
- ieeeExtended53, // x87 real rounded to precision of double.
- ibmExtended, // IBM 128-bit extended
- ieeeQuadruple,
-}
-
-// Constants used for extracting the components of the representation.
-// They supplement the built-in floating point properties.
-template floatTraits(T)
-{
- import std.traits : Unqual;
-
- // EXPMASK is a ushort mask to select the exponent portion (without sign)
- // EXPSHIFT is the number of bits the exponent is left-shifted by in its ushort
- // EXPBIAS is the exponent bias - 1 (exp == EXPBIAS yields ×2^-1).
- // EXPPOS_SHORT is the index of the exponent when represented as a ushort array.
- // SIGNPOS_BYTE is the index of the sign when represented as a ubyte array.
- // RECIP_EPSILON is the value such that (smallest_subnormal) * RECIP_EPSILON == T.min_normal
- enum Unqual!T RECIP_EPSILON = (1/T.epsilon);
- static if (T.mant_dig == 24)
- {
- // Single precision float
- enum ushort EXPMASK = 0x7F80;
- enum ushort EXPSHIFT = 7;
- enum ushort EXPBIAS = 0x3F00;
- enum uint EXPMASK_INT = 0x7F80_0000;
- enum uint MANTISSAMASK_INT = 0x007F_FFFF;
- enum realFormat = RealFormat.ieeeSingle;
- version (LittleEndian)
- {
- enum EXPPOS_SHORT = 1;
- enum SIGNPOS_BYTE = 3;
- }
- else
- {
- enum EXPPOS_SHORT = 0;
- enum SIGNPOS_BYTE = 0;
- }
- }
- else static if (T.mant_dig == 53)
- {
- static if (T.sizeof == 8)
- {
- // Double precision float, or real == double
- enum ushort EXPMASK = 0x7FF0;
- enum ushort EXPSHIFT = 4;
- enum ushort EXPBIAS = 0x3FE0;
- enum uint EXPMASK_INT = 0x7FF0_0000;
- enum uint MANTISSAMASK_INT = 0x000F_FFFF; // for the MSB only
- enum ulong MANTISSAMASK_LONG = 0x000F_FFFF_FFFF_FFFF;
- enum realFormat = RealFormat.ieeeDouble;
- version (LittleEndian)
- {
- enum EXPPOS_SHORT = 3;
- enum SIGNPOS_BYTE = 7;
- }
- else
- {
- enum EXPPOS_SHORT = 0;
- enum SIGNPOS_BYTE = 0;
- }
- }
- else static if (T.sizeof == 12)
- {
- // Intel extended real80 rounded to double
- enum ushort EXPMASK = 0x7FFF;
- enum ushort EXPSHIFT = 0;
- enum ushort EXPBIAS = 0x3FFE;
- enum realFormat = RealFormat.ieeeExtended53;
- version (LittleEndian)
- {
- enum EXPPOS_SHORT = 4;
- enum SIGNPOS_BYTE = 9;
- }
- else
- {
- enum EXPPOS_SHORT = 0;
- enum SIGNPOS_BYTE = 0;
- }
- }
- else
- static assert(false, "No traits support for " ~ T.stringof);
- }
- else static if (T.mant_dig == 64)
- {
- // Intel extended real80
- enum ushort EXPMASK = 0x7FFF;
- enum ushort EXPSHIFT = 0;
- enum ushort EXPBIAS = 0x3FFE;
- enum realFormat = RealFormat.ieeeExtended;
- version (LittleEndian)
- {
- enum EXPPOS_SHORT = 4;
- enum SIGNPOS_BYTE = 9;
- }
- else
- {
- enum EXPPOS_SHORT = 0;
- enum SIGNPOS_BYTE = 0;
- }
- }
- else static if (T.mant_dig == 113)
- {
- // Quadruple precision float
- enum ushort EXPMASK = 0x7FFF;
- enum ushort EXPSHIFT = 0;
- enum ushort EXPBIAS = 0x3FFE;
- enum realFormat = RealFormat.ieeeQuadruple;
- version (LittleEndian)
- {
- enum EXPPOS_SHORT = 7;
- enum SIGNPOS_BYTE = 15;
- }
- else
- {
- enum EXPPOS_SHORT = 0;
- enum SIGNPOS_BYTE = 0;
- }
- }
- else static if (T.mant_dig == 106)
- {
- // IBM Extended doubledouble
- enum ushort EXPMASK = 0x7FF0;
- enum ushort EXPSHIFT = 4;
- enum realFormat = RealFormat.ibmExtended;
-
- // For IBM doubledouble the larger magnitude double comes first.
- // It's really a double[2] and arrays don't index differently
- // between little and big-endian targets.
- enum DOUBLEPAIR_MSB = 0;
- enum DOUBLEPAIR_LSB = 1;
-
- // The exponent/sign byte is for most significant part.
- version (LittleEndian)
- {
- enum EXPPOS_SHORT = 3;
- enum SIGNPOS_BYTE = 7;
- }
- else
- {
- enum EXPPOS_SHORT = 0;
- enum SIGNPOS_BYTE = 0;
- }
- }
- else
- static assert(false, "No traits support for " ~ T.stringof);
-}
-
-// These apply to all floating-point types
-version (LittleEndian)
-{
- enum MANTISSA_LSB = 0;
- enum MANTISSA_MSB = 1;
-}
-else
-{
- enum MANTISSA_LSB = 1;
- enum MANTISSA_MSB = 0;
-}
diff --git a/libphobos/src/std/math/rounding.d b/libphobos/src/std/math/rounding.d
index 7dbe89b..f6654fc 100644
--- a/libphobos/src/std/math/rounding.d
+++ b/libphobos/src/std/math/rounding.d
@@ -551,7 +551,7 @@ long lrint(real x) @trusted pure nothrow @nogc
}
else
{
- import std.math : floatTraits, RealFormat, MANTISSA_MSB, MANTISSA_LSB;
+ import std.math.traits : floatTraits, RealFormat, MANTISSA_MSB, MANTISSA_LSB;
alias F = floatTraits!(real);
static if (F.realFormat == RealFormat.ieeeDouble)
@@ -896,7 +896,7 @@ long rndtol(float x) @safe pure nothrow @nogc { return rndtol(cast(real) x); }
// Helper for floor/ceil
T floorImpl(T)(const T x) @trusted pure nothrow @nogc
{
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
alias F = floatTraits!(T);
// Take care not to trigger library calls from the compiler,
diff --git a/libphobos/src/std/math/traits.d b/libphobos/src/std/math/traits.d
index 2841bad..81ab1b7 100644
--- a/libphobos/src/std/math/traits.d
+++ b/libphobos/src/std/math/traits.d
@@ -137,7 +137,7 @@ if (isFloatingPoint!(X))
*/
bool isFinite(X)(X x) @trusted pure nothrow @nogc
{
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
static if (__traits(isFloating, X))
if (__ctfe)
@@ -202,7 +202,7 @@ bool isFinite(X)(X x) @trusted pure nothrow @nogc
*/
bool isNormal(X)(X x) @trusted pure nothrow @nogc
{
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
static if (__traits(isFloating, X))
if (__ctfe)
@@ -264,7 +264,7 @@ bool isNormal(X)(X x) @trusted pure nothrow @nogc
*/
bool isSubnormal(X)(X x) @trusted pure nothrow @nogc
{
- import std.math : floatTraits, RealFormat, MANTISSA_MSB, MANTISSA_LSB;
+ import std.math.traits : floatTraits, RealFormat, MANTISSA_MSB, MANTISSA_LSB;
static if (__traits(isFloating, X))
if (__ctfe)
@@ -344,7 +344,7 @@ bool isSubnormal(X)(X x) @trusted pure nothrow @nogc
bool isInfinity(X)(X x) @nogc @trusted pure nothrow
if (isFloatingPoint!(X))
{
- import std.math : floatTraits, RealFormat, MANTISSA_MSB, MANTISSA_LSB;
+ import std.math.traits : floatTraits, RealFormat, MANTISSA_MSB, MANTISSA_LSB;
alias F = floatTraits!(X);
static if (F.realFormat == RealFormat.ieeeSingle)
@@ -466,7 +466,7 @@ if (isFloatingPoint!(X))
*/
bool isIdentical(real x, real y) @trusted pure nothrow @nogc
{
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
// We're doing a bitwise comparison so the endianness is irrelevant.
long* pxs = cast(long *)&x;
@@ -510,7 +510,7 @@ bool isIdentical(real x, real y) @trusted pure nothrow @nogc
*/
int signbit(X)(X x) @nogc @trusted pure nothrow
{
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
if (__ctfe)
{
@@ -594,7 +594,7 @@ Returns:
R copysign(R, X)(R to, X from) @trusted pure nothrow @nogc
if (isFloatingPoint!(R) && isFloatingPoint!(X))
{
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
if (__ctfe)
{
@@ -851,3 +851,168 @@ if (isNumeric!X)
}}
}
+// Underlying format exposed through floatTraits
+enum RealFormat
+{
+ ieeeHalf,
+ ieeeSingle,
+ ieeeDouble,
+ ieeeExtended, // x87 80-bit real
+ ieeeExtended53, // x87 real rounded to precision of double.
+ ibmExtended, // IBM 128-bit extended
+ ieeeQuadruple,
+}
+
+// Constants used for extracting the components of the representation.
+// They supplement the built-in floating point properties.
+template floatTraits(T)
+{
+ import std.traits : Unqual;
+
+ // EXPMASK is a ushort mask to select the exponent portion (without sign)
+ // EXPSHIFT is the number of bits the exponent is left-shifted by in its ushort
+ // EXPBIAS is the exponent bias - 1 (exp == EXPBIAS yields ×2^-1).
+ // EXPPOS_SHORT is the index of the exponent when represented as a ushort array.
+ // SIGNPOS_BYTE is the index of the sign when represented as a ubyte array.
+ // RECIP_EPSILON is the value such that (smallest_subnormal) * RECIP_EPSILON == T.min_normal
+ enum Unqual!T RECIP_EPSILON = (1/T.epsilon);
+ static if (T.mant_dig == 24)
+ {
+ // Single precision float
+ enum ushort EXPMASK = 0x7F80;
+ enum ushort EXPSHIFT = 7;
+ enum ushort EXPBIAS = 0x3F00;
+ enum uint EXPMASK_INT = 0x7F80_0000;
+ enum uint MANTISSAMASK_INT = 0x007F_FFFF;
+ enum realFormat = RealFormat.ieeeSingle;
+ version (LittleEndian)
+ {
+ enum EXPPOS_SHORT = 1;
+ enum SIGNPOS_BYTE = 3;
+ }
+ else
+ {
+ enum EXPPOS_SHORT = 0;
+ enum SIGNPOS_BYTE = 0;
+ }
+ }
+ else static if (T.mant_dig == 53)
+ {
+ static if (T.sizeof == 8)
+ {
+ // Double precision float, or real == double
+ enum ushort EXPMASK = 0x7FF0;
+ enum ushort EXPSHIFT = 4;
+ enum ushort EXPBIAS = 0x3FE0;
+ enum uint EXPMASK_INT = 0x7FF0_0000;
+ enum uint MANTISSAMASK_INT = 0x000F_FFFF; // for the MSB only
+ enum ulong MANTISSAMASK_LONG = 0x000F_FFFF_FFFF_FFFF;
+ enum realFormat = RealFormat.ieeeDouble;
+ version (LittleEndian)
+ {
+ enum EXPPOS_SHORT = 3;
+ enum SIGNPOS_BYTE = 7;
+ }
+ else
+ {
+ enum EXPPOS_SHORT = 0;
+ enum SIGNPOS_BYTE = 0;
+ }
+ }
+ else static if (T.sizeof == 12)
+ {
+ // Intel extended real80 rounded to double
+ enum ushort EXPMASK = 0x7FFF;
+ enum ushort EXPSHIFT = 0;
+ enum ushort EXPBIAS = 0x3FFE;
+ enum realFormat = RealFormat.ieeeExtended53;
+ version (LittleEndian)
+ {
+ enum EXPPOS_SHORT = 4;
+ enum SIGNPOS_BYTE = 9;
+ }
+ else
+ {
+ enum EXPPOS_SHORT = 0;
+ enum SIGNPOS_BYTE = 0;
+ }
+ }
+ else
+ static assert(false, "No traits support for " ~ T.stringof);
+ }
+ else static if (T.mant_dig == 64)
+ {
+ // Intel extended real80
+ enum ushort EXPMASK = 0x7FFF;
+ enum ushort EXPSHIFT = 0;
+ enum ushort EXPBIAS = 0x3FFE;
+ enum realFormat = RealFormat.ieeeExtended;
+ version (LittleEndian)
+ {
+ enum EXPPOS_SHORT = 4;
+ enum SIGNPOS_BYTE = 9;
+ }
+ else
+ {
+ enum EXPPOS_SHORT = 0;
+ enum SIGNPOS_BYTE = 0;
+ }
+ }
+ else static if (T.mant_dig == 113)
+ {
+ // Quadruple precision float
+ enum ushort EXPMASK = 0x7FFF;
+ enum ushort EXPSHIFT = 0;
+ enum ushort EXPBIAS = 0x3FFE;
+ enum realFormat = RealFormat.ieeeQuadruple;
+ version (LittleEndian)
+ {
+ enum EXPPOS_SHORT = 7;
+ enum SIGNPOS_BYTE = 15;
+ }
+ else
+ {
+ enum EXPPOS_SHORT = 0;
+ enum SIGNPOS_BYTE = 0;
+ }
+ }
+ else static if (T.mant_dig == 106)
+ {
+ // IBM Extended doubledouble
+ enum ushort EXPMASK = 0x7FF0;
+ enum ushort EXPSHIFT = 4;
+ enum realFormat = RealFormat.ibmExtended;
+
+ // For IBM doubledouble the larger magnitude double comes first.
+ // It's really a double[2] and arrays don't index differently
+ // between little and big-endian targets.
+ enum DOUBLEPAIR_MSB = 0;
+ enum DOUBLEPAIR_LSB = 1;
+
+ // The exponent/sign byte is for most significant part.
+ version (LittleEndian)
+ {
+ enum EXPPOS_SHORT = 3;
+ enum SIGNPOS_BYTE = 7;
+ }
+ else
+ {
+ enum EXPPOS_SHORT = 0;
+ enum SIGNPOS_BYTE = 0;
+ }
+ }
+ else
+ static assert(false, "No traits support for " ~ T.stringof);
+}
+
+// These apply to all floating-point types
+version (LittleEndian)
+{
+ enum MANTISSA_LSB = 0;
+ enum MANTISSA_MSB = 1;
+}
+else
+{
+ enum MANTISSA_LSB = 1;
+ enum MANTISSA_MSB = 0;
+}
diff --git a/libphobos/src/std/math/trigonometry.d b/libphobos/src/std/math/trigonometry.d
index a3d04c6..4f5f5c5 100644
--- a/libphobos/src/std/math/trigonometry.d
+++ b/libphobos/src/std/math/trigonometry.d
@@ -307,7 +307,7 @@ Lret:
private T tanImpl(T)(T x) @safe pure nothrow @nogc
{
- import std.math : floatTraits, RealFormat;
+ import std.math.traits : floatTraits, RealFormat;
import std.math.constants : PI, PI_4;
import std.math.rounding : floor;
import std.math.algebraic : poly;
@@ -675,8 +675,7 @@ float atan(float x) @safe pure nothrow @nogc { return __ctfe ? cast(float) atan(
private T atanImpl(T)(T x) @safe pure nothrow @nogc
{
- import std.math : floatTraits, RealFormat;
- import std.math.traits : copysign, isInfinity, signbit;
+ import std.math.traits : floatTraits, RealFormat, copysign, isInfinity, signbit;
import std.math.constants : PI_2, PI_4;
import std.math.algebraic : poly;
diff --git a/libphobos/src/std/mmfile.d b/libphobos/src/std/mmfile.d
index f8f8a90..b2cab31 100644
--- a/libphobos/src/std/mmfile.d
+++ b/libphobos/src/std/mmfile.d
@@ -2,10 +2,22 @@
/**
* Read and write memory mapped files.
+ *
+ * Memory mapped files are a mechanism in operating systems that allows
+ * file access through virtual memory. After opening a file with `MmFile`,
+ * the contents can be read from or written to with standard slice / pointer operations.
+ * Changes to the memory are automatically reflected in the underlying file.
+ *
+ * Memory mapping can increase I/O performance of large files, compared to buffered
+ * read / write operations from `std.file` and `std.stdio`. However, I/O errors are
+ * not handled as safely: when for example the disk that the file is on gets removed,
+ * reading from it may result in a segfault.
+ *
* Copyright: Copyright The D Language Foundation 2004 - 2009.
* License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
* Authors: $(HTTP digitalmars.com, Walter Bright),
* Matthew Wilson
+ * References: $(LINK https://en.wikipedia.org/wiki/Memory-mapped_file)
* Source: $(PHOBOSSRC std/mmfile.d)
*
* $(SCRIPT inhibitQuickIndex = 1;)
@@ -612,23 +624,47 @@ private:
{
static assert(0);
}
+}
+
+/// Read an existing file
+@system unittest
+{
+ import std.file;
+ std.file.write(deleteme, "hello"); // deleteme is a temporary filename
+ scope(exit) remove(deleteme);
+
+ // Use a scope class so the file will be closed at the end of this function
+ scope mmfile = new MmFile(deleteme);
+
+ assert(mmfile.length == "hello".length);
+
+ // Access file contents with the slice operator
+ // This is typed as `void[]`, so cast to `char[]` or `ubyte[]` to use it
+ const data = cast(const(char)[]) mmfile[];
+
+ // At this point, the file content may not have been read yet.
+ // In that case, the following memory access will intentionally
+ // trigger a page fault, causing the kernel to load the file contents
+ assert(data[0 .. 5] == "hello");
+}
+
+/// Write a new file
+@system unittest
+{
+ import std.file;
+ scope(exit) remove(deleteme);
+
+ scope mmfile = new MmFile(deleteme, MmFile.Mode.readWriteNew, 5, null);
+ assert(mmfile.length == 5);
+
+ auto data = cast(ubyte[]) mmfile[];
+
+ // This write to memory will be reflected in the file contents
+ data[] = '\n';
+
+ mmfile.flush();
- // Report error, where errno gives the error number
- // void errNo()
- // {
- // version (Windows)
- // {
- // throw new FileException(filename, GetLastError());
- // }
- // else version (linux)
- // {
- // throw new FileException(filename, errno);
- // }
- // else
- // {
- // static assert(0);
- // }
- // }
+ assert(std.file.read(deleteme) == "\n\n\n\n\n");
}
@system unittest
diff --git a/libphobos/src/std/regex/internal/backtracking.d b/libphobos/src/std/regex/internal/backtracking.d
index ac73f70..a488e06 100644
--- a/libphobos/src/std/regex/internal/backtracking.d
+++ b/libphobos/src/std/regex/internal/backtracking.d
@@ -682,7 +682,7 @@ final:
while (prevStack()) {}
return re.ir[pc].data;
default:
- debug printBytecode(re.ir[0..$]);
+ debug(std_regex_debug) printBytecode(re.ir[0..$]);
assert(0);
L_backtrack:
if (!popState())
diff --git a/libphobos/src/std/regex/internal/ir.d b/libphobos/src/std/regex/internal/ir.d
index 069d75f..04b902f 100644
--- a/libphobos/src/std/regex/internal/ir.d
+++ b/libphobos/src/std/regex/internal/ir.d
@@ -403,7 +403,7 @@ struct Group(DataIndex)
}
//debugging tool, prints out instruction along with opcodes
-@trusted string disassemble(in Bytecode[] irb, uint pc, in NamedGroup[] dict=[])
+debug(std_regex_parser) @trusted string disassemble(in Bytecode[] irb, uint pc, in NamedGroup[] dict=[])
{
import std.array : appender;
import std.format.write : formattedWrite;
@@ -467,7 +467,7 @@ struct Group(DataIndex)
}
//disassemble the whole chunk
-@trusted void printBytecode()(in Bytecode[] slice, in NamedGroup[] dict=[])
+debug(std_regex_parser) @trusted void printBytecode()(in Bytecode[] slice, in NamedGroup[] dict=[])
{
import std.stdio : writeln;
for (uint pc=0; pc<slice.length; pc += slice[pc].length)
diff --git a/libphobos/src/std/typecons.d b/libphobos/src/std/typecons.d
index 67a1ede..13ae294 100644
--- a/libphobos/src/std/typecons.d
+++ b/libphobos/src/std/typecons.d
@@ -3256,11 +3256,19 @@ struct Nullable(T)
* Params:
* value = The value to initialize this `Nullable` with.
*/
- this(inout T value) inout
- {
- _value.payload = value;
- _isNull = false;
- }
+ static if (isCopyable!T)
+ this(inout T value) inout
+ {
+ _value.payload = value;
+ _isNull = false;
+ }
+ else
+ this(T value) inout
+ {
+ import std.algorithm.mutation : move;
+ _value.payload = move(value);
+ _isNull = false;
+ }
static if (hasElaborateDestructor!T)
{
@@ -3273,6 +3281,9 @@ struct Nullable(T)
}
}
+ static if (!isCopyable!T)
+ @disable this(this);
+ else
static if (__traits(hasPostblit, T))
{
this(this)
@@ -3511,22 +3522,18 @@ struct Nullable(T)
* Params:
* value = A value of type `T` to assign to this `Nullable`.
*/
- Nullable opAssign()(T value)
+ ref Nullable opAssign()(T value) return
{
import std.algorithm.mutation : moveEmplace, move;
- // the lifetime of the value in copy shall be managed by
- // this Nullable, so we must avoid calling its destructor.
- auto copy = DontCallDestructorT(value);
-
if (_isNull)
{
// trusted since payload is known to be uninitialized.
- () @trusted { moveEmplace(copy.payload, _value.payload); }();
+ () @trusted { moveEmplace(value, _value.payload); }();
}
else
{
- move(copy.payload, _value.payload);
+ move(value, _value.payload);
}
_isNull = false;
return this;
@@ -3604,12 +3611,14 @@ struct Nullable(T)
alias back = front;
/// ditto
+ static if (isCopyable!T)
@property inout(typeof(this)) save() inout
{
return this;
}
/// ditto
+ static if (isCopyable!T)
inout(typeof(this)) opIndex(size_t[2] dim) inout
in (dim[0] <= length && dim[1] <= length && dim[1] >= dim[0])
{
@@ -4088,16 +4097,12 @@ auto nullable(T)(T t)
struct Test
{
- bool b;
-
- nothrow invariant { assert(b == true); }
-
SysTime _st;
static bool destroyed;
@disable this();
- this(bool b) { this.b = b; }
+ this(int _dummy) {}
~this() @safe { destroyed = true; }
// mustn't call opAssign on Test.init in Nullable!Test, because the invariant
@@ -4109,7 +4114,7 @@ auto nullable(T)(T t)
{
Nullable!Test nt;
- nt = Test(true);
+ nt = Test(1);
// destroy value
Test.destroyed = false;
@@ -10676,6 +10681,21 @@ unittest
assert(s2.get().b == 3);
}
+// https://issues.dlang.org/show_bug.cgi?id=24318
+@system unittest
+{
+ static struct S
+ {
+ @disable this(this);
+ int i;
+ }
+
+ Nullable!S s = S(1);
+ assert(s.get().i == 1);
+ s = S(2);
+ assert(s.get().i == 2);
+}
+
/// The old version of $(LREF SafeRefCounted), before $(LREF borrow) existed.
/// Old code may be relying on `@safe`ty of some of the member functions which
/// cannot be safe in the new scheme, and