views:

307

answers:

3

What I want is something similar to STL vector when it comes to access complexity, reallocation on resize, etc. I want it to support arbitrary index range, for example there could be elements indexed from -2 to +7 or from +5 to +10. I want to be able to push_front efficiently. Also I want two-way resize...

I know I could write something like this myself, but if there is an already written library that supports this please tell me.

+3  A: 

Deque is very much like a vector in that it supports random access and efficient insertion at the end and it also supports efficient insertion at the beginning.

Map supports access based on arbitrary keys, you can have any range you want, or even a sparsely populated array. Iteration over the collection is slow.

Unordered map (tr1) is similar to map except it supports better iteration.

As a general rule of thumb, use a vector (in your case adapt it to the behaviour you want) and only change when you have evidence that the vector is causing slowness.

Dave Hillier
*Finding* a given key in a map is slow (O(log n)). *Iteration* over a map is fast -- amortised O(1) time per element.
j_random_hacker
Looks like deque is the answer. Thanks, I just did not know the name of the container. @random_hacker I wanted something with fast random access and without keys.
Muxecoid
deques don't have significantly larger memory use than vector. They also don't need to copy any existing elements on resize. You can think of the implementation as a linked list of vectors. To add more elements (front or back), you just add another node if the existing ones are full.
KeithB
@j_random_hacker. What is faster find on a deque at O(N) or a map at O(log N)? O(1) doesn't mean fast, it just means that it's the same regardless of the size of your collection.
Dave Hillier
@KeithB I've removed that info.
Dave Hillier
@Dave: Sure, Big-Oh notation doesn't provide all the relevant information. On a typical CPU I expect iteration over a map to be at least 3 times slower than over a deque or vector, even though both are O(1), because pointers need to be followed.
j_random_hacker
+2  A: 

It seems the only difference between what you want and a vector is the offset you require for accessing elements, which you take care if by overloading operator [] or something. Unless I didn't understand what you meant by two-way resize.

Assaf Lavie
This helps I can override [] of deque and count the number fo push-fronts.
Muxecoid
A: 

If you want 2 way resize, etc... you could create your own vector class with 2 vectors inside one for the 0 and positive values and another for the negative ones.

Then just implement the common functions and add new ones (ex: push_begin to add to the negative indexes vector), and update the correspndent vectors inside.

João Augusto
This does not help when I push front if existing indices go, for example, from +10 to +100.
Muxecoid
Same as when you will "push_begin", you will have to keep track of the index that starts so that _v1[10] will be _v1[10 - startIndex].You have the same problem with the Deque...
João Augusto