Skip to content

Instantly share code, notes, and snippets.

@landonf
Created January 5, 2015 21:37
Show Gist options
  • Save landonf/cdc369a30b095dc40339 to your computer and use it in GitHub Desktop.
Save landonf/cdc369a30b095dc40339 to your computer and use it in GitHub Desktop.
Unboxed unsigned types (including direct unboxed Array[Int] representation)
import scala.language.implicitConversions
object Unsigned {
// No-boxing tag
private type Tagged[T] = { type Tag = T }
type Unsigned[T] = T with Tagged[UTag[T]]
sealed trait UTag[T]
@inline def apply[T] (u: T) : Unsigned[T] = u.asInstanceOf[Unsigned[T]]
@inline private def unwrap[T] (u: Unsigned[T]): T = u.asInstanceOf[T]
implicit class UnsignedIntOps (val self: Unsigned[Int]) extends AnyVal {
// unsigned op implementations from Spire
@inline def unary_~ : UnsignedIntOps = self
@inline def + (that: Unsigned[Int]): UnsignedIntOps = (unwrap(self) + unwrap(that)).U
@inline def - (that: Unsigned[Int]): UnsignedIntOps = (unwrap(self) - unwrap(that)).U
@inline def * (that: Unsigned[Int]): UnsignedIntOps = (unwrap(self) * unwrap(that)).U
@inline final def % (that: Unsigned[Int]): UnsignedIntOps = self.U - (self.U / that) * that
@inline final def / (that: Unsigned[Int]): UnsignedIntOps = {
val n = unwrap(self)
val d = unwrap(that)
if (d == 0) {
throw new java.lang.ArithmeticException("Division by zero")
} else if (d < 0) {
if (n >= 0 || n < d) 0.U else 1.U
} else if (n >= 0) {
(n / d).U
} else {
val half = n >>> 1
if (half < d) {
1.U
} else {
(((half / d) << 1) + (((half % d) << 1) + (n & 1)) / d).U
}
}
}
}
implicit class UnsignedIntPromotion (val value: Int) extends AnyVal {
@inline def U: UnsignedIntOps = UnsignedIntOps(Unsigned(value))
}
@inline implicit def mkUnsignedIntFromOps (ops: UnsignedIntOps): Unsigned[Int] = ops.self
def exampleUnboxedWrapping (i: Int): Unsigned[Int] = Unsigned(i)
def exampleUnboxedArray (arr: Array[Unsigned[Int]]): Unsigned[Int] = {
arr.foldLeft(0.U)(_ + _)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment