From d19f9ee0c5a2c193504b3c7a397d632a601a097e Mon Sep 17 00:00:00 2001 From: Ilya Gorbunov Date: Fri, 22 May 2020 01:10:05 +0300 Subject: [PATCH] Simplify min/max implementation --- .../stdlib/common/src/generated/_Arrays.kt | 32 +++++-------------- .../common/src/generated/_Collections.kt | 16 +++------- .../stdlib/common/src/generated/_Sequences.kt | 16 +++------- .../stdlib/test/collections/CollectionTest.kt | 6 ++++ .../src/templates/Aggregates.kt | 26 +++++++-------- 5 files changed, 33 insertions(+), 63 deletions(-) diff --git a/libraries/stdlib/common/src/generated/_Arrays.kt b/libraries/stdlib/common/src/generated/_Arrays.kt index 9b709991a3f..1250d31aac3 100644 --- a/libraries/stdlib/common/src/generated/_Arrays.kt +++ b/libraries/stdlib/common/src/generated/_Arrays.kt @@ -13084,11 +13084,9 @@ public inline fun CharArray.forEachIndexed(action: (index: Int, Char) -> Unit): public fun Array.max(): Double? { if (isEmpty()) return null var max = this[0] - if (max.isNaN()) return max for (i in 1..lastIndex) { val e = this[i] - if (e.isNaN()) return e - if (max < e) max = e + max = maxOf(max, e) } return max } @@ -13102,11 +13100,9 @@ public fun Array.max(): Double? { public fun Array.max(): Float? { if (isEmpty()) return null var max = this[0] - if (max.isNaN()) return max for (i in 1..lastIndex) { val e = this[i] - if (e.isNaN()) return e - if (max < e) max = e + max = maxOf(max, e) } return max } @@ -13184,11 +13180,9 @@ public fun LongArray.max(): Long? { public fun FloatArray.max(): Float? { if (isEmpty()) return null var max = this[0] - if (max.isNaN()) return max for (i in 1..lastIndex) { val e = this[i] - if (e.isNaN()) return e - if (max < e) max = e + max = maxOf(max, e) } return max } @@ -13201,11 +13195,9 @@ public fun FloatArray.max(): Float? { public fun DoubleArray.max(): Double? { if (isEmpty()) return null var max = this[0] - if (max.isNaN()) return max for (i in 1..lastIndex) { val e = this[i] - if (e.isNaN()) return e - if (max < e) max = e + max = maxOf(max, e) } return max } @@ -15059,11 +15051,9 @@ public fun CharArray.maxWith(comparator: Comparator): Char? { public fun Array.min(): Double? { if (isEmpty()) return null var min = this[0] - if (min.isNaN()) return min for (i in 1..lastIndex) { val e = this[i] - if (e.isNaN()) return e - if (min > e) min = e + min = minOf(min, e) } return min } @@ -15077,11 +15067,9 @@ public fun Array.min(): Double? { public fun Array.min(): Float? { if (isEmpty()) return null var min = this[0] - if (min.isNaN()) return min for (i in 1..lastIndex) { val e = this[i] - if (e.isNaN()) return e - if (min > e) min = e + min = minOf(min, e) } return min } @@ -15159,11 +15147,9 @@ public fun LongArray.min(): Long? { public fun FloatArray.min(): Float? { if (isEmpty()) return null var min = this[0] - if (min.isNaN()) return min for (i in 1..lastIndex) { val e = this[i] - if (e.isNaN()) return e - if (min > e) min = e + min = minOf(min, e) } return min } @@ -15176,11 +15162,9 @@ public fun FloatArray.min(): Float? { public fun DoubleArray.min(): Double? { if (isEmpty()) return null var min = this[0] - if (min.isNaN()) return min for (i in 1..lastIndex) { val e = this[i] - if (e.isNaN()) return e - if (min > e) min = e + min = minOf(min, e) } return min } diff --git a/libraries/stdlib/common/src/generated/_Collections.kt b/libraries/stdlib/common/src/generated/_Collections.kt index 15c4af755ae..12b130c9c30 100644 --- a/libraries/stdlib/common/src/generated/_Collections.kt +++ b/libraries/stdlib/common/src/generated/_Collections.kt @@ -1729,11 +1729,9 @@ public fun Iterable.max(): Double? { val iterator = iterator() if (!iterator.hasNext()) return null var max = iterator.next() - if (max.isNaN()) return max while (iterator.hasNext()) { val e = iterator.next() - if (e.isNaN()) return e - if (max < e) max = e + max = maxOf(max, e) } return max } @@ -1748,11 +1746,9 @@ public fun Iterable.max(): Float? { val iterator = iterator() if (!iterator.hasNext()) return null var max = iterator.next() - if (max.isNaN()) return max while (iterator.hasNext()) { val e = iterator.next() - if (e.isNaN()) return e - if (max < e) max = e + max = maxOf(max, e) } return max } @@ -1993,11 +1989,9 @@ public fun Iterable.min(): Double? { val iterator = iterator() if (!iterator.hasNext()) return null var min = iterator.next() - if (min.isNaN()) return min while (iterator.hasNext()) { val e = iterator.next() - if (e.isNaN()) return e - if (min > e) min = e + min = minOf(min, e) } return min } @@ -2012,11 +2006,9 @@ public fun Iterable.min(): Float? { val iterator = iterator() if (!iterator.hasNext()) return null var min = iterator.next() - if (min.isNaN()) return min while (iterator.hasNext()) { val e = iterator.next() - if (e.isNaN()) return e - if (min > e) min = e + min = minOf(min, e) } return min } diff --git a/libraries/stdlib/common/src/generated/_Sequences.kt b/libraries/stdlib/common/src/generated/_Sequences.kt index 297bde74066..41fd8fbd458 100644 --- a/libraries/stdlib/common/src/generated/_Sequences.kt +++ b/libraries/stdlib/common/src/generated/_Sequences.kt @@ -1178,11 +1178,9 @@ public fun Sequence.max(): Double? { val iterator = iterator() if (!iterator.hasNext()) return null var max = iterator.next() - if (max.isNaN()) return max while (iterator.hasNext()) { val e = iterator.next() - if (e.isNaN()) return e - if (max < e) max = e + max = maxOf(max, e) } return max } @@ -1199,11 +1197,9 @@ public fun Sequence.max(): Float? { val iterator = iterator() if (!iterator.hasNext()) return null var max = iterator.next() - if (max.isNaN()) return max while (iterator.hasNext()) { val e = iterator.next() - if (e.isNaN()) return e - if (max < e) max = e + max = maxOf(max, e) } return max } @@ -1468,11 +1464,9 @@ public fun Sequence.min(): Double? { val iterator = iterator() if (!iterator.hasNext()) return null var min = iterator.next() - if (min.isNaN()) return min while (iterator.hasNext()) { val e = iterator.next() - if (e.isNaN()) return e - if (min > e) min = e + min = minOf(min, e) } return min } @@ -1489,11 +1483,9 @@ public fun Sequence.min(): Float? { val iterator = iterator() if (!iterator.hasNext()) return null var min = iterator.next() - if (min.isNaN()) return min while (iterator.hasNext()) { val e = iterator.next() - if (e.isNaN()) return e - if (min > e) min = e + min = minOf(min, e) } return min } diff --git a/libraries/stdlib/test/collections/CollectionTest.kt b/libraries/stdlib/test/collections/CollectionTest.kt index dfb6d08e8a1..a424def797e 100644 --- a/libraries/stdlib/test/collections/CollectionTest.kt +++ b/libraries/stdlib/test/collections/CollectionTest.kt @@ -832,6 +832,9 @@ class CollectionTest { expect("a", { listOf("a", "b").min() }) expect(null, { listOf().asSequence().min() }) expect(2, { listOf(2, 3).asSequence().min() }) + + assertIsNegativeZero(listOf(0.0, -0.0).shuffled().min()!!) + assertIsNegativeZero(listOf(0.0F, -0.0F).shuffled().min()!!.toDouble()) } @Test fun max() { @@ -843,6 +846,9 @@ class CollectionTest { expect("b", { listOf("a", "b").max() }) expect(null, { listOf().asSequence().max() }) expect(3, { listOf(2, 3).asSequence().max() }) + + assertIsPositiveZero(listOf(0.0, -0.0).shuffled().max()!!) + assertIsPositiveZero(listOf(0.0F, -0.0F).shuffled().max()!!.toDouble()) } @Test fun minWith() { diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Aggregates.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Aggregates.kt index 685035462e3..44f43c16732 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Aggregates.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Aggregates.kt @@ -329,38 +329,34 @@ object Aggregates : TemplateGroupBase() { } returns("T?") + val acc = op + val cmpBlock = if (isFloat) + """$acc = ${op}Of($acc, e)""" + else + """if ($acc ${if (op == "max") "<" else ">"} e) $acc = e""" body { """ val iterator = iterator() if (!iterator.hasNext()) return null - var $op = iterator.next() - ${if (isFloat) "if ($op.isNaN()) return $op" else "\\"} - + var $acc = iterator.next() while (iterator.hasNext()) { val e = iterator.next() - ${if (isFloat) "if (e.isNaN()) return e" else "\\"} - if ($op ${if (op == "max") "<" else ">"} e) $op = e + $cmpBlock } - return $op + return $acc """ } body(ArraysOfObjects, ArraysOfPrimitives, CharSequences, ArraysOfUnsigned) { """ if (isEmpty()) return null - var $op = this[0] - ${if (isFloat) "if ($op.isNaN()) return $op" else "\\"} - + var $acc = this[0] for (i in 1..lastIndex) { val e = this[i] - ${if (isFloat) "if (e.isNaN()) return e" else "\\"} - if ($op ${if (op == "max") "<" else ">"} e) $op = e + $cmpBlock } - return $op + return $acc """ } - body { - body!!.replace(Regex("""^\s+\\\n""", RegexOption.MULTILINE), "") // remove empty lines ending with \ - } } } }