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

walkmc.extensions.collections.FloatProgression.kt Maven / Gradle / Ivy

There is a newer version: 2.4.0
Show newest version
@file:Suppress("NOTHING_TO_INLINE")

package walkmc.extensions.collections

typealias FloatRange = ClosedFloatingPointRange

/**
 * Represents a float progression to extends the kotlin range.
 * This is very similar than [IntProgression]
 */
class FloatProgression(
   override val start: Float,
   override val endInclusive: Float,
   val step: Float,
   var overflow: Boolean = false,
) : ClosedFloatingPointRange, Iterable {
   override fun iterator(): Iterator = FloatProgressionIterator(start, endInclusive, step, overflow)
   
   override fun lessThanOrEquals(a: Float, b: Float): Boolean = a <= b
   
   override fun contains(value: Float): Boolean = value in start..endInclusive
   override fun isEmpty(): Boolean = start > endInclusive
   
   override fun equals(other: Any?): Boolean =
      other is FloatProgression &&
         (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 float progressions.
 */
internal class FloatProgressionIterator(
   first: Float,
   last: Float,
   val step: Float,
   var overflow: Boolean,
) : FloatIterator() {
   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 nextFloat(): Float {
      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 [FloatProgression] from this float floating point range by the specified [step].
 */
inline infix fun ClosedFloatingPointRange.step(step: Number): FloatProgression =
   FloatProgression(start, endInclusive, step.toFloat())

/**
 * Changes if this float progression can overflow or not. For example:
 *
 * ```kt
 * for (index in 1f..5f step 1.5 overflow false)
 *   println(index) // prints [1.0, 2.5, 4.0]
 *
 * for (index in 1f..5f step 1.5 overflow true)
 *   println(index) // prints [1.0, 2.5, 4.0, 5.5]
 * ```
 *
 * By defaults overflow is false.
 */
infix fun FloatProgression.overflow(overflow: Boolean): FloatProgression {
   this.overflow = overflow
   return this
}





© 2015 - 2025 Weber Informatics LLC | Privacy Policy