@@ -23,6 +23,8 @@ object Deriving {
23
23
def update (n : Int , x : Any ) = elems(n) = x.asInstanceOf [AnyRef ]
24
24
}
25
25
26
+ def productElement [T ](x : Any , idx : Int ) = x.asInstanceOf [Product ].productElement(idx).asInstanceOf [T ]
27
+
26
28
/** The Generic class hierarchy allows typelevel access to
27
29
* enums, case classes and objects, and their sealed parents.
28
30
*/
@@ -52,7 +54,6 @@ object Deriving {
52
54
type CaseLabel <: String
53
55
type ElemLabels <: Tuple
54
56
55
- def toProduct (x : T ): scala.Product
56
57
def fromProduct (p : scala.Product ): T
57
58
}
58
59
@@ -95,10 +96,8 @@ object Lst {
95
96
type ElemTypes = (T , Lst [T ])
96
97
type CaseLabel = " Cons"
97
98
type ElemLabels = (" hd" , " tl" )
98
- def toProduct (x : Cons [T ]): Product = x
99
99
def fromProduct (p : Product ): Cons [T ] =
100
- new Cons (p.productElement(0 ).asInstanceOf [T ],
101
- p.productElement(1 ).asInstanceOf [Lst [T ]])
100
+ new Cons (productElement[T ](p, 0 ), productElement[Lst [T ]](p, 1 ))
102
101
}
103
102
implicit def GenericCons [T ]: GenericCons [T ] = new GenericCons [T ]
104
103
}
@@ -127,9 +126,8 @@ object Pair {
127
126
type ElemTypes = (T , T )
128
127
type CaseLabel = " Pair"
129
128
type ElemLabels = (" x" , " y" )
130
- def toProduct (x : Pair [T ]): Product = x
131
129
def fromProduct (p : Product ): Pair [T ] =
132
- Pair (p. productElement( 0 ). asInstanceOf , p. productElement( 1 ). asInstanceOf )
130
+ Pair (productElement[ T ](p, 0 ), productElement[ T ](p, 1 ) )
133
131
}
134
132
implicit def GenericPair [T ]: GenericPair [T ] = new GenericPair [T ]
135
133
@@ -173,8 +171,7 @@ object Left {
173
171
type ElemTypes = L *: Unit
174
172
type CaseLabel = " Left"
175
173
type ElemLabels = " x" *: Unit
176
- def toProduct (x : Left [L ]) = x
177
- def fromProduct (p : Product ): Left [L ] = Left (p.productElement(0 ).asInstanceOf [L ])
174
+ def fromProduct (p : Product ): Left [L ] = Left (productElement[L ](p, 0 ))
178
175
}
179
176
implicit def GenericLeft [L ]: GenericLeft [L ] = new GenericLeft [L ]
180
177
}
@@ -185,8 +182,7 @@ object Right {
185
182
type ElemTypes = R *: Unit
186
183
type CaseLabel = " Right"
187
184
type ElemLabels = " x" *: Unit
188
- def toProduct (x : Right [R ]) = x
189
- def fromProduct (p : Product ): Right [R ] = Right (p.productElement(0 ).asInstanceOf [R ])
185
+ def fromProduct (p : Product ): Right [R ] = Right (productElement[R ](p, 0 ))
190
186
}
191
187
implicit def GenericRight [R ]: GenericRight [R ] = new GenericRight [R ]
192
188
}
@@ -208,26 +204,24 @@ object Eq {
208
204
case eq : Eq [T ] => eq.eql(x, y)
209
205
}
210
206
211
- inline def eqlElems [Elems <: Tuple ](n : Int )(x : Product , y : Product ): Boolean =
207
+ inline def eqlElems [Elems <: Tuple ](n : Int )(x : Any , y : Any ): Boolean =
212
208
inline erasedValue[Elems ] match {
213
209
case _ : (elem *: elems1) =>
214
- tryEql[elem](
215
- x.productElement(n).asInstanceOf [elem],
216
- y.productElement(n).asInstanceOf [elem]) &&
210
+ tryEql[elem](productElement[elem](x, n), productElement[elem](y, n)) &&
217
211
eqlElems[elems1](n + 1 )(x, y)
218
212
case _ : Unit =>
219
213
true
220
214
}
221
215
222
- inline def eqlProduct [T ](g : Generic .Product [T ])(x : T , y : T ): Boolean =
223
- eqlElems[g.ElemTypes ](0 )(g.toProduct(x), g.toProduct(y) )
216
+ inline def eqlProduct [T ](g : Generic .Product [T ])(x : Any , y : Any ): Boolean =
217
+ eqlElems[g.ElemTypes ](0 )(x, y )
224
218
225
219
inline def eqlCases [T ](g : Generic .Sum [T ], n : Int )(x : T , y : T , ord : Int ): Boolean =
226
220
inline if (n == g.numberOfCases)
227
221
false
228
222
else if (ord == n)
229
223
inline g.alternative(n) match {
230
- case g : Generic .Product [p] => eqlProduct[p](g)(x. asInstanceOf [p] , y. asInstanceOf [p] )
224
+ case g : Generic .Product [p] => eqlProduct[p](g)(x, y)
231
225
case g : Generic .Singleton [_] => true
232
226
}
233
227
else eqlCases[T ](g, n + 1 )(x, y, ord)
@@ -266,23 +260,23 @@ object Pickler {
266
260
case pkl : Pickler [T ] => pkl.pickle(buf, x)
267
261
}
268
262
269
- inline def pickleElems [Elems <: Tuple ](n : Int )(buf : mutable.ListBuffer [Int ], x : Product ): Unit =
263
+ inline def pickleElems [Elems <: Tuple ](n : Int )(buf : mutable.ListBuffer [Int ], x : Any ): Unit =
270
264
inline erasedValue[Elems ] match {
271
265
case _ : (elem *: elems1) =>
272
- tryPickle[elem](buf, x. productElement(n). asInstanceOf [elem])
266
+ tryPickle[elem](buf, productElement[elem](x, n) )
273
267
pickleElems[elems1](n + 1 )(buf, x)
274
268
case _ : Unit =>
275
269
}
276
270
277
- inline def pickleProduct [T ](g : Generic .Product [T ])(buf : mutable.ListBuffer [Int ], x : T ): Unit =
278
- pickleElems[g.ElemTypes ](0 )(buf, g.toProduct(x) )
271
+ inline def pickleProduct [T ](g : Generic .Product [T ])(buf : mutable.ListBuffer [Int ], x : Any ): Unit =
272
+ pickleElems[g.ElemTypes ](0 )(buf, x )
279
273
280
274
inline def pickleCases [T ](g : Generic .Sum [T ], inline n : Int )(buf : mutable.ListBuffer [Int ], x : T , ord : Int ): Unit =
281
275
inline if (n == g.numberOfCases)
282
276
()
283
277
else if (ord == n)
284
278
inline g.alternative(n) match {
285
- case g : Generic .Product [p] => pickleProduct(g)(buf, x. asInstanceOf [p] )
279
+ case g : Generic .Product [p] => pickleProduct(g)(buf, x)
286
280
case g : Generic .Singleton [s] =>
287
281
}
288
282
else pickleCases[T ](g, n + 1 )(buf, x, ord)
@@ -360,30 +354,30 @@ object Show {
360
354
case s : Show [T ] => s.show(x)
361
355
}
362
356
363
- inline def showElems [Elems <: Tuple , Labels <: Tuple ](n : Int )(x : Product ): List [String ] =
357
+ inline def showElems [Elems <: Tuple , Labels <: Tuple ](n : Int )(x : Any ): List [String ] =
364
358
inline erasedValue[Elems ] match {
365
359
case _ : (elem *: elems1) =>
366
360
inline erasedValue[Labels ] match {
367
361
case _ : (label *: labels1) =>
368
362
val formal = constValue[label]
369
- val actual = tryShow(x. productElement(n). asInstanceOf [elem])
363
+ val actual = tryShow(productElement[elem](x, n) )
370
364
s " $formal = $actual" :: showElems[elems1, labels1](n + 1 )(x)
371
365
}
372
366
case _ : Unit =>
373
367
Nil
374
368
}
375
369
376
- inline def showProduct [T ](g : Generic .Product [T ])(x : T ): String = {
370
+ inline def showProduct [T ](g : Generic .Product [T ])(x : Any ): String = {
377
371
val labl = constValue[g.CaseLabel ]
378
- showElems[g.ElemTypes , g.ElemLabels ](0 )(g.toProduct(x) ).mkString(s " $labl( " , " , " , " )" )
372
+ showElems[g.ElemTypes , g.ElemLabels ](0 )(x ).mkString(s " $labl( " , " , " , " )" )
379
373
}
380
374
381
375
inline def showCases [T ](g : Generic .Sum [T ], n : Int )(x : T , ord : Int ): String =
382
376
inline if (n == g.numberOfCases)
383
377
" "
384
378
else if (ord == n)
385
379
inline g.alternative(n) match {
386
- case g : Generic .Product [p] => showProduct(g)(x. asInstanceOf [p] )
380
+ case g : Generic .Product [p] => showProduct(g)(x)
387
381
case g : Generic .Singleton [s] => constValue[g.CaseLabel ]
388
382
}
389
383
else showCases[T ](g, n + 1 )(x, ord)
0 commit comments