diff --git a/libraries/stdlib/common/src/generated/_UArrays.kt b/libraries/stdlib/common/src/generated/_UArrays.kt index 8858f0f299c..25172ca80f9 100644 --- a/libraries/stdlib/common/src/generated/_UArrays.kt +++ b/libraries/stdlib/common/src/generated/_UArrays.kt @@ -2176,7 +2176,6 @@ public inline fun UShortArray.copyOfRange(fromIndex: Int, toIndex: Int): UShortA */ @SinceKotlin("1.3") @ExperimentalUnsignedTypes -@kotlin.internal.InlineOnly public inline val UIntArray.indices: IntRange get() = storage.indices @@ -2185,7 +2184,6 @@ public inline val UIntArray.indices: IntRange */ @SinceKotlin("1.3") @ExperimentalUnsignedTypes -@kotlin.internal.InlineOnly public inline val ULongArray.indices: IntRange get() = storage.indices @@ -2194,7 +2192,6 @@ public inline val ULongArray.indices: IntRange */ @SinceKotlin("1.3") @ExperimentalUnsignedTypes -@kotlin.internal.InlineOnly public inline val UByteArray.indices: IntRange get() = storage.indices @@ -2203,7 +2200,6 @@ public inline val UByteArray.indices: IntRange */ @SinceKotlin("1.3") @ExperimentalUnsignedTypes -@kotlin.internal.InlineOnly public inline val UShortArray.indices: IntRange get() = storage.indices @@ -2212,7 +2208,6 @@ public inline val UShortArray.indices: IntRange */ @SinceKotlin("1.3") @ExperimentalUnsignedTypes -@kotlin.internal.InlineOnly public inline val UIntArray.lastIndex: Int get() = storage.lastIndex @@ -2221,7 +2216,6 @@ public inline val UIntArray.lastIndex: Int */ @SinceKotlin("1.3") @ExperimentalUnsignedTypes -@kotlin.internal.InlineOnly public inline val ULongArray.lastIndex: Int get() = storage.lastIndex @@ -2230,7 +2224,6 @@ public inline val ULongArray.lastIndex: Int */ @SinceKotlin("1.3") @ExperimentalUnsignedTypes -@kotlin.internal.InlineOnly public inline val UByteArray.lastIndex: Int get() = storage.lastIndex @@ -2239,7 +2232,6 @@ public inline val UByteArray.lastIndex: Int */ @SinceKotlin("1.3") @ExperimentalUnsignedTypes -@kotlin.internal.InlineOnly public inline val UShortArray.lastIndex: Int get() = storage.lastIndex @@ -2731,6 +2723,522 @@ public inline fun UShortArray.count(predicate: (UShort) -> Boolean): Int { return count } +/** + * Performs the given [action] on each element. + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UIntArray.forEach(action: (UInt) -> Unit): Unit { + for (element in this) action(element) +} + +/** + * Performs the given [action] on each element. + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun ULongArray.forEach(action: (ULong) -> Unit): Unit { + for (element in this) action(element) +} + +/** + * Performs the given [action] on each element. + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UByteArray.forEach(action: (UByte) -> Unit): Unit { + for (element in this) action(element) +} + +/** + * Performs the given [action] on each element. + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UShortArray.forEach(action: (UShort) -> Unit): Unit { + for (element in this) action(element) +} + +/** + * Performs the given [action] on each element, providing sequential index with the element. + * @param [action] function that takes the index of an element and the element itself + * and performs the desired action on the element. + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UIntArray.forEachIndexed(action: (index: Int, UInt) -> Unit): Unit { + var index = 0 + for (item in this) action(index++, item) +} + +/** + * Performs the given [action] on each element, providing sequential index with the element. + * @param [action] function that takes the index of an element and the element itself + * and performs the desired action on the element. + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun ULongArray.forEachIndexed(action: (index: Int, ULong) -> Unit): Unit { + var index = 0 + for (item in this) action(index++, item) +} + +/** + * Performs the given [action] on each element, providing sequential index with the element. + * @param [action] function that takes the index of an element and the element itself + * and performs the desired action on the element. + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UByteArray.forEachIndexed(action: (index: Int, UByte) -> Unit): Unit { + var index = 0 + for (item in this) action(index++, item) +} + +/** + * Performs the given [action] on each element, providing sequential index with the element. + * @param [action] function that takes the index of an element and the element itself + * and performs the desired action on the element. + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UShortArray.forEachIndexed(action: (index: Int, UShort) -> Unit): Unit { + var index = 0 + for (item in this) action(index++, item) +} + +/** + * Returns the largest element or `null` if there are no elements. + */ +@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 +} + +/** + * Returns the largest element or `null` if there are no elements. + */ +@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 +} + +/** + * Returns the largest element or `null` if there are no elements. + */ +@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 +} + +/** + * Returns the largest element or `null` if there are no elements. + */ +@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 +} + +/** + * Returns the first element yielding the largest value of the given function or `null` if there are no elements. + * + * @sample samples.collections.Collections.Aggregates.maxBy + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun > UIntArray.maxBy(selector: (UInt) -> R): UInt? { + if (isEmpty()) return null + var maxElem = this[0] + var maxValue = selector(maxElem) + for (i in 1..lastIndex) { + val e = this[i] + val v = selector(e) + if (maxValue < v) { + maxElem = e + maxValue = v + } + } + return maxElem +} + +/** + * Returns the first element yielding the largest value of the given function or `null` if there are no elements. + * + * @sample samples.collections.Collections.Aggregates.maxBy + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun > ULongArray.maxBy(selector: (ULong) -> R): ULong? { + if (isEmpty()) return null + var maxElem = this[0] + var maxValue = selector(maxElem) + for (i in 1..lastIndex) { + val e = this[i] + val v = selector(e) + if (maxValue < v) { + maxElem = e + maxValue = v + } + } + return maxElem +} + +/** + * Returns the first element yielding the largest value of the given function or `null` if there are no elements. + * + * @sample samples.collections.Collections.Aggregates.maxBy + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun > UByteArray.maxBy(selector: (UByte) -> R): UByte? { + if (isEmpty()) return null + var maxElem = this[0] + var maxValue = selector(maxElem) + for (i in 1..lastIndex) { + val e = this[i] + val v = selector(e) + if (maxValue < v) { + maxElem = e + maxValue = v + } + } + return maxElem +} + +/** + * Returns the first element yielding the largest value of the given function or `null` if there are no elements. + * + * @sample samples.collections.Collections.Aggregates.maxBy + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun > UShortArray.maxBy(selector: (UShort) -> R): UShort? { + if (isEmpty()) return null + var maxElem = this[0] + var maxValue = selector(maxElem) + for (i in 1..lastIndex) { + val e = this[i] + val v = selector(e) + if (maxValue < v) { + maxElem = e + maxValue = v + } + } + return maxElem +} + +/** + * Returns the first element having the largest value according to the provided [comparator] or `null` if there are no elements. + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +public fun UIntArray.maxWith(comparator: Comparator): UInt? { + if (isEmpty()) return null + var max = this[0] + for (i in 1..lastIndex) { + val e = this[i] + if (comparator.compare(max, e) < 0) max = e + } + return max +} + +/** + * Returns the first element having the largest value according to the provided [comparator] or `null` if there are no elements. + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +public fun ULongArray.maxWith(comparator: Comparator): ULong? { + if (isEmpty()) return null + var max = this[0] + for (i in 1..lastIndex) { + val e = this[i] + if (comparator.compare(max, e) < 0) max = e + } + return max +} + +/** + * Returns the first element having the largest value according to the provided [comparator] or `null` if there are no elements. + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +public fun UByteArray.maxWith(comparator: Comparator): UByte? { + if (isEmpty()) return null + var max = this[0] + for (i in 1..lastIndex) { + val e = this[i] + if (comparator.compare(max, e) < 0) max = e + } + return max +} + +/** + * Returns the first element having the largest value according to the provided [comparator] or `null` if there are no elements. + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +public fun UShortArray.maxWith(comparator: Comparator): UShort? { + if (isEmpty()) return null + var max = this[0] + for (i in 1..lastIndex) { + val e = this[i] + if (comparator.compare(max, e) < 0) max = e + } + return max +} + +/** + * Returns the smallest element or `null` if there are no elements. + */ +@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 +} + +/** + * Returns the smallest element or `null` if there are no elements. + */ +@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 +} + +/** + * Returns the smallest element or `null` if there are no elements. + */ +@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 +} + +/** + * Returns the smallest element or `null` if there are no elements. + */ +@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 +} + +/** + * Returns the first element yielding the smallest value of the given function or `null` if there are no elements. + * + * @sample samples.collections.Collections.Aggregates.minBy + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun > UIntArray.minBy(selector: (UInt) -> R): UInt? { + if (isEmpty()) return null + var minElem = this[0] + var minValue = selector(minElem) + for (i in 1..lastIndex) { + val e = this[i] + val v = selector(e) + if (minValue > v) { + minElem = e + minValue = v + } + } + return minElem +} + +/** + * Returns the first element yielding the smallest value of the given function or `null` if there are no elements. + * + * @sample samples.collections.Collections.Aggregates.minBy + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun > ULongArray.minBy(selector: (ULong) -> R): ULong? { + if (isEmpty()) return null + var minElem = this[0] + var minValue = selector(minElem) + for (i in 1..lastIndex) { + val e = this[i] + val v = selector(e) + if (minValue > v) { + minElem = e + minValue = v + } + } + return minElem +} + +/** + * Returns the first element yielding the smallest value of the given function or `null` if there are no elements. + * + * @sample samples.collections.Collections.Aggregates.minBy + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun > UByteArray.minBy(selector: (UByte) -> R): UByte? { + if (isEmpty()) return null + var minElem = this[0] + var minValue = selector(minElem) + for (i in 1..lastIndex) { + val e = this[i] + val v = selector(e) + if (minValue > v) { + minElem = e + minValue = v + } + } + return minElem +} + +/** + * Returns the first element yielding the smallest value of the given function or `null` if there are no elements. + * + * @sample samples.collections.Collections.Aggregates.minBy + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun > UShortArray.minBy(selector: (UShort) -> R): UShort? { + if (isEmpty()) return null + var minElem = this[0] + var minValue = selector(minElem) + for (i in 1..lastIndex) { + val e = this[i] + val v = selector(e) + if (minValue > v) { + minElem = e + minValue = v + } + } + return minElem +} + +/** + * Returns the first element having the smallest value according to the provided [comparator] or `null` if there are no elements. + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +public fun UIntArray.minWith(comparator: Comparator): UInt? { + if (isEmpty()) return null + var min = this[0] + for (i in 1..lastIndex) { + val e = this[i] + if (comparator.compare(min, e) > 0) min = e + } + return min +} + +/** + * Returns the first element having the smallest value according to the provided [comparator] or `null` if there are no elements. + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +public fun ULongArray.minWith(comparator: Comparator): ULong? { + if (isEmpty()) return null + var min = this[0] + for (i in 1..lastIndex) { + val e = this[i] + if (comparator.compare(min, e) > 0) min = e + } + return min +} + +/** + * Returns the first element having the smallest value according to the provided [comparator] or `null` if there are no elements. + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +public fun UByteArray.minWith(comparator: Comparator): UByte? { + if (isEmpty()) return null + var min = this[0] + for (i in 1..lastIndex) { + val e = this[i] + if (comparator.compare(min, e) > 0) min = e + } + return min +} + +/** + * Returns the first element having the smallest value according to the provided [comparator] or `null` if there are no elements. + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +public fun UShortArray.minWith(comparator: Comparator): UShort? { + if (isEmpty()) return null + var min = this[0] + for (i in 1..lastIndex) { + val e = this[i] + if (comparator.compare(min, e) > 0) min = e + } + return min +} + /** * Returns `true` if the array has no elements. * @@ -2831,6 +3339,290 @@ public inline fun UShortArray.none(predicate: (UShort) -> Boolean): Boolean { return true } +/** + * Accumulates value starting with the first element and applying [operation] from left to right to current accumulator value and each element. + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UIntArray.reduce(operation: (acc: UInt, UInt) -> UInt): UInt { + if (isEmpty()) + throw UnsupportedOperationException("Empty array can't be reduced.") + var accumulator = this[0] + for (index in 1..lastIndex) { + accumulator = operation(accumulator, this[index]) + } + return accumulator +} + +/** + * Accumulates value starting with the first element and applying [operation] from left to right to current accumulator value and each element. + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun ULongArray.reduce(operation: (acc: ULong, ULong) -> ULong): ULong { + if (isEmpty()) + throw UnsupportedOperationException("Empty array can't be reduced.") + var accumulator = this[0] + for (index in 1..lastIndex) { + accumulator = operation(accumulator, this[index]) + } + return accumulator +} + +/** + * Accumulates value starting with the first element and applying [operation] from left to right to current accumulator value and each element. + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UByteArray.reduce(operation: (acc: UByte, UByte) -> UByte): UByte { + if (isEmpty()) + throw UnsupportedOperationException("Empty array can't be reduced.") + var accumulator = this[0] + for (index in 1..lastIndex) { + accumulator = operation(accumulator, this[index]) + } + return accumulator +} + +/** + * Accumulates value starting with the first element and applying [operation] from left to right to current accumulator value and each element. + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UShortArray.reduce(operation: (acc: UShort, UShort) -> UShort): UShort { + if (isEmpty()) + throw UnsupportedOperationException("Empty array can't be reduced.") + var accumulator = this[0] + for (index in 1..lastIndex) { + accumulator = operation(accumulator, this[index]) + } + return accumulator +} + +/** + * Accumulates value starting with the first element and applying [operation] from left to right + * to current accumulator value and each element with its index in the original array. + * @param [operation] function that takes the index of an element, current accumulator value + * and the element itself and calculates the next accumulator value. + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UIntArray.reduceIndexed(operation: (index: Int, acc: UInt, UInt) -> UInt): UInt { + if (isEmpty()) + throw UnsupportedOperationException("Empty array can't be reduced.") + var accumulator = this[0] + for (index in 1..lastIndex) { + accumulator = operation(index, accumulator, this[index]) + } + return accumulator +} + +/** + * Accumulates value starting with the first element and applying [operation] from left to right + * to current accumulator value and each element with its index in the original array. + * @param [operation] function that takes the index of an element, current accumulator value + * and the element itself and calculates the next accumulator value. + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun ULongArray.reduceIndexed(operation: (index: Int, acc: ULong, ULong) -> ULong): ULong { + if (isEmpty()) + throw UnsupportedOperationException("Empty array can't be reduced.") + var accumulator = this[0] + for (index in 1..lastIndex) { + accumulator = operation(index, accumulator, this[index]) + } + return accumulator +} + +/** + * Accumulates value starting with the first element and applying [operation] from left to right + * to current accumulator value and each element with its index in the original array. + * @param [operation] function that takes the index of an element, current accumulator value + * and the element itself and calculates the next accumulator value. + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UByteArray.reduceIndexed(operation: (index: Int, acc: UByte, UByte) -> UByte): UByte { + if (isEmpty()) + throw UnsupportedOperationException("Empty array can't be reduced.") + var accumulator = this[0] + for (index in 1..lastIndex) { + accumulator = operation(index, accumulator, this[index]) + } + return accumulator +} + +/** + * Accumulates value starting with the first element and applying [operation] from left to right + * to current accumulator value and each element with its index in the original array. + * @param [operation] function that takes the index of an element, current accumulator value + * and the element itself and calculates the next accumulator value. + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UShortArray.reduceIndexed(operation: (index: Int, acc: UShort, UShort) -> UShort): UShort { + if (isEmpty()) + throw UnsupportedOperationException("Empty array can't be reduced.") + var accumulator = this[0] + for (index in 1..lastIndex) { + accumulator = operation(index, accumulator, this[index]) + } + return accumulator +} + +/** + * Accumulates value starting with last element and applying [operation] from right to left to each element and current accumulator value. + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UIntArray.reduceRight(operation: (UInt, acc: UInt) -> UInt): UInt { + var index = lastIndex + if (index < 0) throw UnsupportedOperationException("Empty array can't be reduced.") + var accumulator = get(index--) + while (index >= 0) { + accumulator = operation(get(index--), accumulator) + } + return accumulator +} + +/** + * Accumulates value starting with last element and applying [operation] from right to left to each element and current accumulator value. + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun ULongArray.reduceRight(operation: (ULong, acc: ULong) -> ULong): ULong { + var index = lastIndex + if (index < 0) throw UnsupportedOperationException("Empty array can't be reduced.") + var accumulator = get(index--) + while (index >= 0) { + accumulator = operation(get(index--), accumulator) + } + return accumulator +} + +/** + * Accumulates value starting with last element and applying [operation] from right to left to each element and current accumulator value. + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UByteArray.reduceRight(operation: (UByte, acc: UByte) -> UByte): UByte { + var index = lastIndex + if (index < 0) throw UnsupportedOperationException("Empty array can't be reduced.") + var accumulator = get(index--) + while (index >= 0) { + accumulator = operation(get(index--), accumulator) + } + return accumulator +} + +/** + * Accumulates value starting with last element and applying [operation] from right to left to each element and current accumulator value. + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UShortArray.reduceRight(operation: (UShort, acc: UShort) -> UShort): UShort { + var index = lastIndex + if (index < 0) throw UnsupportedOperationException("Empty array can't be reduced.") + var accumulator = get(index--) + while (index >= 0) { + accumulator = operation(get(index--), accumulator) + } + return accumulator +} + +/** + * Accumulates value starting with last element and applying [operation] from right to left + * to each element with its index in the original array and current accumulator value. + * @param [operation] function that takes the index of an element, the element itself + * and current accumulator value, and calculates the next accumulator value. + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UIntArray.reduceRightIndexed(operation: (index: Int, UInt, acc: UInt) -> UInt): UInt { + var index = lastIndex + if (index < 0) throw UnsupportedOperationException("Empty array can't be reduced.") + var accumulator = get(index--) + while (index >= 0) { + accumulator = operation(index, get(index), accumulator) + --index + } + return accumulator +} + +/** + * Accumulates value starting with last element and applying [operation] from right to left + * to each element with its index in the original array and current accumulator value. + * @param [operation] function that takes the index of an element, the element itself + * and current accumulator value, and calculates the next accumulator value. + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun ULongArray.reduceRightIndexed(operation: (index: Int, ULong, acc: ULong) -> ULong): ULong { + var index = lastIndex + if (index < 0) throw UnsupportedOperationException("Empty array can't be reduced.") + var accumulator = get(index--) + while (index >= 0) { + accumulator = operation(index, get(index), accumulator) + --index + } + return accumulator +} + +/** + * Accumulates value starting with last element and applying [operation] from right to left + * to each element with its index in the original array and current accumulator value. + * @param [operation] function that takes the index of an element, the element itself + * and current accumulator value, and calculates the next accumulator value. + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UByteArray.reduceRightIndexed(operation: (index: Int, UByte, acc: UByte) -> UByte): UByte { + var index = lastIndex + if (index < 0) throw UnsupportedOperationException("Empty array can't be reduced.") + var accumulator = get(index--) + while (index >= 0) { + accumulator = operation(index, get(index), accumulator) + --index + } + return accumulator +} + +/** + * Accumulates value starting with last element and applying [operation] from right to left + * to each element with its index in the original array and current accumulator value. + * @param [operation] function that takes the index of an element, the element itself + * and current accumulator value, and calculates the next accumulator value. + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UShortArray.reduceRightIndexed(operation: (index: Int, UShort, acc: UShort) -> UShort): UShort { + var index = lastIndex + if (index < 0) throw UnsupportedOperationException("Empty array can't be reduced.") + var accumulator = get(index--) + while (index >= 0) { + accumulator = operation(index, get(index), accumulator) + --index + } + return accumulator +} + /** * Returns the sum of all values produced by [selector] function applied to each element in the array. */ diff --git a/libraries/stdlib/test/collections/UnsignedArraysTest.kt b/libraries/stdlib/test/collections/UnsignedArraysTest.kt index c324527799a..1b7cc8af9d6 100644 --- a/libraries/stdlib/test/collections/UnsignedArraysTest.kt +++ b/libraries/stdlib/test/collections/UnsignedArraysTest.kt @@ -411,4 +411,161 @@ class UnsignedArraysTest { assertFailsWith(exClass, bounds) { ushortArrayOf(1).sliceArray(range) } } } + + @Test + fun min() { + expect(null) { arrayOf().min() } + expect(1u) { arrayOf(1).min() } + expect(2u) { arrayOf(2, 3).min() } + expect(2uL) { arrayOf(3, 2).min() } + } + + @Test + fun minInUnsignedArrays() { + expect(null) { ubyteArrayOf().min() } + expect(1u) { ushortArrayOf(1).min() } + expect(2u) { uintArrayOf(2, 3).min() } + expect(2uL) { ulongArrayOf(3, 2).min() } + } + + @Test + fun max() { + expect(null) { arrayOf().max() } + expect(1u) { arrayOf(1).max() } + expect(3u) { arrayOf(2, 3).max() } + expect(3uL) { arrayOf(3, 2).max() } + } + + @Test + fun maxInUnsignedArrays() { + expect(null) { ubyteArrayOf().max() } + expect(1u) { ushortArrayOf(1).max() } + expect(3u) { uintArrayOf(2, 3).max() } + expect(3uL) { ulongArrayOf(3, 2).max() } + } + + @Test + fun minWith() { + expect(null) { arrayOf().minWith(naturalOrder()) } + expect(1u) { arrayOf(1).minWith(naturalOrder()) } + expect(2u) { arrayOf(2, 3).minWith(naturalOrder()) } + expect(2uL) { arrayOf(3, 2).minWith(naturalOrder()) } + } + + @Test + fun minWithInUnsignedArrays() { + expect(null) { ubyteArrayOf().minWith(reverseOrder()) } + expect(1u) { ushortArrayOf(1).minWith(reverseOrder()) } + expect(3u) { uintArrayOf(2, 3).minWith(reverseOrder()) } + expect(3uL) { ulongArrayOf(3, 2).minWith(reverseOrder()) } + } + + @Test + fun maxWith() { + expect(null) { arrayOf().maxWith(naturalOrder()) } + expect(1u) { arrayOf(1).maxWith(naturalOrder()) } + expect(3u) { arrayOf(2, 3).maxWith(naturalOrder()) } + expect(3uL) { arrayOf(3, 2).maxWith(naturalOrder()) } + } + + @Test + fun maxWithInUnsignedArrays() { + expect(null) { ubyteArrayOf().maxWith(reverseOrder()) } + expect(1u) { ushortArrayOf(1).maxWith(reverseOrder()) } + expect(2u) { uintArrayOf(2, 3).maxWith(reverseOrder()) } + expect(2uL) { ulongArrayOf(3, 2).maxWith(reverseOrder()) } + } + + @Test + fun minBy() { + expect(null) { arrayOf().minBy { it * it } } + expect(1u) { arrayOf(1).minBy { it * it } } + expect(2u) { arrayOf(2, 3).minBy { it * it } } + expect(3uL) { arrayOf(3, 2).minBy { it - 3 } } + } + + @Test + fun minByInUnsignedArrays() { + expect(null) { ubyteArrayOf().minBy { it * it } } + expect(1u) { ushortArrayOf(1).minBy { it * it } } + expect(2u) { uintArrayOf(2, 3).minBy { it * it } } + expect(3uL) { ulongArrayOf(3, 2).minBy { it - 3 } } + } + + @Test + fun maxBy() { + expect(null) { arrayOf().maxBy { it + 1 } } + expect(1u) { arrayOf(1).maxBy { it + 1 } } + expect(2u) { arrayOf(2, 3).maxBy { it - 3 } } + expect(3uL) { arrayOf(3, 2).maxBy { it + 1 } } + } + + @Test + fun maxByInUnsignedArrays() { + expect(null) { ubyteArrayOf().maxBy { it + 1 } } + expect(1u) { ushortArrayOf(1).maxBy { it + 1 } } + expect(2u) { uintArrayOf(2, 3).maxBy { it - 3 } } + expect(3uL) { ulongArrayOf(3, 2).maxBy { it + 1 } } + } + + @Test + fun reduce() { + expect(0u) { ubyteArrayOf(3, 2, 1).reduce { acc, e -> (acc - e).toUByte() } } + expect(0u) { ushortArrayOf(3, 2, 1).reduce { acc, e -> (acc - e).toUShort() } } + expect((-4).toUInt()) { uintArrayOf(1, 2, 3).reduce { acc, e -> acc - e } } + expect((-4).toULong()) { ulongArrayOf(1, 2, 3).reduce { acc, e -> acc - e } } + + assertFailsWith { + uintArrayOf().reduce { acc, e -> acc + e } + } + } + + @Test + fun reduceIndexed() { + expect(1u) { ubyteArrayOf(3, 2, 1).reduceIndexed { index, acc, e -> if (index != 2) (e - acc).toUByte() else e } } + expect(1u) { ushortArrayOf(3, 2, 1).reduceIndexed { index, acc, e -> if (index != 2) (e - acc).toUShort() else e } } + expect(UInt.MAX_VALUE) { uintArrayOf(1, 2, 3).reduceIndexed { index, acc, e -> index.toUInt() + acc - e } } + expect(ULong.MAX_VALUE) { ulongArrayOf(1, 2, 3).reduceIndexed { index, acc, e -> index.toULong() + acc - e } } + + assertFailsWith { + uintArrayOf().reduceIndexed { index, acc, e -> index.toUInt() + e + acc } + } + } + + @Test + fun reduceRight() { + expect(2u) { ubyteArrayOf(1, 2, 3).reduceRight { e, acc -> (e - acc).toUByte() } } + expect(2u) { ushortArrayOf(1, 2, 3).reduceRight { e, acc -> (e - acc).toUShort() } } + expect(2u) { uintArrayOf(1, 2, 3).reduceRight { e, acc -> e - acc } } + expect(2uL) { ulongArrayOf(1, 2, 3).reduceRight { e, acc -> e - acc } } + + assertFailsWith { + uintArrayOf().reduceRight { e, acc -> e + acc } + } + } + + @Test + fun reduceRightIndexed() { + expect(1u) { ubyteArrayOf(3, 2, 1).reduceRightIndexed { index, e, acc -> if (index != 1) (e - acc).toUByte() else e } } + expect(1u) { ushortArrayOf(3, 2, 1).reduceRightIndexed { index, e, acc -> if (index != 1) (e - acc).toUShort() else e } } + expect(1u) { uintArrayOf(1, 2, 3).reduceRightIndexed { index, e, acc -> index.toUInt() + e - acc } } + expect(1uL) { ulongArrayOf(1, 2, 3).reduceRightIndexed { index, e, acc -> index.toULong() + e - acc } } + + assertFailsWith { + uintArrayOf().reduceRightIndexed { index, e, acc -> index.toUInt() + e + acc } + } + } + + @Test + fun forEach() { + var i = 0 + val a = ubyteArrayOf(3, 2, 1) + a.forEach { e -> assertEquals(e, a[i++]) } + } + + @Test + fun forEachIndexed() { + val a = ubyteArrayOf(3, 2, 1) + a.forEachIndexed { index, e -> assertEquals(e, a[index]) } + } } \ No newline at end of file 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 b584d687250..919d16d31ce 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 @@ -2323,6 +2323,14 @@ public final class kotlin/collections/UArraysKt { public static final fun firstOrNull-GBYM_sE ([B)Lkotlin/UByte; public static final fun firstOrNull-QwZRm1k ([J)Lkotlin/ULong; public static final fun firstOrNull-rL5Bavg ([S)Lkotlin/UShort; + public static final fun getIndices--ajY-9A ([I)Lkotlin/ranges/IntRange; + public static final fun getIndices-GBYM_sE ([B)Lkotlin/ranges/IntRange; + public static final fun getIndices-QwZRm1k ([J)Lkotlin/ranges/IntRange; + public static final fun getIndices-rL5Bavg ([S)Lkotlin/ranges/IntRange; + public static final fun getLastIndex--ajY-9A ([I)I + public static final fun getLastIndex-GBYM_sE ([B)I + public static final fun getLastIndex-QwZRm1k ([J)I + public static final fun getLastIndex-rL5Bavg ([S)I public static final fun getOrNull-PpDY95g ([BI)Lkotlin/UByte; public static final fun getOrNull-nggk6HY ([SI)Lkotlin/UShort; public static final fun getOrNull-qFRl0hI ([II)Lkotlin/UInt; @@ -2331,6 +2339,22 @@ public final class kotlin/collections/UArraysKt { public static final fun lastOrNull-GBYM_sE ([B)Lkotlin/UByte; public static final fun lastOrNull-QwZRm1k ([J)Lkotlin/ULong; public static final fun lastOrNull-rL5Bavg ([S)Lkotlin/UShort; + public static final fun max--ajY-9A ([I)Lkotlin/UInt; + 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 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; + public static final fun maxWith-zrEWJaI ([JLjava/util/Comparator;)Lkotlin/ULong; + public static final fun min--ajY-9A ([I)Lkotlin/UInt; + 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 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; + public static final fun minWith-zrEWJaI ([JLjava/util/Comparator;)Lkotlin/ULong; public static final fun plus-CFIt9YE ([ILjava/util/Collection;)[I public static final fun plus-kzHmqpY ([JLjava/util/Collection;)[J public static final fun plus-ojwP5H8 ([SLjava/util/Collection;)[S diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Aggregates.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Aggregates.kt index e97ce2bf527..2931291430a 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Aggregates.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Aggregates.kt @@ -276,6 +276,7 @@ object Aggregates : TemplateGroupBase() { include(Sequences, genericSpecializations) include(ArraysOfObjects, genericSpecializations) include(ArraysOfPrimitives, PrimitiveType.defaultPrimitives - PrimitiveType.Boolean) + include(ArraysOfUnsigned) include(CharSequences) } builder { val isFloat = primitive?.isFloatingPoint() == true @@ -307,7 +308,7 @@ object Aggregates : TemplateGroupBase() { return $op """ } - body(ArraysOfObjects, ArraysOfPrimitives, CharSequences) { + body(ArraysOfObjects, ArraysOfPrimitives, CharSequences, ArraysOfUnsigned) { """ if (isEmpty()) return null var $op = this[0] @@ -330,9 +331,11 @@ object Aggregates : TemplateGroupBase() { val f_minBy = fn("minBy(selector: (T) -> R)") { includeDefault() - include(Maps, CharSequences) + include(Maps, CharSequences, ArraysOfUnsigned) } builder { inline() + specialFor(ArraysOfUnsigned) { inlineOnly() } + doc { "Returns the first ${f.element} yielding the smallest value of the given function or `null` if there are no ${f.element.pluralize()}." } sample("samples.collections.Collections.Aggregates.minBy") typeParam("R : Comparable") @@ -355,7 +358,7 @@ object Aggregates : TemplateGroupBase() { return minElem """ } - body(CharSequences, ArraysOfObjects, ArraysOfPrimitives) { + body(CharSequences, ArraysOfObjects, ArraysOfPrimitives, ArraysOfUnsigned) { """ if (isEmpty()) return null @@ -379,7 +382,7 @@ object Aggregates : TemplateGroupBase() { val f_minWith = fn("minWith(comparator: Comparator)") { includeDefault() - include(Maps, CharSequences) + include(Maps, CharSequences, ArraysOfUnsigned) } builder { doc { "Returns the first ${f.element} having the smallest value according to the provided [comparator] or `null` if there are no ${f.element.pluralize()}." } returns("T?") @@ -396,7 +399,7 @@ object Aggregates : TemplateGroupBase() { return min """ } - body(CharSequences, ArraysOfObjects, ArraysOfPrimitives) { + body(CharSequences, ArraysOfObjects, ArraysOfPrimitives, ArraysOfUnsigned) { """ if (isEmpty()) return null var min = this[0] @@ -412,9 +415,10 @@ object Aggregates : TemplateGroupBase() { val f_maxBy = fn("maxBy(selector: (T) -> R)") { includeDefault() - include(Maps, CharSequences) + include(Maps, CharSequences, ArraysOfUnsigned) } builder { inline() + specialFor(ArraysOfUnsigned) { inlineOnly() } doc { "Returns the first ${f.element} yielding the largest value of the given function or `null` if there are no ${f.element.pluralize()}." } sample("samples.collections.Collections.Aggregates.maxBy") @@ -438,7 +442,7 @@ object Aggregates : TemplateGroupBase() { return maxElem """ } - body(CharSequences, ArraysOfObjects, ArraysOfPrimitives) { + body(CharSequences, ArraysOfObjects, ArraysOfPrimitives, ArraysOfUnsigned) { """ if (isEmpty()) return null @@ -463,7 +467,7 @@ object Aggregates : TemplateGroupBase() { val f_maxWith = fn("maxWith(comparator: Comparator)") { includeDefault() - include(Maps, CharSequences) + include(Maps, CharSequences, ArraysOfUnsigned) } builder { doc { "Returns the first ${f.element} having the largest value according to the provided [comparator] or `null` if there are no ${f.element.pluralize()}." } returns("T?") @@ -480,7 +484,7 @@ object Aggregates : TemplateGroupBase() { return max """ } - body(CharSequences, ArraysOfObjects, ArraysOfPrimitives) { + body(CharSequences, ArraysOfObjects, ArraysOfPrimitives, ArraysOfUnsigned) { """ if (isEmpty()) return null @@ -614,9 +618,10 @@ object Aggregates : TemplateGroupBase() { } val f_reduceIndexed = fn("reduceIndexed(operation: (index: Int, acc: T, T) -> T)") { - include(ArraysOfPrimitives, CharSequences) + include(ArraysOfPrimitives, ArraysOfUnsigned, CharSequences) } builder { inline() + specialFor(ArraysOfUnsigned) { inlineOnly() } doc { """ @@ -686,9 +691,10 @@ object Aggregates : TemplateGroupBase() { } val f_reduceRightIndexed = fn("reduceRightIndexed(operation: (index: Int, T, acc: T) -> T)") { - include(CharSequences, ArraysOfPrimitives) + include(CharSequences, ArraysOfPrimitives, ArraysOfUnsigned) } builder { inline() + specialFor(ArraysOfUnsigned) { inlineOnly() } doc { """ @@ -763,9 +769,10 @@ object Aggregates : TemplateGroupBase() { } val f_reduce = fn("reduce(operation: (acc: T, T) -> T)") { - include(ArraysOfPrimitives, CharSequences) + include(ArraysOfPrimitives, ArraysOfUnsigned, CharSequences) } builder { inline() + specialFor(ArraysOfUnsigned) { inlineOnly() } doc { "Accumulates value starting with the first ${f.element} and applying [operation] from left to right to current accumulator value and each ${f.element}." } returns("T") @@ -819,9 +826,10 @@ object Aggregates : TemplateGroupBase() { } val f_reduceRight = fn("reduceRight(operation: (T, acc: T) -> T)") { - include(CharSequences, ArraysOfPrimitives) + include(CharSequences, ArraysOfPrimitives, ArraysOfUnsigned) } builder { inline() + specialFor(ArraysOfUnsigned) { inlineOnly() } doc { "Accumulates value starting with last ${f.element} and applying [operation] from right to left to each ${f.element} and current accumulator value." } returns("T") @@ -885,7 +893,7 @@ object Aggregates : TemplateGroupBase() { specialFor(Iterables, Maps, CharSequences) { inline() doc { "Performs the given [action] on each ${f.element} and returns the ${f.collection} itself afterwards." } - val collectionType = when(f) { + val collectionType = when (f) { Maps -> "M" CharSequences -> "S" else -> "C" @@ -914,9 +922,10 @@ object Aggregates : TemplateGroupBase() { val f_forEach = fn("forEach(action: (T) -> Unit)") { includeDefault() - include(Maps, CharSequences) + include(Maps, CharSequences, ArraysOfUnsigned) } builder { inline() + specialFor(ArraysOfUnsigned) { inlineOnly() } doc { "Performs the given [action] on each ${f.element}." } specialFor(Iterables, Maps) { annotation("@kotlin.internal.HidesMembers") } @@ -930,9 +939,11 @@ object Aggregates : TemplateGroupBase() { val f_forEachIndexed = fn("forEachIndexed(action: (index: Int, T) -> Unit)") { includeDefault() - include(CharSequences) + include(CharSequences, ArraysOfUnsigned) } builder { inline() + specialFor(ArraysOfUnsigned) { inlineOnly() } + doc { """ Performs the given [action] on each ${f.element}, providing sequential index with the ${f.element}. diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Arrays.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Arrays.kt index bd15dabc081..ffda824e4bb 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Arrays.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Arrays.kt @@ -52,7 +52,12 @@ object ArrayOps : TemplateGroupBase() { "get() = size - 1" } specialFor(ArraysOfUnsigned) { - inlineOnly() + // TODO: Make inlineOnly after KT-30185 is fixed. + // InlineOnly properties currently are not inlined and may lead to IllegalAccessException + // when accessed from an inline (or inlineOnly) method. + // It is because the method body contains access call to inlineOnly property in nonpublic multifile part, + // which may be inaccessible from method call site, where method body gets inlined. + inline() body { "get() = storage.lastIndex" } } } @@ -66,7 +71,12 @@ object ArrayOps : TemplateGroupBase() { "get() = IntRange(0, lastIndex)" } specialFor(ArraysOfUnsigned) { - inlineOnly() + // TODO: Make inlineOnly after KT-30185 is fixed. + // InlineOnly properties currently are not inlined and may lead to IllegalAccessException + // when accessed from an inline (or inlineOnly) method. + // It is because the method body contains access call to inlineOnly property in nonpublic multifile part, + // which may be inaccessible from method call site, where method body gets inlined. + inline() body { "get() = storage.indices" } } }