If you'd rather read code than my explanation, here's the C++ code I'm trying to emulate.
I've written a simple profiler that times blocks of code. It looks very roughly like this:
pub const Profiler = struct {
anchors: [num_anchors]Anchor,
pub fn startBlock(self *Profiler, label: []const u8, index: usize) void {
...
}
pub fn endBlock(self *Profiler) void {
...
}
}
When I have some Zig code that I want to time, I import it into the file and create a global Profiler. Here's how it's used when I want to time a function:
fn foo() void {
profiler.startBlock("foo", 1);
defer profiler.endBlock();
}
The index parameter of startBlock is used to index the anchors field of the profiler. So every time foo is called, I want to update the Anchor at index 1 of anchors with the additional time that foo took. For a different function the timing data might be stored at index 2, and so on. The thing is, I don't want to manually have to put in different indices for every instance of profiler.startBlock cuz it's both tedious and error-prone.
The profiler I'm basing this on uses the __COUNTER__ macro to automatically create a new index at compile time for every block of code to be timed.
It seems like something similar should be possible with comptime, but I haven't been able to create a comptime variable that can be stored in a Profiler and incremented only at compile time. I've tried some different permutations and gotten only compile errors.
If there's no clean equivalent, how would you solve this in Zig?
Source code for the https://computerenhance.com programming series - cmuratori/computer_enhance