randomaccessseq.scala

来自「JAVA 语言的函数式编程扩展」· SCALA 代码 · 共 207 行

SCALA
207
字号
/*                     __                                               *\**     ________ ___   / /  ___     Scala API                            ****    / __/ __// _ | / /  / _ |    (c) 2006-2008, LAMP/EPFL             ****  __\ \/ /__/ __ |/ /__/ __ |    http://scala-lang.org/               **** /____/\___/_/ |_/____/_/ | |                                         ****                          |/                                          **\*                                                                      */// $Id: RandomAccessSeq.scala 14416 2008-03-19 01:17:25Z mihaylov $package scalaobject RandomAccessSeq {  trait Projection[+A] extends Seq.Projection[A] with RandomAccessSeq[A] {    override def projection = this    override def force : RandomAccessSeq[A] = toArray    protected class MapProjection[B](f : A => B) extends super.MapProjection(f) with Projection[B]    override def map[B](f: A => B) : Projection[B] = new MapProjection[B](f)    override def append[B >: A](that: => Iterable[B]): Projection[B] = {      val that0 : Seq[B] = that match {      case that : Seq.Projection[b] => that      case that : Seq[b] => that      case that => that.toList      }      new Projection[B] {        def length = Projection.this.length + that0.length        def apply(idx : Int) =           if (idx < Projection.this.length) Projection.this(idx)          else that0(idx - Projection.this.length)      }            }  }  private[scala] trait Slice[+A] extends Projection[A] {    protected def from  : Int    protected def until : Int    protected def underlying : RandomAccessSeq[A]    def length = {      val length0 = underlying.length      if (from >= until || from >= length0) 0      else (if (until >= length0) length0 else until) - (if (from < 0) 0 else from)    }    def apply(idx : Int) = if (idx < 0 || idx >= length) throw new Predef.IndexOutOfBoundsException                           else underlying.apply((if (from < 0) 0 else from) + idx)    override def slice(from0 : Int, until0 : Int) = {      val from = if (this.from < 0) 0 else this.from      underlying.slice(from + from0, from + until0)      }  }  private[scala] trait Patch[+A] extends Projection[A] {    protected def original : RandomAccessSeq[A]    protected def patch : RandomAccessSeq[A]    protected def from : Int    protected def replaced : Int    def length = original.length + patch.length - replaced    def apply(idx : Int) =       if (idx < from) original.apply(idx)      else if (idx < from + patch.length) patch.apply(idx - from)      else original.apply(idx - patch.length + replaced)    override def stringPrefix = "patch"  }    /** A random access sequence that supports update (e.g., an array) */  trait Mutable[A] extends RandomAccessSeq[A] {    /** <p>     *    Update the element at given index.      *  </p>     *  <p>     *    Indices start a <code>0</code>; <code>xs.apply(0)</code> is the first      *    element of mutable sequence <code>xs</code>.     *  </p>     *  <p>     *    Note the indexing syntax <code>xs(i) = x</code> is a shorthand      *    for <code>xs.update(i, x)</code>.     *  </p>     *     *  @param i   the index     *  @param x   the value to be written at index <code>i</code>     *  @throws ArrayIndexOutOfBoundsException if <code>i < 0</code> or     *          <code>length <= i</code>     */    def update(idx : Int, what : A) : Unit    override def projection : MutableProjection[A] = new MutableProjection[A] {      override def force : Mutable[A] = Mutable.this      def update(idx : Int, what : A) : Unit = Mutable.this.update(idx, what)      def length = Mutable.this.length      def apply(idx : Int) = Mutable.this.apply(idx)    }    def readOnly : RandomAccessSeq[A] = new RandomAccessSeq[A] {      def length = Mutable.this.length      def apply(idx : Int) = Mutable.this.apply(idx)      override def stringPrefix = Mutable.this.stringPrefix + "RO"    }    override def drop( from: Int): MutableProjection[A] = slice(from, length)    override def take(until: Int): MutableProjection[A] = slice(0, until)    override def slice(from0: Int, until0: Int) : MutableProjection[A] = new MutableSlice[A] {      def from = from0      def until = until0      def underlying = Mutable.this    }    override def reverse : MutableProjection[A] = new MutableProjection[A] {      def update(idx: Int, what: A) { Mutable.this.update(length - idx - 1, what) }      def length = Mutable.this.length      def apply(idx: Int) = Mutable.this.apply(length - idx - 1)      override def stringPrefix = Mutable.this.stringPrefix + "R"      override def reverse: MutableProjection[A] = Mutable.this.projection    }  }  trait MutableProjection[A] extends Projection[A] with Mutable[A] {    override def force : Mutable[A] = toArray    override def projection : MutableProjection[A] = this  }  private[scala] trait MutableSlice[A] extends MutableProjection[A] with Slice[A] {    protected def underlying : Mutable[A]    override def slice(from0 : Int, until0 : Int) = {      val from = (if (this.from < 0) 0 else this.from)      underlying.slice(from + from0, from + until0)      }    override def update(idx : Int, what : A) : Unit = {      val from = (if (this.from < 0) 0 else this.from)      if (idx < 0 || idx >= length) throw new Predef.IndexOutOfBoundsException      else underlying.update(from + idx, what)    }  }}/** Sequences that support O(1) element access and O(1) length computation. *  @author Sean McDirmid */trait RandomAccessSeq[+A] extends Seq[A] {  override def projection : RandomAccessSeq.Projection[A] = new RandomAccessSeq.Projection[A] {    def length = RandomAccessSeq.this.length    def apply(idx : Int) = RandomAccessSeq.this.apply(idx)    override def elements = RandomAccessSeq.this.elements    override def stringPrefix = RandomAccessSeq.this.stringPrefix + "P"  }  override def elements : Iterator[A] = new BufferedIterator.Advanced[A] {    var idx = 0    override def peekList(sz : Int) = new RandomAccessSeq[A] {      override def length = RandomAccessSeq.this.length - idx      override def apply(jdx : Int) = RandomAccessSeq.this.apply(jdx + idx)    }    override def hasNext = idx < RandomAccessSeq.this.length    def next = {      if (!hasNext) throw new Predef.NoSuchElementException      val ret = RandomAccessSeq.this.apply(idx)      idx += 1      ret    }  }  override def drop( from: Int): RandomAccessSeq[A] = slice(from, length)  override def take(until: Int): RandomAccessSeq[A] = slice(0, until)  override def slice(from0 : Int, until0 : Int) : RandomAccessSeq[A] = new RandomAccessSeq.Slice[A] {    def from = from0    def until = until0    def underlying = RandomAccessSeq.this  }  override def reverse : Seq[A] = new RandomAccessSeq.Projection[A] {    def length = RandomAccessSeq.this.length    def apply(idx : Int) = RandomAccessSeq.this.apply(length - idx - 1)    override def stringPrefix = RandomAccessSeq.this.stringPrefix + "R"    override def reverse : RandomAccessSeq.Projection[A] = RandomAccessSeq.this.projection  }    /** insert segment <code>patch</code> into this sequence at <code>from</code>     *  replacing  <code>replaced</code> elements. The result is a projection.   */  def patch[B >: A](from0: Int, patch0: RandomAccessSeq[B], replaced0: Int): RandomAccessSeq.Projection[B] = new RandomAccessSeq.Patch[B] {    override def original = RandomAccessSeq.this    override def from = from0    override def patch = patch0    override def replaced = replaced0    override def stringPrefix = RandomAccessSeq.this.stringPrefix + "P"  }    override def ++[B >: A](that: Iterable[B]): RandomAccessSeq[B] = that match {    case that: RandomAccessSeq[b] =>       val ret = new Array[B](length + that.length)      copyToArray(ret, 0)      (that : RandomAccessSeq[B]).copyToArray(ret, length)      ret    case that =>       val buf = new scala.collection.mutable.ArrayBuffer[B]      this copyToBuffer buf      that copyToBuffer buf      buf.readOnly  }    override def toStream : Stream[A] = new Stream.Definite[A] {    override def isEmpty = RandomAccessSeq.this.isEmpty    override def head = RandomAccessSeq.this.apply(0)    override def tail = RandomAccessSeq.this.drop(1).toStream    protected def addDefinedElems(buf: StringBuilder, prefix: String): StringBuilder = {      var prefix0 = prefix      var buf0 = buf      elements.foreach{e =>        buf0 = buf0.append(prefix0).append(e)        prefix0 = ", "      }      buf0    }  }    /** will return false if index is out of bounds */  final def safeIs(idx : Int, a : Any) = if (idx >= 0 && idx < length) this(idx) == a else false  }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?