Improve min/max specialization for longs and 3-arg overloads in JS

This commit is contained in:
Ilya Gorbunov
2017-11-10 08:38:18 +03:00
parent 2da9f12bc5
commit 233376eef0
3 changed files with 64 additions and 29 deletions
@@ -26,7 +26,7 @@ public fun <T: Comparable<T>> maxOf(a: T, b: T): T {
@SinceKotlin("1.1") @SinceKotlin("1.1")
@kotlin.internal.InlineOnly @kotlin.internal.InlineOnly
public inline fun maxOf(a: Byte, b: Byte): Byte { public inline fun maxOf(a: Byte, b: Byte): Byte {
return Math.max(a.toInt(), b.toInt()).toByte() return Math.max(a.toInt(), b.toInt()).unsafeCast<Byte>()
} }
/** /**
@@ -35,7 +35,7 @@ public inline fun maxOf(a: Byte, b: Byte): Byte {
@SinceKotlin("1.1") @SinceKotlin("1.1")
@kotlin.internal.InlineOnly @kotlin.internal.InlineOnly
public inline fun maxOf(a: Short, b: Short): Short { public inline fun maxOf(a: Short, b: Short): Short {
return Math.max(a.toInt(), b.toInt()).toShort() return Math.max(a.toInt(), b.toInt()).unsafeCast<Short>()
} }
/** /**
@@ -51,9 +51,9 @@ public inline fun maxOf(a: Int, b: Int): Int {
* Returns the greater of two values. * Returns the greater of two values.
*/ */
@SinceKotlin("1.1") @SinceKotlin("1.1")
@kotlin.internal.InlineOnly @Suppress("NOTHING_TO_INLINE")
public inline fun maxOf(a: Long, b: Long): Long { public inline fun maxOf(a: Long, b: Long): Long {
return Math.max(a, b) return if (a >= b) a else b
} }
/** /**
@@ -88,7 +88,7 @@ public fun <T: Comparable<T>> maxOf(a: T, b: T, c: T): T {
@SinceKotlin("1.1") @SinceKotlin("1.1")
@kotlin.internal.InlineOnly @kotlin.internal.InlineOnly
public inline fun maxOf(a: Byte, b: Byte, c: Byte): Byte { public inline fun maxOf(a: Byte, b: Byte, c: Byte): Byte {
return Math.max(a.toInt(), Math.max(b.toInt(), c.toInt())).toByte() return Math.max(a.toInt(), b.toInt(), c.toInt()).unsafeCast<Byte>()
} }
/** /**
@@ -97,7 +97,7 @@ public inline fun maxOf(a: Byte, b: Byte, c: Byte): Byte {
@SinceKotlin("1.1") @SinceKotlin("1.1")
@kotlin.internal.InlineOnly @kotlin.internal.InlineOnly
public inline fun maxOf(a: Short, b: Short, c: Short): Short { public inline fun maxOf(a: Short, b: Short, c: Short): Short {
return Math.max(a.toInt(), Math.max(b.toInt(), c.toInt())).toShort() return Math.max(a.toInt(), b.toInt(), c.toInt()).unsafeCast<Short>()
} }
/** /**
@@ -106,7 +106,7 @@ public inline fun maxOf(a: Short, b: Short, c: Short): Short {
@SinceKotlin("1.1") @SinceKotlin("1.1")
@kotlin.internal.InlineOnly @kotlin.internal.InlineOnly
public inline fun maxOf(a: Int, b: Int, c: Int): Int { public inline fun maxOf(a: Int, b: Int, c: Int): Int {
return maxOf(a, maxOf(b, c)) return Math.max(a, b, c)
} }
/** /**
@@ -124,7 +124,7 @@ public inline fun maxOf(a: Long, b: Long, c: Long): Long {
@SinceKotlin("1.1") @SinceKotlin("1.1")
@kotlin.internal.InlineOnly @kotlin.internal.InlineOnly
public inline fun maxOf(a: Float, b: Float, c: Float): Float { public inline fun maxOf(a: Float, b: Float, c: Float): Float {
return maxOf(a, maxOf(b, c)) return Math.max(a, b, c)
} }
/** /**
@@ -133,7 +133,7 @@ public inline fun maxOf(a: Float, b: Float, c: Float): Float {
@SinceKotlin("1.1") @SinceKotlin("1.1")
@kotlin.internal.InlineOnly @kotlin.internal.InlineOnly
public inline fun maxOf(a: Double, b: Double, c: Double): Double { public inline fun maxOf(a: Double, b: Double, c: Double): Double {
return maxOf(a, maxOf(b, c)) return Math.max(a, b, c)
} }
/** /**
@@ -168,7 +168,7 @@ public fun <T: Comparable<T>> minOf(a: T, b: T): T {
@SinceKotlin("1.1") @SinceKotlin("1.1")
@kotlin.internal.InlineOnly @kotlin.internal.InlineOnly
public inline fun minOf(a: Byte, b: Byte): Byte { public inline fun minOf(a: Byte, b: Byte): Byte {
return Math.min(a.toInt(), b.toInt()).toByte() return Math.min(a.toInt(), b.toInt()).unsafeCast<Byte>()
} }
/** /**
@@ -177,7 +177,7 @@ public inline fun minOf(a: Byte, b: Byte): Byte {
@SinceKotlin("1.1") @SinceKotlin("1.1")
@kotlin.internal.InlineOnly @kotlin.internal.InlineOnly
public inline fun minOf(a: Short, b: Short): Short { public inline fun minOf(a: Short, b: Short): Short {
return Math.min(a.toInt(), b.toInt()).toShort() return Math.min(a.toInt(), b.toInt()).unsafeCast<Short>()
} }
/** /**
@@ -193,9 +193,9 @@ public inline fun minOf(a: Int, b: Int): Int {
* Returns the smaller of two values. * Returns the smaller of two values.
*/ */
@SinceKotlin("1.1") @SinceKotlin("1.1")
@kotlin.internal.InlineOnly @Suppress("NOTHING_TO_INLINE")
public inline fun minOf(a: Long, b: Long): Long { public inline fun minOf(a: Long, b: Long): Long {
return Math.min(a, b) return if (a <= b) a else b
} }
/** /**
@@ -230,7 +230,7 @@ public fun <T: Comparable<T>> minOf(a: T, b: T, c: T): T {
@SinceKotlin("1.1") @SinceKotlin("1.1")
@kotlin.internal.InlineOnly @kotlin.internal.InlineOnly
public inline fun minOf(a: Byte, b: Byte, c: Byte): Byte { public inline fun minOf(a: Byte, b: Byte, c: Byte): Byte {
return Math.min(a.toInt(), Math.min(b.toInt(), c.toInt())).toByte() return Math.min(a.toInt(), b.toInt(), c.toInt()).unsafeCast<Byte>()
} }
/** /**
@@ -239,7 +239,7 @@ public inline fun minOf(a: Byte, b: Byte, c: Byte): Byte {
@SinceKotlin("1.1") @SinceKotlin("1.1")
@kotlin.internal.InlineOnly @kotlin.internal.InlineOnly
public inline fun minOf(a: Short, b: Short, c: Short): Short { public inline fun minOf(a: Short, b: Short, c: Short): Short {
return Math.min(a.toInt(), Math.min(b.toInt(), c.toInt())).toShort() return Math.min(a.toInt(), b.toInt(), c.toInt()).unsafeCast<Short>()
} }
/** /**
@@ -248,7 +248,7 @@ public inline fun minOf(a: Short, b: Short, c: Short): Short {
@SinceKotlin("1.1") @SinceKotlin("1.1")
@kotlin.internal.InlineOnly @kotlin.internal.InlineOnly
public inline fun minOf(a: Int, b: Int, c: Int): Int { public inline fun minOf(a: Int, b: Int, c: Int): Int {
return minOf(a, minOf(b, c)) return Math.min(a, b, c)
} }
/** /**
@@ -266,7 +266,7 @@ public inline fun minOf(a: Long, b: Long, c: Long): Long {
@SinceKotlin("1.1") @SinceKotlin("1.1")
@kotlin.internal.InlineOnly @kotlin.internal.InlineOnly
public inline fun minOf(a: Float, b: Float, c: Float): Float { public inline fun minOf(a: Float, b: Float, c: Float): Float {
return minOf(a, minOf(b, c)) return Math.min(a, b, c)
} }
/** /**
@@ -275,7 +275,7 @@ public inline fun minOf(a: Float, b: Float, c: Float): Float {
@SinceKotlin("1.1") @SinceKotlin("1.1")
@kotlin.internal.InlineOnly @kotlin.internal.InlineOnly
public inline fun minOf(a: Double, b: Double, c: Double): Double { public inline fun minOf(a: Double, b: Double, c: Double): Double {
return minOf(a, minOf(b, c)) return Math.min(a, b, c)
} }
/** /**
+6 -6
View File
@@ -1045,14 +1045,14 @@ public fun abs(n: Int): Int = if (n < 0) (-n or 0) else n
*/ */
@SinceKotlin("1.2") @SinceKotlin("1.2")
@InlineOnly @InlineOnly
public inline fun min(a: Int, b: Int): Int = minOf(a, b) public inline fun min(a: Int, b: Int): Int = nativeMath.min(a, b)
/** /**
* Returns the greater of two values. * Returns the greater of two values.
*/ */
@SinceKotlin("1.2") @SinceKotlin("1.2")
@InlineOnly @InlineOnly
public inline fun max(a: Int, b: Int): Int = maxOf(a, b) public inline fun max(a: Int, b: Int): Int = nativeMath.max(a, b)
/** /**
* Returns the absolute value of this value. * Returns the absolute value of this value.
@@ -1096,15 +1096,15 @@ public fun abs(n: Long): Long = if (n < 0) -n else n
* Returns the smaller of two values. * Returns the smaller of two values.
*/ */
@SinceKotlin("1.2") @SinceKotlin("1.2")
@InlineOnly @Suppress("NOTHING_TO_INLINE")
public inline fun min(a: Long, b: Long): Long = minOf(a, b) public inline fun min(a: Long, b: Long): Long = if (a <= b) a else b
/** /**
* Returns the greater of two values. * Returns the greater of two values.
*/ */
@SinceKotlin("1.2") @SinceKotlin("1.2")
@InlineOnly @Suppress("NOTHING_TO_INLINE")
public inline fun max(a: Long, b: Long): Long = maxOf(a, b) public inline fun max(a: Long, b: Long): Long = if (a >= b) a else b
/** /**
* Returns the absolute value of this value. * Returns the absolute value of this value.
@@ -150,7 +150,6 @@ object ComparableOps : TemplateGroupBase() {
typeParam("T: Comparable<T>") typeParam("T: Comparable<T>")
returns("T") returns("T")
receiver("") receiver("")
specialFor(Primitives) { inlineOnly() }
doc { doc {
""" """
Returns the smaller of two values. Returns the smaller of two values.
@@ -159,15 +158,25 @@ object ComparableOps : TemplateGroupBase() {
} }
// TODO: Add a note about NaN propagation for floats. // TODO: Add a note about NaN propagation for floats.
specialFor(Primitives) { specialFor(Primitives) {
inlineOnly()
doc { doc {
"""Returns the smaller of two values.""" """Returns the smaller of two values."""
} }
// TODO: custom body for JS minOf(Long, Long) var convertBack = "to$primitive()"
on(Platform.JS) {
convertBack = "unsafeCast<$primitive>()"
}
body { body {
"return Math.min(a, b)" "return Math.min(a, b)"
} }
if (primitive in shortIntPrimitives) { if (primitive in shortIntPrimitives) {
body { "return Math.min(a.toInt(), b.toInt()).to$primitive()" } body { "return Math.min(a.toInt(), b.toInt()).$convertBack" }
}
on(Platform.JS) {
if (primitive == PrimitiveType.Long) {
inline(suppressWarning = true)
body { "return if (a <= b) a else b" }
}
} }
} }
body(Generic) { body(Generic) {
@@ -197,6 +206,14 @@ object ComparableOps : TemplateGroupBase() {
specialFor(Primitives) { specialFor(Primitives) {
if (primitive in shortIntPrimitives) { if (primitive in shortIntPrimitives) {
body { "return Math.min(a.toInt(), Math.min(b.toInt(), c.toInt())).to$primitive()" } body { "return Math.min(a.toInt(), Math.min(b.toInt(), c.toInt())).to$primitive()" }
on(Platform.JS) {
body { "return Math.min(a.toInt(), b.toInt(), c.toInt()).unsafeCast<$primitive>()" }
}
}
else if (primitive != PrimitiveType.Long) {
on(Platform.JS) {
body { "return Math.min(a, b, c)" }
}
} }
} }
} }
@@ -245,7 +262,6 @@ object ComparableOps : TemplateGroupBase() {
typeParam("T: Comparable<T>") typeParam("T: Comparable<T>")
returns("T") returns("T")
receiver("") receiver("")
specialFor(Primitives) { inlineOnly() }
doc { doc {
""" """
Returns the greater of two values. Returns the greater of two values.
@@ -254,14 +270,25 @@ object ComparableOps : TemplateGroupBase() {
} }
// TODO: Add a note about NaN propagation for floats. // TODO: Add a note about NaN propagation for floats.
specialFor(Primitives) { specialFor(Primitives) {
inlineOnly()
doc { doc {
"""Returns the greater of two values.""" """Returns the greater of two values."""
} }
var convertBack = "to$primitive()"
on(Platform.JS) {
convertBack = "unsafeCast<$primitive>()"
}
body { body {
"return Math.max(a, b)" "return Math.max(a, b)"
} }
if (primitive in shortIntPrimitives) { if (primitive in shortIntPrimitives) {
body { "return Math.max(a.toInt(), b.toInt()).to$primitive()" } body { "return Math.max(a.toInt(), b.toInt()).$convertBack" }
}
on(Platform.JS) {
if (primitive == PrimitiveType.Long) {
inline(suppressWarning = true)
body { "return if (a >= b) a else b" }
}
} }
} }
body(Generic) { body(Generic) {
@@ -291,6 +318,14 @@ object ComparableOps : TemplateGroupBase() {
specialFor(Primitives) { specialFor(Primitives) {
if (primitive in shortIntPrimitives) { if (primitive in shortIntPrimitives) {
body { "return Math.max(a.toInt(), Math.max(b.toInt(), c.toInt())).to$primitive()" } body { "return Math.max(a.toInt(), Math.max(b.toInt(), c.toInt())).to$primitive()" }
on(Platform.JS) {
body { "return Math.max(a.toInt(), b.toInt(), c.toInt()).unsafeCast<$primitive>()" }
}
}
else if (primitive != PrimitiveType.Long) {
on(Platform.JS) {
body { "return Math.max(a, b, c)" }
}
} }
} }
} }