| ... | ... | @@ -432,6 +432,13 @@ pub fn zeroInit(comptime T: type, init: anytype) T { |
| 432 | 432 | .Struct => |init_info| { |
| 433 | 433 | var value = std.mem.zeroes(T); |
| 434 | 434 | |
| 435 | inline for (struct_info.fields) |field| { |
| 436 | if (field.default_value) |default_value_ptr| { |
| 437 | const default_value = @ptrCast(*const field.field_type, default_value_ptr).*; |
| 438 | @field(value, field.name) = default_value; |
| 439 | } |
| 440 | } |
| 441 | |
| 435 | 442 | if (init_info.is_tuple) { |
| 436 | 443 | inline for (init_info.fields) |field, i| { |
| 437 | 444 | @field(value, struct_info.fields[i].name) = @field(init, field.name); |
| ... | ... | @@ -443,21 +450,14 @@ pub fn zeroInit(comptime T: type, init: anytype) T { |
| 443 | 450 | if (!@hasField(T, field.name)) { |
| 444 | 451 | @compileError("Encountered an initializer for `" ++ field.name ++ "`, but it is not a field of " ++ @typeName(T)); |
| 445 | 452 | } |
| 446 | | } |
| 447 | 453 | |
| 448 | | inline for (struct_info.fields) |field| { |
| 449 | | if (@hasField(Init, field.name)) { |
| 450 | | switch (@typeInfo(field.field_type)) { |
| 451 | | .Struct => { |
| 452 | | @field(value, field.name) = zeroInit(field.field_type, @field(init, field.name)); |
| 453 | | }, |
| 454 | | else => { |
| 455 | | @field(value, field.name) = @field(init, field.name); |
| 456 | | }, |
| 457 | | } |
| 458 | | } else if (field.default_value) |default_value_ptr| { |
| 459 | | const default_value = @ptrCast(*const field.field_type, default_value_ptr).*; |
| 460 | | @field(value, field.name) = default_value; |
| 454 | switch (@typeInfo(field.field_type)) { |
| 455 | .Struct => { |
| 456 | @field(value, field.name) = zeroInit(field.field_type, @field(init, field.name)); |
| 457 | }, |
| 458 | else => { |
| 459 | @field(value, field.name) = @field(init, field.name); |
| 460 | }, |
| 461 | 461 | } |
| 462 | 462 | } |
| 463 | 463 | |
| ... | ... | @@ -515,6 +515,28 @@ test "zeroInit" { |
| 515 | 515 | .b = 0, |
| 516 | 516 | .a = 0, |
| 517 | 517 | }, c); |
| 518 | |
| 519 | const Foo = struct { |
| 520 | foo: u8 = 69, |
| 521 | bar: u8, |
| 522 | }; |
| 523 | |
| 524 | const f = zeroInit(Foo, .{}); |
| 525 | try testing.expectEqual(Foo{ |
| 526 | .foo = 69, |
| 527 | .bar = 0, |
| 528 | }, f); |
| 529 | |
| 530 | const Bar = struct { |
| 531 | foo: u32 = 666, |
| 532 | bar: u32 = 420, |
| 533 | }; |
| 534 | |
| 535 | const b = zeroInit(Bar, .{69}); |
| 536 | try testing.expectEqual(Bar{ |
| 537 | .foo = 69, |
| 538 | .bar = 420, |
| 539 | }, b); |
| 518 | 540 | } |
| 519 | 541 | |
| 520 | 542 | /// Compares two slices of numbers lexicographically. O(n). |