diff options
author | Iain Buclaw <ibuclaw@gdcproject.org> | 2024-01-18 02:39:20 +0100 |
---|---|---|
committer | Iain Buclaw <ibuclaw@gdcproject.org> | 2024-02-03 00:49:46 +0100 |
commit | f204359931866b917856fc959c70dbf55f28c14d (patch) | |
tree | ba1c671045e384fa49a6381f79abf7c1b84a55ea /libphobos/src/std | |
parent | 5470a9b176c2b3030ff3891c7e9403db2b0685b8 (diff) | |
download | gcc-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.d | 4 | ||||
-rw-r--r-- | libphobos/src/std/complex.d | 2 | ||||
-rw-r--r-- | libphobos/src/std/conv.d | 8 | ||||
-rw-r--r-- | libphobos/src/std/exception.d | 6 | ||||
-rw-r--r-- | libphobos/src/std/format/internal/floats.d | 14 | ||||
-rw-r--r-- | libphobos/src/std/format/internal/write.d | 7 | ||||
-rw-r--r-- | libphobos/src/std/math/algebraic.d | 2 | ||||
-rw-r--r-- | libphobos/src/std/math/exponential.d | 44 | ||||
-rw-r--r-- | libphobos/src/std/math/hardware.d | 8 | ||||
-rw-r--r-- | libphobos/src/std/math/operations.d | 21 | ||||
-rw-r--r-- | libphobos/src/std/math/package.d | 166 | ||||
-rw-r--r-- | libphobos/src/std/math/rounding.d | 4 | ||||
-rw-r--r-- | libphobos/src/std/math/traits.d | 179 | ||||
-rw-r--r-- | libphobos/src/std/math/trigonometry.d | 5 | ||||
-rw-r--r-- | libphobos/src/std/mmfile.d | 68 | ||||
-rw-r--r-- | libphobos/src/std/regex/internal/backtracking.d | 2 | ||||
-rw-r--r-- | libphobos/src/std/regex/internal/ir.d | 4 | ||||
-rw-r--r-- | libphobos/src/std/typecons.d | 56 |
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 |