Last active
November 7, 2019 12:03
-
-
Save Jellymath/93532594073463094c74647957f9028e to your computer and use it in GitHub Desktop.
This file contains hidden or 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 inlineEnumSet | |
import java.util.EnumSet | |
inline class InlineEnumSet<T : Enum<T>>(val set: UInt) { | |
companion object | |
} | |
//bit extraction functions | |
fun <T : Enum<T>> T.enumPosition() = 1u shl ordinal | |
inline fun <reified T : Enum<T>> allValuesMask() = | |
generateSequence(1u) { (it shl 1) + 1u }.elementAt(enumValues<T>().lastIndex) | |
//creation functions | |
inline fun <T : Enum<T>> T.toSet() = InlineEnumSet<T>(enumPosition()) | |
inline fun <T : Enum<T>> InlineEnumSet.Companion.emptySet() = InlineEnumSet<T>(0u) | |
inline fun <reified T : Enum<T>> InlineEnumSet.Companion.allValues() = InlineEnumSet<T>(allValuesMask<T>()) | |
inline fun <T : Enum<T>> InlineEnumSet.Companion.from(vararg values: T): InlineEnumSet<T> = | |
InlineEnumSet(values.fold(0u) { acc, curr -> acc or curr.enumPosition() }) | |
//check functions | |
inline operator fun <T : Enum<T>> InlineEnumSet<T>.contains(value: T): Boolean = (set and value.enumPosition()) != 0u | |
inline fun <T : Enum<T>> InlineEnumSet<T>.containsAll(other: InlineEnumSet<T>): Boolean = (other - this).isEmpty() | |
inline fun <T : Enum<T>> InlineEnumSet<T>.isEmpty(): Boolean = set == 0u | |
inline fun <reified T : Enum<T>> InlineEnumSet<T>.containsAllElements(): Boolean = set == allValuesMask<T>() | |
//bitwise functions | |
inline infix fun <T : Enum<T>> T.or(other: T): InlineEnumSet<T> = | |
InlineEnumSet(enumPosition() or other.enumPosition()) | |
inline infix fun <T : Enum<T>> InlineEnumSet<T>.or(other: T): InlineEnumSet<T> = | |
InlineEnumSet(set or other.enumPosition()) | |
inline infix fun <T : Enum<T>> InlineEnumSet<T>.or(other: InlineEnumSet<T>): InlineEnumSet<T> = | |
InlineEnumSet(set or other.set) | |
inline infix fun <T : Enum<T>> InlineEnumSet<T>.xor(other: T): InlineEnumSet<T> = | |
InlineEnumSet((set xor other.enumPosition())) | |
inline infix fun <T : Enum<T>> InlineEnumSet<T>.xor(other: InlineEnumSet<T>): InlineEnumSet<T> = | |
InlineEnumSet((set xor other.set)) | |
inline infix fun <T : Enum<T>> InlineEnumSet<T>.and(other: InlineEnumSet<T>): InlineEnumSet<T> = | |
InlineEnumSet(set and other.set) | |
inline fun <reified T : Enum<T>> InlineEnumSet<T>.negate(): InlineEnumSet<T> = | |
InlineEnumSet(set.inv() and allValuesMask<T>()) | |
//arithmetic functions | |
inline operator fun <T : Enum<T>> InlineEnumSet<T>.plus(other: T): InlineEnumSet<T> = this or other | |
inline operator fun <T : Enum<T>> InlineEnumSet<T>.plus(other: InlineEnumSet<T>): InlineEnumSet<T> = this or other | |
inline operator fun <T : Enum<T>> InlineEnumSet<T>.minus(other: T): InlineEnumSet<T> = | |
InlineEnumSet((set or other.enumPosition()) - other.enumPosition()) | |
inline operator fun <T : Enum<T>> InlineEnumSet<T>.minus(other: InlineEnumSet<T>): InlineEnumSet<T> = | |
InlineEnumSet((set or other.set) - other.set) | |
//space operation functions | |
inline infix fun <T : Enum<T>> InlineEnumSet<T>.intersect(other: InlineEnumSet<T>): InlineEnumSet<T> = | |
this and other | |
inline infix fun <T : Enum<T>> InlineEnumSet<T>.union(other: InlineEnumSet<T>): InlineEnumSet<T> = | |
this or other | |
inline infix fun <T : Enum<T>> InlineEnumSet<T>.symDiff(other: InlineEnumSet<T>): InlineEnumSet<T> = | |
this xor other | |
//convert back to usual collections | |
inline fun <reified T : Enum<T>> InlineEnumSet<T>.toList(): List<T> = enumValues<T>().filter { it in this } | |
inline fun <reified T : Enum<T>> InlineEnumSet<T>.toBoxedSet(): EnumSet<T> = EnumSet.copyOf(toList()) | |
fun main() { | |
val set = Color.Red or Color.Blue | |
val altSet = InlineEnumSet.from(Color.Green, Color.Blue) | |
println(Color.Green in set) | |
} | |
enum class Color { | |
Red, | |
Green, | |
Blue | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment