diff options
Diffstat (limited to 'libphobos/src/std/algorithm')
-rw-r--r-- | libphobos/src/std/algorithm/comparison.d | 2 | ||||
-rw-r--r-- | libphobos/src/std/algorithm/iteration.d | 9 | ||||
-rw-r--r-- | libphobos/src/std/algorithm/mutation.d | 14 | ||||
-rw-r--r-- | libphobos/src/std/algorithm/sorting.d | 73 |
4 files changed, 85 insertions, 13 deletions
diff --git a/libphobos/src/std/algorithm/comparison.d b/libphobos/src/std/algorithm/comparison.d index 5c70960..60fd114 100644 --- a/libphobos/src/std/algorithm/comparison.d +++ b/libphobos/src/std/algorithm/comparison.d @@ -102,7 +102,7 @@ template among(values...) if (isExpressionTuple!values) { uint among(Value)(Value value) - if (!is(CommonType!(Value, values) == void)) + if (!is(CommonType!(Value, values) == void)) { switch (value) { diff --git a/libphobos/src/std/algorithm/iteration.d b/libphobos/src/std/algorithm/iteration.d index 1453d2b..8a3add3 100644 --- a/libphobos/src/std/algorithm/iteration.d +++ b/libphobos/src/std/algorithm/iteration.d @@ -443,7 +443,8 @@ if (fun.length >= 1) A range with each fun applied to all the elements. If there is more than one fun, the element type will be `Tuple` containing one element for each fun. */ - auto map(Range)(Range r) if (isInputRange!(Unqual!Range)) + auto map(Range)(Range r) + if (isInputRange!(Unqual!Range)) { import std.meta : AliasSeq, staticMap; @@ -1308,7 +1309,8 @@ if (is(typeof(unaryFun!predicate))) A range containing only elements `x` in `range` for which `predicate(x)` returns `true`. */ - auto filter(Range)(Range range) if (isInputRange!(Unqual!Range)) + auto filter(Range)(Range range) + if (isInputRange!(Unqual!Range)) { return FilterResult!(unaryFun!predicate, Range)(range); } @@ -1545,7 +1547,8 @@ template filterBidirectional(alias pred) Returns: A range containing only the elements in `r` for which `pred` returns `true`. */ - auto filterBidirectional(Range)(Range r) if (isBidirectionalRange!(Unqual!Range)) + auto filterBidirectional(Range)(Range r) + if (isBidirectionalRange!(Unqual!Range)) { return FilterBidiResult!(unaryFun!pred, Range)(r); } diff --git a/libphobos/src/std/algorithm/mutation.d b/libphobos/src/std/algorithm/mutation.d index e434d24..ea1a1b2 100644 --- a/libphobos/src/std/algorithm/mutation.d +++ b/libphobos/src/std/algorithm/mutation.d @@ -2860,6 +2860,13 @@ Params: lhs = Data to be swapped with `rhs`. rhs = Data to be swapped with `lhs`. */ +void swap(T)(ref T lhs, ref T rhs) +if (is(typeof(lhs.proxySwap(rhs)))) +{ + lhs.proxySwap(rhs); +} + +/// ditto void swap(T)(ref T lhs, ref T rhs) @trusted pure nothrow @nogc if (isBlitAssignable!T && !is(typeof(lhs.proxySwap(rhs)))) { @@ -3121,13 +3128,6 @@ if (isBlitAssignable!T && !is(typeof(lhs.proxySwap(rhs)))) swap(a3, a4); } -/// ditto -void swap(T)(ref T lhs, ref T rhs) -if (is(typeof(lhs.proxySwap(rhs)))) -{ - lhs.proxySwap(rhs); -} - /** Swaps two elements in-place of a range `r`, specified by their indices `i1` and `i2`. diff --git a/libphobos/src/std/algorithm/sorting.d b/libphobos/src/std/algorithm/sorting.d index cb47153..29839d1 100644 --- a/libphobos/src/std/algorithm/sorting.d +++ b/libphobos/src/std/algorithm/sorting.d @@ -2625,11 +2625,21 @@ private template TimSortImpl(alias pred, R) // can't use `temp.length` if there's no default constructor static if (__traits(compiles, { T defaultConstructed; cast(void) defaultConstructed; })) { - if (__ctfe) temp.length = newSize; - else temp = () @trusted { return uninitializedArray!(T[])(newSize); }(); + + static if (hasElaborateAssign!T) + temp.length = newSize; + else + { + if (__ctfe) temp.length = newSize; + else temp = () @trusted { return uninitializedArray!(T[])(newSize); }(); + } } else { + static assert(!hasElaborateAssign!T, + "Structs which have opAssign but cannot be default-initialized " ~ + "do not currently work with stable sort: " ~ + "https://issues.dlang.org/show_bug.cgi?id=24810"); temp = () @trusted { return uninitializedArray!(T[])(newSize); }(); } } @@ -3093,6 +3103,65 @@ private template TimSortImpl(alias pred, R) array.sort!((a, b) => false, SwapStrategy.stable); } +// https://issues.dlang.org/show_bug.cgi?id=24809 +@safe unittest +{ + static struct E + { + int value; + int valid = 42; + + ~this() + { + assert(valid == 42); + } + } + + import std.array : array; + import std.range : chain, only, repeat; + auto arr = chain(repeat(E(41), 18), + only(E(39)), + repeat(E(41), 16), + only(E(1)), + repeat(E(42), 33), + only(E(33)), + repeat(E(42), 16), + repeat(E(43), 27), + only(E(33)), + repeat(E(43), 34), + only(E(34)), + only(E(43)), + only(E(63)), + repeat(E(44), 42), + only(E(27)), + repeat(E(44), 11), + repeat(E(45), 64), + repeat(E(46), 3), + only(E(11)), + repeat(E(46), 7), + only(E(4)), + repeat(E(46), 34), + only(E(36)), + repeat(E(46), 17), + repeat(E(47), 36), + only(E(39)), + repeat(E(47), 26), + repeat(E(48), 17), + only(E(21)), + repeat(E(48), 5), + only(E(39)), + repeat(E(48), 14), + only(E(58)), + repeat(E(48), 24), + repeat(E(49), 13), + only(E(40)), + repeat(E(49), 38), + only(E(18)), + repeat(E(49), 11), + repeat(E(50), 6)).array(); + + arr.sort!((a, b) => a.value < b.value, SwapStrategy.stable)(); +} // schwartzSort /** |