| ... | @@ -432,6 +432,13 @@ pub fn zeroInit(comptime T: type, init: anytype) T { | ... | @@ -432,6 +432,13 @@ pub fn zeroInit(comptime T: type, init: anytype) T { |
| 432 | .Struct => |init_info| { | 432 | .Struct => |init_info| { |
| 433 | var value = std.mem.zeroes(T); | 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 | if (init_info.is_tuple) { | 442 | if (init_info.is_tuple) { |
| 436 | inline for (init_info.fields) |field, i| { | 443 | inline for (init_info.fields) |field, i| { |
| 437 | @field(value, struct_info.fields[i].name) = @field(init, field.name); | 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,21 +450,14 @@ pub fn zeroInit(comptime T: type, init: anytype) T { |
| 443 | if (!@hasField(T, field.name)) { | 450 | if (!@hasField(T, field.name)) { |
| 444 | @compileError("Encountered an initializer for `" ++ field.name ++ "`, but it is not a field of " ++ @typeName(T)); | 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| { | 454 | switch (@typeInfo(field.field_type)) { |
| 449 | if (@hasField(Init, field.name)) { | 455 | .Struct => { |
| 450 | switch (@typeInfo(field.field_type)) { | 456 | @field(value, field.name) = zeroInit(field.field_type, @field(init, field.name)); |
| 451 | .Struct => { | 457 | }, |
| 452 | @field(value, field.name) = zeroInit(field.field_type, @field(init, field.name)); | 458 | else => { |
| 453 | }, | 459 | @field(value, field.name) = @field(init, field.name); |
| 454 | else => { | 460 | }, |
| 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; | | |
| 461 | } | 461 | } |
| 462 | } | 462 | } |
| 463 | | 463 | |
| ... | @@ -515,6 +515,28 @@ test "zeroInit" { | ... | @@ -515,6 +515,28 @@ test "zeroInit" { |
| 515 | .b = 0, | 515 | .b = 0, |
| 516 | .a = 0, | 516 | .a = 0, |
| 517 | }, c); | 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 | /// Compares two slices of numbers lexicographically. O(n). | 542 | /// Compares two slices of numbers lexicographically. O(n). |