diff --git a/libraries/stdlib/common/src/generated/_Ranges.kt b/libraries/stdlib/common/src/generated/_Ranges.kt index 69f8c4391c3..e2124300706 100644 --- a/libraries/stdlib/common/src/generated/_Ranges.kt +++ b/libraries/stdlib/common/src/generated/_Ranges.kt @@ -362,6 +362,52 @@ public operator fun ClosedRange.contains(value: Byte): Boolean { return contains(value.toFloat()) } +/** + * Checks if the specified [value] belongs to this range. + */ +@kotlin.jvm.JvmName("intRangeContains") +@SinceKotlin("1.7") +@ExperimentalStdlibApi +public operator fun OpenEndRange.contains(value: Byte): Boolean { + return contains(value.toInt()) +} + +/** + * Checks if the specified [value] belongs to this range. + */ +@kotlin.jvm.JvmName("longRangeContains") +@SinceKotlin("1.7") +@ExperimentalStdlibApi +public operator fun OpenEndRange.contains(value: Byte): Boolean { + return contains(value.toLong()) +} + +/** + * Checks if the specified [value] belongs to this range. + */ +@kotlin.jvm.JvmName("shortRangeContains") +@SinceKotlin("1.7") +@ExperimentalStdlibApi +public operator fun OpenEndRange.contains(value: Byte): Boolean { + return contains(value.toShort()) +} + +/** + * Checks if the specified [value] belongs to this range. + */ +@kotlin.internal.InlineOnly +public inline operator fun IntRange.contains(value: Byte): Boolean { + return (this as ClosedRange).contains(value) +} + +/** + * Checks if the specified [value] belongs to this range. + */ +@kotlin.internal.InlineOnly +public inline operator fun LongRange.contains(value: Byte): Boolean { + return (this as ClosedRange).contains(value) +} + /** * Checks if the specified [value] belongs to this range. */ @@ -458,7 +504,15 @@ public operator fun ClosedRange.contains(value: Float): Boolean { return contains(value.toDouble()) } -// TODO: for OpenEndRange +/** + * Checks if the specified [value] belongs to this range. + */ +@kotlin.jvm.JvmName("doubleRangeContains") +@SinceKotlin("1.7") +@ExperimentalStdlibApi +public operator fun OpenEndRange.contains(value: Float): Boolean { + return contains(value.toDouble()) +} /** * Checks if the specified [value] belongs to this range. @@ -504,6 +558,44 @@ public operator fun ClosedRange.contains(value: Int): Boolean { return contains(value.toFloat()) } +/** + * Checks if the specified [value] belongs to this range. + */ +@kotlin.jvm.JvmName("longRangeContains") +@SinceKotlin("1.7") +@ExperimentalStdlibApi +public operator fun OpenEndRange.contains(value: Int): Boolean { + return contains(value.toLong()) +} + +/** + * Checks if the specified [value] belongs to this range. + */ +@kotlin.jvm.JvmName("byteRangeContains") +@SinceKotlin("1.7") +@ExperimentalStdlibApi +public operator fun OpenEndRange.contains(value: Int): Boolean { + return value.toByteExactOrNull().let { if (it != null) contains(it) else false } +} + +/** + * Checks if the specified [value] belongs to this range. + */ +@kotlin.jvm.JvmName("shortRangeContains") +@SinceKotlin("1.7") +@ExperimentalStdlibApi +public operator fun OpenEndRange.contains(value: Int): Boolean { + return value.toShortExactOrNull().let { if (it != null) contains(it) else false } +} + +/** + * Checks if the specified [value] belongs to this range. + */ +@kotlin.internal.InlineOnly +public inline operator fun LongRange.contains(value: Int): Boolean { + return (this as ClosedRange).contains(value) +} + /** * Checks if the specified [value] belongs to this range. */ @@ -548,6 +640,44 @@ public operator fun ClosedRange.contains(value: Long): Boolean { return contains(value.toFloat()) } +/** + * Checks if the specified [value] belongs to this range. + */ +@kotlin.jvm.JvmName("intRangeContains") +@SinceKotlin("1.7") +@ExperimentalStdlibApi +public operator fun OpenEndRange.contains(value: Long): Boolean { + return value.toIntExactOrNull().let { if (it != null) contains(it) else false } +} + +/** + * Checks if the specified [value] belongs to this range. + */ +@kotlin.jvm.JvmName("byteRangeContains") +@SinceKotlin("1.7") +@ExperimentalStdlibApi +public operator fun OpenEndRange.contains(value: Long): Boolean { + return value.toByteExactOrNull().let { if (it != null) contains(it) else false } +} + +/** + * Checks if the specified [value] belongs to this range. + */ +@kotlin.jvm.JvmName("shortRangeContains") +@SinceKotlin("1.7") +@ExperimentalStdlibApi +public operator fun OpenEndRange.contains(value: Long): Boolean { + return value.toShortExactOrNull().let { if (it != null) contains(it) else false } +} + +/** + * Checks if the specified [value] belongs to this range. + */ +@kotlin.internal.InlineOnly +public inline operator fun IntRange.contains(value: Long): Boolean { + return (this as ClosedRange).contains(value) +} + /** * Checks if the specified [value] belongs to this range. */ @@ -592,6 +722,52 @@ public operator fun ClosedRange.contains(value: Short): Boolean { return contains(value.toFloat()) } +/** + * Checks if the specified [value] belongs to this range. + */ +@kotlin.jvm.JvmName("intRangeContains") +@SinceKotlin("1.7") +@ExperimentalStdlibApi +public operator fun OpenEndRange.contains(value: Short): Boolean { + return contains(value.toInt()) +} + +/** + * Checks if the specified [value] belongs to this range. + */ +@kotlin.jvm.JvmName("longRangeContains") +@SinceKotlin("1.7") +@ExperimentalStdlibApi +public operator fun OpenEndRange.contains(value: Short): Boolean { + return contains(value.toLong()) +} + +/** + * Checks if the specified [value] belongs to this range. + */ +@kotlin.jvm.JvmName("byteRangeContains") +@SinceKotlin("1.7") +@ExperimentalStdlibApi +public operator fun OpenEndRange.contains(value: Short): Boolean { + return value.toByteExactOrNull().let { if (it != null) contains(it) else false } +} + +/** + * Checks if the specified [value] belongs to this range. + */ +@kotlin.internal.InlineOnly +public inline operator fun IntRange.contains(value: Short): Boolean { + return (this as ClosedRange).contains(value) +} + +/** + * Checks if the specified [value] belongs to this range. + */ +@kotlin.internal.InlineOnly +public inline operator fun LongRange.contains(value: Short): Boolean { + return (this as ClosedRange).contains(value) +} + /** * Returns a progression from this value down to the specified [to] value with the step -1. * diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Ranges.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Ranges.kt index 9f80da5dbf2..df5f65340f2 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Ranges.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Ranges.kt @@ -176,7 +176,7 @@ object RangeOps : TemplateGroupBase() { body { "return until(to)" } } - val f_contains = fn("contains(value: Primitive)").byTwoPrimitives { + val f_containsMixedClosed = fn("contains(value: Primitive)").byTwoPrimitives { include(Ranges, numericCombinations) filter { _, (rangeType, itemType) -> rangeType != itemType } } builderWith { (rangeType, itemType) -> @@ -200,6 +200,40 @@ object RangeOps : TemplateGroupBase() { } } + val f_containsMixedOpenAndPrimitive = fn("contains(value: Primitive)").byTwoPrimitives { + include(OpenRanges, numericCombinations) + include(RangesOfPrimitives, numericCombinations.filter { (rangeType, _) -> rangeType in rangePrimitives }) + filter { _, (rangeType, itemType) -> + rangeType != itemType && rangeType.isIntegral() == itemType.isIntegral() && + rangeType != PrimitiveType.Float + } + } builderWith { (rangeType, itemType) -> + operator() + specialFor(OpenRanges) { + since("1.7") + annotation("@ExperimentalStdlibApi") + } + signature("contains(value: $itemType)") + + check(rangeType.isNumeric() == itemType.isNumeric()) { "Required rangeType and itemType both to be numeric or both not, got: $rangeType, $itemType" } + + platformName("${rangeType.name.decapitalize()}RangeContains") + returns("Boolean") + doc { "Checks if the specified [value] belongs to this range." } + body { + if (shouldCheckForConversionOverflow(fromType = itemType, toType = rangeType)) + "return value.to${rangeType}ExactOrNull().let { if (it != null) contains(it) else false }" + else + "return contains(value.to$rangeType())" + } + specialFor(RangesOfPrimitives) { + inlineOnly() + body { + "return (this as ClosedRange<$rangeType>).contains(value)" + } + } + } + val f_contains_nullable = fn("contains(element: T?)") { include(RangesOfPrimitives, rangePrimitives) } builder {