Implement sum extension function for UArrays (KT-28779)
This commit is contained in:
committed by
Ilya Gorbunov
parent
690e35f11a
commit
7695b5e575
@@ -128,6 +128,7 @@ val reducedRuntimeSources = fullRuntimeSources - listOfKtFilesFrom(
|
||||
"libraries/stdlib/common/src/generated/_UArrays.kt",
|
||||
"libraries/stdlib/common/src/generated/_URanges.kt",
|
||||
"libraries/stdlib/common/src/generated/_UCollections.kt",
|
||||
"libraries/stdlib/common/src/generated/_USequences.kt",
|
||||
"libraries/stdlib/common/src/kotlin/SequencesH.kt",
|
||||
"libraries/stdlib/common/src/kotlin/TextH.kt",
|
||||
"libraries/stdlib/common/src/kotlin/collections/",
|
||||
|
||||
@@ -3735,3 +3735,99 @@ public inline fun UShortArray.sumByDouble(selector: (UShort) -> Double): Double
|
||||
return sum
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sum of all elements in the array.
|
||||
*/
|
||||
@kotlin.jvm.JvmName("sumOfUInt")
|
||||
@SinceKotlin("1.3")
|
||||
@ExperimentalUnsignedTypes
|
||||
public fun Array<out UInt>.sum(): UInt {
|
||||
var sum: UInt = 0u
|
||||
for (element in this) {
|
||||
sum += element
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sum of all elements in the array.
|
||||
*/
|
||||
@kotlin.jvm.JvmName("sumOfULong")
|
||||
@SinceKotlin("1.3")
|
||||
@ExperimentalUnsignedTypes
|
||||
public fun Array<out ULong>.sum(): ULong {
|
||||
var sum: ULong = 0uL
|
||||
for (element in this) {
|
||||
sum += element
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sum of all elements in the array.
|
||||
*/
|
||||
@kotlin.jvm.JvmName("sumOfUByte")
|
||||
@SinceKotlin("1.3")
|
||||
@ExperimentalUnsignedTypes
|
||||
public fun Array<out UByte>.sum(): UInt {
|
||||
var sum: UInt = 0u
|
||||
for (element in this) {
|
||||
sum += element
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sum of all elements in the array.
|
||||
*/
|
||||
@kotlin.jvm.JvmName("sumOfUShort")
|
||||
@SinceKotlin("1.3")
|
||||
@ExperimentalUnsignedTypes
|
||||
public fun Array<out UShort>.sum(): UInt {
|
||||
var sum: UInt = 0u
|
||||
for (element in this) {
|
||||
sum += element
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sum of all elements in the array.
|
||||
*/
|
||||
@SinceKotlin("1.3")
|
||||
@ExperimentalUnsignedTypes
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline fun UIntArray.sum(): UInt {
|
||||
return storage.sum().toUInt()
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sum of all elements in the array.
|
||||
*/
|
||||
@SinceKotlin("1.3")
|
||||
@ExperimentalUnsignedTypes
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline fun ULongArray.sum(): ULong {
|
||||
return storage.sum().toULong()
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sum of all elements in the array.
|
||||
*/
|
||||
@SinceKotlin("1.3")
|
||||
@ExperimentalUnsignedTypes
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline fun UByteArray.sum(): UInt {
|
||||
return sumBy { it.toUInt() }
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sum of all elements in the array.
|
||||
*/
|
||||
@SinceKotlin("1.3")
|
||||
@ExperimentalUnsignedTypes
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline fun UShortArray.sum(): UInt {
|
||||
return sumBy { it.toUInt() }
|
||||
}
|
||||
|
||||
|
||||
@@ -67,3 +67,59 @@ public fun Collection<UShort>.toUShortArray(): UShortArray {
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sum of all elements in the collection.
|
||||
*/
|
||||
@kotlin.jvm.JvmName("sumOfUInt")
|
||||
@SinceKotlin("1.3")
|
||||
@ExperimentalUnsignedTypes
|
||||
public fun Iterable<UInt>.sum(): UInt {
|
||||
var sum: UInt = 0u
|
||||
for (element in this) {
|
||||
sum += element
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sum of all elements in the collection.
|
||||
*/
|
||||
@kotlin.jvm.JvmName("sumOfULong")
|
||||
@SinceKotlin("1.3")
|
||||
@ExperimentalUnsignedTypes
|
||||
public fun Iterable<ULong>.sum(): ULong {
|
||||
var sum: ULong = 0uL
|
||||
for (element in this) {
|
||||
sum += element
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sum of all elements in the collection.
|
||||
*/
|
||||
@kotlin.jvm.JvmName("sumOfUByte")
|
||||
@SinceKotlin("1.3")
|
||||
@ExperimentalUnsignedTypes
|
||||
public fun Iterable<UByte>.sum(): UInt {
|
||||
var sum: UInt = 0u
|
||||
for (element in this) {
|
||||
sum += element
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sum of all elements in the collection.
|
||||
*/
|
||||
@kotlin.jvm.JvmName("sumOfUShort")
|
||||
@SinceKotlin("1.3")
|
||||
@ExperimentalUnsignedTypes
|
||||
public fun Iterable<UShort>.sum(): UInt {
|
||||
var sum: UInt = 0u
|
||||
for (element in this) {
|
||||
sum += element
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@file:kotlin.jvm.JvmMultifileClass
|
||||
@file:kotlin.jvm.JvmName("USequencesKt")
|
||||
|
||||
package kotlin.sequences
|
||||
|
||||
//
|
||||
// NOTE: THIS FILE IS AUTO-GENERATED by the GenerateStandardLib.kt
|
||||
// See: https://github.com/JetBrains/kotlin/tree/master/libraries/stdlib
|
||||
//
|
||||
|
||||
import kotlin.random.*
|
||||
|
||||
/**
|
||||
* Returns the sum of all elements in the sequence.
|
||||
*
|
||||
* The operation is _terminal_.
|
||||
*/
|
||||
@kotlin.jvm.JvmName("sumOfUInt")
|
||||
@SinceKotlin("1.3")
|
||||
@ExperimentalUnsignedTypes
|
||||
public fun Sequence<UInt>.sum(): UInt {
|
||||
var sum: UInt = 0u
|
||||
for (element in this) {
|
||||
sum += element
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sum of all elements in the sequence.
|
||||
*
|
||||
* The operation is _terminal_.
|
||||
*/
|
||||
@kotlin.jvm.JvmName("sumOfULong")
|
||||
@SinceKotlin("1.3")
|
||||
@ExperimentalUnsignedTypes
|
||||
public fun Sequence<ULong>.sum(): ULong {
|
||||
var sum: ULong = 0uL
|
||||
for (element in this) {
|
||||
sum += element
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sum of all elements in the sequence.
|
||||
*
|
||||
* The operation is _terminal_.
|
||||
*/
|
||||
@kotlin.jvm.JvmName("sumOfUByte")
|
||||
@SinceKotlin("1.3")
|
||||
@ExperimentalUnsignedTypes
|
||||
public fun Sequence<UByte>.sum(): UInt {
|
||||
var sum: UInt = 0u
|
||||
for (element in this) {
|
||||
sum += element
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sum of all elements in the sequence.
|
||||
*
|
||||
* The operation is _terminal_.
|
||||
*/
|
||||
@kotlin.jvm.JvmName("sumOfUShort")
|
||||
@SinceKotlin("1.3")
|
||||
@ExperimentalUnsignedTypes
|
||||
public fun Sequence<UShort>.sum(): UInt {
|
||||
var sum: UInt = 0u
|
||||
for (element in this) {
|
||||
sum += element
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
@@ -568,4 +568,20 @@ class UnsignedArraysTest {
|
||||
val a = ubyteArrayOf(3, 2, 1)
|
||||
a.forEachIndexed { index, e -> assertEquals(e, a[index]) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun sum() {
|
||||
expect(14u) { arrayOf(2u, 3u, 9u).asSequence().sum() }
|
||||
expect(400u) { arrayOf<UByte>(200u, 200u).asList().sum() }
|
||||
expect(50000u) { arrayOf<UShort>(20000u, 30000u).asIterable().sum() }
|
||||
expect(12_000_000_000_000_000_000uL) { arrayOf(10_000_000_000_000_000_000uL, 2_000_000_000_000_000_000uL).sum() }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun sumInUnsignedArrays() {
|
||||
expect(14u) { uintArrayOf(2u, 3u, 9u).sum() }
|
||||
expect(400u) { ubyteArrayOf(200u, 200u).sum() }
|
||||
expect(50000u) { ushortArrayOf(20000u, 30000u).sum() }
|
||||
expect(12_000_000_000_000_000_000uL) { ulongArrayOf(10_000_000_000_000_000_000uL, 2_000_000_000_000_000_000uL).sum() }
|
||||
}
|
||||
}
|
||||
+15
@@ -2387,6 +2387,10 @@ public final class kotlin/collections/UArraysKt {
|
||||
public static final fun sliceArray-ojwP5H8 ([SLjava/util/Collection;)[S
|
||||
public static final fun sliceArray-tAntMlw ([ILkotlin/ranges/IntRange;)[I
|
||||
public static final fun sliceArray-xo_DsdI ([BLjava/util/Collection;)[B
|
||||
public static final fun sumOfUByte ([Lkotlin/UByte;)I
|
||||
public static final fun sumOfUInt ([Lkotlin/UInt;)I
|
||||
public static final fun sumOfULong ([Lkotlin/ULong;)J
|
||||
public static final fun sumOfUShort ([Lkotlin/UShort;)I
|
||||
public static final fun toTypedArray--ajY-9A ([I)[Lkotlin/UInt;
|
||||
public static final fun toTypedArray-GBYM_sE ([B)[Lkotlin/UByte;
|
||||
public static final fun toTypedArray-QwZRm1k ([J)[Lkotlin/ULong;
|
||||
@@ -2406,6 +2410,10 @@ public abstract class kotlin/collections/UByteIterator : java/util/Iterator, kot
|
||||
}
|
||||
|
||||
public final class kotlin/collections/UCollectionsKt {
|
||||
public static final fun sumOfUByte (Ljava/lang/Iterable;)I
|
||||
public static final fun sumOfUInt (Ljava/lang/Iterable;)I
|
||||
public static final fun sumOfULong (Ljava/lang/Iterable;)J
|
||||
public static final fun sumOfUShort (Ljava/lang/Iterable;)I
|
||||
public static final fun toUByteArray (Ljava/util/Collection;)[B
|
||||
public static final fun toUIntArray (Ljava/util/Collection;)[I
|
||||
public static final fun toULongArray (Ljava/util/Collection;)[J
|
||||
@@ -4566,6 +4574,13 @@ public final class kotlin/sequences/SequencesKt {
|
||||
public static final fun zipWithNext (Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function2;)Lkotlin/sequences/Sequence;
|
||||
}
|
||||
|
||||
public final class kotlin/sequences/USequencesKt {
|
||||
public static final fun sumOfUByte (Lkotlin/sequences/Sequence;)I
|
||||
public static final fun sumOfUInt (Lkotlin/sequences/Sequence;)I
|
||||
public static final fun sumOfULong (Lkotlin/sequences/Sequence;)J
|
||||
public static final fun sumOfUShort (Lkotlin/sequences/Sequence;)I
|
||||
}
|
||||
|
||||
public final class kotlin/system/TimingKt {
|
||||
public static final fun measureNanoTime (Lkotlin/jvm/functions/Function0;)J
|
||||
public static final fun measureTimeMillis (Lkotlin/jvm/functions/Function0;)J
|
||||
|
||||
@@ -968,7 +968,7 @@ object ArrayOps : TemplateGroupBase() {
|
||||
PrimitiveType.Char ->
|
||||
body { "return withType(\"CharArray\", fillFrom(this, ${primitive}Array(newSize)))" }
|
||||
PrimitiveType.Long ->
|
||||
body { "return withType(\"LongArray\", arrayCopyResize(this, newSize, ZERO))" }
|
||||
body { "return withType(\"LongArray\", arrayCopyResize(this, newSize, ${primitive!!.zero()}))" }
|
||||
else ->
|
||||
body { "return fillFrom(this, ${primitive}Array(newSize))" }
|
||||
}
|
||||
|
||||
@@ -5,31 +5,65 @@
|
||||
|
||||
package templates
|
||||
|
||||
import templates.Family.*
|
||||
|
||||
object Numeric : TemplateGroupBase() {
|
||||
|
||||
init {
|
||||
defaultBuilder {
|
||||
sequenceClassification(SequenceClass.terminal)
|
||||
specialFor(ArraysOfUnsigned) {
|
||||
since("1.3")
|
||||
annotation("@ExperimentalUnsignedTypes")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val numericPrimitivesDefaultOrder = PrimitiveType.defaultPrimitives intersect PrimitiveType.numericPrimitives
|
||||
private val summablePrimitives = numericPrimitivesDefaultOrder + PrimitiveType.unsignedPrimitives
|
||||
|
||||
val f_sum = fn("sum()") {
|
||||
Family.defaultFamilies.forEach { family -> include(family, numericPrimitivesDefaultOrder) }
|
||||
listOf(Iterables, Sequences, ArraysOfObjects).forEach { include(it, summablePrimitives) }
|
||||
include(ArraysOfPrimitives, numericPrimitivesDefaultOrder)
|
||||
include(ArraysOfUnsigned)
|
||||
} builder {
|
||||
val p = primitive!!
|
||||
|
||||
doc { "Returns the sum of all elements in the ${f.collection}." }
|
||||
returns("SUM")
|
||||
platformName("sumOf<T>")
|
||||
body {
|
||||
"""
|
||||
var sum: SUM = ZERO
|
||||
for (element in this) {
|
||||
sum += element
|
||||
returns(p.sumType().name)
|
||||
|
||||
specialFor(ArraysOfUnsigned) {
|
||||
inlineOnly()
|
||||
|
||||
body {
|
||||
if (p == p.sumType())
|
||||
"return storage.sum().to${p.sumType().name}()"
|
||||
else
|
||||
"return sumBy { it.to${p.sumType().name}() }"
|
||||
}
|
||||
}
|
||||
specialFor(Iterables, Sequences, ArraysOfObjects, ArraysOfPrimitives) {
|
||||
platformName("sumOf<T>")
|
||||
|
||||
if (p.isUnsigned()) {
|
||||
require(f != ArraysOfPrimitives) { "Arrays of unsigneds are separate from arrays of primitives." }
|
||||
specialFor(Iterables) { sourceFile(SourceFile.UCollections) }
|
||||
specialFor(Sequences) { sourceFile(SourceFile.USequences) }
|
||||
specialFor(ArraysOfObjects) { sourceFile(SourceFile.UArrays) }
|
||||
|
||||
since("1.3")
|
||||
annotation("@ExperimentalUnsignedTypes")
|
||||
}
|
||||
|
||||
body {
|
||||
"""
|
||||
var sum: ${p.sumType().name} = ${p.sumType().zero()}
|
||||
for (element in this) {
|
||||
sum += element
|
||||
}
|
||||
return sum
|
||||
"""
|
||||
}
|
||||
return sum
|
||||
"""
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -75,6 +75,22 @@ enum class PrimitiveType {
|
||||
fun PrimitiveType.isIntegral(): Boolean = this in PrimitiveType.integralPrimitives
|
||||
fun PrimitiveType.isNumeric(): Boolean = this in PrimitiveType.numericPrimitives
|
||||
fun PrimitiveType.isFloatingPoint(): Boolean = this in PrimitiveType.floatingPointPrimitives
|
||||
fun PrimitiveType.isUnsigned(): Boolean = this in PrimitiveType.unsignedPrimitives
|
||||
|
||||
fun PrimitiveType.sumType() = when (this) {
|
||||
PrimitiveType.Byte, PrimitiveType.Short, PrimitiveType.Char -> PrimitiveType.Int
|
||||
PrimitiveType.UByte, PrimitiveType.UShort -> PrimitiveType.UInt
|
||||
else -> this
|
||||
}
|
||||
|
||||
fun PrimitiveType.zero() = when (this) {
|
||||
PrimitiveType.Double -> "0.0"
|
||||
PrimitiveType.Float -> "0.0f"
|
||||
PrimitiveType.Long -> "0L"
|
||||
PrimitiveType.ULong -> "0uL"
|
||||
in PrimitiveType.unsignedPrimitives -> "0u"
|
||||
else -> "0"
|
||||
}
|
||||
|
||||
enum class Inline {
|
||||
No,
|
||||
|
||||
@@ -194,28 +194,19 @@ class MemberBuilder(
|
||||
"RECEIVER" -> receiver
|
||||
"SELF" -> self
|
||||
"PRIMITIVE" -> primitive?.name ?: token
|
||||
"SUM" -> {
|
||||
when (primitive) {
|
||||
PrimitiveType.Byte, PrimitiveType.Short, PrimitiveType.Char -> "Int"
|
||||
else -> primitive
|
||||
}
|
||||
}
|
||||
"ZERO" -> when (primitive) {
|
||||
PrimitiveType.Double -> "0.0"
|
||||
PrimitiveType.Float -> "0.0f"
|
||||
PrimitiveType.Long -> "0L"
|
||||
else -> "0"
|
||||
}
|
||||
"ONE" -> when (primitive) {
|
||||
PrimitiveType.Double -> "1.0"
|
||||
PrimitiveType.Float -> "1.0f"
|
||||
PrimitiveType.Long -> "1L"
|
||||
PrimitiveType.ULong -> "1uL"
|
||||
in PrimitiveType.unsignedPrimitives -> "1u"
|
||||
else -> "1"
|
||||
}
|
||||
"-ONE" -> when (primitive) {
|
||||
PrimitiveType.Double -> "-1.0"
|
||||
PrimitiveType.Float -> "-1.0f"
|
||||
PrimitiveType.Long -> "-1L"
|
||||
in PrimitiveType.unsignedPrimitives -> error("-ONE is not in the domain of unsigned primitives")
|
||||
else -> "-1"
|
||||
}
|
||||
"TCollection" -> {
|
||||
|
||||
@@ -14,6 +14,7 @@ enum class SourceFile(jvmClassName: String? = null, val multifile: Boolean = tru
|
||||
Sets(packageName = "kotlin.collections"),
|
||||
Maps(packageName = "kotlin.collections"),
|
||||
Sequences(packageName = "kotlin.sequences"),
|
||||
USequences(packageName = "kotlin.sequences"),
|
||||
Ranges(packageName = "kotlin.ranges"),
|
||||
URanges(packageName = "kotlin.ranges"),
|
||||
Comparisons(packageName = "kotlin.comparisons"),
|
||||
|
||||
Reference in New Issue
Block a user