Skip to content

Instantly share code, notes, and snippets.

@ochafik
Created December 9, 2014 15:28
Show Gist options
  • Select an option

  • Save ochafik/be125c12240ee17d5ee4 to your computer and use it in GitHub Desktop.

Select an option

Save ochafik/be125c12240ee17d5ee4 to your computer and use it in GitHub Desktop.
OpenCL Tuples in Scala
import scala.language.dynamics
import scala.language.experimental.macros
sealed trait Arity {
def size: Int
}
class Arity2 extends Arity {
override def size = 2
}
object Arity2 extends Arity2
class Arity3 extends Arity2 {
override def size = 3
}
object Arity3 extends Arity3
class Arity4 extends Arity3 {
override def size = 4
}
object Arity4 extends Arity4
class Arity8 extends Arity4 {
override def size = 8
}
object Arity8 extends Arity8
class Arity16 extends Arity8 {
override def size = 16
}
object Arity16 extends Arity16
object Tuple {
def selectDynamicImpl[T : c.WeakTypeTag, A : c.WeakTypeTag]
(c: reflect.macros.whitebox.Context)
(name: c.Expr[String]): c.Expr[Any] = ???
def updateDynamicImpl[T : c.WeakTypeTag, A : c.WeakTypeTag]
(c: reflect.macros.whitebox.Context)
(name: c.Expr[String], value: c.Expr[Any]): c.Expr[Unit] = ???
}
class Tuple[T, A <: Arity2](val values: T*)(implicit val a: A) extends Dynamic {
assert(values.size == a.size)
def selectDynamic(name: String): Any = macro Tuple.selectDynamicImpl[T, A]
def updateDynamic(name: String, value: Any): Unit = macro Tuple.updateDynamicImpl[T, A]
def s0 = values(0)
def x = s0
def s1 = values(1)
def y = s1
def s2(implicit ev: A <:< Arity3) = values(2)
def z(implicit ev: A <:< Arity3) = s2
def s3(implicit ev: A <:< Arity4) = values(3)
def w(implicit ev: A <:< Arity4) = s3
def s4(implicit ev: A <:< Arity8) = values(4)
def s5(implicit ev: A <:< Arity8) = values(5)
def s6(implicit ev: A <:< Arity8) = values(6)
def s7(implicit ev: A <:< Arity8) = values(7)
def s8(implicit ev: A <:< Arity16) = values(8)
def s9(implicit ev: A <:< Arity16) = values(9)
def sa(implicit ev: A <:< Arity16) = values(10)
def sb(implicit ev: A <:< Arity16) = values(11)
def sc(implicit ev: A <:< Arity16) = values(12)
def sd(implicit ev: A <:< Arity16) = values(13)
def se(implicit ev: A <:< Arity16) = values(14)
def sf(implicit ev: A <:< Arity16) = values(15)
}
class TupleBuilder[T, A <: Arity](val a: A) {
// def unapply(t: Tuple[T, A]) =
// if (t.a == a) Some(t) else None
}
class TupleBuilder2[T] extends TupleBuilder[T, Arity2](Arity2) {
// private[this] implicit def a = Arity2
def apply(s0: T, s1: T) = new Tuple[T, Arity2](s0, s1)(Arity2)
def unapply(t: Tuple[T, _]) = if (t.a != a) None else Some {
val Seq(s0, s1) = t.values
(s0, s1)
}
}
class TupleBuilder3[T] extends TupleBuilder[T, Arity3](Arity3) {
// private[this] implicit def a = Arity3
def apply(s0: T, s1: T, s2: T) = new Tuple[T, Arity3](s0, s1, s2)(Arity3)
def unapply(t: Tuple[T, _]) = if (t.a != a) None else Some {
val Seq(s0, s1, s2) = t.values
(s0, s1, s2)
}
}
class TupleBuilder4[T] extends TupleBuilder[T, Arity4](Arity4) {
// private[this] implicit def a = Arity4
def apply(s0: T, s1: T, s2: T, s3: T) = new Tuple[T, Arity4](s0, s1, s2, s3)(Arity4)
def unapply(t: Tuple[T, _]) = if (t.a != a) None else Some {
val Seq(s0, s1, s2, s3) = t.values
(s0, s1, s2, s3)
}
}
class TupleBuilder8[T] extends TupleBuilder[T, Arity8](Arity8) {
// private[this] implicit def a = Arity8
def apply(s0: T, s1: T, s2: T, s3: T, s4: T, s5: T, s6: T, s7: T) =
new Tuple[T, Arity8](s0, s1, s2, s3, s4, s5, s6, s7)(Arity8)
def unapply(t: Tuple[T, _]) = if (t.a != a) None else Some {
val Seq(s0, s1, s2, s3, s4, s5, s6, s7) = t.values
(s0, s1, s2, s3, s4, s5, s6, s7)
}
}
class TupleBuilder16[T] extends TupleBuilder[T, Arity16](Arity16) {
// private[this] implicit def a = Arity16
def apply(s0: T, s1: T, s2: T, s3: T, s4: T, s5: T, s6: T, s7: T,
s8: T, s9: T, sa: T, sb: T, sc: T, sd: T, se: T, sf: T) =
new Tuple[T, Arity16](s0, s1, s2, s3, s4, s5, s6, s7,
s8, s9, sa, sb, sc, sd, se, sf)(Arity16)
def unapply(t: Tuple[T, _]) = if (t.a != a) None else Some {
val Seq(s0, s1, s2, s3, s4, s5, s6, s7,
s8, s9, sa, sb, sc, sd, se, sf) = t.values
(s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sa, sb, sc, sd, se, sf)
}
}
object Int2 extends TupleBuilder2[Int]
object Int3 extends TupleBuilder3[Int]
object Int4 extends TupleBuilder4[Int]
object Int8 extends TupleBuilder8[Int]
object Int16 extends TupleBuilder16[Int]
object Short2 extends TupleBuilder2[Short]
object Short3 extends TupleBuilder3[Short]
object Short4 extends TupleBuilder4[Short]
object Short8 extends TupleBuilder8[Short]
object Short16 extends TupleBuilder16[Short]
object Long2 extends TupleBuilder2[Long]
object Long3 extends TupleBuilder3[Long]
object Long4 extends TupleBuilder4[Long]
object Long8 extends TupleBuilder8[Long]
object Long6 extends TupleBuilder16[Long]
object Byte2 extends TupleBuilder2[Byte]
object Byte3 extends TupleBuilder3[Byte]
object Byte4 extends TupleBuilder4[Byte]
object Byte8 extends TupleBuilder8[Byte]
object Byte16 extends TupleBuilder16[Byte]
object Float2 extends TupleBuilder2[Float]
object Float3 extends TupleBuilder3[Float]
object Float4 extends TupleBuilder4[Float]
object Float8 extends TupleBuilder8[Float]
object Float16 extends TupleBuilder16[Float]
object Double2 extends TupleBuilder2[Double]
object Double3 extends TupleBuilder3[Double]
object Double4 extends TupleBuilder4[Double]
object Double8 extends TupleBuilder8[Double]
object Double16 extends TupleBuilder16[Double]
object Test extends App {
val t1 = Int2(1, 2)
println(t1)
val Int2(a, b) = t1
println(s"a = $a, b = $b")
println(t1.s0)
println(t1.s1)
// println(t1.s2)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment