Skip to content

Commit

Permalink
Use reified type parameters for KeyIndexer
Browse files Browse the repository at this point in the history
  • Loading branch information
Marcono1234 committed Nov 5, 2023
1 parent 948cebc commit 0db9990
Showing 1 changed file with 13 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,14 @@ internal interface KeyIndexer<K> {
const val NO_INDEX = -1
private fun <E> Collection<E>.asSet() = (this as? Set) ?: this.toSet()

fun <E : Enum<E>> fromEnumConstants(constants: Collection<E>) = fromEnumConstants(constants.asSet())
inline fun <reified E : Enum<E>> fromEnumConstants(constants: Collection<E>) =
fromEnumConstants(constants.asSet())

/** Creates an indexer for a subset of all enum constants. */
fun <E : Enum<E>> fromEnumConstants(constants: Set<E>): KeyIndexer<E> {
val enumClass = constants.first().declaringJavaClass
val allConstants = enumClass.enumConstants
if (allConstants.size == constants.size) return forAllEnumConstants(enumClass)
inline fun <reified E : Enum<E>> fromEnumConstants(constants: Set<E>): KeyIndexer<E> {
require(constants.isNotEmpty())
val allConstants = E::class.java.enumConstants
if (allConstants.size == constants.size) return forAllEnumConstants()

val ordinalToIndex = IntArray(allConstants.size) { NO_INDEX }

Expand All @@ -40,26 +41,24 @@ internal interface KeyIndexer<K> {
index++
}

val indexToConstant = arrayOfNulls<Any>(index)
val indexToConstant = arrayOfNulls<E>(index)
constants.forEach {
indexToConstant[ordinalToIndex[it.ordinal]] = it
}
val indicesCount = index

return object : KeyIndexer<E> {
override fun indicesCount() = index
override fun indicesCount() = indicesCount

override fun keyToIndex(key: E) = ordinalToIndex[key.ordinal]

@Suppress("UNCHECKED_CAST")
override fun indexToKey(index: Int) = indexToConstant[index] as E
// Using `!!` is fine here, assuming KeyIndexer is used correctly and only valid indices are used
override fun indexToKey(index: Int) = indexToConstant[index]!!
}
}

inline fun <reified E : Enum<E>> forAllEnumConstants() = forAllEnumConstants(E::class.java)

@JvmStatic
fun <E : Enum<E>> forAllEnumConstants(enumClass: Class<E>): KeyIndexer<E> {
val enumConstants = enumClass.enumConstants
inline fun <reified E : Enum<E>> forAllEnumConstants(): KeyIndexer<E> {
val enumConstants = E::class.java.enumConstants
return object : KeyIndexer<E> {
override fun indicesCount() = enumConstants.size

Expand Down

0 comments on commit 0db9990

Please sign in to comment.