46 lines
1.1 KiB
Plaintext
46 lines
1.1 KiB
Plaintext
import "@std/meta"
|
|
|
|
EnumMap func($E, $V type) type {
|
|
match typeinfo!(E) {
|
|
.enum |info|: return struct {
|
|
present [info.fields.len]mut bool # fixme: replace with bitset
|
|
values [info.fields.len]mut V
|
|
}
|
|
else: compile_error!("EnumMap key must be an enum")
|
|
}
|
|
}
|
|
|
|
init func(
|
|
$E, $V type,
|
|
values meta.EnumFieldStruct(E, ?V, some!(null)),
|
|
) EnumMap(E, V) {
|
|
map EnumMap(E, V) := undefined
|
|
|
|
match typeinfo!(E) {
|
|
.enum |info|: inline for info.fields |field, i| {
|
|
map.present[i] = false
|
|
|
|
if field!(values, field.name) |value| {
|
|
map.present[i] = true
|
|
map.values[i] = value
|
|
}
|
|
}
|
|
else: compile_error!("EnumMap key must be an enum")
|
|
}
|
|
|
|
return map
|
|
}
|
|
|
|
get func($E, $V type, map @EnumMap(E, V), key E) ?V {
|
|
# fixme: linear lookup; implement an enum index/discriminant map for O(1) lookup
|
|
match typeinfo!(E) {
|
|
.enum |info|: inline for info.fields |field, i| {
|
|
if key == field!(E, field.name) {
|
|
if (map.present[i]) return map.values[i]
|
|
return null
|
|
}
|
|
}
|
|
else: compile_error!("EnumMap key must be an enum")
|
|
}
|
|
}
|