I think it’s better to allocate a single one dimensional slice where all your data lives and then do index arithmetics to get the elements. Check how Zignal does it. Look at the init and at methods.
Sorry, I should’ve been more specific when I said “I think it’s better”.
In the suggested approach, despite the data being contiguous in memory, the access is not, which might introduce cache misses and prevent SIMD optimizations.
Moreover, there’s an extra overhead per row, since we store the ptr and the len for each one. It might be prohibitive if you have many small matrices.
That being said, being able to use the [][] syntax for indexing is cool, though.
I mean, it’s cool that you did come up with a solution that conforms to the requirement of being able to index with [][]. At the same time, it incurs possibly non-negligible performance costs, as @adria explains.
I think clinging to the [][] syntax is misguided (for Zig, which intentionally does not have operator overloading). Just define a struct with a method that takes the two indices and does the arithmetics for you. Zignal’s Matrix linked above (specifically the at() method) looks like a good example.
Oh you mean this implementation. But the original motive was to make it possible to cast [M*N]u8` to [][N]u8 (with runtime known values) so that you could index it like a matrix. Like you can do in C: