Skip to content

Instantly share code, notes, and snippets.

@Jellymath
Last active November 7, 2019 12:03
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Jellymath/93532594073463094c74647957f9028e to your computer and use it in GitHub Desktop.
Save Jellymath/93532594073463094c74647957f9028e to your computer and use it in GitHub Desktop.
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