RangeExtensions.kt
package me.thorny.twoColoredRange.rangeUtils
import me.thorny.twoColoredRange.math.BoundMath
/**
* Checks if [other] range is entirely inside [this].
*/
fun <BoundType: Comparable<BoundType>> ClosedRange<BoundType>.containsRange(
other: ClosedRange<BoundType>,
): Boolean {
return this.start <= other.start && this.endInclusive >= other.endInclusive
}
/**
* Checks if [other] range intersects [this].
*/
fun <BoundType: Comparable<BoundType>> ClosedRange<BoundType>.intersectsRange(
other: ClosedRange<BoundType>,
): Boolean {
return this.start <= other.endInclusive && this.endInclusive >= other.start
}
/**
* Returns a new range by joining [other] range and [this].
*
* @param other the other range.
* @param rangeFactory the range factory.
*/
fun <BoundType: Comparable<BoundType>> ClosedRange<BoundType>.joinedByRange(
other: ClosedRange<BoundType>,
rangeFactory: RangeFactory<BoundType>,
): ClosedRange<BoundType> {
return rangeFactory.makeRange(minOf(this.start, other.start), maxOf(this.endInclusive, other.endInclusive))
}
/**
* Returns a new range by trimming [this] by [other]'s bounds.
*
* @param other the other range.
* @param rangeFactory the range factory.
*/
fun <BoundType: Comparable<BoundType>> ClosedRange<BoundType>.trimmedByRange(
other: ClosedRange<BoundType>,
rangeFactory: RangeFactory<BoundType>,
): ClosedRange<BoundType> {
return rangeFactory.makeRange(maxOf(this.start, other.start), minOf(this.endInclusive, other.endInclusive))
}
/**
* Checks if [other] range is located on a distance of [step] away from [this].
*
* @param other the other range.
* @param step the distance.
* @param math the math.
*/
fun <BoundType: Comparable<BoundType>, LengthType: Comparable<LengthType>> ClosedRange<BoundType>.touchesRange(
other: ClosedRange<BoundType>,
step: LengthType,
math: BoundMath<BoundType, LengthType>,
): Boolean {
return math.add(this.endInclusive, step) == other.start || math.add(other.endInclusive, step) == this.start
}
/**
* Cuts [other] range from [this] and returns a list of non-empty pieces that are left.
*
* @param other the other range.
* @param step minimal non-zero range length.
* @param math the math.
*/
fun <BoundType: Comparable<BoundType>, LengthType: Comparable<LengthType>> ClosedRange<BoundType>.splitByRange(
other: ClosedRange<BoundType>,
step: LengthType,
math: BoundMath<BoundType, LengthType>,
rangeFactory: RangeFactory<BoundType>,
): List<ClosedRange<BoundType>> {
return listOf(
rangeFactory.makeRange(this.start, math.subtract(other.start, step)),
rangeFactory.makeRange(math.add(other.endInclusive, step), this.endInclusive),
).filterNot(ClosedRange<BoundType>::isEmpty)
}