diff --git a/src/generics/lib.generics.ts b/src/generics/lib.generics.ts index a7b2bf1..853884d 100644 --- a/src/generics/lib.generics.ts +++ b/src/generics/lib.generics.ts @@ -321,11 +321,9 @@ namespace __Array { const shift = this.length - 1; const size = this.length >> 1; for (let i = 0; i < size; i++) { - // a `let`, as sort's `temp`: under -mm=own a string element is copied out, where a - // `const` would borrow the slot overwritten next - let v = this[i]; - this[i] = this[shift - i]; - this[shift - i] = v; + // an exchange of the two elements, which moves nothing: through a local, under -mm=own + // an object element would have two owners + [this[i], this[shift - i]] = [this[shift - i], this[i]]; } return this; @@ -373,9 +371,8 @@ namespace __Array { for (let i = 0; i < len - 1; ++i) { for (let j = i + 1; j < len; ++j) { if (compare(a[i], a[j]) > 0) { - let temp: T = a[i]; - a[i] = a[j]; - a[j] = temp; + // an exchange, as in reverse + [a[i], a[j]] = [a[j], a[i]]; } } } diff --git a/tests/array_reverse_class.ts b/tests/array_reverse_class.ts new file mode 100644 index 0000000..e5c8bd4 --- /dev/null +++ b/tests/array_reverse_class.ts @@ -0,0 +1,19 @@ +// reverse over class instances, in place: under -mm=own the elements are exchanged, which moves +// nothing +class Item { + constructor(public key: number, public name: string) {} +} + +function main() { + const items = [new Item(1, "a"), new Item(2, "b"), new Item(3, "c"), new Item(4, "d"), new Item(5, "e")]; + + const reversed = items.reverse(); + console.log(reversed[0].name, reversed[2].name, reversed[4].name); + // Expected output: "e c a" + assert(items[0].key == 5 && items[1].key == 4 && items[2].key == 3 && items[4].key == 1, "reversed in place"); + + items.reverse(); + assert(items[0].name == "a" && items[4].name == "e", "reversed back"); + + console.log("ALL DONE"); +} diff --git a/tests/array_sort_class.ts b/tests/array_sort_class.ts new file mode 100644 index 0000000..e2308d8 --- /dev/null +++ b/tests/array_sort_class.ts @@ -0,0 +1,20 @@ +// sort over class instances, in place. sort's default comparison (compiled even when a comparison is +// given) converts an element to a string, which needs a class to say how. +class Item { + constructor(public key: number, public name: string) {} + + toString() { + return this.name; + } +} + +function main() { + const items = [new Item(3, "c"), new Item(1, "a"), new Item(4, "d"), new Item(2, "b")]; + + const sorted = items.sort((p, q) => p.key - q.key); + console.log(sorted[0].name, sorted[1].name, sorted[2].name, sorted[3].name); + // Expected output: "a b c d" + assert(items[0].key == 1 && items[3].key == 4, "sorted in place"); + + console.log("ALL DONE"); +}