diff --git a/libraries/stdlib/common/src/generated/_UArrays.kt b/libraries/stdlib/common/src/generated/_UArrays.kt index 709fbad1c78..a8929bdf2a2 100644 --- a/libraries/stdlib/common/src/generated/_UArrays.kt +++ b/libraries/stdlib/common/src/generated/_UArrays.kt @@ -1259,3 +1259,415 @@ public inline fun ShortArray.toUShortArray(): UShortArray { return UShortArray(this.copyOf()) } +/** + * Returns `true` if all elements match the given [predicate]. + * + * @sample samples.collections.Collections.Aggregates.all + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UIntArray.all(predicate: (UInt) -> Boolean): Boolean { + for (element in this) if (!predicate(element)) return false + return true +} + +/** + * Returns `true` if all elements match the given [predicate]. + * + * @sample samples.collections.Collections.Aggregates.all + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun ULongArray.all(predicate: (ULong) -> Boolean): Boolean { + for (element in this) if (!predicate(element)) return false + return true +} + +/** + * Returns `true` if all elements match the given [predicate]. + * + * @sample samples.collections.Collections.Aggregates.all + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UByteArray.all(predicate: (UByte) -> Boolean): Boolean { + for (element in this) if (!predicate(element)) return false + return true +} + +/** + * Returns `true` if all elements match the given [predicate]. + * + * @sample samples.collections.Collections.Aggregates.all + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UShortArray.all(predicate: (UShort) -> Boolean): Boolean { + for (element in this) if (!predicate(element)) return false + return true +} + +/** + * Returns `true` if array has at least one element. + * + * @sample samples.collections.Collections.Aggregates.any + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UIntArray.any(): Boolean { + return storage.any() +} + +/** + * Returns `true` if array has at least one element. + * + * @sample samples.collections.Collections.Aggregates.any + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun ULongArray.any(): Boolean { + return storage.any() +} + +/** + * Returns `true` if array has at least one element. + * + * @sample samples.collections.Collections.Aggregates.any + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UByteArray.any(): Boolean { + return storage.any() +} + +/** + * Returns `true` if array has at least one element. + * + * @sample samples.collections.Collections.Aggregates.any + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UShortArray.any(): Boolean { + return storage.any() +} + +/** + * Returns `true` if at least one element matches the given [predicate]. + * + * @sample samples.collections.Collections.Aggregates.anyWithPredicate + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UIntArray.any(predicate: (UInt) -> Boolean): Boolean { + for (element in this) if (predicate(element)) return true + return false +} + +/** + * Returns `true` if at least one element matches the given [predicate]. + * + * @sample samples.collections.Collections.Aggregates.anyWithPredicate + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun ULongArray.any(predicate: (ULong) -> Boolean): Boolean { + for (element in this) if (predicate(element)) return true + return false +} + +/** + * Returns `true` if at least one element matches the given [predicate]. + * + * @sample samples.collections.Collections.Aggregates.anyWithPredicate + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UByteArray.any(predicate: (UByte) -> Boolean): Boolean { + for (element in this) if (predicate(element)) return true + return false +} + +/** + * Returns `true` if at least one element matches the given [predicate]. + * + * @sample samples.collections.Collections.Aggregates.anyWithPredicate + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UShortArray.any(predicate: (UShort) -> Boolean): Boolean { + for (element in this) if (predicate(element)) return true + return false +} + +/** + * Returns the number of elements matching the given [predicate]. + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UIntArray.count(predicate: (UInt) -> Boolean): Int { + var count = 0 + for (element in this) if (predicate(element)) ++count + return count +} + +/** + * Returns the number of elements matching the given [predicate]. + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun ULongArray.count(predicate: (ULong) -> Boolean): Int { + var count = 0 + for (element in this) if (predicate(element)) ++count + return count +} + +/** + * Returns the number of elements matching the given [predicate]. + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UByteArray.count(predicate: (UByte) -> Boolean): Int { + var count = 0 + for (element in this) if (predicate(element)) ++count + return count +} + +/** + * Returns the number of elements matching the given [predicate]. + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UShortArray.count(predicate: (UShort) -> Boolean): Int { + var count = 0 + for (element in this) if (predicate(element)) ++count + return count +} + +/** + * Returns `true` if the array has no elements. + * + * @sample samples.collections.Collections.Aggregates.none + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UIntArray.none(): Boolean { + return isEmpty() +} + +/** + * Returns `true` if the array has no elements. + * + * @sample samples.collections.Collections.Aggregates.none + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun ULongArray.none(): Boolean { + return isEmpty() +} + +/** + * Returns `true` if the array has no elements. + * + * @sample samples.collections.Collections.Aggregates.none + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UByteArray.none(): Boolean { + return isEmpty() +} + +/** + * Returns `true` if the array has no elements. + * + * @sample samples.collections.Collections.Aggregates.none + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UShortArray.none(): Boolean { + return isEmpty() +} + +/** + * Returns `true` if no elements match the given [predicate]. + * + * @sample samples.collections.Collections.Aggregates.noneWithPredicate + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UIntArray.none(predicate: (UInt) -> Boolean): Boolean { + for (element in this) if (predicate(element)) return false + return true +} + +/** + * Returns `true` if no elements match the given [predicate]. + * + * @sample samples.collections.Collections.Aggregates.noneWithPredicate + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun ULongArray.none(predicate: (ULong) -> Boolean): Boolean { + for (element in this) if (predicate(element)) return false + return true +} + +/** + * Returns `true` if no elements match the given [predicate]. + * + * @sample samples.collections.Collections.Aggregates.noneWithPredicate + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UByteArray.none(predicate: (UByte) -> Boolean): Boolean { + for (element in this) if (predicate(element)) return false + return true +} + +/** + * Returns `true` if no elements match the given [predicate]. + * + * @sample samples.collections.Collections.Aggregates.noneWithPredicate + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UShortArray.none(predicate: (UShort) -> Boolean): Boolean { + for (element in this) if (predicate(element)) return false + return true +} + +/** + * Returns the sum of all values produced by [selector] function applied to each element in the array. + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UIntArray.sumBy(selector: (UInt) -> UInt): UInt { + var sum: UInt = 0u + for (element in this) { + sum += selector(element) + } + return sum +} + +/** + * Returns the sum of all values produced by [selector] function applied to each element in the array. + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun ULongArray.sumBy(selector: (ULong) -> UInt): UInt { + var sum: UInt = 0u + for (element in this) { + sum += selector(element) + } + return sum +} + +/** + * Returns the sum of all values produced by [selector] function applied to each element in the array. + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UByteArray.sumBy(selector: (UByte) -> UInt): UInt { + var sum: UInt = 0u + for (element in this) { + sum += selector(element) + } + return sum +} + +/** + * Returns the sum of all values produced by [selector] function applied to each element in the array. + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UShortArray.sumBy(selector: (UShort) -> UInt): UInt { + var sum: UInt = 0u + for (element in this) { + sum += selector(element) + } + return sum +} + +/** + * Returns the sum of all values produced by [selector] function applied to each element in the array. + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UIntArray.sumByDouble(selector: (UInt) -> Double): Double { + var sum: Double = 0.0 + for (element in this) { + sum += selector(element) + } + return sum +} + +/** + * Returns the sum of all values produced by [selector] function applied to each element in the array. + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun ULongArray.sumByDouble(selector: (ULong) -> Double): Double { + var sum: Double = 0.0 + for (element in this) { + sum += selector(element) + } + return sum +} + +/** + * Returns the sum of all values produced by [selector] function applied to each element in the array. + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UByteArray.sumByDouble(selector: (UByte) -> Double): Double { + var sum: Double = 0.0 + for (element in this) { + sum += selector(element) + } + return sum +} + +/** + * Returns the sum of all values produced by [selector] function applied to each element in the array. + */ +@SinceKotlin("1.3") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UShortArray.sumByDouble(selector: (UShort) -> Double): Double { + var sum: Double = 0.0 + for (element in this) { + sum += selector(element) + } + return sum +} + diff --git a/libraries/stdlib/test/collections/UnsignedArraysTest.kt b/libraries/stdlib/test/collections/UnsignedArraysTest.kt index ae31cc1b961..d714934d09e 100644 --- a/libraries/stdlib/test/collections/UnsignedArraysTest.kt +++ b/libraries/stdlib/test/collections/UnsignedArraysTest.kt @@ -285,4 +285,53 @@ class UnsignedArraysTest { expect(1) { uintArrayOf(1, 2).lastIndex } expect(2) { ulongArrayOf(1, 2, 3).lastIndex } } + + @Test + fun all() { + assertTrue(ubyteArrayOf(0, 1, 2).all { it < 3 }) + assertFalse(ushortArrayOf(0, 1, 2).all { it % 2u == 0u }) + assertTrue(uintArrayOf(0, 2, 4).all { it % 2u == 0u }) + assertTrue(ulongArrayOf(2, 3, 4).all { it > 1 }) + } + + @Test + fun none() { + assertTrue(ubyteArrayOf(0, 1, 2).none { it > 2 }) + assertFalse(ushortArrayOf(0, 1, 2).none { it % 2u == 0u }) + assertTrue(uintArrayOf(0, 2, 4).none { it % 2u != 0u }) + assertTrue(ulongArrayOf(2, 3, 4).none { it < 2 }) + } + + @Test + fun any() { + assertTrue(ubyteArrayOf(0, 1, 2).any { it >= 2 }) + assertFalse(ushortArrayOf(0, 1, 2).any { it == 5.toUShort() }) + assertTrue(uintArrayOf(0, 2, 4).any { it % 3u == 1u }) + assertTrue(ulongArrayOf(2, 3, 4).any { it % 3u == 0.toULong() }) + } + + @Test + fun count() { + assertEquals(1, ubyteArrayOf(0, 1, 2).count { it >= 2 }) + assertEquals(2, ushortArrayOf(0, 1, 2).count { it % 2u == 0u }) + assertEquals(0, uintArrayOf(0, 2, 4).count { it % 2u != 0u }) + assertEquals(3, ulongArrayOf(2, 3, 4).count { it > 1 }) + } + + @Test + fun sumBy() { + assertEquals(3u, ubyteArrayOf(0, 1, 2).sumBy { it.toUInt() }) + assertEquals(1u, ushortArrayOf(0, 1, 2).sumBy { it % 2u }) + assertEquals(0u, uintArrayOf(0, 2, 4).sumBy { it % 2u }) + assertEquals(6u, ulongArrayOf(2, 3, 4).sumBy { (it - 1u).toUInt() }) + } + + @Test + fun sumByDouble() { + // TODO: .toInt().toDouble() -> .toDouble() when conversion from unsigned primitives to Double gets implemented. + assertEquals(3.0, ubyteArrayOf(0, 1, 2).sumByDouble { it.toInt().toDouble() }) + assertEquals(1.0, ushortArrayOf(0, 1, 2).sumByDouble { (it % 2u).toInt().toDouble() }) + assertEquals(0.0, uintArrayOf(0, 2, 4).sumByDouble { (it % 2u).toInt().toDouble() }) + assertEquals(6.0, ulongArrayOf(2, 3, 4).sumByDouble { (it - 1u).toInt().toDouble() }) + } } \ No newline at end of file diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Aggregates.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Aggregates.kt index cc22806e145..e97ce2bf527 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Aggregates.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Aggregates.kt @@ -15,14 +15,20 @@ object Aggregates : TemplateGroupBase() { if (sequenceClassification.isEmpty()) { sequenceClassification(terminal) } + specialFor(ArraysOfUnsigned) { + since("1.3") + annotation("@ExperimentalUnsignedTypes") + } } } val f_all = fn("all(predicate: (T) -> Boolean)") { includeDefault() - include(Maps, CharSequences) + include(Maps, CharSequences, ArraysOfUnsigned) } builder { inline() + specialFor(ArraysOfUnsigned) { inlineOnly() } + doc { """ Returns `true` if all ${f.element.pluralize()} match the given [predicate]. @@ -45,9 +51,10 @@ object Aggregates : TemplateGroupBase() { val f_none_predicate = fn("none(predicate: (T) -> Boolean)") { includeDefault() - include(Maps, CharSequences) + include(Maps, CharSequences, ArraysOfUnsigned) } builder { inline() + specialFor(ArraysOfUnsigned) { inlineOnly() } doc { """ @@ -71,8 +78,10 @@ object Aggregates : TemplateGroupBase() { val f_none = fn("none()") { includeDefault() - include(Maps, CharSequences) + include(Maps, CharSequences, ArraysOfUnsigned) } builder { + specialFor(ArraysOfUnsigned) { inlineOnly() } + doc { """ Returns `true` if the ${f.collection} has no ${f.element.pluralize()}. @@ -91,16 +100,18 @@ object Aggregates : TemplateGroupBase() { """ } } - specialFor(Maps, CharSequences, ArraysOfObjects, ArraysOfPrimitives) { - body { "return isEmpty()" } + + body(Maps, CharSequences, ArraysOfObjects, ArraysOfPrimitives, ArraysOfUnsigned) { + "return isEmpty()" } } val f_any_predicate = fn("any(predicate: (T) -> Boolean)") { includeDefault() - include(Maps, CharSequences) + include(Maps, CharSequences, ArraysOfUnsigned) } builder { inline() + specialFor(ArraysOfUnsigned) { inlineOnly() } doc { """ @@ -124,7 +135,7 @@ object Aggregates : TemplateGroupBase() { val f_any = fn("any()") { includeDefault() - include(Maps, CharSequences) + include(Maps, CharSequences, ArraysOfUnsigned) } builder { doc { """ @@ -143,14 +154,20 @@ object Aggregates : TemplateGroupBase() { """ } body(Maps, CharSequences, ArraysOfObjects, ArraysOfPrimitives) { "return !isEmpty()" } + + specialFor(ArraysOfUnsigned) { + inlineOnly() + body { "return storage.any()" } + } } val f_count_predicate = fn("count(predicate: (T) -> Boolean)") { includeDefault() - include(Maps, CharSequences) + include(Maps, CharSequences, ArraysOfUnsigned) } builder { inline() + specialFor(ArraysOfUnsigned) { inlineOnly() } doc { "Returns the number of ${f.element.pluralize()} matching the given [predicate]." } returns("Int") @@ -184,19 +201,21 @@ object Aggregates : TemplateGroupBase() { return count """ } - specialFor(CharSequences, Maps, Collections, ArraysOfObjects, ArraysOfPrimitives) { inlineOnly() } + + specialFor(CharSequences, Maps, Collections, ArraysOfObjects, ArraysOfPrimitives, ArraysOfUnsigned) { inlineOnly() } + specialFor(CharSequences) { doc { "Returns the length of this char sequence." } body { "return length" } } - specialFor(Maps, Collections, ArraysOfObjects, ArraysOfPrimitives) { - body { "return size" } + body(Maps, Collections, ArraysOfObjects, ArraysOfPrimitives, ArraysOfUnsigned) { + "return size" } } val f_sumBy = fn("sumBy(selector: (T) -> Int)") { includeDefault() - include(CharSequences) + include(CharSequences, ArraysOfUnsigned) } builder { inline() doc { "Returns the sum of all values produced by [selector] function applied to each ${f.element} in the ${f.collection}." } @@ -210,13 +229,30 @@ object Aggregates : TemplateGroupBase() { return sum """ } + + specialFor(ArraysOfUnsigned) { + inlineOnly() + signature("sumBy(selector: (T) -> UInt)") + returns("UInt") + body { + """ + var sum: UInt = 0u + for (element in this) { + sum += selector(element) + } + return sum + """ + } + } } val f_sumByDouble = fn("sumByDouble(selector: (T) -> Double)") { includeDefault() - include(CharSequences) + include(CharSequences, ArraysOfUnsigned) } builder { inline() + specialFor(ArraysOfUnsigned) { inlineOnly() } + doc { "Returns the sum of all values produced by [selector] function applied to each ${f.element} in the ${f.collection}." } returns("Double") body {