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

org.fernice.std.Enum.kt Maven / Gradle / Ivy

/*
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

package org.fernice.std

import java.util.EnumSet
import kotlin.enums.EnumEntries
import kotlin.enums.enumEntries

@OptIn(ExperimentalStdlibApi::class)
inline fun , T : Any> PerEnumLazy(noinline initializer: (E) -> T): PerEnumLazy {
    return PerEnumLazy(enumEntries(), initializer)
}

class PerEnumLazy, T : Any>(
    private val entries: EnumEntries,
    private val initializer: (E) -> T,
) : Iterable> {

    private val values = Array(entries.size) { null }

    fun get(enum: E): T {
        check(entries.contains(enum)) { "unknown enum $enum" }

        var value = values[enum.ordinal]
        if (value == null) {
            value = initializer.invoke(enum)
            values[enum.ordinal] = value
        }
        @Suppress("UNCHECKED_CAST")
        return value as T
    }

    fun peek(enum: E): T? {
        check(entries.contains(enum)) { "unknown enum $enum" }

        @Suppress("UNCHECKED_CAST")
        return values[enum.ordinal] as T?
    }

    override fun iterator(): Iterator> = EntryIterator()

    private inner class EntryIterator : Iterator> {

        private var index = 0

        override fun hasNext(): Boolean {
            var index = 0
            while (index < entries.size) {
                if (values[index] != null) return true
                index++
            }
            return false
        }

        override fun next(): Entry {
            if (!hasNext()) throw NoSuchElementException()
            val enum = entries[index]

            @Suppress("UNCHECKED_CAST")
            val value = values[index] as T
            return Entry(enum, value)
        }
    }

    data class Entry, T : Any>(val enum: E, val value: T)
}


inline fun > EnumSet(): EnumSet {
    return EnumSet.noneOf(E::class.java)
}

@Suppress("NOTHING_TO_INLINE")
inline fun > EnumSet.set(enum: E, set: Boolean): Boolean {
    return if (set) {
        add(enum)
    } else {
        remove(enum)
    }
}

fun > EnumSet.with(enum: E): EnumSet {
    val result = EnumSet.copyOf(this)
    result.add(enum)
    return result
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy