Provide common Random API

#KT-17261
This commit is contained in:
Ilya Gorbunov
2018-07-03 03:43:34 +03:00
parent 9df411481c
commit cc031e3a40
9 changed files with 415 additions and 0 deletions
@@ -7,6 +7,8 @@ package kotlin.internal
import kotlin.*
import java.util.regex.MatchResult
import kotlin.random.FallbackThreadLocalRandom
import kotlin.random.Random
internal open class PlatformImplementations {
@@ -17,6 +19,8 @@ internal open class PlatformImplementations {
public open fun getMatchResultNamedGroup(matchResult: MatchResult, name: String): MatchGroup? {
throw UnsupportedOperationException("Retrieving groups by name is not supported on this platform.")
}
public open fun defaultPlatformRandom(): Random = FallbackThreadLocalRandom()
}
@@ -0,0 +1,73 @@
/*
* Copyright 2010-2018 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.
*/
package kotlin.random
import kotlin.UnsupportedOperationException
import kotlin.internal.*
@SinceKotlin("1.3")
public fun Random.asJavaRandom(): java.util.Random =
(this as? AbstractPlatformRandom)?.impl ?: KotlinRandom(this)
@SinceKotlin("1.3")
public fun java.util.Random.asKotlinRandom(): Random =
PlatformRandom(this)
@InlineOnly
internal actual inline fun defaultPlatformRandom(): Random =
IMPLEMENTATIONS.defaultPlatformRandom()
internal actual fun fastLog2(value: Int): Int =
31 - Integer.numberOfLeadingZeros(value)
internal abstract class AbstractPlatformRandom : Random() {
abstract val impl: java.util.Random
override fun nextBits(bitCount: Int): Int = impl.nextInt() ushr (32 - bitCount).coerceAtLeast(0)
override fun nextInt(): Int = impl.nextInt()
override fun nextLong(): Long = impl.nextLong()
override fun nextBoolean(): Boolean = impl.nextBoolean()
override fun nextDouble(): Double = impl.nextDouble()
override fun nextFloat(): Float = impl.nextFloat()
override fun nextBytes(array: ByteArray): ByteArray = run { impl.nextBytes(array); array }
}
internal class FallbackThreadLocalRandom : AbstractPlatformRandom() {
private val implStorage = object : ThreadLocal<java.util.Random>() {
override fun initialValue(): java.util.Random {
return java.util.Random()
}
}
override val impl: java.util.Random
get() = implStorage.get()
}
private class PlatformRandom(override val impl: java.util.Random) : AbstractPlatformRandom()
private class KotlinRandom(val impl: Random) : java.util.Random() {
override fun next(bits: Int): Int = impl.nextBits(bits)
override fun nextInt(): Int = impl.nextInt()
override fun nextInt(bound: Int): Int = impl.nextInt(bound)
override fun nextBoolean(): Boolean = impl.nextBoolean()
override fun nextLong(): Long = impl.nextLong()
override fun nextFloat(): Float = impl.nextFloat()
override fun nextDouble(): Double = impl.nextDouble()
override fun setSeed(seed: Long) {
throw UnsupportedOperationException("Setting seed is not supported")
}
override fun nextBytes(bytes: ByteArray) {
impl.nextBytes(bytes)
}
}