In case it’s of use, I’ve recently had to make a kind of 2D array for my game engine’s entity/component table.
Because of my specific use-case, I’ve called it Table rather than ‘Array2D’, but feel free to rename it if you wish!
The nature of a 2D array makes it a little less suitable for the same kind of interface as Array; technically, it’s probably got more in common with ArrayAllocationBase (if you think about it, it makes sense - e.g. an ‘add’ function which automatically increases the allocation doesn’t really fit in when you have 2 axes to worry about). As such, you do need to specify a capacity, but it is designed to automatically shift stuff around as you would expect it to (in order to keep everything in the same place!).
Here’s the code to stick in a header…
EDIT: Removed old code, since it’s been replaced by this
Another note - I purposely opted to not use ‘row’ and ‘column’ terminology. Due to the way in which 2D data is stored (one axis iterates contiguously, the other by stride), the ‘orientation’ of the table is something best determined on a case-by-case basis. For instance, your data model may be conceptually easier to understand with one particular aspect representing ‘columns’, but that may also be the axis that would benefit (computationally) from being contiguous.
Because of this, I’ve chosen to refer to one axis as defining ‘layers’, and the other axis crosses through those layers; instead of ‘x,y’ or ‘col,row’, the indices are ‘position,layer’, and the dimensions are specified as layer length ('width) * layer count (‘height’). I’m not especially happy with it, but I didn’t want to waste too much time worrying about it so left it as it is!
Hope this helps!
[EDIT] i should point out this is a basic implementation - it’s currently not got any thread safety, and doesn’t have much beyond the basics. Oh, and it assumes uber-primitive types, since it doesn’t construct/destruct! (yep, it is just about the allocation at the moment). I’m in the midst of refactoring it (e.g. making this a TableAllocationBase, and creating a Table class with insert/remove row/column etc…, adding thread safety - and committing to a row-major design!)