Provide implementation of read-only AbstractCollection, AbstractList and AbstractSet,
Alias AbstactMutableCollection to java.util.AbstractCollection. Change inheritance hierarchy of reversed list views.
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package kotlin.collections
|
||||
|
||||
public abstract class AbstractCollection<out E> : Collection<E> {
|
||||
abstract override val size: Int
|
||||
abstract override fun iterator(): Iterator<E>
|
||||
|
||||
override fun contains(element: @UnsafeVariance E): Boolean = any { it == element }
|
||||
|
||||
override fun containsAll(elements: Collection<@UnsafeVariance E>): Boolean =
|
||||
elements.all(this::contains)
|
||||
|
||||
override fun isEmpty(): Boolean = size == 0
|
||||
|
||||
abstract override fun hashCode(): Int
|
||||
|
||||
abstract override fun equals(other: Any?): Boolean
|
||||
|
||||
override fun toString(): String = joinToString(", ", "[", "]") {
|
||||
if (it === this) "(this Collection)" else it.toString()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/*
|
||||
* Based on GWT AbstractList
|
||||
* Copyright 2007 Google Inc.
|
||||
*/
|
||||
|
||||
package kotlin.collections
|
||||
|
||||
public abstract class AbstractList<out E> : AbstractCollection<E>(), List<E> {
|
||||
abstract override val size: Int
|
||||
abstract override fun get(index: Int): E
|
||||
|
||||
override fun iterator(): Iterator<E> = IteratorImpl()
|
||||
|
||||
override fun indexOf(element: @UnsafeVariance E): Int = indexOfFirst { it == element }
|
||||
|
||||
override fun lastIndexOf(element: @UnsafeVariance E): Int = indexOfLast { it == element }
|
||||
|
||||
override fun listIterator(): ListIterator<E> = ListIteratorImpl(0)
|
||||
|
||||
override fun listIterator(index: Int): ListIterator<E> = ListIteratorImpl(index)
|
||||
|
||||
override fun subList(fromIndex: Int, toIndex: Int): List<E> = SubList(this, fromIndex, toIndex)
|
||||
|
||||
internal open class SubList<out E>(private val list: AbstractList<E>, private val fromIndex: Int, toIndex: Int) : AbstractList<E>() {
|
||||
private var _size: Int = 0
|
||||
|
||||
init {
|
||||
checkRangeIndexes(fromIndex, toIndex, list.size)
|
||||
this._size = toIndex - fromIndex
|
||||
}
|
||||
|
||||
override fun get(index: Int): E {
|
||||
checkElementIndex(index, _size)
|
||||
|
||||
return list[fromIndex + index]
|
||||
}
|
||||
|
||||
override val size: Int get() = _size
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (other === this) return true
|
||||
if (other !is List<*>) return false
|
||||
|
||||
return orderedEquals(this, other)
|
||||
}
|
||||
|
||||
override fun hashCode(): Int = orderedHashCode(this)
|
||||
|
||||
internal open inner class IteratorImpl : Iterator<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)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of `MutableListIterator` for abstract lists.
|
||||
*/
|
||||
internal open inner class ListIteratorImpl(index: Int) : IteratorImpl(), ListIterator<E> {
|
||||
|
||||
init {
|
||||
checkPositionIndex(index, this@AbstractList.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
|
||||
}
|
||||
|
||||
companion object {
|
||||
internal fun checkElementIndex(index: Int, size: Int) {
|
||||
if (index < 0 || index >= size) {
|
||||
throw IndexOutOfBoundsException("index: $index, size: $size")
|
||||
}
|
||||
}
|
||||
|
||||
internal fun checkPositionIndex(index: Int, size: Int) {
|
||||
if (index < 0 || index > size) {
|
||||
throw IndexOutOfBoundsException("index: $index, size: $size")
|
||||
}
|
||||
}
|
||||
|
||||
internal fun checkRangeIndexes(start: Int, end: Int, size: Int) {
|
||||
if (start < 0 || end > size) {
|
||||
throw IndexOutOfBoundsException("fromIndex: $start, toIndex: $end, size: $size")
|
||||
}
|
||||
if (start > end) {
|
||||
throw IllegalArgumentException("fromIndex: $start > toIndex: $end")
|
||||
}
|
||||
}
|
||||
|
||||
internal fun orderedHashCode(c: Collection<*>): Int {
|
||||
var hashCode = 1
|
||||
for (e in c) {
|
||||
hashCode = 31 * hashCode + (e?.hashCode() ?: 0)
|
||||
hashCode = hashCode or 0 // make sure we don't overflow
|
||||
}
|
||||
return hashCode
|
||||
}
|
||||
|
||||
internal fun orderedEquals(c: Collection<*>, other: Collection<*>): Boolean {
|
||||
if (c.size != other.size) return false
|
||||
|
||||
val otherIterator = other.iterator()
|
||||
for (elem in c) {
|
||||
val elemOther = otherIterator.next()
|
||||
if (elem != elemOther) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package kotlin.collections
|
||||
|
||||
public abstract class AbstractSet<out E> protected constructor() : AbstractCollection<E>(), Set<E> {
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (other === this) return true
|
||||
if (other !is Set<*>) return false
|
||||
if (other.size != size) return false
|
||||
return containsAll(other)
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var hashCode = 0
|
||||
for (element in this) {
|
||||
hashCode = (hashCode + (element?.hashCode() ?: 0)) or 0
|
||||
}
|
||||
return hashCode
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,25 +18,31 @@
|
||||
|
||||
package kotlin.collections
|
||||
|
||||
import java.util.*
|
||||
|
||||
private open class ReversedListReadOnly<T>(protected open val delegate: List<T>) : AbstractList<T>() {
|
||||
private open class ReversedListReadOnly<out T>(private val delegate: List<T>) : AbstractList<T>() {
|
||||
override val size: Int get() = delegate.size
|
||||
override fun get(index: Int): T = delegate[index.flipIndex()]
|
||||
override fun get(index: Int): T = delegate[reverseElementIndex(index)]
|
||||
|
||||
protected fun Int.flipIndex(): Int = if (this in 0..size - 1) size - this - 1 else throw IndexOutOfBoundsException("index $this should be in range [${0..size - 1}].")
|
||||
protected fun Int.flipIndexForward(): Int = if (this in 0..size) size - this else throw IndexOutOfBoundsException("index $this should be in range [${0..size}].")
|
||||
}
|
||||
|
||||
private class ReversedList<T>(protected override val delegate: MutableList<T>) : ReversedListReadOnly<T>(delegate) {
|
||||
override fun clear() = delegate.clear()
|
||||
override fun removeAt(index: Int): T = delegate.removeAt(index.flipIndex())
|
||||
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)]
|
||||
|
||||
override fun set(index: Int, element: T): T = delegate.set(index.flipIndex(), element)
|
||||
override fun clear() = delegate.clear()
|
||||
override fun removeAt(index: Int): T = delegate.removeAt(reverseElementIndex(index))
|
||||
|
||||
override fun set(index: Int, element: T): T = delegate.set(reverseElementIndex(index), element)
|
||||
override fun add(index: Int, element: T) {
|
||||
delegate.add(index.flipIndexForward(), element)
|
||||
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}].")
|
||||
|
||||
private fun List<*>.reversePositionIndex(index: Int) =
|
||||
if (index in 0..size) size - index else throw IndexOutOfBoundsException("Index $index should be in range [${0..size}].")
|
||||
|
||||
|
||||
/**
|
||||
* Returns a reversed read-only view of the original List.
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
@file:JvmVersion
|
||||
package kotlin.collections
|
||||
|
||||
public typealias AbstractMutableCollection<E> = java.util.AbstractCollection<E>
|
||||
public typealias AbstractMutableList<E> = java.util.AbstractList<E>
|
||||
public typealias AbstractMutableSet<E> = java.util.AbstractSet<E>
|
||||
Reference in New Issue
Block a user