You simply need a class with a method that allows you to read or write any cell, and which resizes upon out-of-bounds access. This is not hard. I was feeling generous so...
Code:
#include <vector>
template <typename T>
class growableMatrix
{
std::vector<T> contents;
size_t num_rows, num_cols;
public:
growableMatrix(size_t rows=0, size_t cols=0) :
contents(rows*cols), num_rows(rows), num_cols(cols)
{}
T &operator()(size_t row, size_t col)
{
if (row >= num_rows && col < num_cols)
{
num_rows = row+1;
contents.resize(num_rows*num_cols);
}
else if (row >= num_rows || col >= num_cols)
{
size_t new_num_rows = std::max(row+1, num_rows);
size_t new_num_cols = std::max(col+1, num_cols);
std::vector<T> new_contents(new_num_rows * new_num_cols);
for (size_t i = 0; i<num_rows; ++i)
for (size_t j = 0; j<num_cols; ++j)
new_contents[i * new_num_cols + j] = contents[i * num_cols + j];
new_contents.swap(contents);
num_rows = new_num_rows;
num_cols = new_num_cols;
}
return contents[row * num_cols + col];
}
T operator()(size_t row, size_t col) const
{
if (row >= num_rows || col >= num_cols)
return T();
return contents[row * num_cols + col];
}
size_t width() const { return num_cols; }
size_t height() const { return num_rows; }
};
// Example usage:
growableMatrix<double> x;
x(3, 4) = 12;
x(4, 5) = 20;
x(4, 8) = 32;
x(6, 8) = 48;
x(2, 7) = 14;
assert(x(3, 4) == 12);
assert(x(4, 5) == 20);
assert(x(4, 8) == 32);
assert(x(6, 8) == 48);
assert(x(2, 7) == 14);
const growableMatrix<double> &y = x;
assert(y(10, 99) == 0.0);
assert(y(4, 8) == 32);
assert(y.height() == 7 && y.width() == 9);
Heck I even tested it today.
Note that it does not support negative indexing, I assume this is not required. You'll note that I also added a const accessor that allows you to perform reads, even to coordinates which have never been written to, in which case you'll get back zero.