refactor: precompute compiler enum mappings
This commit is contained in:
+21
-2
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user