| ... | @@ -273,6 +273,33 @@ pub fn set(comptime T: type, dest: []T, value: T) void { | ... | @@ -273,6 +273,33 @@ pub fn set(comptime T: type, dest: []T, value: T) void { |
| 273 | d.* = value; | 273 | d.* = value; |
| 274 | } | 274 | } |
| 275 | | 275 | |
| | 276 | /// Zero initializes the type. |
| | 277 | /// This can be used to zero initialize a C-struct. |
| | 278 | pub fn zeroes(comptime T: type) T { |
| | 279 | if (@sizeOf(T) == 0) return T{}; |
| | 280 | |
| | 281 | if (comptime meta.containerLayout(T) != .Extern) { |
| | 282 | @compileError("TODO: Currently this only works for extern types"); |
| | 283 | } |
| | 284 | |
| | 285 | var item: T = undefined; |
| | 286 | @memset(@ptrCast([*]u8, &item), 0, @sizeOf(T)); |
| | 287 | return item; |
| | 288 | } |
| | 289 | |
| | 290 | test "mem.zeroes" { |
| | 291 | const C_struct = extern struct { |
| | 292 | x: u32, |
| | 293 | y: u32, |
| | 294 | }; |
| | 295 | |
| | 296 | var a = zeroes(C_struct); |
| | 297 | a.y += 10; |
| | 298 | |
| | 299 | testing.expect(a.x == 0); |
| | 300 | testing.expect(a.y == 10); |
| | 301 | } |
| | 302 | |
| 276 | pub fn secureZero(comptime T: type, s: []T) void { | 303 | pub fn secureZero(comptime T: type, s: []T) void { |
| 277 | // NOTE: We do not use a volatile slice cast here since LLVM cannot | 304 | // NOTE: We do not use a volatile slice cast here since LLVM cannot |
| 278 | // see that it can be replaced by a memset. | 305 | // see that it can be replaced by a memset. |