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

commonMain.HalfOpenIntRange.kt Maven / Gradle / Ivy

package io.fluidsonic.stdlib

import kotlin.math.*


public class HalfOpenIntRange(
	start: Int,
	endExclusive: Int
) : HalfOpenRange, Iterable {

	public val startValue: Int = start
	public val endValueExclusive: Int = endExclusive


	init {
		freeze()
	}


	@Deprecated(
		message = "use .endValueInclusive to avoid boxing",
		replaceWith = ReplaceWith("endValueExclusive"),
		level = DeprecationLevel.WARNING
	)
	override val endExclusive: Int
		get() = endValueExclusive


	public operator fun component1(): Int =
		startValue


	public operator fun component2(): Int =
		endValueExclusive


	override operator fun contains(value: Int): Boolean =
		value in startValue until endValueExclusive


	override fun equals(other: Any?): Boolean =
		this === other ||
			(other is HalfOpenIntRange && startValue == other.startValue && endValueExclusive == other.endValueExclusive) ||
			(other is HalfOpenRange<*> && startValue == other.start && endValueExclusive == other.endExclusive)


	override fun hashCode(): Int =
		hash { startValue x endValueExclusive }


	override fun isEmpty(): Boolean =
		startValue >= endValueExclusive


	override operator fun iterator(): IntIterator =
		when (startValue) {
			endValueExclusive -> emptyRange.iterator()
			else -> (startValue until endValueExclusive).iterator()
		}


	@Deprecated(
		message = "use .startValue to avoid boxing",
		replaceWith = ReplaceWith("startValue"),
		level = DeprecationLevel.WARNING
	)
	override val start: Int
		get() = startValue


	public companion object {

		@Suppress("EmptyRange")
		private val emptyRange = 1 .. 0
	}
}


public fun HalfOpenIntRange.contains(other: HalfOpenIntRange): Boolean =
	contains(other.startValue) && other.endValueExclusive <= endValueExclusive


public fun HalfOpenIntRange.flipped(): HalfOpenIntRange =
	endValueExclusive rangeToExcluding startValue


public fun HalfOpenIntRange.intersection(other: HalfOpenIntRange): HalfOpenIntRange? =
	overlaps(other).thenTake { max(startValue, other.startValue) rangeToExcluding min(endValueExclusive, other.endValueExclusive) }


public fun HalfOpenIntRange.overlaps(other: HalfOpenIntRange): Boolean =
	contains(other.startValue) || other.contains(startValue)


public inline fun HalfOpenIntRange.mapBounds(transform: (Int) -> Int): HalfOpenIntRange =
	transform(startValue) rangeToExcluding transform(endValueExclusive)


public inline fun > HalfOpenIntRange.mapBounds(transform: (Int) -> R): HalfOpenRange =
	transform(startValue) rangeToExcluding transform(endValueExclusive)


public fun HalfOpenIntRange.subtracting(rangeToSubtract: HalfOpenIntRange): List {
	if (rangeToSubtract.startValue >= endValueExclusive || rangeToSubtract.endValueExclusive <= startValue)
		return listOf(this)

	val result = mutableListOf()
	if (rangeToSubtract.startValue > startValue)
		result.add(startValue rangeToExcluding rangeToSubtract.startValue)
	if (rangeToSubtract.endValueExclusive < endValueExclusive)
		result.add(rangeToSubtract.endValueExclusive rangeToExcluding endValueExclusive)

	return result
}


public fun HalfOpenIntRange.toSequence(nextFunction: (Int) -> Int?): Sequence =
	when {
		isEmpty() -> emptySequence()
		else -> generateSequence(startValue) { start ->
			nextFunction(start)?.takeIf { value -> contains(value) }
		}
	}


public infix fun Int.rangeToExcluding(that: Int): HalfOpenIntRange =
	HalfOpenIntRange(start = this, endExclusive = that)




© 2015 - 2024 Weber Informatics LLC | Privacy Policy