All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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