Nobody is really answering this guy's question.
Before I start... I see memcpy in there. You should not be using memcpy. memcpy works fine for POD types, but if you put a complex type (like a string) in this array, it will explode.
There are really 2 ways of doing this:
1) The harder way, which is similar to what vector does, is it allocates memory separately, then places the objects in memory with placement new.
2) The easier way, which is to just use the assignment operator.
Since you're having a hard time, I'd suggest option 2 for this task. The big downside to #2 is it doesn't allow you to destruct individual obejects which means
every resize means a full reallocation and copy, even if you're reducing the overall size of the array.
Option 1 would be more efficient since you could over-allocate and reduce the number of buffer copies, but it would also make the code much more complicated.
When the dimension is shrinking, you simply only copy the necessary elements to the new buffer. When it grows, you copy all of them, and leave the others default constructed (assuming you're using option #2). But remember to
copy with the assignment operator or std::copy. Don't ever use memcpy on templated types or the template will not work with complex types.
Anyway this is tricky since the dimension count is variable, so it's going to take some crafty pointer math.
Also, it's actually one of the few places I would use recursion. I'd probably do something like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
|
void resize(const unsigned* newdims) //you might want to use va_arg here, but I'm using an array to keep it simple.
{
// ...error check and stuff...
unsigned* mindims = new unsigned[num_dimensions];
for(unsigned i = 0; i < num_dimensions; ++i)
mindims[i] = std::min( newdims[i], dimensions[i] );
T* newbuf = new T[newsize];
T* dst = newbuf; // to prevent 'copy_dim' from changing newbuf/data
T* src = data;
copy_dim( num_dimensions - 1, dst, src, mindims, newdims );
delete[] mindims;
delete[] data;
data = newbuf;
std::copy(newdims,newdims + num_dimensions, dimensions);
}
// a private function
void copy_dim( unsigned dim, T*& newbuf, T*& oldbuf, const unsigned* mindims, const unsigned* newdims)
{
if(!dim) // if this is the lowest dim...
{
// copy the data over
std::copy( newbuf, newbuf + mindims[dim], oldbuf );
// then move the pointers to the next row
newbuf += newdims[dim];
oldbuf += dimensions[dim];
}
else // otherwise, this is one of the higher dims
{
// copy the lower dims over
for(unsigned i = 0; i < mindims[dim]; ++i)
copy_dim( dim - 1, newbuf, oldbuf, mindims, newdims );
// EDIT
// you'll need to adjust newbuf ptr here if newdims[i] is > mindims[i]
}
}
|