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 | |
} |
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 allocate an Array of Pairs and also call
toMap
which allocates aLinkedHashMap
(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.