diff --git a/libraries/stdlib/common/src/generated/_Arrays.kt b/libraries/stdlib/common/src/generated/_Arrays.kt index 726f805023c..e9b3cf0a42d 100644 --- a/libraries/stdlib/common/src/generated/_Arrays.kt +++ b/libraries/stdlib/common/src/generated/_Arrays.kt @@ -2418,6 +2418,195 @@ public fun CharArray.random(random: Random): Char { return get(random.nextInt(size)) } +/** + * Returns a random element from this array, or `null` if this array is empty. + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@kotlin.internal.InlineOnly +public inline fun Array.randomOrNull(): T? { + return randomOrNull(Random) +} + +/** + * Returns a random element from this array, or `null` if this array is empty. + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@kotlin.internal.InlineOnly +public inline fun ByteArray.randomOrNull(): Byte? { + return randomOrNull(Random) +} + +/** + * Returns a random element from this array, or `null` if this array is empty. + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@kotlin.internal.InlineOnly +public inline fun ShortArray.randomOrNull(): Short? { + return randomOrNull(Random) +} + +/** + * Returns a random element from this array, or `null` if this array is empty. + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@kotlin.internal.InlineOnly +public inline fun IntArray.randomOrNull(): Int? { + return randomOrNull(Random) +} + +/** + * Returns a random element from this array, or `null` if this array is empty. + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@kotlin.internal.InlineOnly +public inline fun LongArray.randomOrNull(): Long? { + return randomOrNull(Random) +} + +/** + * Returns a random element from this array, or `null` if this array is empty. + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@kotlin.internal.InlineOnly +public inline fun FloatArray.randomOrNull(): Float? { + return randomOrNull(Random) +} + +/** + * Returns a random element from this array, or `null` if this array is empty. + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@kotlin.internal.InlineOnly +public inline fun DoubleArray.randomOrNull(): Double? { + return randomOrNull(Random) +} + +/** + * Returns a random element from this array, or `null` if this array is empty. + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@kotlin.internal.InlineOnly +public inline fun BooleanArray.randomOrNull(): Boolean? { + return randomOrNull(Random) +} + +/** + * Returns a random element from this array, or `null` if this array is empty. + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@kotlin.internal.InlineOnly +public inline fun CharArray.randomOrNull(): Char? { + return randomOrNull(Random) +} + +/** + * Returns a random element from this array using the specified source of randomness, or `null` if this array is empty. + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +public fun Array.randomOrNull(random: Random): T? { + if (isEmpty()) + return null + return get(random.nextInt(size)) +} + +/** + * Returns a random element from this array using the specified source of randomness, or `null` if this array is empty. + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +public fun ByteArray.randomOrNull(random: Random): Byte? { + if (isEmpty()) + return null + return get(random.nextInt(size)) +} + +/** + * Returns a random element from this array using the specified source of randomness, or `null` if this array is empty. + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +public fun ShortArray.randomOrNull(random: Random): Short? { + if (isEmpty()) + return null + return get(random.nextInt(size)) +} + +/** + * Returns a random element from this array using the specified source of randomness, or `null` if this array is empty. + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +public fun IntArray.randomOrNull(random: Random): Int? { + if (isEmpty()) + return null + return get(random.nextInt(size)) +} + +/** + * Returns a random element from this array using the specified source of randomness, or `null` if this array is empty. + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +public fun LongArray.randomOrNull(random: Random): Long? { + if (isEmpty()) + return null + return get(random.nextInt(size)) +} + +/** + * Returns a random element from this array using the specified source of randomness, or `null` if this array is empty. + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +public fun FloatArray.randomOrNull(random: Random): Float? { + if (isEmpty()) + return null + return get(random.nextInt(size)) +} + +/** + * Returns a random element from this array using the specified source of randomness, or `null` if this array is empty. + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +public fun DoubleArray.randomOrNull(random: Random): Double? { + if (isEmpty()) + return null + return get(random.nextInt(size)) +} + +/** + * Returns a random element from this array using the specified source of randomness, or `null` if this array is empty. + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +public fun BooleanArray.randomOrNull(random: Random): Boolean? { + if (isEmpty()) + return null + return get(random.nextInt(size)) +} + +/** + * Returns a random element from this array using the specified source of randomness, or `null` if this array is empty. + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +public fun CharArray.randomOrNull(random: Random): Char? { + if (isEmpty()) + return null + return get(random.nextInt(size)) +} + /** * Returns the single element, or throws an exception if the array is empty or has more than one element. */ diff --git a/libraries/stdlib/common/src/generated/_Collections.kt b/libraries/stdlib/common/src/generated/_Collections.kt index 852693918e8..163cc625697 100644 --- a/libraries/stdlib/common/src/generated/_Collections.kt +++ b/libraries/stdlib/common/src/generated/_Collections.kt @@ -501,6 +501,27 @@ public fun Collection.random(random: Random): T { return elementAt(random.nextInt(size)) } +/** + * Returns a random element from this collection, or `null` if this collection is empty. + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@kotlin.internal.InlineOnly +public inline fun Collection.randomOrNull(): T? { + return randomOrNull(Random) +} + +/** + * Returns a random element from this collection using the specified source of randomness, or `null` if this collection is empty. + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +public fun Collection.randomOrNull(random: Random): T? { + if (isEmpty()) + return null + return elementAt(random.nextInt(size)) +} + /** * Returns the single element, or throws an exception if the collection is empty or has more than one element. */ diff --git a/libraries/stdlib/common/src/generated/_Ranges.kt b/libraries/stdlib/common/src/generated/_Ranges.kt index 87af4c7589e..5812d1cb4d6 100644 --- a/libraries/stdlib/common/src/generated/_Ranges.kt +++ b/libraries/stdlib/common/src/generated/_Ranges.kt @@ -90,6 +90,69 @@ public fun CharRange.random(random: Random): Char { } } +/** + * Returns a random element from this range, or `null` if this range is empty. + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@kotlin.internal.InlineOnly +public inline fun IntRange.randomOrNull(): Int? { + return randomOrNull(Random) +} + +/** + * Returns a random element from this range, or `null` if this range is empty. + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@kotlin.internal.InlineOnly +public inline fun LongRange.randomOrNull(): Long? { + return randomOrNull(Random) +} + +/** + * Returns a random element from this range, or `null` if this range is empty. + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@kotlin.internal.InlineOnly +public inline fun CharRange.randomOrNull(): Char? { + return randomOrNull(Random) +} + +/** + * Returns a random element from this range using the specified source of randomness, or `null` if this range is empty. + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +public fun IntRange.randomOrNull(random: Random): Int? { + if (isEmpty()) + return null + return random.nextInt(this) +} + +/** + * Returns a random element from this range using the specified source of randomness, or `null` if this range is empty. + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +public fun LongRange.randomOrNull(random: Random): Long? { + if (isEmpty()) + return null + return random.nextLong(this) +} + +/** + * Returns a random element from this range using the specified source of randomness, or `null` if this range is empty. + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +public fun CharRange.randomOrNull(random: Random): Char? { + if (isEmpty()) + return null + return random.nextInt(first.toInt(), last.toInt() + 1).toChar() +} + /** * Returns `true` if this range contains the specified [element]. * diff --git a/libraries/stdlib/common/src/generated/_Strings.kt b/libraries/stdlib/common/src/generated/_Strings.kt index 7d25eca6f33..032096c754c 100644 --- a/libraries/stdlib/common/src/generated/_Strings.kt +++ b/libraries/stdlib/common/src/generated/_Strings.kt @@ -194,6 +194,27 @@ public fun CharSequence.random(random: Random): Char { return get(random.nextInt(length)) } +/** + * Returns a random character from this char sequence, or `null` if this char sequence is empty. + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@kotlin.internal.InlineOnly +public inline fun CharSequence.randomOrNull(): Char? { + return randomOrNull(Random) +} + +/** + * Returns a random character from this char sequence using the specified source of randomness, or `null` if this char sequence is empty. + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +public fun CharSequence.randomOrNull(random: Random): Char? { + if (isEmpty()) + return null + return get(random.nextInt(length)) +} + /** * Returns the single character, or throws an exception if the char sequence is empty or has more than one character. */ diff --git a/libraries/stdlib/common/src/generated/_UArrays.kt b/libraries/stdlib/common/src/generated/_UArrays.kt index fef105de02e..399192c9bd4 100644 --- a/libraries/stdlib/common/src/generated/_UArrays.kt +++ b/libraries/stdlib/common/src/generated/_UArrays.kt @@ -1194,6 +1194,98 @@ public fun UShortArray.random(random: Random): UShort { return get(random.nextInt(size)) } +/** + * Returns a random element from this array, or `null` if this array is empty. + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UIntArray.randomOrNull(): UInt? { + return randomOrNull(Random) +} + +/** + * Returns a random element from this array, or `null` if this array is empty. + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun ULongArray.randomOrNull(): ULong? { + return randomOrNull(Random) +} + +/** + * Returns a random element from this array, or `null` if this array is empty. + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UByteArray.randomOrNull(): UByte? { + return randomOrNull(Random) +} + +/** + * Returns a random element from this array, or `null` if this array is empty. + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UShortArray.randomOrNull(): UShort? { + return randomOrNull(Random) +} + +/** + * Returns a random element from this array using the specified source of randomness, or `null` if this array is empty. + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@ExperimentalUnsignedTypes +public fun UIntArray.randomOrNull(random: Random): UInt? { + if (isEmpty()) + return null + return get(random.nextInt(size)) +} + +/** + * Returns a random element from this array using the specified source of randomness, or `null` if this array is empty. + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@ExperimentalUnsignedTypes +public fun ULongArray.randomOrNull(random: Random): ULong? { + if (isEmpty()) + return null + return get(random.nextInt(size)) +} + +/** + * Returns a random element from this array using the specified source of randomness, or `null` if this array is empty. + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@ExperimentalUnsignedTypes +public fun UByteArray.randomOrNull(random: Random): UByte? { + if (isEmpty()) + return null + return get(random.nextInt(size)) +} + +/** + * Returns a random element from this array using the specified source of randomness, or `null` if this array is empty. + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@ExperimentalUnsignedTypes +public fun UShortArray.randomOrNull(random: Random): UShort? { + if (isEmpty()) + return null + return get(random.nextInt(size)) +} + /** * Returns the single element, or throws an exception if the array is empty or has more than one element. */ diff --git a/libraries/stdlib/common/src/generated/_URanges.kt b/libraries/stdlib/common/src/generated/_URanges.kt index 8febb476654..97c123a82a6 100644 --- a/libraries/stdlib/common/src/generated/_URanges.kt +++ b/libraries/stdlib/common/src/generated/_URanges.kt @@ -69,6 +69,52 @@ public fun ULongRange.random(random: Random): ULong { } } +/** + * Returns a random element from this range, or `null` if this range is empty. + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UIntRange.randomOrNull(): UInt? { + return randomOrNull(Random) +} + +/** + * Returns a random element from this range, or `null` if this range is empty. + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun ULongRange.randomOrNull(): ULong? { + return randomOrNull(Random) +} + +/** + * Returns a random element from this range using the specified source of randomness, or `null` if this range is empty. + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@ExperimentalUnsignedTypes +public fun UIntRange.randomOrNull(random: Random): UInt? { + if (isEmpty()) + return null + return random.nextUInt(this) +} + +/** + * Returns a random element from this range using the specified source of randomness, or `null` if this range is empty. + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@ExperimentalUnsignedTypes +public fun ULongRange.randomOrNull(random: Random): ULong? { + if (isEmpty()) + return null + return random.nextULong(this) +} + /** * Returns `true` if this range contains the specified [element]. * diff --git a/libraries/stdlib/test/collections/ArraysTest.kt b/libraries/stdlib/test/collections/ArraysTest.kt index f51892f4db9..57084094d4f 100644 --- a/libraries/stdlib/test/collections/ArraysTest.kt +++ b/libraries/stdlib/test/collections/ArraysTest.kt @@ -665,6 +665,29 @@ class ArraysTest { assertFailsWith { emptyArray().random() } } + @Test fun randomOrNull() { + Array(100) { it }.let { array -> + val tosses = List(10) { array.randomOrNull() } + assertTrue(tosses.distinct().size > 1, "Should be some distinct elements in $tosses") + + val seed = Random.nextInt() + val random1 = Random(seed) + val random2 = Random(seed) + + val tosses1 = List(10) { array.randomOrNull(random1) } + val tosses2 = List(10) { array.randomOrNull(random2) } + + assertEquals(tosses1, tosses2) + } + + arrayOf("x").let { singletonArray -> + val tosses = List(10) { singletonArray.randomOrNull() } + assertEquals(singletonArray.toList(), tosses.distinct()) + } + + assertNull(emptyArray().randomOrNull()) + } + @Test fun contains() { assertTrue(arrayOf("1", "2", "3", "4").contains("2")) diff --git a/libraries/stdlib/test/collections/CollectionTest.kt b/libraries/stdlib/test/collections/CollectionTest.kt index 50311ce0540..3bda9e33de3 100644 --- a/libraries/stdlib/test/collections/CollectionTest.kt +++ b/libraries/stdlib/test/collections/CollectionTest.kt @@ -663,6 +663,31 @@ class CollectionTest { assertFailsWith { emptyList().random() } } + @Test fun randomOrNull() { + val list = List(100) { it } + val set = list.toSet() + listOf(list, set).forEach { collection: Collection -> + val tosses = List(10) { collection.randomOrNull() } + assertTrue(tosses.distinct().size > 1, "Should be some distinct elements in $tosses") + + val seed = Random.nextInt() + val random1 = Random(seed) + val random2 = Random(seed) + + val tosses1 = List(10) { collection.randomOrNull(random1) } + val tosses2 = List(10) { collection.randomOrNull(random2) } + + assertEquals(tosses1, tosses2) + } + + listOf("x").let { singletonList -> + val tosses = List(10) { singletonList.randomOrNull() } + assertEquals(singletonList, tosses.distinct()) + } + + assertNull(emptyList().randomOrNull()) + } + @Test fun subscript() { val list = arrayListOf("foo", "bar") assertEquals("foo", list[0]) diff --git a/libraries/stdlib/test/ranges/RangeTest.kt b/libraries/stdlib/test/ranges/RangeTest.kt index c5cc5e3ce7e..ebd65d11da6 100644 --- a/libraries/stdlib/test/ranges/RangeTest.kt +++ b/libraries/stdlib/test/ranges/RangeTest.kt @@ -423,4 +423,10 @@ public class RangeTest { assertFailsWith { LongRange.EMPTY.random() } assertFailsWith { CharRange.EMPTY.random() } } + + @Test fun randomOrNullInEmptyRange() { + assertNull(IntRange.EMPTY.randomOrNull()) + assertNull(LongRange.EMPTY.randomOrNull()) + assertNull(CharRange.EMPTY.randomOrNull()) + } } diff --git a/libraries/stdlib/test/text/StringTest.kt b/libraries/stdlib/test/text/StringTest.kt index c25150ed031..64f6ad0496f 100644 --- a/libraries/stdlib/test/text/StringTest.kt +++ b/libraries/stdlib/test/text/StringTest.kt @@ -1029,6 +1029,29 @@ class StringTest { assertFailsWith { data("").random() } } + @Test fun randomOrNull() = withOneCharSequenceArg { data -> + data("abcdefg").let { charSeq -> + val tosses = List(10) { charSeq.randomOrNull() } + assertTrue(tosses.distinct().size > 1, "Should be some distinct elements in $tosses") + + val seed = Random.nextInt() + val random1 = Random(seed) + val random2 = Random(seed) + + val tosses1 = List(10) { charSeq.randomOrNull(random1) } + val tosses2 = List(10) { charSeq.randomOrNull(random2) } + + assertEquals(tosses1, tosses2) + } + + data("x").let { singletonCharSeq -> + val tosses = List(10) { singletonCharSeq.randomOrNull() } + assertEquals(singletonCharSeq.toList(), tosses.distinct()) + } + + assertNull(data("").randomOrNull()) + } + @Test fun partition() { val data = "a1b2c3" val pair = data.partition { it.isAsciiDigit() } 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 17fe225375b..3c30d0583b4 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 @@ -1430,6 +1430,15 @@ public final class kotlin/collections/ArraysKt { public static final fun random ([Ljava/lang/Object;Lkotlin/random/Random;)Ljava/lang/Object; public static final fun random ([SLkotlin/random/Random;)S public static final fun random ([ZLkotlin/random/Random;)Z + public static final fun randomOrNull ([BLkotlin/random/Random;)Ljava/lang/Byte; + public static final fun randomOrNull ([CLkotlin/random/Random;)Ljava/lang/Character; + public static final fun randomOrNull ([DLkotlin/random/Random;)Ljava/lang/Double; + public static final fun randomOrNull ([FLkotlin/random/Random;)Ljava/lang/Float; + public static final fun randomOrNull ([ILkotlin/random/Random;)Ljava/lang/Integer; + public static final fun randomOrNull ([JLkotlin/random/Random;)Ljava/lang/Long; + public static final fun randomOrNull ([Ljava/lang/Object;Lkotlin/random/Random;)Ljava/lang/Object; + public static final fun randomOrNull ([SLkotlin/random/Random;)Ljava/lang/Short; + public static final fun randomOrNull ([ZLkotlin/random/Random;)Ljava/lang/Boolean; public static final fun reduce ([BLkotlin/jvm/functions/Function2;)B public static final fun reduce ([CLkotlin/jvm/functions/Function2;)C public static final fun reduce ([DLkotlin/jvm/functions/Function2;)D @@ -2079,6 +2088,7 @@ public final class kotlin/collections/CollectionsKt { public static final fun plus (Ljava/util/Collection;Lkotlin/sequences/Sequence;)Ljava/util/List; public static final fun plus (Ljava/util/Collection;[Ljava/lang/Object;)Ljava/util/List; public static final fun random (Ljava/util/Collection;Lkotlin/random/Random;)Ljava/lang/Object; + public static final fun randomOrNull (Ljava/util/Collection;Lkotlin/random/Random;)Ljava/lang/Object; public static final fun reduce (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object; public static final fun reduceIndexed (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function3;)Ljava/lang/Object; public static final fun reduceOrNull (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object; @@ -2479,6 +2489,10 @@ public final class kotlin/collections/unsigned/UArraysKt { public static final fun random-JzugnMA ([JLkotlin/random/Random;)J public static final fun random-oSF2wD8 ([BLkotlin/random/Random;)B public static final fun random-s5X_as8 ([SLkotlin/random/Random;)S + public static final fun randomOrNull-2D5oskM ([ILkotlin/random/Random;)Lkotlin/UInt; + public static final fun randomOrNull-JzugnMA ([JLkotlin/random/Random;)Lkotlin/ULong; + public static final fun randomOrNull-oSF2wD8 ([BLkotlin/random/Random;)Lkotlin/UByte; + public static final fun randomOrNull-s5X_as8 ([SLkotlin/random/Random;)Lkotlin/UShort; public static final fun reversed--ajY-9A ([I)Ljava/util/List; public static final fun reversed-GBYM_sE ([B)Ljava/util/List; public static final fun reversed-QwZRm1k ([J)Ljava/util/List; @@ -4236,6 +4250,9 @@ public final class kotlin/ranges/RangesKt { public static final fun random (Lkotlin/ranges/CharRange;Lkotlin/random/Random;)C public static final fun random (Lkotlin/ranges/IntRange;Lkotlin/random/Random;)I public static final fun random (Lkotlin/ranges/LongRange;Lkotlin/random/Random;)J + public static final fun randomOrNull (Lkotlin/ranges/CharRange;Lkotlin/random/Random;)Ljava/lang/Character; + public static final fun randomOrNull (Lkotlin/ranges/IntRange;Lkotlin/random/Random;)Ljava/lang/Integer; + public static final fun randomOrNull (Lkotlin/ranges/LongRange;Lkotlin/random/Random;)Ljava/lang/Long; public static final fun rangeTo (DD)Lkotlin/ranges/ClosedFloatingPointRange; public static final fun rangeTo (FF)Lkotlin/ranges/ClosedFloatingPointRange; public static final fun rangeTo (Ljava/lang/Comparable;Ljava/lang/Comparable;)Lkotlin/ranges/ClosedRange; @@ -4368,6 +4385,8 @@ public final class kotlin/ranges/URangesKt { public static final fun downTo-eb3DHEI (JJ)Lkotlin/ranges/ULongProgression; public static final fun random (Lkotlin/ranges/UIntRange;Lkotlin/random/Random;)I public static final fun random (Lkotlin/ranges/ULongRange;Lkotlin/random/Random;)J + public static final fun randomOrNull (Lkotlin/ranges/UIntRange;Lkotlin/random/Random;)Lkotlin/UInt; + public static final fun randomOrNull (Lkotlin/ranges/ULongRange;Lkotlin/random/Random;)Lkotlin/ULong; public static final fun reversed (Lkotlin/ranges/UIntProgression;)Lkotlin/ranges/UIntProgression; public static final fun reversed (Lkotlin/ranges/ULongProgression;)Lkotlin/ranges/ULongProgression; public static final fun step (Lkotlin/ranges/UIntProgression;I)Lkotlin/ranges/UIntProgression; @@ -5090,6 +5109,7 @@ public final class kotlin/text/StringsKt { public static final fun prependIndent (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; public static synthetic fun prependIndent$default (Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Ljava/lang/String; public static final fun random (Ljava/lang/CharSequence;Lkotlin/random/Random;)C + public static final fun randomOrNull (Ljava/lang/CharSequence;Lkotlin/random/Random;)Ljava/lang/Character; public static final fun reduce (Ljava/lang/CharSequence;Lkotlin/jvm/functions/Function2;)C public static final fun reduceIndexed (Ljava/lang/CharSequence;Lkotlin/jvm/functions/Function3;)C public static final fun reduceOrNull (Ljava/lang/CharSequence;Lkotlin/jvm/functions/Function2;)Ljava/lang/Character; diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Elements.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Elements.kt index 352f9bc88ca..e223c47c1a2 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Elements.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Elements.kt @@ -906,6 +906,23 @@ object Elements : TemplateGroupBase() { } } + val f_randomOrNull = fn("randomOrNull()") { + include(Collections, ArraysOfObjects, ArraysOfPrimitives, ArraysOfUnsigned, CharSequences, RangesOfPrimitives) + } builder { + since("1.3") + annotation("@ExperimentalStdlibApi") + inlineOnly() + returns("T?") + doc { + """ + Returns a random ${f.element} from this ${f.collection}, or `null` if this ${f.collection} is empty. + """ + } + body { + """return randomOrNull(Random)""" + } + } + val f_random_random = fn("random(random: Random)") { include(Collections, ArraysOfObjects, ArraysOfPrimitives, ArraysOfUnsigned, CharSequences, RangesOfPrimitives) } builder { @@ -952,6 +969,49 @@ object Elements : TemplateGroupBase() { } } + val f_randomOrNull_random = fn("randomOrNull(random: Random)") { + include(Collections, ArraysOfObjects, ArraysOfPrimitives, ArraysOfUnsigned, CharSequences, RangesOfPrimitives) + } builder { + since("1.3") + annotation("@ExperimentalStdlibApi") + returns("T?") + doc { + """ + Returns a random ${f.element} from this ${f.collection} using the specified source of randomness, or `null` if this ${f.collection} is empty. + """ + } + body { + """ + if (isEmpty()) + return null + return elementAt(random.nextInt(size)) + """ + } + specialFor(ArraysOfObjects, ArraysOfPrimitives, ArraysOfUnsigned, CharSequences) { + body { + val size = if (family == CharSequences) "length" else "size" + """ + if (isEmpty()) + return null + return get(random.nextInt($size)) + """ + } + } + specialFor(RangesOfPrimitives) { + body { + val expr = when (primitive) { + PrimitiveType.Char -> "nextInt(first.toInt(), last.toInt() + 1).toChar()" + else -> "next$primitive(this)" + } + """ + if (isEmpty()) + return null + return random.$expr + """ + } + } + } + val f_components = (1..5).map { n -> fn("component$n()") { include(Lists, ArraysOfObjects, ArraysOfPrimitives, ArraysOfUnsigned)