From 846a7823ad5f164ae423468d96abac76a3469cc8 Mon Sep 17 00:00:00 2001 From: Abduqodiri Qurbonzoda Date: Wed, 20 May 2020 04:56:52 +0300 Subject: [PATCH] Introduce minOrNull and maxOrNull extension functions #KT-39064 --- .../stdlib/common/src/generated/_Arrays.kt | 552 +++++++++++------- .../common/src/generated/_Collections.kt | 184 +++--- .../stdlib/common/src/generated/_Sequences.kt | 208 ++++--- .../stdlib/common/src/generated/_Strings.kt | 52 +- .../stdlib/common/src/generated/_UArrays.kt | 216 ++++--- libraries/stdlib/src/kotlin/text/Indent.kt | 2 +- .../stdlib/test/collections/ArraysTest.kt | 68 +-- .../stdlib/test/collections/CollectionTest.kt | 42 +- .../stdlib/test/collections/IterableTests.kt | 8 +- .../test/collections/UnsignedArraysTest.kt | 40 +- .../stdlib/test/numbers/NaNPropagationTest.kt | 88 +-- libraries/stdlib/test/text/StringTest.kt | 4 +- .../kotlin-stdlib-runtime-merged.txt | 42 ++ .../src/templates/Aggregates.kt | 34 +- 14 files changed, 928 insertions(+), 612 deletions(-) diff --git a/libraries/stdlib/common/src/generated/_Arrays.kt b/libraries/stdlib/common/src/generated/_Arrays.kt index e28f0ff2e88..d08112477c7 100644 --- a/libraries/stdlib/common/src/generated/_Arrays.kt +++ b/libraries/stdlib/common/src/generated/_Arrays.kt @@ -13057,144 +13057,56 @@ public inline fun CharArray.forEachIndexed(action: (index: Int, Char) -> Unit): for (item in this) action(index++, item) } -/** - * Returns the largest element or `null` if there are no elements. - * - * If any of elements is `NaN` returns `NaN`. - */ +@Deprecated("Use maxOrNull instead.", ReplaceWith("maxOrNull()")) @SinceKotlin("1.1") public fun Array.max(): Double? { - if (isEmpty()) return null - var max = this[0] - for (i in 1..lastIndex) { - val e = this[i] - max = maxOf(max, e) - } - return max + return maxOrNull() } -/** - * Returns the largest element or `null` if there are no elements. - * - * If any of elements is `NaN` returns `NaN`. - */ +@Deprecated("Use maxOrNull instead.", ReplaceWith("maxOrNull()")) @SinceKotlin("1.1") public fun Array.max(): Float? { - if (isEmpty()) return null - var max = this[0] - for (i in 1..lastIndex) { - val e = this[i] - max = maxOf(max, e) - } - return max + return maxOrNull() } -/** - * Returns the largest element or `null` if there are no elements. - */ +@Deprecated("Use maxOrNull instead.", ReplaceWith("maxOrNull()")) public fun > Array.max(): T? { - if (isEmpty()) return null - var max = this[0] - for (i in 1..lastIndex) { - val e = this[i] - if (max < e) max = e - } - return max + return maxOrNull() } -/** - * Returns the largest element or `null` if there are no elements. - */ +@Deprecated("Use maxOrNull instead.", ReplaceWith("maxOrNull()")) public fun ByteArray.max(): Byte? { - if (isEmpty()) return null - var max = this[0] - for (i in 1..lastIndex) { - val e = this[i] - if (max < e) max = e - } - return max + return maxOrNull() } -/** - * Returns the largest element or `null` if there are no elements. - */ +@Deprecated("Use maxOrNull instead.", ReplaceWith("maxOrNull()")) public fun ShortArray.max(): Short? { - if (isEmpty()) return null - var max = this[0] - for (i in 1..lastIndex) { - val e = this[i] - if (max < e) max = e - } - return max + return maxOrNull() } -/** - * Returns the largest element or `null` if there are no elements. - */ +@Deprecated("Use maxOrNull instead.", ReplaceWith("maxOrNull()")) public fun IntArray.max(): Int? { - if (isEmpty()) return null - var max = this[0] - for (i in 1..lastIndex) { - val e = this[i] - if (max < e) max = e - } - return max + return maxOrNull() } -/** - * Returns the largest element or `null` if there are no elements. - */ +@Deprecated("Use maxOrNull instead.", ReplaceWith("maxOrNull()")) public fun LongArray.max(): Long? { - if (isEmpty()) return null - var max = this[0] - for (i in 1..lastIndex) { - val e = this[i] - if (max < e) max = e - } - return max + return maxOrNull() } -/** - * Returns the largest element or `null` if there are no elements. - * - * If any of elements is `NaN` returns `NaN`. - */ +@Deprecated("Use maxOrNull instead.", ReplaceWith("maxOrNull()")) public fun FloatArray.max(): Float? { - if (isEmpty()) return null - var max = this[0] - for (i in 1..lastIndex) { - val e = this[i] - max = maxOf(max, e) - } - return max + return maxOrNull() } -/** - * Returns the largest element or `null` if there are no elements. - * - * If any of elements is `NaN` returns `NaN`. - */ +@Deprecated("Use maxOrNull instead.", ReplaceWith("maxOrNull()")) public fun DoubleArray.max(): Double? { - if (isEmpty()) return null - var max = this[0] - for (i in 1..lastIndex) { - val e = this[i] - max = maxOf(max, e) - } - return max + return maxOrNull() } -/** - * Returns the largest element or `null` if there are no elements. - */ +@Deprecated("Use maxOrNull instead.", ReplaceWith("maxOrNull()")) public fun CharArray.max(): Char? { - if (isEmpty()) return null - var max = this[0] - for (i in 1..lastIndex) { - val e = this[i] - if (max < e) max = e - } - return max + return maxOrNull() } /** @@ -14907,6 +14819,154 @@ public inline fun CharArray.maxOfWithOrNull(comparator: Comparator, se return maxValue } +/** + * Returns the largest element or `null` if there are no elements. + * + * If any of elements is `NaN` returns `NaN`. + */ +@SinceKotlin("1.4") +public fun Array.maxOrNull(): Double? { + if (isEmpty()) return null + var max = this[0] + for (i in 1..lastIndex) { + val e = this[i] + max = maxOf(max, e) + } + return max +} + +/** + * Returns the largest element or `null` if there are no elements. + * + * If any of elements is `NaN` returns `NaN`. + */ +@SinceKotlin("1.4") +public fun Array.maxOrNull(): Float? { + if (isEmpty()) return null + var max = this[0] + for (i in 1..lastIndex) { + val e = this[i] + max = maxOf(max, e) + } + return max +} + +/** + * Returns the largest element or `null` if there are no elements. + */ +@SinceKotlin("1.4") +public fun > Array.maxOrNull(): T? { + if (isEmpty()) return null + var max = this[0] + for (i in 1..lastIndex) { + val e = this[i] + if (max < e) max = e + } + return max +} + +/** + * Returns the largest element or `null` if there are no elements. + */ +@SinceKotlin("1.4") +public fun ByteArray.maxOrNull(): Byte? { + if (isEmpty()) return null + var max = this[0] + for (i in 1..lastIndex) { + val e = this[i] + if (max < e) max = e + } + return max +} + +/** + * Returns the largest element or `null` if there are no elements. + */ +@SinceKotlin("1.4") +public fun ShortArray.maxOrNull(): Short? { + if (isEmpty()) return null + var max = this[0] + for (i in 1..lastIndex) { + val e = this[i] + if (max < e) max = e + } + return max +} + +/** + * Returns the largest element or `null` if there are no elements. + */ +@SinceKotlin("1.4") +public fun IntArray.maxOrNull(): Int? { + if (isEmpty()) return null + var max = this[0] + for (i in 1..lastIndex) { + val e = this[i] + if (max < e) max = e + } + return max +} + +/** + * Returns the largest element or `null` if there are no elements. + */ +@SinceKotlin("1.4") +public fun LongArray.maxOrNull(): Long? { + if (isEmpty()) return null + var max = this[0] + for (i in 1..lastIndex) { + val e = this[i] + if (max < e) max = e + } + return max +} + +/** + * Returns the largest element or `null` if there are no elements. + * + * If any of elements is `NaN` returns `NaN`. + */ +@SinceKotlin("1.4") +public fun FloatArray.maxOrNull(): Float? { + if (isEmpty()) return null + var max = this[0] + for (i in 1..lastIndex) { + val e = this[i] + max = maxOf(max, e) + } + return max +} + +/** + * Returns the largest element or `null` if there are no elements. + * + * If any of elements is `NaN` returns `NaN`. + */ +@SinceKotlin("1.4") +public fun DoubleArray.maxOrNull(): Double? { + if (isEmpty()) return null + var max = this[0] + for (i in 1..lastIndex) { + val e = this[i] + max = maxOf(max, e) + } + return max +} + +/** + * Returns the largest element or `null` if there are no elements. + */ +@SinceKotlin("1.4") +public fun CharArray.maxOrNull(): Char? { + if (isEmpty()) return null + var max = this[0] + for (i in 1..lastIndex) { + val e = this[i] + if (max < e) max = e + } + return max +} + /** * Returns the first element having the largest value according to the provided [comparator] or `null` if there are no elements. */ @@ -15024,144 +15084,56 @@ public fun CharArray.maxWith(comparator: Comparator): Char? { return max } -/** - * Returns the smallest element or `null` if there are no elements. - * - * If any of elements is `NaN` returns `NaN`. - */ +@Deprecated("Use minOrNull instead.", ReplaceWith("minOrNull()")) @SinceKotlin("1.1") public fun Array.min(): Double? { - if (isEmpty()) return null - var min = this[0] - for (i in 1..lastIndex) { - val e = this[i] - min = minOf(min, e) - } - return min + return minOrNull() } -/** - * Returns the smallest element or `null` if there are no elements. - * - * If any of elements is `NaN` returns `NaN`. - */ +@Deprecated("Use minOrNull instead.", ReplaceWith("minOrNull()")) @SinceKotlin("1.1") public fun Array.min(): Float? { - if (isEmpty()) return null - var min = this[0] - for (i in 1..lastIndex) { - val e = this[i] - min = minOf(min, e) - } - return min + return minOrNull() } -/** - * Returns the smallest element or `null` if there are no elements. - */ +@Deprecated("Use minOrNull instead.", ReplaceWith("minOrNull()")) public fun > Array.min(): T? { - if (isEmpty()) return null - var min = this[0] - for (i in 1..lastIndex) { - val e = this[i] - if (min > e) min = e - } - return min + return minOrNull() } -/** - * Returns the smallest element or `null` if there are no elements. - */ +@Deprecated("Use minOrNull instead.", ReplaceWith("minOrNull()")) public fun ByteArray.min(): Byte? { - if (isEmpty()) return null - var min = this[0] - for (i in 1..lastIndex) { - val e = this[i] - if (min > e) min = e - } - return min + return minOrNull() } -/** - * Returns the smallest element or `null` if there are no elements. - */ +@Deprecated("Use minOrNull instead.", ReplaceWith("minOrNull()")) public fun ShortArray.min(): Short? { - if (isEmpty()) return null - var min = this[0] - for (i in 1..lastIndex) { - val e = this[i] - if (min > e) min = e - } - return min + return minOrNull() } -/** - * Returns the smallest element or `null` if there are no elements. - */ +@Deprecated("Use minOrNull instead.", ReplaceWith("minOrNull()")) public fun IntArray.min(): Int? { - if (isEmpty()) return null - var min = this[0] - for (i in 1..lastIndex) { - val e = this[i] - if (min > e) min = e - } - return min + return minOrNull() } -/** - * Returns the smallest element or `null` if there are no elements. - */ +@Deprecated("Use minOrNull instead.", ReplaceWith("minOrNull()")) public fun LongArray.min(): Long? { - if (isEmpty()) return null - var min = this[0] - for (i in 1..lastIndex) { - val e = this[i] - if (min > e) min = e - } - return min + return minOrNull() } -/** - * Returns the smallest element or `null` if there are no elements. - * - * If any of elements is `NaN` returns `NaN`. - */ +@Deprecated("Use minOrNull instead.", ReplaceWith("minOrNull()")) public fun FloatArray.min(): Float? { - if (isEmpty()) return null - var min = this[0] - for (i in 1..lastIndex) { - val e = this[i] - min = minOf(min, e) - } - return min + return minOrNull() } -/** - * Returns the smallest element or `null` if there are no elements. - * - * If any of elements is `NaN` returns `NaN`. - */ +@Deprecated("Use minOrNull instead.", ReplaceWith("minOrNull()")) public fun DoubleArray.min(): Double? { - if (isEmpty()) return null - var min = this[0] - for (i in 1..lastIndex) { - val e = this[i] - min = minOf(min, e) - } - return min + return minOrNull() } -/** - * Returns the smallest element or `null` if there are no elements. - */ +@Deprecated("Use minOrNull instead.", ReplaceWith("minOrNull()")) public fun CharArray.min(): Char? { - if (isEmpty()) return null - var min = this[0] - for (i in 1..lastIndex) { - val e = this[i] - if (min > e) min = e - } - return min + return minOrNull() } /** @@ -16874,6 +16846,154 @@ public inline fun CharArray.minOfWithOrNull(comparator: Comparator, se return minValue } +/** + * Returns the smallest element or `null` if there are no elements. + * + * If any of elements is `NaN` returns `NaN`. + */ +@SinceKotlin("1.4") +public fun Array.minOrNull(): Double? { + if (isEmpty()) return null + var min = this[0] + for (i in 1..lastIndex) { + val e = this[i] + min = minOf(min, e) + } + return min +} + +/** + * Returns the smallest element or `null` if there are no elements. + * + * If any of elements is `NaN` returns `NaN`. + */ +@SinceKotlin("1.4") +public fun Array.minOrNull(): Float? { + if (isEmpty()) return null + var min = this[0] + for (i in 1..lastIndex) { + val e = this[i] + min = minOf(min, e) + } + return min +} + +/** + * Returns the smallest element or `null` if there are no elements. + */ +@SinceKotlin("1.4") +public fun > Array.minOrNull(): T? { + if (isEmpty()) return null + var min = this[0] + for (i in 1..lastIndex) { + val e = this[i] + if (min > e) min = e + } + return min +} + +/** + * Returns the smallest element or `null` if there are no elements. + */ +@SinceKotlin("1.4") +public fun ByteArray.minOrNull(): Byte? { + if (isEmpty()) return null + var min = this[0] + for (i in 1..lastIndex) { + val e = this[i] + if (min > e) min = e + } + return min +} + +/** + * Returns the smallest element or `null` if there are no elements. + */ +@SinceKotlin("1.4") +public fun ShortArray.minOrNull(): Short? { + if (isEmpty()) return null + var min = this[0] + for (i in 1..lastIndex) { + val e = this[i] + if (min > e) min = e + } + return min +} + +/** + * Returns the smallest element or `null` if there are no elements. + */ +@SinceKotlin("1.4") +public fun IntArray.minOrNull(): Int? { + if (isEmpty()) return null + var min = this[0] + for (i in 1..lastIndex) { + val e = this[i] + if (min > e) min = e + } + return min +} + +/** + * Returns the smallest element or `null` if there are no elements. + */ +@SinceKotlin("1.4") +public fun LongArray.minOrNull(): Long? { + if (isEmpty()) return null + var min = this[0] + for (i in 1..lastIndex) { + val e = this[i] + if (min > e) min = e + } + return min +} + +/** + * Returns the smallest element or `null` if there are no elements. + * + * If any of elements is `NaN` returns `NaN`. + */ +@SinceKotlin("1.4") +public fun FloatArray.minOrNull(): Float? { + if (isEmpty()) return null + var min = this[0] + for (i in 1..lastIndex) { + val e = this[i] + min = minOf(min, e) + } + return min +} + +/** + * Returns the smallest element or `null` if there are no elements. + * + * If any of elements is `NaN` returns `NaN`. + */ +@SinceKotlin("1.4") +public fun DoubleArray.minOrNull(): Double? { + if (isEmpty()) return null + var min = this[0] + for (i in 1..lastIndex) { + val e = this[i] + min = minOf(min, e) + } + return min +} + +/** + * Returns the smallest element or `null` if there are no elements. + */ +@SinceKotlin("1.4") +public fun CharArray.minOrNull(): Char? { + if (isEmpty()) return null + var min = this[0] + for (i in 1..lastIndex) { + val e = this[i] + if (min > e) min = e + } + return min +} + /** * Returns the first element having the smallest value according to the provided [comparator] or `null` if there are no elements. */ diff --git a/libraries/stdlib/common/src/generated/_Collections.kt b/libraries/stdlib/common/src/generated/_Collections.kt index e65855cf190..3443f801c6c 100644 --- a/libraries/stdlib/common/src/generated/_Collections.kt +++ b/libraries/stdlib/common/src/generated/_Collections.kt @@ -1719,52 +1719,21 @@ public inline fun Iterable.forEachIndexed(action: (index: Int, T) -> Unit for (item in this) action(checkIndexOverflow(index++), item) } -/** - * Returns the largest element or `null` if there are no elements. - * - * If any of elements is `NaN` returns `NaN`. - */ +@Deprecated("Use maxOrNull instead.", ReplaceWith("maxOrNull()")) @SinceKotlin("1.1") public fun Iterable.max(): Double? { - val iterator = iterator() - if (!iterator.hasNext()) return null - var max = iterator.next() - while (iterator.hasNext()) { - val e = iterator.next() - max = maxOf(max, e) - } - return max + return maxOrNull() } -/** - * Returns the largest element or `null` if there are no elements. - * - * If any of elements is `NaN` returns `NaN`. - */ +@Deprecated("Use maxOrNull instead.", ReplaceWith("maxOrNull()")) @SinceKotlin("1.1") public fun Iterable.max(): Float? { - val iterator = iterator() - if (!iterator.hasNext()) return null - var max = iterator.next() - while (iterator.hasNext()) { - val e = iterator.next() - max = maxOf(max, e) - } - return max + return maxOrNull() } -/** - * Returns the largest element or `null` if there are no elements. - */ +@Deprecated("Use maxOrNull instead.", ReplaceWith("maxOrNull()")) public fun > Iterable.max(): T? { - val iterator = iterator() - if (!iterator.hasNext()) return null - var max = iterator.next() - while (iterator.hasNext()) { - val e = iterator.next() - if (max < e) max = e - } - return max + return maxOrNull() } /** @@ -1965,6 +1934,55 @@ public inline fun Iterable.maxOfWithOrNull(comparator: Comparator.maxOrNull(): Double? { + val iterator = iterator() + if (!iterator.hasNext()) return null + var max = iterator.next() + while (iterator.hasNext()) { + val e = iterator.next() + max = maxOf(max, e) + } + return max +} + +/** + * Returns the largest element or `null` if there are no elements. + * + * If any of elements is `NaN` returns `NaN`. + */ +@SinceKotlin("1.4") +public fun Iterable.maxOrNull(): Float? { + val iterator = iterator() + if (!iterator.hasNext()) return null + var max = iterator.next() + while (iterator.hasNext()) { + val e = iterator.next() + max = maxOf(max, e) + } + return max +} + +/** + * Returns the largest element or `null` if there are no elements. + */ +@SinceKotlin("1.4") +public fun > Iterable.maxOrNull(): T? { + val iterator = iterator() + if (!iterator.hasNext()) return null + var max = iterator.next() + while (iterator.hasNext()) { + val e = iterator.next() + if (max < e) max = e + } + return max +} + /** * Returns the first element having the largest value according to the provided [comparator] or `null` if there are no elements. */ @@ -1979,52 +1997,21 @@ public fun Iterable.maxWith(comparator: Comparator): T? { return max } -/** - * Returns the smallest element or `null` if there are no elements. - * - * If any of elements is `NaN` returns `NaN`. - */ +@Deprecated("Use minOrNull instead.", ReplaceWith("minOrNull()")) @SinceKotlin("1.1") public fun Iterable.min(): Double? { - val iterator = iterator() - if (!iterator.hasNext()) return null - var min = iterator.next() - while (iterator.hasNext()) { - val e = iterator.next() - min = minOf(min, e) - } - return min + return minOrNull() } -/** - * Returns the smallest element or `null` if there are no elements. - * - * If any of elements is `NaN` returns `NaN`. - */ +@Deprecated("Use minOrNull instead.", ReplaceWith("minOrNull()")) @SinceKotlin("1.1") public fun Iterable.min(): Float? { - val iterator = iterator() - if (!iterator.hasNext()) return null - var min = iterator.next() - while (iterator.hasNext()) { - val e = iterator.next() - min = minOf(min, e) - } - return min + return minOrNull() } -/** - * Returns the smallest element or `null` if there are no elements. - */ +@Deprecated("Use minOrNull instead.", ReplaceWith("minOrNull()")) public fun > Iterable.min(): T? { - val iterator = iterator() - if (!iterator.hasNext()) return null - var min = iterator.next() - while (iterator.hasNext()) { - val e = iterator.next() - if (min > e) min = e - } - return min + return minOrNull() } /** @@ -2225,6 +2212,55 @@ public inline fun Iterable.minOfWithOrNull(comparator: Comparator.minOrNull(): Double? { + val iterator = iterator() + if (!iterator.hasNext()) return null + var min = iterator.next() + while (iterator.hasNext()) { + val e = iterator.next() + min = minOf(min, e) + } + return min +} + +/** + * Returns the smallest element or `null` if there are no elements. + * + * If any of elements is `NaN` returns `NaN`. + */ +@SinceKotlin("1.4") +public fun Iterable.minOrNull(): Float? { + val iterator = iterator() + if (!iterator.hasNext()) return null + var min = iterator.next() + while (iterator.hasNext()) { + val e = iterator.next() + min = minOf(min, e) + } + return min +} + +/** + * Returns the smallest element or `null` if there are no elements. + */ +@SinceKotlin("1.4") +public fun > Iterable.minOrNull(): T? { + val iterator = iterator() + if (!iterator.hasNext()) return null + var min = iterator.next() + while (iterator.hasNext()) { + val e = iterator.next() + if (min > e) min = e + } + return min +} + /** * Returns the first element having the smallest value according to the provided [comparator] or `null` if there are no elements. */ diff --git a/libraries/stdlib/common/src/generated/_Sequences.kt b/libraries/stdlib/common/src/generated/_Sequences.kt index 215711e286e..eac3386a2b4 100644 --- a/libraries/stdlib/common/src/generated/_Sequences.kt +++ b/libraries/stdlib/common/src/generated/_Sequences.kt @@ -1166,58 +1166,21 @@ public inline fun Sequence.forEachIndexed(action: (index: Int, T) -> Unit for (item in this) action(checkIndexOverflow(index++), item) } -/** - * Returns the largest element or `null` if there are no elements. - * - * If any of elements is `NaN` returns `NaN`. - * - * The operation is _terminal_. - */ +@Deprecated("Use maxOrNull instead.", ReplaceWith("maxOrNull()")) @SinceKotlin("1.1") public fun Sequence.max(): Double? { - val iterator = iterator() - if (!iterator.hasNext()) return null - var max = iterator.next() - while (iterator.hasNext()) { - val e = iterator.next() - max = maxOf(max, e) - } - return max + return maxOrNull() } -/** - * Returns the largest element or `null` if there are no elements. - * - * If any of elements is `NaN` returns `NaN`. - * - * The operation is _terminal_. - */ +@Deprecated("Use maxOrNull instead.", ReplaceWith("maxOrNull()")) @SinceKotlin("1.1") public fun Sequence.max(): Float? { - val iterator = iterator() - if (!iterator.hasNext()) return null - var max = iterator.next() - while (iterator.hasNext()) { - val e = iterator.next() - max = maxOf(max, e) - } - return max + return maxOrNull() } -/** - * Returns the largest element or `null` if there are no elements. - * - * The operation is _terminal_. - */ +@Deprecated("Use maxOrNull instead.", ReplaceWith("maxOrNull()")) public fun > Sequence.max(): T? { - val iterator = iterator() - if (!iterator.hasNext()) return null - var max = iterator.next() - while (iterator.hasNext()) { - val e = iterator.next() - if (max < e) max = e - } - return max + return maxOrNull() } /** @@ -1436,6 +1399,61 @@ public inline fun Sequence.maxOfWithOrNull(comparator: Comparator.maxOrNull(): Double? { + val iterator = iterator() + if (!iterator.hasNext()) return null + var max = iterator.next() + while (iterator.hasNext()) { + val e = iterator.next() + max = maxOf(max, e) + } + return max +} + +/** + * Returns the largest element or `null` if there are no elements. + * + * If any of elements is `NaN` returns `NaN`. + * + * The operation is _terminal_. + */ +@SinceKotlin("1.4") +public fun Sequence.maxOrNull(): Float? { + val iterator = iterator() + if (!iterator.hasNext()) return null + var max = iterator.next() + while (iterator.hasNext()) { + val e = iterator.next() + max = maxOf(max, e) + } + return max +} + +/** + * Returns the largest element or `null` if there are no elements. + * + * The operation is _terminal_. + */ +@SinceKotlin("1.4") +public fun > Sequence.maxOrNull(): T? { + val iterator = iterator() + if (!iterator.hasNext()) return null + var max = iterator.next() + while (iterator.hasNext()) { + val e = iterator.next() + if (max < e) max = e + } + return max +} + /** * Returns the first element having the largest value according to the provided [comparator] or `null` if there are no elements. * @@ -1452,58 +1470,21 @@ public fun Sequence.maxWith(comparator: Comparator): T? { return max } -/** - * Returns the smallest element or `null` if there are no elements. - * - * If any of elements is `NaN` returns `NaN`. - * - * The operation is _terminal_. - */ +@Deprecated("Use minOrNull instead.", ReplaceWith("minOrNull()")) @SinceKotlin("1.1") public fun Sequence.min(): Double? { - val iterator = iterator() - if (!iterator.hasNext()) return null - var min = iterator.next() - while (iterator.hasNext()) { - val e = iterator.next() - min = minOf(min, e) - } - return min + return minOrNull() } -/** - * Returns the smallest element or `null` if there are no elements. - * - * If any of elements is `NaN` returns `NaN`. - * - * The operation is _terminal_. - */ +@Deprecated("Use minOrNull instead.", ReplaceWith("minOrNull()")) @SinceKotlin("1.1") public fun Sequence.min(): Float? { - val iterator = iterator() - if (!iterator.hasNext()) return null - var min = iterator.next() - while (iterator.hasNext()) { - val e = iterator.next() - min = minOf(min, e) - } - return min + return minOrNull() } -/** - * Returns the smallest element or `null` if there are no elements. - * - * The operation is _terminal_. - */ +@Deprecated("Use minOrNull instead.", ReplaceWith("minOrNull()")) public fun > Sequence.min(): T? { - val iterator = iterator() - if (!iterator.hasNext()) return null - var min = iterator.next() - while (iterator.hasNext()) { - val e = iterator.next() - if (min > e) min = e - } - return min + return minOrNull() } /** @@ -1722,6 +1703,61 @@ public inline fun Sequence.minOfWithOrNull(comparator: Comparator.minOrNull(): Double? { + val iterator = iterator() + if (!iterator.hasNext()) return null + var min = iterator.next() + while (iterator.hasNext()) { + val e = iterator.next() + min = minOf(min, e) + } + return min +} + +/** + * Returns the smallest element or `null` if there are no elements. + * + * If any of elements is `NaN` returns `NaN`. + * + * The operation is _terminal_. + */ +@SinceKotlin("1.4") +public fun Sequence.minOrNull(): Float? { + val iterator = iterator() + if (!iterator.hasNext()) return null + var min = iterator.next() + while (iterator.hasNext()) { + val e = iterator.next() + min = minOf(min, e) + } + return min +} + +/** + * Returns the smallest element or `null` if there are no elements. + * + * The operation is _terminal_. + */ +@SinceKotlin("1.4") +public fun > Sequence.minOrNull(): T? { + val iterator = iterator() + if (!iterator.hasNext()) return null + var min = iterator.next() + while (iterator.hasNext()) { + val e = iterator.next() + if (min > e) min = e + } + return min +} + /** * Returns the first element having the smallest value according to the provided [comparator] or `null` if there are no elements. * diff --git a/libraries/stdlib/common/src/generated/_Strings.kt b/libraries/stdlib/common/src/generated/_Strings.kt index f766c0ff2c4..29e86e278a0 100644 --- a/libraries/stdlib/common/src/generated/_Strings.kt +++ b/libraries/stdlib/common/src/generated/_Strings.kt @@ -1088,17 +1088,9 @@ public inline fun CharSequence.forEachIndexed(action: (index: Int, Char) -> Unit for (item in this) action(index++, item) } -/** - * Returns the largest character or `null` if there are no characters. - */ +@Deprecated("Use maxOrNull instead.", ReplaceWith("maxOrNull()")) public fun CharSequence.max(): Char? { - if (isEmpty()) return null - var max = this[0] - for (i in 1..lastIndex) { - val e = this[i] - if (max < e) max = e - } - return max + return maxOrNull() } /** @@ -1291,6 +1283,20 @@ public inline fun CharSequence.maxOfWithOrNull(comparator: Comparator, return maxValue } +/** + * Returns the largest character or `null` if there are no characters. + */ +@SinceKotlin("1.4") +public fun CharSequence.maxOrNull(): Char? { + if (isEmpty()) return null + var max = this[0] + for (i in 1..lastIndex) { + val e = this[i] + if (max < e) max = e + } + return max +} + /** * Returns the first character having the largest value according to the provided [comparator] or `null` if there are no characters. */ @@ -1304,17 +1310,9 @@ public fun CharSequence.maxWith(comparator: Comparator): Char? { return max } -/** - * Returns the smallest character or `null` if there are no characters. - */ +@Deprecated("Use minOrNull instead.", ReplaceWith("minOrNull()")) public fun CharSequence.min(): Char? { - if (isEmpty()) return null - var min = this[0] - for (i in 1..lastIndex) { - val e = this[i] - if (min > e) min = e - } - return min + return minOrNull() } /** @@ -1507,6 +1505,20 @@ public inline fun CharSequence.minOfWithOrNull(comparator: Comparator, return minValue } +/** + * Returns the smallest character or `null` if there are no characters. + */ +@SinceKotlin("1.4") +public fun CharSequence.minOrNull(): Char? { + if (isEmpty()) return null + var min = this[0] + for (i in 1..lastIndex) { + val e = this[i] + if (min > e) min = e + } + return min +} + /** * Returns the first character having the smallest value according to the provided [comparator] or `null` if there are no characters. */ diff --git a/libraries/stdlib/common/src/generated/_UArrays.kt b/libraries/stdlib/common/src/generated/_UArrays.kt index bc965861343..dae3e0bb6a4 100644 --- a/libraries/stdlib/common/src/generated/_UArrays.kt +++ b/libraries/stdlib/common/src/generated/_UArrays.kt @@ -5702,64 +5702,32 @@ public inline fun UShortArray.forEachIndexed(action: (index: Int, UShort) -> Uni for (item in this) action(index++, item) } -/** - * Returns the largest element or `null` if there are no elements. - */ +@Deprecated("Use maxOrNull instead.", ReplaceWith("maxOrNull()")) @SinceKotlin("1.3") @ExperimentalUnsignedTypes public fun UIntArray.max(): UInt? { - if (isEmpty()) return null - var max = this[0] - for (i in 1..lastIndex) { - val e = this[i] - if (max < e) max = e - } - return max + return maxOrNull() } -/** - * Returns the largest element or `null` if there are no elements. - */ +@Deprecated("Use maxOrNull instead.", ReplaceWith("maxOrNull()")) @SinceKotlin("1.3") @ExperimentalUnsignedTypes public fun ULongArray.max(): ULong? { - if (isEmpty()) return null - var max = this[0] - for (i in 1..lastIndex) { - val e = this[i] - if (max < e) max = e - } - return max + return maxOrNull() } -/** - * Returns the largest element or `null` if there are no elements. - */ +@Deprecated("Use maxOrNull instead.", ReplaceWith("maxOrNull()")) @SinceKotlin("1.3") @ExperimentalUnsignedTypes public fun UByteArray.max(): UByte? { - if (isEmpty()) return null - var max = this[0] - for (i in 1..lastIndex) { - val e = this[i] - if (max < e) max = e - } - return max + return maxOrNull() } -/** - * Returns the largest element or `null` if there are no elements. - */ +@Deprecated("Use maxOrNull instead.", ReplaceWith("maxOrNull()")) @SinceKotlin("1.3") @ExperimentalUnsignedTypes public fun UShortArray.max(): UShort? { - if (isEmpty()) return null - var max = this[0] - for (i in 1..lastIndex) { - val e = this[i] - if (max < e) max = e - } - return max + return maxOrNull() } /** @@ -6566,6 +6534,66 @@ public inline fun UShortArray.maxOfWithOrNull(comparator: Comparator, return maxValue } +/** + * Returns the largest element or `null` if there are no elements. + */ +@SinceKotlin("1.4") +@ExperimentalUnsignedTypes +public fun UIntArray.maxOrNull(): UInt? { + if (isEmpty()) return null + var max = this[0] + for (i in 1..lastIndex) { + val e = this[i] + if (max < e) max = e + } + return max +} + +/** + * Returns the largest element or `null` if there are no elements. + */ +@SinceKotlin("1.4") +@ExperimentalUnsignedTypes +public fun ULongArray.maxOrNull(): ULong? { + if (isEmpty()) return null + var max = this[0] + for (i in 1..lastIndex) { + val e = this[i] + if (max < e) max = e + } + return max +} + +/** + * Returns the largest element or `null` if there are no elements. + */ +@SinceKotlin("1.4") +@ExperimentalUnsignedTypes +public fun UByteArray.maxOrNull(): UByte? { + if (isEmpty()) return null + var max = this[0] + for (i in 1..lastIndex) { + val e = this[i] + if (max < e) max = e + } + return max +} + +/** + * Returns the largest element or `null` if there are no elements. + */ +@SinceKotlin("1.4") +@ExperimentalUnsignedTypes +public fun UShortArray.maxOrNull(): UShort? { + if (isEmpty()) return null + var max = this[0] + for (i in 1..lastIndex) { + val e = this[i] + if (max < e) max = e + } + return max +} + /** * Returns the first element having the largest value according to the provided [comparator] or `null` if there are no elements. */ @@ -6626,64 +6654,32 @@ public fun UShortArray.maxWith(comparator: Comparator): UShort? { return max } -/** - * Returns the smallest element or `null` if there are no elements. - */ +@Deprecated("Use minOrNull instead.", ReplaceWith("minOrNull()")) @SinceKotlin("1.3") @ExperimentalUnsignedTypes public fun UIntArray.min(): UInt? { - if (isEmpty()) return null - var min = this[0] - for (i in 1..lastIndex) { - val e = this[i] - if (min > e) min = e - } - return min + return minOrNull() } -/** - * Returns the smallest element or `null` if there are no elements. - */ +@Deprecated("Use minOrNull instead.", ReplaceWith("minOrNull()")) @SinceKotlin("1.3") @ExperimentalUnsignedTypes public fun ULongArray.min(): ULong? { - if (isEmpty()) return null - var min = this[0] - for (i in 1..lastIndex) { - val e = this[i] - if (min > e) min = e - } - return min + return minOrNull() } -/** - * Returns the smallest element or `null` if there are no elements. - */ +@Deprecated("Use minOrNull instead.", ReplaceWith("minOrNull()")) @SinceKotlin("1.3") @ExperimentalUnsignedTypes public fun UByteArray.min(): UByte? { - if (isEmpty()) return null - var min = this[0] - for (i in 1..lastIndex) { - val e = this[i] - if (min > e) min = e - } - return min + return minOrNull() } -/** - * Returns the smallest element or `null` if there are no elements. - */ +@Deprecated("Use minOrNull instead.", ReplaceWith("minOrNull()")) @SinceKotlin("1.3") @ExperimentalUnsignedTypes public fun UShortArray.min(): UShort? { - if (isEmpty()) return null - var min = this[0] - for (i in 1..lastIndex) { - val e = this[i] - if (min > e) min = e - } - return min + return minOrNull() } /** @@ -7490,6 +7486,66 @@ public inline fun UShortArray.minOfWithOrNull(comparator: Comparator, return minValue } +/** + * Returns the smallest element or `null` if there are no elements. + */ +@SinceKotlin("1.4") +@ExperimentalUnsignedTypes +public fun UIntArray.minOrNull(): UInt? { + if (isEmpty()) return null + var min = this[0] + for (i in 1..lastIndex) { + val e = this[i] + if (min > e) min = e + } + return min +} + +/** + * Returns the smallest element or `null` if there are no elements. + */ +@SinceKotlin("1.4") +@ExperimentalUnsignedTypes +public fun ULongArray.minOrNull(): ULong? { + if (isEmpty()) return null + var min = this[0] + for (i in 1..lastIndex) { + val e = this[i] + if (min > e) min = e + } + return min +} + +/** + * Returns the smallest element or `null` if there are no elements. + */ +@SinceKotlin("1.4") +@ExperimentalUnsignedTypes +public fun UByteArray.minOrNull(): UByte? { + if (isEmpty()) return null + var min = this[0] + for (i in 1..lastIndex) { + val e = this[i] + if (min > e) min = e + } + return min +} + +/** + * Returns the smallest element or `null` if there are no elements. + */ +@SinceKotlin("1.4") +@ExperimentalUnsignedTypes +public fun UShortArray.minOrNull(): UShort? { + if (isEmpty()) return null + var min = this[0] + for (i in 1..lastIndex) { + val e = this[i] + if (min > e) min = e + } + return min +} + /** * Returns the first element having the smallest value according to the provided [comparator] or `null` if there are no elements. */ diff --git a/libraries/stdlib/src/kotlin/text/Indent.kt b/libraries/stdlib/src/kotlin/text/Indent.kt index 0391a566033..0f860f1e192 100644 --- a/libraries/stdlib/src/kotlin/text/Indent.kt +++ b/libraries/stdlib/src/kotlin/text/Indent.kt @@ -71,7 +71,7 @@ public fun String.replaceIndent(newIndent: String = ""): String { val minCommonIndent = lines .filter(String::isNotBlank) .map(String::indentWidth) - .min() ?: 0 + .minOrNull() ?: 0 return lines.reindent(length + newIndent.length * lines.size, getIndentFunction(newIndent), { line -> line.drop(minCommonIndent) }) } diff --git a/libraries/stdlib/test/collections/ArraysTest.kt b/libraries/stdlib/test/collections/ArraysTest.kt index 891b5889c90..fcb6e8f6f95 100644 --- a/libraries/stdlib/test/collections/ArraysTest.kt +++ b/libraries/stdlib/test/collections/ArraysTest.kt @@ -348,46 +348,46 @@ class ArraysTest { - @Test fun min() { - expect(null, { arrayOf().min() }) - expect(1, { arrayOf(1).min() }) - expect(2, { arrayOf(2, 3).min() }) - expect(2000000000000, { arrayOf(3000000000000, 2000000000000).min() }) - expect('a', { arrayOf('a', 'b').min() }) - expect("a", { arrayOf("a", "b").min() }) + @Test fun minOrNull() { + expect(null, { arrayOf().minOrNull() }) + expect(1, { arrayOf(1).minOrNull() }) + expect(2, { arrayOf(2, 3).minOrNull() }) + expect(2000000000000, { arrayOf(3000000000000, 2000000000000).minOrNull() }) + expect('a', { arrayOf('a', 'b').minOrNull() }) + expect("a", { arrayOf("a", "b").minOrNull() }) } - @Test fun minInPrimitiveArrays() { - expect(null, { intArrayOf().min() }) - expect(1, { intArrayOf(1).min() }) - expect(2, { intArrayOf(2, 3).min() }) - expect(2000000000000, { longArrayOf(3000000000000, 2000000000000).min() }) - expect(1, { byteArrayOf(1, 3, 2).min() }) - expect(2, { shortArrayOf(3, 2).min() }) - expect(2.0F, { floatArrayOf(3.0F, 2.0F).min() }) - expect(2.0, { doubleArrayOf(2.0, 3.0).min() }) - expect('a', { charArrayOf('a', 'b').min() }) + @Test fun minOrNullInPrimitiveArrays() { + expect(null, { intArrayOf().minOrNull() }) + expect(1, { intArrayOf(1).minOrNull() }) + expect(2, { intArrayOf(2, 3).minOrNull() }) + expect(2000000000000, { longArrayOf(3000000000000, 2000000000000).minOrNull() }) + expect(1, { byteArrayOf(1, 3, 2).minOrNull() }) + expect(2, { shortArrayOf(3, 2).minOrNull() }) + expect(2.0F, { floatArrayOf(3.0F, 2.0F).minOrNull() }) + expect(2.0, { doubleArrayOf(2.0, 3.0).minOrNull() }) + expect('a', { charArrayOf('a', 'b').minOrNull() }) } - @Test fun max() { - expect(null, { arrayOf().max() }) - expect(1, { arrayOf(1).max() }) - expect(3, { arrayOf(2, 3).max() }) - expect(3000000000000, { arrayOf(3000000000000, 2000000000000).max() }) - expect('b', { arrayOf('a', 'b').max() }) - expect("b", { arrayOf("a", "b").max() }) + @Test fun maxOrNull() { + expect(null, { arrayOf().maxOrNull() }) + expect(1, { arrayOf(1).maxOrNull() }) + expect(3, { arrayOf(2, 3).maxOrNull() }) + expect(3000000000000, { arrayOf(3000000000000, 2000000000000).maxOrNull() }) + expect('b', { arrayOf('a', 'b').maxOrNull() }) + expect("b", { arrayOf("a", "b").maxOrNull() }) } - @Test fun maxInPrimitiveArrays() { - expect(null, { intArrayOf().max() }) - expect(1, { intArrayOf(1).max() }) - expect(3, { intArrayOf(2, 3).max() }) - expect(3000000000000, { longArrayOf(3000000000000, 2000000000000).max() }) - expect(3, { byteArrayOf(1, 3, 2).max() }) - expect(3, { shortArrayOf(3, 2).max() }) - expect(3.0F, { floatArrayOf(3.0F, 2.0F).max() }) - expect(3.0, { doubleArrayOf(2.0, 3.0).max() }) - expect('b', { charArrayOf('a', 'b').max() }) + @Test fun maxOrNullInPrimitiveArrays() { + expect(null, { intArrayOf().maxOrNull() }) + expect(1, { intArrayOf(1).maxOrNull() }) + expect(3, { intArrayOf(2, 3).maxOrNull() }) + expect(3000000000000, { longArrayOf(3000000000000, 2000000000000).maxOrNull() }) + expect(3, { byteArrayOf(1, 3, 2).maxOrNull() }) + expect(3, { shortArrayOf(3, 2).maxOrNull() }) + expect(3.0F, { floatArrayOf(3.0F, 2.0F).maxOrNull() }) + expect(3.0, { doubleArrayOf(2.0, 3.0).maxOrNull() }) + expect('b', { charArrayOf('a', 'b').maxOrNull() }) } @Test fun minWith() { diff --git a/libraries/stdlib/test/collections/CollectionTest.kt b/libraries/stdlib/test/collections/CollectionTest.kt index a424def797e..cf1048108a8 100644 --- a/libraries/stdlib/test/collections/CollectionTest.kt +++ b/libraries/stdlib/test/collections/CollectionTest.kt @@ -823,32 +823,32 @@ class CollectionTest { assertTrue(hashSetOf(45, 14, 13).toIterable().contains(14)) } - @Test fun min() { - expect(null, { listOf().min() }) - expect(1, { listOf(1).min() }) - expect(2, { listOf(2, 3).min() }) - expect(2000000000000, { listOf(3000000000000, 2000000000000).min() }) - expect('a', { listOf('a', 'b').min() }) - expect("a", { listOf("a", "b").min() }) - expect(null, { listOf().asSequence().min() }) - expect(2, { listOf(2, 3).asSequence().min() }) + @Test fun minOrNull() { + expect(null, { listOf().minOrNull() }) + expect(1, { listOf(1).minOrNull() }) + expect(2, { listOf(2, 3).minOrNull() }) + expect(2000000000000, { listOf(3000000000000, 2000000000000).minOrNull() }) + expect('a', { listOf('a', 'b').minOrNull() }) + expect("a", { listOf("a", "b").minOrNull() }) + expect(null, { listOf().asSequence().minOrNull() }) + expect(2, { listOf(2, 3).asSequence().minOrNull() }) - assertIsNegativeZero(listOf(0.0, -0.0).shuffled().min()!!) - assertIsNegativeZero(listOf(0.0F, -0.0F).shuffled().min()!!.toDouble()) + assertIsNegativeZero(listOf(0.0, -0.0).shuffled().minOrNull()!!) + assertIsNegativeZero(listOf(0.0F, -0.0F).shuffled().minOrNull()!!.toDouble()) } @Test fun max() { - expect(null, { listOf().max() }) - expect(1, { listOf(1).max() }) - expect(3, { listOf(2, 3).max() }) - expect(3000000000000, { listOf(3000000000000, 2000000000000).max() }) - expect('b', { listOf('a', 'b').max() }) - expect("b", { listOf("a", "b").max() }) - expect(null, { listOf().asSequence().max() }) - expect(3, { listOf(2, 3).asSequence().max() }) + expect(null, { listOf().maxOrNull() }) + expect(1, { listOf(1).maxOrNull() }) + expect(3, { listOf(2, 3).maxOrNull() }) + expect(3000000000000, { listOf(3000000000000, 2000000000000).maxOrNull() }) + expect('b', { listOf('a', 'b').maxOrNull() }) + expect("b", { listOf("a", "b").maxOrNull() }) + expect(null, { listOf().asSequence().maxOrNull() }) + expect(3, { listOf(2, 3).asSequence().maxOrNull() }) - assertIsPositiveZero(listOf(0.0, -0.0).shuffled().max()!!) - assertIsPositiveZero(listOf(0.0F, -0.0F).shuffled().max()!!.toDouble()) + assertIsPositiveZero(listOf(0.0, -0.0).shuffled().maxOrNull()!!) + assertIsPositiveZero(listOf(0.0F, -0.0F).shuffled().maxOrNull()!!.toDouble()) } @Test fun minWith() { diff --git a/libraries/stdlib/test/collections/IterableTests.kt b/libraries/stdlib/test/collections/IterableTests.kt index 8dce6de37cd..d5c1a540f56 100644 --- a/libraries/stdlib/test/collections/IterableTests.kt +++ b/libraries/stdlib/test/collections/IterableTests.kt @@ -394,14 +394,14 @@ abstract class IterableTests>(val createFrom: (Array().min() } - expect(1u) { arrayOf(1).min() } - expect(2u) { arrayOf(2, 3).min() } - expect(2uL) { arrayOf(3, 2).min() } + fun minOrNull() { + expect(null) { arrayOf().minOrNull() } + expect(1u) { arrayOf(1).minOrNull() } + expect(2u) { arrayOf(2, 3).minOrNull() } + expect(2uL) { arrayOf(3, 2).minOrNull() } } @Test - fun minInUnsignedArrays() { - expect(null) { ubyteArrayOf().min() } - expect(1u) { ushortArrayOf(1).min() } - expect(2u) { uintArrayOf(2, 3).min() } - expect(2uL) { ulongArrayOf(3, 2).min() } + fun minOrNullInUnsignedArrays() { + expect(null) { ubyteArrayOf().minOrNull() } + expect(1u) { ushortArrayOf(1).minOrNull() } + expect(2u) { uintArrayOf(2, 3).minOrNull() } + expect(2uL) { ulongArrayOf(3, 2).minOrNull() } } @Test - fun max() { - expect(null) { arrayOf().max() } - expect(1u) { arrayOf(1).max() } - expect(3u) { arrayOf(2, 3).max() } - expect(3uL) { arrayOf(3, 2).max() } + fun maxOrNull() { + expect(null) { arrayOf().maxOrNull() } + expect(1u) { arrayOf(1).maxOrNull() } + expect(3u) { arrayOf(2, 3).maxOrNull() } + expect(3uL) { arrayOf(3, 2).maxOrNull() } } @Test - fun maxInUnsignedArrays() { - expect(null) { ubyteArrayOf().max() } - expect(1u) { ushortArrayOf(1).max() } - expect(3u) { uintArrayOf(2, 3).max() } - expect(3uL) { ulongArrayOf(3, 2).max() } + fun maxOrNullInUnsignedArrays() { + expect(null) { ubyteArrayOf().maxOrNull() } + expect(1u) { ushortArrayOf(1).maxOrNull() } + expect(3u) { uintArrayOf(2, 3).maxOrNull() } + expect(3uL) { ulongArrayOf(3, 2).maxOrNull() } } @Test diff --git a/libraries/stdlib/test/numbers/NaNPropagationTest.kt b/libraries/stdlib/test/numbers/NaNPropagationTest.kt index b3fbb898d4f..bdc8e71170d 100644 --- a/libraries/stdlib/test/numbers/NaNPropagationTest.kt +++ b/libraries/stdlib/test/numbers/NaNPropagationTest.kt @@ -83,20 +83,20 @@ class NaNPropagationTest { } @Test - fun arrayMin() { + fun arrayMinOrNull() { propagateOf2( - { a, b -> arrayOf(a, b).min()!! }, - { a, b -> arrayOf(a, b).min()!! }, - "arrayOf().min()" + { a, b -> arrayOf(a, b).minOrNull()!! }, + { a, b -> arrayOf(a, b).minOrNull()!! }, + "arrayOf().minOrNull()" ) } @Test - fun arrayMax() { + fun arrayMaxOrNull() { propagateOf2( - { a, b -> arrayOf(a, b).max()!! }, - { a, b -> arrayOf(a, b).max()!! }, - "arrayOf().max()" + { a, b -> arrayOf(a, b).maxOrNull()!! }, + { a, b -> arrayOf(a, b).maxOrNull()!! }, + "arrayOf().maxOrNull()" ) } @@ -108,7 +108,7 @@ class NaNPropagationTest { "arrayOf().minOf()" ) } - + @Test fun arrayMaxOf() { propagateOf3( @@ -119,20 +119,20 @@ class NaNPropagationTest { } @Test - fun primitiveArrayMin() { + fun primitiveArrayMinOrNull() { propagateOf2( - { a, b -> doubleArrayOf(a, b).min()!! }, - { a, b -> floatArrayOf(a, b).min()!! }, - "primitiveArrayOf().min()" + { a, b -> doubleArrayOf(a, b).minOrNull()!! }, + { a, b -> floatArrayOf(a, b).minOrNull()!! }, + "primitiveArrayOf().minOrNull()" ) } @Test fun primitiveArrayMax() { propagateOf2( - { a, b -> doubleArrayOf(a, b).max()!! }, - { a, b -> floatArrayOf(a, b).max()!! }, - "primitiveArrayOf().max()" + { a, b -> doubleArrayOf(a, b).minOrNull()!! }, + { a, b -> floatArrayOf(a, b).minOrNull()!! }, + "primitiveArrayOf().maxOrNull()" ) } @@ -165,20 +165,20 @@ class NaNPropagationTest { } @Test - fun listMin() { + fun listMinOrNull() { propagateOf2( - { a, b -> listOf(a, b).min()!! }, - { a, b -> listOf(a, b).min()!! }, - "listOf().min()" + { a, b -> listOf(a, b).minOrNull()!! }, + { a, b -> listOf(a, b).minOrNull()!! }, + "listOf().minOrNull()" ) } @Test - fun listMax() { + fun listMaxOrNull() { propagateOf2( - { a, b -> listOf(a, b).max()!! }, - { a, b -> listOf(a, b).max()!! }, - "listOf().max()" + { a, b -> listOf(a, b).maxOrNull()!! }, + { a, b -> listOf(a, b).maxOrNull()!! }, + "listOf().maxOrNull()" ) } @@ -201,20 +201,20 @@ class NaNPropagationTest { } @Test - fun sequenceMin() { + fun sequenceMinOrNull() { propagateOf2( - { a, b -> sequenceOf(a, b).min()!! }, - { a, b -> sequenceOf(a, b).min()!! }, - "sequenceOf().min()" + { a, b -> sequenceOf(a, b).minOrNull()!! }, + { a, b -> sequenceOf(a, b).minOrNull()!! }, + "sequenceOf().minOrNull()" ) } @Test - fun sequenceMax() { + fun sequenceMaxOrNull() { propagateOf2( - { a, b -> sequenceOf(a, b).max()!! }, - { a, b -> sequenceOf(a, b).max()!! }, - "sequenceOf().max()" + { a, b -> sequenceOf(a, b).maxOrNull()!! }, + { a, b -> sequenceOf(a, b).maxOrNull()!! }, + "sequenceOf().maxOrNull()" ) } @@ -266,34 +266,34 @@ class NaNTotalOrderTest { } @Test - fun arrayTMin() { - totalOrderMinOf2>({ a, b -> arrayOf(a, b).min()!! }, "arrayOf().min()") + fun arrayTMinOrNull() { + totalOrderMinOf2>({ a, b -> arrayOf(a, b).minOrNull()!! }, "arrayOf().minOrNull()") } @Test - fun arrayTMax() { - totalOrderMaxOf2>({ a, b -> arrayOf(a, b).max()!! }, "arrayOf().max()") + fun arrayTMaxOrNull() { + totalOrderMaxOf2>({ a, b -> arrayOf(a, b).maxOrNull()!! }, "arrayOf().maxOrNull()") } @Test - fun listTMin() { - totalOrderMinOf2>({ a, b -> listOf(a, b).min()!! }, "listOf().min()") + fun listTMinOrNull() { + totalOrderMinOf2>({ a, b -> listOf(a, b).minOrNull()!! }, "listOf().minOrNull()") } @Test - fun listTMax() { - totalOrderMaxOf2>({ a, b -> listOf(a, b).max()!! }, "listOf().max()") + fun listTMaxOrNull() { + totalOrderMaxOf2>({ a, b -> listOf(a, b).maxOrNull()!! }, "listOf().maxOrNull()") } @Test - fun sequenceTMin() { - totalOrderMinOf2>({ a, b -> sequenceOf(a, b).min()!! }, "sequenceOf().min()") + fun sequenceTMinOrNull() { + totalOrderMinOf2>({ a, b -> sequenceOf(a, b).minOrNull()!! }, "sequenceOf().minOrNull()") } @Test - fun sequenceTMax() { - totalOrderMaxOf2>({ a, b -> sequenceOf(a, b).max()!! }, "sequenceOf().max()") + fun sequenceTMaxOrNull() { + totalOrderMaxOf2>({ a, b -> sequenceOf(a, b).maxOrNull()!! }, "sequenceOf().maxOrNull()") } } diff --git a/libraries/stdlib/test/text/StringTest.kt b/libraries/stdlib/test/text/StringTest.kt index 4ff2a458f9f..3be87e7db33 100644 --- a/libraries/stdlib/test/text/StringTest.kt +++ b/libraries/stdlib/test/text/StringTest.kt @@ -1635,8 +1635,8 @@ ${" "} assertEquals(23, deindented.lines().size) val indents = deindented.lines().map { "^\\s*".toRegex().find(it)!!.value.length } - assertEquals(0, indents.min()) - assertEquals(42, indents.max()) + assertEquals(0, indents.minOrNull()) + assertEquals(42, indents.maxOrNull()) assertEquals(1, deindented.lines().count { it.isEmpty() }) } diff --git a/libraries/tools/binary-compatibility-validator/reference-public-api/kotlin-stdlib-runtime-merged.txt b/libraries/tools/binary-compatibility-validator/reference-public-api/kotlin-stdlib-runtime-merged.txt index 19692b8d814..76d2df18080 100644 --- a/libraries/tools/binary-compatibility-validator/reference-public-api/kotlin-stdlib-runtime-merged.txt +++ b/libraries/tools/binary-compatibility-validator/reference-public-api/kotlin-stdlib-runtime-merged.txt @@ -1393,6 +1393,16 @@ public final class kotlin/collections/ArraysKt { public static final fun maxBy ([Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; public static final fun maxBy ([SLkotlin/jvm/functions/Function1;)Ljava/lang/Short; public static final fun maxBy ([ZLkotlin/jvm/functions/Function1;)Ljava/lang/Boolean; + public static final fun maxOrNull ([B)Ljava/lang/Byte; + public static final fun maxOrNull ([C)Ljava/lang/Character; + public static final fun maxOrNull ([D)Ljava/lang/Double; + public static final fun maxOrNull ([F)Ljava/lang/Float; + public static final fun maxOrNull ([I)Ljava/lang/Integer; + public static final fun maxOrNull ([J)Ljava/lang/Long; + public static final fun maxOrNull ([Ljava/lang/Comparable;)Ljava/lang/Comparable; + public static final fun maxOrNull ([Ljava/lang/Double;)Ljava/lang/Double; + public static final fun maxOrNull ([Ljava/lang/Float;)Ljava/lang/Float; + public static final fun maxOrNull ([S)Ljava/lang/Short; public static final fun maxWith ([BLjava/util/Comparator;)Ljava/lang/Byte; public static final fun maxWith ([CLjava/util/Comparator;)Ljava/lang/Character; public static final fun maxWith ([DLjava/util/Comparator;)Ljava/lang/Double; @@ -1421,6 +1431,16 @@ public final class kotlin/collections/ArraysKt { public static final fun minBy ([Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; public static final fun minBy ([SLkotlin/jvm/functions/Function1;)Ljava/lang/Short; public static final fun minBy ([ZLkotlin/jvm/functions/Function1;)Ljava/lang/Boolean; + public static final fun minOrNull ([B)Ljava/lang/Byte; + public static final fun minOrNull ([C)Ljava/lang/Character; + public static final fun minOrNull ([D)Ljava/lang/Double; + public static final fun minOrNull ([F)Ljava/lang/Float; + public static final fun minOrNull ([I)Ljava/lang/Integer; + public static final fun minOrNull ([J)Ljava/lang/Long; + public static final fun minOrNull ([Ljava/lang/Comparable;)Ljava/lang/Comparable; + public static final fun minOrNull ([Ljava/lang/Double;)Ljava/lang/Double; + public static final fun minOrNull ([Ljava/lang/Float;)Ljava/lang/Float; + public static final fun minOrNull ([S)Ljava/lang/Short; public static final fun minWith ([BLjava/util/Comparator;)Ljava/lang/Byte; public static final fun minWith ([CLjava/util/Comparator;)Ljava/lang/Character; public static final fun minWith ([DLjava/util/Comparator;)Ljava/lang/Double; @@ -2195,11 +2215,17 @@ public final class kotlin/collections/CollectionsKt { public static final fun max (Ljava/lang/Iterable;)Ljava/lang/Double; public static final fun max (Ljava/lang/Iterable;)Ljava/lang/Float; public static final fun maxBy (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; + public static final fun maxOrNull (Ljava/lang/Iterable;)Ljava/lang/Comparable; + public static final fun maxOrNull (Ljava/lang/Iterable;)Ljava/lang/Double; + public static final fun maxOrNull (Ljava/lang/Iterable;)Ljava/lang/Float; public static final fun maxWith (Ljava/lang/Iterable;Ljava/util/Comparator;)Ljava/lang/Object; public static final fun min (Ljava/lang/Iterable;)Ljava/lang/Comparable; public static final fun min (Ljava/lang/Iterable;)Ljava/lang/Double; public static final fun min (Ljava/lang/Iterable;)Ljava/lang/Float; public static final fun minBy (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; + public static final fun minOrNull (Ljava/lang/Iterable;)Ljava/lang/Comparable; + public static final fun minOrNull (Ljava/lang/Iterable;)Ljava/lang/Double; + public static final fun minOrNull (Ljava/lang/Iterable;)Ljava/lang/Float; public static final fun minWith (Ljava/lang/Iterable;Ljava/util/Comparator;)Ljava/lang/Object; public static final fun minus (Ljava/lang/Iterable;Ljava/lang/Iterable;)Ljava/util/List; public static final fun minus (Ljava/lang/Iterable;Ljava/lang/Object;)Ljava/util/List; @@ -2615,6 +2641,10 @@ public final class kotlin/collections/unsigned/UArraysKt { public static final fun max-GBYM_sE ([B)Lkotlin/UByte; public static final fun max-QwZRm1k ([J)Lkotlin/ULong; public static final fun max-rL5Bavg ([S)Lkotlin/UShort; + public static final fun maxOrNull--ajY-9A ([I)Lkotlin/UInt; + public static final fun maxOrNull-GBYM_sE ([B)Lkotlin/UByte; + public static final fun maxOrNull-QwZRm1k ([J)Lkotlin/ULong; + public static final fun maxOrNull-rL5Bavg ([S)Lkotlin/UShort; public static final fun maxWith-XMRcp5o ([BLjava/util/Comparator;)Lkotlin/UByte; public static final fun maxWith-YmdZ_VM ([ILjava/util/Comparator;)Lkotlin/UInt; public static final fun maxWith-eOHTfZs ([SLjava/util/Comparator;)Lkotlin/UShort; @@ -2623,6 +2653,10 @@ public final class kotlin/collections/unsigned/UArraysKt { public static final fun min-GBYM_sE ([B)Lkotlin/UByte; public static final fun min-QwZRm1k ([J)Lkotlin/ULong; public static final fun min-rL5Bavg ([S)Lkotlin/UShort; + public static final fun minOrNull--ajY-9A ([I)Lkotlin/UInt; + public static final fun minOrNull-GBYM_sE ([B)Lkotlin/UByte; + public static final fun minOrNull-QwZRm1k ([J)Lkotlin/ULong; + public static final fun minOrNull-rL5Bavg ([S)Lkotlin/UShort; public static final fun minWith-XMRcp5o ([BLjava/util/Comparator;)Lkotlin/UByte; public static final fun minWith-YmdZ_VM ([ILjava/util/Comparator;)Lkotlin/UInt; public static final fun minWith-eOHTfZs ([SLjava/util/Comparator;)Lkotlin/UShort; @@ -4838,11 +4872,17 @@ public final class kotlin/sequences/SequencesKt { public static final fun max (Lkotlin/sequences/Sequence;)Ljava/lang/Double; public static final fun max (Lkotlin/sequences/Sequence;)Ljava/lang/Float; public static final fun maxBy (Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; + public static final fun maxOrNull (Lkotlin/sequences/Sequence;)Ljava/lang/Comparable; + public static final fun maxOrNull (Lkotlin/sequences/Sequence;)Ljava/lang/Double; + public static final fun maxOrNull (Lkotlin/sequences/Sequence;)Ljava/lang/Float; public static final fun maxWith (Lkotlin/sequences/Sequence;Ljava/util/Comparator;)Ljava/lang/Object; public static final fun min (Lkotlin/sequences/Sequence;)Ljava/lang/Comparable; public static final fun min (Lkotlin/sequences/Sequence;)Ljava/lang/Double; public static final fun min (Lkotlin/sequences/Sequence;)Ljava/lang/Float; public static final fun minBy (Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; + public static final fun minOrNull (Lkotlin/sequences/Sequence;)Ljava/lang/Comparable; + public static final fun minOrNull (Lkotlin/sequences/Sequence;)Ljava/lang/Double; + public static final fun minOrNull (Lkotlin/sequences/Sequence;)Ljava/lang/Float; public static final fun minWith (Lkotlin/sequences/Sequence;Ljava/util/Comparator;)Ljava/lang/Object; public static final fun minus (Lkotlin/sequences/Sequence;Ljava/lang/Iterable;)Lkotlin/sequences/Sequence; public static final fun minus (Lkotlin/sequences/Sequence;Ljava/lang/Object;)Lkotlin/sequences/Sequence; @@ -5241,9 +5281,11 @@ public final class kotlin/text/StringsKt { public static final fun mapTo (Ljava/lang/CharSequence;Ljava/util/Collection;Lkotlin/jvm/functions/Function1;)Ljava/util/Collection; public static final fun max (Ljava/lang/CharSequence;)Ljava/lang/Character; public static final fun maxBy (Ljava/lang/CharSequence;Lkotlin/jvm/functions/Function1;)Ljava/lang/Character; + public static final fun maxOrNull (Ljava/lang/CharSequence;)Ljava/lang/Character; public static final fun maxWith (Ljava/lang/CharSequence;Ljava/util/Comparator;)Ljava/lang/Character; public static final fun min (Ljava/lang/CharSequence;)Ljava/lang/Character; public static final fun minBy (Ljava/lang/CharSequence;Lkotlin/jvm/functions/Function1;)Ljava/lang/Character; + public static final fun minOrNull (Ljava/lang/CharSequence;)Ljava/lang/Character; public static final fun minWith (Ljava/lang/CharSequence;Ljava/util/Comparator;)Ljava/lang/Character; public static final fun none (Ljava/lang/CharSequence;)Z public static final fun none (Ljava/lang/CharSequence;Lkotlin/jvm/functions/Function1;)Z diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Aggregates.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Aggregates.kt index b3f7657311f..afc61dcdb3c 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Aggregates.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Aggregates.kt @@ -306,11 +306,11 @@ object Aggregates : TemplateGroupBase() { } - val f_minMax = run { + val f_minMax = sequence { val genericSpecializations = PrimitiveType.floatingPointPrimitives + setOf(null) - listOf("min", "max").map { op -> - fn("$op()") { + fun def(op: String, nullable: Boolean, orNull: String = "OrNull".ifOrEmpty(nullable)) = + fn("$op$orNull()") { include(Iterables, genericSpecializations) include(Sequences, genericSpecializations) include(ArraysOfObjects, genericSpecializations) @@ -318,19 +318,30 @@ object Aggregates : TemplateGroupBase() { include(ArraysOfUnsigned) include(CharSequences) } builder { - val isFloat = primitive?.isFloatingPoint() == true - val isGeneric = f in listOf(Iterables, Sequences, ArraysOfObjects) - typeParam("T : Comparable") - if (primitive != null) { - if (isFloat && isGeneric) + returns("T?") + + val isFloat = primitive?.isFloatingPoint() == true + + if (!nullable) { + deprecate(Deprecation("Use ${op}OrNull instead.", "${op}OrNull()", DeprecationLevel.WARNING)) + + val isGeneric = f in listOf(Iterables, Sequences, ArraysOfObjects) + if (isFloat && isGeneric) { since("1.1") + } + + body { "return ${op}OrNull()" } + + return@builder } + + since("1.4") + doc { "Returns the ${if (op == "max") "largest" else "smallest"} ${f.element} or `null` if there are no ${f.element.pluralize()}." + if (isFloat) "\n\n" + "If any of ${f.element.pluralize()} is `NaN` returns `NaN`." else "" } - returns("T?") val acc = op val cmpBlock = if (isFloat) @@ -361,7 +372,10 @@ object Aggregates : TemplateGroupBase() { """ } } - } + + for (op in listOf("min", "max")) + for (nullable in listOf(false, true)) + yield(def(op, nullable)) } val f_minBy = fn("minBy(selector: (T) -> R)") {