value: simplify list conversion code
There was really no reason to use ArrayLists here when the list length is known ahead of time. This slightly shortens the code and should be slightly more memory/stack efficient.
This commit is contained in:
parent
39619e7d6b
commit
98eac68929
@ -131,15 +131,18 @@ pub const Value = union(enum) {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
.list, .inline_list => |lst| {
|
.list, .inline_list => |lst| {
|
||||||
var result = try std.ArrayList(ptr.child).initCapacity(allocator, lst.items.len);
|
const result = try allocator.alloc(ptr.child, lst.items.len + @intFromBool(ptr.sentinel != null));
|
||||||
errdefer result.deinit();
|
|
||||||
for (lst.items) |item| {
|
for (result[0..lst.items.len], lst.items) |*res, item| {
|
||||||
result.appendAssumeCapacity(try item.convertTo(ptr.child, allocator, options));
|
res.* = try item.convertTo(ptr.child, allocator, options);
|
||||||
}
|
}
|
||||||
if (ptr.sentinel) |sent| {
|
|
||||||
return try result.toOwnedSliceSentinel(@as(*align(1) const ptr.child, @ptrCast(sent)).*);
|
if (comptime ptr.sentinel) |sentinel| {
|
||||||
|
const sval = @as(*align(1) const ptr.child, @ptrCast(sentinel)).*;
|
||||||
|
result[lst.items.len] = sval;
|
||||||
|
return result[0..lst.items.len :sval];
|
||||||
} else {
|
} else {
|
||||||
return try result.toOwnedSlice();
|
return result;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
else => return error.BadValue,
|
else => return error.BadValue,
|
||||||
@ -151,7 +154,7 @@ pub const Value = union(enum) {
|
|||||||
result.* = try self.convertTo(ptr.child, allocator, options);
|
result.* = try self.convertTo(ptr.child, allocator, options);
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
else => @compileError("Cannot deserialize into many-pointer or c-pointer " ++ @typeName(T)), // do not support many or C item pointers.
|
else => @compileError("Cannot deserialize into many-pointer or c-pointer " ++ @typeName(T)),
|
||||||
},
|
},
|
||||||
.Array => |arr| {
|
.Array => |arr| {
|
||||||
// TODO: There is ambiguity here because a document expecting a list
|
// TODO: There is ambiguity here because a document expecting a list
|
||||||
@ -168,14 +171,12 @@ pub const Value = union(enum) {
|
|||||||
} else return error.BadValue;
|
} else return error.BadValue;
|
||||||
},
|
},
|
||||||
.list, .inline_list => |lst| {
|
.list, .inline_list => |lst| {
|
||||||
var storage = try std.ArrayList(arr.child).initCapacity(allocator, arr.len);
|
if (lst.items.len != arr.len) return error.BadValue;
|
||||||
defer storage.deinit();
|
|
||||||
for (lst.items) |item| {
|
|
||||||
storage.appendAssumeCapacity(try item.convertTo(arr.child, allocator, options));
|
|
||||||
}
|
|
||||||
// this may result in a big stack allocation, which is not ideal
|
|
||||||
var result: T = undefined;
|
var result: T = undefined;
|
||||||
@memcpy(&result, storage.items);
|
for (&result, lst.items) |*res, item| {
|
||||||
|
res.* = try item.convertTo(arr.child, allocator, options);
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
else => return error.BadValue,
|
else => return error.BadValue,
|
||||||
@ -190,8 +191,8 @@ pub const Value = union(enum) {
|
|||||||
.list, .inline_list => |list| {
|
.list, .inline_list => |list| {
|
||||||
if (list.items.len != stt.fields.len) return error.BadValue;
|
if (list.items.len != stt.fields.len) return error.BadValue;
|
||||||
var result: T = undefined;
|
var result: T = undefined;
|
||||||
inline for (stt.fields, 0..) |field, idx| {
|
inline for (stt.fields, &result, list.items) |field, *res, item| {
|
||||||
result[idx] = try list.items[idx].convertTo(field.type, allocator, options);
|
res.* = try item.convertTo(field.type, allocator, options);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user