Question

Do any of the popular C++ libraries have a class (or classes) that allow the developer to use arrays with arbitrary indices without sacrificing speed ?

To give this question more concrete form, I would like the possibility to write code similar to the below:

//An array with indices in [-5,6)
ArbitraryIndicesArray<int> a = ArbitraryIndicesArray<int>(-5,6);  
for(int index = -5;index < 6;++index)
{
    a[index] = index;
}
Was it helpful?

Solution

Really you should be using a vector with an offset. Or even an array with an offset. The extra addition or subtraction isn't going to make any difference to the speed of execution of the program.

If you want something with the exact same speed as a default C array, you can apply the offset to the array pointer:

int* a = new int[10];
a = a + 5;
a[-1] = 1;

However, it is not recommended. If you really want to do that you should create a wrapper class with inline functions that hides the horrible code. You maintain the speed of the C code but end up with the ability to add more error checking.

As mentioned in the comments, after altering the array pointer, you cannot then delete using that pointer. You must reset it to the actual start of the array. The alternative is you always keep the pointer to the start but work with another modified pointer.

//resetting the array by adding the offset (of -5)
delete [] (a - 5);

OTHER TIPS

A std::vector<int> would do the trick here.
Random acess to a single element in a vector is only O(1).

If you really need the custom indices you can make your own small class based on a vector to apply an ofset.

Use the map class from the STL:

std::map<int, int> a;
for( int index = -5; index < 6; ++index )
{ 
    a[index] = index; 
}

map is implemented internally as a sorted container, which uses a binary search to locate items.

[This is an old thread but for reference sake...]

Boost.MultiArray has an extents system for setting any index range.

The arrays in the ObjexxFCL library have full support for arbitrary index ranges.

These are both multi-dimensional array libraries. For the OP 1D array needs the std::vector wrapper above should suffice.

Answer edited because I'm not very smart.

Wrap an std::vector and an offset into a class and provide an operator[]:

template <class T>
class ArbVector
{
    private:
        int _offset;
        std::vector<T> container;
    public:
        ArbVector(int offset) : _offset(offset) {}
        T& operator[](int n) { return container[n + _offset] }
};

Not sure if this compiles, but you get the idea.

Do NOT derive from std::vector though, see comments.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top