Introduce InclusiveRange and InclusiveRangeProgression and deprecate Range and Progression interfaces.

This commit is contained in:
Ilya Gorbunov
2015-10-18 19:06:56 +03:00
parent cea27dd716
commit e699ce9e95
6 changed files with 209 additions and 120 deletions
+32
View File
@@ -22,6 +22,7 @@ package kotlin
* bytecode generation for it. Progressions with a step of -1 can be created through the * bytecode generation for it. Progressions with a step of -1 can be created through the
* `downTo` method on classes representing primitive types. * `downTo` method on classes representing primitive types.
*/ */
@Deprecated("This progression has unclear inclusiveness of end value. Use InclusiveRangeProgression instead.", ReplaceWith("InclusiveRangeProgression<N>"))
public interface Progression<out N : Any> : Iterable<N> { public interface Progression<out N : Any> : Iterable<N> {
/** /**
* The start value of the progression. * The start value of the progression.
@@ -38,3 +39,34 @@ public interface Progression<out N : Any> : Iterable<N> {
*/ */
public val increment: Number 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<out N : Any> : Progression<N> {
/**
* 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
}
+49 -49
View File
@@ -23,26 +23,26 @@ package kotlin
*/ */
public class ByteProgression( public class ByteProgression(
override val start: Byte, override val start: Byte,
override val end: Byte, override val endInclusive: Byte,
override val increment: Int override val increment: Int
) : Progression<Byte> { ) : InclusiveRangeProgression<Byte> {
init { init {
if (increment == 0) throw IllegalArgumentException("Increment must be non-zero") 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. */ /** 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 = override fun equals(other: Any?): Boolean =
other is ByteProgression && (isEmpty() && other.isEmpty() || 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 = 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( public class CharProgression(
override val start: Char, override val start: Char,
override val end: Char, override val endInclusive: Char,
override val increment: Int override val increment: Int
) : Progression<Char> { ) : InclusiveRangeProgression<Char> {
init { init {
if (increment == 0) throw IllegalArgumentException("Increment must be non-zero") 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. */ /** 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 = override fun equals(other: Any?): Boolean =
other is CharProgression && (isEmpty() && other.isEmpty() || 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 = 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( public class ShortProgression(
override val start: Short, override val start: Short,
override val end: Short, override val endInclusive: Short,
override val increment: Int override val increment: Int
) : Progression<Short> { ) : InclusiveRangeProgression<Short> {
init { init {
if (increment == 0) throw IllegalArgumentException("Increment must be non-zero") 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. */ /** 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 = override fun equals(other: Any?): Boolean =
other is ShortProgression && (isEmpty() && other.isEmpty() || 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 = 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( public class IntProgression(
override val start: Int, override val start: Int,
override val end: Int, override val endInclusive: Int,
override val increment: Int override val increment: Int
) : Progression<Int> { ) : InclusiveRangeProgression<Int> {
init { init {
if (increment == 0) throw IllegalArgumentException("Increment must be non-zero") 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. */ /** 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 = override fun equals(other: Any?): Boolean =
other is IntProgression && (isEmpty() && other.isEmpty() || 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 = 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( public class LongProgression(
override val start: Long, override val start: Long,
override val end: Long, override val endInclusive: Long,
override val increment: Long override val increment: Long
) : Progression<Long> { ) : InclusiveRangeProgression<Long> {
init { init {
if (increment == 0L) throw IllegalArgumentException("Increment must be non-zero") 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. */ /** 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 = override fun equals(other: Any?): Boolean =
other is LongProgression && (isEmpty() && other.isEmpty() || 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 = 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) @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( public class FloatProgression(
override val start: Float, override val start: Float,
override val end: Float, override val endInclusive: Float,
override val increment: Float override val increment: Float
) : Progression<Float> { ) : InclusiveRangeProgression<Float> {
init { init {
if (java.lang.Float.isNaN(increment)) throw IllegalArgumentException("Increment must be not NaN") if (java.lang.Float.isNaN(increment)) throw IllegalArgumentException("Increment must be not NaN")
if (increment == 0.0f) throw IllegalArgumentException("Increment must be non-zero") 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. */ /** 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 = override fun equals(other: Any?): Boolean =
other is FloatProgression && (isEmpty() && other.isEmpty() || 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 = 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) @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( public class DoubleProgression(
override val start: Double, override val start: Double,
override val end: Double, override val endInclusive: Double,
override val increment: Double override val increment: Double
) : Progression<Double> { ) : InclusiveRangeProgression<Double> {
init { init {
if (java.lang.Double.isNaN(increment)) throw IllegalArgumentException("Increment must be not NaN") if (java.lang.Double.isNaN(increment)) throw IllegalArgumentException("Increment must be not NaN")
if (increment == 0.0) throw IllegalArgumentException("Increment must be non-zero") 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. */ /** 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 = override fun equals(other: Any?): Boolean =
other is DoubleProgression && (isEmpty() && other.isEmpty() || 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 { override fun hashCode(): Int {
if (isEmpty()) return -1 if (isEmpty()) return -1
var temp = java.lang.Double.doubleToLongBits(start) var temp = java.lang.Double.doubleToLongBits(start)
var result = (temp xor (temp ushr 32)) 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)) result = 31 * result + (temp xor (temp ushr 32))
temp = java.lang.Double.doubleToLongBits(increment) temp = java.lang.Double.doubleToLongBits(increment)
return (31 * result + (temp xor (temp ushr 32))).toInt() 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}"
} }
+33
View File
@@ -20,6 +20,7 @@ package kotlin
* Represents a range of values (for example, numbers or characters). * 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. * 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<T>"))
public interface Range<T : Comparable<T>> { public interface Range<T : Comparable<T>> {
/** /**
* The minimum value in the range. * The minimum value in the range.
@@ -41,3 +42,35 @@ public interface Range<T : Comparable<T>> {
*/ */
public fun isEmpty(): Boolean = start > end 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<T: Comparable<T>> : Range<T> {
/**
* 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
}
+70 -49
View File
@@ -21,24 +21,27 @@ package kotlin
/** /**
* A range of values of type `Byte`. * A range of values of type `Byte`.
*/ */
public class ByteRange(override val start: Byte, override val end: Byte) : Range<Byte>, Progression<Byte> { public class ByteRange(override val start: Byte, override val endInclusive: Byte) : InclusiveRange<Byte>, InclusiveRangeProgression<Byte> {
@Deprecated("Use endInclusive instead.", ReplaceWith("endInclusive"))
override val end: Byte get() = endInclusive
override val increment: Int override val increment: Int
get() = 1 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 = override fun equals(other: Any?): Boolean =
other is ByteRange && (isEmpty() && other.isEmpty() || other is ByteRange && (isEmpty() && other.isEmpty() ||
start == other.start && end == other.end) start == other.start && endInclusive == other.endInclusive)
override fun hashCode(): Int = 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 { companion object {
/** An empty range of values of type Byte. */ /** 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`. * A range of values of type `Char`.
*/ */
public class CharRange(override val start: Char, override val end: Char) : Range<Char>, Progression<Char> { public class CharRange(override val start: Char, override val endInclusive: Char) : InclusiveRange<Char>, InclusiveRangeProgression<Char> {
@Deprecated("Use endInclusive instead.", ReplaceWith("endInclusive"))
override val end: Char get() = endInclusive
override val increment: Int override val increment: Int
get() = 1 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 = override fun equals(other: Any?): Boolean =
other is CharRange && (isEmpty() && other.isEmpty() || other is CharRange && (isEmpty() && other.isEmpty() ||
start == other.start && end == other.end) start == other.start && endInclusive == other.endInclusive)
override fun hashCode(): Int = 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 { companion object {
/** An empty range of values of type Char. */ /** 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`. * A range of values of type `Short`.
*/ */
public class ShortRange(override val start: Short, override val end: Short) : Range<Short>, Progression<Short> { public class ShortRange(override val start: Short, override val endInclusive: Short) : InclusiveRange<Short>, InclusiveRangeProgression<Short> {
@Deprecated("Use endInclusive instead.", ReplaceWith("endInclusive"))
override val end: Short get() = endInclusive
override val increment: Int override val increment: Int
get() = 1 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 = override fun equals(other: Any?): Boolean =
other is ShortRange && (isEmpty() && other.isEmpty() || other is ShortRange && (isEmpty() && other.isEmpty() ||
start == other.start && end == other.end) start == other.start && endInclusive == other.endInclusive)
override fun hashCode(): Int = 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 { companion object {
/** An empty range of values of type Short. */ /** 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`. * A range of values of type `Int`.
*/ */
public class IntRange(override val start: Int, override val end: Int) : Range<Int>, Progression<Int> { public class IntRange(override val start: Int, override val endInclusive: Int) : InclusiveRange<Int>, InclusiveRangeProgression<Int> {
@Deprecated("Use endInclusive instead.", ReplaceWith("endInclusive"))
override val end: Int get() = endInclusive
override val increment: Int override val increment: Int
get() = 1 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 = override fun equals(other: Any?): Boolean =
other is IntRange && (isEmpty() && other.isEmpty() || other is IntRange && (isEmpty() && other.isEmpty() ||
start == other.start && end == other.end) start == other.start && endInclusive == other.endInclusive)
override fun hashCode(): Int = 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 { companion object {
/** An empty range of values of type Int. */ /** An empty range of values of type Int. */
@@ -133,24 +145,27 @@ public class IntRange(override val start: Int, override val end: Int) : Range<In
/** /**
* A range of values of type `Long`. * A range of values of type `Long`.
*/ */
public class LongRange(override val start: Long, override val end: Long) : Range<Long>, Progression<Long> { public class LongRange(override val start: Long, override val endInclusive: Long) : InclusiveRange<Long>, InclusiveRangeProgression<Long> {
@Deprecated("Use endInclusive instead.", ReplaceWith("endInclusive"))
override val end: Long get() = endInclusive
override val increment: Long override val increment: Long
get() = 1 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 = override fun equals(other: Any?): Boolean =
other is LongRange && (isEmpty() && other.isEmpty() || other is LongRange && (isEmpty() && other.isEmpty() ||
start == other.start && end == other.end) start == other.start && endInclusive == other.endInclusive)
override fun hashCode(): Int = 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 { companion object {
/** An empty range of values of type Long. */ /** 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`. * A range of values of type `Float`.
*/ */
public class FloatRange(override val start: Float, override val end: Float) : Range<Float>, Progression<Float> { public class FloatRange(override val start: Float, override val endInclusive: Float) : InclusiveRange<Float>, InclusiveRangeProgression<Float> {
@Deprecated("Use endInclusive instead.", ReplaceWith("endInclusive"))
override val end: Float get() = endInclusive
override val increment: Float override val increment: Float
get() = 1.0f 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 = override fun equals(other: Any?): Boolean =
other is FloatRange && (isEmpty() && other.isEmpty() || 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 = 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 { companion object {
/** An empty range of values of type Float. */ /** 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`. * A range of values of type `Double`.
*/ */
public class DoubleRange(override val start: Double, override val end: Double) : Range<Double>, Progression<Double> { public class DoubleRange(override val start: Double, override val endInclusive: Double) : InclusiveRange<Double>, InclusiveRangeProgression<Double> {
@Deprecated("Use endInclusive instead.", ReplaceWith("endInclusive"))
override val end: Double get() = endInclusive
override val increment: Double override val increment: Double
get() = 1.0 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 = override fun equals(other: Any?): Boolean =
other is DoubleRange && (isEmpty() && other.isEmpty() || 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 { override fun hashCode(): Int {
if (isEmpty()) return -1 if (isEmpty()) return -1
var temp = java.lang.Double.doubleToLongBits(start) var temp = java.lang.Double.doubleToLongBits(start)
val result = (temp xor (temp ushr 32)) 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() return (31 * result + (temp xor (temp ushr 32))).toInt()
} }
override fun toString(): String = "$start..$end" override fun toString(): String = "$start..$endInclusive"
companion object { companion object {
/** An empty range of values of type Double. */ /** An empty range of values of type Double. */
@@ -46,18 +46,18 @@ class GenerateProgressions(out: PrintWriter) : BuiltInsSourceGenerator(out) {
val hashCode = when (kind) { val hashCode = when (kind) {
BYTE, CHAR, SHORT -> "=\n" + 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" + INT -> "=\n" +
" if (isEmpty()) -1 else (31 * (31 * start + end) + increment)" " if (isEmpty()) -1 else (31 * (31 * start + endInclusive) + increment)"
LONG -> "=\n" + 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" + 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" + DOUBLE -> "{\n" +
" if (isEmpty()) return -1\n" + " if (isEmpty()) return -1\n" +
" var temp = ${doubleToLongBits("start")}\n" + " var temp = ${doubleToLongBits("start")}\n" +
" var result = ${hashLong("temp")}\n" + " var result = ${hashLong("temp")}\n" +
" temp = ${doubleToLongBits("end")}\n" + " temp = ${doubleToLongBits("endInclusive")}\n" +
" result = 31 * result + ${hashLong("temp")}\n" + " result = 31 * result + ${hashLong("temp")}\n" +
" temp = ${doubleToLongBits("increment")}\n" + " temp = ${doubleToLongBits("increment")}\n" +
" return (31 * result + ${hashLong("temp")}).toInt()\n" + " return (31 * result + ${hashLong("temp")}).toInt()\n" +
@@ -75,25 +75,25 @@ class GenerateProgressions(out: PrintWriter) : BuiltInsSourceGenerator(out) {
*/ */
public class $progression( public class $progression(
override val start: $t, override val start: $t,
override val end: $t, override val endInclusive: $t,
override val increment: $incrementType override val increment: $incrementType
) : Progression<$t> { ) : InclusiveRangeProgression<$t> {
init { init {
$constructor $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. */ /** 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 = override fun equals(other: Any?): Boolean =
other is $progression && (isEmpty() && other.isEmpty() || 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 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() out.println()
} }
@@ -46,23 +46,23 @@ class GenerateRanges(out: PrintWriter) : BuiltInsSourceGenerator(out) {
val hashCode = when (kind) { val hashCode = when (kind) {
BYTE, CHAR, SHORT -> "=\n" + BYTE, CHAR, SHORT -> "=\n" +
" if (isEmpty()) -1 else (31 * start.toInt() + end.toInt())" " if (isEmpty()) -1 else (31 * start.toInt() + endInclusive.toInt())"
INT -> "=\n" + INT -> "=\n" +
" if (isEmpty()) -1 else (31 * start + end)" " if (isEmpty()) -1 else (31 * start + endInclusive)"
LONG -> "=\n" + LONG -> "=\n" +
" if (isEmpty()) -1 else (31 * ${hashLong("start")} + ${hashLong("end")}).toInt()" " if (isEmpty()) -1 else (31 * ${hashLong("start")} + ${hashLong("endInclusive")}).toInt()"
FLOAT -> "=\n" + FLOAT -> "=\n" +
" if (isEmpty()) -1 else (31 * ${floatToIntBits("start")} + ${floatToIntBits("end")})" " if (isEmpty()) -1 else (31 * ${floatToIntBits("start")} + ${floatToIntBits("endInclusive")})"
DOUBLE -> "{\n" + DOUBLE -> "{\n" +
" if (isEmpty()) return -1\n" + " if (isEmpty()) return -1\n" +
" var temp = ${doubleToLongBits("start")}\n" + " var temp = ${doubleToLongBits("start")}\n" +
" val result = ${hashLong("temp")}\n" + " val result = ${hashLong("temp")}\n" +
" temp = ${doubleToLongBits("end")}\n" + " temp = ${doubleToLongBits("endInclusive")}\n" +
" return (31 * result + ${hashLong("temp")}).toInt()\n" + " return (31 * result + ${hashLong("temp")}).toInt()\n" +
" }" " }"
} }
val toString = "\"\$start..\$end\"" val toString = "\"\$start..\$endInclusive\""
if (kind == FLOAT || kind == DOUBLE) { if (kind == FLOAT || kind == DOUBLE) {
out.println("""@Deprecated("This range implementation has unclear semantics and will be removed soon.", level = DeprecationLevel.WARNING)""") 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`. * 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 override val increment: $incrementType
get() = $increment 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 = override fun equals(other: Any?): Boolean =
other is $range && (isEmpty() && other.isEmpty() || other is $range && (isEmpty() && other.isEmpty() ||
${compare("start")} && ${compare("end")}) ${compare("start")} && ${compare("endInclusive")})
override fun hashCode(): Int $hashCode override fun hashCode(): Int $hashCode