From d2df7c9c9a02cd91d2dabaf4709ab77235df13c2 Mon Sep 17 00:00:00 2001 From: schinz Date: Tue, 8 Jul 2003 08:35:16 +0000 Subject: *** empty log message *** --- sources/scala/collection/Map.scala | 76 ++++++++++++ sources/scala/collection/Set.scala | 67 +++++++++++ sources/scala/collection/immutable/ListMap.scala | 31 +++++ sources/scala/collection/immutable/ListSet.scala | 34 ++++++ sources/scala/collection/immutable/Map.scala | 62 ++++++++++ sources/scala/collection/immutable/Set.scala | 46 ++++++++ sources/scala/collection/mutable/Buffer.scala | 82 +++++++++++++ .../scala/collection/mutable/DefaultMapModel.scala | 46 ++++++++ .../collection/mutable/DoubleLinkedList.scala | 41 +++++++ sources/scala/collection/mutable/HashMap.scala | 24 ++++ sources/scala/collection/mutable/HashSet.scala | 36 ++++++ sources/scala/collection/mutable/HashTable.scala | 130 +++++++++++++++++++++ sources/scala/collection/mutable/History.scala | 36 ++++++ sources/scala/collection/mutable/Inclusion.scala | 13 +++ sources/scala/collection/mutable/LinkedList.scala | 15 +++ sources/scala/collection/mutable/List.scala | 61 ++++++++++ sources/scala/collection/mutable/Map.scala | 58 +++++++++ .../scala/collection/mutable/Modification.scala | 13 +++ sources/scala/collection/mutable/MultiMap.scala | 34 ++++++ .../scala/collection/mutable/ObservableMap.scala | 40 +++++++ .../scala/collection/mutable/ObservableSet.scala | 35 ++++++ .../collection/mutable/ObservableUpdate.scala | 13 +++ sources/scala/collection/mutable/Publisher.scala | 37 ++++++ sources/scala/collection/mutable/Queue.scala | 32 +++++ sources/scala/collection/mutable/Removal.scala | 13 +++ sources/scala/collection/mutable/Reset.scala | 13 +++ .../collection/mutable/RevertableHistory.scala | 25 ++++ sources/scala/collection/mutable/Set.scala | 39 +++++++ .../collection/mutable/SingleLinkedList.scala | 58 +++++++++ sources/scala/collection/mutable/Stack.scala | 30 +++++ sources/scala/collection/mutable/Subscriber.scala | 18 +++ .../scala/collection/mutable/SynchronizedMap.scala | 86 ++++++++++++++ .../scala/collection/mutable/SynchronizedSet.scala | 78 +++++++++++++ sources/scala/collection/mutable/Undo.scala | 15 +++ sources/scala/testing/UnitTest.scala | 61 ++++++++++ 35 files changed, 1498 insertions(+) create mode 100644 sources/scala/collection/Map.scala create mode 100644 sources/scala/collection/Set.scala create mode 100644 sources/scala/collection/immutable/ListMap.scala create mode 100644 sources/scala/collection/immutable/ListSet.scala create mode 100644 sources/scala/collection/immutable/Map.scala create mode 100644 sources/scala/collection/immutable/Set.scala create mode 100644 sources/scala/collection/mutable/Buffer.scala create mode 100644 sources/scala/collection/mutable/DefaultMapModel.scala create mode 100644 sources/scala/collection/mutable/DoubleLinkedList.scala create mode 100644 sources/scala/collection/mutable/HashMap.scala create mode 100644 sources/scala/collection/mutable/HashSet.scala create mode 100644 sources/scala/collection/mutable/HashTable.scala create mode 100644 sources/scala/collection/mutable/History.scala create mode 100644 sources/scala/collection/mutable/Inclusion.scala create mode 100644 sources/scala/collection/mutable/LinkedList.scala create mode 100644 sources/scala/collection/mutable/List.scala create mode 100644 sources/scala/collection/mutable/Map.scala create mode 100644 sources/scala/collection/mutable/Modification.scala create mode 100644 sources/scala/collection/mutable/MultiMap.scala create mode 100644 sources/scala/collection/mutable/ObservableMap.scala create mode 100644 sources/scala/collection/mutable/ObservableSet.scala create mode 100644 sources/scala/collection/mutable/ObservableUpdate.scala create mode 100644 sources/scala/collection/mutable/Publisher.scala create mode 100644 sources/scala/collection/mutable/Queue.scala create mode 100644 sources/scala/collection/mutable/Removal.scala create mode 100644 sources/scala/collection/mutable/Reset.scala create mode 100644 sources/scala/collection/mutable/RevertableHistory.scala create mode 100644 sources/scala/collection/mutable/Set.scala create mode 100644 sources/scala/collection/mutable/SingleLinkedList.scala create mode 100644 sources/scala/collection/mutable/Stack.scala create mode 100644 sources/scala/collection/mutable/Subscriber.scala create mode 100644 sources/scala/collection/mutable/SynchronizedMap.scala create mode 100644 sources/scala/collection/mutable/SynchronizedSet.scala create mode 100644 sources/scala/collection/mutable/Undo.scala create mode 100644 sources/scala/testing/UnitTest.scala (limited to 'sources') 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; + + +/** History[A, B] objects may subscribe to events of + * type A published by an object of type B. + * The history subscriber object records all published events + * up to maximum number of maxHistory 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; + + +/** Publisher[A, This] objects publish events of type A + * 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; + + +/** Subscriber[-A, -B] objects may subscribe to events of + * type A published by an object of type B. + */ +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; + + +/** Subscriber[-A, -B] objects may subscribe to events of + * type A published by an object of type B. + */ +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 + + -- cgit v1.2.3