i was trying to implement a List(like c#) in zig, but i get an error in alloc:
C:\ProgramData\chocolatey\lib\zig\tools\zig-windows-x86_64-0.12.0\lib\std\heap\arena_allocator.zig:181:38: error: unable to evaluate comptime expression var cur_node = if (self.state.buffer_list.first) |first_node|
Here is the code:
const std = @import("std");
const e = error{ OutOfMemory, ErrorReAlloc };
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
pub fn Slice(size: usize, comptime T: type) !type {
const alloc = arena.allocator();
const tmemory = alloc.alloc(T, size) catch return e.OutOfMemory;
return struct {
const This = @This();
var len = size;
var memory = tmemory;
fn Add(position: usize, value: anytype) !void {
if (This.memory.len == 0) This.memory = try alloc.alloc(T, This.len);
if (position >= This.len) {
This.len += position - This.len + This.len / 2;
const newM = alloc.realloc(This.memory, This.len) catch return e.ErrorReAlloc;
std.mem.copyForwards(T, newM, This.memory);
This.memory = tmemory;
}
This.memory[position] = value;
}
fn Get(position: usize) !u8 {
if (position >= This.len) {
return e.OutOfMemory;
}
return This.memory[position];
}
};
}
fn prova(a: u8) type {
_ = a;
return struct {};
}
pub fn main() !void {
comptime var r = try Slice(2, u8);
try r.Add(0, 1);
try r.Add(1, 0);
try r.Add(2, 9);
for (0..r.len) |i| {
std.debug.print("{d} = {d}\n", .{ i, try r.Get(i) }); // try r.Get(i);
}
defer arena.deinit();
}
i expecting that the alloc works, since at runtime there would be the type, don't understand why i can do this. If i do alloc into a function it work perfectly(using a type)
You're trying to allocate memory at compile time, which is not allowed.
The function fn Slice(size: usize, comptime T: type) !type
returns a type, this means that the function must be ran at compile time. That's why the call to alloc.alloc(T, size)
fails.
What is usually done is to add a function called init
to the struct you are returning, and this function makes the allocations and returns an instance of Slice
.
As sigod suggested, this is the pattern that ArrayList uses. Also check out the tests of ArrayList for how this pattern is used.