diff --git a/core/builtins/src/kotlin/Progression.kt b/core/builtins/src/kotlin/Progression.kt index 9f245a43ac5..d64858c7dde 100644 --- a/core/builtins/src/kotlin/Progression.kt +++ b/core/builtins/src/kotlin/Progression.kt @@ -22,6 +22,7 @@ package kotlin * bytecode generation for it. Progressions with a step of -1 can be created through the * `downTo` method on classes representing primitive types. */ +@Deprecated("This progression has unclear inclusiveness of end value. Use InclusiveRangeProgression instead.", ReplaceWith("InclusiveRangeProgression")) public interface Progression : Iterable { /** * The start value of the progression. @@ -38,3 +39,34 @@ public interface Progression : Iterable { */ public val increment: Number } + + +/** + * Represents an arithmetical progression of numbers or characters with a given start value, end value and step. + * This class is intended to be used in 'for' loops, and the JVM backend suggests efficient + * bytecode generation for it. Progressions with a step of -1 can be created through the + * `downTo` method on classes representing primitive types. + */ +public interface InclusiveRangeProgression : Progression { + /** + * The start value of the progression. + */ + public override val start: N + + /** + * The end value of the progression (inclusive). + */ + @Deprecated("Use endInclusive instead.", ReplaceWith("endInclusive")) + public override val end: N get() = endInclusive + + /** + * The end value of the progression (inclusive). + */ + public val endInclusive: N + + /** + * The step of the progression. + */ + public override val increment: Number +} + diff --git a/core/builtins/src/kotlin/Progressions.kt b/core/builtins/src/kotlin/Progressions.kt index 36bd8922a3a..9a8e4a63780 100644 --- a/core/builtins/src/kotlin/Progressions.kt +++ b/core/builtins/src/kotlin/Progressions.kt @@ -23,26 +23,26 @@ package kotlin */ public class ByteProgression( override val start: Byte, - override val end: Byte, + override val endInclusive: Byte, override val increment: Int -) : Progression { +) : InclusiveRangeProgression { init { if (increment == 0) throw IllegalArgumentException("Increment must be non-zero") } - override fun iterator(): ByteIterator = ByteProgressionIterator(start, end, increment) + override fun iterator(): ByteIterator = ByteProgressionIterator(start, endInclusive, increment) /** Checks if the progression is empty. */ - public fun isEmpty(): Boolean = if (increment > 0) start > end else start < end + public fun isEmpty(): Boolean = if (increment > 0) start > endInclusive else start < endInclusive override fun equals(other: Any?): Boolean = other is ByteProgression && (isEmpty() && other.isEmpty() || - start == other.start && end == other.end && increment == other.increment) + start == other.start && endInclusive == other.endInclusive && increment == other.increment) override fun hashCode(): Int = - if (isEmpty()) -1 else (31 * (31 * start.toInt() + end.toInt()) + increment) + if (isEmpty()) -1 else (31 * (31 * start.toInt() + endInclusive.toInt()) + increment) - override fun toString(): String = if (increment > 0) "$start..$end step $increment" else "$start downTo $end step ${-increment}" + override fun toString(): String = if (increment > 0) "$start..$endInclusive step $increment" else "$start downTo $endInclusive step ${-increment}" } /** @@ -50,26 +50,26 @@ public class ByteProgression( */ public class CharProgression( override val start: Char, - override val end: Char, + override val endInclusive: Char, override val increment: Int -) : Progression { +) : InclusiveRangeProgression { init { if (increment == 0) throw IllegalArgumentException("Increment must be non-zero") } - override fun iterator(): CharIterator = CharProgressionIterator(start, end, increment) + override fun iterator(): CharIterator = CharProgressionIterator(start, endInclusive, increment) /** Checks if the progression is empty. */ - public fun isEmpty(): Boolean = if (increment > 0) start > end else start < end + public fun isEmpty(): Boolean = if (increment > 0) start > endInclusive else start < endInclusive override fun equals(other: Any?): Boolean = other is CharProgression && (isEmpty() && other.isEmpty() || - start == other.start && end == other.end && increment == other.increment) + start == other.start && endInclusive == other.endInclusive && increment == other.increment) override fun hashCode(): Int = - if (isEmpty()) -1 else (31 * (31 * start.toInt() + end.toInt()) + increment) + if (isEmpty()) -1 else (31 * (31 * start.toInt() + endInclusive.toInt()) + increment) - override fun toString(): String = if (increment > 0) "$start..$end step $increment" else "$start downTo $end step ${-increment}" + override fun toString(): String = if (increment > 0) "$start..$endInclusive step $increment" else "$start downTo $endInclusive step ${-increment}" } /** @@ -77,26 +77,26 @@ public class CharProgression( */ public class ShortProgression( override val start: Short, - override val end: Short, + override val endInclusive: Short, override val increment: Int -) : Progression { +) : InclusiveRangeProgression { init { if (increment == 0) throw IllegalArgumentException("Increment must be non-zero") } - override fun iterator(): ShortIterator = ShortProgressionIterator(start, end, increment) + override fun iterator(): ShortIterator = ShortProgressionIterator(start, endInclusive, increment) /** Checks if the progression is empty. */ - public fun isEmpty(): Boolean = if (increment > 0) start > end else start < end + public fun isEmpty(): Boolean = if (increment > 0) start > endInclusive else start < endInclusive override fun equals(other: Any?): Boolean = other is ShortProgression && (isEmpty() && other.isEmpty() || - start == other.start && end == other.end && increment == other.increment) + start == other.start && endInclusive == other.endInclusive && increment == other.increment) override fun hashCode(): Int = - if (isEmpty()) -1 else (31 * (31 * start.toInt() + end.toInt()) + increment) + if (isEmpty()) -1 else (31 * (31 * start.toInt() + endInclusive.toInt()) + increment) - override fun toString(): String = if (increment > 0) "$start..$end step $increment" else "$start downTo $end step ${-increment}" + override fun toString(): String = if (increment > 0) "$start..$endInclusive step $increment" else "$start downTo $endInclusive step ${-increment}" } /** @@ -104,26 +104,26 @@ public class ShortProgression( */ public class IntProgression( override val start: Int, - override val end: Int, + override val endInclusive: Int, override val increment: Int -) : Progression { +) : InclusiveRangeProgression { init { if (increment == 0) throw IllegalArgumentException("Increment must be non-zero") } - override fun iterator(): IntIterator = IntProgressionIterator(start, end, increment) + override fun iterator(): IntIterator = IntProgressionIterator(start, endInclusive, increment) /** Checks if the progression is empty. */ - public fun isEmpty(): Boolean = if (increment > 0) start > end else start < end + public fun isEmpty(): Boolean = if (increment > 0) start > endInclusive else start < endInclusive override fun equals(other: Any?): Boolean = other is IntProgression && (isEmpty() && other.isEmpty() || - start == other.start && end == other.end && increment == other.increment) + start == other.start && endInclusive == other.endInclusive && increment == other.increment) override fun hashCode(): Int = - if (isEmpty()) -1 else (31 * (31 * start + end) + increment) + if (isEmpty()) -1 else (31 * (31 * start + endInclusive) + increment) - override fun toString(): String = if (increment > 0) "$start..$end step $increment" else "$start downTo $end step ${-increment}" + override fun toString(): String = if (increment > 0) "$start..$endInclusive step $increment" else "$start downTo $endInclusive step ${-increment}" } /** @@ -131,26 +131,26 @@ public class IntProgression( */ public class LongProgression( override val start: Long, - override val end: Long, + override val endInclusive: Long, override val increment: Long -) : Progression { +) : InclusiveRangeProgression { init { if (increment == 0L) throw IllegalArgumentException("Increment must be non-zero") } - override fun iterator(): LongIterator = LongProgressionIterator(start, end, increment) + override fun iterator(): LongIterator = LongProgressionIterator(start, endInclusive, increment) /** Checks if the progression is empty. */ - public fun isEmpty(): Boolean = if (increment > 0) start > end else start < end + public fun isEmpty(): Boolean = if (increment > 0) start > endInclusive else start < endInclusive override fun equals(other: Any?): Boolean = other is LongProgression && (isEmpty() && other.isEmpty() || - start == other.start && end == other.end && increment == other.increment) + start == other.start && endInclusive == other.endInclusive && increment == other.increment) override fun hashCode(): Int = - if (isEmpty()) -1 else (31 * (31 * (start xor (start ushr 32)) + (end xor (end ushr 32))) + (increment xor (increment ushr 32))).toInt() + if (isEmpty()) -1 else (31 * (31 * (start xor (start ushr 32)) + (endInclusive xor (endInclusive ushr 32))) + (increment xor (increment ushr 32))).toInt() - override fun toString(): String = if (increment > 0) "$start..$end step $increment" else "$start downTo $end step ${-increment}" + override fun toString(): String = if (increment > 0) "$start..$endInclusive step $increment" else "$start downTo $endInclusive step ${-increment}" } @Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.WARNING) @@ -160,27 +160,27 @@ public class LongProgression( */ public class FloatProgression( override val start: Float, - override val end: Float, + override val endInclusive: Float, override val increment: Float -) : Progression { +) : InclusiveRangeProgression { init { if (java.lang.Float.isNaN(increment)) throw IllegalArgumentException("Increment must be not NaN") if (increment == 0.0f) throw IllegalArgumentException("Increment must be non-zero") } - override fun iterator(): FloatIterator = FloatProgressionIterator(start, end, increment) + override fun iterator(): FloatIterator = FloatProgressionIterator(start, endInclusive, increment) /** Checks if the progression is empty. */ - public fun isEmpty(): Boolean = if (increment > 0) start > end else start < end + public fun isEmpty(): Boolean = if (increment > 0) start > endInclusive else start < endInclusive override fun equals(other: Any?): Boolean = other is FloatProgression && (isEmpty() && other.isEmpty() || - java.lang.Float.compare(start, other.start) == 0 && java.lang.Float.compare(end, other.end) == 0 && java.lang.Float.compare(increment, other.increment) == 0) + java.lang.Float.compare(start, other.start) == 0 && java.lang.Float.compare(endInclusive, other.endInclusive) == 0 && java.lang.Float.compare(increment, other.increment) == 0) override fun hashCode(): Int = - if (isEmpty()) -1 else (31 * (31 * java.lang.Float.floatToIntBits(start) + java.lang.Float.floatToIntBits(end)) + java.lang.Float.floatToIntBits(increment)) + if (isEmpty()) -1 else (31 * (31 * java.lang.Float.floatToIntBits(start) + java.lang.Float.floatToIntBits(endInclusive)) + java.lang.Float.floatToIntBits(increment)) - override fun toString(): String = if (increment > 0) "$start..$end step $increment" else "$start downTo $end step ${-increment}" + override fun toString(): String = if (increment > 0) "$start..$endInclusive step $increment" else "$start downTo $endInclusive step ${-increment}" } @Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.WARNING) @@ -190,33 +190,33 @@ public class FloatProgression( */ public class DoubleProgression( override val start: Double, - override val end: Double, + override val endInclusive: Double, override val increment: Double -) : Progression { +) : InclusiveRangeProgression { init { if (java.lang.Double.isNaN(increment)) throw IllegalArgumentException("Increment must be not NaN") if (increment == 0.0) throw IllegalArgumentException("Increment must be non-zero") } - override fun iterator(): DoubleIterator = DoubleProgressionIterator(start, end, increment) + override fun iterator(): DoubleIterator = DoubleProgressionIterator(start, endInclusive, increment) /** Checks if the progression is empty. */ - public fun isEmpty(): Boolean = if (increment > 0) start > end else start < end + public fun isEmpty(): Boolean = if (increment > 0) start > endInclusive else start < endInclusive override fun equals(other: Any?): Boolean = other is DoubleProgression && (isEmpty() && other.isEmpty() || - java.lang.Double.compare(start, other.start) == 0 && java.lang.Double.compare(end, other.end) == 0 && java.lang.Double.compare(increment, other.increment) == 0) + java.lang.Double.compare(start, other.start) == 0 && java.lang.Double.compare(endInclusive, other.endInclusive) == 0 && java.lang.Double.compare(increment, other.increment) == 0) override fun hashCode(): Int { if (isEmpty()) return -1 var temp = java.lang.Double.doubleToLongBits(start) var result = (temp xor (temp ushr 32)) - temp = java.lang.Double.doubleToLongBits(end) + temp = java.lang.Double.doubleToLongBits(endInclusive) result = 31 * result + (temp xor (temp ushr 32)) temp = java.lang.Double.doubleToLongBits(increment) return (31 * result + (temp xor (temp ushr 32))).toInt() } - override fun toString(): String = if (increment > 0) "$start..$end step $increment" else "$start downTo $end step ${-increment}" + override fun toString(): String = if (increment > 0) "$start..$endInclusive step $increment" else "$start downTo $endInclusive step ${-increment}" } diff --git a/core/builtins/src/kotlin/Range.kt b/core/builtins/src/kotlin/Range.kt index 29d1213371a..8e688a86808 100644 --- a/core/builtins/src/kotlin/Range.kt +++ b/core/builtins/src/kotlin/Range.kt @@ -20,6 +20,7 @@ package kotlin * Represents a range of values (for example, numbers or characters). * See the [Kotlin language documentation](http://kotlinlang.org/docs/reference/ranges.html) for more information. */ +@Deprecated("This range has unclear inclusiveness of end value. Use InclusiveRange instead.", ReplaceWith("InclusiveRange")) public interface Range> { /** * The minimum value in the range. @@ -41,3 +42,35 @@ public interface Range> { */ public fun isEmpty(): Boolean = start > end } + +/** + * Represents a range of values (for example, numbers or characters). + * See the [Kotlin language documentation](http://kotlinlang.org/docs/reference/ranges.html) for more information. + */ +public interface InclusiveRange> : Range { + /** + * The minimum value in the range. + */ + public override val start: T + + /** + * The maximum value in the range (inclusive). + */ + @Deprecated("Use endInclusive instead.", ReplaceWith("endInclusive")) + public override val end: T get() = endInclusive + + /** + * The maximum value in the range (inclusive). + */ + public val endInclusive: T + + /** + * Checks if the specified value belongs to the range. + */ + public override operator fun contains(item: T): Boolean = item >= start && item <= endInclusive + + /** + * Checks if the range is empty. + */ + public override fun isEmpty(): Boolean = start > endInclusive +} diff --git a/core/builtins/src/kotlin/Ranges.kt b/core/builtins/src/kotlin/Ranges.kt index c183862a050..af194e42dbc 100644 --- a/core/builtins/src/kotlin/Ranges.kt +++ b/core/builtins/src/kotlin/Ranges.kt @@ -21,24 +21,27 @@ package kotlin /** * A range of values of type `Byte`. */ -public class ByteRange(override val start: Byte, override val end: Byte) : Range, Progression { +public class ByteRange(override val start: Byte, override val endInclusive: Byte) : InclusiveRange, InclusiveRangeProgression { + @Deprecated("Use endInclusive instead.", ReplaceWith("endInclusive")) + override val end: Byte get() = endInclusive + override val increment: Int get() = 1 - override fun contains(item: Byte): Boolean = start <= item && item <= end + override fun contains(item: Byte): Boolean = start <= item && item <= endInclusive - override fun iterator(): ByteIterator = ByteProgressionIterator(start, end, 1) + override fun iterator(): ByteIterator = ByteProgressionIterator(start, endInclusive, 1) - override fun isEmpty(): Boolean = start > end + override fun isEmpty(): Boolean = start > endInclusive override fun equals(other: Any?): Boolean = other is ByteRange && (isEmpty() && other.isEmpty() || - start == other.start && end == other.end) + start == other.start && endInclusive == other.endInclusive) override fun hashCode(): Int = - if (isEmpty()) -1 else (31 * start.toInt() + end.toInt()) + if (isEmpty()) -1 else (31 * start.toInt() + endInclusive.toInt()) - override fun toString(): String = "$start..$end" + override fun toString(): String = "$start..$endInclusive" companion object { /** An empty range of values of type Byte. */ @@ -49,24 +52,27 @@ public class ByteRange(override val start: Byte, override val end: Byte) : Range /** * A range of values of type `Char`. */ -public class CharRange(override val start: Char, override val end: Char) : Range, Progression { +public class CharRange(override val start: Char, override val endInclusive: Char) : InclusiveRange, InclusiveRangeProgression { + @Deprecated("Use endInclusive instead.", ReplaceWith("endInclusive")) + override val end: Char get() = endInclusive + override val increment: Int get() = 1 - override fun contains(item: Char): Boolean = start <= item && item <= end + override fun contains(item: Char): Boolean = start <= item && item <= endInclusive - override fun iterator(): CharIterator = CharProgressionIterator(start, end, 1) + override fun iterator(): CharIterator = CharProgressionIterator(start, endInclusive, 1) - override fun isEmpty(): Boolean = start > end + override fun isEmpty(): Boolean = start > endInclusive override fun equals(other: Any?): Boolean = other is CharRange && (isEmpty() && other.isEmpty() || - start == other.start && end == other.end) + start == other.start && endInclusive == other.endInclusive) override fun hashCode(): Int = - if (isEmpty()) -1 else (31 * start.toInt() + end.toInt()) + if (isEmpty()) -1 else (31 * start.toInt() + endInclusive.toInt()) - override fun toString(): String = "$start..$end" + override fun toString(): String = "$start..$endInclusive" companion object { /** An empty range of values of type Char. */ @@ -77,24 +83,27 @@ public class CharRange(override val start: Char, override val end: Char) : Range /** * A range of values of type `Short`. */ -public class ShortRange(override val start: Short, override val end: Short) : Range, Progression { +public class ShortRange(override val start: Short, override val endInclusive: Short) : InclusiveRange, InclusiveRangeProgression { + @Deprecated("Use endInclusive instead.", ReplaceWith("endInclusive")) + override val end: Short get() = endInclusive + override val increment: Int get() = 1 - override fun contains(item: Short): Boolean = start <= item && item <= end + override fun contains(item: Short): Boolean = start <= item && item <= endInclusive - override fun iterator(): ShortIterator = ShortProgressionIterator(start, end, 1) + override fun iterator(): ShortIterator = ShortProgressionIterator(start, endInclusive, 1) - override fun isEmpty(): Boolean = start > end + override fun isEmpty(): Boolean = start > endInclusive override fun equals(other: Any?): Boolean = other is ShortRange && (isEmpty() && other.isEmpty() || - start == other.start && end == other.end) + start == other.start && endInclusive == other.endInclusive) override fun hashCode(): Int = - if (isEmpty()) -1 else (31 * start.toInt() + end.toInt()) + if (isEmpty()) -1 else (31 * start.toInt() + endInclusive.toInt()) - override fun toString(): String = "$start..$end" + override fun toString(): String = "$start..$endInclusive" companion object { /** An empty range of values of type Short. */ @@ -105,24 +114,27 @@ public class ShortRange(override val start: Short, override val end: Short) : Ra /** * A range of values of type `Int`. */ -public class IntRange(override val start: Int, override val end: Int) : Range, Progression { +public class IntRange(override val start: Int, override val endInclusive: Int) : InclusiveRange, InclusiveRangeProgression { + @Deprecated("Use endInclusive instead.", ReplaceWith("endInclusive")) + override val end: Int get() = endInclusive + override val increment: Int get() = 1 - override fun contains(item: Int): Boolean = start <= item && item <= end + override fun contains(item: Int): Boolean = start <= item && item <= endInclusive - override fun iterator(): IntIterator = IntProgressionIterator(start, end, 1) + override fun iterator(): IntIterator = IntProgressionIterator(start, endInclusive, 1) - override fun isEmpty(): Boolean = start > end + override fun isEmpty(): Boolean = start > endInclusive override fun equals(other: Any?): Boolean = other is IntRange && (isEmpty() && other.isEmpty() || - start == other.start && end == other.end) + start == other.start && endInclusive == other.endInclusive) override fun hashCode(): Int = - if (isEmpty()) -1 else (31 * start + end) + if (isEmpty()) -1 else (31 * start + endInclusive) - override fun toString(): String = "$start..$end" + override fun toString(): String = "$start..$endInclusive" companion object { /** An empty range of values of type Int. */ @@ -133,24 +145,27 @@ public class IntRange(override val start: Int, override val end: Int) : Range, Progression { +public class LongRange(override val start: Long, override val endInclusive: Long) : InclusiveRange, InclusiveRangeProgression { + @Deprecated("Use endInclusive instead.", ReplaceWith("endInclusive")) + override val end: Long get() = endInclusive + override val increment: Long get() = 1 - override fun contains(item: Long): Boolean = start <= item && item <= end + override fun contains(item: Long): Boolean = start <= item && item <= endInclusive - override fun iterator(): LongIterator = LongProgressionIterator(start, end, 1) + override fun iterator(): LongIterator = LongProgressionIterator(start, endInclusive, 1) - override fun isEmpty(): Boolean = start > end + override fun isEmpty(): Boolean = start > endInclusive override fun equals(other: Any?): Boolean = other is LongRange && (isEmpty() && other.isEmpty() || - start == other.start && end == other.end) + start == other.start && endInclusive == other.endInclusive) override fun hashCode(): Int = - if (isEmpty()) -1 else (31 * (start xor (start ushr 32)) + (end xor (end ushr 32))).toInt() + if (isEmpty()) -1 else (31 * (start xor (start ushr 32)) + (endInclusive xor (endInclusive ushr 32))).toInt() - override fun toString(): String = "$start..$end" + override fun toString(): String = "$start..$endInclusive" companion object { /** An empty range of values of type Long. */ @@ -163,24 +178,27 @@ public class LongRange(override val start: Long, override val end: Long) : Range /** * A range of values of type `Float`. */ -public class FloatRange(override val start: Float, override val end: Float) : Range, Progression { +public class FloatRange(override val start: Float, override val endInclusive: Float) : InclusiveRange, InclusiveRangeProgression { + @Deprecated("Use endInclusive instead.", ReplaceWith("endInclusive")) + override val end: Float get() = endInclusive + override val increment: Float get() = 1.0f - override fun contains(item: Float): Boolean = start <= item && item <= end + override fun contains(item: Float): Boolean = start <= item && item <= endInclusive - override fun iterator(): FloatIterator = FloatProgressionIterator(start, end, 1.0f) + override fun iterator(): FloatIterator = FloatProgressionIterator(start, endInclusive, 1.0f) - override fun isEmpty(): Boolean = start > end + override fun isEmpty(): Boolean = start > endInclusive override fun equals(other: Any?): Boolean = other is FloatRange && (isEmpty() && other.isEmpty() || - java.lang.Float.compare(start, other.start) == 0 && java.lang.Float.compare(end, other.end) == 0) + java.lang.Float.compare(start, other.start) == 0 && java.lang.Float.compare(endInclusive, other.endInclusive) == 0) override fun hashCode(): Int = - if (isEmpty()) -1 else (31 * java.lang.Float.floatToIntBits(start) + java.lang.Float.floatToIntBits(end)) + if (isEmpty()) -1 else (31 * java.lang.Float.floatToIntBits(start) + java.lang.Float.floatToIntBits(endInclusive)) - override fun toString(): String = "$start..$end" + override fun toString(): String = "$start..$endInclusive" companion object { /** An empty range of values of type Float. */ @@ -193,29 +211,32 @@ public class FloatRange(override val start: Float, override val end: Float) : Ra /** * A range of values of type `Double`. */ -public class DoubleRange(override val start: Double, override val end: Double) : Range, Progression { +public class DoubleRange(override val start: Double, override val endInclusive: Double) : InclusiveRange, InclusiveRangeProgression { + @Deprecated("Use endInclusive instead.", ReplaceWith("endInclusive")) + override val end: Double get() = endInclusive + override val increment: Double get() = 1.0 - override fun contains(item: Double): Boolean = start <= item && item <= end + override fun contains(item: Double): Boolean = start <= item && item <= endInclusive - override fun iterator(): DoubleIterator = DoubleProgressionIterator(start, end, 1.0) + override fun iterator(): DoubleIterator = DoubleProgressionIterator(start, endInclusive, 1.0) - override fun isEmpty(): Boolean = start > end + override fun isEmpty(): Boolean = start > endInclusive override fun equals(other: Any?): Boolean = other is DoubleRange && (isEmpty() && other.isEmpty() || - java.lang.Double.compare(start, other.start) == 0 && java.lang.Double.compare(end, other.end) == 0) + java.lang.Double.compare(start, other.start) == 0 && java.lang.Double.compare(endInclusive, other.endInclusive) == 0) override fun hashCode(): Int { if (isEmpty()) return -1 var temp = java.lang.Double.doubleToLongBits(start) val result = (temp xor (temp ushr 32)) - temp = java.lang.Double.doubleToLongBits(end) + temp = java.lang.Double.doubleToLongBits(endInclusive) return (31 * result + (temp xor (temp ushr 32))).toInt() } - override fun toString(): String = "$start..$end" + override fun toString(): String = "$start..$endInclusive" companion object { /** An empty range of values of type Double. */ diff --git a/generators/src/org/jetbrains/kotlin/generators/builtins/progressions.kt b/generators/src/org/jetbrains/kotlin/generators/builtins/progressions.kt index 88011debdcc..de8fe9a061f 100644 --- a/generators/src/org/jetbrains/kotlin/generators/builtins/progressions.kt +++ b/generators/src/org/jetbrains/kotlin/generators/builtins/progressions.kt @@ -46,18 +46,18 @@ class GenerateProgressions(out: PrintWriter) : BuiltInsSourceGenerator(out) { val hashCode = when (kind) { BYTE, CHAR, SHORT -> "=\n" + - " if (isEmpty()) -1 else (31 * (31 * start.toInt() + end.toInt()) + increment)" + " if (isEmpty()) -1 else (31 * (31 * start.toInt() + endInclusive.toInt()) + increment)" INT -> "=\n" + - " if (isEmpty()) -1 else (31 * (31 * start + end) + increment)" + " if (isEmpty()) -1 else (31 * (31 * start + endInclusive) + increment)" LONG -> "=\n" + - " if (isEmpty()) -1 else (31 * (31 * ${hashLong("start")} + ${hashLong("end")}) + ${hashLong("increment")}).toInt()" + " if (isEmpty()) -1 else (31 * (31 * ${hashLong("start")} + ${hashLong("endInclusive")}) + ${hashLong("increment")}).toInt()" FLOAT -> "=\n" + - " if (isEmpty()) -1 else (31 * (31 * ${floatToIntBits("start")} + ${floatToIntBits("end")}) + ${floatToIntBits("increment")})" + " if (isEmpty()) -1 else (31 * (31 * ${floatToIntBits("start")} + ${floatToIntBits("endInclusive")}) + ${floatToIntBits("increment")})" DOUBLE -> "{\n" + " if (isEmpty()) return -1\n" + " var temp = ${doubleToLongBits("start")}\n" + " var result = ${hashLong("temp")}\n" + - " temp = ${doubleToLongBits("end")}\n" + + " temp = ${doubleToLongBits("endInclusive")}\n" + " result = 31 * result + ${hashLong("temp")}\n" + " temp = ${doubleToLongBits("increment")}\n" + " return (31 * result + ${hashLong("temp")}).toInt()\n" + @@ -75,25 +75,25 @@ class GenerateProgressions(out: PrintWriter) : BuiltInsSourceGenerator(out) { */ public class $progression( override val start: $t, - override val end: $t, + override val endInclusive: $t, override val increment: $incrementType -) : Progression<$t> { +) : InclusiveRangeProgression<$t> { init { $constructor } - override fun iterator(): ${t}Iterator = ${t}ProgressionIterator(start, end, increment) + override fun iterator(): ${t}Iterator = ${t}ProgressionIterator(start, endInclusive, increment) /** Checks if the progression is empty. */ - public fun isEmpty(): Boolean = if (increment > 0) start > end else start < end + public fun isEmpty(): Boolean = if (increment > 0) start > endInclusive else start < endInclusive override fun equals(other: Any?): Boolean = other is $progression && (isEmpty() && other.isEmpty() || - ${compare("start")} && ${compare("end")} && ${compare("increment")}) + ${compare("start")} && ${compare("endInclusive")} && ${compare("increment")}) override fun hashCode(): Int $hashCode - override fun toString(): String = ${"if (increment > 0) \"\$start..\$end step \$increment\" else \"\$start downTo \$end step \${-increment}\""} + override fun toString(): String = ${"if (increment > 0) \"\$start..\$endInclusive step \$increment\" else \"\$start downTo \$endInclusive step \${-increment}\""} }""") out.println() } diff --git a/generators/src/org/jetbrains/kotlin/generators/builtins/ranges.kt b/generators/src/org/jetbrains/kotlin/generators/builtins/ranges.kt index 881b8b16818..fdd51142152 100644 --- a/generators/src/org/jetbrains/kotlin/generators/builtins/ranges.kt +++ b/generators/src/org/jetbrains/kotlin/generators/builtins/ranges.kt @@ -46,23 +46,23 @@ class GenerateRanges(out: PrintWriter) : BuiltInsSourceGenerator(out) { val hashCode = when (kind) { BYTE, CHAR, SHORT -> "=\n" + - " if (isEmpty()) -1 else (31 * start.toInt() + end.toInt())" + " if (isEmpty()) -1 else (31 * start.toInt() + endInclusive.toInt())" INT -> "=\n" + - " if (isEmpty()) -1 else (31 * start + end)" + " if (isEmpty()) -1 else (31 * start + endInclusive)" LONG -> "=\n" + - " if (isEmpty()) -1 else (31 * ${hashLong("start")} + ${hashLong("end")}).toInt()" + " if (isEmpty()) -1 else (31 * ${hashLong("start")} + ${hashLong("endInclusive")}).toInt()" FLOAT -> "=\n" + - " if (isEmpty()) -1 else (31 * ${floatToIntBits("start")} + ${floatToIntBits("end")})" + " if (isEmpty()) -1 else (31 * ${floatToIntBits("start")} + ${floatToIntBits("endInclusive")})" DOUBLE -> "{\n" + " if (isEmpty()) return -1\n" + " var temp = ${doubleToLongBits("start")}\n" + " val result = ${hashLong("temp")}\n" + - " temp = ${doubleToLongBits("end")}\n" + + " temp = ${doubleToLongBits("endInclusive")}\n" + " return (31 * result + ${hashLong("temp")}).toInt()\n" + " }" } - val toString = "\"\$start..\$end\"" + val toString = "\"\$start..\$endInclusive\"" if (kind == FLOAT || kind == DOUBLE) { out.println("""@Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.WARNING)""") @@ -73,19 +73,22 @@ class GenerateRanges(out: PrintWriter) : BuiltInsSourceGenerator(out) { """/** * A range of values of type `$t`. */ -public class $range(override val start: $t, override val end: $t) : Range<$t>, Progression<$t> { +public class $range(override val start: $t, override val endInclusive: $t) : InclusiveRange<$t>, InclusiveRangeProgression<$t> { + @Deprecated("Use endInclusive instead.", ReplaceWith("endInclusive")) + override val end: $t get() = endInclusive + override val increment: $incrementType get() = $increment - override fun contains(item: $t): Boolean = start <= item && item <= end + override fun contains(item: $t): Boolean = start <= item && item <= endInclusive - override fun iterator(): ${t}Iterator = ${t}ProgressionIterator(start, end, $increment) + override fun iterator(): ${t}Iterator = ${t}ProgressionIterator(start, endInclusive, $increment) - override fun isEmpty(): Boolean = start > end + override fun isEmpty(): Boolean = start > endInclusive override fun equals(other: Any?): Boolean = other is $range && (isEmpty() && other.isEmpty() || - ${compare("start")} && ${compare("end")}) + ${compare("start")} && ${compare("endInclusive")}) override fun hashCode(): Int $hashCode