| // LANGUAGE: +FullValueClasses |
| // CHECK_BYTECODE_LISTING |
| |
| value class Rational(val m: Long, val n: Long) { |
| init { |
| require(n > 0) { "Illegal natural number $n." } |
| } |
| |
| private fun gcd(a: Long, b: Long): Long = if (b == 0L) a else gcd(b, a % b) |
| |
| override fun equals(other: Any?): Boolean { |
| if (other !is Rational) return false |
| val thisGcd = gcd(this.m, this.n) |
| val otherGcd = gcd(other.m, other.n) |
| return this.m / thisGcd == other.m / otherGcd && this.n / thisGcd == other.n / otherGcd |
| } |
| |
| override fun hashCode(): Int { |
| val gcd = gcd(m, n) |
| return (m / gcd).hashCode() * 31 + (n / gcd).hashCode() |
| } |
| } |
| |
| infix fun Long.ratDiv(other: Long) = Rational(this, other) |
| |
| value class Wrapper<T>(val x: T) |
| |
| fun box(): String { |
| val x = 2L ratDiv 3L |
| val y = 4L ratDiv 6L |
| |
| require(x == y) { "$x != $y" } |
| |
| val wrapperX = Wrapper(x) |
| val wrapperY = Wrapper(y) |
| require(wrapperX == wrapperY) { "$wrapperX != $wrapperY" } |
| |
| return "OK" |
| } |