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.
|
* @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
|
// 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.
|
* @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
|
var changed = false
|
||||||
for (v in elements) {
|
for (v in elements) {
|
||||||
if (add(v)) changed = true
|
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.
|
* @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()
|
val it = iterator()
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
if (it.next() == element) {
|
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.
|
* @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.
|
* 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.
|
* @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.
|
* Removes all elements from this collection.
|
||||||
*/
|
*/
|
||||||
override fun clear(): Unit {
|
actual override fun clear(): Unit {
|
||||||
val it = iterator()
|
val it = iterator()
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
it.next()
|
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