diff --git a/runtime/src/main/kotlin/kotlin/collections/AbstractMutableCollection.kt b/runtime/src/main/kotlin/kotlin/collections/AbstractMutableCollection.kt index bdd69eb418d..e90053fd8ae 100644 --- a/runtime/src/main/kotlin/kotlin/collections/AbstractMutableCollection.kt +++ b/runtime/src/main/kotlin/kotlin/collections/AbstractMutableCollection.kt @@ -10,7 +10,7 @@ package kotlin.collections * * @param E the type of elements contained in the collection. The collection is invariant on its element type. */ -public abstract class AbstractMutableCollection protected constructor(): MutableCollection, AbstractCollection() { +public actual abstract class AbstractMutableCollection protected actual constructor(): MutableCollection, AbstractCollection() { // Bulk Modification Operations /** @@ -18,7 +18,7 @@ public abstract class AbstractMutableCollection protected constructor(): Muta * * @return `true` if any of the specified elements was added to the collection, `false` if the collection was not modified. */ - override public fun addAll(elements: Collection): Boolean { + actual override public fun addAll(elements: Collection): Boolean { var changed = false for (v in elements) { if (add(v)) changed = true @@ -32,7 +32,7 @@ public abstract class AbstractMutableCollection protected constructor(): Muta * * @return `true` if the element has been successfully removed; `false` if it was not present in the collection. */ - override fun remove(element: E): Boolean { + actual override fun remove(element: E): Boolean { val it = iterator() while (it.hasNext()) { if (it.next() == element) { @@ -48,19 +48,19 @@ public abstract class AbstractMutableCollection protected constructor(): Muta * * @return `true` if any of the specified elements was removed from the collection, `false` if the collection was not modified. */ - override public fun removeAll(elements: Collection): Boolean = (this as MutableIterable).removeAll { it in elements } + actual override public fun removeAll(elements: Collection): Boolean = (this as MutableIterable).removeAll { it in elements } /** * Retains only the elements in this collection that are contained in the specified collection. * * @return `true` if any element was removed from the collection, `false` if the collection was not modified. */ - override public fun retainAll(elements: Collection): Boolean = (this as MutableIterable).retainAll { it in elements } + actual override public fun retainAll(elements: Collection): Boolean = (this as MutableIterable).retainAll { it in elements } /** * Removes all elements from this collection. */ - override fun clear(): Unit { + actual override fun clear(): Unit { val it = iterator() while (it.hasNext()) { it.next() diff --git a/runtime/src/main/kotlin/kotlin/collections/AbstractMutableMap.kt b/runtime/src/main/kotlin/kotlin/collections/AbstractMutableMap.kt new file mode 100644 index 00000000000..8dc29978e54 --- /dev/null +++ b/runtime/src/main/kotlin/kotlin/collections/AbstractMutableMap.kt @@ -0,0 +1,135 @@ +package kotlin.collections + +/** + * Provides a skeletal implementation of the [MutableMap] interface. + * + * The implementor is required to implement [entries] property, which should return mutable set of map entries, and [put] function. + * + * @param K the type of map keys. The map is invariant on its key type. + * @param V the type of map values. The map is invariant on its value type. + */ +@SinceKotlin("1.1") +public actual abstract class AbstractMutableMap protected actual constructor() : AbstractMap(), MutableMap { + /** + * Associates the specified [value] with the specified [key] in the map. + * + * @return the previous value associated with the key, or `null` if the key was not present in the map. + */ + actual abstract override fun put(key: K, value: V): V? + + + /** + * A mutable [Map.Entry] shared by several [Map] implementations. + */ + internal open class SimpleEntry(override val key: K, value: V) : MutableMap.MutableEntry { + constructor(entry: Map.Entry) : this(entry.key, entry.value) + + private var _value = value + + override val value: V get() = _value + + override fun setValue(newValue: V): V { + val oldValue = this._value + this._value = newValue + return oldValue + } + + override fun hashCode(): Int = entryHashCode(this) + override fun toString(): String = entryToString(this) + override fun equals(other: Any?): Boolean = entryEquals(this, other) + } + + + actual override fun putAll(from: Map) { + for ((key, value) in from) { + put(key, value) + } + } + + actual override fun remove(key: K): V? { + val iter = entries.iterator() + while (iter.hasNext()) { + val entry = iter.next() + val k = entry.key + if (key == k) { + val value = entry.value + iter.remove() + return value + } + } + return null + } + + actual override fun clear() { + entries.clear() + } + + private var _keys: MutableSet? = null + actual override val keys: MutableSet + get() { + if (_keys == null) { + _keys = object : AbstractMutableSet() { + override fun add(element: K): Boolean = throw UnsupportedOperationException("Add is not supported on keys") + override fun clear() { + this@AbstractMutableMap.clear() + } + + override operator fun contains(element: K): Boolean = containsKey(element) + + override operator fun iterator(): MutableIterator { + val entryIterator = entries.iterator() + return object : MutableIterator { + override fun hasNext(): Boolean = entryIterator.hasNext() + override fun next(): K = entryIterator.next().key + override fun remove() = entryIterator.remove() + } + } + + override fun remove(element: K): Boolean { + if (containsKey(element)) { + this@AbstractMutableMap.remove(element) + return true + } + return false + } + + override val size: Int get() = this@AbstractMutableMap.size + } + } + return _keys!! + } + + private var _values: MutableCollection? = null + actual override val values: MutableCollection + get() { + if (_values == null) { + _values = object : AbstractMutableCollection() { + override fun add(element: V): Boolean = throw UnsupportedOperationException("Add is not supported on values") + override fun clear() = this@AbstractMutableMap.clear() + + override operator fun contains(element: V): Boolean = containsValue(element) + + override operator fun iterator(): MutableIterator { + val entryIterator = entries.iterator() + return object : MutableIterator { + override fun hasNext(): Boolean = entryIterator.hasNext() + override fun next(): V = entryIterator.next().value + override fun remove() = entryIterator.remove() + } + } + + override val size: Int get() = this@AbstractMutableMap.size + + // TODO: should we implement them this way? Currently it's unspecified in JVM + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other !is Collection<*>) return false + return AbstractList.orderedEquals(this, other) + } + + override fun hashCode(): Int = AbstractList.orderedHashCode(this) + } + } + return _values!! + } +} diff --git a/runtime/src/main/kotlin/kotlin/collections/AbstractMutableSet.kt b/runtime/src/main/kotlin/kotlin/collections/AbstractMutableSet.kt new file mode 100644 index 00000000000..fedb8e5f55d --- /dev/null +++ b/runtime/src/main/kotlin/kotlin/collections/AbstractMutableSet.kt @@ -0,0 +1,32 @@ +package kotlin.collections + +/** + * Provides a skeletal implementation of the [MutableSet] interface. + * + * @param E the type of elements contained in the set. The set is invariant on its element type. + */ +@SinceKotlin("1.1") +public actual abstract class AbstractMutableSet protected actual constructor() : AbstractMutableCollection(), MutableSet { + /** + * Adds the specified element to the set. + * + * @return `true` if the element has been added, `false` if the element is already contained in the set. + */ + actual abstract override fun add(element: E): Boolean + + /** + * Compares this set with another set instance with the unordered structural equality. + * + * @return true, if [other] instance is a [Set] of the same size, all elements of which are contained in this set. + */ + override fun equals(other: Any?): Boolean { + if (other === this) return true + if (other !is Set<*>) return false + return AbstractSet.setEquals(this, other) + } + + /** + * Returns the hash code value for this set. + */ + override fun hashCode(): Int = AbstractSet.unorderedHashCode(this) +} \ No newline at end of file diff --git a/runtime/src/main/kotlin/kotlin/collections/MutableCollections.kt b/runtime/src/main/kotlin/kotlin/collections/MutableCollections.kt index c9a599ba7b3..ee0e8f75ab2 100644 --- a/runtime/src/main/kotlin/kotlin/collections/MutableCollections.kt +++ b/runtime/src/main/kotlin/kotlin/collections/MutableCollections.kt @@ -25,51 +25,3 @@ public actual fun MutableList.sortWith(comparator: Comparator): Uni } } } -/** - * Provides a skeletal implementation of the [MutableMap] interface. - * - * The implementor is required to implement [entries] property, which should return mutable set of map entries, and [put] function. - * - * @param K the type of map keys. The map is invariant on its key type. - * @param V the type of map values. The map is invariant on its value type. - */ -@SinceKotlin("1.1") -actual abstract class AbstractMutableMap protected actual constructor() : AbstractMap(), MutableMap { - /** - * Associates the specified [value] with the specified [key] in the map. - * - * This method is redeclared as abstract, because it's not implemented in the base class, - * so it must be always overridden in the concrete mutable collection implementation. - * - * @return the previous value associated with the key, or `null` if the key was not present in the map. - */ - actual abstract override fun put(key: K, value: V): V? - - /** - * Returns a [MutableSet] of all keys in this map. - */ - abstract override val keys: MutableSet - - /** - * Returns a [MutableCollection] of all values in this map. Note that this collection may contain duplicate values. - */ - abstract override val values: MutableCollection -} - -/** - * Provides a skeletal implementation of the [MutableSet] interface. - * - * @param E the type of elements contained in the set. The set is invariant on its element type. - */ -@SinceKotlin("1.1") -actual abstract class AbstractMutableSet protected actual constructor() : AbstractSet(), MutableSet { - /** - * Adds the specified element to the set. - * - * This method is redeclared as abstract, because it's not implemented in the base class, - * so it must be always overridden in the concrete mutable collection implementation. - * - * @return `true` if the element has been added, `false` if the element is already contained in the set. - */ - actual abstract override fun add(element: E): Boolean -} \ No newline at end of file