aboutsummaryrefslogtreecommitdiff
path: root/libphobos/src/std/algorithm
diff options
context:
space:
mode:
Diffstat (limited to 'libphobos/src/std/algorithm')
-rw-r--r--libphobos/src/std/algorithm/comparison.d2
-rw-r--r--libphobos/src/std/algorithm/iteration.d9
-rw-r--r--libphobos/src/std/algorithm/mutation.d14
-rw-r--r--libphobos/src/std/algorithm/sorting.d73
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
/**