Extension random() to select random element from a collection
Fixes #KT-15539
This commit is contained in:
@@ -13,6 +13,17 @@ object Elements : TemplateGroupBase() {
|
||||
init {
|
||||
defaultBuilder {
|
||||
sequenceClassification(terminal)
|
||||
specialFor(ArraysOfUnsigned) {
|
||||
since("1.3")
|
||||
annotation("@ExperimentalUnsignedTypes")
|
||||
}
|
||||
specialFor(RangesOfPrimitives) {
|
||||
if (primitive in PrimitiveType.unsignedPrimitives) {
|
||||
since("1.3")
|
||||
annotation("@ExperimentalUnsignedTypes")
|
||||
sourceFile(SourceFile.URanges)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -808,6 +819,69 @@ object Elements : TemplateGroupBase() {
|
||||
}
|
||||
}
|
||||
|
||||
val f_random = fn("random()") {
|
||||
include(Collections, ArraysOfObjects, ArraysOfPrimitives, ArraysOfUnsigned, CharSequences, RangesOfPrimitives)
|
||||
} builder {
|
||||
since("1.3")
|
||||
inlineOnly()
|
||||
returns("T")
|
||||
doc {
|
||||
"""
|
||||
Returns a random ${f.element} from this ${f.collection}.
|
||||
|
||||
@throws ${if (f == RangesOfPrimitives) "IllegalArgumentException" else "NoSuchElementException"} if this ${f.collection} is empty.
|
||||
"""
|
||||
}
|
||||
body {
|
||||
"""return random(Random)"""
|
||||
}
|
||||
}
|
||||
|
||||
val f_random_random = fn("random(random: Random)") {
|
||||
include(Collections, ArraysOfObjects, ArraysOfPrimitives, ArraysOfUnsigned, CharSequences, RangesOfPrimitives)
|
||||
} builder {
|
||||
since("1.3")
|
||||
returns("T")
|
||||
doc {
|
||||
"""
|
||||
Returns a random ${f.element} from this ${f.collection} using the specified source of randomness.
|
||||
|
||||
@throws ${if (f == RangesOfPrimitives) "IllegalArgumentException" else "NoSuchElementException"} if this ${f.collection} is empty.
|
||||
"""
|
||||
}
|
||||
body {
|
||||
"""
|
||||
if (isEmpty())
|
||||
throw NoSuchElementException("${f.doc.collection.capitalize()} is empty.")
|
||||
return elementAt(random.nextInt(size))
|
||||
"""
|
||||
}
|
||||
specialFor(ArraysOfObjects, ArraysOfPrimitives, ArraysOfUnsigned, CharSequences) {
|
||||
body {
|
||||
val size = if (family == CharSequences) "length" else "size"
|
||||
"""
|
||||
if (isEmpty())
|
||||
throw NoSuchElementException("${f.doc.collection.capitalize()} is empty.")
|
||||
return get(random.nextInt($size))
|
||||
"""
|
||||
}
|
||||
}
|
||||
specialFor(Maps) {
|
||||
body {
|
||||
"""return entries.random(random)"""
|
||||
}
|
||||
}
|
||||
specialFor(RangesOfPrimitives) {
|
||||
body {
|
||||
val expr = when (primitive) {
|
||||
PrimitiveType.Char -> "nextInt(first.toInt(), last.toInt() + 1).toChar()"
|
||||
else -> "next$primitive(this)"
|
||||
}
|
||||
"""return random.$expr"""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val f_components = (1..5).map { n ->
|
||||
fn("component$n()") {
|
||||
include(Lists, ArraysOfObjects, ArraysOfPrimitives)
|
||||
|
||||
@@ -10,7 +10,7 @@ import templates.PrimitiveType.Companion.maxByCapacity
|
||||
|
||||
object RangeOps : TemplateGroupBase() {
|
||||
|
||||
private val rangePrimitives = setOf(PrimitiveType.Int, PrimitiveType.Long, PrimitiveType.Char, PrimitiveType.UInt, PrimitiveType.ULong)
|
||||
private val rangePrimitives = PrimitiveType.rangePrimitives
|
||||
private fun rangeElementType(fromType: PrimitiveType, toType: PrimitiveType) =
|
||||
maxByCapacity(fromType, toType).let {
|
||||
when {
|
||||
|
||||
@@ -60,6 +60,7 @@ enum class PrimitiveType {
|
||||
val defaultPrimitives = PrimitiveType.values().toSet() - unsignedPrimitives
|
||||
val numericPrimitives = setOf(Int, Long, Byte, Short, Double, Float)
|
||||
val integralPrimitives = setOf(Int, Long, Byte, Short, Char)
|
||||
val rangePrimitives = setOf(Int, Long, Char, UInt, ULong)
|
||||
|
||||
val descendingByDomainCapacity = listOf(Double, Float, Long, Int, Short, Char, Byte)
|
||||
val descendingByDomainCapacityUnsigned = listOf(ULong, UInt, UShort, UByte)
|
||||
|
||||
@@ -32,8 +32,9 @@ object DocExtensions {
|
||||
val Family.collection: String
|
||||
get() = when (this) {
|
||||
CharSequences -> "char sequence"
|
||||
ArraysOfObjects, ArraysOfPrimitives, InvariantArraysOfObjects -> "array"
|
||||
Strings, Sequences, Maps, Lists, Sets, Ranges -> name.singularize().decapitalize()
|
||||
ArraysOfObjects, ArraysOfPrimitives, InvariantArraysOfObjects, ArraysOfUnsigned -> "array"
|
||||
Ranges, RangesOfPrimitives -> "range"
|
||||
Strings, Sequences, Maps, Lists, Sets -> name.singularize().decapitalize()
|
||||
else -> "collection"
|
||||
}
|
||||
|
||||
|
||||
@@ -149,6 +149,7 @@ abstract class MemberTemplateDefinition<TParam> : MemberTemplate {
|
||||
private fun defaultPrimitives(f: Family): Set<PrimitiveType> =
|
||||
when {
|
||||
f == Family.Unsigned || f == Family.ArraysOfUnsigned -> PrimitiveType.unsignedPrimitives
|
||||
f == Family.RangesOfPrimitives -> PrimitiveType.rangePrimitives
|
||||
f.isPrimitiveSpecialization -> PrimitiveType.defaultPrimitives
|
||||
else -> emptySet()
|
||||
}
|
||||
|
||||
@@ -92,6 +92,9 @@ fun List<MemberBuilder>.writeTo(file: File, platformSource: PlatformSourceFile)
|
||||
writer.appendln("import kotlin.*")
|
||||
writer.appendln("import kotlin.text.*")
|
||||
writer.appendln("import kotlin.comparisons.*")
|
||||
if (platform == Platform.Common) {
|
||||
writer.appendln("import kotlin.random.*")
|
||||
}
|
||||
|
||||
if (sourceFile == SourceFile.Sequences) {
|
||||
writer.appendln("import kotlin.coroutines.experimental.*")
|
||||
|
||||
Reference in New Issue
Block a user