stdlib: Add AbstractMutableList implementation
The implementation is based on the AbstractMutableList class of JS backend.
This commit is contained in:
@@ -137,4 +137,188 @@ public abstract class AbstractList<out E> protected constructor() : AbstractColl
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* AbstractMutableList implementation copied from JS backend
|
||||
* (see <Kotlin JVM root>js/js.libraries/src/core/collections/AbstractMutableList.kt).
|
||||
*
|
||||
* Based on GWT AbstractList
|
||||
* Copyright 2007 Google Inc.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Provides a skeletal implementation of the [MutableList] interface.
|
||||
*
|
||||
* @param E the type of elements contained in the list. The list is invariant on its element type.
|
||||
*/
|
||||
public abstract class AbstractMutableList<E> protected constructor() : AbstractMutableCollection<E>(), MutableList<E> {
|
||||
protected var modCount: Int = 0
|
||||
|
||||
abstract override fun add(index: Int, element: E): Unit
|
||||
abstract override fun removeAt(index: Int): E
|
||||
abstract override fun set(index: Int, element: E): E
|
||||
|
||||
override fun add(element: E): Boolean {
|
||||
add(size, element)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun addAll(index: Int, elements: Collection<E>): Boolean {
|
||||
var i = index
|
||||
var changed = false
|
||||
for (e in elements) {
|
||||
add(i++, e)
|
||||
changed = true
|
||||
}
|
||||
return changed
|
||||
}
|
||||
|
||||
override fun clear() {
|
||||
removeRange(0, size)
|
||||
}
|
||||
|
||||
override fun removeAll(elements: Collection<E>): Boolean = removeAll { it in elements }
|
||||
override fun retainAll(elements: Collection<E>): Boolean = removeAll { it !in elements }
|
||||
|
||||
|
||||
override fun iterator(): MutableIterator<E> = IteratorImpl()
|
||||
|
||||
override fun contains(element: E): Boolean = indexOf(element) >= 0
|
||||
|
||||
override fun indexOf(element: E): Int {
|
||||
for (index in 0..lastIndex) {
|
||||
if (get(index) == element) {
|
||||
return index
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
override fun lastIndexOf(element: E): Int {
|
||||
for (index in lastIndex downTo 0) {
|
||||
if (get(index) == element) {
|
||||
return index
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
override fun listIterator(): MutableListIterator<E> = listIterator(0)
|
||||
override fun listIterator(index: Int): MutableListIterator<E> = ListIteratorImpl(index)
|
||||
|
||||
|
||||
override fun subList(fromIndex: Int, toIndex: Int): MutableList<E> = SubList(this, fromIndex, toIndex)
|
||||
|
||||
/**
|
||||
* Removes the range of elements from this list starting from [fromIndex] and ending with but not including [toIndex].
|
||||
*/
|
||||
protected open fun removeRange(fromIndex: Int, toIndex: Int) {
|
||||
val iterator = listIterator(fromIndex)
|
||||
repeat(toIndex - fromIndex) {
|
||||
iterator.next()
|
||||
iterator.remove()
|
||||
}
|
||||
}
|
||||
|
||||
private open inner class IteratorImpl : MutableIterator<E> {
|
||||
/** the index of the item that will be returned on the next call to [next]`()` */
|
||||
protected var index = 0
|
||||
/** the index of the item that was returned on the previous call to [next]`()`
|
||||
* or [ListIterator.previous]`()` (for `ListIterator`),
|
||||
* -1 if no such item exists
|
||||
*/
|
||||
protected var last = -1
|
||||
|
||||
override fun hasNext(): Boolean = index < size
|
||||
|
||||
override fun next(): E {
|
||||
if (!hasNext()) throw NoSuchElementException()
|
||||
last = index++
|
||||
return get(last)
|
||||
}
|
||||
|
||||
override fun remove() {
|
||||
check(last != -1) { "Call next() or previous() before removing element from the iterator."}
|
||||
|
||||
removeAt(last)
|
||||
index = last
|
||||
last = -1
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of `MutableListIterator` for abstract lists.
|
||||
*/
|
||||
private inner class ListIteratorImpl(index: Int) : IteratorImpl(), MutableListIterator<E> {
|
||||
|
||||
init {
|
||||
AbstractList.checkPositionIndex(index, this@AbstractMutableList.size)
|
||||
this.index = index
|
||||
}
|
||||
|
||||
override fun hasPrevious(): Boolean = index > 0
|
||||
|
||||
override fun nextIndex(): Int = index
|
||||
|
||||
override fun previous(): E {
|
||||
if (!hasPrevious()) throw NoSuchElementException()
|
||||
|
||||
last = --index
|
||||
return get(last)
|
||||
}
|
||||
|
||||
override fun previousIndex(): Int = index - 1
|
||||
|
||||
override fun add(element: E) {
|
||||
add(index, element)
|
||||
index++
|
||||
last = -1
|
||||
}
|
||||
|
||||
override fun set(element: E) {
|
||||
check(last != -1) { "Call next() or previous() before updating element value with the iterator."}
|
||||
this@AbstractMutableList[last] = element
|
||||
}
|
||||
}
|
||||
|
||||
private class SubList<E>(private val list: AbstractMutableList<E>, private val fromIndex: Int, toIndex: Int) : AbstractMutableList<E>() {
|
||||
private var _size: Int = 0
|
||||
|
||||
init {
|
||||
AbstractList.checkRangeIndexes(fromIndex, toIndex, list.size)
|
||||
this._size = toIndex - fromIndex
|
||||
}
|
||||
|
||||
override fun add(index: Int, element: E) {
|
||||
AbstractList.checkPositionIndex(index, _size)
|
||||
|
||||
list.add(fromIndex + index, element)
|
||||
_size++
|
||||
}
|
||||
|
||||
override fun get(index: Int): E {
|
||||
AbstractList.checkElementIndex(index, _size)
|
||||
|
||||
return list[fromIndex + index]
|
||||
}
|
||||
|
||||
override fun removeAt(index: Int): E {
|
||||
AbstractList.checkElementIndex(index, _size)
|
||||
|
||||
val result = list.removeAt(fromIndex + index)
|
||||
_size--
|
||||
return result
|
||||
}
|
||||
|
||||
override fun set(index: Int, element: E): E {
|
||||
AbstractList.checkElementIndex(index, _size)
|
||||
|
||||
return list.set(fromIndex + index, element)
|
||||
}
|
||||
|
||||
override val size: Int get() = _size
|
||||
}
|
||||
|
||||
}
|
||||
@@ -338,7 +338,7 @@ public fun <T: Comparable<T>> List<T?>.binarySearch(element: T?, fromIndex: Int
|
||||
val comparisonResult = compareValues(middleValue, element)
|
||||
|
||||
if (comparisonResult < 0)
|
||||
low = middleIndex + 1
|
||||
lowBorder = middleIndex + 1
|
||||
else if (comparisonResult > 0)
|
||||
highBorder = middleIndex - 1
|
||||
else
|
||||
@@ -367,7 +367,7 @@ public fun <T> List<T>.binarySearch(element: T, comparator: Comparator<in T>, fr
|
||||
var lowBorder = fromIndex
|
||||
var highBorder = toIndex - 1
|
||||
|
||||
while (lowBorder <= high) {
|
||||
while (lowBorder <= highBorder) {
|
||||
val middleIndex = (lowBorder + highBorder).ushr(1) // safe from overflows
|
||||
val middleValue = get(middleIndex)
|
||||
val comparisonResult = comparator.compare(middleValue, element)
|
||||
@@ -375,7 +375,7 @@ public fun <T> List<T>.binarySearch(element: T, comparator: Comparator<in T>, fr
|
||||
if (comparisonResult < 0)
|
||||
lowBorder = middleIndex + 1
|
||||
else if (comparisonResult > 0)
|
||||
highBorderBorder = middleIndex - 1
|
||||
highBorder = middleIndex - 1
|
||||
else
|
||||
return middleIndex // key found
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ private open class ReversedListReadOnly<out T>(private val delegate: List<T>) :
|
||||
override fun get(index: Int): T = delegate[reverseElementIndex(index)]
|
||||
|
||||
}
|
||||
/*
|
||||
|
||||
private class ReversedList<T>(private val delegate: MutableList<T>) : AbstractMutableList<T>() {
|
||||
override val size: Int get() = delegate.size
|
||||
override fun get(index: Int): T = delegate[reverseElementIndex(index)]
|
||||
@@ -33,7 +33,7 @@ private class ReversedList<T>(private val delegate: MutableList<T>) : AbstractMu
|
||||
override fun add(index: Int, element: T) {
|
||||
delegate.add(reversePositionIndex(index), element)
|
||||
}
|
||||
}*/
|
||||
}
|
||||
private fun List<*>.reverseElementIndex(index: Int) = // TODO: Use AbstractList.checkElementIndex: run { AbstractList.checkElementIndex(index, size); lastIndex - index }
|
||||
if (index in 0..size - 1) size - index - 1 else throw IndexOutOfBoundsException("Index $index should be in range [${0..size - 1}].")
|
||||
|
||||
@@ -46,10 +46,9 @@ private fun List<*>.reversePositionIndex(index: Int) =
|
||||
* All changes made in the original list will be reflected in the reversed one.
|
||||
*/
|
||||
public fun <T> List<T>.asReversed(): List<T> = ReversedListReadOnly(this)
|
||||
/*
|
||||
|
||||
/**
|
||||
* Returns a reversed mutable view of the original mutable List.
|
||||
* All changes made in the original list will be reflected in the reversed one and vice versa.
|
||||
*/
|
||||
public fun <T> MutableList<T>.asReversed(): MutableList<T> = ReversedList(this)
|
||||
*/
|
||||
Reference in New Issue
Block a user