Append an element to an array at comptime

i found the following function when googling around:

fn append(a: anytype, e: anytype) @TypeOf(a ++ .{e}) {
    return a ++ .{e};
}

looks right (i think)… but what i can’t figure out is how to declare an array value that i could pass to append… in psuedo code:

comptime {
    var arr = // some zero-length array of (say) u8
    assert(arr.len == 0);
    arr = append(arr, 10);
    assert(arr.len == 1);
    assert(arr[0] == 10);
}

what’s the “right” way to append an element to an array at comptime ???

I don’t know how or if it can be done with arrays but I’ve seen it done with slices in a comptime context:

const std = @import("std");

pub fn main() !void {
    comptime var slice: []const u8 = &[0]u8{};
    slice = slice ++ [1]u8{1};
    slice = slice ++ &[1]u8{2};
    slice = slice ++ .{3};
    std.debug.print("{any}\n", .{slice});
}

Nice, I like defining comptime constants globally since global context is a comptime one, so there’s no need for the comptime keyword.

const std = @import("std");

const SLICE = blk: {
    var slice: []const u8 = &.{};
    slice = slice ++ .{1};
    slice = slice ++ .{2};
    break :blk slice ++ .{3};
};

pub fn main() void {
    std.debug.print("{any}\n", .{SLICE});
}

i tried an “inside-out” variant of your gist:

const LIST = blk: {
    comptime var slice: []const u8 = &[0]u8{};
    const res = struct {
        fn get() []const u8 {
            return slice;
        }
        fn append(e: u8) void {
            slice = slice ++ .{e};
        }
    };
    break :blk res;
};

in its initial state, assert(LIST.get().len == 0) passes…

but after calling LIST.append(10), the underlying slice is still empty…

said another way, i would like my comptime slice to somehow exist OUTSIDE of the scope in which it was originally defined… is this possible in zig???

based on this recent post, it looks like i need to keep my comptime var within a function/block scope… i’ll design accordingly…

but then, my question is: can i pass a reference to my “local” comptime var to some (comptime) function that would presumably manipulate the var???

answering my own question, it would appear so after a quick trip to the sandbox…

1 Like