Iterate over multiple std containers afterwards

I have the following class (which obviously doesn't work as intended yet):

class A
{
private:
    std::vector<int> firstVector, secondVector;
public:
    std::vector<int>::iterator begin(){
        return firstVector.begin();
    }
    std::vector<int>::iterator end(){
        return secondVector.end();
    }
};

      

How can I define an iterator that will subsequently go through two member containers for example. after firstVector.end()-1

secondVector.begin()

comes back and goes all the way to secondVector.end()

?

+3


source to share


3 answers


Nothing prevents you from skating on your own. Might even make it random access!

struct chain_iterator 
    : std::iterator<std::random_access_iterator_tag, int>
{
    using it = std::vector<int>::iterator;

    std::pair<it, it> v1, v2;
    bool first;
    it cur;
};

      

We keep the original iterator pairs so that we can do the random access correctly.

The increment is what you expect:

chain_iterator& operator++() {
    ++cur;
    if (first && cur == v1.second) {
        first = false;
        cur = v2.first;
    }
    return *this;
}

      



The distinction is trivial:

int& operator*() { return *cur; }

      

Advance should perform additional checks:

chain_iterator& operator+=(size_t n) {
    if (!first) {
        // trivial case
        cur += n;
    }
    else {
        size_t d = v1.second - cur;
        if (d < n) {
            cur += n;
        }
        else {
            first = false;
            cur = v2.first + (d - n);
        }
    }
    return *this;
}

      

I will leave all operations as an exercise.

+2


source


Basically you need to define some kind of custom iterator that internally checks for the end of the first range and then moves on to the next.

However, this kind of thing happens a lot. Eventually you ask why an iterator for two vectors, why an iterator for two vectors, why a sequence of the same container type, etc. Nir Tzachar and I wrote a C ++ Python port of itertools that does things like this. In this case, you simply use



chain(firstVector, secondVector)

      

It can be downloaded from this beatbox repo .

+4


source


You can write your own function to increase:

std::vector<int>::iterator& inc(std::vector<int>::iterator& it) {
    ++it;
    if (it == firstVector.end())
        it = secondVector.begin();
    return it;
}

      

It is also a good sign for others that the increment is not happening normally.

-2


source







All Articles