Make AbstractMutableCollections satisfy expect declarations from common
- Add actuals to AbstractMutableCollection - Add hashCode/equals to AbstractMutableSet - Take implementation of AbstractMutableMap from JS
This commit is contained in:
committed by
Vasily Levchenko
parent
91aba74f1d
commit
7d9ec09c9d
@@ -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<E> protected constructor(): MutableCollection<E>, AbstractCollection<E>() {
|
||||
public actual abstract class AbstractMutableCollection<E> protected actual constructor(): MutableCollection<E>, AbstractCollection<E>() {
|
||||
|
||||
// Bulk Modification Operations
|
||||
/**
|
||||
@@ -18,7 +18,7 @@ public abstract class AbstractMutableCollection<E> 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<E>): Boolean {
|
||||
actual override public fun addAll(elements: Collection<E>): Boolean {
|
||||
var changed = false
|
||||
for (v in elements) {
|
||||
if (add(v)) changed = true
|
||||
@@ -32,7 +32,7 @@ public abstract class AbstractMutableCollection<E> 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<E> 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<E>): Boolean = (this as MutableIterable<E>).removeAll { it in elements }
|
||||
actual override public fun removeAll(elements: Collection<E>): Boolean = (this as MutableIterable<E>).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<E>): Boolean = (this as MutableIterable<E>).retainAll { it in elements }
|
||||
actual override public fun retainAll(elements: Collection<E>): Boolean = (this as MutableIterable<E>).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()
|
||||
|
||||
@@ -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<K, V> protected actual constructor() : AbstractMap<K, V>(), MutableMap<K, V> {
|
||||
/**
|
||||
* 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<K, V>(override val key: K, value: V) : MutableMap.MutableEntry<K, V> {
|
||||
constructor(entry: Map.Entry<K, V>) : 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<out K, V>) {
|
||||
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<K>? = null
|
||||
actual override val keys: MutableSet<K>
|
||||
get() {
|
||||
if (_keys == null) {
|
||||
_keys = object : AbstractMutableSet<K>() {
|
||||
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<K> {
|
||||
val entryIterator = entries.iterator()
|
||||
return object : MutableIterator<K> {
|
||||
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<V>? = null
|
||||
actual override val values: MutableCollection<V>
|
||||
get() {
|
||||
if (_values == null) {
|
||||
_values = object : AbstractMutableCollection<V>() {
|
||||
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<V> {
|
||||
val entryIterator = entries.iterator()
|
||||
return object : MutableIterator<V> {
|
||||
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!!
|
||||
}
|
||||
}
|
||||
@@ -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<E> protected actual constructor() : AbstractMutableCollection<E>(), MutableSet<E> {
|
||||
/**
|
||||
* 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)
|
||||
}
|
||||
@@ -25,51 +25,3 @@ public actual fun <T> MutableList<T>.sortWith(comparator: Comparator<in T>): 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<K, V> protected actual constructor() : AbstractMap<K, V>(), MutableMap<K, V> {
|
||||
/**
|
||||
* 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<K>
|
||||
|
||||
/**
|
||||
* Returns a [MutableCollection] of all values in this map. Note that this collection may contain duplicate values.
|
||||
*/
|
||||
abstract override val values: MutableCollection<V>
|
||||
}
|
||||
|
||||
/**
|
||||
* 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<E> protected actual constructor() : AbstractSet<E>(), MutableSet<E> {
|
||||
/**
|
||||
* 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
|
||||
}
|
||||
Reference in New Issue
Block a user