blob: b925317b3d29f359059ac42ee33545413a40df1c [file] [log] [blame]
/*
* Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
*/
package kotlinx.coroutines.internal
@Suppress("UNCHECKED_CAST")
internal class CopyOnWriteList<E>(private var array: Array<Any?> = arrayOfNulls(4)) : AbstractMutableList<E>() {
private var _size = 0
override val size: Int get() = _size
override fun add(element: E): Boolean {
val newSize = if (_size == array.size) array.size * 2 else array.size
val update = array.copyOf(newSize)
update[_size++] = element
array = update
return true
}
override fun add(index: Int, element: E) {
rangeCheck(index)
val update = arrayOfNulls<Any?>(if (array.size == _size) array.size * 2 else array.size)
array.copyInto(
destination = update,
endIndex = index
)
update[index] = element
array.copyInto(
destination = update,
destinationOffset = index + 1,
startIndex = index,
endIndex = _size + 1
)
++_size
array = update
}
override fun remove(element: E): Boolean {
val index = array.indexOf(element as Any)
if (index == -1) {
return false
}
removeAt(index)
return true
}
override fun removeAt(index: Int): E {
rangeCheck(index)
modCount++
val n = array.size
val element = array[index]
val update = arrayOfNulls<Any>(n)
array.copyInto(
destination = update,
endIndex = index
)
array.copyInto(
destination = update,
destinationOffset = index,
startIndex = index + 1,
endIndex = n
)
array = update
--_size
return element as E
}
override fun iterator(): MutableIterator<E> = IteratorImpl(array as Array<E>, size)
override fun listIterator(): MutableListIterator<E> = throw UnsupportedOperationException("Operation is not supported")
override fun listIterator(index: Int): MutableListIterator<E> = throw UnsupportedOperationException("Operation is not supported")
override fun isEmpty(): Boolean = size == 0
override fun set(index: Int, element: E): E = throw UnsupportedOperationException("Operation is not supported")
override fun get(index: Int): E = array[rangeCheck(index)]!! as E
private class IteratorImpl<E>(private var array: Array<E>, private val size: Int) : MutableIterator<E> {
private var current = 0
override fun hasNext(): Boolean = current != size
override fun next(): E {
if (!hasNext()) {
throw NoSuchElementException()
}
return array[current++]!!
}
override fun remove() = throw UnsupportedOperationException("Operation is not supported")
}
private fun rangeCheck(index: Int) = index.apply {
if (index < 0 || index >= _size) {
throw IndexOutOfBoundsException("index: $index, size: $size")
}
}
}