Use lambdas in stdlib. (#140)
This commit is contained in:
+4
-2
@@ -51,12 +51,14 @@ internal fun emitLLVM(context: Context) {
|
||||
LLVMWriteBitcodeToFile(llvmModule, outFile)
|
||||
}
|
||||
|
||||
internal fun verifyModule(llvmModule: LLVMModuleRef) {
|
||||
internal fun verifyModule(llvmModule: LLVMModuleRef, current: String = "") {
|
||||
memScoped {
|
||||
val errorRef = allocPointerTo<CInt8Var>()
|
||||
// TODO: use LLVMDisposeMessage() on errorRef, once possible in interop.
|
||||
if (LLVMVerifyModule(
|
||||
llvmModule, LLVMVerifierFailureAction.LLVMPrintMessageAction, errorRef.ptr) == 1) {
|
||||
if (current.length > 0)
|
||||
println("Error in ${current}")
|
||||
LLVMDumpModule(llvmModule)
|
||||
throw Error("Invalid module");
|
||||
}
|
||||
@@ -516,7 +518,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
||||
|
||||
codegen.epilogue(declaration)
|
||||
|
||||
verifyModule(context.llvmModule!!)
|
||||
verifyModule(context.llvmModule!!, ir2string(declaration))
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
@@ -149,7 +149,9 @@ KString Kotlin_String_plusImpl(KString thiz, KString other) {
|
||||
}
|
||||
|
||||
KBoolean Kotlin_String_equals(KString thiz, KConstRef other) {
|
||||
if (other == nullptr || other->type_info() != theStringTypeInfo) return 0;
|
||||
if (other == nullptr || other->type_info() != theStringTypeInfo) return false;
|
||||
// Important, due to literal internalization.
|
||||
if (thiz == other) return true;
|
||||
KString otherString = reinterpret_cast<KString>(other);
|
||||
return thiz->count_ == otherString->count_ &&
|
||||
memcmp(ByteArrayAddressOfElementAt(thiz, 0),
|
||||
|
||||
@@ -191,6 +191,7 @@ KInt Kotlin_Int_dec (KInt a ) { return --a; }
|
||||
KInt Kotlin_Int_unaryPlus (KInt a ) { return +a; }
|
||||
KInt Kotlin_Int_unaryMinus (KInt a ) { return -a; }
|
||||
|
||||
KInt Kotlin_Int_or_Int (KInt a, KInt b) { return a | b; }
|
||||
KInt Kotlin_Int_xor_Int (KInt a, KInt b) { return a ^ b; }
|
||||
KInt Kotlin_Int_and_Int (KInt a, KInt b) { return a & b; }
|
||||
KInt Kotlin_Int_shl_Int (KInt a, KInt b) { return a << b; }
|
||||
@@ -257,6 +258,8 @@ KLong Kotlin_Long_unaryPlus (KLong a ) { return +a; }
|
||||
KLong Kotlin_Long_unaryMinus (KLong a ) { return -a; }
|
||||
|
||||
KLong Kotlin_Long_xor_Long (KLong a, KLong b) { return a ^ b; }
|
||||
KLong Kotlin_Long_or_Long (KLong a, KLong b) { return a | b; }
|
||||
KLong Kotlin_Long_and_Long (KLong a, KLong b) { return a & b; }
|
||||
KLong Kotlin_Long_shr_Int (KLong a, KInt b) {
|
||||
return a >> b;
|
||||
}
|
||||
|
||||
@@ -23,3 +23,25 @@ annotation class ExportTypeInfo(val name: String)
|
||||
*/
|
||||
public annotation class Used
|
||||
|
||||
|
||||
// Following annotations can be used to mark functions that need to be fixed,
|
||||
// once certain language feature is implemented.
|
||||
/**
|
||||
* Need to be fixed because of boxing.
|
||||
*/
|
||||
public annotation class FixmeBoxing
|
||||
|
||||
/**
|
||||
* Need to be fixed because of inner classes.
|
||||
*/
|
||||
public annotation class FixmeInner
|
||||
|
||||
/**
|
||||
* Need to be fixed because of lambdas.
|
||||
*/
|
||||
public annotation class FixmeLambda
|
||||
|
||||
/**
|
||||
* Need to be fixed.
|
||||
*/
|
||||
public annotation class Fixme
|
||||
|
||||
@@ -47,6 +47,7 @@ public fun <T, C : MutableCollection<in T>> Array<out T>.toCollection(destinatio
|
||||
return destination
|
||||
}
|
||||
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline operator fun <T> Array<T>.plus(elements: Array<T>): Array<T> {
|
||||
val result = copyOfUninitializedElements(this.size + elements.size)
|
||||
elements.copyRangeTo(result, 0, elements.size, this.size)
|
||||
|
||||
@@ -333,3 +333,177 @@ private class BooleanIteratorImpl(val collection: BooleanArray) : BooleanIterato
|
||||
return index < collection.size
|
||||
}
|
||||
}
|
||||
|
||||
// This part is from generated _Arrays.kt.
|
||||
|
||||
/**
|
||||
* Returns `true` if array has at least one element.
|
||||
*/
|
||||
public fun <T> Array<out T>.any(): Boolean {
|
||||
for (element in this) return true
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns `true` if at least one element matches the given [predicate].
|
||||
*/
|
||||
public inline fun <T> Array<out T>.any(predicate: (T) -> Boolean): Boolean {
|
||||
for (element in this) if (predicate(element)) return true
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns `true` if all elements match the given [predicate].
|
||||
*/
|
||||
public inline fun <T> Array<out T>.all(predicate: (T) -> Boolean): Boolean {
|
||||
for (element in this) if (!predicate(element)) return false
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns `true` if [element] is found in the array.
|
||||
*/
|
||||
public operator fun <@kotlin.internal.OnlyInputTypes T> Array<out T>.contains(element: T): Boolean {
|
||||
return indexOf(element) >= 0
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns first index of [element], or -1 if the array does not contain element.
|
||||
*/
|
||||
public fun <@kotlin.internal.OnlyInputTypes T> Array<out T>.indexOf(element: T): Int {
|
||||
if (element == null) {
|
||||
for (index in indices) {
|
||||
if (this[index] == null) {
|
||||
return index
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (index in indices) {
|
||||
if (element == this[index]) {
|
||||
return index
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns index of the first element matching the given [predicate], or -1 if the array does not contain such element.
|
||||
*/
|
||||
public inline fun <T> Array<out T>.indexOfFirst(predicate: (T) -> Boolean): Int {
|
||||
for (index in indices) {
|
||||
if (predicate(this[index])) {
|
||||
return index
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns index of the last element matching the given [predicate], or -1 if the array does not contain such element.
|
||||
*/
|
||||
public inline fun <T> Array<out T>.indexOfLast(predicate: (T) -> Boolean): Int {
|
||||
for (index in indices.reversed()) {
|
||||
if (predicate(this[index])) {
|
||||
return index
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list containing all elements not matching the given [predicate].
|
||||
*/
|
||||
public inline fun <T> Array<out T>.filterNot(predicate: (T) -> Boolean): List<T> {
|
||||
return filterNotTo(ArrayList<T>(), predicate)
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends all elements not matching the given [predicate] to the given [destination].
|
||||
*/
|
||||
public inline fun <T, C : MutableCollection<in T>> Array<out T>.filterNotTo(destination: C, predicate: (T) -> Boolean): C {
|
||||
for (element in this) if (!predicate(element)) destination.add(element)
|
||||
return destination
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list containing all elements that are not `null`.
|
||||
*/
|
||||
public fun <T : Any> Array<out T?>.filterNotNull(): List<T> {
|
||||
return filterNotNullTo(ArrayList<T>())
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends all elements that are not `null` to the given [destination].
|
||||
*/
|
||||
public fun <C : MutableCollection<in T>, T : Any> Array<out T?>.filterNotNullTo(destination: C): C {
|
||||
for (element in this) if (element != null) destination.add(element)
|
||||
return destination
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first element matching the given [predicate], or `null` if no such element was found.
|
||||
*/
|
||||
public inline fun <T> Array<out T>.find(predicate: (T) -> Boolean): T? {
|
||||
return firstOrNull(predicate)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last element matching the given [predicate], or `null` if no such element was found.
|
||||
*/
|
||||
public inline fun <T> Array<out T>.findLast(predicate: (T) -> Boolean): T? {
|
||||
return lastOrNull(predicate)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first element, or `null` if the array is empty.
|
||||
*/
|
||||
public fun <T> Array<out T>.firstOrNull(): T? {
|
||||
return if (isEmpty()) null else this[0]
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first element matching the given [predicate], or `null` if element was not found.
|
||||
*/
|
||||
public inline fun <T> Array<out T>.firstOrNull(predicate: (T) -> Boolean): T? {
|
||||
for (element in this) if (predicate(element)) return element
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last element, or `null` if the array is empty.
|
||||
*/
|
||||
public fun <T> Array<out T>.lastOrNull(): T? {
|
||||
return if (isEmpty()) null else this[size - 1]
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last element matching the given [predicate], or `null` if no such element was found.
|
||||
*/
|
||||
public inline fun <T> Array<out T>.lastOrNull(predicate: (T) -> Boolean): T? {
|
||||
for (index in this.indices.reversed()) {
|
||||
val element = this[index]
|
||||
if (predicate(element)) return element
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns `true` if the array is empty.
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline fun <T> Array<out T>.isEmpty(): Boolean {
|
||||
return size == 0
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the range of valid indices for the array.
|
||||
*/
|
||||
public val <T> Array<out T>.indices: IntRange
|
||||
get() = IntRange(0, lastIndex)
|
||||
|
||||
/**
|
||||
* Returns the last valid index for the array.
|
||||
*/
|
||||
public val <T> Array<out T>.lastIndex: Int
|
||||
get() = size - 1
|
||||
|
||||
@@ -136,13 +136,4 @@ public class AssertionError : Error {
|
||||
|
||||
constructor(message: String, cause: Throwable) : super(message, cause) {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: does it belong here?
|
||||
fun TODO() {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
fun TODO(message: String) {
|
||||
throw UnsupportedOperationException(message)
|
||||
}
|
||||
@@ -4,7 +4,6 @@ public abstract class AbstractCollection<out E> protected constructor() : Collec
|
||||
abstract override val size: Int
|
||||
abstract override fun iterator(): Iterator<E>
|
||||
|
||||
/* TODO: uncomment, once can support lambdas.
|
||||
override fun contains(element: @UnsafeVariance E): Boolean = any { it == element }
|
||||
|
||||
override fun containsAll(elements: Collection<@UnsafeVariance E>): Boolean =
|
||||
@@ -12,8 +11,8 @@ public abstract class AbstractCollection<out E> protected constructor() : Collec
|
||||
|
||||
override fun isEmpty(): Boolean = size == 0
|
||||
|
||||
/*
|
||||
override fun toString(): String = joinToString(", ", "[", "]") {
|
||||
if (it === this) "(this Collection)" else it.toString()
|
||||
} */
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Based on GWT AbstractList
|
||||
* Copyright 2007 Google Inc.
|
||||
*/
|
||||
package kotlin.collections
|
||||
|
||||
public abstract class AbstractList<out E> protected constructor() : AbstractCollection<E>(), List<E> {
|
||||
abstract override val size: Int
|
||||
abstract override fun get(index: Int): E
|
||||
|
||||
// TODO: fix once have inner classes.
|
||||
@FixmeInner
|
||||
override fun iterator(): Iterator<E> = TODO() // IteratorImpl()
|
||||
|
||||
override fun indexOf(element: @UnsafeVariance E): Int = indexOfFirst { it == element }
|
||||
|
||||
override fun lastIndexOf(element: @UnsafeVariance E): Int = indexOfLast { it == element }
|
||||
|
||||
// TODO: fix once have inner classes.
|
||||
@FixmeInner
|
||||
override fun listIterator(): ListIterator<E> = TODO() // ListIteratorImpl(0)
|
||||
|
||||
@FixmeInner
|
||||
override fun listIterator(index: Int): ListIterator<E> = TODO() // 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)
|
||||
|
||||
// TODO: enable, once have inner classes.
|
||||
/*
|
||||
private 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
|
||||
|
||||
override fun hasNext(): Boolean = index < size
|
||||
|
||||
override fun next(): E {
|
||||
if (!hasNext()) throw NoSuchElementException()
|
||||
return get(index++)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of `MutableListIterator` for abstract lists.
|
||||
*/
|
||||
private 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()
|
||||
return get(--index)
|
||||
}
|
||||
|
||||
override fun previousIndex(): Int = index - 1
|
||||
} */
|
||||
|
||||
internal 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 + (if (e != null) e.hashCode() else 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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -34,7 +34,7 @@ fun IntArray.copyOfUninitializedElements(newSize: Int): IntArray {
|
||||
* either throwing exception or returning some kind of implementation-specific default value.
|
||||
*/
|
||||
fun <E> Array<E>.resetAt(index: Int) {
|
||||
(this as Array<Any?>)[index] = null
|
||||
(@Suppress("UNCHECKED_CAST")(this as Array<Any?>))[index] = null
|
||||
}
|
||||
|
||||
@SymbolName("Kotlin_Array_fillImpl")
|
||||
@@ -51,7 +51,7 @@ external private fun fillImpl(array: IntArray, fromIndex: Int, toIndex: Int, val
|
||||
* either throwing exception or returning some kind of implementation-specific default value.
|
||||
*/
|
||||
fun <E> Array<E>.resetRange(fromIndex: Int, toIndex: Int) {
|
||||
fillImpl(this as Array<Any>, fromIndex, toIndex, null)
|
||||
fillImpl(@Suppress("UNCHECKED_CAST") (this as Array<Any>), fromIndex, toIndex, null)
|
||||
}
|
||||
|
||||
fun IntArray.fill(fromIndex: Int, toIndex: Int, value: Int) {
|
||||
@@ -71,7 +71,9 @@ external private fun copyImpl(array: IntArray, fromIndex: Int,
|
||||
* to another [destination] array starting at [destinationIndex].
|
||||
*/
|
||||
fun <E> Array<E>.copyRangeTo(destination: Array<E>, fromIndex: Int, toIndex: Int, destinationIndex: Int = 0) {
|
||||
copyImpl(this as Array<Any>, fromIndex, destination as Array<Any>, destinationIndex, toIndex - fromIndex)
|
||||
copyImpl(@Suppress("UNCHECKED_CAST") (this as Array<Any>), fromIndex,
|
||||
@Suppress("UNCHECKED_CAST") (destination as Array<Any>),
|
||||
destinationIndex, toIndex - fromIndex)
|
||||
}
|
||||
|
||||
fun IntArray.copyRangeTo(destination: IntArray, fromIndex: Int, toIndex: Int, destinationIndex: Int = 0) {
|
||||
|
||||
@@ -39,6 +39,90 @@ internal object EmptyList : List<Nothing>/*, RandomAccess */ {
|
||||
private fun readResolve(): Any = EmptyList
|
||||
}
|
||||
|
||||
internal fun <T> Array<out T>.asCollection(): Collection<T> = ArrayAsCollection(this, isVarargs = false)
|
||||
|
||||
private class ArrayAsCollection<T>(val values: Array<out T>, val isVarargs: Boolean): Collection<T> {
|
||||
override val size: Int get() = values.size
|
||||
override fun isEmpty(): Boolean = values.isEmpty()
|
||||
override fun contains(element: T): Boolean = values.contains(element)
|
||||
override fun containsAll(elements: Collection<T>): Boolean = elements.all { contains(it) }
|
||||
override fun iterator(): Iterator<T> = values.iterator()
|
||||
// override hidden toArray implementation to prevent copying of values array
|
||||
public fun toArray(): Array<out Any?> = values.copyToArrayOfAny(isVarargs)
|
||||
}
|
||||
|
||||
/** Returns an empty read-only list. */
|
||||
public fun <T> emptyList(): List<T> = EmptyList
|
||||
|
||||
/** Returns a new read-only list of given elements. */
|
||||
public fun <T> listOf(vararg elements: T): List<T> = if (elements.size > 0) elements.asList() else emptyList()
|
||||
|
||||
/** Returns an empty read-only list. */
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline fun <T> listOf(): List<T> = emptyList()
|
||||
|
||||
/** Returns a new [MutableList] with the given elements. */
|
||||
public fun <T> mutableListOf(vararg elements: T): MutableList<T>
|
||||
= if (elements.size == 0) ArrayList() else ArrayList(ArrayAsCollection(elements, isVarargs = true))
|
||||
|
||||
// This part is from generated _Collections.kt.
|
||||
|
||||
/** Returns a new [ArrayList] with the given elements. */
|
||||
public fun <T> arrayListOf(vararg elements: T): ArrayList<T>
|
||||
= if (elements.size == 0) ArrayList() else ArrayList(ArrayAsCollection(elements, isVarargs = true))
|
||||
|
||||
/** Returns a new read-only list either of single given element, if it is not null,
|
||||
* or empty list it the element is null.*/
|
||||
public fun <T : Any> listOfNotNull(element: T?): List<T> =
|
||||
if (element != null) listOf(element) else emptyList()
|
||||
|
||||
/** Returns a new read-only list only of those given elements, that are not null. */
|
||||
public fun <T : Any> listOfNotNull(vararg elements: T?): List<T> = elements.filterNotNull()
|
||||
|
||||
/**
|
||||
* Returns an [IntRange] of the valid indices for this collection.
|
||||
*/
|
||||
public val Collection<*>.indices: IntRange
|
||||
get() = 0..size - 1
|
||||
|
||||
/**
|
||||
* Returns the index of the last item in the list or -1 if the list is empty.
|
||||
*
|
||||
* @sample samples.collections.Collections.Lists.lastIndexOfList
|
||||
*/
|
||||
public val <T> List<T>.lastIndex: Int
|
||||
get() = this.size - 1
|
||||
|
||||
/** Returns `true` if the collection is not empty. */
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline fun <T> Collection<T>.isNotEmpty(): Boolean = !isEmpty()
|
||||
|
||||
/** Returns this Collection if it's not `null` and the empty list otherwise. */
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline fun <T> Collection<T>?.orEmpty(): Collection<T> = this ?: emptyList()
|
||||
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline fun <T> List<T>?.orEmpty(): List<T> = this ?: emptyList()
|
||||
|
||||
/**
|
||||
* Checks if all elements in the specified collection are contained in this collection.
|
||||
*
|
||||
* Allows to overcome type-safety restriction of `containsAll` that requires to pass a collection of type `Collection<E>`.
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline fun <@kotlin.internal.OnlyInputTypes T> Collection<T>.containsAll(
|
||||
elements: Collection<T>): Boolean = this.containsAll(elements)
|
||||
|
||||
// copies typed varargs array to array of objects
|
||||
// TODO: generally wrong, wrt specialization.
|
||||
@Fixme
|
||||
private fun <T> Array<out T>.copyToArrayOfAny(isVarargs: Boolean): Array<Any?> =
|
||||
if (isVarargs)
|
||||
// if the array came from varargs and already is array of Any, copying isn't required.
|
||||
@Suppress("UNCHECKED_CAST") (this as Array<Any?>)
|
||||
else
|
||||
@Suppress("UNCHECKED_CAST") (this.copyOfUninitializedElements(this.size) as Array<Any?>)
|
||||
|
||||
|
||||
/**
|
||||
* Classes that inherit from this interface can be represented as a sequence of elements that can
|
||||
@@ -63,6 +147,61 @@ public interface MutableIterable<out T> : Iterable<T> {
|
||||
override fun iterator(): MutableIterator<T>
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns `true` if all elements match the given [predicate].
|
||||
*/
|
||||
public inline fun <T> Iterable<T>.all(predicate: (T) -> Boolean): Boolean {
|
||||
for (element in this) if (!predicate(element)) return false
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns `true` if collection has at least one element.
|
||||
*/
|
||||
public fun <T> Iterable<T>.any(): Boolean {
|
||||
for (element in this) return true
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns `true` if at least one element matches the given [predicate].
|
||||
*/
|
||||
public inline fun <T> Iterable<T>.any(predicate: (T) -> Boolean): Boolean {
|
||||
for (element in this) if (predicate(element)) return true
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list containing all elements not matching the given [predicate].
|
||||
*/
|
||||
public inline fun <T> Iterable<T>.filterNot(predicate: (T) -> Boolean): List<T> {
|
||||
return filterNotTo(ArrayList<T>(), predicate)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list containing all elements that are not `null`.
|
||||
*/
|
||||
public fun <T : Any> Iterable<T?>.filterNotNull(): List<T> {
|
||||
return filterNotNullTo(ArrayList<T>())
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends all elements that are not `null` to the given [destination].
|
||||
*/
|
||||
public fun <C : MutableCollection<in T>, T : Any> Iterable<T?>.filterNotNullTo(destination: C): C {
|
||||
for (element in this) if (element != null) destination.add(element)
|
||||
return destination
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends all elements not matching the given [predicate] to the given [destination].
|
||||
*/
|
||||
public inline fun <T, C : MutableCollection<in T>> Iterable<T>.filterNotTo(destination: C, predicate: (T) -> Boolean): C {
|
||||
for (element in this) if (!predicate(element)) destination.add(element)
|
||||
return destination
|
||||
}
|
||||
|
||||
|
||||
fun <E> Array<E>.asList(): List<E> {
|
||||
// TODO: consider making lighter list over an array.
|
||||
val result = ArrayList<E>(this.size)
|
||||
@@ -71,6 +210,17 @@ fun <E> Array<E>.asList(): List<E> {
|
||||
}
|
||||
return result
|
||||
}
|
||||
/* TODO: use this one!
|
||||
public fun <T> Array<out T>.asList(): List<T> {
|
||||
return object : AbstractList<T>() {
|
||||
override val size: Int get() = this@asList.size
|
||||
override fun isEmpty(): Boolean = this@asList.isEmpty()
|
||||
override fun contains(element: T): Boolean = this@asList.contains(element)
|
||||
override fun get(index: Int): T = this@asList[index]
|
||||
override fun indexOf(element: T): Int = this@asList.indexOf(element)
|
||||
override fun lastIndexOf(element: T): Int = this@asList.lastIndexOf(element)
|
||||
}
|
||||
} */
|
||||
|
||||
fun <E> Array<E>.toSet(): Set<E> {
|
||||
val result = HashSet<E>(this.size)
|
||||
@@ -80,21 +230,63 @@ fun <E> Array<E>.toSet(): Set<E> {
|
||||
return result
|
||||
}
|
||||
|
||||
public fun <T> arrayListOf(vararg args: T): MutableList<T> {
|
||||
val result = ArrayList<T>(args.size)
|
||||
for (arg in args) {
|
||||
result.add(arg)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
public fun <T> listOf(): List<T> = EmptyList
|
||||
|
||||
public fun <T> listOf(vararg args: T): List<T> = args.asList()
|
||||
|
||||
public fun <T, C : MutableCollection</*in */T>> Iterable<T>.toCollection(destination: C): C {
|
||||
for (item in this) {
|
||||
destination.add(item)
|
||||
}
|
||||
return destination
|
||||
}
|
||||
|
||||
// From generated _Collections.kt.
|
||||
/**
|
||||
* Returns index of the first element matching the given [predicate], or -1 if the collection does not contain such element.
|
||||
*/
|
||||
public inline fun <T> Iterable<T>.indexOfFirst(predicate: (T) -> Boolean): Int {
|
||||
var index = 0
|
||||
for (item in this) {
|
||||
if (predicate(item))
|
||||
return index
|
||||
index++
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns index of the first element matching the given [predicate], or -1 if the list does not contain such element.
|
||||
*/
|
||||
public inline fun <T> List<T>.indexOfFirst(predicate: (T) -> Boolean): Int {
|
||||
var index = 0
|
||||
for (item in this) {
|
||||
if (predicate(item))
|
||||
return index
|
||||
index++
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns index of the last element matching the given [predicate], or -1 if the collection does not contain such element.
|
||||
*/
|
||||
public inline fun <T> Iterable<T>.indexOfLast(predicate: (T) -> Boolean): Int {
|
||||
var lastIndex = -1
|
||||
var index = 0
|
||||
for (item in this) {
|
||||
if (predicate(item))
|
||||
lastIndex = index
|
||||
index++
|
||||
}
|
||||
return lastIndex
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns index of the last element matching the given [predicate], or -1 if the list does not contain such element.
|
||||
*/
|
||||
public inline fun <T> List<T>.indexOfLast(predicate: (T) -> Boolean): Int {
|
||||
val iterator = this.listIterator(size)
|
||||
while (iterator.hasPrevious()) {
|
||||
if (predicate(iterator.previous())) {
|
||||
return iterator.nextIndex()
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
@@ -64,7 +64,8 @@ class HashSet<K> internal constructor(
|
||||
override fun equals(other: Any?): Boolean {
|
||||
return other === this ||
|
||||
(other is Set<*>) &&
|
||||
contentEquals(other as Set<K>)
|
||||
contentEquals(
|
||||
@Suppress("UNCHECKED_CAST") (other as Set<K>))
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
|
||||
@@ -22,7 +22,7 @@ private object EmptyMap : Map<Any?, Nothing> {
|
||||
* Returns an empty read-only map of specified type. The returned map is serializable (JVM).
|
||||
* @sample samples.collections.Maps.Instantiation.emptyReadOnlyMap
|
||||
*/
|
||||
public fun <K, V> emptyMap(): Map<K, V> = @Suppress("UNCHECKED_CAST") (EmptyMap as Map<K, V>)
|
||||
public fun <K, V> emptyMap(): Map<K, V> = EmptyMap as Map<K, V>
|
||||
|
||||
/**
|
||||
* Returns a new read-only map with the specified contents, given as a list of pairs
|
||||
@@ -34,12 +34,14 @@ public fun <K, V> emptyMap(): Map<K, V> = @Suppress("UNCHECKED_CAST") (EmptyMap
|
||||
*
|
||||
* @sample samples.collections.Maps.Instantiation.mapFromPairs
|
||||
*/
|
||||
public fun <K, V> mapOf(vararg pairs: Pair<K, V>): Map<K, V> = if (pairs.size > 0) hashMapOf(*pairs) else emptyMap()
|
||||
public fun <K, V> mapOf(vararg pairs: Pair<K, V>): Map<K, V> =
|
||||
if (pairs.size > 0) hashMapOf(*pairs) else emptyMap()
|
||||
|
||||
/**
|
||||
* Returns an empty read-only map. The returned map is serializable (JVM).
|
||||
* @sample samples.collections.Maps.Instantiation.emptyReadOnlyMap
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline fun <K, V> mapOf(): Map<K, V> = emptyMap()
|
||||
|
||||
/**
|
||||
@@ -57,6 +59,7 @@ public inline fun <K, V> mapOf(): Map<K, V> = emptyMap()
|
||||
* @sample samples.collections.Maps.Instantiation.mutableMapFromPairs
|
||||
* @sample samples.collections.Maps.Instantiation.emptyMutableMap
|
||||
*/
|
||||
@Fixme
|
||||
public fun <K, V> mutableMapOf(vararg pairs: Pair<K, V>): MutableMap<K, V> = hashMapOf(*pairs)
|
||||
// = HashMap<K, V>(mapCapacity(pairs.size)).apply { putAll(pairs) }
|
||||
|
||||
@@ -100,25 +103,30 @@ internal fun mapCapacity(expectedSize: Int): Int {
|
||||
return Int.MAX_VALUE // any large value
|
||||
}
|
||||
|
||||
@Fixme
|
||||
private const val INT_MAX_POWER_OF_TWO: Int = 0x40000000 // Int.MAX_VALUE / 2 + 1
|
||||
|
||||
/** Returns `true` if this map is not empty. */
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline fun <K, V> Map<out K, V>.isNotEmpty(): Boolean = !isEmpty()
|
||||
|
||||
/**
|
||||
* Returns the [Map] if its not `null`, or the empty [Map] otherwise.
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline fun <K, V> Map<K, V>?.orEmpty() : Map<K, V> = this ?: emptyMap()
|
||||
|
||||
/**
|
||||
* Checks if the map contains the given key. This method allows to use the `x in map` syntax for checking
|
||||
* whether an object is contained in the map.
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline operator fun <@kotlin.internal.OnlyInputTypes K, V> Map<out K, V>.contains(key: K) : Boolean = containsKey(key)
|
||||
|
||||
/**
|
||||
* Returns the value corresponding to the given [key], or `null` if such a key is not present in the map.
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline operator fun <@kotlin.internal.OnlyInputTypes K, V> Map<out K, V>.get(key: K): V?
|
||||
= @Suppress("UNCHECKED_CAST") (this as Map<K, V>).get(key)
|
||||
|
||||
@@ -127,6 +135,7 @@ public inline operator fun <@kotlin.internal.OnlyInputTypes K, V> Map<out K, V>.
|
||||
*
|
||||
* Allows to overcome type-safety restriction of `containsKey` that requires to pass a key of type `K`.
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline fun <@kotlin.internal.OnlyInputTypes K> Map<out K, *>.containsKey(key: K): Boolean
|
||||
= @Suppress("UNCHECKED_CAST") (this as Map<K, *>).containsKey(key)
|
||||
|
||||
@@ -135,6 +144,7 @@ public inline fun <@kotlin.internal.OnlyInputTypes K> Map<out K, *>.containsKey(
|
||||
*
|
||||
* Allows to overcome type-safety restriction of `containsValue` that requires to pass a value of type `V`.
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline fun <K, @kotlin.internal.OnlyInputTypes V> Map<K, V>.containsValue(value: V): Boolean = this.containsValue(value)
|
||||
|
||||
|
||||
@@ -145,6 +155,7 @@ public inline fun <K, @kotlin.internal.OnlyInputTypes V> Map<K, V>.containsValue
|
||||
|
||||
* Allows to overcome type-safety restriction of `remove` that requires to pass a key of type `K`.
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline fun <@kotlin.internal.OnlyInputTypes K, V> MutableMap<out K, V>.remove(key: K): V?
|
||||
= @Suppress("UNCHECKED_CAST") (this as MutableMap<K, V>).remove(key)
|
||||
|
||||
@@ -158,6 +169,7 @@ public inline fun <@kotlin.internal.OnlyInputTypes K, V> MutableMap<out K, V>.re
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline operator fun <K, V> Map.Entry<K, V>.component1(): K = key
|
||||
|
||||
/**
|
||||
@@ -169,11 +181,13 @@ public inline operator fun <K, V> Map.Entry<K, V>.component1(): K = key
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline operator fun <K, V> Map.Entry<K, V>.component2(): V = value
|
||||
|
||||
/**
|
||||
* Converts entry to [Pair] with key being first component and value being second.
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline fun <K, V> Map.Entry<K, V>.toPair(): Pair<K, V> = Pair(key, value)
|
||||
|
||||
/**
|
||||
@@ -184,7 +198,10 @@ public inline fun <K, V> Map.Entry<K, V>.toPair(): Pair<K, V> = Pair(key, value)
|
||||
public inline fun <K, V> Map<K, V>.getOrElse(key: K, defaultValue: () -> V): V = get(key) ?: defaultValue()
|
||||
|
||||
|
||||
//internal inline fun <K, V> Map<K, V>.getOrElseNullable(key: K, defaultValue: () -> V): V {
|
||||
@Fixme
|
||||
internal inline fun <K, V> Map<K, V>.getOrElseNullable(key: K, defaultValue: () -> V): V {
|
||||
TODO()
|
||||
}
|
||||
// val value = get(key)
|
||||
// if (value == null && !containsKey(key)) {
|
||||
// return defaultValue()
|
||||
@@ -217,21 +234,26 @@ public inline fun <K, V> MutableMap<K, V>.getOrPut(key: K, defaultValue: () -> V
|
||||
*
|
||||
* @sample samples.collections.Maps.Usage.forOverEntries
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline operator fun <K, V> Map<out K, V>.iterator(): Iterator<Map.Entry<K, V>> = entries.iterator()
|
||||
|
||||
/**
|
||||
* Returns a [MutableIterator] over the mutable entries in the [MutableMap].
|
||||
*
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline operator fun <K, V> MutableMap<K, V>.iterator(): MutableIterator<MutableMap.MutableEntry<K, V>> = entries.iterator()
|
||||
|
||||
/**
|
||||
* Populates the given [destination] map with entries having the keys of this map and the values obtained
|
||||
* by applying the [transform] function to each entry in this [Map].
|
||||
*/
|
||||
//public inline fun <K, V, R, M : MutableMap<in K, in R>> Map<out K, V>.mapValuesTo(destination: M, transform: (Map.Entry<K, V>) -> R): M {
|
||||
@Fixme
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline fun <K, V, R, M : MutableMap<in K, in R>> Map<out K, V>.mapValuesTo(destination: M, transform: (Map.Entry<K, V>) -> R): M {
|
||||
TODO()
|
||||
// return entries.associateByTo(destination, { it.key }, transform)
|
||||
//}
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates the given [destination] map with entries having the keys obtained
|
||||
@@ -240,9 +262,11 @@ public inline operator fun <K, V> MutableMap<K, V>.iterator(): MutableIterator<M
|
||||
* In case if any two entries are mapped to the equal keys, the value of the latter one will overwrite
|
||||
* the value associated with the former one.
|
||||
*/
|
||||
//public inline fun <K, V, R, M : MutableMap<in R, in V>> Map<out K, V>.mapKeysTo(destination: M, transform: (Map.Entry<K, V>) -> R): M {
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline fun <K, V, R, M : MutableMap<in R, in V>> Map<out K, V>.mapKeysTo(destination: M, transform: (Map.Entry<K, V>) -> R): M {
|
||||
TODO()
|
||||
// return entries.associateByTo(destination, transform, { it.value })
|
||||
//}
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts all the given [pairs] into this [MutableMap] with the first component in the pair being the key and the second the value.
|
||||
@@ -463,21 +487,17 @@ public fun <K, V> Map</*out */K, V>.toMutableMap(): MutableMap<K, V> = HashMap(t
|
||||
/**
|
||||
* Populates and returns the [destination] mutable map with key-value pairs from the given map.
|
||||
*/
|
||||
public fun <K, V, M : MutableMap<in K, in V>> Map<out K, V>.toMap(destination: M): M {
|
||||
for (key in keys) {
|
||||
destination.put(key, get(key)!!)
|
||||
}
|
||||
return destination
|
||||
}
|
||||
// = destination.apply { putAll(this@toMap) }
|
||||
public fun <K, V, M : MutableMap<in K, in V>> Map<out K, V>.toMap(destination: M): M
|
||||
= destination.apply { putAll(this@toMap) }
|
||||
|
||||
// TODO: fix me, once have correct type variance in HashMap.
|
||||
/**
|
||||
* Creates a new read-only map by replacing or adding an entry to this map from a given key-value [pair].
|
||||
*
|
||||
* The returned map preserves the entry iteration order of the original map.
|
||||
* The [pair] is iterated in the end if it has a unique key.
|
||||
*/
|
||||
//public operator fun <K, V> Map<out K, V>.plus(pair: Pair<K, V>): Map<K, V>
|
||||
// public operator fun <K, V> Map<out K, V>.plus(pair: Pair<K, V>): Map<K, V>
|
||||
// = if (this.isEmpty()) mapOf(pair) else HashMap(this).apply { put(pair.first, pair.second) }
|
||||
|
||||
/**
|
||||
@@ -516,10 +536,10 @@ public fun <K, V, M : MutableMap<in K, in V>> Map<out K, V>.toMap(destination: M
|
||||
//public operator fun <K, V> Map<out K, V>.plus(map: Map<out K, V>): Map<K, V>
|
||||
// = HashMap(this).apply { putAll(map) }
|
||||
|
||||
|
||||
/**
|
||||
* Appends or replaces the given [pair] in this mutable map.
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline operator fun <K, V> MutableMap<in K, in V>.plusAssign(pair: Pair<K, V>) {
|
||||
put(pair.first, pair.second)
|
||||
}
|
||||
@@ -527,6 +547,7 @@ public inline operator fun <K, V> MutableMap<in K, in V>.plusAssign(pair: Pair<K
|
||||
/**
|
||||
* Appends or replaces all pairs from the given collection of [pairs] in this mutable map.
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline operator fun <K, V> MutableMap<in K, in V>.plusAssign(pairs: Iterable<Pair<K, V>>) {
|
||||
putAll(pairs)
|
||||
}
|
||||
@@ -534,6 +555,7 @@ public inline operator fun <K, V> MutableMap<in K, in V>.plusAssign(pairs: Itera
|
||||
/**
|
||||
* Appends or replaces all pairs from the given array of [pairs] in this mutable map.
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline operator fun <K, V> MutableMap<in K, in V>.plusAssign(pairs: Array<out Pair<K, V>>) {
|
||||
putAll(pairs)
|
||||
}
|
||||
@@ -541,6 +563,7 @@ public inline operator fun <K, V> MutableMap<in K, in V>.plusAssign(pairs: Array
|
||||
/**
|
||||
* Appends or replaces all pairs from the given sequence of [pairs] in this mutable map.
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline operator fun <K, V> MutableMap<in K, in V>.plusAssign(pairs: Sequence<Pair<K, V>>) {
|
||||
putAll(pairs)
|
||||
}
|
||||
@@ -548,11 +571,11 @@ public inline operator fun <K, V> MutableMap<in K, in V>.plusAssign(pairs: Seque
|
||||
/**
|
||||
* Appends or replaces all entries from the given [map] in this mutable map.
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline operator fun <K, V> MutableMap<in K, in V>.plusAssign(map: Map<K, V>) {
|
||||
putAll(map)
|
||||
}
|
||||
|
||||
|
||||
// do not expose for now @kotlin.internal.InlineExposed
|
||||
internal fun <K, V> Map<K, V>.optimizeReadOnlyMap() = when (size) {
|
||||
0 -> emptyMap()
|
||||
@@ -566,3 +589,128 @@ internal fun <K, V> Map<K, V>.optimizeReadOnlyMap() = when (size) {
|
||||
// creates a singleton copy of map
|
||||
//internal fun <K, V> Map<out K, V>.toSingletonMap(): Map<K, V>
|
||||
// = with (entries.iterator().next()) { java.util.Collections.singletonMap(key, value) }
|
||||
|
||||
// This is from generated _Maps.kt.
|
||||
/**
|
||||
* Returns a [List] containing all key-value pairs.
|
||||
*/
|
||||
public fun <K, V> Map<out K, V>.toList(): List<Pair<K, V>> {
|
||||
if (size == 0)
|
||||
return emptyList()
|
||||
val iterator = entries.iterator()
|
||||
if (!iterator.hasNext())
|
||||
return emptyList()
|
||||
val first = iterator.next()
|
||||
if (!iterator.hasNext())
|
||||
return listOf(first.toPair())
|
||||
val result = ArrayList<Pair<K, V>>(size)
|
||||
result.add(first.toPair())
|
||||
do {
|
||||
result.add(iterator.next().toPair())
|
||||
} while (iterator.hasNext())
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a single list of all elements yielded from results of [transform] function being invoked on each entry of original map.
|
||||
*/
|
||||
public inline fun <K, V, R> Map<out K, V>.flatMap(transform: (Map.Entry<K, V>) -> Iterable<R>): List<R> {
|
||||
return flatMapTo(ArrayList<R>(), transform)
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends all elements yielded from results of [transform] function being invoked on each entry of original map, to the given [destination].
|
||||
*/
|
||||
public inline fun <K, V, R, C : MutableCollection<in R>> Map<out K, V>.flatMapTo(destination: C, transform: (Map.Entry<K, V>) -> Iterable<R>): C {
|
||||
for (element in this) {
|
||||
val list = transform(element)
|
||||
destination.addAll(list)
|
||||
}
|
||||
return destination
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list containing the results of applying the given [transform] function
|
||||
* to each entry in the original map.
|
||||
*/
|
||||
public inline fun <K, V, R> Map<out K, V>.map(transform: (Map.Entry<K, V>) -> R): List<R> {
|
||||
return mapTo(ArrayList<R>(size), transform)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list containing only the non-null results of applying the given [transform] function
|
||||
* to each entry in the original map.
|
||||
*/
|
||||
public inline fun <K, V, R : Any> Map<out K, V>.mapNotNull(transform: (Map.Entry<K, V>) -> R?): List<R> {
|
||||
return mapNotNullTo(ArrayList<R>(), transform)
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the given [transform] function to each entry in the original map
|
||||
* and appends only the non-null results to the given [destination].
|
||||
*/
|
||||
@FixmeLambda
|
||||
public inline fun <K, V, R : Any, C : MutableCollection<in R>> Map<out K, V>.mapNotNullTo(destination: C, transform: (Map.Entry<K, V>) -> R?): C {
|
||||
TODO()
|
||||
//forEach { element -> transform(element)?.let { destination.add(it) } }
|
||||
//return destination
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the given [transform] function to each entry of the original map
|
||||
* and appends the results to the given [destination].
|
||||
*/
|
||||
public inline fun <K, V, R, C : MutableCollection<in R>> Map<out K, V>.mapTo(destination: C, transform: (Map.Entry<K, V>) -> R): C {
|
||||
for (item in this)
|
||||
destination.add(transform(item))
|
||||
return destination
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns `true` if all entries match the given [predicate].
|
||||
*/
|
||||
public inline fun <K, V> Map<out K, V>.all(predicate: (Map.Entry<K, V>) -> Boolean): Boolean {
|
||||
for (element in this) if (!predicate(element)) return false
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns `true` if map has at least one entry.
|
||||
*/
|
||||
public fun <K, V> Map<out K, V>.any(): Boolean {
|
||||
for (element in this) return true
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns `true` if at least one entry matches the given [predicate].
|
||||
*/
|
||||
public inline fun <K, V> Map<out K, V>.any(predicate: (Map.Entry<K, V>) -> Boolean): Boolean {
|
||||
for (element in this) if (predicate(element)) return true
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of entries in this map.
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline fun <K, V> Map<out K, V>.count(): Int {
|
||||
return size
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of entries matching the given [predicate].
|
||||
*/
|
||||
public inline fun <K, V> Map<out K, V>.count(predicate: (Map.Entry<K, V>) -> Boolean): Int {
|
||||
var count = 0
|
||||
for (element in this) if (predicate(element)) count++
|
||||
return count
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the given [action] on each entry.
|
||||
*/
|
||||
@kotlin.internal.HidesMembers
|
||||
public inline fun <K, V> Map<out K, V>.forEach(action: (Map.Entry<K, V>) -> Unit): Unit {
|
||||
for (element in this) action(element)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,303 @@
|
||||
package kotlin.collections
|
||||
|
||||
/**
|
||||
* Removes a single instance of the specified element from this
|
||||
* collection, if it is present.
|
||||
*
|
||||
* Allows to overcome type-safety restriction of `remove` that requires to pass an element of type `E`.
|
||||
*
|
||||
* @return `true` if the element has been successfully removed; `false` if it was not present in the collection.
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline fun <@kotlin.internal.OnlyInputTypes T> MutableCollection<out T>.remove(element: T): Boolean
|
||||
= @Suppress("UNCHECKED_CAST") (this as MutableCollection<T>).remove(element)
|
||||
|
||||
/**
|
||||
* Removes all of this collection's elements that are also contained in the specified collection.
|
||||
|
||||
* Allows to overcome type-safety restriction of `removeAll` that requires to pass a collection of type `Collection<E>`.
|
||||
*
|
||||
* @return `true` if any of the specified elements was removed from the collection, `false` if the collection was not modified.
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline fun <@kotlin.internal.OnlyInputTypes T> MutableCollection<out T>.removeAll(elements: Collection<T>): Boolean
|
||||
= @Suppress("UNCHECKED_CAST") (this as MutableCollection<T>).removeAll(elements)
|
||||
|
||||
/**
|
||||
* Retains only the elements in this collection that are contained in the specified collection.
|
||||
*
|
||||
* Allows to overcome type-safety restriction of `retailAll` that requires to pass a collection of type `Collection<E>`.
|
||||
*
|
||||
* @return `true` if any element was removed from the collection, `false` if the collection was not modified.
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline fun <@kotlin.internal.OnlyInputTypes T> MutableCollection<out T>.retainAll(elements: Collection<T>): Boolean
|
||||
= @Suppress("UNCHECKED_CAST") (this as MutableCollection<T>).retainAll(elements)
|
||||
|
||||
/**
|
||||
* Removes the element at the specified [index] from this list.
|
||||
* In Kotlin one should use the [MutableList.removeAt] function instead.
|
||||
*/
|
||||
@Deprecated("Use removeAt(index) instead.", ReplaceWith("removeAt(index)"), level = DeprecationLevel.ERROR)
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline fun <T> MutableList<T>.remove(index: Int): T = removeAt(index)
|
||||
|
||||
/**
|
||||
* Adds the specified [element] to this mutable collection.
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline operator fun <T> MutableCollection<in T>.plusAssign(element: T) {
|
||||
this.add(element)
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds all elements of the given [elements] collection to this mutable collection.
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline operator fun <T> MutableCollection<in T>.plusAssign(elements: Iterable<T>) {
|
||||
this.addAll(elements)
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds all elements of the given [elements] array to this mutable collection.
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline operator fun <T> MutableCollection<in T>.plusAssign(elements: Array<T>) {
|
||||
this.addAll(elements)
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds all elements of the given [elements] sequence to this mutable collection.
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline operator fun <T> MutableCollection<in T>.plusAssign(elements: Sequence<T>) {
|
||||
this.addAll(elements)
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a single instance of the specified [element] from this mutable collection.
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline operator fun <T> MutableCollection<in T>.minusAssign(element: T) {
|
||||
this.remove(element)
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all elements contained in the given [elements] collection from this mutable collection.
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline operator fun <T> MutableCollection<in T>.minusAssign(elements: Iterable<T>) {
|
||||
this.removeAll(elements)
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all elements contained in the given [elements] array from this mutable collection.
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline operator fun <T> MutableCollection<in T>.minusAssign(elements: Array<T>) {
|
||||
this.removeAll(elements)
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all elements contained in the given [elements] sequence from this mutable collection.
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline operator fun <T> MutableCollection<in T>.minusAssign(elements: Sequence<T>) {
|
||||
this.removeAll(elements)
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds all elements of the given [elements] collection to this [MutableCollection].
|
||||
*/
|
||||
public fun <T> MutableCollection<in T>.addAll(elements: Iterable<T>): Boolean {
|
||||
when (elements) {
|
||||
is Collection -> return addAll(elements)
|
||||
else -> {
|
||||
var result: Boolean = false
|
||||
for (item in elements)
|
||||
if (add(item)) result = true
|
||||
return result
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds all elements of the given [elements] sequence to this [MutableCollection].
|
||||
*/
|
||||
public fun <T> MutableCollection<in T>.addAll(elements: Sequence<T>): Boolean {
|
||||
var result: Boolean = false
|
||||
for (item in elements) {
|
||||
if (add(item)) result = true
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds all elements of the given [elements] array to this [MutableCollection].
|
||||
*/
|
||||
public fun <T> MutableCollection<in T>.addAll(elements: Array<out T>): Boolean {
|
||||
return addAll(elements.asList())
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all elements from this [MutableIterable] that match the given [predicate].
|
||||
*/
|
||||
public fun <T> MutableIterable<T>.removeAll(predicate: (T) -> Boolean): Boolean = filterInPlace(predicate, true)
|
||||
|
||||
/**
|
||||
* Retains only elements of this [MutableIterable] that match the given [predicate].
|
||||
*/
|
||||
public fun <T> MutableIterable<T>.retainAll(predicate: (T) -> Boolean): Boolean = filterInPlace(predicate, false)
|
||||
|
||||
// TODO: due to boxing problems, cannot use Boolean type.
|
||||
@FixmeBoxing
|
||||
private fun <T> MutableIterable<T>.filterInPlace(predicate: (T) -> Boolean, predicateResultToRemove: Boolean): Boolean {
|
||||
TODO()
|
||||
/*
|
||||
var result = false
|
||||
with (iterator()) {
|
||||
while (hasNext())
|
||||
if (predicate(next()).toString() == predicateResultToRemove) {
|
||||
remove()
|
||||
result = true
|
||||
}
|
||||
}
|
||||
return result */
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all elements from this [MutableList] that match the given [predicate].
|
||||
*/
|
||||
public fun <T> MutableList<T>.removeAll(predicate: (T) -> Boolean): Boolean = filterInPlace(predicate, true)
|
||||
|
||||
/**
|
||||
* Retains only elements of this [MutableList] that match the given [predicate].
|
||||
*/
|
||||
public fun <T> MutableList<T>.retainAll(predicate: (T) -> Boolean): Boolean = filterInPlace(predicate, false)
|
||||
|
||||
@Fixme
|
||||
private fun <T> MutableList<T>.filterInPlace(predicate: (T) -> Boolean, predicateResultToRemove: Boolean): Boolean {
|
||||
TODO()
|
||||
}
|
||||
/* TODO: fix downTo, RandomAccess
|
||||
if (this !is RandomAccess)
|
||||
return (this as MutableIterable<T>).filterInPlace(predicate, predicateResultToRemove)
|
||||
|
||||
var writeIndex: Int = 0
|
||||
for (readIndex in 0..lastIndex) {
|
||||
val element = this[readIndex]
|
||||
if (predicate(element) == predicateResultToRemove)
|
||||
continue
|
||||
|
||||
if (writeIndex != readIndex)
|
||||
this[writeIndex] = element
|
||||
|
||||
writeIndex++
|
||||
}
|
||||
if (writeIndex < size) {
|
||||
for (removeIndex in lastIndex downTo writeIndex)
|
||||
removeAt(removeIndex)
|
||||
|
||||
return true
|
||||
}
|
||||
else {
|
||||
return false
|
||||
}
|
||||
} */
|
||||
|
||||
/**
|
||||
* Removes all elements from this [MutableCollection] that are also contained in the given [elements] collection.
|
||||
*/
|
||||
@Fixme
|
||||
public fun <T> MutableCollection<in T>.removeAll(elements: Iterable<T>): Boolean {
|
||||
// TODO: add convertToSetForSetOperationWith
|
||||
// return removeAll(elements.convertToSetForSetOperationWith(this))
|
||||
var removed = false
|
||||
for (e in elements) {
|
||||
removed = removed or remove(e)
|
||||
}
|
||||
return removed
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all elements from this [MutableCollection] that are also contained in the given [elements] sequence.
|
||||
*/
|
||||
@Fixme
|
||||
public fun <T> MutableCollection<in T>.removeAll(elements: Sequence<T>): Boolean {
|
||||
// TODO: add toHashSet()
|
||||
//val set = elements.toHashSet()
|
||||
// return set.isNotEmpty() && removeAll(set)
|
||||
var removed = false
|
||||
for (e in elements) {
|
||||
removed = removed or remove(e)
|
||||
}
|
||||
return removed
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all elements from this [MutableCollection] that are also contained in the given [elements] array.
|
||||
*/
|
||||
@Fixme
|
||||
public fun <T> MutableCollection<in T>.removeAll(elements: Array<out T>): Boolean {
|
||||
// TODO: add toHashSet()
|
||||
// return elements.isNotEmpty() && removeAll(elements.toHashSet())
|
||||
var removed = false
|
||||
for (e in elements) {
|
||||
removed = removed or remove(e)
|
||||
}
|
||||
return removed
|
||||
}
|
||||
|
||||
/**
|
||||
* Retains only elements of this [MutableCollection] that are contained in the given [elements] collection.
|
||||
*/
|
||||
@Fixme
|
||||
public fun <T> MutableCollection<in T>.retainAll(elements: Iterable<T>): Boolean {
|
||||
TODO()
|
||||
//return retainAll(elements.convertToSetForSetOperationWith(this))
|
||||
}
|
||||
|
||||
/**
|
||||
* Retains only elements of this [MutableCollection] that are contained in the given [elements] array.
|
||||
*/
|
||||
public fun <T> MutableCollection<in T>.retainAll(elements: Array<out T>): Boolean {
|
||||
if (elements.isNotEmpty())
|
||||
return retainAll(elements.toHashSet())
|
||||
else
|
||||
return retainNothing()
|
||||
}
|
||||
|
||||
/**
|
||||
* Retains only elements of this [MutableCollection] that are contained in the given [elements] sequence.
|
||||
*/
|
||||
public fun <T> MutableCollection<in T>.retainAll(elements: Sequence<T>): Boolean {
|
||||
val set = elements.toHashSet()
|
||||
if (set.isNotEmpty())
|
||||
return retainAll(set)
|
||||
else
|
||||
return retainNothing()
|
||||
}
|
||||
|
||||
private fun MutableCollection<*>.retainNothing(): Boolean {
|
||||
val result = isNotEmpty()
|
||||
clear()
|
||||
return result
|
||||
} */
|
||||
|
||||
/**
|
||||
* Sorts elements in the list in-place according to their natural sort order.
|
||||
*/
|
||||
@Fixme
|
||||
public fun <T : Comparable<T>> MutableList<T>.sort(): Unit {
|
||||
TODO()
|
||||
//if (size > 1) java.util.Collections.sort(this)
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts elements in the list in-place according to the order specified with [comparator].
|
||||
*/
|
||||
@Fixme
|
||||
public fun <T> MutableList<T>.sortWith(comparator: Comparator<in T>): Unit {
|
||||
TODO()
|
||||
//if (size > 1) java.util.Collections.sort(this, comparator)
|
||||
}
|
||||
@@ -25,7 +25,8 @@ public fun <T> emptySet(): Set<T> = EmptySet
|
||||
*/
|
||||
public fun <T> setOf(vararg elements: T): Set<T> = if (elements.size > 0) elements.toSet() else emptySet()
|
||||
|
||||
/** Returns an empty read-only set. The returned set is serializable (JVM). */
|
||||
/** Returns an empty read-only set. */
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline fun <T> setOf(): Set<T> = emptySet()
|
||||
|
||||
/**
|
||||
@@ -44,6 +45,7 @@ public fun <T> hashSetOf(vararg elements: T): HashSet<T> = elements.toCollection
|
||||
//public fun <T> linkedSetOf(vararg elements: T): LinkedHashSet<T> = elements.toCollection(LinkedHashSet(mapCapacity(elements.size)))
|
||||
|
||||
/** Returns this Set if it's not `null` and the empty set otherwise. */
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline fun <T> Set<T>?.orEmpty(): Set<T> = this ?: emptySet()
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,8 +1,54 @@
|
||||
package kotlin.internal
|
||||
|
||||
/**
|
||||
* Specifies that the corresponding type should be ignored during type inference.
|
||||
*/
|
||||
@Target(AnnotationTarget.TYPE)
|
||||
@Retention(AnnotationRetention.BINARY)
|
||||
internal annotation class NoInfer
|
||||
|
||||
/**
|
||||
* Specifies that the constraint built for the type during type inference should be an equality one.
|
||||
*/
|
||||
@Target(AnnotationTarget.TYPE)
|
||||
@Retention(AnnotationRetention.BINARY)
|
||||
internal annotation class Exact
|
||||
|
||||
/**
|
||||
* Specifies that a corresponding member has the lowest priority in overload resolution.
|
||||
*/
|
||||
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY)
|
||||
@Retention(AnnotationRetention.BINARY)
|
||||
internal annotation class LowPriorityInOverloadResolution
|
||||
|
||||
/**
|
||||
* Specifies that the corresponding member has the highest priority in overload resolution. Effectively this means that
|
||||
* an extension annotated with this annotation will win in overload resolution over a member with the same signature.
|
||||
*/
|
||||
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY)
|
||||
@Retention(AnnotationRetention.BINARY)
|
||||
internal annotation class HidesMembers
|
||||
|
||||
/**
|
||||
* The value of this type parameter should be mentioned in input types (argument types, receiver type or expected type).
|
||||
*/
|
||||
@Target(AnnotationTarget.TYPE, AnnotationTarget.TYPE_PARAMETER)
|
||||
public annotation class OnlyInputTypes
|
||||
|
||||
|
||||
@Target(AnnotationTarget.TYPE, AnnotationTarget.TYPE_PARAMETER)
|
||||
public annotation class OnlyOutputTypes
|
||||
public annotation class OnlyOutputTypes
|
||||
|
||||
/**
|
||||
* Specifies that this function should not be called directly without inlining
|
||||
*/
|
||||
@Target(AnnotationTarget.FUNCTION)
|
||||
@Retention(AnnotationRetention.BINARY)
|
||||
internal annotation class InlineOnly
|
||||
|
||||
/**
|
||||
* Specifies that this part of internal API is effectively public exposed by using in public inline function
|
||||
*/
|
||||
@Target(AnnotationTarget.CLASS, AnnotationTarget.CONSTRUCTOR, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY)
|
||||
@Retention(AnnotationRetention.BINARY)
|
||||
internal annotation class InlineExposed
|
||||
|
||||
@@ -324,3 +324,12 @@ public fun Long.coerceIn(range: ClosedRange<Long>): Long {
|
||||
if (range.isEmpty()) throw IllegalArgumentException("Cannot coerce value to an empty range: $range.")
|
||||
return if (this < range.start) range.start else if (this > range.endInclusive) range.endInclusive else this
|
||||
}
|
||||
|
||||
|
||||
// This part is from generated _Ranges.kt.
|
||||
/**
|
||||
* Returns a progression that goes over the same range in the opposite direction with the same step.
|
||||
*/
|
||||
public fun IntProgression.reversed(): IntProgression {
|
||||
return IntProgression.fromClosedRange(last, first, -step)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
package kotlin
|
||||
|
||||
/**
|
||||
* An exception is thrown to indicate that a method body remains to be implemented.
|
||||
*/
|
||||
public class NotImplementedError(message: String) : Error(message)
|
||||
|
||||
/**
|
||||
* Always throws [NotImplementedError] stating that operation is not implemented.
|
||||
*/
|
||||
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline fun TODO(): Nothing = throw NotImplementedError("An operation is not implemented.")
|
||||
|
||||
/**
|
||||
* Always throws [NotImplementedError] stating that operation is not implemented.
|
||||
*
|
||||
* @param reason a string explaining why the implementation is missing.
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline fun TODO(reason: String): Nothing = throw NotImplementedError("An operation is not implemented: $reason")
|
||||
|
||||
|
||||
/**
|
||||
* Calls the specified function [block] and returns its result.
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline fun <R> run(block: () -> R): R = block()
|
||||
|
||||
/**
|
||||
* Calls the specified function [block] with `this` value as its receiver and returns its result.
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline fun <T, R> T.run(block: T.() -> R): R = block()
|
||||
|
||||
/**
|
||||
* Calls the specified function [block] with the given [receiver] as its receiver and returns its result.
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline fun <T, R> with(receiver: T, block: T.() -> R): R = receiver.block()
|
||||
|
||||
/**
|
||||
* Calls the specified function [block] with `this` value as its receiver and returns `this` value.
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline fun <T> T.apply(block: T.() -> Unit): T { block(); return this }
|
||||
|
||||
/**
|
||||
* Calls the specified function [block] with `this` value as its argument and returns its result.
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline fun <T, R> T.let(block: (T) -> R): R = block(this)
|
||||
|
||||
/**
|
||||
* Executes the given function [action] specified number of [times].
|
||||
*
|
||||
* A zero-based index of current iteration is passed as a parameter to [action].
|
||||
*/
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline fun repeat(times: Int, action: (Int) -> Unit) {
|
||||
for (index in 0..times - 1) {
|
||||
action(index)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user