I don’t think that phrase is accurate since I don’t assume anything. Elements can literally not even have a coherent bit representation for all I care. Technically I don’t even need the type, just the length in memory of each element.
I think the current definition is sufficiently accurate and necessary given the context around this algorithm.
Still, I reworded it as:
/// Returns an iterator capable of generating all permutations of the elements
/// present in the given buffer, regardless of their value, uniqueness or
/// initial ordering.
Wtf. First of all, that function is magic. Second of all, I was falsely under the impression that std.testing.allocator was doing that kind of job for me and that was the point of using it. It is weird for me having a debug allocator and a testing allocator but neither seems to do a great job a catching these.
To be honest the checkAllAllocationFailures function is god-like already and knowing of it’s existence will prove useful, but I kinda feel like this testing should be somehow included in test blocks or allocators by default.
On the other hand, reading the docs seems like errdefer is basically mandatory after an allocation so this could just be a warning at LSP level, an error at compile time, or just embedded in the language itself honestly.
I do struggle! Some time ago I saw Andrew’s DOP talk and I really liked to learn about alignment, but I didn’t used it so I lost it. At this point I feel like to write Zig I need a degree in computer science.
After 2 hours of trying to understand this I get to various conclusions:
-
I can do the stupid easy and allocWithOptions to align my big backing ints to 1 so they fit right after the Trackers. I thought this might hurt performance or even give me random performance per iteration depending of the amount of Trackers I have, but apparently it doesn’t.
-
I can adapt calculateAllocations so it takes into account alignment but that requires me to pass the pointer to the backing buffer to the function since that pointer itself might be aligned in various ways such as that even when Trackers len is % 4 == 0 the allocator’s end is not aligned to 4 but to 2…
-
I can burn my PC
Given that the alignment of the backing int doesn’t affect performance and keeps everything smaller, I’ll go that route for now I think.
You are quite exhaustive. Changed it to:
try std.testing.expectEqualStrings(&toPermutate, "123");
try std.testing.expect(it.next());
try std.testing.expectEqualStrings(&toPermutate, "132");
try std.testing.expect(it.next());
try std.testing.expectEqualStrings(&toPermutate, "312");
try std.testing.expect(it.next());
try std.testing.expectEqualStrings(&toPermutate, "321");
try std.testing.expect(it.next());
try std.testing.expectEqualStrings(&toPermutate, "231");
try std.testing.expect(it.next());
try std.testing.expectEqualStrings(&toPermutate, "213");
try std.testing.expect(!it.next());
Btw, I discovered that certain tests can affect the performance of other tests. Commenting out test "test fixed buffer" will add 5ns per .nest() to test "test iteration performance".
Kinda funny, still, I just don’t care enough to make a proper performance testing suit.