
walkmc.extensions.collections.DoubleProgression.kt Maven / Gradle / Ivy
@file:Suppress("NOTHING_TO_INLINE")
package walkmc.extensions.collections
typealias DoubleRange = ClosedFloatingPointRange
/**
* Represents a double progression to extends the kotlin range.
* This is very similar than [IntProgression]
*/
class DoubleProgression(
override val start: Double,
override val endInclusive: Double,
val step: Double,
var overflow: Boolean = false,
) : ClosedFloatingPointRange, Iterable {
override fun iterator(): Iterator = DoubleProgressionIterator(start, endInclusive, step, overflow)
override fun lessThanOrEquals(a: Double, b: Double): Boolean = a <= b
override fun contains(value: Double): Boolean = value in start..endInclusive
override fun isEmpty(): Boolean = start > endInclusive
override fun equals(other: Any?): Boolean =
other is DoubleProgression &&
(isEmpty() && other.isEmpty() || start == other.start && endInclusive == other.endInclusive)
override fun hashCode(): Int = if (isEmpty()) -1 else 31 * start.hashCode() + endInclusive.hashCode()
override fun toString(): String = "$start..$endInclusive"
}
/**
* A progression iterator for double progressions.
*/
internal class DoubleProgressionIterator(
first: Double,
last: Double,
val step: Double,
var overflow: Boolean,
) : DoubleIterator() {
private val finalElement = last
private var hasNext = if (step > 0) first <= last else first >= last
private var next = if (hasNext) first else last
override fun hasNext(): Boolean = hasNext
override fun nextDouble(): Double {
val value = next
val bool = if (overflow) value >= finalElement else (value + step) > finalElement
if (bool) {
if (!hasNext) throw kotlin.NoSuchElementException()
hasNext = false
} else {
next += step
}
return value
}
}
/**
* Creates a [DoubleProgression] from this double floating point range by the specified [step].
*/
infix fun ClosedFloatingPointRange.step(step: Number): DoubleProgression =
DoubleProgression(start, endInclusive, step.toDouble())
/**
* Changes if this double progression can overflow or not. For example:
*
* prints (1.0, 3.0, 5.0)
* ```
* for (index in 1.0..5.0 step 2.0 overflow false)
* println(index)
* ```
*
* prints (1.0, 3.0, 5.0, 7.0)
* ```
* for (index in 1.0..5.0 step 2.0 overflow true)
* println(index)
* ```
*
* By defaults overflow is false.
*/
infix fun DoubleProgression.overflow(overflow: Boolean): DoubleProgression {
this.overflow = overflow
return this
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy