From 9ea653eed4db0098402978453fcf2cfc382caac8 Mon Sep 17 00:00:00 2001 From: Thayne McCombs Date: Sun, 4 Sep 2016 22:24:57 -0600 Subject: [PATCH 001/163] Allow using Unique with interfaces --- std/typecons.d | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/std/typecons.d b/std/typecons.d index 62cf0fb6b8f..96ef731104a 100644 --- a/std/typecons.d +++ b/std/typecons.d @@ -56,7 +56,7 @@ class object, in which case Unique behaves polymorphically too. struct Unique(T) { /** Represents a reference to $(D T). Resolves to $(D T*) if $(D T) is a value type. */ -static if (is(T:Object)) +static if (is(T == class) || is(T == interface)) alias RefT = T; else alias RefT = T*; @@ -261,6 +261,35 @@ private: assert(!ub2.isEmpty); } +@system unittest +{ + debug(Unique) writeln("Unique interface"); + interface Bar + { + int val() const; + } + class BarImpl : Bar + { + ~this() { debug(Unique) writeln(" C destructor"); } + int val() const { return 4; }; + } + alias UBar = Unique!Bar; + UBar g(UBar u) + { + debug(Unique) writeln("inside g"); + return u.release; + } + auto ub = UBar(new BarImpl); + assert(!ub.isEmpty); + assert(ub.val == 4); + static assert(!__traits(compiles, {auto ub3 = g(ub);})); + debug(Unique) writeln("Calling g"); + auto ub2 = g(ub.release); + debug(Unique) writeln("Returned from g"); + assert(ub.isEmpty); + assert(!ub2.isEmpty); +} + @system unittest { debug(Unique) writeln("Unique struct"); From b6c2e381e9d3ee67c3bbf73d0d3740018e384677 Mon Sep 17 00:00:00 2001 From: Thayne McCombs Date: Mon, 5 Sep 2016 19:24:21 -0600 Subject: [PATCH 002/163] Add a little documentation --- std/typecons.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/std/typecons.d b/std/typecons.d index 96ef731104a..262e44ff169 100644 --- a/std/typecons.d +++ b/std/typecons.d @@ -51,7 +51,7 @@ Encapsulates unique ownership of a resource. Resource of type $(D T) is deleted at the end of the scope, unless it is transferred. The transfer can be explicit, by calling $(D release), or implicit, when returning Unique from a function. The resource can be a polymorphic -class object, in which case Unique behaves polymorphically too. +class object or instance of an interface, in which case Unique behaves polymorphically too. */ struct Unique(T) { From 9e58ecab2aa6eb2d800d1e7e0635f7eee1a774aa Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Thu, 26 May 2016 15:49:32 +0200 Subject: [PATCH 003/163] Fix issue 16079 - memoize should work with arrays and objects --- std/functional.d | 77 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/std/functional.d b/std/functional.d index 57a195b28d7..f9ae79bad11 100644 --- a/std/functional.d +++ b/std/functional.d @@ -1162,6 +1162,83 @@ template memoize(alias fun, uint maxSize) assert(func(int.init) == 1); } +// 16079: memoize should work with arrays +unittest +{ + int executed = 0; + T median(T)(const T[] nums) { + import std.algorithm.sorting : sort; + executed++; + auto arr = nums.dup; + arr.sort(); + if (arr.length % 2) + return arr[$ / 2]; + else + return (arr[$ / 2 - 1] + + arr[$ / 2]) / 2; + } + + alias fastMedian = memoize!(median!int); + + assert(fastMedian([7, 5, 3]) == 5); + assert(fastMedian([7, 5, 3]) == 5); + + assert(executed == 1); +} + +// 16079: memoize should work with structs +unittest +{ + int executed = 0; + T pickFirst(T)(T first) + { + executed++; + return first; + } + + struct Foo { int k; } + Foo A = Foo(3); + + alias first = memoize!(pickFirst!Foo); + assert(first(Foo(3)) == A); + assert(first(Foo(3)) == A); + assert(executed == 1); +} + +// 16079: memoize should work with classes +unittest +{ + int executed = 0; + T pickFirst(T)(T first) + { + executed++; + return first; + } + + class Bar + { + size_t k; + this(size_t k) + { + this.k = k; + } + override size_t toHash() + { + return k; + } + override bool opEquals(Object o) + { + auto b = cast(Bar) o; + return b && k == b.k; + } + } + + alias firstClass = memoize!(pickFirst!Bar); + assert(firstClass(new Bar(3)).k == 3); + assert(firstClass(new Bar(3)).k == 3); + assert(executed == 1); +} + private struct DelegateFaker(F) { import std.typecons : FuncInfo, MemberFunctionGenerator; From 7cbea7473ad16e52e7d5973793aa0dea5a9b9da4 Mon Sep 17 00:00:00 2001 From: Thayne McCombs Date: Thu, 16 Mar 2017 21:40:55 -0600 Subject: [PATCH 004/163] Remove trailing space --- std/typecons.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/std/typecons.d b/std/typecons.d index 6af4a3dc6a7..879a635f46e 100644 --- a/std/typecons.d +++ b/std/typecons.d @@ -61,7 +61,7 @@ $(D T) to deallocate or clean up any non-GC resources. If it is desirable to persist a $(D Unique!T) outside of its original scope, then it can be transferred. The transfer can be explicit, by calling $(D release), or implicit, when returning Unique from a -function. The resource $(D T) can be a polymorphic class object or +function. The resource $(D T) can be a polymorphic class object or instance of an interface, in which case Unique behaves polymorphically too. From 70a9e2a5030a85a8001c534f06952c9e777da053 Mon Sep 17 00:00:00 2001 From: Thayne McCombs Date: Thu, 16 Mar 2017 22:13:02 -0600 Subject: [PATCH 005/163] Improve unit test for Unique with interface --- std/typecons.d | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/std/typecons.d b/std/typecons.d index 879a635f46e..2b44c751b6e 100644 --- a/std/typecons.d +++ b/std/typecons.d @@ -290,7 +290,15 @@ private: } class BarImpl : Bar { - ~this() { debug(Unique) writeln(" C destructor"); } + static int count; + this() + { + count++; + } + ~this() + { + count--; + } int val() const { return 4; }; } alias UBar = Unique!Bar; @@ -299,7 +307,13 @@ private: debug(Unique) writeln("inside g"); return u.release; } + void consume(UBar u) + { + assert(u.val() == 4); + // Resource automatically deleted here + } auto ub = UBar(new BarImpl); + assert(BarImpl.count == 1); assert(!ub.isEmpty); assert(ub.val == 4); static assert(!__traits(compiles, {auto ub3 = g(ub);})); @@ -308,6 +322,8 @@ private: debug(Unique) writeln("Returned from g"); assert(ub.isEmpty); assert(!ub2.isEmpty); + consume(ub2.release); + assert(BarImpl.count == 0); } @system unittest From 59508c4949fb56b6f5d88853d3c189c2e81edd9c Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Sat, 18 Feb 2017 03:47:25 +0100 Subject: [PATCH 006/163] [Static if] replace overload constraints with static if (sorting.d) --- std/algorithm/sorting.d | 70 +++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 41 deletions(-) diff --git a/std/algorithm/sorting.d b/std/algorithm/sorting.d index 384a9c00ec8..3c38cddd15b 100644 --- a/std/algorithm/sorting.d +++ b/std/algorithm/sorting.d @@ -3748,58 +3748,46 @@ void topNIndex(alias less = "a < b", SwapStrategy ss = SwapStrategy.unstable, (Range r, RangeIndex index, SortOutput sorted = No.sortOutput) if (isRandomAccessRange!Range && isRandomAccessRange!RangeIndex && - hasAssignableElements!RangeIndex && - isIntegral!(ElementType!(RangeIndex))) + hasAssignableElements!RangeIndex) { static assert(ss == SwapStrategy.unstable, "Stable swap strategy not implemented yet."); - import std.container : BinaryHeap; - import std.exception : enforce; - + import std.container.binaryheap : BinaryHeap; if (index.empty) return; - enforce(ElementType!(RangeIndex).max >= index.length, - "Index type too small"); - bool indirectLess(ElementType!(RangeIndex) a, ElementType!(RangeIndex) b) - { - return binaryFun!(less)(r[a], r[b]); - } - auto heap = BinaryHeap!(RangeIndex, indirectLess)(index, 0); - foreach (i; 0 .. r.length) - { - heap.conditionalInsert(cast(ElementType!RangeIndex) i); - } - if (sorted == Yes.sortOutput) - { - while (!heap.empty) heap.removeFront(); - } -} -/// ditto -void topNIndex(alias less = "a < b", SwapStrategy ss = SwapStrategy.unstable, - Range, RangeIndex) - (Range r, RangeIndex index, SortOutput sorted = No.sortOutput) -if (isRandomAccessRange!Range && - isRandomAccessRange!RangeIndex && - hasAssignableElements!RangeIndex && - is(ElementType!(RangeIndex) == ElementType!(Range)*)) -{ - static assert(ss == SwapStrategy.unstable, - "Stable swap strategy not implemented yet."); + static if (isIntegral!(ElementType!(RangeIndex))) + { + import std.exception : enforce; - import std.container : BinaryHeap; + enforce(ElementType!(RangeIndex).max >= index.length, + "Index type too small"); + bool indirectLess(ElementType!(RangeIndex) a, ElementType!(RangeIndex) b) + { + return binaryFun!(less)(r[a], r[b]); + } + auto heap = BinaryHeap!(RangeIndex, indirectLess)(index, 0); + foreach (i; 0 .. r.length) + { + heap.conditionalInsert(cast(ElementType!RangeIndex) i); + } - if (index.empty) return; - static bool indirectLess(const ElementType!(RangeIndex) a, - const ElementType!(RangeIndex) b) - { - return binaryFun!less(*a, *b); } - auto heap = BinaryHeap!(RangeIndex, indirectLess)(index, 0); - foreach (i; 0 .. r.length) + else static if (is(ElementType!(RangeIndex) == ElementType!(Range)*)) { - heap.conditionalInsert(&r[i]); + static bool indirectLess(const ElementType!(RangeIndex) a, + const ElementType!(RangeIndex) b) + { + return binaryFun!less(*a, *b); + } + auto heap = BinaryHeap!(RangeIndex, indirectLess)(index, 0); + foreach (i; 0 .. r.length) + { + heap.conditionalInsert(&r[i]); + } } + else static assert(0, "Invalid ElementType"); + if (sorted == Yes.sortOutput) { while (!heap.empty) heap.removeFront(); From 95f6d5bff36f2f951e0df6e899e92dc27e8311e8 Mon Sep 17 00:00:00 2001 From: Nick Treleaven Date: Wed, 10 May 2017 12:36:40 +0100 Subject: [PATCH 007/163] Fix Issue 17389 - hasNested infinite recursion Happens with a class with a member of the same type. --- std/traits.d | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/std/traits.d b/std/traits.d index ec9a9c356e7..2b6bb6bdf2d 100644 --- a/std/traits.d +++ b/std/traits.d @@ -2316,12 +2316,17 @@ have a context pointer. */ template hasNested(T) { - import std.meta : anySatisfy; + import std.meta : anySatisfy, Filter; + static if (isStaticArray!T && T.length) enum hasNested = hasNested!(typeof(T.init[0])); else static if (is(T == class) || is(T == struct) || is(T == union)) + { + // prevent infinite recursion for class with member of same type + enum notSame(U) = !is(Unqual!T == Unqual!U); enum hasNested = isNested!T || - anySatisfy!(.hasNested, Fields!T); + anySatisfy!(.hasNested, Filter!(notSame, Fields!T)); + } else enum hasNested = false; } @@ -2387,6 +2392,12 @@ template hasNested(T) static assert(!__traits(compiles, isNested!(NestedClass[1]))); static assert( hasNested!(NestedClass[1])); static assert(!hasNested!(NestedClass[0])); + + static class A + { + A a; + } + static assert(!hasNested!A); } From 3d2d786110fb1ebf27648a136ddaba074c413d7c Mon Sep 17 00:00:00 2001 From: Geod24 Date: Thu, 1 Jun 2017 23:53:11 +0200 Subject: [PATCH 008/163] std.format: Add a test for range of argument formatting This feature was totally untested and is not documented either. The only way I could find about it was while reading a comment in the code. --- std/format.d | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/std/format.d b/std/format.d index a746008d640..2a0c1199966 100644 --- a/std/format.d +++ b/std/format.d @@ -6055,3 +6055,10 @@ char[] sformat(Char, Args...)(char[] buf, in Char[] fmt, Args args) tmp = format("%19,?f", '.', -1234567.891011); assert(tmp == " -1.234.567.891.011", "'" ~ tmp ~ "'"); } + +// Test for multiple indexes +@safe unittest +{ + auto tmp = format("%2:5$s", 1, 2, 3, 4, 5); + assert(tmp == "2345", tmp); +} From fe55345a744fb55c0c893e28628b468a465cfe9c Mon Sep 17 00:00:00 2001 From: Geod24 Date: Fri, 2 Jun 2017 00:15:54 +0200 Subject: [PATCH 009/163] Simplify and improve format positional argument output The previous code was needlessly complicated, storing arguments' as `void*` in an array, and having a matching array of delegates to cast them. It was not ctfe-able which required an extra code path, and tricks such as an artificial call to the `formatValue` function to ensure correct inference of `@safe`ty. The new code do away with those limitations by simply using a switch of which branches are CT-generated. This simple technique makes the code faster, as less instructions are generated, inlining is possible, and a switch with not so many cases will usually result in a jump table being generated. --- std/format.d | 101 ++++++++++++++++----------------------------------- 1 file changed, 32 insertions(+), 69 deletions(-) diff --git a/std/format.d b/std/format.d index 2a0c1199966..b6129784119 100644 --- a/std/format.d +++ b/std/format.d @@ -467,31 +467,13 @@ uint formattedWrite(Writer, Char, A...)(Writer w, in Char[] fmt, A args) { import std.conv : text; - alias FPfmt = void function(Writer, scope const(void)*, const ref FormatSpec!Char) @safe pure nothrow; - auto spec = FormatSpec!Char(fmt); - FPfmt[A.length] funs; - const(void)*[A.length] argsAddresses; - if (!__ctfe) - { - foreach (i, Arg; A) - { - funs[i] = ()@trusted{ return cast(FPfmt)&formatGeneric!(Writer, Arg, Char); }(); - // We can safely cast away shared because all data is either - // immutable or completely owned by this function. - argsAddresses[i] = (ref arg)@trusted{ return cast(const void*) &arg; }(args[i]); - - // Reflect formatting @safe/pure ability of each arguments to this function - if (0) formatValue(w, args[i], spec); - } - } - // Are we already done with formats? Then just dump each parameter in turn uint currentArg = 0; while (spec.writeUpToNextSpec(w)) { - if (currentArg == funs.length && !spec.indexStart) + if (currentArg == A.length && !spec.indexStart) { // leftover spec? enforceFmt(fmt.length == 0, @@ -568,36 +550,43 @@ uint formattedWrite(Writer, Char, A...)(Writer w, in Char[] fmt, A args) break; } - // Format! - if (spec.indexStart > 0) + // Format an argument + // This switch uses a static foreach to generate a jump table. + // Currently `spec.indexStart` use the special value '0' to signal + // we should use the current argument. An enhancement would be to + // always store the index. + size_t index = currentArg; + if (spec.indexStart != 0) + index = spec.indexStart - 1; + else + ++currentArg; + SWITCH: switch (index) { - // using positional parameters! - - // Make the conditional compilation of this loop explicit, to avoid "statement not reachable" warnings. - static if (A.length > 0) + foreach (i, Tunused; A) { - foreach (i; spec.indexStart - 1 .. spec.indexEnd) + case i: + formatValue(w, args[i], spec); + if (currentArg < spec.indexEnd) + currentArg = spec.indexEnd; + // A little know feature of format is to format a range + // of arguments, e.g. `%1:3$` will format the first 3 + // arguments. Since they have to be consecutive we can + // just use explicit fallthrough to cover that case. + if (i + 1 < spec.indexEnd) { - if (A.length <= i) - throw new FormatException( - text("Positional specifier %", i + 1, '$', spec.spec, - " index exceeds ", A.length)); - - if (__ctfe) - formatNth(w, spec, i, args); + // You cannot goto case if the next case is the default + static if (i + 1 < A.length) + goto case; else - funs[i](w, argsAddresses[i], spec); + goto default; } + else + break SWITCH; } - if (currentArg < spec.indexEnd) currentArg = spec.indexEnd; - } - else - { - if (__ctfe) - formatNth(w, spec, currentArg, args); - else - funs[currentArg](w, argsAddresses[currentArg], spec); - ++currentArg; + default: + throw new FormatException( + text("Positional specifier %", spec.indexStart, '$', spec.spec, + " index exceeds ", A.length)); } } return currentArg; @@ -4015,32 +4004,6 @@ if (isDelegate!T) version (linux) formatTest( &func, "void delegate() @system" ); } -/* - Formats an object of type 'D' according to 'f' and writes it to - 'w'. The pointer 'arg' is assumed to point to an object of type - 'D'. The untyped signature is for the sake of taking this function's - address. - */ -private void formatGeneric(Writer, D, Char)(Writer w, const(void)* arg, const ref FormatSpec!Char f) -{ - formatValue(w, *cast(D*) arg, f); -} - -private void formatNth(Writer, Char, A...)(Writer w, const ref FormatSpec!Char f, size_t index, A args) -{ - switch (index) - { - foreach (n, _; A) - { - case n: - formatValue(w, args[n], f); - return; - } - default: - assert(0, "n = "~cast(char)(index + '0')); - } -} - @safe pure unittest { int[] a = [ 1, 3, 2 ]; From e7c8d2b1dc0c841ea4ab72820506b1d9949c8738 Mon Sep 17 00:00:00 2001 From: Wulfklaue Date: Wed, 7 Jun 2017 13:42:52 +0200 Subject: [PATCH 010/163] A simple example added to Date - toString First attempt at using GIT for updating the documentation. Added a simple example to the date documentation. --- std/datetime/date.d | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/std/datetime/date.d b/std/datetime/date.d index a7d33830128..1ede4395a86 100644 --- a/std/datetime/date.d +++ b/std/datetime/date.d @@ -7254,6 +7254,12 @@ public: return toSimpleString(); } + /// + unittest + { + assert(Date(2010, 7, 4).toString() == "2010-Jul-04"); + } + @safe unittest { auto date = Date(1999, 7, 6); From 6b41acd9bae7e2f52ce064a1c5b858dd1789559f Mon Sep 17 00:00:00 2001 From: Rainer Schuetze Date: Sat, 27 May 2017 16:20:20 +0200 Subject: [PATCH 011/163] map std.traits.mangleName directly to mangleof --- std/traits.d | 69 ++++++---------------------------------------------- 1 file changed, 7 insertions(+), 62 deletions(-) diff --git a/std/traits.d b/std/traits.d index 91b4d015b21..bd8a8dfc347 100644 --- a/std/traits.d +++ b/std/traits.d @@ -7264,8 +7264,8 @@ unittest /** Returns the mangled name of symbol or type $(D sth). -$(D mangledName) is the same as builtin $(D .mangleof) property, except that -the correct names of property functions are obtained. +$(D mangledName) is the same as builtin $(D .mangleof) property, kept +for compatibility as property functions used to behave differently. -------------------- module test; import std.traits : mangledName; @@ -7274,82 +7274,27 @@ class C { int value() @property; } -pragma(msg, C.value.mangleof); // prints "i" +pragma(msg, C.value.mangleof); // prints "_D4test1C5valueMFNdZi", was "i" pragma(msg, mangledName!(C.value)); // prints "_D4test1C5valueMFNdZi" -------------------- */ template mangledName(sth...) if (sth.length == 1) { - static if (is(typeof(sth[0]) X) && is(X == void)) - { - // sth[0] is a template symbol - enum string mangledName = removeDummyEnvelope(Dummy!sth.Hook.mangleof); - } - else - { - enum string mangledName = sth[0].mangleof; - } + enum string mangledName = sth[0].mangleof; } -private template Dummy(T...) { struct Hook {} } - -private string removeDummyEnvelope(string s) -{ - // remove --> S3std6traits ... Z4Hook - s = s[12 .. $ - 6]; - - // remove --> DIGIT+ __T5Dummy - foreach (i, c; s) - { - if (c < '0' || '9' < c) - { - s = s[i .. $]; - break; - } - } - s = s[9 .. $]; // __T5Dummy - - // remove --> T | V | S - immutable kind = s[0]; - s = s[1 .. $]; - - if (kind == 'S') // it's a symbol - { - /* - * The mangled symbol name is packed in LName --> Number Name. Here - * we are chopping off the useless preceding Number, which is the - * length of Name in decimal notation. - * - * NOTE: n = m + Log(m) + 1; n = LName.length, m = Name.length. - */ - immutable n = s.length; - size_t m_upb = 10; - - foreach (k; 1 .. 5) // k = Log(m_upb) - { - if (n < m_upb + k + 1) - { - // Now m_upb/10 <= m < m_upb; hence k = Log(m) + 1. - s = s[k .. $]; - break; - } - m_upb *= 10; - } - } - - return s; -} +version(unittest) void freeFunc(string); @safe unittest { class C { int value() @property { return 0; } } static assert(mangledName!int == int.mangleof); static assert(mangledName!C == C.mangleof); + static assert(mangledName!(C.value) == C.value.mangleof); static assert(mangledName!(C.value)[$ - 12 .. $] == "5valueMFNdZi"); static assert(mangledName!mangledName == "3std6traits11mangledName"); - static assert(mangledName!removeDummyEnvelope == - "_D3std6traits19removeDummyEnvelopeFAyaZAya"); + static assert(mangledName!freeFunc == "_D3std6traits8freeFuncFAyaZv"); int x; static if (is(typeof({ return x; }) : int delegate() pure)) // issue 9148 static assert(mangledName!((int a) { return a+x; }) == "DFNaNbNiNfiZi"); // pure nothrow @safe @nogc From f1455701eaeb63bfbd7590daf74c927efebc037a Mon Sep 17 00:00:00 2001 From: Andrei Alexandrescu Date: Sun, 11 Jun 2017 14:03:41 -0400 Subject: [PATCH 012/163] Eliminate shared this from std/net/curl.d --- std/net/curl.d | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/std/net/curl.d b/std/net/curl.d index 711c49819c6..53a3d4f8bd7 100644 --- a/std/net/curl.d +++ b/std/net/curl.d @@ -4158,29 +4158,30 @@ private struct CurlAPI enforce!CurlException(!_api.global_init(CurlGlobal.all), "Failed to initialize libcurl"); - return handle; - } - - shared static ~this() - { - if (_handle is null) return; - - _api.global_cleanup(); - version (Posix) + static extern(C) void cleanup() { - import core.sys.posix.dlfcn : dlclose; - dlclose(_handle); - } - else version (Windows) - { - import core.sys.windows.windows : FreeLibrary; - FreeLibrary(_handle); + if (_handle is null) return; + _api.global_cleanup(); + version (Posix) + { + import core.sys.posix.dlfcn : dlclose; + dlclose(_handle); + } + else version (Windows) + { + import core.sys.windows.windows : FreeLibrary; + FreeLibrary(_handle); + } + else + static assert(0, "unimplemented"); + _api = API.init; + _handle = null; } - else - static assert(0, "unimplemented"); - _api = API.init; - _handle = null; + import core.stdc.stdlib : atexit; + atexit(&cleanup); + + return handle; } } From 7c217521979df28deb23517a90c7a3c9aba970b6 Mon Sep 17 00:00:00 2001 From: David Marquant Date: Sun, 11 Jun 2017 22:24:20 +0200 Subject: [PATCH 013/163] Fix Issue 12866 - concatenating to std.container.array of static arrays --- std/container/array.d | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/std/container/array.d b/std/container/array.d index b92a9c3e36b..dec1b9ecebb 100644 --- a/std/container/array.d +++ b/std/container/array.d @@ -730,7 +730,7 @@ if (!is(Unqual!T == bool)) void opOpAssign(string op, Stuff)(Stuff stuff) if (op == "~") { - static if (is(typeof(stuff[]))) + static if (is(typeof(stuff[])) && isImplicitlyConvertible!(typeof(stuff[0]), T)) { insertBack(stuff[]); } @@ -2400,3 +2400,23 @@ if (is(Unqual!T == bool)) assert(a.length == 11, to!string(a.length)); assert(a[5]); } +@system unittest +{ + alias V3 = int[3]; + V3 v = [1, 2, 3]; + Array!V3 arr; + arr ~= v; + assert(arr[0] == [1, 2, 3]); + + arr = arr ~ v; + assert(arr[1] == [1, 2, 3]); +} +@system unittest +{ + alias V3 = int[3]; + V3[2] v = [[1, 2, 3], [4, 5, 6]]; + Array!V3 arr; + arr ~= v; + assert(arr[0] == [1, 2, 3]); + assert(arr[1] == [4, 5, 6]); +} From 879f0b9d0a223525edabb2465c1ffc2cf18c7208 Mon Sep 17 00:00:00 2001 From: David Marquant Date: Sun, 11 Jun 2017 22:27:03 +0200 Subject: [PATCH 014/163] Remove redundant check using binop --- std/container/array.d | 3 --- 1 file changed, 3 deletions(-) diff --git a/std/container/array.d b/std/container/array.d index dec1b9ecebb..654c457090b 100644 --- a/std/container/array.d +++ b/std/container/array.d @@ -2407,9 +2407,6 @@ if (is(Unqual!T == bool)) Array!V3 arr; arr ~= v; assert(arr[0] == [1, 2, 3]); - - arr = arr ~ v; - assert(arr[1] == [1, 2, 3]); } @system unittest { From f381477bdcc647a739d16d3cbf5bf9c417526320 Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Thu, 15 Jun 2017 06:50:30 +0200 Subject: [PATCH 015/163] Issue 17224 - Foreach documentation still refers to TypeTuples, rather than AliasSequences --- std/traits.d | 334 +++++++++++++++++++++++++-------------------------- 1 file changed, 167 insertions(+), 167 deletions(-) diff --git a/std/traits.d b/std/traits.d index 506dd3ffeaf..13f778c7534 100644 --- a/std/traits.d +++ b/std/traits.d @@ -164,7 +164,7 @@ */ module std.traits; -import std.typetuple; // TypeTuple +import std.meta : AliasSeq, allSatisfy; /////////////////////////////////////////////////////////////////////////////// // Functions @@ -251,25 +251,25 @@ private static if (is(ucent)) { - alias CentTypeList = TypeTuple!(cent, ucent); - alias SignedCentTypeList = TypeTuple!(cent); - alias UnsignedCentTypeList = TypeTuple!(ucent); + alias CentTypeList = AliasSeq!(cent, ucent); + alias SignedCentTypeList = AliasSeq!(cent); + alias UnsignedCentTypeList = AliasSeq!(ucent); } else { - alias CentTypeList = TypeTuple!(); - alias SignedCentTypeList = TypeTuple!(); - alias UnsignedCentTypeList = TypeTuple!(); + alias CentTypeList = AliasSeq!(); + alias SignedCentTypeList = AliasSeq!(); + alias UnsignedCentTypeList = AliasSeq!(); } - alias IntegralTypeList = TypeTuple!(byte, ubyte, short, ushort, int, uint, long, ulong, CentTypeList); - alias SignedIntTypeList = TypeTuple!(byte, short, int, long, SignedCentTypeList); - alias UnsignedIntTypeList = TypeTuple!(ubyte, ushort, uint, ulong, UnsignedCentTypeList); - alias FloatingPointTypeList = TypeTuple!(float, double, real); - alias ImaginaryTypeList = TypeTuple!(ifloat, idouble, ireal); - alias ComplexTypeList = TypeTuple!(cfloat, cdouble, creal); - alias NumericTypeList = TypeTuple!(IntegralTypeList, FloatingPointTypeList); - alias CharTypeList = TypeTuple!(char, wchar, dchar); + alias IntegralTypeList = AliasSeq!(byte, ubyte, short, ushort, int, uint, long, ulong, CentTypeList); + alias SignedIntTypeList = AliasSeq!(byte, short, int, long, SignedCentTypeList); + alias UnsignedIntTypeList = AliasSeq!(ubyte, ushort, uint, ulong, UnsignedCentTypeList); + alias FloatingPointTypeList = AliasSeq!(float, double, real); + alias ImaginaryTypeList = AliasSeq!(ifloat, idouble, ireal); + alias ComplexTypeList = AliasSeq!(cfloat, cdouble, creal); + alias NumericTypeList = AliasSeq!(IntegralTypeList, FloatingPointTypeList); + alias CharTypeList = AliasSeq!(char, wchar, dchar); } package @@ -327,7 +327,7 @@ template QualifierOf(T) version(unittest) { - alias TypeQualifierList = TypeTuple!(MutableOf, ConstOf, SharedOf, SharedConstOf, ImmutableOf); + alias TypeQualifierList = AliasSeq!(MutableOf, ConstOf, SharedOf, SharedConstOf, ImmutableOf); struct SubTypeOf(T) { @@ -608,8 +608,8 @@ private template fqnType(T, _inout = 3 } - alias qualifiers = TypeTuple!(is(T == const), is(T == immutable), is(T == shared), is(T == inout)); - alias noQualifiers = TypeTuple!(false, false, false, false); + alias qualifiers = AliasSeq!(is(T == const), is(T == immutable), is(T == shared), is(T == inout)); + alias noQualifiers = AliasSeq!(false, false, false, false); string storageClassesString(uint psc)() @property { @@ -967,14 +967,14 @@ alias ParameterTypeTuple = Parameters; @safe unittest { int foo(int i, bool b) { return 0; } - static assert(is(ParameterTypeTuple!foo == TypeTuple!(int, bool))); - static assert(is(ParameterTypeTuple!(typeof(&foo)) == TypeTuple!(int, bool))); + static assert(is(ParameterTypeTuple!foo == AliasSeq!(int, bool))); + static assert(is(ParameterTypeTuple!(typeof(&foo)) == AliasSeq!(int, bool))); struct S { real opCall(real r, int i) { return 0.0; } } S s; - static assert(is(ParameterTypeTuple!S == TypeTuple!(real, int))); - static assert(is(ParameterTypeTuple!(S*) == TypeTuple!(real, int))); - static assert(is(ParameterTypeTuple!s == TypeTuple!(real, int))); + static assert(is(ParameterTypeTuple!S == AliasSeq!(real, int))); + static assert(is(ParameterTypeTuple!(S*) == AliasSeq!(real, int))); + static assert(is(ParameterTypeTuple!s == AliasSeq!(real, int))); class Test { @@ -1052,14 +1052,14 @@ template ParameterStorageClassTuple(func...) enum rest = demang.rest; alias demangleNextParameter = - TypeTuple!( + AliasSeq!( demang.value + 0, // workaround: "not evaluatable at ..." demangleNextParameter!(rest[skip .. $], i + 1) ); } else // went thru all the parameters { - alias demangleNextParameter = TypeTuple!(); + alias demangleNextParameter = AliasSeq!(); } } @@ -1161,15 +1161,15 @@ template ParameterIdentifierTuple(func...) // Define dummy entities to avoid pointless errors template Get(size_t i) { enum Get = ""; } - alias PT = TypeTuple!(); + alias PT = AliasSeq!(); } template Impl(size_t i = 0) { static if (i == PT.length) - alias Impl = TypeTuple!(); + alias Impl = AliasSeq!(); else - alias Impl = TypeTuple!(Get!i, Impl!(i+1)); + alias Impl = AliasSeq!(Get!i, Impl!(i+1)); } alias ParameterIdentifierTuple = Impl!(); @@ -1213,7 +1213,7 @@ template ParameterIdentifierTuple(func...) static assert([PIT!baw] == ["_param_0", "_param_1", "_param_2"]); // depends on internal - void baz(TypeTuple!(int, string, int[]) args){} + void baz(AliasSeq!(int, string, int[]) args){} static assert([PIT!baz] == ["_param_0", "_param_1", "_param_2"]); +/ } @@ -1253,15 +1253,15 @@ template ParameterDefaults(func...) // Define dummy entities to avoid pointless errors template Get(size_t i) { enum Get = ""; } - alias PT = TypeTuple!(); + alias PT = AliasSeq!(); } template Impl(size_t i = 0) { static if (i == PT.length) - alias Impl = TypeTuple!(); + alias Impl = AliasSeq!(); else - alias Impl = TypeTuple!(Get!i, Impl!(i+1)); + alias Impl = AliasSeq!(Get!i, Impl!(i+1)); } alias ParameterDefaults = Impl!(); @@ -1290,20 +1290,20 @@ alias ParameterDefaultValueTuple = ParameterDefaults; static assert(PDVT!bar.length == 2); static assert(PDVT!bar[0] == 1); static assert(PDVT!bar[1] == "hello"); - static assert(is(typeof(PDVT!bar) == typeof(TypeTuple!(1, "hello")))); + static assert(is(typeof(PDVT!bar) == typeof(AliasSeq!(1, "hello")))); void baz(int x, int n = 1, string s = "hello"){} static assert(PDVT!baz.length == 3); static assert(is(PDVT!baz[0] == void)); static assert( PDVT!baz[1] == 1); static assert( PDVT!baz[2] == "hello"); - static assert(is(typeof(PDVT!baz) == typeof(TypeTuple!(void, 1, "hello")))); + static assert(is(typeof(PDVT!baz) == typeof(AliasSeq!(void, 1, "hello")))); // bug 10800 - property functions return empty string @property void foo(int x = 3) { } static assert(PDVT!foo.length == 1); static assert(PDVT!foo[0] == 3); - static assert(is(typeof(PDVT!foo) == typeof(TypeTuple!(3)))); + static assert(is(typeof(PDVT!foo) == typeof(AliasSeq!(3)))); struct Colour { @@ -2052,7 +2052,7 @@ template FunctionTypeOf(func...) int test(int); int test() @property; } - alias ov = TypeTuple!(__traits(getVirtualFunctions, Overloads, "test")); + alias ov = AliasSeq!(__traits(getVirtualFunctions, Overloads, "test")); alias F_ov0 = FunctionTypeOf!(ov[0]); alias F_ov1 = FunctionTypeOf!(ov[1]); alias F_ov2 = FunctionTypeOf!(ov[2]); @@ -2189,10 +2189,10 @@ version (unittest) import std.algorithm.iteration : reduce; alias FA = FunctionAttribute; - foreach (BaseT; TypeTuple!(typeof(&sc), typeof(&novar), typeof(&cstyle), + foreach (BaseT; AliasSeq!(typeof(&sc), typeof(&novar), typeof(&cstyle), typeof(&dstyle), typeof(&typesafe))) { - foreach (T; TypeTuple!(BaseT, FunctionTypeOf!BaseT)) + foreach (T; AliasSeq!(BaseT, FunctionTypeOf!BaseT)) (){ // avoid slow optimizations for large functions @@@BUG@@@ 2396 enum linkage = functionLinkage!T; enum attrs = functionAttributes!T; @@ -2203,7 +2203,7 @@ version (unittest) // Check that all linkage types work (D-style variadics require D linkage). static if (variadicFunctionStyle!T != Variadic.d) { - foreach (newLinkage; TypeTuple!("D", "C", "Windows", "Pascal", "C++")) + foreach (newLinkage; AliasSeq!("D", "C", "Windows", "Pascal", "C++")) { alias New = SetFunctionAttributes!(T, newLinkage, attrs); static assert(functionLinkage!New == newLinkage, @@ -2406,14 +2406,14 @@ template Fields(T) else static if (is(T == class)) alias Fields = typeof(T.tupleof); else - alias Fields = TypeTuple!T; + alias Fields = AliasSeq!T; } /// @safe unittest { struct S { int x; float y; } - static assert(is(Fields!S == TypeTuple!(int, float))); + static assert(is(Fields!S == AliasSeq!(int, float))); } /** @@ -2423,24 +2423,24 @@ alias FieldTypeTuple = Fields; @safe unittest { - static assert(is(FieldTypeTuple!int == TypeTuple!int)); + static assert(is(FieldTypeTuple!int == AliasSeq!int)); static struct StaticStruct1 { } - static assert(is(FieldTypeTuple!StaticStruct1 == TypeTuple!())); + static assert(is(FieldTypeTuple!StaticStruct1 == AliasSeq!())); static struct StaticStruct2 { int a, b; } - static assert(is(FieldTypeTuple!StaticStruct2 == TypeTuple!(int, int))); + static assert(is(FieldTypeTuple!StaticStruct2 == AliasSeq!(int, int))); int i; struct NestedStruct1 { void f() { ++i; } } - static assert(is(FieldTypeTuple!NestedStruct1 == TypeTuple!())); + static assert(is(FieldTypeTuple!NestedStruct1 == AliasSeq!())); struct NestedStruct2 { int a; void f() { ++i; } } - static assert(is(FieldTypeTuple!NestedStruct2 == TypeTuple!int)); + static assert(is(FieldTypeTuple!NestedStruct2 == AliasSeq!int)); class NestedClass { int a; void f() { ++i; } } - static assert(is(FieldTypeTuple!NestedClass == TypeTuple!int)); + static assert(is(FieldTypeTuple!NestedClass == AliasSeq!int)); } @@ -2462,37 +2462,37 @@ template FieldNameTuple(T) else static if (is(T == class)) alias FieldNameTuple = staticMap!(NameOf, T.tupleof); else - alias FieldNameTuple = TypeTuple!""; + alias FieldNameTuple = AliasSeq!""; } /// @safe unittest { struct S { int x; float y; } - static assert(FieldNameTuple!S == TypeTuple!("x", "y")); - static assert(FieldNameTuple!int == TypeTuple!""); + static assert(FieldNameTuple!S == AliasSeq!("x", "y")); + static assert(FieldNameTuple!int == AliasSeq!""); } @safe unittest { - static assert(FieldNameTuple!int == TypeTuple!""); + static assert(FieldNameTuple!int == AliasSeq!""); static struct StaticStruct1 { } - static assert(is(FieldNameTuple!StaticStruct1 == TypeTuple!())); + static assert(is(FieldNameTuple!StaticStruct1 == AliasSeq!())); static struct StaticStruct2 { int a, b; } - static assert(FieldNameTuple!StaticStruct2 == TypeTuple!("a", "b")); + static assert(FieldNameTuple!StaticStruct2 == AliasSeq!("a", "b")); int i; struct NestedStruct1 { void f() { ++i; } } - static assert(is(FieldNameTuple!NestedStruct1 == TypeTuple!())); + static assert(is(FieldNameTuple!NestedStruct1 == AliasSeq!())); struct NestedStruct2 { int a; void f() { ++i; } } - static assert(FieldNameTuple!NestedStruct2 == TypeTuple!"a"); + static assert(FieldNameTuple!NestedStruct2 == AliasSeq!"a"); class NestedClass { int a; void f() { ++i; } } - static assert(FieldNameTuple!NestedClass == TypeTuple!"a"); + static assert(FieldNameTuple!NestedClass == AliasSeq!"a"); } @@ -2506,7 +2506,7 @@ template RepresentationTypeTuple(T) { static if (T.length == 0) { - alias Impl = TypeTuple!(); + alias Impl = AliasSeq!(); } else { @@ -2525,7 +2525,7 @@ template RepresentationTypeTuple(T) } else { - alias Impl = TypeTuple!(T[0], Impl!(T[1 .. $])); + alias Impl = AliasSeq!(T[0], Impl!(T[1 .. $])); } } } @@ -2554,14 +2554,14 @@ template RepresentationTypeTuple(T) @safe unittest { alias S1 = RepresentationTypeTuple!int; - static assert(is(S1 == TypeTuple!int)); + static assert(is(S1 == AliasSeq!int)); struct S2 { int a; } struct S3 { int a; char b; } struct S4 { S1 a; int b; S3 c; } - static assert(is(RepresentationTypeTuple!S2 == TypeTuple!int)); - static assert(is(RepresentationTypeTuple!S3 == TypeTuple!(int, char))); - static assert(is(RepresentationTypeTuple!S4 == TypeTuple!(int, int, int, char))); + static assert(is(RepresentationTypeTuple!S2 == AliasSeq!int)); + static assert(is(RepresentationTypeTuple!S3 == AliasSeq!(int, char))); + static assert(is(RepresentationTypeTuple!S4 == AliasSeq!(int, int, int, char))); struct S11 { int a; float b; } struct S21 { char[] a; union { S11 b; S11 * c; } } @@ -3916,7 +3916,7 @@ template EnumMembers(E) //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::// /*** - * Get a $(D_PARAM TypeTuple) of the base class and base interfaces of + * Get a $(D_PARAM AliasSeq) of the base class and base interfaces of * this class or interface. $(D_PARAM BaseTypeTuple!Object) returns * the empty type tuple. */ @@ -3934,11 +3934,11 @@ template BaseTypeTuple(A) interface I1 { } interface I2 { } interface I12 : I1, I2 { } - static assert(is(BaseTypeTuple!I12 == TypeTuple!(I1, I2))); + static assert(is(BaseTypeTuple!I12 == AliasSeq!(I1, I2))); interface I3 : I1 { } interface I123 : I1, I2, I3 { } - static assert(is(BaseTypeTuple!I123 == TypeTuple!(I1, I2, I3))); + static assert(is(BaseTypeTuple!I123 == AliasSeq!(I1, I2, I3))); } @safe unittest @@ -3958,7 +3958,7 @@ template BaseTypeTuple(A) } /** - * Get a $(D_PARAM TypeTuple) of $(I all) base classes of this class, + * Get a $(D_PARAM AliasSeq) of $(I all) base classes of this class, * in decreasing order. Interfaces are not included. $(D_PARAM * BaseClassesTuple!Object) yields the empty type tuple. */ @@ -3967,16 +3967,16 @@ template BaseClassesTuple(T) { static if (is(T == Object)) { - alias BaseClassesTuple = TypeTuple!(); + alias BaseClassesTuple = AliasSeq!(); } else static if (is(BaseTypeTuple!T[0] == Object)) { - alias BaseClassesTuple = TypeTuple!Object; + alias BaseClassesTuple = AliasSeq!Object; } else { alias BaseClassesTuple = - TypeTuple!(BaseTypeTuple!T[0], + AliasSeq!(BaseTypeTuple!T[0], BaseClassesTuple!(BaseTypeTuple!T[0])); } } @@ -3988,9 +3988,9 @@ template BaseClassesTuple(T) class C2 : C1 { } class C3 : C2 { } static assert(!BaseClassesTuple!Object.length); - static assert(is(BaseClassesTuple!C1 == TypeTuple!(Object))); - static assert(is(BaseClassesTuple!C2 == TypeTuple!(C1, Object))); - static assert(is(BaseClassesTuple!C3 == TypeTuple!(C2, C1, Object))); + static assert(is(BaseClassesTuple!C1 == AliasSeq!(Object))); + static assert(is(BaseClassesTuple!C2 == AliasSeq!(C1, Object))); + static assert(is(BaseClassesTuple!C3 == AliasSeq!(C2, C1, Object))); } @safe unittest @@ -4001,11 +4001,11 @@ template BaseClassesTuple(T) static assert(!__traits(compiles, BaseClassesTuple!I)); class C4 : I { } class C5 : C4, I { } - static assert(is(BaseClassesTuple!C5 == TypeTuple!(C4, Object))); + static assert(is(BaseClassesTuple!C5 == AliasSeq!(C4, Object))); } /** - * Get a $(D_PARAM TypeTuple) of $(I all) interfaces directly or + * Get a $(D_PARAM AliasSeq) of $(I all) interfaces directly or * indirectly inherited by this class or interface. Interfaces do not * repeat if multiply implemented. $(D_PARAM InterfacesTuple!Object) * yields the empty type tuple. @@ -4017,12 +4017,12 @@ template InterfacesTuple(T) { static if (T.length) { - alias Flatten = TypeTuple!(Flatten!H, Flatten!T); + alias Flatten = AliasSeq!(Flatten!H, Flatten!T); } else { static if (is(H == interface)) - alias Flatten = TypeTuple!(H, InterfacesTuple!H); + alias Flatten = AliasSeq!(H, InterfacesTuple!H); else alias Flatten = InterfacesTuple!H; } @@ -4031,7 +4031,7 @@ template InterfacesTuple(T) static if (is(T S == super) && S.length) alias InterfacesTuple = NoDuplicates!(Flatten!S); else - alias InterfacesTuple = TypeTuple!(); + alias InterfacesTuple = AliasSeq!(); } @safe unittest @@ -4059,14 +4059,14 @@ template InterfacesTuple(T) class B2 : J {} class C2 : B2, Ia, Ib {} static assert(is(InterfacesTuple!I == - TypeTuple!(Ia, Iaa, Iab, Ib, Iba, Ibb))); + AliasSeq!(Ia, Iaa, Iab, Ib, Iba, Ibb))); static assert(is(InterfacesTuple!C2 == - TypeTuple!(J, Ia, Iaa, Iab, Ib, Iba, Ibb))); + AliasSeq!(J, Ia, Iaa, Iab, Ib, Iba, Ibb))); } /** - * Get a $(D_PARAM TypeTuple) of $(I all) base classes of $(D_PARAM + * Get a $(D_PARAM AliasSeq) of $(I all) base classes of $(D_PARAM * T), in decreasing order, followed by $(D_PARAM T)'s * interfaces. $(D_PARAM TransitiveBaseTypeTuple!Object) yields the * empty type tuple. @@ -4074,10 +4074,10 @@ template InterfacesTuple(T) template TransitiveBaseTypeTuple(T) { static if (is(T == Object)) - alias TransitiveBaseTypeTuple = TypeTuple!(); + alias TransitiveBaseTypeTuple = AliasSeq!(); else alias TransitiveBaseTypeTuple = - TypeTuple!(BaseClassesTuple!T, InterfacesTuple!T); + AliasSeq!(BaseClassesTuple!T, InterfacesTuple!T); } /// @@ -4118,28 +4118,28 @@ template MemberFunctionsTuple(C, string name) static if (__traits(hasMember, Node, name) && __traits(compiles, __traits(getMember, Node, name))) { // Get all overloads in sight (not hidden). - alias inSight = TypeTuple!(__traits(getVirtualFunctions, Node, name)); + alias inSight = AliasSeq!(__traits(getVirtualFunctions, Node, name)); // And collect all overloads in ancestor classes to reveal hidden // methods. The result may contain duplicates. template walkThru(Parents...) { static if (Parents.length > 0) - alias walkThru = TypeTuple!( + alias walkThru = AliasSeq!( CollectOverloads!(Parents[0]), walkThru!(Parents[1 .. $]) ); else - alias walkThru = TypeTuple!(); + alias walkThru = AliasSeq!(); } static if (is(Node Parents == super)) - alias CollectOverloads = TypeTuple!(inSight, walkThru!Parents); + alias CollectOverloads = AliasSeq!(inSight, walkThru!Parents); else - alias CollectOverloads = TypeTuple!inSight; + alias CollectOverloads = AliasSeq!inSight; } else - alias CollectOverloads = TypeTuple!(); // no overloads in this hierarchy + alias CollectOverloads = AliasSeq!(); // no overloads in this hierarchy } // duplicates in this tuple will be removed by shrink() @@ -4174,13 +4174,13 @@ template MemberFunctionsTuple(C, string name) alias shrinkOne = shrinkOne!(rest[0], rest[1 .. $]); else // target and rest[0] are distinct. - alias shrinkOne = TypeTuple!( + alias shrinkOne = AliasSeq!( shrinkOne!(target, rest[1 .. $]), rest[0] // keep ); } else - alias shrinkOne = TypeTuple!target; // done + alias shrinkOne = AliasSeq!target; // done } /* @@ -4191,17 +4191,17 @@ template MemberFunctionsTuple(C, string name) static if (overloads.length > 0) { alias temp = shrinkOne!overloads; - alias shrink = TypeTuple!(temp[0], shrink!(temp[1 .. $])); + alias shrink = AliasSeq!(temp[0], shrink!(temp[1 .. $])); } else - alias shrink = TypeTuple!(); // done + alias shrink = AliasSeq!(); // done } // done. alias MemberFunctionsTuple = shrink!overloads; } else - alias MemberFunctionsTuple = TypeTuple!(); + alias MemberFunctionsTuple = AliasSeq!(); } /// @@ -4328,7 +4328,7 @@ template TemplateOf(T : Base!Args, alias Base, Args...) /** -Returns a $(D TypeTuple) of the template arguments used to instantiate $(D T). +Returns a $(D AliasSeq) of the template arguments used to instantiate $(D T). */ template TemplateArgsOf(alias T : Base!Args, alias Base, Args...) { @@ -4345,7 +4345,7 @@ template TemplateArgsOf(T : Base!Args, alias Base, Args...) @safe unittest { struct Foo(T, U) {} - static assert(is(TemplateArgsOf!(Foo!(int, real)) == TypeTuple!(int, real))); + static assert(is(TemplateArgsOf!(Foo!(int, real)) == AliasSeq!(int, real))); } @safe unittest @@ -4362,15 +4362,15 @@ template TemplateArgsOf(T : Base!Args, alias Base, Args...) enum x = 123; enum y = "123"; - static assert(is(TemplateArgsOf!(Foo1!(int)) == TypeTuple!(int))); - static assert(is(TemplateArgsOf!(Foo2!(int, int)) == TypeTuple!(int, int))); - static assert(__traits(isSame, TemplateArgsOf!(Foo3!(x)), TypeTuple!(x))); - static assert(TemplateArgsOf!(Foo4!(y)) == TypeTuple!(y)); - static assert(is(TemplateArgsOf!(Foo5!(int)) == TypeTuple!(int))); - static assert(is(TemplateArgsOf!(Foo6!(int, int)) == TypeTuple!(int, int))); - static assert(__traits(isSame, TemplateArgsOf!(Foo7!(x)), TypeTuple!(x))); - static assert(is(TemplateArgsOf!(Foo8!(int).Foo9!(real)) == TypeTuple!(real))); - static assert(is(TemplateArgsOf!(Foo10!()) == TypeTuple!())); + static assert(is(TemplateArgsOf!(Foo1!(int)) == AliasSeq!(int))); + static assert(is(TemplateArgsOf!(Foo2!(int, int)) == AliasSeq!(int, int))); + static assert(__traits(isSame, TemplateArgsOf!(Foo3!(x)), AliasSeq!(x))); + static assert(TemplateArgsOf!(Foo4!(y)) == AliasSeq!(y)); + static assert(is(TemplateArgsOf!(Foo5!(int)) == AliasSeq!(int))); + static assert(is(TemplateArgsOf!(Foo6!(int, int)) == AliasSeq!(int, int))); + static assert(__traits(isSame, TemplateArgsOf!(Foo7!(x)), AliasSeq!(x))); + static assert(is(TemplateArgsOf!(Foo8!(int).Foo9!(real)) == AliasSeq!(real))); + static assert(is(TemplateArgsOf!(Foo10!()) == AliasSeq!())); } @@ -4476,62 +4476,62 @@ template ImplicitConversionTargets(T) { static if (is(T == bool)) alias ImplicitConversionTargets = - TypeTuple!(byte, ubyte, short, ushort, int, uint, long, ulong, CentTypeList, + AliasSeq!(byte, ubyte, short, ushort, int, uint, long, ulong, CentTypeList, float, double, real, char, wchar, dchar); else static if (is(T == byte)) alias ImplicitConversionTargets = - TypeTuple!(short, ushort, int, uint, long, ulong, CentTypeList, + AliasSeq!(short, ushort, int, uint, long, ulong, CentTypeList, float, double, real, char, wchar, dchar); else static if (is(T == ubyte)) alias ImplicitConversionTargets = - TypeTuple!(short, ushort, int, uint, long, ulong, CentTypeList, + AliasSeq!(short, ushort, int, uint, long, ulong, CentTypeList, float, double, real, char, wchar, dchar); else static if (is(T == short)) alias ImplicitConversionTargets = - TypeTuple!(int, uint, long, ulong, CentTypeList, float, double, real); + AliasSeq!(int, uint, long, ulong, CentTypeList, float, double, real); else static if (is(T == ushort)) alias ImplicitConversionTargets = - TypeTuple!(int, uint, long, ulong, CentTypeList, float, double, real); + AliasSeq!(int, uint, long, ulong, CentTypeList, float, double, real); else static if (is(T == int)) alias ImplicitConversionTargets = - TypeTuple!(long, ulong, CentTypeList, float, double, real); + AliasSeq!(long, ulong, CentTypeList, float, double, real); else static if (is(T == uint)) alias ImplicitConversionTargets = - TypeTuple!(long, ulong, CentTypeList, float, double, real); + AliasSeq!(long, ulong, CentTypeList, float, double, real); else static if (is(T == long)) - alias ImplicitConversionTargets = TypeTuple!(float, double, real); + alias ImplicitConversionTargets = AliasSeq!(float, double, real); else static if (is(T == ulong)) - alias ImplicitConversionTargets = TypeTuple!(float, double, real); + alias ImplicitConversionTargets = AliasSeq!(float, double, real); else static if (is(cent) && is(T == cent)) - alias ImplicitConversionTargets = TypeTuple!(float, double, real); + alias ImplicitConversionTargets = AliasSeq!(float, double, real); else static if (is(ucent) && is(T == ucent)) - alias ImplicitConversionTargets = TypeTuple!(float, double, real); + alias ImplicitConversionTargets = AliasSeq!(float, double, real); else static if (is(T == float)) - alias ImplicitConversionTargets = TypeTuple!(double, real); + alias ImplicitConversionTargets = AliasSeq!(double, real); else static if (is(T == double)) - alias ImplicitConversionTargets = TypeTuple!real; + alias ImplicitConversionTargets = AliasSeq!real; else static if (is(T == char)) alias ImplicitConversionTargets = - TypeTuple!(wchar, dchar, byte, ubyte, short, ushort, + AliasSeq!(wchar, dchar, byte, ubyte, short, ushort, int, uint, long, ulong, CentTypeList, float, double, real); else static if (is(T == wchar)) alias ImplicitConversionTargets = - TypeTuple!(dchar, short, ushort, int, uint, long, ulong, CentTypeList, + AliasSeq!(dchar, short, ushort, int, uint, long, ulong, CentTypeList, float, double, real); else static if (is(T == dchar)) alias ImplicitConversionTargets = - TypeTuple!(int, uint, long, ulong, CentTypeList, float, double, real); + AliasSeq!(int, uint, long, ulong, CentTypeList, float, double, real); else static if (is(T : typeof(null))) - alias ImplicitConversionTargets = TypeTuple!(typeof(null)); + alias ImplicitConversionTargets = AliasSeq!(typeof(null)); else static if (is(T : Object)) alias ImplicitConversionTargets = TransitiveBaseTypeTuple!(T); else static if (isDynamicArray!T && !is(typeof(T.init[0]) == const)) alias ImplicitConversionTargets = - TypeTuple!(const(Unqual!(typeof(T.init[0])))[]); + AliasSeq!(const(Unqual!(typeof(T.init[0])))[]); else static if (is(T : void*)) - alias ImplicitConversionTargets = TypeTuple!(void*); + alias ImplicitConversionTargets = AliasSeq!(void*); else - alias ImplicitConversionTargets = TypeTuple!(); + alias ImplicitConversionTargets = AliasSeq!(); } @safe unittest @@ -5019,7 +5019,7 @@ int i = rvalueOf!int; // error, no actual value is returned static struct S { } int i; struct Nested { void f() { ++i; } } - foreach (T; TypeTuple!(int, immutable int, inout int, string, S, Nested, Object)) + foreach (T; AliasSeq!(int, immutable int, inout int, string, S, Nested, Object)) { static assert(!__traits(compiles, needLvalue(rvalueOf!T))); static assert( __traits(compiles, needLvalue(lvalueOf!T))); @@ -5039,7 +5039,7 @@ int i = rvalueOf!int; // error, no actual value is returned private template AliasThisTypeOf(T) if (isAggregateType!T) { - alias members = TypeTuple!(__traits(getAliasThis, T)); + alias members = AliasSeq!(__traits(getAliasThis, T)); static if (members.length == 1) { @@ -5069,14 +5069,14 @@ template BooleanTypeOf(T) @safe unittest { // unexpected failure, maybe dmd type-merging bug - foreach (T; TypeTuple!bool) + foreach (T; AliasSeq!bool) foreach (Q; TypeQualifierList) { static assert( is(Q!T == BooleanTypeOf!( Q!T ))); static assert( is(Q!T == BooleanTypeOf!( SubTypeOf!(Q!T) ))); } - foreach (T; TypeTuple!(void, NumericTypeList, ImaginaryTypeList, ComplexTypeList, CharTypeList)) + foreach (T; AliasSeq!(void, NumericTypeList, ImaginaryTypeList, ComplexTypeList, CharTypeList)) foreach (Q; TypeQualifierList) { static assert(!is(BooleanTypeOf!( Q!T )), Q!T.stringof); @@ -5127,7 +5127,7 @@ template IntegralTypeOf(T) static assert( is(Q!T == IntegralTypeOf!( SubTypeOf!(Q!T) ))); } - foreach (T; TypeTuple!(void, bool, FloatingPointTypeList, ImaginaryTypeList, ComplexTypeList, CharTypeList)) + foreach (T; AliasSeq!(void, bool, FloatingPointTypeList, ImaginaryTypeList, ComplexTypeList, CharTypeList)) foreach (Q; TypeQualifierList) { static assert(!is(IntegralTypeOf!( Q!T ))); @@ -5162,7 +5162,7 @@ template FloatingPointTypeOf(T) static assert( is(Q!T == FloatingPointTypeOf!( SubTypeOf!(Q!T) ))); } - foreach (T; TypeTuple!(void, bool, IntegralTypeList, ImaginaryTypeList, ComplexTypeList, CharTypeList)) + foreach (T; AliasSeq!(void, bool, IntegralTypeList, ImaginaryTypeList, ComplexTypeList, CharTypeList)) foreach (Q; TypeQualifierList) { static assert(!is(FloatingPointTypeOf!( Q!T ))); @@ -5191,7 +5191,7 @@ template NumericTypeOf(T) static assert( is(Q!T == NumericTypeOf!( SubTypeOf!(Q!T) ))); } - foreach (T; TypeTuple!(void, bool, CharTypeList, ImaginaryTypeList, ComplexTypeList)) + foreach (T; AliasSeq!(void, bool, CharTypeList, ImaginaryTypeList, ComplexTypeList)) foreach (Q; TypeQualifierList) { static assert(!is(NumericTypeOf!( Q!T ))); @@ -5252,14 +5252,14 @@ template CharTypeOf(T) static assert( is(CharTypeOf!( SubTypeOf!(Q!T) ))); } - foreach (T; TypeTuple!(void, bool, NumericTypeList, ImaginaryTypeList, ComplexTypeList)) + foreach (T; AliasSeq!(void, bool, NumericTypeList, ImaginaryTypeList, ComplexTypeList)) foreach (Q; TypeQualifierList) { static assert(!is(CharTypeOf!( Q!T ))); static assert(!is(CharTypeOf!( SubTypeOf!(Q!T) ))); } - foreach (T; TypeTuple!(string, wstring, dstring, char[4])) + foreach (T; AliasSeq!(string, wstring, dstring, char[4])) foreach (Q; TypeQualifierList) { static assert(!is(CharTypeOf!( Q!T ))); @@ -5284,8 +5284,8 @@ template StaticArrayTypeOf(T) @safe unittest { - foreach (T; TypeTuple!(bool, NumericTypeList, ImaginaryTypeList, ComplexTypeList)) - foreach (Q; TypeTuple!(TypeQualifierList, InoutOf, SharedInoutOf)) + foreach (T; AliasSeq!(bool, NumericTypeList, ImaginaryTypeList, ComplexTypeList)) + foreach (Q; AliasSeq!(TypeQualifierList, InoutOf, SharedInoutOf)) { static assert(is( Q!( T[1] ) == StaticArrayTypeOf!( Q!( T[1] ) ) )); @@ -5295,8 +5295,8 @@ template StaticArrayTypeOf(T) } } - foreach (T; TypeTuple!void) - foreach (Q; TypeTuple!TypeQualifierList) + foreach (T; AliasSeq!void) + foreach (Q; AliasSeq!TypeQualifierList) { static assert(is( StaticArrayTypeOf!( Q!(void[1]) ) == Q!(void[1]) )); } @@ -5321,13 +5321,13 @@ template DynamicArrayTypeOf(T) @safe unittest { - foreach (T; TypeTuple!(/*void, */bool, NumericTypeList, ImaginaryTypeList, ComplexTypeList)) - foreach (Q; TypeTuple!(TypeQualifierList, InoutOf, SharedInoutOf)) + foreach (T; AliasSeq!(/*void, */bool, NumericTypeList, ImaginaryTypeList, ComplexTypeList)) + foreach (Q; AliasSeq!(TypeQualifierList, InoutOf, SharedInoutOf)) { static assert(is( Q!T[] == DynamicArrayTypeOf!( Q!T[] ) )); static assert(is( Q!(T[]) == DynamicArrayTypeOf!( Q!(T[]) ) )); - foreach (P; TypeTuple!(MutableOf, ConstOf, ImmutableOf)) + foreach (P; AliasSeq!(MutableOf, ConstOf, ImmutableOf)) { static assert(is( Q!(P!T[]) == DynamicArrayTypeOf!( Q!(SubTypeOf!(P!T[])) ) )); static assert(is( Q!(P!(T[])) == DynamicArrayTypeOf!( Q!(SubTypeOf!(P!(T[]))) ) )); @@ -5377,7 +5377,7 @@ template StringTypeOf(T) @safe unittest { foreach (T; CharTypeList) - foreach (Q; TypeTuple!(MutableOf, ConstOf, ImmutableOf, InoutOf)) + foreach (Q; AliasSeq!(MutableOf, ConstOf, ImmutableOf, InoutOf)) { static assert(is(Q!T[] == StringTypeOf!( Q!T[] ))); @@ -5392,7 +5392,7 @@ template StringTypeOf(T) } foreach (T; CharTypeList) - foreach (Q; TypeTuple!(SharedOf, SharedConstOf, SharedInoutOf)) + foreach (Q; AliasSeq!(SharedOf, SharedConstOf, SharedInoutOf)) { static assert(!is(StringTypeOf!( Q!T[] ))); } @@ -5422,19 +5422,19 @@ template AssocArrayTypeOf(T) @safe unittest { - foreach (T; TypeTuple!(int/*bool, CharTypeList, NumericTypeList, ImaginaryTypeList, ComplexTypeList*/)) - foreach (P; TypeTuple!(TypeQualifierList, InoutOf, SharedInoutOf)) - foreach (Q; TypeTuple!(TypeQualifierList, InoutOf, SharedInoutOf)) - foreach (R; TypeTuple!(TypeQualifierList, InoutOf, SharedInoutOf)) + foreach (T; AliasSeq!(int/*bool, CharTypeList, NumericTypeList, ImaginaryTypeList, ComplexTypeList*/)) + foreach (P; AliasSeq!(TypeQualifierList, InoutOf, SharedInoutOf)) + foreach (Q; AliasSeq!(TypeQualifierList, InoutOf, SharedInoutOf)) + foreach (R; AliasSeq!(TypeQualifierList, InoutOf, SharedInoutOf)) { static assert(is( P!(Q!T[R!T]) == AssocArrayTypeOf!( P!(Q!T[R!T]) ) )); } - foreach (T; TypeTuple!(int/*bool, CharTypeList, NumericTypeList, ImaginaryTypeList, ComplexTypeList*/)) - foreach (O; TypeTuple!(TypeQualifierList, InoutOf, SharedInoutOf)) - foreach (P; TypeTuple!TypeQualifierList) - foreach (Q; TypeTuple!TypeQualifierList) - foreach (R; TypeTuple!TypeQualifierList) + foreach (T; AliasSeq!(int/*bool, CharTypeList, NumericTypeList, ImaginaryTypeList, ComplexTypeList*/)) + foreach (O; AliasSeq!(TypeQualifierList, InoutOf, SharedInoutOf)) + foreach (P; AliasSeq!TypeQualifierList) + foreach (Q; AliasSeq!TypeQualifierList) + foreach (R; AliasSeq!TypeQualifierList) { static assert(is( O!(P!(Q!T[R!T])) == AssocArrayTypeOf!( O!(SubTypeOf!(P!(Q!T[R!T]))) ) )); } @@ -5580,7 +5580,7 @@ enum bool isFloatingPoint(T) = __traits(isFloating, T) && !(is(Unqual!T == cfloa { enum EF : real { a = 1.414, b = 1.732, c = 2.236 } - foreach (T; TypeTuple!(FloatingPointTypeList, EF)) + foreach (T; AliasSeq!(FloatingPointTypeList, EF)) { foreach (Q; TypeQualifierList) { @@ -5653,7 +5653,7 @@ enum bool isNumeric(T) = __traits(isArithmetic, T) && !(is(Unqual!T == bool) || @safe unittest { - foreach (T; TypeTuple!(NumericTypeList)) + foreach (T; AliasSeq!(NumericTypeList)) { foreach (Q; TypeQualifierList) { @@ -5754,7 +5754,7 @@ enum bool isUnsigned(T) = __traits(isUnsigned, T) && !(is(Unqual!T == char) || @safe unittest { - foreach (T; TypeTuple!(UnsignedIntTypeList)) + foreach (T; AliasSeq!(UnsignedIntTypeList)) { foreach (Q; TypeQualifierList) { @@ -5798,7 +5798,7 @@ enum bool isSigned(T) = __traits(isArithmetic, T) && !__traits(isUnsigned, T); enum Eubyte : ubyte { e1 = 0 } static assert(!isSigned!Eubyte); - foreach (T; TypeTuple!(SignedIntTypeList)) + foreach (T; AliasSeq!(SignedIntTypeList)) { foreach (Q; TypeQualifierList) { @@ -5854,7 +5854,7 @@ enum bool isSomeChar(T) = is(CharTypeOf!T) && !isAggregateType!T; { enum EC : char { a = 'x', b = 'y' } - foreach (T; TypeTuple!(CharTypeList, EC)) + foreach (T; AliasSeq!(CharTypeList, EC)) { foreach (Q; TypeQualifierList) { @@ -5906,7 +5906,7 @@ enum bool isSomeString(T) = is(StringTypeOf!T) && !isAggregateType!T && !isStati @safe unittest { - foreach (T; TypeTuple!(char[], dchar[], string, wstring, dstring)) + foreach (T; AliasSeq!(char[], dchar[], string, wstring, dstring)) { static assert( isSomeString!( T )); static assert(!isSomeString!(SubTypeOf!(T))); @@ -5935,16 +5935,16 @@ enum bool isNarrowString(T) = (is(T : const char[]) || is(T : const wchar[])) && @safe unittest { - foreach (T; TypeTuple!(char[], string, wstring)) + foreach (T; AliasSeq!(char[], string, wstring)) { - foreach (Q; TypeTuple!(MutableOf, ConstOf, ImmutableOf)/*TypeQualifierList*/) + foreach (Q; AliasSeq!(MutableOf, ConstOf, ImmutableOf)/*TypeQualifierList*/) { static assert( isNarrowString!( Q!T )); static assert(!isNarrowString!( SubTypeOf!(Q!T) )); } } - foreach (T; TypeTuple!(int, int[], byte[], dchar[], dstring, char[4])) + foreach (T; AliasSeq!(int, int[], byte[], dchar[], dstring, char[4])) { foreach (Q; TypeQualifierList) { @@ -6051,7 +6051,7 @@ enum bool isStaticArray(T) = __traits(isStaticArray, T); @safe unittest { - foreach (T; TypeTuple!(int[51], int[][2], + foreach (T; AliasSeq!(int[51], int[][2], char[][int][11], immutable char[13u], const(real)[1], const(real)[1][1], void[0])) { @@ -6139,7 +6139,7 @@ enum bool isAssociativeArray(T) = __traits(isAssociativeArray, T); @property uint[] values() { return null; } } - foreach (T; TypeTuple!(int[int], int[string], immutable(char[5])[int])) + foreach (T; AliasSeq!(int[int], int[string], immutable(char[5])[int])) { foreach (Q; TypeQualifierList) { @@ -6205,7 +6205,7 @@ enum bool isPointer(T) = is(T == U*, U) && !isAggregateType!T; @safe unittest { - foreach (T; TypeTuple!(int*, void*, char[]*)) + foreach (T; AliasSeq!(int*, void*, char[]*)) { foreach (Q; TypeQualifierList) { @@ -7190,10 +7190,10 @@ template mostNegative(T) /// @safe unittest { - foreach (T; TypeTuple!(bool, byte, short, int, long)) + foreach (T; AliasSeq!(bool, byte, short, int, long)) static assert(mostNegative!T == T.min); - foreach (T; TypeTuple!(ubyte, ushort, uint, ulong, char, wchar, dchar)) + foreach (T; AliasSeq!(ubyte, ushort, uint, ulong, char, wchar, dchar)) static assert(mostNegative!T == 0); } @@ -7222,14 +7222,14 @@ unittest unittest { // promote to int: - foreach (T; TypeTuple!(bool, byte, ubyte, short, ushort, char, wchar)) + foreach (T; AliasSeq!(bool, byte, ubyte, short, ushort, char, wchar)) { static assert(is(Promoted!T == int)); static assert(is(Promoted!(shared(const T)) == shared(const int))); } // already promoted: - foreach (T; TypeTuple!(int, uint, long, ulong, float, double, real)) + foreach (T; AliasSeq!(int, uint, long, ulong, float, double, real)) { static assert(is(Promoted!T == T)); static assert(is(Promoted!(immutable(T)) == immutable(T))); From c336bb96cf8a0a1b4be57c25d6ef59e3ef781b54 Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Thu, 15 Jun 2017 06:56:09 +0200 Subject: [PATCH 016/163] Issue 17224 - Remove std.typetuple from the documentation build --- posix.mak | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/posix.mak b/posix.mak index c0107ed2c0f..d2f6531a207 100644 --- a/posix.mak +++ b/posix.mak @@ -179,7 +179,7 @@ PACKAGE_std = array ascii base64 bigint bitmanip compiler complex concurrency \ conv csv demangle encoding exception file format \ functional getopt json math mathspecial meta mmfile numeric \ outbuffer parallelism path process random signals socket stdint \ - stdio string system traits typecons typetuple uni \ + stdio string system traits typecons uni \ uri utf uuid variant xml zip zlib PACKAGE_std_experimental = checkedint typecons PACKAGE_std_algorithm = comparison iteration mutation package searching setops \ @@ -227,6 +227,7 @@ EXTRA_MODULES_INTERNAL := $(addprefix std/, \ processinit scopebuffer test/dummyrange \ $(addprefix unicode_, comp decomp grapheme norm tables) \ ) \ + typetuple \ ) EXTRA_MODULES += $(EXTRA_DOCUMENTABLES) $(EXTRA_MODULES_INTERNAL) From f6615959e8d81b918644932c5f7840014cde783d Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Thu, 15 Jun 2017 17:43:48 +0200 Subject: [PATCH 017/163] Fix booktable in std.traits --- std/traits.d | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/std/traits.d b/std/traits.d index 506dd3ffeaf..75c7c0ad85d 100644 --- a/std/traits.d +++ b/std/traits.d @@ -66,21 +66,19 @@ * $(LREF isImplicitlyConvertible) * )) * $(TR $(TD SomethingTypeOf) $(TD - * $(LREF BooleanTypeOf) - * $(LREF IntegralTypeOf) - * $(LREF FloatingPointTypeOf) - * $(LREF NumericTypeOf) - * $(LREF UnsignedTypeOf) - * $(LREF SignedTypeOf) - * $(LREF CharTypeOf) - * $(LREF StaticArrayTypeOf) - * $(LREF DynamicArrayTypeOf) - * $(LREF ArrayTypeOf) - * $(LREF StringTypeOf) - * $(LREF AssocArrayTypeOf) - * $(LREF BuiltinTypeOf) + * $(LREF rvalueOf) + * $(LREF lvalueOf) + * $(LREF InoutOf) + * $(LREF ConstOf) + * $(LREF SharedOf) + * $(LREF SharedInoutOf) + * $(LREF SharedConstOf) + * $(LREF ImmutableOf) + * $(LREF QualifierOf) * )) * $(TR $(TD Categories of types) $(TD + * $(LREF allSameType) + * $(LREF ifTestable) * $(LREF isType) * $(LREF isAggregateType) * $(LREF isArray) From 1c91f39000b114a051dbef498e82492c0a544644 Mon Sep 17 00:00:00 2001 From: Vladimir Panteleev Date: Sun, 18 Jun 2017 08:18:59 +0000 Subject: [PATCH 018/163] std.range.package: Fix DDoc syntax https://github.com/dlang/dlang.org/pull/1526#issuecomment-309263501 --- std/range/package.d | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/std/range/package.d b/std/range/package.d index 27e1e9c3c5f..fee18a6a272 100644 --- a/std/range/package.d +++ b/std/range/package.d @@ -2921,13 +2921,13 @@ pure @safe nothrow @nogc unittest /++ Convenience function which calls - `range.$(REF popFrontN, std, range, primitives)(n) and returns `range`. + $(REF popFrontN, std, _range, primitives)`(range, n)` and returns `range`. `drop` makes it easier to pop elements from a range and then pass it to another function within a single expression, whereas `popFrontN` would require multiple statements. `dropBack` provides the same functionality but instead calls - `range.$(REF popBackN, std, range, primitives)(n) + $(REF popBackN, std, _range, primitives)`(range, n)` Note: `drop` and `dropBack` will only pop $(I up to) `n` elements but will stop if the range is empty first. From f77a768843ef492e6141bd1055a03b70252492dd Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Mon, 19 Jun 2017 12:55:12 +0200 Subject: [PATCH 019/163] Use Dscanner with selective checks --- posix.mak | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/posix.mak b/posix.mak index 653bb8e870e..0eabd8dd372 100644 --- a/posix.mak +++ b/posix.mak @@ -522,8 +522,8 @@ checkwhitespace: $(LIB) $(TOOLS_DIR)/checkwhitespace.d ############################# ../dscanner: - git clone https://github.com/Hackerpilot/Dscanner ../dscanner - git -C ../dscanner checkout tags/v0.4.0 + git clone https://github.com/dlang-community/Dscanner ../dscanner + git -C ../dscanner checkout phobos git -C ../dscanner submodule update --init --recursive ../dscanner/dsc: ../dscanner From 43b33c6b98b2a490d7e2f085b383735970b1c7f9 Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Mon, 19 Jun 2017 13:02:53 +0200 Subject: [PATCH 020/163] Enable selective module checks --- .dscanner.ini | 85 +++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 62 insertions(+), 23 deletions(-) diff --git a/.dscanner.ini b/.dscanner.ini index a2b0999c75a..0fe24530b48 100644 --- a/.dscanner.ini +++ b/.dscanner.ini @@ -2,20 +2,20 @@ [analysis.config.StaticAnalysisConfig] ; Check variable, class, struct, interface, union, and function names against ; the Phobos style guide -style_check="disabled" +style_check="enabled" ; Check for array literals that cause unnecessary allocation enum_array_literal_check="enabled" ; Check for poor exception handling practices -exception_check="disabled" ; FIXME +exception_check="enabled" ; Check for use of the deprecated 'delete' keyword delete_check="enabled" ; Check for use of the deprecated floating point operators float_operator_check="enabled" ; Check number literals for readability -number_style_check="skip-unittest"; +number_style_check="enabled" ; Checks that opEquals, opCmp, toHash, and toString are either const, immutable ; , or inout. -object_const_check="disabled" +object_const_check="enabled" ; Checks for .. expressions where the left side is larger than the right. backwards_range_check="enabled" ; Checks for if statements whose 'then' block is the same as the 'else' block @@ -23,43 +23,44 @@ if_else_same_check="enabled" ; Checks for some problems with constructors constructor_check="enabled" ; Checks for unused variables and function parameters -unused_variable_check="disabled" +unused_variable_check="enabled" ; Checks for unused labels -unused_label_check="disabled" ; FIXME +unused_label_check="enabled" ; Checks for duplicate attributes duplicate_attribute="enabled" ; Checks that opEquals and toHash are both defined or neither are defined -opequals_tohash_check="disabled" +opequals_tohash_check="enabled" ; Checks for subtraction from .length properties -length_subtraction_check="disabled" -; Checks for methods or properties whose names conflict with built-in properties -builtin_property_names_check="enabled"; FIXME +length_subtraction_check="enabled" +; Checks for methods or properties whose names conflict with built-in propertie +; s +builtin_property_names_check="enabled" ; Checks for confusing code in inline asm statements -asm_style_check="disabled"; FIXME +asm_style_check="enabled" ; Checks for confusing logical operator precedence -logical_precedence_check="disabled" +logical_precedence_check="enabled" ; Checks for undocumented public declarations -undocumented_declaration_check="disabled"; FIXME +undocumented_declaration_check="enabled" ; Checks for poor placement of function attributes -function_attribute_check="disabled" +function_attribute_check="enabled" ; Checks for use of the comma operator comma_expression_check="enabled" ; Checks for local imports that are too broad local_import_check="skip-unittest" ; Checks for variables that could be declared immutable -could_be_immutable_check="disabled" +could_be_immutable_check="enabled" ; Checks for redundant expressions in if statements redundant_if_check="enabled" ; Checks for redundant parenthesis redundant_parens_check="enabled" ; Checks for mismatched argument and parameter names -mismatched_args_check="disabled" +mismatched_args_check="enabled" ; Checks for labels with the same name as variables -label_var_same_name_check="disabled" +label_var_same_name_check="enabled" ; Checks for lines longer than 120 characters long_line_check="enabled" ; Checks for assignment to auto-ref function parameters -auto_ref_assignment_check="disabled" ; FIXME +auto_ref_assignment_check="enabled" ; Checks for incorrect infinite range definitions incorrect_infinite_range_check="enabled" ; Checks for asserts that are always true @@ -71,10 +72,48 @@ static_if_else_check="enabled" ; Check for unclear lambda syntax lambda_return_check="enabled" ; Check for auto function without return statement -auto_function_check = "enabled" -; Check for explicitly annotated unittests -explicitly_annotated_unittests = "enabled" +auto_function_check="enabled" ; Check for sortedness of imports -imports_sortedness = "disabled" +imports_sortedness="enabled" +; Check for explicitly annotated unittests +explicitly_annotated_unittests="enabled" +; Check for properly documented public functions (Returns, Params) +properly_documented_public_functions="enabled" ; Check for useless usage of the final attribute -final_attribute_check = "enabled" +final_attribute_check="enabled" +; Check for virtual calls in the class constructors +vcall_in_ctor="enabled" +; Check for useless user defined initializers +useless_initializer="enabled" +; Check allman brace style +allman_braces_check="disabled" +; Check for redundant attributes +redundant_attributes_check="enabled" + +; Configure which modules are checked with a specific checker +; Please help to extend these checks onto more Phobos modules +[analysis.config.ModuleFilters] +asm_style_check="+std.algorithm" +auto_ref_assignment_check="+std.algorithm.searching" +could_be_immutable_check="+std.algorithm.internal" +exception_check="+std.algorithm" +function_attribute_check="+std.algorithm.searching" +imports_sortedness = "+std.algorithm.disabled" ; currently disabled, see https://github.com/dlang/phobos/pull/5478 +label_var_same_name_check="+std.algorithm.searching" +length_subtraction_check="+std.algorithm.comparison" +logical_precedence_check="+std.algorithm.internal" +long_line_check="-std.regex.internal.thompson"; Dscanner bug: https://github.com/dlang-community/D-Scanner/pull/465 +mismatched_args_check="+std.algorithm" +mismatched_args_check="+std.algorithm" +number_style_check="+std.algorithm.searching" +object_const_check="+std.algorithm.internal" +opequals_tohash_check="+std.algorithm.comparison" +redundant_attributes_check = "+std.algorithm" +style_check="+std.algorithm.searching" +undocumented_declaration_check="+std.algorithm.searching" +unused_label_check="+std.algorithm" +unused_variable_check="+std.algorithm.internal" +useless_initializer = "+std.algorithm.comparison" +vcall_in_ctor="-std.socket,-std.xml" +properly_documented_public_functions="+std.algorithm.internal" +explicitly_annotated_unittests="+std.algorithm.searching" From 5facd9b6740640863ebdee1cc6f452fc17c31c59 Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Mon, 19 Jun 2017 13:03:27 +0200 Subject: [PATCH 021/163] Remove unused label --- std/algorithm/sorting.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/std/algorithm/sorting.d b/std/algorithm/sorting.d index 99ac551649e..e18f2d0d9b7 100644 --- a/std/algorithm/sorting.d +++ b/std/algorithm/sorting.d @@ -3402,7 +3402,7 @@ body r.swapAt(rite, pivot); } // Second loop: make left and pivot meet - outer: for (; rite > pivot; --rite) + for (; rite > pivot; --rite) { if (!lp(r[rite], r[oldPivot])) continue; while (rite > pivot) From ffc6ec5d6b5ca81cc4c97cbce4c7874d476898f6 Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Mon, 19 Jun 2017 13:13:42 +0200 Subject: [PATCH 022/163] Remove has_public_example in favor of Dscanner Previously one could only apply a check for an entire codebase and not selectively for specific modules. As a temporary solution, has_public_example has been introduced - a standalone checker with filtering capabilities. However, with selective filtering integrated in Dscanner, the analog Dscanner check `explicitly_annotated_unittests` can be used. --- .dscanner.ini | 2 +- circle.yml | 1 - circleci.sh | 7 ------- posix.mak | 8 +------- 4 files changed, 2 insertions(+), 16 deletions(-) diff --git a/.dscanner.ini b/.dscanner.ini index 0fe24530b48..8a092861bbd 100644 --- a/.dscanner.ini +++ b/.dscanner.ini @@ -116,4 +116,4 @@ unused_variable_check="+std.algorithm.internal" useless_initializer = "+std.algorithm.comparison" vcall_in_ctor="-std.socket,-std.xml" properly_documented_public_functions="+std.algorithm.internal" -explicitly_annotated_unittests="+std.algorithm.searching" +explicitly_annotated_unittests="-std.array,-std.allocator,-std.base64,-std.bitmanip,-std.concurrency,-std.conv,-std.csv,-std.datetime,-std.demangle,-std.digest.hmac,-std.digest.sha,-std.encoding,-std.exception,-std.file,-std.format,-std.getopt,-std.internal,-std.isemail,-std.json,-std.logger.core,-std.logger.nulllogger,-std.math,-std.mathspecial,-std.net.curl,-std.numeric,-std.parallelism,-std.path,-std.process,-std.random,-std.range,-std.regex,-std.socket,-std.stdio,-std.string,-std.traits,-std.typecons,-std.uni,-std.uri,-std.utf,-std.uuid,-std.xml,-std.zlib" diff --git a/circle.yml b/circle.yml index 72801310c99..aedcc77f9fb 100644 --- a/circle.yml +++ b/circle.yml @@ -8,7 +8,6 @@ test: override: - ./circleci.sh setup-repos - ./circleci.sh style_lint - - ./circleci.sh has_public_example - ./circleci.sh publictests - ./circleci.sh coverage: parallel: true diff --git a/circleci.sh b/circleci.sh index 80e528b5ac4..8865a3c7a0b 100755 --- a/circleci.sh +++ b/circleci.sh @@ -133,18 +133,11 @@ publictests() make -f posix.mak -j$N publictests DUB=$DUB } -# check modules for public unittests -has_public_example() -{ - make -f posix.mak -j$N has_public_example DUB=$DUB -} - case $1 in install-deps) install_deps ;; setup-repos) setup_repos ;; coverage) coverage ;; publictests) publictests ;; - has_public_example) has_public_example;; style_lint) style_lint ;; *) echo "Unknown command"; exit 1;; esac diff --git a/posix.mak b/posix.mak index 0eabd8dd372..582477ea58c 100644 --- a/posix.mak +++ b/posix.mak @@ -506,7 +506,6 @@ ${TOOLS_DIR}: git clone --depth=1 ${GIT_HOME}/$(@F) $@ $(TOOLS_DIR)/checkwhitespace.d: | $(TOOLS_DIR) $(TOOLS_DIR)/styles/tests_extractor.d: | $(TOOLS_DIR) -$(TOOLS_DIR)/styles/has_public_example.d: | $(TOOLS_DIR) #################### test for undesired white spaces ########################## CWS_TOCHECK = posix.mak win32.mak win64.mak osmodel.mak @@ -532,7 +531,7 @@ checkwhitespace: $(LIB) $(TOOLS_DIR)/checkwhitespace.d mv dscanner_makefile_tmp ../dscanner/makefile make -C ../dscanner githash debug -style: has_public_example publictests style_lint +style: publictests style_lint style_lint: ../dscanner/dsc $(LIB) @echo "Check for trailing whitespace" @@ -599,11 +598,6 @@ $(TEST_EXTRACTOR): $(TOOLS_DIR)/styles/tests_extractor.d $(LIB) @$(TEST_EXTRACTOR) --inputdir $< --outputdir $(PUBLICTESTS_DIR) @$(DMD) $(DFLAGS) -defaultlib= -debuglib= $(LIB) -main -unittest -run $(PUBLICTESTS_DIR)/$(subst /,_,$<) -has_public_example: $(LIB) - # checks whether public function have public examples (for now some modules are excluded) - rm -rf ./out - DFLAGS="$(DFLAGS) $(LIB) $(LINKDL)" $(DUB) -v --compiler=$${PWD}/$(DMD) --root=../tools/styles -c has_public_example -- --inputdir std --ignore "array.d,allocator,base64.d,bitmanip.d,concurrency.d,conv.d,csv.d,datetime/date.d,datetime/interval.d,datetime/package.d,datetime/stopwatch.d,datetime/systime.d,datetime/timezone.d,demangle.d,digest/hmac.d,digest/sha.d,encoding.d,exception.d,file.d,format.d,getopt.d,index.d,internal,isemail.d,json.d,logger/core.d,logger/nulllogger.d,math.d,mathspecial.d,net/curl.d,numeric.d,parallelism.d,path.d,process.d,random.d,range,regex/package.d,socket.d,stdio.d,string.d,traits.d,typecons.d,uni.d,unittest.d,uri.d,utf.d,uuid.d,xml.d,zlib.d" - .PHONY : auto-tester-build auto-tester-build: all checkwhitespace From 3a13b1212021769f9e417c641b4dbb2b6fbad48c Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Mon, 19 Jun 2017 14:06:49 +0200 Subject: [PATCH 023/163] Use current DMD to compile Dscanner --- posix.mak | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/posix.mak b/posix.mak index 582477ea58c..6b6c9bb0a3e 100644 --- a/posix.mak +++ b/posix.mak @@ -525,11 +525,11 @@ checkwhitespace: $(LIB) $(TOOLS_DIR)/checkwhitespace.d git -C ../dscanner checkout phobos git -C ../dscanner submodule update --init --recursive -../dscanner/dsc: ../dscanner +../dscanner/dsc: ../dscanner $(DMD) $(LIB) # debug build is faster, but disable 'missing import' messages (missing core from druntime) sed 's/dparse_verbose/StdLoggerDisableWarning/' ../dscanner/makefile > dscanner_makefile_tmp mv dscanner_makefile_tmp ../dscanner/makefile - make -C ../dscanner githash debug + DC=$(DMD) DFLAGS="$(DFLAGS) -defaultlib=$(LIB)" make -C ../dscanner githash debug style: publictests style_lint From 3d447171f327f8fdfccacdb122108e5ea47bb62d Mon Sep 17 00:00:00 2001 From: Walter Bright Date: Mon, 19 Jun 2017 15:28:48 -0700 Subject: [PATCH 024/163] osmodel.mak: add comments --- osmodel.mak | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/osmodel.mak b/osmodel.mak index d0f160ae374..dd94b4098bc 100644 --- a/osmodel.mak +++ b/osmodel.mak @@ -1,5 +1,15 @@ -# This Makefile snippet detects the OS and the architecture MODEL -# Keep this file in sync between druntime, phobos, and dmd repositories! +# osmodel.mak +# +# Detects and sets the macros: +# +# OS = one of {osx,linux,freebsd,openbsd,netbsd,solaris} +# MODEL = one of { 32, 64 } +# MODEL_FLAG = one of { -m32, -m64 } +# +# Note: +# Keep this file in sync between druntime, phobos, and dmd repositories! +# Source: https://github.com/dlang/phobos/blob/master/osmodel.mak + ifeq (,$(OS)) uname_S:=$(shell uname -s) @@ -12,12 +22,12 @@ ifeq (,$(OS)) ifeq (FreeBSD,$(uname_S)) OS:=freebsd endif - ifeq (NetBSD,$(uname_S)) - OS:=netbsd - endif ifeq (OpenBSD,$(uname_S)) OS:=openbsd endif + ifeq (NetBSD,$(uname_S)) + OS:=netbsd + endif ifeq (Solaris,$(uname_S)) OS:=solaris endif From 2ec7e9199beff75beaf0f9903d179c2d7021a361 Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Tue, 20 Jun 2017 01:11:00 +0200 Subject: [PATCH 025/163] Fix Ddoc comments --- std/datetime/timezone.d | 2 +- std/net/curl.d | 4 ++-- std/regex/package.d | 5 ++++- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/std/datetime/timezone.d b/std/datetime/timezone.d index 0b3bfa74e2d..066b150b559 100644 --- a/std/datetime/timezone.d +++ b/std/datetime/timezone.d @@ -3347,7 +3347,7 @@ else version(Posix) does. Params: - windowsZonesXMLFileText The text from + windowsZonesXMLText = The text from $(HTTP unicode.org/cldr/data/common/supplemental/windowsZones.xml, windowsZones.xml) Throws: diff --git a/std/net/curl.d b/std/net/curl.d index e8212735363..6740ecfd86b 100644 --- a/std/net/curl.d +++ b/std/net/curl.d @@ -2933,7 +2933,7 @@ struct HTTP * * code = http.getTiming(CurlInfo.namelookup_time, val); * assert(code == CurlError.ok); - *--- + * --- */ CurlCode getTiming(CurlInfo timing, ref double val) { @@ -3648,7 +3648,7 @@ struct FTP * * code = http.getTiming(CurlInfo.namelookup_time, val); * assert(code == CurlError.ok); - *--- + * --- */ CurlCode getTiming(CurlInfo timing, ref double val) { diff --git a/std/regex/package.d b/std/regex/package.d index 3b7c4e7c2a8..9e66f7eacf4 100644 --- a/std/regex/package.d +++ b/std/regex/package.d @@ -350,7 +350,10 @@ public alias StaticRegex(Char) = std.regex.internal.ir.StaticRegex!(Char); the same character width as $(D pattern). Params: - pattern(s) = Regular expression(s) to match + pattern = A single regular expression to match. + patterns = An array of regular expression strings. + The resulting `Regex` object will match any expression; + use $(LREF whichPattern) to know which. flags = The _attributes (g, i, m and x accepted) Throws: $(D RegexException) if there were any errors during compilation. From 77f68cafa31c39637cb8c0c63e5ed0c63034cec4 Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Wed, 21 Jun 2017 06:42:31 +0200 Subject: [PATCH 026/163] Fix long lines in Phobos --- .dscanner.ini | 3 ++- std/range/package.d | 3 ++- std/uni.d | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.dscanner.ini b/.dscanner.ini index 8a092861bbd..33ebda224dd 100644 --- a/.dscanner.ini +++ b/.dscanner.ini @@ -102,7 +102,8 @@ imports_sortedness = "+std.algorithm.disabled" ; currently disabled, see https:/ label_var_same_name_check="+std.algorithm.searching" length_subtraction_check="+std.algorithm.comparison" logical_precedence_check="+std.algorithm.internal" -long_line_check="-std.regex.internal.thompson"; Dscanner bug: https://github.com/dlang-community/D-Scanner/pull/465 +; Checks for lines with more than 120 visual characters - see https://github.com/dlang/phobos/pull/5500 for details +long_line_check="-std.datetime.timezone" mismatched_args_check="+std.algorithm" mismatched_args_check="+std.algorithm" number_style_check="+std.algorithm.searching" diff --git a/std/range/package.d b/std/range/package.d index fee18a6a272..589cf127ce2 100644 --- a/std/range/package.d +++ b/std/range/package.d @@ -4566,7 +4566,8 @@ private string lockstepMixin(Ranges...)(bool withIndex, bool reverse) { indexDef = q{ size_t index = ranges[0].length-1; - enforce(_stoppingPolicy == StoppingPolicy.requireSameLength, "lockstep can only be used with foreach_reverse when stoppingPolicy == requireSameLength"); + enforce(_stoppingPolicy == StoppingPolicy.requireSameLength, + "lockstep can only be used with foreach_reverse when stoppingPolicy == requireSameLength"); foreach (range; ranges[1..$]) enforce(range.length == ranges[0].length); diff --git a/std/uni.d b/std/uni.d index d71e482063b..40c4799c1d7 100644 --- a/std/uni.d +++ b/std/uni.d @@ -6288,7 +6288,8 @@ enum EMPTY_CASE_TRIE = ushort.max;// from what gen_uni uses internally // control - '\r' enum controlSwitch = ` - case '\u0000':..case '\u0008':case '\u000E':..case '\u001F':case '\u007F':..case '\u0084':case '\u0086':..case '\u009F': case '\u0009':..case '\u000C': case '\u0085': + case '\u0000':..case '\u0008':case '\u000E':..case '\u001F':case '\u007F':.. + case '\u0084':case '\u0086':..case '\u009F': case '\u0009':..case '\u000C': case '\u0085': `; // TODO: redo the most of hangul stuff algorithmically in case of Graphemes too // kill unrolled switches From 483f163982d7bc3a80ae6252f83f2514f945b977 Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Wed, 21 Jun 2017 07:31:17 +0200 Subject: [PATCH 027/163] Fix DScanner to a specific commit --- posix.mak | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/posix.mak b/posix.mak index 6b6c9bb0a3e..12d32423118 100644 --- a/posix.mak +++ b/posix.mak @@ -522,7 +522,7 @@ checkwhitespace: $(LIB) $(TOOLS_DIR)/checkwhitespace.d ../dscanner: git clone https://github.com/dlang-community/Dscanner ../dscanner - git -C ../dscanner checkout phobos + git -C ../dscanner checkout 455cc3fe50e6d0742c866737b4ac24669d51a992 git -C ../dscanner submodule update --init --recursive ../dscanner/dsc: ../dscanner $(DMD) $(LIB) From f3770ba1d675ed952012cbfc8dd38b823e1d3ca7 Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Wed, 21 Jun 2017 09:58:21 +0200 Subject: [PATCH 028/163] Fix Issue 17539 - std.parallellism.parallel triggers 'statement not reachable' --- std/parallelism.d | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/std/parallelism.d b/std/parallelism.d index 51d322172d0..3207bb56d9b 100644 --- a/std/parallelism.d +++ b/std/parallelism.d @@ -3500,7 +3500,7 @@ int doSizeZeroCase(R, Delegate)(ref ParallelForeach!R p, Delegate dg) { res = dg(elem); } - if (res) foreachErr(); + if (res) break; index++; } } @@ -3516,10 +3516,11 @@ int doSizeZeroCase(R, Delegate)(ref ParallelForeach!R p, Delegate dg) { res = dg(elem); } - if (res) foreachErr(); + if (res) break; index++; } } + if (res) foreachErr; return res; } } @@ -4624,3 +4625,12 @@ version(unittest) arr.parallel.each!"a++"; }))); } + +// https://issues.dlang.org/show_bug.cgi?id=17539 +@system unittest +{ + import std.random : rndGen; + // ensure compilation + try foreach (rnd; rndGen.parallel) break; + catch (ParallelForeachError e) {} +} From bbcbae55fdf2e3d17b7e1d19b299aaaf462d5322 Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Wed, 21 Jun 2017 06:52:33 +0200 Subject: [PATCH 029/163] DScanner: Enable a check blacklist for a gradual transition --- .dscanner.ini | 85 +++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 62 insertions(+), 23 deletions(-) diff --git a/.dscanner.ini b/.dscanner.ini index 33ebda224dd..33613858e46 100644 --- a/.dscanner.ini +++ b/.dscanner.ini @@ -86,35 +86,74 @@ vcall_in_ctor="enabled" ; Check for useless user defined initializers useless_initializer="enabled" ; Check allman brace style -allman_braces_check="disabled" +allman_braces_check="enabled" ; Check for redundant attributes redundant_attributes_check="enabled" ; Configure which modules are checked with a specific checker ; Please help to extend these checks onto more Phobos modules +; Process: +; - Pick your favorite check +; - Remove a module from the blacklist +; - Run DScanner +; - Fix the warnings +; - Submit a PR to Phobos +; - GOTO: Remove a module +; +; Some checks are currently disabled. +; For more details, please see https://github.com/dlang/phobos/pull/5501 [analysis.config.ModuleFilters] -asm_style_check="+std.algorithm" -auto_ref_assignment_check="+std.algorithm.searching" -could_be_immutable_check="+std.algorithm.internal" -exception_check="+std.algorithm" -function_attribute_check="+std.algorithm.searching" -imports_sortedness = "+std.algorithm.disabled" ; currently disabled, see https://github.com/dlang/phobos/pull/5478 -label_var_same_name_check="+std.algorithm.searching" -length_subtraction_check="+std.algorithm.comparison" -logical_precedence_check="+std.algorithm.internal" +; Check allman brace style +allman_braces_check="+disabled" +; Checks for confusing code in inline asm statements +asm_style_check="-std.math" +; Checks for assignment to auto-ref function parameters +auto_ref_assignment_check="-std.algorithm.mutation,-std.format" +; Checks for variables that could be declared immutable +could_be_immutable_check="-std.algorithm.comparison,-std.algorithm.iteration,-std.algorithm.mutation,-std.algorithm.searching,-std.algorithm.setops,-std.algorithm.sorting,-std.array,-std.base64,-std.bigint,-std.bitmanip,-std.complex,-std.concurrency,-std.container,-std.container.array,-std.container.binaryheap,-std.container.dlist,-std.container.rbtree,-std.container.slist,-std.container.util,-std.conv,-std.csv,-std.datetime,-std.datetime.date,-std.datetime.interval,-std.datetime.stopwatch,-std.datetime.systime,-std.datetime.timezone,-std.digest.crc,-std.digest.digest,-std.digest.hmac,-std.digest.md,-std.digest.murmurhash,-std.digest.ripemd,-std.digest.sha,-std.encoding,-std.exception,-std.experimental.allocator,-std.experimental.allocator.building_blocks.affix_allocator,-std.experimental.allocator.building_blocks.allocator_list,-std.experimental.allocator.building_blocks.bitmapped_block,-std.experimental.allocator.building_blocks.bucketizer,-std.experimental.allocator.building_blocks.fallback_allocator,-std.experimental.allocator.building_blocks.free_list,-std.experimental.allocator.building_blocks.free_tree,-std.experimental.allocator.building_blocks.kernighan_ritchie,-std.experimental.allocator.building_blocks.region,-std.experimental.allocator.building_blocks.stats_collector,-std.experimental.allocator.gc_allocator,-std.experimental.allocator.mallocator,-std.experimental.allocator.typed,-std.experimental.checkedint,-std.experimental.logger.core,-std.experimental.logger.multilogger,-std.experimental.typecons,-std.file,-std.format,-std.functional,-std.getopt,-std.internal.cstring,-std.internal.digest.sha_SSSE3,-std.internal.math.biguintcore,-std.internal.math.biguintnoasm,-std.internal.math.biguintx86,-std.internal.math.errorfunction,-std.internal.math.gammafunction,-std.internal.scopebuffer,-std.internal.test.dummyrange,-std.json,-std.math,-std.mathspecial,-std.meta,-std.mmfile,-std.net.curl,-std.net.isemail,-std.numeric,-std.outbuffer,-std.parallelism,-std.path,-std.process,-std.random,-std.range,-std.range.interfaces,-std.range.primitives,-std.regex,-std.regex.internal.backtracking,-std.regex.internal.generator,-std.regex.internal.ir,-std.regex.internal.kickstart,-std.regex.internal.parser,-std.regex.internal.tests,-std.regex.internal.thompson,-std.signals,-std.socket,-std.stdio,-std.string,-std.uni,-std.uri,-std.utf,-std.uuid,-std.variant,-std.windows.registry,-std.xml,-std.zip,-std.zlib" +; Check for poor exception handling practices +exception_check="-std.concurrency,-std.net.curl,-std.parallelism,-std.range,-std.socket" +; Checks for poor placement of function attributes +function_attribute_check="-std.algorithm.iteration,-std.concurrency,-std.conv,-std.datetime.interval,-std.exception,-std.functional,-std.net.curl,-std.numeric,-std.parallelism,-std.random,-std.range,-std.range.primitives,-std.socket,-std.uni" +; Check for sortedness of imports +imports_sortedness="+disabled" +;imports_sortedness="-etc.c.curl,-std.algorithm.comparison,-std.algorithm.internal,-std.algorithm.iteration,-std.algorithm.mutation,-std.algorithm.searching,-std.algorithm.setops,-std.algorithm.sorting,-std.array,-std.bigint,-std.bitmanip,-std.c.freebsd.socket,-std.c.linux.pthread,-std.c.process,-std.complex,-std.concurrency,-std.container.array,-std.container.binaryheap,-std.container.dlist,-std.container.rbtree,-std.container.slist,-std.container.util,-std.conv,-std.datetime,-std.datetime.date,-std.datetime.interval,-std.datetime.systime,-std.datetime.timezone,-std.digest.digest,-std.digest.hmac,-std.exception,-std.experimental.allocator,-std.experimental.allocator.building_blocks,-std.experimental.allocator.building_blocks.affix_allocator,-std.experimental.allocator.building_blocks.allocator_list,-std.experimental.allocator.building_blocks.free_list,-std.experimental.allocator.building_blocks.free_tree,-std.experimental.allocator.building_blocks.kernighan_ritchie,-std.experimental.allocator.building_blocks.region,-std.experimental.allocator.common,-std.experimental.allocator.mallocator,-std.experimental.allocator.mmap_allocator,-std.experimental.allocator.showcase,-std.experimental.allocator.typed,-std.experimental.checkedint,-std.experimental.logger.core,-std.experimental.typecons,-std.file,-std.format,-std.functional,-std.getopt,-std.internal.math.biguintcore,-std.internal.test.dummyrange,-std.json,-std.math,-std.meta,-std.mmfile,-std.net.curl,-std.net.isemail,-std.numeric,-std.outbuffer,-std.parallelism,-std.path,-std.process,-std.random,-std.range,-std.range.primitives,-std.regex,-std.regex.internal.backtracking,-std.regex.internal.generator,-std.regex.internal.kickstart,-std.regex.internal.parser,-std.regex.internal.tests,-std.signals,-std.socket,-std.stdio,-std.string,-std.uni,-std.utf,-std.uuid,-std.variant,-std.windows.charset,-std.windows.registry,-std.windows.syserror,-std.zip" +; Checks for labels with the same name as variables +label_var_same_name_check="-std.algorithm.iteration,-std.algorithm.sorting,-std.array,-std.bigint,-std.bitmanip,-std.conv,-std.encoding,-std.experimental.allocator.building_blocks.segregator,-std.experimental.typecons,-std.format,-std.internal.digest.sha_SSSE3,-std.parallelism,-std.process,-std.utf" +; Checks for subtraction from .length properties +length_subtraction_check="+disabled" +;length_subtraction_check="-std.algorithm.internal,-std.algorithm.iteration,-std.algorithm.mutation,-std.algorithm.searching,-std.algorithm.sorting,-std.array,-std.concurrency,-std.container.array,-std.container.binaryheap,-std.conv,-std.datetime.timezone,-std.experimental.allocator.building_blocks.segregator,-std.experimental.logger.core,-std.file,-std.format,-std.getopt,-std.internal.math.biguintcore,-std.internal.math.biguintnoasm,-std.internal.math.biguintx86,-std.internal.scopebuffer,-std.math,-std.net.curl,-std.net.isemail,-std.numeric,-std.parallelism,-std.path,-std.process,-std.range,-std.regex,-std.regex.internal.parser,-std.regex.internal.tests,-std.string,-std.uni,-std.windows.charset,-std.windows.registry,-std.zip" +; Checks for confusing logical operator precedence +logical_precedence_check="+disabled" +;logical_precedence_check="-std.algorithm.mutation,-std.algorithm.searching,-std.algorithm.setops,-std.algorithm.sorting,-std.array,-std.container.array,-std.conv,-std.experimental.checkedint,-std.file,-std.format,-std.getopt,-std.math,-std.net.isemail,-std.path,-std.range,-std.range.primitives,-std.stdio,-std.string" ; Checks for lines with more than 120 visual characters - see https://github.com/dlang/phobos/pull/5500 for details long_line_check="-std.datetime.timezone" -mismatched_args_check="+std.algorithm" -mismatched_args_check="+std.algorithm" -number_style_check="+std.algorithm.searching" -object_const_check="+std.algorithm.internal" -opequals_tohash_check="+std.algorithm.comparison" -redundant_attributes_check = "+std.algorithm" -style_check="+std.algorithm.searching" -undocumented_declaration_check="+std.algorithm.searching" -unused_label_check="+std.algorithm" -unused_variable_check="+std.algorithm.internal" -useless_initializer = "+std.algorithm.comparison" +; Checks for mismatched argument and parameter names +mismatched_args_check="-std.container.dlist,-std.encoding,-std.internal.math.biguintcore,-std.math,-std.net.curl,-std.numeric,-std.range.primitives,-std.uni" +; Check number literals for readability +number_style_check="+disabled" +;number_style_check="-std.algorithm.iteration,-std.algorithm.sorting,-std.array,-std.bigint,-std.bitmanip,-std.container.array,-std.conv,-std.datetime.date,-std.datetime.systime,-std.datetime.timezone,-std.digest.crc,-std.digest.digest,-std.digest.md,-std.digest.ripemd,-std.digest.sha,-std.experimental.allocator.building_blocks.free_tree,-std.experimental.allocator.building_blocks.kernighan_ritchie,-std.experimental.checkedint,-std.file,-std.format,-std.functional,-std.internal.math.biguintcore,-std.internal.math.gammafunction,-std.json,-std.math,-std.outbuffer,-std.parallelism,-std.random,-std.range,-std.regex.internal.generator,-std.utf,-std.zip,-std.zlib" +; Checks that opEquals, opCmp, toHash, and toString are either const, immutable +; , or inout. +object_const_check="-std.algorithm.searching,-std.array,-std.bitmanip,-std.concurrency,-std.container.rbtree,-std.conv,-std.datetime.interval,-std.encoding,-std.exception,-std.experimental.checkedint,-std.experimental.logger.core,-std.experimental.typecons,-std.format,-std.functional,-std.meta,-std.numeric,-std.range,-std.regex,-std.stdio,-std.variant,-std.xml" +; Checks that opEquals and toHash are both defined or neither are defined +opequals_tohash_check="-std.algorithm.searching,-std.array,-std.complex,-std.container.array,-std.container.dlist,-std.container.rbtree,-std.container.slist,-std.datetime,-std.datetime.date,-std.experimental.checkedint,-std.functional,-std.internal.test.dummyrange,-std.json,-std.numeric,-std.random,-std.range,-std.socket,-std.uni" +; Check for properly documented public functions (Returns, Params) +properly_documented_public_functions="-etc.c.odbc.sql,-etc.c.odbc.sqlext,-etc.c.zlib,-std.algorithm.comparison,-std.algorithm.iteration,-std.algorithm.mutation,-std.algorithm.searching,-std.algorithm.setops,-std.algorithm.sorting,-std.array,-std.ascii,-std.base64,-std.bigint,-std.bitmanip,-std.complex,-std.container,-std.container.array,-std.container.binaryheap,-std.container.dlist,-std.container.rbtree,-std.container.slist,-std.container.util,-std.csv,-std.datetime,-std.datetime.date,-std.datetime.interval,-std.datetime.stopwatch,-std.datetime.systime,-std.datetime.timezone,-std.demangle,-std.digest.crc,-std.digest.digest,-std.digest.hmac,-std.digest.md,-std.digest.murmurhash,-std.digest.ripemd,-std.digest.sha,-std.encoding,-std.exception,-std.experimental.allocator,-std.experimental.allocator.building_blocks.affix_allocator,-std.experimental.allocator.building_blocks.allocator_list,-std.experimental.allocator.building_blocks.bitmapped_block,-std.experimental.allocator.building_blocks.bucketizer,-std.experimental.allocator.building_blocks.fallback_allocator,-std.experimental.allocator.building_blocks.free_list,-std.experimental.allocator.building_blocks.free_tree,-std.experimental.allocator.building_blocks.kernighan_ritchie,-std.experimental.allocator.building_blocks.null_allocator,-std.experimental.allocator.building_blocks.quantizer,-std.experimental.allocator.building_blocks.region,-std.experimental.allocator.building_blocks.scoped_allocator,-std.experimental.allocator.building_blocks.segregator,-std.experimental.allocator.building_blocks.stats_collector,-std.experimental.allocator.common,-std.experimental.allocator.gc_allocator,-std.experimental.allocator.mallocator,-std.experimental.allocator.showcase,-std.experimental.allocator.typed,-std.experimental.checkedint,-std.experimental.logger.core,-std.experimental.logger.filelogger,-std.file,-std.format,-std.functional,-std.getopt,-std.internal.cstring,-std.internal.math.biguintcore,-std.internal.math.biguintnoasm,-std.internal.scopebuffer,-std.internal.test.dummyrange,-std.internal.unicode_tables,-std.json,-std.math,-std.mathspecial,-std.meta,-std.mmfile,-std.net.curl,-std.net.isemail,-std.numeric,-std.outbuffer,-std.parallelism,-std.path,-std.random,-std.range,-std.range.interfaces,-std.range.primitives,-std.regex,-std.regex.internal.backtracking,-std.regex.internal.ir,-std.regex.internal.kickstart,-std.regex.internal.parser,-std.regex.internal.thompson,-std.signals,-std.socket,-std.stdio,-std.string,-std.uni,-std.uri,-std.utf,-std.uuid,-std.variant,-std.xml,-std.zip,-std.zlib" +; Check for redundant attributes +redundant_attributes_check="-std.concurrency,-std.digest.md,-std.digest.ripemd,-std.digest.sha,-std.internal.math.biguintcore,-std.math,-std.meta,-std.range,-std.regex.internal.ir,-std.uni,-std.windows.registry" +; Check variable, class, struct, interface, union, and function names against +; the Phobos style guide +style_check="+disabled" +;style_check="-etc.c.curl,-etc.c.odbc.sqlext,-etc.c.odbc.sqltypes,-etc.c.odbc.sqlucode,-etc.c.sqlite3,-etc.c.zlib,-std.algorithm.comparison,-std.algorithm.internal,-std.algorithm.iteration,-std.algorithm.mutation,-std.algorithm.sorting,-std.array,-std.base64,-std.bitmanip,-std.c.linux.linux,-std.compiler,-std.container.array,-std.conv,-std.datetime.date,-std.datetime.interval,-std.datetime.systime,-std.digest.digest,-std.digest.murmurhash,-std.digest.sha,-std.encoding,-std.exception,-std.experimental.allocator,-std.experimental.allocator.building_blocks.affix_allocator,-std.experimental.allocator.building_blocks.allocator_list,-std.experimental.allocator.building_blocks.bucketizer,-std.experimental.allocator.building_blocks.fallback_allocator,-std.experimental.allocator.building_blocks.free_list,-std.experimental.allocator.building_blocks.free_tree,-std.experimental.allocator.building_blocks.null_allocator,-std.experimental.allocator.building_blocks.region,-std.experimental.allocator.building_blocks.segregator,-std.experimental.allocator.common,-std.experimental.allocator.gc_allocator,-std.experimental.allocator.mallocator,-std.experimental.allocator.mmap_allocator,-std.experimental.checkedint,-std.experimental.typecons,-std.format,-std.functional,-std.getopt,-std.internal.digest.sha_SSSE3,-std.internal.math.errorfunction,-std.internal.math.gammafunction,-std.internal.test.dummyrange,-std.internal.unicode_tables,-std.json,-std.math,-std.meta,-std.numeric,-std.parallelism,-std.path,-std.process,-std.random,-std.range,-std.range.primitives,-std.regex,-std.regex.internal.ir,-std.regex.internal.kickstart,-std.signals,-std.socket,-std.stdio,-std.string,-std.uni,-std.uri,-std.utf,-std.uuid,-std.variant,-std.zlib" +; Checks for undocumented public declarations +undocumented_declaration_check="-etc.c.curl,-etc.c.odbc.sql,-etc.c.odbc.sqlext,-etc.c.odbc.sqltypes,-etc.c.odbc.sqlucode,-etc.c.sqlite3,-etc.c.zlib,-std.algorithm.sorting,-std.array,-std.ascii,-std.base64,-std.bitmanip,-std.c.linux.linux,-std.c.linux.socket,-std.c.osx.socket,-std.c.process,-std.compiler,-std.complex,-std.concurrency,-std.container,-std.container.array,-std.container.binaryheap,-std.container.dlist,-std.container.rbtree,-std.container.slist,-std.conv,-std.csv,-std.datetime.date,-std.digest.digest,-std.digest.hmac,-std.digest.md,-std.digest.murmurhash,-std.digest.ripemd,-std.digest.sha,-std.encoding,-std.exception,-std.experimental.allocator,-std.experimental.allocator.building_blocks.affix_allocator,-std.experimental.allocator.building_blocks.allocator_list,-std.experimental.allocator.building_blocks.bitmapped_block,-std.experimental.allocator.building_blocks.fallback_allocator,-std.experimental.allocator.building_blocks.free_list,-std.experimental.allocator.building_blocks.free_tree,-std.experimental.allocator.building_blocks.kernighan_ritchie,-std.experimental.allocator.building_blocks.quantizer,-std.experimental.allocator.building_blocks.region,-std.experimental.allocator.building_blocks.segregator,-std.experimental.allocator.building_blocks.stats_collector,-std.experimental.allocator.gc_allocator,-std.experimental.allocator.mallocator,-std.experimental.checkedint,-std.experimental.logger.core,-std.experimental.typecons,-std.file,-std.format,-std.functional,-std.internal.digest.sha_SSSE3,-std.internal.math.biguintcore,-std.internal.math.biguintnoasm,-std.internal.math.biguintx86,-std.internal.math.errorfunction,-std.internal.math.gammafunction,-std.internal.test.dummyrange,-std.internal.test.uda,-std.internal.windows.advapi32,-std.json,-std.math,-std.mmfile,-std.numeric,-std.outbuffer,-std.parallelism,-std.path,-std.process,-std.regex,-std.regex.internal.parser,-std.signals,-std.socket,-std.stdio,-std.string,-std.system,-std.uni,-std.utf,-std.variant,-std.windows.charset,-std.windows.registry,-std.windows.syserror,-std.xml,-std.zip,-std.zlib" +; Checks for unused labels +unused_label_check="-std.conv,-std.format,-std.internal.math.biguintx86,-std.regex.internal.thompson,-std.signals,-std.uni" +; Checks for unused variables and function parameters +unused_variable_check="-std.algorithm.comparison,-std.algorithm.iteration,-std.algorithm.mutation,-std.algorithm.searching,-std.algorithm.setops,-std.algorithm.sorting,-std.array,-std.bigint,-std.bitmanip,-std.complex,-std.concurrency,-std.container,-std.container.array,-std.container.dlist,-std.container.rbtree,-std.container.slist,-std.conv,-std.csv,-std.datetime,-std.datetime.date,-std.datetime.interval,-std.datetime.stopwatch,-std.datetime.systime,-std.datetime.timezone,-std.digest.crc,-std.digest.digest,-std.digest.md,-std.digest.murmurhash,-std.digest.ripemd,-std.digest.sha,-std.encoding,-std.exception,-std.experimental.allocator,-std.experimental.allocator.building_blocks.affix_allocator,-std.experimental.allocator.building_blocks.bitmapped_block,-std.experimental.allocator.building_blocks.bucketizer,-std.experimental.allocator.building_blocks.kernighan_ritchie,-std.experimental.allocator.building_blocks.stats_collector,-std.experimental.allocator.common,-std.experimental.allocator.gc_allocator,-std.experimental.allocator.mallocator,-std.experimental.allocator.typed,-std.experimental.checkedint,-std.experimental.logger.core,-std.experimental.typecons,-std.file,-std.format,-std.functional,-std.getopt,-std.internal.cstring,-std.internal.digest.sha_SSSE3,-std.internal.math.biguintcore,-std.internal.math.biguintx86,-std.internal.math.errorfunction,-std.internal.scopebuffer,-std.internal.test.dummyrange,-std.json,-std.math,-std.meta,-std.mmfile,-std.net.curl,-std.numeric,-std.parallelism,-std.process,-std.random,-std.range,-std.range.interfaces,-std.range.primitives,-std.regex.internal.backtracking,-std.regex.internal.tests,-std.regex.internal.thompson,-std.signals,-std.socket,-std.stdio,-std.string,-std.uni,-std.uri,-std.utf,-std.uuid,-std.variant,-std.windows.registry,-std.xml,-std.zip,-std.zlib" +; Check for useless user defined initializers +useless_initializer="+disabled" +;useless_initializer="-etc.c.odbc.sqlext,-etc.c.zlib,-std.algorithm.iteration,-std.algorithm.mutation,-std.algorithm.searching,-std.algorithm.setops,-std.algorithm.sorting,-std.array,-std.bigint,-std.bitmanip,-std.compiler,-std.container.array,-std.container.dlist,-std.container.rbtree,-std.conv,-std.csv,-std.datetime.systime,-std.digest.md,-std.digest.murmurhash,-std.digest.ripemd,-std.encoding,-std.exception,-std.experimental.allocator,-std.experimental.allocator.building_blocks.bitmapped_block,-std.experimental.allocator.building_blocks.free_tree,-std.experimental.allocator.building_blocks.kernighan_ritchie,-std.experimental.allocator.common,-std.experimental.allocator.mallocator,-std.experimental.logger.core,-std.experimental.logger.multilogger,-std.file,-std.format,-std.functional,-std.getopt,-std.internal.cstring,-std.internal.digest.sha_SSSE3,-std.internal.math.biguintcore,-std.internal.math.biguintnoasm,-std.internal.math.biguintx86,-std.internal.math.gammafunction,-std.internal.test.dummyrange,-std.json,-std.math,-std.net.curl,-std.numeric,-std.parallelism,-std.path,-std.process,-std.random,-std.range,-std.range.interfaces,-std.range.primitives,-std.regex,-std.regex.internal.backtracking,-std.regex.internal.generator,-std.regex.internal.ir,-std.regex.internal.kickstart,-std.regex.internal.parser,-std.regex.internal.tests,-std.regex.internal.thompson,-std.signals,-std.socket,-std.stdio,-std.string,-std.uni,-std.uri,-std.utf,-std.uuid,-std.variant,-std.windows.registry,-std.windows.syserror,-std.xml,-std.zip,-std.zlib" +; Check for virtual calls in the class constructors vcall_in_ctor="-std.socket,-std.xml" -properly_documented_public_functions="+std.algorithm.internal" -explicitly_annotated_unittests="-std.array,-std.allocator,-std.base64,-std.bitmanip,-std.concurrency,-std.conv,-std.csv,-std.datetime,-std.demangle,-std.digest.hmac,-std.digest.sha,-std.encoding,-std.exception,-std.file,-std.format,-std.getopt,-std.internal,-std.isemail,-std.json,-std.logger.core,-std.logger.nulllogger,-std.math,-std.mathspecial,-std.net.curl,-std.numeric,-std.parallelism,-std.path,-std.process,-std.random,-std.range,-std.regex,-std.socket,-std.stdio,-std.string,-std.traits,-std.typecons,-std.uni,-std.uri,-std.utf,-std.uuid,-std.xml,-std.zlib" From a47530b97b3aa29c55fda27f672b63a3c750537e Mon Sep 17 00:00:00 2001 From: Lionello Lunesu Date: Thu, 22 Jun 2017 16:39:27 +0800 Subject: [PATCH 030/163] Added Base64URLNoPadding (backport from vibe.d) --- changelog/std-base64-base64urlnopadding.dd | 11 +++++++++++ std/base64.d | 22 +++++++++++++++++++--- 2 files changed, 30 insertions(+), 3 deletions(-) create mode 100644 changelog/std-base64-base64urlnopadding.dd diff --git a/changelog/std-base64-base64urlnopadding.dd b/changelog/std-base64-base64urlnopadding.dd new file mode 100644 index 00000000000..2d4d64e38ac --- /dev/null +++ b/changelog/std-base64-base64urlnopadding.dd @@ -0,0 +1,11 @@ +`Base64URLNoPadding` (URL-safe Base64 without padding) was added + +$(REF Base64URLNoPadding, std, base64) allows encoding/decoding without padding: + +--- +import std.base64 : Base64URLNoPadding; + +ubyte[] data = [0x83, 0xd7, 0x30, 0x7b, 0xef]; +assert(Base64URLNoPadding.encode(data) == "g9cwe-8"); +assert(Base64URLNoPadding.decode("g9cwe-8") == data); +--- diff --git a/std/base64.d b/std/base64.d index 59c941e27b4..d39e8164784 100644 --- a/std/base64.d +++ b/std/base64.d @@ -104,14 +104,30 @@ alias Base64URL = Base64Impl!('-', '_'); assert(Base64URL.decode("g9cwegE_") == data); } +/** + * Unpadded variation of Base64 encoding that is safe for use in URLs and + * filenames, as used in RFCs 4648 and 7515 (JWS/JWT/JWE). + * + * See $(LREF Base64Impl) for a description of available methods. + */ +alias Base64URLNoPadding = Base64Impl!('-', '_', Base64.NoPadding); + +/// +@safe unittest +{ + ubyte[] data = [0x83, 0xd7, 0x30, 0x7b, 0xef]; + assert(Base64URLNoPadding.encode(data) == "g9cwe-8"); + assert(Base64URLNoPadding.decode("g9cwe-8") == data); +} /** * Template for implementing Base64 encoding and decoding. * * For most purposes, direct usage of this template is not necessary; instead, - * this module provides two default implementations: $(LREF Base64) and - * $(LREF Base64URL), that implement basic Base64 encoding and a variant - * intended for use in URLs and filenames, respectively. + * this module provides default implementations: $(LREF Base64), implementing + * basic Base64 encoding, and $(LREF Base64URL) and $(LREF Base64URLNoPadding), + * that implement the Base64 variant for use in URLs and filenames, with + * and without padding, respectively. * * Customized Base64 encoding schemes can be implemented by instantiating this * template with the appropriate arguments. For example: From 4de14ab4c993072ab8d2156f3455f60f4adea448 Mon Sep 17 00:00:00 2001 From: Steven Schveighoffer Date: Mon, 26 Jun 2017 10:54:39 -0400 Subject: [PATCH 031/163] Change opOpAssign to use auto ref to prevent copying static arrays --- std/container/array.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/std/container/array.d b/std/container/array.d index 654c457090b..aaa0111908e 100644 --- a/std/container/array.d +++ b/std/container/array.d @@ -727,7 +727,7 @@ if (!is(Unqual!T == bool)) /** * Forwards to `insertBack`. */ - void opOpAssign(string op, Stuff)(Stuff stuff) + void opOpAssign(string op, Stuff)(auto ref Stuff stuff) if (op == "~") { static if (is(typeof(stuff[])) && isImplicitlyConvertible!(typeof(stuff[0]), T)) From 5983bcc8de9ab7a23b3487a52eaba28d3c43a6a2 Mon Sep 17 00:00:00 2001 From: dukc Date: Fri, 24 Feb 2017 23:41:14 +0200 Subject: [PATCH 032/163] Since std.concurrency.Generator is a class already, I made it to implement std.range.interfaces.InputRange without having to call inputRangeObject(). --- std/concurrency.d | 88 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 86 insertions(+), 2 deletions(-) diff --git a/std/concurrency.d b/std/concurrency.d index 397c9d76c82..5ecbb70488a 100644 --- a/std/concurrency.d +++ b/std/concurrency.d @@ -74,6 +74,14 @@ import std.traits; private { + import core.atomic; + import core.thread; + import core.sync.mutex; + import core.sync.condition; + import std.range.primitives; + import std.range.interfaces; + import std.traits; + template hasLocalAliasing(T...) { static if (!T.length) @@ -1496,7 +1504,8 @@ private interface IsGenerator {} * } * --- */ -class Generator(T) : Fiber, IsGenerator +class Generator(T) : + Fiber, IsGenerator, InputRange!T { /** * Initializes a generator object which is associated with a static @@ -1585,13 +1594,52 @@ class Generator(T) : Fiber, IsGenerator } /** - * Returns the most recently generated value. + * Returns the most recently generated value by shallow copy. */ final T front() @property { return *m_value; } + /** + * Returns the most recently generated value without excuting a copy + * contructor. Will not compile for element types defining a + * postblit, because Generator does not return by reference. + */ + final T moveFront() + { + static if (!hasElaborateCopyConstructor!T) + { + return front; + } + else + { + static assert(0, + "Fiber front is rvalue and thus cannot be moved when it defines a postblit."); + } + } + + final int opApply(scope int delegate(T) loopBody) + { + int broken; + for (; !empty; popFront()) + { + broken = loopBody(front); + if (broken) break; + } + return broken; + } + + final int opApply(scope int delegate(size_t, T) loopBody) + { + int broken; + for (size_t i; !empty; ++i, popFront()) + { + broken = loopBody(i, front); + if (broken) break; + } + return broken; + } private: T* m_value; } @@ -1624,6 +1672,7 @@ void yield(T)(T value) { import core.exception; import std.exception; + import std.range.interfaces; static void testScheduler(Scheduler s) { @@ -1661,6 +1710,7 @@ void yield(T)(T value) { tid.send(e); } + }); scheduler = null; } @@ -1668,7 +1718,41 @@ void yield(T)(T value) testScheduler(new ThreadScheduler); testScheduler(new FiberScheduler); } +/// +@system unittest +{ + import std.range; + + InputRange!int myIota = iota(10).inputRangeObject; + + myIota.popFront(); + myIota.popFront(); + assert(myIota.moveFront == 2); + assert(myIota.front == 2); + myIota.popFront(); + assert(myIota.front == 3); + + //can be assigned to std.range.interfaces.InputRange directly + myIota = new Generator!int( + { + foreach (i; 0 .. 10) yield(i); + }); + + myIota.popFront(); + myIota.popFront(); + assert(myIota.moveFront == 2); + assert(myIota.front == 2); + myIota.popFront(); + assert(myIota.front == 3); + + size_t[2] counter = [0, 0]; + foreach (i, unused; myIota) counter[] += [1, i]; + + assert(myIota.empty); + assert(counter == [7, 21]); +} +// MessageBox Implementation private { /* From 5d1bd05eed778f660641df43735155417180ce64 Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Mon, 26 Jun 2017 20:20:54 +0200 Subject: [PATCH 033/163] Re-add has_public_example to circleci.sh for legacy compatibility --- circleci.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/circleci.sh b/circleci.sh index 8865a3c7a0b..b1f47249f19 100755 --- a/circleci.sh +++ b/circleci.sh @@ -139,5 +139,7 @@ case $1 in coverage) coverage ;; publictests) publictests ;; style_lint) style_lint ;; + # has_public_example has been removed and is kept for compatibility with older PRs + has_public_example) echo "OK" ;; *) echo "Unknown command"; exit 1;; esac From 0fb66f092b897b55318509c6582008b3f912311a Mon Sep 17 00:00:00 2001 From: Sophie Kirschner Date: Fri, 10 Feb 2017 11:20:45 -0500 Subject: [PATCH 034/163] Fix issue 17562 - tan returning -nan for inputs where abs(x) >= 2^63 The fptan instruction pushes a 1.0 onto the FPU register stack after a successful operation, but when abs(input) >= 2^63 the C2 flag is set to indicate that the input was out of bounds, and it doesn't push the 1.0. Prior to this PR, the top value of the FPU stack was popped irrespective of whether C2 was set, which in the case of an out-of-bounds input caused the input to be removed from the stack and ultimately resulted in an incorrect return value of -nan. This PR changes this behavior, only popping after fptan when C2 was not set. See: http://x86.renejeschke.de/html/file_module_x86_id_109.html * Added unit tests for handling out-of-range inputs of fptan --- std/math.d | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/std/math.d b/std/math.d index 0ce6f21e114..1245abbafb2 100644 --- a/std/math.d +++ b/std/math.d @@ -768,10 +768,9 @@ real tan(real x) @trusted pure nothrow @nogc jc trigerr ; // x is NAN, infinity, or empty // 387's can handle subnormals SC18: fptan ; - fstp ST(0) ; // dump X, which is always 1 fstsw AX ; sahf ; - jnp Lret ; // C2 = 1 (x is out of range) + jnp Clear1 ; // C2 = 1 (x is out of range) // Do argument reduction to bring x into range fldpi ; @@ -789,6 +788,10 @@ trigerr: } return real.nan; +Clear1: asm pure nothrow @nogc{ + fstp ST(0) ; // dump X, which is always 1 + } + Lret: {} } else version(D_InlineAsm_X86_64) @@ -815,10 +818,9 @@ Lret: {} jnz trigerr ; // x is NAN, infinity, or empty // 387's can handle subnormals SC18: fptan ; - fstp ST(0) ; // dump X, which is always 1 fstsw AX ; test AH,4 ; - jz Lret ; // C2 = 1 (x is out of range) + jz Clear1 ; // C2 = 1 (x is out of range) // Do argument reduction to bring x into range fldpi ; @@ -837,6 +839,10 @@ trigerr: } return real.nan; +Clear1: asm pure nothrow @nogc{ + fstp ST(0) ; // dump X, which is always 1 + } + Lret: {} } else @@ -7174,6 +7180,12 @@ deprecated("Phobos1 math functions are deprecated, use isInfinity ") alias isinf real r = tan(-2.0L); assert(fabs(r - 2.18504f) < .00001); + + // Verify correct behavior for large inputs + assert(!isNaN(tan(0x1p63))); + assert(!isNaN(tan(0x1p300L))); + assert(!isNaN(tan(-0x1p63))); + assert(!isNaN(tan(-0x1p300L))); } @safe pure nothrow unittest From 820a6767f8a2557809132b7e47648b3f09710ed9 Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Wed, 28 Jun 2017 02:37:06 +0200 Subject: [PATCH 035/163] Make $(DMD) and $(LIB) an order-only dependency for DScanner This avoids recompilation of DScanner when a file in Phobos has been changed. DScanner only needs a recent Phobos version to be built once. --- posix.mak | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/posix.mak b/posix.mak index 12d32423118..6c669978a2d 100644 --- a/posix.mak +++ b/posix.mak @@ -525,7 +525,7 @@ checkwhitespace: $(LIB) $(TOOLS_DIR)/checkwhitespace.d git -C ../dscanner checkout 455cc3fe50e6d0742c866737b4ac24669d51a992 git -C ../dscanner submodule update --init --recursive -../dscanner/dsc: ../dscanner $(DMD) $(LIB) +../dscanner/dsc: | ../dscanner $(DMD) $(LIB) # debug build is faster, but disable 'missing import' messages (missing core from druntime) sed 's/dparse_verbose/StdLoggerDisableWarning/' ../dscanner/makefile > dscanner_makefile_tmp mv dscanner_makefile_tmp ../dscanner/makefile From 96a31759e67e77b6d18d6eee7bd4092b41830711 Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Wed, 28 Jun 2017 02:40:22 +0200 Subject: [PATCH 036/163] Make DScanner a separate Makefile target --- posix.mak | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/posix.mak b/posix.mak index 6c669978a2d..9b031619df8 100644 --- a/posix.mak +++ b/posix.mak @@ -533,7 +533,13 @@ checkwhitespace: $(LIB) $(TOOLS_DIR)/checkwhitespace.d style: publictests style_lint -style_lint: ../dscanner/dsc $(LIB) +# runs static code analysis with Dscanner +dscanner: | ../dscanner/dsc + # at the moment libdparse has problems to parse some modules (->excludes) + @echo "Running DScanner" + ../dscanner/dsc --config .dscanner.ini --styleCheck $$(find etc std -type f -name '*.d' | grep -vE 'std/traits.d|std/typecons.d') -I. + +style_lint: dscanner $(LIB) @echo "Check for trailing whitespace" grep -nr '[[:blank:]]$$' etc std ; test $$? -eq 1 @@ -577,10 +583,6 @@ style_lint: ../dscanner/dsc $(LIB) @echo "Check that Ddoc runs without errors" $(DMD) $(DFLAGS) -defaultlib= -debuglib= $(LIB) -w -D -Df/dev/null -main -c -o- $$(find etc std -type f -name '*.d') 2>&1 | grep -v "Deprecation:"; test $$? -eq 1 - # at the moment libdparse has problems to parse some modules (->excludes) - @echo "Running DScanner" - ../dscanner/dsc --config .dscanner.ini --styleCheck $$(find etc std -type f -name '*.d' | grep -vE 'std/traits.d|std/typecons.d') -I. - ################################################################################ # Check for missing imports in public unittest examples. ################################################################################ From 0e90f7a189c0e6110d2b7826fd560ea405dd3ffb Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Wed, 28 Jun 2017 15:01:15 +0200 Subject: [PATCH 037/163] Use a unique DScanner directory (with commit hash) --- posix.mak | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/posix.mak b/posix.mak index 9b031619df8..50a968b35f2 100644 --- a/posix.mak +++ b/posix.mak @@ -63,6 +63,8 @@ ROOT = $(ROOT_OF_THEM_ALL)/$(OS)/$(BUILD)/$(MODEL) DUB=dub GIT_HOME=https://github.com/dlang TOOLS_DIR=../tools +DSCANNER_HASH=455cc3fe50e6d0742c866737b4ac24669d51a992 +DSCANNER_DIR=../dscanner-$(DSCANNER_HASH) # Documentation-related stuff DOCSRC = ../dlang.org @@ -520,24 +522,24 @@ checkwhitespace: $(LIB) $(TOOLS_DIR)/checkwhitespace.d # See also: http://dlang.org/dstyle.html ############################# -../dscanner: - git clone https://github.com/dlang-community/Dscanner ../dscanner - git -C ../dscanner checkout 455cc3fe50e6d0742c866737b4ac24669d51a992 - git -C ../dscanner submodule update --init --recursive +$(DSCANNER_DIR): + git clone https://github.com/dlang-community/Dscanner $@ + git -C $@ checkout $(DSCANNER_HASH) + git -C $@ submodule update --init --recursive -../dscanner/dsc: | ../dscanner $(DMD) $(LIB) +$(DSCANNER_DIR)/dsc: | $(DSCANNER_DIR) $(DMD) $(LIB) # debug build is faster, but disable 'missing import' messages (missing core from druntime) - sed 's/dparse_verbose/StdLoggerDisableWarning/' ../dscanner/makefile > dscanner_makefile_tmp - mv dscanner_makefile_tmp ../dscanner/makefile - DC=$(DMD) DFLAGS="$(DFLAGS) -defaultlib=$(LIB)" make -C ../dscanner githash debug + sed 's/dparse_verbose/StdLoggerDisableWarning/' $(DSCANNER_DIR)/makefile > $(DSCANNER_DIR)/dscanner_makefile_tmp + mv $(DSCANNER_DIR)/dscanner_makefile_tmp $(DSCANNER_DIR)/makefile + DC=$(DMD) DFLAGS="$(DFLAGS) -defaultlib=$(LIB)" make -C $(DSCANNER_DIR) githash debug style: publictests style_lint # runs static code analysis with Dscanner -dscanner: | ../dscanner/dsc +dscanner: | $(DSCANNER_DIR)/dsc # at the moment libdparse has problems to parse some modules (->excludes) @echo "Running DScanner" - ../dscanner/dsc --config .dscanner.ini --styleCheck $$(find etc std -type f -name '*.d' | grep -vE 'std/traits.d|std/typecons.d') -I. + $(DSCANNER_DIR)/dsc --config .dscanner.ini --styleCheck $$(find etc std -type f -name '*.d' | grep -vE 'std/traits.d|std/typecons.d') -I. style_lint: dscanner $(LIB) @echo "Check for trailing whitespace" From 108d0c7ba15fa1caa3fe6469fe3c144ed21c3a2c Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Tue, 20 Jun 2017 03:45:17 +0200 Subject: [PATCH 038/163] Import std.meta.staticMap in std.typecons to avoid regressions See also: https://github.com/dlang/phobos/pull/5484#discussion_r122602797 --- std/traits.d | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/std/traits.d b/std/traits.d index 13f778c7534..f42509a3ae1 100644 --- a/std/traits.d +++ b/std/traits.d @@ -166,6 +166,13 @@ module std.traits; import std.meta : AliasSeq, allSatisfy; +// Legacy inheritance from std.typetuple +// See also: https://github.com/dlang/phobos/pull/5484#discussion_r122602797 +import std.meta : staticMapMeta = staticMap; +// TODO: find a way to trigger deprecation warnings +//deprecated("staticMap is part of std.meta: Please import std.meta") +alias staticMap = staticMapMeta; + /////////////////////////////////////////////////////////////////////////////// // Functions /////////////////////////////////////////////////////////////////////////////// From f89cf8c395a6e873679dcc7d2cb8b862c35205f5 Mon Sep 17 00:00:00 2001 From: Vladimir Panteleev Date: Wed, 28 Jun 2017 19:33:30 +0000 Subject: [PATCH 039/163] std.concurrency: Fix "Synposis" typo --- std/concurrency.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/std/concurrency.d b/std/concurrency.d index 397c9d76c82..44b5918be3f 100644 --- a/std/concurrency.d +++ b/std/concurrency.d @@ -19,7 +19,7 @@ * schedulers are available that multiplex fibers across the main thread or * use some combination of the two approaches. * - * Synposis: + * Synopsis: * --- * import std.stdio; * import std.concurrency; From 46cfe3fcc14adb290d02f0d32e3bda56b50d1216 Mon Sep 17 00:00:00 2001 From: "H. S. Teoh" Date: Thu, 29 Jun 2017 11:11:17 -0700 Subject: [PATCH 040/163] Fix broken ddoc macro. --- std/typecons.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/std/typecons.d b/std/typecons.d index 6671f5e9d46..ac94ece139e 100644 --- a/std/typecons.d +++ b/std/typecons.d @@ -5141,7 +5141,7 @@ scope, they will automatically increment or decrement the reference count. When the reference count goes down to zero, $(D RefCounted) will call $(D destroy) against the payload and call $(D free) to deallocate the store. If the $(D T) payload contains any references -to GC-allocated memory, then $(RefCounted) will add it to the GC memory +to GC-allocated memory, then `RefCounted` will add it to the GC memory that is scanned for pointers, and remove it from GC scanning before $(D free) is called on the store. From bb0340766b4810fd72f92d2a55981aba8006396e Mon Sep 17 00:00:00 2001 From: Hackerpilot Date: Thu, 29 Jun 2017 15:18:27 -0700 Subject: [PATCH 041/163] Fix issue 17574 - Avoid range error by checking the result of indexOf --- std/getopt.d | 2 ++ 1 file changed, 2 insertions(+) diff --git a/std/getopt.d b/std/getopt.d index 890a3c3f233..2a264980026 100644 --- a/std/getopt.d +++ b/std/getopt.d @@ -947,6 +947,8 @@ private bool handleOption(R)(string option, R receiver, ref string[] args, static Tuple!(K, V) getter(string input) { auto j = indexOf(input, assignChar); + enforce!GetOptException(j != -1, "Could not find '" + ~ to!string(assignChar) ~ "' in argument '" ~ input ~ "'."); auto key = input[0 .. j]; auto value = input[j + 1 .. $]; return tuple(to!K(key), to!V(value)); From 2523fa1c3daf93ab4bfe5946114609342abec5d5 Mon Sep 17 00:00:00 2001 From: Iain Buclaw Date: Thu, 29 Jun 2017 20:27:43 +0200 Subject: [PATCH 042/163] Fix ARM unittest (again) in std.math. See #4132 and the revert of it in #4592. Added a comment so that the mistake is not done for the third time in a row. --- std/math.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/std/math.d b/std/math.d index 431e5f56138..49d0e4ea0cc 100644 --- a/std/math.d +++ b/std/math.d @@ -5878,7 +5878,7 @@ real NaN(ulong payload) @trusted pure nothrow @nogc } } -@safe pure nothrow @nogc unittest +@system pure nothrow @nogc unittest // not @safe because taking address of local. { static if (floatTraits!(real).realFormat == RealFormat.ieeeDouble) { From 818deb3615d8f6e0e73f9e2369d0d21f21f20d84 Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Fri, 30 Jun 2017 01:32:33 +0200 Subject: [PATCH 043/163] Fix DDoc macros --- .../allocator/building_blocks/segregator.d | 2 +- std/net/curl.d | 2 +- std/regex/package.d | 2 +- std/stdio.d | 10 +++++----- std/string.d | 4 ++-- std/typecons.d | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/std/experimental/allocator/building_blocks/segregator.d b/std/experimental/allocator/building_blocks/segregator.d index 83520117935..76ca6f409d0 100644 --- a/std/experimental/allocator/building_blocks/segregator.d +++ b/std/experimental/allocator/building_blocks/segregator.d @@ -50,7 +50,7 @@ struct Segregator(size_t threshold, SmallAllocator, LargeAllocator) /** This method is defined only if at least one of the allocators defines it. If $(D SmallAllocator) defines $(D expand) and $(D b.length + - delta <= threshold), the call is forwarded to $(D SmallAllocator). If $( + delta <= threshold), the call is forwarded to $(D SmallAllocator). If $(D LargeAllocator) defines $(D expand) and $(D b.length > threshold), the call is forwarded to $(D LargeAllocator). Otherwise, the call returns $(D false). diff --git a/std/net/curl.d b/std/net/curl.d index 6740ecfd86b..d36ee30b5dd 100644 --- a/std/net/curl.d +++ b/std/net/curl.d @@ -2377,7 +2377,7 @@ private bool decodeLineInto(Terminator, Char = char)(ref const(ubyte)[] basesrc, * http.perform(); * --- * - * See_Also: $(HTTP www.ietf.org/rfc/rfc2616.txt, RFC2616) + * See_Also: $(_HTTP www.ietf.org/rfc/rfc2616.txt, RFC2616) * */ struct HTTP diff --git a/std/regex/package.d b/std/regex/package.d index 9e66f7eacf4..f21d9f2e0d6 100644 --- a/std/regex/package.d +++ b/std/regex/package.d @@ -79,7 +79,7 @@ $(TR $(TD Objects) $(TD assert(m.front[1] == "12"); ... - // The result of the $(D matchAll/matchFirst) is directly testable with if/assert/while. + // The result of the `matchAll/matchFirst` is directly testable with if/assert/while. // e.g. test if a string consists of letters: assert(matchFirst("Letter", `^\p{L}+$`)); --- diff --git a/std/stdio.d b/std/stdio.d index 1464445fd7f..5f8df7bb939 100644 --- a/std/stdio.d +++ b/std/stdio.d @@ -337,7 +337,7 @@ void main(string[] args) } f.writeln("!"); // f exits scope, reference count falls to zero, - // underlying $(D FILE*) is closed. + // underlying `FILE*` is closed. } ---- $(CONSOLE @@ -1519,7 +1519,7 @@ Throws: Example: --- -// Reads $(D stdin) and writes it to $(D stdout). +// Reads `stdin` and writes it to `stdout`. import std.stdio; void main() @@ -1603,9 +1603,9 @@ conversion error. Example: --- -// Read lines from $(D stdin) into a string +// Read lines from `stdin` into a string // Ignore lines starting with '#' -// Write the string to $(D stdout) +// Write the string to `stdout` void main() { @@ -1635,7 +1635,7 @@ largest buffer returned by $(D readln): Example: --- -// Read lines from $(D stdin) and count words +// Read lines from `stdin` and count words void main() { diff --git a/std/string.d b/std/string.d index 2635a78f521..f4dff356e06 100644 --- a/std/string.d +++ b/std/string.d @@ -2744,8 +2744,8 @@ if ((hasSlicing!Range && hasLength!Range && isSomeChar!(ElementType!Range) || string s = "Hello\nmy\rname\nis"; - /* notice the call to $(D array) to turn the lazy range created by - lineSplitter comparable to the $(D string[]) created by splitLines. + /* notice the call to `array` to turn the lazy range created by + lineSplitter comparable to the `string[]` created by splitLines. */ assert(lineSplitter(s).array == splitLines(s)); } diff --git a/std/typecons.d b/std/typecons.d index ac94ece139e..d4838d810dc 100644 --- a/std/typecons.d +++ b/std/typecons.d @@ -5414,7 +5414,7 @@ assert(refCountedStore.isInitialized)). /// pure @system nothrow @nogc unittest { - // A pair of an $(D int) and a $(D size_t) - the latter being the + // A pair of an `int` and a `size_t` - the latter being the // reference count - will be dynamically allocated auto rc1 = RefCounted!int(5); assert(rc1 == 5); @@ -7328,7 +7328,7 @@ public: BitFlags!Enum flags1; assert(!(flags1 & (Enum.A | Enum.B | Enum.C))); - // You need to specify the $(D unsafe) parameter for enum with custom values + // You need to specify the `unsafe` parameter for enum with custom values enum UnsafeEnum { A, From d574d0827294fcfbf6179ad6a7da35c924de2b57 Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Thu, 29 Jun 2017 09:58:45 +0200 Subject: [PATCH 044/163] Upgrade DScanner to 620ffaffe9a8019caed12f405edd73e6d9134406 Most notably this contains: - upgraded libdparse with support for deprecated C-style alias declarations (-> https://github.com/dlang-community/libdparse/pull/150) - has_public_example check Full changelog: https://github.com/dlang-community/D-Scanner/compare/455cc3fe50e6d0742c866737b4ac24669d51a992...40d75610a2e00440dbb3d08d9f06462d43dbee22 --- posix.mak | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/posix.mak b/posix.mak index 50a968b35f2..5b91334065a 100644 --- a/posix.mak +++ b/posix.mak @@ -63,7 +63,7 @@ ROOT = $(ROOT_OF_THEM_ALL)/$(OS)/$(BUILD)/$(MODEL) DUB=dub GIT_HOME=https://github.com/dlang TOOLS_DIR=../tools -DSCANNER_HASH=455cc3fe50e6d0742c866737b4ac24669d51a992 +DSCANNER_HASH=071cd08a6de9bbe1720c763b0aff4d19864b27f1 DSCANNER_DIR=../dscanner-$(DSCANNER_HASH) # Documentation-related stuff From a311ba161a042a648d368a51ff5ce5a264c53fee Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Thu, 29 Jun 2017 11:33:29 +0200 Subject: [PATCH 045/163] Remove hard-coded DScanner exclusion of std.traits and std.typecons --- .dscanner.ini | 22 ++++++++++++---------- posix.mak | 3 +-- std/traits.d | 17 +++++++++-------- std/typecons.d | 26 +++++++++++++++++++------- 4 files changed, 41 insertions(+), 27 deletions(-) diff --git a/.dscanner.ini b/.dscanner.ini index 33613858e46..4d3e92a09cd 100644 --- a/.dscanner.ini +++ b/.dscanner.ini @@ -103,23 +103,25 @@ redundant_attributes_check="enabled" ; Some checks are currently disabled. ; For more details, please see https://github.com/dlang/phobos/pull/5501 [analysis.config.ModuleFilters] +; Check for uses of the old-style alias syntax +alias_syntax_check="-std.traits,-std.typecons" ; Check allman brace style allman_braces_check="+disabled" ; Checks for confusing code in inline asm statements asm_style_check="-std.math" ; Checks for assignment to auto-ref function parameters -auto_ref_assignment_check="-std.algorithm.mutation,-std.format" +auto_ref_assignment_check="-std.algorithm.mutation,-std.format,-std.typecons" ; Checks for variables that could be declared immutable -could_be_immutable_check="-std.algorithm.comparison,-std.algorithm.iteration,-std.algorithm.mutation,-std.algorithm.searching,-std.algorithm.setops,-std.algorithm.sorting,-std.array,-std.base64,-std.bigint,-std.bitmanip,-std.complex,-std.concurrency,-std.container,-std.container.array,-std.container.binaryheap,-std.container.dlist,-std.container.rbtree,-std.container.slist,-std.container.util,-std.conv,-std.csv,-std.datetime,-std.datetime.date,-std.datetime.interval,-std.datetime.stopwatch,-std.datetime.systime,-std.datetime.timezone,-std.digest.crc,-std.digest.digest,-std.digest.hmac,-std.digest.md,-std.digest.murmurhash,-std.digest.ripemd,-std.digest.sha,-std.encoding,-std.exception,-std.experimental.allocator,-std.experimental.allocator.building_blocks.affix_allocator,-std.experimental.allocator.building_blocks.allocator_list,-std.experimental.allocator.building_blocks.bitmapped_block,-std.experimental.allocator.building_blocks.bucketizer,-std.experimental.allocator.building_blocks.fallback_allocator,-std.experimental.allocator.building_blocks.free_list,-std.experimental.allocator.building_blocks.free_tree,-std.experimental.allocator.building_blocks.kernighan_ritchie,-std.experimental.allocator.building_blocks.region,-std.experimental.allocator.building_blocks.stats_collector,-std.experimental.allocator.gc_allocator,-std.experimental.allocator.mallocator,-std.experimental.allocator.typed,-std.experimental.checkedint,-std.experimental.logger.core,-std.experimental.logger.multilogger,-std.experimental.typecons,-std.file,-std.format,-std.functional,-std.getopt,-std.internal.cstring,-std.internal.digest.sha_SSSE3,-std.internal.math.biguintcore,-std.internal.math.biguintnoasm,-std.internal.math.biguintx86,-std.internal.math.errorfunction,-std.internal.math.gammafunction,-std.internal.scopebuffer,-std.internal.test.dummyrange,-std.json,-std.math,-std.mathspecial,-std.meta,-std.mmfile,-std.net.curl,-std.net.isemail,-std.numeric,-std.outbuffer,-std.parallelism,-std.path,-std.process,-std.random,-std.range,-std.range.interfaces,-std.range.primitives,-std.regex,-std.regex.internal.backtracking,-std.regex.internal.generator,-std.regex.internal.ir,-std.regex.internal.kickstart,-std.regex.internal.parser,-std.regex.internal.tests,-std.regex.internal.thompson,-std.signals,-std.socket,-std.stdio,-std.string,-std.uni,-std.uri,-std.utf,-std.uuid,-std.variant,-std.windows.registry,-std.xml,-std.zip,-std.zlib" +could_be_immutable_check="-std.algorithm.comparison,-std.algorithm.iteration,-std.algorithm.mutation,-std.algorithm.searching,-std.algorithm.setops,-std.algorithm.sorting,-std.array,-std.base64,-std.bigint,-std.bitmanip,-std.complex,-std.concurrency,-std.container,-std.container.array,-std.container.binaryheap,-std.container.dlist,-std.container.rbtree,-std.container.slist,-std.container.util,-std.conv,-std.csv,-std.datetime,-std.datetime.date,-std.datetime.interval,-std.datetime.stopwatch,-std.datetime.systime,-std.datetime.timezone,-std.digest.crc,-std.digest.digest,-std.digest.hmac,-std.digest.md,-std.digest.murmurhash,-std.digest.ripemd,-std.digest.sha,-std.encoding,-std.exception,-std.experimental.allocator,-std.experimental.allocator.building_blocks.affix_allocator,-std.experimental.allocator.building_blocks.allocator_list,-std.experimental.allocator.building_blocks.bitmapped_block,-std.experimental.allocator.building_blocks.bucketizer,-std.experimental.allocator.building_blocks.fallback_allocator,-std.experimental.allocator.building_blocks.free_list,-std.experimental.allocator.building_blocks.free_tree,-std.experimental.allocator.building_blocks.kernighan_ritchie,-std.experimental.allocator.building_blocks.region,-std.experimental.allocator.building_blocks.stats_collector,-std.experimental.allocator.gc_allocator,-std.experimental.allocator.mallocator,-std.experimental.allocator.typed,-std.experimental.checkedint,-std.experimental.logger.core,-std.experimental.logger.multilogger,-std.experimental.typecons,-std.file,-std.format,-std.functional,-std.getopt,-std.internal.cstring,-std.internal.digest.sha_SSSE3,-std.internal.math.biguintcore,-std.internal.math.biguintnoasm,-std.internal.math.biguintx86,-std.internal.math.errorfunction,-std.internal.math.gammafunction,-std.internal.scopebuffer,-std.internal.test.dummyrange,-std.json,-std.math,-std.mathspecial,-std.meta,-std.mmfile,-std.net.curl,-std.net.isemail,-std.numeric,-std.outbuffer,-std.parallelism,-std.path,-std.process,-std.random,-std.range,-std.range.interfaces,-std.range.primitives,-std.regex,-std.regex.internal.backtracking,-std.regex.internal.generator,-std.regex.internal.ir,-std.regex.internal.kickstart,-std.regex.internal.parser,-std.regex.internal.tests,-std.regex.internal.thompson,-std.signals,-std.socket,-std.stdio,-std.string,-std.traits,-std.typecons,-std.uni,-std.uri,-std.utf,-std.uuid,-std.variant,-std.windows.registry,-std.xml,-std.zip,-std.zlib" ; Check for poor exception handling practices -exception_check="-std.concurrency,-std.net.curl,-std.parallelism,-std.range,-std.socket" +exception_check="-std.concurrency,-std.net.curl,-std.parallelism,-std.range,-std.socket,-std.typecons" ; Checks for poor placement of function attributes -function_attribute_check="-std.algorithm.iteration,-std.concurrency,-std.conv,-std.datetime.interval,-std.exception,-std.functional,-std.net.curl,-std.numeric,-std.parallelism,-std.random,-std.range,-std.range.primitives,-std.socket,-std.uni" +function_attribute_check="-std.algorithm.iteration,-std.concurrency,-std.conv,-std.datetime.interval,-std.exception,-std.functional,-std.net.curl,-std.numeric,-std.parallelism,-std.random,-std.range,-std.range.primitives,-std.socket,-std.traits,-std.typecons,-std.uni" ; Check for sortedness of imports imports_sortedness="+disabled" ;imports_sortedness="-etc.c.curl,-std.algorithm.comparison,-std.algorithm.internal,-std.algorithm.iteration,-std.algorithm.mutation,-std.algorithm.searching,-std.algorithm.setops,-std.algorithm.sorting,-std.array,-std.bigint,-std.bitmanip,-std.c.freebsd.socket,-std.c.linux.pthread,-std.c.process,-std.complex,-std.concurrency,-std.container.array,-std.container.binaryheap,-std.container.dlist,-std.container.rbtree,-std.container.slist,-std.container.util,-std.conv,-std.datetime,-std.datetime.date,-std.datetime.interval,-std.datetime.systime,-std.datetime.timezone,-std.digest.digest,-std.digest.hmac,-std.exception,-std.experimental.allocator,-std.experimental.allocator.building_blocks,-std.experimental.allocator.building_blocks.affix_allocator,-std.experimental.allocator.building_blocks.allocator_list,-std.experimental.allocator.building_blocks.free_list,-std.experimental.allocator.building_blocks.free_tree,-std.experimental.allocator.building_blocks.kernighan_ritchie,-std.experimental.allocator.building_blocks.region,-std.experimental.allocator.common,-std.experimental.allocator.mallocator,-std.experimental.allocator.mmap_allocator,-std.experimental.allocator.showcase,-std.experimental.allocator.typed,-std.experimental.checkedint,-std.experimental.logger.core,-std.experimental.typecons,-std.file,-std.format,-std.functional,-std.getopt,-std.internal.math.biguintcore,-std.internal.test.dummyrange,-std.json,-std.math,-std.meta,-std.mmfile,-std.net.curl,-std.net.isemail,-std.numeric,-std.outbuffer,-std.parallelism,-std.path,-std.process,-std.random,-std.range,-std.range.primitives,-std.regex,-std.regex.internal.backtracking,-std.regex.internal.generator,-std.regex.internal.kickstart,-std.regex.internal.parser,-std.regex.internal.tests,-std.signals,-std.socket,-std.stdio,-std.string,-std.uni,-std.utf,-std.uuid,-std.variant,-std.windows.charset,-std.windows.registry,-std.windows.syserror,-std.zip" ; Checks for labels with the same name as variables -label_var_same_name_check="-std.algorithm.iteration,-std.algorithm.sorting,-std.array,-std.bigint,-std.bitmanip,-std.conv,-std.encoding,-std.experimental.allocator.building_blocks.segregator,-std.experimental.typecons,-std.format,-std.internal.digest.sha_SSSE3,-std.parallelism,-std.process,-std.utf" +label_var_same_name_check="-std.algorithm.iteration,-std.algorithm.sorting,-std.array,-std.bigint,-std.bitmanip,-std.conv,-std.encoding,-std.experimental.allocator.building_blocks.segregator,-std.experimental.typecons,-std.format,-std.internal.digest.sha_SSSE3,-std.parallelism,-std.process,-std.typecons,-std.utf" ; Checks for subtraction from .length properties length_subtraction_check="+disabled" ;length_subtraction_check="-std.algorithm.internal,-std.algorithm.iteration,-std.algorithm.mutation,-std.algorithm.searching,-std.algorithm.sorting,-std.array,-std.concurrency,-std.container.array,-std.container.binaryheap,-std.conv,-std.datetime.timezone,-std.experimental.allocator.building_blocks.segregator,-std.experimental.logger.core,-std.file,-std.format,-std.getopt,-std.internal.math.biguintcore,-std.internal.math.biguintnoasm,-std.internal.math.biguintx86,-std.internal.scopebuffer,-std.math,-std.net.curl,-std.net.isemail,-std.numeric,-std.parallelism,-std.path,-std.process,-std.range,-std.regex,-std.regex.internal.parser,-std.regex.internal.tests,-std.string,-std.uni,-std.windows.charset,-std.windows.registry,-std.zip" @@ -135,11 +137,11 @@ number_style_check="+disabled" ;number_style_check="-std.algorithm.iteration,-std.algorithm.sorting,-std.array,-std.bigint,-std.bitmanip,-std.container.array,-std.conv,-std.datetime.date,-std.datetime.systime,-std.datetime.timezone,-std.digest.crc,-std.digest.digest,-std.digest.md,-std.digest.ripemd,-std.digest.sha,-std.experimental.allocator.building_blocks.free_tree,-std.experimental.allocator.building_blocks.kernighan_ritchie,-std.experimental.checkedint,-std.file,-std.format,-std.functional,-std.internal.math.biguintcore,-std.internal.math.gammafunction,-std.json,-std.math,-std.outbuffer,-std.parallelism,-std.random,-std.range,-std.regex.internal.generator,-std.utf,-std.zip,-std.zlib" ; Checks that opEquals, opCmp, toHash, and toString are either const, immutable ; , or inout. -object_const_check="-std.algorithm.searching,-std.array,-std.bitmanip,-std.concurrency,-std.container.rbtree,-std.conv,-std.datetime.interval,-std.encoding,-std.exception,-std.experimental.checkedint,-std.experimental.logger.core,-std.experimental.typecons,-std.format,-std.functional,-std.meta,-std.numeric,-std.range,-std.regex,-std.stdio,-std.variant,-std.xml" +object_const_check="-std.algorithm.searching,-std.array,-std.bitmanip,-std.concurrency,-std.container.rbtree,-std.conv,-std.datetime.interval,-std.encoding,-std.exception,-std.experimental.checkedint,-std.experimental.logger.core,-std.experimental.typecons,-std.format,-std.functional,-std.meta,-std.numeric,-std.range,-std.regex,-std.stdio,-std.typecons,-std.variant,-std.xml" ; Checks that opEquals and toHash are both defined or neither are defined -opequals_tohash_check="-std.algorithm.searching,-std.array,-std.complex,-std.container.array,-std.container.dlist,-std.container.rbtree,-std.container.slist,-std.datetime,-std.datetime.date,-std.experimental.checkedint,-std.functional,-std.internal.test.dummyrange,-std.json,-std.numeric,-std.random,-std.range,-std.socket,-std.uni" +opequals_tohash_check="-std.algorithm.searching,-std.array,-std.complex,-std.container.array,-std.container.dlist,-std.container.rbtree,-std.container.slist,-std.datetime,-std.datetime.date,-std.experimental.checkedint,-std.functional,-std.internal.test.dummyrange,-std.json,-std.numeric,-std.random,-std.range,-std.socket,-std.traits,-std.typecons,-std.uni" ; Check for properly documented public functions (Returns, Params) -properly_documented_public_functions="-etc.c.odbc.sql,-etc.c.odbc.sqlext,-etc.c.zlib,-std.algorithm.comparison,-std.algorithm.iteration,-std.algorithm.mutation,-std.algorithm.searching,-std.algorithm.setops,-std.algorithm.sorting,-std.array,-std.ascii,-std.base64,-std.bigint,-std.bitmanip,-std.complex,-std.container,-std.container.array,-std.container.binaryheap,-std.container.dlist,-std.container.rbtree,-std.container.slist,-std.container.util,-std.csv,-std.datetime,-std.datetime.date,-std.datetime.interval,-std.datetime.stopwatch,-std.datetime.systime,-std.datetime.timezone,-std.demangle,-std.digest.crc,-std.digest.digest,-std.digest.hmac,-std.digest.md,-std.digest.murmurhash,-std.digest.ripemd,-std.digest.sha,-std.encoding,-std.exception,-std.experimental.allocator,-std.experimental.allocator.building_blocks.affix_allocator,-std.experimental.allocator.building_blocks.allocator_list,-std.experimental.allocator.building_blocks.bitmapped_block,-std.experimental.allocator.building_blocks.bucketizer,-std.experimental.allocator.building_blocks.fallback_allocator,-std.experimental.allocator.building_blocks.free_list,-std.experimental.allocator.building_blocks.free_tree,-std.experimental.allocator.building_blocks.kernighan_ritchie,-std.experimental.allocator.building_blocks.null_allocator,-std.experimental.allocator.building_blocks.quantizer,-std.experimental.allocator.building_blocks.region,-std.experimental.allocator.building_blocks.scoped_allocator,-std.experimental.allocator.building_blocks.segregator,-std.experimental.allocator.building_blocks.stats_collector,-std.experimental.allocator.common,-std.experimental.allocator.gc_allocator,-std.experimental.allocator.mallocator,-std.experimental.allocator.showcase,-std.experimental.allocator.typed,-std.experimental.checkedint,-std.experimental.logger.core,-std.experimental.logger.filelogger,-std.file,-std.format,-std.functional,-std.getopt,-std.internal.cstring,-std.internal.math.biguintcore,-std.internal.math.biguintnoasm,-std.internal.scopebuffer,-std.internal.test.dummyrange,-std.internal.unicode_tables,-std.json,-std.math,-std.mathspecial,-std.meta,-std.mmfile,-std.net.curl,-std.net.isemail,-std.numeric,-std.outbuffer,-std.parallelism,-std.path,-std.random,-std.range,-std.range.interfaces,-std.range.primitives,-std.regex,-std.regex.internal.backtracking,-std.regex.internal.ir,-std.regex.internal.kickstart,-std.regex.internal.parser,-std.regex.internal.thompson,-std.signals,-std.socket,-std.stdio,-std.string,-std.uni,-std.uri,-std.utf,-std.uuid,-std.variant,-std.xml,-std.zip,-std.zlib" +properly_documented_public_functions="-etc.c.odbc.sql,-etc.c.odbc.sqlext,-etc.c.zlib,-std.algorithm.comparison,-std.algorithm.iteration,-std.algorithm.mutation,-std.algorithm.searching,-std.algorithm.setops,-std.algorithm.sorting,-std.array,-std.ascii,-std.base64,-std.bigint,-std.bitmanip,-std.complex,-std.container,-std.container.array,-std.container.binaryheap,-std.container.dlist,-std.container.rbtree,-std.container.slist,-std.container.util,-std.csv,-std.datetime,-std.datetime.date,-std.datetime.interval,-std.datetime.stopwatch,-std.datetime.systime,-std.datetime.timezone,-std.demangle,-std.digest.crc,-std.digest.digest,-std.digest.hmac,-std.digest.md,-std.digest.murmurhash,-std.digest.ripemd,-std.digest.sha,-std.encoding,-std.exception,-std.experimental.allocator,-std.experimental.allocator.building_blocks.affix_allocator,-std.experimental.allocator.building_blocks.allocator_list,-std.experimental.allocator.building_blocks.bitmapped_block,-std.experimental.allocator.building_blocks.bucketizer,-std.experimental.allocator.building_blocks.fallback_allocator,-std.experimental.allocator.building_blocks.free_list,-std.experimental.allocator.building_blocks.free_tree,-std.experimental.allocator.building_blocks.kernighan_ritchie,-std.experimental.allocator.building_blocks.null_allocator,-std.experimental.allocator.building_blocks.quantizer,-std.experimental.allocator.building_blocks.region,-std.experimental.allocator.building_blocks.scoped_allocator,-std.experimental.allocator.building_blocks.segregator,-std.experimental.allocator.building_blocks.stats_collector,-std.experimental.allocator.common,-std.experimental.allocator.gc_allocator,-std.experimental.allocator.mallocator,-std.experimental.allocator.showcase,-std.experimental.allocator.typed,-std.experimental.checkedint,-std.experimental.logger.core,-std.experimental.logger.filelogger,-std.file,-std.format,-std.functional,-std.getopt,-std.internal.cstring,-std.internal.math.biguintcore,-std.internal.math.biguintnoasm,-std.internal.scopebuffer,-std.internal.test.dummyrange,-std.internal.unicode_tables,-std.json,-std.math,-std.mathspecial,-std.meta,-std.mmfile,-std.net.curl,-std.net.isemail,-std.numeric,-std.outbuffer,-std.parallelism,-std.path,-std.random,-std.range,-std.range.interfaces,-std.range.primitives,-std.regex,-std.regex.internal.backtracking,-std.regex.internal.ir,-std.regex.internal.kickstart,-std.regex.internal.parser,-std.regex.internal.thompson,-std.signals,-std.socket,-std.stdio,-std.string,-std.traits,-std.typecons,-std.uni,-std.uri,-std.utf,-std.uuid,-std.variant,-std.xml,-std.zip,-std.zlib" ; Check for redundant attributes redundant_attributes_check="-std.concurrency,-std.digest.md,-std.digest.ripemd,-std.digest.sha,-std.internal.math.biguintcore,-std.math,-std.meta,-std.range,-std.regex.internal.ir,-std.uni,-std.windows.registry" ; Check variable, class, struct, interface, union, and function names against @@ -147,11 +149,11 @@ redundant_attributes_check="-std.concurrency,-std.digest.md,-std.digest.ripemd,- style_check="+disabled" ;style_check="-etc.c.curl,-etc.c.odbc.sqlext,-etc.c.odbc.sqltypes,-etc.c.odbc.sqlucode,-etc.c.sqlite3,-etc.c.zlib,-std.algorithm.comparison,-std.algorithm.internal,-std.algorithm.iteration,-std.algorithm.mutation,-std.algorithm.sorting,-std.array,-std.base64,-std.bitmanip,-std.c.linux.linux,-std.compiler,-std.container.array,-std.conv,-std.datetime.date,-std.datetime.interval,-std.datetime.systime,-std.digest.digest,-std.digest.murmurhash,-std.digest.sha,-std.encoding,-std.exception,-std.experimental.allocator,-std.experimental.allocator.building_blocks.affix_allocator,-std.experimental.allocator.building_blocks.allocator_list,-std.experimental.allocator.building_blocks.bucketizer,-std.experimental.allocator.building_blocks.fallback_allocator,-std.experimental.allocator.building_blocks.free_list,-std.experimental.allocator.building_blocks.free_tree,-std.experimental.allocator.building_blocks.null_allocator,-std.experimental.allocator.building_blocks.region,-std.experimental.allocator.building_blocks.segregator,-std.experimental.allocator.common,-std.experimental.allocator.gc_allocator,-std.experimental.allocator.mallocator,-std.experimental.allocator.mmap_allocator,-std.experimental.checkedint,-std.experimental.typecons,-std.format,-std.functional,-std.getopt,-std.internal.digest.sha_SSSE3,-std.internal.math.errorfunction,-std.internal.math.gammafunction,-std.internal.test.dummyrange,-std.internal.unicode_tables,-std.json,-std.math,-std.meta,-std.numeric,-std.parallelism,-std.path,-std.process,-std.random,-std.range,-std.range.primitives,-std.regex,-std.regex.internal.ir,-std.regex.internal.kickstart,-std.signals,-std.socket,-std.stdio,-std.string,-std.uni,-std.uri,-std.utf,-std.uuid,-std.variant,-std.zlib" ; Checks for undocumented public declarations -undocumented_declaration_check="-etc.c.curl,-etc.c.odbc.sql,-etc.c.odbc.sqlext,-etc.c.odbc.sqltypes,-etc.c.odbc.sqlucode,-etc.c.sqlite3,-etc.c.zlib,-std.algorithm.sorting,-std.array,-std.ascii,-std.base64,-std.bitmanip,-std.c.linux.linux,-std.c.linux.socket,-std.c.osx.socket,-std.c.process,-std.compiler,-std.complex,-std.concurrency,-std.container,-std.container.array,-std.container.binaryheap,-std.container.dlist,-std.container.rbtree,-std.container.slist,-std.conv,-std.csv,-std.datetime.date,-std.digest.digest,-std.digest.hmac,-std.digest.md,-std.digest.murmurhash,-std.digest.ripemd,-std.digest.sha,-std.encoding,-std.exception,-std.experimental.allocator,-std.experimental.allocator.building_blocks.affix_allocator,-std.experimental.allocator.building_blocks.allocator_list,-std.experimental.allocator.building_blocks.bitmapped_block,-std.experimental.allocator.building_blocks.fallback_allocator,-std.experimental.allocator.building_blocks.free_list,-std.experimental.allocator.building_blocks.free_tree,-std.experimental.allocator.building_blocks.kernighan_ritchie,-std.experimental.allocator.building_blocks.quantizer,-std.experimental.allocator.building_blocks.region,-std.experimental.allocator.building_blocks.segregator,-std.experimental.allocator.building_blocks.stats_collector,-std.experimental.allocator.gc_allocator,-std.experimental.allocator.mallocator,-std.experimental.checkedint,-std.experimental.logger.core,-std.experimental.typecons,-std.file,-std.format,-std.functional,-std.internal.digest.sha_SSSE3,-std.internal.math.biguintcore,-std.internal.math.biguintnoasm,-std.internal.math.biguintx86,-std.internal.math.errorfunction,-std.internal.math.gammafunction,-std.internal.test.dummyrange,-std.internal.test.uda,-std.internal.windows.advapi32,-std.json,-std.math,-std.mmfile,-std.numeric,-std.outbuffer,-std.parallelism,-std.path,-std.process,-std.regex,-std.regex.internal.parser,-std.signals,-std.socket,-std.stdio,-std.string,-std.system,-std.uni,-std.utf,-std.variant,-std.windows.charset,-std.windows.registry,-std.windows.syserror,-std.xml,-std.zip,-std.zlib" +undocumented_declaration_check="-etc.c.curl,-etc.c.odbc.sql,-etc.c.odbc.sqlext,-etc.c.odbc.sqltypes,-etc.c.odbc.sqlucode,-etc.c.sqlite3,-etc.c.zlib,-std.algorithm.sorting,-std.array,-std.ascii,-std.base64,-std.bitmanip,-std.c.linux.linux,-std.c.linux.socket,-std.c.osx.socket,-std.c.process,-std.compiler,-std.complex,-std.concurrency,-std.container,-std.container.array,-std.container.binaryheap,-std.container.dlist,-std.container.rbtree,-std.container.slist,-std.conv,-std.csv,-std.datetime.date,-std.digest.digest,-std.digest.hmac,-std.digest.md,-std.digest.murmurhash,-std.digest.ripemd,-std.digest.sha,-std.encoding,-std.exception,-std.experimental.allocator,-std.experimental.allocator.building_blocks.affix_allocator,-std.experimental.allocator.building_blocks.allocator_list,-std.experimental.allocator.building_blocks.bitmapped_block,-std.experimental.allocator.building_blocks.fallback_allocator,-std.experimental.allocator.building_blocks.free_list,-std.experimental.allocator.building_blocks.free_tree,-std.experimental.allocator.building_blocks.kernighan_ritchie,-std.experimental.allocator.building_blocks.quantizer,-std.experimental.allocator.building_blocks.region,-std.experimental.allocator.building_blocks.segregator,-std.experimental.allocator.building_blocks.stats_collector,-std.experimental.allocator.gc_allocator,-std.experimental.allocator.mallocator,-std.experimental.checkedint,-std.experimental.logger.core,-std.experimental.typecons,-std.file,-std.format,-std.functional,-std.internal.digest.sha_SSSE3,-std.internal.math.biguintcore,-std.internal.math.biguintnoasm,-std.internal.math.biguintx86,-std.internal.math.errorfunction,-std.internal.math.gammafunction,-std.internal.test.dummyrange,-std.internal.test.uda,-std.internal.windows.advapi32,-std.json,-std.math,-std.mmfile,-std.numeric,-std.outbuffer,-std.parallelism,-std.path,-std.process,-std.regex,-std.regex.internal.parser,-std.signals,-std.socket,-std.stdio,-std.string,-std.system,-std.traits,-std.uni,-std.utf,-std.variant,-std.windows.charset,-std.windows.registry,-std.windows.syserror,-std.xml,-std.zip,-std.zlib" ; Checks for unused labels unused_label_check="-std.conv,-std.format,-std.internal.math.biguintx86,-std.regex.internal.thompson,-std.signals,-std.uni" ; Checks for unused variables and function parameters -unused_variable_check="-std.algorithm.comparison,-std.algorithm.iteration,-std.algorithm.mutation,-std.algorithm.searching,-std.algorithm.setops,-std.algorithm.sorting,-std.array,-std.bigint,-std.bitmanip,-std.complex,-std.concurrency,-std.container,-std.container.array,-std.container.dlist,-std.container.rbtree,-std.container.slist,-std.conv,-std.csv,-std.datetime,-std.datetime.date,-std.datetime.interval,-std.datetime.stopwatch,-std.datetime.systime,-std.datetime.timezone,-std.digest.crc,-std.digest.digest,-std.digest.md,-std.digest.murmurhash,-std.digest.ripemd,-std.digest.sha,-std.encoding,-std.exception,-std.experimental.allocator,-std.experimental.allocator.building_blocks.affix_allocator,-std.experimental.allocator.building_blocks.bitmapped_block,-std.experimental.allocator.building_blocks.bucketizer,-std.experimental.allocator.building_blocks.kernighan_ritchie,-std.experimental.allocator.building_blocks.stats_collector,-std.experimental.allocator.common,-std.experimental.allocator.gc_allocator,-std.experimental.allocator.mallocator,-std.experimental.allocator.typed,-std.experimental.checkedint,-std.experimental.logger.core,-std.experimental.typecons,-std.file,-std.format,-std.functional,-std.getopt,-std.internal.cstring,-std.internal.digest.sha_SSSE3,-std.internal.math.biguintcore,-std.internal.math.biguintx86,-std.internal.math.errorfunction,-std.internal.scopebuffer,-std.internal.test.dummyrange,-std.json,-std.math,-std.meta,-std.mmfile,-std.net.curl,-std.numeric,-std.parallelism,-std.process,-std.random,-std.range,-std.range.interfaces,-std.range.primitives,-std.regex.internal.backtracking,-std.regex.internal.tests,-std.regex.internal.thompson,-std.signals,-std.socket,-std.stdio,-std.string,-std.uni,-std.uri,-std.utf,-std.uuid,-std.variant,-std.windows.registry,-std.xml,-std.zip,-std.zlib" +unused_variable_check="-std.algorithm.comparison,-std.algorithm.iteration,-std.algorithm.mutation,-std.algorithm.searching,-std.algorithm.setops,-std.algorithm.sorting,-std.array,-std.bigint,-std.bitmanip,-std.complex,-std.concurrency,-std.container,-std.container.array,-std.container.dlist,-std.container.rbtree,-std.container.slist,-std.conv,-std.csv,-std.datetime,-std.datetime.date,-std.datetime.interval,-std.datetime.stopwatch,-std.datetime.systime,-std.datetime.timezone,-std.digest.crc,-std.digest.digest,-std.digest.md,-std.digest.murmurhash,-std.digest.ripemd,-std.digest.sha,-std.encoding,-std.exception,-std.experimental.allocator,-std.experimental.allocator.building_blocks.affix_allocator,-std.experimental.allocator.building_blocks.bitmapped_block,-std.experimental.allocator.building_blocks.bucketizer,-std.experimental.allocator.building_blocks.kernighan_ritchie,-std.experimental.allocator.building_blocks.stats_collector,-std.experimental.allocator.common,-std.experimental.allocator.gc_allocator,-std.experimental.allocator.mallocator,-std.experimental.allocator.typed,-std.experimental.checkedint,-std.experimental.logger.core,-std.experimental.typecons,-std.file,-std.format,-std.functional,-std.getopt,-std.internal.cstring,-std.internal.digest.sha_SSSE3,-std.internal.math.biguintcore,-std.internal.math.biguintx86,-std.internal.math.errorfunction,-std.internal.scopebuffer,-std.internal.test.dummyrange,-std.json,-std.math,-std.meta,-std.mmfile,-std.net.curl,-std.numeric,-std.parallelism,-std.process,-std.random,-std.range,-std.range.interfaces,-std.range.primitives,-std.regex.internal.backtracking,-std.regex.internal.tests,-std.regex.internal.thompson,-std.signals,-std.socket,-std.stdio,-std.string,-std.traits,-std.typecons,-std.uni,-std.uri,-std.utf,-std.uuid,-std.variant,-std.windows.registry,-std.xml,-std.zip,-std.zlib" ; Check for useless user defined initializers useless_initializer="+disabled" ;useless_initializer="-etc.c.odbc.sqlext,-etc.c.zlib,-std.algorithm.iteration,-std.algorithm.mutation,-std.algorithm.searching,-std.algorithm.setops,-std.algorithm.sorting,-std.array,-std.bigint,-std.bitmanip,-std.compiler,-std.container.array,-std.container.dlist,-std.container.rbtree,-std.conv,-std.csv,-std.datetime.systime,-std.digest.md,-std.digest.murmurhash,-std.digest.ripemd,-std.encoding,-std.exception,-std.experimental.allocator,-std.experimental.allocator.building_blocks.bitmapped_block,-std.experimental.allocator.building_blocks.free_tree,-std.experimental.allocator.building_blocks.kernighan_ritchie,-std.experimental.allocator.common,-std.experimental.allocator.mallocator,-std.experimental.logger.core,-std.experimental.logger.multilogger,-std.file,-std.format,-std.functional,-std.getopt,-std.internal.cstring,-std.internal.digest.sha_SSSE3,-std.internal.math.biguintcore,-std.internal.math.biguintnoasm,-std.internal.math.biguintx86,-std.internal.math.gammafunction,-std.internal.test.dummyrange,-std.json,-std.math,-std.net.curl,-std.numeric,-std.parallelism,-std.path,-std.process,-std.random,-std.range,-std.range.interfaces,-std.range.primitives,-std.regex,-std.regex.internal.backtracking,-std.regex.internal.generator,-std.regex.internal.ir,-std.regex.internal.kickstart,-std.regex.internal.parser,-std.regex.internal.tests,-std.regex.internal.thompson,-std.signals,-std.socket,-std.stdio,-std.string,-std.uni,-std.uri,-std.utf,-std.uuid,-std.variant,-std.windows.registry,-std.windows.syserror,-std.xml,-std.zip,-std.zlib" diff --git a/posix.mak b/posix.mak index 5b91334065a..66d963f2325 100644 --- a/posix.mak +++ b/posix.mak @@ -537,9 +537,8 @@ style: publictests style_lint # runs static code analysis with Dscanner dscanner: | $(DSCANNER_DIR)/dsc - # at the moment libdparse has problems to parse some modules (->excludes) @echo "Running DScanner" - $(DSCANNER_DIR)/dsc --config .dscanner.ini --styleCheck $$(find etc std -type f -name '*.d' | grep -vE 'std/traits.d|std/typecons.d') -I. + $(DSCANNER_DIR)/dsc --config .dscanner.ini --styleCheck etc std -I. style_lint: dscanner $(LIB) @echo "Check for trailing whitespace" diff --git a/std/traits.d b/std/traits.d index c23e52c69a4..4bb0644ba94 100644 --- a/std/traits.d +++ b/std/traits.d @@ -590,7 +590,7 @@ private template fqnSym(alias T) static assert(fqn!Barrier == "core.sync.barrier.Barrier"); } -unittest +@safe unittest { struct TemplatedStruct() { @@ -854,7 +854,8 @@ private template fqnType(T, static assert(fqn!(typeof(data)) == format("shared(const(%s[string])[])", inner_name)); // Function types + function attributes - static assert(fqn!(typeof(func)) == format("const(%s[string])(ref %s, scope lazy string) ref", inner_name, inner_name)); + static assert(fqn!(typeof(func)) == format("const(%s[string])(ref %s, scope lazy string) ref", + inner_name, inner_name)); static assert(fqn!(typeof(retfunc)) == format("const(%s[string])(return %s) ref", inner_name, inner_name)); static assert(fqn!(typeof(inoutFunc)) == format("inout(%s(inout(%s)))", inner_name, inner_name)); static assert(fqn!(typeof(deleg)) == format("const(%s delegate(double, string) nothrow @safe)", inner_name)); @@ -1549,7 +1550,7 @@ template hasFunctionAttributes(args...) } /// -unittest +@safe unittest { real func(real x) pure nothrow @safe; static assert(hasFunctionAttributes!(func, "@safe", "pure")); @@ -1564,7 +1565,7 @@ unittest static assert(!hasFunctionAttributes!(myFunc!bool, "shared")); } -unittest +@system unittest { struct S { @@ -3640,7 +3641,7 @@ template hasStaticMember(T, string member) static void delegate() sd; void m(); - final void m2() const pure nothrow @nogc @safe; + void m2() const pure nothrow @nogc @safe; inout(int) iom() inout; static inout(int) iosf(inout int x); @@ -7213,7 +7214,7 @@ template Promoted(T) } /// -unittest +@safe unittest { ubyte a = 3, b = 5; static assert(is(typeof(a * b) == Promoted!ubyte)); @@ -7224,7 +7225,7 @@ unittest static assert(is(Promoted!double == double)); } -unittest +@safe unittest { // promote to int: foreach (T; AliasSeq!(bool, byte, ubyte, short, ushort, char, wchar)) @@ -7788,7 +7789,7 @@ template getSymbolsByUDA(alias symbol, alias attribute) } // #16387: getSymbolsByUDA works with structs but fails with classes -unittest +@safe unittest { enum Attr; class A diff --git a/std/typecons.d b/std/typecons.d index d4838d810dc..d1ad5edcfe9 100644 --- a/std/typecons.d +++ b/std/typecons.d @@ -1255,7 +1255,7 @@ private template ReverseTupleSpecs(T...) } // ensure that internal Tuple unittests are compiled -unittest +@safe unittest { Tuple!() t; } @@ -2848,7 +2848,7 @@ Returns: // https://issues.dlang.org/show_bug.cgi?id=11135 // disable test until https://issues.dlang.org/show_bug.cgi?id=15316 gets fixed -version (none) unittest +version (none) @system unittest { foreach (T; AliasSeq!(float, double, real)) { @@ -5729,10 +5729,22 @@ mixin template Proxy(alias a) auto ref opSliceAssign(this X, V )(auto ref V v) { return a[] = v; } auto ref opSliceAssign(this X, V, B, E)(auto ref V v, auto ref B b, auto ref E e) { return a[b .. e] = v; } - auto ref opOpAssign (string op, this X, V )(auto ref V v) { return mixin("a " ~op~"= v"); } - auto ref opIndexOpAssign(string op, this X, V, D...)(auto ref V v, auto ref D i) { return mixin("a[i] " ~op~"= v"); } - auto ref opSliceOpAssign(string op, this X, V )(auto ref V v) { return mixin("a[] " ~op~"= v"); } - auto ref opSliceOpAssign(string op, this X, V, B, E)(auto ref V v, auto ref B b, auto ref E e) { return mixin("a[b .. e] "~op~"= v"); } + auto ref opOpAssign (string op, this X, V )(auto ref V v) + { + return mixin("a " ~op~"= v"); + } + auto ref opIndexOpAssign(string op, this X, V, D...)(auto ref V v, auto ref D i) + { + return mixin("a[i] " ~op~"= v"); + } + auto ref opSliceOpAssign(string op, this X, V )(auto ref V v) + { + return mixin("a[] " ~op~"= v"); + } + auto ref opSliceOpAssign(string op, this X, V, B, E)(auto ref V v, auto ref B b, auto ref E e) + { + return mixin("a[b .. e] "~op~"= v"); + } template opDispatch(string name) { @@ -6619,7 +6631,7 @@ template scoped(T) size_t* currD = cast(size_t*) &Scoped_store[$ - size_t.sizeof]; if (d != *currD) { - import core.stdc.string; + import core.stdc.string : memmove; memmove(alignedStore, Scoped_store.ptr + *currD, __traits(classInstanceSize, T)); *currD = d; } From b9229d0960d0a43adbe83d40d2f3a88feda12d73 Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Fri, 30 Jun 2017 02:37:49 +0200 Subject: [PATCH 046/163] Enable has_public_example check --- .dscanner.ini | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.dscanner.ini b/.dscanner.ini index 4d3e92a09cd..958d79981ae 100644 --- a/.dscanner.ini +++ b/.dscanner.ini @@ -89,6 +89,8 @@ useless_initializer="enabled" allman_braces_check="enabled" ; Check for redundant attributes redundant_attributes_check="enabled" +; Check for public declarations without a documented unittest +has_public_example="enabled" ; Configure which modules are checked with a specific checker ; Please help to extend these checks onto more Phobos modules @@ -117,6 +119,8 @@ could_be_immutable_check="-std.algorithm.comparison,-std.algorithm.iteration,-st exception_check="-std.concurrency,-std.net.curl,-std.parallelism,-std.range,-std.socket,-std.typecons" ; Checks for poor placement of function attributes function_attribute_check="-std.algorithm.iteration,-std.concurrency,-std.conv,-std.datetime.interval,-std.exception,-std.functional,-std.net.curl,-std.numeric,-std.parallelism,-std.random,-std.range,-std.range.primitives,-std.socket,-std.traits,-std.typecons,-std.uni" +; Check for public declarations without a documented unittest +has_public_example="-etc.c.curl,-etc.c.sqlite3,-etc.c.zlib,-std.algorithm.comparison,-std.algorithm.mutation,-std.array,-std.ascii,-std.base64,-std.bitmanip,-std.complex,-std.concurrency,-std.container.array,-std.container.dlist,-std.container.rbtree,-std.container.slist,-std.conv,-std.csv,-std.datetime,-std.datetime.date,-std.datetime.interval,-std.datetime.stopwatch,-std.datetime.systime,-std.datetime.timezone,-std.demangle,-std.digest.digest,-std.digest.hmac,-std.digest.murmurhash,-std.digest.sha,-std.encoding,-std.exception,-std.experimental.allocator,-std.experimental.allocator.building_blocks.allocator_list,-std.experimental.allocator.building_blocks.bitmapped_block,-std.experimental.allocator.building_blocks.fallback_allocator,-std.experimental.allocator.building_blocks.free_list,-std.experimental.allocator.building_blocks.free_tree,-std.experimental.allocator.building_blocks.null_allocator,-std.experimental.allocator.building_blocks.stats_collector,-std.experimental.allocator.common,-std.experimental.allocator.mmap_allocator,-std.experimental.allocator.typed,-std.experimental.checkedint,-std.experimental.logger.core,-std.experimental.logger.filelogger,-std.experimental.logger.multilogger,-std.experimental.typecons,-std.file,-std.format,-std.getopt,-std.internal.math.biguintcore,-std.internal.math.biguintnoasm,-std.internal.math.errorfunction,-std.internal.math.gammafunction,-std.internal.scopebuffer,-std.internal.test.dummyrange,-std.json,-std.math,-std.mathspecial,-std.mmfile,-std.net.curl,-std.net.isemail,-std.numeric,-std.outbuffer,-std.parallelism,-std.path,-std.process,-std.random,-std.range,-std.range.interfaces,-std.range.primitives,-std.regex,-std.regex.internal.ir,-std.socket,-std.stdio,-std.string,-std.traits,-std.typecons,-std.uni,-std.uri,-std.utf,-std.uuid,-std.variant,-std.xml,-std.zip,-std.zlib" ; Check for sortedness of imports imports_sortedness="+disabled" ;imports_sortedness="-etc.c.curl,-std.algorithm.comparison,-std.algorithm.internal,-std.algorithm.iteration,-std.algorithm.mutation,-std.algorithm.searching,-std.algorithm.setops,-std.algorithm.sorting,-std.array,-std.bigint,-std.bitmanip,-std.c.freebsd.socket,-std.c.linux.pthread,-std.c.process,-std.complex,-std.concurrency,-std.container.array,-std.container.binaryheap,-std.container.dlist,-std.container.rbtree,-std.container.slist,-std.container.util,-std.conv,-std.datetime,-std.datetime.date,-std.datetime.interval,-std.datetime.systime,-std.datetime.timezone,-std.digest.digest,-std.digest.hmac,-std.exception,-std.experimental.allocator,-std.experimental.allocator.building_blocks,-std.experimental.allocator.building_blocks.affix_allocator,-std.experimental.allocator.building_blocks.allocator_list,-std.experimental.allocator.building_blocks.free_list,-std.experimental.allocator.building_blocks.free_tree,-std.experimental.allocator.building_blocks.kernighan_ritchie,-std.experimental.allocator.building_blocks.region,-std.experimental.allocator.common,-std.experimental.allocator.mallocator,-std.experimental.allocator.mmap_allocator,-std.experimental.allocator.showcase,-std.experimental.allocator.typed,-std.experimental.checkedint,-std.experimental.logger.core,-std.experimental.typecons,-std.file,-std.format,-std.functional,-std.getopt,-std.internal.math.biguintcore,-std.internal.test.dummyrange,-std.json,-std.math,-std.meta,-std.mmfile,-std.net.curl,-std.net.isemail,-std.numeric,-std.outbuffer,-std.parallelism,-std.path,-std.process,-std.random,-std.range,-std.range.primitives,-std.regex,-std.regex.internal.backtracking,-std.regex.internal.generator,-std.regex.internal.kickstart,-std.regex.internal.parser,-std.regex.internal.tests,-std.signals,-std.socket,-std.stdio,-std.string,-std.uni,-std.utf,-std.uuid,-std.variant,-std.windows.charset,-std.windows.registry,-std.windows.syserror,-std.zip" From 9456dd2a520863894290c342556e069553cae23d Mon Sep 17 00:00:00 2001 From: Roman Chistokhodov Date: Fri, 30 Jun 2017 16:38:14 +0300 Subject: [PATCH 047/163] Add documentation comments for ErrnoException constructors --- std/exception.d | 2 ++ 1 file changed, 2 insertions(+) diff --git a/std/exception.d b/std/exception.d index 5767e8710a0..5a239f30648 100644 --- a/std/exception.d +++ b/std/exception.d @@ -1485,11 +1485,13 @@ class ErrnoException : Exception { final @property uint errno() { return _errno; } /// Operating system error code. private uint _errno; + /// Constructor which takes an error message. The current global $(D errno) value is used as error code. this(string msg, string file = null, size_t line = 0) @trusted { import core.stdc.errno : errno; this(msg, errno, file, line); } + /// Constructor which takes an error message and error code. this(string msg, int errno, string file = null, size_t line = 0) @trusted { import core.stdc.string : strlen; From 87e7cc25a25134c53578332fdccb4ab4be23177e Mon Sep 17 00:00:00 2001 From: Roman Chistokhodov Date: Fri, 30 Jun 2017 18:12:46 +0300 Subject: [PATCH 048/163] Refer to global errno in ErrnoException doc comments --- std/exception.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/std/exception.d b/std/exception.d index 5a239f30648..12752009226 100644 --- a/std/exception.d +++ b/std/exception.d @@ -1485,7 +1485,7 @@ class ErrnoException : Exception { final @property uint errno() { return _errno; } /// Operating system error code. private uint _errno; - /// Constructor which takes an error message. The current global $(D errno) value is used as error code. + /// 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) @trusted { import core.stdc.errno : errno; From 3f8b5b30e7058452a7fa7aac1c321e6e45ef78ec Mon Sep 17 00:00:00 2001 From: ZombineDev Date: Fri, 30 Jun 2017 18:13:38 +0300 Subject: [PATCH 049/163] Annotate with @nogc most of std.datetime.date's API --- std/datetime/date.d | 218 ++++++++++++++++++++++---------------------- 1 file changed, 111 insertions(+), 107 deletions(-) diff --git a/std/datetime/date.d b/std/datetime/date.d index 453ebc3327f..9ee03fdfdfd 100644 --- a/std/datetime/date.d +++ b/std/datetime/date.d @@ -115,7 +115,7 @@ public: date = The date portion of $(LREF DateTime). tod = The time portion of $(LREF DateTime). +/ - this(in Date date, in TimeOfDay tod = TimeOfDay.init) @safe pure nothrow + this(in Date date, in TimeOfDay tod = TimeOfDay.init) @safe pure nothrow @nogc { _date = date; _tod = tod; @@ -184,7 +184,7 @@ public: $(TR $(TD this > rhs) $(TD > 0)) ) +/ - int opCmp(in DateTime rhs) @safe const pure nothrow + int opCmp(in DateTime rhs) const @safe pure nothrow @nogc { immutable dateResult = _date.opCmp(rhs._date); @@ -394,7 +394,7 @@ public: /++ The date portion of $(LREF DateTime). +/ - @property Date date() @safe const pure nothrow + @property Date date() const @safe pure nothrow @nogc { return _date; } @@ -424,7 +424,7 @@ public: Params: date = The Date to set this $(LREF DateTime)'s date portion to. +/ - @property void date(in Date date) @safe pure nothrow + @property void date(in Date date) @safe pure nothrow @nogc { _date = date; } @@ -446,7 +446,7 @@ public: /++ The time portion of $(LREF DateTime). +/ - @property TimeOfDay timeOfDay() @safe const pure nothrow + @property TimeOfDay timeOfDay() const @safe pure nothrow @nogc { return _tod; } @@ -477,7 +477,7 @@ public: tod = The $(REF TimeOfDay,std,datetime,date) to set this $(LREF DateTime)'s time portion to. +/ - @property void timeOfDay(in TimeOfDay tod) @safe pure nothrow + @property void timeOfDay(in TimeOfDay tod) @safe pure nothrow @nogc { _tod = tod; } @@ -500,7 +500,7 @@ public: Year of the Gregorian Calendar. Positive numbers are A.D. Non-positive are B.C. +/ - @property short year() @safe const pure nothrow + @property short year() const @safe pure nothrow @nogc { return _date.year; } @@ -573,7 +573,7 @@ public: Throws: $(REF DateTimeException,std,datetime,date) if $(D isAD) is true. +/ - @property short yearBC() @safe const pure + @property short yearBC() const @safe pure { return _date.yearBC; } @@ -643,7 +643,7 @@ public: /++ Month of a Gregorian Year. +/ - @property Month month() @safe const pure nothrow + @property Month month() const @safe pure nothrow @nogc { return _date.month; } @@ -713,7 +713,7 @@ public: /++ Day of a Gregorian Month. +/ - @property ubyte day() @safe const pure nothrow + @property ubyte day() const @safe pure nothrow @nogc { return _date.day; } @@ -856,7 +856,7 @@ public: /++ Hours past midnight. +/ - @property ubyte hour() @safe const pure nothrow + @property ubyte hour() const @safe pure nothrow @nogc { return _tod.hour; } @@ -906,7 +906,7 @@ public: /++ Minutes past the hour. +/ - @property ubyte minute() @safe const pure nothrow + @property ubyte minute() const @safe pure nothrow @nogc { return _tod.minute; } @@ -956,7 +956,7 @@ public: /++ Seconds past the minute. +/ - @property ubyte second() @safe const pure nothrow + @property ubyte second() const @safe pure nothrow @nogc { return _tod.second; } @@ -1023,7 +1023,7 @@ public: causing the month to increment. +/ ref DateTime add(string units) - (long value, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) @safe pure nothrow + (long value, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) @safe pure nothrow @nogc if (units == "years" || units == "months") { _date.add!units(value, allowOverflow); @@ -1085,7 +1085,7 @@ public: causing the month to increment. +/ ref DateTime roll(string units) - (long value, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) @safe pure nothrow + (long value, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) @safe pure nothrow @nogc if (units == "years" || units == "months") { _date.roll!units(value, allowOverflow); @@ -1151,7 +1151,7 @@ public: value = The number of $(D_PARAM units) to add to this $(LREF DateTime). +/ - ref DateTime roll(string units)(long value) @safe pure nothrow + ref DateTime roll(string units)(long value) @safe pure nothrow @nogc if (units == "days") { _date.roll!"days"(value); @@ -1192,7 +1192,7 @@ public: // Shares documentation with "days" version. - ref DateTime roll(string units)(long value) @safe pure nothrow + ref DateTime roll(string units)(long value) @safe pure nothrow @nogc if (units == "hours" || units == "minutes" || units == "seconds") @@ -2079,7 +2079,7 @@ public: duration = The $(REF Duration, core,time) to add to or subtract from this $(LREF DateTime). +/ - DateTime opBinary(string op)(Duration duration) @safe const pure nothrow + DateTime opBinary(string op)(Duration duration) const @safe pure nothrow @nogc if (op == "+" || op == "-") { DateTime retval = this; @@ -2156,7 +2156,7 @@ public: // Explicitly undocumented. It will be removed in January 2018. @@@DEPRECATED_2018-01@@@ deprecated("Use Duration instead of TickDuration.") - DateTime opBinary(string op)(in TickDuration td) @safe const pure nothrow + DateTime opBinary(string op)(in TickDuration td) const @safe pure nothrow @nogc if (op == "+" || op == "-") { DateTime retval = this; @@ -2198,7 +2198,7 @@ public: duration = The duration to add to or subtract from this $(LREF DateTime). +/ - ref DateTime opOpAssign(string op, D)(in D duration) @safe pure nothrow + ref DateTime opOpAssign(string op, D)(in D duration) @safe pure nothrow @nogc if ((op == "+" || op == "-") && (is(Unqual!D == Duration) || is(Unqual!D == TickDuration))) @@ -2300,7 +2300,7 @@ public: // Explicitly undocumented. It will be removed in January 2018. @@@DEPRECATED_2018-01@@@ deprecated("Use Duration instead of TickDuration.") - ref DateTime opOpAssign(string op)(TickDuration td) @safe pure nothrow + ref DateTime opOpAssign(string op)(TickDuration td) @safe pure nothrow @nogc if (op == "+" || op == "-") { DateTime retval = this; @@ -2350,7 +2350,7 @@ public: $(TR $(TD DateTime) $(TD -) $(TD DateTime) $(TD -->) $(TD duration)) ) +/ - Duration opBinary(string op)(in DateTime rhs) @safe const pure nothrow + Duration opBinary(string op)(in DateTime rhs) const @safe pure nothrow @nogc if (op == "-") { immutable dateResult = _date - rhs.date; @@ -2435,7 +2435,7 @@ public: Params: rhs = The $(LREF DateTime) to subtract from this one. +/ - int diffMonths(in DateTime rhs) @safe const pure nothrow + int diffMonths(in DateTime rhs) const @safe pure nothrow @nogc { return _date.diffMonths(rhs._date); } @@ -2478,7 +2478,7 @@ public: /++ Whether this $(LREF DateTime) is in a leap year. +/ - @property bool isLeapYear() @safe const pure nothrow + @property bool isLeapYear() const @safe pure nothrow @nogc { return _date.isLeapYear; } @@ -2497,7 +2497,7 @@ public: /++ Day of the week this $(LREF DateTime) is on. +/ - @property DayOfWeek dayOfWeek() @safe const pure nothrow + @property DayOfWeek dayOfWeek() const @safe pure nothrow @nogc { return _date.dayOfWeek; } @@ -2516,7 +2516,7 @@ public: /++ Day of the year this $(LREF DateTime) is on. +/ - @property ushort dayOfYear() @safe const pure nothrow + @property ushort dayOfYear() const @safe pure nothrow @nogc { return _date.dayOfYear; } @@ -2547,7 +2547,7 @@ public: day = The day of the year to set which day of the year this $(LREF DateTime) is on. +/ - @property void dayOfYear(int day) @safe pure + @property void dayOfYear(int day) @safe pure nothrow @nogc { _date.dayOfYear = day; } @@ -2567,7 +2567,7 @@ public: /++ The Xth day of the Gregorian Calendar that this $(LREF DateTime) is on. +/ - @property int dayOfGregorianCal() @safe const pure nothrow + @property int dayOfGregorianCal() const @safe pure nothrow @nogc { return _date.dayOfGregorianCal; } @@ -2605,7 +2605,7 @@ public: days = The day of the Gregorian Calendar to set this $(LREF DateTime) to. +/ - @property void dayOfGregorianCal(int days) @safe pure nothrow + @property void dayOfGregorianCal(int days) @safe pure nothrow @nogc { _date.dayOfGregorianCal = days; } @@ -2654,7 +2654,7 @@ public: See_Also: $(HTTP en.wikipedia.org/wiki/ISO_week_date, ISO Week Date) +/ - @property ubyte isoWeek() @safe const pure nothrow + @property ubyte isoWeek() const @safe pure nothrow { return _date.isoWeek; } @@ -2675,7 +2675,7 @@ public: $(LREF DateTime) is in. The time portion of endOfMonth is always 23:59:59. +/ - @property DateTime endOfMonth() @safe const pure nothrow + @property DateTime endOfMonth() const @safe pure nothrow { try return DateTime(_date.endOfMonth, TimeOfDay(23, 59, 59)); @@ -2741,7 +2741,7 @@ public: /++ The last day in the month that this $(LREF DateTime) is in. +/ - @property ubyte daysInMonth() @safe const pure nothrow + @property ubyte daysInMonth() const @safe pure nothrow @nogc { return _date.daysInMonth; } @@ -2767,7 +2767,7 @@ public: /++ Whether the current year is a date in A.D. +/ - @property bool isAD() @safe const pure nothrow + @property bool isAD() const @safe pure nothrow @nogc { return _date.isAD; } @@ -2797,7 +2797,7 @@ public: returns 2_450_173, while from noon onward, the julian day number would be 2_450_174, so this function returns 2_450_174. +/ - @property long julianDay() @safe const pure nothrow + @property long julianDay() const @safe pure nothrow @nogc { if (_tod._hour < 12) return _date.julianDay - 1; @@ -2842,7 +2842,7 @@ public: The modified $(HTTP en.wikipedia.org/wiki/Julian_day, Julian day) for any time on this date (since, the modified Julian day changes at midnight). +/ - @property long modJulianDay() @safe const pure nothrow + @property long modJulianDay() const @safe pure nothrow @nogc { return _date.modJulianDay; } @@ -2865,7 +2865,7 @@ public: /++ Converts this $(LREF DateTime) to a string with the format YYYYMMDDTHHMMSS. +/ - string toISOString() @safe const pure nothrow + string toISOString() const @safe pure nothrow { import std.format : format; try @@ -2918,7 +2918,7 @@ public: Converts this $(LREF DateTime) to a string with the format YYYY-MM-DDTHH:MM:SS. +/ - string toISOExtString() @safe const pure nothrow + string toISOExtString() const @safe pure nothrow { import std.format : format; try @@ -2970,7 +2970,7 @@ public: Converts this $(LREF DateTime) to a string with the format YYYY-Mon-DD HH:MM:SS. +/ - string toSimpleString() @safe const pure nothrow + string toSimpleString() const @safe pure nothrow { import std.format : format; try @@ -3022,7 +3022,7 @@ public: /++ Converts this $(LREF DateTime) to a string. +/ - string toString() @safe const pure nothrow + string toString() const @safe pure nothrow { return toSimpleString(); } @@ -3311,7 +3311,7 @@ public: Returns the $(LREF DateTime) farthest in the past which is representable by $(LREF DateTime). +/ - @property static DateTime min() @safe pure nothrow + @property static DateTime min() @safe pure nothrow @nogc out(result) { assert(result._date == Date.min); @@ -3338,7 +3338,7 @@ public: Returns the $(LREF DateTime) farthest in the future which is representable by $(LREF DateTime). +/ - @property static DateTime max() @safe pure nothrow + @property static DateTime max() @safe pure nothrow @nogc out(result) { assert(result._date == Date.max); @@ -3375,7 +3375,7 @@ private: Params: seconds = The number of seconds to add to this $(LREF DateTime). +/ - ref DateTime _addSeconds(long seconds) return @safe pure nothrow + ref DateTime _addSeconds(long seconds) return @safe pure nothrow @nogc { long hnsecs = convert!("seconds", "hnsecs")(seconds); hnsecs += convert!("hours", "hnsecs")(_tod._hour); @@ -3688,7 +3688,7 @@ public: day = The Xth day of the Gregorian Calendar that the constructed $(LREF Date) will be for. +/ - this(int day) @safe pure nothrow + this(int day) @safe pure nothrow @nogc { if (day > 0) { @@ -3831,7 +3831,7 @@ public: $(TR $(TD this > rhs) $(TD > 0)) ) +/ - int opCmp(in Date rhs) @safe const pure nothrow + int opCmp(in Date rhs) const @safe pure nothrow @nogc { if (_year < rhs._year) return -1; @@ -3939,7 +3939,7 @@ public: Year of the Gregorian Calendar. Positive numbers are A.D. Non-positive are B.C. +/ - @property short year() @safe const pure nothrow + @property short year() const @safe pure nothrow @nogc { return _year; } @@ -4021,7 +4021,7 @@ public: Throws: $(REF DateTimeException,std,datetime,date) if $(D isAD) is true. +/ - @property ushort yearBC() @safe const pure + @property ushort yearBC() const @safe pure { import std.format : format; @@ -4096,7 +4096,7 @@ public: /++ Month of a Gregorian Year. +/ - @property Month month() @safe const pure nothrow + @property Month month() const @safe pure nothrow @nogc { return _month; } @@ -4166,7 +4166,7 @@ public: /++ Day of a Gregorian Month. +/ - @property ubyte day() @safe const pure nothrow + @property ubyte day() const @safe pure nothrow @nogc { return _day; } @@ -4324,7 +4324,8 @@ public: allowOverflow = Whether the day should be allowed to overflow, causing the month to increment. +/ - ref Date add(string units)(long value, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) @safe pure nothrow + @safe pure nothrow @nogc + ref Date add(string units)(long value, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) if (units == "years") { _year += value; @@ -4564,7 +4565,8 @@ public: // Shares documentation with "years" version. - ref Date add(string units)(long months, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) @safe pure nothrow + @safe pure nothrow @nogc + ref Date add(string units)(long months, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) if (units == "months") { auto years = months / 12; @@ -5104,7 +5106,8 @@ public: allowOverflow = Whether the day should be allowed to overflow, causing the month to increment. +/ - ref Date roll(string units)(long value, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) @safe pure nothrow + @safe pure nothrow @nogc + ref Date roll(string units)(long value, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) if (units == "years") { return add!"years"(value, allowOverflow); @@ -5148,7 +5151,8 @@ public: // Shares documentation with "years" version. - ref Date roll(string units)(long months, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) @safe pure nothrow + @safe pure nothrow @nogc + ref Date roll(string units)(long months, AllowDayOverflow allowOverflow = AllowDayOverflow.yes) if (units == "months") { months %= 12; @@ -5742,7 +5746,7 @@ public: units = The units to add. Must be $(D "days"). days = The number of days to add to this $(LREF Date). +/ - ref Date roll(string units)(long days) @safe pure nothrow + ref Date roll(string units)(long days) @safe pure nothrow @nogc if (units == "days") { immutable limit = maxDay(_year, _month); @@ -5980,7 +5984,7 @@ public: duration = The $(REF Duration, core,time) to add to or subtract from this $(LREF Date). +/ - Date opBinary(string op)(Duration duration) @safe const pure nothrow + Date opBinary(string op)(Duration duration) const @safe pure nothrow @nogc if (op == "+" || op == "-") { Date retval = this; @@ -6054,7 +6058,7 @@ public: // Explicitly undocumented. It will be removed in January 2018. @@@DEPRECATED_2018-01@@@ deprecated("Use Duration instead of TickDuration.") - Date opBinary(string op)(TickDuration td) @safe const pure nothrow + Date opBinary(string op)(TickDuration td) const @safe pure nothrow @nogc if (op == "+" || op == "-") { Date retval = this; @@ -6095,7 +6099,7 @@ public: duration = The $(REF Duration, core,time) to add to or subtract from this $(LREF Date). +/ - ref Date opOpAssign(string op)(Duration duration) @safe pure nothrow + ref Date opOpAssign(string op)(Duration duration) @safe pure nothrow @nogc if (op == "+" || op == "-") { immutable days = duration.total!"days"; @@ -6161,7 +6165,7 @@ public: // Explicitly undocumented. It will be removed in January 2018. @@@DEPRECATED_2018-01@@@ deprecated("Use Duration instead of TickDuration.") - ref Date opOpAssign(string op)(TickDuration td) @safe pure nothrow + ref Date opOpAssign(string op)(TickDuration td) @safe pure nothrow @nogc if (op == "+" || op == "-") { immutable days = convert!("seconds", "days")(td.seconds); @@ -6210,7 +6214,7 @@ public: $(TR $(TD Date) $(TD -) $(TD Date) $(TD -->) $(TD duration)) ) +/ - Duration opBinary(string op)(in Date rhs) @safe const pure nothrow + Duration opBinary(string op)(in Date rhs) const @safe pure nothrow @nogc if (op == "-") { return dur!"days"(this.dayOfGregorianCal - rhs.dayOfGregorianCal); @@ -6264,7 +6268,7 @@ public: Params: rhs = The $(LREF Date) to subtract from this one. +/ - int diffMonths(in Date rhs) @safe const pure nothrow + int diffMonths(in Date rhs) const @safe pure nothrow @nogc { immutable yearDiff = _year - rhs._year; immutable monthDiff = _month - rhs._month; @@ -6502,7 +6506,7 @@ public: /++ Whether this $(LREF Date) is in a leap year. +/ - @property bool isLeapYear() @safe const pure nothrow + @property bool isLeapYear() const @safe pure nothrow @nogc { return yearIsLeapYear(_year); } @@ -6521,7 +6525,7 @@ public: /++ Day of the week this $(LREF Date) is on. +/ - @property DayOfWeek dayOfWeek() @safe const pure nothrow + @property DayOfWeek dayOfWeek() const @safe pure nothrow @nogc { return getDayOfWeek(dayOfGregorianCal); } @@ -6540,7 +6544,7 @@ public: /++ Day of the year this $(LREF Date) is on. +/ - @property ushort dayOfYear() @safe const pure nothrow + @property ushort dayOfYear() const @safe pure nothrow @nogc { if (_month >= Month.jan && _month <= Month.dec) { @@ -6594,12 +6598,12 @@ public: $(REF DateTimeException,std,datetime,date) if the given day is an invalid day of the year. +/ - @property void dayOfYear(int day) @safe pure + @property void dayOfYear(int day) @safe pure nothrow @nogc { immutable int[] lastDay = isLeapYear ? lastDayLeap : lastDayNonLeap; if (day <= 0 || day > (isLeapYear ? daysInLeapYear : daysInYear)) - throw new DateTimeException("Invalid day of the year."); + assert(0, "Invalid day of the year."); foreach (i; 1 .. lastDay.length) { @@ -6644,7 +6648,7 @@ public: /++ The Xth day of the Gregorian Calendar that this $(LREF Date) is on. +/ - @property int dayOfGregorianCal() @safe const pure nothrow + @property int dayOfGregorianCal() const @safe pure nothrow @nogc { if (isAD) { @@ -6733,7 +6737,7 @@ public: Params: day = The day of the Gregorian Calendar to set this $(LREF Date) to. +/ - @property void dayOfGregorianCal(int day) @safe pure nothrow + @property void dayOfGregorianCal(int day) @safe pure nothrow @nogc { this = Date(day); } @@ -6785,7 +6789,7 @@ public: See_Also: $(HTTP en.wikipedia.org/wiki/ISO_week_date, ISO Week Date) +/ - @property ubyte isoWeek() @safe const pure nothrow + @property ubyte isoWeek() const @safe pure nothrow { immutable weekday = dayOfWeek; immutable adjustedWeekday = weekday == DayOfWeek.sun ? 7 : weekday; @@ -6884,7 +6888,7 @@ public: /++ $(LREF Date) for the last day in the month that this $(LREF Date) is in. +/ - @property Date endOfMonth() @safe const pure nothrow + @property Date endOfMonth() const @safe pure nothrow { try return Date(_year, _month, maxDay(_year, _month)); @@ -6943,7 +6947,7 @@ public: /++ The last day in the month that this $(LREF Date) is in. +/ - @property ubyte daysInMonth() @safe const pure nothrow + @property ubyte daysInMonth() const @safe pure nothrow @nogc { return maxDay(_year, _month); } @@ -6999,7 +7003,7 @@ public: /++ Whether the current year is a date in A.D. +/ - @property bool isAD() @safe const pure nothrow + @property bool isAD() const @safe pure nothrow @nogc { return _year > 0; } @@ -7032,7 +7036,7 @@ public: The $(HTTP en.wikipedia.org/wiki/Julian_day, Julian day) for this $(LREF Date) at noon (since the Julian day changes at noon). +/ - @property long julianDay() @safe const pure nothrow + @property long julianDay() const @safe pure nothrow @nogc { return dayOfGregorianCal + 1_721_425; } @@ -7060,7 +7064,7 @@ public: any time on this date (since, the modified Julian day changes at midnight). +/ - @property long modJulianDay() @safe const pure nothrow + @property long modJulianDay() const @safe pure nothrow @nogc { return julianDay - 2_400_001; } @@ -7080,7 +7084,7 @@ public: /++ Converts this $(LREF Date) to a string with the format YYYYMMDD. +/ - string toISOString() @safe const pure nothrow + string toISOString() const @safe pure nothrow { import std.format : format; try @@ -7136,7 +7140,7 @@ public: /++ Converts this $(LREF Date) to a string with the format YYYY-MM-DD. +/ - string toISOExtString() @safe const pure nothrow + string toISOExtString() const @safe pure nothrow { import std.format : format; try @@ -7192,7 +7196,7 @@ public: /++ Converts this $(LREF Date) to a string with the format YYYY-Mon-DD. +/ - string toSimpleString() @safe const pure nothrow + string toSimpleString() const @safe pure nothrow { import std.format : format; try @@ -7249,7 +7253,7 @@ public: /++ Converts this $(LREF Date) to a string. +/ - string toString() @safe const pure nothrow + string toString() const @safe pure nothrow { return toSimpleString(); } @@ -7654,7 +7658,7 @@ public: Returns the $(LREF Date) farthest in the past which is representable by $(LREF Date). +/ - @property static Date min() @safe pure nothrow + @property static Date min() @safe pure nothrow @nogc { auto date = Date.init; date._year = short.min; @@ -7675,7 +7679,7 @@ public: Returns the $(LREF Date) farthest in the future which is representable by $(LREF Date). +/ - @property static Date max() @safe pure nothrow + @property static Date max() @safe pure nothrow @nogc { auto date = Date.init; date._year = short.max; @@ -7702,7 +7706,7 @@ private: month = The month of the Gregorian Calendar to test. day = The day of the month to test. +/ - static bool _valid(int year, int month, int day) @safe pure nothrow + static bool _valid(int year, int month, int day) @safe pure nothrow @nogc { if (!valid!"months"(month)) return false; @@ -7728,7 +7732,7 @@ package: Params: days = The number of days to add to this Date. +/ - ref Date _addDays(long days) return @safe pure nothrow + ref Date _addDays(long days) return @safe pure nothrow @nogc { dayOfGregorianCal = cast(int)(dayOfGregorianCal + days); return this; @@ -7978,7 +7982,7 @@ public: $(TR $(TD this > rhs) $(TD > 0)) ) +/ - int opCmp(in TimeOfDay rhs) @safe const pure nothrow + int opCmp(in TimeOfDay rhs) const @safe pure nothrow @nogc { if (_hour < rhs._hour) return -1; @@ -8038,7 +8042,7 @@ public: /++ Hours past midnight. +/ - @property ubyte hour() @safe const pure nothrow + @property ubyte hour() const @safe pure nothrow @nogc { return _hour; } @@ -8089,7 +8093,7 @@ public: /++ Minutes past the hour. +/ - @property ubyte minute() @safe const pure nothrow + @property ubyte minute() const @safe pure nothrow @nogc { return _minute; } @@ -8140,7 +8144,7 @@ public: /++ Seconds past the minute. +/ - @property ubyte second() @safe const pure nothrow + @property ubyte second() const @safe pure nothrow @nogc { return _second; } @@ -8204,7 +8208,7 @@ public: value = The number of $(D_PARAM units) to add to this $(LREF TimeOfDay). +/ - ref TimeOfDay roll(string units)(long value) @safe pure nothrow + ref TimeOfDay roll(string units)(long value) @safe pure nothrow @nogc if (units == "hours") { return this += dur!"hours"(value); @@ -8252,7 +8256,7 @@ public: // Shares documentation with "hours" version. - ref TimeOfDay roll(string units)(long value) @safe pure nothrow + ref TimeOfDay roll(string units)(long value) @safe pure nothrow @nogc if (units == "minutes" || units == "seconds") { import std.format : format; @@ -8447,7 +8451,7 @@ public: duration = The $(REF Duration, core,time) to add to or subtract from this $(LREF TimeOfDay). +/ - TimeOfDay opBinary(string op)(Duration duration) @safe const pure nothrow + TimeOfDay opBinary(string op)(Duration duration) const @safe pure nothrow @nogc if (op == "+" || op == "-") { TimeOfDay retval = this; @@ -8517,7 +8521,7 @@ public: // Explicitly undocumented. It will be removed in January 2018. @@@DEPRECATED_2018-01@@@ deprecated("Use Duration instead of TickDuration.") - TimeOfDay opBinary(string op)(TickDuration td) @safe const pure nothrow + TimeOfDay opBinary(string op)(TickDuration td) const @safe pure nothrow @nogc if (op == "+" || op == "-") { TimeOfDay retval = this; @@ -8559,7 +8563,7 @@ public: duration = The $(REF Duration, core,time) to add to or subtract from this $(LREF TimeOfDay). +/ - ref TimeOfDay opOpAssign(string op)(Duration duration) @safe pure nothrow + ref TimeOfDay opOpAssign(string op)(Duration duration) @safe pure nothrow @nogc if (op == "+" || op == "-") { immutable seconds = duration.total!"seconds"; @@ -8612,7 +8616,7 @@ public: // Explicitly undocumented. It will be removed in January 2018. @@@DEPRECATED_2018-01@@@ deprecated("Use Duration instead of TickDuration.") - ref TimeOfDay opOpAssign(string op)(TickDuration td) @safe pure nothrow + ref TimeOfDay opOpAssign(string op)(TickDuration td) @safe pure nothrow @nogc if (op == "+" || op == "-") { immutable seconds = td.seconds; @@ -8665,7 +8669,7 @@ public: Params: rhs = The $(LREF TimeOfDay) to subtract from this one. +/ - Duration opBinary(string op)(in TimeOfDay rhs) @safe const pure nothrow + Duration opBinary(string op)(in TimeOfDay rhs) const @safe pure nothrow @nogc if (op == "-") { immutable lhsSec = _hour * 3600 + _minute * 60 + _second; @@ -8706,7 +8710,7 @@ public: /++ Converts this $(LREF TimeOfDay) to a string with the format HHMMSS. +/ - string toISOString() @safe const pure nothrow + string toISOString() const @safe pure nothrow { import std.format : format; try @@ -8736,7 +8740,7 @@ public: /++ Converts this $(LREF TimeOfDay) to a string with the format HH:MM:SS. +/ - string toISOExtString() @safe const pure nothrow + string toISOExtString() const @safe pure nothrow { import std.format : format; try @@ -8766,7 +8770,7 @@ public: /++ Converts this TimeOfDay to a string. +/ - string toString() @safe const pure nothrow + string toString() const @safe pure nothrow { return toISOExtString(); } @@ -9012,7 +9016,7 @@ public: /++ Returns midnight. +/ - @property static TimeOfDay min() @safe pure nothrow + @property static TimeOfDay min() @safe pure nothrow @nogc { return TimeOfDay.init; } @@ -9029,7 +9033,7 @@ public: /++ Returns one second short of midnight. +/ - @property static TimeOfDay max() @safe pure nothrow + @property static TimeOfDay max() @safe pure nothrow @nogc { auto tod = TimeOfDay.init; tod._hour = maxHour; @@ -9061,7 +9065,7 @@ private: Params: seconds = The number of seconds to add to this TimeOfDay. +/ - ref TimeOfDay _addSeconds(long seconds) return @safe pure nothrow + ref TimeOfDay _addSeconds(long seconds) return @safe pure nothrow @nogc { long hnsecs = convert!("seconds", "hnsecs")(seconds); hnsecs += convert!("hours", "hnsecs")(_hour); @@ -9163,7 +9167,7 @@ private: /+ Whether the given values form a valid $(LREF TimeOfDay). +/ - static bool _valid(int hour, int minute, int second) @safe pure nothrow + static bool _valid(int hour, int minute, int second) @safe pure nothrow @nogc { return valid!"hours"(hour) && valid!"minutes"(minute) && valid!"seconds"(second); } @@ -9199,7 +9203,7 @@ package: units = The units of time to validate. value = The number to validate. +/ -bool valid(string units)(int value) @safe pure nothrow +bool valid(string units)(int value) @safe pure nothrow @nogc if (units == "months" || units == "hours" || units == "minutes" || @@ -9233,7 +9237,7 @@ if (units == "months" || month = The month of the day to validate. day = The day to validate. +/ -bool valid(string units)(int year, int month, int day) @safe pure nothrow +bool valid(string units)(int year, int month, int day) @safe pure nothrow @nogc if (units == "days") { return day > 0 && day <= maxDay(year, month); @@ -9313,7 +9317,7 @@ if (units == "days") currDoW = The current day of the week. dow = The day of the week to get the number of days to. +/ -int daysToDayOfWeek(DayOfWeek currDoW, DayOfWeek dow) @safe pure nothrow +int daysToDayOfWeek(DayOfWeek currDoW, DayOfWeek dow) @safe pure nothrow @nogc { if (currDoW == dow) return 0; @@ -9464,7 +9468,7 @@ int monthsToMonth(int currMonth, int month) @safe pure Params: year = The year to to be tested. +/ -bool yearIsLeapYear(int year) @safe pure nothrow +bool yearIsLeapYear(int year) @safe pure nothrow @nogc { if (year % 400 == 0) return true; @@ -9597,7 +9601,7 @@ private: can handle precision greater than hnsecs, and the few functions in core.time which deal with "nsecs" deal with it explicitly. +/ -bool validTimeUnits(string[] units...) @safe pure nothrow +bool validTimeUnits(string[] units...) @safe pure nothrow @nogc { import std.algorithm.searching : canFind; foreach (str; units) @@ -9688,7 +9692,7 @@ if (validTimeUnits(lhs, rhs)) // Helper function for CmpTimeUnits. -private int cmpTimeUnitsCTFE(string lhs, string rhs) @safe pure nothrow +private int cmpTimeUnitsCTFE(string lhs, string rhs) @safe pure nothrow @nogc { import std.algorithm.searching : countUntil; auto tstrings = timeStrings; @@ -9754,7 +9758,7 @@ immutable string[12] _monthNames = ["Jan", year = The year to get the day for. month = The month of the Gregorian Calendar to get the day for. +/ -ubyte maxDay(int year, int month) @safe pure nothrow +ubyte maxDay(int year, int month) @safe pure nothrow @nogc in { assert(valid!"months"(month)); @@ -9844,7 +9848,7 @@ body Returns: The number of the given units from converting hnsecs to those units. +/ -long splitUnitsFromHNSecs(string units)(ref long hnsecs) @safe pure nothrow +long splitUnitsFromHNSecs(string units)(ref long hnsecs) @safe pure nothrow @nogc if (validTimeUnits(units) && CmpTimeUnits!(units, "months") < 0) { import core.time : convert; @@ -9873,7 +9877,7 @@ if (validTimeUnits(units) && CmpTimeUnits!(units, "months") < 0) day = The day of the Gregorian Calendar for which to get the day of the week. +/ -DayOfWeek getDayOfWeek(int day) @safe pure nothrow +DayOfWeek getDayOfWeek(int day) @safe pure nothrow @nogc { // January 1st, 1 A.D. was a Monday if (day >= 0) From 8ef9c2f07b0b96b7c4c17d6754882fda3d3bc32a Mon Sep 17 00:00:00 2001 From: ZombineDev Date: Fri, 30 Jun 2017 20:31:57 +0300 Subject: [PATCH 050/163] Make throwing on invalid input optional in stda.datetime.date.Date.dayOfYear * Keep throwing on invalid input in the public API * Use assert for Date.this(), where exceptions are not appropriate --- std/datetime/date.d | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/std/datetime/date.d b/std/datetime/date.d index 9ee03fdfdfd..093c683b98b 100644 --- a/std/datetime/date.d +++ b/std/datetime/date.d @@ -2547,7 +2547,7 @@ public: day = The day of the year to set which day of the year this $(LREF DateTime) is on. +/ - @property void dayOfYear(int day) @safe pure nothrow @nogc + @property void dayOfYear(int day) @safe pure { _date.dayOfYear = day; } @@ -3738,20 +3738,14 @@ public: { _year = cast(short) years; - try - dayOfYear = day; - catch (Exception e) - assert(0, "dayOfYear assignment threw."); + setDayOfYear(day); } } else if (day <= 0 && -day < daysInLeapYear) { _year = 0; - try - dayOfYear = (daysInLeapYear + day); - catch (Exception e) - assert(0, "dayOfYear assignment threw."); + setDayOfYear(daysInLeapYear + day); } else { @@ -3803,10 +3797,7 @@ public: _year = cast(short) years; immutable newDoY = (yearIsLeapYear(_year) ? daysInLeapYear : daysInYear) + day + 1; - try - dayOfYear = newDoY; - catch (Exception e) - assert(0, "dayOfYear assignment threw."); + setDayOfYear(newDoY); } } } @@ -6598,12 +6589,26 @@ public: $(REF DateTimeException,std,datetime,date) if the given day is an invalid day of the year. +/ - @property void dayOfYear(int day) @safe pure nothrow @nogc + @property void dayOfYear(int day) @safe pure + { + setDayOfYear!true(day); + } + + private void setDayOfYear(bool useExceptions = false)(int day) { immutable int[] lastDay = isLeapYear ? lastDayLeap : lastDayNonLeap; - if (day <= 0 || day > (isLeapYear ? daysInLeapYear : daysInYear)) - assert(0, "Invalid day of the year."); + bool dayOutOfRange = day <= 0 || day > (isLeapYear ? daysInLeapYear : daysInYear); + enum errorMsg = "Invalid day of the year."; + + static if (useExceptions) + { + if (dayOutOfRange) throw new DateTimeException(errorMsg); + } + else + { + assert(!dayOutOfRange, errorMsg); + } foreach (i; 1 .. lastDay.length) { From 20d40a954cecfb8efa1cac8ba7659e64b837e4f0 Mon Sep 17 00:00:00 2001 From: Jack Stouffer Date: Thu, 29 Jun 2017 10:19:08 -0400 Subject: [PATCH 051/163] Switched package-wide datetime imports to new sub-packages --- std/experimental/logger/core.d | 3 ++- std/experimental/logger/filelogger.d | 2 +- std/file.d | 31 +++++++++++++++++++--------- std/net/curl.d | 4 ++-- std/zip.d | 4 ++-- 5 files changed, 28 insertions(+), 16 deletions(-) diff --git a/std/experimental/logger/core.d b/std/experimental/logger/core.d index c794d19461a..1cf25568081 100644 --- a/std/experimental/logger/core.d +++ b/std/experimental/logger/core.d @@ -2,7 +2,8 @@ module std.experimental.logger.core; import core.sync.mutex : Mutex; -import std.datetime; +import std.datetime.date : DateTime; +import std.datetime.systime : Clock, SysTime; import std.range.primitives; import std.traits; diff --git a/std/experimental/logger/filelogger.d b/std/experimental/logger/filelogger.d index 3b6e5ddddd7..43ace4cd178 100644 --- a/std/experimental/logger/filelogger.d +++ b/std/experimental/logger/filelogger.d @@ -11,7 +11,7 @@ is already present new log messages will be append at its end. class FileLogger : Logger { import std.concurrency : Tid; - import std.datetime : SysTime; + import std.datetime.systime : SysTime; import std.format : formattedWrite; /** A constructor for the $(D FileLogger) Logger. diff --git a/std/file.d b/std/file.d index d39093a37fe..59a86a91a8d 100644 --- a/std/file.d +++ b/std/file.d @@ -79,8 +79,10 @@ Source: $(PHOBOSSRC std/_file.d) module std.file; import core.stdc.errno, core.stdc.stdlib, core.stdc.string; +import core.time : abs, dur, hnsecs, seconds; -import std.datetime; +import std.datetime.date : DateTime; +import std.datetime.systime : Clock, SysTime, unixTimeToStdTime; import std.internal.cstring; import std.meta; import std.range.primitives; @@ -970,6 +972,8 @@ if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) && { version(Windows) { + import std.datetime.systime : FILETIMEToSysTime; + with (getFileAttributesWin(name)) { accessTime = FILETIMEToSysTime(&ftLastAccessTime); @@ -1102,11 +1106,13 @@ else version(Windows) if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) && !isConvertibleToString!R) { + import std.datetime.systime : FILETIMEToSysTime; + with (getFileAttributesWin(name)) { - fileCreationTime = std.datetime.FILETIMEToSysTime(&ftCreationTime); - fileAccessTime = std.datetime.FILETIMEToSysTime(&ftLastAccessTime); - fileModificationTime = std.datetime.FILETIMEToSysTime(&ftLastWriteTime); + fileCreationTime = FILETIMEToSysTime(&ftCreationTime); + fileAccessTime = FILETIMEToSysTime(&ftLastAccessTime); + fileModificationTime = FILETIMEToSysTime(&ftLastWriteTime); } } @@ -1210,6 +1216,8 @@ if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) && { version(Windows) { + import std.datetime.systime : SysTimeToFILETIME; + auto namez = name.tempCString!FSChar(); static auto trustedCreateFileW(const(FSChar)* namez, DWORD dwDesiredAccess, DWORD dwShareMode, SECURITY_ATTRIBUTES *lpSecurityAttributes, DWORD dwCreationDisposition, @@ -2966,6 +2974,8 @@ else version(Windows) this(string path) { + import std.datetime.systime : FILETIMEToSysTime; + if (!path.exists()) throw new FileException(path, "File does not exist"); @@ -2974,9 +2984,9 @@ else version(Windows) with (getFileAttributesWin(path)) { _size = makeUlong(nFileSizeLow, nFileSizeHigh); - _timeCreated = std.datetime.FILETIMEToSysTime(&ftCreationTime); - _timeLastAccessed = std.datetime.FILETIMEToSysTime(&ftLastAccessTime); - _timeLastModified = std.datetime.FILETIMEToSysTime(&ftLastWriteTime); + _timeCreated = FILETIMEToSysTime(&ftCreationTime); + _timeLastAccessed = FILETIMEToSysTime(&ftLastAccessTime); + _timeLastModified = FILETIMEToSysTime(&ftLastWriteTime); _attributes = dwFileAttributes; } } @@ -2984,15 +2994,16 @@ else version(Windows) private this(string path, in WIN32_FIND_DATAW *fd) { import core.stdc.wchar_ : wcslen; + import std.datetime.systime : FILETIMEToSysTime; import std.path : buildPath; size_t clength = wcslen(fd.cFileName.ptr); _name = toUTF8(fd.cFileName[0 .. clength]); _name = buildPath(path, toUTF8(fd.cFileName[0 .. clength])); _size = (cast(ulong) fd.nFileSizeHigh << 32) | fd.nFileSizeLow; - _timeCreated = std.datetime.FILETIMEToSysTime(&fd.ftCreationTime); - _timeLastAccessed = std.datetime.FILETIMEToSysTime(&fd.ftLastAccessTime); - _timeLastModified = std.datetime.FILETIMEToSysTime(&fd.ftLastWriteTime); + _timeCreated = FILETIMEToSysTime(&fd.ftCreationTime); + _timeLastAccessed = FILETIMEToSysTime(&fd.ftLastAccessTime); + _timeLastModified = FILETIMEToSysTime(&fd.ftLastWriteTime); _attributes = fd.dwFileAttributes; } diff --git a/std/net/curl.d b/std/net/curl.d index 6740ecfd86b..67c7dadaa61 100644 --- a/std/net/curl.d +++ b/std/net/curl.d @@ -1471,7 +1471,7 @@ private mixin template WorkerThreadProtocol(Unit, alias units) */ bool wait(Duration d) { - import std.datetime : StopWatch; + import std.datetime.stopwatch : StopWatch; if (state == State.gotUnits) return true; @@ -2384,7 +2384,7 @@ struct HTTP { mixin Protocol; - import std.datetime : SysTime; + import std.datetime.systime : SysTime; /// Authentication method equal to $(REF CurlAuth, etc,c,curl) alias AuthMethod = CurlAuth; diff --git a/std/zip.d b/std/zip.d index 47a3aa27a78..f27bbe0d6b1 100644 --- a/std/zip.d +++ b/std/zip.d @@ -98,7 +98,7 @@ enum CompressionMethod : ushort final class ArchiveMember { import std.conv : to, octal; - import std.datetime : DosFileTime, SysTime, SysTimeToDosFileTime; + import std.datetime.systime : DosFileTime, SysTime, SysTimeToDosFileTime; /** * Read/Write: Usually the file name of the archive member; it is used to @@ -289,7 +289,7 @@ final class ZipArchive import std.algorithm.comparison : max; import std.bitmanip : littleEndianToNative, nativeToLittleEndian; import std.conv : to; - import std.datetime : DosFileTime; + import std.datetime.systime : DosFileTime; string comment; /// Read/Write: the archive comment. Must be less than 65536 bytes in length. From 59108e6d3a6df2d2812ae55781280df69989076b Mon Sep 17 00:00:00 2001 From: Hackerpilot Date: Fri, 30 Jun 2017 13:21:56 -0700 Subject: [PATCH 052/163] Unit test for 17574. --- std/getopt.d | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/std/getopt.d b/std/getopt.d index 2a264980026..f54c6c2dc8c 100644 --- a/std/getopt.d +++ b/std/getopt.d @@ -973,6 +973,26 @@ private bool handleOption(R)(string option, R receiver, ref string[] args, return ret; } +// 17574 +@system unittest +{ + import std.algorithm.searching : startsWith; + + try + { + string[string] mapping; + immutable as = arraySep; + arraySep = ","; + scope (exit) + arraySep = as; + string[] args = ["testProgram", "-m", "a=b,c=\"d,e,f\""]; + args.getopt("m", &mapping); + assert(false, "Exception not thrown"); + } + catch (GetOptException goe) + assert(goe.msg.startsWith("Could not find")); +} + // 5316 - arrays with arraySep @system unittest { From dc7f8026055d4d2b2eb94ec7c11d21ae27d05d41 Mon Sep 17 00:00:00 2001 From: Roman Chistokhodov Date: Sat, 1 Jul 2017 01:43:24 +0300 Subject: [PATCH 053/163] Add errnoString to remove code duplication from some modules --- std/exception.d | 43 +++++++++++++++++++++++++++++-------------- std/file.d | 4 ++-- std/process.d | 15 ++------------- std/stdio.d | 26 ++------------------------ 4 files changed, 35 insertions(+), 53 deletions(-) diff --git a/std/exception.d b/std/exception.d index 12752009226..4667276adab 100644 --- a/std/exception.d +++ b/std/exception.d @@ -1478,6 +1478,34 @@ private bool isUnionAliasedImpl(T)(size_t offset) static assert( isUnionAliased!(S.A5, 1)); //a5.b1; } +package string errnoString(int errno) +{ + import core.stdc.string : strlen; + version (CRuntime_Glibc) + { + import core.stdc.string : strerror_r; + char[1024] buf = void; + auto s = strerror_r(errno, buf.ptr, buf.length); + } + else version (Posix) + { + // XSI-compliant + import core.stdc.string : strerror_r; + char[1024] buf = void; + const(char)* s; + if (strerror_r(errno, buf.ptr, buf.length) == 0) + s = buf.ptr; + else + s = "Unknown error"; + } + else + { + import core.stdc.string : strerror; + auto s = strerror(errno); + } + return s[0 .. s.strlen].idup; +} + /********************* * Thrown if errors that set $(D errno) occur. */ @@ -1494,21 +1522,8 @@ class ErrnoException : Exception /// Constructor which takes an error message and error code. this(string msg, int errno, string file = null, size_t line = 0) @trusted { - import core.stdc.string : strlen; - _errno = errno; - version (CRuntime_Glibc) - { - import core.stdc.string : strerror_r; - char[1024] buf = void; - auto s = strerror_r(errno, buf.ptr, buf.length); - } - else - { - import core.stdc.string : strerror; - auto s = strerror(errno); - } - super(msg ~ " (" ~ s[0 .. s.strlen].idup ~ ")", file, line); + super(msg ~ " (" ~ errnoString(errno) ~ ")", file, line); } @system unittest diff --git a/std/file.d b/std/file.d index 59a86a91a8d..47099789741 100644 --- a/std/file.d +++ b/std/file.d @@ -208,8 +208,8 @@ class FileException : Exception string file = __FILE__, size_t line = __LINE__) @trusted { - auto s = strerror(errno); - this(name, to!string(s), file, line); + import std.exception : errnoString; + this(name, errnoString(errno), file, line); this.errno = errno; } } diff --git a/std/process.d b/std/process.d index 93627da1e13..bcbedde89d6 100644 --- a/std/process.d +++ b/std/process.d @@ -2433,19 +2433,8 @@ class ProcessException : Exception string file = __FILE__, size_t line = __LINE__) { - import std.conv : to; - version (CRuntime_Glibc) - { - import core.stdc.string : strerror_r; - char[1024] buf; - auto errnoMsg = to!string( - core.stdc.string.strerror_r(error, buf.ptr, buf.length)); - } - else - { - import core.stdc.string : strerror; - auto errnoMsg = to!string(strerror(error)); - } + import std.exception : errnoString; + auto errnoMsg = errnoString(error); auto msg = customMsg.empty ? errnoMsg : customMsg ~ " (" ~ errnoMsg ~ ')'; return new ProcessException(msg, file, line); diff --git a/std/stdio.d b/std/stdio.d index 5f8df7bb939..ba4bd4592db 100644 --- a/std/stdio.d +++ b/std/stdio.d @@ -4477,31 +4477,9 @@ Initialize with a message and an error code. */ this(string message, uint e = core.stdc.errno.errno) @trusted { - import std.conv : to; - + import std.exception : errnoString; errno = e; - version (Posix) - { - import core.stdc.string : strerror_r; - - char[256] buf = void; - version (CRuntime_Glibc) - { - auto s = strerror_r(errno, buf.ptr, buf.length); - } - else - { - strerror_r(errno, buf.ptr, buf.length); - auto s = buf.ptr; - } - } - else - { - import core.stdc.string : strerror; - - auto s = strerror(errno); - } - auto sysmsg = to!string(s); + auto sysmsg = errnoString(errno); // If e is 0, we don't use the system error message. (The message // is "Success", which is rather pointless for an exception.) super(e == 0 ? message From 942da358c24081ec59821703bb0f450c2c6dc905 Mon Sep 17 00:00:00 2001 From: dukc Date: Tue, 27 Jun 2017 16:35:10 +0300 Subject: [PATCH 054/163] Some cleanup on imports and comments --- std/concurrency.d | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/std/concurrency.d b/std/concurrency.d index 5ecbb70488a..82eebdfd999 100644 --- a/std/concurrency.d +++ b/std/concurrency.d @@ -70,18 +70,11 @@ import core.sync.condition; import core.sync.mutex; import core.thread; import std.range.primitives; +import std.range.interfaces : InputRange; import std.traits; private { - import core.atomic; - import core.thread; - import core.sync.mutex; - import core.sync.condition; - import std.range.primitives; - import std.range.interfaces; - import std.traits; - template hasLocalAliasing(T...) { static if (!T.length) @@ -1602,8 +1595,8 @@ class Generator(T) : } /** - * Returns the most recently generated value without excuting a copy - * contructor. Will not compile for element types defining a + * Returns the most recently generated value without executing a + * copy contructor. Will not compile for element types defining a * postblit, because Generator does not return by reference. */ final T moveFront() @@ -1615,7 +1608,7 @@ class Generator(T) : else { static assert(0, - "Fiber front is rvalue and thus cannot be moved when it defines a postblit."); + "Fiber front is always rvalue and thus cannot be moved since it defines a postblit."); } } @@ -1672,7 +1665,6 @@ void yield(T)(T value) { import core.exception; import std.exception; - import std.range.interfaces; static void testScheduler(Scheduler s) { @@ -1710,7 +1702,6 @@ void yield(T)(T value) { tid.send(e); } - }); scheduler = null; } @@ -1752,7 +1743,6 @@ void yield(T)(T value) assert(counter == [7, 21]); } -// MessageBox Implementation private { /* From 954dccd7f156270ae6b17fdc6afd5fa5fa2916a2 Mon Sep 17 00:00:00 2001 From: Vladimir Panteleev Date: Sat, 1 Jul 2017 10:37:15 +0000 Subject: [PATCH 055/163] std.datetime: Clarify range of integer month parameters Months are 0-11 in C's tm and the old std.date, so it's better to clarify the range for every instance of `int month` in the API. --- std/datetime/date.d | 6 +++--- std/datetime/interval.d | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/std/datetime/date.d b/std/datetime/date.d index 093c683b98b..6e88f3d0040 100644 --- a/std/datetime/date.d +++ b/std/datetime/date.d @@ -146,7 +146,7 @@ public: /++ Params: year = The year portion of the date. - month = The month portion of the date. + month = The month portion of the date (January is 1). day = The day portion of the date. hour = The hour portion of the time; minute = The minute portion of the time; @@ -3609,7 +3609,7 @@ public: year = Year of the Gregorian Calendar. Positive values are A.D. Non-positive values are B.C. with year 0 being the year prior to 1 A.D. - month = Month of the year. + month = Month of the year (January is 1). day = Day of the month. +/ this(int year, int month, int day) @safe pure @@ -9239,7 +9239,7 @@ if (units == "months" || Params: units = The units of time to validate. year = The year of the day to validate. - month = The month of the day to validate. + month = The month of the day to validate (January is 1). day = The day to validate. +/ bool valid(string units)(int year, int month, int day) @safe pure nothrow @nogc diff --git a/std/datetime/interval.d b/std/datetime/interval.d index 302b4c28e99..936f280bebf 100644 --- a/std/datetime/interval.d +++ b/std/datetime/interval.d @@ -7690,7 +7690,8 @@ if (isTimePoint!TP && dir = The direction to iterate in. If passing the return value to $(D fwdRange), use $(D Direction.fwd). If passing it to $(D bwdRange), use $(D Direction.bwd). - month = The month that each time point in the range will be in. + month = The month that each time point in the range will be in + (January is 1). +/ TP delegate(in TP) everyMonth(TP, Direction dir = Direction.fwd)(int month) if (isTimePoint!TP && From 7f17f84ce1c6566f3da35792901eabc3762e3202 Mon Sep 17 00:00:00 2001 From: Roman Chistokhodov Date: Sat, 1 Jul 2017 15:01:12 +0300 Subject: [PATCH 056/163] Fix errnoString attributes --- std/exception.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/std/exception.d b/std/exception.d index 4667276adab..e24c1349d00 100644 --- a/std/exception.d +++ b/std/exception.d @@ -1478,7 +1478,7 @@ private bool isUnionAliasedImpl(T)(size_t offset) static assert( isUnionAliased!(S.A5, 1)); //a5.b1; } -package string errnoString(int errno) +package string errnoString(int errno) nothrow @trusted { import core.stdc.string : strlen; version (CRuntime_Glibc) From 9216d923a0e9fd63b7b21f3bbed57141ecabc731 Mon Sep 17 00:00:00 2001 From: Petar Kirov Date: Sat, 1 Jul 2017 20:13:35 +0300 Subject: [PATCH 057/163] [std.exception.errnoString]: avoid redundant allocation in case `strerror_r` fails. --- std/exception.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/std/exception.d b/std/exception.d index e24c1349d00..5a58a8fae74 100644 --- a/std/exception.d +++ b/std/exception.d @@ -1496,7 +1496,7 @@ package string errnoString(int errno) nothrow @trusted if (strerror_r(errno, buf.ptr, buf.length) == 0) s = buf.ptr; else - s = "Unknown error"; + return "Unknown error"; } else { From 10d05229ae6ce48927ac56ec694e9d1aea1ba8cc Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Wed, 28 Jun 2017 01:14:29 +0200 Subject: [PATCH 058/163] Make Phobos module examples runnable --- std/concurrency.d | 65 ++++++++++++++++++++++---------------------- std/random.d | 35 +++++++++++++----------- std/typecons.d | 56 +++++++++++++++++++++----------------- std/variant.d | 69 +++++++++++++++++++++++++---------------------- 4 files changed, 122 insertions(+), 103 deletions(-) diff --git a/std/concurrency.d b/std/concurrency.d index 4bff9020c1c..2aff38375ed 100644 --- a/std/concurrency.d +++ b/std/concurrency.d @@ -19,38 +19,6 @@ * schedulers are available that multiplex fibers across the main thread or * use some combination of the two approaches. * - * Synopsis: - * --- - * import std.stdio; - * import std.concurrency; - * - * void spawnedFunc(Tid ownerTid) - * { - * // Receive a message from the owner thread. - * receive( - * (int i) { writeln("Received the number ", i);} - * ); - * - * // Send a message back to the owner thread - * // indicating success. - * send(ownerTid, true); - * } - * - * void main() - * { - * // Start spawnedFunc in a new thread. - * auto childTid = spawn(&spawnedFunc, thisTid); - * - * // Send the number 42 to this new thread. - * send(childTid, 42); - * - * // Receive the result code. - * auto wasSuccessful = receiveOnly!(bool); - * assert(wasSuccessful); - * writeln("Successfully printed number."); - * } - * --- - * * Copyright: Copyright Sean Kelly 2009 - 2014. * License: Boost License 1.0. * Authors: Sean Kelly, Alex Rønne Petersen, Martin Nowak @@ -73,6 +41,39 @@ import std.range.primitives; import std.range.interfaces : InputRange; import std.traits; +// Avoids writeln output during a normal test-suite run +// Using writeln is very helpful for runnable unittest examples +version(unittest) +{ + void writeln(T...)(T t){} +} + +/// +@system unittest +{ + static void spawnedFunc(Tid ownerTid) + { + // Receive a message from the owner thread. + receive( + (int i) { writeln("Received the number ", i);} + ); + + // Send a message back to the owner thread + // indicating success. + send(ownerTid, true); + } + + // Start spawnedFunc in a new thread. + auto childTid = spawn(&spawnedFunc, thisTid); + + // Send the number 42 to this new thread. + send(childTid, 42); + + // Receive the result code. + auto wasSuccessful = receiveOnly!(bool); + assert(wasSuccessful); +} + private { template hasLocalAliasing(T...) diff --git a/std/random.d b/std/random.d index 7fcda195312..d7f8a563c68 100644 --- a/std/random.d +++ b/std/random.d @@ -23,21 +23,6 @@ useful. The standard library provides an alias $(D_PARAM Random) for whichever generator it considers the most fit for the target environment. -Example: - ----- -// Generate a uniformly-distributed integer in the range [0, 14] -auto i = uniform(0, 15); - -// Generate a uniformly-distributed real in the range [0, 100) -// using a specific random generator -Random gen; -auto r = uniform(0.0L, 100.0L, gen); - -// Generate a 32-bit random number -auto l = uniform!uint(); ----- - In addition to random number generators, this module features distributions, which skew a generator's output statistical distribution in various ways. So far the uniform distribution for @@ -70,6 +55,26 @@ module std.random; import std.range.primitives; import std.traits; +/// +@safe unittest +{ + // seed a random generator with a constant + auto rnd = Random(42); + + // Generate a uniformly-distributed integer in the range [0, 14] + // If no random generator is passed, the global `rndGen` would be used + auto i = uniform(0, 15, rnd); + assert(i == 12); + + // Generate a uniformly-distributed real in the range [0, 100) + auto r = uniform(0.0L, 100.0L, rnd); + assert(r == 79.65429843861011285); + + // Generate a 32-bit random number + auto u = uniform!uint(rnd); + assert(u == 4083286876); +} + version(unittest) { static import std.meta; diff --git a/std/typecons.d b/std/typecons.d index d1ad5edcfe9..2b163b13064 100644 --- a/std/typecons.d +++ b/std/typecons.d @@ -6,30 +6,6 @@ that allow construction of new, useful general-purpose types. Source: $(PHOBOSSRC std/_typecons.d) -Synopsis: - ----- -// value tuples -alias Coord = Tuple!(float, "x", float, "y", float, "z"); -Coord c; -c[1] = 1; // access by index -c.z = 1; // access by given name -alias DicEntry = Tuple!(string, string); // names can be omitted - -// Rebindable references to const and immutable objects -void bar() -{ - const w1 = new Widget, w2 = new Widget; - w1.foo(); - // w1 = w2 would not work; can't rebind const object - auto r = Rebindable!(const Widget)(w1); - // invoke method as if r were a Widget object - r.foo(); - // rebind r to refer to another object - r = w2; -} ----- - Copyright: Copyright the respective authors, 2008- License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). Authors: $(HTTP erdani.org, Andrei Alexandrescu), @@ -44,6 +20,38 @@ import core.stdc.stdint : uintptr_t; import std.meta; // : AliasSeq, allSatisfy; import std.traits; +/// +@safe unittest +{ + // value tuples + alias Coord = Tuple!(int, "x", int, "y", int, "z"); + Coord c; + c[1] = 1; // access by index + c.z = 1; // access by given name + assert(c == Coord(0, 1, 1)); + + // names can be omitted + alias DicEntry = Tuple!(string, string); + + // tuples can also be constructed on instantiation + assert(tuple(2, 3, 4)[1] == 3); + // construction on instantiation works with names too + assert(tuple!("x", "y", "z")(2, 3, 4).y == 3); + + // Rebindable references to const and immutable objects + { + class Widget { void foo() const @safe {} } + const w1 = new Widget, w2 = new Widget; + w1.foo(); + // w1 = w2 would not work; can't rebind const object + auto r = Rebindable!(const Widget)(w1); + // invoke method as if r were a Widget object + r.foo(); + // rebind r to refer to another object + r = w2; + } +} + debug(Unique) import std.stdio; /** diff --git a/std/variant.d b/std/variant.d index 8ca53732568..574e2c5a375 100644 --- a/std/variant.d +++ b/std/variant.d @@ -10,38 +10,6 @@ Such types are useful for type-uniform binary interfaces, interfacing with scripting languages, and comfortable exploratory programming. -Synopsis: ----- -Variant a; // Must assign before use, otherwise exception ensues -// Initialize with an integer; make the type int -Variant b = 42; -assert(b.type == typeid(int)); -// Peek at the value -assert(b.peek!(int) !is null && *b.peek!(int) == 42); -// Automatically convert per language rules -auto x = b.get!(real); -// Assign any other type, including other variants -a = b; -a = 3.14; -assert(a.type == typeid(double)); -// Implicit conversions work just as with built-in types -assert(a < b); -// Check for convertibility -assert(!a.convertsTo!(int)); // double not convertible to int -// Strings and all other arrays are supported -a = "now I'm a string"; -assert(a == "now I'm a string"); -a = new int[42]; // can also assign arrays -assert(a.length == 42); -a[5] = 7; -assert(a[5] == 7); -// Can also assign class values -class Foo {} -auto foo = new Foo; -a = foo; -assert(*a.peek!(Foo) == foo); // and full type information is preserved ----- - A $(LREF Variant) object can hold a value of any type, with very few restrictions (such as `shared` types and noncopyable types). Setting the value is as immediate as assigning to the `Variant` object. To read back the value of @@ -67,6 +35,43 @@ module std.variant; import std.meta, std.traits, std.typecons; +/// +@system unittest +{ + Variant a; // Must assign before use, otherwise exception ensues + // Initialize with an integer; make the type int + Variant b = 42; + assert(b.type == typeid(int)); + // Peek at the value + assert(b.peek!(int) !is null && *b.peek!(int) == 42); + // Automatically convert per language rules + auto x = b.get!(real); + + // Assign any other type, including other variants + a = b; + a = 3.14; + assert(a.type == typeid(double)); + // Implicit conversions work just as with built-in types + assert(a < b); + // Check for convertibility + assert(!a.convertsTo!(int)); // double not convertible to int + // Strings and all other arrays are supported + a = "now I'm a string"; + assert(a == "now I'm a string"); + + // can also assign arrays + a = new int[42]; + assert(a.length == 42); + a[5] = 7; + assert(a[5] == 7); + + // Can also assign class values + class Foo {} + auto foo = new Foo; + a = foo; + assert(*a.peek!(Foo) == foo); // and full type information is preserved +} + /++ Gives the $(D sizeof) the largest type given. +/ From 9b5c34053fefe802cfea805ac15c7bb2cf125542 Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Fri, 9 Jun 2017 14:59:35 +0200 Subject: [PATCH 059/163] Immediately send CodeCov notifications --- .codecov.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.codecov.yml b/.codecov.yml index d084b0217db..569f0257521 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -1,6 +1,10 @@ # Documentation: https://github.com/codecov/support/wiki/codecov.yml codecov: + ci: + - "circleci.com" + notify: + after_n_builds: 1 # send notifications after the first upload bot: dlang-bot coverage: From 018094a70b4a2c03b1d812b95c536d17088ba15f Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Mon, 3 Jul 2017 00:23:15 +0200 Subject: [PATCH 060/163] Upgrade to latest tools --- circleci.sh | 9 ++++----- posix.mak | 14 ++++++++------ 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/circleci.sh b/circleci.sh index b1f47249f19..7ef04a56e7d 100755 --- a/circleci.sh +++ b/circleci.sh @@ -86,6 +86,10 @@ setup_repos() fi done + # checkout a specific version of https://github.com/dlang/tools + clone https://github.com/dlang/tools.git ../tools master + git -C ../tools checkout 87c63705dcacac38ba7c84d19699f656d834139d + # load environment for bootstrap compiler source "$(CURL_USER_AGENT=\"$CURL_USER_AGENT\" bash ~/dlang/install.sh dmd-$HOST_DMD_VER --activate)" @@ -100,11 +104,6 @@ style_lint() # dscanner needs a more up-to-date DMD version source "$(CURL_USER_AGENT=\"$CURL_USER_AGENT\" bash ~/dlang/install.sh dmd-$DSCANNER_DMD_VER --activate)" - # some style tools are at the tools repo - clone https://github.com/dlang/tools.git ../tools master - # fix to a specific version of https://github.com/dlang/tools/tree/master/styles - git -C ../tools checkout 60583c8363ff25d00017dffdb18c7ee7e7d9a343 - make -f posix.mak style_lint DUB=$DUB } diff --git a/posix.mak b/posix.mak index 66d963f2325..6e803cf50d7 100644 --- a/posix.mak +++ b/posix.mak @@ -266,7 +266,7 @@ IGNORED_PUBLICTESTS= $(addprefix std/, \ ) digest/hmac \ file math stdio traits typecons uuid) PUBLICTESTS= $(addsuffix .publictests,$(filter-out $(IGNORED_PUBLICTESTS), $(D_MODULES))) -TEST_EXTRACTOR=$(TOOLS_DIR)/styles/test_extractor +TESTS_EXTRACTOR=$(ROOT)/tests_extractor PUBLICTESTS_DIR=$(ROOT)/publictests ################################################################################ @@ -506,8 +506,9 @@ changelog.html: changelog.dd ${TOOLS_DIR}: git clone --depth=1 ${GIT_HOME}/$(@F) $@ + $(TOOLS_DIR)/checkwhitespace.d: | $(TOOLS_DIR) -$(TOOLS_DIR)/styles/tests_extractor.d: | $(TOOLS_DIR) +$(TOOLS_DIR)/tests_extractor.d: | $(TOOLS_DIR) #################### test for undesired white spaces ########################## CWS_TOCHECK = posix.mak win32.mak win64.mak osmodel.mak @@ -589,16 +590,17 @@ style_lint: dscanner $(LIB) ################################################################################ publictests: $(PUBLICTESTS) -$(TEST_EXTRACTOR): $(TOOLS_DIR)/styles/tests_extractor.d $(LIB) - DFLAGS="$(DFLAGS) $(LIB) -defaultlib= -debuglib= $(LINKDL)" $(DUB) build --force --compiler=$${PWD}/$(DMD) --root=$(TOOLS_DIR)/styles -c tests_extractor +$(TESTS_EXTRACTOR): $(TOOLS_DIR)/tests_extractor.d $(LIB) + DFLAGS="$(DFLAGS) $(LIB) -defaultlib= -debuglib= $(LINKDL)" $(DUB) build --force --compiler=$${PWD}/$(DMD) --single $< + mv $(TOOLS_DIR)/tests_extractor $@ ################################################################################ # Extract public tests of a module and test them in an separate file (i.e. without its module) # This is done to check for potentially missing imports in the examples, e.g. # make -f posix.mak std/format.publictests ################################################################################ -%.publictests: %.d $(LIB) $(TEST_EXTRACTOR) | $(PUBLICTESTS_DIR)/.directory - @$(TEST_EXTRACTOR) --inputdir $< --outputdir $(PUBLICTESTS_DIR) +%.publictests: %.d $(LIB) $(TESTS_EXTRACTOR) | $(PUBLICTESTS_DIR)/.directory + @$(TESTS_EXTRACTOR) --inputdir $< --outputdir $(PUBLICTESTS_DIR) @$(DMD) $(DFLAGS) -defaultlib= -debuglib= $(LIB) -main -unittest -run $(PUBLICTESTS_DIR)/$(subst /,_,$<) .PHONY : auto-tester-build From ca67e2fbdcc4d1510fb604cff7e1352af7e03376 Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Mon, 3 Jul 2017 21:06:39 +0200 Subject: [PATCH 061/163] Remove osmodel.mak in favor of ../dmd/osmodel.mak --- osmodel.mak | 65 ----------------------------------------------------- posix.mak | 11 ++++----- 2 files changed, 6 insertions(+), 70 deletions(-) delete mode 100644 osmodel.mak diff --git a/osmodel.mak b/osmodel.mak deleted file mode 100644 index dd94b4098bc..00000000000 --- a/osmodel.mak +++ /dev/null @@ -1,65 +0,0 @@ -# osmodel.mak -# -# Detects and sets the macros: -# -# OS = one of {osx,linux,freebsd,openbsd,netbsd,solaris} -# MODEL = one of { 32, 64 } -# MODEL_FLAG = one of { -m32, -m64 } -# -# Note: -# Keep this file in sync between druntime, phobos, and dmd repositories! -# Source: https://github.com/dlang/phobos/blob/master/osmodel.mak - - -ifeq (,$(OS)) - uname_S:=$(shell uname -s) - ifeq (Darwin,$(uname_S)) - OS:=osx - endif - ifeq (Linux,$(uname_S)) - OS:=linux - endif - ifeq (FreeBSD,$(uname_S)) - OS:=freebsd - endif - ifeq (OpenBSD,$(uname_S)) - OS:=openbsd - endif - ifeq (NetBSD,$(uname_S)) - OS:=netbsd - endif - ifeq (Solaris,$(uname_S)) - OS:=solaris - endif - ifeq (SunOS,$(uname_S)) - OS:=solaris - endif - ifeq (,$(OS)) - $(error Unrecognized or unsupported OS for uname: $(uname_S)) - endif -endif - -# When running make from XCode it may set environment var OS=MACOS. -# Adjust it here: -ifeq (MACOS,$(OS)) - OS:=osx -endif - -ifeq (,$(MODEL)) - ifeq ($(OS), solaris) - uname_M:=$(shell isainfo -n) - else - uname_M:=$(shell uname -m) - endif - ifneq (,$(findstring $(uname_M),x86_64 amd64)) - MODEL:=64 - endif - ifneq (,$(findstring $(uname_M),i386 i586 i686)) - MODEL:=32 - endif - ifeq (,$(MODEL)) - $(error Cannot figure 32/64 model from uname -m: $(uname_M)) - endif -endif - -MODEL_FLAG:=-m$(MODEL) diff --git a/posix.mak b/posix.mak index 6e803cf50d7..63e76199c7c 100644 --- a/posix.mak +++ b/posix.mak @@ -31,8 +31,10 @@ QUIET:= DEBUGGER=gdb +GIT_HOME=https://github.com/dlang +DMD_DIR=../dmd -include osmodel.mak +include $(DMD_DIR)/src/osmodel.mak ifeq (osx,$(OS)) export MACOSX_DEPLOYMENT_TARGET=10.7 @@ -61,7 +63,6 @@ ZIPFILE = phobos.zip ROOT_OF_THEM_ALL = generated ROOT = $(ROOT_OF_THEM_ALL)/$(OS)/$(BUILD)/$(MODEL) DUB=dub -GIT_HOME=https://github.com/dlang TOOLS_DIR=../tools DSCANNER_HASH=071cd08a6de9bbe1720c763b0aff4d19864b27f1 DSCANNER_DIR=../dscanner-$(DSCANNER_HASH) @@ -96,7 +97,7 @@ ifeq ($(OS),win32wine) DMD = wine dmd.exe RUN = wine else - DMD = ../dmd/generated/$(OS)/release/$(MODEL)/dmd + DMD = $(DMD_DIR)/generated/$(OS)/release/$(MODEL)/dmd ifeq ($(OS),win32) CC = dmc else @@ -142,7 +143,7 @@ LINKDL:=$(if $(findstring $(OS),linux),-L-ldl,) TIMELIMIT:=$(if $(shell which timelimit 2>/dev/null || true),timelimit -t 90 ,) # Set VERSION, where the file is that contains the version string -VERSION=../dmd/VERSION +VERSION=$(DMD_DIR)/VERSION # Set LIB, the ultimate target ifeq (,$(findstring win,$(OS))) @@ -511,7 +512,7 @@ $(TOOLS_DIR)/checkwhitespace.d: | $(TOOLS_DIR) $(TOOLS_DIR)/tests_extractor.d: | $(TOOLS_DIR) #################### test for undesired white spaces ########################## -CWS_TOCHECK = posix.mak win32.mak win64.mak osmodel.mak +CWS_TOCHECK = posix.mak win32.mak win64.mak CWS_TOCHECK += $(ALL_D_FILES) index.d checkwhitespace: $(LIB) $(TOOLS_DIR)/checkwhitespace.d From 339308b8299b54ffe7450dcf476124921b4c8508 Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Mon, 3 Jul 2017 23:36:15 +0200 Subject: [PATCH 062/163] Add // nocoverage to non-deterministically covered lines --- std/parallelism.d | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/std/parallelism.d b/std/parallelism.d index 51d322172d0..369e5110c30 100644 --- a/std/parallelism.d +++ b/std/parallelism.d @@ -3445,7 +3445,7 @@ private void submitAndExecute( } catch (Throwable e) { - tasks[0].exception = e; + tasks[0].exception = e; // nocoverage } tasks[0].taskStatus = TaskStatus.done; @@ -3787,9 +3787,9 @@ private void addToChain( { if (firstException) { - assert(lastException); - lastException.next = e; - lastException = findLastException(e); + assert(lastException); // nocoverage + lastException.next = e; // nocoverage + lastException = findLastException(e); // nocoverage } else { From c266aa9087829d34d00a0140be524c73e04c906c Mon Sep 17 00:00:00 2001 From: Vladimir Panteleev Date: Mon, 3 Jul 2017 23:06:18 +0000 Subject: [PATCH 063/163] index.d: Use MREF to fix broken DDox links Partial fix for issue 14085. --- index.d | 304 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 152 insertions(+), 152 deletions(-) diff --git a/index.d b/index.d index 52fed13c351..36a69662559 100644 --- a/index.d +++ b/index.d @@ -21,12 +21,12 @@ $(BOOKTABLE , $(LEADINGROW Algorithms & ranges) $(TR $(TDNW - $(LINK2 std_algorithm.html, std.algorithm)$(BR) - $(LINK2 std_range.html, std.range)$(BR) - $(LINK2 std_range_primitives.html, std.range.primitives)$(BR) - $(LINK2 std_range_interfaces.html, std.range.interfaces)$(BR) + $(MREF std,algorithm)$(BR) + $(MREF std,range)$(BR) + $(MREF std,range,primitives)$(BR) + $(MREF std,range,interfaces)$(BR) ) - $(TD Generic algorithms that work with $(LINK2 std_range.html, ranges) + $(TD Generic algorithms that work with $(MREF_ALTTEXT ranges, std,range) of any type, including strings, arrays, and other kinds of sequentially-accessed data. Algorithms include searching, comparison, iteration, sorting, set operations, and mutation. @@ -35,8 +35,8 @@ $(BOOKTABLE , $(LEADINGROW Array manipulation) $(TR $(TDNW - $(LINK2 std_array.html, std.array)$(BR) - $(LINK2 std_algorithm.html, std.algorithm)$(BR) + $(MREF std,array)$(BR) + $(MREF std,algorithm)$(BR) ) $(TD Convenient operations commonly used with built-in arrays. Note that many common array operations are subsets of more generic @@ -47,155 +47,155 @@ $(BOOKTABLE , $(LEADINGROW Containers) $(TR $(TDNW - $(LINK2 std_container_array.html, std.container.array)$(BR) - $(LINK2 std_container_binaryheap.html, std.container.binaryheap)$(BR) - $(LINK2 std_container_dlist.html, std.container.dlist)$(BR) - $(LINK2 std_container_rbtree.html, std.container.rbtree)$(BR) - $(LINK2 std_container_slist.html, std.container.slist)$(BR) + $(MREF std,container,array)$(BR) + $(MREF std,container,binaryheap)$(BR) + $(MREF std,container,dlist)$(BR) + $(MREF std,container,rbtree)$(BR) + $(MREF std,container,slist)$(BR) ) - $(TD See $(LINK2 std_container.html, std.container.*) for an + $(TD See $(MREF_ALTTEXT std.container.*, std,container) for an overview. ) ) $(LEADINGROW Data formats) $(TR - $(TDNW $(LINK2 std_base64.html, std.base64)) + $(TDNW $(MREF std,base64)) $(TD Encoding / decoding Base64 format.) ) $(TR - $(TDNW $(LINK2 std_csv.html, std.csv)) + $(TDNW $(MREF std,csv)) $(TD Read Comma Separated Values and its variants from an input range of $(CODE dchar).) ) $(TR - $(TDNW $(LINK2 std_json.html, std.json)) + $(TDNW $(MREF std,json)) $(TD Read/write data in JSON format.) ) $(TR - $(TDNW $(LINK2 std_xml.html, std.xml)) + $(TDNW $(MREF std,xml)) $(TD Read/write data in XML format.) ) $(TR - $(TDNW $(LINK2 std_zip.html, std.zip)) + $(TDNW $(MREF std,zip)) $(TD Read/write data in the ZIP archive format.) ) $(TR - $(TDNW $(LINK2 std_zlib.html, std.zlib)) + $(TDNW $(MREF std,zlib)) $(TD Compress/decompress data using the zlib library.) ) $(LEADINGROW Data integrity) $(TR - $(TDNW $(LINK2 std_experimental_checkedint.html, std.experimental.checkedint)) + $(TDNW $(MREF std,experimental,checkedint)) $(TD Checked integral types.) ) $(TR - $(TDNW $(LINK2 std_digest_crc.html, std.digest.crc)) + $(TDNW $(MREF std,digest,crc)) $(TD Cyclic Redundancy Check (32-bit) implementation.) ) $(TR - $(TDNW $(LINK2 std_digest_digest.html, std.digest.digest)) + $(TDNW $(MREF std,digest,digest)) $(TD Compute digests such as md5, sha1 and crc32.) ) $(TR - $(TDNW $(LINK2 std_digest_hmac.html, std.digest.hmac)) + $(TDNW $(MREF std,digest,hmac)) $(TD Compute HMAC digests of arbitrary data.) ) $(TR - $(TDNW $(LINK2 std_digest_md.html, std.digest.md)) + $(TDNW $(MREF std,digest,md)) $(TD Compute MD5 hash of arbitrary data.) ) $(TR - $(TDNW $(LINK2 std_digest_murmurhash.html, std.digest.murmurhash)) + $(TDNW $(MREF std,digest,murmurhash)) $(TD Compute MurmurHash of arbitrary data.) ) $(TR - $(TDNW $(LINK2 std_digest_ripemd.html, std.digest.ripemd)) + $(TDNW $(MREF std,digest,ripemd)) $(TD Compute RIPEMD-160 hash of arbitrary data.) ) $(TR - $(TDNW $(LINK2 std_digest_sha.html, std.digest.sha)) + $(TDNW $(MREF std,digest,sha)) $(TD Compute SHA1 and SHA2 hashes of arbitrary data.) ) $(LEADINGROW Date & time) $(TR - $(TDNW $(LINK2 std_datetime.html, std.datetime)) + $(TDNW $(MREF std,datetime)) $(TD Provides convenient access to date and time representations.) ) $(TR - $(TDNW $(LINK2 core_time.html, core.time)) + $(TDNW $(MREF core,time)) $(TD Implements low-level time primitives.) ) $(LEADINGROW Exception handling) $(TR - $(TDNW $(LINK2 std_exception.html, std.exception)) + $(TDNW $(MREF std,exception)) $(TD Implements routines related to exceptions.) ) $(TR - $(TDNW $(LINK2 core_exception.html, core.exception)) + $(TDNW $(MREF core,exception)) $(TD Defines built-in exception types and low-level language hooks required by the compiler.) ) $(LEADINGROW External library bindings) $(TR - $(TDNW $(LINK2 etc_c_curl.html, etc.c.curl)) + $(TDNW $(MREF etc,c,curl)) $(TD Interface to libcurl C library.) ) $(TR - $(TDNW $(LINK2 etc_c_odbc_sql.html, etc.c.odbc.sql)) + $(TDNW $(MREF etc,c,odbc,sql)) $(TD Interface to ODBC C library.) ) $(TR - $(TDNW $(LINK2 etc_c_odbc_sqlext.html, etc.c.odbc.sqlext)) + $(TDNW $(MREF etc,c,odbc,sqlext)) ) $(TR - $(TDNW $(LINK2 etc_c_odbc_sqltypes.html, etc.c.odbc.sqltypes)) + $(TDNW $(MREF etc,c,odbc,sqltypes)) ) $(TR - $(TDNW $(LINK2 etc_c_odbc_sqlucode.html, etc.c.odbc.sqlucode)) + $(TDNW $(MREF etc,c,odbc,sqlucode)) ) $(TR - $(TDNW $(LINK2 etc_c_sqlite3.html, etc.c.sqlite3)) + $(TDNW $(MREF etc,c,sqlite3)) $(TD Interface to SQLite C library.) ) $(TR - $(TDNW $(LINK2 etc_c_zlib.html, etc.c.zlib)) + $(TDNW $(MREF etc,c,zlib)) $(TD Interface to zlib C library.) ) $(LEADINGROW I/O & File system) $(TR - $(TDNW $(LINK2 std_file.html, std.file)) + $(TDNW $(MREF std,file)) $(TD Manipulate files and directories.) ) $(TR - $(TDNW $(LINK2 std_path.html, std.path)) + $(TDNW $(MREF std,path)) $(TD Manipulate strings that represent filesystem paths.) ) $(TR - $(TDNW $(LINK2 std_stdio.html, std.stdio)) + $(TDNW $(MREF std,stdio)) $(TD Perform buffered I/O.) ) $(LEADINGROW Interoperability) $(TR $(TDNW - $(LINK2 core_stdc_complex.html, core.stdc.complex)$(BR) - $(LINK2 core_stdc_ctype.html, core.stdc.ctype)$(BR) - $(LINK2 core_stdc_errno.html, core.stdc.errno)$(BR) - $(LINK2 core_stdc_fenv.html, core.stdc.fenv)$(BR) - $(LINK2 core_stdc_float_.html, core.stdc.float_)$(BR) - $(LINK2 core_stdc_inttypes.html, core.stdc.inttypes)$(BR) - $(LINK2 core_stdc_limits.html, core.stdc.limits)$(BR) - $(LINK2 core_stdc_locale.html, core.stdc.locale)$(BR) - $(LINK2 core_stdc_math.html, core.stdc.math)$(BR) - $(LINK2 core_stdc_signal.html, core.stdc.signal)$(BR) - $(LINK2 core_stdc_stdarg.html, core.stdc.stdarg)$(BR) - $(LINK2 core_stdc_stddef.html, core.stdc.stddef)$(BR) - $(LINK2 core_stdc_stdint.html, core.stdc.stdint)$(BR) - $(LINK2 core_stdc_stdio.html, core.stdc.stdio)$(BR) - $(LINK2 core_stdc_stdlib.html, core.stdc.stdlib)$(BR) - $(LINK2 core_stdc_string.html, core.stdc.string)$(BR) - $(LINK2 core_stdc_tgmath.html, core.stdc.tgmath)$(BR) - $(LINK2 core_stdc_time.html, core.stdc.time)$(BR) - $(LINK2 core_stdc_wchar_.html, core.stdc.wchar_)$(BR) - $(LINK2 core_stdc_wctype.html, core.stdc.wctype)$(BR) + $(MREF core,stdc,complex)$(BR) + $(MREF core,stdc,ctype)$(BR) + $(MREF core,stdc,errno)$(BR) + $(MREF core,stdc,fenv)$(BR) + $(MREF core,stdc,float_)$(BR) + $(MREF core,stdc,inttypes)$(BR) + $(MREF core,stdc,limits)$(BR) + $(MREF core,stdc,locale)$(BR) + $(MREF core,stdc,math)$(BR) + $(MREF core,stdc,signal)$(BR) + $(MREF core,stdc,stdarg)$(BR) + $(MREF core,stdc,stddef)$(BR) + $(MREF core,stdc,stdint)$(BR) + $(MREF core,stdc,stdio)$(BR) + $(MREF core,stdc,stdlib)$(BR) + $(MREF core,stdc,string)$(BR) + $(MREF core,stdc,tgmath)$(BR) + $(MREF core,stdc,time)$(BR) + $(MREF core,stdc,wchar_)$(BR) + $(MREF core,stdc,wctype)$(BR) ) $(TD D bindings for standard C headers.$(BR)$(BR) @@ -206,253 +206,253 @@ $(BOOKTABLE , ) $(LEADINGROW Memory management) $(TR - $(TDNW $(LINK2 core_memory.html, core.memory)) + $(TDNW $(MREF core,memory)) $(TD Control the built-in garbage collector.) ) $(TR - $(TDNW $(LINK2 std_typecons.html, std.typecons)) + $(TDNW $(MREF std,typecons)) $(TD Build scoped variables and reference-counted types.) ) $(LEADINGROW Metaprogramming) $(TR - $(TDNW $(LINK2 core_attribute.html, core.attribute)) + $(TDNW $(MREF core,attribute)) $(TD Definitions of special attributes recognized by the compiler.) ) $(TR - $(TDNW $(LINK2 core_demangle.html, core.demangle)) + $(TDNW $(MREF core,demangle)) $(TD Convert $(I mangled) D symbol identifiers to source representation.) ) $(TR - $(TDNW $(LINK2 std_demangle.html, std.demangle)) + $(TDNW $(MREF std,demangle)) $(TD A simple wrapper around core.demangle.) ) $(TR - $(TDNW $(LINK2 std_meta.html, std.meta)) + $(TDNW $(MREF std,meta)) $(TD Construct and manipulate template argument lists (aka type lists).) ) $(TR - $(TDNW $(LINK2 std_traits.html, std.traits)) + $(TDNW $(MREF std,traits)) $(TD Extract information about types and symbols at compile time.) ) $(TR - $(TDNW $(LINK2 std_typecons.html, std.typecons)) + $(TDNW $(MREF std,typecons)) $(TD Construct new, useful general purpose types.) ) $(LEADINGROW Multitasking) $(TR - $(TDNW $(LINK2 std_concurrency.html, std.concurrency)) + $(TDNW $(MREF std,concurrency)) $(TD Low level messaging API for threads.) ) $(TR - $(TDNW $(LINK2 std_parallelism.html, std.parallelism)) + $(TDNW $(MREF std,parallelism)) $(TD High level primitives for SMP parallelism.) ) $(TR - $(TDNW $(LINK2 std_process.html, std.process)) + $(TDNW $(MREF std,process)) $(TD Starting and manipulating processes.) ) $(TR - $(TDNW $(LINK2 core_atomic.html, core.atomic)) + $(TDNW $(MREF core,atomic)) $(TD Basic support for lock-free concurrent programming.) ) $(TR - $(TDNW $(LINK2 core_sync_barrier.html, core.sync.barrier)) + $(TDNW $(MREF core,sync,barrier)) $(TD Synchronize the progress of a group of threads.) ) $(TR - $(TDNW $(LINK2 core_sync_condition.html, core.sync.condition)) + $(TDNW $(MREF core,sync,condition)) $(TD Synchronized condition checking.) ) $(TR - $(TDNW $(LINK2 core_sync_exception.html, core.sync.exception)) + $(TDNW $(MREF core,sync,exception)) $(TD Base class for synchronization exceptions.) ) $(TR - $(TDNW $(LINK2 core_sync_mutex.html, core.sync.mutex)) + $(TDNW $(MREF core,sync,mutex)) $(TD Mutex for mutually exclusive access.) ) $(TR - $(TDNW $(LINK2 core_sync_rwmutex.html, core.sync.rwmutex)) + $(TDNW $(MREF core,sync,rwmutex)) $(TD Shared read access and mutually exclusive write access.) ) $(TR - $(TDNW $(LINK2 core_sync_semaphore.html, core.sync.semaphore)) + $(TDNW $(MREF core,sync,semaphore)) $(TD General use synchronization semaphore.) ) $(TR - $(TDNW $(LINK2 core_thread.html, core.thread)) + $(TDNW $(MREF core,thread)) $(TD Thread creation and management.) ) $(LEADINGROW Networking) $(TR - $(TDNW $(LINK2 std_socket.html, std.socket)) + $(TDNW $(MREF std,socket)) $(TD Socket primitives.) ) $(TR - $(TDNW $(LINK2 std_net_curl.html, std.net.curl)) + $(TDNW $(MREF std,net,curl)) $(TD Networking client functionality as provided by libcurl.) ) $(TR - $(TDNW $(LINK2 std_net_isemail.html, std.net.isemail)) + $(TDNW $(MREF std,net,isemail)) $(TD Validates an email address according to RFCs 5321, 5322 and others.) ) $(TR - $(TDNW $(LINK2 std_uri.html, std.uri)) + $(TDNW $(MREF std,uri)) $(TD Encode and decode Uniform Resource Identifiers (URIs).) ) $(TR - $(TDNW $(LINK2 std_uuid.html, std.uuid)) + $(TDNW $(MREF std,uuid)) $(TD Universally-unique identifiers for resources in distributed systems.) ) $(LEADINGROW Numeric) $(TR - $(TDNW $(LINK2 std_bigint.html, std.bigint)) + $(TDNW $(MREF std,bigint)) $(TD An arbitrary-precision integer type.) ) $(TR - $(TDNW $(LINK2 std_complex.html, std.complex)) + $(TDNW $(MREF std,complex)) $(TD A complex number type.) ) $(TR - $(TDNW $(LINK2 std_math.html, std.math)) + $(TDNW $(MREF std,math)) $(TD Elementary mathematical functions (powers, roots, trigonometry).) ) $(TR - $(TDNW $(LINK2 std_mathspecial.html, std.mathspecial)) + $(TDNW $(MREF std,mathspecial)) $(TD Families of transcendental functions.) ) $(TR - $(TDNW $(LINK2 std_numeric.html, std.numeric)) + $(TDNW $(MREF std,numeric)) $(TD Floating point numerics functions.) ) $(TR - $(TDNW $(LINK2 std_random.html, std.random)) + $(TDNW $(MREF std,random)) $(TD Pseudo-random number generators.) ) $(TR - $(TDNW $(LINK2 core_checkedint.html, core.checkedint)) + $(TDNW $(MREF core,checkedint)) $(TD Range-checking integral arithmetic primitives.) ) $(TR - $(TDNW $(LINK2 core_math.html, core.math)) + $(TDNW $(MREF core,math)) $(TD Built-in mathematical intrinsics.) ) $(LEADINGROW Paradigms) $(TR - $(TDNW $(LINK2 std_functional.html, std.functional)) + $(TDNW $(MREF std,functional)) $(TD Functions that manipulate other functions.) ) $(TR - $(TDNW $(LINK2 std_algorithm.html, std.algorithm)) + $(TDNW $(MREF std,algorithm)) $(TD Generic algorithms for processing sequences.) ) $(TR - $(TDNW $(LINK2 std_signals.html, std.signals)) + $(TDNW $(MREF std,signals)) $(TD Signal-and-slots framework for event-driven programming.) ) $(LEADINGROW Runtime utilities) $(TR - $(TDNW $(LINK2 object.html, object)) + $(TDNW $(MREF object)) $(TD Core language definitions. Automatically imported.) ) $(TR - $(TDNW $(LINK2 std_getopt.html, std.getopt)) + $(TDNW $(MREF std,getopt)) $(TD Parsing of command-line arguments.) ) $(TR - $(TDNW $(LINK2 std_compiler.html, std.compiler)) + $(TDNW $(MREF std,compiler)) $(TD Host compiler vendor string and language version.) ) $(TR - $(TDNW $(LINK2 std_system.html, std.system)) + $(TDNW $(MREF std,system)) $(TD Runtime environment, such as OS type and endianness.) ) $(TR - $(TDNW $(LINK2 core_cpuid.html, core.cpuid)) + $(TDNW $(MREF core,cpuid)) $(TD Capabilities of the CPU the program is running on.) ) $(TR - $(TDNW $(LINK2 core_memory.html, core.memory)) + $(TDNW $(MREF core,memory)) $(TD Control the built-in garbage collector.) ) $(TR - $(TDNW $(LINK2 core_runtime.html, core.runtime)) + $(TDNW $(MREF core,runtime)) $(TD Control and configure the D runtime.) ) $(LEADINGROW String manipulation) $(TR - $(TDNW $(LINK2 std_string.html, std.string)) + $(TDNW $(MREF std,string)) $(TD Algorithms that work specifically with strings.) ) $(TR - $(TDNW $(LINK2 std_array.html, std.array)) + $(TDNW $(MREF std,array)) $(TD Manipulate builtin arrays.) ) $(TR - $(TDNW $(LINK2 std_algorithm.html, std.algorithm)) + $(TDNW $(MREF std,algorithm)) $(TD Generic algorithms for processing sequences.) ) $(TR - $(TDNW $(LINK2 std_uni.html, std.uni)) + $(TDNW $(MREF std,uni)) $(TD Fundamental Unicode algorithms and data structures.) ) $(TR - $(TDNW $(LINK2 std_utf.html, std.utf)) + $(TDNW $(MREF std,utf)) $(TD Encode and decode UTF-8, UTF-16 and UTF-32 strings.) ) $(TR - $(TDNW $(LINK2 std_format.html, std.format)) + $(TDNW $(MREF std,format)) $(TD Format data into strings.) ) $(TR - $(TDNW $(LINK2 std_path.html, std.path)) + $(TDNW $(MREF std,path)) $(TD Manipulate strings that represent filesystem paths.) ) $(TR - $(TDNW $(LINK2 std_regex.html, std.regex)) + $(TDNW $(MREF std,regex)) $(TD Regular expressions.) ) $(TR - $(TDNW $(LINK2 std_ascii.html, std.ascii)) + $(TDNW $(MREF std,ascii)) $(TD Routines specific to the ASCII subset of Unicode.) ) $(TR - $(TDNW $(LINK2 std_encoding.html, std.encoding)) + $(TDNW $(MREF std,encoding)) $(TD Handle and transcode between various text encodings.) ) $(TR - $(TDNW $(LINK2 std_windows_charset.html, std.windows.charset)) + $(TDNW $(MREF std,windows,charset)) $(TD Windows specific character set support.) ) $(TR - $(TDNW $(LINK2 std_outbuffer.html, std.outbuffer)) + $(TDNW $(MREF std,outbuffer)) $(TD Serialize data to $(CODE ubyte) arrays.) ) $(LEADINGROW Type manipulations) $(TR - $(TDNW $(LINK2 std_conv.html, std.conv)) + $(TDNW $(MREF std,conv)) $(TD Convert types from one type to another.) ) $(TR - $(TDNW $(LINK2 std_typecons.html, std.typecons)) + $(TDNW $(MREF std,typecons)) $(TD Type constructors for scoped variables, ref counted types, etc.) ) $(TR - $(TDNW $(LINK2 std_bitmanip.html, std.bitmanip)) + $(TDNW $(MREF std,bitmanip)) $(TD High level bit level manipulation, bit arrays, bit fields.) ) $(TR - $(TDNW $(LINK2 std_variant.html, std.variant)) + $(TDNW $(MREF std,variant)) $(TD Discriminated unions and algebraic types.) ) $(TR - $(TDNW $(LINK2 core_bitop.html, core.bitop)) + $(TDNW $(MREF core,bitop)) $(TD Low level bit manipulation.) ) $(LEADINGROW Vector programming) $(TR - $(TDNW $(LINK2 core_simd.html, core.simd)) + $(TDNW $(MREF core,simd)) $(TD SIMD intrinsics) ) @@ -460,15 +460,15 @@ $(COMMENT $(LEADINGROW Undocumented modules (intentionally omitted).) $(TR $(TDNW - $(LINK2 core_sync_config.html, core.sync.config)$(BR) - $(LINK2 std_container_util.html, std.container.util)$(BR) - $(LINK2 std_regex_internal_backtracking.html, std.regex.internal.backtracking)$(BR) - $(LINK2 std_regex_internal_generator.html, std.regex.internal.generator)$(BR) - $(LINK2 std_regex_internal_ir.html, std.regex.internal.ir)$(BR) - $(LINK2 std_regex_internal_kickstart.html, std.regex.internal.kickstart)$(BR) - $(LINK2 std_regex_internal_parser.html, std.regex.internal.parser)$(BR) - $(LINK2 std_regex_internal_tests.html, std.regex.internal.tests)$(BR) - $(LINK2 std_regex_internal_thompson.html, std.regex.internal.thompson)$(BR) + $(MREF core,sync,config)$(BR) + $(MREF std,container,util)$(BR) + $(MREF std,regex,internal,backtracking)$(BR) + $(MREF std,regex,internal,generator)$(BR) + $(MREF std,regex,internal,ir)$(BR) + $(MREF std,regex,internal,kickstart)$(BR) + $(MREF std,regex,internal,parser)$(BR) + $(MREF std,regex,internal,tests)$(BR) + $(MREF std,regex,internal,thompson)$(BR) ) $(TD Internal modules. @@ -476,21 +476,21 @@ $(COMMENT ) $(TR $(TDNW - $(LINK2 core_vararg.html, core.vararg)$(BR) - $(LINK2 std_c_fenv.html, std.c.fenv)$(BR) - $(LINK2 std_c_linux_linux.html, std.c.linux_linux)$(BR) - $(LINK2 std_c_linux_socket.html, std.c.linux_socket)$(BR) - $(LINK2 std_c_locale.html, std.c.locale)$(BR) - $(LINK2 std_c_math.html, std.c.math)$(BR) - $(LINK2 std_c_process.html, std.c.process)$(BR) - $(LINK2 std_c_stdarg.html, std.c.stdarg)$(BR) - $(LINK2 std_c_stddef.html, std.c.stddef)$(BR) - $(LINK2 std_c_stdio.html, std.c.stdio)$(BR) - $(LINK2 std_c_stdlib.html, std.c.stdlib)$(BR) - $(LINK2 std_c_string.html, std.c.string)$(BR) - $(LINK2 std_c_time.html, std.c.time)$(BR) - $(LINK2 std_c_wcharh.html, std.c.wcharh)$(BR) - $(LINK2 std_stdint.html, std.stdint)$(BR) + $(MREF core,vararg)$(BR) + $(MREF std,c,fenv)$(BR) + $(MREF std,c,linux,linux)$(BR) + $(MREF std,c,linux,socket)$(BR) + $(MREF std,c,locale)$(BR) + $(MREF std,c,math)$(BR) + $(MREF std,c,process)$(BR) + $(MREF std,c,stdarg)$(BR) + $(MREF std,c,stddef)$(BR) + $(MREF std,c,stdio)$(BR) + $(MREF std,c,stdlib)$(BR) + $(MREF std,c,string)$(BR) + $(MREF std,c,time)$(BR) + $(MREF std,c,wcharh)$(BR) + $(MREF std,stdint)$(BR) ) $(TDN Redirect modules. @@ -498,8 +498,8 @@ $(COMMENT ) $(TR $(TDNW - $(LINK2 std_mmfile.html, std.mmfile)$(BR) - $(LINK2 std_typetuple.html, std.typetuple)$(BR) + $(MREF std,mmfile)$(BR) + $(MREF std,typetuple)$(BR) ) $(TD Deprecated modules. @@ -507,11 +507,11 @@ $(COMMENT ) $(TR $(TDNW - $(LINK2 std_experimental_logger.html, std.experimental.logger)$(BR) - $(LINK2 std_experimental_logger_core.html, std.experimental.logger.core)$(BR) - $(LINK2 std_experimental_logger_filelogger.html, std.experimental.logger.filelogger)$(BR) - $(LINK2 std_experimental_logger_multilogger.html, std.experimental.logger.multilogger)$(BR) - $(LINK2 std_experimental_logger_nulllogger.html, std.experimental.logger.nulllogger)$(BR) + $(MREF std,experimental,logger)$(BR) + $(MREF std,experimental,logger,core)$(BR) + $(MREF std,experimental,logger,filelogger)$(BR) + $(MREF std,experimental,logger,multilogger)$(BR) + $(MREF std,experimental,logger,nulllogger)$(BR) ) $(TD Experimental modules. From 73244e12bf794808144bdbaa90a4a1cb30775a32 Mon Sep 17 00:00:00 2001 From: Rainer Schuetze Date: Sun, 4 Jun 2017 16:06:09 +0200 Subject: [PATCH 064/163] mangledName: update documentation and add runnable example using staticMap --- std/traits.d | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/std/traits.d b/std/traits.d index bd8a8dfc347..f15435e35b9 100644 --- a/std/traits.d +++ b/std/traits.d @@ -7264,24 +7264,21 @@ unittest /** Returns the mangled name of symbol or type $(D sth). -$(D mangledName) is the same as builtin $(D .mangleof) property, kept -for compatibility as property functions used to behave differently. --------------------- -module test; -import std.traits : mangledName; - -class C -{ - int value() @property; -} -pragma(msg, C.value.mangleof); // prints "_D4test1C5valueMFNdZi", was "i" -pragma(msg, mangledName!(C.value)); // prints "_D4test1C5valueMFNdZi" --------------------- +$(D mangledName) is the same as builtin $(D .mangleof) property, but +might be more convenient in generic code, e.g. as a template argument +when invoking staticMap. */ template mangledName(sth...) if (sth.length == 1) { - enum string mangledName = sth[0].mangleof; + enum string mangledName = sth[0].mangleof; +} + +/// +@safe unittest +{ + alias TL = staticMap!(mangledName, int, const int, immutable int); + static assert(TL == AliasSeq!("i", "xi", "yi")); } version(unittest) void freeFunc(string); From b37db353899a6fef6828e7e1b312e21e42921a47 Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Wed, 5 Jul 2017 01:51:19 +0200 Subject: [PATCH 065/163] Fix CircleCI - unittests need to be annotated --- std/datetime/date.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/std/datetime/date.d b/std/datetime/date.d index 08643aa965d..396cae9cfc3 100644 --- a/std/datetime/date.d +++ b/std/datetime/date.d @@ -7264,7 +7264,7 @@ public: } /// - unittest + @safe unittest { assert(Date(2010, 7, 4).toString() == "2010-Jul-04"); } From 1d1b42f413c7b929dcd5c3081dd181638a912fd6 Mon Sep 17 00:00:00 2001 From: RazvanN7 Date: Wed, 5 Jul 2017 11:35:06 +0300 Subject: [PATCH 066/163] Fix Issue 17525 - std.algorithm.skipOver should have a single argument with pred version --- std/algorithm/searching.d | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/std/algorithm/searching.d b/std/algorithm/searching.d index 72a6f341d39..bab2600f7fa 100644 --- a/std/algorithm/searching.d +++ b/std/algorithm/searching.d @@ -3894,7 +3894,8 @@ if (isInputRange!Range && !isInfinite!Range && /** Skip over the initial portion of the first given range that matches the second -range, or do nothing if there is no match. +range, or if no second range is given skip over the elements that fullfil pred. +Do nothing if there is no match. Params: pred = The predicate that determines whether elements from each respective @@ -3905,9 +3906,9 @@ Params: representing the initial segment of $(D r1) to skip over. Returns: -true if the initial segment of $(D r1) matches $(D r2), and $(D r1) has been -advanced to the point past this segment; otherwise false, and $(D r1) is left -in its original position. +true if the initial segment of $(D r1) matches $(D r2) or $(D pred) evaluates to true, +and $(D r1) has been advanced to the point past this segment; otherwise false, and +$(D r1) is left in its original position. */ bool skipOver(R1, R2)(ref R1 r1, R2 r2) if (isForwardRange!R1 && isInputRange!R2 @@ -3953,6 +3954,20 @@ if (is(typeof(binaryFun!pred(r1.front, r2.front))) && return r2.empty; } +/// Ditto +bool skipOver(alias pred, R)(ref R r1) +if (isForwardRange!R && + ifTestable!(typeof(r1.front), unaryFun!pred)) +{ + if (r1.empty || !unaryFun!pred(r1.front)) + return false; + + do + r1.popFront(); + while (!r1.empty && unaryFun!pred(r1.front)); + return true; +} + /// @safe unittest { @@ -3969,6 +3984,16 @@ if (is(typeof(binaryFun!pred(r1.front, r2.front))) && assert(r1 == ["abc", "def", "hij"]); assert(skipOver!((a, b) => a.equal(b))(r1, r2)); assert(r1 == ["def", "hij"]); + + import std.ascii : isWhite; + import std.range.primitives : empty; + + auto s2 = "\t\tvalue"; + auto s3 = ""; + auto s4 = "\t\t\t"; + assert(s2.skipOver!isWhite && s2 == "value"); + assert(!s3.skipOver!isWhite); + assert(s4.skipOver!isWhite && s3.empty); } /** From 74a8f6bb477563d1158a4c2528c6822784d1fecf Mon Sep 17 00:00:00 2001 From: RazvanN7 Date: Wed, 5 Jul 2017 17:09:51 +0300 Subject: [PATCH 067/163] Fix Issue 17365 - checkedint.html is missing the Throw hook description --- std/experimental/checkedint.d | 3 +++ 1 file changed, 3 insertions(+) diff --git a/std/experimental/checkedint.d b/std/experimental/checkedint.d index 96dc4f282cf..2fe5301eca5 100644 --- a/std/experimental/checkedint.d +++ b/std/experimental/checkedint.d @@ -50,6 +50,9 @@ $(BOOKTABLE , second parameter, i.e. `Checked!short` is the same as $(D Checked!(short, Abort)). )) + $(TR $(TD $(LREF Throw)) $(TD + fails every incorrect operation by throwing an exception. + )) $(TR $(TD $(LREF Warn)) $(TD prints incorrect operations to $(REF stderr, std, stdio) but otherwise preserves the built-in behavior. From 19f2a965b26ef77519af123ed8c04187eac535c8 Mon Sep 17 00:00:00 2001 From: Jack Stouffer Date: Tue, 23 May 2017 11:02:49 -0400 Subject: [PATCH 068/163] Remove some extra string allocations in std.datetime.date.datetime --- std/datetime/date.d | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/std/datetime/date.d b/std/datetime/date.d index 8fde94edad6..dea813f639f 100644 --- a/std/datetime/date.d +++ b/std/datetime/date.d @@ -2869,9 +2869,18 @@ public: { import std.format : format; try - return format("%sT%s", _date.toISOString(), _tod.toISOString()); + { + return format!("%sT%02d%02d%02d")( + _date.toISOString(), + _tod._hour, + _tod._minute, + _tod._second + ); + } catch (Exception e) + { assert(0, "format() threw."); + } } /// @@ -2922,9 +2931,18 @@ public: { import std.format : format; try - return format("%sT%s", _date.toISOExtString(), _tod.toISOExtString()); + { + return format!("%sT%02d:%02d:%02d")( + _date.toISOExtString(), + _tod._hour, + _tod._minute, + _tod._second + ); + } catch (Exception e) + { assert(0, "format() threw."); + } } /// @@ -2974,9 +2992,18 @@ public: { import std.format : format; try - return format("%s %s", _date.toSimpleString(), _tod.toString()); + { + return format!("%s %02d:%02d:%02d")( + _date.toSimpleString(), + _tod._hour, + _tod._minute, + _tod._second + ); + } catch (Exception e) + { assert(0, "format() threw."); + } } /// From 16431f11c1d989bf6719725cb5cb228fa1965790 Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Wed, 5 Jul 2017 18:17:55 +0200 Subject: [PATCH 069/163] Trigger a hard error on deprecation messages --- posix.mak | 2 +- win32.mak | 2 +- win64.mak | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/posix.mak b/posix.mak index 63e76199c7c..fee516c259d 100644 --- a/posix.mak +++ b/posix.mak @@ -115,7 +115,7 @@ else endif # Set DFLAGS -DFLAGS=-conf= -I$(DRUNTIME_PATH)/import $(DMDEXTRAFLAGS) -w -dip25 $(MODEL_FLAG) $(PIC) +DFLAGS=-conf= -I$(DRUNTIME_PATH)/import $(DMDEXTRAFLAGS) -w -de -dip25 $(MODEL_FLAG) $(PIC) ifeq ($(BUILD),debug) DFLAGS += -g -debug else diff --git a/win32.mak b/win32.mak index 22a6de97fa8..e83ef7965ea 100644 --- a/win32.mak +++ b/win32.mak @@ -43,7 +43,7 @@ DRUNTIMELIB=$(DRUNTIME)\lib\druntime.lib ## Flags for dmd D compiler -DFLAGS=-conf= -O -release -w -dip25 -I$(DRUNTIME)\import +DFLAGS=-conf= -O -release -w -de -dip25 -I$(DRUNTIME)\import #DFLAGS=-unittest -g #DFLAGS=-unittest -cov -g diff --git a/win64.mak b/win64.mak index b0c49217a7a..c97fd1e4e02 100644 --- a/win64.mak +++ b/win64.mak @@ -46,7 +46,7 @@ DRUNTIMELIB=$(DRUNTIME)\lib\druntime$(MODEL).lib ## Flags for dmd D compiler -DFLAGS=-conf= -m$(MODEL) -O -release -w -dip25 -I$(DRUNTIME)\import +DFLAGS=-conf= -m$(MODEL) -O -release -w -de -dip25 -I$(DRUNTIME)\import #DFLAGS=-m$(MODEL) -unittest -g #DFLAGS=-m$(MODEL) -unittest -cov -g From 16b9188b4a19f7f889032ef200de97c7bbc7162b Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Wed, 5 Jul 2017 18:18:18 +0200 Subject: [PATCH 070/163] Fix deprecations --- std/algorithm/searching.d | 2 +- std/string.d | 7 +++++++ std/uni.d | 6 +++--- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/std/algorithm/searching.d b/std/algorithm/searching.d index 72a6f341d39..7fc765f000f 100644 --- a/std/algorithm/searching.d +++ b/std/algorithm/searching.d @@ -637,7 +637,7 @@ if (isInputRange!Range && !isInfinite!Range && assert(count("ababab", "abab") == 1); assert(count("ababab", "abx") == 0); // fuzzy count range in range - assert(count!((a, b) => std.uni.toLower(a) == std.uni.toLower(b))("AbcAdFaBf", "ab") == 2); + assert(count!((a, b) => toLower(a) == toLower(b))("AbcAdFaBf", "ab") == 2); // count predicate in range assert(count!("a > 1")(a) == 8); } diff --git a/std/string.d b/std/string.d index f4dff356e06..b24f1ee3554 100644 --- a/std/string.d +++ b/std/string.d @@ -5288,6 +5288,7 @@ if (isSomeString!S) } +deprecated @safe pure @nogc unittest { import std.conv : to; @@ -5363,6 +5364,7 @@ if (isSomeString!S && isSomeString!S1) return count; } +deprecated @safe pure @nogc unittest { import std.conv : to; @@ -5417,6 +5419,7 @@ if (isSomeString!S) return s; } +deprecated @safe pure unittest { import std.conv : to; @@ -5433,6 +5436,7 @@ if (isSomeString!S) }); } +deprecated @safe pure unittest { assert(removechars("abc", "x") == "abc"); @@ -5493,6 +5497,7 @@ S squeeze(S)(S s, in S pattern = null) return changed ? ((r is null) ? s[0 .. lasti] : cast(S) r) : s; } +deprecated @system pure unittest { import std.conv : to; @@ -5549,6 +5554,7 @@ S1 munch(S1, S2)(ref S1 s, S2 pattern) @safe pure @nogc } /// +deprecated @safe pure @nogc unittest { string s = "123abc"; @@ -5558,6 +5564,7 @@ S1 munch(S1, S2)(ref S1 s, S2 pattern) @safe pure @nogc assert(t == "" && s == "abc"); } +deprecated @safe pure @nogc unittest { string s = "123€abc"; diff --git a/std/uni.d b/std/uni.d index 40c4799c1d7..b301cd17579 100644 --- a/std/uni.d +++ b/std/uni.d @@ -4762,9 +4762,9 @@ template Utf8Matcher() static auto encode(size_t sz)(dchar ch) if (sz > 1) { - import std.utf : encode; + import std.utf : encodeUTF = encode; char[4] buf; - std.utf.encode(buf, ch); + encodeUTF(buf, ch); char[sz] ret; buf[0] &= leadMask!sz; foreach (n; 1 .. sz) @@ -7380,7 +7380,7 @@ package auto simpleCaseFoldings(dchar ch) @safe return len == 0; } - @property uint length() const + @property size_t length() const { if (isSmall) { From 4b3172762823b7969bf517ac9ad24f8c3c977b1c Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Wed, 5 Jul 2017 19:02:33 +0200 Subject: [PATCH 071/163] Update tools to get a deprecation-free DScanner --- circleci.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/circleci.sh b/circleci.sh index 7ef04a56e7d..443f74b545c 100755 --- a/circleci.sh +++ b/circleci.sh @@ -88,7 +88,7 @@ setup_repos() # checkout a specific version of https://github.com/dlang/tools clone https://github.com/dlang/tools.git ../tools master - git -C ../tools checkout 87c63705dcacac38ba7c84d19699f656d834139d + git -C ../tools checkout df3dfa3061d25996ac98158d3bdb3525c8d89445 # load environment for bootstrap compiler source "$(CURL_USER_AGENT=\"$CURL_USER_AGENT\" bash ~/dlang/install.sh dmd-$HOST_DMD_VER --activate)" From 5b456a10a9a618f64414603351793685042cab4d Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Wed, 5 Jul 2017 19:32:19 +0200 Subject: [PATCH 072/163] Undocument failing unittests --- std/csv.d | 1 - std/uni.d | 3 --- 2 files changed, 4 deletions(-) diff --git a/std/csv.d b/std/csv.d index a896159b5b0..06f8bdf16d9 100644 --- a/std/csv.d +++ b/std/csv.d @@ -1099,7 +1099,6 @@ public: } } -/// @safe pure unittest { import std.algorithm.comparison : equal; diff --git a/std/uni.d b/std/uni.d index b301cd17579..33407dc5868 100644 --- a/std/uni.d +++ b/std/uni.d @@ -2546,7 +2546,6 @@ private: return this; } - /// @safe unittest { assert(unicode.Cyrillic.intersect('-').byInterval.empty); @@ -4340,7 +4339,6 @@ if (sumOfIntegerTuple!sizes == 21) } } -/// @system pure unittest { import std.algorithm.comparison : max; @@ -4644,7 +4642,6 @@ public struct MatcherConcept return this; } - /// @safe unittest { auto m = utfMatcher!char(unicode.Number); From 8b4dc6c7b43d3ce6e4f9b4e30cd564643a2ed60d Mon Sep 17 00:00:00 2001 From: "H. S. Teoh" Date: Wed, 5 Jul 2017 10:34:45 -0700 Subject: [PATCH 073/163] Improve docs for std.algorithm.remove. Rationale: the most common use for this function is to remove an element from an array. Therefore, the first example the user should see in the docs is how to achieve this. All the rest of the complications, like `remove` not changing the length of the array and what-not, should be discussed *afterwards*, not smack in the user's face. The current first example is a poor choice for a first example from a user's POV, because it throws a complicated case out there without first telling the reader (presumably someone new to the language, since seasoned D coders wouldn't be needing to read the docs for `remove`) how to accomplish the simplest, and most common, use case. --- std/algorithm/mutation.d | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/std/algorithm/mutation.d b/std/algorithm/mutation.d index 49f3c850c7f..1124cea4fa6 100644 --- a/std/algorithm/mutation.d +++ b/std/algorithm/mutation.d @@ -1660,8 +1660,21 @@ enum SwapStrategy } /** -Eliminates elements at given offsets from $(D range) and returns the -shortened range. In the simplest call, one element is removed. +Eliminates elements at given offsets from `range` and returns the shortened +range. + +For example, here is how to _remove a single element from an array: + +---- +string[] a = [ "a", "b", "c", "d" ]; +a = a.remove(1); // remove element at offset 1 +assert(a == [ "a", "c", "d"]); +---- + +Note that `remove` does not change the length of the original _range directly; +instead, it returns the shortened _range. If its return value is not assigned to +the original _range, the original _range will retain its original length, though +its contents will have changed: ---- int[] a = [ 3, 5, 7, 8 ]; @@ -1669,15 +1682,13 @@ assert(remove(a, 1) == [ 3, 7, 8 ]); assert(a == [ 3, 7, 8, 8 ]); ---- -In the case above the element at offset $(D 1) is removed and $(D -remove) returns the range smaller by one element. The original array -has remained of the same length because all functions in $(D -std.algorithm) only change $(I content), not $(I topology). The value -$(D 8) is repeated because $(LREF move) was invoked to -move elements around and on integers $(D move) simply copies the source to -the destination. To replace $(D a) with the effect of the removal, -simply assign $(D a = remove(a, 1)). The slice will be rebound to the -shorter array and the operation completes with maximal efficiency. +The element at _offset `1` has been removed and the rest of the elements have +shifted up to fill its place, however, the original array remains of the same +length. This is because all functions in `std.algorithm` only change $(I +content), not $(I topology). The value `8` is repeated because $(LREF move) was +invoked to rearrange elements, and on integers `move` simply copies the source +to the destination. To replace `a` with the effect of the removal, simply +assign the slice returned by `remove` to it, as shown in the first example. Multiple indices can be passed into $(D remove). In that case, elements at the respective indices are all removed. The indices must @@ -1689,7 +1700,7 @@ assert(remove(a, 1, 3, 5) == [ 0, 2, 4, 6, 7, 8, 9, 10 ]); ---- -(Note how all indices refer to slots in the $(I original) array, not +(Note that all indices refer to slots in the $(I original) array, not in the array as it is being progressively shortened.) Finally, any combination of integral offsets and tuples composed of two integral offsets can be passed in. From 58ebf548cce41cc9ad19d42045738a0c61b80342 Mon Sep 17 00:00:00 2001 From: Jack Stouffer Date: Wed, 5 Jul 2017 15:08:55 -0400 Subject: [PATCH 074/163] Optimized std.datetime.date.DateTime from string methods --- std/datetime/date.d | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/std/datetime/date.d b/std/datetime/date.d index 396cae9cfc3..6e0978f6d4f 100644 --- a/std/datetime/date.d +++ b/std/datetime/date.d @@ -3055,20 +3055,19 @@ public: if (isSomeString!S) { import std.algorithm.searching : countUntil; - import std.conv : to; import std.exception : enforce; import std.format : format; import std.string : strip; - immutable dstr = to!dstring(strip(isoString)); + immutable str = strip(isoString); - enforce(dstr.length >= 15, new DateTimeException(format("Invalid ISO String: %s", isoString))); - auto t = dstr.countUntil('T'); + enforce(str.length >= 15, new DateTimeException(format("Invalid ISO String: %s", isoString))); + auto t = str.countUntil('T'); enforce(t != -1, new DateTimeException(format("Invalid ISO String: %s", isoString))); - immutable date = Date.fromISOString(dstr[0 .. t]); - immutable tod = TimeOfDay.fromISOString(dstr[t+1 .. $]); + immutable date = Date.fromISOString(str[0 .. t]); + immutable tod = TimeOfDay.fromISOString(str[t+1 .. $]); return DateTime(date, tod); } @@ -3144,20 +3143,19 @@ public: if (isSomeString!(S)) { import std.algorithm.searching : countUntil; - import std.conv : to; import std.exception : enforce; import std.format : format; import std.string : strip; - immutable dstr = to!dstring(strip(isoExtString)); + immutable str = strip(isoExtString); - enforce(dstr.length >= 15, new DateTimeException(format("Invalid ISO Extended String: %s", isoExtString))); - auto t = dstr.countUntil('T'); + enforce(str.length >= 15, new DateTimeException(format("Invalid ISO Extended String: %s", isoExtString))); + auto t = str.countUntil('T'); enforce(t != -1, new DateTimeException(format("Invalid ISO Extended String: %s", isoExtString))); - immutable date = Date.fromISOExtString(dstr[0 .. t]); - immutable tod = TimeOfDay.fromISOExtString(dstr[t+1 .. $]); + immutable date = Date.fromISOExtString(str[0 .. t]); + immutable tod = TimeOfDay.fromISOExtString(str[t+1 .. $]); return DateTime(date, tod); } @@ -3232,20 +3230,19 @@ public: if (isSomeString!(S)) { import std.algorithm.searching : countUntil; - import std.conv : to; import std.exception : enforce; import std.format : format; import std.string : strip; - immutable dstr = to!dstring(strip(simpleString)); + immutable str = strip(simpleString); - enforce(dstr.length >= 15, new DateTimeException(format("Invalid string format: %s", simpleString))); - auto t = dstr.countUntil(' '); + enforce(str.length >= 15, new DateTimeException(format("Invalid string format: %s", simpleString))); + auto t = str.countUntil(' '); enforce(t != -1, new DateTimeException(format("Invalid string format: %s", simpleString))); - immutable date = Date.fromSimpleString(dstr[0 .. t]); - immutable tod = TimeOfDay.fromISOExtString(dstr[t+1 .. $]); + immutable date = Date.fromSimpleString(str[0 .. t]); + immutable tod = TimeOfDay.fromISOExtString(str[t+1 .. $]); return DateTime(date, tod); } From 3b9fbff15a7e8d96acdfc70acf2b1731a30d271a Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Thu, 6 Jul 2017 00:44:59 +0200 Subject: [PATCH 075/163] Fix style (space between a .. b) in std/json.d --- std/json.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/std/json.d b/std/json.d index 0289e6e7cea..0c436de9743 100644 --- a/std/json.d +++ b/std/json.d @@ -1176,7 +1176,7 @@ string toJSON(const ref JSONValue root, in bool pretty = false, in JSONOptions o // of UTF-16 surrogate characters, as per RFC 4627. wchar[2] wchars; // 1 or 2 UTF-16 code units size_t wNum = encode(wchars, c); // number of UTF-16 code units - foreach (wc; wchars[0..wNum]) + foreach (wc; wchars[0 .. wNum]) { json.put("\\u"); foreach_reverse (i; 0 .. 4) From d8959320e0c47a1861e32bbbf6a3ba30a019798e Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Wed, 5 Jul 2017 19:56:37 +0200 Subject: [PATCH 076/163] Fix deprecations on Windows --- std/datetime/timezone.d | 6 ++---- std/file.d | 16 +++++++--------- std/windows/charset.d | 3 +-- std/windows/registry.d | 13 ++++++------- 4 files changed, 16 insertions(+), 22 deletions(-) diff --git a/std/datetime/timezone.d b/std/datetime/timezone.d index 066b150b559..1716eb15d0a 100644 --- a/std/datetime/timezone.d +++ b/std/datetime/timezone.d @@ -2991,8 +2991,6 @@ else version(Windows) static immutable(WindowsTimeZone) getTimeZone(string name) @trusted { - import std.utf : toUTF16; - scope baseKey = Registry.localMachine.getKey(`Software\Microsoft\Windows NT\CurrentVersion\Time Zones`); foreach (tzKeyName; baseKey.keyNames) @@ -3015,8 +3013,8 @@ else version(Windows) TIME_ZONE_INFORMATION tzInfo; - auto wstdName = toUTF16(stdName); - auto wdstName = toUTF16(dstName); + auto wstdName = stdName.to!wstring; + auto wdstName = dstName.to!wstring; auto wstdNameLen = wstdName.length > 32 ? 32 : wstdName.length; auto wdstNameLen = wdstName.length > 32 ? 32 : wdstName.length; diff --git a/std/file.d b/std/file.d index 47099789741..b6434a4d3de 100644 --- a/std/file.d +++ b/std/file.d @@ -2644,7 +2644,6 @@ version(Posix) @system unittest // input range of dchars version(Windows) string getcwd() { import std.conv : to; - import std.utf : toUTF8; /* GetCurrentDirectory's return value: 1. function succeeds: the number of characters that are written to the buffer, not including the terminating null character. @@ -2658,7 +2657,7 @@ version(Windows) string getcwd() // we can do it because toUTFX always produces a fresh string if (n < buffW.length) { - return toUTF8(buffW[0 .. n]); + return buffW[0 .. n].to!string; } else //staticBuff isn't enough { @@ -2666,7 +2665,7 @@ version(Windows) string getcwd() scope(exit) free(ptr); immutable n2 = GetCurrentDirectoryW(n, ptr); cenforce(n2 && n2 < n, "getcwd"); - return toUTF8(ptr[0 .. n2]); + return ptr[0 .. n2].to!string; } } else version (Solaris) string getcwd() @@ -2968,7 +2967,6 @@ else version(Windows) { struct DirEntry { - import std.utf : toUTF8; public: alias name this; @@ -2994,12 +2992,12 @@ else version(Windows) private this(string path, in WIN32_FIND_DATAW *fd) { import core.stdc.wchar_ : wcslen; + import std.conv : to; import std.datetime.systime : FILETIMEToSysTime; import std.path : buildPath; size_t clength = wcslen(fd.cFileName.ptr); - _name = toUTF8(fd.cFileName[0 .. clength]); - _name = buildPath(path, toUTF8(fd.cFileName[0 .. clength])); + _name = buildPath(path, fd.cFileName[0 .. clength].to!string); _size = (cast(ulong) fd.nFileSizeHigh << 32) | fd.nFileSizeLow; _timeCreated = FILETIMEToSysTime(&fd.ftCreationTime); _timeLastAccessed = FILETIMEToSysTime(&fd.ftLastAccessTime); @@ -3431,7 +3429,7 @@ private void copyImpl(const(char)[] f, const(char)[] t, const(FSChar)* fromz, co { version(Windows) { - assert(preserve == Yes.preserve); + assert(preserve == Yes.preserveAttributes); immutable result = CopyFileW(fromz, toz, false); if (!result) { @@ -4287,11 +4285,11 @@ string tempDir() @trusted { version(Windows) { - import std.utf : toUTF8; + import std.conv : to; // http://msdn.microsoft.com/en-us/library/windows/desktop/aa364992(v=vs.85).aspx wchar[MAX_PATH + 2] buf; DWORD len = GetTempPathW(buf.length, buf.ptr); - if (len) cache = toUTF8(buf[0 .. len]); + if (len) cache = buf[0 .. len].to!string; } else version(Android) { diff --git a/std/windows/charset.d b/std/windows/charset.d index c6abe7a381a..67bd99da1ad 100644 --- a/std/windows/charset.d +++ b/std/windows/charset.d @@ -53,7 +53,6 @@ version (Windows): private import core.sys.windows.windows; private import std.conv; private import std.string; -private import std.utf; private import std.windows.syserror; import std.internal.cstring; @@ -114,7 +113,7 @@ string fromMBSz(immutable(char)* s, int codePage = 0) sysErrorString(GetLastError())); } - return std.utf.toUTF8(result[0 .. result.length-1]); // omit trailing null + return result[0 .. result.length-1].to!string; // omit trailing null } } return s[0 .. c-s]; // string is ASCII, no conversion necessary diff --git a/std/windows/registry.d b/std/windows/registry.d index 0b5e3d2d1c3..e600c852213 100644 --- a/std/windows/registry.d +++ b/std/windows/registry.d @@ -45,7 +45,6 @@ import std.exception; import std.internal.cstring; private import std.internal.windows.advapi32; import std.system : Endian, endian; -import std.utf : toUTF8, toUTF16; import std.windows.syserror; //debug = winreg; @@ -557,7 +556,7 @@ body if (wstr.length && wstr[$-1] == '\0') wstr.length = wstr.length - 1; assert(wstr.length == 0 || wstr[$-1] != '\0'); - value = toUTF8(wstr); + value = wstr.to!string; break; case REG_VALUE_TYPE.REG_DWORD_LITTLE_ENDIAN: @@ -623,7 +622,7 @@ body value.length = list.length; foreach (i, ref v; value) { - v = toUTF8(list[i]); + v = list[i].to!string; } } @@ -752,7 +751,7 @@ private void regProcessNthKey(HKEY hkey, scope void delegate(scope LONG delegate immutable res = regEnumKeyName(hkey, index, sName, cchName); if (res == ERROR_SUCCESS) { - name = toUTF8(sName[0 .. cchName]); + name = sName[0 .. cchName].to!string; } return res; }); @@ -774,7 +773,7 @@ private void regProcessNthValue(HKEY hkey, scope void delegate(scope LONG delega immutable res = regEnumValueName(hkey, index, sName, cchName); if (res == ERROR_SUCCESS) { - name = toUTF8(sName[0 .. cchName]); + name = sName[0 .. cchName].to!string; } return res; }); @@ -1098,7 +1097,7 @@ public: wstring[] data = new wstring[value.length+1]; foreach (i, ref s; data[0..$-1]) { - s = toUTF16(value[i]); + s = value[i].to!wstring; } data[$-1] = "\0"; auto ws = std.array.join(data, "\0"w); @@ -1235,7 +1234,7 @@ public: ExpandEnvironmentStringsW(srcTmp, newValue.ptr, to!DWORD(newValue.length)), "Failed to expand environment variables"); - return toUTF8(newValue[0 .. count-1]); // remove trailing 0 + return newValue[0 .. count-1].to!string; // remove trailing 0 } /** From 7988c28c51de6dab45593110e06ec37afa216728 Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Thu, 6 Jul 2017 13:11:17 +0200 Subject: [PATCH 077/163] Move tools checkout to style_lint to avoid failing PRs --- circleci.sh | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/circleci.sh b/circleci.sh index 443f74b545c..1e34e45e22b 100755 --- a/circleci.sh +++ b/circleci.sh @@ -86,10 +86,6 @@ setup_repos() fi done - # checkout a specific version of https://github.com/dlang/tools - clone https://github.com/dlang/tools.git ../tools master - git -C ../tools checkout df3dfa3061d25996ac98158d3bdb3525c8d89445 - # load environment for bootstrap compiler source "$(CURL_USER_AGENT=\"$CURL_USER_AGENT\" bash ~/dlang/install.sh dmd-$HOST_DMD_VER --activate)" @@ -129,6 +125,12 @@ coverage() # extract publictests and run them independently publictests() { + # checkout a specific version of https://github.com/dlang/tools + if [ ! -d ../tools ] ; then + clone https://github.com/dlang/tools.git ../tools master + fi + git -C ../tools checkout df3dfa3061d25996ac98158d3bdb3525c8d89445 + make -f posix.mak -j$N publictests DUB=$DUB } From 43eadc38e3e31258470b53237db4176876ad54c5 Mon Sep 17 00:00:00 2001 From: RazvanN7 Date: Thu, 6 Jul 2017 12:15:58 +0300 Subject: [PATCH 078/163] Fix Issue 17369 - [Module std.traits] Documentation lists ditto in table --- std/traits.d | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/std/traits.d b/std/traits.d index 078fb662996..1fc1804148b 100644 --- a/std/traits.d +++ b/std/traits.d @@ -279,21 +279,21 @@ private package { - /// Add specific qualifier to the given type T. + /// Add the mutable qualifier to the given type T. template MutableOf(T) { alias MutableOf = T ; } } -/// Add specific qualifier to the given type T. +/// Add the inout qualifier to the given type T. template InoutOf(T) { alias InoutOf = inout(T) ; } -/// ditto. +/// Add the const qualifier to the given type T. template ConstOf(T) { alias ConstOf = const(T) ; } -/// ditto. +/// Add the shared qualifier to the given type T. template SharedOf(T) { alias SharedOf = shared(T) ; } -/// ditto. +/// Add the shared and inout qualifiers to the given type T. template SharedInoutOf(T) { alias SharedInoutOf = shared(inout(T)); } -/// ditto. +/// Add the shared and const qualifiers to the given type T. template SharedConstOf(T) { alias SharedConstOf = shared(const(T)); } -/// ditto. +/// Add the immutable qualifier to the given type T. template ImmutableOf(T) { alias ImmutableOf = immutable(T) ; } @safe unittest From 8d29b4d6c1c7dec1ef6553d47f2ddf1696e40d63 Mon Sep 17 00:00:00 2001 From: RazvanN7 Date: Thu, 6 Jul 2017 13:53:07 +0300 Subject: [PATCH 079/163] Made the comment of MutableOf private --- std/traits.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/std/traits.d b/std/traits.d index 1fc1804148b..d32a5e967ec 100644 --- a/std/traits.d +++ b/std/traits.d @@ -279,7 +279,7 @@ private package { - /// Add the mutable qualifier to the given type T. + // Add the mutable qualifier to the given type T. template MutableOf(T) { alias MutableOf = T ; } } From 657339069c9d2e72f3fce4e6d144ec42ce6cc399 Mon Sep 17 00:00:00 2001 From: Vladimir Panteleev Date: Thu, 6 Jul 2017 02:04:44 +0000 Subject: [PATCH 080/163] Fix broken links --- index.d | 2 +- std/digest/digest.d | 2 +- std/digest/hmac.d | 2 +- std/file.d | 2 +- std/range/package.d | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/index.d b/index.d index 36a69662559..2792b7b0326 100644 --- a/index.d +++ b/index.d @@ -353,7 +353,7 @@ $(BOOKTABLE , ) $(LEADINGROW Runtime utilities) $(TR - $(TDNW $(MREF object)) + $(TDNW $(MREF1 object)) $(TD Core language definitions. Automatically imported.) ) $(TR diff --git a/std/digest/digest.d b/std/digest/digest.d index 3e120922828..1d2eaf541d4 100644 --- a/std/digest/digest.d +++ b/std/digest/digest.d @@ -393,7 +393,7 @@ template hasPeek(T) /** * Checks whether the digest has a $(D blockSize) member, which contains the - * digest's internal block size in bits. It is primarily used by $(REF HMAC, std,digest.hmac). + * digest's internal block size in bits. It is primarily used by $(REF HMAC, std,digest,hmac). */ template hasBlockSize(T) diff --git a/std/digest/hmac.d b/std/digest/hmac.d index 20d9821488c..516f6d6c62a 100644 --- a/std/digest/hmac.d +++ b/std/digest/hmac.d @@ -26,7 +26,7 @@ import std.meta : allSatisfy; * information about the block size, it can be supplied explicitly using * the second overload. * - * This type conforms to $(REF isDigest, std,digest.digest). + * This type conforms to $(REF isDigest, std,digest,digest). */ version(StdDdoc) diff --git a/std/file.d b/std/file.d index b6434a4d3de..5ec650626bd 100644 --- a/std/file.d +++ b/std/file.d @@ -2705,7 +2705,7 @@ else version (NetBSD) * Returns the full path of the current executable. * * Throws: - * $(REF Exception, std,object) + * $(REF1 Exception, object) */ @trusted string thisExePath () { diff --git a/std/range/package.d b/std/range/package.d index 589cf127ce2..cf0362ae2ab 100644 --- a/std/range/package.d +++ b/std/range/package.d @@ -493,7 +493,7 @@ Params: Returns: At minimum, an input range. The resulting range will adopt the range primitives of the underlying range as long as - $(REF, hasLength, std,range,primitives) is `true`. + $(REF hasLength, std,range,primitives) is `true`. */ auto stride(Range)(Range r, size_t n) if (isInputRange!(Unqual!Range)) From e40a35675a89ec9346ba90cf973a423ff8e5d973 Mon Sep 17 00:00:00 2001 From: RazvanN7 Date: Tue, 4 Jul 2017 17:26:41 +0300 Subject: [PATCH 081/163] Fix Issue 17540 - std.net.curl: HTTP no possibillity to set CURLOPT_NOPROXY --- std/net/curl.d | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/std/net/curl.d b/std/net/curl.d index 1e752416c8a..f7075dc254f 100644 --- a/std/net/curl.d +++ b/std/net/curl.d @@ -2047,6 +2047,17 @@ private mixin template Protocol() p.curl.set(CurlOption.localport, cast(long) port); } + /** + Set the no proxy flag for the specified host names. + Params: + test = a list of comma host names that do not require + proxy to get reached + */ + void setNoProxy(string hosts) + { + p.curl.set(CurlOption.noproxy, hosts); + } + /** Set the local outgoing port range to use. This can be used together with the localPort property. @@ -2122,6 +2133,9 @@ private mixin template Protocol() http.onReceive = (ubyte[] data) { return data.length; }; http.setAuthentication("user", "pass"); http.perform(); + + // Bugzilla 17540 + http.setNoProxy("www.example.com"); } /** From 734641b4dfbd2670b2321203c00709512c215f94 Mon Sep 17 00:00:00 2001 From: RazvanN7 Date: Thu, 6 Jul 2017 11:52:35 +0300 Subject: [PATCH 082/163] Optimize count with an overload which calls walkLength --- std/algorithm/searching.d | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/std/algorithm/searching.d b/std/algorithm/searching.d index 7fc765f000f..b9047659ed6 100644 --- a/std/algorithm/searching.d +++ b/std/algorithm/searching.d @@ -604,6 +604,11 @@ $(D 2). The third version counts the elements for which $(D pred(x)) is $(D true). Performs $(BIGOH haystack.length) evaluations of $(D pred). +The fourth version counts the number of elements in a range. It is +an optimization for the third version: if the given range has the +`length` property the count is returned right away, otherwise +performs $(BIGOH haystack.length) to walk the range. + Note: Regardless of the overload, $(D count) will not accept infinite ranges for $(D haystack). @@ -630,6 +635,7 @@ if (isInputRange!Range && !isInfinite!Range && // count elements in range int[] a = [ 1, 2, 4, 3, 2, 5, 3, 2, 4 ]; + assert(count(a) == 9); assert(count(a, 2) == 3); assert(count!("a > b")(a, 2) == 5); // count range in range @@ -692,7 +698,7 @@ if (isForwardRange!R1 && !isInfinite!R1 && } /// Ditto -size_t count(alias pred = "true", R)(R haystack) +size_t count(alias pred, R)(R haystack) if (isInputRange!R && !isInfinite!R && is(typeof(unaryFun!pred(haystack.front)) : bool)) { @@ -703,6 +709,13 @@ if (isInputRange!R && !isInfinite!R && return result; } +/// Ditto +size_t count(R)(R haystack) +if (isInputRange!R && !isInfinite!R) +{ + return walkLength(haystack); +} + @safe unittest { int[] a = [ 1, 2, 4, 3, 2, 5, 3, 2, 4 ]; From 54bda1e5bcb98f898342c51186f659293f73aa86 Mon Sep 17 00:00:00 2001 From: Martin Nowak Date: Fri, 7 Jul 2017 12:29:02 +0200 Subject: [PATCH 083/163] fix Issue 17616 - makeIndex cannot fully use range of index type --- std/algorithm/sorting.d | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/std/algorithm/sorting.d b/std/algorithm/sorting.d index e18f2d0d9b7..8b7f6d5b4b9 100644 --- a/std/algorithm/sorting.d +++ b/std/algorithm/sorting.d @@ -994,15 +994,15 @@ if (isRandomAccessRange!Range && !isInfinite!Range && "r and index must be same length for makeIndex."); static if (IndexType.sizeof < size_t.sizeof) { - enforce(r.length <= IndexType.max, "Cannot create an index with " ~ + enforce(r.length <= size_t(IndexType.max + 1), "Cannot create an index with " ~ "element type " ~ IndexType.stringof ~ " with length " ~ to!string(r.length) ~ "."); } - for (IndexType i = 0; i < r.length; ++i) - { - index[cast(size_t) i] = i; - } + // Use size_t as loop index to avoid overflow on ++i, + // e.g. when squeezing 256 elements into a ubyte index. + foreach (i; size_t(0) .. size_t(r.length)) + index[i] = cast(IndexType) i; // sort the index sort!((a, b) => binaryFun!less(r[cast(size_t) a], r[cast(size_t) b]), ss) @@ -1056,6 +1056,18 @@ if (isRandomAccessRange!Range && !isInfinite!Range && (index3)); } +@safe unittest +{ + import std.algorithm.comparison : equal; + + ubyte[256] index = void; + iota(256).makeIndex(index[]); + assert(index[].equal(iota(256))); + byte[128] sindex = void; + iota(128).makeIndex(sindex[]); + assert(sindex[].equal(iota(128))); +} + struct Merge(alias less = "a < b", Rs...) if (Rs.length >= 2 && allSatisfy!(isInputRange, Rs) && From 2267cf26204d2b15e8f9c760fbd6a9fadd17478c Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Fri, 7 Jul 2017 14:37:50 +0200 Subject: [PATCH 084/163] makeIndex: fix special case for uint --- std/algorithm/sorting.d | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/std/algorithm/sorting.d b/std/algorithm/sorting.d index 8b7f6d5b4b9..ea55e29f9c9 100644 --- a/std/algorithm/sorting.d +++ b/std/algorithm/sorting.d @@ -994,7 +994,7 @@ if (isRandomAccessRange!Range && !isInfinite!Range && "r and index must be same length for makeIndex."); static if (IndexType.sizeof < size_t.sizeof) { - enforce(r.length <= size_t(IndexType.max + 1), "Cannot create an index with " ~ + enforce(r.length <= size_t(1) + IndexType.max, "Cannot create an index with " ~ "element type " ~ IndexType.stringof ~ " with length " ~ to!string(r.length) ~ "."); } @@ -1066,6 +1066,10 @@ if (isRandomAccessRange!Range && !isInfinite!Range && byte[128] sindex = void; iota(128).makeIndex(sindex[]); assert(sindex[].equal(iota(128))); + + auto index2 = new uint[10]; + 10.iota.makeIndex(index2); + assert(index2.equal(10.iota)); } struct Merge(alias less = "a < b", Rs...) From b4e1043a9649116c90f430e17df8e9e2347e6f53 Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Fri, 7 Jul 2017 14:45:50 +0200 Subject: [PATCH 085/163] makeIndex: Remove the explicit casting from the foreach loop --- std/algorithm/sorting.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/std/algorithm/sorting.d b/std/algorithm/sorting.d index ea55e29f9c9..e1c7792459c 100644 --- a/std/algorithm/sorting.d +++ b/std/algorithm/sorting.d @@ -1001,7 +1001,7 @@ if (isRandomAccessRange!Range && !isInfinite!Range && // Use size_t as loop index to avoid overflow on ++i, // e.g. when squeezing 256 elements into a ubyte index. - foreach (i; size_t(0) .. size_t(r.length)) + foreach (size_t i; 0 .. r.length) index[i] = cast(IndexType) i; // sort the index From 2108df251c51c0b7078d11fbeec6926be2206f9e Mon Sep 17 00:00:00 2001 From: Jack Stouffer Date: Fri, 7 Jul 2017 10:43:26 -0400 Subject: [PATCH 086/163] Added examples to std.array.split --- std/array.d | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/std/array.d b/std/array.d index e3d94ad17ae..33b731782d2 100644 --- a/std/array.d +++ b/std/array.d @@ -1363,6 +1363,9 @@ $(D @safe), $(D pure) and $(D CTFE)-able. Params: s = the string to split +Returns: + An array of each word in `s` + See_Also: $(REF splitter, std,algorithm,iteration) for a version that splits using any separator. @@ -1402,6 +1405,29 @@ if (isSomeString!S) return result; } +/// +@safe unittest +{ + string str = "Hello World!"; + assert(str.split == ["Hello", "World!"]); + + string str2 = "Hello\t\tWorld\t!"; + assert(str2.split == ["Hello", "World", "!"]); +} + +/** + * `split` allocates memory, so the same effect can be achieved lazily + * using $(REF splitter, std,algorithm,iteration). + */ +@safe unittest +{ + import std.ascii : isWhite; + import std.algorithm.comparison : equal; + + string str = "Hello World!"; + assert(str.splitter!(isWhite).equal(["Hello", "World!"])); +} + @safe unittest { import std.conv : to; From 73c36a85bf41785aab04a343a825967a4016f871 Mon Sep 17 00:00:00 2001 From: Jack Stouffer Date: Fri, 7 Jul 2017 11:23:37 -0400 Subject: [PATCH 087/163] Removed old debug printfs --- std/string.d | 73 ---------------------------------------------------- 1 file changed, 73 deletions(-) diff --git a/std/string.d b/std/string.d index b24f1ee3554..fefd44dad3c 100644 --- a/std/string.d +++ b/std/string.d @@ -148,15 +148,6 @@ Source: $(PHOBOSSRC std/_string.d) */ module std.string; -//debug=string; // uncomment to turn on debugging trustedPrintf's - -debug(string) private -void trustedPrintf(in char* str) @trusted nothrow @nogc -{ - import core.stdc.stdio : printf; - printf("%s", str); -} - version (unittest) { private: @@ -580,7 +571,6 @@ if (isConvertibleToString!Range) import std.exception : assertCTFEable; import std.traits : EnumMembers; import std.utf : byChar, byWchar, byDchar; - debug(string) trustedPrintf("string.indexOf.unittest\n"); assertCTFEable!( { @@ -636,7 +626,6 @@ if (isConvertibleToString!Range) import std.conv : to; import std.traits : EnumMembers; import std.utf : byCodeUnit, byChar, byWchar; - debug(string) trustedPrintf("string.indexOf(startIdx).unittest\n"); assert("hello".byCodeUnit.indexOf(cast(dchar)'l', 1) == 2); assert("hello".byWchar.indexOf(cast(dchar)'l', 1) == 2); @@ -835,7 +824,6 @@ if (!(isForwardRange!Range && isSomeChar!(ElementEncodingType!Range) && import std.conv : to; import std.exception : assertCTFEable; import std.traits : EnumMembers; - debug(string) trustedPrintf("string.indexOf.unittest\n"); assertCTFEable!( { @@ -906,7 +894,6 @@ unittest { import std.conv : to; import std.traits : EnumMembers; - debug(string) trustedPrintf("string.indexOf(startIdx).unittest\n"); foreach (S; AliasSeq!(string, wstring, dstring)) { @@ -1083,7 +1070,6 @@ if (isSomeChar!Char) import std.conv : to; import std.exception : assertCTFEable; import std.traits : EnumMembers; - debug(string) trustedPrintf("string.lastIndexOf.unittest\n"); assertCTFEable!( { @@ -1124,8 +1110,6 @@ if (isSomeChar!Char) import std.conv : to; import std.traits : EnumMembers; - debug(string) trustedPrintf("string.lastIndexOf.unittest\n"); - foreach (S; AliasSeq!(string, wstring, dstring)) { assert(lastIndexOf(cast(S) null, 'a') == -1); @@ -1310,8 +1294,6 @@ if (isSomeChar!Char1 && isSomeChar!Char2) import std.exception : assertCTFEable; import std.traits : EnumMembers; - debug(string) trustedPrintf("string.lastIndexOf.unittest\n"); - assertCTFEable!( { foreach (S; AliasSeq!(string, wstring, dstring)) @@ -1388,8 +1370,6 @@ if (isSomeChar!Char1 && isSomeChar!Char2) import std.conv : to; import std.traits : EnumMembers; - debug(string) trustedPrintf("string.lastIndexOf.unittest\n"); - foreach (S; AliasSeq!(string, wstring, dstring)) { foreach (T; AliasSeq!(string, wstring, dstring)) @@ -1636,8 +1616,6 @@ if (isSomeChar!Char && isSomeChar!Char2) import std.conv : to; import std.exception : assertCTFEable; - debug(string) trustedPrintf("string.indexOfAny.unittest\n"); - assertCTFEable!( { foreach (S; AliasSeq!(string, wstring, dstring)) @@ -1677,8 +1655,6 @@ if (isSomeChar!Char && isSomeChar!Char2) import std.conv : to; import std.traits : EnumMembers; - debug(string) trustedPrintf("string.indexOfAny(startIdx).unittest\n"); - foreach (S; AliasSeq!(string, wstring, dstring)) { foreach (T; AliasSeq!(string, wstring, dstring)) @@ -1804,8 +1780,6 @@ if (isSomeChar!Char && isSomeChar!Char2) import std.conv : to; import std.exception : assertCTFEable; - debug(string) trustedPrintf("string.lastIndexOfAny.unittest\n"); - assertCTFEable!( { foreach (S; AliasSeq!(string, wstring, dstring)) @@ -1859,8 +1833,6 @@ if (isSomeChar!Char && isSomeChar!Char2) import std.conv : to; import std.exception : assertCTFEable; - debug(string) trustedPrintf("string.lastIndexOfAny(index).unittest\n"); - assertCTFEable!( { foreach (S; AliasSeq!(string, wstring, dstring)) @@ -1986,8 +1958,6 @@ if (isSomeChar!Char && isSomeChar!Char2) import std.conv : to; import std.exception : assertCTFEable; - debug(string) trustedPrintf("string.indexOf.unittest\n"); - assertCTFEable!( { foreach (S; AliasSeq!(string, wstring, dstring)) @@ -2032,8 +2002,6 @@ if (isSomeChar!Char && isSomeChar!Char2) import std.conv : to; import std.exception : assertCTFEable; - debug(string) trustedPrintf("string.indexOfNeither(index).unittest\n"); - assertCTFEable!( { foreach (S; AliasSeq!(string, wstring, dstring)) @@ -2144,8 +2112,6 @@ if (isSomeChar!Char && isSomeChar!Char2) import std.conv : to; import std.exception : assertCTFEable; - debug(string) trustedPrintf("string.lastIndexOfNeither.unittest\n"); - assertCTFEable!( { foreach (S; AliasSeq!(string, wstring, dstring)) @@ -2191,8 +2157,6 @@ if (isSomeChar!Char && isSomeChar!Char2) import std.conv : to; import std.exception : assertCTFEable; - debug(string) trustedPrintf("string.lastIndexOfNeither(index).unittest\n"); - assertCTFEable!( { foreach (S; AliasSeq!(string, wstring, dstring)) @@ -2511,8 +2475,6 @@ if (!isSomeString!S && is(StringTypeOf!S)) import std.conv : to; import std.exception : assertCTFEable; - debug(string) trustedPrintf("string.splitLines.unittest\n"); - assertCTFEable!( { foreach (S; AliasSeq!(char[], wchar[], dchar[], string, wstring, dstring)) @@ -2762,8 +2724,6 @@ if (isConvertibleToString!Range) import std.conv : to; import std.exception : assertCTFEable; - debug(string) trustedPrintf("string.lineSplitter.unittest\n"); - assertCTFEable!( { foreach (S; AliasSeq!(char[], wchar[], dchar[], string, wstring, dstring)) @@ -3148,8 +3108,6 @@ if (isConvertibleToString!Range) import std.conv : to; import std.exception : assertCTFEable; - debug(string) trustedPrintf("string.strip.unittest\n"); - assertCTFEable!( { foreach (S; AliasSeq!( char[], const char[], string, @@ -3353,7 +3311,6 @@ if (isConvertibleToString!Range) import std.conv : to; import std.exception : assertCTFEable; - debug(string) trustedPrintf("string.chomp.unittest\n"); string s; assertCTFEable!( @@ -3645,8 +3602,6 @@ if (isConvertibleToString!Range) import std.conv : to; import std.exception : assertCTFEable; - debug(string) trustedPrintf("string.chop.unittest\n"); - assertCTFEable!( { foreach (S; AliasSeq!(char[], wchar[], dchar[], string, wstring, dstring)) @@ -4032,8 +3987,6 @@ unittest import std.conv : to; import std.exception : assertCTFEable; - debug(string) trustedPrintf("string.justify.unittest\n"); - assertCTFEable!( { foreach (S; AliasSeq!(char[], wchar[], dchar[], string, wstring, dstring)) @@ -4372,8 +4325,6 @@ if (isConvertibleToString!Range) import std.conv : to; import std.exception : assertCTFEable; - debug(string) trustedPrintf("string.detab.unittest\n"); - assertCTFEable!( { foreach (S; AliasSeq!(char[], wchar[], dchar[], string, wstring, dstring)) @@ -4711,8 +4662,6 @@ unittest import std.conv : to; import std.exception : assertCTFEable; - debug(string) trustedPrintf("string.entab.unittest\n"); - assertCTFEable!( { assert(entab(cast(string) null) is null); @@ -5294,8 +5243,6 @@ deprecated import std.conv : to; import std.exception : assertCTFEable; - debug(string) trustedPrintf("std.string.inPattern.unittest\n"); - assertCTFEable!( { assert(inPattern('x', "x") == 1); @@ -5370,8 +5317,6 @@ deprecated import std.conv : to; import std.exception : assertCTFEable; - debug(string) trustedPrintf("std.string.count.unittest\n"); - assertCTFEable!( { assert(countchars("abc", "a-c") == 3); @@ -5425,8 +5370,6 @@ deprecated import std.conv : to; import std.exception : assertCTFEable; - debug(string) trustedPrintf("std.string.removechars.unittest\n"); - assertCTFEable!( { assert(removechars("abc", "a-c").length == 0); @@ -5503,8 +5446,6 @@ deprecated import std.conv : to; import std.exception : assertCTFEable; - debug(string) trustedPrintf("std.string.squeeze.unittest\n"); - assertCTFEable!( { string s; @@ -5645,8 +5586,6 @@ if (isSomeString!S) import std.conv : to; import std.exception : assertCTFEable; - debug(string) trustedPrintf("std.string.succ.unittest\n"); - assertCTFEable!( { assert(succ(string.init) is null); @@ -5819,8 +5758,6 @@ C1[] tr(C1, C2, C3, C4 = immutable char) import std.conv : to; import std.exception : assertCTFEable; - debug(string) trustedPrintf("std.string.tr.unittest\n"); - // Complete list of test types; too slow to test'em all // alias TestTypes = AliasSeq!( // char[], const( char)[], immutable( char)[], @@ -6143,8 +6080,6 @@ if (isSomeString!S || import std.conv : to; import std.exception : assertCTFEable; - debug(string) trustedPrintf("isNumeric(in string, bool = false).unittest\n"); - assertCTFEable!( { // Test the isNumeric(in string) function @@ -6458,8 +6393,6 @@ string[string] abbrev(string[] values) @safe pure import std.conv : to; import std.exception : assertCTFEable; - debug(string) trustedPrintf("string.abbrev.unittest\n"); - assertCTFEable!( { string[] values; @@ -6601,8 +6534,6 @@ if (isConvertibleToString!Range) import std.conv : to; import std.exception : assertCTFEable; - debug(string) trustedPrintf("string.column.unittest\n"); - assertCTFEable!( { assert(column(string.init) == 0); @@ -6716,8 +6647,6 @@ if (isSomeString!S) import std.conv : to; import std.exception : assertCTFEable; - debug(string) trustedPrintf("string.wrap.unittest\n"); - assertCTFEable!( { assert(wrap(string.init) == "\n"); @@ -6858,8 +6787,6 @@ if (isSomeString!S) import std.conv : to; import std.exception : assertCTFEable; - debug(string) trustedPrintf("string.outdent.unittest\n"); - template outdent_testStr(S) { enum S outdent_testStr = From efd740e55132a7c0fce4de4263104d599233e066 Mon Sep 17 00:00:00 2001 From: Vladimir Panteleev Date: Fri, 7 Jul 2017 15:39:28 +0000 Subject: [PATCH 088/163] Improve documentation of std.file.SpanMode (issue 8680) This clarifies the terminology used for describing the iteration order of dirEntries, as the current terminology has been found misleading. --- std/file.d | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/std/file.d b/std/file.d index 5ec650626bd..ac518964906 100644 --- a/std/file.d +++ b/std/file.d @@ -3670,12 +3670,23 @@ enum SpanMode { /** Only spans one directory. */ shallow, - /** Spans the directory depth-first, i.e. the content of any + /** Spans the directory in + $(HTTPS en.wikipedia.org/wiki/Tree_traversal#Post-order, + _depth-first $(B post)-order), i.e. the content of any subdirectory is spanned before that subdirectory itself. Useful e.g. when recursively deleting files. */ depth, - /** Spans the directory breadth-first, i.e. the content of any - subdirectory is spanned right after that subdirectory itself. */ + /** Spans the directory in + $(HTTPS en.wikipedia.org/wiki/Tree_traversal#Pre-order, depth-first + $(B pre)-order), i.e. the content of any subdirectory is spanned + right after that subdirectory itself. + + Note that $(D SpanMode.breadth) will not result in all directory + members occurring before any subdirectory members, i.e. it is not + _true + $(HTTPS en.wikipedia.org/wiki/Tree_traversal#Breadth-first_search, + _breadth-first traversal). + */ breadth, } @@ -3925,9 +3936,12 @@ public: Params: path = The directory to iterate over. If empty, the current directory will be iterated. - mode = Whether the directory's sub-directories should be iterated - over depth-first ($(D_PARAM depth)), breadth-first - ($(D_PARAM breadth)), or not at all ($(D_PARAM shallow)). + + mode = Whether the directory's sub-directories should be + iterated in depth-first port-order ($(LREF depth)), + depth-first pre-order ($(LREF breadth)), or not at all + ($(LREF shallow)). + followSymlink = Whether symbolic links which point to directories should be treated as directories and their contents iterated over. From 4697a127c2e1ea298f4ad0df28a71ca6fdf2e59d Mon Sep 17 00:00:00 2001 From: Vladimir Panteleev Date: Fri, 7 Jul 2017 16:31:57 +0000 Subject: [PATCH 089/163] Update a missed dirEntries overload (fixup for #5569) --- std/file.d | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/std/file.d b/std/file.d index ac518964906..6d8ad063cf9 100644 --- a/std/file.d +++ b/std/file.d @@ -4091,9 +4091,12 @@ auto dirEntries(string path, SpanMode mode, bool followSymlink = true) pattern = String with wildcards, such as $(RED "*.d"). The supported wildcard strings are described under $(REF globMatch, std,_path). - mode = Whether the directory's sub-directories should be iterated - over depth-first ($(D_PARAM depth)), breadth-first - ($(D_PARAM breadth)), or not at all ($(D_PARAM shallow)). + + mode = Whether the directory's sub-directories should be + iterated in depth-first port-order ($(LREF depth)), + depth-first pre-order ($(LREF breadth)), or not at all + ($(LREF shallow)). + followSymlink = Whether symbolic links which point to directories should be treated as directories and their contents iterated over. From 2e6c52d02f80ef9c45c42a0c7a092ddf09952371 Mon Sep 17 00:00:00 2001 From: Vladimir Panteleev Date: Fri, 7 Jul 2017 17:33:29 +0000 Subject: [PATCH 090/163] std.file: Unify dirEntries overloads' documentation --- std/file.d | 43 +++++++++++++------------------------------ 1 file changed, 13 insertions(+), 30 deletions(-) diff --git a/std/file.d b/std/file.d index 6d8ad063cf9..7a6edb48159 100644 --- a/std/file.d +++ b/std/file.d @@ -3937,6 +3937,12 @@ public: path = The directory to iterate over. If empty, the current directory will be iterated. + pattern = Optional string with wildcards, such as $(RED + "*.d"). When present, it is used to filter the + results by their file name. The supported wildcard + strings are described under $(REF globMatch, + std,_path). + mode = Whether the directory's sub-directories should be iterated in depth-first port-order ($(LREF depth)), depth-first pre-order ($(LREF breadth)), or not at all @@ -3981,6 +3987,12 @@ foreach (d; parallel(dFiles, 1)) //passes by 1 file to each thread writeln(cmd); std.process.system(cmd); } + +// Iterate over all D source files in current directory and all its +// subdirectories +auto dFiles = dirEntries("","*.{d,di}",SpanMode.depth); +foreach (d; dFiles) + writeln(d.name); -------------------- +/ auto dirEntries(string path, SpanMode mode, bool followSymlink = true) @@ -4083,36 +4095,7 @@ auto dirEntries(string path, SpanMode mode, bool followSymlink = true) dirEntries("", SpanMode.shallow).walkLength(); } -/++ - Convenience wrapper for filtering file names with a glob pattern. - - Params: - path = The directory to iterate over. - pattern = String with wildcards, such as $(RED "*.d"). The supported - wildcard strings are described under - $(REF globMatch, std,_path). - - mode = Whether the directory's sub-directories should be - iterated in depth-first port-order ($(LREF depth)), - depth-first pre-order ($(LREF breadth)), or not at all - ($(LREF shallow)). - - followSymlink = Whether symbolic links which point to directories - should be treated as directories and their contents - iterated over. - - Throws: - $(D FileException) if the directory does not exist. - -Example: --------------------- -// Iterate over all D source files in current directory and all its -// subdirectories -auto dFiles = dirEntries("","*.{d,di}",SpanMode.depth); -foreach (d; dFiles) - writeln(d.name); --------------------- - +/ +/// Ditto auto dirEntries(string path, string pattern, SpanMode mode, bool followSymlink = true) { From e3c91711a1e3889c5354690b68afc9895d99bb7c Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Fri, 7 Jul 2017 21:40:59 +0200 Subject: [PATCH 091/163] Fix random coverage in std.algorithm.sorting --- std/algorithm/sorting.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/std/algorithm/sorting.d b/std/algorithm/sorting.d index e1c7792459c..30a95f3bbd5 100644 --- a/std/algorithm/sorting.d +++ b/std/algorithm/sorting.d @@ -895,7 +895,7 @@ if (ss == SwapStrategy.unstable && isRandomAccessRange!Range auto a = new int[](uniform(0, 100, r)); foreach (ref e; a) { - e = uniform(0, 50); + e = uniform(0, 50, r); } auto pieces = partition3(a, 25); assert(pieces[0].length + pieces[1].length + pieces[2].length == a.length); From 9465e4426989597eae982a84a2aa0639437932ca Mon Sep 17 00:00:00 2001 From: anonymous Date: Fri, 7 Jul 2017 22:57:57 +0200 Subject: [PATCH 092/163] show documentation for rounding modes and exceptions The doc comments were there but not actually attached to anything. Using version(StdDdoc) and lots of "ditto" to make them visible. --- std/math.d | 46 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 11 deletions(-) diff --git a/std/math.d b/std/math.d index 49d0e4ea0cc..ba6203a5f7b 100644 --- a/std/math.d +++ b/std/math.d @@ -4920,10 +4920,20 @@ struct FloatingPointControl { alias RoundingMode = uint; - /** IEEE rounding modes. - * The default mode is roundToNearest. - */ - version(ARM) + version(StdDdoc) + { + enum : RoundingMode + { + /** IEEE rounding modes. + * The default mode is roundToNearest. + */ + roundToNearest, + roundDown, /// ditto + roundUp, /// ditto + roundToZero /// ditto + } + } + else version(ARM) { enum : RoundingMode { @@ -4954,10 +4964,27 @@ struct FloatingPointControl } } - /** IEEE hardware exceptions. - * By default, all exceptions are masked (disabled). - */ - version(ARM) + version(StdDdoc) + { + enum : uint + { + /** IEEE hardware exceptions. + * By default, all exceptions are masked (disabled). + * + * severeExceptions = The overflow, division by zero, and invalid + * exceptions. + */ + subnormalException, + inexactException, /// ditto + underflowException, /// ditto + overflowException, /// ditto + divByZeroException, /// ditto + invalidException, /// ditto + severeExceptions, /// ditto + allExceptions, /// ditto + } + } + else version(ARM) { enum : uint { @@ -4967,7 +4994,6 @@ struct FloatingPointControl overflowException = 0x0400, divByZeroException = 0x0200, invalidException = 0x0100, - /// Severe = The overflow, division by zero, and invalid exceptions. severeExceptions = overflowException | divByZeroException | invalidException, allExceptions = severeExceptions | underflowException @@ -4983,7 +5009,6 @@ struct FloatingPointControl underflowException = 0x0020, overflowException = 0x0040, invalidException = 0x0080, - /// Severe = The overflow, division by zero, and invalid exceptions. severeExceptions = overflowException | divByZeroException | invalidException, allExceptions = severeExceptions | underflowException @@ -5000,7 +5025,6 @@ struct FloatingPointControl divByZeroException = 0x04, subnormalException = 0x02, invalidException = 0x01, - /// Severe = The overflow, division by zero, and invalid exceptions. severeExceptions = overflowException | divByZeroException | invalidException, allExceptions = severeExceptions | underflowException From c239ec55aeb7375686adf55a38db394175126d0f Mon Sep 17 00:00:00 2001 From: anonymous Date: Fri, 7 Jul 2017 23:06:41 +0200 Subject: [PATCH 093/163] show definition of RoundingMode in docs Because `rounding`'s signatures refer to it. --- std/math.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/std/math.d b/std/math.d index ba6203a5f7b..dc5c68dd11e 100644 --- a/std/math.d +++ b/std/math.d @@ -4918,7 +4918,7 @@ assert(rint(1.1) == 1); */ struct FloatingPointControl { - alias RoundingMode = uint; + alias RoundingMode = uint; /// version(StdDdoc) { From 979fa0357188247d7bde518620f06630c84d8ee1 Mon Sep 17 00:00:00 2001 From: anonymous Date: Fri, 7 Jul 2017 23:10:47 +0200 Subject: [PATCH 094/163] move `rounding` up to RoundingMode (for docs) Now rounding functionality comes first, and then exception functionality. Before, it was a back-and-forth between them. --- std/math.d | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/std/math.d b/std/math.d index dc5c68dd11e..a9ceef1f409 100644 --- a/std/math.d +++ b/std/math.d @@ -4964,6 +4964,19 @@ struct FloatingPointControl } } + //// Change the floating-point hardware rounding mode + @property void rounding(RoundingMode newMode) @nogc + { + initialize(); + setControlState((getControlState() & ~ROUNDING_MASK) | (newMode & ROUNDING_MASK)); + } + + /// Returns: the currently active rounding mode + @property static RoundingMode rounding() @nogc + { + return cast(RoundingMode)(getControlState() & ROUNDING_MASK); + } + version(StdDdoc) { enum : uint @@ -5100,13 +5113,6 @@ public: setControlState(getControlState() & ~(exceptions & EXCEPTION_MASK)); } - //// Change the floating-point hardware rounding mode - @property void rounding(RoundingMode newMode) @nogc - { - initialize(); - setControlState((getControlState() & ~ROUNDING_MASK) | (newMode & ROUNDING_MASK)); - } - /// Returns: the exceptions which are currently enabled (unmasked) @property static uint enabledExceptions() @nogc { @@ -5117,12 +5123,6 @@ public: return (getControlState() & EXCEPTION_MASK); } - /// Returns: the currently active rounding mode - @property static RoundingMode rounding() @nogc - { - return cast(RoundingMode)(getControlState() & ROUNDING_MASK); - } - /// Clear all pending exceptions, then restore the original exception state and rounding mode. ~this() @nogc { From a6dd9497174fbaf1631d7fad9e9cf2b6459f0a08 Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Sat, 8 Jul 2017 00:24:44 +0200 Subject: [PATCH 095/163] Unify needle overloads of std.algorithm.searching.find --- std/algorithm/searching.d | 390 +++++++++++++++++++------------------- 1 file changed, 192 insertions(+), 198 deletions(-) diff --git a/std/algorithm/searching.d b/std/algorithm/searching.d index cd67bdcf21d..5ea5f801c4d 100644 --- a/std/algorithm/searching.d +++ b/std/algorithm/searching.d @@ -1888,25 +1888,202 @@ such position exists, returns $(D haystack) advanced to termination). */ R1 find(alias pred = "a == b", R1, R2)(R1 haystack, scope R2 needle) if (isForwardRange!R1 && isForwardRange!R2 - && is(typeof(binaryFun!pred(haystack.front, needle.front)) : bool) - && !isRandomAccessRange!R1) + && is(typeof(binaryFun!pred(haystack.front, needle.front)) : bool)) { - static if (is(typeof(pred == "a == b")) && pred == "a == b" && isSomeString!R1 && isSomeString!R2 - && haystack[0].sizeof == needle[0].sizeof) + static if (!isRandomAccessRange!R1) { - // return cast(R1) find(representation(haystack), representation(needle)); - // Specialization for simple string search - alias Representation = - Select!(haystack[0].sizeof == 1, ubyte[], - Select!(haystack[0].sizeof == 2, ushort[], uint[])); - // Will use the array specialization - static TO force(TO, T)(T r) @trusted { return cast(TO) r; } - return force!R1(.find!(pred, Representation, Representation) - (force!Representation(haystack), force!Representation(needle))); + static if (is(typeof(pred == "a == b")) && pred == "a == b" && isSomeString!R1 && isSomeString!R2 + && haystack[0].sizeof == needle[0].sizeof) + { + // return cast(R1) find(representation(haystack), representation(needle)); + // Specialization for simple string search + alias Representation = + Select!(haystack[0].sizeof == 1, ubyte[], + Select!(haystack[0].sizeof == 2, ushort[], uint[])); + // Will use the array specialization + static TO force(TO, T)(T r) @trusted { return cast(TO) r; } + return force!R1(.find!(pred, Representation, Representation) + (force!Representation(haystack), force!Representation(needle))); + } + else + { + return simpleMindedFind!pred(haystack, needle); + } } - else + else static if (!isBidirectionalRange!R2 || !hasSlicing!R1) { - return simpleMindedFind!pred(haystack, needle); + static if (!is(ElementType!R1 == ElementType!R2)) + { + return simpleMindedFind!pred(haystack, needle); + } + else + { + // Prepare the search with needle's first element + if (needle.empty) + return haystack; + + haystack = .find!pred(haystack, needle.front); + + static if (hasLength!R1 && hasLength!R2 && is(typeof(takeNone(haystack)) == R1)) + { + if (needle.length > haystack.length) + return takeNone(haystack); + } + else + { + if (haystack.empty) + return haystack; + } + + needle.popFront(); + size_t matchLen = 1; + + // Loop invariant: haystack[0 .. matchLen] matches everything in + // the initial needle that was popped out of needle. + for (;;) + { + // Extend matchLength as much as possible + for (;;) + { + import std.range : takeNone; + + if (needle.empty || haystack.empty) + return haystack; + + static if (hasLength!R1 && is(typeof(takeNone(haystack)) == R1)) + { + if (matchLen == haystack.length) + return takeNone(haystack); + } + + if (!binaryFun!pred(haystack[matchLen], needle.front)) + break; + + ++matchLen; + needle.popFront(); + } + + auto bestMatch = haystack[0 .. matchLen]; + haystack.popFront(); + haystack = .find!pred(haystack, bestMatch); + } + } + } + else // static if (hasSlicing!R1 && isBidirectionalRange!R2) + { + if (needle.empty) return haystack; + + static if (hasLength!R2) + { + immutable needleLength = needle.length; + } + else + { + immutable needleLength = walkLength(needle.save); + } + if (needleLength > haystack.length) + { + return haystack[haystack.length .. haystack.length]; + } + // Optimization in case the ranges are both SortedRanges. + // Binary search can be used to find the first occurence + // of the first element of the needle in haystack. + // When it is found O(walklength(needle)) steps are performed. + // 8829 enhancement + import std.algorithm.comparison : mismatch; + import std.range : SortedRange; + static if (is(R1 == R2) + && is(R1 : SortedRange!TT, TT) + && pred == "a == b") + { + auto needleFirstElem = needle[0]; + auto partitions = haystack.trisect(needleFirstElem); + auto firstElemLen = partitions[1].length; + size_t count = 0; + + if (firstElemLen == 0) + return haystack[$ .. $]; + + while (needle.front() == needleFirstElem) + { + needle.popFront(); + ++count; + + if (count > firstElemLen) + return haystack[$ .. $]; + } + + auto m = mismatch(partitions[2], needle); + + if (m[1].empty) + return haystack[partitions[0].length + partitions[1].length - count .. $]; + } + else static if (isRandomAccessRange!R2) + { + immutable lastIndex = needleLength - 1; + auto last = needle[lastIndex]; + size_t j = lastIndex, skip = 0; + for (; j < haystack.length;) + { + if (!binaryFun!pred(haystack[j], last)) + { + ++j; + continue; + } + immutable k = j - lastIndex; + // last elements match + for (size_t i = 0;; ++i) + { + if (i == lastIndex) + return haystack[k .. haystack.length]; + if (!binaryFun!pred(haystack[k + i], needle[i])) + break; + } + if (skip == 0) + { + skip = 1; + while (skip < needleLength && needle[needleLength - 1 - skip] != needle[needleLength - 1]) + { + ++skip; + } + } + j += skip; + } + } + else + { + // @@@BUG@@@ + // auto needleBack = moveBack(needle); + // Stage 1: find the step + size_t step = 1; + auto needleBack = needle.back; + needle.popBack(); + for (auto i = needle.save; !i.empty && i.back != needleBack; + i.popBack(), ++step) + { + } + // Stage 2: linear find + size_t scout = needleLength - 1; + for (;;) + { + if (scout >= haystack.length) + break; + if (!binaryFun!pred(haystack[scout], needleBack)) + { + ++scout; + continue; + } + // Found a match with the last element in the needle + auto cand = haystack[scout + 1 - needleLength .. haystack.length]; + if (startsWith!pred(cand, needle)) + { + // found + return cand; + } + scout += step; + } + } + return haystack[haystack.length .. haystack.length]; } } @@ -1945,126 +2122,6 @@ if (isForwardRange!R1 && isForwardRange!R2 assert(equal(r, SList!int(2, 5, 7, 3)[])); } -/// ditto -R1 find(alias pred = "a == b", R1, R2)(R1 haystack, scope R2 needle) -if (isRandomAccessRange!R1 && hasLength!R1 && hasSlicing!R1 && isBidirectionalRange!R2 - && is(typeof(binaryFun!pred(haystack.front, needle.front)) : bool)) -{ - if (needle.empty) return haystack; - - static if (hasLength!R2) - { - immutable needleLength = needle.length; - } - else - { - immutable needleLength = walkLength(needle.save); - } - if (needleLength > haystack.length) - { - return haystack[haystack.length .. haystack.length]; - } - // Optimization in case the ranges are both SortedRanges. - // Binary search can be used to find the first occurence - // of the first element of the needle in haystack. - // When it is found O(walklength(needle)) steps are performed. - // 8829 enhancement - import std.algorithm.comparison : mismatch; - import std.range : SortedRange; - static if (is(R1 == R2) - && is(R1 : SortedRange!TT, TT) - && pred == "a == b") - { - auto needleFirstElem = needle[0]; - auto partitions = haystack.trisect(needleFirstElem); - auto firstElemLen = partitions[1].length; - size_t count = 0; - - if (firstElemLen == 0) - return haystack[$ .. $]; - - while (needle.front() == needleFirstElem) - { - needle.popFront(); - ++count; - - if (count > firstElemLen) - return haystack[$ .. $]; - } - - auto m = mismatch(partitions[2], needle); - - if (m[1].empty) - return haystack[partitions[0].length + partitions[1].length - count .. $]; - } - else static if (isRandomAccessRange!R2) - { - immutable lastIndex = needleLength - 1; - auto last = needle[lastIndex]; - size_t j = lastIndex, skip = 0; - for (; j < haystack.length;) - { - if (!binaryFun!pred(haystack[j], last)) - { - ++j; - continue; - } - immutable k = j - lastIndex; - // last elements match - for (size_t i = 0;; ++i) - { - if (i == lastIndex) - return haystack[k .. haystack.length]; - if (!binaryFun!pred(haystack[k + i], needle[i])) - break; - } - if (skip == 0) - { - skip = 1; - while (skip < needleLength && needle[needleLength - 1 - skip] != needle[needleLength - 1]) - { - ++skip; - } - } - j += skip; - } - } - else - { - // @@@BUG@@@ - // auto needleBack = moveBack(needle); - // Stage 1: find the step - size_t step = 1; - auto needleBack = needle.back; - needle.popBack(); - for (auto i = needle.save; !i.empty && i.back != needleBack; - i.popBack(), ++step) - { - } - // Stage 2: linear find - size_t scout = needleLength - 1; - for (;;) - { - if (scout >= haystack.length) - break; - if (!binaryFun!pred(haystack[scout], needleBack)) - { - ++scout; - continue; - } - // Found a match with the last element in the needle - auto cand = haystack[scout + 1 - needleLength .. haystack.length]; - if (startsWith!pred(cand, needle)) - { - // found - return cand; - } - scout += step; - } - } - return haystack[haystack.length .. haystack.length]; -} - @safe unittest { import std.range; @@ -2102,69 +2159,6 @@ if (isRandomAccessRange!R1 && hasLength!R1 && hasSlicing!R1 && isBidirectionalRa auto r = BiRange([1, 2, 3, 10, 11, 4]); } -/// ditto -R1 find(alias pred = "a == b", R1, R2)(R1 haystack, scope R2 needle) -if (isRandomAccessRange!R1 && isForwardRange!R2 && !isBidirectionalRange!R2 && - is(typeof(binaryFun!pred(haystack.front, needle.front)) : bool)) -{ - static if (!is(ElementType!R1 == ElementType!R2)) - { - return simpleMindedFind!pred(haystack, needle); - } - else - { - // Prepare the search with needle's first element - if (needle.empty) - return haystack; - - haystack = .find!pred(haystack, needle.front); - - static if (hasLength!R1 && hasLength!R2 && is(typeof(takeNone(haystack)) == R1)) - { - if (needle.length > haystack.length) - return takeNone(haystack); - } - else - { - if (haystack.empty) - return haystack; - } - - needle.popFront(); - size_t matchLen = 1; - - // Loop invariant: haystack[0 .. matchLen] matches everything in - // the initial needle that was popped out of needle. - for (;;) - { - // Extend matchLength as much as possible - for (;;) - { - import std.range : takeNone; - - if (needle.empty || haystack.empty) - return haystack; - - static if (hasLength!R1 && is(typeof(takeNone(haystack)) == R1)) - { - if (matchLen == haystack.length) - return takeNone(haystack); - } - - if (!binaryFun!pred(haystack[matchLen], needle.front)) - break; - - ++matchLen; - needle.popFront(); - } - - auto bestMatch = haystack[0 .. matchLen]; - haystack.popFront(); - haystack = .find!pred(haystack, bestMatch); - } - } -} - @safe unittest { import std.container : SList; From 97e9db7f02ea072acb1a3f1bd11e3a1f3fca193a Mon Sep 17 00:00:00 2001 From: Martin Nowak Date: Wed, 5 Jul 2017 21:09:49 +0200 Subject: [PATCH 096/163] throw specific HTTPStatusException on http request errors - To make them distinguishable from (e.g. connection) errors and allow appropriate handling in client code. --- std/net/curl.d | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/std/net/curl.d b/std/net/curl.d index 1e752416c8a..1ffa223ea74 100644 --- a/std/net/curl.d +++ b/std/net/curl.d @@ -1047,9 +1047,8 @@ private auto _basicHTTP(T)(const(char)[] url, const(void)[] sendData, HTTP clien }; client.onReceiveStatusLine = (HTTP.StatusLine l) { statusLine = l; }; client.perform(); - enforce!CurlException(statusLine.code / 100 == 2, - format("HTTP request returned status code %d (%s)", - statusLine.code, statusLine.reason)); + enforce(statusLine.code / 100 == 2, new HTTPStatusException(statusLine.code, + format("HTTP request returned status code %d (%s)", statusLine.code, statusLine.reason))); return _decodeContent!T(content.data, client.p.charset); } @@ -1063,8 +1062,9 @@ private auto _basicHTTP(T)(const(char)[] url, const(void)[] sendData, HTTP clien assert(req.hdrs.canFind("GET /path")); s.send(httpNotFound()); }); - auto e = collectException!CurlException(get(testServer.addr ~ "/path")); + auto e = collectException!HTTPStatusException(get(testServer.addr ~ "/path")); assert(e.msg == "HTTP request returned status code 404 (Not Found)"); + assert(e.status == 404); } // Bugzilla 14760 - content length must be reset after post @@ -4058,6 +4058,33 @@ class CurlTimeoutException : CurlException } } +/++ + Exception thrown on HTTP request failures, e.g. 404 Not Found. ++/ +class HTTPStatusException : CurlException +{ + /++ + Params: + status = The HTTP status code. + msg = The message for the exception. + file = The file where the exception occurred. + line = The line number where the exception occurred. + next = The previous exception in the chain of exceptions, if any. + +/ + @safe pure nothrow + this(int status, + string msg, + string file = __FILE__, + size_t line = __LINE__, + Throwable next = null) + { + super(msg, file, line, next); + this.status = status; + } + + immutable int status; /// The HTTP status code +} + /// Equal to $(REF CURLcode, etc,c,curl) alias CurlCode = CURLcode; From 1f7e59980539fe0f9ba352b258e8266db6bdff01 Mon Sep 17 00:00:00 2001 From: Martin Nowak Date: Sat, 8 Jul 2017 20:09:58 +0200 Subject: [PATCH 097/163] fix test coverage - use single tests as workaround for Issue 16397 - fix single tests (broken sed command) --- circleci.sh | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/circleci.sh b/circleci.sh index 1e34e45e22b..4c945abd8ce 100755 --- a/circleci.sh +++ b/circleci.sh @@ -110,12 +110,13 @@ coverage() # remove all existing coverage files (just in case) rm -rf $(find -name '*.lst') - # currently using the test_runner yields wrong code coverage results - # see https://github.com/dlang/phobos/pull/4719 for details - ENABLE_COVERAGE="1" make -f posix.mak MODEL=$MODEL unittest-debug + # Coverage information of the test runner can be missing for some template instatiations. + # https://issues.dlang.org/show_bug.cgi?id=16397 + # ENABLE_COVERAGE="1" make -f posix.mak MODEL=$MODEL unittest-debug - # instead we run all tests individually - make -f posix.mak $(find std etc -name "*.d" | sed "s/[.]d$/.test") + # So instead we run all tests individually (hoping that that doesn't break any tests). + # -cov is enabled by the %.test target itself + make -f posix.mak $(find std etc -name "*.d" | sed "s/[.]d$/.test/") # Remove coverage information from lines with non-deterministic coverage. # These lines are annotated with a comment containing "nocoverage". From f4672d51f90baa4df9527c078878db67eacd00d6 Mon Sep 17 00:00:00 2001 From: Martin Nowak Date: Sat, 8 Jul 2017 20:33:50 +0200 Subject: [PATCH 098/163] remove import of deprecated std.c.linux.linux - was only privately imported anyhow --- std/c/linux/pthread.d | 2 -- 1 file changed, 2 deletions(-) diff --git a/std/c/linux/pthread.d b/std/c/linux/pthread.d index 041bc570c26..bc8a1f3ae5b 100644 --- a/std/c/linux/pthread.d +++ b/std/c/linux/pthread.d @@ -14,6 +14,4 @@ deprecated("Import core.sys.posix.pthread or the appropriate core.sys.posix.* mo module std.c.linux.pthread; version (linux): -import std.c.linux.linux; - public import core.sys.posix.pthread; From 87587ce66195177b02e12b4f247c6d60057bb9a6 Mon Sep 17 00:00:00 2001 From: Martin Nowak Date: Sat, 8 Jul 2017 20:38:03 +0200 Subject: [PATCH 099/163] run coverage tests in parallel - merging is done with file locking by druntime --- circleci.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/circleci.sh b/circleci.sh index 4c945abd8ce..d2882804924 100755 --- a/circleci.sh +++ b/circleci.sh @@ -112,11 +112,11 @@ coverage() # Coverage information of the test runner can be missing for some template instatiations. # https://issues.dlang.org/show_bug.cgi?id=16397 - # ENABLE_COVERAGE="1" make -f posix.mak MODEL=$MODEL unittest-debug + # ENABLE_COVERAGE="1" make -j$N -f posix.mak MODEL=$MODEL unittest-debug # So instead we run all tests individually (hoping that that doesn't break any tests). # -cov is enabled by the %.test target itself - make -f posix.mak $(find std etc -name "*.d" | sed "s/[.]d$/.test/") + make -j$N -f posix.mak $(find std etc -name "*.d" | sed "s/[.]d$/.test/") # Remove coverage information from lines with non-deterministic coverage. # These lines are annotated with a comment containing "nocoverage". From 0503b9b4a55512335ce038a34aa57a137b76753d Mon Sep 17 00:00:00 2001 From: anonymous Date: Wed, 5 Jul 2017 23:25:53 +0200 Subject: [PATCH 100/163] add JSONOptions.doNotEscapeSlashes Fixes issue 17587 (enhancement request). --- std/json.d | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/std/json.d b/std/json.d index 0c436de9743..6b2915de482 100644 --- a/std/json.d +++ b/std/json.d @@ -75,7 +75,8 @@ enum JSONOptions { none, /// standard parsing specialFloatLiterals = 0x1, /// encode NaN and Inf float values as strings - escapeNonAsciiChars = 0x2 /// encode non ascii characters with an unicode escape sequence + escapeNonAsciiChars = 0x2, /// encode non ascii characters with an unicode escape sequence + doNotEscapeSlashes = 0x4, /// do not escape slashes ('/') } /** @@ -1153,7 +1154,13 @@ string toJSON(const ref JSONValue root, in bool pretty = false, in JSONOptions o { case '"': json.put("\\\""); break; case '\\': json.put("\\\\"); break; - case '/': json.put("\\/"); break; + + case '/': + if (!(options & JSONOptions.doNotEscapeSlashes)) + json.put('\\'); + json.put('/'); + break; + case '\b': json.put("\\b"); break; case '\f': json.put("\\f"); break; case '\n': json.put("\\n"); break; @@ -1842,3 +1849,11 @@ pure nothrow @safe unittest // issue 15884 assert(parseJSON("\"\xFF\"".byChar).str == "\xFF"); assert(parseJSON("\"\U0001D11E\"".byChar).str == "\U0001D11E"); } + +@safe unittest // JSONOptions.doNotEscapeSlashes (issue 17587) +{ + assert(parseJSON(`"/"`).toString == `"\/"`); + assert(parseJSON(`"\/"`).toString == `"\/"`); + assert(parseJSON(`"/"`).toString(JSONOptions.doNotEscapeSlashes) == `"/"`); + assert(parseJSON(`"\/"`).toString(JSONOptions.doNotEscapeSlashes) == `"/"`); +} From 59a32d50ac8245cf7424c204e76ecf38f8973155 Mon Sep 17 00:00:00 2001 From: anonymous Date: Sat, 8 Jul 2017 23:42:56 +0200 Subject: [PATCH 101/163] code formatting --- std/json.d | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/std/json.d b/std/json.d index 6b2915de482..fd6cf41968c 100644 --- a/std/json.d +++ b/std/json.d @@ -75,8 +75,8 @@ enum JSONOptions { none, /// standard parsing specialFloatLiterals = 0x1, /// encode NaN and Inf float values as strings - escapeNonAsciiChars = 0x2, /// encode non ascii characters with an unicode escape sequence - doNotEscapeSlashes = 0x4, /// do not escape slashes ('/') + escapeNonAsciiChars = 0x2, /// encode non ascii characters with an unicode escape sequence + doNotEscapeSlashes = 0x4, /// do not escape slashes ('/') } /** @@ -1156,10 +1156,10 @@ string toJSON(const ref JSONValue root, in bool pretty = false, in JSONOptions o case '\\': json.put("\\\\"); break; case '/': - if (!(options & JSONOptions.doNotEscapeSlashes)) - json.put('\\'); - json.put('/'); - break; + if (!(options & JSONOptions.doNotEscapeSlashes)) + json.put('\\'); + json.put('/'); + break; case '\b': json.put("\\b"); break; case '\f': json.put("\\f"); break; From 334642bbb6b3fc3beb89300d81a24ff824878c6b Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Sat, 8 Jul 2017 23:43:24 +0200 Subject: [PATCH 102/163] has_public_example: std.algorithm.comparison --- .dscanner.ini | 2 +- std/algorithm/comparison.d | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.dscanner.ini b/.dscanner.ini index 958d79981ae..2a6f88b0aec 100644 --- a/.dscanner.ini +++ b/.dscanner.ini @@ -120,7 +120,7 @@ exception_check="-std.concurrency,-std.net.curl,-std.parallelism,-std.range,-std ; Checks for poor placement of function attributes function_attribute_check="-std.algorithm.iteration,-std.concurrency,-std.conv,-std.datetime.interval,-std.exception,-std.functional,-std.net.curl,-std.numeric,-std.parallelism,-std.random,-std.range,-std.range.primitives,-std.socket,-std.traits,-std.typecons,-std.uni" ; Check for public declarations without a documented unittest -has_public_example="-etc.c.curl,-etc.c.sqlite3,-etc.c.zlib,-std.algorithm.comparison,-std.algorithm.mutation,-std.array,-std.ascii,-std.base64,-std.bitmanip,-std.complex,-std.concurrency,-std.container.array,-std.container.dlist,-std.container.rbtree,-std.container.slist,-std.conv,-std.csv,-std.datetime,-std.datetime.date,-std.datetime.interval,-std.datetime.stopwatch,-std.datetime.systime,-std.datetime.timezone,-std.demangle,-std.digest.digest,-std.digest.hmac,-std.digest.murmurhash,-std.digest.sha,-std.encoding,-std.exception,-std.experimental.allocator,-std.experimental.allocator.building_blocks.allocator_list,-std.experimental.allocator.building_blocks.bitmapped_block,-std.experimental.allocator.building_blocks.fallback_allocator,-std.experimental.allocator.building_blocks.free_list,-std.experimental.allocator.building_blocks.free_tree,-std.experimental.allocator.building_blocks.null_allocator,-std.experimental.allocator.building_blocks.stats_collector,-std.experimental.allocator.common,-std.experimental.allocator.mmap_allocator,-std.experimental.allocator.typed,-std.experimental.checkedint,-std.experimental.logger.core,-std.experimental.logger.filelogger,-std.experimental.logger.multilogger,-std.experimental.typecons,-std.file,-std.format,-std.getopt,-std.internal.math.biguintcore,-std.internal.math.biguintnoasm,-std.internal.math.errorfunction,-std.internal.math.gammafunction,-std.internal.scopebuffer,-std.internal.test.dummyrange,-std.json,-std.math,-std.mathspecial,-std.mmfile,-std.net.curl,-std.net.isemail,-std.numeric,-std.outbuffer,-std.parallelism,-std.path,-std.process,-std.random,-std.range,-std.range.interfaces,-std.range.primitives,-std.regex,-std.regex.internal.ir,-std.socket,-std.stdio,-std.string,-std.traits,-std.typecons,-std.uni,-std.uri,-std.utf,-std.uuid,-std.variant,-std.xml,-std.zip,-std.zlib" +has_public_example="-etc.c.curl,-etc.c.sqlite3,-etc.c.zlib,-std.algorithm.mutation,-std.array,-std.ascii,-std.base64,-std.bitmanip,-std.complex,-std.concurrency,-std.container.array,-std.container.dlist,-std.container.rbtree,-std.container.slist,-std.conv,-std.csv,-std.datetime,-std.datetime.date,-std.datetime.interval,-std.datetime.stopwatch,-std.datetime.systime,-std.datetime.timezone,-std.demangle,-std.digest.digest,-std.digest.hmac,-std.digest.murmurhash,-std.digest.sha,-std.encoding,-std.exception,-std.experimental.allocator,-std.experimental.allocator.building_blocks.allocator_list,-std.experimental.allocator.building_blocks.bitmapped_block,-std.experimental.allocator.building_blocks.fallback_allocator,-std.experimental.allocator.building_blocks.free_list,-std.experimental.allocator.building_blocks.free_tree,-std.experimental.allocator.building_blocks.null_allocator,-std.experimental.allocator.building_blocks.stats_collector,-std.experimental.allocator.common,-std.experimental.allocator.mmap_allocator,-std.experimental.allocator.typed,-std.experimental.checkedint,-std.experimental.logger.core,-std.experimental.logger.filelogger,-std.experimental.logger.multilogger,-std.experimental.typecons,-std.file,-std.format,-std.getopt,-std.internal.math.biguintcore,-std.internal.math.biguintnoasm,-std.internal.math.errorfunction,-std.internal.math.gammafunction,-std.internal.scopebuffer,-std.internal.test.dummyrange,-std.json,-std.math,-std.mathspecial,-std.mmfile,-std.net.curl,-std.net.isemail,-std.numeric,-std.outbuffer,-std.parallelism,-std.path,-std.process,-std.random,-std.range,-std.range.interfaces,-std.range.primitives,-std.regex,-std.regex.internal.ir,-std.socket,-std.stdio,-std.string,-std.traits,-std.typecons,-std.uni,-std.uri,-std.utf,-std.uuid,-std.variant,-std.xml,-std.zip,-std.zlib" ; Check for sortedness of imports imports_sortedness="+disabled" ;imports_sortedness="-etc.c.curl,-std.algorithm.comparison,-std.algorithm.internal,-std.algorithm.iteration,-std.algorithm.mutation,-std.algorithm.searching,-std.algorithm.setops,-std.algorithm.sorting,-std.array,-std.bigint,-std.bitmanip,-std.c.freebsd.socket,-std.c.linux.pthread,-std.c.process,-std.complex,-std.concurrency,-std.container.array,-std.container.binaryheap,-std.container.dlist,-std.container.rbtree,-std.container.slist,-std.container.util,-std.conv,-std.datetime,-std.datetime.date,-std.datetime.interval,-std.datetime.systime,-std.datetime.timezone,-std.digest.digest,-std.digest.hmac,-std.exception,-std.experimental.allocator,-std.experimental.allocator.building_blocks,-std.experimental.allocator.building_blocks.affix_allocator,-std.experimental.allocator.building_blocks.allocator_list,-std.experimental.allocator.building_blocks.free_list,-std.experimental.allocator.building_blocks.free_tree,-std.experimental.allocator.building_blocks.kernighan_ritchie,-std.experimental.allocator.building_blocks.region,-std.experimental.allocator.common,-std.experimental.allocator.mallocator,-std.experimental.allocator.mmap_allocator,-std.experimental.allocator.showcase,-std.experimental.allocator.typed,-std.experimental.checkedint,-std.experimental.logger.core,-std.experimental.typecons,-std.file,-std.format,-std.functional,-std.getopt,-std.internal.math.biguintcore,-std.internal.test.dummyrange,-std.json,-std.math,-std.meta,-std.mmfile,-std.net.curl,-std.net.isemail,-std.numeric,-std.outbuffer,-std.parallelism,-std.path,-std.process,-std.random,-std.range,-std.range.primitives,-std.regex,-std.regex.internal.backtracking,-std.regex.internal.generator,-std.regex.internal.kickstart,-std.regex.internal.parser,-std.regex.internal.tests,-std.signals,-std.socket,-std.stdio,-std.string,-std.uni,-std.utf,-std.uuid,-std.variant,-std.windows.charset,-std.windows.registry,-std.windows.syserror,-std.zip" diff --git a/std/algorithm/comparison.d b/std/algorithm/comparison.d index 566b686b16a..faa4d444fbd 100644 --- a/std/algorithm/comparison.d +++ b/std/algorithm/comparison.d @@ -1007,6 +1007,16 @@ enum EditOp : char remove = 'r' } +/// +@safe unittest +{ + with(EditOp) + { + assert(levenshteinDistanceAndPath("foo", "foobar")[1] == [none, none, none, insert, insert, insert]); + assert(levenshteinDistanceAndPath("banana", "fazan")[1] == [substitute, none, substitute, none, none, remove]); + } +} + private struct Levenshtein(Range, alias equals, CostType = size_t) { EditOp[] path() From 81801789866af7a7a1ac11c9e6ef7ebd27f86b8d Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Sat, 8 Jul 2017 23:44:00 +0200 Subject: [PATCH 103/163] has_public_example: std.algorithm.mutation --- .dscanner.ini | 2 +- std/algorithm/mutation.d | 30 ++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/.dscanner.ini b/.dscanner.ini index 2a6f88b0aec..4cd2682e543 100644 --- a/.dscanner.ini +++ b/.dscanner.ini @@ -120,7 +120,7 @@ exception_check="-std.concurrency,-std.net.curl,-std.parallelism,-std.range,-std ; Checks for poor placement of function attributes function_attribute_check="-std.algorithm.iteration,-std.concurrency,-std.conv,-std.datetime.interval,-std.exception,-std.functional,-std.net.curl,-std.numeric,-std.parallelism,-std.random,-std.range,-std.range.primitives,-std.socket,-std.traits,-std.typecons,-std.uni" ; Check for public declarations without a documented unittest -has_public_example="-etc.c.curl,-etc.c.sqlite3,-etc.c.zlib,-std.algorithm.mutation,-std.array,-std.ascii,-std.base64,-std.bitmanip,-std.complex,-std.concurrency,-std.container.array,-std.container.dlist,-std.container.rbtree,-std.container.slist,-std.conv,-std.csv,-std.datetime,-std.datetime.date,-std.datetime.interval,-std.datetime.stopwatch,-std.datetime.systime,-std.datetime.timezone,-std.demangle,-std.digest.digest,-std.digest.hmac,-std.digest.murmurhash,-std.digest.sha,-std.encoding,-std.exception,-std.experimental.allocator,-std.experimental.allocator.building_blocks.allocator_list,-std.experimental.allocator.building_blocks.bitmapped_block,-std.experimental.allocator.building_blocks.fallback_allocator,-std.experimental.allocator.building_blocks.free_list,-std.experimental.allocator.building_blocks.free_tree,-std.experimental.allocator.building_blocks.null_allocator,-std.experimental.allocator.building_blocks.stats_collector,-std.experimental.allocator.common,-std.experimental.allocator.mmap_allocator,-std.experimental.allocator.typed,-std.experimental.checkedint,-std.experimental.logger.core,-std.experimental.logger.filelogger,-std.experimental.logger.multilogger,-std.experimental.typecons,-std.file,-std.format,-std.getopt,-std.internal.math.biguintcore,-std.internal.math.biguintnoasm,-std.internal.math.errorfunction,-std.internal.math.gammafunction,-std.internal.scopebuffer,-std.internal.test.dummyrange,-std.json,-std.math,-std.mathspecial,-std.mmfile,-std.net.curl,-std.net.isemail,-std.numeric,-std.outbuffer,-std.parallelism,-std.path,-std.process,-std.random,-std.range,-std.range.interfaces,-std.range.primitives,-std.regex,-std.regex.internal.ir,-std.socket,-std.stdio,-std.string,-std.traits,-std.typecons,-std.uni,-std.uri,-std.utf,-std.uuid,-std.variant,-std.xml,-std.zip,-std.zlib" +has_public_example="-etc.c.curl,-etc.c.sqlite3,-etc.c.zlib,-std.array,-std.ascii,-std.base64,-std.bitmanip,-std.complex,-std.concurrency,-std.container.array,-std.container.dlist,-std.container.rbtree,-std.container.slist,-std.conv,-std.csv,-std.datetime,-std.datetime.date,-std.datetime.interval,-std.datetime.stopwatch,-std.datetime.systime,-std.datetime.timezone,-std.demangle,-std.digest.digest,-std.digest.hmac,-std.digest.murmurhash,-std.digest.sha,-std.encoding,-std.exception,-std.experimental.allocator,-std.experimental.allocator.building_blocks.allocator_list,-std.experimental.allocator.building_blocks.bitmapped_block,-std.experimental.allocator.building_blocks.fallback_allocator,-std.experimental.allocator.building_blocks.free_list,-std.experimental.allocator.building_blocks.free_tree,-std.experimental.allocator.building_blocks.null_allocator,-std.experimental.allocator.building_blocks.stats_collector,-std.experimental.allocator.common,-std.experimental.allocator.mmap_allocator,-std.experimental.allocator.typed,-std.experimental.checkedint,-std.experimental.logger.core,-std.experimental.logger.filelogger,-std.experimental.logger.multilogger,-std.experimental.typecons,-std.file,-std.format,-std.getopt,-std.internal.math.biguintcore,-std.internal.math.biguintnoasm,-std.internal.math.errorfunction,-std.internal.math.gammafunction,-std.internal.scopebuffer,-std.internal.test.dummyrange,-std.json,-std.math,-std.mathspecial,-std.mmfile,-std.net.curl,-std.net.isemail,-std.numeric,-std.outbuffer,-std.parallelism,-std.path,-std.process,-std.random,-std.range,-std.range.interfaces,-std.range.primitives,-std.regex,-std.regex.internal.ir,-std.socket,-std.stdio,-std.string,-std.traits,-std.typecons,-std.uni,-std.uri,-std.utf,-std.uuid,-std.variant,-std.xml,-std.zip,-std.zlib" ; Check for sortedness of imports imports_sortedness="+disabled" ;imports_sortedness="-etc.c.curl,-std.algorithm.comparison,-std.algorithm.internal,-std.algorithm.iteration,-std.algorithm.mutation,-std.algorithm.searching,-std.algorithm.setops,-std.algorithm.sorting,-std.array,-std.bigint,-std.bitmanip,-std.c.freebsd.socket,-std.c.linux.pthread,-std.c.process,-std.complex,-std.concurrency,-std.container.array,-std.container.binaryheap,-std.container.dlist,-std.container.rbtree,-std.container.slist,-std.container.util,-std.conv,-std.datetime,-std.datetime.date,-std.datetime.interval,-std.datetime.systime,-std.datetime.timezone,-std.digest.digest,-std.digest.hmac,-std.exception,-std.experimental.allocator,-std.experimental.allocator.building_blocks,-std.experimental.allocator.building_blocks.affix_allocator,-std.experimental.allocator.building_blocks.allocator_list,-std.experimental.allocator.building_blocks.free_list,-std.experimental.allocator.building_blocks.free_tree,-std.experimental.allocator.building_blocks.kernighan_ritchie,-std.experimental.allocator.building_blocks.region,-std.experimental.allocator.common,-std.experimental.allocator.mallocator,-std.experimental.allocator.mmap_allocator,-std.experimental.allocator.showcase,-std.experimental.allocator.typed,-std.experimental.checkedint,-std.experimental.logger.core,-std.experimental.typecons,-std.file,-std.format,-std.functional,-std.getopt,-std.internal.math.biguintcore,-std.internal.test.dummyrange,-std.json,-std.math,-std.meta,-std.mmfile,-std.net.curl,-std.net.isemail,-std.numeric,-std.outbuffer,-std.parallelism,-std.path,-std.process,-std.random,-std.range,-std.range.primitives,-std.regex,-std.regex.internal.backtracking,-std.regex.internal.generator,-std.regex.internal.kickstart,-std.regex.internal.parser,-std.regex.internal.tests,-std.signals,-std.socket,-std.stdio,-std.string,-std.uni,-std.utf,-std.uuid,-std.variant,-std.windows.charset,-std.windows.registry,-std.windows.syserror,-std.zip" diff --git a/std/algorithm/mutation.d b/std/algorithm/mutation.d index 1124cea4fa6..495afabb4ee 100644 --- a/std/algorithm/mutation.d +++ b/std/algorithm/mutation.d @@ -1659,6 +1659,36 @@ enum SwapStrategy stable, } +/// +@safe unittest +{ + import std.stdio; + import std.algorithm.sorting : partition; + int[] a = [0, 1, 2, 3]; + assert(remove!(SwapStrategy.stable)(a, 1) == [0, 2, 3]); + a = [0, 1, 2, 3]; + assert(remove!(SwapStrategy.unstable)(a, 1) == [0, 3, 2]); +} + +/// +@safe unittest +{ + import std.algorithm.sorting : partition; + + // Put stuff greater than 3 on the left + auto arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + assert(partition!(a => a > 3, SwapStrategy.stable)(arr) == [1, 2, 3]); + assert(arr == [4, 5, 6, 7, 8, 9, 10, 1, 2, 3]); + + arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + assert(partition!(a => a > 3, SwapStrategy.semistable)(arr) == [2, 3, 1]); + assert(arr == [4, 5, 6, 7, 8, 9, 10, 2, 3, 1]); + + arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + assert(partition!(a => a > 3, SwapStrategy.unstable)(arr) == [3, 2, 1]); + assert(arr == [10, 9, 8, 4, 5, 6, 7, 3, 2, 1]); +} + /** Eliminates elements at given offsets from `range` and returns the shortened range. From b2f88c3ea31ff82772f224819b6ad4698ce82f38 Mon Sep 17 00:00:00 2001 From: Jack Stouffer Date: Sat, 8 Jul 2017 23:05:49 -0400 Subject: [PATCH 104/163] Removed old debug printfs --- std/utf.d | 8 -------- 1 file changed, 8 deletions(-) diff --git a/std/utf.d b/std/utf.d index 339243cfcef..4f4344ba295 100644 --- a/std/utf.d +++ b/std/utf.d @@ -65,10 +65,6 @@ import std.range.primitives; import std.traits; // isSomeChar, isSomeString import std.typecons; // Flag, Yes, No -//debug=utf; // uncomment to turn on debugging printf's - -debug (utf) import core.stdc.stdio : printf; - /++ Exception thrown on errors in std.utf functions. @@ -259,7 +255,6 @@ bool isValidDchar(dchar c) pure nothrow @safe @nogc pure nothrow @safe @nogc unittest { import std.exception; - debug(utf) printf("utf.isValidDchar.unittest\n"); assertCTFEable!( { @@ -1895,7 +1890,6 @@ version(unittest) private void testBadDecodeBack(R)(R range, size_t line = __LIN { import std.conv : to; import std.exception; - debug(utf) printf("utf.decode.unittest\n"); assertCTFEable!( { @@ -2371,7 +2365,6 @@ void encode(UseReplacementDchar useReplacementDchar = No.useReplacementDchar)( @safe unittest { import std.exception; - debug(utf) printf("utf.encode.unittest\n"); assertCTFEable!( { @@ -3118,7 +3111,6 @@ if (isSomeChar!C) @safe pure unittest { import std.exception; - debug(utf) printf("utf.toUTF.unittest\n"); assertCTFEable!( { From 60b32e78e6fff7f718cd1de8082fece36025731d Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Sun, 9 Jul 2017 01:20:30 +0200 Subject: [PATCH 105/163] Make dependencies of tests_extrator order-only --- posix.mak | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/posix.mak b/posix.mak index fee516c259d..ce5a59ffce4 100644 --- a/posix.mak +++ b/posix.mak @@ -591,7 +591,7 @@ style_lint: dscanner $(LIB) ################################################################################ publictests: $(PUBLICTESTS) -$(TESTS_EXTRACTOR): $(TOOLS_DIR)/tests_extractor.d $(LIB) +$(TESTS_EXTRACTOR): $(TOOLS_DIR)/tests_extractor.d | $(LIB) DFLAGS="$(DFLAGS) $(LIB) -defaultlib= -debuglib= $(LINKDL)" $(DUB) build --force --compiler=$${PWD}/$(DMD) --single $< mv $(TOOLS_DIR)/tests_extractor $@ From 2c281e38e48b4fb9b4787bf904f9e623e8604dcf Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Sun, 9 Jul 2017 01:15:48 +0200 Subject: [PATCH 106/163] Make std.uuid examples runnable --- posix.mak | 2 +- std/uuid.d | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/posix.mak b/posix.mak index ce5a59ffce4..249e48e6906 100644 --- a/posix.mak +++ b/posix.mak @@ -265,7 +265,7 @@ IGNORED_PUBLICTESTS= $(addprefix std/, \ base64 $(addprefix experimental/allocator/, \ building_blocks/free_list building_blocks/quantizer \ ) digest/hmac \ - file math stdio traits typecons uuid) + file math stdio traits typecons) PUBLICTESTS= $(addsuffix .publictests,$(filter-out $(IGNORED_PUBLICTESTS), $(D_MODULES))) TESTS_EXTRACTOR=$(ROOT)/tests_extractor PUBLICTESTS_DIR=$(ROOT)/publictests diff --git a/std/uuid.d b/std/uuid.d index a2db742c4bb..c804e8eb7e8 100644 --- a/std/uuid.d +++ b/std/uuid.d @@ -1710,6 +1710,18 @@ public class UUIDParsingException : Exception } /// +@safe unittest +{ + import std.exception : collectException; + + const inputUUID = "this-is-an-invalid-uuid"; + auto ex = collectException!UUIDParsingException(UUID(inputUUID)); + assert(ex !is null); // check that exception was thrown + assert(ex.input == inputUUID); + assert(ex.position == 0); + assert(ex.reason == UUIDParsingException.Reason.tooLittle); +} + @safe unittest { auto ex = new UUIDParsingException("foo", 10, UUIDParsingException.Reason.tooMuch); From 28b521b7009683ffeca85415cd21c9405e794e90 Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Sun, 9 Jul 2017 01:20:08 +0200 Subject: [PATCH 107/163] Make std.typecons examples runnable --- posix.mak | 2 +- std/typecons.d | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/posix.mak b/posix.mak index 249e48e6906..077af17c6c6 100644 --- a/posix.mak +++ b/posix.mak @@ -265,7 +265,7 @@ IGNORED_PUBLICTESTS= $(addprefix std/, \ base64 $(addprefix experimental/allocator/, \ building_blocks/free_list building_blocks/quantizer \ ) digest/hmac \ - file math stdio traits typecons) + file math stdio traits) PUBLICTESTS= $(addsuffix .publictests,$(filter-out $(IGNORED_PUBLICTESTS), $(D_MODULES))) TESTS_EXTRACTOR=$(ROOT)/tests_extractor PUBLICTESTS_DIR=$(ROOT)/publictests diff --git a/std/typecons.d b/std/typecons.d index d1ad5edcfe9..57638b0cc95 100644 --- a/std/typecons.d +++ b/std/typecons.d @@ -4706,6 +4706,7 @@ if (!isMutable!Target) /// @system unittest { + import std.traits : FunctionAttribute, functionAttributes; interface A { int run(); } interface B { int stop(); @property int status(); } class X @@ -7329,6 +7330,8 @@ public: /// BitFlags can be manipulated with the usual operators @safe @nogc pure nothrow unittest { + import std.traits : EnumMembers; + // You can use such an enum with BitFlags straight away enum Enum { From 283cab2f205c59557ec5d21ad440feca902aac3d Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Sun, 9 Jul 2017 01:31:32 +0200 Subject: [PATCH 108/163] Make std.base64 examples runnable --- posix.mak | 2 +- std/base64.d | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/posix.mak b/posix.mak index 077af17c6c6..dd089a5dd38 100644 --- a/posix.mak +++ b/posix.mak @@ -262,7 +262,7 @@ SHARED=$(if $(findstring $(OS),linux freebsd),1,) # A blacklist of ignored module is provided as not all public unittest in # Phobos are independently runnable yet IGNORED_PUBLICTESTS= $(addprefix std/, \ - base64 $(addprefix experimental/allocator/, \ + $(addprefix experimental/allocator/, \ building_blocks/free_list building_blocks/quantizer \ ) digest/hmac \ file math stdio traits) diff --git a/std/base64.d b/std/base64.d index 59c941e27b4..28b796c3279 100644 --- a/std/base64.d +++ b/std/base64.d @@ -178,7 +178,7 @@ template Base64Impl(char Map62th, char Map63th, char Padding = '=') ubyte[] data = [0x1a, 0x2b, 0x3c, 0x4d, 0x5d, 0x6e]; // Allocate a buffer large enough to hold the encoded string. - auto buf = new char[encodeLength(data.length)]; + auto buf = new char[Base64.encodeLength(data.length)]; Base64.encode(data, buf); assert(buf == "Gis8TV1u"); From cf7766c1a924c1e23b18ae4b4c0c0968baa6a112 Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Sun, 9 Jul 2017 01:33:06 +0200 Subject: [PATCH 109/163] Make std.file examples runnable --- posix.mak | 2 +- std/file.d | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/posix.mak b/posix.mak index dd089a5dd38..c624f34e24c 100644 --- a/posix.mak +++ b/posix.mak @@ -265,7 +265,7 @@ IGNORED_PUBLICTESTS= $(addprefix std/, \ $(addprefix experimental/allocator/, \ building_blocks/free_list building_blocks/quantizer \ ) digest/hmac \ - file math stdio traits) + math stdio traits) PUBLICTESTS= $(addsuffix .publictests,$(filter-out $(IGNORED_PUBLICTESTS), $(D_MODULES))) TESTS_EXTRACTOR=$(ROOT)/tests_extractor PUBLICTESTS_DIR=$(ROOT)/publictests diff --git a/std/file.d b/std/file.d index 7a6edb48159..f34e3161a7c 100644 --- a/std/file.d +++ b/std/file.d @@ -4232,6 +4232,8 @@ slurp(Types...)(string filename, in char[] format) /// @system unittest { + import std.typecons : tuple; + scope(exit) { assert(exists(deleteme)); From 5c31dd26ed289b397a4bad32ac29af6e77247ef7 Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Sun, 9 Jul 2017 17:59:59 +0200 Subject: [PATCH 110/163] Issue 15750 - remove substr from std.net.isemail --- std/net/isemail.d | 100 ++-------------------------------------------- 1 file changed, 4 insertions(+), 96 deletions(-) diff --git a/std/net/isemail.d b/std/net/isemail.d index d37093db375..cd6aa419701 100644 --- a/std/net/isemail.d +++ b/std/net/isemail.d @@ -405,7 +405,7 @@ if (isSomeChar!(Char)) index = addressLiteral.lastIndexOf(matchesIp.front); if (index != 0) - addressLiteral = addressLiteral.substr(0, index) ~ "0:0"; + addressLiteral = addressLiteral[0 .. index] ~ "0:0"; } if (index == 0) @@ -416,7 +416,7 @@ if (isSomeChar!(Char)) else { - auto ipV6 = addressLiteral.substr(5); + auto ipV6 = addressLiteral[5 .. $]; matchesIp = ipV6.split(Token.colon); immutable groupCount = matchesIp.length; index = ipV6.indexOf(Token.doubleColon); @@ -445,10 +445,10 @@ if (isSomeChar!(Char)) } } - if (ipV6.substr(0, 1) == Token.colon && ipV6.substr(1, 1) != Token.colon) + if (ipV6[0 .. 1] == Token.colon && ipV6[1 .. 2] != Token.colon) returnStatus ~= EmailStatusCode.rfc5322IpV6ColonStart; - else if (ipV6.substr(-1) == Token.colon && ipV6.substr(-2, -1) != Token.colon) + else if (ipV6[$ - 1 .. $] == Token.colon && ipV6[$ - 2 .. $ - 1] != Token.colon) returnStatus ~= EmailStatusCode.rfc5322IpV6ColonEnd; else if (!matchesIp @@ -1768,98 +1768,6 @@ enum AsciiToken delete_ = 127 } -/* - * Returns the portion of string specified by the $(D_PARAM start) and - * $(D_PARAM length) parameters. - * - * Params: - * str = the input string. Must be one character or longer. - * start = if $(D_PARAM start) is non-negative, the returned string will start at the - * $(D_PARAM start)'th position in $(D_PARAM str), counting from zero. - * For instance, in the string "abcdef", the character at position 0 is 'a', - * the character at position 2 is 'c', and so forth. - * - * If $(D_PARAM start) is negative, the returned string will start at the - * $(D_PARAM start)'th character from the end of $(D_PARAM str). - * - * If $(D_PARAM str) is less than or equal to $(D_PARAM start) characters long, - * $(D_KEYWORD true) will be returned. - * - * length = if $(D_PARAM length) is given and is positive, the string returned will - * contain at most $(D_PARAM length) characters beginning from $(D_PARAM start) - * (depending on the length of string). - * - * If $(D_PARAM length) is given and is negative, then that many characters - * will be omitted from the end of string (after the start position has been - * calculated when a $(D_PARAM start) is negative). If $(D_PARAM start) - * denotes the position of this truncation or beyond, $(D_KEYWORD false) - * will be returned. - * - * If $(D_PARAM length) is given and is 0, an empty string will be returned. - * - * If $(D_PARAM length) is omitted, the substring starting from $(D_PARAM start) - * until the end of the string will be returned. - * - * Returns: the extracted part of string, or an empty string. - */ -T[] substr (T) (T[] str, ptrdiff_t start = 0, ptrdiff_t length = ptrdiff_t.min) -{ - ptrdiff_t end = length; - - if (start < 0) - { - start = str.length + start; - - if (end < 0) - { - if (end == ptrdiff_t.min) - end = 0; - - end = str.length + end; - } - - else - end = start + end; - } - - else - { - if (end == ptrdiff_t.min) - end = str.length; - - if (end < 0) - end = str.length + end; - - else - end = start + end; - } - - if (start > end) - end = start; - - if (end > str.length) - end = str.length; - - return str[start .. end]; -} - -@safe unittest -{ - assert("abcdef".substr(-1) == "f"); - assert("abcdef".substr(-2) == "ef"); - assert("abcdef".substr(-3, 1) == "d"); -} - -@safe unittest -{ - assert("abcdef".substr(0, -1) == "abcde"); - assert("abcdef".substr(2, -1) == "cde"); - assert("abcdef".substr(4, -4) == []); - assert("abcdef".substr(-3, -1) == "de"); - assert("abcdef".substr(1, 1) == "b"); - assert("abcdef".substr(-1, -1) == []); -} - /* * Compare the two given strings lexicographically. An upper limit of the number of * characters, that will be used in the comparison, can be specified. Supports both From b6512b94f4a689e1f1e5198cc8e340752892accc Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Sat, 8 Jul 2017 23:53:50 +0200 Subject: [PATCH 111/163] has_public_example: std.array --- .dscanner.ini | 2 +- std/array.d | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 88 insertions(+), 2 deletions(-) diff --git a/.dscanner.ini b/.dscanner.ini index 4cd2682e543..f2c68a8d52d 100644 --- a/.dscanner.ini +++ b/.dscanner.ini @@ -120,7 +120,7 @@ exception_check="-std.concurrency,-std.net.curl,-std.parallelism,-std.range,-std ; Checks for poor placement of function attributes function_attribute_check="-std.algorithm.iteration,-std.concurrency,-std.conv,-std.datetime.interval,-std.exception,-std.functional,-std.net.curl,-std.numeric,-std.parallelism,-std.random,-std.range,-std.range.primitives,-std.socket,-std.traits,-std.typecons,-std.uni" ; Check for public declarations without a documented unittest -has_public_example="-etc.c.curl,-etc.c.sqlite3,-etc.c.zlib,-std.array,-std.ascii,-std.base64,-std.bitmanip,-std.complex,-std.concurrency,-std.container.array,-std.container.dlist,-std.container.rbtree,-std.container.slist,-std.conv,-std.csv,-std.datetime,-std.datetime.date,-std.datetime.interval,-std.datetime.stopwatch,-std.datetime.systime,-std.datetime.timezone,-std.demangle,-std.digest.digest,-std.digest.hmac,-std.digest.murmurhash,-std.digest.sha,-std.encoding,-std.exception,-std.experimental.allocator,-std.experimental.allocator.building_blocks.allocator_list,-std.experimental.allocator.building_blocks.bitmapped_block,-std.experimental.allocator.building_blocks.fallback_allocator,-std.experimental.allocator.building_blocks.free_list,-std.experimental.allocator.building_blocks.free_tree,-std.experimental.allocator.building_blocks.null_allocator,-std.experimental.allocator.building_blocks.stats_collector,-std.experimental.allocator.common,-std.experimental.allocator.mmap_allocator,-std.experimental.allocator.typed,-std.experimental.checkedint,-std.experimental.logger.core,-std.experimental.logger.filelogger,-std.experimental.logger.multilogger,-std.experimental.typecons,-std.file,-std.format,-std.getopt,-std.internal.math.biguintcore,-std.internal.math.biguintnoasm,-std.internal.math.errorfunction,-std.internal.math.gammafunction,-std.internal.scopebuffer,-std.internal.test.dummyrange,-std.json,-std.math,-std.mathspecial,-std.mmfile,-std.net.curl,-std.net.isemail,-std.numeric,-std.outbuffer,-std.parallelism,-std.path,-std.process,-std.random,-std.range,-std.range.interfaces,-std.range.primitives,-std.regex,-std.regex.internal.ir,-std.socket,-std.stdio,-std.string,-std.traits,-std.typecons,-std.uni,-std.uri,-std.utf,-std.uuid,-std.variant,-std.xml,-std.zip,-std.zlib" +has_public_example="-etc.c.curl,-etc.c.sqlite3,-etc.c.zlib,-std.ascii,-std.base64,-std.bitmanip,-std.complex,-std.concurrency,-std.container.array,-std.container.dlist,-std.container.rbtree,-std.container.slist,-std.conv,-std.csv,-std.datetime,-std.datetime.date,-std.datetime.interval,-std.datetime.stopwatch,-std.datetime.systime,-std.datetime.timezone,-std.demangle,-std.digest.digest,-std.digest.hmac,-std.digest.murmurhash,-std.digest.sha,-std.encoding,-std.exception,-std.experimental.allocator,-std.experimental.allocator.building_blocks.allocator_list,-std.experimental.allocator.building_blocks.bitmapped_block,-std.experimental.allocator.building_blocks.fallback_allocator,-std.experimental.allocator.building_blocks.free_list,-std.experimental.allocator.building_blocks.free_tree,-std.experimental.allocator.building_blocks.null_allocator,-std.experimental.allocator.building_blocks.stats_collector,-std.experimental.allocator.common,-std.experimental.allocator.mmap_allocator,-std.experimental.allocator.typed,-std.experimental.checkedint,-std.experimental.logger.core,-std.experimental.logger.filelogger,-std.experimental.logger.multilogger,-std.experimental.typecons,-std.file,-std.format,-std.getopt,-std.internal.math.biguintcore,-std.internal.math.biguintnoasm,-std.internal.math.errorfunction,-std.internal.math.gammafunction,-std.internal.scopebuffer,-std.internal.test.dummyrange,-std.json,-std.math,-std.mathspecial,-std.mmfile,-std.net.curl,-std.net.isemail,-std.numeric,-std.outbuffer,-std.parallelism,-std.path,-std.process,-std.random,-std.range,-std.range.interfaces,-std.range.primitives,-std.regex,-std.regex.internal.ir,-std.socket,-std.stdio,-std.string,-std.traits,-std.typecons,-std.uni,-std.uri,-std.utf,-std.uuid,-std.variant,-std.xml,-std.zip,-std.zlib" ; Check for sortedness of imports imports_sortedness="+disabled" ;imports_sortedness="-etc.c.curl,-std.algorithm.comparison,-std.algorithm.internal,-std.algorithm.iteration,-std.algorithm.mutation,-std.algorithm.searching,-std.algorithm.setops,-std.algorithm.sorting,-std.array,-std.bigint,-std.bitmanip,-std.c.freebsd.socket,-std.c.linux.pthread,-std.c.process,-std.complex,-std.concurrency,-std.container.array,-std.container.binaryheap,-std.container.dlist,-std.container.rbtree,-std.container.slist,-std.container.util,-std.conv,-std.datetime,-std.datetime.date,-std.datetime.interval,-std.datetime.systime,-std.datetime.timezone,-std.digest.digest,-std.digest.hmac,-std.exception,-std.experimental.allocator,-std.experimental.allocator.building_blocks,-std.experimental.allocator.building_blocks.affix_allocator,-std.experimental.allocator.building_blocks.allocator_list,-std.experimental.allocator.building_blocks.free_list,-std.experimental.allocator.building_blocks.free_tree,-std.experimental.allocator.building_blocks.kernighan_ritchie,-std.experimental.allocator.building_blocks.region,-std.experimental.allocator.common,-std.experimental.allocator.mallocator,-std.experimental.allocator.mmap_allocator,-std.experimental.allocator.showcase,-std.experimental.allocator.typed,-std.experimental.checkedint,-std.experimental.logger.core,-std.experimental.typecons,-std.file,-std.format,-std.functional,-std.getopt,-std.internal.math.biguintcore,-std.internal.test.dummyrange,-std.json,-std.math,-std.meta,-std.mmfile,-std.net.curl,-std.net.isemail,-std.numeric,-std.outbuffer,-std.parallelism,-std.path,-std.process,-std.random,-std.range,-std.range.primitives,-std.regex,-std.regex.internal.backtracking,-std.regex.internal.generator,-std.regex.internal.kickstart,-std.regex.internal.parser,-std.regex.internal.tests,-std.signals,-std.socket,-std.stdio,-std.string,-std.uni,-std.utf,-std.uuid,-std.variant,-std.windows.charset,-std.windows.registry,-std.windows.syserror,-std.zip" diff --git a/std/array.d b/std/array.d index 33b731782d2..3b22cd32737 100644 --- a/std/array.d +++ b/std/array.d @@ -212,6 +212,18 @@ if (isNarrowString!String) return cast(typeof(return)) str.toUTF32; } +/// +@safe unittest +{ + import std.range.primitives : isRandomAccessRange; + + assert("Hello D".array == "Hello D"d); + static assert(isRandomAccessRange!string == false); + + assert("Hello D"w.array == "Hello D"d); + static assert(isRandomAccessRange!dstring == true); +} + @system unittest { // @system due to array!string @@ -534,7 +546,7 @@ if (isDynamicArray!T && allSatisfy!(isIntegral, I) && hasIndirections!(ElementEn return arrayAllocImpl!(false, T, ST)(sizes); } -/// +/// ditto auto uninitializedArray(T, I...)(I sizes) nothrow @trusted if (isDynamicArray!T && allSatisfy!(isIntegral, I) && !hasIndirections!(ElementEncodingType!T)) { @@ -588,6 +600,18 @@ if (isDynamicArray!T && allSatisfy!(isIntegral, I)) return arrayAllocImpl!(true, T, ST)(sizes); } +/// +@safe pure nothrow unittest +{ + import std.algorithm.comparison : equal; + import std.range : repeat; + + auto arr = minimallyInitializedArray!(int[])(42); + assert(arr.length == 42); + // Elements aren't necessarily initialized to 0 + assert(!arr.equal(0.repeat(42))); +} + @safe pure nothrow unittest { cast(void) minimallyInitializedArray!(int[][][][][])(); @@ -1535,6 +1559,15 @@ if (isForwardRange!Range && is(typeof(unaryFun!isTerminator(range.front)))) return range.splitter!isTerminator.array; } +/// +@safe unittest +{ + import std.uni : isWhite; + assert("Learning,D,is,fun".split(",") == ["Learning", "D", "is", "fun"]); + assert("Learning D is fun".split!isWhite == ["Learning", "D", "is", "fun"]); + assert("Learning D is fun".split(" D ") == ["Learning", "is fun"]); +} + @safe unittest { import std.algorithm.comparison : cmp; @@ -3212,6 +3245,23 @@ if (isDynamicArray!A) } } +/// +@system pure nothrow +unittest +{ + int[] a = [1, 2]; + auto app2 = appender(&a); + assert(app2.data == [1, 2]); + assert(a == [1, 2]); + app2 ~= 3; + app2 ~= [4, 5, 6]; + assert(app2.data == [1, 2, 3, 4, 5, 6]); + assert(a == [1, 2, 3, 4, 5, 6]); + + app2.reserve(5); + assert(app2.capacity >= 5); +} + /++ Convenience function that returns an $(LREF Appender) instance, optionally initialized with $(D array). @@ -3334,6 +3384,25 @@ Appender!(E[]) appender(A : E[], E)(auto ref A array) }); } +/// +@safe pure nothrow +unittest +{ + auto w = appender!string; + // pre-allocate space for at least 10 elements (this avoids costly reallocations) + w.reserve(10); + assert(w.capacity >= 10); + + w.put('a'); // single elements + w.put("bc"); // multiple elements + + // use the append syntax + w ~= 'd'; + w ~= "ef"; + + assert(w.data == "abcdef"); +} + @safe pure nothrow unittest { { @@ -3597,6 +3666,23 @@ RefAppender!(E[]) appender(P : E[]*, E)(P arrayPtr) return RefAppender!(E[])(arrayPtr); } +/// +@system pure nothrow +unittest +{ + int[] a = [1, 2]; + auto app2 = appender(&a); + assert(app2.data == [1, 2]); + assert(a == [1, 2]); + app2 ~= 3; + app2 ~= [4, 5, 6]; + assert(app2.data == [1, 2, 3, 4, 5, 6]); + assert(a == [1, 2, 3, 4, 5, 6]); + + app2.reserve(5); + assert(app2.capacity >= 5); +} + @system unittest { import std.exception; From cc80b5715fea22eec8692ca4d1aa6d965417963e Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Sun, 9 Jul 2017 00:41:35 +0200 Subject: [PATCH 112/163] has_public_example: std.ascii --- .dscanner.ini | 2 +- std/ascii.d | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/.dscanner.ini b/.dscanner.ini index f2c68a8d52d..4fa89fbc497 100644 --- a/.dscanner.ini +++ b/.dscanner.ini @@ -120,7 +120,7 @@ exception_check="-std.concurrency,-std.net.curl,-std.parallelism,-std.range,-std ; Checks for poor placement of function attributes function_attribute_check="-std.algorithm.iteration,-std.concurrency,-std.conv,-std.datetime.interval,-std.exception,-std.functional,-std.net.curl,-std.numeric,-std.parallelism,-std.random,-std.range,-std.range.primitives,-std.socket,-std.traits,-std.typecons,-std.uni" ; Check for public declarations without a documented unittest -has_public_example="-etc.c.curl,-etc.c.sqlite3,-etc.c.zlib,-std.ascii,-std.base64,-std.bitmanip,-std.complex,-std.concurrency,-std.container.array,-std.container.dlist,-std.container.rbtree,-std.container.slist,-std.conv,-std.csv,-std.datetime,-std.datetime.date,-std.datetime.interval,-std.datetime.stopwatch,-std.datetime.systime,-std.datetime.timezone,-std.demangle,-std.digest.digest,-std.digest.hmac,-std.digest.murmurhash,-std.digest.sha,-std.encoding,-std.exception,-std.experimental.allocator,-std.experimental.allocator.building_blocks.allocator_list,-std.experimental.allocator.building_blocks.bitmapped_block,-std.experimental.allocator.building_blocks.fallback_allocator,-std.experimental.allocator.building_blocks.free_list,-std.experimental.allocator.building_blocks.free_tree,-std.experimental.allocator.building_blocks.null_allocator,-std.experimental.allocator.building_blocks.stats_collector,-std.experimental.allocator.common,-std.experimental.allocator.mmap_allocator,-std.experimental.allocator.typed,-std.experimental.checkedint,-std.experimental.logger.core,-std.experimental.logger.filelogger,-std.experimental.logger.multilogger,-std.experimental.typecons,-std.file,-std.format,-std.getopt,-std.internal.math.biguintcore,-std.internal.math.biguintnoasm,-std.internal.math.errorfunction,-std.internal.math.gammafunction,-std.internal.scopebuffer,-std.internal.test.dummyrange,-std.json,-std.math,-std.mathspecial,-std.mmfile,-std.net.curl,-std.net.isemail,-std.numeric,-std.outbuffer,-std.parallelism,-std.path,-std.process,-std.random,-std.range,-std.range.interfaces,-std.range.primitives,-std.regex,-std.regex.internal.ir,-std.socket,-std.stdio,-std.string,-std.traits,-std.typecons,-std.uni,-std.uri,-std.utf,-std.uuid,-std.variant,-std.xml,-std.zip,-std.zlib" +has_public_example="-etc.c.curl,-etc.c.sqlite3,-etc.c.zlib,-std.base64,-std.bitmanip,-std.complex,-std.concurrency,-std.container.array,-std.container.dlist,-std.container.rbtree,-std.container.slist,-std.conv,-std.csv,-std.datetime,-std.datetime.date,-std.datetime.interval,-std.datetime.stopwatch,-std.datetime.systime,-std.datetime.timezone,-std.demangle,-std.digest.digest,-std.digest.hmac,-std.digest.murmurhash,-std.digest.sha,-std.encoding,-std.exception,-std.experimental.allocator,-std.experimental.allocator.building_blocks.allocator_list,-std.experimental.allocator.building_blocks.bitmapped_block,-std.experimental.allocator.building_blocks.fallback_allocator,-std.experimental.allocator.building_blocks.free_list,-std.experimental.allocator.building_blocks.free_tree,-std.experimental.allocator.building_blocks.null_allocator,-std.experimental.allocator.building_blocks.stats_collector,-std.experimental.allocator.common,-std.experimental.allocator.mmap_allocator,-std.experimental.allocator.typed,-std.experimental.checkedint,-std.experimental.logger.core,-std.experimental.logger.filelogger,-std.experimental.logger.multilogger,-std.experimental.typecons,-std.file,-std.format,-std.getopt,-std.internal.math.biguintcore,-std.internal.math.biguintnoasm,-std.internal.math.errorfunction,-std.internal.math.gammafunction,-std.internal.scopebuffer,-std.internal.test.dummyrange,-std.json,-std.math,-std.mathspecial,-std.mmfile,-std.net.curl,-std.net.isemail,-std.numeric,-std.outbuffer,-std.parallelism,-std.path,-std.process,-std.random,-std.range,-std.range.interfaces,-std.range.primitives,-std.regex,-std.regex.internal.ir,-std.socket,-std.stdio,-std.string,-std.traits,-std.typecons,-std.uni,-std.uri,-std.utf,-std.uuid,-std.variant,-std.xml,-std.zip,-std.zlib" ; Check for sortedness of imports imports_sortedness="+disabled" ;imports_sortedness="-etc.c.curl,-std.algorithm.comparison,-std.algorithm.internal,-std.algorithm.iteration,-std.algorithm.mutation,-std.algorithm.searching,-std.algorithm.setops,-std.algorithm.sorting,-std.array,-std.bigint,-std.bitmanip,-std.c.freebsd.socket,-std.c.linux.pthread,-std.c.process,-std.complex,-std.concurrency,-std.container.array,-std.container.binaryheap,-std.container.dlist,-std.container.rbtree,-std.container.slist,-std.container.util,-std.conv,-std.datetime,-std.datetime.date,-std.datetime.interval,-std.datetime.systime,-std.datetime.timezone,-std.digest.digest,-std.digest.hmac,-std.exception,-std.experimental.allocator,-std.experimental.allocator.building_blocks,-std.experimental.allocator.building_blocks.affix_allocator,-std.experimental.allocator.building_blocks.allocator_list,-std.experimental.allocator.building_blocks.free_list,-std.experimental.allocator.building_blocks.free_tree,-std.experimental.allocator.building_blocks.kernighan_ritchie,-std.experimental.allocator.building_blocks.region,-std.experimental.allocator.common,-std.experimental.allocator.mallocator,-std.experimental.allocator.mmap_allocator,-std.experimental.allocator.showcase,-std.experimental.allocator.typed,-std.experimental.checkedint,-std.experimental.logger.core,-std.experimental.typecons,-std.file,-std.format,-std.functional,-std.getopt,-std.internal.math.biguintcore,-std.internal.test.dummyrange,-std.json,-std.math,-std.meta,-std.mmfile,-std.net.curl,-std.net.isemail,-std.numeric,-std.outbuffer,-std.parallelism,-std.path,-std.process,-std.random,-std.range,-std.range.primitives,-std.regex,-std.regex.internal.backtracking,-std.regex.internal.generator,-std.regex.internal.kickstart,-std.regex.internal.parser,-std.regex.internal.tests,-std.signals,-std.socket,-std.stdio,-std.string,-std.uni,-std.utf,-std.uuid,-std.variant,-std.windows.charset,-std.windows.registry,-std.windows.syserror,-std.zip" diff --git a/std/ascii.d b/std/ascii.d index e5fa3e33d1a..3867c563305 100644 --- a/std/ascii.d +++ b/std/ascii.d @@ -87,6 +87,29 @@ enum LetterCase : bool lower /// Lower case letters } +/// +@safe unittest +{ + import std.conv : to; + + assert(42.to!string(16, LetterCase.upper) == "2A"); + assert(42.to!string(16, LetterCase.lower) == "2a"); +} + +/// +@system unittest +{ + import std.digest.hmac : hmac; + import std.digest.digest : toHexString; + import std.digest.sha : SHA1; + import std.string : representation; + + const sha1HMAC = "A very long phrase".representation + .hmac!SHA1("secret".representation) + .toHexString!(LetterCase.lower); + assert(sha1HMAC == "49f2073c7bf58577e8c9ae59fe8cfd37c9ab94e5"); +} + /// Newline sequence for this system. version(Windows) immutable newline = "\r\n"; From 54c47a71930cad62ec1858e9b4ac9ab283f56d6c Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Sun, 9 Jul 2017 00:42:49 +0200 Subject: [PATCH 113/163] has_public_example: std.base64 --- .dscanner.ini | 2 +- std/base64.d | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/.dscanner.ini b/.dscanner.ini index 4fa89fbc497..0404ee5c9c0 100644 --- a/.dscanner.ini +++ b/.dscanner.ini @@ -120,7 +120,7 @@ exception_check="-std.concurrency,-std.net.curl,-std.parallelism,-std.range,-std ; Checks for poor placement of function attributes function_attribute_check="-std.algorithm.iteration,-std.concurrency,-std.conv,-std.datetime.interval,-std.exception,-std.functional,-std.net.curl,-std.numeric,-std.parallelism,-std.random,-std.range,-std.range.primitives,-std.socket,-std.traits,-std.typecons,-std.uni" ; Check for public declarations without a documented unittest -has_public_example="-etc.c.curl,-etc.c.sqlite3,-etc.c.zlib,-std.base64,-std.bitmanip,-std.complex,-std.concurrency,-std.container.array,-std.container.dlist,-std.container.rbtree,-std.container.slist,-std.conv,-std.csv,-std.datetime,-std.datetime.date,-std.datetime.interval,-std.datetime.stopwatch,-std.datetime.systime,-std.datetime.timezone,-std.demangle,-std.digest.digest,-std.digest.hmac,-std.digest.murmurhash,-std.digest.sha,-std.encoding,-std.exception,-std.experimental.allocator,-std.experimental.allocator.building_blocks.allocator_list,-std.experimental.allocator.building_blocks.bitmapped_block,-std.experimental.allocator.building_blocks.fallback_allocator,-std.experimental.allocator.building_blocks.free_list,-std.experimental.allocator.building_blocks.free_tree,-std.experimental.allocator.building_blocks.null_allocator,-std.experimental.allocator.building_blocks.stats_collector,-std.experimental.allocator.common,-std.experimental.allocator.mmap_allocator,-std.experimental.allocator.typed,-std.experimental.checkedint,-std.experimental.logger.core,-std.experimental.logger.filelogger,-std.experimental.logger.multilogger,-std.experimental.typecons,-std.file,-std.format,-std.getopt,-std.internal.math.biguintcore,-std.internal.math.biguintnoasm,-std.internal.math.errorfunction,-std.internal.math.gammafunction,-std.internal.scopebuffer,-std.internal.test.dummyrange,-std.json,-std.math,-std.mathspecial,-std.mmfile,-std.net.curl,-std.net.isemail,-std.numeric,-std.outbuffer,-std.parallelism,-std.path,-std.process,-std.random,-std.range,-std.range.interfaces,-std.range.primitives,-std.regex,-std.regex.internal.ir,-std.socket,-std.stdio,-std.string,-std.traits,-std.typecons,-std.uni,-std.uri,-std.utf,-std.uuid,-std.variant,-std.xml,-std.zip,-std.zlib" +has_public_example="-etc.c.curl,-etc.c.sqlite3,-etc.c.zlib,-std.bitmanip,-std.complex,-std.concurrency,-std.container.array,-std.container.dlist,-std.container.rbtree,-std.container.slist,-std.conv,-std.csv,-std.datetime,-std.datetime.date,-std.datetime.interval,-std.datetime.stopwatch,-std.datetime.systime,-std.datetime.timezone,-std.demangle,-std.digest.digest,-std.digest.hmac,-std.digest.murmurhash,-std.digest.sha,-std.encoding,-std.exception,-std.experimental.allocator,-std.experimental.allocator.building_blocks.allocator_list,-std.experimental.allocator.building_blocks.bitmapped_block,-std.experimental.allocator.building_blocks.fallback_allocator,-std.experimental.allocator.building_blocks.free_list,-std.experimental.allocator.building_blocks.free_tree,-std.experimental.allocator.building_blocks.null_allocator,-std.experimental.allocator.building_blocks.stats_collector,-std.experimental.allocator.common,-std.experimental.allocator.mmap_allocator,-std.experimental.allocator.typed,-std.experimental.checkedint,-std.experimental.logger.core,-std.experimental.logger.filelogger,-std.experimental.logger.multilogger,-std.experimental.typecons,-std.file,-std.format,-std.getopt,-std.internal.math.biguintcore,-std.internal.math.biguintnoasm,-std.internal.math.errorfunction,-std.internal.math.gammafunction,-std.internal.scopebuffer,-std.internal.test.dummyrange,-std.json,-std.math,-std.mathspecial,-std.mmfile,-std.net.curl,-std.net.isemail,-std.numeric,-std.outbuffer,-std.parallelism,-std.path,-std.process,-std.random,-std.range,-std.range.interfaces,-std.range.primitives,-std.regex,-std.regex.internal.ir,-std.socket,-std.stdio,-std.string,-std.traits,-std.typecons,-std.uni,-std.uri,-std.utf,-std.uuid,-std.variant,-std.xml,-std.zip,-std.zlib" ; Check for sortedness of imports imports_sortedness="+disabled" ;imports_sortedness="-etc.c.curl,-std.algorithm.comparison,-std.algorithm.internal,-std.algorithm.iteration,-std.algorithm.mutation,-std.algorithm.searching,-std.algorithm.setops,-std.algorithm.sorting,-std.array,-std.bigint,-std.bitmanip,-std.c.freebsd.socket,-std.c.linux.pthread,-std.c.process,-std.complex,-std.concurrency,-std.container.array,-std.container.binaryheap,-std.container.dlist,-std.container.rbtree,-std.container.slist,-std.container.util,-std.conv,-std.datetime,-std.datetime.date,-std.datetime.interval,-std.datetime.systime,-std.datetime.timezone,-std.digest.digest,-std.digest.hmac,-std.exception,-std.experimental.allocator,-std.experimental.allocator.building_blocks,-std.experimental.allocator.building_blocks.affix_allocator,-std.experimental.allocator.building_blocks.allocator_list,-std.experimental.allocator.building_blocks.free_list,-std.experimental.allocator.building_blocks.free_tree,-std.experimental.allocator.building_blocks.kernighan_ritchie,-std.experimental.allocator.building_blocks.region,-std.experimental.allocator.common,-std.experimental.allocator.mallocator,-std.experimental.allocator.mmap_allocator,-std.experimental.allocator.showcase,-std.experimental.allocator.typed,-std.experimental.checkedint,-std.experimental.logger.core,-std.experimental.typecons,-std.file,-std.format,-std.functional,-std.getopt,-std.internal.math.biguintcore,-std.internal.test.dummyrange,-std.json,-std.math,-std.meta,-std.mmfile,-std.net.curl,-std.net.isemail,-std.numeric,-std.outbuffer,-std.parallelism,-std.path,-std.process,-std.random,-std.range,-std.range.primitives,-std.regex,-std.regex.internal.backtracking,-std.regex.internal.generator,-std.regex.internal.kickstart,-std.regex.internal.parser,-std.regex.internal.tests,-std.signals,-std.socket,-std.stdio,-std.string,-std.uni,-std.utf,-std.uuid,-std.variant,-std.windows.charset,-std.windows.registry,-std.windows.syserror,-std.zip" diff --git a/std/base64.d b/std/base64.d index 59c941e27b4..7582a6d1961 100644 --- a/std/base64.d +++ b/std/base64.d @@ -1721,6 +1721,21 @@ template Base64Impl(char Map62th, char Map63th, char Padding = '=') } } +/// +@safe unittest +{ + import std.string : representation; + + // pre-defined: alias Base64 = Base64Impl!('+', '/'); + ubyte[] emptyArr; + assert(Base64.encode(emptyArr) == ""); + assert(Base64.encode("f".representation) == "Zg=="); + assert(Base64.encode("foo".representation) == "Zm9v"); + + alias Base64Re = Base64Impl!('!', '=', Base64.NoPadding); + assert(Base64Re.encode("f".representation) == "Zg"); + assert(Base64Re.encode("foo".representation) == "Zm9v"); +} /** * Exception thrown upon encountering Base64 encoding or decoding errors. @@ -1734,6 +1749,13 @@ class Base64Exception : Exception } } +/// +@system unittest +{ + import std.exception : assertThrown; + assertThrown!Base64Exception(Base64.decode("ab|c")); +} + @system unittest { From 28e7c95c97e4f51dbc3b8dabf62f1d9de58d7ac9 Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Wed, 4 Jan 2017 17:48:51 +0100 Subject: [PATCH 114/163] rename digest.d -> package.d --- std/digest/{digest.d => package.d} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename std/digest/{digest.d => package.d} (99%) diff --git a/std/digest/digest.d b/std/digest/package.d similarity index 99% rename from std/digest/digest.d rename to std/digest/package.d index 1d2eaf541d4..e3b2dfe792c 100644 --- a/std/digest/digest.d +++ b/std/digest/package.d @@ -47,7 +47,7 @@ $(TR $(TDNW Implementation helpers) $(TD $(MYREF digestLength) $(MYREF WrapperDi * Authors: * Johannes Pfau * - * Source: $(PHOBOSSRC std/_digest/_digest.d) + * Source: $(PHOBOSSRC std/_digest/_package.d) * * CTFE: * Digests do not work in CTFE @@ -61,7 +61,7 @@ $(TR $(TDNW Implementation helpers) $(TD $(MYREF digestLength) $(MYREF WrapperDi * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) */ -module std.digest.digest; +module std.digest; public import std.ascii : LetterCase; import std.meta : allSatisfy; From 5774d017eb4fa154491385a91f590abc2f66b964 Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Wed, 4 Jan 2017 17:49:00 +0100 Subject: [PATCH 115/163] Fix issue 16191 - std/digest/digest.d should be renamed to package.d --- posix.mak | 2 +- std/digest/crc.d | 23 +++++++++++------------ std/digest/digest.d | 21 +++++++++++++++++++++ std/digest/hmac.d | 6 +++--- std/digest/md.d | 16 ++++++++-------- std/digest/murmurhash.d | 8 ++++---- std/digest/ripemd.d | 16 ++++++++-------- std/digest/sha.d | 16 ++++++++-------- win32.mak | 3 ++- win64.mak | 3 ++- 10 files changed, 68 insertions(+), 46 deletions(-) create mode 100644 std/digest/digest.d diff --git a/posix.mak b/posix.mak index c624f34e24c..dbba3ce3362 100644 --- a/posix.mak +++ b/posix.mak @@ -189,7 +189,7 @@ PACKAGE_std_algorithm = comparison iteration mutation package searching setops \ sorting PACKAGE_std_container = array binaryheap dlist package rbtree slist util PACKAGE_std_datetime = date interval package stopwatch systime timezone -PACKAGE_std_digest = crc digest hmac md murmurhash ripemd sha +PACKAGE_std_digest = crc digest hmac md murmurhash package ripemd sha PACKAGE_std_experimental_logger = core filelogger \ nulllogger multilogger package PACKAGE_std_experimental_allocator = \ diff --git a/std/digest/crc.d b/std/digest/crc.d index 7aaff655193..33f8ca1b141 100644 --- a/std/digest/crc.d +++ b/std/digest/crc.d @@ -18,16 +18,16 @@ $(TR $(TDNW Helpers) $(TD $(MYREF crcHexString) $(MYREF crc32Of)) ) * - * This module conforms to the APIs defined in $(D std.digest.digest). To understand the - * differences between the template and the OOP API, see $(D std.digest.digest). + * This module conforms to the APIs defined in $(D std.digest). To understand the + * differences between the template and the OOP API, see $(D std.digest). * - * This module publicly imports $(D std.digest.digest) and can be used as a stand-alone + * This module publicly imports $(D std.digest) and can be used as a stand-alone * module. * * Note: * CRCs are usually printed with the MSB first. When using - * $(REF toHexString, std,digest,digest) the result will be in an unexpected - * order. Use $(REF toHexString, std,digest,digest)'s optional order parameter + * $(REF toHexString, std,digest) the result will be in an unexpected + * order. Use $(REF toHexString, std,digest)'s optional order parameter * to specify decreasing order for the correct result. The $(LREF crcHexString) * alias can also be used for this purpose. * @@ -58,7 +58,7 @@ $(TR $(TDNW Helpers) $(TD $(MYREF crcHexString) $(MYREF crc32Of)) */ module std.digest.crc; -public import std.digest.digest; +public import std.digest; version(unittest) import std.exception; @@ -133,7 +133,7 @@ private T[256][8] genTables(T)(T polynomial) /** * Template API CRC32 implementation. - * See $(D std.digest.digest) for differences between template and OOP API. + * See $(D std.digest) for differences between template and OOP API. */ alias CRC32 = CRC!(32, 0xEDB88320); @@ -461,7 +461,7 @@ struct CRC(uint N, ulong P) if (N == 32 || N == 64) } /** - * This is a convenience alias for $(REF digest, std,digest,digest) using the + * This is a convenience alias for $(REF digest, std,digest) using the * CRC32 implementation. * * Params: @@ -496,7 +496,7 @@ ubyte[4] crc32Of(T...)(T data) } /** - * This is a convenience alias for $(REF digest, std,digest,digest) using the + * This is a convenience alias for $(REF digest, std,digest) using the * CRC64-ECMA implementation. * * Params: @@ -569,7 +569,6 @@ ubyte[8] crc64ISOOf(T...)(T data) } /** - * This is a convenience alias for $(REF toHexString, std,digest,digest) * producing the usual CRC32 string output. */ public alias crcHexString = toHexString!(Order.decreasing); @@ -578,9 +577,9 @@ public alias crcHexString = toHexString!(Order.decreasing, 16); /** * OOP API CRC32 implementation. - * See $(D std.digest.digest) for differences between template and OOP API. + * See $(D std.digest) for differences between template and OOP API. * - * This is an alias for $(D $(REF WrapperDigest, std,digest,digest)!CRC32), see + * This is an alias for $(D $(REF WrapperDigest, std,digest)!CRC32), see * there for more information. */ alias CRC32Digest = WrapperDigest!CRC32; diff --git a/std/digest/digest.d b/std/digest/digest.d new file mode 100644 index 00000000000..175b9a696bc --- /dev/null +++ b/std/digest/digest.d @@ -0,0 +1,21 @@ +module std.digest.digest; + +static import std.digest; + +// scheduled for deprecation in 2.077 +// See also: https://github.com/dlang/phobos/pull/5013#issuecomment-313987845 +alias isDigest = std.digest.isDigest; +alias DigestType = std.digest.DigestType; +alias hasPeek = std.digest.hasPeek; +alias hasBlockSize = std.digest.hasBlockSize; +alias digest = std.digest.digest; +alias hexDigest = std.digest.hexDigest; +alias makeDigest = std.digest.makeDigest; +alias Digest = std.digest.Digest; +alias Order = std.digest.Order; +alias toHexString = std.digest.toHexString; +alias asArray = std.digest.asArray; +alias digestLength = std.digest.digestLength; +alias WrapperDigest = std.digest.WrapperDigest; +alias secureEqual = std.digest.secureEqual; +alias LetterCase = std.digest.LetterCase; diff --git a/std/digest/hmac.d b/std/digest/hmac.d index 516f6d6c62a..a2689d1555b 100644 --- a/std/digest/hmac.d +++ b/std/digest/hmac.d @@ -16,7 +16,7 @@ Source: $(PHOBOSSRC std/digest/_hmac.d) module std.digest.hmac; -import std.digest.digest : isDigest, hasBlockSize, isDigestibleRange, DigestType; +import std.digest : isDigest, hasBlockSize, isDigestibleRange, DigestType; import std.meta : allSatisfy; /** @@ -26,7 +26,7 @@ import std.meta : allSatisfy; * information about the block size, it can be supplied explicitly using * the second overload. * - * This type conforms to $(REF isDigest, std,digest,digest). + * This type conforms to $(REF isDigest, std,digest). */ version(StdDdoc) @@ -286,7 +286,7 @@ if (isDigest!H) version(unittest) { - import std.digest.digest : toHexString, LetterCase; + import std.digest : toHexString, LetterCase; alias hex = toHexString!(LetterCase.lower); } diff --git a/std/digest/md.d b/std/digest/md.d index 8ef7bbcb583..5f15d958bf2 100644 --- a/std/digest/md.d +++ b/std/digest/md.d @@ -18,10 +18,10 @@ $(TR $(TDNW Helpers) $(TD $(MYREF md5Of)) ) ) - * This module conforms to the APIs defined in $(D std.digest.digest). To understand the - * differences between the template and the OOP API, see $(D std.digest.digest). + * This module conforms to the APIs defined in $(D std.digest). To understand the + * differences between the template and the OOP API, see $(D std.digest). * - * This module publicly imports $(D std.digest.digest) and can be used as a stand-alone + * This module publicly imports $(D std.digest) and can be used as a stand-alone * module. * * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0). @@ -45,7 +45,7 @@ $(TR $(TDNW Helpers) $(TD $(MYREF md5Of)) */ module std.digest.md; -public import std.digest.digest; +public import std.digest; /// @safe unittest @@ -91,7 +91,7 @@ private uint rotateLeft(uint x, uint n) @safe pure nothrow @nogc /** * Template API MD5 implementation. - * See $(D std.digest.digest) for differences between template and OOP API. + * See $(D std.digest) for differences between template and OOP API. */ struct MD5 { @@ -493,7 +493,7 @@ struct MD5 } /** - * This is a convenience alias for $(REF digest, std,digest,digest) using the + * This is a convenience alias for $(REF digest, std,digest) using the * MD5 implementation. */ //simple alias doesn't work here, hope this gets inlined... @@ -511,9 +511,9 @@ auto md5Of(T...)(T data) /** * OOP API MD5 implementation. - * See $(D std.digest.digest) for differences between template and OOP API. + * See $(D std.digest) for differences between template and OOP API. * - * This is an alias for $(D $(REF WrapperDigest, std,digest,digest)!MD5), see + * This is an alias for $(D $(REF WrapperDigest, std,digest)!MD5), see * there for more information. */ alias MD5Digest = WrapperDigest!MD5; diff --git a/std/digest/murmurhash.d b/std/digest/murmurhash.d index 89b4b1cd476..e8930a7cc55 100644 --- a/std/digest/murmurhash.d +++ b/std/digest/murmurhash.d @@ -22,9 +22,9 @@ $(LI The current implementation is optimized for little endian architectures. less uniform distribution.) ) -This module conforms to the APIs defined in $(D std.digest.digest). +This module conforms to the APIs defined in $(D std.digest). -This module publicly imports $(D std.digest.digest) and can be used as a stand-alone module. +This module publicly imports $(D std.digest) and can be used as a stand-alone module. License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0). Authors: Guillaume Chatelet @@ -41,7 +41,7 @@ module std.digest.murmurhash; @safe unittest { // MurmurHash3!32, MurmurHash3!(128, 32) and MurmurHash3!(128, 64) implement - // the std.digest.digest Template API. + // the std.digest Template API. static assert(isDigest!(MurmurHash3!32)); // The convenient digest template allows for quick hashing of any data. ubyte[4] hashed = digest!(MurmurHash3!32)([1, 2, 3, 4]); @@ -88,7 +88,7 @@ module std.digest.murmurhash; auto hashed = hasher.getBytes(); } -public import std.digest.digest; +public import std.digest; @safe: diff --git a/std/digest/ripemd.d b/std/digest/ripemd.d index 0dd472c03e4..60420f4c34a 100644 --- a/std/digest/ripemd.d +++ b/std/digest/ripemd.d @@ -18,10 +18,10 @@ $(TR $(TDNW Helpers) $(TD $(MYREF ripemd160Of)) ) ) - * This module conforms to the APIs defined in $(D std.digest.digest). To understand the - * differences between the template and the OOP API, see $(D std.digest.digest). + * This module conforms to the APIs defined in $(D std.digest). To understand the + * differences between the template and the OOP API, see $(D std.digest). * - * This module publicly imports $(D std.digest.digest) and can be used as a stand-alone + * This module publicly imports $(D std.digest) and can be used as a stand-alone * module. * * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0). @@ -46,7 +46,7 @@ $(TR $(TDNW Helpers) $(TD $(MYREF ripemd160Of)) module std.digest.ripemd; -public import std.digest.digest; +public import std.digest; /// @safe unittest @@ -95,7 +95,7 @@ private uint rotateLeft(uint x, uint n) @safe pure nothrow @nogc /** * Template API RIPEMD160 implementation. - * See $(D std.digest.digest) for differences between template and OOP API. + * See $(D std.digest) for differences between template and OOP API. */ struct RIPEMD160 { @@ -662,7 +662,7 @@ struct RIPEMD160 } /** - * This is a convenience alias for $(REF digest, std,digest,digest) using the + * This is a convenience alias for $(REF digest, std,digest) using the * RIPEMD160 implementation. */ //simple alias doesn't work here, hope this gets inlined... @@ -680,9 +680,9 @@ auto ripemd160Of(T...)(T data) /** * OOP API RIPEMD160 implementation. - * See $(D std.digest.digest) for differences between template and OOP API. + * See $(D std.digest) for differences between template and OOP API. * - * This is an alias for $(D $(REF WrapperDigest, std,digest,digest)!RIPEMD160), + * This is an alias for $(D $(REF WrapperDigest, std,digest)!RIPEMD160), * see there for more information. */ alias RIPEMD160Digest = WrapperDigest!RIPEMD160; diff --git a/std/digest/sha.d b/std/digest/sha.d index 4f661f7c2b9..91ffd55023d 100644 --- a/std/digest/sha.d +++ b/std/digest/sha.d @@ -23,10 +23,10 @@ $(TR $(TDNW Helpers) $(TD $(MYREF sha1Of)) * SHA2 comes in several different versions, all supported by this module: * SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224 and SHA-512/256. * - * This module conforms to the APIs defined in $(D std.digest.digest). To understand the - * differences between the template and the OOP API, see $(D std.digest.digest). + * This module conforms to the APIs defined in $(D std.digest). To understand the + * differences between the template and the OOP API, see $(D std.digest). * - * This module publicly imports $(D std.digest.digest) and can be used as a stand-alone + * This module publicly imports $(D std.digest) and can be used as a stand-alone * module. * * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0). @@ -124,7 +124,7 @@ version(unittest) } -public import std.digest.digest; +public import std.digest; /* * Helper methods for encoding the buffer. @@ -193,7 +193,7 @@ private ulong rotateRight(ulong x, uint n) @safe pure nothrow @nogc * simply use the convenience aliases: SHA1, SHA224, SHA256, SHA384, SHA512, * SHA512_224 and SHA512_256. * - * See $(D std.digest.digest) for differences between template and OOP API. + * See $(D std.digest) for differences between template and OOP API. */ struct SHA(uint hashBlockSize, uint digestSize) { @@ -1122,7 +1122,7 @@ alias SHA512_256 = SHA!(1024, 256); /// SHA alias for SHA-512/256, hash is ubyte } /** - * These are convenience aliases for $(REF digest, std,digest,digest) using the + * These are convenience aliases for $(REF digest, std,digest) using the * SHA implementation. */ //simple alias doesn't work here, hope this gets inlined... @@ -1199,9 +1199,9 @@ auto sha512_256Of(T...)(T data) /** * OOP API SHA1 and SHA2 implementations. - * See $(D std.digest.digest) for differences between template and OOP API. + * See $(D std.digest) for differences between template and OOP API. * - * This is an alias for $(D $(REF WrapperDigest, std,digest,digest)!SHA1), see + * This is an alias for $(D $(REF WrapperDigest, std,digest)!SHA1), see * there for more information. */ alias SHA1Digest = WrapperDigest!SHA1; diff --git a/win32.mak b/win32.mak index e83ef7965ea..4c6821c42c2 100644 --- a/win32.mak +++ b/win32.mak @@ -208,7 +208,8 @@ SRC_STD_DIGEST= \ std\digest\ripemd.d \ std\digest\digest.d \ std\digest\hmac.d \ - std\digest\murmurhash.d + std\digest\murmurhash.d \ + std\digest\package.d SRC_STD_NET= \ std\net\isemail.d \ diff --git a/win64.mak b/win64.mak index c97fd1e4e02..6a7c552b4e0 100644 --- a/win64.mak +++ b/win64.mak @@ -233,7 +233,8 @@ SRC_STD_DIGEST= \ std\digest\ripemd.d \ std\digest\digest.d \ std\digest\hmac.d \ - std\digest\murmurhash.d + std\digest\murmurhash.d \ + std\digest\package.d SRC_STD_NET= \ std\net\isemail.d \ From 720018f9d4fd3ed4a851365990419e0dcf87d431 Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Sat, 7 Jan 2017 17:01:26 +0100 Subject: [PATCH 116/163] Add changelog entry for the std.digest.digest -> std.digest rename --- changelog/std-digest-package.dd | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 changelog/std-digest-package.dd diff --git a/changelog/std-digest-package.dd b/changelog/std-digest-package.dd new file mode 100644 index 00000000000..e94f7d82113 --- /dev/null +++ b/changelog/std-digest-package.dd @@ -0,0 +1,8 @@ +`std.digest.digest` was renamed to `std.digest`. + +$(B Motivation): + +The fully qualified name of the digest function template was `std.digest.digest.digest`. +This is because `std.digest` is a package, with a module named `digest` in it, and the function `digest` inside that. + +$(MREF std, digest) contains the former `std.digest.digest` package. From 1772b24e3d822d5b9bdf32bbf371876fe72d35a0 Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Mon, 10 Jul 2017 04:00:18 +0200 Subject: [PATCH 117/163] Update .dscanner.ini to ignore std.digest --- .dscanner.ini | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.dscanner.ini b/.dscanner.ini index 0404ee5c9c0..a5610f7d100 100644 --- a/.dscanner.ini +++ b/.dscanner.ini @@ -114,16 +114,16 @@ asm_style_check="-std.math" ; Checks for assignment to auto-ref function parameters auto_ref_assignment_check="-std.algorithm.mutation,-std.format,-std.typecons" ; Checks for variables that could be declared immutable -could_be_immutable_check="-std.algorithm.comparison,-std.algorithm.iteration,-std.algorithm.mutation,-std.algorithm.searching,-std.algorithm.setops,-std.algorithm.sorting,-std.array,-std.base64,-std.bigint,-std.bitmanip,-std.complex,-std.concurrency,-std.container,-std.container.array,-std.container.binaryheap,-std.container.dlist,-std.container.rbtree,-std.container.slist,-std.container.util,-std.conv,-std.csv,-std.datetime,-std.datetime.date,-std.datetime.interval,-std.datetime.stopwatch,-std.datetime.systime,-std.datetime.timezone,-std.digest.crc,-std.digest.digest,-std.digest.hmac,-std.digest.md,-std.digest.murmurhash,-std.digest.ripemd,-std.digest.sha,-std.encoding,-std.exception,-std.experimental.allocator,-std.experimental.allocator.building_blocks.affix_allocator,-std.experimental.allocator.building_blocks.allocator_list,-std.experimental.allocator.building_blocks.bitmapped_block,-std.experimental.allocator.building_blocks.bucketizer,-std.experimental.allocator.building_blocks.fallback_allocator,-std.experimental.allocator.building_blocks.free_list,-std.experimental.allocator.building_blocks.free_tree,-std.experimental.allocator.building_blocks.kernighan_ritchie,-std.experimental.allocator.building_blocks.region,-std.experimental.allocator.building_blocks.stats_collector,-std.experimental.allocator.gc_allocator,-std.experimental.allocator.mallocator,-std.experimental.allocator.typed,-std.experimental.checkedint,-std.experimental.logger.core,-std.experimental.logger.multilogger,-std.experimental.typecons,-std.file,-std.format,-std.functional,-std.getopt,-std.internal.cstring,-std.internal.digest.sha_SSSE3,-std.internal.math.biguintcore,-std.internal.math.biguintnoasm,-std.internal.math.biguintx86,-std.internal.math.errorfunction,-std.internal.math.gammafunction,-std.internal.scopebuffer,-std.internal.test.dummyrange,-std.json,-std.math,-std.mathspecial,-std.meta,-std.mmfile,-std.net.curl,-std.net.isemail,-std.numeric,-std.outbuffer,-std.parallelism,-std.path,-std.process,-std.random,-std.range,-std.range.interfaces,-std.range.primitives,-std.regex,-std.regex.internal.backtracking,-std.regex.internal.generator,-std.regex.internal.ir,-std.regex.internal.kickstart,-std.regex.internal.parser,-std.regex.internal.tests,-std.regex.internal.thompson,-std.signals,-std.socket,-std.stdio,-std.string,-std.traits,-std.typecons,-std.uni,-std.uri,-std.utf,-std.uuid,-std.variant,-std.windows.registry,-std.xml,-std.zip,-std.zlib" +could_be_immutable_check="-std.algorithm.comparison,-std.algorithm.iteration,-std.algorithm.mutation,-std.algorithm.searching,-std.algorithm.setops,-std.algorithm.sorting,-std.array,-std.base64,-std.bigint,-std.bitmanip,-std.complex,-std.concurrency,-std.container,-std.container.array,-std.container.binaryheap,-std.container.dlist,-std.container.rbtree,-std.container.slist,-std.container.util,-std.conv,-std.csv,-std.datetime,-std.datetime.date,-std.datetime.interval,-std.datetime.stopwatch,-std.datetime.systime,-std.datetime.timezone,-std.digest.crc,-std.digest,-std.digest.hmac,-std.digest.md,-std.digest.murmurhash,-std.digest.ripemd,-std.digest.sha,-std.encoding,-std.exception,-std.experimental.allocator,-std.experimental.allocator.building_blocks.affix_allocator,-std.experimental.allocator.building_blocks.allocator_list,-std.experimental.allocator.building_blocks.bitmapped_block,-std.experimental.allocator.building_blocks.bucketizer,-std.experimental.allocator.building_blocks.fallback_allocator,-std.experimental.allocator.building_blocks.free_list,-std.experimental.allocator.building_blocks.free_tree,-std.experimental.allocator.building_blocks.kernighan_ritchie,-std.experimental.allocator.building_blocks.region,-std.experimental.allocator.building_blocks.stats_collector,-std.experimental.allocator.gc_allocator,-std.experimental.allocator.mallocator,-std.experimental.allocator.typed,-std.experimental.checkedint,-std.experimental.logger.core,-std.experimental.logger.multilogger,-std.experimental.typecons,-std.file,-std.format,-std.functional,-std.getopt,-std.internal.cstring,-std.internal.digest.sha_SSSE3,-std.internal.math.biguintcore,-std.internal.math.biguintnoasm,-std.internal.math.biguintx86,-std.internal.math.errorfunction,-std.internal.math.gammafunction,-std.internal.scopebuffer,-std.internal.test.dummyrange,-std.json,-std.math,-std.mathspecial,-std.meta,-std.mmfile,-std.net.curl,-std.net.isemail,-std.numeric,-std.outbuffer,-std.parallelism,-std.path,-std.process,-std.random,-std.range,-std.range.interfaces,-std.range.primitives,-std.regex,-std.regex.internal.backtracking,-std.regex.internal.generator,-std.regex.internal.ir,-std.regex.internal.kickstart,-std.regex.internal.parser,-std.regex.internal.tests,-std.regex.internal.thompson,-std.signals,-std.socket,-std.stdio,-std.string,-std.traits,-std.typecons,-std.uni,-std.uri,-std.utf,-std.uuid,-std.variant,-std.windows.registry,-std.xml,-std.zip,-std.zlib" ; Check for poor exception handling practices exception_check="-std.concurrency,-std.net.curl,-std.parallelism,-std.range,-std.socket,-std.typecons" ; Checks for poor placement of function attributes function_attribute_check="-std.algorithm.iteration,-std.concurrency,-std.conv,-std.datetime.interval,-std.exception,-std.functional,-std.net.curl,-std.numeric,-std.parallelism,-std.random,-std.range,-std.range.primitives,-std.socket,-std.traits,-std.typecons,-std.uni" ; Check for public declarations without a documented unittest -has_public_example="-etc.c.curl,-etc.c.sqlite3,-etc.c.zlib,-std.bitmanip,-std.complex,-std.concurrency,-std.container.array,-std.container.dlist,-std.container.rbtree,-std.container.slist,-std.conv,-std.csv,-std.datetime,-std.datetime.date,-std.datetime.interval,-std.datetime.stopwatch,-std.datetime.systime,-std.datetime.timezone,-std.demangle,-std.digest.digest,-std.digest.hmac,-std.digest.murmurhash,-std.digest.sha,-std.encoding,-std.exception,-std.experimental.allocator,-std.experimental.allocator.building_blocks.allocator_list,-std.experimental.allocator.building_blocks.bitmapped_block,-std.experimental.allocator.building_blocks.fallback_allocator,-std.experimental.allocator.building_blocks.free_list,-std.experimental.allocator.building_blocks.free_tree,-std.experimental.allocator.building_blocks.null_allocator,-std.experimental.allocator.building_blocks.stats_collector,-std.experimental.allocator.common,-std.experimental.allocator.mmap_allocator,-std.experimental.allocator.typed,-std.experimental.checkedint,-std.experimental.logger.core,-std.experimental.logger.filelogger,-std.experimental.logger.multilogger,-std.experimental.typecons,-std.file,-std.format,-std.getopt,-std.internal.math.biguintcore,-std.internal.math.biguintnoasm,-std.internal.math.errorfunction,-std.internal.math.gammafunction,-std.internal.scopebuffer,-std.internal.test.dummyrange,-std.json,-std.math,-std.mathspecial,-std.mmfile,-std.net.curl,-std.net.isemail,-std.numeric,-std.outbuffer,-std.parallelism,-std.path,-std.process,-std.random,-std.range,-std.range.interfaces,-std.range.primitives,-std.regex,-std.regex.internal.ir,-std.socket,-std.stdio,-std.string,-std.traits,-std.typecons,-std.uni,-std.uri,-std.utf,-std.uuid,-std.variant,-std.xml,-std.zip,-std.zlib" +has_public_example="-etc.c.curl,-etc.c.sqlite3,-etc.c.zlib,-std.bitmanip,-std.complex,-std.concurrency,-std.container.array,-std.container.dlist,-std.container.rbtree,-std.container.slist,-std.conv,-std.csv,-std.datetime,-std.datetime.date,-std.datetime.interval,-std.datetime.stopwatch,-std.datetime.systime,-std.datetime.timezone,-std.demangle,-std.digest,-std.digest.hmac,-std.digest.murmurhash,-std.digest.sha,-std.encoding,-std.exception,-std.experimental.allocator,-std.experimental.allocator.building_blocks.allocator_list,-std.experimental.allocator.building_blocks.bitmapped_block,-std.experimental.allocator.building_blocks.fallback_allocator,-std.experimental.allocator.building_blocks.free_list,-std.experimental.allocator.building_blocks.free_tree,-std.experimental.allocator.building_blocks.null_allocator,-std.experimental.allocator.building_blocks.stats_collector,-std.experimental.allocator.common,-std.experimental.allocator.mmap_allocator,-std.experimental.allocator.typed,-std.experimental.checkedint,-std.experimental.logger.core,-std.experimental.logger.filelogger,-std.experimental.logger.multilogger,-std.experimental.typecons,-std.file,-std.format,-std.getopt,-std.internal.math.biguintcore,-std.internal.math.biguintnoasm,-std.internal.math.errorfunction,-std.internal.math.gammafunction,-std.internal.scopebuffer,-std.internal.test.dummyrange,-std.json,-std.math,-std.mathspecial,-std.mmfile,-std.net.curl,-std.net.isemail,-std.numeric,-std.outbuffer,-std.parallelism,-std.path,-std.process,-std.random,-std.range,-std.range.interfaces,-std.range.primitives,-std.regex,-std.regex.internal.ir,-std.socket,-std.stdio,-std.string,-std.traits,-std.typecons,-std.uni,-std.uri,-std.utf,-std.uuid,-std.variant,-std.xml,-std.zip,-std.zlib" ; Check for sortedness of imports imports_sortedness="+disabled" -;imports_sortedness="-etc.c.curl,-std.algorithm.comparison,-std.algorithm.internal,-std.algorithm.iteration,-std.algorithm.mutation,-std.algorithm.searching,-std.algorithm.setops,-std.algorithm.sorting,-std.array,-std.bigint,-std.bitmanip,-std.c.freebsd.socket,-std.c.linux.pthread,-std.c.process,-std.complex,-std.concurrency,-std.container.array,-std.container.binaryheap,-std.container.dlist,-std.container.rbtree,-std.container.slist,-std.container.util,-std.conv,-std.datetime,-std.datetime.date,-std.datetime.interval,-std.datetime.systime,-std.datetime.timezone,-std.digest.digest,-std.digest.hmac,-std.exception,-std.experimental.allocator,-std.experimental.allocator.building_blocks,-std.experimental.allocator.building_blocks.affix_allocator,-std.experimental.allocator.building_blocks.allocator_list,-std.experimental.allocator.building_blocks.free_list,-std.experimental.allocator.building_blocks.free_tree,-std.experimental.allocator.building_blocks.kernighan_ritchie,-std.experimental.allocator.building_blocks.region,-std.experimental.allocator.common,-std.experimental.allocator.mallocator,-std.experimental.allocator.mmap_allocator,-std.experimental.allocator.showcase,-std.experimental.allocator.typed,-std.experimental.checkedint,-std.experimental.logger.core,-std.experimental.typecons,-std.file,-std.format,-std.functional,-std.getopt,-std.internal.math.biguintcore,-std.internal.test.dummyrange,-std.json,-std.math,-std.meta,-std.mmfile,-std.net.curl,-std.net.isemail,-std.numeric,-std.outbuffer,-std.parallelism,-std.path,-std.process,-std.random,-std.range,-std.range.primitives,-std.regex,-std.regex.internal.backtracking,-std.regex.internal.generator,-std.regex.internal.kickstart,-std.regex.internal.parser,-std.regex.internal.tests,-std.signals,-std.socket,-std.stdio,-std.string,-std.uni,-std.utf,-std.uuid,-std.variant,-std.windows.charset,-std.windows.registry,-std.windows.syserror,-std.zip" +;imports_sortedness="-etc.c.curl,-std.algorithm.comparison,-std.algorithm.internal,-std.algorithm.iteration,-std.algorithm.mutation,-std.algorithm.searching,-std.algorithm.setops,-std.algorithm.sorting,-std.array,-std.bigint,-std.bitmanip,-std.c.freebsd.socket,-std.c.linux.pthread,-std.c.process,-std.complex,-std.concurrency,-std.container.array,-std.container.binaryheap,-std.container.dlist,-std.container.rbtree,-std.container.slist,-std.container.util,-std.conv,-std.datetime,-std.datetime.date,-std.datetime.interval,-std.datetime.systime,-std.datetime.timezone,-std.digest,-std.digest.hmac,-std.exception,-std.experimental.allocator,-std.experimental.allocator.building_blocks,-std.experimental.allocator.building_blocks.affix_allocator,-std.experimental.allocator.building_blocks.allocator_list,-std.experimental.allocator.building_blocks.free_list,-std.experimental.allocator.building_blocks.free_tree,-std.experimental.allocator.building_blocks.kernighan_ritchie,-std.experimental.allocator.building_blocks.region,-std.experimental.allocator.common,-std.experimental.allocator.mallocator,-std.experimental.allocator.mmap_allocator,-std.experimental.allocator.showcase,-std.experimental.allocator.typed,-std.experimental.checkedint,-std.experimental.logger.core,-std.experimental.typecons,-std.file,-std.format,-std.functional,-std.getopt,-std.internal.math.biguintcore,-std.internal.test.dummyrange,-std.json,-std.math,-std.meta,-std.mmfile,-std.net.curl,-std.net.isemail,-std.numeric,-std.outbuffer,-std.parallelism,-std.path,-std.process,-std.random,-std.range,-std.range.primitives,-std.regex,-std.regex.internal.backtracking,-std.regex.internal.generator,-std.regex.internal.kickstart,-std.regex.internal.parser,-std.regex.internal.tests,-std.signals,-std.socket,-std.stdio,-std.string,-std.uni,-std.utf,-std.uuid,-std.variant,-std.windows.charset,-std.windows.registry,-std.windows.syserror,-std.zip" ; Checks for labels with the same name as variables label_var_same_name_check="-std.algorithm.iteration,-std.algorithm.sorting,-std.array,-std.bigint,-std.bitmanip,-std.conv,-std.encoding,-std.experimental.allocator.building_blocks.segregator,-std.experimental.typecons,-std.format,-std.internal.digest.sha_SSSE3,-std.parallelism,-std.process,-std.typecons,-std.utf" ; Checks for subtraction from .length properties @@ -138,26 +138,26 @@ long_line_check="-std.datetime.timezone" mismatched_args_check="-std.container.dlist,-std.encoding,-std.internal.math.biguintcore,-std.math,-std.net.curl,-std.numeric,-std.range.primitives,-std.uni" ; Check number literals for readability number_style_check="+disabled" -;number_style_check="-std.algorithm.iteration,-std.algorithm.sorting,-std.array,-std.bigint,-std.bitmanip,-std.container.array,-std.conv,-std.datetime.date,-std.datetime.systime,-std.datetime.timezone,-std.digest.crc,-std.digest.digest,-std.digest.md,-std.digest.ripemd,-std.digest.sha,-std.experimental.allocator.building_blocks.free_tree,-std.experimental.allocator.building_blocks.kernighan_ritchie,-std.experimental.checkedint,-std.file,-std.format,-std.functional,-std.internal.math.biguintcore,-std.internal.math.gammafunction,-std.json,-std.math,-std.outbuffer,-std.parallelism,-std.random,-std.range,-std.regex.internal.generator,-std.utf,-std.zip,-std.zlib" +;number_style_check="-std.algorithm.iteration,-std.algorithm.sorting,-std.array,-std.bigint,-std.bitmanip,-std.container.array,-std.conv,-std.datetime.date,-std.datetime.systime,-std.datetime.timezone,-std.digest.crc,-std.digest,-std.digest.md,-std.digest.ripemd,-std.digest.sha,-std.experimental.allocator.building_blocks.free_tree,-std.experimental.allocator.building_blocks.kernighan_ritchie,-std.experimental.checkedint,-std.file,-std.format,-std.functional,-std.internal.math.biguintcore,-std.internal.math.gammafunction,-std.json,-std.math,-std.outbuffer,-std.parallelism,-std.random,-std.range,-std.regex.internal.generator,-std.utf,-std.zip,-std.zlib" ; Checks that opEquals, opCmp, toHash, and toString are either const, immutable ; , or inout. object_const_check="-std.algorithm.searching,-std.array,-std.bitmanip,-std.concurrency,-std.container.rbtree,-std.conv,-std.datetime.interval,-std.encoding,-std.exception,-std.experimental.checkedint,-std.experimental.logger.core,-std.experimental.typecons,-std.format,-std.functional,-std.meta,-std.numeric,-std.range,-std.regex,-std.stdio,-std.typecons,-std.variant,-std.xml" ; Checks that opEquals and toHash are both defined or neither are defined opequals_tohash_check="-std.algorithm.searching,-std.array,-std.complex,-std.container.array,-std.container.dlist,-std.container.rbtree,-std.container.slist,-std.datetime,-std.datetime.date,-std.experimental.checkedint,-std.functional,-std.internal.test.dummyrange,-std.json,-std.numeric,-std.random,-std.range,-std.socket,-std.traits,-std.typecons,-std.uni" ; Check for properly documented public functions (Returns, Params) -properly_documented_public_functions="-etc.c.odbc.sql,-etc.c.odbc.sqlext,-etc.c.zlib,-std.algorithm.comparison,-std.algorithm.iteration,-std.algorithm.mutation,-std.algorithm.searching,-std.algorithm.setops,-std.algorithm.sorting,-std.array,-std.ascii,-std.base64,-std.bigint,-std.bitmanip,-std.complex,-std.container,-std.container.array,-std.container.binaryheap,-std.container.dlist,-std.container.rbtree,-std.container.slist,-std.container.util,-std.csv,-std.datetime,-std.datetime.date,-std.datetime.interval,-std.datetime.stopwatch,-std.datetime.systime,-std.datetime.timezone,-std.demangle,-std.digest.crc,-std.digest.digest,-std.digest.hmac,-std.digest.md,-std.digest.murmurhash,-std.digest.ripemd,-std.digest.sha,-std.encoding,-std.exception,-std.experimental.allocator,-std.experimental.allocator.building_blocks.affix_allocator,-std.experimental.allocator.building_blocks.allocator_list,-std.experimental.allocator.building_blocks.bitmapped_block,-std.experimental.allocator.building_blocks.bucketizer,-std.experimental.allocator.building_blocks.fallback_allocator,-std.experimental.allocator.building_blocks.free_list,-std.experimental.allocator.building_blocks.free_tree,-std.experimental.allocator.building_blocks.kernighan_ritchie,-std.experimental.allocator.building_blocks.null_allocator,-std.experimental.allocator.building_blocks.quantizer,-std.experimental.allocator.building_blocks.region,-std.experimental.allocator.building_blocks.scoped_allocator,-std.experimental.allocator.building_blocks.segregator,-std.experimental.allocator.building_blocks.stats_collector,-std.experimental.allocator.common,-std.experimental.allocator.gc_allocator,-std.experimental.allocator.mallocator,-std.experimental.allocator.showcase,-std.experimental.allocator.typed,-std.experimental.checkedint,-std.experimental.logger.core,-std.experimental.logger.filelogger,-std.file,-std.format,-std.functional,-std.getopt,-std.internal.cstring,-std.internal.math.biguintcore,-std.internal.math.biguintnoasm,-std.internal.scopebuffer,-std.internal.test.dummyrange,-std.internal.unicode_tables,-std.json,-std.math,-std.mathspecial,-std.meta,-std.mmfile,-std.net.curl,-std.net.isemail,-std.numeric,-std.outbuffer,-std.parallelism,-std.path,-std.random,-std.range,-std.range.interfaces,-std.range.primitives,-std.regex,-std.regex.internal.backtracking,-std.regex.internal.ir,-std.regex.internal.kickstart,-std.regex.internal.parser,-std.regex.internal.thompson,-std.signals,-std.socket,-std.stdio,-std.string,-std.traits,-std.typecons,-std.uni,-std.uri,-std.utf,-std.uuid,-std.variant,-std.xml,-std.zip,-std.zlib" +properly_documented_public_functions="-etc.c.odbc.sql,-etc.c.odbc.sqlext,-etc.c.zlib,-std.algorithm.comparison,-std.algorithm.iteration,-std.algorithm.mutation,-std.algorithm.searching,-std.algorithm.setops,-std.algorithm.sorting,-std.array,-std.ascii,-std.base64,-std.bigint,-std.bitmanip,-std.complex,-std.container,-std.container.array,-std.container.binaryheap,-std.container.dlist,-std.container.rbtree,-std.container.slist,-std.container.util,-std.csv,-std.datetime,-std.datetime.date,-std.datetime.interval,-std.datetime.stopwatch,-std.datetime.systime,-std.datetime.timezone,-std.demangle,-std.digest.crc,-std.digest,-std.digest.hmac,-std.digest.md,-std.digest.murmurhash,-std.digest.ripemd,-std.digest.sha,-std.encoding,-std.exception,-std.experimental.allocator,-std.experimental.allocator.building_blocks.affix_allocator,-std.experimental.allocator.building_blocks.allocator_list,-std.experimental.allocator.building_blocks.bitmapped_block,-std.experimental.allocator.building_blocks.bucketizer,-std.experimental.allocator.building_blocks.fallback_allocator,-std.experimental.allocator.building_blocks.free_list,-std.experimental.allocator.building_blocks.free_tree,-std.experimental.allocator.building_blocks.kernighan_ritchie,-std.experimental.allocator.building_blocks.null_allocator,-std.experimental.allocator.building_blocks.quantizer,-std.experimental.allocator.building_blocks.region,-std.experimental.allocator.building_blocks.scoped_allocator,-std.experimental.allocator.building_blocks.segregator,-std.experimental.allocator.building_blocks.stats_collector,-std.experimental.allocator.common,-std.experimental.allocator.gc_allocator,-std.experimental.allocator.mallocator,-std.experimental.allocator.showcase,-std.experimental.allocator.typed,-std.experimental.checkedint,-std.experimental.logger.core,-std.experimental.logger.filelogger,-std.file,-std.format,-std.functional,-std.getopt,-std.internal.cstring,-std.internal.math.biguintcore,-std.internal.math.biguintnoasm,-std.internal.scopebuffer,-std.internal.test.dummyrange,-std.internal.unicode_tables,-std.json,-std.math,-std.mathspecial,-std.meta,-std.mmfile,-std.net.curl,-std.net.isemail,-std.numeric,-std.outbuffer,-std.parallelism,-std.path,-std.random,-std.range,-std.range.interfaces,-std.range.primitives,-std.regex,-std.regex.internal.backtracking,-std.regex.internal.ir,-std.regex.internal.kickstart,-std.regex.internal.parser,-std.regex.internal.thompson,-std.signals,-std.socket,-std.stdio,-std.string,-std.traits,-std.typecons,-std.uni,-std.uri,-std.utf,-std.uuid,-std.variant,-std.xml,-std.zip,-std.zlib" ; Check for redundant attributes redundant_attributes_check="-std.concurrency,-std.digest.md,-std.digest.ripemd,-std.digest.sha,-std.internal.math.biguintcore,-std.math,-std.meta,-std.range,-std.regex.internal.ir,-std.uni,-std.windows.registry" ; Check variable, class, struct, interface, union, and function names against ; the Phobos style guide style_check="+disabled" -;style_check="-etc.c.curl,-etc.c.odbc.sqlext,-etc.c.odbc.sqltypes,-etc.c.odbc.sqlucode,-etc.c.sqlite3,-etc.c.zlib,-std.algorithm.comparison,-std.algorithm.internal,-std.algorithm.iteration,-std.algorithm.mutation,-std.algorithm.sorting,-std.array,-std.base64,-std.bitmanip,-std.c.linux.linux,-std.compiler,-std.container.array,-std.conv,-std.datetime.date,-std.datetime.interval,-std.datetime.systime,-std.digest.digest,-std.digest.murmurhash,-std.digest.sha,-std.encoding,-std.exception,-std.experimental.allocator,-std.experimental.allocator.building_blocks.affix_allocator,-std.experimental.allocator.building_blocks.allocator_list,-std.experimental.allocator.building_blocks.bucketizer,-std.experimental.allocator.building_blocks.fallback_allocator,-std.experimental.allocator.building_blocks.free_list,-std.experimental.allocator.building_blocks.free_tree,-std.experimental.allocator.building_blocks.null_allocator,-std.experimental.allocator.building_blocks.region,-std.experimental.allocator.building_blocks.segregator,-std.experimental.allocator.common,-std.experimental.allocator.gc_allocator,-std.experimental.allocator.mallocator,-std.experimental.allocator.mmap_allocator,-std.experimental.checkedint,-std.experimental.typecons,-std.format,-std.functional,-std.getopt,-std.internal.digest.sha_SSSE3,-std.internal.math.errorfunction,-std.internal.math.gammafunction,-std.internal.test.dummyrange,-std.internal.unicode_tables,-std.json,-std.math,-std.meta,-std.numeric,-std.parallelism,-std.path,-std.process,-std.random,-std.range,-std.range.primitives,-std.regex,-std.regex.internal.ir,-std.regex.internal.kickstart,-std.signals,-std.socket,-std.stdio,-std.string,-std.uni,-std.uri,-std.utf,-std.uuid,-std.variant,-std.zlib" +;style_check="-etc.c.curl,-etc.c.odbc.sqlext,-etc.c.odbc.sqltypes,-etc.c.odbc.sqlucode,-etc.c.sqlite3,-etc.c.zlib,-std.algorithm.comparison,-std.algorithm.internal,-std.algorithm.iteration,-std.algorithm.mutation,-std.algorithm.sorting,-std.array,-std.base64,-std.bitmanip,-std.c.linux.linux,-std.compiler,-std.container.array,-std.conv,-std.datetime.date,-std.datetime.interval,-std.datetime.systime,-std.digest,-std.digest.murmurhash,-std.digest.sha,-std.encoding,-std.exception,-std.experimental.allocator,-std.experimental.allocator.building_blocks.affix_allocator,-std.experimental.allocator.building_blocks.allocator_list,-std.experimental.allocator.building_blocks.bucketizer,-std.experimental.allocator.building_blocks.fallback_allocator,-std.experimental.allocator.building_blocks.free_list,-std.experimental.allocator.building_blocks.free_tree,-std.experimental.allocator.building_blocks.null_allocator,-std.experimental.allocator.building_blocks.region,-std.experimental.allocator.building_blocks.segregator,-std.experimental.allocator.common,-std.experimental.allocator.gc_allocator,-std.experimental.allocator.mallocator,-std.experimental.allocator.mmap_allocator,-std.experimental.checkedint,-std.experimental.typecons,-std.format,-std.functional,-std.getopt,-std.internal.digest.sha_SSSE3,-std.internal.math.errorfunction,-std.internal.math.gammafunction,-std.internal.test.dummyrange,-std.internal.unicode_tables,-std.json,-std.math,-std.meta,-std.numeric,-std.parallelism,-std.path,-std.process,-std.random,-std.range,-std.range.primitives,-std.regex,-std.regex.internal.ir,-std.regex.internal.kickstart,-std.signals,-std.socket,-std.stdio,-std.string,-std.uni,-std.uri,-std.utf,-std.uuid,-std.variant,-std.zlib" ; Checks for undocumented public declarations -undocumented_declaration_check="-etc.c.curl,-etc.c.odbc.sql,-etc.c.odbc.sqlext,-etc.c.odbc.sqltypes,-etc.c.odbc.sqlucode,-etc.c.sqlite3,-etc.c.zlib,-std.algorithm.sorting,-std.array,-std.ascii,-std.base64,-std.bitmanip,-std.c.linux.linux,-std.c.linux.socket,-std.c.osx.socket,-std.c.process,-std.compiler,-std.complex,-std.concurrency,-std.container,-std.container.array,-std.container.binaryheap,-std.container.dlist,-std.container.rbtree,-std.container.slist,-std.conv,-std.csv,-std.datetime.date,-std.digest.digest,-std.digest.hmac,-std.digest.md,-std.digest.murmurhash,-std.digest.ripemd,-std.digest.sha,-std.encoding,-std.exception,-std.experimental.allocator,-std.experimental.allocator.building_blocks.affix_allocator,-std.experimental.allocator.building_blocks.allocator_list,-std.experimental.allocator.building_blocks.bitmapped_block,-std.experimental.allocator.building_blocks.fallback_allocator,-std.experimental.allocator.building_blocks.free_list,-std.experimental.allocator.building_blocks.free_tree,-std.experimental.allocator.building_blocks.kernighan_ritchie,-std.experimental.allocator.building_blocks.quantizer,-std.experimental.allocator.building_blocks.region,-std.experimental.allocator.building_blocks.segregator,-std.experimental.allocator.building_blocks.stats_collector,-std.experimental.allocator.gc_allocator,-std.experimental.allocator.mallocator,-std.experimental.checkedint,-std.experimental.logger.core,-std.experimental.typecons,-std.file,-std.format,-std.functional,-std.internal.digest.sha_SSSE3,-std.internal.math.biguintcore,-std.internal.math.biguintnoasm,-std.internal.math.biguintx86,-std.internal.math.errorfunction,-std.internal.math.gammafunction,-std.internal.test.dummyrange,-std.internal.test.uda,-std.internal.windows.advapi32,-std.json,-std.math,-std.mmfile,-std.numeric,-std.outbuffer,-std.parallelism,-std.path,-std.process,-std.regex,-std.regex.internal.parser,-std.signals,-std.socket,-std.stdio,-std.string,-std.system,-std.traits,-std.uni,-std.utf,-std.variant,-std.windows.charset,-std.windows.registry,-std.windows.syserror,-std.xml,-std.zip,-std.zlib" +undocumented_declaration_check="-etc.c.curl,-etc.c.odbc.sql,-etc.c.odbc.sqlext,-etc.c.odbc.sqltypes,-etc.c.odbc.sqlucode,-etc.c.sqlite3,-etc.c.zlib,-std.algorithm.sorting,-std.array,-std.ascii,-std.base64,-std.bitmanip,-std.c.linux.linux,-std.c.linux.socket,-std.c.osx.socket,-std.c.process,-std.compiler,-std.complex,-std.concurrency,-std.container,-std.container.array,-std.container.binaryheap,-std.container.dlist,-std.container.rbtree,-std.container.slist,-std.conv,-std.csv,-std.datetime.date,-std.digest,-std.digest.hmac,-std.digest.md,-std.digest.murmurhash,-std.digest.ripemd,-std.digest.sha,-std.encoding,-std.exception,-std.experimental.allocator,-std.experimental.allocator.building_blocks.affix_allocator,-std.experimental.allocator.building_blocks.allocator_list,-std.experimental.allocator.building_blocks.bitmapped_block,-std.experimental.allocator.building_blocks.fallback_allocator,-std.experimental.allocator.building_blocks.free_list,-std.experimental.allocator.building_blocks.free_tree,-std.experimental.allocator.building_blocks.kernighan_ritchie,-std.experimental.allocator.building_blocks.quantizer,-std.experimental.allocator.building_blocks.region,-std.experimental.allocator.building_blocks.segregator,-std.experimental.allocator.building_blocks.stats_collector,-std.experimental.allocator.gc_allocator,-std.experimental.allocator.mallocator,-std.experimental.checkedint,-std.experimental.logger.core,-std.experimental.typecons,-std.file,-std.format,-std.functional,-std.internal.digest.sha_SSSE3,-std.internal.math.biguintcore,-std.internal.math.biguintnoasm,-std.internal.math.biguintx86,-std.internal.math.errorfunction,-std.internal.math.gammafunction,-std.internal.test.dummyrange,-std.internal.test.uda,-std.internal.windows.advapi32,-std.json,-std.math,-std.mmfile,-std.numeric,-std.outbuffer,-std.parallelism,-std.path,-std.process,-std.regex,-std.regex.internal.parser,-std.signals,-std.socket,-std.stdio,-std.string,-std.system,-std.traits,-std.uni,-std.utf,-std.variant,-std.windows.charset,-std.windows.registry,-std.windows.syserror,-std.xml,-std.zip,-std.zlib" ; Checks for unused labels unused_label_check="-std.conv,-std.format,-std.internal.math.biguintx86,-std.regex.internal.thompson,-std.signals,-std.uni" ; Checks for unused variables and function parameters -unused_variable_check="-std.algorithm.comparison,-std.algorithm.iteration,-std.algorithm.mutation,-std.algorithm.searching,-std.algorithm.setops,-std.algorithm.sorting,-std.array,-std.bigint,-std.bitmanip,-std.complex,-std.concurrency,-std.container,-std.container.array,-std.container.dlist,-std.container.rbtree,-std.container.slist,-std.conv,-std.csv,-std.datetime,-std.datetime.date,-std.datetime.interval,-std.datetime.stopwatch,-std.datetime.systime,-std.datetime.timezone,-std.digest.crc,-std.digest.digest,-std.digest.md,-std.digest.murmurhash,-std.digest.ripemd,-std.digest.sha,-std.encoding,-std.exception,-std.experimental.allocator,-std.experimental.allocator.building_blocks.affix_allocator,-std.experimental.allocator.building_blocks.bitmapped_block,-std.experimental.allocator.building_blocks.bucketizer,-std.experimental.allocator.building_blocks.kernighan_ritchie,-std.experimental.allocator.building_blocks.stats_collector,-std.experimental.allocator.common,-std.experimental.allocator.gc_allocator,-std.experimental.allocator.mallocator,-std.experimental.allocator.typed,-std.experimental.checkedint,-std.experimental.logger.core,-std.experimental.typecons,-std.file,-std.format,-std.functional,-std.getopt,-std.internal.cstring,-std.internal.digest.sha_SSSE3,-std.internal.math.biguintcore,-std.internal.math.biguintx86,-std.internal.math.errorfunction,-std.internal.scopebuffer,-std.internal.test.dummyrange,-std.json,-std.math,-std.meta,-std.mmfile,-std.net.curl,-std.numeric,-std.parallelism,-std.process,-std.random,-std.range,-std.range.interfaces,-std.range.primitives,-std.regex.internal.backtracking,-std.regex.internal.tests,-std.regex.internal.thompson,-std.signals,-std.socket,-std.stdio,-std.string,-std.traits,-std.typecons,-std.uni,-std.uri,-std.utf,-std.uuid,-std.variant,-std.windows.registry,-std.xml,-std.zip,-std.zlib" +unused_variable_check="-std.algorithm.comparison,-std.algorithm.iteration,-std.algorithm.mutation,-std.algorithm.searching,-std.algorithm.setops,-std.algorithm.sorting,-std.array,-std.bigint,-std.bitmanip,-std.complex,-std.concurrency,-std.container,-std.container.array,-std.container.dlist,-std.container.rbtree,-std.container.slist,-std.conv,-std.csv,-std.datetime,-std.datetime.date,-std.datetime.interval,-std.datetime.stopwatch,-std.datetime.systime,-std.datetime.timezone,-std.digest.crc,-std.digest,-std.digest.md,-std.digest.murmurhash,-std.digest.ripemd,-std.digest.sha,-std.encoding,-std.exception,-std.experimental.allocator,-std.experimental.allocator.building_blocks.affix_allocator,-std.experimental.allocator.building_blocks.bitmapped_block,-std.experimental.allocator.building_blocks.bucketizer,-std.experimental.allocator.building_blocks.kernighan_ritchie,-std.experimental.allocator.building_blocks.stats_collector,-std.experimental.allocator.common,-std.experimental.allocator.gc_allocator,-std.experimental.allocator.mallocator,-std.experimental.allocator.typed,-std.experimental.checkedint,-std.experimental.logger.core,-std.experimental.typecons,-std.file,-std.format,-std.functional,-std.getopt,-std.internal.cstring,-std.internal.digest.sha_SSSE3,-std.internal.math.biguintcore,-std.internal.math.biguintx86,-std.internal.math.errorfunction,-std.internal.scopebuffer,-std.internal.test.dummyrange,-std.json,-std.math,-std.meta,-std.mmfile,-std.net.curl,-std.numeric,-std.parallelism,-std.process,-std.random,-std.range,-std.range.interfaces,-std.range.primitives,-std.regex.internal.backtracking,-std.regex.internal.tests,-std.regex.internal.thompson,-std.signals,-std.socket,-std.stdio,-std.string,-std.traits,-std.typecons,-std.uni,-std.uri,-std.utf,-std.uuid,-std.variant,-std.windows.registry,-std.xml,-std.zip,-std.zlib" ; Check for useless user defined initializers useless_initializer="+disabled" ;useless_initializer="-etc.c.odbc.sqlext,-etc.c.zlib,-std.algorithm.iteration,-std.algorithm.mutation,-std.algorithm.searching,-std.algorithm.setops,-std.algorithm.sorting,-std.array,-std.bigint,-std.bitmanip,-std.compiler,-std.container.array,-std.container.dlist,-std.container.rbtree,-std.conv,-std.csv,-std.datetime.systime,-std.digest.md,-std.digest.murmurhash,-std.digest.ripemd,-std.encoding,-std.exception,-std.experimental.allocator,-std.experimental.allocator.building_blocks.bitmapped_block,-std.experimental.allocator.building_blocks.free_tree,-std.experimental.allocator.building_blocks.kernighan_ritchie,-std.experimental.allocator.common,-std.experimental.allocator.mallocator,-std.experimental.logger.core,-std.experimental.logger.multilogger,-std.file,-std.format,-std.functional,-std.getopt,-std.internal.cstring,-std.internal.digest.sha_SSSE3,-std.internal.math.biguintcore,-std.internal.math.biguintnoasm,-std.internal.math.biguintx86,-std.internal.math.gammafunction,-std.internal.test.dummyrange,-std.json,-std.math,-std.net.curl,-std.numeric,-std.parallelism,-std.path,-std.process,-std.random,-std.range,-std.range.interfaces,-std.range.primitives,-std.regex,-std.regex.internal.backtracking,-std.regex.internal.generator,-std.regex.internal.ir,-std.regex.internal.kickstart,-std.regex.internal.parser,-std.regex.internal.tests,-std.regex.internal.thompson,-std.signals,-std.socket,-std.stdio,-std.string,-std.uni,-std.uri,-std.utf,-std.uuid,-std.variant,-std.windows.registry,-std.windows.syserror,-std.xml,-std.zip,-std.zlib" From 0c41d96b136184d52963e013c1d5a9b740b10c3a Mon Sep 17 00:00:00 2001 From: cjoan Date: Thu, 6 Jul 2017 02:55:09 -0400 Subject: [PATCH 118/163] Bugfix for "undefined identifier _min" in SharedFreeList. When instantiating SharedFreeList with a 0 minSize and a chooseAtRuntime maxSize, it will give an error like so: std/experimental/allocator/building_blocks/free_list.d(822): Error: undefined identifier _min, did you mean alias min? This commit resolves the error message by using 'min' instead of '_min', because '_min' is only available when (minSize == chooseAtRuntime). --- .../allocator/building_blocks/free_list.d | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/std/experimental/allocator/building_blocks/free_list.d b/std/experimental/allocator/building_blocks/free_list.d index c43b080a035..25f739c1f6d 100644 --- a/std/experimental/allocator/building_blocks/free_list.d +++ b/std/experimental/allocator/building_blocks/free_list.d @@ -817,7 +817,7 @@ struct SharedFreeList(ParentAllocator, @property size_t max() const shared { return _max; } @property void max(size_t x) shared { - enforce(x >= _min && x >= (void*).sizeof); + enforce(x >= min && x >= (void*).sizeof); enforce(cas(&_max, chooseAtRuntime, x), "SharedFreeList.max must be initialized exactly once."); } @@ -1095,6 +1095,7 @@ struct SharedFreeList(ParentAllocator, { import std.experimental.allocator.mallocator : Mallocator; shared SharedFreeList!(Mallocator, chooseAtRuntime, chooseAtRuntime) a; + scope(exit) a.deallocateAll(); auto c = a.allocate(64); assert(a.reallocate(c, 96)); assert(c.length == 96); @@ -1105,6 +1106,7 @@ struct SharedFreeList(ParentAllocator, { import std.experimental.allocator.mallocator : Mallocator; shared SharedFreeList!(Mallocator, chooseAtRuntime, chooseAtRuntime, chooseAtRuntime) a; + scope(exit) a.deallocateAll; a.allocate(64); } @@ -1112,6 +1114,7 @@ struct SharedFreeList(ParentAllocator, { import std.experimental.allocator.mallocator : Mallocator; shared SharedFreeList!(Mallocator, 30, 40) a; + scope(exit) a.deallocateAll; a.allocate(64); } @@ -1119,5 +1122,26 @@ struct SharedFreeList(ParentAllocator, { import std.experimental.allocator.mallocator : Mallocator; shared SharedFreeList!(Mallocator, 30, 40, chooseAtRuntime) a; + scope(exit) a.deallocateAll; + a.allocate(64); +} + +@system unittest +{ + // Pull request #5556 + import std.experimental.allocator.mallocator : Mallocator; + shared SharedFreeList!(Mallocator, 0, chooseAtRuntime) a; + scope(exit) a.deallocateAll; + a.max = 64; + a.allocate(64); +} + +@system unittest +{ + // Pull request #5556 + import std.experimental.allocator.mallocator : Mallocator; + shared SharedFreeList!(Mallocator, chooseAtRuntime, 64) a; + scope(exit) a.deallocateAll; + a.min = 32; a.allocate(64); } From b875d70e97ced92baee0e0456a75adcb1ffc9b14 Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Mon, 10 Jul 2017 02:00:29 +0200 Subject: [PATCH 119/163] Make digest.hmac @safe --- std/digest/hmac.d | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/std/digest/hmac.d b/std/digest/hmac.d index a2689d1555b..0e3d8f3b8d2 100644 --- a/std/digest/hmac.d +++ b/std/digest/hmac.d @@ -19,6 +19,8 @@ module std.digest.hmac; import std.digest : isDigest, hasBlockSize, isDigestibleRange, DigestType; import std.meta : allSatisfy; +@safe: + /** * Template API HMAC implementation. * @@ -258,15 +260,15 @@ if (isDigest!H) DigestType!H hmac(T...)(scope T data, scope const(ubyte)[] secret) if (allSatisfy!(isDigestibleRange, typeof(data))) { - import std.algorithm.mutation : copy; + import std.range.primitives : put; auto hash = HMAC!(H, blockSize)(secret); foreach (datum; data) - copy(datum, &hash); + put(hash, datum); return hash.finish(); } /// - @system pure nothrow @nogc unittest + @safe pure nothrow @nogc unittest { import std.algorithm.iteration : map; import std.digest.hmac, std.digest.sha; @@ -300,7 +302,7 @@ unittest static assert(hasBlockSize!(HMAC!MD5) && HMAC!MD5.blockSize == MD5.blockSize); } -@system pure nothrow +@safe pure nothrow unittest { import std.digest.md : MD5; From de8de6faecdd8249e408c55a3ff55a11d90d6d08 Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Mon, 10 Jul 2017 02:01:06 +0200 Subject: [PATCH 120/163] Make module unittest runnable --- posix.mak | 2 +- std/digest/hmac.d | 15 ++++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/posix.mak b/posix.mak index dbba3ce3362..08fc17c3aa6 100644 --- a/posix.mak +++ b/posix.mak @@ -264,7 +264,7 @@ SHARED=$(if $(findstring $(OS),linux freebsd),1,) IGNORED_PUBLICTESTS= $(addprefix std/, \ $(addprefix experimental/allocator/, \ building_blocks/free_list building_blocks/quantizer \ - ) digest/hmac \ + ) \ math stdio traits) PUBLICTESTS= $(addsuffix .publictests,$(filter-out $(IGNORED_PUBLICTESTS), $(D_MODULES))) TESTS_EXTRACTOR=$(ROOT)/tests_extractor diff --git a/std/digest/hmac.d b/std/digest/hmac.d index 0e3d8f3b8d2..a3ec2c81a8c 100644 --- a/std/digest/hmac.d +++ b/std/digest/hmac.d @@ -31,18 +31,19 @@ import std.meta : allSatisfy; * This type conforms to $(REF isDigest, std,digest). */ -version(StdDdoc) -/// Computes an HMAC over data read from stdin. +/// Compute HMAC over an input string @safe unittest { - import std.digest.hmac, std.digest.sha, std.stdio; + import std.ascii : LetterCase; + import std.digest : toHexString; + import std.digest.sha : SHA1; import std.string : representation; auto secret = "secret".representation; - stdin.byChunk(4096) - .hmac!SHA1(secret) - .toHexString!(LetterCase.lower) - .writeln; + assert("The quick brown fox jumps over the lazy dog" + .representation + .hmac!SHA1(secret) + .toHexString!(LetterCase.lower) == "198ea1ea04c435c1246b586a06d5cf11c3ffcda6"); } template HMAC(H) From 24df657e2451f54f3dd6575fdff7c9075d7eac17 Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Fri, 7 Jul 2017 22:02:46 +0200 Subject: [PATCH 121/163] Add initial version of a CODEOWNERS mapping --- CODEOWNERS | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 CODEOWNERS diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 00000000000..a84bc629884 --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1,76 @@ +# See also: +# - https://github.com/blog/2392-introducing-code-owners +# - https://help.github.com/articles/about-codeowners/ + +# Each line is a file pattern followed by one or more owners (sorted alphabetically). +# Please feel free to add yourself to a module or create a new mapping. +# Ideally each module should have two or more owners. + +# Code owners are automatically requested for review +# when someone opens a pull request that modifies code that they own. +# Later matches take precedence. + +.dscanner.ini @wilzbach +circleci.sh @CyberShadow @MartinNowak @wilzbach +etc/c/* @CyberShadow +posix.mak @CyberShadow @MartinNowak @wilzbach +std/* @andralex +std/algorithm/* @andralex @JackStouffer @wilzbach @ZombineDev +std/array.d @JackStouffer @wilzbach @ZombineDev +std/ascii.d @JackStouffer @wilzbach +#std/base64.d +std/bigint.d @Biotronic +#std/bitmanip.d +std/c/windows/* @CyberShadow +#std/compiler.d +std/complex.d @kyllingstad +std/concurrency.d @MartinNowak +std/container/ @ZombineDev +std/conv.d @JackStouffer +#std/csv.d +std/datetime/* @jmdavis +std/demangle.d @MartinNowak @rainers +std/digest/* @jpf91 +#std/encoding.d +#std/exception.d +std/experimental/allocator/* @andralex @wilzbach @ZombineDev +std/experimental/checkedint/* @andralex +std/experimental/logger/* @burner +#std/experimental/typecons.d +std/file.d @CyberShadow +#std/format.d +#std/functional.d +#std/getopt.d +#std/internal/ +std/json.d @CyberShadow +std/math* @Biotronic @ibuclaw @klickverbot +std/meta.d @Biotronic @klickverbot @MetaLang @ZombineDev +#std/mmfile.d +std/net/curl.d @CyberShadow +std/net/isemail.d @JackStouffer +#std/numeric.d +#std/outbuffer.d +#std/parallelism.d +std/path.d @CyberShadow @kyllingstad +std/process.d @CyberShadow @kyllingstad @schveiguy +std/random.d @WebDrake @wilzbach +std/range/* @andralex @JackStouffer @wilzbach @ZombineDev +std/regex/* @DmitryOlshansky +#std/signals.d +std/socket.d @CyberShadow @klickverbot +#std/stdint.d +std/stdio.d @CyberShadow @schveiguy +std/string.d @burner @JackStouffer +#std/system.d +std/traits.d @Biotronic @klickverbot @ZombineDev +std/typecons.d @Biotronic @MetaLang @ZombineDev +#std/typetuple.d +std/uni.d @DmitryOlshansky +#std/uri.d +std/utf.d @jmdavis +std/uuid.d @jpf91 +#std/variant.d +std/windows/* @CyberShadow +#std/xml.d +std/zip.d * @CyberShadow +std/zlib.d * @CyberShadow From 70f06b23576eeccd0b079665283abdae3e7e4be8 Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Thu, 6 Jul 2017 00:32:32 +0200 Subject: [PATCH 122/163] Remove old, redundant private import access specifier Very very old versions of D (well into 0.x) had imports public by default, like C header files. This modernizes the codebase and removes the redundant `private` access specifier. This has been done with: sed "s/private import/import/g" -i **/*.d --- etc/c/curl.d | 2 +- etc/c/odbc/sqlext.d | 4 +-- std/bigint.d | 8 +++--- std/c/linux/socket.d | 2 +- std/c/osx/socket.d | 2 +- std/c/process.d | 2 +- .../allocator/building_blocks/region.d | 2 +- .../building_blocks/scoped_allocator.d | 4 +-- std/experimental/allocator/showcase.d | 6 ++--- std/internal/math/biguintcore.d | 10 +++---- std/internal/scopebuffer.d | 4 +-- std/internal/windows/advapi32.d | 2 +- std/mathspecial.d | 4 +-- std/mmfile.d | 26 +++++++++---------- std/socket.d | 22 ++++++++-------- std/typecons.d | 2 +- std/uni.d | 2 +- std/uri.d | 4 +-- std/windows/charset.d | 8 +++--- std/windows/registry.d | 6 ++--- std/zlib.d | 4 +-- 21 files changed, 63 insertions(+), 63 deletions(-) diff --git a/etc/c/curl.d b/etc/c/curl.d index f5c709f0c07..65c56c49e5b 100644 --- a/etc/c/curl.d +++ b/etc/c/curl.d @@ -117,7 +117,7 @@ alias curl_socket_t = socket_t; /// jdrewsen - Would like to get socket error constant from std.socket by it is private atm. version(Windows) { - private import core.sys.windows.windows, core.sys.windows.winsock2; + import core.sys.windows.windows, core.sys.windows.winsock2; enum CURL_SOCKET_BAD = SOCKET_ERROR; } version(Posix) enum CURL_SOCKET_BAD = -1; diff --git a/etc/c/odbc/sqlext.d b/etc/c/odbc/sqlext.d index c54ce29de1a..323ce568242 100644 --- a/etc/c/odbc/sqlext.d +++ b/etc/c/odbc/sqlext.d @@ -14,8 +14,8 @@ See_Also: $(LINK2 https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/odb module etc.c.odbc.sqlext; -private import etc.c.odbc.sql; -private import etc.c.odbc.sqltypes; +import etc.c.odbc.sql; +import etc.c.odbc.sqltypes; extern (Windows): diff --git a/std/bigint.d b/std/bigint.d index 861df64b1ce..a5e96b17e47 100644 --- a/std/bigint.d +++ b/std/bigint.d @@ -27,10 +27,10 @@ module std.bigint; import std.conv : ConvException; -private import std.format : FormatSpec, FormatException; -private import std.internal.math.biguintcore; -private import std.range.primitives; -private import std.traits; +import std.format : FormatSpec, FormatException; +import std.internal.math.biguintcore; +import std.range.primitives; +import std.traits; /** A struct representing an arbitrary precision integer. * diff --git a/std/c/linux/socket.d b/std/c/linux/socket.d index fcc577d1cd2..2e677c8b06a 100644 --- a/std/c/linux/socket.d +++ b/std/c/linux/socket.d @@ -13,7 +13,7 @@ deprecated("Import the appropriate core.sys.posix.* modules instead") module std.c.linux.socket; version (linux): -private import core.stdc.stdint; +import core.stdc.stdint; public import core.sys.posix.arpa.inet; public import core.sys.posix.netdb; public import core.sys.posix.netinet.in_; diff --git a/std/c/osx/socket.d b/std/c/osx/socket.d index 167af36a88e..4921e07a473 100644 --- a/std/c/osx/socket.d +++ b/std/c/osx/socket.d @@ -13,7 +13,7 @@ deprecated("Import the appropriate core.sys.posix.* instead") module std.c.osx.socket; version (OSX): -private import core.stdc.stdint; +import core.stdc.stdint; public import core.sys.posix.arpa.inet; public import core.sys.posix.netdb; public import core.sys.posix.netinet.in_; diff --git a/std/c/process.d b/std/c/process.d index 14fc729c6c7..bafe962ebbe 100644 --- a/std/c/process.d +++ b/std/c/process.d @@ -12,7 +12,7 @@ deprecated("Import core.stdc.stdlib or the appropriate core.sys.posix.* modules instead") module std.c.process; -private import core.stdc.stddef; +import core.stdc.stddef; public import core.stdc.stdlib : exit, abort, system; extern (C): diff --git a/std/experimental/allocator/building_blocks/region.d b/std/experimental/allocator/building_blocks/region.d index 0cc60b9dd58..37dd1b42e34 100644 --- a/std/experimental/allocator/building_blocks/region.d +++ b/std/experimental/allocator/building_blocks/region.d @@ -591,7 +591,7 @@ SbrkRegion) adversely. */ version(Posix) struct SbrkRegion(uint minAlign = platformAlignment) { - private import core.sys.posix.pthread : pthread_mutex_init, pthread_mutex_destroy, + import core.sys.posix.pthread : pthread_mutex_init, pthread_mutex_destroy, pthread_mutex_t, pthread_mutex_lock, pthread_mutex_unlock, PTHREAD_MUTEX_INITIALIZER; private static shared pthread_mutex_t sbrkMutex = PTHREAD_MUTEX_INITIALIZER; diff --git a/std/experimental/allocator/building_blocks/scoped_allocator.d b/std/experimental/allocator/building_blocks/scoped_allocator.d index 998a05f2894..ff3261f3e05 100644 --- a/std/experimental/allocator/building_blocks/scoped_allocator.d +++ b/std/experimental/allocator/building_blocks/scoped_allocator.d @@ -22,9 +22,9 @@ struct ScopedAllocator(ParentAllocator) testAllocator!(() => ScopedAllocator()); } - private import std.experimental.allocator.building_blocks.affix_allocator + import std.experimental.allocator.building_blocks.affix_allocator : AffixAllocator; - private import std.traits : hasMember; + import std.traits : hasMember; import std.typecons : Ternary; private struct Node diff --git a/std/experimental/allocator/showcase.d b/std/experimental/allocator/showcase.d index 84bad447671..6985e5dad14 100644 --- a/std/experimental/allocator/showcase.d +++ b/std/experimental/allocator/showcase.d @@ -61,10 +61,10 @@ auto mmapRegionList(size_t bytesPerRegion) static struct Factory { size_t bytesPerRegion; - private import std.algorithm.comparison : max; - private import std.experimental.allocator.building_blocks.region + import std.algorithm.comparison : max; + import std.experimental.allocator.building_blocks.region : Region; - private import std.experimental.allocator.mmap_allocator + import std.experimental.allocator.mmap_allocator : MmapAllocator; this(size_t n) { diff --git a/std/internal/math/biguintcore.d b/std/internal/math/biguintcore.d index 6391a70a9f2..9048336e9c2 100644 --- a/std/internal/math/biguintcore.d +++ b/std/internal/math/biguintcore.d @@ -46,10 +46,10 @@ alias multibyteAdd = multibyteAddSub!('+'); alias multibyteSub = multibyteAddSub!('-'); -private import core.cpuid; +import core.cpuid; public import std.ascii : LetterCase; -private import std.range.primitives; -private import std.traits; +import std.range.primitives; +import std.traits; shared static this() { @@ -75,8 +75,8 @@ else static if (BigDigit.sizeof == long.sizeof) } else static assert(0, "Unsupported BigDigit size"); -private import std.exception : assumeUnique; -private import std.traits : isIntegral; +import std.exception : assumeUnique; +import std.traits : isIntegral; enum BigDigitBits = BigDigit.sizeof*8; template maxBigDigits(T) if (isIntegral!T) diff --git a/std/internal/scopebuffer.d b/std/internal/scopebuffer.d index 8d7548a6eb2..70a7c8d1202 100644 --- a/std/internal/scopebuffer.d +++ b/std/internal/scopebuffer.d @@ -10,8 +10,8 @@ module std.internal.scopebuffer; //debug=ScopeBuffer; -private import core.stdc.stdlib : realloc; -private import std.traits; +import core.stdc.stdlib : realloc; +import std.traits; /************************************** * ScopeBuffer encapsulates using a local array as a temporary buffer. diff --git a/std/internal/windows/advapi32.d b/std/internal/windows/advapi32.d index d5d04fd1b9b..386c0a9b1d4 100644 --- a/std/internal/windows/advapi32.d +++ b/std/internal/windows/advapi32.d @@ -12,7 +12,7 @@ module std.internal.windows.advapi32; version(Windows): -private import core.sys.windows.windows; +import core.sys.windows.windows; pragma(lib, "advapi32.lib"); diff --git a/std/mathspecial.d b/std/mathspecial.d index 4b85189e94c..e35c74cc5aa 100644 --- a/std/mathspecial.d +++ b/std/mathspecial.d @@ -53,8 +53,8 @@ * Source: $(PHOBOSSRC std/_mathspecial.d) */ module std.mathspecial; -private import std.internal.math.errorfunction; -private import std.internal.math.gammafunction; +import std.internal.math.errorfunction; +import std.internal.math.gammafunction; public import std.math; /* *********************************************** diff --git a/std/mmfile.d b/std/mmfile.d index 627abb37629..a8fdeb39102 100644 --- a/std/mmfile.d +++ b/std/mmfile.d @@ -17,13 +17,13 @@ */ module std.mmfile; -private import core.stdc.errno; -private import core.stdc.stdio; -private import core.stdc.stdlib; +import core.stdc.errno; +import core.stdc.stdio; +import core.stdc.stdlib; import std.conv, std.exception, std.stdio; -private import std.file; -private import std.path; -private import std.string; +import std.file; +import std.path; +import std.string; import std.internal.cstring; @@ -31,16 +31,16 @@ import std.internal.cstring; version (Windows) { - private import core.sys.windows.windows; - private import std.utf; - private import std.windows.syserror; + import core.sys.windows.windows; + import std.utf; + import std.windows.syserror; } else version (Posix) { - private import core.sys.posix.fcntl; - private import core.sys.posix.sys.mman; - private import core.sys.posix.sys.stat; - private import core.sys.posix.unistd; + import core.sys.posix.fcntl; + import core.sys.posix.sys.mman; + import core.sys.posix.sys.stat; + import core.sys.posix.unistd; } else { diff --git a/std/socket.d b/std/socket.d index a375e2ee058..608e1a4d612 100644 --- a/std/socket.d +++ b/std/socket.d @@ -60,7 +60,7 @@ version(Windows) pragma (lib, "ws2_32.lib"); pragma (lib, "wsock32.lib"); - private import core.sys.windows.windows, std.windows.syserror; + import core.sys.windows.windows, std.windows.syserror; public import core.sys.windows.winsock2; private alias _ctimeval = core.sys.windows.winsock2.timeval; private alias _clinger = core.sys.windows.winsock2.linger; @@ -85,20 +85,20 @@ else version(Posix) } } - private import core.sys.posix.arpa.inet; - private import core.sys.posix.fcntl; + import core.sys.posix.arpa.inet; + import core.sys.posix.fcntl; import core.sys.posix.netdb; - private import core.sys.posix.netinet.in_; - private import core.sys.posix.netinet.tcp; - private import core.sys.posix.sys.select; - private import core.sys.posix.sys.socket; - private import core.sys.posix.sys.time; + import core.sys.posix.netinet.in_; + import core.sys.posix.netinet.tcp; + import core.sys.posix.sys.select; + import core.sys.posix.sys.socket; + import core.sys.posix.sys.time; import core.sys.posix.sys.un : sockaddr_un; - private import core.sys.posix.unistd; + import core.sys.posix.unistd; private alias _ctimeval = core.sys.posix.sys.time.timeval; private alias _clinger = core.sys.posix.sys.socket.linger; - private import core.stdc.errno; + import core.stdc.errno; enum socket_t : int32_t { init = -1 } private const int _SOCKET_ERROR = -1; @@ -125,7 +125,7 @@ version(unittest) static assert(is(uint32_t == uint)); static assert(is(uint16_t == ushort)); - private import std.stdio : writefln; + import std.stdio : writefln; // Print a message on exception instead of failing the unittest. private void softUnittest(void delegate() @safe test, int line = __LINE__) @trusted diff --git a/std/typecons.d b/std/typecons.d index c69b77c99e6..3a1fe7926cd 100644 --- a/std/typecons.d +++ b/std/typecons.d @@ -5729,7 +5729,7 @@ mixin template Proxy(alias a) static if (!is(typeof(this) == class)) { - private import std.traits; + import std.traits; static if (isAssignable!ValueType) { auto ref opAssign(this X)(auto ref typeof(this) v) diff --git a/std/uni.d b/std/uni.d index 33407dc5868..58923be53d4 100644 --- a/std/uni.d +++ b/std/uni.d @@ -2436,7 +2436,7 @@ public: --- */ - private import std.format : FormatException, FormatSpec; + import std.format : FormatException, FormatSpec; /*************************************** * Obtain a textual representation of this InversionList diff --git a/std/uri.d b/std/uri.d index 75208e1982c..0852955a9b8 100644 --- a/std/uri.d +++ b/std/uri.d @@ -24,8 +24,8 @@ module std.uri; //debug=uri; // uncomment to turn on debugging writefln's -debug(uri) private import std.stdio; -private import std.traits : isSomeChar; +debug(uri) import std.stdio; +import std.traits : isSomeChar; /** This Exception is thrown if something goes wrong when encoding or decoding a URI. diff --git a/std/windows/charset.d b/std/windows/charset.d index 67bd99da1ad..ee7211d446b 100644 --- a/std/windows/charset.d +++ b/std/windows/charset.d @@ -50,10 +50,10 @@ else: version (Windows): -private import core.sys.windows.windows; -private import std.conv; -private import std.string; -private import std.windows.syserror; +import core.sys.windows.windows; +import std.conv; +import std.string; +import std.windows.syserror; import std.internal.cstring; diff --git a/std/windows/registry.d b/std/windows/registry.d index e600c852213..073e568df65 100644 --- a/std/windows/registry.d +++ b/std/windows/registry.d @@ -43,7 +43,7 @@ import std.array; import std.conv; import std.exception; import std.internal.cstring; -private import std.internal.windows.advapi32; +import std.internal.windows.advapi32; import std.system : Endian, endian; import std.windows.syserror; @@ -223,7 +223,7 @@ enum REG_VALUE_TYPE : DWORD /* ************* private *************** */ -private import core.sys.windows.winnt : +import core.sys.windows.winnt : DELETE , READ_CONTROL , WRITE_DAC , @@ -240,7 +240,7 @@ private import core.sys.windows.winnt : SPECIFIC_RIGHTS_ALL ; -private import core.sys.windows.winreg : +import core.sys.windows.winreg : REG_CREATED_NEW_KEY , REG_OPENED_EXISTING_KEY ; diff --git a/std/zlib.d b/std/zlib.d index 7965f3055b0..e6cce240fd5 100644 --- a/std/zlib.d +++ b/std/zlib.d @@ -674,8 +674,8 @@ class UnCompress /* ========================== unittest ========================= */ -private import std.random; -private import std.stdio; +import std.random; +import std.stdio; @system unittest // by Dave { From e8806ada8fe34dbed3c8b716f2eee2f5fad69e4d Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Thu, 6 Jul 2017 00:59:53 +0200 Subject: [PATCH 123/163] Remove redundant public: labels in std.uni + move FormatException import into unittest --- std/uni.d | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/std/uni.d b/std/uni.d index 58923be53d4..88307e6e00a 100644 --- a/std/uni.d +++ b/std/uni.d @@ -2069,8 +2069,6 @@ pure: { import std.range : assumeSorted; -public: - /** Construct from another code point set of any type. */ @@ -2436,7 +2434,7 @@ public: --- */ - import std.format : FormatException, FormatSpec; + private import std.format : FormatSpec; /*************************************** * Obtain a textual representation of this InversionList @@ -2495,7 +2493,7 @@ public: @safe unittest { import std.exception : assertThrown; - import std.format : format; + import std.format : format, FormatException; assertThrown!FormatException(format("%a", unicode.ASCII)); } From 57ef9199632b8cb5451f9d7d8c76aad29410db84 Mon Sep 17 00:00:00 2001 From: Jonathan M Davis Date: Tue, 11 Jul 2017 05:36:40 -0600 Subject: [PATCH 124/163] Fix issue 16993: Clarify documentation of std.datetime's toString functions. I should have done this years ago, but this makes the documentation clear that std.datetime's toString is intended simply for easy printing of the type rather than for code that actually cares about the format of the string. There are other, explicit functions for code that actually cares. --- std/datetime/date.d | 66 ++++++++++++++++++++++++++++++++++++++---- std/datetime/systime.d | 20 +++++++++++++ 2 files changed, 80 insertions(+), 6 deletions(-) diff --git a/std/datetime/date.d b/std/datetime/date.d index e5df2d60b97..ca1b0b644fa 100644 --- a/std/datetime/date.d +++ b/std/datetime/date.d @@ -3048,6 +3048,26 @@ public: /++ Converts this $(LREF DateTime) to a string. + + This function exists to make it easy to convert a $(LREF DateTime) to a + string for code that does not care what the exact format is - just that + it presents the information in a clear manner. It also makes it easy to + simply convert a $(LREF DateTime) to a string when using functions such + as `to!string`, `format`, or `writeln` which use toString to convert + user-defined types. So, it is unlikely that much code will call + toString directly. + + The format of the string is purposefully unspecified, and code that + cares about the format of the string should use `toISOString`, + `toISOExtString`, `toSimpleString`, or some other custom formatting + function that explicitly generates the format that the code needs. The + reason is that the code is then clear about what format it's using, + making it less error-prone to maintain the code and interact with other + software that consumes the generated strings. It's for this same reason + that $(LREF DateTime) has no `fromString` function, whereas it does have + `fromISOString`, `fromISOExtString`, and `fromSimpleString`. + + The format returned by toString may or may not change in the future. +/ string toString() const @safe pure nothrow { @@ -7281,18 +7301,32 @@ public: /++ Converts this $(LREF Date) to a string. + + This function exists to make it easy to convert a $(LREF Date) to a + string for code that does not care what the exact format is - just that + it presents the information in a clear manner. It also makes it easy to + simply convert a $(LREF Date) to a string when using functions such as + `to!string`, `format`, or `writeln` which use toString to convert + user-defined types. So, it is unlikely that much code will call + toString directly. + + The format of the string is purposefully unspecified, and code that + cares about the format of the string should use `toISOString`, + `toISOExtString`, `toSimpleString`, or some other custom formatting + function that explicitly generates the format that the code needs. The + reason is that the code is then clear about what format it's using, + making it less error-prone to maintain the code and interact with other + software that consumes the generated strings. It's for this same reason + $(LREF Date) has no `fromString` function, whereas it does have + `fromISOString`, `fromISOExtString`, and `fromSimpleString`. + + The format returned by toString may or may not change in the future. +/ string toString() const @safe pure nothrow { return toSimpleString(); } - /// - @safe unittest - { - assert(Date(2010, 7, 4).toString() == "2010-Jul-04"); - } - @safe unittest { auto date = Date(1999, 7, 6); @@ -8804,6 +8838,26 @@ public: /++ Converts this TimeOfDay to a string. + + This function exists to make it easy to convert a $(LREF TimeOfDay) to a + string for code that does not care what the exact format is - just that + it presents the information in a clear manner. It also makes it easy to + simply convert a $(LREF TimeOfDay) to a string when using functions such + as `to!string`, `format`, or `writeln` which use toString to convert + user-defined types. So, it is unlikely that much code will call + toString directly. + + The format of the string is purposefully unspecified, and code that + cares about the format of the string should use `toISOString`, + `toISOExtString`, or some other custom formatting function that + explicitly generates the format that the code needs. The reason is that + the code is then clear about what format it's using, making it less + error-prone to maintain the code and interact with other software that + consumes the generated strings. It's for this same reason that + $(LREF TimeOfDay) has no `fromString` function, whereas it does have + `fromISOString` and `fromISOExtString`. + + The format returned by toString may or may not change in the future. +/ string toString() const @safe pure nothrow { diff --git a/std/datetime/systime.d b/std/datetime/systime.d index 46eee5c8325..88cb36bfffa 100644 --- a/std/datetime/systime.d +++ b/std/datetime/systime.d @@ -8180,6 +8180,26 @@ public: /++ Converts this $(LREF SysTime) to a string. + + This function exists to make it easy to convert a $(LREF SysTime) to a + string for code that does not care what the exact format is - just that + it presents the information in a clear manner. It also makes it easy to + simply convert a $(LREF SysTime) to a string when using functions such + as `to!string`, `format`, or `writeln` which use toString to convert + user-defined types. So, it is unlikely that much code will call + toString directly. + + The format of the string is purposefully unspecified, and code that + cares about the format of the string should use `toISOString`, + `toISOExtString`, `toSimpleString`, or some other custom formatting + function that explicitly generates the format that the code needs. The + reason is that the code is then clear about what format it's using, + making it less error-prone to maintain the code and interact with other + software that consumes the generated strings. It's for this same reason + that $(LREF SysTime) has no `fromString` function, whereas it does have + `fromISOString`, `fromISOExtString`, and `fromSimpleString`. + + The format returned by toString may or may not change in the future. +/ string toString() @safe const nothrow { From 350300b585015b62ec48b4abc16bcce8f6561d87 Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Tue, 11 Jul 2017 20:02:16 +0200 Subject: [PATCH 125/163] Fix docs for std.algorithm.remove (avoid Ddoc auto-escape) --- std/algorithm/mutation.d | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/std/algorithm/mutation.d b/std/algorithm/mutation.d index 495afabb4ee..e4149e35149 100644 --- a/std/algorithm/mutation.d +++ b/std/algorithm/mutation.d @@ -1776,7 +1776,7 @@ cases.)) Params: s = a SwapStrategy to determine if the original order needs to be preserved - range = a $(REF_ALTTEXT bidirectional range, isBidirectionalRange, std,range,primitives) + range = a $(REF_ALTTEXT bidirectional range, isBidirectionalRange, std,_range,primitives) with a length member offset = which element(s) to remove @@ -2011,7 +2011,7 @@ if (s == SwapStrategy.stable /** Reduces the length of the -$(REF_ALTTEXT bidirectional range, isBidirectionalRange, std,range,primitives) $(D range) by removing +$(REF_ALTTEXT bidirectional range, isBidirectionalRange, std,_range,primitives) $(D range) by removing elements that satisfy $(D pred). If $(D s = SwapStrategy.unstable), elements are moved from the right end of the range over the elements to eliminate. If $(D s = SwapStrategy.stable) (the default), From 09ab8e96e33e8a41b735928f38629536fba883b6 Mon Sep 17 00:00:00 2001 From: RazvanN7 Date: Tue, 11 Jul 2017 15:29:25 +0300 Subject: [PATCH 126/163] Fix Issue 16062 - Add 'clear' method to OutBuffer (std.outbuffer) --- std/outbuffer.d | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/std/outbuffer.d b/std/outbuffer.d index 913a29881fd..24f72501e46 100644 --- a/std/outbuffer.d +++ b/std/outbuffer.d @@ -202,6 +202,12 @@ class OutBuffer fill0(alignsize - nbytes); } + /// Clear the data in the buffer + void clear() + { + offset = 0; + } + /**************************************** * Optimize common special case alignSize(2) */ @@ -380,6 +386,11 @@ class OutBuffer buf.write("world"[]); buf.printf(" %d", 62665); assert(cmp(buf.toString(), "hello world 62665") == 0); + + buf.clear(); + assert(cmp(buf.toString(), "") == 0); + buf.write("New data"[]); + assert(cmp(buf.toString(),"New data") == 0); } @safe unittest From d7e0de242ef5434442401da935a4268c41185792 Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Wed, 12 Jul 2017 10:22:52 +0200 Subject: [PATCH 127/163] Cleanup std.outbuffer: remove unnecessary slicing + make unittest documented --- std/outbuffer.d | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/std/outbuffer.d b/std/outbuffer.d index 24f72501e46..1d594982cc1 100644 --- a/std/outbuffer.d +++ b/std/outbuffer.d @@ -374,6 +374,7 @@ class OutBuffer } } +/// @safe unittest { import std.string : cmp; @@ -381,15 +382,15 @@ class OutBuffer OutBuffer buf = new OutBuffer(); assert(buf.offset == 0); - buf.write("hello"[]); + buf.write("hello"); buf.write(cast(byte) 0x20); - buf.write("world"[]); + buf.write("world"); buf.printf(" %d", 62665); assert(cmp(buf.toString(), "hello world 62665") == 0); buf.clear(); assert(cmp(buf.toString(), "") == 0); - buf.write("New data"[]); + buf.write("New data"); assert(cmp(buf.toString(),"New data") == 0); } From e85381ee42652029a8b1c8d8397aee78c2ae7139 Mon Sep 17 00:00:00 2001 From: RazvanN7 Date: Tue, 11 Jul 2017 16:18:52 +0300 Subject: [PATCH 128/163] Fix Issue 15771 - FileLogger should create the output directory if it does not exist --- std/experimental/logger/filelogger.d | 65 +++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/std/experimental/logger/filelogger.d b/std/experimental/logger/filelogger.d index 43ace4cd178..8f97b5ba7ea 100644 --- a/std/experimental/logger/filelogger.d +++ b/std/experimental/logger/filelogger.d @@ -4,6 +4,12 @@ module std.experimental.logger.filelogger; import std.experimental.logger.core; import std.stdio; +import std.typecons : Flag; + +/** An option to create $(LREF FileLogger) directory if it is non-existent. +*/ +alias CreateFolder = Flag!"CreateFolder"; + /** This $(D Logger) implementation writes log messages to the associated file. The name of the file has to be passed on construction time. If the file is already present new log messages will be append at its end. @@ -20,18 +26,57 @@ class FileLogger : Logger fn = The filename of the output file of the $(D FileLogger). If that file can not be opened for writting an exception will be thrown. lv = The $(D LogLevel) for the $(D FileLogger). By default the - $(D LogLevel) for $(D FileLogger) is $(D LogLevel.all). Example: ------------- auto l1 = new FileLogger("logFile"); auto l2 = new FileLogger("logFile", LogLevel.fatal); + auto l3 = new FileLogger("logFile", LogLevel.fatal, CreateFolder.yes); ------------- */ this(in string fn, const LogLevel lv = LogLevel.all) @safe { + this(fn, lv, CreateFolder.yes); + } + + /** A constructor for the $(D FileLogger) Logger that takes a reference to + a $(D File). + + The $(D File) passed must be open for all the log call to the + $(D FileLogger). If the $(D File) gets closed, using the $(D FileLogger) + for logging will result in undefined behaviour. + + Params: + fn = The file used for logging. + lv = The $(D LogLevel) for the $(D FileLogger). By default the + $(D LogLevel) for $(D FileLogger) is $(D LogLevel.all). + createFileNameFolder = if yes and fn contains a folder name, this + folder will be created. + + Example: + ------------- + auto file = File("logFile.log", "w"); + auto l1 = new FileLogger(file); + auto l2 = new FileLogger(file, LogLevel.fatal); + ------------- + */ + this(in string fn, const LogLevel lv, CreateFolder createFileNameFolder) @safe + { + import std.file : exists, mkdirRecurse; + import std.path : dirName; + import std.conv : text; + super(lv); this.filename = fn; + + if (createFileNameFolder) + { + auto d = dirName(this.filename); + mkdirRecurse(d); + assert(exists(d), text("The folder the FileLogger should have", + " created in '", d,"' could not be created.")); + } + this.file_.open(this.filename, "a"); } @@ -158,6 +203,24 @@ class FileLogger : Logger assert(readLine.indexOf(notWritten) == -1, readLine); } +@safe unittest +{ + import std.file : rmdirRecurse, exists, deleteme; + import std.path : dirName; + + const string tmpFolder = dirName(deleteme); + const string filepath = tmpFolder ~ "/bug15771/minas/oops/"; + const string filename = filepath ~ "output.txt"; + assert(!exists(filepath)); + + auto f = new FileLogger(filename, LogLevel.all, CreateFolder.yes); + scope(exit) () @trusted { rmdirRecurse(tmpFolder ~ "/bug15771"); }(); + + f.log("Hello World!"); + assert(exists(filepath)); + f.file.close(); +} + @system unittest { import std.array : empty; From a5afe1609feed83f2233cad80a54201dccdd4b1e Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Wed, 12 Jul 2017 16:03:25 +0200 Subject: [PATCH 129/163] Fix Issue 17640 - std.concurrenct writeln conflicts with std.stdio writeln in unittests --- std/concurrency.d | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/std/concurrency.d b/std/concurrency.d index 2aff38375ed..5b5b95678f3 100644 --- a/std/concurrency.d +++ b/std/concurrency.d @@ -41,26 +41,21 @@ import std.range.primitives; import std.range.interfaces : InputRange; import std.traits; -// Avoids writeln output during a normal test-suite run -// Using writeln is very helpful for runnable unittest examples -version(unittest) -{ - void writeln(T...)(T t){} -} - /// @system unittest { + __gshared string received; static void spawnedFunc(Tid ownerTid) { + import std.conv : text; // Receive a message from the owner thread. - receive( - (int i) { writeln("Received the number ", i);} - ); + receive((int i){ + received = text("Received the number ", i); - // Send a message back to the owner thread - // indicating success. - send(ownerTid, true); + // Send a message back to the owner thread + // indicating success. + send(ownerTid, true); + }); } // Start spawnedFunc in a new thread. @@ -72,6 +67,7 @@ version(unittest) // Receive the result code. auto wasSuccessful = receiveOnly!(bool); assert(wasSuccessful); + assert(received == "Received the number 42"); } private From 360f6db57936bd2fac238704630c11d8dc8d3c42 Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Wed, 12 Jul 2017 16:18:56 +0200 Subject: [PATCH 130/163] Remove invalid stars from the CODEOWNERS file --- CODEOWNERS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CODEOWNERS b/CODEOWNERS index a84bc629884..dbc1a48028a 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -72,5 +72,5 @@ std/uuid.d @jpf91 #std/variant.d std/windows/* @CyberShadow #std/xml.d -std/zip.d * @CyberShadow -std/zlib.d * @CyberShadow +std/zip.d @CyberShadow +std/zlib.d @CyberShadow From f9aade3265294fb87dc52c5e8a8f7877c3acbd50 Mon Sep 17 00:00:00 2001 From: Jack Stouffer Date: Wed, 12 Jul 2017 10:22:05 -0400 Subject: [PATCH 131/163] Removed old debug printfs --- std/array.d | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/std/array.d b/std/array.d index 3b22cd32737..8fc605e0109 100644 --- a/std/array.d +++ b/std/array.d @@ -1361,8 +1361,6 @@ if (isInputRange!S && !isDynamicArray!S) { import std.conv : to; - debug(std_array) printf("array.replicate.unittest\n"); - foreach (S; AliasSeq!(string, wstring, dstring, char[], wchar[], dchar[])) { S s; @@ -1573,7 +1571,6 @@ if (isForwardRange!Range && is(typeof(unaryFun!isTerminator(range.front)))) import std.algorithm.comparison : cmp; import std.conv; - debug(std_array) printf("array.split\n"); foreach (S; AliasSeq!(string, wstring, dstring, immutable(string), immutable(wstring), immutable(dstring), char[], wchar[], dchar[], @@ -1904,8 +1901,6 @@ if (isInputRange!RoR && import std.conv : to; import std.range; - debug(std_array) printf("array.join.unittest\n"); - foreach (R; AliasSeq!(string, wstring, dstring)) { R word1 = "日本語"; @@ -2127,8 +2122,6 @@ if (isOutputRange!(Sink, E) && isDynamicArray!(E[]) import std.algorithm.comparison : cmp; import std.conv : to; - debug(std_array) printf("array.replace.unittest\n"); - foreach (S; AliasSeq!(string, wstring, dstring, char[], wchar[], dchar[])) { foreach (T; AliasSeq!(string, wstring, dstring, char[], wchar[], dchar[])) @@ -2571,8 +2564,6 @@ if (isDynamicArray!(E[]) && import std.algorithm.comparison : cmp; import std.conv : to; - debug(std_array) printf("array.replaceFirst.unittest\n"); - foreach (S; AliasSeq!(string, wstring, dstring, char[], wchar[], dchar[], const(char[]), immutable(char[]))) { @@ -2686,8 +2677,6 @@ if (isDynamicArray!(E[]) && import std.algorithm.comparison : cmp; import std.conv : to; - debug(std_array) printf("array.replaceLast.unittest\n"); - foreach (S; AliasSeq!(string, wstring, dstring, char[], wchar[], dchar[], const(char[]), immutable(char[]))) { @@ -2763,7 +2752,6 @@ body @system unittest { import std.algorithm.comparison : cmp; - debug(std_array) printf("array.replaceSlice.unittest\n"); string s = "hello"; string slice = s[2 .. 4]; From 68ea591dbdf7d1512d9c37b7eff9180477016bc0 Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Wed, 12 Jul 2017 18:30:42 +0200 Subject: [PATCH 132/163] CODEOWNERS: Add whitespace after # comments due to GitHub bug According to the GitHub support: We currently have a bug with CODEOWNERS files where commenting out a line will stop the feature working entirely. If you remove any lines with a # it should start to work correctly again. Alternatively - since you have a lot of commented out lines in that file - you can add a space after the # characters which should also fix the issue. --- CODEOWNERS | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/CODEOWNERS b/CODEOWNERS index dbc1a48028a..48b6427a7d8 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -18,59 +18,59 @@ std/* @andralex std/algorithm/* @andralex @JackStouffer @wilzbach @ZombineDev std/array.d @JackStouffer @wilzbach @ZombineDev std/ascii.d @JackStouffer @wilzbach -#std/base64.d +# std/base64.d std/bigint.d @Biotronic -#std/bitmanip.d +# std/bitmanip.d std/c/windows/* @CyberShadow -#std/compiler.d +# std/compiler.d std/complex.d @kyllingstad std/concurrency.d @MartinNowak std/container/ @ZombineDev std/conv.d @JackStouffer -#std/csv.d +# std/csv.d std/datetime/* @jmdavis std/demangle.d @MartinNowak @rainers std/digest/* @jpf91 -#std/encoding.d -#std/exception.d +# std/encoding.d +# std/exception.d std/experimental/allocator/* @andralex @wilzbach @ZombineDev std/experimental/checkedint/* @andralex std/experimental/logger/* @burner -#std/experimental/typecons.d +# std/experimental/typecons.d std/file.d @CyberShadow -#std/format.d -#std/functional.d -#std/getopt.d -#std/internal/ +# std/format.d +# std/functional.d +# std/getopt.d +# std/internal/ std/json.d @CyberShadow std/math* @Biotronic @ibuclaw @klickverbot std/meta.d @Biotronic @klickverbot @MetaLang @ZombineDev -#std/mmfile.d +# std/mmfile.d std/net/curl.d @CyberShadow std/net/isemail.d @JackStouffer -#std/numeric.d -#std/outbuffer.d -#std/parallelism.d +# std/numeric.d +# std/outbuffer.d +# std/parallelism.d std/path.d @CyberShadow @kyllingstad std/process.d @CyberShadow @kyllingstad @schveiguy std/random.d @WebDrake @wilzbach std/range/* @andralex @JackStouffer @wilzbach @ZombineDev std/regex/* @DmitryOlshansky -#std/signals.d +# std/signals.d std/socket.d @CyberShadow @klickverbot -#std/stdint.d +# std/stdint.d std/stdio.d @CyberShadow @schveiguy std/string.d @burner @JackStouffer -#std/system.d +# std/system.d std/traits.d @Biotronic @klickverbot @ZombineDev std/typecons.d @Biotronic @MetaLang @ZombineDev -#std/typetuple.d +# std/typetuple.d std/uni.d @DmitryOlshansky -#std/uri.d +# std/uri.d std/utf.d @jmdavis std/uuid.d @jpf91 -#std/variant.d +# std/variant.d std/windows/* @CyberShadow -#std/xml.d +# std/xml.d std/zip.d @CyberShadow std/zlib.d @CyberShadow From 1a08d2a8d6a5ebab9cd137035e258228ba6d9ba6 Mon Sep 17 00:00:00 2001 From: Andrei Alexandrescu Date: Wed, 12 Jul 2017 15:19:57 -0400 Subject: [PATCH 133/163] Convert section labels to title case --- std/container/rbtree.d | 4 ++-- std/csv.d | 4 ++-- std/exception.d | 2 +- std/math.d | 20 ++++++++++---------- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/std/container/rbtree.d b/std/container/rbtree.d index 7db3ca61408..089dde36f84 100644 --- a/std/container/rbtree.d +++ b/std/container/rbtree.d @@ -688,7 +688,7 @@ private struct RBRange(N) /** * pop the front element from the range * - * complexity: amortized $(BIGOH 1) + * Complexity: amortized $(BIGOH 1) */ void popFront() { @@ -698,7 +698,7 @@ private struct RBRange(N) /** * pop the back element from the range * - * complexity: amortized $(BIGOH 1) + * Complexity: amortized $(BIGOH 1) */ void popBack() { diff --git a/std/csv.d b/std/csv.d index a896159b5b0..2ee623bf331 100644 --- a/std/csv.d +++ b/std/csv.d @@ -1145,7 +1145,7 @@ private: size_t[] _popCount; public: /* - * params: + * Params: * input = Pointer to a character input range * delimiter = Separator for each column * quote = Character used for quotation @@ -1349,7 +1349,7 @@ public: * start with either a delimiter or record break (\n, \r\n, \r) which * must be removed for subsequent calls. * - * params: + * Params: * input = Any CSV input * ans = The first field in the input * sep = The character to represent a comma in the specification diff --git a/std/exception.d b/std/exception.d index 5a58a8fae74..fa00f288b17 100644 --- a/std/exception.d +++ b/std/exception.d @@ -1795,7 +1795,7 @@ Params: Returns: A wrapper $(D struct) that preserves the range interface of $(D input). -opSlice: +Note: Infinite ranges with slicing support must return an instance of $(REF Take, std,range) when sliced with a specific lower and upper bound (see $(REF hasSlicing, std,range,primitives)); $(D handle) deals with diff --git a/std/math.d b/std/math.d index 49d0e4ea0cc..78ef51cfca9 100644 --- a/std/math.d +++ b/std/math.d @@ -5290,9 +5290,9 @@ private: /********************************* * Determines if $(D_PARAM x) is NaN. - * params: + * Params: * x = a floating point number. - * returns: + * Returns: * $(D true) if $(D_PARAM x) is Nan. */ bool isNaN(X)(X x) @nogc @trusted pure nothrow @@ -5378,9 +5378,9 @@ if (isFloatingPoint!(X)) /********************************* * Determines if $(D_PARAM x) is finite. - * params: + * Params: * x = a floating point number. - * returns: + * Returns: * $(D true) if $(D_PARAM x) is finite. */ bool isFinite(X)(X x) @trusted pure nothrow @nogc @@ -5421,9 +5421,9 @@ bool isFinite(X)(X x) @trusted pure nothrow @nogc * * A normalized number must not be zero, subnormal, infinite nor $(NAN). * - * params: + * Params: * x = a floating point number. - * returns: + * Returns: * $(D true) if $(D_PARAM x) is normalized. */ @@ -5471,9 +5471,9 @@ bool isNormal(X)(X x) @trusted pure nothrow @nogc * Subnormals (also known as "denormal number"), have a 0 exponent * and a 0 most significant mantissa bit. * - * params: + * Params: * x = a floating point number. - * returns: + * Returns: * $(D true) if $(D_PARAM x) is a denormal number. */ bool isSubnormal(X)(X x) @trusted pure nothrow @nogc @@ -5533,9 +5533,9 @@ bool isSubnormal(X)(X x) @trusted pure nothrow @nogc /********************************* * Determines if $(D_PARAM x) is $(PLUSMN)$(INFIN). - * params: + * Params: * x = a floating point number. - * returns: + * Returns: * $(D true) if $(D_PARAM x) is $(PLUSMN)$(INFIN). */ bool isInfinity(X)(X x) @nogc @trusted pure nothrow From b6ea0d7d1abc54c6da43555d9107fa0f2f39c7c7 Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Tue, 11 Jul 2017 22:06:01 +0200 Subject: [PATCH 134/163] Add std.meta.Stride --- changelog/std-meta-stride.dd | 9 ++++++ std/meta.d | 55 ++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 changelog/std-meta-stride.dd diff --git a/changelog/std-meta-stride.dd b/changelog/std-meta-stride.dd new file mode 100644 index 00000000000..a01da903d9e --- /dev/null +++ b/changelog/std-meta-stride.dd @@ -0,0 +1,9 @@ +`std.meta.Stride` was added + +$(REF Stride, std,meta) allows selecting a subset of template by a step size and offset: + +--- +alias attribs = AliasSeq!(short, int, long, ushort, uint, ulong); +static assert(is(Stride!(3, attribs) == AliasSeq!(short, ushort))); +static assert(is(Stride!(3, attribs[1 .. $]) == AliasSeq!(int, uint))); +--- diff --git a/std/meta.d b/std/meta.d index 77ed211d6e0..ffca2c0ee71 100644 --- a/std/meta.d +++ b/std/meta.d @@ -26,6 +26,7 @@ * $(LREF EraseAll) * $(LREF Filter) * $(LREF NoDuplicates) + * $(LREF Stride) * )) * $(TR $(TD Alias sequence type hierarchy) $(TD * $(LREF DerivedToFront) @@ -1494,6 +1495,60 @@ template staticIsSorted(alias cmp, Seq...) static assert(!staticIsSorted!(Comp, uint, short, ubyte, long, ulong)); } +/** +Selects a subset of the argument list by stepping with fixed `stepSize` over the list. +A negative `stepSize` starts iteration with the last list element. + +Params: + stepSize = Number of elements to increment on each iteration. Can't be `0`. + Args = Template arguments + +Returns: A template argument list filtered by the selected stride. +*/ +template Stride(int stepSize, Args...) +if (stepSize != 0) +{ + static if (Args.length == 0) + { + alias Stride = AliasSeq!(); + } + else static if (stepSize > 0) + { + static if (stepSize >= Args.length) + alias Stride = AliasSeq!(Args[0]); + else + alias Stride = AliasSeq!(Args[0], Stride!(stepSize, Args[stepSize .. $])); + } + else + { + static if (-stepSize >= Args.length) + alias Stride = AliasSeq!(Args[$ - 1]); + else + alias Stride = AliasSeq!(Args[$ - 1], Stride!(stepSize, Args[0 .. $ + stepSize])); + } +} + +/// +@safe unittest +{ + static assert(is(Stride!(1, short, int, long) == AliasSeq!(short, int, long))); + static assert(is(Stride!(2, short, int, long) == AliasSeq!(short, long))); + static assert(is(Stride!(-1, short, int, long) == AliasSeq!(long, int, short))); + static assert(is(Stride!(-2, short, int, long) == AliasSeq!(long, short))); + + alias attribs = AliasSeq!(short, int, long, ushort, uint, ulong); + static assert(is(Stride!(3, attribs) == AliasSeq!(short, ushort))); + static assert(is(Stride!(3, attribs[1 .. $]) == AliasSeq!(int, uint))); + static assert(is(Stride!(-3, attribs) == AliasSeq!(ulong, long))); +} + +@safe unittest +{ + static assert(Pack!(Stride!(5, int)).equals!(int)); + static assert(Pack!(Stride!(-5, int)).equals!(int)); + static assert(!__traits(compiles, Stride!(0, int))); +} + // : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : // private: From 296184f5419e1a7f8748688606950e747338f8f1 Mon Sep 17 00:00:00 2001 From: Jon Degenhardt Date: Sat, 15 Jul 2017 13:08:53 -0700 Subject: [PATCH 135/163] Fix issue 17650: std.getopt range violation when option value is a hyphen. --- std/getopt.d | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/std/getopt.d b/std/getopt.d index f54c6c2dc8c..5beddcc23b4 100644 --- a/std/getopt.d +++ b/std/getopt.d @@ -1105,7 +1105,7 @@ private bool optMatch(string arg, string optPattern, ref string value, import std.uni : toUpper; //writeln("optMatch:\n ", arg, "\n ", optPattern, "\n ", value); //scope(success) writeln("optMatch result: ", value); - if (!arg.length || arg[0] != optionChar) return false; + if (arg.length < 2 || arg[0] != optionChar) return false; // yank the leading '-' arg = arg[1 .. $]; immutable isLong = arg.length > 1 && arg[0] == optionChar; @@ -1834,3 +1834,24 @@ void defaultGetoptFormatter(Output)(Output output, string text, Option[] opt) assert(x == 17); assert(y == 50); } + +@system unittest // Hyphens at the start of option values; Issue 17650 +{ + auto args = ["program", "-m", "-5", "-n", "-50", "-c", "-", "-f", "-"]; + + int m; + int n; + char c; + string f; + + getopt(args, + "m|mm", "integer", &m, + "n|nn", "integer", &n, + "c|cc", "character", &c, + "f|file", "filename or hyphen for stdin", &f); + + assert(m == -5); + assert(n == -50); + assert(c == '-'); + assert(f == "-"); +} From 82c3371d85154b7f98b1c9187b79805a50fc59dd Mon Sep 17 00:00:00 2001 From: Andrei Alexandrescu Date: Sat, 17 Jun 2017 12:18:44 +0200 Subject: [PATCH 136/163] Convert range primitives to CNF like a boss --- std/range/primitives.d | 289 +++++++++++++++-------------------------- std/traits.d | 1 + 2 files changed, 103 insertions(+), 187 deletions(-) diff --git a/std/range/primitives.d b/std/range/primitives.d index 7dc0d018a02..99064ba73ec 100644 --- a/std/range/primitives.d +++ b/std/range/primitives.d @@ -161,17 +161,12 @@ Params: Returns: true if R is an InputRange, false if not */ -template isInputRange(R) -{ - enum bool isInputRange = is(typeof( - (inout int = 0) - { - R r = R.init; // can define a range object - if (r.empty) {} // can test for empty - r.popFront; // can invoke popFront() - auto h = r.front; // can get the front of the range - })); -} +enum bool isInputRange(R) = + is(typeof(R.init) == R) + && is(ReturnType!((R r) => r.empty) == bool) + && is(typeof((R r) => r.front)) + && !is(ReturnType!((R r) => r.front) == void) + && is(typeof((R r) => r.popFront)); /// @safe unittest @@ -189,6 +184,40 @@ template isInputRange(R) static assert( isInputRange!(char[])); static assert(!isInputRange!(char[4])); static assert( isInputRange!(inout(int)[])); + + static struct NotDefaultConstructible + { + @disable this(); + void popFront(); + @property bool empty(); + @property int front(); + } + static assert( isInputRange!NotDefaultConstructible); + + static struct NotDefaultConstructibleOrCopyable + { + @disable this(); + @disable this(this); + void popFront(); + @property bool empty(); + @property int front(); + } + static assert(isInputRange!NotDefaultConstructibleOrCopyable); + + static struct Frontless + { + void popFront(); + @property bool empty(); + } + static assert(!isInputRange!Frontless); + + static struct VoidFront + { + void popFront(); + @property bool empty(); + void front(); + } + static assert(!isInputRange!VoidFront); } /+ @@ -691,16 +720,8 @@ are: 2: if $(D E) is a non $(empty) $(D InputRange), then placing $(D e) is guaranteed to not overflow the range. +/ -package(std) template isNativeOutputRange(R, E) -{ - enum bool isNativeOutputRange = is(typeof( - (inout int = 0) - { - R r = void; - E e; - doPut(r, e); - })); -} +package(std) enum bool isNativeOutputRange(R, E) = + is(typeof(doPut(lvalueOf!R, lvalueOf!E))); @safe unittest { @@ -715,21 +736,14 @@ package(std) template isNativeOutputRange(R, E) if (!r.empty) put(r, [1, 2]); //May actually error out. } + /++ Returns $(D true) if $(D R) is an output range for elements of type $(D E). An output range is defined functionally as a range that supports the operation $(D put(r, e)) as defined above. +/ -template isOutputRange(R, E) -{ - enum bool isOutputRange = is(typeof( - (inout int = 0) - { - R r = R.init; - E e = E.init; - put(r, e); - })); -} +enum bool isOutputRange(R, E) = + is(typeof(put(lvalueOf!R, lvalueOf!E))); /// @safe unittest @@ -791,19 +805,8 @@ are the same as for an input range, with the additional requirement that backtracking must be possible by saving a copy of the range object with $(D save) and using it later. */ -template isForwardRange(R) -{ - enum bool isForwardRange = isInputRange!R && is(typeof( - (inout int = 0) - { - R r1 = R.init; - // NOTE: we cannot check typeof(r1.save) directly - // because typeof may not check the right type there, and - // because we want to ensure the range can be copied. - auto s1 = r1.save; - static assert(is(typeof(s1) == R)); - })); -} +enum bool isForwardRange(R) = isInputRange!R + && is(ReturnType!((R r) => r.save) == R); /// @safe unittest @@ -841,18 +844,9 @@ $(UL $(LI $(D r.back) returns (possibly a reference to) the last element in the range. Calling $(D r.back) is allowed only if calling $(D r.empty) has, or would have, returned $(D false).)) */ -template isBidirectionalRange(R) -{ - enum bool isBidirectionalRange = isForwardRange!R && is(typeof( - (inout int = 0) - { - R r = R.init; - r.popBack; - auto t = r.back; - auto w = r.front; - static assert(is(typeof(t) == typeof(w))); - })); -} +enum bool isBidirectionalRange(R) = isForwardRange!R + && is(typeof((R r) => r.popBack)) + && is(ReturnType!((R r) => r.back) == ElementType!R); /// @safe unittest @@ -911,29 +905,14 @@ isRandomAccessRange) yields $(D false) for them because they use variable-length encodings (UTF-8 and UTF-16 respectively). These types are bidirectional ranges only. */ -template isRandomAccessRange(R) -{ - enum bool isRandomAccessRange = is(typeof( - (inout int = 0) - { - static assert(isBidirectionalRange!R || - isForwardRange!R && isInfinite!R); - R r = R.init; - auto e = r[1]; - auto f = r.front; - static assert(is(typeof(e) == typeof(f))); - static assert(!isNarrowString!R); - static assert(hasLength!R || isInfinite!R); - - static if (is(typeof(r[$]))) - { - static assert(is(typeof(f) == typeof(r[$]))); - - static if (!isInfinite!R) - static assert(is(typeof(f) == typeof(r[$ - 1]))); - } - })); -} +enum bool isRandomAccessRange(R) = + is(typeof(lvalueOf!R[1]) == ElementType!R) + && !isNarrowString!R + && isForwardRange!R + && (isBidirectionalRange!R || isInfinite!R) + && (hasLength!R || isInfinite!R) + && (isInfinite!R || !is(typeof(lvalueOf!R[$ - 1])) + || is(typeof(lvalueOf!R[$ - 1]) == ElementType!R)); /// @safe unittest @@ -1065,20 +1044,13 @@ static if (isRandomAccessRange!R) static assert(is(typeof(moveAt(r, 0)) == E)); ---- */ -template hasMobileElements(R) -{ - enum bool hasMobileElements = isInputRange!R && is(typeof( - (inout int = 0) - { - alias E = ElementType!R; - R r = R.init; - static assert(is(typeof(moveFront(r)) == E)); - static if (isBidirectionalRange!R) - static assert(is(typeof(moveBack(r)) == E)); - static if (isRandomAccessRange!R) - static assert(is(typeof(moveAt(r, 0)) == E)); - })); -} +enum bool hasMobileElements(R) = + isInputRange!R + && is(typeof(moveFront(lvalueOf!R)) == ElementType!R) + && (!isBidirectionalRange!R + || is(typeof(moveBack(lvalueOf!R)) == ElementType!R)) + && (!isRandomAccessRange!R + || is(typeof(moveAt(lvalueOf!R, 0)) == ElementType!R)); /// @safe unittest @@ -1271,14 +1243,12 @@ static if (isRandomAccessRange!R) swap(r[0], r.front); template hasSwappableElements(R) { import std.algorithm.mutation : swap; - enum bool hasSwappableElements = isInputRange!R && is(typeof( - (inout int = 0) - { - R r = R.init; - swap(r.front, r.front); - static if (isBidirectionalRange!R) swap(r.back, r.front); - static if (isRandomAccessRange!R) swap(r[0], r.front); - })); + enum bool hasSwappableElements = isInputRange!R + && is(typeof((ref R r) => swap(r.front, r.front))) + && (!isBidirectionalRange!R + || is(typeof((ref R r) => swap(r.back, r.front)))) + && (!isRandomAccessRange!R + || is(typeof((ref R r) => swap(r[0], r.front)))); } /// @@ -1308,17 +1278,12 @@ static if (isBidirectionalRange!R) r.back = r.front; static if (isRandomAccessRange!R) r[0] = r.front; ---- */ -template hasAssignableElements(R) -{ - enum bool hasAssignableElements = isInputRange!R && is(typeof( - (inout int = 0) - { - R r = R.init; - r.front = r.front; - static if (isBidirectionalRange!R) r.back = r.front; - static if (isRandomAccessRange!R) r[0] = r.front; - })); -} +enum bool hasAssignableElements(R) = isInputRange!R + && is(typeof(lvalueOf!R.front = lvalueOf!R.front)) + && (!isBidirectionalRange!R + || is(typeof(lvalueOf!R.back = lvalueOf!R.back))) + && (!isRandomAccessRange!R + || is(typeof(lvalueOf!R[0] = lvalueOf!R.front))); /// @safe unittest @@ -1347,19 +1312,12 @@ static if (isBidirectionalRange!R) passByRef(r.back); static if (isRandomAccessRange!R) passByRef(r[0]); ---- */ -template hasLvalueElements(R) -{ - enum bool hasLvalueElements = isInputRange!R && is(typeof( - (inout int = 0) - { - void checkRef(ref ElementType!R stuff); - R r = R.init; - - checkRef(r.front); - static if (isBidirectionalRange!R) checkRef(r.back); - static if (isRandomAccessRange!R) checkRef(r[0]); - })); -} +enum bool hasLvalueElements(R) = isInputRange!R + && is(typeof(((ref x) => x)(lvalueOf!R.front))) + && (!isBidirectionalRange!R + || is(typeof(((ref x) => x)(lvalueOf!R.back)))) + && (!isRandomAccessRange!R + || is(typeof(((ref x) => x)(lvalueOf!R[0])))); /// @safe unittest @@ -1502,76 +1460,33 @@ original range (they both return the same type for infinite ranges). However, when using $(D opDollar), the result of $(D opSlice) must be that of the original range type. -The following code must compile for $(D hasSlicing) to be $(D true): +The following expression must be true for `hasSlicing` to be `true`: ---- -R r = void; - -static if (isInfinite!R) - typeof(take(r, 1)) s = r[1 .. 2]; -else -{ - static assert(is(typeof(r[1 .. 2]) == R)); - R s = r[1 .. 2]; -} - -s = r[1 .. 2]; - -static if (is(typeof(r[0 .. $]))) -{ - static assert(is(typeof(r[0 .. $]) == R)); - R t = r[0 .. $]; - t = r[0 .. $]; - - static if (!isInfinite!R) + isForwardRange!R + && !isNarrowString!R + && is(ReturnType!((R r) => r[1 .. 1].length) == size_t) + && (is(typeof(lvalueOf!R[1 .. 1]) == R) || isInfinite!R) + && (!is(typeof(lvalueOf!R[0 .. $])) || is(typeof(lvalueOf!R[0 .. $]) == R)) + && (!is(typeof(lvalueOf!R[0 .. $])) || isInfinite!R + || is(typeof(lvalueOf!R[0 .. $ - 1]) == R)) + && is(typeof((ref R r) { - static assert(is(typeof(r[0 .. $ - 1]) == R)); - R u = r[0 .. $ - 1]; - u = r[0 .. $ - 1]; - } -} - -static assert(isForwardRange!(typeof(r[1 .. 2]))); -static assert(hasLength!(typeof(r[1 .. 2]))); + static assert(isForwardRange!(typeof(r[1 .. 2]))); + })); ---- */ -template hasSlicing(R) -{ - enum bool hasSlicing = isForwardRange!R && !isNarrowString!R && is(typeof( - (inout int = 0) +enum bool hasSlicing(R) = isForwardRange!R + && !isNarrowString!R + && is(ReturnType!((R r) => r[1 .. 1].length) == size_t) + && (is(typeof(lvalueOf!R[1 .. 1]) == R) || isInfinite!R) + && (!is(typeof(lvalueOf!R[0 .. $])) || is(typeof(lvalueOf!R[0 .. $]) == R)) + && (!is(typeof(lvalueOf!R[0 .. $])) || isInfinite!R + || is(typeof(lvalueOf!R[0 .. $ - 1]) == R)) + && is(typeof((ref R r) { - R r = R.init; - - static if (isInfinite!R) - { - typeof(r[1 .. 1]) s = r[1 .. 2]; - } - else - { - static assert(is(typeof(r[1 .. 2]) == R)); - R s = r[1 .. 2]; - } - - s = r[1 .. 2]; - - static if (is(typeof(r[0 .. $]))) - { - static assert(is(typeof(r[0 .. $]) == R)); - R t = r[0 .. $]; - t = r[0 .. $]; - - static if (!isInfinite!R) - { - static assert(is(typeof(r[0 .. $ - 1]) == R)); - R u = r[0 .. $ - 1]; - u = r[0 .. $ - 1]; - } - } - static assert(isForwardRange!(typeof(r[1 .. 2]))); - static assert(hasLength!(typeof(r[1 .. 2]))); })); -} /// @safe unittest diff --git a/std/traits.d b/std/traits.d index d32a5e967ec..5b8700cca80 100644 --- a/std/traits.d +++ b/std/traits.d @@ -7943,4 +7943,5 @@ enum isCopyable(S) = is(typeof( static assert(isCopyable!C1); static assert(isCopyable!int); + static assert(isCopyable!(int[])); } From b4284db1f937e90fec6ffe4a9e4e2bf4783799bb Mon Sep 17 00:00:00 2001 From: RazvanN7 Date: Mon, 17 Jul 2017 13:32:08 +0300 Subject: [PATCH 137/163] Fix Issue 17250 - ProcessPipes (std.process) should provide a test for a null pid --- std/process.d | 1 - 1 file changed, 1 deletion(-) diff --git a/std/process.d b/std/process.d index bcbedde89d6..74601a02ae3 100644 --- a/std/process.d +++ b/std/process.d @@ -2168,7 +2168,6 @@ struct ProcessPipes /// The $(LREF Pid) of the child process. @property Pid pid() @safe nothrow { - assert(_pid !is null); return _pid; } From e471b222ce995e73e037c18b81c3086566b0af7b Mon Sep 17 00:00:00 2001 From: RazvanN7 Date: Mon, 17 Jul 2017 11:51:51 +0300 Subject: [PATCH 138/163] Rename nWayUnion => multiwayMerge and NWayUnion => MultiwayMerge --- std/algorithm/setops.d | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/std/algorithm/setops.d b/std/algorithm/setops.d index f948cb0635c..966dbda0f90 100644 --- a/std/algorithm/setops.d +++ b/std/algorithm/setops.d @@ -13,7 +13,7 @@ $(T2 largestPartialIntersection, $(T2 largestPartialIntersectionWeighted, Copies out the values that occur most frequently (multiplied by per-value weights) in a range of ranges.) -$(T2 nWayUnion, +$(T2 multiwayMerge, Computes the union of a set of sets implemented as a range of sorted ranges.) $(T2 setDifference, @@ -647,7 +647,7 @@ void largestPartialIntersectionWeighted { return weights[a[0]] * a[1] > weights[b[0]] * b[1]; } - topNCopy!heapComp(group(nWayUnion!less(ror)), tgt, sorted); + topNCopy!heapComp(group(multiwayMerge!less(ror)), tgt, sorted); } /// @@ -744,7 +744,7 @@ void largestPartialIntersectionWeighted assert(arrayOne == arrayTwo); } -// NWayUnion +// MultiwayMerge /** Computes the union of multiple sets. The input sets are passed as a range of ranges and each is assumed to be sorted by $(D @@ -752,13 +752,18 @@ less). Computation is done lazily, one union element at a time. The complexity of one $(D popFront) operation is $(BIGOH log(ror.length)). However, the length of $(D ror) decreases as ranges in it are exhausted, so the complexity of a full pass through $(D -NWayUnion) is dependent on the distribution of the lengths of ranges +MultiwayMerge) is dependent on the distribution of the lengths of ranges contained within $(D ror). If all ranges have the same length $(D n) (worst case scenario), the complexity of a full pass through $(D -NWayUnion) is $(BIGOH n * ror.length * log(ror.length)), i.e., $(D +MultiwayMerge) is $(BIGOH n * ror.length * log(ror.length)), i.e., $(D log(ror.length)) times worse than just spanning all ranges in turn. The output comes sorted (unstably) by $(D less). +For backward compatibility, `multiwayMerge` is available under +the name `nWayUnion` and `MultiwayMerge` under the name of `NWayUnion` . +Future code should use `multiwayMerge` and `MultiwayMerge` as `nWayUnion` +and `NWayUnion` will be deprecated. + Params: less = Predicate the given ranges are sorted by. ror = A range of ranges sorted by `less` to compute the union for. @@ -766,14 +771,14 @@ Params: Returns: A range of the union of the ranges in `ror`. -Warning: Because $(D NWayUnion) does not allocate extra memory, it -will leave $(D ror) modified. Namely, $(D NWayUnion) assumes ownership +Warning: Because $(D MultiwayMerge) does not allocate extra memory, it +will leave $(D ror) modified. Namely, $(D MultiwayMerge) assumes ownership of $(D ror) and discretionarily swaps and advances elements of it. If you want $(D ror) to preserve its contents after the call, you may -want to pass a duplicate to $(D NWayUnion) (and perhaps cache the +want to pass a duplicate to $(D MultiwayMerge) (and perhaps cache the duplicate in between calls). */ -struct NWayUnion(alias less, RangeOfRanges) +struct MultiwayMerge(alias less, RangeOfRanges) { import std.container : BinaryHeap; @@ -830,7 +835,7 @@ struct NWayUnion(alias less, RangeOfRanges) } /// Ditto -NWayUnion!(less, RangeOfRanges) nWayUnion +MultiwayMerge!(less, RangeOfRanges) multiwayMerge (alias less = "a < b", RangeOfRanges) (RangeOfRanges ror) { @@ -853,9 +858,12 @@ NWayUnion!(less, RangeOfRanges) nWayUnion auto witness = [ 1, 1, 1, 4, 4, 7, 7, 7, 7, 8, 8 ]; - assert(equal(nWayUnion(a), witness)); + assert(equal(multiwayMerge(a), witness)); } +alias nWayUnion = multiwayMerge; +alias NWayUnion = MultiwayMerge; + /** Lazily computes the difference of $(D r1) and $(D r2). The two ranges are assumed to be sorted by $(D less). The element types of the two From 9efa504bdca2b2644375e86d3b1527170512b726 Mon Sep 17 00:00:00 2001 From: RazvanN7 Date: Mon, 17 Jul 2017 12:28:40 +0300 Subject: [PATCH 139/163] Fix Issue 6718 - nWayUnion => nWayMerge, plus true nWayUnion --- std/algorithm/setops.d | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/std/algorithm/setops.d b/std/algorithm/setops.d index 966dbda0f90..c556cbf8526 100644 --- a/std/algorithm/setops.d +++ b/std/algorithm/setops.d @@ -864,6 +864,45 @@ MultiwayMerge!(less, RangeOfRanges) multiwayMerge alias nWayUnion = multiwayMerge; alias NWayUnion = MultiwayMerge; +/** +Computes the union of multiple ranges. The input ranges are passed +as a range of ranges and each is assumed to be sorted by $(D +less). Computation is done lazily, one union element at a time. +`multiwayUnion(ror)` is functionally equivalent to `multiwayMerge(ror).uniq`. + +Params: + less = Predicate the given ranges are sorted by. + ror = A range of ranges sorted by `less` to compute the intersection for. + +Returns: + A range of the intersection of the ranges in `ror`. + +See also: $(LREF NWayUnion) + */ +auto multiwayUnion(alias less = "a < b", RangeOfRanges)(RangeOfRanges ror) +{ + import std.algorithm.iteration : uniq; + return ror.multiwayMerge.uniq; +} + +/// +@system unittest +{ + import std.algorithm.comparison : equal; + + double[][] a = + [ + [ 1, 4, 7, 8 ], + [ 1, 7 ], + [ 1, 7, 8], + [ 4 ], + [ 7 ], + ]; + + auto witness = [1, 4, 7, 8]; + assert(equal(multiwayUnion(a), witness)); +} + /** Lazily computes the difference of $(D r1) and $(D r2). The two ranges are assumed to be sorted by $(D less). The element types of the two From 8a1a73c9775647bff2aae76f95c3ff6d9d3c3991 Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Wed, 12 Jul 2017 22:14:38 +0200 Subject: [PATCH 140/163] Unify function overloads in std.range: chooseAmong --- std/range/package.d | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/std/range/package.d b/std/range/package.d index cf0362ae2ab..8d928411a53 100644 --- a/std/range/package.d +++ b/std/range/package.d @@ -1574,18 +1574,14 @@ Returns: alias of that range's type. */ auto chooseAmong(Ranges...)(size_t index, Ranges rs) -if (Ranges.length > 2 - && is(typeof(choose(true, rs[0], rs[1]))) - && is(typeof(chooseAmong(0, rs[1 .. $])))) +if (Ranges.length >= 2 + && allSatisfy!(isInputRange, staticMap!(Unqual, Ranges)) + && !is(CommonType!(staticMap!(ElementType, Ranges)) == void)) { - return choose(index == 0, rs[0], chooseAmong(index - 1, rs[1 .. $])); -} - -/// ditto -auto chooseAmong(Ranges...)(size_t index, Ranges rs) -if (Ranges.length == 2 && is(typeof(choose(true, rs[0], rs[1])))) -{ - return choose(index == 0, rs[0], rs[1]); + static if (Ranges.length == 2) + return choose(index == 0, rs[0], rs[1]); + else + return choose(index == 0, rs[0], chooseAmong(index - 1, rs[1 .. $])); } /// From 5373f12b4253005741b0bef60d2b2cdc199c1b83 Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Wed, 12 Jul 2017 22:14:48 +0200 Subject: [PATCH 141/163] Unify function overloads in std.range: take --- std/range/package.d | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/std/range/package.d b/std/range/package.d index 8d928411a53..938e4cdea11 100644 --- a/std/range/package.d +++ b/std/range/package.d @@ -1919,11 +1919,23 @@ Returns: and `length`, `take` offers them as well. */ Take!R take(R)(R input, size_t n) -if (isInputRange!(Unqual!R) && !isInfinite!(Unqual!R) && hasSlicing!(Unqual!R) && - !is(R T == Take!T)) +if (isInputRange!(Unqual!R)) { - import std.algorithm.comparison : min; - return input[0 .. min(n, input.length)]; + alias U = Unqual!R; + static if (is(R T == Take!T)) + { + import std.algorithm.comparison : min; + return R(input.source, min(n, input._maxAvailable)); + } + else static if (!isInfinite!U && hasSlicing!U) + { + import std.algorithm.comparison : min; + return input[0 .. min(n, input.length)]; + } + else + { + return Take!R(input, n); + } } /// ditto @@ -2154,21 +2166,6 @@ pure @safe nothrow unittest assert(equal(t, [ 1, 2, 3 ])); } -/// ditto -Take!R take(R)(R input, size_t n) -if (is(R T == Take!T)) -{ - import std.algorithm.comparison : min; - return R(input.source, min(n, input._maxAvailable)); -} - -/// ditto -Take!(R) take(R)(R input, size_t n) -if (isInputRange!(Unqual!R) && (isInfinite!(Unqual!R) || !hasSlicing!(Unqual!R) && !is(R T == Take!T))) -{ - return Take!R(input, n); -} - pure @safe nothrow unittest { import std.algorithm.comparison : equal; From f52fd356cad79cf4ea0f6ad74404c7ee4b2417ef Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Wed, 12 Jul 2017 22:14:54 +0200 Subject: [PATCH 142/163] Unify function overloads in std.range: refRange --- std/range/package.d | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/std/range/package.d b/std/range/package.d index 938e4cdea11..5bd5b010064 100644 --- a/std/range/package.d +++ b/std/range/package.d @@ -10707,16 +10707,12 @@ private: /// ditto auto refRange(R)(R* range) -if (isInputRange!R && !is(R == class)) -{ - return RefRange!R(range); -} - -/// ditto -auto refRange(R)(R* range) -if (isInputRange!R && is(R == class)) +if (isInputRange!R) { - return *range; + static if (!is(R == class)) + return RefRange!R(range); + else + return *range; } /*****************************************************************************/ From 948b390e9d5df11c99a9e9fecd27934e85388769 Mon Sep 17 00:00:00 2001 From: "H. S. Teoh" Date: Mon, 17 Jul 2017 13:04:36 -0700 Subject: [PATCH 143/163] [dox] Positive example for isStaticArray. The current ddoc'd unittest for isStaticArray is pretty ridiculous: it gives the user examples of what is *not* a static array, but not even a single example of what *is* a static array! --- std/traits.d | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/std/traits.d b/std/traits.d index d32a5e967ec..959b6f4aa5c 100644 --- a/std/traits.d +++ b/std/traits.d @@ -6056,6 +6056,10 @@ enum bool isStaticArray(T) = __traits(isStaticArray, T); /// @safe unittest { + static assert( isStaticArray!(int[3])); + static assert( isStaticArray!(const(int)[5])); + static assert( isStaticArray!(const(int)[][5])); + static assert(!isStaticArray!(const(int)[])); static assert(!isStaticArray!(immutable(int)[])); static assert(!isStaticArray!(const(int)[4][])); From f46a73ad26f2cec85d18a19258ac19e78010b0a8 Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Mon, 17 Jul 2017 22:05:08 +0200 Subject: [PATCH 144/163] Mark random coverage line in std.concurrency --- std/concurrency.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/std/concurrency.d b/std/concurrency.d index 5b5b95678f3..acac8e102b7 100644 --- a/std/concurrency.d +++ b/std/concurrency.d @@ -2235,7 +2235,7 @@ private if (m_last is m_first) m_last = null; else if (m_last is n.next) - m_last = n; + m_last = n; // nocoverage Node* to_free = n.next; n.next = n.next.next; freeNode(to_free); From a8859e95452541af6c64b3cd272e2f0d7907dbbc Mon Sep 17 00:00:00 2001 From: Rainer Schuetze Date: Tue, 18 Jul 2017 09:27:18 +0200 Subject: [PATCH 145/163] reimplement std.traits.ParameterStorageClassTuple() with __traits --- std/traits.d | 81 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 51 insertions(+), 30 deletions(-) diff --git a/std/traits.d b/std/traits.d index 5b8700cca80..efa82d01ed0 100644 --- a/std/traits.d +++ b/std/traits.d @@ -1016,8 +1016,11 @@ template arity(alias func) } /** -Returns a tuple consisting of the storage classes of the parameters of a -function $(D func). +Get tuple, one per function parameter, of the storage classes of the parameters. +Params: + func = function symbol or type of function, delegate, or pointer to function +Returns: + a tuple of ParameterStorageClass bits */ enum ParameterStorageClass : uint { @@ -1037,39 +1040,28 @@ enum ParameterStorageClass : uint template ParameterStorageClassTuple(func...) if (func.length == 1 && isCallable!func) { - alias Func = Unqual!(FunctionTypeOf!func); - - /* - * TypeFuncion: - * CallConvention FuncAttrs Arguments ArgClose Type - */ - alias Params = Parameters!Func; - - // chop off CallConvention and FuncAttrs - enum margs = demangleFunctionAttributes(mangledName!Func[1 .. $]).rest; + alias Func = FunctionTypeOf!func; - // demangle Arguments and store parameter storage classes in a tuple - template demangleNextParameter(string margs, size_t i = 0) + static if (is(Func PT == __parameters)) { - static if (i < Params.length) + template StorageClass(size_t i) { - enum demang = demangleParameterStorageClass(margs); - enum skip = mangledName!(Params[i]).length; // for bypassing Type - enum rest = demang.rest; - - alias demangleNextParameter = - AliasSeq!( - demang.value + 0, // workaround: "not evaluatable at ..." - demangleNextParameter!(rest[skip .. $], i + 1) - ); - } - else // went thru all the parameters - { - alias demangleNextParameter = AliasSeq!(); + static if (i < PT.length) + { + alias StorageClass = AliasSeq!( + extractParameterStorageClassFlags!(__traits(getParameterStorageClasses, Func, i)), + StorageClass!(i + 1)); + } + else + alias StorageClass = AliasSeq!(); } + alias ParameterStorageClassTuple = StorageClass!0; + } + else + { + static assert(0, func[0].stringof ~ " is not a function"); + alias ParameterStorageClassTuple = AliasSeq!(); } - - alias ParameterStorageClassTuple = demangleNextParameter!margs; } /// @@ -1087,6 +1079,35 @@ template ParameterStorageClassTuple(func...) static assert(pstc[2] == STC.none); } +/***************** + * Convert string tuple Attribs to ParameterStorageClass bits + * Params: + * Attribs = string tuple + * Returns: + * ParameterStorageClass bits + */ +ParameterStorageClass extractParameterStorageClassFlags(Attribs...)() +{ + auto result = ParameterStorageClass.none; + foreach (attrib; Attribs) + { + final switch (attrib) with (ParameterStorageClass) + { + case "scope": result |= scope_; break; + case "out": result |= out_; break; + case "ref": result |= ref_; break; + case "lazy": result |= lazy_; break; + case "return": result |= return_; break; + } + } + /* Mimic behavor of original version of ParameterStorageClassTuple() + * to avoid breaking existing code. + */ + if (result == (ParameterStorageClass.ref_ | ParameterStorageClass.return_)) + result = ParameterStorageClass.return_; + return result; +} + @safe unittest { alias STC = ParameterStorageClass; From 8ef2b195f1ce72e86d72e088549926b2a01b2942 Mon Sep 17 00:00:00 2001 From: Jonathan M Davis Date: Tue, 18 Jul 2017 06:04:40 -0600 Subject: [PATCH 146/163] Move some deprecations along. --- std/algorithm/iteration.d | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/std/algorithm/iteration.d b/std/algorithm/iteration.d index 74eba6c3447..1ed78fb210e 100644 --- a/std/algorithm/iteration.d +++ b/std/algorithm/iteration.d @@ -5098,30 +5098,6 @@ if (isRandomAccessRange!Range && hasLength!Range) private Range _r; private bool _empty; - // Explicitly undocumented. It will be removed in June 2017. @@@DEPRECATED_2017-06@@@ - deprecated("Private variable. Use front()") - @property size_t[] indices() pure nothrow @nogc @safe { return _indices; } - - // Explicitly undocumented. It will be removed in June 2017. @@@DEPRECATED_2017-06@@@ - deprecated("Private variable. Don't set it manually") - @property void indices(size_t[] indices) pure nothrow @nogc @safe { _indices = indices; } - - // Explicitly undocumented. It will be removed in June 2017. @@@DEPRECATED_2017-06@@@ - deprecated("Private variable. Use front()") - @property size_t[] state() pure nothrow @nogc @safe { return _state; } - - // Explicitly undocumented. It will be removed in June 2017. @@@DEPRECATED_2017-06@@@ - deprecated("Private variable. Don't set it manually") - @property void state(size_t[] state) pure nothrow @nogc @safe { state = state; } - - // Explicitly undocumented. It will be removed in June 2017. @@@DEPRECATED_2017-06@@@ - deprecated("Private variable. Access will be forbidden.") - @property Range r() pure nothrow @nogc @safe { return _r; } - - // Explicitly undocumented. It will be removed in June 2017. @@@DEPRECATED_2017-06@@@ - deprecated("Private variable. Don't set it manually") - @property void r(Range r) pure nothrow @nogc @safe { _r = r; } - /// this(Range r) { From d9a65e1730344077a4fb4d217ce68326fdbece7c Mon Sep 17 00:00:00 2001 From: Jonathan M Davis Date: Tue, 18 Jul 2017 06:04:48 -0600 Subject: [PATCH 147/163] Fix the date on some deprecations. They were only deprecated a year ago, and the deprecation cycle is supposed to be two years. --- std/conv.d | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/std/conv.d b/std/conv.d index 85a62cfdc08..042409a1e98 100644 --- a/std/conv.d +++ b/std/conv.d @@ -3991,7 +3991,7 @@ if (isInputRange!Source && isSomeChar!(ElementType!Source) && string text(T...)(T args) if (T.length > 0) { return textImpl!string(args); } -// @@@DEPRECATED_2017-06@@@ +// @@@DEPRECATED_2018-06@@@ deprecated("Calling `text` with 0 arguments is deprecated") string text(T...)(T args) if (T.length == 0) { return textImpl!string(args); } @@ -4000,7 +4000,7 @@ if (T.length == 0) { return textImpl!string(args); } wstring wtext(T...)(T args) if (T.length > 0) { return textImpl!wstring(args); } -// @@@DEPRECATED_2017-06@@@ +// @@@DEPRECATED_2018-06@@@ deprecated("Calling `wtext` with 0 arguments is deprecated") wstring wtext(T...)(T args) if (T.length == 0) { return textImpl!wstring(args); } @@ -4017,7 +4017,7 @@ if (T.length > 0) { return textImpl!dstring(args); } assert(dtext(42, ' ', 1.5, ": xyz") == "42 1.5: xyz"d); } -// @@@DEPRECATED_2017-06@@@ +// @@@DEPRECATED_2018-06@@@ deprecated("Calling `dtext` with 0 arguments is deprecated") dstring dtext(T...)(T args) if (T.length == 0) { return textImpl!dstring(args); } From abe4f45d9f2b2d3e57774ed68e151222a4eb70d1 Mon Sep 17 00:00:00 2001 From: Jonathan M Davis Date: Tue, 18 Jul 2017 06:37:07 -0600 Subject: [PATCH 148/163] Move some std.datetime deprecations along. --- std/datetime/systime.d | 28 +++++----- std/datetime/timezone.d | 117 ++-------------------------------------- 2 files changed, 19 insertions(+), 126 deletions(-) diff --git a/std/datetime/systime.d b/std/datetime/systime.d index 88cb36bfffa..a4fc5b3201a 100644 --- a/std/datetime/systime.d +++ b/std/datetime/systime.d @@ -7785,11 +7785,12 @@ public: generated +HH:MM or -HH:MM for the time zone when it was not $(REF LocalTime,std,datetime,timezone) or $(REF UTC,std,datetime,timezone), which is not in conformance with - ISO 9601 for the non-extended string format. This has now been + ISO 8601 for the non-extended string format. This has now been fixed. However, for now, fromISOString will continue to accept the extended format for the time zone so that any code which has been writing out the result of toISOString to read in later will continue - to work.) + to work. The current behavior will be kept until July 2019 at which + point, fromISOString will be fixed to be standards compliant.) +/ string toISOString() @safe const nothrow { @@ -8248,11 +8249,12 @@ public: $(LREF toISOExtString) and generated +HH:MM or -HH:MM for the time zone when it was not $(REF LocalTime,std,datetime,timezone) or $(REF UTC,std,datetime,timezone), which is not in conformance with - ISO 9601 for the non-extended string format. This has now been + ISO 8601 for the non-extended string format. This has now been fixed. However, for now, fromISOString will continue to accept the extended format for the time zone so that any code which has been writing out the result of toISOString to read in later will continue - to work.) + to work. The current behavior will be kept until July 2019 at which + point, fromISOString will be fixed to be standards compliant.) Params: isoString = A string formatted in the ISO format for dates and times. @@ -8453,16 +8455,16 @@ public: test("20101222T172201.0000000+0130", SysTime(DateTime(2010, 12, 22, 17, 22, 01), east90)); test("20101222T172201.45+0800", SysTime(DateTime(2010, 12, 22, 17, 22, 01), hnsecs(4_500_000), east480)); - // @@@DEPRECATED_2017-07@@@ + // @@@DEPRECATED_2019-07@@@ // This isn't deprecated per se, but that text will make it so that it - // pops up when deprecations are moved along around July 2017. At that - // time, the notice on the documentation should be removed, and we may - // or may not change the behavior of fromISOString to no longer accept - // ISO extended time zones (the concern being that programs will have - // written out strings somewhere to read in again that they'll still be - // reading in for years to come and may not be able to fix, even if the - // code is fixed). If/when we do change the behavior, these tests will - // start failing and will need to be updated accordingly. + // pops up when deprecations are moved along around July 2019. At that + // time, we will update fromISOString so that it is conformant with ISO + // 8601, and it will no longer accept ISO extended time zones (it does + // currently because of issue #15654 - toISOString used to incorrectly + // use the ISO extended time zone format). These tests will then start + // failing will need to be updated accordingly. Also, the notes about + // this issue in toISOString and fromISOString's documentation will need + // to be removed. test("20101222T172201-01:00", SysTime(DateTime(2010, 12, 22, 17, 22, 01), west60)); test("20101222T172201-01:30", SysTime(DateTime(2010, 12, 22, 17, 22, 01), west90)); test("20101222T172201-08:00", SysTime(DateTime(2010, 12, 22, 17, 22, 01), west480)); diff --git a/std/datetime/timezone.d b/std/datetime/timezone.d index 1716eb15d0a..4743292c9c5 100644 --- a/std/datetime/timezone.d +++ b/std/datetime/timezone.d @@ -142,43 +142,7 @@ public: return dur!"hnsecs"(utcToTZ(stdTime) - stdTime); } - // @@@DEPRECATED_2017-07@@@ - /++ - $(RED Deprecated. Use either PosixTimeZone.getTimeZone or - WindowsTimeZone.getTimeZone. ($(LREF parseTZConversions) can be - used to convert time zone names if necessary). Microsoft changes - their time zones too often for us to compile the conversions into - Phobos and have them be properly up-to-date. TimeZone.getTimeZone - will be removed in July 2017.) - - Returns a $(LREF TimeZone) with the give name per the TZ Database. - - This returns a $(LREF PosixTimeZone) on Posix systems and a - $(LREF WindowsTimeZone) on Windows systems. For - $(LREF PosixTimeZone) on Windows, call $(D PosixTimeZone.getTimeZone) - directly and give it the location of the TZ Database time zone files on - disk. - - On Windows, the given TZ Database name is converted to the corresponding - time zone name on Windows prior to calling - $(D WindowsTimeZone.getTimeZone). This function allows for - the same time zone names on both Windows and Posix systems. - - See_Also: - $(HTTP en.wikipedia.org/wiki/Tz_database, Wikipedia entry on TZ - Database)
- $(HTTP en.wikipedia.org/wiki/List_of_tz_database_time_zones, List of - Time Zones)
- $(HTTP unicode.org/repos/cldr-tmp/trunk/diff/supplemental/zone_tzid.html, - Windows <-> TZ Database Name Conversion Table) - - Params: - name = The TZ Database name of the desired time zone - - Throws: - $(REF DateTimeException,std,datetime,date) if the given time zone - could not be found. - +/ + // Explicitly undocumented. It will be removed in June 2018. @@@DEPRECATED_2018-07@@@ deprecated("Use PosixTimeZone.getTimeZone or WindowsTimeZone.getTimeZone instead") static immutable(TimeZone) getTimeZone(string name) @safe { @@ -524,35 +488,7 @@ public: } - // @@@DEPRECATED_2017-07@@@ - /++ - $(RED Deprecated. Use either PosixTimeZone.getInstalledTZNames or - WindowsTimeZone.getInstalledTZNames. ($(LREF parseTZConversions) - can be used to convert time zone names if necessary). Microsoft - changes their time zones too often for us to compile the - conversions into Phobos and have them be properly up-to-date. - TimeZone.getInstalledTZNames will be removed in July 2017.) - - Returns a list of the names of the time zones installed on the system. - - Providing a sub-name narrows down the list of time zones (which - can number in the thousands). For example, - passing in "America" as the sub-name returns only the time zones which - begin with "America". - - On Windows, this function will convert the Windows time zone names to - the corresponding TZ Database names with - $(D windowsTZNameToTZDatabaseName). To get the actual Windows time - zone names, use $(D WindowsTimeZone.getInstalledTZNames) directly. - - Params: - subName = The first part of the time zones desired. - - Throws: - $(D FileException) on Posix systems if it fails to read from disk. - $(REF DateTimeException,std,datetime,date) on Windows systems if - it fails to read the registry. - +/ + // Explicitly undocumented. It will be removed in June 2018. @@@DEPRECATED_2018-07@@@ deprecated("Use PosixTimeZone.getInstalledTZNames or WindowsTimeZone.getInstalledTZNames instead") static string[] getInstalledTZNames(string subName = "") @safe { @@ -3523,34 +3459,7 @@ For terms of use, see http://www.unicode.org/copyright.html } -// @@@DEPRECATED_2017-07@@@ -/++ - $(RED Deprecated. Use $(LREF parseTZConversions) instead. Microsoft changes - their time zones too often for us to compile the conversions into - Phobos and have them be properly up-to-date. - tzDatabaseNameToWindowsTZName will be removed in July 2017.) - - Converts the given TZ Database name to the corresponding Windows time zone - name. - - Note that in a few cases, a TZ Dabatase name corresponds to two different - Windows time zone names. So, while in most cases converting from one to the - other and back again will result in the same time zone name started - with, in a few case, it'll get a different name. - - Also, there are far more TZ Database names than Windows time zones, so some - of the more exotic TZ Database names don't have corresponding Windows time - zone names. - - Returns null if the given time zone name cannot be converted. - - See_Also: - $(HTTP unicode.org/repos/cldr-tmp/trunk/diff/supplemental/zone_tzid.html, - Windows <-> TZ Database Name Conversion Table) - - Params: - tzName = The TZ Database name to convert. - +/ +// Explicitly undocumented. It will be removed in June 2018. @@@DEPRECATED_2018-07@@@ deprecated("Use parseTZConversions instead") string tzDatabaseNameToWindowsTZName(string tzName) @safe pure nothrow @nogc { @@ -4019,25 +3928,7 @@ version(Windows) version(UpdateWindowsTZTranslations) deprecated @system unittes } -// @@@DEPRECATED_2017-07@@@ -/++ - $(RED Deprecated. Use $(LREF parseTZConversions) instead. Microsoft changes - their time zones too often for us to compile the conversions into - Phobos and have them be properly up-to-date. - windowsTZNameToTZDatabaseName will be removed in July 2017.) - - Converts the given Windows time zone name to a corresponding TZ Database - name. - - Returns null if the given time zone name cannot be converted. - - See_Also: - $(HTTP unicode.org/repos/cldr-tmp/trunk/diff/supplemental/zone_tzid.html, - Windows <-> TZ Database Name Conversion Table) - - Params: - tzName = The TZ Database name to convert. - +/ +// Explicitly undocumented. It will be removed in June 2018. @@@DEPRECATED_2018-07@@@ deprecated("Use parseTZConversions instead") string windowsTZNameToTZDatabaseName(string tzName) @safe pure nothrow @nogc { From 102cd2da250412234206fa235e20ba0b2a4af312 Mon Sep 17 00:00:00 2001 From: Rainer Schuetze Date: Tue, 18 Jul 2017 22:36:24 +0200 Subject: [PATCH 149/163] fix case in documentation --- std/traits.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/std/traits.d b/std/traits.d index efa82d01ed0..37f4f123110 100644 --- a/std/traits.d +++ b/std/traits.d @@ -1020,7 +1020,7 @@ Get tuple, one per function parameter, of the storage classes of the parameters. Params: func = function symbol or type of function, delegate, or pointer to function Returns: - a tuple of ParameterStorageClass bits + A tuple of ParameterStorageClass bits */ enum ParameterStorageClass : uint { From 2c0e2c7bd8fb2cdba04d171230a6066e0b9b21b6 Mon Sep 17 00:00:00 2001 From: Rainer Schuetze Date: Wed, 19 Jul 2017 01:01:59 +0200 Subject: [PATCH 150/163] convert static loop into runtime/CTFE loop --- std/traits.d | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/std/traits.d b/std/traits.d index 37f4f123110..1a27ea86b3d 100644 --- a/std/traits.d +++ b/std/traits.d @@ -1089,22 +1089,25 @@ template ParameterStorageClassTuple(func...) ParameterStorageClass extractParameterStorageClassFlags(Attribs...)() { auto result = ParameterStorageClass.none; - foreach (attrib; Attribs) + static if (Attribs.length > 0) { - final switch (attrib) with (ParameterStorageClass) + foreach (attrib; [Attribs]) { - case "scope": result |= scope_; break; - case "out": result |= out_; break; - case "ref": result |= ref_; break; - case "lazy": result |= lazy_; break; - case "return": result |= return_; break; + final switch (attrib) with (ParameterStorageClass) + { + case "scope": result |= scope_; break; + case "out": result |= out_; break; + case "ref": result |= ref_; break; + case "lazy": result |= lazy_; break; + case "return": result |= return_; break; + } } + /* Mimic behavor of original version of ParameterStorageClassTuple() + * to avoid breaking existing code. + */ + if (result == (ParameterStorageClass.ref_ | ParameterStorageClass.return_)) + result = ParameterStorageClass.return_; } - /* Mimic behavor of original version of ParameterStorageClassTuple() - * to avoid breaking existing code. - */ - if (result == (ParameterStorageClass.ref_ | ParameterStorageClass.return_)) - result = ParameterStorageClass.return_; return result; } From 598c5636277a868e1de009f72e8372a73657d825 Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Wed, 19 Jul 2017 01:09:16 +0200 Subject: [PATCH 151/163] Add @safe to unittests to fix CircleCi --- std/functional.d | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/std/functional.d b/std/functional.d index b4370c78074..2c4104c145f 100644 --- a/std/functional.d +++ b/std/functional.d @@ -1170,7 +1170,7 @@ template memoize(alias fun, uint maxSize) } // 16079: memoize should work with arrays -unittest +@safe unittest { int executed = 0; T median(T)(const T[] nums) { @@ -1194,7 +1194,7 @@ unittest } // 16079: memoize should work with structs -unittest +@safe unittest { int executed = 0; T pickFirst(T)(T first) @@ -1213,7 +1213,7 @@ unittest } // 16079: memoize should work with classes -unittest +@safe unittest { int executed = 0; T pickFirst(T)(T first) From 272722fc5bf56e2528c8d89e1fea7957d4e065b7 Mon Sep 17 00:00:00 2001 From: Rainer Schuetze Date: Wed, 19 Jul 2017 08:09:37 +0200 Subject: [PATCH 152/163] avoid new CTFE function to be emitted to the object file --- std/traits.d | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/std/traits.d b/std/traits.d index 1a27ea86b3d..fecc8e36bfe 100644 --- a/std/traits.d +++ b/std/traits.d @@ -1086,29 +1086,32 @@ template ParameterStorageClassTuple(func...) * Returns: * ParameterStorageClass bits */ -ParameterStorageClass extractParameterStorageClassFlags(Attribs...)() +template extractParameterStorageClassFlags(Attribs...) { - auto result = ParameterStorageClass.none; - static if (Attribs.length > 0) + enum ParameterStorageClass extractParameterStorageClassFlags = () { - foreach (attrib; [Attribs]) + auto result = ParameterStorageClass.none; + static if (Attribs.length > 0) { - final switch (attrib) with (ParameterStorageClass) + foreach (attrib; [Attribs]) { - case "scope": result |= scope_; break; - case "out": result |= out_; break; - case "ref": result |= ref_; break; - case "lazy": result |= lazy_; break; - case "return": result |= return_; break; + final switch (attrib) with (ParameterStorageClass) + { + case "scope": result |= scope_; break; + case "out": result |= out_; break; + case "ref": result |= ref_; break; + case "lazy": result |= lazy_; break; + case "return": result |= return_; break; + } } + /* Mimic behavor of original version of ParameterStorageClassTuple() + * to avoid breaking existing code. + */ + if (result == (ParameterStorageClass.ref_ | ParameterStorageClass.return_)) + result = ParameterStorageClass.return_; } - /* Mimic behavor of original version of ParameterStorageClassTuple() - * to avoid breaking existing code. - */ - if (result == (ParameterStorageClass.ref_ | ParameterStorageClass.return_)) - result = ParameterStorageClass.return_; - } - return result; + return result; + }(); } @safe unittest From caf274304e37b02394f03fea610382288658dc03 Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Thu, 20 Jul 2017 21:00:36 +0200 Subject: [PATCH 153/163] Mention TypeTuple at std.meta.AliasSeq --- std/meta.d | 2 ++ 1 file changed, 2 insertions(+) diff --git a/std/meta.d b/std/meta.d index ffca2c0ee71..e4ff802a835 100644 --- a/std/meta.d +++ b/std/meta.d @@ -75,6 +75,8 @@ module std.meta; /** * Creates a sequence of zero or more aliases. This is most commonly * used as template parameters or arguments. + * + * In previous versions of Phobos, this was known as `TypeTuple`. */ template AliasSeq(TList...) { From 58989c347ff9e3d1e662f1d135619f0c2c889011 Mon Sep 17 00:00:00 2001 From: MetaLang Date: Thu, 20 Jul 2017 16:48:05 -0300 Subject: [PATCH 154/163] Remove all mentions of TypeTuple from std.meta --- std/meta.d | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/std/meta.d b/std/meta.d index ffca2c0ee71..afde75acdc8 100644 --- a/std/meta.d +++ b/std/meta.d @@ -343,7 +343,7 @@ if (args.length >= 1) } /** - * Returns a typetuple created from TList with the first occurrence, + * Returns an `AliasSeq` created from TList with the first occurrence, * if any, of T removed. */ template Erase(T, TList...) @@ -401,7 +401,7 @@ if (args.length >= 1) /** - * Returns a typetuple created from TList with the all occurrences, + * Returns an `AliasSeq` created from TList with the all occurrences, * if any, of T removed. */ template EraseAll(T, TList...) @@ -464,7 +464,7 @@ if (args.length >= 1) /** - * Returns a typetuple created from TList with the all duplicate + * Returns an `AliasSeq` created from TList with the all duplicate * types removed. */ template NoDuplicates(TList...) @@ -523,7 +523,7 @@ template NoDuplicates(TList...) /** - * Returns a typetuple created from TList with the first occurrence + * Returns an `AliasSeq` created from TList with the first occurrence * of type T, if found, replaced with type U. */ template Replace(T, U, TList...) @@ -603,7 +603,7 @@ if (args.length >= 2) } /** - * Returns a typetuple created from TList with all occurrences + * Returns an `AliasSeq` created from TList with all occurrences * of type T, if found, replaced with type U. */ template ReplaceAll(T, U, TList...) @@ -683,7 +683,7 @@ if (args.length >= 2) } /** - * Returns a typetuple created from TList with the order reversed. + * Returns an `AliasSeq` created from TList with the order reversed. */ template Reverse(TList...) { @@ -736,7 +736,7 @@ template MostDerived(T, TList...) } /** - * Returns the typetuple TList with the types sorted so that the most + * Returns the `AliasSeq` TList with the types sorted so that the most * derived types come first. */ template DerivedToFront(TList...) From 2e2bab3b7409fc041d39103cbf29340f70b18559 Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Thu, 20 Jul 2017 22:29:35 +0200 Subject: [PATCH 155/163] std.digest link cleanup - Convert references to MREFs - Add source link to std.digest.murmurhash - Add assert to the examples in std.digest.murmurhash --- std/digest/crc.d | 4 ++-- std/digest/md.d | 4 ++-- std/digest/murmurhash.d | 8 ++++++-- std/digest/ripemd.d | 4 ++-- std/digest/sha.d | 4 ++-- 5 files changed, 14 insertions(+), 10 deletions(-) diff --git a/std/digest/crc.d b/std/digest/crc.d index f18598c38e7..323c17489c0 100644 --- a/std/digest/crc.d +++ b/std/digest/crc.d @@ -19,9 +19,9 @@ $(TR $(TDNW Helpers) $(TD $(MYREF crcHexString) $(MYREF crc32Of) $(MYREF crc64EC * * This module conforms to the APIs defined in $(D std.digest). To understand the - * differences between the template and the OOP API, see $(D std.digest). + * differences between the template and the OOP API, see $(MREF std, digest). * - * This module publicly imports $(D std.digest) and can be used as a stand-alone + * This module publicly imports $(MREF std, digest) and can be used as a stand-alone * module. * * Note: diff --git a/std/digest/md.d b/std/digest/md.d index 5f15d958bf2..ef7c04d8668 100644 --- a/std/digest/md.d +++ b/std/digest/md.d @@ -19,9 +19,9 @@ $(TR $(TDNW Helpers) $(TD $(MYREF md5Of)) ) * This module conforms to the APIs defined in $(D std.digest). To understand the - * differences between the template and the OOP API, see $(D std.digest). + * differences between the template and the OOP API, see $(MREF std, digest). * - * This module publicly imports $(D std.digest) and can be used as a stand-alone + * This module publicly imports $(MREF std, digest) and can be used as a stand-alone * module. * * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0). diff --git a/std/digest/murmurhash.d b/std/digest/murmurhash.d index e8930a7cc55..74efed56898 100644 --- a/std/digest/murmurhash.d +++ b/std/digest/murmurhash.d @@ -22,10 +22,11 @@ $(LI The current implementation is optimized for little endian architectures. less uniform distribution.) ) -This module conforms to the APIs defined in $(D std.digest). +This module conforms to the APIs defined in $(MREF std, digest). -This module publicly imports $(D std.digest) and can be used as a stand-alone module. +This module publicly imports $(MREF std, digest) and can be used as a stand-alone module. +Source: $(PHOBOSSRC std/digest/_murmurhash.d) License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0). Authors: Guillaume Chatelet References: $(LINK2 https://github.com/aappleby/smhasher, Reference implementation) @@ -45,6 +46,7 @@ module std.digest.murmurhash; static assert(isDigest!(MurmurHash3!32)); // The convenient digest template allows for quick hashing of any data. ubyte[4] hashed = digest!(MurmurHash3!32)([1, 2, 3, 4]); + assert(hashed == [0, 173, 69, 68]); } /// @@ -62,6 +64,7 @@ module std.digest.murmurhash; // - the remaining bits are processed // - the hash gets finalized auto hashed = hasher.finish(); + assert(hashed == [181, 151, 88, 252]); } /// @@ -86,6 +89,7 @@ module std.digest.murmurhash; hasher.finalize(); // Finally get the hashed value. auto hashed = hasher.getBytes(); + assert(hashed == [188, 165, 108, 2]); } public import std.digest; diff --git a/std/digest/ripemd.d b/std/digest/ripemd.d index 60420f4c34a..5c3153f5e3b 100644 --- a/std/digest/ripemd.d +++ b/std/digest/ripemd.d @@ -18,8 +18,8 @@ $(TR $(TDNW Helpers) $(TD $(MYREF ripemd160Of)) ) ) - * This module conforms to the APIs defined in $(D std.digest). To understand the - * differences between the template and the OOP API, see $(D std.digest). + * This module conforms to the APIs defined in $(MREF std, digest). To understand the + * differences between the template and the OOP API, see $(MREF std, digest). * * This module publicly imports $(D std.digest) and can be used as a stand-alone * module. diff --git a/std/digest/sha.d b/std/digest/sha.d index 91ffd55023d..3374cbfb634 100644 --- a/std/digest/sha.d +++ b/std/digest/sha.d @@ -23,8 +23,8 @@ $(TR $(TDNW Helpers) $(TD $(MYREF sha1Of)) * SHA2 comes in several different versions, all supported by this module: * SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224 and SHA-512/256. * - * This module conforms to the APIs defined in $(D std.digest). To understand the - * differences between the template and the OOP API, see $(D std.digest). + * This module conforms to the APIs defined in $(MREF std, digest). To understand the + * differences between the template and the OOP API, see $(MREF std, digest). * * This module publicly imports $(D std.digest) and can be used as a stand-alone * module. From dc648c5b38f9c43d07a69a20855beb2616fa49d4 Mon Sep 17 00:00:00 2001 From: RazvanN7 Date: Fri, 21 Jul 2017 09:19:02 +0300 Subject: [PATCH 156/163] Add documentation and unittests regarding multisets --- std/algorithm/package.d | 3 +- std/algorithm/setops.d | 128 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 124 insertions(+), 7 deletions(-) diff --git a/std/algorithm/package.d b/std/algorithm/package.d index 656dbcfd85e..4c9a72f71c9 100644 --- a/std/algorithm/package.d +++ b/std/algorithm/package.d @@ -116,7 +116,8 @@ $(TR $(SUBREF setops, cartesianProduct) $(SUBREF setops, largestPartialIntersection) $(SUBREF setops, largestPartialIntersectionWeighted) - $(SUBREF setops, nWayUnion) + $(SUBREF setops, multiwayMerge) + $(SUBREF setops, multiwayUnion) $(SUBREF setops, setDifference) $(SUBREF setops, setIntersection) $(SUBREF setops, setSymmetricDifference) diff --git a/std/algorithm/setops.d b/std/algorithm/setops.d index c556cbf8526..f7a0080af2c 100644 --- a/std/algorithm/setops.d +++ b/std/algorithm/setops.d @@ -3,6 +3,14 @@ This is a submodule of $(MREF std, algorithm). It contains generic algorithms that implement set operations. +The functions $(LREF multiwayMerge), $(LREF multiwayUnion), $(LREF setDifference), +$(LREF setIntersection), $(LREF setSymmetricDifference) expect a range of sorted +ranges as input. + +All algorithms are generalized to accept as input not only sets but also +$(HTTP https://en.wikipedia.org/wiki/Multiset, multisets). Each algorithm +documents behaviour in the presence of duplicated inputs. + $(SCRIPT inhibitQuickIndex = 1;) $(BOOKTABLE Cheat Sheet, $(TR $(TH Function Name) $(TH Description)) @@ -14,8 +22,9 @@ $(T2 largestPartialIntersectionWeighted, Copies out the values that occur most frequently (multiplied by per-value weights) in a range of ranges.) $(T2 multiwayMerge, - Computes the union of a set of sets implemented as a range of sorted - ranges.) + Merges a range of sorted ranges.) +$(T2 multiwayUnion, + Computes the union of a range of sorted ranges.) $(T2 setDifference, Lazily computes the set difference of two or more sorted ranges.) $(T2 setIntersection, @@ -568,6 +577,11 @@ array of the occurrences and then selecting its top items, and also requires less memory ($(D largestPartialIntersection) builds its result directly in $(D tgt) and requires no extra memory). +If at least one of the ranges is a multiset, then all occurences +of a duplicate element are taken into account. The result is +equivalent to merging all ranges and picking the most frequent +$(D tgt.length) elements. + Warning: Because $(D largestPartialIntersection) does not allocate extra memory, it will leave $(D ror) modified. Namely, $(D largestPartialIntersection) assumes ownership of $(D ror) and @@ -616,6 +630,22 @@ void largestPartialIntersection largestPartialIntersection(a, c); assert(c[0] == tuple(1.0, 3u)); // 1.0 occurs in 3 inputs + + // multiset + double[][] x = + [ + [1, 1, 1, 1, 4, 7, 8], + [1, 7], + [1, 7, 8], + [4, 7], + [7] + ]; + auto y = new Tuple!(double, uint)[2]; + largestPartialIntersection(x.dup, y); + // 7.0 occurs 5 times + assert(y[0] == tuple(7.0, 5u)); + // 1.0 occurs 6 times + assert(y[1] == tuple(1.0, 6u)); } import std.algorithm.sorting : SortOutput; // FIXME @@ -625,6 +655,11 @@ import std.algorithm.sorting : SortOutput; // FIXME Similar to $(D largestPartialIntersection), but associates a weight with each distinct element in the intersection. +If at least one of the ranges is a multiset, then all occurences +of a duplicate element are taken into account. The result +is equivalent to merging all input ranges and picking the highest +$(D tgt.length), weight-based ranking elements. + Params: less = The predicate the ranges are sorted by. ror = A range of $(REF_ALTTEXT forward ranges, isForwardRange, std,range,primitives) @@ -672,6 +707,20 @@ void largestPartialIntersectionWeighted assert(b[0] == tuple(4.0, 2u)); // 4.0 occurs 2 times -> 4.6 (2 * 2.3) // 7.0 occurs 3 times -> 4.4 (3 * 1.1) + + // multiset + double[][] x = + [ + [ 1, 1, 1, 4, 7, 8 ], + [ 1, 7 ], + [ 1, 7, 8], + [ 4 ], + [ 7 ], + ]; + auto y = new Tuple!(double, uint)[1]; + largestPartialIntersectionWeighted(x, y, weights); + assert(y[0] == tuple(1.0, 5u)); + // 1.0 occurs 5 times -> 1.2 * 5 = 6 } @system unittest @@ -746,7 +795,7 @@ void largestPartialIntersectionWeighted // MultiwayMerge /** -Computes the union of multiple sets. The input sets are passed as a +Merges multiple sets. The input sets are passed as a range of ranges and each is assumed to be sorted by $(D less). Computation is done lazily, one union element at a time. The complexity of one $(D popFront) operation is $(BIGOH @@ -759,6 +808,10 @@ MultiwayMerge) is $(BIGOH n * ror.length * log(ror.length)), i.e., $(D log(ror.length)) times worse than just spanning all ranges in turn. The output comes sorted (unstably) by $(D less). +The length of the resulting range is the sum of all lengths of +the ranges passed as input. This means that all elements (duplicates +included) are transferred to the resulting range. + For backward compatibility, `multiwayMerge` is available under the name `nWayUnion` and `MultiwayMerge` under the name of `NWayUnion` . Future code should use `multiwayMerge` and `MultiwayMerge` as `nWayUnion` @@ -859,6 +912,18 @@ MultiwayMerge!(less, RangeOfRanges) multiwayMerge 1, 1, 1, 4, 4, 7, 7, 7, 7, 8, 8 ]; assert(equal(multiwayMerge(a), witness)); + + double[][] b = + [ + // range with duplicates + [ 1, 1, 4, 7, 8 ], + [ 7 ], + [ 1, 7, 8], + [ 4 ], + [ 7 ], + ]; + // duplicates are propagated to the resulting range + assert(equal(multiwayMerge(b), witness)); } alias nWayUnion = multiwayMerge; @@ -870,14 +935,16 @@ as a range of ranges and each is assumed to be sorted by $(D less). Computation is done lazily, one union element at a time. `multiwayUnion(ror)` is functionally equivalent to `multiwayMerge(ror).uniq`. +"The output of multiwayUnion has no duplicates even when its inputs contain duplicates." + Params: less = Predicate the given ranges are sorted by. ror = A range of ranges sorted by `less` to compute the intersection for. Returns: - A range of the intersection of the ranges in `ror`. + A range of the union of the ranges in `ror`. -See also: $(LREF NWayUnion) +See also: $(LREF multiwayMerge) */ auto multiwayUnion(alias less = "a < b", RangeOfRanges)(RangeOfRanges ror) { @@ -890,6 +957,7 @@ auto multiwayUnion(alias less = "a < b", RangeOfRanges)(RangeOfRanges ror) { import std.algorithm.comparison : equal; + // sets double[][] a = [ [ 1, 4, 7, 8 ], @@ -901,6 +969,17 @@ auto multiwayUnion(alias less = "a < b", RangeOfRanges)(RangeOfRanges ror) auto witness = [1, 4, 7, 8]; assert(equal(multiwayUnion(a), witness)); + + // multisets + double[][] b = + [ + [ 1, 1, 1, 4, 7, 8 ], + [ 1, 7 ], + [ 1, 7, 7, 8], + [ 4 ], + [ 7 ], + ]; + assert(equal(multiwayUnion(b), witness)); } /** @@ -908,6 +987,11 @@ Lazily computes the difference of $(D r1) and $(D r2). The two ranges are assumed to be sorted by $(D less). The element types of the two ranges must have a common type. + +In the case of multisets, considering that element `a` appears `x` +times in $(D r1) and `y` times and $(D r2), the number of occurences +of `a` in the resulting range is going to be `x-y` if x > y or 0 othwerise. + Params: less = Predicate the given ranges are sorted by. r1 = The first range. @@ -997,10 +1081,18 @@ SetDifference!(less, R1, R2) setDifference(alias less = "a < b", R1, R2) import std.algorithm.comparison : equal; import std.range.primitives : isForwardRange; + //sets int[] a = [ 1, 2, 4, 5, 7, 9 ]; int[] b = [ 0, 1, 2, 4, 7, 8 ]; - assert(equal(setDifference(a, b), [5, 9][])); + assert(equal(setDifference(a, b), [5, 9])); static assert(isForwardRange!(typeof(setDifference(a, b)))); + + // multisets + int[] x = [1, 1, 1, 2, 3]; + int[] y = [1, 1, 2, 4, 5]; + auto r = setDifference(x, y); + assert(equal(r, [1, 3])); + assert(setDifference(r, x).empty); } @safe unittest // Issue 10460 @@ -1019,6 +1111,10 @@ Lazily computes the intersection of two or more input ranges $(D ranges). The ranges are assumed to be sorted by $(D less). The element types of the ranges must have a common type. +In the case of multisets, the range with the minimum number of +occurences of a given element, propagates the number of +occurences of this element to the resulting range. + Params: less = Predicate the given ranges are sorted by. ranges = The ranges to compute the intersection for. @@ -1132,12 +1228,19 @@ if (Rs.length >= 2 && allSatisfy!(isInputRange, Rs) && { import std.algorithm.comparison : equal; + // sets int[] a = [ 1, 2, 4, 5, 7, 9 ]; int[] b = [ 0, 1, 2, 4, 7, 8 ]; int[] c = [ 0, 1, 4, 5, 7, 8 ]; assert(equal(setIntersection(a, a), a)); assert(equal(setIntersection(a, b), [1, 2, 4, 7])); assert(equal(setIntersection(a, b, c), [1, 4, 7])); + + // multisets + int[] d = [ 1, 1, 2, 2, 7, 7 ]; + int[] e = [ 1, 1, 1, 7]; + assert(equal(setIntersection(a, d), [1, 2, 7])); + assert(equal(setIntersection(d, e), [1, 1, 7])); } @safe unittest @@ -1177,6 +1280,12 @@ r2). The two ranges are assumed to be sorted by $(D less), and the output is also sorted by $(D less). The element types of the two ranges must have a common type. +If both ranges are sets (without duplicated elements), the resulting +range is going to be a set. If at least one of the ranges is a multiset, +the number of occurences of an element `x` in the resulting range is `abs(a-b)` +where `a` is the number of occurences of `x` in $(D r1), `b` is the number of +occurences of `x` in $(D r2), and `abs` is the absolute value. + If both arguments are ranges of L-values of the same type then $(D SetSymmetricDifference) will also be a range of L-values of that type. @@ -1288,10 +1397,17 @@ setSymmetricDifference(alias less = "a < b", R1, R2) import std.algorithm.comparison : equal; import std.range.primitives : isForwardRange; + // sets int[] a = [ 1, 2, 4, 5, 7, 9 ]; int[] b = [ 0, 1, 2, 4, 7, 8 ]; assert(equal(setSymmetricDifference(a, b), [0, 5, 8, 9][])); static assert(isForwardRange!(typeof(setSymmetricDifference(a, b)))); + + //mutisets + int[] c = [1, 1, 1, 1, 2, 2, 2, 4, 5, 6]; + int[] d = [1, 1, 2, 2, 2, 2, 4, 7, 9]; + assert(equal(setSymmetricDifference(c, d), setSymmetricDifference(d, c))); + assert(equal(setSymmetricDifference(c, d), [1, 1, 2, 5, 6, 7, 9])); } @safe unittest // Issue 10460 From e3a650c2cec4e2cdcf575a4237753c1192b16f09 Mon Sep 17 00:00:00 2001 From: Adrian Matoga Date: Sun, 16 Jul 2017 21:23:09 +0200 Subject: [PATCH 157/163] Support abstract UnixAddress --- changelog/std-socket-abstract.dd | 10 +++ std/socket.d | 113 +++++++++++++++++++++++-------- 2 files changed, 95 insertions(+), 28 deletions(-) create mode 100644 changelog/std-socket-abstract.dd diff --git a/changelog/std-socket-abstract.dd b/changelog/std-socket-abstract.dd new file mode 100644 index 00000000000..1ccc8bf145b --- /dev/null +++ b/changelog/std-socket-abstract.dd @@ -0,0 +1,10 @@ +`std.socket.UnixAddress` now supports abstract addresses. + +UNIX domain sockets are usually identified by pathnames. Linux offers a +non-portable extension to this scheme, known as abstract socket addresses, +which are independent of the filesystem. An abstract socket address starts with +a null byte (`'\0'`), e.g.: + +--- +auto addr = new UnixAddress("\0/tmp/dbus-OtHLWmCLPR"); +--- diff --git a/std/socket.d b/std/socket.d index 608e1a4d612..e9011685a74 100644 --- a/std/socket.d +++ b/std/socket.d @@ -1269,6 +1269,20 @@ abstract class Address /// Returns actual size of underlying $(D sockaddr) structure. abstract @property socklen_t nameLen() const pure nothrow @nogc; + // Socket.remoteAddress, Socket.localAddress, and Socket.receiveFrom + // use setNameLen to set the actual size of the address as returned by + // getsockname, getpeername, and recvfrom, respectively. + // The following implementation is sufficient for fixed-length addresses, + // and ensures that the length is not changed. + // Must be overridden for variable-length addresses. + protected void setNameLen(socklen_t len) + { + if (len != this.nameLen) + throw new AddressException( + format("%s expects address of length %d, not %d", typeid(this), + this.nameLen, len), 0); + } + /// Family of this address. @property AddressFamily addressFamily() const pure nothrow @nogc { @@ -1914,7 +1928,22 @@ version(StdDdoc) /** * $(D UnixAddress) encapsulates an address for a Unix domain socket - * ($(D AF_UNIX)). Available only on supported systems. + * ($(D AF_UNIX)), i.e. a socket bound to a path name in the file system. + * Available only on supported systems. + * + * Linux also supports an abstract address namespace, in which addresses + * are independent of the file system. A socket address is abstract + * iff `path` starts with a _null byte (`'\0'`). Null bytes in other + * positions of an abstract address are allowed and have no special + * meaning. + * + * Example: + * --- + * auto addr = new UnixAddress("/var/run/dbus/system_bus_socket"); + * auto abstractAddr = new UnixAddress("\0/tmp/dbus-OtHLWmCLPR"); + * --- + * + * See_Also: $(HTTP http://man7.org/linux/man-pages/man7/unix.7.html, UNIX(7)) */ class UnixAddress: Address { @@ -1947,6 +1976,8 @@ static if (is(sockaddr_un)) class UnixAddress: Address { protected: + socklen_t _nameLen; + struct { align (1): @@ -1958,6 +1989,14 @@ static if (is(sockaddr_un)) { sun.sun_family = AddressFamily.UNIX; sun.sun_path = '?'; + _nameLen = sun.sizeof; + } + + override void setNameLen(socklen_t len) @trusted + { + if (len > sun.sizeof) + throw new SocketParameterException("Not enough socket address storage"); + _nameLen = len; } public: @@ -1973,8 +2012,7 @@ static if (is(sockaddr_un)) override @property socklen_t nameLen() @trusted const { - return cast(socklen_t) (sockaddr_un.init.sun_path.offsetof + - strlen(cast(const(char*)) sun.sun_path.ptr) + 1); + return _nameLen; } this(in char[] path) @trusted pure @@ -1982,7 +2020,18 @@ static if (is(sockaddr_un)) enforce(path.length <= sun.sun_path.sizeof, new SocketParameterException("Path too long")); sun.sun_family = AddressFamily.UNIX; sun.sun_path.ptr[0 .. path.length] = (cast(byte[]) path)[]; - sun.sun_path.ptr[path.length] = 0; + _nameLen = cast(socklen_t) + { + auto len = sockaddr_un.init.sun_path.offsetof + path.length; + // Pathname socket address must be terminated with '\0' + // which must be included in the address length. + if (sun.sun_path.ptr[0]) + { + sun.sun_path.ptr[path.length] = 0; + ++len; + } + return len; + }(); } this(sockaddr_un addr) pure nothrow @nogc @@ -1993,7 +2042,11 @@ static if (is(sockaddr_un)) @property string path() @trusted const pure { - return to!string(cast(const(char)*)sun.sun_path.ptr); + auto len = _nameLen - sockaddr_un.init.sun_path.offsetof; + // For pathname socket address we need to strip off the terminating '\0' + if (sun.sun_path.ptr[0]) + --len; + return (cast(const(char)*) sun.sun_path.ptr)[0 .. len].idup; } override string toString() const pure @@ -2010,32 +2063,36 @@ static if (is(sockaddr_un)) immutable ubyte[] data = [1, 2, 3, 4]; Socket[2] pair; - auto name = deleteme ~ "-unix-socket"; - auto address = new UnixAddress(name); + auto names = [ deleteme ~ "-unix-socket" ]; + version (linux) + names ~= "\0" ~ deleteme ~ "-abstract\0unix\0socket"; + foreach (name; names) + { + auto address = new UnixAddress(name); - auto listener = new Socket(AddressFamily.UNIX, SocketType.STREAM); - scope(exit) listener.close(); + auto listener = new Socket(AddressFamily.UNIX, SocketType.STREAM); + scope(exit) listener.close(); + listener.bind(address); + scope(exit) () @trusted { if (name[0]) remove(name.tempCString()); } (); + assert(listener.localAddress.toString == name); - listener.bind(address); - scope(exit) () @trusted { remove(name.tempCString()); } (); - assert(listener.localAddress.toString == name); + listener.listen(1); - listener.listen(1); + pair[0] = new Socket(AddressFamily.UNIX, SocketType.STREAM); + scope(exit) listener.close(); - pair[0] = new Socket(AddressFamily.UNIX, SocketType.STREAM); - scope(exit) listener.close(); + pair[0].connect(address); + scope(exit) pair[0].close(); - pair[0].connect(address); - scope(exit) pair[0].close(); + pair[1] = listener.accept(); + scope(exit) pair[1].close(); - pair[1] = listener.accept(); - scope(exit) pair[1].close(); + pair[0].send(data); - pair[0].send(data); - - auto buf = new ubyte[data.length]; - pair[1].receive(buf); - assert(buf == data); + auto buf = new ubyte[data.length]; + pair[1].receive(buf); + assert(buf == data); + } } } @@ -2889,8 +2946,7 @@ public: socklen_t nameLen = addr.nameLen; if (_SOCKET_ERROR == .getpeername(sock, addr.name, &nameLen)) throw new SocketOSException("Unable to obtain remote socket address"); - if (nameLen > addr.nameLen) - throw new SocketParameterException("Not enough socket address storage"); + addr.setNameLen(nameLen); assert(addr.addressFamily == _family); return addr; } @@ -2902,8 +2958,7 @@ public: socklen_t nameLen = addr.nameLen; if (_SOCKET_ERROR == .getsockname(sock, addr.name, &nameLen)) throw new SocketOSException("Unable to obtain local socket address"); - if (nameLen > addr.nameLen) - throw new SocketParameterException("Not enough socket address storage"); + addr.setNameLen(nameLen); assert(addr.addressFamily == _family); return addr; } @@ -3046,6 +3101,7 @@ public: version(Windows) { auto read = .recvfrom(sock, buf.ptr, capToInt(buf.length), cast(int) flags, from.name, &nameLen); + from.setNameLen(nameLen); assert(from.addressFamily == _family); // if (!read) //connection closed return read; @@ -3053,6 +3109,7 @@ public: else { auto read = .recvfrom(sock, buf.ptr, buf.length, cast(int) flags, from.name, &nameLen); + from.setNameLen(nameLen); assert(from.addressFamily == _family); // if (!read) //connection closed return read; From 7d1b0891bb7fe7a23b4f27bb7039013e5304f894 Mon Sep 17 00:00:00 2001 From: Jack Applegame Date: Sun, 23 Jul 2017 15:18:59 +0300 Subject: [PATCH 158/163] formattedWrite should take output range by reference At the moment formattedWrite takes output range by value. It prevents to pass non-copyable ranges. --- std/format.d | 52 ++++++++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/std/format.d b/std/format.d index 10adbf24b42..d467bad7897 100644 --- a/std/format.d +++ b/std/format.d @@ -438,7 +438,7 @@ My friends are "John", "Nancy". My friends are John, Nancy. ) */ -uint formattedWrite(alias fmt, Writer, A...)(Writer w, A args) +uint formattedWrite(alias fmt, Writer, A...)(ref Writer w, A args) if (isSomeString!(typeof(fmt))) { alias e = checkFormatException!(fmt, A); @@ -463,7 +463,7 @@ if (isSomeString!(typeof(fmt))) } /// ditto -uint formattedWrite(Writer, Char, A...)(Writer w, in Char[] fmt, A args) +uint formattedWrite(Writer, Char, A...)(ref Writer w, in Char[] fmt, A args) { import std.conv : text; @@ -1163,7 +1163,7 @@ if (is(Unqual!Char == Char)) trailing = fmt; } - bool writeUpToNextSpec(OutputRange)(OutputRange writer) + bool writeUpToNextSpec(OutputRange)(ref OutputRange writer) { if (trailing.empty) return false; @@ -1724,7 +1724,7 @@ Params: obj = The value to write. f = The $(D FormatSpec) defining how to write the value. */ -void formatValue(Writer, T, Char)(Writer w, T obj, const ref FormatSpec!Char f) +void formatValue(Writer, T, Char)(ref Writer w, T obj, const ref FormatSpec!Char f) if (is(BooleanTypeOf!T) && !is(T == enum) && !hasToString!(T, Char)) { BooleanTypeOf!T val = obj; @@ -1806,7 +1806,7 @@ Params: obj = The value to write. f = The $(D FormatSpec) defining how to write the value. */ -void formatValue(Writer, T, Char)(Writer w, T obj, const ref FormatSpec!Char f) +void formatValue(Writer, T, Char)(ref Writer w, T obj, const ref FormatSpec!Char f) if (is(Unqual!T == typeof(null)) && !is(T == enum) && !hasToString!(T, Char)) { enforceFmt(f.spec == 's', @@ -1844,7 +1844,7 @@ Params: obj = The value to write. f = The $(D FormatSpec) defining how to write the value. */ -void formatValue(Writer, T, Char)(Writer w, T obj, const ref FormatSpec!Char f) +void formatValue(Writer, T, Char)(ref Writer w, T obj, const ref FormatSpec!Char f) if (is(IntegralTypeOf!T) && !is(T == enum) && !hasToString!(T, Char)) { alias U = IntegralTypeOf!T; @@ -1900,7 +1900,7 @@ if (is(IntegralTypeOf!T) && !is(T == enum) && !hasToString!(T, Char)) assert(w.data == "1337"); } -private void formatIntegral(Writer, T, Char)(Writer w, const(T) val, const ref FormatSpec!Char fs, +private void formatIntegral(Writer, T, Char)(ref Writer w, const(T) val, const ref FormatSpec!Char fs, uint base, ulong mask) { T arg = val; @@ -1918,7 +1918,7 @@ private void formatIntegral(Writer, T, Char)(Writer w, const(T) val, const ref F formatUnsigned(w, (cast(ulong) arg) & mask, fs, base, negative); } -private void formatUnsigned(Writer, T, Char)(Writer w, T arg, const ref FormatSpec!Char fs, uint base, bool negative) +private void formatUnsigned(Writer, T, Char)(ref Writer w, T arg, const ref FormatSpec!Char fs, uint base, bool negative) { /* Write string: * leftpad prefix1 prefix2 zerofill digits rightpad @@ -2120,7 +2120,7 @@ Params: obj = The value to write. f = The $(D FormatSpec) defining how to write the value. */ -void formatValue(Writer, T, Char)(Writer w, T obj, const ref FormatSpec!Char f) +void formatValue(Writer, T, Char)(ref Writer w, T obj, const ref FormatSpec!Char f) if (is(FloatingPointTypeOf!T) && !is(T == enum) && !hasToString!(T, Char)) { import std.algorithm.comparison : min; @@ -2344,7 +2344,7 @@ Params: obj = The value to write. f = The $(D FormatSpec) defining how to write the value. */ -void formatValue(Writer, T, Char)(Writer w, T obj, const ref FormatSpec!Char f) +void formatValue(Writer, T, Char)(ref Writer w, T obj, const ref FormatSpec!Char f) if (is(Unqual!T : creal) && !is(T == enum) && !hasToString!(T, Char)) { immutable creal val = obj; @@ -2400,7 +2400,7 @@ Params: obj = The value to write. f = The $(D FormatSpec) defining how to write the value. */ -void formatValue(Writer, T, Char)(Writer w, T obj, const ref FormatSpec!Char f) +void formatValue(Writer, T, Char)(ref Writer w, T obj, const ref FormatSpec!Char f) if (is(Unqual!T : ireal) && !is(T == enum) && !hasToString!(T, Char)) { immutable ireal val = obj; @@ -2447,7 +2447,7 @@ Params: obj = The value to write. f = The $(D FormatSpec) defining how to write the value. */ -void formatValue(Writer, T, Char)(Writer w, T obj, const ref FormatSpec!Char f) +void formatValue(Writer, T, Char)(ref Writer w, T obj, const ref FormatSpec!Char f) if (is(CharTypeOf!T) && !is(T == enum) && !hasToString!(T, Char)) { CharTypeOf!T val = obj; @@ -2520,7 +2520,7 @@ Params: obj = The value to write. f = The $(D FormatSpec) defining how to write the value. */ -void formatValue(Writer, T, Char)(Writer w, T obj, const ref FormatSpec!Char f) +void formatValue(Writer, T, Char)(ref Writer w, T obj, const ref FormatSpec!Char f) if (is(StringTypeOf!T) && !is(StaticArrayTypeOf!T) && !is(T == enum) && !hasToString!(T, Char)) { Unqual!(StringTypeOf!T) val = obj; // for `alias this`, see bug5371 @@ -2598,7 +2598,7 @@ Params: obj = The value to write. f = The $(D FormatSpec) defining how to write the value. */ -void formatValue(Writer, T, Char)(Writer w, auto ref T obj, const ref FormatSpec!Char f) +void formatValue(Writer, T, Char)(ref Writer w, auto ref T obj, const ref FormatSpec!Char f) if (is(StaticArrayTypeOf!T) && !is(T == enum) && !hasToString!(T, Char)) { formatValue(w, obj[], f); @@ -2641,7 +2641,7 @@ Params: obj = The value to write. f = The $(D FormatSpec) defining how to write the value. */ -void formatValue(Writer, T, Char)(Writer w, T obj, const ref FormatSpec!Char f) +void formatValue(Writer, T, Char)(ref Writer w, T obj, const ref FormatSpec!Char f) if (is(DynamicArrayTypeOf!T) && !is(StringTypeOf!T) && !is(T == enum) && !hasToString!(T, Char)) { static if (is(const(ArrayTypeOf!T) == const(void[]))) @@ -3024,7 +3024,7 @@ if (isInputRange!T) } // character formatting with ecaping -private void formatChar(Writer)(Writer w, in dchar c, in char quote) +private void formatChar(Writer)(ref Writer w, in dchar c, in char quote) { import std.uni : isGraphical; @@ -3062,7 +3062,7 @@ private void formatChar(Writer)(Writer w, in dchar c, in char quote) // undocumented because of deprecation // string elements are formatted like UTF-8 string literals. -void formatElement(Writer, T, Char)(Writer w, T val, const ref FormatSpec!Char f) +void formatElement(Writer, T, Char)(ref Writer w, T val, const ref FormatSpec!Char f) if (is(StringTypeOf!T) && !is(T == enum)) { import std.array : appender; @@ -3147,7 +3147,7 @@ if (is(StringTypeOf!T) && !is(T == enum)) // undocumented because of deprecation // Character elements are formatted like UTF-8 character literals. -void formatElement(Writer, T, Char)(Writer w, T val, const ref FormatSpec!Char f) +void formatElement(Writer, T, Char)(ref Writer w, T val, const ref FormatSpec!Char f) if (is(CharTypeOf!T) && !is(T == enum)) { if (f.spec == 's') @@ -3173,7 +3173,7 @@ if (is(CharTypeOf!T) && !is(T == enum)) // undocumented // Maybe T is noncopyable struct, so receive it by 'auto ref'. -void formatElement(Writer, T, Char)(Writer w, auto ref T val, const ref FormatSpec!Char f) +void formatElement(Writer, T, Char)(ref Writer w, auto ref T val, const ref FormatSpec!Char f) if (!is(StringTypeOf!T) && !is(CharTypeOf!T) || is(T == enum)) { formatValue(w, val, f); @@ -3188,7 +3188,7 @@ Params: obj = The value to write. f = The $(D FormatSpec) defining how to write the value. */ -void formatValue(Writer, T, Char)(Writer w, T obj, const ref FormatSpec!Char f) +void formatValue(Writer, T, Char)(ref Writer w, T obj, const ref FormatSpec!Char f) if (is(AssocArrayTypeOf!T) && !is(T == enum) && !hasToString!(T, Char)) { AssocArrayTypeOf!T val = obj; @@ -3433,7 +3433,7 @@ const string toString(); Otherwise, are formatted just as their type name. */ -void formatValue(Writer, T, Char)(Writer w, T val, const ref FormatSpec!Char f) +void formatValue(Writer, T, Char)(ref Writer w, T val, const ref FormatSpec!Char f) if (is(T == class) && !is(T == enum)) { enforceValidFormatSpec!(T, Char)(f); @@ -3582,7 +3582,7 @@ if (is(T == class) && !is(T == enum)) } /// ditto -void formatValue(Writer, T, Char)(Writer w, T val, const ref FormatSpec!Char f) +void formatValue(Writer, T, Char)(ref Writer w, T val, const ref FormatSpec!Char f) if (is(T == interface) && (hasToString!(T, Char) || !is(BuiltinTypeOf!T)) && !is(T == enum)) { enforceValidFormatSpec!(T, Char)(f); @@ -3662,7 +3662,7 @@ if (is(T == interface) && (hasToString!(T, Char) || !is(BuiltinTypeOf!T)) && !is /// ditto // Maybe T is noncopyable struct, so receive it by 'auto ref'. -void formatValue(Writer, T, Char)(Writer w, auto ref T val, const ref FormatSpec!Char f) +void formatValue(Writer, T, Char)(ref Writer w, auto ref T val, const ref FormatSpec!Char f) if ((is(T == struct) || is(T == union)) && (hasToString!(T, Char) || !is(BuiltinTypeOf!T)) && !is(T == enum)) { enforceValidFormatSpec!(T, Char)(f); @@ -3797,7 +3797,7 @@ Params: val = The value to write. f = The $(D FormatSpec) defining how to write the value. */ -void formatValue(Writer, T, Char)(Writer w, T val, const ref FormatSpec!Char f) +void formatValue(Writer, T, Char)(ref Writer w, T val, const ref FormatSpec!Char f) if (is(T == enum)) { if (f.spec == 's') @@ -3866,7 +3866,7 @@ if (is(T == enum)) /** Pointers are formatted as hex integers. */ -void formatValue(Writer, T, Char)(Writer w, T val, const ref FormatSpec!Char f) +void formatValue(Writer, T, Char)(ref Writer w, T val, const ref FormatSpec!Char f) if (isPointer!T && !is(T == enum) && !hasToString!(T, Char)) { static if (isInputRange!T) @@ -3971,7 +3971,7 @@ if (isPointer!T && !is(T == enum) && !hasToString!(T, Char)) /** Delegates are formatted by 'ReturnType delegate(Parameters) FunctionAttributes' */ -void formatValue(Writer, T, Char)(Writer w, scope T, const ref FormatSpec!Char f) +void formatValue(Writer, T, Char)(ref Writer w, scope T, const ref FormatSpec!Char f) if (isDelegate!T) { formatValue(w, T.stringof, f); From 6995c19d61c54fc360b0c76c37aa82c6fb7c8ce8 Mon Sep 17 00:00:00 2001 From: Jack Applegame Date: Sun, 23 Jul 2017 15:27:05 +0300 Subject: [PATCH 159/163] Change "ref" to "auto ref" --- std/format.d | 54 ++++++++++++++++++++++++++-------------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/std/format.d b/std/format.d index d467bad7897..87c70747bdd 100644 --- a/std/format.d +++ b/std/format.d @@ -438,7 +438,7 @@ My friends are "John", "Nancy". My friends are John, Nancy. ) */ -uint formattedWrite(alias fmt, Writer, A...)(ref Writer w, A args) +uint formattedWrite(alias fmt, Writer, A...)(auto ref Writer w, A args) if (isSomeString!(typeof(fmt))) { alias e = checkFormatException!(fmt, A); @@ -463,7 +463,7 @@ if (isSomeString!(typeof(fmt))) } /// ditto -uint formattedWrite(Writer, Char, A...)(ref Writer w, in Char[] fmt, A args) +uint formattedWrite(Writer, Char, A...)(auto ref Writer w, in Char[] fmt, A args) { import std.conv : text; @@ -1724,7 +1724,7 @@ Params: obj = The value to write. f = The $(D FormatSpec) defining how to write the value. */ -void formatValue(Writer, T, Char)(ref Writer w, T obj, const ref FormatSpec!Char f) +void formatValue(Writer, T, Char)(auto ref Writer w, T obj, const ref FormatSpec!Char f) if (is(BooleanTypeOf!T) && !is(T == enum) && !hasToString!(T, Char)) { BooleanTypeOf!T val = obj; @@ -1806,7 +1806,7 @@ Params: obj = The value to write. f = The $(D FormatSpec) defining how to write the value. */ -void formatValue(Writer, T, Char)(ref Writer w, T obj, const ref FormatSpec!Char f) +void formatValue(Writer, T, Char)(auto ref Writer w, T obj, const ref FormatSpec!Char f) if (is(Unqual!T == typeof(null)) && !is(T == enum) && !hasToString!(T, Char)) { enforceFmt(f.spec == 's', @@ -1844,7 +1844,7 @@ Params: obj = The value to write. f = The $(D FormatSpec) defining how to write the value. */ -void formatValue(Writer, T, Char)(ref Writer w, T obj, const ref FormatSpec!Char f) +void formatValue(Writer, T, Char)(auto ref Writer w, T obj, const ref FormatSpec!Char f) if (is(IntegralTypeOf!T) && !is(T == enum) && !hasToString!(T, Char)) { alias U = IntegralTypeOf!T; @@ -1900,7 +1900,7 @@ if (is(IntegralTypeOf!T) && !is(T == enum) && !hasToString!(T, Char)) assert(w.data == "1337"); } -private void formatIntegral(Writer, T, Char)(ref Writer w, const(T) val, const ref FormatSpec!Char fs, +private void formatIntegral(Writer, T, Char)(auto ref Writer w, const(T) val, const ref FormatSpec!Char fs, uint base, ulong mask) { T arg = val; @@ -1918,7 +1918,7 @@ private void formatIntegral(Writer, T, Char)(ref Writer w, const(T) val, const r formatUnsigned(w, (cast(ulong) arg) & mask, fs, base, negative); } -private void formatUnsigned(Writer, T, Char)(ref Writer w, T arg, const ref FormatSpec!Char fs, uint base, bool negative) +private void formatUnsigned(Writer, T, Char)(auto ref Writer w, T arg, const ref FormatSpec!Char fs, uint base, bool negative) { /* Write string: * leftpad prefix1 prefix2 zerofill digits rightpad @@ -2120,7 +2120,7 @@ Params: obj = The value to write. f = The $(D FormatSpec) defining how to write the value. */ -void formatValue(Writer, T, Char)(ref Writer w, T obj, const ref FormatSpec!Char f) +void formatValue(Writer, T, Char)(auto ref Writer w, T obj, const ref FormatSpec!Char f) if (is(FloatingPointTypeOf!T) && !is(T == enum) && !hasToString!(T, Char)) { import std.algorithm.comparison : min; @@ -2344,7 +2344,7 @@ Params: obj = The value to write. f = The $(D FormatSpec) defining how to write the value. */ -void formatValue(Writer, T, Char)(ref Writer w, T obj, const ref FormatSpec!Char f) +void formatValue(Writer, T, Char)(auto ref Writer w, T obj, const ref FormatSpec!Char f) if (is(Unqual!T : creal) && !is(T == enum) && !hasToString!(T, Char)) { immutable creal val = obj; @@ -2400,7 +2400,7 @@ Params: obj = The value to write. f = The $(D FormatSpec) defining how to write the value. */ -void formatValue(Writer, T, Char)(ref Writer w, T obj, const ref FormatSpec!Char f) +void formatValue(Writer, T, Char)(auto ref Writer w, T obj, const ref FormatSpec!Char f) if (is(Unqual!T : ireal) && !is(T == enum) && !hasToString!(T, Char)) { immutable ireal val = obj; @@ -2447,7 +2447,7 @@ Params: obj = The value to write. f = The $(D FormatSpec) defining how to write the value. */ -void formatValue(Writer, T, Char)(ref Writer w, T obj, const ref FormatSpec!Char f) +void formatValue(Writer, T, Char)(auto ref Writer w, T obj, const ref FormatSpec!Char f) if (is(CharTypeOf!T) && !is(T == enum) && !hasToString!(T, Char)) { CharTypeOf!T val = obj; @@ -2520,7 +2520,7 @@ Params: obj = The value to write. f = The $(D FormatSpec) defining how to write the value. */ -void formatValue(Writer, T, Char)(ref Writer w, T obj, const ref FormatSpec!Char f) +void formatValue(Writer, T, Char)(auto ref Writer w, T obj, const ref FormatSpec!Char f) if (is(StringTypeOf!T) && !is(StaticArrayTypeOf!T) && !is(T == enum) && !hasToString!(T, Char)) { Unqual!(StringTypeOf!T) val = obj; // for `alias this`, see bug5371 @@ -2598,7 +2598,7 @@ Params: obj = The value to write. f = The $(D FormatSpec) defining how to write the value. */ -void formatValue(Writer, T, Char)(ref Writer w, auto ref T obj, const ref FormatSpec!Char f) +void formatValue(Writer, T, Char)(auto ref Writer w, auto ref T obj, const ref FormatSpec!Char f) if (is(StaticArrayTypeOf!T) && !is(T == enum) && !hasToString!(T, Char)) { formatValue(w, obj[], f); @@ -2641,7 +2641,7 @@ Params: obj = The value to write. f = The $(D FormatSpec) defining how to write the value. */ -void formatValue(Writer, T, Char)(ref Writer w, T obj, const ref FormatSpec!Char f) +void formatValue(Writer, T, Char)(auto ref Writer w, T obj, const ref FormatSpec!Char f) if (is(DynamicArrayTypeOf!T) && !is(StringTypeOf!T) && !is(T == enum) && !hasToString!(T, Char)) { static if (is(const(ArrayTypeOf!T) == const(void[]))) @@ -2855,7 +2855,7 @@ if (is(DynamicArrayTypeOf!T) && !is(StringTypeOf!T) && !is(T == enum) && !hasToS } // input range formatting -private void formatRange(Writer, T, Char)(ref Writer w, ref T val, const ref FormatSpec!Char f) +private void formatRange(Writer, T, Char)(auto ref Writer w, ref T val, const ref FormatSpec!Char f) if (isInputRange!T) { import std.conv : text; @@ -3024,7 +3024,7 @@ if (isInputRange!T) } // character formatting with ecaping -private void formatChar(Writer)(ref Writer w, in dchar c, in char quote) +private void formatChar(Writer)(auto ref Writer w, in dchar c, in char quote) { import std.uni : isGraphical; @@ -3062,7 +3062,7 @@ private void formatChar(Writer)(ref Writer w, in dchar c, in char quote) // undocumented because of deprecation // string elements are formatted like UTF-8 string literals. -void formatElement(Writer, T, Char)(ref Writer w, T val, const ref FormatSpec!Char f) +void formatElement(Writer, T, Char)(auto ref Writer w, T val, const ref FormatSpec!Char f) if (is(StringTypeOf!T) && !is(T == enum)) { import std.array : appender; @@ -3147,7 +3147,7 @@ if (is(StringTypeOf!T) && !is(T == enum)) // undocumented because of deprecation // Character elements are formatted like UTF-8 character literals. -void formatElement(Writer, T, Char)(ref Writer w, T val, const ref FormatSpec!Char f) +void formatElement(Writer, T, Char)(auto ref Writer w, T val, const ref FormatSpec!Char f) if (is(CharTypeOf!T) && !is(T == enum)) { if (f.spec == 's') @@ -3173,7 +3173,7 @@ if (is(CharTypeOf!T) && !is(T == enum)) // undocumented // Maybe T is noncopyable struct, so receive it by 'auto ref'. -void formatElement(Writer, T, Char)(ref Writer w, auto ref T val, const ref FormatSpec!Char f) +void formatElement(Writer, T, Char)(auto ref Writer w, auto ref T val, const ref FormatSpec!Char f) if (!is(StringTypeOf!T) && !is(CharTypeOf!T) || is(T == enum)) { formatValue(w, val, f); @@ -3188,7 +3188,7 @@ Params: obj = The value to write. f = The $(D FormatSpec) defining how to write the value. */ -void formatValue(Writer, T, Char)(ref Writer w, T obj, const ref FormatSpec!Char f) +void formatValue(Writer, T, Char)(auto ref Writer w, T obj, const ref FormatSpec!Char f) if (is(AssocArrayTypeOf!T) && !is(T == enum) && !hasToString!(T, Char)) { AssocArrayTypeOf!T val = obj; @@ -3332,7 +3332,7 @@ template hasToString(T, Char) } // object formatting with toString -private void formatObject(Writer, T, Char)(ref Writer w, ref T val, const ref FormatSpec!Char f) +private void formatObject(Writer, T, Char)(auto ref Writer w, ref T val, const ref FormatSpec!Char f) if (hasToString!(T, Char)) { static if (is(typeof(val.toString((const(char)[] s){}, f)))) @@ -3433,7 +3433,7 @@ const string toString(); Otherwise, are formatted just as their type name. */ -void formatValue(Writer, T, Char)(ref Writer w, T val, const ref FormatSpec!Char f) +void formatValue(Writer, T, Char)(auto ref Writer w, T val, const ref FormatSpec!Char f) if (is(T == class) && !is(T == enum)) { enforceValidFormatSpec!(T, Char)(f); @@ -3582,7 +3582,7 @@ if (is(T == class) && !is(T == enum)) } /// ditto -void formatValue(Writer, T, Char)(ref Writer w, T val, const ref FormatSpec!Char f) +void formatValue(Writer, T, Char)(auto ref Writer w, T val, const ref FormatSpec!Char f) if (is(T == interface) && (hasToString!(T, Char) || !is(BuiltinTypeOf!T)) && !is(T == enum)) { enforceValidFormatSpec!(T, Char)(f); @@ -3662,7 +3662,7 @@ if (is(T == interface) && (hasToString!(T, Char) || !is(BuiltinTypeOf!T)) && !is /// ditto // Maybe T is noncopyable struct, so receive it by 'auto ref'. -void formatValue(Writer, T, Char)(ref Writer w, auto ref T val, const ref FormatSpec!Char f) +void formatValue(Writer, T, Char)(auto ref Writer w, auto ref T val, const ref FormatSpec!Char f) if ((is(T == struct) || is(T == union)) && (hasToString!(T, Char) || !is(BuiltinTypeOf!T)) && !is(T == enum)) { enforceValidFormatSpec!(T, Char)(f); @@ -3797,7 +3797,7 @@ Params: val = The value to write. f = The $(D FormatSpec) defining how to write the value. */ -void formatValue(Writer, T, Char)(ref Writer w, T val, const ref FormatSpec!Char f) +void formatValue(Writer, T, Char)(auto ref Writer w, T val, const ref FormatSpec!Char f) if (is(T == enum)) { if (f.spec == 's') @@ -3866,7 +3866,7 @@ if (is(T == enum)) /** Pointers are formatted as hex integers. */ -void formatValue(Writer, T, Char)(ref Writer w, T val, const ref FormatSpec!Char f) +void formatValue(Writer, T, Char)(auto ref Writer w, T val, const ref FormatSpec!Char f) if (isPointer!T && !is(T == enum) && !hasToString!(T, Char)) { static if (isInputRange!T) @@ -3971,7 +3971,7 @@ if (isPointer!T && !is(T == enum) && !hasToString!(T, Char)) /** Delegates are formatted by 'ReturnType delegate(Parameters) FunctionAttributes' */ -void formatValue(Writer, T, Char)(ref Writer w, scope T, const ref FormatSpec!Char f) +void formatValue(Writer, T, Char)(auto ref Writer w, scope T, const ref FormatSpec!Char f) if (isDelegate!T) { formatValue(w, T.stringof, f); From d2a3d8ae71b5643f1ae0fa0adcdf7e7e9c843c38 Mon Sep 17 00:00:00 2001 From: Jack Applegame Date: Sun, 23 Jul 2017 16:02:18 +0300 Subject: [PATCH 160/163] Remove unnecessary auto refs and fix style. --- std/format.d | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/std/format.d b/std/format.d index 87c70747bdd..cd6b82ceac8 100644 --- a/std/format.d +++ b/std/format.d @@ -1900,7 +1900,7 @@ if (is(IntegralTypeOf!T) && !is(T == enum) && !hasToString!(T, Char)) assert(w.data == "1337"); } -private void formatIntegral(Writer, T, Char)(auto ref Writer w, const(T) val, const ref FormatSpec!Char fs, +private void formatIntegral(Writer, T, Char)(ref Writer w, const(T) val, const ref FormatSpec!Char fs, uint base, ulong mask) { T arg = val; @@ -1918,7 +1918,8 @@ private void formatIntegral(Writer, T, Char)(auto ref Writer w, const(T) val, co formatUnsigned(w, (cast(ulong) arg) & mask, fs, base, negative); } -private void formatUnsigned(Writer, T, Char)(auto ref Writer w, T arg, const ref FormatSpec!Char fs, uint base, bool negative) +private void formatUnsigned(Writer, T, Char) +(ref Writer w, T arg, const ref FormatSpec!Char fs, uint base, bool negative) { /* Write string: * leftpad prefix1 prefix2 zerofill digits rightpad @@ -2855,7 +2856,7 @@ if (is(DynamicArrayTypeOf!T) && !is(StringTypeOf!T) && !is(T == enum) && !hasToS } // input range formatting -private void formatRange(Writer, T, Char)(auto ref Writer w, ref T val, const ref FormatSpec!Char f) +private void formatRange(Writer, T, Char)(ref Writer w, ref T val, const ref FormatSpec!Char f) if (isInputRange!T) { import std.conv : text; @@ -3024,7 +3025,7 @@ if (isInputRange!T) } // character formatting with ecaping -private void formatChar(Writer)(auto ref Writer w, in dchar c, in char quote) +private void formatChar(Writer)(ref Writer w, in dchar c, in char quote) { import std.uni : isGraphical; @@ -3332,7 +3333,7 @@ template hasToString(T, Char) } // object formatting with toString -private void formatObject(Writer, T, Char)(auto ref Writer w, ref T val, const ref FormatSpec!Char f) +private void formatObject(Writer, T, Char)(ref Writer w, ref T val, const ref FormatSpec!Char f) if (hasToString!(T, Char)) { static if (is(typeof(val.toString((const(char)[] s){}, f)))) From 2e293eb6ed094d1327912e92cf75f69201962c30 Mon Sep 17 00:00:00 2001 From: Jack Applegame Date: Sun, 23 Jul 2017 16:56:56 +0300 Subject: [PATCH 161/163] Remove extra semicolon --- std/typecons.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/std/typecons.d b/std/typecons.d index 563e9e93cff..fe813679bfc 100644 --- a/std/typecons.d +++ b/std/typecons.d @@ -307,7 +307,7 @@ private: { count--; } - int val() const { return 4; }; + int val() const { return 4; } } alias UBar = Unique!Bar; UBar g(UBar u) From 1e4476396e8eda9c7e7756e6ae7e57f88683316f Mon Sep 17 00:00:00 2001 From: RazvanN7 Date: Thu, 20 Jul 2017 17:39:39 +0300 Subject: [PATCH 162/163] improve unittests --- std/range/package.d | 73 +++++++++++++++++++++++++++++++-------------- 1 file changed, 50 insertions(+), 23 deletions(-) diff --git a/std/range/package.d b/std/range/package.d index 497b667e157..4dc7b33bd29 100644 --- a/std/range/package.d +++ b/std/range/package.d @@ -397,8 +397,9 @@ pure @safe nothrow unittest test([ 1, 2, 3, 4, 5 ], [ 5, 4, 3, 2, 1 ]); test([ 1, 2, 3, 4, 5, 6 ], [ 6, 5, 4, 3, 2, 1 ]); - immutable foo = [1,2,3].idup; - auto r = retro(foo); + immutable foo = [1,2,3].idup; + auto r = retro(foo); + assert(equal(r, [3, 2, 1])); } pure @safe nothrow unittest @@ -698,9 +699,11 @@ pure @safe nothrow unittest pure @safe nothrow @nogc unittest { + import std.algorithm.comparison : equal; + int[4] testArr = [1,2,3,4]; - //just checking it compiles - auto s = testArr[].stride(2); + static immutable result = [1, 3]; + assert(equal(testArr[].stride(2), result)); } debug pure nothrow @system unittest @@ -1280,7 +1283,7 @@ pure @safe nothrow unittest // Make sure bug 3311 is fixed. ChainImpl should compile even if not all // elements are mutable. - auto c = chain( iota(0, 10), iota(0, 10) ); + assert(equal(chain(iota(0, 3), iota(0, 3)), [0, 1, 2, 0, 1, 2])); // Test the case where infinite ranges are present. auto inf = chain([0,1,2][], cycle([4,5,6][]), [7,8,9][]); // infinite range @@ -1343,7 +1346,7 @@ pure @safe nothrow @nogc unittest class Foo{} immutable(Foo)[] a; immutable(Foo)[] b; - auto c = chain(a, b); + assert(chain(a, b).empty); } /** @@ -2252,13 +2255,16 @@ pure @safe nothrow @nogc unittest int[] r1; Take!(int[]) t1; t1 = take(r1, 1); + assert(t1.empty); string r2; Take!string t2; t2 = take(r2, 1); + assert(t2.empty); Take!(Take!string) t3; t3 = take(t2, 1); + assert(t3.empty); } pure @safe nothrow @nogc unittest @@ -2276,6 +2282,9 @@ pure @safe nothrow @nogc unittest //12731 auto a = repeat(1); auto s = a[1 .. 5]; s = s[1 .. 3]; + assert(s.length == 2); + assert(s[0] == 1); + assert(s[1] == 1); } pure @safe nothrow @nogc unittest //13151 @@ -2399,16 +2408,20 @@ pure @safe nothrow unittest auto a = [ 1, 2, 3, 4, 5 ]; auto b = takeExactly(a, 3); + assert(equal(b, [1, 2, 3])); auto c = takeExactly(b, 2); + assert(equal(c, [1, 2])); + - auto d = filter!"a > 0"(a); + + auto d = filter!"a > 2"(a); auto e = takeExactly(d, 3); - assert(equal(e, [1, 2, 3])); + assert(equal(e, [3, 4, 5])); static assert(is(typeof(e.length) == size_t)); assert(e.length == 3); - assert(e.front == 1); + assert(e.front == 3); - assert(equal(takeExactly(e, 3), [1, 2, 3])); + assert(equal(takeExactly(e, 3), [3, 4, 5])); } pure @safe nothrow unittest @@ -3205,6 +3218,8 @@ pure @safe nothrow unittest assert(r[0 .. 4].equal([ 5, 5, 5, 5 ])); R r2 = r[5 .. $]; + assert(r2.back == 5); + assert(r2.front == 5); } /** @@ -3233,10 +3248,17 @@ pure @safe nothrow unittest //12007 rc = rc.save; import std.algorithm.setops : cartesianProduct; + import std.algorithm.comparison : equal; + import std.typecons : tuple; immutable int[] A = [1,2,3]; immutable int[] B = [4,5,6]; - auto AB = cartesianProduct(A,B); + assert(equal(cartesianProduct(A,B), + [ + tuple(1, 4), tuple(1, 5), tuple(1, 6), + tuple(2, 4), tuple(2, 5), tuple(2, 6), + tuple(3, 4), tuple(3, 5), tuple(3, 6), + ])); } /** @@ -3736,7 +3758,6 @@ if (isStaticArray!R) assert(nums[0] == 2); immutable int[] immarr = [1, 2, 3]; - auto cycleimm = cycle(immarr); foreach (DummyType; AllDummyRanges) { @@ -3889,7 +3910,7 @@ if (isStaticArray!R) @safe unittest // 12177 { - auto a = recurrence!q{a[n - 1] ~ a[n - 2]}("1", "0"); + static assert(__traits(compiles, recurrence!q{a[n - 1] ~ a[n - 2]}("1", "0"))); } // Issue 13390 @@ -4522,7 +4543,7 @@ pure @safe unittest } R r; auto z = zip(r, r); - auto zz = z.save; + assert(z.save == z); } pure @system unittest @@ -4834,7 +4855,12 @@ if (allSatisfy!(isInputRange, Ranges)) // Make sure StoppingPolicy.requireSameLength doesn't throw. auto ls = lockstep(arr1, arr2, StoppingPolicy.requireSameLength); - foreach (a, b; ls) {} + int k = 1; + foreach (a, b; ls) + { + assert(a - b == k); + ++k; + } // Make sure StoppingPolicy.requireSameLength throws. arr2.popBack(); @@ -4848,6 +4874,10 @@ if (allSatisfy!(isInputRange, Ranges)) // Just make sure 1-range case instantiates. This hangs the compiler // when no explicit stopping policy is specified due to Bug 4652. auto stuff = lockstep([1,2,3,4,5], StoppingPolicy.shortest); + foreach (int i, a; stuff) + { + assert(stuff[i] == a); + } // Test with indexing. uint[] res1; @@ -5535,9 +5565,9 @@ body import std.math : approxEqual; auto r = iota(0, 10, 1); - assert(equal(r, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9][])); + assert(equal(r, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])); r = iota(0, 11, 3); - assert(equal(r, [0, 3, 6, 9][])); + assert(equal(r, [0, 3, 6, 9])); assert(r[2] == 6); auto rf = iota(0.0, 0.5, 0.1); assert(approxEqual(rf, [0.0, 0.1, 0.2, 0.3, 0.4])); @@ -5545,10 +5575,7 @@ body nothrow @nogc @safe unittest { - auto t0 = iota(0, 10); - auto t1 = iota(0, 10, 2); - auto t2 = iota(1, 1, 0); - //float overloads use std.conv.to so can't be @nogc or nothrow + //float overloads use std.conv.to so can't be @nogc or nothrow alias ssize_t = Signed!size_t; assert(iota(ssize_t.max, 0, -1).length == ssize_t.max); assert(iota(ssize_t.max, ssize_t.min, -1).length == size_t.max); @@ -5834,8 +5861,8 @@ if (!isIntegral!(CommonType!(B, E)) && this(int start) { current = start % wrapAround; } - bool opEquals(Cyclic c) { return current == c.current; } - bool opEquals(int i) { return current == i; } + bool opEquals(Cyclic c) const { return current == c.current; } + bool opEquals(int i) const { return current == i; } void opUnary(string op)() if (op == "++") { current = (current + 1) % wrapAround; From 8dfcb49361e1849fd5da365cab029cde3c80fe1a Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Thu, 20 Jul 2017 22:03:18 +0200 Subject: [PATCH 163/163] Add bookmark table to std.typecons --- std/typecons.d | 54 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/std/typecons.d b/std/typecons.d index fe813679bfc..ff79209ecb5 100644 --- a/std/typecons.d +++ b/std/typecons.d @@ -4,7 +4,58 @@ This module implements a variety of type constructors, i.e., templates that allow construction of new, useful general-purpose types. -Source: $(PHOBOSSRC std/_typecons.d) +$(SCRIPT inhibitQuickIndex = 1;) +$(BOOKTABLE, +$(TR $(TH Category) $(TH Functions)) +$(TR $(TD Tuple) $(TD + $(LREF isTuple) + $(LREF Tuple) + $(LREF tuple) + $(LREF reverse) +)) +$(TR $(TD Flags) $(TD + $(LREF BitFlags) + $(LREF isBitFlagEnum) + $(LREF Flag) + $(LREF No) + $(LREF Yes) +)) +$(TR $(TD Memory allocation) $(TD + $(LREF RefCounted) + $(LREF refCounted) + $(LREF RefCountedAutoInitialize) + $(LREF scoped) + $(LREF Unique) +)) +$(TR $(TD Code generation) $(TD + $(LREF AutoImplement) + $(LREF BlackHole) + $(LREF generateAssertTrap) + $(LREF generateEmptyFunction) + $(LREF WhiteHole) +)) +$(TR $(TD Nullable) $(TD + $(LREF Nullable) + $(LREF nullable) + $(LREF NullableRef) + $(LREF nullableRef) +)) +$(TR $(TD Proxies) $(TD + $(LREF Proxy) + $(LREF rebindable) + $(LREF Rebindable) + $(LREF ReplaceType) + $(LREF unwrap) + $(LREF wrap) +)) +$(TR $(TD Types) $(TD + $(LREF alignForSize) + $(LREF Ternary) + $(LREF Typedef) + $(LREF TypedefType) + $(LREF UnqualRef) +)) +) Copyright: Copyright the respective authors, 2008- License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). @@ -52,6 +103,7 @@ import std.traits; } } +Source: $(PHOBOSSRC std/_typecons.d) debug(Unique) import std.stdio; /**