kotlin.random.PlatformRandom.kt Maven / Gradle / Ivy
/*
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
* 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.internal.IMPLEMENTATIONS
import kotlin.internal.InlineOnly
/**
* Creates a [java.util.Random][java.util.Random] instance that uses the specified Kotlin [Random] generator as a randomness source.
*/
@SinceKotlin("1.3")
public fun Random.asJavaRandom(): java.util.Random =
(this as? AbstractPlatformRandom)?.impl ?: KotlinRandom(this)
/**
* Creates a Kotlin [Random] instance that uses the specified [java.util.Random][java.util.Random] generator as a randomness source.
*/
@SinceKotlin("1.3")
public fun java.util.Random.asKotlinRandom(): Random =
(this as? KotlinRandom)?.impl ?: PlatformRandom(this)
@InlineOnly
internal actual inline fun defaultPlatformRandom(): Random =
IMPLEMENTATIONS.defaultPlatformRandom()
internal actual fun doubleFromParts(hi26: Int, low27: Int): Double =
(hi26.toLong().shl(27) + low27) / (1L shl 53).toDouble()
internal abstract class AbstractPlatformRandom : Random() {
abstract val impl: java.util.Random
override fun nextBits(bitCount: Int): Int =
impl.nextInt().takeUpperBits(bitCount)
override fun nextInt(): Int = impl.nextInt()
override fun nextInt(until: Int): Int = impl.nextInt(until)
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 = array.also { impl.nextBytes(it) }
}
internal class FallbackThreadLocalRandom : AbstractPlatformRandom() {
private val implStorage = object : ThreadLocal() {
override fun initialValue(): java.util.Random = java.util.Random()
}
override val impl: java.util.Random
get() = implStorage.get()
}
private class PlatformRandom(override val impl: java.util.Random) : AbstractPlatformRandom(), Serializable {
private companion object {
private const val serialVersionUID: Long = 0L
}
}
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 nextBytes(bytes: ByteArray) {
impl.nextBytes(bytes)
}
private var seedInitialized: Boolean = false
override fun setSeed(seed: Long) {
if (!seedInitialized) {
// ignore seed value from constructor
seedInitialized = true
} else {
throw UnsupportedOperationException("Setting seed is not supported.")
}
}
private companion object {
private const val serialVersionUID: Long = 0L
}
}