2
2
// community-build/community-projects/stdLib213/src/library/scala/math/Integral.scala
3
3
// community-build/community-projects/stdLib213/src/library/scala/math/Fractional.scala
4
4
5
+ import scala .util .Try
5
6
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?
7
8
transparent inline def plus (inline x : T , inline y : T ): T
9
+ transparent inline def minus (inline x : T , inline y : T ): T
8
10
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
+
10
29
object InlineNumeric :
11
30
extension [T ](inline x : T )(using inline num : InlineNumeric [T ])
12
31
transparent inline def + (inline y : T ): T = num.plus(x, y)
32
+ transparent inline def - (inline y : T ) = num.minus(x, y)
13
33
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)
15
43
16
44
trait InlineIntegral [T ] extends InlineNumeric [T ]:
17
45
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
+
19
48
object InlineIntegral :
20
49
// TODO: how are these imported/composed with Numeric/Integral. Should the extension methods be defined in trait InlineIntegral?
21
50
extension [T ](inline lhs : T )(using inline int : InlineIntegral [T ])
22
51
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
24
57
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)
26
62
27
- given IntIsInlineIntegral : InlineIntegral [Int ] with
63
+ given IntIsInlineIntegral : InlineIntegral [Int ] with Ordering . IntOrdering with
28
64
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
29
66
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
+
30
75
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
32
89
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
34
94
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
35
96
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
+
36
105
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
38
137
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
40
199
41
200
object tests :
42
201
import InlineNumeric .*
@@ -45,6 +204,28 @@ object tests:
45
204
inline def foo [T : InlineNumeric ](a : T , b : T ) =
46
205
a + b * b
47
206
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
+
48
219
def test (a : Int , b : Int ) =
49
220
foo(a, b) // should be a + b * b // can check with -Xprint:inlining
50
221
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