@@ -15,17 +15,12 @@ trait InlineNumeric[T] extends Ordering[T]: // extends Numeric[T] // TODO can we
15
15
transparent inline def toLong (inline x : T ): Long
16
16
transparent inline def toFloat (inline x : T ): Float
17
17
transparent inline def toDouble (inline x : T ): Double
18
+ transparent inline def abs (inline x : T ): T
19
+ transparent inline def sign (inline x : T ): T
18
20
19
21
transparent inline def zero = fromInt(0 )
20
22
transparent inline def one = fromInt(1 )
21
23
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
-
29
24
object InlineNumeric :
30
25
extension [T ](inline x : T )(using inline num : InlineNumeric [T ])
31
26
transparent inline def + (inline y : T ): T = num.plus(x, y)
@@ -36,12 +31,16 @@ object InlineNumeric:
36
31
transparent inline def toLong : Long = num.toLong(x)
37
32
transparent inline def toFloat : Float = num.toFloat(x)
38
33
transparent inline def toDouble : Double = num.toDouble(x)
39
-
40
34
transparent inline def abs : T = num.abs(x)
41
-
42
35
transparent inline def sign : T = num.sign(x)
43
36
44
37
trait InlineIntegral [T ] extends InlineNumeric [T ]:
38
+ transparent inline def abs (inline x : T ): T = if lt(x, zero) then negate(x) else x
39
+ transparent inline def sign (inline x : T ): T =
40
+ if lt(x, zero) then negate(one)
41
+ else if gt(x, zero) then one
42
+ else zero
43
+
45
44
transparent inline def quot (inline x : T , inline y : T ): T
46
45
transparent inline def rem (inline x : T , inline y : T ): T
47
46
@@ -53,7 +52,16 @@ object InlineIntegral:
53
52
transparent inline def /% (inline rhs : T ) = (int.quot(lhs, rhs), int.rem(lhs, rhs))
54
53
55
54
trait InlineFractional [T ] extends InlineNumeric [T ]:
55
+ transparent inline def abs (inline x : T ): T = if lt(x, zero) || isNegZero(x) then negate(x) else x
56
+ transparent inline def sign (inline x : T ): T =
57
+ if isNaN(x) || isNegZero(x) then x
58
+ else if lt(x, zero) then negate(one)
59
+ else if gt(x, zero) then one
60
+ else zero
61
+
56
62
transparent inline def div (inline x : T , inline y : T ): T
63
+ protected transparent inline def isNaN (inline x : T ): Boolean
64
+ protected transparent inline def isNegZero (inline x : T ): Boolean
57
65
58
66
object InlineFractional :
59
67
// TODO: how are these imported/composed with Numeric/Fractional. Should the extension methods be defined in trait InlineFractional?
@@ -163,6 +171,8 @@ given FloatIsInlineFractional: InlineFractional[Float] with Ordering.Float.IeeeO
163
171
transparent inline def toDouble (inline x : Float ): Double = x.toDouble
164
172
165
173
transparent inline def div (inline x : Float , inline y : Float ): Float = x / y
174
+ protected transparent inline def isNaN (inline x : Float ): Boolean = x.isNaN
175
+ protected transparent inline def isNegZero (inline x : Float ): Boolean = x.equals(- 0f )
166
176
167
177
given DoubleIsInlineFractional : InlineFractional [Double ] with Ordering .Double .IeeeOrdering with
168
178
transparent inline def plus (inline x : Double , inline y : Double ): Double = x + y
@@ -177,6 +187,8 @@ given DoubleIsInlineFractional: InlineFractional[Double] with Ordering.Double.Ie
177
187
transparent inline def toDouble (inline x : Double ): Double = x
178
188
179
189
transparent inline def div (inline x : Double , inline y : Double ): Double = x / y
190
+ protected transparent inline def isNaN (inline x : Double ): Boolean = x.isNaN
191
+ protected transparent inline def isNegZero (inline x : Double ): Boolean = x.equals(- 0.0 )
180
192
181
193
trait BigDecimalIsConflicted extends InlineNumeric [BigDecimal ] with Ordering .BigDecimalOrdering :
182
194
transparent inline def plus (inline x : BigDecimal , inline y : BigDecimal ): BigDecimal = x + y
@@ -192,6 +204,9 @@ trait BigDecimalIsConflicted extends InlineNumeric[BigDecimal] with Ordering.Big
192
204
193
205
given BigDecimalIsInlineFractional : BigDecimalIsConflicted with InlineFractional [BigDecimal ] with
194
206
transparent inline def div (inline x : BigDecimal , inline y : BigDecimal ): BigDecimal = x / y
207
+ protected transparent inline def isNaN (inline x : BigDecimal ): Boolean = false
208
+ protected transparent inline def isNegZero (inline x : BigDecimal ): Boolean = false
209
+
195
210
196
211
given BigDecimalAsIfInlineIntegral : BigDecimalIsConflicted with InlineIntegral [BigDecimal ] with
197
212
transparent inline def quot (inline x : BigDecimal , inline y : BigDecimal ): BigDecimal = x quot y
@@ -214,7 +229,8 @@ object tests:
214
229
215
230
inline def bar [T : InlineNumeric ](a : T ) = a.toInt
216
231
217
- inline def sign [T : InlineNumeric ](a : T ) = a.sign
232
+ inline def signInt [T : InlineIntegral ](a : T ) = a.sign
233
+ inline def signFrac [T : InlineFractional ](a : T ) = a.sign
218
234
219
235
def test (a : Int , b : Int ) =
220
236
foo(a, b) // should be a + b * b // can check with -Xprint:inlining
@@ -226,6 +242,9 @@ object tests:
226
242
bar(a.toFloat) // should be a.toFloat.toInt
227
243
bar(a) // should be a
228
244
229
- sign(a)
230
- sign(a.toChar)
231
- sign(- 7F )
245
+ signInt(a)
246
+ signInt(a.toChar)
247
+ signFrac(- 7F )
248
+
249
+ signInt(BigDecimal (a))
250
+ signFrac(BigDecimal (a)) // the condition with isNan() should be removed
0 commit comments