I said that I find myself needing it, "
more out of convenience and code cleanliness than necessity", and I was very careful to phrase it that way.
For convenience, because I have multiple classes needing it, I'm making a container that
is very much like a vector.
It's a resizable 2D array... that resizes in all four directions (north, east, south, west).
I could just use a 1D vector, and index into it like
((y * width) + x) like I normally do and have done in the past.
Or I could use
std::vector< std::vector<Type> > (which I don't particularly like, preferring 1D vectors treated as 2D to ensure the rows all stay the same lengths).
However, using a regular vector requires me to worry about re-arranging the location of the elements anyway.
Example: 3 x 3 grid
0 1 2
3 4 5
6 7 8
Resized to 5 x 5 grid:
0 1 2 3 4
5 6 7 8 +
+ + + + +
+ + + + +
+ + + + +
The elements are no longer in their correct positions, relative to each other.
I'd prefer it to be resized as:
0 1 2 + +
3 4 5 + +
6 7 8 + +
+ + + + +
+ + + + +
Unless I need to extend the grid on the other sides (which I do need in my code):
+ 0 1 2 +
+ 3 4 5 +
+ 6 7 8 +
+ + + + +
+ + + + +
So I created a container class called Grid, which is "
a resizable 2D array container, that resizes without harming the relative location of the elements held by the container, and supports negative indices, like a 2D Cartesian grid." (important characteristics underlined - only the first is covered by std::vector)
Yes, I could use std::vector to solve the same thing, but then I'd have to A) have the classes using the vector fumbling around with keeping elements in-sync, B) always be offsetting their indices to correctly support negative indexing. The Grid class handles it all cleanly and intuitively, so I don't bloat the classes using Grid. The Grid class itself is less than 350 lines of code - including excessive whitespacing and comments - so Grid itself isn't bloated or untidy (I'm a real sucker for clean code
).
So yes, "
more out of convenience and code cleanliness than necessity".
I'll post it tomorrow, and you can judge it for yourself - I just want to fix one mistake I'm making somewhere in it where resizing is invalidating the data.
Really, the class only took me a few hours to put together - it's just the manual constructing/destructing parts that is new territory for me. And though I could've just made the class wrap std::vector internally (which would still require the class to be made anyway), it's worth taking the extra time to explore the new territory.