LongDuZboub
LongDuZboub

Reputation: 1051

Cast an iterator to another type

I'm working on a renderer using OpenGL.

I've got a first class, Geometry:

class Geometry
{
 public:

    void setIndices( const unsigned int* indices, int indicesCount );

 private:
    std::vector<unsigned char> colors;
    std::vector<float>         positions;
    std::vector<unsigned int>  indices;
};

Sometimes, my geometries need to stock for his indices with different type, data can be:

1. std::vector<unsigned char> 
2. std::vector<short> 
3. std::vector<int>

// I've already think about std::vector<void>, but it sound dirty :/.

Currently, I use unsigned int everywhere and I cast my data when I want to set it to my geometry:

const char* indices = { 0, 1, 2, 3 };
geometry.setIndices( (const unsigned int*) indices, 4 );

Later, I would like to update or read this array during runtime (array can stock more than 60000 indices sometimes), so I do something like that:

std::vector<unsigned int>* indices = geometry.getIndices();
indices->resize(newIndicesCount);

std::vector<unsigned int>::iterator it = indices->begin();

The problem is that my iterator loop on a unsigned int array, so iterator goto 4 bytes to 4 bytes, my initial data can be char (so 1 byte to 1 byte). It's impossible to read my initial data or update it with new data.

When I want update my vector, my only solution is to create a new array, fill it with data, then cast it to an unsigned int array, I would like to iterate on my indices pointer.

  1. How can I do something generic (working with unsigned int, char and short)?
  2. How can I iterate over the array without copy?

Thanks for your time!

Upvotes: 1

Views: 3571

Answers (1)

Mike Seymour
Mike Seymour

Reputation: 254431

Casting to the wrong pointer type would give undefined behaviour and will certainly fail if, as here, the type has the wrong size.

How can I do something generic (working with unsigned int, char and short)?

A template would be the simplest way to make that generic:

template <typename InputIterator>
void setIndices(InputIterator begin, InputIterator end) {
    indices.assign(begin, end);
}

Usage (correcting your example to use an array rather than a pointer):

const char indices[] = { 0, 1, 2, 3 };
geometry.setIndices(std::begin(indices), std::end(indices));

You might consider a convenience overload to take containers, arrays and other range types directly:

template <typename Range>
void setIndices(Range const & range) {
    setIndices(std::begin(range), std::end(range));
}

const char indices[] = { 0, 1, 2, 3 };
geometry.setIndices(indices);

How can I iterate over the array without copy?

You can't change the type of an array without copying the data. To avoid a copy, you'll have to expect the correct array type.

Upvotes: 2

Related Questions