Change Log: 2.074.0
Download D 2.074.0
released Apr 10, 2017
Runtime changes
Library changes
- Added std.range.bitwise to create a bitwise adapter over an integral type range, consuming the range elements bit by bit.
- Allow a generic function for std.variant.visit.
- Added std.utf.decodeBack which decodes the last UTF code point of given character range.
- Performance improvements for std.algorithm.searching.{min,max}Element
- std.format.formattedWrite now accepts a compile-time checked format string
- New: Checked, a lightweight and highly configurable checked integral
- Added std.traits.hasStaticMember to check whether a symbol is a static member of a type.
- std.experimental.ndslice has been removed
- std.format.formattedRead now accepts ref parameters as input arguments.
- std.stdio.readf now accepts ref parameters as input arguments.
- MersenneTwisterEngine has been updated so that its template signature matches the C++11 standard.
List of all bug fixes and enhancements in D 2.074.0.
Runtime changes
- TypeInfo.init has been @disabled.
TypeInfo.init has been @disabled. Use TypeInfo.initializer instead.
TypeInfo.init is a legacy alias of the method that is now called TypeInfo.initializer. The name change is necessary because the name "init" clashes with the type property of the same name (init).
The legacy alias has been deprecated since 2.072.0. It's going to be removed in 2.075.0.
Library changes
- Added std.range.bitwise to create a bitwise adapter over an integral type range, consuming the range elements bit by bit.
std.range.bitwise creates a bit by bit adapter over an integral type range:
import std.range : bitwise; ubyte[] arr = [3, 9]; auto r = arr.bitwise; r[2] = 1; assert(arr[0] == 7);
- Allow a generic function for std.variant.visit.
If a lambda with a single generic parameter is provided as a handler to std.variant.visit, it is invoked for any type contained in the Algebraic which does not have a handler for that type.
This allows something like:
// Assume Circle, Square, and Triangle all define center() Algebraic!(Circle, Square, Triangle) someShape; auto center = someShape.visit!(x => x.center);
This may be combined with explicitly typed handlers and a single fallback handler for an empty variant:
Algebraic!(int, float, string) something; something.visit!((string s) => s.length, // called for string x => x, // called for int/float () => 0); // called if empty
- Added std.utf.decodeBack which decodes the last UTF code point of given character range.
import std.utf : decodeBack; string text = "サイト"; assert(decodeBack(text) == 'ト'); assert(decodeBack(text) == 'イ'); assert(decodeBack(text) == 'サ'); assert(text.empty);
- Performance improvements for std.algorithm.searching.{min,max}Element
std.algorithm.searching.minElement and std.algorithm.searching.maxElement are now considerably faster (almost 2x in microbenchmarks) as a special path for the identity case is provided. This allows the compiler to make use of SSE instructions.
The exact improvements are:
% dmd -release -O test.d && ./test extremum.before = 54 secs, 12 ms, 347 μs, and 9 hnsecs extremum.after = 29 secs, 521 ms, 896 μs, and 5 hnsecs
% ldc -release -O3 test.d && ./test extremum.before = 13 secs, 186 ms, 176 μs, and 4 hnsecs extremum.after = 2 secs, 241 ms, 454 μs, and 9 hnsecs
- std.format.formattedWrite now accepts a compile-time checked format string
std.format.formattedWrite and related functions now have overloads to take the format string as a compile-time argument. This allows the format specifiers to be matched against the argument types passed. Any mismatch or orphaned specifiers/arguments will cause a compile-time error:
import std.format, std.stdio; auto s = format!"%s is %s"("Pi", 3.14); assert(s == "Pi is 3.14"); writefln!"%c is %s"('e', 1.61); static assert(!__traits(compiles, {s = format!"%l"();})); // missing arg static assert(!__traits(compiles, {s = format!""(404);})); // surplus arg static assert(!__traits(compiles, {s = format!"%d"(4.03);})); // incompatible arg
- New: Checked, a lightweight and highly configurable checked integral
std.experimental.checkedint.Checked is a wrapper around any integral type that inserts checks against common sources of bugs: overflow in operators, mixed-sign comparisons, and casts that lose information.
The example below illustrates the basic use of the facility:
void main() { import std.experimental.checkedint, std.stdio; writeln((checked(5) + 7).get); // 12 writeln((checked(10) * 1000 * 1000 * 1000).get); // Overflow }
By default, all checks are enabled and the program is aborted if any check fails. An implementation based on hooks discoverable by using Design by Introspection allows unbounded customizations of both the checks to do, and the enforcement policy.
- Added std.traits.hasStaticMember to check whether a symbol is a static member of a type.
import std.traits : hasStaticMember; struct S { static int staticVar; int nonstaticVar; } assert( hasStaticMember!(S, "staticVar")); assert(!hasStaticMember!(S, "nonstaticVar"));
- std.experimental.ndslice has been removed
The synchronization between Phobos and Mir turned out to be a high amount of work with little gain. Users of std.experimental.ndslice are advised to switch to the upstream mir-algorithm package.
It comes with a lot of new features
- mir.ndslice.topology - Multidimensional std.range analog. Includes bitwise, bitpack, zip, unzip, map, indexed and many other features.
- mir.ndslice.concatenation - Concatenation and padding
- mir.ndslice.algorithm - Slim multidimensional std.algorithm analog
- mir.ndslice.sorting - Multidimensional sorting utilities
ndslice design was changed. New ndslices can be created on top of random access iterators including pointers. There are three kinds of ndslice:
- Contiguous - Contiguous in memory representation. It does not store strides and can be always flattened to 1 dimensional ndslice on top of the same iterator type.
- Canonical - BLAS like. Stride for row dimension assumed to be equal to 1.
- Universal - Numpy like. Each dimension has strides. All dimensions can be exchanged without reallocation. The old ndslice ABI corresponds to to the Universal ndslice.
- std.format.formattedRead now accepts ref parameters as input arguments.
When std.format.formattedRead is used with ref parameters it is @safe. For compatibility it's still possible to use std.format.formattedRead with pointers:
import std.format; void main() { string text = "1 2 3"; int a, b, c; formattedRead(text, "%d %d %d", a, b, c); // pointers can still be used formattedRead(text, "%d %d %d", &a, &b, &c); // and even combined: formattedRead(text, "%d %d %d", a, &b, c); }
- std.stdio.readf now accepts ref parameters as input arguments.
import std.stdio : readf; void main() { // assume every line from stdin is similar to "1 2 3"; int a, b, c; readf(" %d %d %d", a, b, c); // pointers can still be used readf(" %d %d %d, &a, &b, &c); // and even combined: readf(" %d %d %d, a, &b, c); }
- MersenneTwisterEngine has been updated so that its template signature matches the C++11 standard.
MersenneTwisterEngine has been updated so that its template signature matches the C++11 standard (adding two new template parameters, an extra tempering parameter d and the initialization multiplier f).
Handling of the word size w has been fixed so that the generator will now properly handle cases where it is less than the number of bits in the chosen UIntType. This has been validated against the behaviour of a widely-used implementation of the C++11 standard.
For anyone using the standard template instantiation Mt19937 this will have no noticeable effect. However, these will be breaking changes for anyone using the MersenneTwisterEngine template directly.
The internal implementation has been reworked to use Ilya Yaroshenko's highly optimized algorithm from mir-random. This should have a very noticeable positive effect for anyone who cares about generating a lot of random numbers quickly.
A new Mt19937_64 template instantiation has been added, corresponding to the standard 64-bit implementation of the algorithm (MT19937-64). This fixes https://issues.dlang.org/show_bug.cgi?id=10900.
List of all bug fixes and enhancements in D 2.074.0:
DMD Compiler regressions
- Bugzilla 15947: [REG 2.069.0?] simple multithreaded program + "-profile=gc" = crash
- Bugzilla 16680: dmd doesn't use druntime optimized versions of subtraction array operations
- Bugzilla 17117: [REG2.073] erroneous "escaping reference to local variable"
- Bugzilla 17123: [REG 2.073] Issues with return @safe inference
- Bugzilla 17291: [REG 2.074-b1] windows: invalid relocation entries
- Bugzilla 17292: [REG 2.069] Windows: dmd causes "out of memory" when using less than 2GB of memory
DMD Compiler bugs
- Bugzilla 6400: opDispatch with WithStatement
- Bugzilla 15428: __traits(compiles, super()) cause error "multiple constructor calls" later
- Bugzilla 15616: missing candidate in error message
- Bugzilla 15676: The compiler does not preserve @disable while generating .di files
- Bugzilla 16083: AliasSeq loses type of enums that have the same value
- Bugzilla 16245: the message emitted when a const function mutates members is misleading
- Bugzilla 16346: Enum used as a constructor evaluates to the underlying type, not to the enum type.
- Bugzilla 16355: __xpostblit incorrectly generated for a struct with a zero-length static array
- Bugzilla 16382: Passing &this as a CT parameter seg faults dmd
- Bugzilla 16483: ICE in expression.d from typeof
- Bugzilla 17049: [scope] member methods not escape checked like free functions
- Bugzilla 17057: trait "allMembers" incorrectly includes imports
- Bugzilla 17076: [scope] compiling identity function template with -dip1000 causes error
- Bugzilla 17086: DMD segfault with multiple template matches and invalid code
- Bugzilla 17255: Warning when compiling ddmd.backend/ptrntab.c about type-punning
DMD Compiler enhancements
- Bugzilla 14859: static declared array with more than 16MB size should be allowed in struct and class declaration
- Bugzilla 16513: Speed up TemplateInstance.findExistingInstance hash
- Bugzilla 16697: Extend IsExpression to accept __vector as a TypeSpecialization
- Bugzilla 17111: DMD accepts switch statement with non-const case variables
Phobos regressions
- Bugzilla 17282: [REG 2.074.0-b1] std.conv.parse throws with -debug
Phobos bugs
- Bugzilla 8260: * used three or more times on an array inside std.format.formattedRead and not guarded by template constraint
- Bugzilla 8471: std.stdio.readf should be @trusted
- Bugzilla 9615: std.conv.parse!(T[]) fails on trailing comma
- Bugzilla 11703: Typedef properties should not be of the original type
- Bugzilla 13619: std.container.array capacity not updated when length increases
- Bugzilla 16342: std.algorithm.fill can't fill a char[]?
- Bugzilla 16442: FrontTransversal fails with empty ranges
- Bugzilla 16564: KRRegion.empty sometimes returns Ternary.no
- Bugzilla 16642: byCodeUnit doesn't work AutodecodableStrings unless they're actually strings or alias a variable that's a string
- Bugzilla 16824: std.experimental.allocator.dispose leaks memory for arrays of more than 1 dimension
- Bugzilla 17075: ctRegex BacktrackingMatcher.prevStack: free(): invalid pointer
- Bugzilla 17102: std.write.file generates a segmentation fault when the file name is a string with a default value
- Bugzilla 17116: std.typecons.ReplaceType is not able to process const delegate
- Bugzilla 17153: std.container.array.Array cannot be used in @nogc code
- Bugzilla 17154: std.conv.toChars doesn't support $ in slicing
- Bugzilla 17157: ctRegex.matchAll doesn't set last item in Captures
- Bugzilla 17177: AutoImplement fails on function overload sets with "cannot infer type from overloaded function symbol"
- Bugzilla 17217: std.net.isemail.isEmail doesn't work with non char arrays
- Bugzilla 17229: File.byChunk (ubyte) w/ stdout.lockingTextWriter corrupts utf-8 data (and is very slow)
- Bugzilla 17243: std.math.{FloatingPointControl,ieeeFlags} don't work on x86_64
- Bugzilla 17247: std.bitmanip.read should not assume sliceable range is assign-copyable to ubyte[].
Phobos enhancements
- Bugzilla 10900: Mersenne Twister should have a 64-bit (ulong) version
- Bugzilla 13017: opEquals for null std.typecons.Nullable
- Bugzilla 16281: std.format.formattedRead should use ref instead of requiring pointers
- Bugzilla 16323: std.utf.decodeBack
- Bugzilla 16736: Retrieving cUrl time values is quite cumbersome
Druntime regressions
- Bugzilla 17130: [Reg 2.074] ambiguous implicit super call when inheriting core.sync.mutex.Mutex
Druntime bugs
- Bugzilla 16470: Segfault with negative array length
Druntime enhancements
- Bugzilla 8411: core.time: No easy way to check if Duration is empty
dlang.org bugs
- Bugzilla 17115: [404 Not Found] std.concurrencybase
dlang.org enhancements
- Bugzilla 16991: Make writeln documentation palatable
Tools bugs
- Bugzilla 17139: [BLOCKING] dscanner needs to handle 'scope' function attributes