From 2068560890ff96121befe4e3eaf40f2f46860cd6 Mon Sep 17 00:00:00 2001 From: Lukas Rytz Date: Sat, 16 May 2009 09:15:52 +0000 Subject: fixed .net build --- src/dotnet-library/scala/List.scala | 1433 -------------------- src/dotnet-library/scala/Numeric.scala | 117 ++ src/dotnet-library/scala/Ordering.scala | 319 +++++ src/dotnet-library/scala/Predef.scala | 10 +- src/dotnet-library/scala/Range.scala | 234 ++++ src/dotnet-library/scala/StringBuilder.scala | 912 ------------- .../scala/collection/JavaConversions.scala | 1 + .../scala/collection/immutable/List.scala | 863 ++++++++++++ .../scala/collection/jcl/ArrayList.scala | 1 - .../scala/collection/jcl/Buffer.scala | 1 - .../scala/collection/jcl/BufferIterator.scala | 1 - .../scala/collection/jcl/BufferWrapper.scala | 1 - .../scala/collection/jcl/Collection.scala | 1 - .../scala/collection/jcl/CollectionWrapper.scala | 1 - .../scala/collection/jcl/Conversions.scala | 1 - .../scala/collection/jcl/HashMap.scala | 1 - .../scala/collection/jcl/HashSet.scala | 1 - .../scala/collection/jcl/Hashtable.scala | 1 - .../scala/collection/jcl/IdentityHashMap.scala | 1 - .../scala/collection/jcl/IterableWrapper.scala | 1 - .../scala/collection/jcl/LinkedHashMap.scala | 1 - .../scala/collection/jcl/LinkedHashSet.scala | 1 - .../scala/collection/jcl/LinkedList.scala | 1 - src/dotnet-library/scala/collection/jcl/Map.scala | 1 - .../scala/collection/jcl/MapWrapper.scala | 1 - .../scala/collection/jcl/MutableIterable.scala | 1 - .../scala/collection/jcl/MutableIterator.scala | 1 - .../scala/collection/jcl/MutableSeq.scala | 1 - .../scala/collection/jcl/Ranged.scala | 1 - .../scala/collection/jcl/SeqIterator.scala | 1 - src/dotnet-library/scala/collection/jcl/Set.scala | 1 - .../scala/collection/jcl/SetWrapper.scala | 1 - .../scala/collection/jcl/Sorted.scala | 1 - .../scala/collection/jcl/SortedMap.scala | 1 - .../scala/collection/jcl/SortedMapWrapper.scala | 1 - .../scala/collection/jcl/SortedSet.scala | 1 - .../scala/collection/jcl/SortedSetWrapper.scala | 1 - .../scala/collection/jcl/Tests.scala | 1 - .../scala/collection/jcl/TreeMap.scala | 1 - .../scala/collection/jcl/TreeSet.scala | 1 - .../scala/collection/jcl/WeakHashMap.scala | 1 - .../scala/collection/mutable/JavaMapAdaptor.scala | 1 - .../scala/collection/mutable/JavaSetAdaptor.scala | 1 - .../scala/collection/mutable/StringBuilder.scala | 957 +++++++++++++ .../scala/collection/mutable/WeakHashMap.scala | 1 + src/dotnet-library/scala/runtime/RichChar.scala | 24 +- src/dotnet-library/scala/runtime/RichInt.scala | 4 +- src/dotnet-library/scala/runtime/RichString.scala | 129 +- .../scala/runtime/RichStringBuilder.scala | 1 - .../scalax/collection/immutable/List.scala | 929 ------------- 50 files changed, 2568 insertions(+), 3401 deletions(-) delete mode 100644 src/dotnet-library/scala/List.scala create mode 100755 src/dotnet-library/scala/Numeric.scala create mode 100644 src/dotnet-library/scala/Ordering.scala create mode 100644 src/dotnet-library/scala/Range.scala delete mode 100644 src/dotnet-library/scala/StringBuilder.scala create mode 100644 src/dotnet-library/scala/collection/JavaConversions.scala create mode 100644 src/dotnet-library/scala/collection/immutable/List.scala delete mode 100644 src/dotnet-library/scala/collection/jcl/ArrayList.scala delete mode 100644 src/dotnet-library/scala/collection/jcl/Buffer.scala delete mode 100644 src/dotnet-library/scala/collection/jcl/BufferIterator.scala delete mode 100644 src/dotnet-library/scala/collection/jcl/BufferWrapper.scala delete mode 100644 src/dotnet-library/scala/collection/jcl/Collection.scala delete mode 100644 src/dotnet-library/scala/collection/jcl/CollectionWrapper.scala delete mode 100644 src/dotnet-library/scala/collection/jcl/Conversions.scala delete mode 100644 src/dotnet-library/scala/collection/jcl/HashMap.scala delete mode 100644 src/dotnet-library/scala/collection/jcl/HashSet.scala delete mode 100644 src/dotnet-library/scala/collection/jcl/Hashtable.scala delete mode 100644 src/dotnet-library/scala/collection/jcl/IdentityHashMap.scala delete mode 100644 src/dotnet-library/scala/collection/jcl/IterableWrapper.scala delete mode 100644 src/dotnet-library/scala/collection/jcl/LinkedHashMap.scala delete mode 100644 src/dotnet-library/scala/collection/jcl/LinkedHashSet.scala delete mode 100644 src/dotnet-library/scala/collection/jcl/LinkedList.scala delete mode 100644 src/dotnet-library/scala/collection/jcl/Map.scala delete mode 100644 src/dotnet-library/scala/collection/jcl/MapWrapper.scala delete mode 100644 src/dotnet-library/scala/collection/jcl/MutableIterable.scala delete mode 100644 src/dotnet-library/scala/collection/jcl/MutableIterator.scala delete mode 100644 src/dotnet-library/scala/collection/jcl/MutableSeq.scala delete mode 100644 src/dotnet-library/scala/collection/jcl/Ranged.scala delete mode 100644 src/dotnet-library/scala/collection/jcl/SeqIterator.scala delete mode 100644 src/dotnet-library/scala/collection/jcl/Set.scala delete mode 100644 src/dotnet-library/scala/collection/jcl/SetWrapper.scala delete mode 100644 src/dotnet-library/scala/collection/jcl/Sorted.scala delete mode 100644 src/dotnet-library/scala/collection/jcl/SortedMap.scala delete mode 100644 src/dotnet-library/scala/collection/jcl/SortedMapWrapper.scala delete mode 100644 src/dotnet-library/scala/collection/jcl/SortedSet.scala delete mode 100644 src/dotnet-library/scala/collection/jcl/SortedSetWrapper.scala delete mode 100644 src/dotnet-library/scala/collection/jcl/Tests.scala delete mode 100644 src/dotnet-library/scala/collection/jcl/TreeMap.scala delete mode 100644 src/dotnet-library/scala/collection/jcl/TreeSet.scala delete mode 100644 src/dotnet-library/scala/collection/jcl/WeakHashMap.scala delete mode 100644 src/dotnet-library/scala/collection/mutable/JavaMapAdaptor.scala delete mode 100644 src/dotnet-library/scala/collection/mutable/JavaSetAdaptor.scala create mode 100644 src/dotnet-library/scala/collection/mutable/StringBuilder.scala create mode 100644 src/dotnet-library/scala/collection/mutable/WeakHashMap.scala delete mode 100644 src/dotnet-library/scala/runtime/RichStringBuilder.scala delete mode 100644 src/dotnet-library/scalax/collection/immutable/List.scala (limited to 'src/dotnet-library') diff --git a/src/dotnet-library/scala/List.scala b/src/dotnet-library/scala/List.scala deleted file mode 100644 index 4aef6126cd..0000000000 --- a/src/dotnet-library/scala/List.scala +++ /dev/null @@ -1,1433 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2009, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -// $Id$ - - -package scala - -import scala.collection.mutable.{ListBuffer, LinkedHashMap} -import annotation.tailrec -import Predef._ - -/** This object provides methods for creating specialized lists, and for - * transforming special kinds of lists (e.g. lists of lists). - * - * @author Martin Odersky and others - * @version 1.0, 15/07/2003 - */ -object List { - - /** Create a list with given elements. - * - * @param xs the elements to put in the list - * @return the list containing elements xs. - */ - def apply[A](xs: A*): List[A] = xs.toList - - /** for unapply matching - */ - def unapplySeq[A](x: List[A]): Some[List[A]] = Some(x) - - /** Create a sorted list of all integers in a range. - * - * @param from the start value of the list - * @param end the end value of the list - * @return the sorted list of all integers in range [from;end). - */ - def range(start: Int, end: Int): List[Int] = - range(start, end, 1) - - /** Create a list with element values - * vn+1 = vn + step - * where v0 = start - * and elements are in the range between start (inclusive) - * and end (exclusive) - * - * @param start the start value of the list - * @param end the end value of the list - * @param step the increment value of the list - * @return the sorted list of all integers in range [start;end). - */ - def range(start: Int, end: Int, step: Int): List[Int] = { - if (step == 0) - throw new IllegalArgumentException("step is zero") - val b = new ListBuffer[Int] - var i = start - while ((step <= 0 || i < end) && (step >= 0 || i > end)) { - b += i - i += step - } - b.toList - } - - /** Create a sorted list with element values - * vn+1 = step(vn) - * where v0 = start - * and elements are in the range between start (inclusive) - * and end (exclusive) - * - * @param start the start value of the list - * @param end the end value of the list - * @param step the increment function of the list, which given vn, - * computes vn+1. Must be monotonically increasing - * or decreasing. - * @return the sorted list of all integers in range [start;end). - */ - def range(start: Int, end: Int, step: Int => Int): List[Int] = { - val up = step(start) > start - val down = step(start) < start - val b = new ListBuffer[Int] - var i = start - while ((!up || i < end) && (!down || i > end)) { - b += i - val next = step(i) - if (i == next) - throw new IllegalArgumentException("the step function did not make any progress on "+ i) - i = next - } - b.toList - } - - /** Create a list containing several copies of an element. - * - * @param n the length of the resulting list - * @param elem the element composing the resulting list - * @return a list composed of n elements all equal to elem - */ - def make[A](n: Int, elem: A): List[A] = { - val b = new ListBuffer[A] - var i = 0 - while (i < n) { - b += elem - i += 1 - } - b.toList - } - - /** Create a list by applying a function to successive integers. - * - * @param n the length of the resulting list - * @param maker the procedure which, given an integer n, - * returns the nth element of the resulting list, where - * n is in interval [0;n). - * @return the list obtained by applying the maker function to - * successive integers from 0 to n (exclusive). - */ - def tabulate[A](n: Int, maker: Int => A): List[A] = { - val b = new ListBuffer[A] - var i = 0 - while (i < n) { - b += maker(i) - i += 1 - } - b.toList - } - - /** Concatenate all the elements of a given list of lists. - * - * @param xss the list of lists that are to be concatenated - * @return the concatenation of all the lists - */ - def flatten[A](xss: List[List[A]]): List[A] = concat(xss: _*) - - /** Concatenate all the argument lists into a single list. - * - * @param xss the lists that are to be concatenated - * @return the concatenation of all the lists - */ - def concat[A](xss: List[A]*): List[A] = { - val b = new ListBuffer[A] - for (xs <- xss) { - var xc = xs - while (!xc.isEmpty) { - b += xc.head - xc = xc.tail - } - } - b.toList - } - - /** Transforms a list of pairs into a pair of lists. - * - * @param xs the list of pairs to unzip - * @return a pair of lists. - */ - def unzip[A,B](xs: List[(A,B)]): (List[A], List[B]) = { - val b1 = new ListBuffer[A] - val b2 = new ListBuffer[B] - var xc = xs - while (!xc.isEmpty) { - b1 += xc.head._1 - b2 += xc.head._2 - xc = xc.tail - } - (b1.toList, b2.toList) - } - - /** Transforms an iterable of pairs into a pair of lists. - * - * @param xs the iterable of pairs to unzip - * @return a pair of lists. - */ - def unzip[A,B](xs: Iterable[(A,B)]): (List[A], List[B]) = - xs.foldRight[(List[A], List[B])]((Nil, Nil)) { - case ((x, y), (xs, ys)) => (x :: xs, y :: ys) - } - - /** - * Returns the Left values in the given Iterable of Eithers. - */ - def lefts[A, B](es: Iterable[Either[A, B]]) = - es.foldRight[List[A]](Nil)((e, as) => e match { - case Left(a) => a :: as - case Right(_) => as - }) - - /** - * Returns the Right values in the givenIterable of Eithers. - */ - def rights[A, B](es: Iterable[Either[A, B]]) = - es.foldRight[List[B]](Nil)((e, bs) => e match { - case Left(_) => bs - case Right(b) => b :: bs - }) - - /** Transforms an Iterable of Eithers into a pair of lists. - * - * @param xs the iterable of Eithers to separate - * @return a pair of lists. - */ - def separate[A,B](es: Iterable[Either[A,B]]): (List[A], List[B]) = - es.foldRight[(List[A], List[B])]((Nil, Nil)) { - case (Left(a), (lefts, rights)) => (a :: lefts, rights) - case (Right(b), (lefts, rights)) => (lefts, b :: rights) - } - - /** Converts an iterator to a list. - * - * @param it the iterator to convert - * @return a list that contains the elements returned by successive - * calls to it.next - */ - def fromIterator[A](it: Iterator[A]): List[A] = it.toList - - /** Converts an array into a list. - * - * @param arr the array to convert - * @return a list that contains the same elements than arr - * in the same order - */ - def fromArray[A](arr: Array[A]): List[A] = fromArray(arr, 0, arr.length) - - /** Converts a range of an array into a list. - * - * @param arr the array to convert - * @param start the first index to consider - * @param len the lenght of the range to convert - * @return a list that contains the same elements than arr - * in the same order - */ - def fromArray[A](arr: Array[A], start: Int, len: Int): List[A] = { - var res: List[A] = Nil - var i = start + len - while (i > start) { - i -= 1 - res = arr(i) :: res - } - res - } - - /** Parses a string which contains substrings separated by a - * separator character and returns a list of all substrings. - * - * @param str the string to parse - * @param separator the separator character - * @return the list of substrings - */ - def fromString(str: String, separator: Char): List[String] = { - var words: List[String] = Nil - var pos = str.length() - while (pos > 0) { - val pos1 = str.lastIndexOf(separator, pos - 1) - if (pos1 + 1 < pos) - words = str.substring(pos1 + 1, pos) :: words - pos = pos1 - } - words - } - - /** Returns the given string as a list of characters. - * - * @param str the string to convert. - * @return the string as a list of characters. - * @deprecated use str.toList instead - */ - @deprecated def fromString(str: String): List[Char] = - str.toList - - /** Returns the given list of characters as a string. - * - * @param xs the list to convert. - * @return the list in form of a string. - */ - def toString(xs: List[Char]): String = { - val sb = new StringBuilder() - var xc = xs - while (!xc.isEmpty) { - sb.append(xc.head) - xc = xc.tail - } - sb.toString() - } - - /** Like xs map f, but returns xs unchanged if function - * f maps all elements to themselves. - * - * @param xs ... - * @param f ... - * @return ... - */ - def mapConserve[A <: AnyRef](xs: List[A])(f: A => A): List[A] = { - def loop(ys: List[A]): List[A] = - if (ys.isEmpty) xs - else { - val head0 = ys.head - val head1 = f(head0) - if (head1 eq head0) { - loop(ys.tail) - } else { - val ys1 = head1 :: mapConserve(ys.tail)(f) - if (xs eq ys) ys1 - else { - val b = new ListBuffer[A] - var xc = xs - while (xc ne ys) { - b += xc.head - xc = xc.tail - } - b.prependToList(ys1) - } - } - } - loop(xs) - } - - /** Returns the list resulting from applying the given function f - * to corresponding elements of the argument lists. - * - * @param f function to apply to each pair of elements. - * @return [f(a0,b0), ..., f(an,bn)] if the lists are - * [a0, ..., ak], [b0, ..., bl] and - * n = min(k,l) - */ - def map2[A,B,C](xs: List[A], ys: List[B])(f: (A, B) => C): List[C] = { - val b = new ListBuffer[C] - var xc = xs - var yc = ys - while (!xc.isEmpty && !yc.isEmpty) { - b += f(xc.head, yc.head) - xc = xc.tail - yc = yc.tail - } - b.toList - } - - /** Returns the list resulting from applying the given function - * f to corresponding elements of the argument lists. - * - * @param f function to apply to each pair of elements. - * @return [f(a0,b0,c0), - * ..., f(an,bn,cn)] - * if the lists are [a0, ..., ak], - * [b0, ..., bl], - * [c0, ..., cm] and - * n = min(k,l,m) - */ - def map3[A,B,C,D](xs: List[A], ys: List[B], zs: List[C])(f: (A, B, C) => D): List[D] = { - val b = new ListBuffer[D] - var xc = xs - var yc = ys - var zc = zs - while (!xc.isEmpty && !yc.isEmpty && !zc.isEmpty) { - b += f(xc.head, yc.head, zc.head) - xc = xc.tail - yc = yc.tail - zc = zc.tail - } - b.toList - } - - /** Tests whether the given predicate p holds - * for all corresponding elements of the argument lists. - * - * @param p function to apply to each pair of elements. - * @return (p(a0,b0) && - * ... && p(an,bn))] - * if the lists are [a0, ..., ak]; - * [b0, ..., bl] - * and n = min(k,l) - */ - def forall2[A,B](xs: List[A], ys: List[B])(f: (A, B) => Boolean): Boolean = { - var xc = xs - var yc = ys - while (!xc.isEmpty && !yc.isEmpty) { - if (!f(xc.head, yc.head)) return false - xc = xc.tail - yc = yc.tail - } - true - } - - /** Tests whether the given predicate p holds - * for some corresponding elements of the argument lists. - * - * @param p function to apply to each pair of elements. - * @return n != 0 && (p(a0,b0) || - * ... || p(an,bn))] if the lists are - * [a0, ..., ak], - * [b0, ..., bl] and - * n = min(k,l) - */ - def exists2[A,B](xs: List[A], ys: List[B])(f: (A, B) => Boolean): Boolean = { - var xc = xs - var yc = ys - while (!xc.isEmpty && !yc.isEmpty) { - if (f(xc.head, yc.head)) return true - xc = xc.tail - yc = yc.tail - } - false - } - - /** Transposes a list of lists. - * pre: All element lists have the same length. - * - * @param xss the list of lists - * @return the transposed list of lists - */ - def transpose[A](xss: List[List[A]]): List[List[A]] = { - val buf = new ListBuffer[List[A]] - var yss = xss - while (!yss.head.isEmpty) { - buf += (yss map (_.head)) - yss = (yss map (_.tail)) - } - buf.toList - } - - /** Lists with ordered elements are ordered - implicit def list2ordered[a <% Ordered[a]](x: List[a]): Ordered[List[a]] = new Ordered[List[a]] { - def compare [b >: List[a] <% Ordered[b]](y: b): Int = y match { - case y1: List[a] => compareLists(x, y1); - case _ => -(y compare x) - } - private def compareLists(xs: List[a], ys: List[a]): Int = { - if (xs.isEmpty && ys.isEmpty) 0 - else if (xs.isEmpty) -1 - else if (ys.isEmpty) 1 - else { - val s = xs.head compare ys.head; - if (s != 0) s - else compareLists(xs.tail, ys.tail) - } - } - } - */ -} - -/** A class representing an ordered collection of elements of type - * a. This class comes with two implementing case - * classes scala.Nil and scala.:: that - * implement the abstract members isEmpty, - * head and tail. - * - * @author Martin Odersky and others - * @version 1.0, 16/07/2003 - */ -sealed abstract class List[+A] extends Seq[A] with Product { - - /** Returns true if the list does not contain any elements. - * @return true, iff the list is empty. - */ - override def isEmpty: Boolean - - /** Returns this first element of the list. - * - * @return the first element of this list. - * @throws Predef.NoSuchElementException if the list is empty. - */ - def head: A - - /** Result of comparing length with operand l. - * returns x where - * x < 0 iff this.length < l - * x == 0 iff this.length == l - * x > 0 iff this.length > that. - * - * This method is used by matching streams against right-ignoring (...,_*) patterns. - * - * This method does not call List.length, it works for O(l), - * not for O(length). - */ - override def lengthCompare(l: Int) = { - if (isEmpty) 0 - l - else if (l <= 0) 1 - else tail.lengthCompare(l - 1) - } - - /** Returns this list without its first element. - * - * @return this list without its first element. - * @throws Predef.NoSuchElementException if the list is empty. - */ - def tail: List[A] - - /**

- * Add an element x at the beginning of this list. - *

- * - * @param x the element to prepend. - * @return the list with x added at the beginning. - * @ex 1 :: List(2, 3) = List(2, 3).::(1) = List(1, 2, 3) - */ - def ::[B >: A] (x: B): List[B] = - new scala.::(x, this) - - /**

- * Add an element x at the end of this list. - *

- * - * @deprecated Replace uses of l + e with l ::: List(e). - * - * @param x the element to append. - * @return the list with x added at the end. - */ - @deprecated def +[B >: A](x: B): List[B] = - if (isEmpty) List(x) - else { - val buf = new ListBuffer[B] - this copyToBuffer buf - buf += x - buf.toList - } - - /**

- * Returns a list resulting from the concatenation of the given - * list prefix and this list. - *

- * - * @param prefix the list to concatenate at the beginning of this list. - * @return the concatenation of the two lists. - * @ex List(1, 2) ::: List(3, 4) = List(3, 4).:::(List(1, 2)) = List(1, 2, 3, 4) - */ - def :::[B >: A](prefix: List[B]): List[B] = - if (isEmpty) prefix - else { - val b = new ListBuffer[B] - var those = prefix - while (!those.isEmpty) { - b += those.head - those = those.tail - } - b.prependToList(this) - } - - /** Appends two list objects. - */ - override def ++[B >: A](that: Iterable[B]): List[B] = - this ::: that.toList - - /** Reverse the given prefix and append the current list to that. - * This function is equivalent to an application of reverse - * on the prefix followed by a call to :::, but more - * efficient. - * - * @param prefix the prefix to reverse and then prepend - * @return the concatenation of the reversed prefix and the current list. - */ - def reverse_:::[B >: A](prefix: List[B]): List[B] = { - var these: List[B] = this - var pres = prefix - while (!pres.isEmpty) { - these = pres.head :: these - pres = pres.tail - } - these - } - - /** Returns the number of elements in the list. - * - * @return the number of elements in the list. - */ - def length: Int = { - var these = this - var len = 0 - while (!these.isEmpty) { - len += 1 - these = these.tail - } - len - } - - /** Creates a list with all indices in the list. This is - * equivalent to a call to List.range(0, xs.length). - * - * @return a list of all indices in the list. - */ - def indices: List[Int] = { - val b = new ListBuffer[Int] - var i = 0 - var these = this - while (!these.isEmpty) { - b += i - i += 1 - these = these.tail - } - b.toList - } - - /** Returns the elements in the list as an iterator - * - * @return an iterator on the list elements. - */ - override def elements: Iterator[A] = new Iterator[A] { - var these = List.this - def hasNext: Boolean = !these.isEmpty - def next: A = - if (!hasNext) - throw new NoSuchElementException("next on empty Iterator") - else { - val result = these.head; these = these.tail; result - } - override def toList: List[A] = these - } - - /** Overrides the method in Iterable for efficiency. - * - * @return the list itself - */ - override def toList: List[A] = this - - /** Returns the list without its last element. - * - * @return the list without its last element. - * @throws Predef.UnsupportedOperationException if the list is empty. - */ - def init: List[A] = - if (isEmpty) throw new UnsupportedOperationException("Nil.init") - else { - val b = new ListBuffer[A] - var elem = head - var next = tail - while (!next.isEmpty) { - b += elem - elem = next.head - next = next.tail - } - b.toList - } - - /** Returns the last element of this list. - * - * @return the last element of the list. - * @throws Predef.NoSuchElementException if the list is empty. - */ - override def last: A = - if (isEmpty) throw new Predef.NoSuchElementException("Nil.last") - else { - var cur = this - var next = this.tail - while (!next.isEmpty) { - cur = next - next = next.tail - } - cur.head - } - - /** Returns the n first elements of this list, or else the whole - * list, if it has less than n elements. - * - * @param n the number of elements to take. - * @return the n first elements of this list. - */ - override def take(n: Int): List[A] = { - val b = new ListBuffer[A] - var i = 0 - var these = this - while (!these.isEmpty && i < n) { - i += 1 - b += these.head - these = these.tail - } - if (these.isEmpty) this - else b.toList - } - - /** Returns the list with elements belonging to the given index range. - * - * @param start the start position of the list slice. - * @param end the end position (exclusive) of the list slice. - * @return the list with elements belonging to the given index range. - */ - override def slice(start: Int, end: Int): List[A] = { - val s = start max 0 - val e = end min this.length - drop(s) take (e - s) - } - - /** Returns the list without its n first elements. - * If this list has less than n elements, the empty list is returned. - * - * @param n the number of elements to drop. - * @return the list without its n first elements. - */ - override def drop(n: Int): List[A] = { - var these = this - var count = n - while (!these.isEmpty && count > 0) { - these = these.tail - count -= 1 - } - these - } - - /** Returns the rightmost n elements from this list. - * - * @param n the number of elements to take - * @return the suffix of length n of the list - */ - def takeRight(n: Int): List[A] = { - @tailrec - def loop(lead: List[A], lag: List[A]): List[A] = lead match { - case Nil => lag - case _ :: tail => loop(tail, lag.tail) - } - loop(drop(n), this) - } - - /** Returns the list wihout its rightmost n elements. - * - * @param n the number of elements to take - * @return the list without its rightmost n elements - */ - def dropRight(n: Int): List[A] = { - def loop(lead: List[A], lag: List[A]): List[A] = lead match { - case Nil => Nil - case _ :: tail => lag.head :: loop(tail, lag.tail) - } - loop(drop(n), this) - } - - /** Split the list at a given point and return the two parts thus - * created. - * - * @param n the position at which to split - * @return a pair of lists composed of the first n - * elements, and the other elements. - */ - def splitAt(n: Int): (List[A], List[A]) = { - val b = new ListBuffer[A] - var i = 0 - var these = this - while (!these.isEmpty && i < n) { - i += 1 - b += these.head - these = these.tail - } - (b.toList, these) - } - - /** Returns the longest prefix of this list whose elements satisfy - * the predicate p. - * - * @param p the test predicate. - * @return the longest prefix of this list whose elements satisfy - * the predicate p. - */ - override def takeWhile(p: A => Boolean): List[A] = { - val b = new ListBuffer[A] - var these = this - while (!these.isEmpty && p(these.head)) { - b += these.head - these = these.tail - } - b.toList - } - - /** Returns the longest suffix of this list whose first element - * does not satisfy the predicate p. - * - * @param p the test predicate. - * @return the longest suffix of the list whose first element - * does not satisfy the predicate p. - */ - override def dropWhile(p: A => Boolean): List[A] = { - @tailrec - def loop(xs: List[A]): List[A] = - if (xs.isEmpty || !p(xs.head)) xs - else loop(xs.tail) - - loop(this) - } - - /** Returns the longest prefix of the list whose elements all satisfy - * the given predicate, and the rest of the list. - * - * @param p the test predicate - * @return a pair consisting of the longest prefix of the list whose - * elements all satisfy p, and the rest of the list. - */ - def span(p: A => Boolean): (List[A], List[A]) = { - val b = new ListBuffer[A] - var these = this - while (!these.isEmpty && p(these.head)) { - b += these.head - these = these.tail - } - (b.toList, these) - } - - /** Like span but with the predicate inverted. - */ - def break(p: A => Boolean): (List[A], List[A]) = span { x => !p(x) } - - /** Returns the n-th element of this list. The first element - * (head of the list) is at position 0. - * - * @param n index of the element to return - * @return the element at position n in this list. - * @throws Predef.NoSuchElementException if the list is too short. - */ - def apply(n: Int): A = drop(n).head - - /** Returns the list resulting from applying the given function f to each - * element of this list. - * - * @param f function to apply to each element. - * @return [f(a0), ..., f(an)] if this list is [a0, ..., an]. - */ - final override def map[B](f: A => B): List[B] = { - val b = new ListBuffer[B] - var these = this - while (!these.isEmpty) { - b += f(these.head) - these = these.tail - } - b.toList - } - - /** Apply a function to all the elements of the list, and return the - * reversed list of results. This is equivalent to a call to map - * followed by a call to reverse, but more efficient. - * - * @param f the function to apply to each elements. - * @return the reversed list of results. - */ - def reverseMap[B](f: A => B): List[B] = { - @tailrec - def loop(l: List[A], res: List[B]): List[B] = l match { - case Nil => res - case head :: tail => loop(tail, f(head) :: res) - } - loop(this, Nil) - } - - /** Apply the given function f to each element of this list - * (while respecting the order of the elements). - * - * @param f the treatment to apply to each element. - */ - final override def foreach(f: A => Unit) { - var these = this - while (!these.isEmpty) { - f(these.head) - these = these.tail - } - } - - /** Returns all the elements of this list that satisfy the - * predicate p. The order of the elements is preserved. - * It is guarenteed that the receiver list itself is returned iff all its - * elements satisfy the predicate `p'. Hence the following equality is valid: - * - * (xs filter p) eq xs == xs forall p - * - * @param p the predicate used to filter the list. - * @return the elements of this list satisfying p. - */ - final override def filter(p: A => Boolean): List[A] = { - // return same list if all elements satisfy p - var these = this - while (!these.isEmpty && p(these.head)) { - these = these.tail - } - if (these.isEmpty) this - else { - val b = new ListBuffer[A] - var these1 = this - while (these1 ne these) { - b += these1.head - these1 = these1.tail - } - - these = these.tail // prevent the second evaluation of the predicate - // on the element on which it first failed - while (!these.isEmpty) { - if (p(these.head)) b += these.head - these = these.tail - } - b.toList - } - } - -// final def filterMap[B](f: PartialFunction[A, B]): List[B] = -// this filter f.isDefinedAt map f - - /** Removes all elements of the list which satisfy the predicate - * p. This is like filter with the - * predicate inversed. - * - * @param p the predicate to use to test elements - * @return the list without all elements which satisfy p - */ - def remove(p: A => Boolean): List[A] = filter (x => !p(x)) - - /** Partition the list in two sub-lists according to a predicate. - * - * @param p the predicate on which to partition - * @return a pair of lists: the list of all elements which satisfy - * p and the list of all elements which do not. - * The relative order of the elements in the sub-lists is the - * same as in the original list. - */ - override def partition(p: A => Boolean): (List[A], List[A]) = { - val btrue = new ListBuffer[A] - val bfalse = new ListBuffer[A] - var these = this - while (!these.isEmpty) { - (if (p(these.head)) btrue else bfalse) += these.head - these = these.tail - } - (btrue.toList, bfalse.toList) - } - - /**

- * Sort the list according to the comparison function - * <(e1: a, e2: a) => Boolean, - * which should be true iff e1 is smaller than - * e2. - *

- * - * @param lt the comparison function - * @return a list sorted according to the comparison function - * <(e1: a, e2: a) => Boolean. - * @ex
-   *    List("Steve", "Tom", "John", "Bob")
-   *      .sort((e1, e2) => (e1 compareTo e2) < 0) =
-   *    List("Bob", "John", "Steve", "Tom")
- */ - def sort(lt : (A,A) => Boolean): List[A] = { - /** Merge two already-sorted lists */ - def merge(l1: List[A], l2: List[A]): List[A] = { - val res = new ListBuffer[A] - var left1 = l1 - var left2 = l2 - - while (!left1.isEmpty && !left2.isEmpty) { - if(lt(left1.head, left2.head)) { - res += left1.head - left1 = left1.tail - } else { - res += left2.head - left2 = left2.tail - } - } - - res ++= left1 - res ++= left2 - - res.toList - } - - /** Split a list into two lists of about the same size */ - def split(lst: List[A]) = { - val res1 = new ListBuffer[A] - val res2 = new ListBuffer[A] - var left = lst - - while (!left.isEmpty) { - res1 += left.head - left = left.tail - if (!left.isEmpty) { - res2 += left.head - left = left.tail - } - } - - (res1.toList, res2.toList) - } - - - /** Merge-sort the specified list */ - def ms(lst: List[A]): List[A] = - lst match { - case Nil => lst - case x :: Nil => lst - case x :: y :: Nil => - if (lt(x,y)) - lst - else - y :: x :: Nil - - case lst => - val (l1, l2) = split(lst) - val l1s = ms(l1) - val l2s = ms(l2) - merge(l1s, l2s) - } - - ms(this) - } - - - /** Count the number of elements in the list which satisfy a predicate. - * - * @param p the predicate for which to count - * @return the number of elements satisfying the predicate p. - */ - def count(p: A => Boolean): Int = { - var cnt = 0 - var these = this - while (!these.isEmpty) { - if (p(these.head)) cnt += 1 - these = these.tail - } - cnt - } - - /** Tests if the predicate p is satisfied by all elements - * in this list. - * - * @param p the test predicate. - * @return true iff all elements of this list satisfy the - * predicate p. - */ - override def forall(p: A => Boolean): Boolean = { - var these = this - while (!these.isEmpty) { - if (!p(these.head)) return false - these = these.tail - } - true - } - - /** Tests the existence in this list of an element that satisfies the - * predicate p. - * - * @param p the test predicate. - * @return true iff there exists an element in this list that - * satisfies the predicate p. - */ - override def exists(p: A => Boolean): Boolean = { - var these = this - while (!these.isEmpty) { - if (p(these.head)) return true - these = these.tail - } - false - } - - /** Find and return the first element of the list satisfying a - * predicate, if any. - * - * @param p the predicate - * @return the first element in the list satisfying p, - * or None if none exists. - */ - override def find(p: A => Boolean): Option[A] = { - var these = this - while (!these.isEmpty) { - if (p(these.head)) return Some(these.head) - these = these.tail - } - None - } - - /** Combines the elements of this list together using the binary - * function f, from left to right, and starting with - * the value z. - * - * @return f(... (f(f(z, a0), a1) ...), - * an) if the list is - * [a0, a1, ..., an]. - */ - override def foldLeft[B](z: B)(f: (B, A) => B): B = { - var acc = z - var these = this - while (!these.isEmpty) { - acc = f(acc, these.head) - these = these.tail - } - acc - } - - /** Combines the elements of this list together using the binary - * function f, from right to left, and starting with - * the value z. - * - * @return f(a0, f(a1, f(..., f(an, z)...))) - * if the list is [a0, a1, ..., an]. - */ - override def foldRight[B](z: B)(f: (A, B) => B): B = this match { - case Nil => z - case x :: xs => f(x, xs.foldRight(z)(f)) - } - - /** Combines the elements of this list together using the binary - * operator op, from left to right - * @param op The operator to apply - * @return op(... op(a0,a1), ..., an) - if the list has elements - * a0, a1, ..., an. - * @throws Predef.UnsupportedOperationException if the list is empty. - */ - override def reduceLeft[B >: A](f: (B, A) => B): B = this match { - case Nil => throw new UnsupportedOperationException("Nil.reduceLeft") - case x :: Nil => x - case x0 :: x1 :: xs => - var acc : B = f(x0, x1) - var these : List[A] = xs - while (!these.isEmpty) { - acc = f(acc, these.head) - these = these.tail - } - acc - } - - /** Combines the elements of this list together using the binary - * operator op, from right to left - * @param op The operator to apply - * - * @return a0 op (... op (an-1 op an)...) - * if the list has elements a0, a1, ..., - * an. - * - * @throws Predef.UnsupportedOperationException if the list is empty. - */ - override def reduceRight[B >: A](f: (A, B) => B): B = this match { - case Nil => throw new UnsupportedOperationException("Nil.reduceRight") - case x :: Nil => x - case x :: xs => f(x, xs reduceRight f) - } - - /** Applies the given function f to each element of - * this list, then concatenates the results. - * - * @param f the function to apply on each element. - * @return f(a0) ::: ... ::: f(an) if - * this list is [a0, ..., an]. - */ - final override def flatMap[B](f: A => Iterable[B]): List[B] = { - val b = new ListBuffer[B] - var these = this - while (!these.isEmpty) { - var those = f(these.head).elements - while (those.hasNext) { - b += those.next - } - these = these.tail - } - b.toList - } - - /** A list consisting of all elements of this list in reverse order. - */ - override def reverse: List[A] = { - var result: List[A] = Nil - var these = this - while (!these.isEmpty) { - result = these.head :: result - these = these.tail - } - result - } - - /** Returns a list formed from this list and the specified list - * that by associating each element of the former with - * the element at the same position in the latter. - * If one of the two lists is longer than the other, its remaining elements are ignored. - * - * @return List((a0,b0), ..., - * (amin(m,n),bmin(m,n))) when - * List(a0, ..., am) - * zip List(b0, ..., bn) is invoked. - */ - def zip[B](that: List[B]): List[(A, B)] = { - val b = new ListBuffer[(A, B)] - var these = this - var those = that - while (!these.isEmpty && !those.isEmpty) { - b += ((these.head, those.head)) - these = these.tail - those = those.tail - } - b.toList - } - - /** Returns a list that pairs each element of this list - * with its index, counting from 0. - * - * @return the list List((a0,0), (a1,1), ...) - * where ai are the elements of this list. - */ - def zipWithIndex: List[(A, Int)] = { - val b = new ListBuffer[(A, Int)] - var these = this - var idx = 0 - - while(!these.isEmpty) { - b += ((these.head, idx)) - these = these.tail - idx += 1 - } - - b.toList - } - - /** Returns a list formed from this list and the specified list - * that by associating each element of the former with - * the element at the same position in the latter. - * - * @param that list that may have a different length - * as the self list. - * @param thisElem element thisElem is used to fill up the - * resulting list if the self list is shorter than - * that - * @param thatElem element thatElem is used to fill up the - * resulting list if that is shorter than - * the self list - * @return List((a0,b0), ..., - * (an,bn), (elem,bn+1), - * ..., {elem,bm}) - * when [a0, ..., an] zip - * [b0, ..., bm] is - * invoked where m > n. - */ - def zipAll[B, C >: A, D >: B](that: List[B], thisElem: C, thatElem: D): List[(C, D)] = { - val b = new ListBuffer[(C, D)] - var these = this - var those = that - while (!these.isEmpty && !those.isEmpty) { - b += ((these.head, those.head)) - these = these.tail - those = those.tail - } - while (!these.isEmpty) { - b += ((these.head, thatElem)) - these = these.tail - } - while (!those.isEmpty) { - b += ((thisElem, those.head)) - those = those.tail - } - b.toList - } - - /**

- * Computes the multiset union of this list and the given list - * that. For example: - *

-   *    val xs = List(1, 1, 2)
-   *    val ys = List(1, 2, 2, 3)
-   *    println(xs union ys)  // prints "List(1, 1, 2, 1, 2, 2, 3)"
-   *    println(ys union xs)  // prints "List(1, 2, 2, 3, 1, 1, 2)"
-   *  
- * - * @param that the list of elements to add to the list. - * @return a list containing the elements of this - * list and those of the given list that. - */ - def union[B >: A](that: List[B]): List[B] = this ++ that - - /**

- * Computes the multiset intersection between this list and the - * given list that; the intersection contains m - * copies of an element contained in both lists, where m is - * the smaller of the number of times the element appears in this - * list or in that. For example: - *

-   *    val xs = List(1, 1, 2)
-   *    val ys = List(3, 2, 2, 1)
-   *    println(xs intersect ys)  // prints "List(1, 2)"
-   *    println(ys intersect xs)  // prints "List(2, 1)"
-   *  
- * - * @param that the list to intersect. - * @return the list of elements contained both in this list and - * in the given list that. - */ - def intersect[B >: A](that: List[B]): List[B] = { - val occ = new LinkedHashMap[B, Int] - that foreach (e => if (occ contains e) occ(e) += 1 else occ(e) = 1) - val buf = new ListBuffer[B] - for (e <- this if occ contains e) { - if (occ(e) > 0) { occ(e) -= 1; buf += e } - } - buf.toList - } - - /**

- * Computes the multiset difference between this list and the - * given list that. If an element appears more - * than once in both lists, the difference contains m copies - * of that element, where m is the difference between the - * number of times the element appears in this list and the number - * of times it appears in that. For example: - *

-   *    val xs = List(1, 1, 2)
-   *    val ys = List(1, 2, 2, 3)
-   *    println(xs diff ys)  // prints "List(1)"
-   *    println(xs -- ys)    // prints "List()"
-   *  
- * - * @param that the list of elements to remove from this list. - * @return the list of elements contained only in this list plus - * m copies of each element present in both lists, - * where m is defined as above. - */ - def diff[B >: A](that: List[B]): List[B] = { - val occ = new LinkedHashMap[B, Int] - that foreach (e => if (occ contains e) occ(e) += 1 else occ(e) = 1) - val buf = new ListBuffer[B] - for (e <- this) { - if (occ contains e) - if (occ(e) > 0) occ(e) -= 1 - else buf += e - else buf += e - } - buf.toList - } - - /** Computes the difference between this list and the given list - * that. - * - * @param that the list of elements to remove from this list. - * @return this list without the elements of the given list - * that. - */ - def -- [B >: A](that: List[B]): List[B] = { - val b = new ListBuffer[B] - var these = this - while (!these.isEmpty) { - if (!that.contains(these.head)) b += these.head - these = these.tail - } - b.toList - } - - /** Computes the difference between this list and the given object - * x. - * - * @param x the object to remove from this list. - * @return this list without the elements of the given object - * x. - */ - def - [B >: A](x: B): List[B] = { - val b = new ListBuffer[B] - var these = this - while (!these.isEmpty) { - if (these.head != x) b += these.head - these = these.tail - } - b.toList - } - - /** Concatenate the elements of this list. The elements of this list - * should be a Iterables. - * - * Note: The compiler might not be able to infer the type parameter, - * so it is recommended to provide an explicit type argument. - * - * Example: - * List(List(1, 3), List(2)).flatten[Int] - * returns - * List(1, 3, 2) - * - * @param f An implicit conversion to an Iterable instance. - * @return The concatenation of all elements of iterables in this list. - */ - def flatten[B](implicit f : A => Iterable[B]) : List[B] = { - val buf = new ListBuffer[B] - foreach(f(_).foreach(buf += _)) - buf.toList - } - - /** Removes redundant elements from the list. Uses the method == - * to decide if two elements are identical. - * - * @return the list without doubles. - */ - def removeDuplicates: List[A] = { - val b = new ListBuffer[A] - var these = this - while (!these.isEmpty) { - if (!these.tail.contains(these.head)) b += these.head - these = these.tail - } - b.toList - } - - override protected def stringPrefix = "List" - override def projection = toStream - override def toStream : Stream[A] = new Stream.Definite[A] { - override def force : List[A] = List.this - override def isEmpty = List.this.isEmpty - override def head = List.this.head - override def tail = List.this.tail.toStream - protected def addDefinedElems(buf: StringBuilder, prefix: String): StringBuilder = if (!isEmpty) { - var prefix0 = prefix - var buf1 = buf.append(prefix0).append(head) - prefix0 = ", " - var tail0 = tail - while (!tail0.isEmpty) { - buf1 = buf.append(prefix0).append(tail0.head) - tail0 = tail0.tail - } - buf1 - } else buf - } - -} - -/** The empty list. - * - * @author Martin Odersky - * @version 1.0, 15/07/2003 - */ -@SerialVersionUID(0 - 8256821097970055419L) -case object Nil extends List[Nothing] { - override def isEmpty = true - def head: Nothing = - throw new NoSuchElementException("head of empty list") - def tail: List[Nothing] = - throw new NoSuchElementException("tail of empty list") -} - -/** A non empty list characterized by a head and a tail. - * - * @author Martin Odersky - * @version 1.0, 15/07/2003 - */ -@SerialVersionUID(0L - 8476791151983527571L) -final case class ::[B](private var hd: B, private[scala] var tl: List[B]) extends List[B] { - def head : B = hd - def tail : List[B] = tl - override def isEmpty: Boolean = false -} - diff --git a/src/dotnet-library/scala/Numeric.scala b/src/dotnet-library/scala/Numeric.scala new file mode 100755 index 0000000000..4f122dd475 --- /dev/null +++ b/src/dotnet-library/scala/Numeric.scala @@ -0,0 +1,117 @@ +package scala + +object Numeric { +// trait BigIntIsIntegral extends Integral[BigInt] { +// def plus(x: BigInt, y: BigInt): BigInt = x + y +// def minus(x: BigInt, y: BigInt): BigInt = x - y +// def times(x: BigInt, y: BigInt): BigInt = x * y +// def quot(x: BigInt, y: BigInt): BigInt = x / y +// def rem(x: BigInt, y: BigInt): BigInt = x % y +// def negate(x: BigInt): BigInt = -x +// def abs(x: BigInt): BigInt = if (x < 0) -x else x +// def signum(x: BigInt): BigInt = if (x < 0) -1 else if (x > 0) 1 else 0 +// def fromInt(x: Int): BigInt = BigInt(x) +// def toInt(x: BigInt): Int = x.intValue +// def toLong(x: BigInt): Long = x.longValue +// def toFloat(x: BigInt): Float = x.longValue.toFloat +// def toDouble(x: BigInt): Double = x.longValue.toDouble +// } +// implicit object BigIntIsIntegral extends BigIntIsIntegral + + trait IntIsIntegral extends Integral[Int] { + def plus(x: Int, y: Int): Int = x + y + def minus(x: Int, y: Int): Int = x - y + def times(x: Int, y: Int): Int = x * y + def quot(x: Int, y: Int): Int = x / y + def rem(x: Int, y: Int): Int = x % y + def negate(x: Int): Int = -x + def abs(x: Int): Int = if (x < 0) -x else x + def signum(x: Int): Int = if (x < 0) -1 else if (x > 0) 1 else 0 + def fromInt(x: Int): Int = x + def toInt(x: Int): Int = x + def toLong(x: Int): Long = x + def toFloat(x: Int): Float = x + def toDouble(x: Int): Double = x + } + implicit object IntIsIntegral extends IntIsIntegral + + trait LongIsIntegral extends Integral[Long] { + def plus(x: Long, y: Long): Long = x + y + def minus(x: Long, y: Long): Long = x - y + def times(x: Long, y: Long): Long = x * y + def quot(x: Long, y: Long): Long = x / y + def rem(x: Long, y: Long): Long = x % y + def negate(x: Long): Long = -x + def abs(x: Long): Long = if (x < 0) -x else x + def signum(x: Long): Long = if (x < 0) -1 else if (x > 0) 1 else 0 + def fromInt(x: Int): Long = x + def toInt(x: Long): Int = x.toInt + def toLong(x: Long): Long = x + def toFloat(x: Long): Float = x + def toDouble(x: Long): Double = x + } + implicit object LongIsIntegral extends LongIsIntegral + + trait FloatIsFractional extends Fractional[Float] { + def plus(x: Float, y: Float): Float = x + y + def minus(x: Float, y: Float): Float = x - y + def times(x: Float, y: Float): Float = x * y + def div(x: Float, y: Float): Float = x / y + def negate(x: Float): Float = -x + def abs(x: Float): Float = if (x < 0) -x else x + def signum(x: Float): Float = if (x < 0) -1 else if (x > 0) 1 else 0 + def fromInt(x: Int): Float = x + def toInt(x: Float): Int = x.toInt + def toLong(x: Float): Long = x.toLong + def toFloat(x: Float): Float = x + def toDouble(x: Float): Double = x + } + implicit object FloatIsFractional extends FloatIsFractional + + trait DoubleIsFractional extends Fractional[Double] { + def plus(x: Double, y: Double): Double = x + y + def minus(x: Double, y: Double): Double = x - y + def times(x: Double, y: Double): Double = x * y + def div(x: Double, y: Double): Double = x / y + def negate(x: Double): Double = -x + def abs(x: Double): Double = if (x < 0) -x else x + def signum(x: Double): Double = if (x < 0) -1 else if (x > 0) 1 else 0 + def fromInt(x: Int): Double = x + def toInt(x: Double): Int = x.toInt + def toLong(x: Double): Long = x.toLong + def toFloat(x: Double): Float = x.toFloat + def toDouble(x: Double): Double = x + } + implicit object DoubleIsFractional extends DoubleIsFractional + +} + +trait Numeric[T] { + def plus(x: T, y: T): T + def minus(x: T, y: T): T + def times(x: T, y: T): T + def negate(x: T): T + def abs(x: T): T + def signum(x: T): T + def fromInt(x: Int): T + def toInt(x: T): Int + def toLong(x: T): Long + def toFloat(x: T): Float + def toDouble(x: T): Double + def zero = fromInt(0) + def one = fromInt(1) + + class Ops(lhs: T) { + def +(rhs: T) = plus(lhs, rhs) + def -(rhs: T) = minus(lhs, rhs) + def *(rhs: T) = times(lhs, rhs) + def unary_-() = negate(lhs) + def abs(): T = Numeric.this.abs(lhs) + def signum(): T = Numeric.this.signum(lhs) + def toInt(): Int = Numeric.this.toInt(lhs) + def toLong(): Long = Numeric.this.toLong(lhs) + def toFloat(): Float = Numeric.this.toFloat(lhs) + def toDouble(): Double = Numeric.this.toDouble(lhs) + } + implicit def mkNumericOps(lhs: T): Ops = new Ops(lhs) +} diff --git a/src/dotnet-library/scala/Ordering.scala b/src/dotnet-library/scala/Ordering.scala new file mode 100644 index 0000000000..625f5977aa --- /dev/null +++ b/src/dotnet-library/scala/Ordering.scala @@ -0,0 +1,319 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2003-2009, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +// $Id: Ordering.scala 17712 2009-05-12 14:30:04Z extempore $ + +package scala + +/** A trait for representing total orderings. It is important to + * distinguish between a type that has a total order and a representation + * of total ordering on some type. This trait is for representing the + * latter. + * + * A total ordering + * is a binary relation on a type T that is also an equivalence relation + * and partial ordering on values of type T. This relation is exposed as + * the compare method of the Ordering trait. + * This relation must be: + * + * + * @author Geoffrey Washburn + * @version 0.9.5, 2008-04-15 + */ + +trait Ordering[T] extends PartialOrdering[T] { + /** Returns a negative integer iff x comes before + * y in the ordering, returns 0 iff x + * is the same in the ordering as y, and returns a + * positive number iff x comes after + * y in the ordering. + */ + def compare(x: T, y: T): Int + + /** Returns true iff x comes before + * y in the ordering. + */ + override def lteq(x: T, y: T): Boolean = compare(x, y) <= 0 + + /** Returns true iff y comes before + * x in the ordering. + */ + override def gteq(x: T, y: T): Boolean = compare(x, y) >= 0 + + /** Returns true iff x comes before + * y in the ordering and is not the same as y. + */ + override def lt(x: T, y: T): Boolean = compare(x, y) < 0 + + /** Returns true iff y comes before + * x in the ordering and is not the same as x. + */ + override def gt(x: T, y: T): Boolean = compare(x, y) > 0 + + /** Returns true iff x is equivalent to + * y in the ordering. + */ + override def equiv(x: T, y: T): Boolean = compare(x, y) == 0 + + class Ops(lhs: T) { + def <(rhs: T) = lt(lhs, rhs) + def <=(rhs: T) = lteq(lhs, rhs) + def >(rhs: T) = gt(lhs, rhs) + def >=(rhs: T) = gteq(lhs, rhs) + def ===(rhs: T) = equiv(lhs, rhs) + def !==(rhs: T) = !equiv(lhs, rhs) + } + implicit def mkOrderingOps(lhs: T): Ops = new Ops(lhs) +} + +object Ordering +{ + def apply[T](implicit ord : Ordering[T]) = ord + + implicit val Unit : Ordering[Unit] = new Ordering[Unit] { + def compare(x : Unit, y : Unit) = 0; + } + + implicit val Boolean : Ordering[Boolean] = new Ordering[Boolean] { + def compare(x : Boolean, y : Boolean) = (x, y) match { + case (false, true) => -1; + case (true, false) => 1; + case _ => 0; + } + } + + implicit val Byte : Ordering[Byte] = new Ordering[Byte] { + def compare(x : Byte, y : Byte) = x.toInt - y.toInt; + } + + implicit val Char : Ordering[Char] = new Ordering[Char] { + def compare(x : Char, y : Char) = x.toInt - y.toInt; + } + + implicit val Short : Ordering[Short] = new Ordering[Short] { + def compare(x : Short, y : Short) = x.toInt - y.toInt; + } + + implicit val Int : Ordering[Int] = new Ordering[Int] { + def compare(x : Int, y : Int) = + if(x < y) -1; + else if (x == y) 0; + else 1 + } + + implicit val Long : Ordering[Long] = new Ordering[Long] { + def compare(x : Long, y : Long) = + if(x < y) -1; + else if (x == y) 0; + else 1 + } + + implicit val Float : Ordering[Float] = new Ordering[Float] { + def compare(x : Float, y : Float) = + if(x < y) -1; + else if (x == y) 0; + else 1 + } + + implicit val Double : Ordering[Double] = new Ordering[Double] { + def compare(x : Double, y : Double) = + if(x < y) -1; + else if (x == y) 0; + else 1 + } + +// implicit val BigInt : Ordering[BigInt] = new Ordering[BigInt] { +// def compare(x : BigInt, y : BigInt) = x.compare(y); +// } + + implicit val String : Ordering[String] = new Ordering[String] { + def compare(x : String, y : String) = x.compareTo(y); + } + + implicit def Option[T](implicit ord : Ordering[T]) : Ordering[Option[T]] = + new Ordering[Option[T]] { + def compare(x : Option[T], y : Option[T]) = (x, y) match { + case (None, None) => 0; + case (None, _) => -1; + case (_, None) => 1 + case (Some(x), Some(y)) => ord.compare(x, y); + } + } + + implicit def Iterable[T](implicit ord : Ordering[T]) : Ordering[Iterable[T]] = + new Ordering[Iterable[T]] { + def compare(x : Iterable[T], y : Iterable[T]) : Int = { + val xe = x.elements; + val ye = y.elements; + + while (xe.hasNext && ye.hasNext){ + val res = ord.compare(xe.next, ye.next); + if (res != 0) return res; + } + + Boolean.compare(xe.hasNext, ye.hasNext); + } + } + + implicit def Tuple2[T1, T2](implicit ord1 : Ordering[T1], ord2 : Ordering[T2]) : Ordering[(T1, T2)] = + new Ordering[(T1, T2)]{ + def compare(x : Tuple2[T1, T2], y : Tuple2[T1, T2]) : Int = { + val compare1 = ord1.compare(x._1, y._1); + if (compare1 != 0) return compare1; + val compare2 = ord2.compare(x._2, y._2); + if (compare2 != 0) return compare2; + 0; + } + } + + implicit def Tuple3[T1, T2, T3](implicit ord1 : Ordering[T1], ord2 : Ordering[T2], ord3 : Ordering[T3]) : Ordering[(T1, T2, T3)] = + new Ordering[(T1, T2, T3)]{ + def compare(x : Tuple3[T1, T2, T3], y : Tuple3[T1, T2, T3]) : Int = { + val compare1 = ord1.compare(x._1, y._1); + if (compare1 != 0) return compare1; + val compare2 = ord2.compare(x._2, y._2); + if (compare2 != 0) return compare2; + val compare3 = ord3.compare(x._3, y._3); + if (compare3 != 0) return compare3; + 0; + } + } + + implicit def Tuple4[T1, T2, T3, T4](implicit ord1 : Ordering[T1], ord2 : Ordering[T2], ord3 : Ordering[T3], ord4 : Ordering[T4]) : Ordering[(T1, T2, T3, T4)] = + new Ordering[(T1, T2, T3, T4)]{ + def compare(x : Tuple4[T1, T2, T3, T4], y : Tuple4[T1, T2, T3, T4]) : Int = { + val compare1 = ord1.compare(x._1, y._1); + if (compare1 != 0) return compare1; + val compare2 = ord2.compare(x._2, y._2); + if (compare2 != 0) return compare2; + val compare3 = ord3.compare(x._3, y._3); + if (compare3 != 0) return compare3; + val compare4 = ord4.compare(x._4, y._4); + if (compare4 != 0) return compare4; + 0; + } + } + + implicit def Tuple5[T1, T2, T3, T4, T5](implicit ord1 : Ordering[T1], ord2 : Ordering[T2], ord3 : Ordering[T3], ord4 : Ordering[T4], ord5 : Ordering[T5]) : Ordering[(T1, T2, T3, T4, T5)] = + new Ordering[(T1, T2, T3, T4, T5)]{ + def compare(x : Tuple5[T1, T2, T3, T4, T5], y : Tuple5[T1, T2, T3, T4, T5]) : Int = { + val compare1 = ord1.compare(x._1, y._1); + if (compare1 != 0) return compare1; + val compare2 = ord2.compare(x._2, y._2); + if (compare2 != 0) return compare2; + val compare3 = ord3.compare(x._3, y._3); + if (compare3 != 0) return compare3; + val compare4 = ord4.compare(x._4, y._4); + if (compare4 != 0) return compare4; + val compare5 = ord5.compare(x._5, y._5); + if (compare5 != 0) return compare5; + 0; + } + } + + implicit def Tuple6[T1, T2, T3, T4, T5, T6](implicit ord1 : Ordering[T1], ord2 : Ordering[T2], ord3 : Ordering[T3], ord4 : Ordering[T4], ord5 : Ordering[T5], ord6 : Ordering[T6]) : Ordering[(T1, T2, T3, T4, T5, T6)] = + new Ordering[(T1, T2, T3, T4, T5, T6)]{ + def compare(x : Tuple6[T1, T2, T3, T4, T5, T6], y : Tuple6[T1, T2, T3, T4, T5, T6]) : Int = { + val compare1 = ord1.compare(x._1, y._1); + if (compare1 != 0) return compare1; + val compare2 = ord2.compare(x._2, y._2); + if (compare2 != 0) return compare2; + val compare3 = ord3.compare(x._3, y._3); + if (compare3 != 0) return compare3; + val compare4 = ord4.compare(x._4, y._4); + if (compare4 != 0) return compare4; + val compare5 = ord5.compare(x._5, y._5); + if (compare5 != 0) return compare5; + val compare6 = ord6.compare(x._6, y._6); + if (compare6 != 0) return compare6; + 0; + } + } + + implicit def Tuple7[T1, T2, T3, T4, T5, T6, T7](implicit ord1 : Ordering[T1], ord2 : Ordering[T2], ord3 : Ordering[T3], ord4 : Ordering[T4], ord5 : Ordering[T5], ord6 : Ordering[T6], ord7 : Ordering[T7]) : Ordering[(T1, T2, T3, T4, T5, T6, T7)] = + new Ordering[(T1, T2, T3, T4, T5, T6, T7)]{ + def compare(x : Tuple7[T1, T2, T3, T4, T5, T6, T7], y : Tuple7[T1, T2, T3, T4, T5, T6, T7]) : Int = { + val compare1 = ord1.compare(x._1, y._1); + if (compare1 != 0) return compare1; + val compare2 = ord2.compare(x._2, y._2); + if (compare2 != 0) return compare2; + val compare3 = ord3.compare(x._3, y._3); + if (compare3 != 0) return compare3; + val compare4 = ord4.compare(x._4, y._4); + if (compare4 != 0) return compare4; + val compare5 = ord5.compare(x._5, y._5); + if (compare5 != 0) return compare5; + val compare6 = ord6.compare(x._6, y._6); + if (compare6 != 0) return compare6; + val compare7 = ord7.compare(x._7, y._7); + if (compare7 != 0) return compare7; + 0; + } + } + + implicit def Tuple8[T1, T2, T3, T4, T5, T6, T7, T8](implicit ord1 : Ordering[T1], ord2 : Ordering[T2], ord3 : Ordering[T3], ord4 : Ordering[T4], ord5 : Ordering[T5], ord6 : Ordering[T6], ord7 : Ordering[T7], ord8 : Ordering[T8]) : Ordering[(T1, T2, T3, T4, T5, T6, T7, T8)] = + new Ordering[(T1, T2, T3, T4, T5, T6, T7, T8)]{ + def compare(x : Tuple8[T1, T2, T3, T4, T5, T6, T7, T8], y : Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]) : Int = { + val compare1 = ord1.compare(x._1, y._1); + if (compare1 != 0) return compare1; + val compare2 = ord2.compare(x._2, y._2); + if (compare2 != 0) return compare2; + val compare3 = ord3.compare(x._3, y._3); + if (compare3 != 0) return compare3; + val compare4 = ord4.compare(x._4, y._4); + if (compare4 != 0) return compare4; + val compare5 = ord5.compare(x._5, y._5); + if (compare5 != 0) return compare5; + val compare6 = ord6.compare(x._6, y._6); + if (compare6 != 0) return compare6; + val compare7 = ord7.compare(x._7, y._7); + if (compare7 != 0) return compare7; + val compare8 = ord8.compare(x._8, y._8); + if (compare8 != 0) return compare8; + 0; + } + } + + implicit def Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9](implicit ord1 : Ordering[T1], ord2 : Ordering[T2], ord3 : Ordering[T3], ord4 : Ordering[T4], ord5 : Ordering[T5], ord6 : Ordering[T6], ord7 : Ordering[T7], ord8 : Ordering[T8], ord9 : Ordering[T9]) : Ordering[(T1, T2, T3, T4, T5, T6, T7, T8, T9)] = + new Ordering[(T1, T2, T3, T4, T5, T6, T7, T8, T9)]{ + def compare(x : Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9], y : Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]) : Int = { + val compare1 = ord1.compare(x._1, y._1); + if (compare1 != 0) return compare1; + val compare2 = ord2.compare(x._2, y._2); + if (compare2 != 0) return compare2; + val compare3 = ord3.compare(x._3, y._3); + if (compare3 != 0) return compare3; + val compare4 = ord4.compare(x._4, y._4); + if (compare4 != 0) return compare4; + val compare5 = ord5.compare(x._5, y._5); + if (compare5 != 0) return compare5; + val compare6 = ord6.compare(x._6, y._6); + if (compare6 != 0) return compare6; + val compare7 = ord7.compare(x._7, y._7); + if (compare7 != 0) return compare7; + val compare8 = ord8.compare(x._8, y._8); + if (compare8 != 0) return compare8; + val compare9 = ord9.compare(x._9, y._9); + if (compare9 != 0) return compare9; + 0; + } + } + +} diff --git a/src/dotnet-library/scala/Predef.scala b/src/dotnet-library/scala/Predef.scala index da2255e3a9..eae88b94bc 100644 --- a/src/dotnet-library/scala/Predef.scala +++ b/src/dotnet-library/scala/Predef.scala @@ -52,10 +52,15 @@ object Predef { type UnsupportedOperationException = System.InvalidOperationException type IllegalArgumentException = System.ArgumentException type NoSuchElementException = System.InvalidOperationException - //type NumberFormatException = java.lang.NumberFormatException + type NumberFormatException = System.FormatException + type AbstractMethodError = System.InvalidOperationException // miscelleaneous ----------------------------------------------------- + private val P = scala.`package` // to force scala package object to be seen. + private val L = scala.collection.immutable.List // to force Nil, :: to be seen. + private val S = scala.collection.mutable.StringBuilder // to force StringBuilder to be seen. + //val $scope = scala.xml.TopScope type Function[-A, +B] = Function1[A, B] @@ -184,7 +189,6 @@ object Predef { implicit def unitWrapper(x: Boolean) = new runtime.RichUnit implicit def stringWrapper(x: String) = new runtime.RichString(x) - //implicit def stringBuilderWrapper(x : StringBuilder): runtime.RichStringBuilder = new runtime.RichStringBuilder(x) implicit def any2stringadd(x: Any) = new runtime.StringAdd(x) @@ -323,7 +327,7 @@ object Predef { implicit def float2double(x: Float): Double = x.toDouble - implicit def forceArrayProjection[A](x : Array.Projection[A]) : Array[A] = x.force + //implicit def forceArrayProjection[A](x : Array.Projection[A]) : Array[A] = x.force !!! re-enable? def currentThread = System.Threading.Thread.CurrentThread diff --git a/src/dotnet-library/scala/Range.scala b/src/dotnet-library/scala/Range.scala new file mode 100644 index 0000000000..617a0f78b1 --- /dev/null +++ b/src/dotnet-library/scala/Range.scala @@ -0,0 +1,234 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2006-2009, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +// $Id: Range.scala 17726 2009-05-13 19:53:43Z extempore $ + +package scala + +import collection.immutable.Vector +import collection.generic.VectorView + +/**

+ * GenericRange is a generified version of the + * Range class which works with arbitrary types. + * It must be supplied with Integral and Ordering implementations + * of the range type. + * + * Factories for likely types include Range.BigInt and Range.Long. + * Range.Int exists for completeness, but the Int-based scala.Range + * should be more performant. + *

+ *     val r1 = new Range(0, 100, 1)
+ *     val veryBig = Math.MAX_INT.toLong + 1
+ *     val r2 = Range.Long(veryBig, veryBig + 100, 1)
+ *     assert(r1 sameElements r2.map(_ - veryBig))
+ *  
+ * + * @author Paul Phillips + * @version 2.8 + */ +abstract class GenericRange[T] + (val start: T, val end: T, val step: T) + (implicit num: Integral[T], ord: Ordering[T]) +extends VectorView[T, Vector[T]] with RangeToString[T] { + import num._ + import ord._ + + // this lets us pretend all ranges are exclusive + val isInclusive: Boolean + private val trueEnd = if (isInclusive) end + one else end + + // todo? - we could lift the length restriction by implementing a range as a sequence of + // subranges and limiting the subranges to MAX_INT. There's no other way around it because + // the generics we inherit assume integer-based indexing (as well they should.) + require(step !== zero) + require(genericLength <= fromInt(Math.MAX_INT), "Implementation restricts ranges to Math.MAX_INT elements.") + + protected def underlying = Vector.empty[T] + + /** Create a new range with the start and end values of this range and + * a new step. + */ + def by(step: T): GenericRange[T] = + if (isInclusive) GenericRange.inclusive(start, end, step) + else GenericRange(start, end, step) + + override def foreach[U](f: T => U) { + var i = start + if (step > zero) { + while (i < trueEnd) { + f(i) + i = i + step + } + } else { + while (i > trueEnd) { + f(i) + i = i + step + } + } + } + + lazy val genericLength: T = { + def plen(start: T, end: T, step: T) = + if (trueEnd <= start) zero + else (trueEnd - start - one) / step + one + + if (step > zero) plen(start, trueEnd, step) + else plen(trueEnd, start, -step) + } + lazy val length: Int = toInt(genericLength) + + // Since apply(Int) already exists, we are not allowed apply(T) since + // they erase to the same thing. + def apply(idx: Int): T = applyAt(fromInt(idx)) + def applyAt(idx: T): T = { + if (idx < zero || idx >= genericLength) throw new IndexOutOfBoundsException(idx.toString) + start + idx * step + } + + override def contains(_x: Any): Boolean = { + // XXX - can we avoid this cast and still have a contains method? + val x = + try { _x.asInstanceOf[T] } + catch { case _: ClassCastException => return false } + + if (step > zero) start <= x && x < trueEnd + else start >= x && x > trueEnd + } +} + +private[scala] trait RangeToString[T] extends VectorView[T, Vector[T]] { + // The default toString() tries to print every element and will exhaust memory + // if the Range is unduly large. This interacts poorly with the REPL. + override def toString() = { + val MAX_PRINT = 512 // some arbitrary value + val str = (this take MAX_PRINT).toString + + if (length > MAX_PRINT) str.substring(0, str.length-1) + "...)" + else str + } +} + + +object GenericRange { + import Numeric._ + import Ordering._ + + class Inclusive[T](start: T, end: T, step: T)(implicit num: Integral[T], ord: Ordering[T]) + extends GenericRange(start, end, step) + { + val isInclusive = true + def exclusive: Exclusive[T] = new Exclusive(start, end, step) + } + class Exclusive[T](start: T, end: T, step: T)(implicit num: Integral[T], ord: Ordering[T]) + extends GenericRange(start, end, step) + { + val isInclusive = false + def inclusive: Inclusive[T] = new Inclusive(start, end, step) + } + + def apply[T](start: T, end: T, step: T)(implicit num: Integral[T], ord: Ordering[T]) = + new Exclusive(start, end, step) + + def inclusive[T](start: T, end: T, step: T)(implicit num: Integral[T], ord: Ordering[T]) = + new Inclusive(start, end, step) +} + + +/**

+ * The Range class represents integer values in range + * [start;end) with non-zero step value step. + * Sort of acts like a sequence also (supports length and contains). + * For example: + *

+ *     val r1 = 0 until 10
+ *     val r2 = r1.start until r1.end by r1.step + 1
+ *     println(r2.length) // = 5
+ *  
+ * + * @author Martin Odersky + * @version 2.8 + */ +class Range(val start: Int, val end: Int, val step: Int) +extends VectorView[Int, Vector[Int]] with RangeToString[Int] +{ + require(step != 0) + + protected def underlying = Vector.empty[Int] + + /** Create a new range with the start and end values of this range and + * a new step. + */ + def by(step: Int): Range = new Range(start, end, step) + + final override def foreach[U](f: Int => U) { + var i = start + if (step > 0) { + while (i < end) { + f(i) + i += step + } + } else { + while (i > end) { + f(i) + i += step + } + } + } + + lazy val length: Int = { + def plen(start: Int, end: Int, step: Int) = + if (end <= start) 0 else (end - start - 1) / step + 1 + if (step > 0) plen(start, end, step) + else plen(end, start, -step) + } + + @inline + final def apply(idx: Int): Int = { + if (idx < 0 || idx >= length) throw new IndexOutOfBoundsException(idx.toString) + start + idx * step + } + + def contains(x: Int): Boolean = + if (step > 0) start <= x && x < end + else start >= x && x > end + + def inclusive = Range.inclusive(start, end, step) +} + +object Range { + /** @deprecated use Range.inclusive instead */ + final class Inclusive(start: Int, end0: Int, step: Int) + extends Range(start, if (step > 0) end0 + 1 else end0 - 1, step) { self => + override def by(step: Int): Range = new Inclusive(start, end0, step) + } + + def apply(start: Int, end: Int, step: Int) = + new Range(start, end, step) + + def inclusive(start: Int, end: Int, step: Int): Range = + new Range.Inclusive(start, end, step) + +// object BigInt { +// def apply(start: BigInt, end: BigInt, step: BigInt) = GenericRange(start, end, step) +// def inclusive(start: BigInt, end: BigInt, step: BigInt) = GenericRange.inclusive(start, end, step) +// } + object Long { + def apply(start: Long, end: Long, step: Long) = GenericRange(start, end, step) + def inclusive(start: Long, end: Long, step: Long) = GenericRange.inclusive(start, end, step) + } + + // Illustrating genericity with Int Range, which should have the same behavior + // as the original Range class. However we leave the original Range + // indefinitely, for performance and because the compiler seems to bootstrap + // off it and won't do so with our parameterized version without modifications. + object Int { + def apply(start: Int, end: Int, step: Int) = GenericRange(start, end, step) + def inclusive(start: Int, end: Int, step: Int) = GenericRange.inclusive(start, end, step) + } +} diff --git a/src/dotnet-library/scala/StringBuilder.scala b/src/dotnet-library/scala/StringBuilder.scala deleted file mode 100644 index fc65e6335a..0000000000 --- a/src/dotnet-library/scala/StringBuilder.scala +++ /dev/null @@ -1,912 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2006-2009, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -// $Id$ - - -package scala - -import Predef._ - -/**

- * A mutable sequence of characters. This class provides an API compatible - * with - * java.lang.StringBuilder. - *

- * - * @author Stephane Micheloud - * @version 1.0 - */ -final class StringBuilder(initCapacity: Int, private val initValue: String) - extends (Int => Char) { - if (initCapacity < 0) throw new IllegalArgumentException - if (initValue eq null) throw new NullPointerException - - /** The value is used for character storage. */ - private var value = new Array[Char](initCapacity + initValue.length) - - /** The count is the number of characters used. */ - private var count: Int = 0 - - /** Constructs a string builder with no characters in it and an - * initial capacity of 16 characters. - */ - def this() = this(16, "") - - /** Constructs a string builder with no characters in it and an - * initial capacity specified by the capacity argument. - * - * @param capacity the initial capacity. - * @throws NegativeArraySizeException if the capacity - * argument is less than 0. - */ - def this(capacity: Int) = this(capacity, "") - - def this(str: String) = this(16, str) - - append(initValue) - - def toArray: Array[Char] = value - - def length: Int = count - - def length_=(n: Int) { setLength(n) } - - /** Sets the length of the character sequence. - * - * @param newLength the new length - * @throws IndexOutOfBoundsException if the n argument is negative. - */ - def setLength(n: Int) { - if (n < 0) - throw new StringIndexOutOfBoundsException//(n) - if (n > value.length) expandCapacity(n) - if (count < n) - while (count < n) { - value(count) = '\0'; count += 1 - } - else - count = n - } - - /** Returns the current capacity. The capacity is the amount of storage - * available for newly inserted characters, beyond which an allocation - * will occur. - * - * @return the current capacity - */ - def capacity: Int = value.length - - /** Same as ensureCapacity. */ - def capacity_=(n: Int) { ensureCapacity(n) } - - /**

- * Ensures that the capacity is at least equal to the specified minimum. - * If the current capacity is less than the argument, then a new internal - * array is allocated with greater capacity. The new capacity is the larger of: - *

- * - *

- * If the n argument is non-positive, this - * method takes no action and simply returns. - *

- * - * @param n the minimum desired capacity. - */ - def ensureCapacity(n: Int) { - if (n > value.length) expandCapacity(n) - } - - private def expandCapacity(n: Int) { - val newCapacity = (value.length + 1) * 2 - value = StringBuilder.copyOf( - value, - if (newCapacity < 0) Math.MAX_INT else if (n > newCapacity) n else newCapacity - ) - } - - /**

- * Returns the Char value in this sequence at the specified index. - * The first Char value is at index 0, the next at index - * 1, and so on, as in array indexing. - *

- *

- * The index argument must be greater than or equal to - * 0, and less than the length of this sequence. - *

- * - * @param index the index of the desired Char value. - * @return the Char value at the specified index. - * @throws IndexOutOfBoundsException if index is - * negative or greater than or equal to length(). - */ - def charAt(index: Int): Char = { - if (index < 0 || index >= count) - throw new StringIndexOutOfBoundsException//(index) - value(index) - } - - /** Same as charAt. */ - def apply(i: Int): Char = charAt(i) - - /**

- * Removes the Char at the specified position in this - * sequence. This sequence is shortened by one Char. - *

- * - * @param index Index of Char to remove - * @return This object. - * @throws StringIndexOutOfBoundsException if the index - * is negative or greater than or equal to length(). - */ - def deleteCharAt(index: Int): StringBuilder = { - if (index < 0 || index >= count) - throw new StringIndexOutOfBoundsException//(index) - compat.Platform.arraycopy(value, index + 1, value, index, count - index - 1) - count -= 1 - this - } - - /**

- * The character at the specified index is set to ch. This - * sequence is altered to represent a new character sequence that is - * identical to the old character sequence, except that it contains the - * character ch at position index. - *

- *

- * The index argument must be greater than or equal to - * 0, and less than the length of this sequence. - *

- * - * @param index the index of the character to modify. - * @param ch the new character. - * @throws IndexOutOfBoundsException if index is - * negative or greater than or equal to length(). - */ - def setCharAt(index: Int, ch: Char) { - if (index < 0 || index >= count) - throw new StringIndexOutOfBoundsException//(index) - value(index) = ch - } - - /** Same as setCharAt. */ - def update(i: Int, c: Char) { setCharAt(i, c) } - - /** Returns a new String that contains a subsequence of - * characters currently contained in this character sequence. The - * substring begins at the specified index and extends to the end of - * this sequence. - * - * @param start The beginning index, inclusive. - * @return The new string. - * @throws StringIndexOutOfBoundsException if start is - * less than zero, or greater than the length of this object. - */ - def substring(start: Int): String = substring(start, count) - - /** Returns a new String that contains a subsequence of - * characters currently contained in this sequence. The - * substring begins at the specified start and - * extends to the character at index end - 1. - * - * @param start The beginning index, inclusive. - * @param end The ending index, exclusive. - * @return The new string. - * @throws StringIndexOutOfBoundsException if start - * or end are negative or greater than - * length(), or start is - * greater than end. - */ - def substring(start: Int, end: Int): String = { - if (start < 0) - throw new StringIndexOutOfBoundsException//(start) - if (end > count) - throw new StringIndexOutOfBoundsException//(end) - if (start > end) - throw new StringIndexOutOfBoundsException//(end - start) - new String(value, start, end - start) - } - - /**

- * Appends the string representation of the Any - * argument. - *

- *

- * The argument is converted to a string as if by the method - * System.Convert.ToString, and the characters of - * that string are then appended to this sequence. - *

- * - * @param x an Any object. - * @return a reference to this object. - */ - def append(x: Any): StringBuilder = - append(System.Convert.ToString(x)) - - /** Appends the specified string to this character sequence. - * - * @param s a string. - * @return a reference to this object. - */ - def append(s: String): StringBuilder = { - val str = if (s == null) "null" else s - val len = str.length - if (len > 0) { - val newCount = count + len - if (newCount > value.length) expandCapacity(newCount) - compat.Platform.arraycopy(str.ToCharArray, 0, value, count, len) - count = newCount - } - this - } - - /** Appends the specified string builder to this sequence. - * - * @param sb - * @return - */ - def append(sb: StringBuilder): StringBuilder = - if (sb == null) - append("null") - else { - val len = sb.length - val newCount = count + len - if (newCount > value.length) expandCapacity(newCount) - compat.Platform.arraycopy(sb.toArray, 0, value, count, len) - count = newCount - this - } - - /**

- * Appends the string representation of the Char sequence - * argument to this sequence. - *

- *

- * The characters of the sequence argument are appended, in order, - * to the contents of this sequence. The length of this sequence - * increases by the length of the argument. - *

- * - * @param x the characters to be appended. - * @return a reference to this object. - */ - def append(x: Seq[Char]): StringBuilder = - append(x.toArray, 0, x.length) - - /**

- * Appends the string representation of the Char array - * argument to this sequence. - *

- *

- * The characters of the array argument are appended, in order, to - * the contents of this sequence. The length of this sequence - * increases by the length of the argument. - *

- * - * @param x the characters to be appended. - * @return a reference to this object. - */ - def append(x: Array[Char]): StringBuilder = - append(x, 0, x.length) - - /**

- * Appends the string representation of a subarray of the - * char array argument to this sequence. - *

- *

- * Characters of the Char array x, starting at - * index offset, are appended, in order, to the contents - * of this sequence. The length of this sequence increases - * by the value of len. - *

- * - * @param x the characters to be appended. - * @param offset the index of the first Char to append. - * @param len the number of Chars to append. - * @return a reference to this object. - */ - def append(x: Array[Char], offset: Int, len: Int): StringBuilder = { - val newCount = count + len - if (newCount > value.length) expandCapacity(newCount) - compat.Platform.arraycopy(x, offset, value, count, len) - count = newCount - this - } - - /**

- * Appends the string representation of the Boolean - * argument to the sequence. - *

- *

- * The argument is converted to a string as if by the method - * System.Convert.ToString, and the characters of - * that string are then appended to this sequence. - *

- * - * @param x a Boolean. - * @return a reference to this object. - */ - def append(x: Boolean): StringBuilder = { - if (x) { - val newCount = count + 4 - if (newCount > value.length) expandCapacity(newCount) - value(count) = 't'; count += 1 - value(count) = 'r'; count += 1 - value(count) = 'u'; count += 1 - value(count) = 'e'; count += 1 - } else { - val newCount = count + 5 - if (newCount > value.length) expandCapacity(newCount) - value(count) = 'f'; count += 1 - value(count) = 'a'; count += 1 - value(count) = 'l'; count += 1 - value(count) = 's'; count += 1 - value(count) = 'e'; count += 1 - } - this - } - - def append(x: Char): StringBuilder = { - val newCount = count + 1 - if (newCount > value.length) expandCapacity(newCount) - value(count) = x; count += 1 - this - } - - def append(x: Short): StringBuilder = - append(System.Convert.ToString(x)) - - def append(x: Int): StringBuilder = - append(System.Convert.ToString(x)) - - def append(x: Long): StringBuilder = - append(System.Convert.ToString(x)) - - def append(x: Float): StringBuilder = - append(System.Convert.ToString(x)) - - def append(x: Double): StringBuilder = - append(System.Convert.ToString(x)) - - /** Removes the characters in a substring of this sequence. - * The substring begins at the specified start and extends to - * the character at index end - 1 or to the end of the - * sequence if no such character exists. If - * start is equal to end, no changes are made. - * - * @param start The beginning index, inclusive. - * @param end The ending index, exclusive. - * @return This object. - * @throws StringIndexOutOfBoundsException if start - * is negative, greater than length(), or - * greater than end. - */ - def delete(start: Int, end: Int): StringBuilder = { - if (start < 0 || start > end) - throw new StringIndexOutOfBoundsException//(start) - val end0 = if (end > count) count else end - val len = end0 - start - if (len > 0) { - compat.Platform.arraycopy(value, start + len, value, start, count - end0) - count -= len - } - this - } - - /** Replaces the characters in a substring of this sequence - * with characters in the specified String. The substring - * begins at the specified start and extends to the character - * at index end - 1 or to the end of the sequence if no such - * character exists. First the characters in the substring are removed and - * then the specified String is inserted at start. - * - * @param start The beginning index, inclusive. - * @param end The ending index, exclusive. - * @param str String that will replace previous contents. - * @return This object. - * @throws StringIndexOutOfBoundsException if start - * is negative, greater than length(), or - * greater than end. - */ - def replace(start: Int, end: Int, str: String) { - if (start < 0 || start > count || start > end) - throw new StringIndexOutOfBoundsException//(start) - - val end0 = if (end > count) count else end - val len = str.length() - val newCount = count + len - (end0 - start) - if (newCount > value.length) expandCapacity(newCount) - - compat.Platform.arraycopy(value, end, value, start + len, count - end) - compat.Platform.arraycopy(str.ToCharArray, 0, value, start, len) - count = newCount - this - } - - /** Inserts the string representation of a subarray of the str - * array argument into this sequence. The subarray begins at the specified - * offset and extends len chars. - * The characters of the subarray are inserted into this sequence at - * the position indicated by index. The length of this - * sequence increases by len Chars. - * - * @param index position at which to insert subarray. - * @param str a Char array. - * @param offset the index of the first char in subarray to - * be inserted. - * @param len the number of Chars in the subarray to - * be inserted. - * @return This object - * @throws StringIndexOutOfBoundsException if index - * is negative or greater than length(), or - * offset or len are negative, or - * (offset+len) is greater than - * str.length. - */ - def insert(index: Int, str: Array[Char], offset: Int, len: Int): StringBuilder = { - if (index < 0 || index > count) - throw new StringIndexOutOfBoundsException//(index) - if (offset < 0 || len < 0 || offset > str.length - len) - throw new StringIndexOutOfBoundsException/*( - "offset " + offset + ", len " + len + - ", str.length " + str.length)*/ - val newCount = count + len - if (newCount > value.length) expandCapacity(newCount) - compat.Platform.arraycopy(value, index, value, index + len, count - index) - compat.Platform.arraycopy(str, offset, value, index, len) - count = newCount - this - } - - /**

- * Inserts the string representation of the Any - * argument into this character sequence. - *

- *

- * The second argument is converted to a string as if by the method - * System.Convert.ToString, and the characters of that - * string are then inserted into this sequence at the indicated - * offset. - *

- *

- * The offset argument must be greater than or equal to - * 0, and less than or equal to the length of this - * sequence. - *

- * - * @param offset the offset. - * @param x an Any value. - * @return a reference to this object. - * @throws StringIndexOutOfBoundsException if the offset is invalid. - */ - def insert(at: Int, x: Any): StringBuilder = - insert(at, System.Convert.ToString(x)) - - /** Inserts the string into this character sequence. - * - * @param at the offset position. - * @param x a string. - * @return a reference to this object. - * @throws StringIndexOutOfBoundsException if the offset is invalid. - */ - def insert(at: Int, x: String): StringBuilder = { - if (at < 0 || at > count) - throw new StringIndexOutOfBoundsException//(at) - val str = if (x == null) "null" else x - val len = str.length - val newCount = count + len - if (newCount > value.length) expandCapacity(newCount) - compat.Platform.arraycopy(value, at, value, at + len, count - at) - compat.Platform.arraycopy(str.ToCharArray, 0, value, at, len) - count = newCount - this - } - - /** Inserts the string representation of the Char sequence - * argument into this sequence. - * - * @param at the offset position. - * @param x a character sequence. - * @return a reference to this object. - * @throws StringIndexOutOfBoundsException if the offset is invalid. - */ - def insert(at: Int, x: Seq[Char]): StringBuilder = - insert(at, x.toArray) - - /** Inserts the string representation of the Char array - * argument into this sequence. - * - * @param at the offset position. - * @param x a character array. - * @return a reference to this object. - * @throws StringIndexOutOfBoundsException if the offset is invalid. - */ - def insert(at: Int, x: Array[Char]): StringBuilder = { - if (at < 0 || at > count) - throw new StringIndexOutOfBoundsException//(at) - val len = x.length - val newCount = count + len - if (newCount > value.length) expandCapacity(newCount) - compat.Platform.arraycopy(value, at, value, at + len, count - at) - compat.Platform.arraycopy(x, 0, value, at, len) - count = newCount - this - } - - /**

- * Inserts the string representation of the Boolean argument - * into this sequence. - *

- *

- * The offset argument must be greater than or equal to 0, and less than - * or equal to the length of this sequence. - *

- * - * @param at the offset position. - * @param x a Boolean value. - * @return a reference to this object. - */ - def insert(at: Int, x: Boolean): StringBuilder = - insert(at, System.Convert.ToString(x)) - - - /**

- * Inserts the string representation of the Char argument - * into this sequence. - *

- *

- * The offset argument must be greater than or equal to 0, and less than - * or equal to the length of this sequence. - *

- * - * @param at the offset position. - * @param x a Char value. - * @return a reference to this object. - */ - def insert(at: Int, x: Char): StringBuilder = { - if (at < 0 || at > count) - throw new StringIndexOutOfBoundsException//(at) - val newCount = count + 1 - if (newCount > value.length) expandCapacity(newCount) - compat.Platform.arraycopy(value, at, value, at + 1, count - at) - value(at) = x - count = newCount - this - } - - /**

- * Inserts the string representation of the Short argument - * into this sequence. - *

- *

- * The offset argument must be greater than or equal to 0, and less than - * or equal to the length of this sequence. - *

- * - * @param at the offset position. - * @param x a Short value. - * @return a reference to this object. - */ - def insert(at: Int, x: Short): StringBuilder = - insert(at, System.Convert.ToString(x)) - - /**

- * Inserts the string representation of the Int argument - * into this sequence. - *

- *

- * The offset argument must be greater than or equal to 0, and less than - * or equal to the length of this sequence. - *

- * - * @param at the offset position. - * @param x a Int value. - * @return a reference to this object. - */ - def insert(at: Int, x: Int): StringBuilder = - insert(at, System.Convert.ToString(x)) - - /**

- * Inserts the string representation of the Long argument - * into this sequence. - *

- *

- * The offset argument must be greater than or equal to 0, and less than - * or equal to the length of this sequence. - *

- * - * @param at the offset position. - * @param x a Long value. - * @return a reference to this object. - */ - def insert(at: Int, x: Long): StringBuilder = - insert(at, System.Convert.ToString(x)) - - /**

- * Inserts the string representation of the Float argument - * into this sequence. - *

- *

- * The offset argument must be greater than or equal to 0, and less than - * or equal to the length of this sequence. - *

- * - * @param at the offset position. - * @param x a Float value. - * @return a reference to this object. - */ - def insert(at: Int, x: Float): StringBuilder = - insert(at, System.Convert.ToString(x)) - - /**

- * Inserts the string representation of the Double argument - * into this sequence. - *

- *

- * The offset argument must be greater than or equal to 0, and less than - * or equal to the length of this sequence. - *

- * - * @param at the offset position. - * @param x a Double value. - * @return a reference to this object. - */ - def insert(at: Int, x: Double): StringBuilder = - insert(at, System.Convert.ToString(x)) - - /**

- * Returns the index within this string of the first occurrence of the - * specified substring. The integer returned is the smallest value - * k such that: - *

- *
-   *  this.toString().startsWith(str, k)
- *
- *

- * is true. - *

- * - * @param str any string. - * @return if the string argument occurs as a substring within this - * object, then the index of the first character of the first - * such substring is returned; if it does not occur as a - * substring, -1 is returned. - * @throws NullPointerException if str is null. - */ - def indexOf(str: String): Int = indexOf(str, 0) - - /**

- * Returns the index within this string of the first occurrence of the - * specified substring, starting at the specified index. The integer - * returned is the smallest value k for which: - *

-   *    k >= Math.min(fromIndex, str.length()) &&
-   *                   this.toString().startsWith(str, k)
- *

- * If no such value of k exists, then -1 - * is returned. - *

- * - * @param str the substring for which to search. - * @param fromIndex the index from which to start the search. - * @return the index within this string of the first occurrence - * of the specified substring, starting at the specified index. - */ - def indexOf(str: String, fromIndex: Int): Int = - StringBuilder.indexOf(value, 0, count, str.ToCharArray, 0, str.length(), fromIndex) - - /**

- * Returns the index within this string of the rightmost occurrence - * of the specified substring. The rightmost empty string "" is - * considered to occur at the index value this.length(). - * The returned index is the largest value k such that - *

- *
-   *  this.toString().startsWith(str, k)
- *
- *

- * is true. - *

- * - * @param str the substring to search for. - * @return if the string argument occurs one or more times as a substring - * within this object, then the index of the first character of - * the last such substring is returned. If it does not occur as - * a substring, -1 is returned. - * @throws NullPointerException if str is null. - */ - def lastIndexOf(str: String): Int = lastIndexOf(str, count) - - /**

- * Returns the index within this string of the last occurrence of the - * specified substring. The integer returned is the largest value - * k such that: - *

-   *    k <= Math.min(fromIndex, str.length()) &&
-   *                   this.toString().startsWith(str, k)
- *

- * If no such value of k exists, then -1 - * is returned. - *

- * - * @param str the substring to search for. - * @param fromIndex the index to start the search from. - * @return the index within this sequence of the last occurrence - * of the specified substring. - */ - def lastIndexOf(str: String, fromIndex: Int): Int = - StringBuilder.lastIndexOf(value, 0, count, str.ToCharArray, 0, str.length(), fromIndex) - - /**

- * Causes this character sequence to be replaced by the reverse of the - * sequence. If there are any surrogate pairs included in the sequence, - * these are treated as single characters for the reverse operation. - * Thus, the order of the high-low surrogates is never reversed. - *

- *

- * Let n be the character length of this character sequence - * (not the length in Char values) just prior to - * execution of the reverse method. Then the - * character at index k in the new character sequence is - * equal to the character at index n-k-1 in the old - * character sequence. - *

- * - * @return a reference to this object. - */ - def reverse(): StringBuilder = { - import StringBuilder._ - var hasSurrogate = false - val n = count - 1 - var j = (n-1) >> 1 - while (j >= 0) { - val temp = value(j) - val temp2 = value(n - j) - if (!hasSurrogate) - hasSurrogate = - (temp >= MIN_HIGH_SURROGATE && temp <= MAX_LOW_SURROGATE) || - (temp2 >= MIN_HIGH_SURROGATE && temp2 <= MAX_LOW_SURROGATE) - value(j) = temp2 - value(n - j) = temp - j -= 1 - } - if (hasSurrogate) { - // Reverse back all valid surrogate pairs - var i = 0 - while (i < count - 1) { - val c2 = value(i) - if (isLowSurrogate(c2)) { - val c1 = value(i + 1) - if (isHighSurrogate(c1)) { - value(i) = c1; i += 1 - value(i) = c2 - } - } - i += 1 - } - } - this - } - - /** Returns a string representing the data in this sequence. - * A new String object is allocated and initialized to - * contain the character sequence currently represented by this - * object. This String is then returned. Subsequent - * changes to this sequence do not affect the contents of the - * String. - * - * @return a string representation of this sequence of characters. - */ - override def toString(): String = new String(value, 0, count) - -} - - -object StringBuilder -{ - private val MIN_HIGH_SURROGATE = '\uD800' - private val MAX_HIGH_SURROGATE = '\uDBFF' - - private val MIN_LOW_SURROGATE = '\uDC00' - private val MAX_LOW_SURROGATE = '\uDFFF' - - // constants java.langCharacter.MIN-/MAX_SURROGATE exist since 1.5 - private val MIN_SURROGATE = MIN_HIGH_SURROGATE - private val MAX_SURROGATE = MAX_LOW_SURROGATE - - // methods java.langCharacter.isLow-/isHighSurrogate exist since 1.5 - private def isLowSurrogate(ch: Char): Boolean = - MIN_LOW_SURROGATE <= ch && ch <= MAX_LOW_SURROGATE - - private def isHighSurrogate(ch: Char): Boolean = - MIN_HIGH_SURROGATE <= ch && ch <= MAX_HIGH_SURROGATE - - // method java.util.Arrays.copyOf exists since 1.6 - private def copyOf(src: Array[Char], newLength: Int): Array[Char] = { - val dest = new Array[Char](newLength) - compat.Platform.arraycopy(src, 0, dest, 0, Math.min(src.length, newLength)) - dest - } - - private def indexOf(source: Array[Char], sourceOffset: Int, sourceCount: Int, - target: Array[Char], targetOffset: Int, targetCount: Int, - fromIndex: Int): Int = - if (fromIndex >= sourceCount) - if (targetCount == 0) sourceCount else -1 - else { - val inx = if (fromIndex < 0) 0 else fromIndex - if (targetCount == 0) - inx - else { - val first = target(targetOffset) - val max = sourceOffset + (sourceCount - targetCount) - - var i = sourceOffset + inx - while (i <= max) { - /* Look for first character. */ - if (source(i) != first) { - i += 1 - while (i <= max && source(i) != first) i += 1 - } - /* Found first character, now look at the rest of v2 */ - if (i <= max) { - var j = i + 1 - val end = j + targetCount - 1 - var k = targetOffset + 1 - while (j < end && source(j) == target(k)) { - j += 1 - k += 1 - } - if (j == end) { - /* Found whole string. */ - return i - sourceOffset - } - } // if - i += 1 - } // while - -1 - } - } - - private def lastIndexOf(source: Array[Char], sourceOffset: Int, sourceCount: Int, - target: Array[Char], targetOffset: Int, targetCount: Int, - fromIndex: Int): Int = { - val rightIndex = sourceCount - targetCount - if (fromIndex < 0) return -1 - val inx = if (fromIndex > rightIndex) rightIndex else fromIndex - // Empty string always matches - if (targetCount == 0) return inx - - val strLastIndex = targetOffset + targetCount - 1 - val strLastChar = target(strLastIndex) - val min = sourceOffset + targetCount - 1 - var i = min + fromIndex - - while (true) { - while (i >= min && source(i) != strLastChar) i -= 1 - if (i < min) return -1 - var j = i - 1 - val start = j - (targetCount - 1) - var k = strLastIndex - 1 - var outerWhile = false - while (j > start && !outerWhile) { - if (source(j) != target(k)) { - j -= 1 - k -= 1 - i -= 1 - outerWhile = true - } - } - if (!outerWhile) return start - sourceOffset + 1 - } - -1 - } -} diff --git a/src/dotnet-library/scala/collection/JavaConversions.scala b/src/dotnet-library/scala/collection/JavaConversions.scala new file mode 100644 index 0000000000..381f93aaaa --- /dev/null +++ b/src/dotnet-library/scala/collection/JavaConversions.scala @@ -0,0 +1 @@ +/* JavaConversions does not exist for the dotnet target */ diff --git a/src/dotnet-library/scala/collection/immutable/List.scala b/src/dotnet-library/scala/collection/immutable/List.scala new file mode 100644 index 0000000000..dd3ed146c3 --- /dev/null +++ b/src/dotnet-library/scala/collection/immutable/List.scala @@ -0,0 +1,863 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2003-2009, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +// $Id: List.scala 16287 2008-10-18 13:41:36Z nielsen $ + + +package scala.collection.immutable + +import mutable.ListBuffer +import generic._ + +/** A class representing an ordered collection of elements of type + * a. This class comes with two implementing case + * classes scala.Nil and scala.:: that + * implement the abstract members isEmpty, + * head and tail. + * + * @author Martin Odersky and others + * @version 2.8 + */ +sealed abstract class List[+A] extends LinearSequence[A] + with Product + with TraversableClass[A, List] + with LinearSequenceTemplate[A, List[A]] { + override def companion: Companion[List] = List + + import collection.{Iterable, Traversable, Sequence, Vector} + + /** Returns true if the list does not contain any elements. + * @return true, iff the list is empty. + */ + def isEmpty: Boolean + + /** Returns this first element of the list. + * + * @return the first element of this list. + * @throws Predef.NoSuchElementException if the list is empty. + */ + def head: A + + /** Returns this list without its first element. + * + * @return this list without its first element. + * @throws Predef.NoSuchElementException if the list is empty. + */ + def tail: List[A] + + // New methods in List + + /**

+ * Add an element x at the beginning of this list. + *

+ * + * @param x the element to prepend. + * @return the list with x added at the beginning. + * @ex 1 :: List(2, 3) = List(2, 3).::(1) = List(1, 2, 3) + */ + def ::[B >: A] (x: B): List[B] = + new scala.collection.immutable.::(x, this) + + /**

+ * Returns a list resulting from the concatenation of the given + * list prefix and this list. + *

+ * + * @param prefix the list to concatenate at the beginning of this list. + * @return the concatenation of the two lists. + * @ex List(1, 2) ::: List(3, 4) = List(3, 4).:::(List(1, 2)) = List(1, 2, 3, 4) + */ + def :::[B >: A](prefix: List[B]): List[B] = + if (isEmpty) prefix + else (new ListBuffer[B] ++ prefix).prependToList(this) + + /** Reverse the given prefix and append the current list to that. + * This function is equivalent to an application of reverse + * on the prefix followed by a call to :::, but is more + * efficient. + * + * @param prefix the prefix to reverse and then prepend + * @return the concatenation of the reversed prefix and the current list. + */ + def reverse_:::[B >: A](prefix: List[B]): List[B] = { + var these: List[B] = this + var pres = prefix + while (!pres.isEmpty) { + these = pres.head :: these + pres = pres.tail + } + these + } + + /** Apply a function to all the elements of the list, and return the + * reversed list of results. This is equivalent to a call to map + * followed by a call to reverse, but more efficient. + * !!! should we deprecate this? Why have reverseMap, but not filterMap or reverseFilter, say? + * @param f the function to apply to each elements. + * @return the reversed list of results. + */ + def reverseMap[B](f: A => B): List[B] = { + def loop(l: List[A], res: List[B]): List[B] = l match { + case Nil => res + case head :: tail => loop(tail, f(head) :: res) + } + loop(this, Nil) + } + + /** Like xs map f, but returns xs unchanged if function + * f maps all elements to themselves (wrt ==). + * @note Unlike `map`, `mapConserve` is not tail-recursive. + */ + def mapConserve[B >: A] (f: A => B): List[B] = { + def loop(ys: List[A]): List[B] = + if (ys.isEmpty) this + else { + val head0 = ys.head + val head1 = f(head0) + if (head1 == head0) { + loop(ys.tail) + } else { + val ys1 = head1 :: ys.tail.mapConserve(f) + if (this eq ys) ys1 + else { + val b = new ListBuffer[B] + var xc = this + while (xc ne ys) { + b += xc.head + xc = xc.tail + } + b.prependToList(ys1) + } + } + } + loop(this) + } + + // Overridden methods from IterableTemplate or overloaded variants of such methods + + /** Create a new list which contains all elements of this list + * followed by all elements of Traversable `that' + */ + override def ++[B >: A, That](that: Traversable[B])(implicit bf: BuilderFactory[B, That, List[A]]): That = { + val b = bf(this) + if (b.isInstanceOf[ListBuffer[_]]) (this ::: that.toList).asInstanceOf[That] + else super.++(that) + } + + /** Create a new list which contains all elements of this list + * followed by all elements of Iterator `that' + */ + override def ++[B >: A, That](that: Iterator[B])(implicit bf: BuilderFactory[B, That, List[A]]): That = + this ++ that.toList + + /** Overrides the method in Iterable for efficiency. + * + * @return the list itself + */ + override def toList: List[A] = this + + /** Returns the n first elements of this list, or else the whole + * list, if it has less than n elements. + + * @param n the number of elements to take. + * @return the n first elements of this list. + */ + override def take(n: Int): List[A] = { + val b = new ListBuffer[A] + var i = 0 + var these = this + while (!these.isEmpty && i < n) { + i += 1 + b += these.head + these = these.tail + } + if (these.isEmpty) this + else b.toList + } + + /** Returns the list without its n first elements. + * If this list has less than n elements, the empty list is returned. + * + * @param n the number of elements to drop. + * @return the list without its n first elements. + */ + override def drop(n: Int): List[A] = { + var these = this + var count = n + while (!these.isEmpty && count > 0) { + these = these.tail + count -= 1 + } + these + } + + /** Returns the list with elements belonging to the given index range. + * + * @param start the start position of the list slice. + * @param end the end position (exclusive) of the list slice. + * @return the list with elements belonging to the given index range. + */ + override def slice(start: Int, end: Int): List[A] = { + var len = end + if (start > 0) len -= start + drop(start) take len + } + + /** Returns the rightmost n elements from this list. + * + * @param n the number of elements to take + * @return the suffix of length n of the list + */ + override def takeRight(n: Int): List[A] = { + def loop(lead: List[A], lag: List[A]): List[A] = lead match { + case Nil => lag + case _ :: tail => loop(tail, lag.tail) + } + loop(drop(n), this) + } + + // dropRight is inherited from Stream + + /** Split the list at a given point and return the two parts thus + * created. + * + * @param n the position at which to split + * @return a pair of lists composed of the first n + * elements, and the other elements. + */ + override def splitAt(n: Int): (List[A], List[A]) = { + val b = new ListBuffer[A] + var i = 0 + var these = this + while (!these.isEmpty && i < n) { + i += 1 + b += these.head + these = these.tail + } + (b.toList, these) + } + + /** Returns the longest prefix of this list whose elements satisfy + * the predicate p. + * + * @param p the test predicate. + * @return the longest prefix of this list whose elements satisfy + * the predicate p. + */ + override def takeWhile(p: A => Boolean): List[A] = { + val b = new ListBuffer[A] + var these = this + while (!these.isEmpty && p(these.head)) { + b += these.head + these = these.tail + } + b.toList + } + + /** Returns the longest suffix of this list whose first element + * does not satisfy the predicate p. + * + * @param p the test predicate. + * @return the longest suffix of the list whose first element + * does not satisfy the predicate p. + */ + override def dropWhile(p: A => Boolean): List[A] = + if (isEmpty || !p(head)) this + else tail dropWhile p + + /** Returns the longest prefix of the list whose elements all satisfy + * the given predicate, and the rest of the list. + * + * @param p the test predicate + * @return a pair consisting of the longest prefix of the list whose + * elements all satisfy p, and the rest of the list. + */ + override def span(p: A => Boolean): (List[A], List[A]) = { + val b = new ListBuffer[A] + var these = this + while (!these.isEmpty && p(these.head)) { + b += these.head + these = these.tail + } + (b.toList, these) + } + + /** A list consisting of all elements of this list in reverse order. + */ + override def reverse: List[A] = { + var result: List[A] = Nil + var these = this + while (!these.isEmpty) { + result = these.head :: result + these = these.tail + } + result + } + + override def stringPrefix = "List" + + override def toStream : Stream[A] = + if (isEmpty) Stream.Empty + else new Stream.Cons(head, tail.toStream) + + // !!! todo: work in patch + + /** Computes the difference between this list and the given list + * that. + * + * @param that the list of elements to remove from this list. + * @return this list without the elements of the given list + * that. + * @deprecated use diff instead + */ + @deprecated def -- [B >: A](that: List[B]): List[B] = { + val b = new ListBuffer[B] + var these = this + while (!these.isEmpty) { + if (!that.contains(these.head)) b += these.head + these = these.tail + } + b.toList + } + + /** Computes the difference between this list and the given object + * x. + * + * @param x the object to remove from this list. + * @return this list without occurrences of the given object + * x. + * @deprecated use diff instead + */ + @deprecated def - [B >: A](x: B): List[B] = { + val b = new ListBuffer[B] + var these = this + while (!these.isEmpty) { + if (these.head != x) b += these.head + these = these.tail + } + b.toList + } + + /**

+ * Sort the list according to the comparison function + * <(e1: a, e2: a) => Boolean, + * which should be true iff e1 is smaller than + * e2. + * !!! todo: move sorting to IterableTemplate + *

+ * + * @param lt the comparison function + * @return a list sorted according to the comparison function + * <(e1: a, e2: a) => Boolean. + * @ex
+   *    List("Steve", "Tom", "John", "Bob")
+   *      .sort((e1, e2) => (e1 compareTo e2) < 0) =
+   *    List("Bob", "John", "Steve", "Tom")
+ * @deprecated use sortWith instead + */ + @deprecated def sort(lt : (A,A) => Boolean): List[A] = { + /** Merge two already-sorted lists */ + def merge(l1: List[A], l2: List[A]): List[A] = { + val res = new ListBuffer[A] + var left1 = l1 + var left2 = l2 + + while (!left1.isEmpty && !left2.isEmpty) { + if(lt(left1.head, left2.head)) { + res += left1.head + left1 = left1.tail + } else { + res += left2.head + left2 = left2.tail + } + } + + res ++= left1 + res ++= left2 + + res.toList + } + + /** Split a list into two lists of about the same size */ + def split(lst: List[A]) = { + val res1 = new ListBuffer[A] + val res2 = new ListBuffer[A] + var left = lst + + while (!left.isEmpty) { + res1 += left.head + left = left.tail + if (!left.isEmpty) { + res2 += left.head + left = left.tail + } + } + + (res1.toList, res2.toList) + } + + + /** Merge-sort the specified list */ + def ms(lst: List[A]): List[A] = + lst match { + case Nil => lst + case x :: Nil => lst + case x :: y :: Nil => + if (lt(x,y)) + lst + else + y :: x :: Nil + + case lst => + val (l1, l2) = split(lst) + val l1s = ms(l1) + val l2s = ms(l2) + merge(l1s, l2s) + } + + ms(this) + } + +} + +/** The empty list. + * + * @author Martin Odersky + * @version 1.0, 15/07/2003 + */ +@SerialVersionUID(0 - 8256821097970055419L) +case object Nil extends List[Nothing] { + override def isEmpty = true + override def head: Nothing = + throw new NoSuchElementException("head of empty list") + override def tail: List[Nothing] = + throw new NoSuchElementException("tail of empty list") + override def equals(that: Any) = that match { + case that1: Sequence[_] => that1.isEmpty + case _ => false + } +} + +/** A non empty list characterized by a head and a tail. + * + * @author Martin Odersky + * @version 1.0, 15/07/2003 + */ +@SerialVersionUID(0L - 8476791151983527571L) +final case class ::[B](private var hd: B, private[scala] var tl: List[B]) extends List[B] { + override def head : B = hd + override def tail : List[B] = tl + override def isEmpty: Boolean = false + +// import java.io._ + +// private def writeObject(out: ObjectOutputStream) { +// var xs: List[B] = this +// while (!xs.isEmpty) { out.writeObject(xs.head); xs = xs.tail } +// out.writeObject(ListSerializeEnd) +// } + +// private def readObject(in: ObjectInputStream) { +// hd = in.readObject.asInstanceOf[B] +// assert(hd != ListSerializeEnd) +// var current: ::[B] = this +// while (true) in.readObject match { +// case ListSerializeEnd => +// current.tl = Nil +// return +// case a : Any => +// val list : ::[B] = new ::(a.asInstanceOf[B], Nil) +// current.tl = list +// current = list +// } +// } +} + +/** This object provides methods for creating specialized lists, and for + * transforming special kinds of lists (e.g. lists of lists). + * + * @author Martin Odersky + * @version 2.8 + */ +object List extends SequenceFactory[List] { + + import collection.{Iterable, Sequence, Vector} + + implicit def builderFactory[A]: BuilderFactory[A, List[A], Coll] = new VirtualBuilderFactory[A] + def newBuilder[A]: Builder[A, List[A]] = new ListBuffer[A] + + override def empty[A]: List[A] = Nil + + override def apply[A](xs: A*): List[A] = xs.toList + + /** Create a sorted list with element values + * vn+1 = step(vn) + * where v0 = start + * and elements are in the range between start (inclusive) + * and end (exclusive) + * + * @deprecated use @see iterate instead. + * @param start the start value of the list + * @param end the end value of the list + * @param step the increment function of the list, which given vn, + * computes vn+1. Must be monotonically increasing + * or decreasing. + * @return the sorted list of all integers in range [start;end). + */ + @deprecated def range(start: Int, end: Int, step: Int => Int): List[Int] = { + val up = step(start) > start + val down = step(start) < start + val b = new ListBuffer[Int] + var i = start + while ((!up || i < end) && (!down || i > end)) { + b += i + val next = step(i) + if (i == next) + throw new IllegalArgumentException("the step function did not make any progress on "+ i) + i = next + } + b.toList + } + + /** Create a list containing several copies of an element. + * @deprecated use @see fill instead + * + * @param n the length of the resulting list + * @param elem the element composing the resulting list + * @return a list composed of n elements all equal to elem + */ + @deprecated def make[A](n: Int, elem: A): List[A] = { + val b = new ListBuffer[A] + var i = 0 + while (i < n) { + b += elem + i += 1 + } + b.toList + } + + /** Concatenate all the elements of a given list of lists. + * + * @deprecated use `xss.flatten` instead + * @param xss the list of lists that are to be concatenated + * @return the concatenation of all the lists + */ + @deprecated def flatten[A](xss: List[List[A]]): List[A] = { + val b = new ListBuffer[A] + for (xs <- xss) { + var xc = xs + while (!xc.isEmpty) { + b += xc.head + xc = xc.tail + } + } + b.toList + } + + /** Transforms a list of pairs into a pair of lists. + * + * @param xs the list of pairs to unzip + * @return a pair of lists. + * @deprecated use `xs.unzp` instead + */ + @deprecated def unzip[A,B](xs: List[(A,B)]): (List[A], List[B]) = { + val b1 = new ListBuffer[A] + val b2 = new ListBuffer[B] + var xc = xs + while (!xc.isEmpty) { + b1 += xc.head._1 + b2 += xc.head._2 + xc = xc.tail + } + (b1.toList, b2.toList) + } + + /** Transforms an iterable of pairs into a pair of lists. + * + * @deprecated use `xs.unzip` instead + * @param xs the iterable of pairs to unzip + * @return a pair of lists. + */ + @deprecated def unzip[A,B](xs: Iterable[(A,B)]): (List[A], List[B]) = + xs.foldRight[(List[A], List[B])]((Nil, Nil)) { + case ((x, y), (xs, ys)) => (x :: xs, y :: ys) + } + + /** + * Returns the Left values in the given Iterable of Eithers. + * @deprecated use `Either.lefts` instead + */ + @deprecated def lefts[A, B](es: Iterable[Either[A, B]]) = + es.foldRight[List[A]](Nil)((e, as) => e match { + case Left(a) => a :: as + case Right(_) => as + }) + + /** + * Returns the Right values in the givenIterable of Eithers. + * @deprecated use `Either.rights` instead + */ + @deprecated def rights[A, B](es: Iterable[Either[A, B]]) = + es.foldRight[List[B]](Nil)((e, bs) => e match { + case Left(_) => bs + case Right(b) => b :: bs + }) + + /** Transforms an Iterable of Eithers into a pair of lists. + * + * @param xs the iterable of Eithers to separate + * @return a pair of lists. + * @deprecated use `Either.separate` instead + */ + @deprecated def separate[A,B](es: Iterable[Either[A,B]]): (List[A], List[B]) = + es.foldRight[(List[A], List[B])]((Nil, Nil)) { + case (Left(a), (lefts, rights)) => (a :: lefts, rights) + case (Right(b), (lefts, rights)) => (lefts, b :: rights) + } + + /** Converts an iterator to a list. + * + * @param it the iterator to convert + * @return a list that contains the elements returned by successive + * calls to it.next + * @deprecated use it.toList instead + */ + @deprecated def fromIterator[A](it: Iterator[A]): List[A] = it.toList + + /** Converts an array into a list. + * + * @param arr the array to convert + * @return a list that contains the same elements than arr + * in the same order + * @deprecated use `array.toList` instead + */ + @deprecated def fromArray[A](arr: Array[A]): List[A] = fromArray(arr, 0, arr.length) + + /** Converts a range of an array into a list. + * + * @param arr the array to convert + * @param start the first index to consider + * @param len the lenght of the range to convert + * @return a list that contains the same elements than arr + * in the same order + * @deprecated use `array.view(start, end).toList` instead + */ + @deprecated def fromArray[A](arr: Array[A], start: Int, len: Int): List[A] = { + var res: List[A] = Nil + var i = start + len + while (i > start) { + i -= 1 + res = arr(i) :: res + } + res + } + + /** Parses a string which contains substrings separated by a + * separator character and returns a list of all substrings. + * + * @param str the string to parse + * @param separator the separator character + * @return the list of substrings + * @deprecated use `str.split(separator).toList` instead + */ + @deprecated def fromString(str: String, separator: Char): List[String] = { + var words: List[String] = Nil + var pos = str.length() + while (pos > 0) { + val pos1 = str.lastIndexOf(separator, pos - 1) + if (pos1 + 1 < pos) + words = str.substring(pos1 + 1, pos) :: words + pos = pos1 + } + words + } + + /** Returns the given string as a list of characters. + * + * @param str the string to convert. + * @return the string as a list of characters. + * @deprecated use str.toList instead + */ + @deprecated def fromString(str: String): List[Char] = str.toList + + /** Returns the given list of characters as a string. + * + * @param xs the list to convert. + * @return the list in form of a string. + * @deprecated use xs.mkString instead + */ + @deprecated def toString(xs: List[Char]): String = { + val sb = new StringBuilder() + var xc = xs + while (!xc.isEmpty) { + sb.append(xc.head) + xc = xc.tail + } + sb.toString() + } + + /** Like xs map f, but returns xs unchanged if function + * f maps all elements to themselves. + * @deprecated use xs.mapConserve(f) + */ + @deprecated def mapConserve[A <: AnyRef](xs: List[A])(f: A => A): List[A] = { + def loop(ys: List[A]): List[A] = + if (ys.isEmpty) xs + else { + val head0 = ys.head + val head1 = f(head0) + if (head1 eq head0) { + loop(ys.tail) + } else { + val ys1 = head1 :: mapConserve(ys.tail)(f) + if (xs eq ys) ys1 + else { + val b = new ListBuffer[A] + var xc = xs + while (xc ne ys) { + b += xc.head + xc = xc.tail + } + b.prependToList(ys1) + } + } + } + loop(xs) + } + + /** Returns the list resulting from applying the given function f + * to corresponding elements of the argument lists. + * @deprecated use (xs, ys).map(f) instead + * @param f function to apply to each pair of elements. + * @return [f(a0,b0), ..., f(an,bn)] if the lists are + * [a0, ..., ak], [b0, ..., bl] and + * n = min(k,l) + */ + @deprecated def map2[A,B,C](xs: List[A], ys: List[B])(f: (A, B) => C): List[C] = { + val b = new ListBuffer[C] + var xc = xs + var yc = ys + while (!xc.isEmpty && !yc.isEmpty) { + b += f(xc.head, yc.head) + xc = xc.tail + yc = yc.tail + } + b.toList + } + + /** Returns the list resulting from applying the given function + * f to corresponding elements of the argument lists. + * + * @param f function to apply to each pair of elements. + * @deprecated use (xs, ys, zs).map(f) instead + * @return [f(a0,b0,c0), + * ..., f(an,bn,cn)] + * if the lists are [a0, ..., ak], + * [b0, ..., bl], + * [c0, ..., cm] and + * n = min(k,l,m) + */ + @deprecated def map3[A,B,C,D](xs: List[A], ys: List[B], zs: List[C])(f: (A, B, C) => D): List[D] = { + val b = new ListBuffer[D] + var xc = xs + var yc = ys + var zc = zs + while (!xc.isEmpty && !yc.isEmpty && !zc.isEmpty) { + b += f(xc.head, yc.head, zc.head) + xc = xc.tail + yc = yc.tail + zc = zc.tail + } + b.toList + } + + /** Tests whether the given predicate p holds + * for all corresponding elements of the argument lists. + * + * @param p function to apply to each pair of elements. + * @return (p(a0,b0) && + * ... && p(an,bn))] + * if the lists are [a0, ..., ak]; + * [b0, ..., bl] + * and n = min(k,l) + * @deprecated use (xs, ys).forall(f) instead + */ + @deprecated def forall2[A,B](xs: List[A], ys: List[B])(f: (A, B) => Boolean): Boolean = { + var xc = xs + var yc = ys + while (!xc.isEmpty && !yc.isEmpty) { + if (!f(xc.head, yc.head)) return false + xc = xc.tail + yc = yc.tail + } + true + } + + /** Tests whether the given predicate p holds + * for some corresponding elements of the argument lists. + * + * @param p function to apply to each pair of elements. + * @return n != 0 && (p(a0,b0) || + * ... || p(an,bn))] if the lists are + * [a0, ..., ak], + * [b0, ..., bl] and + * n = min(k,l) + * @deprecated use (xs, ys).forall(f) instead + */ + @deprecated def exists2[A,B](xs: List[A], ys: List[B])(f: (A, B) => Boolean): Boolean = { + var xc = xs + var yc = ys + while (!xc.isEmpty && !yc.isEmpty) { + if (f(xc.head, yc.head)) return true + xc = xc.tail + yc = yc.tail + } + false + } + + /** Transposes a list of lists. + * pre: All element lists have the same length. + * + * @param xss the list of lists + * @return the transposed list of lists + * @deprecated use xss.transpose instead + */ + @deprecated def transpose[A](xss: List[List[A]]): List[List[A]] = { + val buf = new ListBuffer[List[A]] + var yss = xss + while (!yss.head.isEmpty) { + buf += (yss map (_.head)) + yss = (yss map (_.tail)) + } + buf.toList + } + + /** Lists with ordered elements are ordered + implicit def list2ordered[a <% Ordered[a]](x: List[a]): Ordered[List[a]] = new Ordered[List[a]] { + def compare [b >: List[a] <% Ordered[b]](y: b): Int = y match { + case y1: List[a] => compareLists(x, y1); + case _ => -(y compare x) + } + private def compareLists(xs: List[a], ys: List[a]): Int = { + if (xs.isEmpty && ys.isEmpty) 0 + else if (xs.isEmpty) -1 + else if (ys.isEmpty) 1 + else { + val s = xs.head compare ys.head; + if (s != 0) s + else compareLists(xs.tail, ys.tail) + } + } + } + */ +} + +/** Only used for list serialization */ +@SerialVersionUID(0L - 8476791151975527571L) +private[scala] case object ListSerializeEnd + diff --git a/src/dotnet-library/scala/collection/jcl/ArrayList.scala b/src/dotnet-library/scala/collection/jcl/ArrayList.scala deleted file mode 100644 index b708c82a82..0000000000 --- a/src/dotnet-library/scala/collection/jcl/ArrayList.scala +++ /dev/null @@ -1 +0,0 @@ -/* ArrayList does not exist for the dotnet target */ diff --git a/src/dotnet-library/scala/collection/jcl/Buffer.scala b/src/dotnet-library/scala/collection/jcl/Buffer.scala deleted file mode 100644 index e90266c12c..0000000000 --- a/src/dotnet-library/scala/collection/jcl/Buffer.scala +++ /dev/null @@ -1 +0,0 @@ -/* Buffer does not exist for the dotnet target */ diff --git a/src/dotnet-library/scala/collection/jcl/BufferIterator.scala b/src/dotnet-library/scala/collection/jcl/BufferIterator.scala deleted file mode 100644 index 4807032991..0000000000 --- a/src/dotnet-library/scala/collection/jcl/BufferIterator.scala +++ /dev/null @@ -1 +0,0 @@ -/* BufferIterator does not exist for the dotnet target */ diff --git a/src/dotnet-library/scala/collection/jcl/BufferWrapper.scala b/src/dotnet-library/scala/collection/jcl/BufferWrapper.scala deleted file mode 100644 index ba776946e2..0000000000 --- a/src/dotnet-library/scala/collection/jcl/BufferWrapper.scala +++ /dev/null @@ -1 +0,0 @@ -/* BufferWrapper does not exist for the dotnet target */ diff --git a/src/dotnet-library/scala/collection/jcl/Collection.scala b/src/dotnet-library/scala/collection/jcl/Collection.scala deleted file mode 100644 index 6972e147bb..0000000000 --- a/src/dotnet-library/scala/collection/jcl/Collection.scala +++ /dev/null @@ -1 +0,0 @@ -/* Collection does not exist for the dotnet target */ diff --git a/src/dotnet-library/scala/collection/jcl/CollectionWrapper.scala b/src/dotnet-library/scala/collection/jcl/CollectionWrapper.scala deleted file mode 100644 index 7006b11d7e..0000000000 --- a/src/dotnet-library/scala/collection/jcl/CollectionWrapper.scala +++ /dev/null @@ -1 +0,0 @@ -/* CollectionWrapper does not exist for the dotnet target */ diff --git a/src/dotnet-library/scala/collection/jcl/Conversions.scala b/src/dotnet-library/scala/collection/jcl/Conversions.scala deleted file mode 100644 index 97c99f62a9..0000000000 --- a/src/dotnet-library/scala/collection/jcl/Conversions.scala +++ /dev/null @@ -1 +0,0 @@ -/* Conversions does not exist for the dotnet target */ diff --git a/src/dotnet-library/scala/collection/jcl/HashMap.scala b/src/dotnet-library/scala/collection/jcl/HashMap.scala deleted file mode 100644 index e62738f04f..0000000000 --- a/src/dotnet-library/scala/collection/jcl/HashMap.scala +++ /dev/null @@ -1 +0,0 @@ -/* HashMap does not exist for the dotnet target */ diff --git a/src/dotnet-library/scala/collection/jcl/HashSet.scala b/src/dotnet-library/scala/collection/jcl/HashSet.scala deleted file mode 100644 index c2599b23ad..0000000000 --- a/src/dotnet-library/scala/collection/jcl/HashSet.scala +++ /dev/null @@ -1 +0,0 @@ -/* HashSet does not exist for the dotnet target */ diff --git a/src/dotnet-library/scala/collection/jcl/Hashtable.scala b/src/dotnet-library/scala/collection/jcl/Hashtable.scala deleted file mode 100644 index cf07705526..0000000000 --- a/src/dotnet-library/scala/collection/jcl/Hashtable.scala +++ /dev/null @@ -1 +0,0 @@ -/* Hashtable does not exist for the dotnet target */ diff --git a/src/dotnet-library/scala/collection/jcl/IdentityHashMap.scala b/src/dotnet-library/scala/collection/jcl/IdentityHashMap.scala deleted file mode 100644 index e121285da2..0000000000 --- a/src/dotnet-library/scala/collection/jcl/IdentityHashMap.scala +++ /dev/null @@ -1 +0,0 @@ -/* IdentityHashMap does not exist for the dotnet target */ diff --git a/src/dotnet-library/scala/collection/jcl/IterableWrapper.scala b/src/dotnet-library/scala/collection/jcl/IterableWrapper.scala deleted file mode 100644 index 076d707d99..0000000000 --- a/src/dotnet-library/scala/collection/jcl/IterableWrapper.scala +++ /dev/null @@ -1 +0,0 @@ -/* IterableWrapper does not exist for the dotnet target */ diff --git a/src/dotnet-library/scala/collection/jcl/LinkedHashMap.scala b/src/dotnet-library/scala/collection/jcl/LinkedHashMap.scala deleted file mode 100644 index 77de6a4f44..0000000000 --- a/src/dotnet-library/scala/collection/jcl/LinkedHashMap.scala +++ /dev/null @@ -1 +0,0 @@ -/* LinkedHashMap does not exist for the dotnet target */ diff --git a/src/dotnet-library/scala/collection/jcl/LinkedHashSet.scala b/src/dotnet-library/scala/collection/jcl/LinkedHashSet.scala deleted file mode 100644 index 3de125b5b1..0000000000 --- a/src/dotnet-library/scala/collection/jcl/LinkedHashSet.scala +++ /dev/null @@ -1 +0,0 @@ -/* LinkedHashSet does not exist for the dotnet target */ diff --git a/src/dotnet-library/scala/collection/jcl/LinkedList.scala b/src/dotnet-library/scala/collection/jcl/LinkedList.scala deleted file mode 100644 index e512dd45f3..0000000000 --- a/src/dotnet-library/scala/collection/jcl/LinkedList.scala +++ /dev/null @@ -1 +0,0 @@ -/* LinkedList does not exist for the dotnet target */ diff --git a/src/dotnet-library/scala/collection/jcl/Map.scala b/src/dotnet-library/scala/collection/jcl/Map.scala deleted file mode 100644 index aed3a996e8..0000000000 --- a/src/dotnet-library/scala/collection/jcl/Map.scala +++ /dev/null @@ -1 +0,0 @@ -/* Map does not exist for the dotnet target */ diff --git a/src/dotnet-library/scala/collection/jcl/MapWrapper.scala b/src/dotnet-library/scala/collection/jcl/MapWrapper.scala deleted file mode 100644 index 77d4700908..0000000000 --- a/src/dotnet-library/scala/collection/jcl/MapWrapper.scala +++ /dev/null @@ -1 +0,0 @@ -/* MapWrapper does not exist for the dotnet target */ diff --git a/src/dotnet-library/scala/collection/jcl/MutableIterable.scala b/src/dotnet-library/scala/collection/jcl/MutableIterable.scala deleted file mode 100644 index 87b2d9f639..0000000000 --- a/src/dotnet-library/scala/collection/jcl/MutableIterable.scala +++ /dev/null @@ -1 +0,0 @@ -/* MutableIterable does not exist for the dotnet target */ diff --git a/src/dotnet-library/scala/collection/jcl/MutableIterator.scala b/src/dotnet-library/scala/collection/jcl/MutableIterator.scala deleted file mode 100644 index 1ada29b861..0000000000 --- a/src/dotnet-library/scala/collection/jcl/MutableIterator.scala +++ /dev/null @@ -1 +0,0 @@ -/* MutableIterator does not exist for the dotnet target */ diff --git a/src/dotnet-library/scala/collection/jcl/MutableSeq.scala b/src/dotnet-library/scala/collection/jcl/MutableSeq.scala deleted file mode 100644 index 60132e8785..0000000000 --- a/src/dotnet-library/scala/collection/jcl/MutableSeq.scala +++ /dev/null @@ -1 +0,0 @@ -/* MutableSeq does not exist for the dotnet target */ diff --git a/src/dotnet-library/scala/collection/jcl/Ranged.scala b/src/dotnet-library/scala/collection/jcl/Ranged.scala deleted file mode 100644 index 5394b8b56c..0000000000 --- a/src/dotnet-library/scala/collection/jcl/Ranged.scala +++ /dev/null @@ -1 +0,0 @@ -/* Ranged does not exist for the dotnet target */ diff --git a/src/dotnet-library/scala/collection/jcl/SeqIterator.scala b/src/dotnet-library/scala/collection/jcl/SeqIterator.scala deleted file mode 100644 index 1d952baa0e..0000000000 --- a/src/dotnet-library/scala/collection/jcl/SeqIterator.scala +++ /dev/null @@ -1 +0,0 @@ -/* SeqIterator does not exist for the dotnet target */ diff --git a/src/dotnet-library/scala/collection/jcl/Set.scala b/src/dotnet-library/scala/collection/jcl/Set.scala deleted file mode 100644 index 5c5bae7b48..0000000000 --- a/src/dotnet-library/scala/collection/jcl/Set.scala +++ /dev/null @@ -1 +0,0 @@ -/* Set does not exist for the dotnet target */ diff --git a/src/dotnet-library/scala/collection/jcl/SetWrapper.scala b/src/dotnet-library/scala/collection/jcl/SetWrapper.scala deleted file mode 100644 index 448b137163..0000000000 --- a/src/dotnet-library/scala/collection/jcl/SetWrapper.scala +++ /dev/null @@ -1 +0,0 @@ -/* SetWrapper does not exist for the dotnet target */ diff --git a/src/dotnet-library/scala/collection/jcl/Sorted.scala b/src/dotnet-library/scala/collection/jcl/Sorted.scala deleted file mode 100644 index 7fcfe8a6b1..0000000000 --- a/src/dotnet-library/scala/collection/jcl/Sorted.scala +++ /dev/null @@ -1 +0,0 @@ -/* Sorted does not exist for the dotnet target */ diff --git a/src/dotnet-library/scala/collection/jcl/SortedMap.scala b/src/dotnet-library/scala/collection/jcl/SortedMap.scala deleted file mode 100644 index dbbc1032d3..0000000000 --- a/src/dotnet-library/scala/collection/jcl/SortedMap.scala +++ /dev/null @@ -1 +0,0 @@ -/* SortedMap does not exist for the dotnet target */ diff --git a/src/dotnet-library/scala/collection/jcl/SortedMapWrapper.scala b/src/dotnet-library/scala/collection/jcl/SortedMapWrapper.scala deleted file mode 100644 index dbf001f4ef..0000000000 --- a/src/dotnet-library/scala/collection/jcl/SortedMapWrapper.scala +++ /dev/null @@ -1 +0,0 @@ -/* SortedMapWrapper does not exist for the dotnet target */ diff --git a/src/dotnet-library/scala/collection/jcl/SortedSet.scala b/src/dotnet-library/scala/collection/jcl/SortedSet.scala deleted file mode 100644 index 6b7351bae2..0000000000 --- a/src/dotnet-library/scala/collection/jcl/SortedSet.scala +++ /dev/null @@ -1 +0,0 @@ -/* SortedSet does not exist for the dotnet target */ diff --git a/src/dotnet-library/scala/collection/jcl/SortedSetWrapper.scala b/src/dotnet-library/scala/collection/jcl/SortedSetWrapper.scala deleted file mode 100644 index e2667debd2..0000000000 --- a/src/dotnet-library/scala/collection/jcl/SortedSetWrapper.scala +++ /dev/null @@ -1 +0,0 @@ -/* SortedSetWrapper does not exist for the dotnet target */ diff --git a/src/dotnet-library/scala/collection/jcl/Tests.scala b/src/dotnet-library/scala/collection/jcl/Tests.scala deleted file mode 100644 index 3939b18a48..0000000000 --- a/src/dotnet-library/scala/collection/jcl/Tests.scala +++ /dev/null @@ -1 +0,0 @@ -/* Tests does not exist for the dotnet target */ diff --git a/src/dotnet-library/scala/collection/jcl/TreeMap.scala b/src/dotnet-library/scala/collection/jcl/TreeMap.scala deleted file mode 100644 index 3c6efabca1..0000000000 --- a/src/dotnet-library/scala/collection/jcl/TreeMap.scala +++ /dev/null @@ -1 +0,0 @@ -/* TreeMap does not exist for the dotnet target */ diff --git a/src/dotnet-library/scala/collection/jcl/TreeSet.scala b/src/dotnet-library/scala/collection/jcl/TreeSet.scala deleted file mode 100644 index 9a32c527f3..0000000000 --- a/src/dotnet-library/scala/collection/jcl/TreeSet.scala +++ /dev/null @@ -1 +0,0 @@ -/* TreeSet does not exist for the dotnet target */ diff --git a/src/dotnet-library/scala/collection/jcl/WeakHashMap.scala b/src/dotnet-library/scala/collection/jcl/WeakHashMap.scala deleted file mode 100644 index dbe2039713..0000000000 --- a/src/dotnet-library/scala/collection/jcl/WeakHashMap.scala +++ /dev/null @@ -1 +0,0 @@ -/* WeakHashMap does not exist for the dotnet target */ diff --git a/src/dotnet-library/scala/collection/mutable/JavaMapAdaptor.scala b/src/dotnet-library/scala/collection/mutable/JavaMapAdaptor.scala deleted file mode 100644 index fec485876c..0000000000 --- a/src/dotnet-library/scala/collection/mutable/JavaMapAdaptor.scala +++ /dev/null @@ -1 +0,0 @@ -/* JavaMapAdaptor does not exist for the dotnet target */ diff --git a/src/dotnet-library/scala/collection/mutable/JavaSetAdaptor.scala b/src/dotnet-library/scala/collection/mutable/JavaSetAdaptor.scala deleted file mode 100644 index 36ba221cb0..0000000000 --- a/src/dotnet-library/scala/collection/mutable/JavaSetAdaptor.scala +++ /dev/null @@ -1 +0,0 @@ -/* JavaSetAdaptor does not exist for the dotnet target */ diff --git a/src/dotnet-library/scala/collection/mutable/StringBuilder.scala b/src/dotnet-library/scala/collection/mutable/StringBuilder.scala new file mode 100644 index 0000000000..2a1da07232 --- /dev/null +++ b/src/dotnet-library/scala/collection/mutable/StringBuilder.scala @@ -0,0 +1,957 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2006-2009, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +// $Id: StringBuilder.scala 16884 2009-01-09 16:52:09Z cunei $ + + +package scala.collection.mutable + +import collection.generic._ +import scala.runtime.RichString + +/**

+ * A mutable sequence of characters. This class provides an API compatible + * with + * java.lang.StringBuilder. + *

generic/ + * + * @author Stephane Micheloud + * @author Martin Odersky + * @version 2.8 + */ +//@serializable +//@SerialVersionUID(0 - 8525408645367278351L) +final class StringBuilder(initCapacity: Int, private val initValue: String) + extends Builder[Char, String] + with Vector[Char] { + + require(initCapacity > 0) + + /** The value is used for character storage. */ + private var array = new Array[Char](initCapacity + initValue.length) + + /** The count is the number of characters used. */ + private var count: Int = 0 + + /** Constructs a string builder with no characters in it and an + * initial capacity of 16 characters. + */ + def this() = this(16, "") + + /** Constructs a string builder with no characters in it and an + * initial capacity specified by the capacity argument. + * + * @param capacity the initial capacity. + * @throws NegativeArraySizeException if the capacity + * argument is less than 0. + */ + def this(capacity: Int) = this(capacity, "") + + /** Constructs a string builder with initial characters + * equal to characters of `str`. + */ + def this(str: String) = this(16, str) + + append(initValue) + + def toArray: Array[Char] = array + + def length: Int = count + def length_=(n: Int) { setLength(n) } + + /** Clears the builder contents. + */ + def clear(): Unit = setLength(0) + + /** Sets the length of the character sequence. + * + * @param newLength the new length + * @throws IndexOutOfBoundsException if the n argument is negative. + */ + def setLength(n: Int) { + require(n >= 0, n) + while (count < n) append('\0') + count = n + } + + /** Returns the current capacity. The capacity is the amount of storage + * available for newly inserted characters, beyond which an allocation + * will occur. + * + * @return the current capacity + */ + def capacity: Int = array.length + + /** Same as ensureCapacity. + * @deprecated use `ensureCapacity` instead. An assignment is misleading + * because it can never decrease the capacity. + */ + @deprecated def capacity_=(n: Int) { ensureCapacity(n) } + + /**

+ * Ensures that the capacity is at least equal to the specified minimum. + * If the current capacity is less than the argument, then a new internal + * array is allocated with greater capacity. The new capacity is the larger of: + *

+ * + *

+ * If the n argument is non-positive, this + * method takes no action and simply returns. + *

+ * + * @param n the minimum desired capacity. + */ + def ensureCapacity(n: Int) { + if (n > array.length) { + var newsize = array.length * 2 + while (n > newsize) + newsize = newsize * 2 + val newar = new Array[Char](newsize) + Array.copy(array, 0, newar, 0, count) + array = newar + } + } + + /**

+ * Returns the Char value in this sequence at the specified index. + * The first Char value is at index 0, the next at index + * 1, and so on, as in array indexing. + *

+ *

+ * The index argument must be greater than or equal to + * 0, and less than the length of this sequence. + *

+ * + * @param index the index of the desired Char value. + * @return the Char value at the specified index. + * @throws IndexOutOfBoundsException if index is + * negative or greater than or equal to length(). + */ + def charAt(index: Int): Char = { + if (index < 0 || index >= count) + throw new StringIndexOutOfBoundsException//(index) + array(index) + } + + /** Same as charAt. */ + def apply(i: Int): Char = charAt(i) + + /**

+ * Removes the Char at the specified position in this + * sequence. This sequence is shortened by one Char. + *

+ * + * @param index Index of Char to remove + * @return This object. + * @throws StringIndexOutOfBoundsException if the index + * is negative or greater than or equal to length(). + */ + def deleteCharAt(index: Int): StringBuilder = { + if (index < 0 || index >= count) + throw new StringIndexOutOfBoundsException//(index) + compat.Platform.arraycopy(array, index + 1, array, index, count - index - 1) + count -= 1 + this + } + + /**

+ * The character at the specified index is set to ch. This + * sequence is altered to represent a new character sequence that is + * identical to the old character sequence, except that it contains the + * character ch at position index. + *

+ *

+ * The index argument must be greater than or equal to + * 0, and less than the length of this sequence. + *

+ * + * @param index the index of the character to modify. + * @param ch the new character. + * @throws IndexOutOfBoundsException if index is + * negative or greater than or equal to length(). + */ + def setCharAt(index: Int, ch: Char) { + if (index < 0 || index >= count) + throw new StringIndexOutOfBoundsException//(index) + array(index) = ch + } + + /** Same as setCharAt. */ + def update(i: Int, c: Char) { setCharAt(i, c) } + + /** Returns a new String that contains a subsequence of + * characters currently contained in this character sequence. The + * substring begins at the specified index and extends to the end of + * this sequence. + * + * @param start The beginning index, inclusive. + * @return The new string. + * @throws StringIndexOutOfBoundsException if start is + * less than zero, or greater than the length of this object. + */ + def substring(start: Int): String = substring(start, count) + + /** Returns a new String that contains a subsequence of + * characters currently contained in this sequence. The + * substring begins at the specified start and + * extends to the character at index end - 1. + * + * @param start The beginning index, inclusive. + * @param end The ending index, exclusive. + * @return The new string. + * @throws StringIndexOutOfBoundsException if start + * or end are negative or greater than + * length(), or start is + * greater than end. + */ + def substring(start: Int, end: Int): String = { + if (start < 0) + throw new StringIndexOutOfBoundsException//(start) + if (end > count) + throw new StringIndexOutOfBoundsException//(end) + if (start > end) + throw new StringIndexOutOfBoundsException//(end - start) + new String(array, start, end - start) + } + +// def subSequence(start: Int, end: Int): java.lang.CharSequence = substring(start, end) + + /* Appends the string representation of the Any argument. + */ + def +=(x: Char): this.type = { append(x); this } + + def +(x: Char): this.type = { +=(x); this } + + + /**

+ * Appends the string representation of the Any + * argument. + *

+ *

+ * The argument is converted to a string as if by the method + * System.Convert.ToString, and the characters of that + * string are then appended to this sequence. + *

+ * + * @param x an Any object. + * @return a reference to this object. + */ + def append(x: Any): StringBuilder = + append(System.Convert.ToString(x)) + + /** Appends the specified string to this character sequence. + * + * @param s a string. + * @return a reference to this object. + */ + def append(s: String): StringBuilder = { + val str = if (s == null) "null" else s + val len = str.length + ensureCapacity(count + len) + compat.Platform.arraycopy(str.ToCharArray, 0, array, count, len) + count += len + this + } + + /** Appends the specified string builder to this sequence. + * + * @param sb + * @return + */ + def append(sb: StringBuilder): StringBuilder = + if (sb == null) + append("null") + else { + val len = sb.length + ensureCapacity(count + len) + compat.Platform.arraycopy(sb.toArray, 0, array, count, len) + count += len + this + } + + /**

+ * Appends the string representation of the Char sequence + * argument to this sequence. + *

+ *

+ * The characters of the sequence argument are appended, in order, + * to the contents of this sequence. The length of this sequence + * increases by the length of the argument. + *

+ * + * @param x the characters to be appended. + * @return a reference to this object. + */ + def appendAll(x: Seq[Char]): StringBuilder = + appendAll(x.toArray, 0, x.length) + + /* @deprecated use appendAll instead. This method is deprecated + * because of the possible confusion with `append(Any)`. + */ + @deprecated def append(x: Seq[Char]): StringBuilder = + appendAll(x) + + /**

+ * Appends the string representation of the Char array + * argument to this sequence. + *

+ *

+ * The characters of the array argument are appended, in order, to + * the contents of this sequence. The length of this sequence + * increases by the length of the argument. + *

+ * + * @param x the characters to be appended. + * @return a reference to this object. + */ + def appendAll(x: Array[Char]): StringBuilder = + appendAll(x, 0, x.length) + + /** @deprecated use appendAll instead. This method is deprecated + * because of the possible confusion with `append(Any)`. + */ + @deprecated def append(x: Array[Char]): StringBuilder = + appendAll(x) + + /**

+ * Appends the string representation of a subarray of the + * char array argument to this sequence. + *

+ *

+ * Characters of the Char array x, starting at + * index offset, are appended, in order, to the contents + * of this sequence. The length of this sequence increases + * by the value of len. + *

+ * + * @param x the characters to be appended. + * @param offset the index of the first Char to append. + * @param len the number of Chars to append. + * @return a reference to this object. + */ + def appendAll(x: Array[Char], offset: Int, len: Int): StringBuilder = { + ensureCapacity(count + len) + compat.Platform.arraycopy(x, offset, array, count, len) + count += len + this + } + + /** @deprecated use appendAll instead. This method is deprecated + * because of the possible confusion with `append(Any, Int, Int)`. + */ + @deprecated def append(x: Array[Char], offset: Int, len: Int): StringBuilder = + appendAll(x, offset, len) + + /**

+ * Appends the string representation of the Boolean + * argument to the sequence. + *

+ *

+ * The argument is converted to a string as if by the method + * System.Convert.ToString, and the characters of that + * string are then appended to this sequence. + *

+ * + * @param x a Boolean. + * @return a reference to this object. + */ + def append(x: Boolean): StringBuilder = append(System.Convert.ToString(x)) +// def append(x: Byte): StringBuilder = append(System.Convert.ToString(x)) + + def append(x: Char): StringBuilder = { + ensureCapacity(count + 1) + array(count) = x + count += 1 + this + } + + def append(x: Short): StringBuilder = + append(System.Convert.ToString(x)) + + def append(x: Int): StringBuilder = + append(System.Convert.ToString(x)) + + def append(x: Long): StringBuilder = + append(System.Convert.ToString(x)) + + def append(x: Float): StringBuilder = + append(System.Convert.ToString(x)) + + def append(x: Double): StringBuilder = + append(System.Convert.ToString(x)) + + /** Removes the characters in a substring of this sequence. + * The substring begins at the specified start and extends to + * the character at index end - 1 or to the end of the + * sequence if no such character exists. If + * start is equal to end, no changes are made. + * + * @param start The beginning index, inclusive. + * @param end The ending index, exclusive. + * @return This object. + * @throws StringIndexOutOfBoundsException if start + * is negative, greater than length(), or + * greater than end. + */ + def delete(start: Int, end: Int): StringBuilder = { + if (start < 0 || start > end) + throw new StringIndexOutOfBoundsException//(start) + val end0 = if (end > count) count else end + val len = end0 - start + if (len > 0) { + compat.Platform.arraycopy(array, start + len, array, start, count - end0) + count -= len + } + this + } + + /** Replaces the characters in a substring of this sequence + * with characters in the specified String. The substring + * begins at the specified start and extends to the character + * at index end - 1 or to the end of the sequence if no such + * character exists. First the characters in the substring are removed and + * then the specified String is inserted at start. + * + * @param start The beginning index, inclusive. + * @param end The ending index, exclusive. + * @param str String that will replace previous contents. + * @return This object. + * @throws StringIndexOutOfBoundsException if start + * is negative, greater than length(), or + * greater than end. + */ + def replace(start: Int, end: Int, str: String) { + if (start < 0 || start > count || start > end) + throw new StringIndexOutOfBoundsException//(start) + + val end0 = if (end > count) count else end + val len = str.length() + val newCount = count + len - (end0 - start) + ensureCapacity(newCount) + + compat.Platform.arraycopy(array, end, array, start + len, count - end) + compat.Platform.arraycopy(str.ToCharArray, 0, array, start, len) + count = newCount + this + } + + /** Inserts the string representation of a subarray of the str + * array argument into this sequence. The subarray begins at the specified + * offset and extends len chars. + * The characters of the subarray are inserted into this sequence at + * the position indicated by index. The length of this + * sequence increases by len Chars. + * + * @param index position at which to insert subarray. + * @param str a Char array. + * @param offset the index of the first char in subarray to + * be inserted. + * @param len the number of Chars in the subarray to + * be inserted. + * @return This object + * @throws StringIndexOutOfBoundsException if index + * is negative or greater than length(), or + * offset or len are negative, or + * (offset+len) is greater than + * str.length. + */ + def insertAll(index: Int, str: Array[Char], offset: Int, len: Int): StringBuilder = { + if (index < 0 || index > count) + throw new StringIndexOutOfBoundsException//(index) + if (offset < 0 || len < 0 || offset > str.length - len) + throw new StringIndexOutOfBoundsException//( +// "offset " + offset + ", len " + len + +// ", str.length " + str.length) + ensureCapacity(count + len) + compat.Platform.arraycopy(array, index, array, index + len, count - index) + compat.Platform.arraycopy(str, offset, array, index, len) + count += len + this + } + + /** @deprecated use insertAll instead. This method is deprecated + * because of the possible confusion with `insert(Int, Any, Int, Int)`. + */ + @deprecated def insert(index: Int, str: Array[Char], offset: Int, len: Int): StringBuilder = + insertAll(index, str, offset, len) + + /**

+ * Inserts the string representation of the Any + * argument into this character sequence. + *

+ *

+ * The second argument is converted to a string as if by the method + * System.Convert.ToString, and the characters of that + * string are then inserted into this sequence at the indicated + * offset. + *

+ *

+ * The offset argument must be greater than or equal to + * 0, and less than or equal to the length of this + * sequence. + *

+ * + * @param offset the offset. + * @param x an Any value. + * @return a reference to this object. + * @throws StringIndexOutOfBoundsException if the offset is invalid. + */ + def insert(at: Int, x: Any): StringBuilder = + insert(at, System.Convert.ToString(x)) + + /** Inserts the string into this character sequence. + * + * @param at the offset position. + * @param x a string. + * @return a reference to this object. + * @throws StringIndexOutOfBoundsException if the offset is invalid. + */ + def insert(at: Int, x: String): StringBuilder = { + if (at < 0 || at > count) + throw new StringIndexOutOfBoundsException//(at) + val str = if (x == null) "null" else x + val len = str.length + ensureCapacity(count + len) + compat.Platform.arraycopy(array, at, array, at + len, count - at) + compat.Platform.arraycopy(str.ToCharArray, 0, array, at, len) + count += len + this + } + + /** Inserts the string representation of the Char sequence + * argument into this sequence. + * + * @param at the offset position. + * @param x a character sequence. + * @return a reference to this object. + * @throws StringIndexOutOfBoundsException if the offset is invalid. + */ + def insertAll(at: Int, x: Seq[Char]): StringBuilder = + insertAll(at, x.toArray) + + /* @deprecated use insertAll instead. This method is deprecated + * because of the possible confusion with `insert(Int, Any)`. + */ + @deprecated def insert(at: Int, x: Seq[Char]): StringBuilder = + insertAll(at, x) + + /** Inserts the string representation of the Char array + * argument into this sequence. + * + * @param at the offset position. + * @param x a character array. + * @return a reference to this object. + * @throws StringIndexOutOfBoundsException if the offset is invalid. + */ + def insertAll(at: Int, x: Array[Char]): StringBuilder = { + if (at < 0 || at > count) + throw new StringIndexOutOfBoundsException//(at) + val len = x.length + ensureCapacity(count + len) + compat.Platform.arraycopy(array, at, array, at + len, count - at) + compat.Platform.arraycopy(x, 0, array, at, len) + count += len + this + } + + /* @deprecated use insertAll instead. This method is deprecated + * because of the possible confusion with `insert(Int, Any)`. + */ + @deprecated def insert(at: Int, x: Array[Char]): StringBuilder = + insertAll(at, x) + + /**

+ * Inserts the string representation of the Boolean argument + * into this sequence. + *

+ *

+ * The offset argument must be greater than or equal to 0, and less than + * or equal to the length of this sequence. + *

+ * + * @param at the offset position. + * @param x a Boolean value. + * @return a reference to this object. + */ + def insert(at: Int, x: Boolean): StringBuilder = + insert(at, System.Convert.ToString(x)) + + /**

+ * Inserts the string representation of the Byte argument + * into this sequence. + *

+ *

+ * The offset argument must be greater than or equal to 0, and less than + * or equal to the length of this sequence. + *

+ * + * @param at the offset position. + * @param x a Byte value. + * @return a reference to this object. + */ +// def insert(at: Int, x: Byte): StringBuilder = +// insert(at, System.Convert.ToString(x)) + + /**

+ * Inserts the string representation of the Char argument + * into this sequence. + *

+ *

+ * The offset argument must be greater than or equal to 0, and less than + * or equal to the length of this sequence. + *

+ * + * @param at the offset position. + * @param x a Char value. + * @return a reference to this object. + */ + def insert(at: Int, x: Char): StringBuilder = { + if (at < 0 || at > count) + throw new StringIndexOutOfBoundsException//(at) + ensureCapacity(count + 1) + compat.Platform.arraycopy(array, at, array, at + 1, count - at) + array(at) = x + count += 1 + this + } + + /**

+ * Inserts the string representation of the Short argument + * into this sequence. + *

+ *

+ * The offset argument must be greater than or equal to 0, and less than + * or equal to the length of this sequence. + *

+ * + * @param at the offset position. + * @param x a Short value. + * @return a reference to this object. + */ + def insert(at: Int, x: Short): StringBuilder = + insert(at, System.Convert.ToString(x)) + + /**

+ * Inserts the string representation of the Int argument + * into this sequence. + *

+ *

+ * The offset argument must be greater than or equal to 0, and less than + * or equal to the length of this sequence. + *

+ * + * @param at the offset position. + * @param x a Int value. + * @return a reference to this object. + */ + def insert(at: Int, x: Int): StringBuilder = + insert(at, System.Convert.ToString(x)) + + /**

+ * Inserts the string representation of the Long argument + * into this sequence. + *

+ *

+ * The offset argument must be greater than or equal to 0, and less than + * or equal to the length of this sequence. + *

+ * + * @param at the offset position. + * @param x a Long value. + * @return a reference to this object. + */ + def insert(at: Int, x: Long): StringBuilder = + insert(at, System.Convert.ToString(x)) + + /**

+ * Inserts the string representation of the Float argument + * into this sequence. + *

+ *

+ * The offset argument must be greater than or equal to 0, and less than + * or equal to the length of this sequence. + *

+ * + * @param at the offset position. + * @param x a Float value. + * @return a reference to this object. + */ + def insert(at: Int, x: Float): StringBuilder = + insert(at, System.Convert.ToString(x)) + + /**

+ * Inserts the string representation of the Double argument + * into this sequence. + *

+ *

+ * The offset argument must be greater than or equal to 0, and less than + * or equal to the length of this sequence. + *

+ * + * @param at the offset position. + * @param x a Double value. + * @return a reference to this object. + */ + def insert(at: Int, x: Double): StringBuilder = + insert(at, System.Convert.ToString(x)) + + /**

+ * Returns the index within this string of the first occurrence of the + * specified substring. The integer returned is the smallest value + * k such that: + *

+ *
+   *  this.toString().startsWith(str, k)
+ *
+ *

+ * is true. + *

+ * + * @param str any string. + * @return if the string argument occurs as a substring within this + * object, then the index of the first character of the first + * such substring is returned; if it does not occur as a + * substring, -1 is returned. + * @throws NullPointerException if str is null. + */ + def indexOf(str: String): Int = indexOf(str, 0) + + /**

+ * Returns the index within this string of the first occurrence of the + * specified substring, starting at the specified index. The integer + * returned is the smallest value k for which: + *

+   *    k >= Math.min(fromIndex, str.length()) &&
+   *                   this.toString().startsWith(str, k)
+ *

+ * If no such value of k exists, then -1 + * is returned. + *

+ * + * @param str the substring for which to search. + * @param fromIndex the index from which to start the search. + * @return the index within this string of the first occurrence + * of the specified substring, starting at the specified index. + */ + def indexOf(str: String, fromIndex: Int): Int = + StringBuilder.indexOf(array, 0, count, str.ToCharArray, 0, str.length(), fromIndex) + + /**

+ * Returns the index within this string of the rightmost occurrence + * of the specified substring. The rightmost empty string "" is + * considered to occur at the index value this.length(). + * The returned index is the largest value k such that + *

+ *
+   *  this.toString().startsWith(str, k)
+ *
+ *

+ * is true. + *

+ * + * @param str the substring to search for. + * @return if the string argument occurs one or more times as a substring + * within this object, then the index of the first character of + * the last such substring is returned. If it does not occur as + * a substring, -1 is returned. + * @throws NullPointerException if str is null. + */ + def lastIndexOf(str: String): Int = lastIndexOf(str, count) + + /**

+ * Returns the index within this string of the last occurrence of the + * specified substring. The integer returned is the largest value + * k such that: + *

val
+   *    k <= Math.min(fromIndex, str.length()) &&
+   *                   this.toString().startsWith(str, k)
+ *

+ * If no such value of k exists, then -1 + * is returned. + *

+ * + * @param str the substring to search for. + * @param fromIndex the index to start the search from. + * @return the index within this sequence of the last occurrence + * of the specified substring. + */ + def lastIndexOf(str: String, fromIndex: Int): Int = + StringBuilder.lastIndexOf(array, 0, count, str.ToCharArray, 0, str.length(), fromIndex) + + /**

+ * Causes this character sequence to be replaced by the reverse of the + * sequence. If there are any surrogate pairs included in the sequence, + * these are treated as single characters for the reverse operation. + * Thus, the order of the high-low surrogates is never reversed. + *

+ *

+ * Let n be the character length of this character sequence + * (not the length in Char values) just prior to + * execution of the reverse method. Then the + * character at index k in the new character sequence is + * equal to the character at index n-k-1 in the old + * character sequence. + *

+ * + * @return a reference to this object. + */ + override def reverse(): StringBuilder = { + var hasSurrogate = false + val n = count - 1 + var j = (n-1) >> 1 + while (j >= 0) { + val temp = array(j) + val temp2 = array(n - j) + if (!hasSurrogate) + hasSurrogate = + (temp >= StringBuilder.MIN_SURROGATE && temp <= StringBuilder.MAX_SURROGATE) || + (temp2 >= StringBuilder.MIN_SURROGATE && temp2 <= StringBuilder.MAX_SURROGATE) + array(j) = temp2 + array(n - j) = temp + j -= 1 + } + if (hasSurrogate) { + // Reverse back all valid surrogate pairs + var i = 0 + while (i < count - 1) { + val c2 = array(i) + if (StringBuilder.isLowSurrogate(c2)) { + val c1 = array(i + 1) + if (StringBuilder.isHighSurrogate(c1)) { + array(i) = c1; i += 1 + array(i) = c2 + } + } + i += 1 + } + } + this + } + + /** Returns a string representing the data in this sequence. + * A new String object is allocated and initialized to + * contain the character sequence currently represented by this + * object. This String is then returned. Subsequent + * changes to this sequence do not affect the contents of the + * String. + * + * @return a string representation of this sequence of characters. + */ + override def toString: String = new String(array, 0, count) + + def result(): String = toString +} + + +object StringBuilder { + + type Array[T] = scala.Array[T] // !!! + + private val MIN_HIGH_SURROGATE = '\uD800' + private val MAX_HIGH_SURROGATE = '\uDBFF' + + private val MIN_LOW_SURROGATE = '\uDC00' + private val MAX_LOW_SURROGATE = '\uDFFF' + + // constants java.langCharacter.MIN-/MAX_SURROGATE exist since 1.5 + private val MIN_SURROGATE = MIN_HIGH_SURROGATE + private val MAX_SURROGATE = MAX_LOW_SURROGATE + + // methods java.langCharacter.isLow-/isHighSurrogate exist since 1.5 + private def isLowSurrogate(ch: Char): Boolean = + MIN_LOW_SURROGATE <= ch && ch <= MAX_LOW_SURROGATE + + private def isHighSurrogate(ch: Char): Boolean = + MIN_HIGH_SURROGATE <= ch && ch <= MAX_HIGH_SURROGATE + + // method java.util.Arrays.copyOf exists since 1.6 + private def copyOf(src: Array[Char], newLength: Int): Array[Char] = { + val dest = new Array[Char](newLength) + compat.Platform.arraycopy(src, 0, dest, 0, Math.min(src.length, newLength)) + dest + } + + private def indexOf(source: Array[Char], sourceOffset: Int, sourceCount: Int, + target: Array[Char], targetOffset: Int, targetCount: Int, + fromIndex: Int): Int = + // todo: There are faster string search algorithms than this! + // we should use at least KMP here. + if (fromIndex >= sourceCount) + if (targetCount == 0) sourceCount else -1 + else { + val inx = if (fromIndex < 0) 0 else fromIndex + if (targetCount == 0) + inx + else { + val first = target(targetOffset) + val max = sourceOffset + (sourceCount - targetCount) + + var i = sourceOffset + inx + while (i <= max) { + /* Look for first character. */ + if (source(i) != first) { + i += 1 + while (i <= max && source(i) != first) i += 1 + } + /* Found first character, now look at the rest of v2 */ + if (i <= max) { + var j = i + 1 + val end = j + targetCount - 1 + var k = targetOffset + 1 + while (j < end && source(j) == target(k)) { + j += 1 + k += 1 + } + if (j == end) { + /* Found whole string. */ + return i - sourceOffset + } + } // if + i += 1 + } // while + -1 + } + } + + private def lastIndexOf(source: Array[Char], sourceOffset: Int, sourceCount: Int, + target: Array[Char], targetOffset: Int, targetCount: Int, + fromIndex: Int): Int = { + val rightIndex = sourceCount - targetCount + if (fromIndex < 0) return -1 + val inx = if (fromIndex > rightIndex) rightIndex else fromIndex + // Empty string always matches + if (targetCount == 0) return inx + + val strLastIndex = targetOffset + targetCount - 1 + val strLastChar = target(strLastIndex) + val min = sourceOffset + targetCount - 1 + var i = min + fromIndex + + while (true) { + while (i >= min && source(i) != strLastChar) i -= 1 + if (i < min) return -1 + var j = i - 1 + val start = j - (targetCount - 1) + var k = strLastIndex - 1 + var outerWhile = false + while (j > start && !outerWhile) { + if (source(j) != target(k)) { + j -= 1 + k -= 1 + i -= 1 + outerWhile = true + } + } + if (!outerWhile) return start - sourceOffset + 1 + } + -1 + } +} diff --git a/src/dotnet-library/scala/collection/mutable/WeakHashMap.scala b/src/dotnet-library/scala/collection/mutable/WeakHashMap.scala new file mode 100644 index 0000000000..dbe2039713 --- /dev/null +++ b/src/dotnet-library/scala/collection/mutable/WeakHashMap.scala @@ -0,0 +1 @@ +/* WeakHashMap does not exist for the dotnet target */ diff --git a/src/dotnet-library/scala/runtime/RichChar.scala b/src/dotnet-library/scala/runtime/RichChar.scala index 75599e3744..5c88cce137 100644 --- a/src/dotnet-library/scala/runtime/RichChar.scala +++ b/src/dotnet-library/scala/runtime/RichChar.scala @@ -11,8 +11,10 @@ package scala.runtime - -import Predef.NoSuchElementException +//import java.lang.Character +import collection.Vector +import collection.generic.VectorView +import Predef.{require, NoSuchElementException} /**

* For example, in the following code @@ -51,24 +53,22 @@ final class RichChar(x: Char) extends Proxy with Ordered[Char] { def toLowerCase: Char = System.Char.ToLower(x) def toUpperCase: Char = System.Char.ToUpper(x) - /** Create a RandomAccessSeq.Projection[Char] over the characters from 'x' to 'y' - 1 + /** Create a [Char] over the characters from 'x' to 'y' - 1 */ - def until(limit: Char): RandomAccessSeq.Projection[Char] = - if (limit <= x) RandomAccessSeq.empty.projection + def until(limit: Char): VectorView[Char, Vector[Char]] = + if (limit <= x) Vector.empty.view else - new RandomAccessSeq.Projection[Char] { + new VectorView[Char, Vector[Char]] { + protected def underlying = Vector.empty[Char] def length = limit - x def apply(i: Int): Char = { - Predef.require(i >= 0 && i < length) + require(i >= 0 && i < length) (x + i).toChar } - override def stringPrefix = "RandomAccessSeq.Projection" - } - - //def until(y: Char): Iterator[Char] = to(y) + } /** Create a RandomAccessSeq.Projection[Char] over the characters from 'x' to 'y' */ - def to(y: Char): RandomAccessSeq.Projection[Char] = until((y + 1).toChar) + def to(y: Char): VectorView[Char, Vector[Char]] = until((y + 1).toChar) } diff --git a/src/dotnet-library/scala/runtime/RichInt.scala b/src/dotnet-library/scala/runtime/RichInt.scala index 5d73aa83e8..3ebfc12a89 100644 --- a/src/dotnet-library/scala/runtime/RichInt.scala +++ b/src/dotnet-library/scala/runtime/RichInt.scala @@ -12,7 +12,7 @@ package scala.runtime -final class RichInt(start: Int) extends Proxy with Ordered[Int] { +final class RichInt(val start: Int) extends Proxy with Ordered[Int] { // Proxy def self: Any = start @@ -27,7 +27,7 @@ final class RichInt(start: Int) extends Proxy with Ordered[Int] { def until(end: Int, step: Int): Range = new Range(start, end, step) /** like until, but includes the last index */ - def to(end: Int) = new Range.Inclusive(start, end, 1) + def to(end: Int) = Range.inclusive(start, end, 1) def min(that: Int): Int = if (start < that) start else that def max(that: Int): Int = if (start > that) start else that diff --git a/src/dotnet-library/scala/runtime/RichString.scala b/src/dotnet-library/scala/runtime/RichString.scala index 1151174b00..9ffdee8017 100644 --- a/src/dotnet-library/scala/runtime/RichString.scala +++ b/src/dotnet-library/scala/runtime/RichString.scala @@ -11,67 +11,40 @@ package scala.runtime -import Predef._ +//import scala.util.matching.Regex +import collection.generic._ +//import collection.mutable.StringBuilder +import collection.immutable.Vector -final class RichString(val self: String) extends Proxy with RandomAccessSeq[Char] with Ordered[String] { - import RichString._ - override def apply(n: Int) = self charAt n - override def length = self.length - override def toString = self - override def mkString = self - - override def slice(from: Int, until: Int): RichString = { - val len = self.length - new RichString( - if (from >= until || from >= len) - "" - else { - val from0 = if (from < 0) 0 else from - val until0 = if (until > len) len else until - self.substring(from0, until0) - } - ) - } +object RichString { - //override def ++ [B >: A](that: Iterable[B]): Seq[B] = { - override def ++[B >: Char](that: Iterable[B]): RandomAccessSeq[B] = that match { - case that: RichString => new RichString(self + that.self) - case that => super.++(that) - } + def newBuilder: Builder[Char, RichString] = new StringBuilder() mapResult (new RichString(_)) + implicit def builderFactory: BuilderFactory[Char, RichString, RichString] = new BuilderFactory[Char, RichString, RichString] { def apply(from: RichString) = newBuilder } + implicit def builderFactory2: BuilderFactory[Char, RichString, String] = new BuilderFactory[Char, RichString, String] { def apply(from: String) = newBuilder } - override def take(until: Int): RichString = slice(0, until) + // just statics for rich string. + private final val LF: Char = 0x0A + private final val FF: Char = 0x0C + private final val CR: Char = 0x0D + private final val SU: Char = 0x1A +} - override def drop(from: Int): RichString = slice(from, self.length) +import RichString._ - override def startsWith[B](that: Seq[B]) = that match { - case that: RichString => self startsWith that.self - case that => super.startsWith(that) - } +class RichString(val self: String) extends Proxy with Vector[Char] with VectorTemplate[Char, RichString] with PartialFunction[Int, Char] with Ordered[String] { - override def endsWith[B](that: Seq[B]) = that match { - case that: RichString => self endsWith that.self - case that => super.endsWith(that) - } + /** Creates a string builder buffer as builder for this class */ + override protected[this] def newBuilder = RichString.newBuilder - override def indexOf[B](that: Seq[B]) = that match { - case that: RichString => self indexOf that.self - case that => super.indexOf(that) - } + /** Return element at index `n` + * @throws IndexOutofBoundsException if the index is not valid + */ + def apply(n: Int): Char = self charAt n - override def containsSlice[B](that: Seq[B]) = that match { - case that: RichString => self contains that.self - case that => super.containsSlice(that) - } + def length: Int = self.length - override def reverse: RichString = { - val buf = new StringBuilder - var i = self.length - 1 - while (i >= 0) { - buf append (self charAt i) - i -= 1 - } - new RichString(buf.toString) - } + override def mkString = self + override def toString = self /** return n times the current string */ @@ -184,9 +157,23 @@ final class RichString(val self: String) extends Proxy with RandomAccessSeq[Char */ def stripMargin: String = stripMargin('|') - def split(separator: Char): Array[String] = self.Split(Array(separator)) +// private def escape(ch: Char): String = "\\Q" + ch + "\\E" + +// @throws(classOf[java.util.regex.PatternSyntaxException]) +// def split(separator: Char): Array[String] = self.split(escape(separator)) - def split(separators: Array[Char]): Array[String] = self.Split(separators) +// @throws(classOf[java.util.regex.PatternSyntaxException]) +// def split(separators: Array[Char]): Array[String] = { +// val re = separators.foldLeft("[")(_+escape(_)) + "]" +// self.split(re) +// } + + /** You can follow a string with `.r', turning + * it into a Regex. E.g. + * + * """A\w*""".r is the regular expression for identifiers starting with `A'. + */ +// def r: Regex = new Regex(self) def toBoolean: Boolean = System.Boolean.Parse(self) def toByte: Byte = System.Byte.Parse(self) @@ -196,8 +183,19 @@ final class RichString(val self: String) extends Proxy with RandomAccessSeq[Char def toFloat: Float = System.Single.Parse(self) def toDouble: Double = System.Double.Parse(self) + private def parseBoolean(s: String): Boolean = + if (s != null) s.toLowerCase match { + case "true" => true + case "false" => false + case _ => throw new NumberFormatException("For input string: \""+s+"\"") + } + else + throw new NumberFormatException("For input string: \"null\"") + def toArray: Array[Char] = { - self.ToCharArray() + val result = new Array[Char](length) + compat.Platform.arraycopy(self.ToCharArray, 0, result, 0, length) + result } /**

@@ -214,24 +212,7 @@ final class RichString(val self: String) extends Proxy with RandomAccessSeq[Char * @param args the arguments used to instantiating the pattern. * @throws java.lang.IllegalArgumentException */ - // def format(args : Any*) : String = - // the toList is necessary right now because Array(1,2,3).toArray[Any] throws a CCE - // Predef.format(self, args.toList.toArray[Any].asInstanceOf[Array[AnyRef]]: _*) +// def format(args : Any*) : String = +// java.lang.String.format(self, args.toArray[Any].asInstanceOf[Array[AnyRef]]: _*) } -object RichString { - // just statics for rich string. - private final val LF: Char = 0x0A - private final val FF: Char = 0x0C - private final val CR: Char = 0x0D - private final val SU: Char = 0x1A - - private def parseBoolean(s: String): Boolean = - if (s != null) s.toLowerCase match { - case "true" => true - case "false" => false - case _ => throw new System.FormatException("For input string: \""+s+"\"") - } - else - throw new System.FormatException("For input string: \"null\"") -} diff --git a/src/dotnet-library/scala/runtime/RichStringBuilder.scala b/src/dotnet-library/scala/runtime/RichStringBuilder.scala deleted file mode 100644 index 67c1c793e6..0000000000 --- a/src/dotnet-library/scala/runtime/RichStringBuilder.scala +++ /dev/null @@ -1 +0,0 @@ -/* RichStringBuilder does not exist for the dotnet target */ diff --git a/src/dotnet-library/scalax/collection/immutable/List.scala b/src/dotnet-library/scalax/collection/immutable/List.scala deleted file mode 100644 index 72af5a0278..0000000000 --- a/src/dotnet-library/scalax/collection/immutable/List.scala +++ /dev/null @@ -1,929 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2009, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -// $Id: List.scala 16287 2008-10-18 13:41:36Z nielsen $ - - -package scalax.collection.immutable - -import mutable.ListBuffer -import generic.{SequenceTemplate, SequenceFactory, EmptyIterableFactory, Builder} -import annotation.unchecked.uncheckedVariance - -/** A class representing an ordered collection of elements of type - * a. This class comes with two implementing case - * classes scala.Nil and scala.:: that - * implement the abstract members isEmpty, - * head and tail. - * - * @author Martin Odersky and others - * @version 2.8 - */ -sealed abstract class List[+A] extends Stream[A] - with SequenceTemplate[List, A @uncheckedVariance] - with Product { - - import collection.{Iterable, OrderedIterable, Sequence, Vector} - - /** Returns true if the list does not contain any elements. - * @return true, iff the list is empty. - */ - def isEmpty: Boolean - - /** Returns this first element of the list. - * - * @return the first element of this list. - * @throws Predef.NoSuchElementException if the list is empty. - */ - def head: A - - /** Returns this list without its first element. - * - * @return this list without its first element. - * @throws Predef.NoSuchElementException if the list is empty. - */ - def tail: List[A] - - /** Creates a list buffer as builder for this class */ - override def newBuilder[B]: Builder[List, B] = new ListBuffer[B] - - // New methods in List - - /**

- * Add an element x at the beginning of this list. - *

- * - * @param x the element to prepend. - * @return the list with x added at the beginning. - * @ex 1 :: List(2, 3) = List(2, 3).::(1) = List(1, 2, 3) - */ - def ::[B >: A] (x: B): List[B] = - new scalax.collection.immutable.::(x, this) - - /**

- * Returns a list resulting from the concatenation of the given - * list prefix and this list. - *

- * - * @param prefix the list to concatenate at the beginning of this list. - * @return the concatenation of the two lists. - * @ex List(1, 2) ::: List(3, 4) = List(3, 4).:::(List(1, 2)) = List(1, 2, 3, 4) - */ - def :::[B >: A](prefix: List[B]): List[B] = - if (isEmpty) prefix - else (new ListBuffer[B] ++ prefix).prependToList(this) - - /** Reverse the given prefix and append the current list to that. - * This function is equivalent to an application of reverse - * on the prefix followed by a call to :::, but is more - * efficient. - * - * @param prefix the prefix to reverse and then prepend - * @return the concatenation of the reversed prefix and the current list. - */ - def reverse_:::[B >: A](prefix: List[B]): List[B] = { - var these: List[B] = this - var pres = prefix - while (!pres.isEmpty) { - these = pres.head :: these - pres = pres.tail - } - these - } - - /** Apply a function to all the elements of the list, and return the - * reversed list of results. This is equivalent to a call to map - * followed by a call to reverse, but more efficient. - * !!! should we deprecate this? Why have reverseMap, but not filterMap, say? - * @param f the function to apply to each elements. - * @return the reversed list of results. - */ - def reverseMap[B](f: A => B): List[B] = { - def loop(l: List[A], res: List[B]): List[B] = l match { - case Nil => res - case head :: tail => loop(tail, f(head) :: res) - } - loop(this, Nil) - } - - /** Like xs map f, but returns xs unchanged if function - * f maps all elements to themselves (wrt eq) - * @note Unlike `map`, `mapConserve` is not tail-recursive - */ - def mapConserve[B >: A] (f: A => B): List[B] = { - def loop(ys: List[A]): List[B] = - if (ys.isEmpty) this - else { - val head0 = ys.head - val head1 = f(head0) - if (head1.asInstanceOf[AnyRef] eq head0.asInstanceOf[AnyRef]) { - loop(ys.tail) - } else { - val ys1 = head1 :: ys.tail.mapConserve(f) - if (this eq ys) ys1 - else { - val b = new ListBuffer[B] - var xc = this - while (xc ne ys) { - b += xc.head - xc = xc.tail - } - b.prependToList(ys1) - } - } - } - loop(this) - } - - // Overridden methods from IterableTemplate or overloaded variants of such methods - - /** Appends two list objects. - */ - override def ++[B >: A](that: Iterable[B]): List[B] = - this ::: that.toList - - /** Overrides the method in Iterable for efficiency. - * - * @return the list itself - */ - override def toList: List[A] = this - - /** Returns the n first elements of this list, or else the whole - * list, if it has less than n elements. - - * @param n the number of elements to take. - * @return the n first elements of this list. - */ - override def take(n: Int): List[A] = { - val b = new ListBuffer[A] - var i = 0 - var these = this - while (!these.isEmpty && i < n) { - i += 1 - b += these.head - these = these.tail - } - if (these.isEmpty) this - else b.toList - } - - /** Returns the list without its n first elements. - * If this list has less than n elements, the empty list is returned. - * - * @param n the number of elements to drop. - * @return the list without its n first elements. - */ - override def drop(n: Int): List[A] = { - var these = this - var count = n - while (!these.isEmpty && count > 0) { - these = these.tail - count -= 1 - } - these - } - - /** Returns the list with elements belonging to the given index range. - * - * @param start the start position of the list slice. - * @param end the end position (exclusive) of the list slice. - * @return the list with elements belonging to the given index range. - */ - override def slice(start: Int, end: Int): List[A] = { - val s = start max 0 - val e = end min this.length - drop(s) take (e - s) - } - - /** Returns the rightmost n elements from this list. - * - * @param n the number of elements to take - * @return the suffix of length n of the list - */ - override def takeRight(n: Int): List[A] = { - def loop(lead: List[A], lag: List[A]): List[A] = lead match { - case Nil => lag - case _ :: tail => loop(tail, lag.tail) - } - loop(drop(n), this) - } - - // dropRight is inherited from Stream - - /** Split the list at a given point and return the two parts thus - * created. - * - * @param n the position at which to split - * @return a pair of lists composed of the first n - * elements, and the other elements. - */ - override def splitAt(n: Int): (List[A], List[A]) = { - val b = new ListBuffer[A] - var i = 0 - var these = this - while (!these.isEmpty && i < n) { - i += 1 - b += these.head - these = these.tail - } - (b.toList, these) - } - - /** Returns the longest prefix of this list whose elements satisfy - * the predicate p. - * - * @param p the test predicate. - * @return the longest prefix of this list whose elements satisfy - * the predicate p. - */ - override def takeWhile(p: A => Boolean): List[A] = { - val b = new ListBuffer[A] - var these = this - while (!these.isEmpty && p(these.head)) { - b += these.head - these = these.tail - } - b.toList - } - - /** Returns the longest suffix of this list whose first element - * does not satisfy the predicate p. - * - * @param p the test predicate. - * @return the longest suffix of the list whose first element - * does not satisfy the predicate p. - */ - override def dropWhile(p: A => Boolean): List[A] = - if (isEmpty || !p(head)) this - else tail dropWhile p - - /** Returns the longest prefix of the list whose elements all satisfy - * the given predicate, and the rest of the list. - * - * @param p the test predicate - * @return a pair consisting of the longest prefix of the list whose - * elements all satisfy p, and the rest of the list. - */ - override def span(p: A => Boolean): (List[A], List[A]) = { - val b = new ListBuffer[A] - var these = this - while (!these.isEmpty && p(these.head)) { - b += these.head - these = these.tail - } - (b.toList, these) - } - - /** Returns the list resulting from applying the given function f to each - * element of this list. - * - * @param f function to apply to each element. - * @return [f(a0), ..., f(an)] if this list is [a0, ..., an]. - */ - final override def map[B](f: A => B): List[B] = { - val b = new ListBuffer[B] - var these = this - while (!these.isEmpty) { - b += f(these.head) - these = these.tail - } - b.toList - } - - /** Returns all the elements of this list that satisfy the - * predicate p. The order of the elements is preserved. - * It is guarenteed that the receiver list itself is returned iff all its - * elements satisfy the predicate `p'. Hence the following equality is valid: - * - * (xs filter p) eq xs == xs forall p - * - * @param p the predicate used to filter the list. - * @return the elements of this list satisfying p. - */ - final override def filter(p: A => Boolean): List[A] = { - // return same list if all elements satisfy p - var these = this - var allTrue = true - val b = new ListBuffer[A] - while (!these.isEmpty) { - if (p(these.head)) b += these.head - else allTrue = false - these = these.tail - } - if (allTrue) this else b.toList - } - - /** Applies the given function f to each element of - * this list, then concatenates the results. - * - * @param f the function to apply on each element. - * @return f(a0) ::: ... ::: f(an) if - * this list is [a0, ..., an]. - */ - final override def flatMap[B](f: A => Iterable[B]): List[B] = { - val b = new ListBuffer[B] - var these = this - while (!these.isEmpty) { - b ++= f(these.head) - these = these.tail - } - b.toList - } - - /** Returns a list formed from this list and the specified list - * that by associating each element of the former with - * the element at the same position in the latter. - * If one of the two lists is longer than the other, its remaining elements are ignored. - * - * !!! todo: perform speed with inherited version from Iterable, and drop - * if not significantly better - * @return List((a0,b0), ..., - * (amin(m,n),bmin(m,n))) when - * List(a0, ..., am) - * zip List(b0, ..., bn) is invoked. - */ - def zip[B](that: List[B]): List[(A, B)] = { - val b = new ListBuffer[(A, B)] - var these = this - var those = that - while (!these.isEmpty && !those.isEmpty) { - b += ((these.head, those.head)) - these = these.tail - those = those.tail - } - b.toList - } - - /** Returns a list formed from this list and the specified list - * that by associating each element of the former with - * the element at the same position in the latter. - * - * @param that list that may have a different length - * as the self list. - * @param thisElem element thisElem is used to fill up the - * resulting list if the self list is shorter than - * that - * @param thatElem element thatElem is used to fill up the - * resulting list if that is shorter than - * the self list - * @return List((a0,b0), ..., - * (an,bn), (elem,bn+1), - * ..., {elem,bm}) - * when [a0, ..., an] zip - * [b0, ..., bm] is - * invoked where m > n. - */ - def zipAll[B, C >: A, D >: B](that: List[B], thisElem: C, thatElem: D): List[(C, D)] = { - val b = new ListBuffer[(C, D)] - var these = this - var those = that - while (!these.isEmpty && !those.isEmpty) { - b += ((these.head, those.head)) - these = these.tail - those = those.tail - } - while (!these.isEmpty) { - b += ((these.head, thatElem)) - these = these.tail - } - while (!those.isEmpty) { - b += ((thisElem, those.head)) - those = those.tail - } - b.toList - } - - override def stringPrefix = "List" - - override def toStream : Stream[A] = this - - /** Computes the difference between this list and the given list - * that. - * - * @param that the list of elements to remove from this list. - * @return this list without the elements of the given list - * that. - * @deprecated use diff instead - */ - @deprecated def -- [B >: A](that: List[B]): List[B] = { - val b = new ListBuffer[B] - var these = this - while (!these.isEmpty) { - if (!that.contains(these.head)) b += these.head - these = these.tail - } - b.toList - } - - /** Computes the difference between this list and the given object - * x. - * - * @param x the object to remove from this list. - * @return this list without the elements of the given object - * x. - * @deprecated use diff instead - */ - @deprecated def - [B >: A](x: B): List[B] = { - val b = new ListBuffer[B] - var these = this - while (!these.isEmpty) { - if (these.head != x) b += these.head - these = these.tail - } - b.toList - } - - /**

- * Sort the list according to the comparison function - * <(e1: a, e2: a) => Boolean, - * which should be true iff e1 is smaller than - * e2. - * !!! todo: move sorting to IterableTemplate - *

- * - * @param lt the comparison function - * @return a list sorted according to the comparison function - * <(e1: a, e2: a) => Boolean. - * @ex
-   *    List("Steve", "Tom", "John", "Bob")
-   *      .sort((e1, e2) => (e1 compareTo e2) < 0) =
-   *    List("Bob", "John", "Steve", "Tom")
- * @deprecated use sortWith instead - */ - @deprecated def sort(lt : (A,A) => Boolean): List[A] = { - /** Merge two already-sorted lists */ - def merge(l1: List[A], l2: List[A]): List[A] = { - val res = new ListBuffer[A] - var left1 = l1 - var left2 = l2 - - while (!left1.isEmpty && !left2.isEmpty) { - if(lt(left1.head, left2.head)) { - res += left1.head - left1 = left1.tail - } else { - res += left2.head - left2 = left2.tail - } - } - - res ++= left1 - res ++= left2 - - res.toList - } - - /** Split a list into two lists of about the same size */ - def split(lst: List[A]) = { - val res1 = new ListBuffer[A] - val res2 = new ListBuffer[A] - var left = lst - - while (!left.isEmpty) { - res1 += left.head - left = left.tail - if (!left.isEmpty) { - res2 += left.head - left = left.tail - } - } - - (res1.toList, res2.toList) - } - - - /** Merge-sort the specified list */ - def ms(lst: List[A]): List[A] = - lst match { - case Nil => lst - case x :: Nil => lst - case x :: y :: Nil => - if (lt(x,y)) - lst - else - y :: x :: Nil - - case lst => - val (l1, l2) = split(lst) - val l1s = ms(l1) - val l2s = ms(l2) - merge(l1s, l2s) - } - - ms(this) - } - -} - -/** The empty list. - * - * @author Martin Odersky - * @version 1.0, 15/07/2003 - */ -@SerialVersionUID(0 - 8256821097970055419L) -case object Nil extends List[Nothing] { - override def isEmpty = true - override def head: Nothing = - throw new NoSuchElementException("head of empty list") - override def tail: List[Nothing] = - throw new NoSuchElementException("tail of empty list") -} - -/** A non empty list characterized by a head and a tail. - * - * @author Martin Odersky - * @version 1.0, 15/07/2003 - */ -@SerialVersionUID(0L - 8476791151983527571L) -final case class ::[B](private var hd: B, private[scalax] var tl: List[B]) extends List[B] { - override def head : B = hd - override def tail : List[B] = tl - override def isEmpty: Boolean = false -} - -/** This object provides methods for creating specialized lists, and for - * transforming special kinds of lists (e.g. lists of lists). - * - * @author Martin Odersky and others - * @version 1.0, 15/07/2003 - */ -object List extends SequenceFactory[List] with EmptyIterableFactory[List] { - - override val empty: List[Nothing] = Nil - - override def apply[A](xs: A*) = xs.asInstanceOf[Iterable[A]].toList // !@! - - override def newBuilder[B]: Builder[List, B] = new ListBuffer[B] - - /** Create a sorted list with element values - * vn+1 = step(vn) - * where v0 = start - * and elements are in the range between start (inclusive) - * and end (exclusive) - * - * @deprecated use @see iterate instead. - * @param start the start value of the list - * @param end the end value of the list - * @param step the increment function of the list, which given vn, - * computes vn+1. Must be monotonically increasing - * or decreasing. - * @return the sorted list of all integers in range [start;end). - */ - @deprecated def range(start: Int, end: Int, step: Int => Int): List[Int] = { - val up = step(start) > start - val down = step(start) < start - val b = new ListBuffer[Int] - var i = start - while ((!up || i < end) && (!down || i > end)) { - b += i - val next = step(i) - if (i == next) - throw new IllegalArgumentException("the step function did not make any progress on "+ i) - i = next - } - b.toList - } - - /** Create a list containing several copies of an element. - * @deprecated use @see fill instead - * - * @param n the length of the resulting list - * @param elem the element composing the resulting list - * @return a list composed of n elements all equal to elem - */ - @deprecated def make[A](n: Int, elem: A): List[A] = { - val b = new ListBuffer[A] - var i = 0 - while (i < n) { - b += elem - i += 1 - } - b.toList - } - - /** Concatenate all the elements of a given list of lists. - * - * @deprecated use `xss.flatten` instead - * @param xss the list of lists that are to be concatenated - * @return the concatenation of all the lists - */ - @deprecated def flatten[A](xss: List[List[A]]): List[A] = { - val b = new ListBuffer[A] - for (xs <- xss) { - var xc = xs - while (!xc.isEmpty) { - b += xc.head - xc = xc.tail - } - } - b.toList - } - - /** Transforms a list of pairs into a pair of lists. - * - * @param xs the list of pairs to unzip - * @return a pair of lists. - * @deprecated use `xs.unzp` instead - */ - @deprecated def unzip[A,B](xs: List[(A,B)]): (List[A], List[B]) = { - val b1 = new ListBuffer[A] - val b2 = new ListBuffer[B] - var xc = xs - while (!xc.isEmpty) { - b1 += xc.head._1 - b2 += xc.head._2 - xc = xc.tail - } - (b1.toList, b2.toList) - } - - /** Transforms an iterable of pairs into a pair of lists. - * - * @deprecated use `xs.unzip` instead - * @param xs the iterable of pairs to unzip - * @return a pair of lists. - */ - @deprecated def unzip[A,B](xs: Iterable[(A,B)]): (List[A], List[B]) = - xs.foldRight[(List[A], List[B])]((Nil, Nil)) { - case ((x, y), (xs, ys)) => (x :: xs, y :: ys) - } - - /** - * Returns the Left values in the given Iterable of Eithers. - * @deprecated use `Either.lefts` instead - */ - @deprecated def lefts[A, B](es: Iterable[Either[A, B]]) = - es.foldRight[List[A]](Nil)((e, as) => e match { - case Left(a) => a :: as - case Right(_) => as - }) - - /** - * Returns the Right values in the givenIterable of Eithers. - * @deprecated use `Either.rights` instead - */ - @deprecated def rights[A, B](es: Iterable[Either[A, B]]) = - es.foldRight[List[B]](Nil)((e, bs) => e match { - case Left(_) => bs - case Right(b) => b :: bs - }) - - /** Transforms an Iterable of Eithers into a pair of lists. - * - * @param xs the iterable of Eithers to separate - * @return a pair of lists. - * @deprecated use `Either.separate` instead - */ - @deprecated def separate[A,B](es: Iterable[Either[A,B]]): (List[A], List[B]) = - es.foldRight[(List[A], List[B])]((Nil, Nil)) { - case (Left(a), (lefts, rights)) => (a :: lefts, rights) - case (Right(b), (lefts, rights)) => (lefts, b :: rights) - } - - /** Converts an iterator to a list. - * - * @param it the iterator to convert - * @return a list that contains the elements returned by successive - * calls to it.next - * @deprecated use it.toList instead - */ - @deprecated def fromIterator[A](it: Iterator[A]): List[A] = it.toList - - /** Converts an array into a list. - * - * @param arr the array to convert - * @return a list that contains the same elements than arr - * in the same order - * @deprecated use `array.toList` instead - */ - @deprecated def fromArray[A](arr: Array[A]): List[A] = fromArray(arr, 0, arr.length) - - /** Converts a range of an array into a list. - * - * @param arr the array to convert - * @param start the first index to consider - * @param len the lenght of the range to convert - * @return a list that contains the same elements than arr - * in the same order - * @deprecated use `array.view(start, end).toList` instead - */ - @deprecated def fromArray[A](arr: Array[A], start: Int, len: Int): List[A] = { - var res: List[A] = Nil - var i = start + len - while (i > start) { - i -= 1 - res = arr(i) :: res - } - res - } - - /** Parses a string which contains substrings separated by a - * separator character and returns a list of all substrings. - * - * @param str the string to parse - * @param separator the separator character - * @return the list of substrings - * @deprecated use `str.split(separator).toList` instead - */ - @deprecated def fromString(str: String, separator: Char): List[String] = { - var words: List[String] = Nil - var pos = str.length() - while (pos > 0) { - val pos1 = str.lastIndexOf(separator, pos - 1) - if (pos1 + 1 < pos) - words = str.substring(pos1 + 1, pos) :: words - pos = pos1 - } - words - } - - /** Returns the given string as a list of characters. - * - * @param str the string to convert. - * @return the string as a list of characters. - * @deprecated use str.toList instead - */ - @deprecated def fromString(str: String): List[Char] = - str.toList.asInstanceOf[List[Char]] // !@! - - /** Returns the given list of characters as a string. - * - * @param xs the list to convert. - * @return the list in form of a string. - * @deprecated use xs.mkString instead - */ - @deprecated def toString(xs: List[Char]): String = { - val sb = new StringBuilder() - var xc = xs - while (!xc.isEmpty) { - sb.append(xc.head) - xc = xc.tail - } - sb.toString() - } - - /** Like xs map f, but returns xs unchanged if function - * f maps all elements to themselves. - * @deprecated use xs.mapConserve(f) - */ - @deprecated def mapConserve[A <: AnyRef](xs: List[A])(f: A => A): List[A] = { - def loop(ys: List[A]): List[A] = - if (ys.isEmpty) xs - else { - val head0 = ys.head - val head1 = f(head0) - if (head1 eq head0) { - loop(ys.tail) - } else { - val ys1 = head1 :: mapConserve(ys.tail)(f) - if (xs eq ys) ys1 - else { - val b = new ListBuffer[A] - var xc = xs - while (xc ne ys) { - b += xc.head - xc = xc.tail - } - b.prependToList(ys1) - } - } - } - loop(xs) - } - - /** Returns the list resulting from applying the given function f - * to corresponding elements of the argument lists. - * @deprecated use (xs, ys).map(f) instead - * @param f function to apply to each pair of elements. - * @return [f(a0,b0), ..., f(an,bn)] if the lists are - * [a0, ..., ak], [b0, ..., bl] and - * n = min(k,l) - */ - @deprecated def map2[A,B,C](xs: List[A], ys: List[B])(f: (A, B) => C): List[C] = { - val b = new ListBuffer[C] - var xc = xs - var yc = ys - while (!xc.isEmpty && !yc.isEmpty) { - b += f(xc.head, yc.head) - xc = xc.tail - yc = yc.tail - } - b.toList - } - - /** Returns the list resulting from applying the given function - * f to corresponding elements of the argument lists. - * - * @param f function to apply to each pair of elements. - * @deprecated use (xs, ys, zs).map(f) instead - * @return [f(a0,b0,c0), - * ..., f(an,bn,cn)] - * if the lists are [a0, ..., ak], - * [b0, ..., bl], - * [c0, ..., cm] and - * n = min(k,l,m) - */ - @deprecated def map3[A,B,C,D](xs: List[A], ys: List[B], zs: List[C])(f: (A, B, C) => D): List[D] = { - val b = new ListBuffer[D] - var xc = xs - var yc = ys - var zc = zs - while (!xc.isEmpty && !yc.isEmpty && !zc.isEmpty) { - b += f(xc.head, yc.head, zc.head) - xc = xc.tail - yc = yc.tail - zc = zc.tail - } - b.toList - } - - /** Tests whether the given predicate p holds - * for all corresponding elements of the argument lists. - * - * @param p function to apply to each pair of elements. - * @return (p(a0,b0) && - * ... && p(an,bn))] - * if the lists are [a0, ..., ak]; - * [b0, ..., bl] - * and n = min(k,l) - * @deprecated use (xs, ys).forall(f) instead - */ - @deprecated def forall2[A,B](xs: List[A], ys: List[B])(f: (A, B) => Boolean): Boolean = { - var xc = xs - var yc = ys - while (!xc.isEmpty && !yc.isEmpty) { - if (!f(xc.head, yc.head)) return false - xc = xc.tail - yc = yc.tail - } - true - } - - /** Tests whether the given predicate p holds - * for some corresponding elements of the argument lists. - * - * @param p function to apply to each pair of elements. - * @return n != 0 && (p(a0,b0) || - * ... || p(an,bn))] if the lists are - * [a0, ..., ak], - * [b0, ..., bl] and - * n = min(k,l) - * @deprecated use (xs, ys).forall(f) instead - */ - @deprecated def exists2[A,B](xs: List[A], ys: List[B])(f: (A, B) => Boolean): Boolean = { - var xc = xs - var yc = ys - while (!xc.isEmpty && !yc.isEmpty) { - if (f(xc.head, yc.head)) return true - xc = xc.tail - yc = yc.tail - } - false - } - - /** Transposes a list of lists. - * pre: All element lists have the same length. - * - * @param xss the list of lists - * @return the transposed list of lists - * @deprecated use xss.transpose instead - */ - @deprecated def transpose[A](xss: List[List[A]]): List[List[A]] = { - val buf = new ListBuffer[List[A]] - var yss = xss - while (!yss.head.isEmpty) { - buf += (yss map (_.head)) - yss = (yss map (_.tail)) - } - buf.toList - } - - /** Lists with ordered elements are ordered - implicit def list2ordered[a <% Ordered[a]](x: List[a]): Ordered[List[a]] = new Ordered[List[a]] { - def compare [b >: List[a] <% Ordered[b]](y: b): Int = y match { - case y1: List[a] => compareLists(x, y1); - case _ => -(y compare x) - } - private def compareLists(xs: List[a], ys: List[a]): Int = { - if (xs.isEmpty && ys.isEmpty) 0 - else if (xs.isEmpty) -1 - else if (ys.isEmpty) 1 - else { - val s = xs.head compare ys.head; - if (s != 0) s - else compareLists(xs.tail, ys.tail) - } - } - } - */ -} - -/** Only used for list serialization */ -@SerialVersionUID(0L - 8476791151975527571L) -private[scalax] case object ListSerializeEnd - -- cgit v1.2.3