#Cast `[]?T` to `[]T`?
1 messages · Page 1 of 1 (latest)
You need to create a new slice, think of ?T as stuct { null: bool, data: T}
if you cast you roughly half of the data will actually be the null field (plus padding) not the actual data that you want.
Yeah you're right, casting wouldn't make sense. But maybe there is a built in function or something for this purpose? If there is not, would this be the "proper" way?
const array = try allocator.alloc(?usize, size);
// some logic ...
const array_concrete = try allocator.alloc(usize, size);
for (array, array_concrete) |v, *v_conc| v_conc.* = v.?;
no buitin for this, the for loop is the solution.
However it is questionable that you have a []?T in the firstplace, depending on what you are doing there might be a better solution.
If T happens to be a pointer, casting would be possible
Hmm, this is the actual function I made:
fn findLargestBatteryPackIndexes(self: *const Self, allocator: std.mem.Allocator) ![]usize {
const pack_indexes = try allocator.alloc(?usize, self.pack_size);
@memset(pack_indexes, null);
defer allocator.free(pack_indexes);
var bank_idx: usize = 1;
while (bank_idx < self.bank.len) : (bank_idx += 1) {
var pack_idx: usize = @max(
0,
@as(isize, @intCast(self.pack_size)) - (@as(isize, @intCast(self.bank.len)) - @as(isize, @intCast(bank_idx))),
);
while (pack_idx < pack_indexes.len) : (pack_idx += 1) {
if (pack_indexes[pack_idx]) |idx| {
if (self.bank[bank_idx] > self.bank[idx]) {
pack_indexes[pack_idx] = bank_idx;
if (pack_idx < pack_indexes.len - 1) @memset(pack_indexes[pack_idx + 1 ..], null);
break;
}
} else {
pack_indexes[pack_idx] = bank_idx;
break;
}
}
}
const pack_indexes_concrete = try allocator.alloc(usize, self.pack_size);
for (pack_indexes, pack_indexes_concrete) |idx, *idx_conc| idx_conc.* = idx.?;
return pack_indexes_concrete;
}
I'm using null values to check for unassigned indexes. But at the end of the processing I know there should be no null values and want to return a non-optional slice. I'd love to hear suggestions tho
Is this aoc? I haven't made it past day 2 yet 💀
ye haha, day 3 part 2
Just lack of time during the week
I would have a second slice of bools []bool instead of a single []?usize, call it something like active_indexes.
it uses less memory, and avoids having to copy all the usize into a new slice.
just add a defer for (active_indexes) |active| std.debug.assert(active); to ensure you dont miss any