summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sources/scala/collection/Map.scala76
-rw-r--r--sources/scala/collection/Set.scala67
-rw-r--r--sources/scala/collection/immutable/ListMap.scala31
-rw-r--r--sources/scala/collection/immutable/ListSet.scala34
-rw-r--r--sources/scala/collection/immutable/Map.scala62
-rw-r--r--sources/scala/collection/immutable/Set.scala46
-rw-r--r--sources/scala/collection/mutable/Buffer.scala82
-rw-r--r--sources/scala/collection/mutable/DefaultMapModel.scala46
-rw-r--r--sources/scala/collection/mutable/DoubleLinkedList.scala41
-rw-r--r--sources/scala/collection/mutable/HashMap.scala24
-rw-r--r--sources/scala/collection/mutable/HashSet.scala36
-rw-r--r--sources/scala/collection/mutable/HashTable.scala130
-rw-r--r--sources/scala/collection/mutable/History.scala36
-rw-r--r--sources/scala/collection/mutable/Inclusion.scala13
-rw-r--r--sources/scala/collection/mutable/LinkedList.scala15
-rw-r--r--sources/scala/collection/mutable/List.scala61
-rw-r--r--sources/scala/collection/mutable/Map.scala58
-rw-r--r--sources/scala/collection/mutable/Modification.scala13
-rw-r--r--sources/scala/collection/mutable/MultiMap.scala34
-rw-r--r--sources/scala/collection/mutable/ObservableMap.scala40
-rw-r--r--sources/scala/collection/mutable/ObservableSet.scala35
-rw-r--r--sources/scala/collection/mutable/ObservableUpdate.scala13
-rw-r--r--sources/scala/collection/mutable/Publisher.scala37
-rw-r--r--sources/scala/collection/mutable/Queue.scala32
-rw-r--r--sources/scala/collection/mutable/Removal.scala13
-rw-r--r--sources/scala/collection/mutable/Reset.scala13
-rw-r--r--sources/scala/collection/mutable/RevertableHistory.scala25
-rw-r--r--sources/scala/collection/mutable/Set.scala39
-rw-r--r--sources/scala/collection/mutable/SingleLinkedList.scala58
-rw-r--r--sources/scala/collection/mutable/Stack.scala30
-rw-r--r--sources/scala/collection/mutable/Subscriber.scala18
-rw-r--r--sources/scala/collection/mutable/SynchronizedMap.scala86
-rw-r--r--sources/scala/collection/mutable/SynchronizedSet.scala78
-rw-r--r--sources/scala/collection/mutable/Undo.scala15
-rw-r--r--sources/scala/testing/UnitTest.scala61
35 files changed, 1498 insertions, 0 deletions
diff --git a/sources/scala/collection/Map.scala b/sources/scala/collection/Map.scala
new file mode 100644
index 0000000000..049f4a6998
--- /dev/null
+++ b/sources/scala/collection/Map.scala
@@ -0,0 +1,76 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+** $Id$
+\* */
+
+package scala;
+
+/** I promise, there will be some documentation soon! :-) Matthias
+ */
+trait Map[A, +B] with PartialFunction[A, B]
+ with Iterable[Pair[A, B]] {
+
+ def size: Int;
+
+ def get(key: A): Option[B];
+
+ def isEmpty: Boolean = (size == 0);
+
+ def apply(key: A): B = get(key) match {
+ case None => error("key not found")
+ case Some(value) => value
+ }
+
+ def contains(key: A): Boolean = get(key) match {
+ case None => false
+ case Some(_) => true
+ }
+
+ def isDefinedAt(key: A) = contains(key);
+
+ def keys: Iterator[A] = new Iterator[A] {
+ val iter = elements;
+ def hasNext = iter.hasNext;
+ def next = iter.next._1;
+ }
+
+ def values: Iterator[B] = new Iterator[B] {
+ val iter = elements;
+ def hasNext = iter.hasNext;
+ def next = iter.next._2;
+ }
+
+ def foreach(f: (A, B) => Unit) = {
+ val iter = elements;
+ while (iter.hasNext) {
+ val Pair(key, value) = iter.next;
+ f(key, value);
+ }
+ }
+
+ def toList: List[Pair[A, B]] = {
+ var res: List[Pair[A, B]] = Nil;
+ val iter = elements;
+ while (iter.hasNext) {
+ res = iter.next :: res;
+ }
+ res;
+ }
+
+ override def toString() =
+ if (size == 0)
+ "{}"
+ else
+ "{" + {
+ val iter = elements;
+ var res = iter.next.toString();
+ while (iter.hasNext) {
+ res = res + ", " + iter.next;
+ }
+ res;
+ } + "}";
+}
diff --git a/sources/scala/collection/Set.scala b/sources/scala/collection/Set.scala
new file mode 100644
index 0000000000..3f9912d984
--- /dev/null
+++ b/sources/scala/collection/Set.scala
@@ -0,0 +1,67 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+** $Id$
+\* */
+
+package scala;
+
+
+trait Set[A] with Iterable[A] {
+
+ def size: Int;
+
+ def isEmpty: Boolean = (size == 0);
+
+ def contains(elem: A): Boolean;
+
+ def subsetOf(that: Set[A]): Boolean = {
+ val iter = elements;
+ var res = true;
+ while (res && iter.hasNext) {
+ res = that.contains(iter.next);
+ }
+ res
+ }
+
+ def foreach(f: A => Unit): Unit = {
+ val iter = elements;
+ while (iter.hasNext) {
+ f(iter.next);
+ }
+ }
+
+ def exists(p: A => Boolean): Boolean = {
+ val iter = elements;
+ var res = false;
+ while (!res && iter.hasNext) {
+ if (p(iter.next)) { res = true; }
+ }
+ res;
+ }
+
+ def toList: List[A] = {
+ var res: List[A] = Nil;
+ val iter = elements;
+ while (iter.hasNext) {
+ res = iter.next :: res;
+ }
+ res;
+ }
+
+ override def toString() =
+ if (size == 0)
+ "{}"
+ else
+ "{" + {
+ val iter = elements;
+ var res = iter.next.toString();
+ while (iter.hasNext) {
+ res = res + ", " + iter.next;
+ }
+ res;
+ } + "}";
+}
diff --git a/sources/scala/collection/immutable/ListMap.scala b/sources/scala/collection/immutable/ListMap.scala
new file mode 100644
index 0000000000..814e42799f
--- /dev/null
+++ b/sources/scala/collection/immutable/ListMap.scala
@@ -0,0 +1,31 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+
+package scala;
+
+
+class ListMap[A, B] extends MutableMap[A, B] with DefaultMapModel[A, B] {
+
+ var xs: List[Entry] = Nil;
+
+ def size: Int = xs.length;
+
+ override def clear: Unit = { xs = Nil; }
+
+ protected def findEntry(key: A) = xs find {e => e.key == key};
+
+ protected def addEntry(e: Entry) = { xs = e :: xs; }
+
+ def remove(key: A) = { xs = xs filter {e => e.key != key}; }
+
+ protected def entries = xs.elements;
+
+}
diff --git a/sources/scala/collection/immutable/ListSet.scala b/sources/scala/collection/immutable/ListSet.scala
new file mode 100644
index 0000000000..970308db2c
--- /dev/null
+++ b/sources/scala/collection/immutable/ListSet.scala
@@ -0,0 +1,34 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+
+package scala;
+
+/** I promise, there will be some documentation soon! :-) Matthias
+ */
+class ListSet[A] extends MutableSet[A] {
+
+ protected var elems: List[A] = Nil;
+
+ def size: Int = elems.length;
+
+ def contains(elem: A): Boolean = elems.contains(elem);
+
+ def add(elem: A): Unit = if (!elems.contains(elem)) elems = elem :: elems;
+
+ def remove(elem: A): Unit = { elems = elems.filter(e => e != elem); }
+
+ def clear: Unit = { elems = Nil; }
+
+ def elements: Iterator[A] = elems.elements;
+
+ override def toList: List[A] = elems;
+
+}
diff --git a/sources/scala/collection/immutable/Map.scala b/sources/scala/collection/immutable/Map.scala
new file mode 100644
index 0000000000..7182d18e78
--- /dev/null
+++ b/sources/scala/collection/immutable/Map.scala
@@ -0,0 +1,62 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+** $Id$
+\* */
+
+package scala;
+
+trait ImmutableMap[A, B, This <: ImmutableMap[A, B, This]]: This with Map[A, B] {
+
+ def update(key: A, value: B): This;
+
+ def remove(key: A): This;
+
+ def clear: This;
+
+ def put(mappings: Pair[A, B]*): This = putMap(mappings);
+
+ def putMap(map: Iterable[Pair[A, B]]): This = {
+ val iter = map.elements;
+ var res = this;
+ while (iter.hasNext) {
+ val Pair(key, value) = iter.next;
+ res = res.update(key, value);
+ }
+ res;
+ }
+
+ def map(f: (A, B) => B): This = {
+ var res = this;
+ elements foreach {
+ case Pair(key, value) => res = res.update(key, f(key, value));
+ }
+ res;
+ }
+
+ def filter(p: (A, B) => Boolean): This = {
+ var res = this;
+ toList foreach {
+ case Pair(key, value) => if (p(key, value)) { res = res.remove(key); }
+ }
+ res;
+ }
+
+ override def toString() =
+ if (size == 0)
+ "{}"
+ else
+ "{" + {
+ val iter = elements;
+ var res = mappingToString(iter.next);
+ while (iter.hasNext) {
+ res = res + ", " + mappingToString(iter.next);
+ }
+ res;
+ } + "}";
+
+ def mappingToString(p: Pair[A, B]) = p._1.toString() + " -> " + p._2;
+}
diff --git a/sources/scala/collection/immutable/Set.scala b/sources/scala/collection/immutable/Set.scala
new file mode 100644
index 0000000000..7e59d8dbaf
--- /dev/null
+++ b/sources/scala/collection/immutable/Set.scala
@@ -0,0 +1,46 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+** $Id$
+\* */
+
+package scala;
+
+
+trait ImmutableSet[A, This <: ImmutableSet[A, This]]: This with Set[A] {
+
+ def add(elem: A): This;
+
+ def addAll(elems: A*): This = addSet(elems);
+
+ def addSet(that: Iterable[A]): This = {
+ var res = this;
+ that.elements.foreach(elem => res = res.add(elem));
+ res;
+ }
+
+ def remove(elem: A): This;
+
+ def removeAll(elems: A*): This = removeSet(elems);
+
+ def removeSet(that: Iterable[A]): This = {
+ var res = this;
+ that.elements.foreach(elem => res = res.remove(elem));
+ res;
+ }
+
+ def intersect(that: Set[A]): This = filter(that.contains);
+
+ def clear: This;
+
+ def filter(p: A => Boolean): This = {
+ var res = this;
+ toList foreach {
+ elem => if (p(elem)) { res = res.remove(elem); }
+ }
+ res;
+ }
+}
diff --git a/sources/scala/collection/mutable/Buffer.scala b/sources/scala/collection/mutable/Buffer.scala
new file mode 100644
index 0000000000..62efe1b7c4
--- /dev/null
+++ b/sources/scala/collection/mutable/Buffer.scala
@@ -0,0 +1,82 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+** $Id$
+\* */
+
+package scala;
+
+
+class Buffer[A] with MutableList[A] {
+
+ def prepend(elem: A) = prependElem(elem);
+
+ def append(elems: A*) = (this += elems);
+
+ def +=(elem: A) = appendElem(elem);
+
+ def +=(iter: Iterable[A]) = iter.elements.foreach(e => appendElem(e));
+
+ def update(n: Int, newelem: A): Unit = {
+ var elem = first;
+ var i = n;
+ while (i > 0) {
+ elem = elem.next;
+ if (elem == null)
+ error("cannot update element " + n + " in Buffer");
+ i = i - 1;
+ }
+ elem.elem = newelem;
+ }
+
+ def insert(n: Int, newelem: A): Unit = {
+ if (n == 0)
+ prepend(newelem);
+ else if (n >= len)
+ append(newelem);
+ else {
+ var elem = first;
+ var i = n;
+ while (i > 1) {
+ elem = elem.next;
+ if (elem == null)
+ error("cannot insert element " + n + " in Buffer");
+ i = i - 1;
+ }
+ val old = elem.next;
+ elem.next = new LinkedList[A];
+ elem.next.elem = newelem;
+ elem.next.next = old;
+ }
+ }
+
+ def remove(n: Int): A = {
+ val old = apply(n);
+ if (n >= len)
+ error("cannot remove element " + n + " in Buffer");
+ if ((n == 0) && (len == 1)) {
+ first = null;
+ last = null;
+ } else if (n == 0) {
+ first = first.next;
+ } else {
+ var elem = first;
+ var i = n;
+ while (i > 1) {
+ elem = elem.next;
+ i = i - 1;
+ }
+ elem.next = elem.next.next;
+ if (n == (len - 1)) {
+ last = elem.next;
+ }
+ }
+ len = len - 1;
+ old;
+ }
+
+ def clear: Unit = reset;
+}
diff --git a/sources/scala/collection/mutable/DefaultMapModel.scala b/sources/scala/collection/mutable/DefaultMapModel.scala
new file mode 100644
index 0000000000..2e272dc59b
--- /dev/null
+++ b/sources/scala/collection/mutable/DefaultMapModel.scala
@@ -0,0 +1,46 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+
+package scala;
+
+
+trait DefaultMapModel[A, B] extends MutableMap[A, B] {
+
+ protected def findEntry(key: A): Option[Entry];
+
+ protected def addEntry(e: Entry): Unit;
+
+ protected def entries: Iterator[Entry];
+
+ def get(key: A) = findEntry(key) match {
+ case None => None
+ case Some(e) => Some(e.value);
+ }
+
+ def update(key: A, value: B) = findEntry(key) match {
+ case None => addEntry(new Entry(key, value));
+ case Some(e) => e.value = value;
+ }
+
+ def elements = new Iterator[Pair[A, B]] {
+ val iter = entries;
+ def hasNext = iter.hasNext;
+ def next = iter.next.toPair;
+ }
+
+ protected class Entry(k: A, v: B) {
+ def key = k;
+ var value = v;
+ def toPair = Pair(k, value);
+ override def toString() = k.toString() + " -> " + value;
+ }
+
+}
diff --git a/sources/scala/collection/mutable/DoubleLinkedList.scala b/sources/scala/collection/mutable/DoubleLinkedList.scala
new file mode 100644
index 0000000000..800db9d158
--- /dev/null
+++ b/sources/scala/collection/mutable/DoubleLinkedList.scala
@@ -0,0 +1,41 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+** $Id$
+\* */
+
+package scala;
+
+
+abstract class DoubleLinkedList[A, This <: DoubleLinkedList[A, This]]: This
+ extends SingleLinkedList[A, This] {
+
+ var prev: This = _;
+
+ override def append(that: This): Unit =
+ if (that == null)
+ ()
+ else if (next == null) {
+ next = that;
+ that.prev = this;
+ } else
+ next.append(that);
+
+ override def insert(that: This): Unit = if (that != null) {
+ that.append(next);
+ next = that;
+ that.prev = this;
+ }
+
+ def remove: Unit = {
+ if (next != null)
+ next.prev = prev;
+ if (prev != null)
+ prev.next = next;
+ prev = null;
+ next = null;
+ }
+}
diff --git a/sources/scala/collection/mutable/HashMap.scala b/sources/scala/collection/mutable/HashMap.scala
new file mode 100644
index 0000000000..fd5ba85580
--- /dev/null
+++ b/sources/scala/collection/mutable/HashMap.scala
@@ -0,0 +1,24 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+** $Id$
+\* */
+
+package scala;
+
+/** I promise, there will be some documentation soon! :-) Matthias
+ */
+class HashMap[A, B] extends MutableMap[A, B]
+ with HashTable[A]
+ with DefaultMapModel[A, B] {
+
+ protected def entryKey(e: Entry) = e.key;
+
+ override def clear = {
+ initTable(table.length - 1);
+ tableSize = 0;
+ }
+}
diff --git a/sources/scala/collection/mutable/HashSet.scala b/sources/scala/collection/mutable/HashSet.scala
new file mode 100644
index 0000000000..55d01dc54a
--- /dev/null
+++ b/sources/scala/collection/mutable/HashSet.scala
@@ -0,0 +1,36 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+** $Id$
+\* */
+
+package scala;
+
+/** I promise, there will be some documentation soon! :-) Matthias
+ */
+class HashSet[A] extends MutableSet[A] with HashTable[A] {
+
+ def contains(elem: A): Boolean = findEntry(elem) match {
+ case None => false
+ case Some(_) => true
+ }
+
+ def add(elem: A): Unit = findEntry(elem) match {
+ case None => addEntry(elem);
+ case Some(_) =>
+ }
+
+ def elements = entries;
+
+ override def clear = {
+ initTable(table.length - 1);
+ tableSize = 0;
+ }
+
+ protected type Entry = A;
+
+ protected def entryKey(e: Entry) = e;
+}
diff --git a/sources/scala/collection/mutable/HashTable.scala b/sources/scala/collection/mutable/HashTable.scala
new file mode 100644
index 0000000000..caae9f2f98
--- /dev/null
+++ b/sources/scala/collection/mutable/HashTable.scala
@@ -0,0 +1,130 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+** $Id$
+\* */
+
+package scala;
+
+/** I promise, there will be some documentation soon! :-) Matthias
+ */
+abstract class HashTable[A] {
+
+ /** The load factor for the hash table.
+ */
+ protected val loadFactor: Float = 0.75f;
+
+ /** The initial size of the hash table.
+ */
+ protected val initialSize: Int = 16;
+
+ /** The initial threshold
+ */
+ protected val initialThreshold: Int = ((initialSize as Float) * loadFactor) as Int;
+
+ /** The actual hash table.
+ */
+ protected var table: Array[List[Entry]] = new Array(initialSize);
+ initTable(initialSize - 1);
+
+ /** The number of mappings contained in this hash table.
+ */
+ protected var tableSize: Int = 0;
+
+ /** The next size value at which to resize (capacity * load factor).
+ */
+ protected var threshold: Int = initialThreshold;
+
+ /** Returns the size of this hash map.
+ */
+ def size = tableSize;
+
+ protected def findEntry(key: A): Option[Entry] =
+ table(index(elemHashCode(key))).find(entryFor(key));
+
+ protected def addEntry(e: Entry): Unit = {
+ val h = index(elemHashCode(entryKey(e)));
+ table(h) = e :: table(h);
+ tableSize = tableSize + 1;
+ if (tableSize > threshold)
+ resize(2 * table.length);
+ }
+
+ def remove(key: A): Unit = {
+ val old = findEntry(key);
+ old match {
+ case None =>
+ case Some(e) => {
+ val idx = index(elemHashCode(key));
+ table(idx) = table(idx).filter(e => !elemEquals(entryKey(e), key));
+ tableSize = tableSize - 1;
+ }
+ }
+ }
+
+ protected type Entry;
+
+ protected def entryKey(e: Entry): A;
+
+ protected def entries: Iterator[Entry] = new Iterator[Entry] {
+ val iterTable = table;
+ var idx = table.length - 1;
+ var xs = iterTable(idx);
+ scan();
+ def hasNext = !xs.isEmpty;
+ def next = {
+ val res = xs.head;
+ xs = xs.tail;
+ scan();
+ res;
+ }
+ def scan(): Unit = if (xs.isEmpty && (idx > 0)) {
+ idx = idx - 1;
+ xs = iterTable(idx);
+ scan();
+ }
+ }
+
+ private def entryFor(key: A) = (e: Entry => elemEquals(entryKey(e), key));
+
+ protected def initTable(n: Int): Unit = {
+ table(n) = Nil;
+ if (n > 0) initTable(n - 1);
+ }
+
+ private def resize(newSize: Int) = {
+ val newTable: Array[List[Entry]] = new Array(newSize);
+ initTable(newSize - 1);
+ def rehash(i: Int) = {
+ if (i >= 0)
+ rehashList(table(i));
+ }
+ def rehashList(xs: List[Entry]): Unit = xs.match {
+ case Nil => ()
+ case e :: es => {
+ val idx = improve(elemHashCode(entryKey(e))) & (newSize - 1);
+ newTable(idx) = e :: newTable(idx);
+ rehashList(es);
+ }
+ }
+ rehash(table.length - 1);
+ table = newTable;
+ threshold = ((newSize as Float) * loadFactor) as Int;
+ }
+
+ protected def elemEquals(key1: A, key2: A): Boolean = (key1 == key2);
+
+ protected def elemHashCode(key: A) = key.hashCode();
+
+ protected final def improve(hcode: Int) = {
+ var h: Int = hcode + ~(hcode << 9);
+ h = h ^ (h >>> 14);
+ h = h + (h << 4);
+ h ^ (h >>> 10);
+ }
+
+ protected final def index(hcode: Int) = improve(hcode) & (table.length - 1);
+}
diff --git a/sources/scala/collection/mutable/History.scala b/sources/scala/collection/mutable/History.scala
new file mode 100644
index 0000000000..115fb850dc
--- /dev/null
+++ b/sources/scala/collection/mutable/History.scala
@@ -0,0 +1,36 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+** $Id$
+\* */
+
+package scala;
+
+
+/** <tt>History[A, B]</tt> objects may subscribe to events of
+ * type <tt>A</tt> published by an object of type <tt>B</tt>.
+ * The history subscriber object records all published events
+ * up to maximum number of <tt>maxHistory</tt> events.
+ */
+class History[A, B] with Subscriber[A, B] {
+
+ protected val log: Queue[Pair[B, A]] = new Queue[Pair[B, A]];
+
+ val maxHistory: Int = 32000;
+
+ def update(pub: B, event: A): Unit = {
+ if (log.length >= maxHistory) {
+ val old = log.dequeue;
+ }
+ log.enqueue(Pair(pub, event));
+ }
+
+ def getHistory: Iterator[Pair[B, A]] = log.toList.elements;
+
+ def historySize: Int = log.length;
+
+ def clear: Unit = log.clear;
+}
diff --git a/sources/scala/collection/mutable/Inclusion.scala b/sources/scala/collection/mutable/Inclusion.scala
new file mode 100644
index 0000000000..52ee525d08
--- /dev/null
+++ b/sources/scala/collection/mutable/Inclusion.scala
@@ -0,0 +1,13 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+** $Id$
+\* */
+
+package scala;
+
+
+case class Inclusion[A](elem: A) extends ObservableUpdate[A];
diff --git a/sources/scala/collection/mutable/LinkedList.scala b/sources/scala/collection/mutable/LinkedList.scala
new file mode 100644
index 0000000000..380acdb1be
--- /dev/null
+++ b/sources/scala/collection/mutable/LinkedList.scala
@@ -0,0 +1,15 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+** $Id$
+\* */
+
+package scala;
+
+class LinkedList[A](head: A, tail: LinkedList[A]) extends SingleLinkedList[A, LinkedList[A]] {
+ elem = head;
+ next = tail;
+}
diff --git a/sources/scala/collection/mutable/List.scala b/sources/scala/collection/mutable/List.scala
new file mode 100644
index 0000000000..d15b6c3739
--- /dev/null
+++ b/sources/scala/collection/mutable/List.scala
@@ -0,0 +1,61 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+** $Id$
+\* */
+
+package scala;
+
+
+class MutableList[A] with Seq[A] with PartialFunction[Int, A] {
+
+ protected var first: LinkedList[A] = null;
+ protected var last: LinkedList[A] = null;
+ protected var len: Int = 0;
+
+ def length: Int = len;
+
+ def isDefinedAt(n: Int) = (n >= 0) && (n < len);
+
+ def apply(n: Int): A = get(n) match {
+ case None => error("element not found")
+ case Some(value) => value
+ }
+
+ def get(n: Int): Option[A] = first.get(n);
+
+ def at(n: Int): A = apply(n);
+
+ protected def prependElem(elem: A): Unit = {
+ first = new LinkedList[A](elem, first);
+ if (len == 0)
+ last = first;
+ len = len + 1;
+ }
+
+ protected def appendElem(elem: A): Unit = {
+ if (len == 0)
+ prependElem(elem);
+ else {
+ last.next = new LinkedList[A](elem, null);
+ last = last.next;
+ len = len + 1;
+ }
+ }
+
+ protected def reset: Unit = {
+ first = null;
+ last = null;
+ len = 0;
+ }
+
+ def elements: Iterator[A] =
+ if (first == null) Nil.elements else first.elements;
+
+ def toList: List[A] = if (first == null) Nil else first.toList;
+
+ override def toString() = toList.toString();
+}
diff --git a/sources/scala/collection/mutable/Map.scala b/sources/scala/collection/mutable/Map.scala
new file mode 100644
index 0000000000..3533edcc47
--- /dev/null
+++ b/sources/scala/collection/mutable/Map.scala
@@ -0,0 +1,58 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+** $Id$
+\* */
+
+package scala;
+
+/** I promise, there will be some documentation soon! :-) Matthias
+ */
+trait MutableMap[A, B] with Map[A, B] {
+
+ def update(key: A, value: B): Unit;
+
+ def remove(key: A): Unit;
+
+ def clear: Unit = {
+ val iter = keys;
+ while (iter.hasNext) {
+ remove(iter.next);
+ }
+ }
+
+ def put(mappings: Pair[A, B]*): Unit = {
+ val ys = mappings as List[Pair[A, B]];
+ ys foreach { case Pair(key, value) => update(key, value); };
+ }
+
+ def putMap(map: Iterable[Pair[A, B]]): Unit = map.elements foreach {
+ case Pair(key, value) => update(key, value);
+ }
+
+ def map(f: (A, B) => B): Unit = elements foreach {
+ case Pair(key, value) => update(key, f(key, value));
+ }
+
+ def filter(p: (A, B) => Boolean): Unit = toList foreach {
+ case Pair(key, value) => if (p(key, value)) remove(key);
+ }
+
+ override def toString() =
+ if (size == 0)
+ "{}"
+ else
+ "{" + {
+ val iter = elements;
+ var res = mappingToString(iter.next);
+ while (iter.hasNext) {
+ res = res + ", " + mappingToString(iter.next);
+ }
+ res;
+ } + "}";
+
+ def mappingToString(p: Pair[A, B]) = p._1.toString() + " -> " + p._2;
+}
diff --git a/sources/scala/collection/mutable/Modification.scala b/sources/scala/collection/mutable/Modification.scala
new file mode 100644
index 0000000000..4da13bd61a
--- /dev/null
+++ b/sources/scala/collection/mutable/Modification.scala
@@ -0,0 +1,13 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+** $Id$
+\* */
+
+package scala;
+
+
+case class Modification[A](old: A, nu: A) extends ObservableUpdate[A];
diff --git a/sources/scala/collection/mutable/MultiMap.scala b/sources/scala/collection/mutable/MultiMap.scala
new file mode 100644
index 0000000000..7bc6cc2518
--- /dev/null
+++ b/sources/scala/collection/mutable/MultiMap.scala
@@ -0,0 +1,34 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+** $Id$
+\* */
+
+package scala;
+
+
+trait MultiMap[A, B] extends MutableMap[A, MutableSet[B]] {
+ protected def makeSet: MutableSet[B] = new HashSet[B];
+
+ def add(key: A, value: B): Unit = get(key) match {
+ case None => val set = makeSet;
+ set.add(value);
+ update(key, set);
+ case Some(set) => set.add(value);
+ }
+
+ override def remove(key: A) = super.remove(key);
+
+ override def remove(key: A, value: B) = get(key) match {
+ case None =>
+ case Some(set) => set.remove(value);
+ }
+
+ def exists(key: A, p: B => Boolean): Boolean = get(key) match {
+ case None => false
+ case Some(set) => set.exists(p);
+ }
+}
diff --git a/sources/scala/collection/mutable/ObservableMap.scala b/sources/scala/collection/mutable/ObservableMap.scala
new file mode 100644
index 0000000000..420a0feeaa
--- /dev/null
+++ b/sources/scala/collection/mutable/ObservableMap.scala
@@ -0,0 +1,40 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+** $Id$
+\* */
+
+package scala;
+
+
+abstract class ObservableMap[A, B, This <: ObservableMap[A, B, This]]: This
+ extends MutableMap[A, B]
+ with Publisher[ObservableUpdate[Pair[A, B]] with Undo, This] {
+
+ override def update(key: A, value: B): Unit = get(key) match {
+ case None => super.update(key, value);
+ publish(new Inclusion(Pair(key, value)) with Undo {
+ def undo = remove(key);
+ });
+ case Some(old) => super.update(key, value);
+ publish(new Modification(Pair(key, old), Pair(key, value)) with Undo {
+ def undo = update(key, old._2);
+ });
+ }
+
+ override def remove(key: A): Unit = get(key) match {
+ case None =>
+ case Some(old) => super.remove(key);
+ publish(new Removal(Pair(key, old)) with Undo {
+ def undo = update(key, old);
+ });
+ }
+
+ override def clear: Unit = {
+ super.clear;
+ publish(new Reset() with Undo { def undo = error("cannot undo"); });
+ }
+}
diff --git a/sources/scala/collection/mutable/ObservableSet.scala b/sources/scala/collection/mutable/ObservableSet.scala
new file mode 100644
index 0000000000..c862c33648
--- /dev/null
+++ b/sources/scala/collection/mutable/ObservableSet.scala
@@ -0,0 +1,35 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+** $Id$
+\* */
+
+package scala;
+
+
+abstract class ObservableSet[A, This <: ObservableSet[A, This]]: This
+ extends MutableSet[A]
+ with Publisher[ObservableUpdate[A] with Undo, This] {
+
+ override def add(elem: A): Unit = if (!contains(elem)) {
+ super.add(elem);
+ publish(new Inclusion(elem) with Undo {
+ def undo = remove(elem);
+ });
+ }
+
+ override def remove(elem: A): Unit = if (contains(elem)) {
+ super.remove(elem);
+ publish(new Removal(elem) with Undo {
+ def undo = add(elem);
+ });
+ }
+
+ override def clear: Unit = {
+ super.clear;
+ publish(new Reset() with Undo { def undo = error("cannot undo"); });
+ }
+}
diff --git a/sources/scala/collection/mutable/ObservableUpdate.scala b/sources/scala/collection/mutable/ObservableUpdate.scala
new file mode 100644
index 0000000000..fabe049f40
--- /dev/null
+++ b/sources/scala/collection/mutable/ObservableUpdate.scala
@@ -0,0 +1,13 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+** $Id$
+\* */
+
+package scala;
+
+
+trait ObservableUpdate[+A];
diff --git a/sources/scala/collection/mutable/Publisher.scala b/sources/scala/collection/mutable/Publisher.scala
new file mode 100644
index 0000000000..5d6df1f140
--- /dev/null
+++ b/sources/scala/collection/mutable/Publisher.scala
@@ -0,0 +1,37 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+** $Id$
+\* */
+
+package scala;
+
+
+/** <tt>Publisher[A, This]</tt> objects publish events of type <tt>A</tt>
+ * to all registered subscribers.
+ */
+class Publisher[A, This <: Publisher[A, This]]: This {
+ private val filters = new HashMap[Subscriber[A, This], MutableSet[A => Boolean]]
+ with MultiMap[Subscriber[A, This], A => Boolean];
+ private val suspended = new HashSet[Subscriber[A, This]];
+
+ def subscribe(sub: Subscriber[A, This]): Unit = subscribe(sub, (event => true));
+
+ def subscribe(sub: Subscriber[A, This], filter: A => Boolean): Unit =
+ filters.add(sub, filter);
+
+ def suspendSubscription(sub: Subscriber[A, This]): Unit = suspended.add(sub);
+
+ def activateSubscription(sub: Subscriber[A, This]): Unit = suspended.remove(sub);
+
+ def removeSubscription(sub: Subscriber[A, This]): Unit = filters.remove(sub);
+
+ def removeSubscriptions: Unit = filters.clear;
+
+ protected def publish(event: A): Unit =
+ filters.keys.foreach(sub =>
+ if (filters.exists(sub, (p => p(event)))) sub.update(this, event));
+}
diff --git a/sources/scala/collection/mutable/Queue.scala b/sources/scala/collection/mutable/Queue.scala
new file mode 100644
index 0000000000..7ab2011bea
--- /dev/null
+++ b/sources/scala/collection/mutable/Queue.scala
@@ -0,0 +1,32 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+** $Id$
+\* */
+
+package scala;
+
+
+class Queue[A] with MutableList[A] {
+
+ def +=(elem: A) = appendElem(elem);
+
+ def +=(iter: Iterable[A]) = iter.elements.foreach(e => appendElem(e));
+
+ def enqueue(elems: A*): Unit = (this += elems);
+
+ def dequeue: A = {
+ if (first == null)
+ error("queue empty");
+ else {
+ val res = first.elem;
+ first = first.next;
+ res;
+ }
+ }
+
+ def clear: Unit = reset;
+}
diff --git a/sources/scala/collection/mutable/Removal.scala b/sources/scala/collection/mutable/Removal.scala
new file mode 100644
index 0000000000..37b062709e
--- /dev/null
+++ b/sources/scala/collection/mutable/Removal.scala
@@ -0,0 +1,13 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+** $Id$
+\* */
+
+package scala;
+
+
+case class Removal[A](elem: A) extends ObservableUpdate[A];
diff --git a/sources/scala/collection/mutable/Reset.scala b/sources/scala/collection/mutable/Reset.scala
new file mode 100644
index 0000000000..b458560251
--- /dev/null
+++ b/sources/scala/collection/mutable/Reset.scala
@@ -0,0 +1,13 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+** $Id$
+\* */
+
+package scala;
+
+
+case class Reset[A]() extends ObservableUpdate[A];
diff --git a/sources/scala/collection/mutable/RevertableHistory.scala b/sources/scala/collection/mutable/RevertableHistory.scala
new file mode 100644
index 0000000000..760f5dcea6
--- /dev/null
+++ b/sources/scala/collection/mutable/RevertableHistory.scala
@@ -0,0 +1,25 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+** $Id$
+\* */
+
+package scala;
+
+
+/** <tt>Subscriber[-A, -B]</tt> objects may subscribe to events of
+ * type <tt>A</tt> published by an object of type <tt>B</tt>.
+ */
+class RevertableHistory[A <: Undo, B] extends History[A, B] with Undo {
+
+ def undo: Unit = {
+ val old = log.toList.reverse;
+ clear;
+ old.foreach {
+ case Pair(sub, event) => event.undo;
+ }
+ }
+}
diff --git a/sources/scala/collection/mutable/Set.scala b/sources/scala/collection/mutable/Set.scala
new file mode 100644
index 0000000000..c64104989d
--- /dev/null
+++ b/sources/scala/collection/mutable/Set.scala
@@ -0,0 +1,39 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+** $Id$
+\* */
+
+package scala;
+
+
+trait MutableSet[A] with Set[A] {
+
+ def add(elem: A): Unit;
+
+ def addAll(elems: A*): Unit = {
+ val ys = elems as List[A];
+ ys foreach { y => add(y); };
+ }
+
+ def addSet(that: Iterable[A]): Unit =
+ that.elements.foreach(elem => add(elem));
+
+ def remove(elem: A): Unit;
+
+ def removeAll(elems: A*): Unit = removeSet(elems);
+
+ def removeSet(that: Iterable[A]): Unit =
+ that.elements.foreach(elem => remove(elem));
+
+ def intersect(that: Set[A]): Unit = filter(that.contains);
+
+ def clear: Unit;
+
+ def filter(p: A => Boolean): Unit = toList foreach {
+ elem => if (p(elem)) remove(elem);
+ }
+}
diff --git a/sources/scala/collection/mutable/SingleLinkedList.scala b/sources/scala/collection/mutable/SingleLinkedList.scala
new file mode 100644
index 0000000000..5fd2fe937c
--- /dev/null
+++ b/sources/scala/collection/mutable/SingleLinkedList.scala
@@ -0,0 +1,58 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id$
+
+
+package scala;
+
+
+abstract class SingleLinkedList[A, This <: SingleLinkedList[A, This]]: This with Seq[A] {
+
+ var elem: A = _;
+
+ var next: This = _;
+
+ def length: Int = 1 + (if (next == null) 0 else next.length);
+
+ def append(that: This): Unit =
+ if (next == null) { next = that; } else next.append(that);
+
+ def insert(that: This): Unit = if (that != null) {
+ that.append(next);
+ next = that;
+ }
+
+ def apply(n: Int): A = {
+ if (n == 0) elem
+ else if (next == null) null
+ else next.apply(n - 1);
+ }
+
+ def at(n: Int): A = apply(n);
+
+ def get(n: Int): Option[A] = {
+ if (n == 0) Some(elem)
+ else if (next == null) None
+ else next.get(n - 1);
+ }
+
+ def elements: Iterator[A] = new Iterator[A] {
+ var elems = SingleLinkedList.this;
+ def hasNext = (elems != null);
+ def next = {
+ val res = elems.elem;
+ elems = elems.next;
+ res;
+ }
+ }
+
+ def toList: List[A] =
+ if (next == null) (elem :: Nil) else (elem :: next.toList);
+
+}
diff --git a/sources/scala/collection/mutable/Stack.scala b/sources/scala/collection/mutable/Stack.scala
new file mode 100644
index 0000000000..67f1065aef
--- /dev/null
+++ b/sources/scala/collection/mutable/Stack.scala
@@ -0,0 +1,30 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+** $Id$
+\* */
+
+package scala;
+
+
+class Stack[A] with MutableList[A] {
+
+ def +=(elem: A) = prependElem(elem);
+
+ def +=(iter: Iterable[A]) = iter.elements.foreach(e => prependElem(e));
+
+ def push(elems: A*): Unit = (this += elems);
+
+ def top: A = if (first == null) error("stack empty"); else first.elem;
+
+ def pop: Unit = if (first != null) { first = first.next; }
+
+ def clear: Unit = reset;
+
+ override def elements: Iterator[A] = toList.elements;
+
+ override def toList: List[A] = super.toList.reverse;
+}
diff --git a/sources/scala/collection/mutable/Subscriber.scala b/sources/scala/collection/mutable/Subscriber.scala
new file mode 100644
index 0000000000..f41dd3e44d
--- /dev/null
+++ b/sources/scala/collection/mutable/Subscriber.scala
@@ -0,0 +1,18 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+** $Id$
+\* */
+
+package scala;
+
+
+/** <tt>Subscriber[-A, -B]</tt> objects may subscribe to events of
+ * type <tt>A</tt> published by an object of type <tt>B</tt>.
+ */
+trait Subscriber[-A, -B] {
+ def update(pub: B, event: A): Unit;
+}
diff --git a/sources/scala/collection/mutable/SynchronizedMap.scala b/sources/scala/collection/mutable/SynchronizedMap.scala
new file mode 100644
index 0000000000..a710fcf761
--- /dev/null
+++ b/sources/scala/collection/mutable/SynchronizedMap.scala
@@ -0,0 +1,86 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+** $Id$
+\* */
+
+package scala;
+
+
+trait SynchronizedMap[A, B] extends MutableMap[A, B] with Monitor {
+
+ override def size: Int = synchronized {
+ super.size;
+ }
+
+ override def get(key: A): Option[B] = synchronized {
+ super.get(key);
+ }
+
+ override def isEmpty: Boolean = synchronized {
+ super.isEmpty;
+ }
+
+ override def apply(key: A): B = synchronized {
+ super.apply(key);
+ }
+
+ override def contains(key: A): Boolean = synchronized {
+ super.contains(key);
+ }
+
+ override def isDefinedAt(key: A) = synchronized {
+ super.isDefinedAt(key);
+ }
+
+ override def keys: Iterator[A] = synchronized {
+ super.keys;
+ }
+
+ override def values: Iterator[B] = synchronized {
+ super.values;
+ }
+
+ override def foreach(f: (A, B) => Unit) = synchronized {
+ super.foreach(f);
+ }
+
+ override def toList: List[Pair[A, B]] = synchronized {
+ super.toList;
+ }
+
+ override def update(key: A, value: B): Unit = synchronized {
+ super.update(key, value);
+ }
+
+ override def remove(key: A): Unit = synchronized {
+ super.remove(key);
+ }
+
+ override def clear: Unit = synchronized {
+ super.clear;
+ }
+
+ override def put(mappings: Pair[A, B]*) = synchronized {
+ super.putMap(mappings);
+ }
+
+ override def putMap(map: Iterable[Pair[A, B]]): Unit = synchronized {
+ super.putMap(map);
+ }
+
+ override def map(f: (A, B) => B): Unit = synchronized {
+ super.map(f);
+ }
+
+ override def filter(p: (A, B) => Boolean): Unit = synchronized {
+ super.filter(p);
+ }
+
+ override def toString() = synchronized {
+ super.toString();
+ }
+}
diff --git a/sources/scala/collection/mutable/SynchronizedSet.scala b/sources/scala/collection/mutable/SynchronizedSet.scala
new file mode 100644
index 0000000000..1e0600afa9
--- /dev/null
+++ b/sources/scala/collection/mutable/SynchronizedSet.scala
@@ -0,0 +1,78 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+** $Id$
+\* */
+
+package scala;
+
+
+trait SynchronizedSet[A] extends MutableSet[A] with Monitor {
+
+ override def size: Int = synchronized {
+ super.size
+ }
+
+ override def isEmpty: Boolean = synchronized {
+ super.isEmpty
+ }
+
+ override def contains(elem: A) = synchronized {
+ super.contains(elem);
+ }
+
+ override def add(elem: A): Unit = synchronized {
+ super.add(elem);
+ }
+
+ override def addAll(elems: A*): Unit = synchronized {
+ super.addSet(elems);
+ }
+
+ override def addSet(that: Iterable[A]) = synchronized {
+ super.addSet(that);
+ }
+
+ override def remove(elem: A): Unit = synchronized {
+ super.remove(elem);
+ }
+
+ override def removeAll(elems: A*): Unit = synchronized {
+ super.removeSet(elems);
+ }
+
+ override def removeSet(that: Iterable[A]) = synchronized {
+ super.removeSet(that);
+ }
+
+ override def intersect(that: Set[A]) = synchronized {
+ super.intersect(that);
+ }
+
+ override def clear: Unit = synchronized {
+ super.clear;
+ }
+
+ override def subsetOf(that: Set[A]) = synchronized {
+ super.subsetOf(that);
+ }
+
+ override def foreach(f: A => Unit) = synchronized {
+ super.foreach(f);
+ }
+
+ override def filter(p: A => Boolean) = synchronized {
+ super.filter(p);
+ }
+
+ override def toList: List[A] = synchronized {
+ super.toList;
+ }
+
+ override def toString() = synchronized {
+ super.toString();
+ }
+}
diff --git a/sources/scala/collection/mutable/Undo.scala b/sources/scala/collection/mutable/Undo.scala
new file mode 100644
index 0000000000..4349851e5a
--- /dev/null
+++ b/sources/scala/collection/mutable/Undo.scala
@@ -0,0 +1,15 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+** $Id$
+\* */
+
+package scala;
+
+
+trait Undo {
+ def undo: Unit;
+}
diff --git a/sources/scala/testing/UnitTest.scala b/sources/scala/testing/UnitTest.scala
new file mode 100644
index 0000000000..1973ab08c5
--- /dev/null
+++ b/sources/scala/testing/UnitTest.scala
@@ -0,0 +1,61 @@
+package scala ;
+
+object UnitTest {
+
+ def message_passedOK:Unit = {
+ System.out.println("passed ok")
+ }
+
+ def message_failed( actual:String, expected:String ):Unit = {
+ System.out.print("failed! we got");
+ System.out.print( "\""+ actual +"\"" );
+ System.out.println(" but expected " + expected)
+ }
+
+ def testEquals[a]( actual: a, expected: a ):Unit = {
+
+ if( actual == expected )
+ {
+ message_passedOK
+ }
+ else
+ {
+ message_failed( actual.toString(), expected.toString() )
+ }
+
+ } // testEquals
+
+ def test[b,a]( doit:b => a,
+ input: b,
+ expected:a ):Unit = {
+ val actual = doit( input );
+ if( actual == expected )
+ {
+ message_passedOK
+ }
+ else
+ {
+ message_failed( actual.toString(), expected.toString() )
+ }
+
+ } // test
+
+ def test2[c,b,a]( doit:(c,b) => a,
+ in1: c,
+ in2: b,
+ expected:a ):Unit = {
+ val actual = doit( in1, in2 );
+ if( actual == expected )
+ {
+ message_passedOK;
+ }
+ else
+ {
+ message_failed( actual.toString(), expected.toString() )
+ }
+
+ } // test2
+
+} // unitTest
+
+