Generate until, downTo, step, reversed functions for unsigned ranges/progressions

This commit is contained in:
Ilya Gorbunov
2018-08-15 19:32:45 +03:00
parent add0894f54
commit 3d2eb36486
4 changed files with 320 additions and 35 deletions
@@ -4135,6 +4135,21 @@ public final class kotlin/ranges/ULongRange$Companion {
public final fun getEMPTY ()Lkotlin/ranges/ULongRange;
}
public final class kotlin/ranges/URangesKt {
public static final fun downTo (BB)Lkotlin/ranges/UIntProgression;
public static final fun downTo (II)Lkotlin/ranges/UIntProgression;
public static final fun downTo (JJ)Lkotlin/ranges/ULongProgression;
public static final fun downTo (SS)Lkotlin/ranges/UIntProgression;
public static final fun reversed (Lkotlin/ranges/UIntProgression;)Lkotlin/ranges/UIntProgression;
public static final fun reversed (Lkotlin/ranges/ULongProgression;)Lkotlin/ranges/ULongProgression;
public static final fun step (Lkotlin/ranges/UIntProgression;I)Lkotlin/ranges/UIntProgression;
public static final fun step (Lkotlin/ranges/ULongProgression;J)Lkotlin/ranges/ULongProgression;
public static final fun until (BB)Lkotlin/ranges/UIntRange;
public static final fun until (II)Lkotlin/ranges/UIntRange;
public static final fun until (JJ)Lkotlin/ranges/ULongRange;
public static final fun until (SS)Lkotlin/ranges/UIntRange;
}
public abstract interface class kotlin/reflect/KAnnotatedElement {
public abstract fun getAnnotations ()Ljava/util/List;
}
@@ -10,9 +10,15 @@ import templates.PrimitiveType.Companion.maxByCapacity
object RangeOps : TemplateGroupBase() {
private val rangePrimitives = setOf(PrimitiveType.Int, PrimitiveType.Long, PrimitiveType.Char)
private fun rangeElementType(fromType: PrimitiveType, toType: PrimitiveType)
= maxByCapacity(fromType, toType).let { if (it == PrimitiveType.Char) it else maxByCapacity(it, PrimitiveType.Int) }
private val rangePrimitives = setOf(PrimitiveType.Int, PrimitiveType.Long, PrimitiveType.Char, PrimitiveType.UInt, PrimitiveType.ULong)
private fun rangeElementType(fromType: PrimitiveType, toType: PrimitiveType) =
maxByCapacity(fromType, toType).let {
when {
it == PrimitiveType.Char -> it
it in PrimitiveType.unsignedPrimitives -> maxByCapacity(it, PrimitiveType.UInt)
else -> maxByCapacity(it, PrimitiveType.Int)
}
}
private fun <T> Collection<T>.permutations(): List<Pair<T, T>> = flatMap { a -> map { b -> a to b } }
@@ -20,7 +26,25 @@ object RangeOps : TemplateGroupBase() {
private val numericPermutations = numericPrimitives.permutations()
private val primitivePermutations = numericPermutations + (PrimitiveType.Char to PrimitiveType.Char)
private val integralPermutations = primitivePermutations.filter { it.first.isIntegral() && it.second.isIntegral() }
private val unsignedPermutations = PrimitiveType.unsignedPrimitives.map { it to it }
val PrimitiveType.stepType get() = when(this) {
PrimitiveType.Char -> "Int"
PrimitiveType.Int, PrimitiveType.Long -> name
PrimitiveType.UInt, PrimitiveType.ULong -> name.drop(1)
else -> error("Unsupported progression specialization: $this")
}
init {
defaultBuilder {
sourceFile(SourceFile.Ranges)
if (primitive in PrimitiveType.unsignedPrimitives) {
since("1.3")
annotation("@ExperimentalUnsignedTypes")
sourceFile(SourceFile.URanges)
}
}
}
val f_reversed = fn("reversed()") {
include(ProgressionsOfPrimitives, rangePrimitives)
@@ -32,11 +56,12 @@ object RangeOps : TemplateGroupBase() {
}
}
val f_step = fn("step(step: SUM)") {
val f_step = fn("step(step: STEP)") {
include(ProgressionsOfPrimitives, rangePrimitives)
} builder {
infix(true)
doc { "Returns a progression that goes over the same range with the given step." }
signature("step(step: ${primitive!!.stepType})", notForSorting = true)
returns("TProgression")
body {
"""
@@ -47,10 +72,8 @@ object RangeOps : TemplateGroupBase() {
}
val f_downTo = fn("downTo(to: Primitive)").byTwoPrimitives {
include(Primitives, integralPermutations)
include(Primitives, integralPermutations + unsignedPermutations)
} builderWith { (fromType, toType) ->
sourceFile(SourceFile.Ranges)
val elementType = rangeElementType(fromType, toType)
val progressionType = elementType.name + "Progression"
@@ -71,7 +94,7 @@ object RangeOps : TemplateGroupBase() {
val fromExpr = if (elementType == fromType) "this" else "this.to$elementType()"
val toExpr = if (elementType == toType) "to" else "to.to$elementType()"
val incrementExpr = when (elementType) {
PrimitiveType.Long -> "-1L"
PrimitiveType.Long, PrimitiveType.ULong -> "-1L"
PrimitiveType.Float -> "-1.0F"
PrimitiveType.Double -> "-1.0"
else -> "-1"
@@ -84,10 +107,8 @@ object RangeOps : TemplateGroupBase() {
val f_until = fn("until(to: Primitive)").byTwoPrimitives {
include(Primitives, integralPermutations)
include(Primitives, integralPermutations + unsignedPermutations)
} builderWith { (fromType, toType) ->
sourceFile(SourceFile.Ranges)
infix()
signature("until(to: $toType)")
@@ -155,7 +176,6 @@ object RangeOps : TemplateGroupBase() {
} builderWith { (fromType, toType) ->
check(toType.isIntegral())
visibility("internal")
sourceFile(SourceFile.Ranges)
signature("to${toType}ExactOrNull()")
returns("$toType?")