authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-05-26 12:15:08-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-05-26 12:15:08-04:00
log62fefe864840e4d2c8bf4d6ad5509bcac141e7c3
tree6987bc1c7b9be6d30c8edf1b01aced6a86143968
parent5cdeac3b0eaf61bc07e45012d9c335a74f437276

std.fmt: non-exhaustive enums: avoid the loop when it's not necessary


1 files changed, 18 insertions(+), 32 deletions(-)

lib/std/fmt.zig+18-32
...@@ -359,38 +359,24 @@ pub fn formatType(...@@ -359,38 +359,24 @@ pub fn formatType(
359 },359 },
360 .Enum => |enumInfo| {360 .Enum => |enumInfo| {
361 try out_stream.writeAll(@typeName(T));361 try out_stream.writeAll(@typeName(T));
362
363 var has_name: bool = undefined;
364 if (enumInfo.is_exhaustive) {362 if (enumInfo.is_exhaustive) {
365 has_name = true;363 try out_stream.writeAll(".");
366 } else {364 try out_stream.writeAll(@tagName(value));
367 has_name = false;365 return;
368 // Use @tagName only if value is one of known fields
369 inline for (enumInfo.fields) |enumField| {
370 if (@enumToInt(value) == enumField.value) {
371 has_name = true;
372 break;
373 }
374 }
375 }366 }
376367
377 var use_name = has_name;368 // Use @tagName only if value is one of known fields
378 if (comptime std.mem.eql(u8, fmt, "x") or369 inline for (enumInfo.fields) |enumField| {
379 comptime std.mem.eql(u8, fmt, "X") or370 if (@enumToInt(value) == enumField.value) {
380 comptime std.mem.eql(u8, fmt, "d") or371 try out_stream.writeAll(".");
381 comptime std.mem.eql(u8, fmt, "b"))372 try out_stream.writeAll(@tagName(value));
382 {373 return;
383 use_name = false;374 }
384 }375 }
385376
386 if (use_name) {377 try out_stream.writeAll("(");
387 try out_stream.writeAll(".");378 try formatType(@enumToInt(value), fmt, options, out_stream, max_depth);
388 try out_stream.writeAll(@tagName(value));379 try out_stream.writeAll(")");
389 } else {
390 try out_stream.writeAll("(");
391 try formatType(@enumToInt(value), fmt, options, out_stream, max_depth);
392 try out_stream.writeAll(")");
393 }
394 },380 },
395 .Union => {381 .Union => {
396 try out_stream.writeAll(@typeName(T));382 try out_stream.writeAll(@typeName(T));
...@@ -1331,8 +1317,8 @@ test "enum" {...@@ -1331,8 +1317,8 @@ test "enum" {
1331 const value = Enum.Two;1317 const value = Enum.Two;
1332 try testFmt("enum: Enum.Two\n", "enum: {}\n", .{value});1318 try testFmt("enum: Enum.Two\n", "enum: {}\n", .{value});
1333 try testFmt("enum: Enum.Two\n", "enum: {}\n", .{&value});1319 try testFmt("enum: Enum.Two\n", "enum: {}\n", .{&value});
1334 try testFmt("enum: Enum(0)\n", "enum: {x}\n", .{Enum.One});1320 try testFmt("enum: Enum.One\n", "enum: {x}\n", .{Enum.One});
1335 try testFmt("enum: Enum(1)\n", "enum: {X}\n", .{Enum.Two});1321 try testFmt("enum: Enum.Two\n", "enum: {X}\n", .{Enum.Two});
1336}1322}
13371323
1338test "non-exhaustive enum" {1324test "non-exhaustive enum" {
...@@ -1344,9 +1330,9 @@ test "non-exhaustive enum" {...@@ -1344,9 +1330,9 @@ test "non-exhaustive enum" {
1344 try testFmt("enum: Enum.One\n", "enum: {}\n", .{Enum.One});1330 try testFmt("enum: Enum.One\n", "enum: {}\n", .{Enum.One});
1345 try testFmt("enum: Enum.Two\n", "enum: {}\n", .{Enum.Two});1331 try testFmt("enum: Enum.Two\n", "enum: {}\n", .{Enum.Two});
1346 try testFmt("enum: Enum(4660)\n", "enum: {}\n", .{@intToEnum(Enum, 0x1234)});1332 try testFmt("enum: Enum(4660)\n", "enum: {}\n", .{@intToEnum(Enum, 0x1234)});
1347 try testFmt("enum: Enum(f)\n", "enum: {x}\n", .{Enum.One});1333 try testFmt("enum: Enum.One\n", "enum: {x}\n", .{Enum.One});
1348 try testFmt("enum: Enum(beef)\n", "enum: {x}\n", .{Enum.Two});1334 try testFmt("enum: Enum.Two\n", "enum: {x}\n", .{Enum.Two});
1349 try testFmt("enum: Enum(BEEF)\n", "enum: {X}\n", .{Enum.Two});1335 try testFmt("enum: Enum.Two\n", "enum: {X}\n", .{Enum.Two});
1350 try testFmt("enum: Enum(1234)\n", "enum: {x}\n", .{@intToEnum(Enum, 0x1234)});1336 try testFmt("enum: Enum(1234)\n", "enum: {x}\n", .{@intToEnum(Enum, 0x1234)});
1351}1337}
13521338