Dispatch iterator (THRUST)

Is there technical possibility to implement (imaginary) thrust::dispatch_iterator, which constructor receives a tuple of iterators and one “selector” iterator, value_type of which is convertible to common difference_type.
Before each of its dereference it have to dereference “selector” iterator at first and use it as an index of element in the tuple of iterators and finally return a result of dereferencing of this selected iterator. Upcoming increment/decrement of thrust::dispatch_iterator have to increment/decrement both recently dereferenced iterator from tuple and “selector” iterator.
Surely all iterators that make up a tuple of iterators should have value_type’s convertible to some single type (say, specified as first parameter of the iterator class template or to thrust::make_dispatch_iterator function).
It can be input or output.
Seems it have to be not better then bidirectional iterator, due to its nature (history of individual increments/decrements matters).

I think you can combine zip iterators with transform iterator to achieve this.

Something similar to this: (pseudo code)

auto dataBegin = make zip iterator(data1.begin(), data2.begin())
auto dataEnd = make zip iterator(data1.end(), data2.end())
auto selectors = ...

auto tmpBegin = make zip iterator(dataBegin, selectors.begin())
auto tmpEnd = make zip iterator(dataEnd, selectors.end())

auto dispatchIter = make transform iterator(tmpBegin, tmpEnd, [](const auto& tmp){
    selector = thrust::get<1>(tmp)
    data = thrust::get<0>(tmp)
    if(selector == 0)
        return thrust::get<0>(data)
    if(selector == 1)
        return thrust::get<1>(data)

})

This is not close to the solution. Despite of error in make_transform_iterator call (arity of which is two, not three), your dispatchIterator will increment all underlying iterators every its own increment. Not the only of them.

I think its unlikely that you will find a solution for this purely as an iterator.

The iterator would have to know the conditional behavior for all previous dereferences.

You could construct that information with a set of prefix sums calculated prior to the usage of the iterator.

With that information, you could use a scatter or gather type operation (or permutation iterator) to assemble the data for use in the proper order by a non-custom iterator.

It seems (from what you said) that Trust not tend to support iterators less stricter then random access ones.

But how thrust::stable_partition_copy works? Seems it does what I want, but for number of iterators == 2.

That’s an algorithm, not an iterator. Note what I said:

Many thrust algorithms use simpler constructs like prefix sums to assemble more complicated operations.

Many things are possible in thrust. That does not mean that they are all trivial to achieve purely as an iterator.

Thank you. Now I understand.