refactor: precompute compiler enum mappings

This commit is contained in:
2026-10-30 10:10:43 +01:00
parent d7e637dc3b
commit 30a98db379
13 changed files with 452 additions and 279 deletions
+21 -2
View File
@@ -15,6 +15,25 @@ EnumMap proc($E, $V type) type {
init proc(
$E, $V type,
values meta.EnumFieldStruct(E, ?V, some!(null)),
) EnumMap(E, V) {
return initialize(E, V, null, values)
}
#! initializes absent value slots without making their keys present.
#! use fully initialized storage when a sparse map must be materialized at compile time.
init_filled proc(
$E, $V type,
storage_default V,
values meta.EnumFieldStruct(E, ?V, some!(null)),
) EnumMap(E, V) {
return initialize(E, V, some!(storage_default), values)
}
@hide:file
initialize proc(
$E, $V type,
storage_default ?V,
values meta.EnumFieldStruct(E, ?V, some!(null)),
) EnumMap(E, V) {
map EnumMap(E, V) := undefined
@@ -25,7 +44,7 @@ init proc(
if field!(values, field.name) |value| {
map.present[i] = true
map.values[i] = value
}
} else if (storage_default) |value| map.values[i] = value
}
else: compile_error!("EnumMap key must be an enum")
}
@@ -38,7 +57,7 @@ get proc($E, $V type, map @EnumMap(E, V), key E) ?V {
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]
if (map.present[i]) return some!(map.values[i])
return null
}
}
+16
View File
@@ -25,6 +25,22 @@ handles_sparse_enum_get test {
try testing.expect_equal(null, eof)
}
@hide:file
sparse_optional_values :: $init_filled(TestEnum, ?i16, null, {
ident = some!(null),
int = some!(some!(i16(42))),
})
filled_comptime_storage_preserves_absence_and_nested_optional_presence test {
absent :: get(&sparse_optional_values, TestEnum.eof)
present_null :: get(&sparse_optional_values, TestEnum.ident)
present_value :: get(&sparse_optional_values, TestEnum.int)
try testing.expect(absent == null)
try testing.expect(present_null != null)
try testing.expect(present_null? == null)
try testing.expect_equal(i16(42), present_value??)
}
@hide:file
TestLeftError :: enum {
shared