From 89e4fdfa9c8c331d57e05f8f796a31f6d92d1c5d Mon Sep 17 00:00:00 2001 From: Ilya Gorbunov Date: Fri, 4 May 2018 07:39:39 +0300 Subject: [PATCH] Implement unsigned comparisons --- generators/builtins/unsignedTypes.kt | 8 +++++++- libraries/stdlib/unsigned/src/kotlin/UByte.kt | 8 ++++---- libraries/stdlib/unsigned/src/kotlin/UInt.kt | 8 ++++---- libraries/stdlib/unsigned/src/kotlin/ULong.kt | 8 ++++---- libraries/stdlib/unsigned/src/kotlin/UShort.kt | 8 ++++---- libraries/stdlib/unsigned/src/kotlin/UnsignedUtils.kt | 9 +++++++++ 6 files changed, 32 insertions(+), 17 deletions(-) create mode 100644 libraries/stdlib/unsigned/src/kotlin/UnsignedUtils.kt diff --git a/generators/builtins/unsignedTypes.kt b/generators/builtins/unsignedTypes.kt index d1fe7e6ee39..8cf3a504975 100644 --- a/generators/builtins/unsignedTypes.kt +++ b/generators/builtins/unsignedTypes.kt @@ -86,7 +86,13 @@ class UnsignedTypeGenerator(val type: UnsignedType, out: PrintWriter) : BuiltIns */""") out.print(" public ") if (otherType == type) out.print("override ") - out.println("operator fun compareTo(other: ${otherType.capitalized}): Int = TODO()") + out.print("operator fun compareTo(other: ${otherType.capitalized}): Int = ") + if (otherType == type && maxByDomainCapacity(type, UnsignedType.UINT) == type) { + out.println("${className.toLowerCase()}Compare(this.data, other.data)") + } else { + val ctype = maxByDomainCapacity(maxByDomainCapacity(type, otherType), UnsignedType.UINT) + out.println("${convert("this", type, ctype)}.compareTo(${convert("other", otherType, ctype)})") + } } out.println() } diff --git a/libraries/stdlib/unsigned/src/kotlin/UByte.kt b/libraries/stdlib/unsigned/src/kotlin/UByte.kt index 2c2debaf303..e8988f8b43c 100644 --- a/libraries/stdlib/unsigned/src/kotlin/UByte.kt +++ b/libraries/stdlib/unsigned/src/kotlin/UByte.kt @@ -28,28 +28,28 @@ public inline class UByte internal constructor(private val data: Byte) : Compara * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ - public override operator fun compareTo(other: UByte): Int = TODO() + public override operator fun compareTo(other: UByte): Int = this.toUInt().compareTo(other.toUInt()) /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ - public operator fun compareTo(other: UShort): Int = TODO() + public operator fun compareTo(other: UShort): Int = this.toUInt().compareTo(other.toUInt()) /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ - public operator fun compareTo(other: UInt): Int = TODO() + public operator fun compareTo(other: UInt): Int = this.toUInt().compareTo(other) /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ - public operator fun compareTo(other: ULong): Int = TODO() + public operator fun compareTo(other: ULong): Int = this.toULong().compareTo(other) /** Adds the other value to this value. */ public operator fun plus(other: UByte): UInt = TODO() diff --git a/libraries/stdlib/unsigned/src/kotlin/UInt.kt b/libraries/stdlib/unsigned/src/kotlin/UInt.kt index bb099268e2c..bf5780aeafa 100644 --- a/libraries/stdlib/unsigned/src/kotlin/UInt.kt +++ b/libraries/stdlib/unsigned/src/kotlin/UInt.kt @@ -28,28 +28,28 @@ public inline class UInt internal constructor(private val data: Int) : Comparabl * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ - public operator fun compareTo(other: UByte): Int = TODO() + public operator fun compareTo(other: UByte): Int = this.compareTo(other.toUInt()) /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ - public operator fun compareTo(other: UShort): Int = TODO() + public operator fun compareTo(other: UShort): Int = this.compareTo(other.toUInt()) /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ - public override operator fun compareTo(other: UInt): Int = TODO() + public override operator fun compareTo(other: UInt): Int = uintCompare(this.data, other.data) /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ - public operator fun compareTo(other: ULong): Int = TODO() + public operator fun compareTo(other: ULong): Int = this.toULong().compareTo(other) /** Adds the other value to this value. */ public operator fun plus(other: UByte): UInt = TODO() diff --git a/libraries/stdlib/unsigned/src/kotlin/ULong.kt b/libraries/stdlib/unsigned/src/kotlin/ULong.kt index 122c5cac3f6..6fdee736deb 100644 --- a/libraries/stdlib/unsigned/src/kotlin/ULong.kt +++ b/libraries/stdlib/unsigned/src/kotlin/ULong.kt @@ -28,28 +28,28 @@ public inline class ULong internal constructor(private val data: Long) : Compara * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ - public operator fun compareTo(other: UByte): Int = TODO() + public operator fun compareTo(other: UByte): Int = this.compareTo(other.toULong()) /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ - public operator fun compareTo(other: UShort): Int = TODO() + public operator fun compareTo(other: UShort): Int = this.compareTo(other.toULong()) /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ - public operator fun compareTo(other: UInt): Int = TODO() + public operator fun compareTo(other: UInt): Int = this.compareTo(other.toULong()) /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ - public override operator fun compareTo(other: ULong): Int = TODO() + public override operator fun compareTo(other: ULong): Int = ulongCompare(this.data, other.data) /** Adds the other value to this value. */ public operator fun plus(other: UByte): ULong = TODO() diff --git a/libraries/stdlib/unsigned/src/kotlin/UShort.kt b/libraries/stdlib/unsigned/src/kotlin/UShort.kt index 167e30f02f5..ef9609da2cc 100644 --- a/libraries/stdlib/unsigned/src/kotlin/UShort.kt +++ b/libraries/stdlib/unsigned/src/kotlin/UShort.kt @@ -28,28 +28,28 @@ public inline class UShort internal constructor(private val data: Short) : Compa * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ - public operator fun compareTo(other: UByte): Int = TODO() + public operator fun compareTo(other: UByte): Int = this.toUInt().compareTo(other.toUInt()) /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ - public override operator fun compareTo(other: UShort): Int = TODO() + public override operator fun compareTo(other: UShort): Int = this.toUInt().compareTo(other.toUInt()) /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ - public operator fun compareTo(other: UInt): Int = TODO() + public operator fun compareTo(other: UInt): Int = this.toUInt().compareTo(other) /** * Compares this value with the specified value for order. * Returns zero if this value is equal to the specified other value, a negative number if it's less than other, * or a positive number if it's greater than other. */ - public operator fun compareTo(other: ULong): Int = TODO() + public operator fun compareTo(other: ULong): Int = this.toULong().compareTo(other) /** Adds the other value to this value. */ public operator fun plus(other: UByte): UInt = TODO() diff --git a/libraries/stdlib/unsigned/src/kotlin/UnsignedUtils.kt b/libraries/stdlib/unsigned/src/kotlin/UnsignedUtils.kt new file mode 100644 index 00000000000..6d9743ea651 --- /dev/null +++ b/libraries/stdlib/unsigned/src/kotlin/UnsignedUtils.kt @@ -0,0 +1,9 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package kotlin + +internal fun uintCompare(v1: Int, v2: Int): Int = (v1 xor Int.MIN_VALUE).compareTo(v2 xor Int.MIN_VALUE) +internal fun ulongCompare(v1: Long, v2: Long): Int = (v1 xor Long.MIN_VALUE).compareTo(v2 xor Long.MIN_VALUE) \ No newline at end of file