mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 14:23:09 +00:00
Processed review comments. Updated documentation, used the typinfo for field access, generate compile error on allowzero and set C poitners to null
This commit is contained in:
parent
195195d238
commit
f7aa4f5280
@ -276,8 +276,12 @@ pub fn set(comptime T: type, dest: []T, value: T) void {
|
|||||||
d.* = value;
|
d.* = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Generally, Zig users are encouraged to explicitly initialize all fields of a struct explicitly rather than using this function.
|
||||||
|
/// However, it is recognized that there are sometimes use cases for initializing all fields to a "zero" value. For example, when
|
||||||
|
/// interfacing with a C API where this practice is more common and relied upon. If you are performing code review and see this
|
||||||
|
/// function used, examine closely - it may be a code smell.
|
||||||
/// Zero initializes the type.
|
/// Zero initializes the type.
|
||||||
/// This can be used to zero initialize a C-struct.
|
/// This can be used to zero initialize a any type for which it makes sense. Structs will be initialized recursively.
|
||||||
pub fn zeroes(comptime T: type) T {
|
pub fn zeroes(comptime T: type) T {
|
||||||
switch (@typeInfo(T)) {
|
switch (@typeInfo(T)) {
|
||||||
.ComptimeInt, .Int, .ComptimeFloat, .Float => {
|
.ComptimeInt, .Int, .ComptimeFloat, .Float => {
|
||||||
@ -295,7 +299,7 @@ pub fn zeroes(comptime T: type) T {
|
|||||||
.Optional, .Null => {
|
.Optional, .Null => {
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
.Struct => {
|
.Struct => |struct_info| {
|
||||||
if (@sizeOf(T) == 0) return T{};
|
if (@sizeOf(T) == 0) return T{};
|
||||||
if (comptime meta.containerLayout(T) == .Extern) {
|
if (comptime meta.containerLayout(T) == .Extern) {
|
||||||
var item: T = undefined;
|
var item: T = undefined;
|
||||||
@ -303,25 +307,23 @@ pub fn zeroes(comptime T: type) T {
|
|||||||
return item;
|
return item;
|
||||||
} else {
|
} else {
|
||||||
var structure: T = undefined;
|
var structure: T = undefined;
|
||||||
comptime var field_i = 0;
|
inline for (struct_info.fields) |field| {
|
||||||
inline while (field_i < @memberCount(T)) : (field_i += 1) {
|
@field(structure, field.name) = zeroes(@TypeOf(@field(structure, field.name)));
|
||||||
@field(structure, @memberName(T, field_i)) = zeroes(@TypeOf(@field(structure, @memberName(T, field_i))));
|
|
||||||
}
|
}
|
||||||
return structure;
|
return structure;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.Pointer => |ptr_info| {
|
.Pointer => |ptr_info| {
|
||||||
if (ptr_info.is_allowzero) {
|
switch (ptr_info.size) {
|
||||||
return null;
|
.Slice => {
|
||||||
} else {
|
return &[_]ptr_info.child{};
|
||||||
switch (ptr_info.size) {
|
},
|
||||||
.Slice => {
|
.C => {
|
||||||
return &[_]ptr_info.child{};
|
return null;
|
||||||
},
|
},
|
||||||
.One, .Many, .C => {
|
.One, .Many => {
|
||||||
@compileError("Can't set a non nullable pointer to zero.");
|
@compileError("Can't set a non nullable pointer to zero.");
|
||||||
},
|
},
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.Array => |info| {
|
.Array => |info| {
|
||||||
@ -372,6 +374,7 @@ test "mem.zeroes" {
|
|||||||
|
|
||||||
const Pointers = struct {
|
const Pointers = struct {
|
||||||
optional: ?*u8,
|
optional: ?*u8,
|
||||||
|
c_pointer: [*c]u8,
|
||||||
slice: []u8,
|
slice: []u8,
|
||||||
};
|
};
|
||||||
pointers: Pointers,
|
pointers: Pointers,
|
||||||
@ -397,6 +400,7 @@ test "mem.zeroes" {
|
|||||||
testing.expectEqual(@as(f32, 0), b.integral_types.float_32);
|
testing.expectEqual(@as(f32, 0), b.integral_types.float_32);
|
||||||
testing.expectEqual(@as(f64, 0), b.integral_types.float_64);
|
testing.expectEqual(@as(f64, 0), b.integral_types.float_64);
|
||||||
testing.expectEqual(@as(?*u8, null), b.pointers.optional);
|
testing.expectEqual(@as(?*u8, null), b.pointers.optional);
|
||||||
|
testing.expectEqual(@as([*c]u8, null), b.pointers.c_pointer);
|
||||||
testing.expectEqual(@as([]u8, &[_]u8{}), b.pointers.slice);
|
testing.expectEqual(@as([]u8, &[_]u8{}), b.pointers.slice);
|
||||||
for (b.array) |e| {
|
for (b.array) |e| {
|
||||||
testing.expectEqual(@as(u32, 0), e);
|
testing.expectEqual(@as(u32, 0), e);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user