Skip to content

Commit a1b4cc3

Browse files
Implement missing methods, add examples
Add methods missing in the skeleton Add given for all primitive types Add test methods for division, modulo, sign and toInt
1 parent 8bb74d7 commit a1b4cc3

File tree

1 file changed

+192
-11
lines changed

1 file changed

+192
-11
lines changed

InlineNumeric.scala

Lines changed: 192 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,41 +2,200 @@
22
// community-build/community-projects/stdLib213/src/library/scala/math/Integral.scala
33
// community-build/community-projects/stdLib213/src/library/scala/math/Fractional.scala
44

5+
import scala.util.Try
56

6-
trait InlineNumeric[T]: // extends Numeric[T] // TODO can we do this?
7+
trait InlineNumeric[T] extends Ordering[T]: // extends Numeric[T] // TODO can we do this?
78
transparent inline def plus(inline x: T, inline y: T): T
9+
transparent inline def minus(inline x: T, inline y: T): T
810
transparent inline def times(inline x: T, inline y: T): T
9-
// TODO add missing methods
11+
transparent inline def negate(inline x: T): T
12+
transparent inline def fromInt(inline x: Int): T
13+
transparent inline def parseString(inline str: String): Option[T]
14+
transparent inline def toInt(inline x: T): Int
15+
transparent inline def toLong(inline x: T): Long
16+
transparent inline def toFloat(inline x: T): Float
17+
transparent inline def toDouble(inline x: T): Double
18+
19+
transparent inline def zero = fromInt(0)
20+
transparent inline def one = fromInt(1)
21+
22+
transparent inline def abs(inline x: T): T = if lt(x, zero) then negate(x) else x
23+
24+
transparent inline def sign(inline x: T): T =
25+
if lt(x, zero) then negate(one)
26+
else if gt(x, zero) then one
27+
else zero
28+
1029
object InlineNumeric:
1130
extension [T](inline x: T)(using inline num: InlineNumeric[T])
1231
transparent inline def +(inline y: T): T = num.plus(x, y)
32+
transparent inline def -(inline y: T) = num.minus(x, y)
1333
transparent inline def *(inline y: T): T = num.times(x, y)
14-
// TODO add missing methods
34+
transparent inline def unary_- = num.negate(x)
35+
transparent inline def toInt: Int = num.toInt(x)
36+
transparent inline def toLong: Long = num.toLong(x)
37+
transparent inline def toFloat: Float = num.toFloat(x)
38+
transparent inline def toDouble: Double = num.toDouble(x)
39+
40+
transparent inline def abs: T = num.abs(x)
41+
42+
transparent inline def sign: T = num.sign(x)
1543

1644
trait InlineIntegral[T] extends InlineNumeric[T]:
1745
transparent inline def quot(inline x: T, inline y: T): T
18-
// TODO add missing methods
46+
transparent inline def rem(inline x: T, inline y: T): T
47+
1948
object InlineIntegral:
2049
// TODO: how are these imported/composed with Numeric/Integral. Should the extension methods be defined in trait InlineIntegral?
2150
extension [T](inline lhs: T)(using inline int: InlineIntegral[T])
2251
transparent inline def /(inline rhs: T) = int.quot(lhs, rhs)
23-
// TODO add missing methods
52+
transparent inline def %(inline rhs: T) = int.rem(lhs, rhs)
53+
transparent inline def /%(inline rhs: T) = (int.quot(lhs, rhs), int.rem(lhs, rhs))
54+
55+
trait InlineFractional[T] extends InlineNumeric[T]:
56+
transparent inline def div(inline x: T, inline y: T): T
2457

25-
// TODO: InlineFractional
58+
object InlineFractional:
59+
// TODO: how are these imported/composed with Numeric/Fractional. Should the extension methods be defined in trait InlineFractional?
60+
extension [T](inline lhs: T)(using inline frac: InlineFractional[T])
61+
transparent inline def /(inline rhs: T) = frac.div(lhs, rhs)
2662

27-
given IntIsInlineIntegral: InlineIntegral[Int] with
63+
given IntIsInlineIntegral: InlineIntegral[Int] with Ordering.IntOrdering with
2864
transparent inline def plus(inline x: Int, inline y: Int): Int = x + y
65+
transparent inline def minus(inline x: Int, inline y: Int): Int = x - y
2966
transparent inline def times(inline x: Int, inline y: Int): Int = x * y
67+
transparent inline def negate(inline x: Int): Int = -x
68+
transparent inline def fromInt(inline x: Int): Int = x
69+
transparent inline def parseString(inline str: String): Option[Int] = str.toIntOption
70+
transparent inline def toInt(inline x: Int): Int = x
71+
transparent inline def toLong(inline x: Int): Long = x.toLong
72+
transparent inline def toFloat(inline x: Int): Float = x.toFloat
73+
transparent inline def toDouble(inline x: Int): Double = x.toDouble
74+
3075
transparent inline def quot(inline x: Int, inline y: Int): Int = x / y
31-
// TODO add missing methods
76+
transparent inline def rem(inline x: Int, inline y: Int): Int = x % y
77+
78+
given BigIntIsInlineIntegral: InlineIntegral[BigInt] with Ordering.BigIntOrdering with
79+
transparent inline def plus(inline x: BigInt, inline y: BigInt): BigInt = x + y
80+
transparent inline def minus(inline x: BigInt, inline y: BigInt): BigInt = x - y
81+
transparent inline def times(inline x: BigInt, inline y: BigInt): BigInt = x * y
82+
transparent inline def negate(inline x: BigInt): BigInt = -x
83+
transparent inline def fromInt(inline x: Int): BigInt = BigInt(x)
84+
transparent inline def parseString(inline str: String): Option[BigInt] = Try(BigInt(str)).toOption
85+
transparent inline def toInt(inline x: BigInt): Int = x.intValue
86+
transparent inline def toLong(inline x: BigInt): Long = x.longValue
87+
transparent inline def toFloat(inline x: BigInt): Float = x.floatValue
88+
transparent inline def toDouble(inline x: BigInt): Double = x.doubleValue
3289

33-
given ShortIsInlineIntegral: InlineIntegral[Short] with
90+
transparent inline def quot(inline x: BigInt, inline y: BigInt): BigInt = x / y
91+
transparent inline def rem(inline x: BigInt, inline y: BigInt): BigInt = x % y
92+
93+
given ShortIsInlineIntegral: InlineIntegral[Short] with Ordering.ShortOrdering with
3494
transparent inline def plus(inline x: Short, inline y: Short): Short = (x + y).toShort
95+
transparent inline def minus(inline x: Short, inline y: Short): Short = (x - y).toShort
3596
transparent inline def times(inline x: Short, inline y: Short): Short = (x * y).toShort
97+
transparent inline def negate(inline x: Short): Short = (-x).toShort
98+
transparent inline def fromInt(inline x: Int): Short = x.toShort
99+
transparent inline def parseString(inline str: String): Option[Short] = str.toShortOption
100+
transparent inline def toInt(inline x: Short): Int = x.toInt
101+
transparent inline def toLong(inline x: Short): Long = x.toLong
102+
transparent inline def toFloat(inline x: Short): Float = x.toFloat
103+
transparent inline def toDouble(inline x: Short): Double = x.toDouble
104+
36105
transparent inline def quot(inline x: Short, inline y: Short): Short = (x / y).toShort
37-
// TODO add missing methods
106+
transparent inline def rem(inline x: Short, inline y: Short): Short = (x % y).toShort
107+
108+
given ByteIsInlineIntegral: InlineIntegral[Byte] with Ordering.ByteOrdering with
109+
transparent inline def plus(inline x: Byte, inline y: Byte): Byte = (x + y).toByte
110+
transparent inline def minus(inline x: Byte, inline y: Byte): Byte = (x - y).toByte
111+
transparent inline def times(inline x: Byte, inline y: Byte): Byte = (x * y).toByte
112+
transparent inline def negate(inline x: Byte): Byte = (-x).toByte
113+
transparent inline def fromInt(inline x: Int): Byte = x.toByte
114+
transparent inline def parseString(inline str: String): Option[Byte] = str.toByteOption
115+
transparent inline def toInt(inline x: Byte): Int = x.toInt
116+
transparent inline def toLong(inline x: Byte): Long = x.toLong
117+
transparent inline def toFloat(inline x: Byte): Float = x.toFloat
118+
transparent inline def toDouble(inline x: Byte): Double = x.toDouble
119+
120+
transparent inline def quot(inline x: Byte, inline y: Byte): Byte = (x / y).toByte
121+
transparent inline def rem(inline x: Byte, inline y: Byte): Byte = (x % y).toByte
122+
123+
given CharIsInlineIntegral: InlineIntegral[Char] with Ordering.CharOrdering with
124+
transparent inline def plus(inline x: Char, inline y: Char): Char = (x + y).toChar
125+
transparent inline def minus(inline x: Char, inline y: Char): Char = (x - y).toChar
126+
transparent inline def times(inline x: Char, inline y: Char): Char = (x * y).toChar
127+
transparent inline def negate(inline x: Char): Char = (-x).toChar
128+
transparent inline def fromInt(inline x: Int): Char = x.toChar
129+
transparent inline def parseString(inline str: String): Option[Char] = Try(str.toInt.toChar).toOption
130+
transparent inline def toInt(inline x: Char): Int = x.toInt
131+
transparent inline def toLong(inline x: Char): Long = x.toLong
132+
transparent inline def toFloat(inline x: Char): Float = x.toFloat
133+
transparent inline def toDouble(inline x: Char): Double = x.toDouble
134+
135+
transparent inline def quot(inline x: Char, inline y: Char): Char = (x / y).toChar
136+
transparent inline def rem(inline x: Char, inline y: Char): Char = (x % y).toChar
38137

39-
// TODO add missing primitive types
138+
given LongIsInlineIntegral: InlineIntegral[Long] with Ordering.LongOrdering with
139+
transparent inline def plus(inline x: Long, inline y: Long): Long = x + y
140+
transparent inline def minus(inline x: Long, inline y: Long): Long = x - y
141+
transparent inline def times(inline x: Long, inline y: Long): Long = x * y
142+
transparent inline def negate(inline x: Long): Long = -x
143+
transparent inline def fromInt(inline x: Int): Long = x.toLong
144+
transparent inline def parseString(inline str: String): Option[Long] = str.toLongOption
145+
transparent inline def toInt(inline x: Long): Int = x.toInt
146+
transparent inline def toLong(inline x: Long): Long = x
147+
transparent inline def toFloat(inline x: Long): Float = x.toFloat
148+
transparent inline def toDouble(inline x: Long): Double = x.toDouble
149+
150+
transparent inline def quot(inline x: Long, inline y: Long): Long = (x / y).toLong
151+
transparent inline def rem(inline x: Long, inline y: Long): Long = (x % y).toLong
152+
153+
given FloatIsInlineFractional: InlineFractional[Float] with Ordering.Float.IeeeOrdering with
154+
transparent inline def plus(inline x: Float, inline y: Float): Float = x + y
155+
transparent inline def minus(inline x: Float, inline y: Float): Float = x - y
156+
transparent inline def times(inline x: Float, inline y: Float): Float = x * y
157+
transparent inline def negate(inline x: Float): Float = -x
158+
transparent inline def fromInt(inline x: Int): Float = x.toFloat
159+
transparent inline def parseString(inline str: String): Option[Float] = str.toFloatOption
160+
transparent inline def toInt(inline x: Float): Int = x.toInt
161+
transparent inline def toLong(inline x: Float): Long = x.toLong
162+
transparent inline def toFloat(inline x: Float): Float = x
163+
transparent inline def toDouble(inline x: Float): Double = x.toDouble
164+
165+
transparent inline def div(inline x: Float, inline y: Float): Float = x / y
166+
167+
given DoubleIsInlineFractional: InlineFractional[Double] with Ordering.Double.IeeeOrdering with
168+
transparent inline def plus(inline x: Double, inline y: Double): Double = x + y
169+
transparent inline def minus(inline x: Double, inline y: Double): Double = x - y
170+
transparent inline def times(inline x: Double, inline y: Double): Double = x * y
171+
transparent inline def negate(inline x: Double): Double = -x
172+
transparent inline def fromInt(inline x: Int): Double = x.toDouble
173+
transparent inline def parseString(inline str: String): Option[Double] = str.toDoubleOption
174+
transparent inline def toInt(inline x: Double): Int = x.toInt
175+
transparent inline def toLong(inline x: Double): Long = x.toLong
176+
transparent inline def toFloat(inline x: Double): Float = x.toFloat
177+
transparent inline def toDouble(inline x: Double): Double = x
178+
179+
transparent inline def div(inline x: Double, inline y: Double): Double = x / y
180+
181+
trait BigDecimalIsConflicted extends InlineNumeric[BigDecimal] with Ordering.BigDecimalOrdering:
182+
transparent inline def plus(inline x: BigDecimal, inline y: BigDecimal): BigDecimal = x + y
183+
transparent inline def minus(inline x: BigDecimal, inline y: BigDecimal): BigDecimal = x - y
184+
transparent inline def times(inline x: BigDecimal, inline y: BigDecimal): BigDecimal = x * y
185+
transparent inline def negate(inline x: BigDecimal): BigDecimal = -x
186+
transparent inline def fromInt(inline x: Int): BigDecimal = BigDecimal(x)
187+
transparent inline def parseString(inline str: String): Option[BigDecimal] = Try(BigDecimal(str)).toOption
188+
transparent inline def toInt(inline x: BigDecimal): Int = x.intValue
189+
transparent inline def toLong(inline x: BigDecimal): Long = x.longValue
190+
transparent inline def toFloat(inline x: BigDecimal): Float = x.floatValue
191+
transparent inline def toDouble(inline x: BigDecimal): Double = x.doubleValue
192+
193+
given BigDecimalIsInlineFractional: BigDecimalIsConflicted with InlineFractional[BigDecimal] with
194+
transparent inline def div(inline x: BigDecimal, inline y: BigDecimal): BigDecimal = x / y
195+
196+
given BigDecimalAsIfInlineIntegral: BigDecimalIsConflicted with InlineIntegral[BigDecimal] with
197+
transparent inline def quot(inline x: BigDecimal, inline y: BigDecimal): BigDecimal = x quot y
198+
transparent inline def rem(inline x: BigDecimal, inline y: BigDecimal): BigDecimal = x remainder y
40199

41200
object tests:
42201
import InlineNumeric.*
@@ -45,6 +204,28 @@ object tests:
45204
inline def foo[T: InlineNumeric](a: T, b: T) =
46205
a + b * b
47206

207+
inline def integDiv[T: InlineIntegral](a: T, b: T) =
208+
import InlineIntegral.{/, %}
209+
a / b % b
210+
211+
inline def fracDiv[T: InlineFractional](a: T, b: T) =
212+
import InlineFractional.{/}
213+
a / b + a
214+
215+
inline def bar[T: InlineNumeric](a: T) = a.toInt
216+
217+
inline def sign[T: InlineNumeric](a: T) = a.sign
218+
48219
def test(a: Int, b: Int) =
49220
foo(a, b) // should be a + b * b // can check with -Xprint:inlining
50221
foo(a.toShort, b.toShort) // should be a + b * b
222+
223+
integDiv(BigDecimal(a), BigDecimal(b)) // should be BigDecimal(a) quot BigDecimal(b) remainder BigDecimal(b)
224+
fracDiv(BigDecimal(a), BigDecimal(b)) // should be BigDecimal(a) / BigDecimal(b) + BigDecimal(a)
225+
226+
bar(a.toFloat) // should be a.toFloat.toInt
227+
bar(a) // should be a
228+
229+
sign(a)
230+
sign(a.toChar)
231+
sign(-7F)

0 commit comments

Comments
 (0)