Introduce overloads to check for T? element contained in iterable range in a constant time
#KT-18483
This commit is contained in:
@@ -93,6 +93,39 @@ public fun CharRange.random(random: Random): Char {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns `true` if this range contains the specified [element].
|
||||||
|
*
|
||||||
|
* Always returns `false` if the [element] is `null`.
|
||||||
|
*/
|
||||||
|
@SinceKotlin("1.3")
|
||||||
|
@kotlin.internal.InlineOnly
|
||||||
|
public inline operator fun IntRange.contains(element: Int?): Boolean {
|
||||||
|
return element != null && contains(element)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns `true` if this range contains the specified [element].
|
||||||
|
*
|
||||||
|
* Always returns `false` if the [element] is `null`.
|
||||||
|
*/
|
||||||
|
@SinceKotlin("1.3")
|
||||||
|
@kotlin.internal.InlineOnly
|
||||||
|
public inline operator fun LongRange.contains(element: Long?): Boolean {
|
||||||
|
return element != null && contains(element)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns `true` if this range contains the specified [element].
|
||||||
|
*
|
||||||
|
* Always returns `false` if the [element] is `null`.
|
||||||
|
*/
|
||||||
|
@SinceKotlin("1.3")
|
||||||
|
@kotlin.internal.InlineOnly
|
||||||
|
public inline operator fun CharRange.contains(element: Char?): Boolean {
|
||||||
|
return element != null && contains(element)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the specified [value] belongs to this range.
|
* Checks if the specified [value] belongs to this range.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -72,6 +72,30 @@ public fun ULongRange.random(random: Random): ULong {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns `true` if this range contains the specified [element].
|
||||||
|
*
|
||||||
|
* Always returns `false` if the [element] is `null`.
|
||||||
|
*/
|
||||||
|
@SinceKotlin("1.3")
|
||||||
|
@ExperimentalUnsignedTypes
|
||||||
|
@kotlin.internal.InlineOnly
|
||||||
|
public inline operator fun UIntRange.contains(element: UInt?): Boolean {
|
||||||
|
return element != null && contains(element)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns `true` if this range contains the specified [element].
|
||||||
|
*
|
||||||
|
* Always returns `false` if the [element] is `null`.
|
||||||
|
*/
|
||||||
|
@SinceKotlin("1.3")
|
||||||
|
@ExperimentalUnsignedTypes
|
||||||
|
@kotlin.internal.InlineOnly
|
||||||
|
public inline operator fun ULongRange.contains(element: ULong?): Boolean {
|
||||||
|
return element != null && contains(element)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a progression from this value down to the specified [to] value with the step -1.
|
* Returns a progression from this value down to the specified [to] value with the step -1.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -98,6 +98,17 @@ public operator fun <T : Comparable<T>> T.rangeTo(that: T): ClosedRange<T> = Com
|
|||||||
public operator fun Double.rangeTo(that: Double): ClosedFloatingPointRange<Double> = ClosedDoubleRange(this, that)
|
public operator fun Double.rangeTo(that: Double): ClosedFloatingPointRange<Double> = ClosedDoubleRange(this, that)
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns `true` if this iterable range contains the specified [element].
|
||||||
|
*
|
||||||
|
* Always returns `false` if the [element] is `null`.
|
||||||
|
*/
|
||||||
|
@SinceKotlin("1.3")
|
||||||
|
@kotlin.internal.InlineOnly
|
||||||
|
public inline operator fun <T, R> R.contains(element: T?): Boolean where T : Any, R : Iterable<T>, R : ClosedRange<T> =
|
||||||
|
element != null && contains(element)
|
||||||
|
|
||||||
|
|
||||||
internal fun checkStepIsPositive(isPositive: Boolean, step: Number) {
|
internal fun checkStepIsPositive(isPositive: Boolean, step: Number) {
|
||||||
if (!isPositive) throw IllegalArgumentException("Step must be positive, was: $step.")
|
if (!isPositive) throw IllegalArgumentException("Step must be positive, was: $step.")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,10 @@ public class RangeTest {
|
|||||||
|
|
||||||
assertFalse(Long.MAX_VALUE in range)
|
assertFalse(Long.MAX_VALUE in range)
|
||||||
|
|
||||||
|
assertFalse(null in range)
|
||||||
|
assertTrue(1 as Int? in range)
|
||||||
|
assertFalse(10 as Int? in range)
|
||||||
|
|
||||||
val openRange = 1 until 10
|
val openRange = 1 until 10
|
||||||
assertTrue(9 in openRange)
|
assertTrue(9 in openRange)
|
||||||
assertFalse(10 in openRange)
|
assertFalse(10 in openRange)
|
||||||
@@ -73,6 +77,8 @@ public class RangeTest {
|
|||||||
|
|
||||||
assertFalse(Long.MAX_VALUE in range)
|
assertFalse(Long.MAX_VALUE in range)
|
||||||
|
|
||||||
|
// assertTrue(1.toByte() as Byte? in range) // expected not to compile
|
||||||
|
|
||||||
val openRange = 1.toByte() until 10.toByte()
|
val openRange = 1.toByte() until 10.toByte()
|
||||||
assertTrue(9.toByte() in openRange)
|
assertTrue(9.toByte() in openRange)
|
||||||
assertFalse(10.toByte() in openRange)
|
assertFalse(10.toByte() in openRange)
|
||||||
@@ -109,6 +115,8 @@ public class RangeTest {
|
|||||||
|
|
||||||
assertFalse(Long.MAX_VALUE in range)
|
assertFalse(Long.MAX_VALUE in range)
|
||||||
|
|
||||||
|
// assertTrue(1.toShort() as Short? in range) // expected not to compile
|
||||||
|
|
||||||
val openRange = 1.toShort() until 10.toShort()
|
val openRange = 1.toShort() until 10.toShort()
|
||||||
assertTrue(9.toShort() in openRange)
|
assertTrue(9.toShort() in openRange)
|
||||||
assertFalse(10.toShort() in openRange)
|
assertFalse(10.toShort() in openRange)
|
||||||
@@ -147,6 +155,9 @@ public class RangeTest {
|
|||||||
assertFalse(Double.MAX_VALUE in range)
|
assertFalse(Double.MAX_VALUE in range)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assertFalse(null in range)
|
||||||
|
assertTrue(1L as Long? in range)
|
||||||
|
assertFalse(10L as Long? in range)
|
||||||
|
|
||||||
val openRange = 1L until 10L
|
val openRange = 1L until 10L
|
||||||
assertTrue(9L in openRange)
|
assertTrue(9L in openRange)
|
||||||
@@ -177,6 +188,10 @@ public class RangeTest {
|
|||||||
assertTrue('v' in (range as ClosedRange<Char>))
|
assertTrue('v' in (range as ClosedRange<Char>))
|
||||||
assertFalse((range as ClosedRange<Char>).isEmpty())
|
assertFalse((range as ClosedRange<Char>).isEmpty())
|
||||||
|
|
||||||
|
assertFalse(null in range)
|
||||||
|
assertTrue('p' as Char? in range)
|
||||||
|
assertFalse('z' as Char? in range)
|
||||||
|
|
||||||
val openRange = 'A' until 'Z'
|
val openRange = 'A' until 'Z'
|
||||||
assertTrue('Y' in openRange)
|
assertTrue('Y' in openRange)
|
||||||
assertFalse('Z' in openRange)
|
assertFalse('Z' in openRange)
|
||||||
|
|||||||
@@ -174,6 +174,25 @@ object RangeOps : TemplateGroupBase() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val f_contains_nullable = fn("contains(element: T?)") {
|
||||||
|
include(RangesOfPrimitives, rangePrimitives)
|
||||||
|
} builder {
|
||||||
|
since("1.3")
|
||||||
|
operator()
|
||||||
|
inlineOnly()
|
||||||
|
|
||||||
|
doc {
|
||||||
|
"""
|
||||||
|
Returns `true` if this ${f.collection} contains the specified [element].
|
||||||
|
|
||||||
|
Always returns `false` if the [element] is `null`.
|
||||||
|
"""
|
||||||
|
}
|
||||||
|
|
||||||
|
returns("Boolean")
|
||||||
|
body { "return element != null && contains(element)" }
|
||||||
|
}
|
||||||
|
|
||||||
val f_toPrimitiveExactOrNull = fn("to{}ExactOrNull()").byTwoPrimitives {
|
val f_toPrimitiveExactOrNull = fn("to{}ExactOrNull()").byTwoPrimitives {
|
||||||
include(Primitives, numericPermutations)
|
include(Primitives, numericPermutations)
|
||||||
filter { _, (fromType, toType) -> fromType.capacity > toType.capacity && toType.isIntegral() }
|
filter { _, (fromType, toType) -> fromType.capacity > toType.capacity && toType.isIntegral() }
|
||||||
|
|||||||
Reference in New Issue
Block a user