04/18/2023, 11:07 AM
Hi. If I have an generic interface that is ment for mapping from `Enum`s to some binary form (lets say arrays of bools), can I enforce at compile-time that the map contains all the enum variants as keys (via annotations perhaps?)
interface BinaryFlagMapper<E : Enum<E>> {
    val map: Map<E, Int> //lets say Int is index in Array of bools

val mapperForMyEnum = object : BinaryFlagMapper<MyEnum> {
    override val map = mapOf(
         // how to enforce at compile time that this contains all the entries in MyEnum as keys?

Wout Werkman

04/18/2023, 11:44 AM
To answer your question: No you can not force this. For the behavior you are describing, you might be interested in
if you're targeting JVM. Otherwise you might be interested in enumValues. Here is a mockup of how you could implement your interface using them:
inline fun <reified E: Enum<E>> binaryFlagMapper(): BinaryFlagMapper<E> {
    val values = enumValues<E>()
    val flags = BooleanArray(values.size) { false }
    val map: Map<E, Int> = values.associateWith { it.ordinal }

    return object: BinaryFlagMapper<E> {
        override val map: Map<E, Int> get() = map

val mapperForMyEnum = binaryFlagMapper<MyEnum>()
Please be aware that inline functions will be inlined into your source code at every call site. Consider keeping the inlined part as small as possible. Example would be:
inline fun <reified E: Enum<E>> binaryFlagMapper(): BinaryFlagMapper<E> = binaryFlagMapper(enumValues<E>())
fun <E : Enum<E>> binaryFlagMapper(values: Array<E>): BinaryFlagMapper<E> {
    TODO("Big function here")


04/18/2023, 2:41 PM
Maybe I will try to replace the map with a function that returns that value and implement it using
expression. That way it will cause an error if its non exhaustive 🤔