package ranges; class Range(val start : Int, val end : Int){ if (start >= end) throw new IndexOutOfBoundsException(); def checkRange(min : Int, max : Int){ if (min < start || max > end) throw new IndexOutOfBoundsException(); } def inBounds(x : Int) : Index = unsafeFromInt(Math.min(end - 1, Math.max(x, start))); def checkBounds (x : Int) : Index = if (x < start || x >= end) throw new IndexOutOfBoundsException() else unsafeFromInt(x); private[Range] def unsafeFromInt (i : Int) = Index(i); // Separated into a method for refactoring and unsafe declaration. val range = start until end; val length = end - start; val maxIndex = unsafeFromInt(end - 1); val minIndex = unsafeFromInt(start); val indices = range.map(unsafeFromInt(_)); trait Slice[T] extends Iterable[T] { def apply(i : Index) : T = unsafeApply(i); def update(i : Index, t : T) = unsafeUpdate(i, t); private[Range] def unsafeApply(i : Int) : T; private[Range] def unsafeUpdate(i : Int, t : T) : Unit; def elements = range.elements.map(unsafeApply(_)); } class ArraySlice[T](array : Array[T]) extends Slice[T]{ if (length < end) throw new IndexOutOfBoundsException(); private[Range] def unsafeApply(i : Int) = array(i); private[Range] def unsafeUpdate(i : Int, t : T) : Unit = array(i) = t; override def foreach(f : T => Unit) = for (val i <- range) array(i); } class CheckedArray[T] extends Slice[T]{ private val array = new Array[T](length); private[Range] def unsafeApply(i : Int) = array(i - start); private[Range] def unsafeUpdate(i : Int, t : T) : Unit = array(i - start) = t; override def foreach(f : T => Unit) = array.foreach(f); } implicit def toInteger(i : Index) = i.toInt; case class Index private[Range] (val toInt : Int){ def max(y : Index) = unsafeFromInt(Math.max(this, y)); def min(y : Index) = unsafeFromInt(Math.min(this, y)); def mid(y : Index) = unsafeFromInt((this + y) >>> 1); def opposite = unsafeFromInt(end + start - 1 - this); }; }
You need to create an account or log in to post comments to this site.