Last active
February 9, 2022 10:00
-
-
Save Miha-x64/5f626228b34175f827734596d6701008 to your computer and use it in GitHub Desktop.
Enum extensions for Kotlin, superseded by https://github.com/Miha-x64/Kotlin-MPP_Collection_utils
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package net.aquadc.common | |
// Gist: https://gist.github.com/Miha-x64/5f626228b34175f827734596d6701008 | |
import java.util.* | |
// maps | |
inline fun <reified K : Enum<K>, V> enumMapOf(): MutableMap<K, V> { | |
return EnumMap<K, V>(K::class.java) | |
} | |
inline fun <reified K : Enum<K>, V> enumMapOf(k: K, v: V): MutableMap<K, V> { | |
val map = EnumMap<K, V>(K::class.java) | |
map.put(k, v) | |
return map | |
} | |
inline fun <reified K : Enum<K>, V> enumMapOf(k0: K, v0: V, k1: K, v1: V): MutableMap<K, V> { | |
val map = EnumMap<K, V>(K::class.java) | |
map.put(k0, v0) | |
map.put(k1, v1) | |
return map | |
} | |
inline fun <reified K : Enum<K>, V> enumMapOf(k0: K, v0: V, k1: K, v1: V, k2: K, v2: V): MutableMap<K, V> { | |
val map = EnumMap<K, V>(K::class.java) | |
map.put(k0, v0) | |
map.put(k1, v1) | |
map.put(k2, v2) | |
return map | |
} | |
inline fun <reified K : Enum<K>, V> enumMapOf(k0: K, v0: V, k1: K, v1: V, k2: K, v2: V, k3: K, v3: V): MutableMap<K, V> { | |
val map = EnumMap<K, V>(K::class.java) | |
map.put(k0, v0) | |
map.put(k1, v1) | |
map.put(k2, v2) | |
map.put(k3, v3) | |
return map | |
} | |
inline fun <reified K : Enum<K>, V> enumMapOf(k0: K, v0: V, k1: K, v1: V, k2: K, v2: V, k3: K, v3: V, k4: K, v4: V): MutableMap<K, V> { | |
val map = EnumMap<K, V>(K::class.java) | |
map.put(k0, v0) | |
map.put(k1, v1) | |
map.put(k2, v2) | |
map.put(k3, v3) | |
map.put(k4, v4) | |
return map | |
} | |
inline fun <reified K : Enum<K>, V> enumMapOf(k0: K, v0: V, k1: K, v1: V, k2: K, v2: V, k3: K, v3: V, k4: K, v4: V, k5: K, v5: V): MutableMap<K, V> { | |
val map = EnumMap<K, V>(K::class.java) | |
map.put(k0, v0) | |
map.put(k1, v1) | |
map.put(k2, v2) | |
map.put(k3, v3) | |
map.put(k4, v4) | |
map.put(k5, v5) | |
return map | |
} | |
inline fun <reified K : Enum<K>, V> enumMapOf(k0: K, v0: V, k1: K, v1: V, k2: K, v2: V, k3: K, v3: V, k4: K, v4: V, k5: K, v5: V, k6: K, v6: V): MutableMap<K, V> { | |
val map = EnumMap<K, V>(K::class.java) | |
map.put(k0, v0) | |
map.put(k1, v1) | |
map.put(k2, v2) | |
map.put(k3, v3) | |
map.put(k4, v4) | |
map.put(k5, v5) | |
map.put(k6, v6) | |
return map | |
} | |
// sets | |
inline fun <reified E : Enum<E>> enumSetOf(): MutableSet<E> = EnumSet.noneOf(E::class.java) | |
inline fun <E : Enum<E>> enumSetOf(single: E): MutableSet<E> = EnumSet.of(single) | |
inline fun <E : Enum<E>> enumSetOf(e0: E, e1: E): MutableSet<E> = EnumSet.of(e0, e1) | |
inline fun <E : Enum<E>> enumSetOf(e0: E, e1: E, e2: E): MutableSet<E> = EnumSet.of(e0, e1, e2) | |
// transforms | |
/** | |
* Variation of groupBy optimized for enum keys; however, this map has is not linked, it has its own order. | |
*/ | |
@JvmName("groupByEnum") | |
inline fun <T, reified K : Enum<K>> Iterable<T>.groupBy(keySelector: (T) -> K): Map<K, List<T>> { | |
return groupByTo(EnumMap<K, MutableList<T>>(K::class.java), keySelector) | |
} | |
@JvmName("associateByEnum") | |
inline fun <T, reified K : Enum<K>> Iterable<T>.associateBy(keySelector: (T) -> K): MutableMap<K, T> { | |
return associateByTo(EnumMap(K::class.java), keySelector) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@file:Suppress("NOTHING_TO_INLINE") | |
package net.aquadc.common.android | |
// Gist: https://gist.github.com/Miha-x64/5f626228b34175f827734596d6701008 | |
import android.content.Intent | |
import android.os.Bundle | |
import android.os.Parcel | |
import java.util.* | |
// enum | |
inline fun Parcel.writeEnum(e: Enum<*>) { | |
writeString(e.name) | |
} | |
inline fun <reified E : Enum<E>> Parcel.readEnum(): E = | |
java.lang.Enum.valueOf(E::class.java, readString()) | |
inline fun <E : Enum<E>> Parcel.readEnum(eClass: Class<E>): E = | |
java.lang.Enum.valueOf(eClass, readString()) | |
inline fun Bundle.putEnum(name: String, value: Enum<*>) { | |
putString(name, value.name) | |
} | |
inline fun <reified E : Enum<E>> Bundle.getEnum(name: String): E = | |
java.lang.Enum.valueOf(E::class.java, getString(name)) | |
inline fun <E : Enum<E>> Bundle.getEnum(name: String, eClass: Class<E>): E = | |
java.lang.Enum.valueOf(eClass, getString(name)) | |
inline fun Intent.putEnumExtra(name: String, value: Enum<*>): Intent = | |
putExtra(name, value.name) | |
inline fun <reified E : Enum<E>> Intent.getEnumExtra(name: String): E = | |
java.lang.Enum.valueOf(E::class.java, getStringExtra(name)) | |
inline fun <E : Enum<E>> Intent.getEnumExtra(name: String, eClass: Class<E>): E = | |
java.lang.Enum.valueOf(eClass, getStringExtra(name)) | |
// enumSet | |
fun <E : Enum<E>> Parcel.writeEnumSet(set: Set<E>) { | |
writeStringArray(set.mapToArray { it.name }) | |
} | |
inline fun <reified E : Enum<E>> Parcel.readEnumSet(): Set<E> = | |
readEnumSet(E::class.java) | |
fun <E : Enum<E>> Parcel.readEnumSet(eClass: Class<E>): Set<E> = | |
createStringArray().mapTo(EnumSet.noneOf(eClass)) { java.lang.Enum.valueOf(eClass, it) } | |
fun <E : Enum<E>> Bundle.putEnumSet(name: String, set: Set<E>) { | |
putStringArray(name, set.mapToArray { it.name }) | |
} | |
inline fun <reified E : Enum<E>> Bundle.getEnumSet(name: String): Set<E> = | |
getEnumSet(name, E::class.java) | |
fun <E : Enum<E>> Bundle.getEnumSet(name: String, eClass: Class<E>): Set<E> = | |
getStringArray(name).mapTo(EnumSet.noneOf(eClass)) { java.lang.Enum.valueOf(eClass, it) } | |
fun <E : Enum<E>> Intent.putEnumSetExtra(name: String, set: Set<E>) { | |
putExtra(name, set.mapToArray { it.name }) | |
} | |
inline fun <reified E : Enum<E>> Intent.getEnumSetExtra(name: String): Set<E> = | |
getEnumSetExtra(name, E::class.java) | |
fun <E : Enum<E>> Intent.getEnumSetExtra(name: String, eClass: Class<E>): Set<E> = | |
getStringArrayExtra(name).mapTo(EnumSet.noneOf(eClass)) { java.lang.Enum.valueOf(eClass, it) } | |
// internal | |
private inline fun <T, reified R> Collection<T>.mapToArray(transform: (T) -> R): Array<R> { | |
val itr = iterator() | |
val array = Array(size) { transform(itr.next()) } | |
check(!itr.hasNext()) | |
return array | |
} |
It's never a good idea to allocate an Array of Pairs and also call toMap
which allocates a LinkedHashMap
(with another Array with Nodes inside) just to pass arguments in 'idiomatic' way or to make static analyzer shut up.
Escape analysis and scalarization may not work for such a complicated case with intermediate map, and no one should ever rely on such a subtle VM optimization.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
It's never a good idea to have function with too many arguments. SonarLint for example will complain. Furthermore there is a more idiomatic way with a single function to create the
EnumMap
as follows: