From d44f822821839739c282fe325d9800ab086b456e Mon Sep 17 00:00:00 2001 From: Lucas Santos <117400842+LucasSantos91@users.noreply.github.com> Date: Fri, 17 Nov 2023 22:01:13 -0300 Subject: [PATCH] Faster implementation of intToEnum. --- lib/std/meta.zig | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/lib/std/meta.zig b/lib/std/meta.zig index d65d53f8f6..75dee47fa7 100644 --- a/lib/std/meta.zig +++ b/lib/std/meta.zig @@ -901,11 +901,20 @@ pub fn intToEnum(comptime EnumTag: type, tag_int: anytype) IntToEnumError!EnumTa return error.InvalidEnumTag; } - inline for (enum_info.fields) |f| { - const this_tag_value = @field(EnumTag, f.name); - if (tag_int == @intFromEnum(this_tag_value)) { - return this_tag_value; + // We don't direcly iterate over the fields of EnumTag, as that + // would require an inline loop. Instead, we create an array of + // values that is comptime-know, but can be iterated at runtime + // without requiring an inline loop. This generates better + // machine code. + const values = comptime blk: { + var result: [enum_info.fields.len]enum_info.tag_type = undefined; + for (&result, enum_info.fields) |*dst, src| { + dst.* = src.value; } + break :blk result; + }; + for (values) |v| { + if (v == tag_int) return @enumFromInt(tag_int); } return error.InvalidEnumTag; }