ImmutableArrayList and listBuilder() prototype
TODO: lots of improvements, documentation, tests
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
package kotlin
|
||||
|
||||
import java.util.List
|
||||
import java.util.AbstractList
|
||||
|
||||
private class ImmutableArrayList<T>(
|
||||
private val array: Array<T>,
|
||||
private val offset: Int,
|
||||
private val length: Int
|
||||
) : AbstractList<T>() {
|
||||
{
|
||||
// impossible
|
||||
if (offset < 0) {
|
||||
throw IllegalArgumentException("negative offset")
|
||||
}
|
||||
// impossible
|
||||
if (length < 0) {
|
||||
throw IllegalArgumentException("negative length")
|
||||
}
|
||||
// possible when builder is used from different threads
|
||||
if (offset + length > array.size) {
|
||||
throw IllegalArgumentException("offset + length > array.length")
|
||||
}
|
||||
}
|
||||
|
||||
protected fun indexInArray(index: Int): Int {
|
||||
if (index < 0) {
|
||||
throw IllegalArgumentException("negative index")
|
||||
}
|
||||
if (index >= length) {
|
||||
throw IllegalArgumentException("index > length")
|
||||
}
|
||||
return index + offset
|
||||
}
|
||||
|
||||
public override fun get(index: Int): T = array[indexInArray(index)] as T
|
||||
|
||||
public override fun size() : Int = length
|
||||
|
||||
public override fun subList(fromIndex: Int, toIndex: Int) : List<T> {
|
||||
if (fromIndex < 0) {
|
||||
throw IllegalArgumentException("negative from index")
|
||||
}
|
||||
if (toIndex < fromIndex) {
|
||||
throw IllegalArgumentException("toIndex < fromIndex")
|
||||
}
|
||||
if (toIndex > length) {
|
||||
throw IllegalArgumentException("fromIndex + toIndex > length")
|
||||
}
|
||||
return ImmutableArrayList(array, offset + fromIndex, toIndex - fromIndex)
|
||||
}
|
||||
|
||||
// TODO: efficiently implement iterator and other stuff
|
||||
}
|
||||
|
||||
// TODO: make val, see http://youtrack.jetbrains.com/issue/KT-2028
|
||||
private fun emptyArray(): Array<Any?> = arrayOfNulls(0)
|
||||
|
||||
public class ImmutableArrayListBuilder<T>() {
|
||||
|
||||
private var array = emptyArray()
|
||||
private var length = 0
|
||||
|
||||
public fun build(): List<T> {
|
||||
val r = ImmutableArrayList<T>(array as Array<T>, 0, length)
|
||||
array = emptyArray()
|
||||
length = 0
|
||||
return r
|
||||
}
|
||||
|
||||
public fun ensureCapacity(capacity: Int) {
|
||||
if (array.size < capacity) {
|
||||
val newSize = Math.max(capacity, Math.max(array.size * 2, 11))
|
||||
array = array.copyOf(newSize)
|
||||
}
|
||||
}
|
||||
|
||||
public fun add(item: T) {
|
||||
ensureCapacity(length + 1)
|
||||
array[length] = item
|
||||
++length
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// default list builder
|
||||
fun <T> listBuilder() = ImmutableArrayListBuilder<T>()
|
||||
Reference in New Issue
Block a user