Implement sum extension function for UArrays (KT-28779)

This commit is contained in:
Abduqodiri Qurbonzoda
2019-01-22 21:19:38 +03:00
committed by Ilya Gorbunov
parent 690e35f11a
commit 7695b5e575
11 changed files with 330 additions and 23 deletions
@@ -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() }
}
}
@@ -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"),