From b7fbb60db43298ad8520533765f6a52896a45a24 Mon Sep 17 00:00:00 2001 From: Ilya Gorbunov Date: Sat, 11 Jul 2015 00:46:52 +0300 Subject: [PATCH] Generate contains function for all combinations of primitive numeric ranges and arguments. #KT-6361 --- libraries/stdlib/src/generated/_Ranges.kt | 210 ++++++++++++++++++ libraries/stdlib/test/language/RangeTest.kt | 49 +++- .../kotlin-stdlib-gen/src/templates/Engine.kt | 2 - .../kotlin-stdlib-gen/src/templates/Ranges.kt | 18 +- 4 files changed, 274 insertions(+), 5 deletions(-) diff --git a/libraries/stdlib/src/generated/_Ranges.kt b/libraries/stdlib/src/generated/_Ranges.kt index 7a3c238f8e8..1507bfce3b9 100644 --- a/libraries/stdlib/src/generated/_Ranges.kt +++ b/libraries/stdlib/src/generated/_Ranges.kt @@ -10,6 +10,216 @@ import java.util.* import java.util.Collections // TODO: it's temporary while we have java.util.Collections in js +/** + * Checks if the specified [item] belongs to this range. + */ +public fun IntRange.contains(item: Byte): Boolean { + return start <= item && item <= end +} + +/** + * Checks if the specified [item] belongs to this range. + */ +public fun LongRange.contains(item: Byte): Boolean { + return start <= item && item <= end +} + +/** + * Checks if the specified [item] belongs to this range. + */ +public fun ShortRange.contains(item: Byte): Boolean { + return start <= item && item <= end +} + +/** + * Checks if the specified [item] belongs to this range. + */ +public fun DoubleRange.contains(item: Byte): Boolean { + return start <= item && item <= end +} + +/** + * Checks if the specified [item] belongs to this range. + */ +public fun FloatRange.contains(item: Byte): Boolean { + return start <= item && item <= end +} + +/** + * Checks if the specified [item] belongs to this range. + */ +public fun IntRange.contains(item: Double): Boolean { + return start <= item && item <= end +} + +/** + * Checks if the specified [item] belongs to this range. + */ +public fun LongRange.contains(item: Double): Boolean { + return start <= item && item <= end +} + +/** + * Checks if the specified [item] belongs to this range. + */ +public fun ByteRange.contains(item: Double): Boolean { + return start <= item && item <= end +} + +/** + * Checks if the specified [item] belongs to this range. + */ +public fun ShortRange.contains(item: Double): Boolean { + return start <= item && item <= end +} + +/** + * Checks if the specified [item] belongs to this range. + */ +public fun FloatRange.contains(item: Double): Boolean { + return start <= item && item <= end +} + +/** + * Checks if the specified [item] belongs to this range. + */ +public fun IntRange.contains(item: Float): Boolean { + return start <= item && item <= end +} + +/** + * Checks if the specified [item] belongs to this range. + */ +public fun LongRange.contains(item: Float): Boolean { + return start <= item && item <= end +} + +/** + * Checks if the specified [item] belongs to this range. + */ +public fun ByteRange.contains(item: Float): Boolean { + return start <= item && item <= end +} + +/** + * Checks if the specified [item] belongs to this range. + */ +public fun ShortRange.contains(item: Float): Boolean { + return start <= item && item <= end +} + +/** + * Checks if the specified [item] belongs to this range. + */ +public fun DoubleRange.contains(item: Float): Boolean { + return start <= item && item <= end +} + +/** + * Checks if the specified [item] belongs to this range. + */ +public fun LongRange.contains(item: Int): Boolean { + return start <= item && item <= end +} + +/** + * Checks if the specified [item] belongs to this range. + */ +public fun ByteRange.contains(item: Int): Boolean { + return start <= item && item <= end +} + +/** + * Checks if the specified [item] belongs to this range. + */ +public fun ShortRange.contains(item: Int): Boolean { + return start <= item && item <= end +} + +/** + * Checks if the specified [item] belongs to this range. + */ +public fun DoubleRange.contains(item: Int): Boolean { + return start <= item && item <= end +} + +/** + * Checks if the specified [item] belongs to this range. + */ +public fun FloatRange.contains(item: Int): Boolean { + return start <= item && item <= end +} + +/** + * Checks if the specified [item] belongs to this range. + */ +public fun IntRange.contains(item: Long): Boolean { + return start <= item && item <= end +} + +/** + * Checks if the specified [item] belongs to this range. + */ +public fun ByteRange.contains(item: Long): Boolean { + return start <= item && item <= end +} + +/** + * Checks if the specified [item] belongs to this range. + */ +public fun ShortRange.contains(item: Long): Boolean { + return start <= item && item <= end +} + +/** + * Checks if the specified [item] belongs to this range. + */ +public fun DoubleRange.contains(item: Long): Boolean { + return start <= item && item <= end +} + +/** + * Checks if the specified [item] belongs to this range. + */ +public fun FloatRange.contains(item: Long): Boolean { + return start <= item && item <= end +} + +/** + * Checks if the specified [item] belongs to this range. + */ +public fun IntRange.contains(item: Short): Boolean { + return start <= item && item <= end +} + +/** + * Checks if the specified [item] belongs to this range. + */ +public fun LongRange.contains(item: Short): Boolean { + return start <= item && item <= end +} + +/** + * Checks if the specified [item] belongs to this range. + */ +public fun ByteRange.contains(item: Short): Boolean { + return start <= item && item <= end +} + +/** + * Checks if the specified [item] belongs to this range. + */ +public fun DoubleRange.contains(item: Short): Boolean { + return start <= item && item <= end +} + +/** + * Checks if the specified [item] belongs to this range. + */ +public fun FloatRange.contains(item: Short): Boolean { + return start <= item && item <= end +} + /** * Returns a progression from this value down to the specified [to] value with the increment -1. * The [to] value has to be less than this value. diff --git a/libraries/stdlib/test/language/RangeTest.kt b/libraries/stdlib/test/language/RangeTest.kt index 3e758863498..cb1816f2028 100644 --- a/libraries/stdlib/test/language/RangeTest.kt +++ b/libraries/stdlib/test/language/RangeTest.kt @@ -21,6 +21,14 @@ public class RangeTest { assertFalse(range.isEmpty()) + assertTrue(1.toShort() in range) + assertTrue(1.toByte() in range) + assertTrue(1.toLong() in range) + assertTrue(1.toFloat() in range) + assertTrue(1.toDouble() in range) + + assertFalse(Long.MAX_VALUE in range) + val openRange = 1 until 10 assertTrue(9 in openRange) assertFalse(10 in openRange) @@ -42,9 +50,18 @@ public class RangeTest { assertFalse(10.toByte() in range) assertFalse(111.toByte() in range) - + assertFalse(range.isEmpty()) + + assertTrue(1.toShort() in range) + assertTrue(1.toInt() in range) + assertTrue(1.toLong() in range) + assertTrue(1.toFloat() in range) + assertTrue(1.toDouble() in range) + + assertFalse(Long.MAX_VALUE in range) + val openRange = 1.toByte() until 10.toByte() assertTrue(9.toByte() in openRange) assertFalse(10.toByte() in openRange) @@ -70,6 +87,14 @@ public class RangeTest { assertFalse(range.isEmpty()) + assertTrue(1.toByte() in range) + assertTrue(1.toInt() in range) + assertTrue(1.toLong() in range) + assertTrue(1.toFloat() in range) + assertTrue(1.toDouble() in range) + + assertFalse(Long.MAX_VALUE in range) + val openRange = 1.toShort() until 10.toShort() assertTrue(9.toShort() in openRange) assertFalse(10.toShort() in openRange) @@ -94,6 +119,14 @@ public class RangeTest { assertFalse(range.isEmpty()) + assertTrue(1.toByte() in range) + assertTrue(1.toShort() in range) + assertTrue(1.toInt() in range) + assertTrue(1.toFloat() in range) + assertTrue(1.toDouble() in range) + + assertFalse(Double.MAX_VALUE in range) + val openRange = 1L until 10L assertTrue(9L in openRange) assertFalse(10L in openRange) @@ -144,6 +177,12 @@ public class RangeTest { assertFalse(1e200 in range) assertFalse(range.isEmpty()) + + assertTrue(1.toByte() in range) + assertTrue(1.toShort() in range) + assertTrue(1.toInt() in range) + assertTrue(1.toLong() in range) + assertTrue(1.toFloat() in range) } test fun floatRange() { @@ -164,6 +203,14 @@ public class RangeTest { assertFalse(1e30f in range) assertFalse(range.isEmpty()) + + assertTrue(1.toByte() in range) + assertTrue(1.toShort() in range) + assertTrue(1.toInt() in range) + assertTrue(1.toLong() in range) + assertTrue(1.toDouble() in range) + + assertFalse(Double.MAX_VALUE in range) } test fun isEmpty() { diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Engine.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Engine.kt index f9de918d15f..f5bd5bddb64 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Engine.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Engine.kt @@ -50,8 +50,6 @@ enum class PrimitiveType { val descendingByDomainCapacity = listOf(Double, Float, Long, Int, Short, Char, Byte) fun maxByCapacity(fromType: PrimitiveType, toType: PrimitiveType): PrimitiveType = descendingByDomainCapacity.first { it == fromType || it == toType } - - val primitivePermutations = numericPrimitives.flatMap { fromType -> numericPrimitives map { toType -> fromType to toType } } + (Char to Char) } } diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Ranges.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Ranges.kt index bfa8144f95f..41f2e354c6a 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Ranges.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Ranges.kt @@ -72,7 +72,11 @@ fun ranges(): List { body { "return $progressionType($fromExpr, $toExpr, $incrementExpr)" } } - templates addAll PrimitiveType.primitivePermutations.map { downTo(it.first, it.second) } + val numericPrimitives = PrimitiveType.numericPrimitives + val numericPermutations = numericPrimitives flatMap { fromType -> numericPrimitives map { toType -> fromType to toType }} + val primitivePermutations = numericPermutations + (PrimitiveType.Char to PrimitiveType.Char) + + templates addAll primitivePermutations.map { downTo(it.first, it.second) } fun until(fromType: PrimitiveType, toType: PrimitiveType) = f("until(to: $toType)") { only(Primitives) @@ -109,9 +113,19 @@ fun ranges(): List { } } - templates addAll PrimitiveType.primitivePermutations + templates addAll primitivePermutations .filter { it.first.isIntegral() && it.second.isIntegral() } .map { until(it.first, it.second) } + fun contains(rangeType: PrimitiveType, itemType: PrimitiveType) = f("contains(item: $itemType)") { + only(RangesOfPrimitives) + only(rangeType) + returns("Boolean") + doc { "Checks if the specified [item] belongs to this range." } + body { "return start <= item && item <= end" } + } + + templates addAll numericPermutations.filter { it.first != it.second }.map { contains(it.first, it.second) } + return templates } \ No newline at end of file