All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.io.matthewnelson.immutable.collections.Immutable.kt Maven / Gradle / Ivy

/*
 * Copyright (c) 2024 Matthew Nelson
 *
 * 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
 *
 *     https://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.
 **/
@file:JvmName("Immutable")

package io.matthewnelson.immutable.collections

import kotlin.jvm.JvmName

@JvmName("listOf")
public fun  Collection.toImmutableList(): List {
    if (isEmpty()) return emptyList()
    if (this is ImmutableList) return this
    return ImmutableList(toList())
}

@JvmName("listOf")
public fun  immutableListOf(vararg elements: T): List {
    if (elements.isEmpty()) return emptyList()
    return ImmutableList(elements.toList())
}

@JvmName("mapOf")
public fun  Map.toImmutableMap(): Map {
    if (isEmpty()) return emptyMap()
    if (this is ImmutableMap) return this
    return ImmutableMap(toMap())
}

@JvmName("mapOf")
public fun  immutableMapOf(vararg pairs: Pair): Map {
    if (pairs.isEmpty()) return emptyMap()
    return ImmutableMap(pairs.toMap())
}

@JvmName("setOf")
public fun  Collection.toImmutableSet(): Set {
    if (isEmpty()) return emptySet()
    if (this is ImmutableSet) return this
    return ImmutableSet(toSet())
}

@JvmName("setOf")
public fun  immutableSetOf(vararg elements: T): Set {
    if (elements.isEmpty()) return emptySet()
    return ImmutableSet(elements.toSet())
}

private open class ImmutableCollection>(
    protected val delegate: D
): Collection {
    final override val size: Int get() = delegate.size
    final override fun isEmpty(): Boolean = delegate.isEmpty()
    final override operator fun iterator(): Iterator = ImmutableIterator(delegate.iterator())
    final override fun containsAll(elements: Collection): Boolean = delegate.containsAll(elements)
    final override operator fun contains(element: T): Boolean = delegate.contains(element)

    final override fun equals(other: Any?): Boolean = delegate == other
    final override fun hashCode(): Int = delegate.hashCode()
    final override fun toString(): String = delegate.toString()
}

private class ImmutableList(
    delegate: List
): ImmutableCollection>(delegate), List {
    override operator fun get(index: Int): T = delegate[index]
    override fun indexOf(element: T): Int = delegate.indexOf(element)
    override fun lastIndexOf(element: T): Int = delegate.lastIndexOf(element)
    override fun listIterator(): ListIterator = ImmutableListIterator(delegate.listIterator())
    override fun listIterator(index: Int): ListIterator = ImmutableListIterator(delegate.listIterator(index))
    override fun subList(fromIndex: Int, toIndex: Int): List {
        if (fromIndex == 0 && toIndex == size) return this
        val subList = delegate.subList(fromIndex, toIndex)
        if (subList.isEmpty()) return emptyList()
        return ImmutableList(subList)
    }
}

private class ImmutableSet(
    delegate: Set
): ImmutableCollection>(delegate), Set

private class ImmutableMap(
    private val delegate: Map
): Map {

    override val entries: Set> by lazy {
        val entries = delegate.entries
        val set = LinkedHashSet>(entries.size, 1.0F)
        entries.mapTo(set) { ImmutableMapEntry(it) }
        ImmutableSet(set)
    }
    override val keys: Set by lazy { ImmutableSet(delegate.keys) }
    override val size: Int get() = delegate.size
    override val values: Collection by lazy { ImmutableCollection(delegate.values) }
    override fun isEmpty(): Boolean = delegate.isEmpty()
    override operator fun get(key: K): V? = delegate[key]
    override fun containsValue(value: V): Boolean = delegate.containsValue(value)
    override fun containsKey(key: K): Boolean = delegate.containsKey(key)

    override fun equals(other: Any?): Boolean = delegate == other
    override fun hashCode(): Int = delegate.hashCode()
    override fun toString(): String = delegate.toString()
}

private class ImmutableMapEntry(
    private val delegate: Map.Entry,
): Map.Entry {
    override val key: K get() = delegate.key
    override val value: V get() = delegate.value

    override fun equals(other: Any?): Boolean = delegate == other
    override fun hashCode(): Int = delegate.hashCode()
    override fun toString(): String = delegate.toString()
}

private open class ImmutableIterator>(
    protected val delegate: D
): Iterator {
    final override operator fun hasNext(): Boolean = delegate.hasNext()
    final override operator fun next(): T = delegate.next()

    final override fun equals(other: Any?): Boolean = delegate == other
    final override fun hashCode(): Int = delegate.hashCode()
    final override fun toString(): String = delegate.toString()
}

private class ImmutableListIterator(
    delegate: ListIterator
): ImmutableIterator>(delegate), ListIterator {
    override fun hasPrevious(): Boolean = delegate.hasPrevious()
    override fun nextIndex(): Int = delegate.nextIndex()
    override fun previous(): T = delegate.previous()
    override fun previousIndex(): Int = delegate.previousIndex()
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy