/* __ *\ ** ________ ___ / / ___ Scala API ** ** / __/ __// _ | / / / _ | (c) 2003-2009, LAMP/EPFL ** ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** ** /____/\___/_/ |_/____/_/ | | ** ** |/ ** \* */ // $Id: BufferTemplate.scala 18545 2009-08-22 14:10:22Z extempore $ package scala.collection.generic import scala.collection._ import scala.collection.mutable.Buffer import scala.collection.script._ /** Buffers are used to create sequences of elements incrementally by * appending, prepending, or inserting new elements. It is also * possible to access and modify elements in a random access fashion * via the index of the element in the current sequence. * * @author Matthias Zenger * @author Martin Odersky * @version 2.8 */ @cloneable trait BufferTemplate[A, +This <: BufferTemplate[A, This] with Buffer[A]] extends Growable[A] with Shrinkable[A] with Scriptable[A] with Addable[A, This] with Subtractable[A, This] with Cloneable[This] with SequenceTemplate[A, This] { self => import collection.{Iterable, Traversable} // Abstract methods from Vector: /** Return element at index `n` * @throws IndexOutofBoundsException if the index is not valid */ def apply(n: Int): A /** Replace element at index <code>n</code> with the new element * <code>newelem</code>. * * @param n the index of the element to replace. * @param newelem the new element. * @throws IndexOutofBoundsException if the index is not valid */ def update(n: Int, newelem: A) /** Return number of elements in the buffer */ def length: Int // Abstract methods from Appendable /** Append a single element to this buffer. * * @param elem the element to append. */ def +=(elem: A): this.type /** Clears the buffer contents. */ def clear() // Abstract methods new in this class /** Prepend a single element to this buffer and return * the identity of the buffer. * @param elem the element to prepend. */ def +:(elem: A): This /** Inserts new elements at the index <code>n</code>. Opposed to method * <code>update</code>, this method will not replace an element with a * one. Instead, it will insert a new element at index <code>n</code>. * * @param n the index where a new element will be inserted. * @param iter the iterable object providing all elements to insert. * @throws IndexOutofBoundsException if the index is not valid */ def insertAll(n: Int, iter: Traversable[A]) /** Removes the element on a given index position. * * @param n the index which refers to the element to delete. * @return the previous element */ def remove(n: Int): A /** Removes a number of elements from a given index position. * * @param n the index which refers to the element to delete. * @param count the number of elements to delete * @throws IndexOutofBoundsException if the index is not valid */ def remove(n: Int, count: Int) { for (i <- 0 until count) remove(n) } /** Removes a single element from this buffer, at its first occurrence. * If the buffer does not contain that element, it is unchanged. * * @param x the element to remove. */ def -= (x: A): this.type = { val i = indexOf(x) if (i != -1) remove(i) this } /** Prepends a number of elements provided by an iterable object * via its <code>iterator</code> method. The identity of the * buffer is returned.(thisCollection /: elems) (_ plus _) * * @param iter the iterable object. */ def ++:(iter: Traversable[A]): This = { for (x <- iter) x +: this; thisCollection } /** Prepends a number of elements provided by an iterator * The identity of the buffer is returned. * * @param iter the iterator * @return the updated buffer. */ def ++:(iter: Iterator[A]): This = { for (x <- iter) x +: this; thisCollection } /** Appends elements to this buffer. * * @param elems the elements to append. */ def append(elems: A*) { this ++= elems } /** Appends a number of elements provided by an iterable object * via its <code>iterator</code> method. * * @param iter the iterable object. */ def appendAll(iter: Traversable[A]) { this ++= iter } /** Prepend given elements to this list. * * @param elem the element to prepend. */ def prepend(elems: A*) { elems ++: this } /** Prepends a number of elements provided by an iterable object * via its <code>iterator</code> method. The identity of the * buffer is returned. * * @param iter the iterable object. */ def prependAll(iter: Traversable[A]) { iter ++: this } /** Prepends a number of elements provided by an iterable object * via its <code>iterator</code> method. The identity of the * buffer is returned. * * @param iter the iterable object. */ def prependAll(iter: Iterator[A]) { iter ++: this } /** Inserts new elements at the index <code>n</code>. Opposed to method * <code>update</code>, this method will not replace an element with a * one. Instead, it will insert the new elements at index <code>n</code>. * * @param n the index where a new element will be inserted. * @param elems the new elements to insert. */ def insert(n: Int, elems: A*) { insertAll(n, elems) } /** Removes the first <code>n</code> elements. * * @param n the number of elements to remove from the beginning * of this buffer. */ def trimStart(n: Int) { remove(0, n) } /** Removes the last <code>n</code> elements. * * @param n the number of elements to remove from the end * of this buffer. */ def trimEnd(n: Int) { remove(length - n max 0, n) } /** Send a message to this scriptable object. * * @param cmd the message to send. */ def <<(cmd: Message[A]): Unit = cmd match { case Include(Start, x) => prepend(x) case Include(End, x) => append(x) case Include(Index(n), x) => insert(n, x) case Include(NoLo, x) => this += x case Update(Start, x) => update(0, x) case Update(End, x) => update(length - 1, x) case Update(Index(n), x) => update(n, x) case Remove(Start, x) => if (this(0) == x) remove(0) case Remove(End, x) => if (this(length - 1) == x) remove(length - 1) case Remove(Index(n), x) => if (this(n) == x) remove(n) case Remove(NoLo, x) => this -= x case Reset() => clear case s: Script[_] => s.iterator foreach << case _ => throw new UnsupportedOperationException("message " + cmd + " not understood") } /** Defines the prefix of the string representation. */ override def stringPrefix: String = "Buffer" /** Adds a number of elements in an array * * @param src the array * @param start the first element to append * @param len the number of elements to append */ @deprecated("replace by: <code>buf ++= src.view(start, end)</code>") def ++=(src: Array[A], start: Int, len: Int) { var i = start val end = i + len while (i < end) { this += src(i) i += 1 } } /** Adds a single element to this collection and returns * the collection itself. * * @param elem the element to add. */ @deprecated("Use += instead if you intend to add by side effect to an existing collection.\n"+ "Use `clone() ++=' if you intend to create a new collection.") override def + (elem: A): This = { +=(elem); thisCollection } /** Adds two or more elements to this collection and returns * the collection itself. * * @param elem1 the first element to add. * @param elem2 the second element to add. * @param elems the remaining elements to add. */ @deprecated("Use += instead if you intend to add by side effect to an existing collection.\n"+ "Use `clone() ++=' if you intend to create a new collection.") override def + (elem1: A, elem2: A, elems: A*): This = { this += elem1 += elem2 ++= elems thisCollection } /** Adds a number of elements provided by a traversable object and returns * either the collection itself. * * @param iter the iterable object. */ @deprecated("Use ++= instead if you intend to add by side effect to an existing collection.\n"+ "Use `clone() ++=` if you intend to create a new collection.") override def ++(iter: Traversable[A]): This = { for (elem <- iter) +=(elem) thisCollection } /** Adds a number of elements provided by an iterator and returns * the collection itself. * * @param iter the iterator */ @deprecated("Use ++= instead if you intend to add by side effect to an existing collection.\n"+ "Use `clone() ++=` if you intend to create a new collection.") override def ++ (iter: Iterator[A]): This = { for (elem <- iter) +=(elem) thisCollection } /** Removes a single element from this collection and returns * the collection itself. * * @param elem the element to remove. */ @deprecated("Use -= instead if you intend to remove by side effect from an existing collection.\n"+ "Use `clone() -=` if you intend to create a new collection.") override def -(elem: A): This = { -=(elem); thisCollection } /** Removes two or more elements from this collection and returns * the collection itself. * * @param elem1 the first element to remove. * @param elem2 the second element to remove. * @param elems the remaining elements to remove. */ @deprecated("Use -= instead if you intend to remove by side effect from an existing collection.\n"+ "Use `clone() -=` if you intend to create a new collection.") override def -(elem1: A, elem2: A, elems: A*): This = { this -= elem1 -= elem2 --= elems thisCollection } /** Removes a number of elements provided by a Traversable object and returns * the collection itself. * * @param iter the Traversable object. */ @deprecated("Use --= instead if you intend to remove by side effect from an existing collection.\n"+ "Use `clone() --=` if you intend to create a new collection.") override def --(iter: Traversable[A]): This = { for (elem <- iter) -=(elem) thisCollection } /** Removes a number of elements provided by an iterator and returns * the collection itself. * * @param iter the iterator */ @deprecated("Use --= instead if you intend to remove by side effect from an existing collection.\n"+ "Use `clone() --=` if you intend to create a new collection.") override def --(iter: Iterator[A]): This = { for (elem <- iter) -=(elem) thisCollection } }