@@ -3,21 +3,21 @@ import scala.annotation.tailrec
33
44// The following command:
55//
6- // sc typeclass-scaling.scala -Xmax-inlines 100 -Xprint:front -color:never -Yshow-no-inline - pagewidth 1000 >& x
6+ // sc typeclass-scaling.scala -Xmax-inlines 100 -Xprint:front -color:never -pagewidth 1000 >& x
77//
88// produces an output file with `wc` measures (lines/words/chars):
99//
10- // 83434 140554 6384738
10+ // 89327 162884 7220258
1111//
1212// The command
1313//
1414// time sc typeclass-scaling.scala -Xmax-inlines 100
1515//
1616// gives (best of three):
1717//
18- // real 0m16.061s
19- // user 1m3.608s
20- // sys 0m1.314s
18+ // real 0m16.593s
19+ // user 1m6.337s
20+ // sys 0m1.344s
2121object datatypes {
2222 import typeclasses ._
2323
@@ -215,42 +215,45 @@ object typeclasses {
215215 object Eq {
216216 import scala .compiletime .erasedValue
217217 import compiletime ._
218- import reflect .{ Mirror , Generic }
218+ import scala . deriving . _
219219
220- inline def tryEql [T ](x : T , y : T ) = implicit match {
221- case eq : Eq [T ] => eq.eql(x, y)
220+ inline def tryEql [TT ](x : TT , y : TT ) : Boolean = implicit match {
221+ case eq : Eq [TT ] => eq.eql(x, y)
222222 }
223223
224- inline def eqlElems [Elems <: Tuple ](xs : Mirror , ys : Mirror , n : Int ): Boolean =
224+ inline def eqlElems [Elems <: Tuple ](n : Int )( x : Any , y : Any ): Boolean =
225225 inline erasedValue[Elems ] match {
226226 case _ : (elem *: elems1) =>
227- tryEql[elem](xs(n). asInstanceOf , ys(n). asInstanceOf ) &&
228- eqlElems[elems1](xs, ys, n + 1 )
227+ tryEql[elem](productElement[elem](x, n), productElement[elem](y, n) ) &&
228+ eqlElems[elems1](n + 1 )(x, y )
229229 case _ : Unit =>
230230 true
231231 }
232232
233- inline def eqlCases [Alts <: Tuple ](xm : Mirror , ym : Mirror , n : Int ): Boolean =
233+ inline def eqlProduct [T ](m : Mirror .ProductOf [T ])(x : Any , y : Any ): Boolean =
234+ eqlElems[m.MirroredElemTypes ](0 )(x, y)
235+
236+ inline def eqlCases [Alts ](n : Int )(x : Any , y : Any , ord : Int ): Boolean =
234237 inline erasedValue[Alts ] match {
235- case _ : (Shape .Case [alt, elems] *: alts1) =>
236- if (xm.ordinal == n) eqlElems[elems](xm, ym, 0 )
237- else eqlCases[alts1](xm, ym, n + 1 )
238- case _ : Unit =>
238+ case _ : (alt *: alts1) =>
239+ if (ord == n)
240+ implicit match {
241+ case m : Mirror .ProductOf [`alt`] => eqlElems[m.MirroredElemTypes ](0 )(x, y)
242+ }
243+ else eqlCases[alts1](n + 1 )(x, y, ord)
244+ case _ : Unit =>
239245 false
240246 }
241247
242- inline def derived [T ](implicit ev : Generic [T ]): Eq [T ] = new {
243- def eql (x : T , y : T ): Boolean = {
244- val xm = ev.reflect(x)
245- val ym = ev.reflect(y)
246- inline erasedValue[ev.Shape ] match {
247- case _ : Shape .Cases [alts] =>
248- xm.ordinal == ym.ordinal &&
249- eqlCases[alts](xm, ym, 0 )
250- case _ : Shape .Case [_, elems] =>
251- eqlElems[elems](xm, ym, 0 )
248+ inline def derived [T ](implicit ev : Mirror .Of [T ]): Eq [T ] = new Eq [T ] {
249+ def eql (x : T , y : T ): Boolean =
250+ inline ev match {
251+ case m : Mirror .SumOf [T ] =>
252+ val ord = m.ordinal(x)
253+ ord == m.ordinal(y) && eqlCases[m.MirroredElemTypes ](0 )(x, y, ord)
254+ case m : Mirror .ProductOf [T ] =>
255+ eqlElems[m.MirroredElemTypes ](0 )(x, y)
252256 }
253- }
254257 }
255258
256259 implicit object IntEq extends Eq [Int ] {
@@ -267,79 +270,86 @@ object typeclasses {
267270 object Pickler {
268271 import scala .compiletime .{erasedValue , constValue }
269272 import compiletime ._
270- import reflect .{ Mirror , Generic }
273+ import deriving . _
271274
272275 def nextInt (buf : mutable.ListBuffer [Int ]): Int = try buf.head finally buf.trimStart(1 )
273276
274277 inline def tryPickle [T ](buf : mutable.ListBuffer [Int ], x : T ): Unit = implicit match {
275278 case pkl : Pickler [T ] => pkl.pickle(buf, x)
276279 }
277280
278- inline def pickleElems [Elems <: Tuple ](buf : mutable.ListBuffer [Int ], elems : Mirror , n : Int ): Unit =
281+ inline def pickleElems [Elems <: Tuple ](n : Int )( buf : mutable.ListBuffer [Int ], x : Any ): Unit =
279282 inline erasedValue[Elems ] match {
280283 case _ : (elem *: elems1) =>
281- tryPickle[elem](buf, elems(n). asInstanceOf [elem])
282- pickleElems[elems1](buf, elems, n + 1 )
284+ tryPickle[elem](buf, productElement [elem](x, n) )
285+ pickleElems[elems1](n + 1 )(buf, x )
283286 case _ : Unit =>
284287 }
285288
286- inline def pickleCases [Alts <: Tuple ](buf : mutable.ListBuffer [Int ], xm : Mirror , n : Int ): Unit =
289+ inline def pickleCases [Alts <: Tuple ](n : Int )( buf : mutable.ListBuffer [Int ], x : Any , ord : Int ): Unit =
287290 inline erasedValue[Alts ] match {
288- case _ : (Shape .Case [alt, elems] *: alts1) =>
289- if (xm.ordinal == n) pickleElems[elems](buf, xm, 0 )
290- else pickleCases[alts1](buf, xm, n + 1 )
291+ case _ : (alt *: alts1) =>
292+ if (ord == n)
293+ implicit match {
294+ case m : Mirror .ProductOf [`alt`] => pickleElems[m.MirroredElemTypes ](0 )(buf, x)
295+ }
296+ else pickleCases[alts1](n + 1 )(buf, x, ord)
291297 case _ : Unit =>
292298 }
293299
294300 inline def tryUnpickle [T ](buf : mutable.ListBuffer [Int ]): T = implicit match {
295301 case pkl : Pickler [T ] => pkl.unpickle(buf)
296302 }
297303
298- inline def unpickleElems [Elems <: Tuple ](buf : mutable.ListBuffer [Int ], elems : Array [ AnyRef ], n : Int ): Unit =
304+ inline def unpickleElems [Elems <: Tuple ](n : Int )( buf : mutable.ListBuffer [Int ], elems : ArrayProduct ): Unit =
299305 inline erasedValue[Elems ] match {
300306 case _ : (elem *: elems1) =>
301307 elems(n) = tryUnpickle[elem](buf).asInstanceOf [AnyRef ]
302- unpickleElems[elems1](buf, elems, n + 1 )
308+ unpickleElems[elems1](n + 1 )(buf, elems )
303309 case _ : Unit =>
304310 }
305311
306- inline def unpickleCase [T , Elems <: Tuple ](gen : Generic [ T ], buf : mutable.ListBuffer [Int ], ordinal : Int ): T = {
312+ inline def unpickleCase [T , Elems <: Tuple ](buf : mutable.ListBuffer [Int ], m : Mirror . ProductOf [ T ] ): T = {
307313 inline val size = constValue[Tuple .Size [Elems ]]
308314 inline if (size == 0 )
309- gen.reify(gen.common.mirror(ordinal) )
315+ m.fromProduct( EmptyProduct )
310316 else {
311- val elems = new Array [ Object ] (size)
312- unpickleElems[Elems ](buf, elems, 0 )
313- gen.reify(gen.common.mirror(ordinal, elems) )
317+ val elems = new ArrayProduct (size)
318+ unpickleElems[Elems ](0 )( buf, elems)
319+ m.fromProduct( elems)
314320 }
315321 }
316322
317- inline def unpickleCases [T , Alts <: Tuple ](gen : Generic [ T ], buf : mutable.ListBuffer [Int ], ordinal : Int , n : Int ): T =
323+ inline def unpickleCases [T , Alts <: Tuple ](n : Int )( buf : mutable.ListBuffer [Int ], ord : Int ): T =
318324 inline erasedValue[Alts ] match {
319- case _ : (Shape .Case [_, elems] *: alts1) =>
320- if (n == ordinal) unpickleCase[T , elems](gen, buf, ordinal)
321- else unpickleCases[T , alts1](gen, buf, ordinal, n + 1 )
322- case _ =>
323- throw new IndexOutOfBoundsException (s " unexpected ordinal number: $ordinal" )
325+ case _ : (alt *: alts1) =>
326+ if (ord == n)
327+ implicit match {
328+ case m : Mirror .ProductOf [`alt` & T ] =>
329+ unpickleCase[`alt` & T , m.MirroredElemTypes ](buf, m)
330+ }
331+ else unpickleCases[T , alts1](n + 1 )(buf, ord)
332+ case _ : Unit =>
333+ throw new IndexOutOfBoundsException (s " unexpected ordinal number: $ord" )
324334 }
325335
326- inline def derived [T ](implicit ev : Generic [T ]): Pickler [T ] = new {
327- def pickle (buf : mutable.ListBuffer [Int ], x : T ): Unit = {
328- val xm = ev.reflect(x)
329- inline erasedValue[ev. Shape ] match {
330- case _ : Shape . Cases [alts] =>
331- buf += xm.ordinal
332- pickleCases[alts]( buf, xm, 0 )
333- case _ : Shape . Case [_, elems ] =>
334- pickleElems[elems]( buf, xm, 0 )
336+ inline def derived [T ](implicit ev : Mirror . Of [T ]): Pickler [T ] = new {
337+ def pickle (buf : mutable.ListBuffer [Int ], x : T ): Unit =
338+ inline ev match {
339+ case m : Mirror . SumOf [ T ] =>
340+ val ord = m.ordinal(x)
341+ buf += ord
342+ pickleCases[m. MirroredElemTypes ]( 0 )( buf, x, ord )
343+ case m : Mirror . ProductOf [ T ] =>
344+ pickleElems[m. MirroredElemTypes ]( 0 )( buf, x )
335345 }
336- }
337346 def unpickle (buf : mutable.ListBuffer [Int ]): T =
338- inline erasedValue[ev.Shape ] match {
339- case _ : Shape .Cases [alts] =>
340- unpickleCases[T , alts](ev, buf, nextInt(buf), 0 )
341- case _ : Shape .Case [_, elems] =>
342- unpickleCase[T , elems](ev, buf, 0 )
347+ inline ev match {
348+ case m : Mirror .SumOf [T ] =>
349+ val ord = nextInt(buf)
350+ unpickleCases[T , m.MirroredElemTypes ](0 )(buf, ord)
351+ case m : Mirror .ProductOf [T ] =>
352+ unpickleCase[T , m.MirroredElemTypes ](buf, m)
343353 }
344354 }
345355
0 commit comments