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+
1029object 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
1644trait 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+
1948object 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
41200object 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