Comptime function call counting

You can’t have a global comptime var. This is because comptime is designed such that the comptime evaluation of one function can’t affect that of another. There have been some hacks to allow mutable global state at comptime (like exploiting error codes), but they aren’t intended and can’t be relied upon.

You could keep track of the number of calls to add at comptime by passing a pointer to a comptime var as a parameter, but you would only have the final call count after the calls to add, and you can’t travel back in time to pass this value into the init function.

This is the closest you could get to your example:

const std = @import("std");

const LabeledTimer = struct {
    timer: std.time.Timer,
    results: [128]u64,

    fn init() !@This() {
        return .{
            .timer = try std.time.Timer.start(),
            .results = undefined,
        };
    }

    inline fn add(self: *@This(), comptime label: []const u8, comptime comptime_info: *LabeledTimerComptime) void {
        self.addRuntime(comptime_info.result_labels.len);

        comptime_info.result_labels = comptime_info.result_labels ++ &[_][]const u8{label};
    }

    fn addRuntime(self: *@This(), idx: usize) void {
        self.results[idx] = self.timer.lap();
    }

    inline fn print(self: *@This(), comptime comptime_info: *LabeledTimerComptime) void {
        self.printRuntime(comptime_info.result_labels);
    }

    fn printRuntime(self: *@This(), result_labels: []const []const u8) void {
        for (self.results[0..result_labels.len], result_labels) |time, label| {
            std.debug.print("{d} : {s}\n", .{ time, label });
        }
    }
};

const LabeledTimerComptime = struct {
    result_labels: []const []const u8,

    const init: LabeledTimerComptime = .{
        .result_labels = &.{},
    };
};

pub fn main() !void {
    comptime var timer_comptime: LabeledTimerComptime = .init;
    var timer = try LabeledTimer.init();

    timer.add("foo", &timer_comptime);
    timer.add("bar", &timer_comptime);

    timer.print(&timer_comptime);
}

1 Like