Created
January 5, 2015 21:37
-
-
Save landonf/cdc369a30b095dc40339 to your computer and use it in GitHub Desktop.
Unboxed unsigned types (including direct unboxed Array[Int] representation)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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