Last active
August 6, 2024 16:23
-
-
Save jimschubert/b1437e210cdb9c411acde6654b4cdd01 to your computer and use it in GitHub Desktop.
Prototyping a Flags/Bitmasks implementation in Kotlin 1.1.1
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
META-INF/ | |
*.class |
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
class BitMask(val value: Long) |
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
interface Flags { | |
val bit: Long | |
fun toBitMask(): BitMask = BitMask(bit) | |
} |
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
infix fun Flags.and(other: Long): BitMask = BitMask(bit and other) | |
infix fun <T: Flags> Flags.or(other: T): BitMask = BitMask(bit or other.bit) | |
operator infix fun Flags.plus(other: Flags): BitMask = BitMask(bit or other.bit) | |
inline fun <reified T> enabledValues(mask: BitMask) : List<T> where T : Enum<T>, T : Flags { | |
return enumValues<T>().filter { | |
mask hasFlag it | |
} | |
} | |
infix fun BitMask.or(other: Flags): BitMask = BitMask(value or other.bit) | |
operator infix fun BitMask.plus(other: BitMask): BitMask = BitMask(value or other.value) | |
operator infix fun BitMask.plus(other: Flags): BitMask = BitMask(value or other.bit) | |
infix fun <T: Flags> BitMask.hasFlag(which: T): Boolean { | |
// an Undefined flag is a special case. | |
if(value == 0L || (value > 0L && which.bit == 0L)) return false | |
return value and which.bit == which.bit | |
} | |
infix fun <T: Flags> BitMask.unset(which: T): BitMask = BitMask(value xor which.bit) |
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
fun main(args : Array<String>){ | |
val mask: BitMask = ParameterFeature.Path + | |
ParameterFeature.Query + | |
ParameterFeature.Header; | |
val enabled = enabledValues<ParameterFeature>(mask) | |
println("flags enabled: $enabled") | |
println("flags disabled: ${enumValues<ParameterFeature>().filterNot { enabled.contains(it) } }") | |
println("mask hasFlag ParameterFeature.Query: ${mask hasFlag ParameterFeature.Query}") | |
println("mask hasFlag ParameterFeature.Body: ${mask hasFlag ParameterFeature.Body}") | |
} |
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
enum class ParameterFeature(override val bit: Long) : Flags { | |
Undefined(0), | |
Path(1 shl 0), | |
Query(1 shl 1), | |
Header(1 shl 2), | |
Body(1 shl 3), | |
FormUnencoded(1 shl 4), | |
FormMultipart(1 shl 5); | |
} |
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
#!/usr/bin/env bash | |
kotlinc {BitMask,Flags,globals,ParameterFeature,main}.kt && kotlin MainKt |
Hidden gem
@fabriciovergara thanks! I'm glad you've found it useful.
nice work! very helpful for network physics
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thank you very much for this awesome example @jimschubert