@@ -2625,11 +2625,21 @@ private template TimSortImpl(alias pred, R)
2625
2625
// can't use `temp.length` if there's no default constructor
2626
2626
static if (__traits(compiles, { T defaultConstructed; cast (void ) defaultConstructed; }))
2627
2627
{
2628
- if (__ctfe) temp.length = newSize;
2629
- else temp = () @trusted { return uninitializedArray! (T[])(newSize); }();
2628
+
2629
+ static if (hasElaborateAssign! T)
2630
+ temp.length = newSize;
2631
+ else
2632
+ {
2633
+ if (__ctfe) temp.length = newSize;
2634
+ else temp = () @trusted { return uninitializedArray! (T[])(newSize); }();
2635
+ }
2630
2636
}
2631
2637
else
2632
2638
{
2639
+ static assert (! hasElaborateAssign! T,
2640
+ " Structs which have opAssign but cannot be default-initialized " ~
2641
+ " do not currently work with stable sort: " ~
2642
+ " https://issues.dlang.org/show_bug.cgi?id=24810" );
2633
2643
temp = () @trusted { return uninitializedArray! (T[])(newSize); }();
2634
2644
}
2635
2645
}
@@ -3093,6 +3103,65 @@ private template TimSortImpl(alias pred, R)
3093
3103
array.sort! ((a, b) => false , SwapStrategy.stable);
3094
3104
}
3095
3105
3106
+ // https://issues.dlang.org/show_bug.cgi?id=24809
3107
+ @safe unittest
3108
+ {
3109
+ static struct E
3110
+ {
3111
+ int value;
3112
+ int valid = 42 ;
3113
+
3114
+ ~this ()
3115
+ {
3116
+ assert (valid == 42 );
3117
+ }
3118
+ }
3119
+
3120
+ import std.array : array;
3121
+ import std.range : chain, only, repeat;
3122
+ auto arr = chain(repeat(E(41 ), 18 ),
3123
+ only(E(39 )),
3124
+ repeat(E(41 ), 16 ),
3125
+ only(E(1 )),
3126
+ repeat(E(42 ), 33 ),
3127
+ only(E(33 )),
3128
+ repeat(E(42 ), 16 ),
3129
+ repeat(E(43 ), 27 ),
3130
+ only(E(33 )),
3131
+ repeat(E(43 ), 34 ),
3132
+ only(E(34 )),
3133
+ only(E(43 )),
3134
+ only(E(63 )),
3135
+ repeat(E(44 ), 42 ),
3136
+ only(E(27 )),
3137
+ repeat(E(44 ), 11 ),
3138
+ repeat(E(45 ), 64 ),
3139
+ repeat(E(46 ), 3 ),
3140
+ only(E(11 )),
3141
+ repeat(E(46 ), 7 ),
3142
+ only(E(4 )),
3143
+ repeat(E(46 ), 34 ),
3144
+ only(E(36 )),
3145
+ repeat(E(46 ), 17 ),
3146
+ repeat(E(47 ), 36 ),
3147
+ only(E(39 )),
3148
+ repeat(E(47 ), 26 ),
3149
+ repeat(E(48 ), 17 ),
3150
+ only(E(21 )),
3151
+ repeat(E(48 ), 5 ),
3152
+ only(E(39 )),
3153
+ repeat(E(48 ), 14 ),
3154
+ only(E(58 )),
3155
+ repeat(E(48 ), 24 ),
3156
+ repeat(E(49 ), 13 ),
3157
+ only(E(40 )),
3158
+ repeat(E(49 ), 38 ),
3159
+ only(E(18 )),
3160
+ repeat(E(49 ), 11 ),
3161
+ repeat(E(50 ), 6 )).array();
3162
+
3163
+ arr.sort! ((a, b) => a.value < b.value, SwapStrategy.stable)();
3164
+ }
3096
3165
3097
3166
// schwartzSort
3098
3167
/**
0 commit comments