Skip to content

Instantly share code, notes, and snippets.

@ochrons
Last active December 17, 2015 21:38
Show Gist options
  • Save ochrons/fb32b96fa225788c72cf to your computer and use it in GitHub Desktop.
Save ochrons/fb32b96fa225788c72cf to your computer and use it in GitHub Desktop.
class ZipModelR[M, S, SS](root: ModelR[M, M], get1: M => S, get2: M => SS)(implicit cts: ClassTag[S], ctss: ClassTag[SS]) extends ModelR[M, (S, SS)] {
private var zipped = Tuple2[S, SS](null.asInstanceOf[S], null.asInstanceOf[SS])
// ZipModel uses optimized `get` functions to compare if the contents of the tuple has changed or not
// Different comparison functions are used for boxed values and real references
private def getXX(compS: (S, S) => Boolean, compSS: (SS, SS) => Boolean)(model: M) = {
// check if inner references have changed
val v1 = get1(root.value)
val v2 = get2(root.value)
if (compS(zipped._1, v1) || compSS(zipped._2, v2)) {
// create a new tuple
zipped = (v1, v2)
}
zipped
}
def valueEq[A](v1: A, v2: A) = v1 != v2
def refEq[A](v1: A, v2: A) = v1.asInstanceOf[AnyRef] ne v2.asInstanceOf[AnyRef]
def chooseEq(ct: ClassTag[_]) = {
ct match {
case ClassTag.Char => valueEq _
case ClassTag.Int => valueEq _
case ClassTag.Boolean => valueEq _
case ClassTag.Long => valueEq _
case ClassTag.Byte => valueEq _
case ClassTag.Short => valueEq _
case ClassTag.Float => valueEq _
case ClassTag.Double => valueEq _
case _ => refEq _
}
}
// choose correct getXX function base on types of S and SS
private val get = getXX(chooseEq(cts), chooseEq(ctss)) _
}
@som-snytt
Copy link

This test scala.runtime.ScalaRunTime.isValueClass(classTag[Int].runtimeClass) is runtimeClass.isPrimitive. Or case Char | Int | Boolean => valueEq _ is less verbose.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment