По сути, вы ищете итератор фасада, который абстрагирует обход через несколько последовательностей.
Поскольку вы работаете с питоном, я предполагаю, что вы больше заботитесь о гибкости, чем о скорости. Под гибкостью я подразумеваю возможность объединять в цепочку различные типы последовательностей (вектор, массив, связанный список, набор и т. Д.), А под скоростью я имею в виду только выделение памяти из стека.
Если это так, то вы можете посмотреть на any_iterator из Adobe Labs:
http://stlab.adobe.com/classadobe_1_1any__iterator.html
Этот итератор даст вам возможность перебирать любой тип последовательности во время выполнения. Чтобы создать цепочку, у вас будет вектор (или массив) из трех кортежей any_iterators, то есть три any_iterators для каждого диапазона, который вы объединяете в цепочку (вам нужно три для итерации вперед или назад, если вам достаточно просто итерировать вперед, достаточно двух).
Допустим, вы хотели пройти по цепочке через последовательность целых чисел:
(непроверенный код psuedo-c ++)
typedef adobe :: any_iterator AnyIntIter;
struct AnyRange {
AnyIntIter начать;
AnyIntIter curr;
AnyIntIter конец;
};
Вы можете определить диапазон, например:
int int_array [] = {1, 2, 3, 4};
AnyRange sequence_0 = {int_array, int_array, int_array + ARRAYSIZE (int_array)};
Ваш класс RangeIterator будет иметь std :: vector.
<code>
class RangeIterator {
public:
RangeIterator() : curr_range_index(0) {}
template <typename Container>
void AddAnyRange(Container& c) {
AnyRange any_range = { c.begin(), c.begin(), c.end() };
ranges.push_back(any_range);
}
// Here's what the operator++() looks like, everything else omitted.
int operator++() {
while (true) {
if (curr_range_index > ranges.size()) {
assert(false, "iterated too far");
return 0;
}
AnyRange* any_range = ranges[curr_range_index];
if (curr_range->curr != curr_range->end()) {
++(curr_range->curr);
return *(curr_range->curr);
}
++curr_range_index;
}
}
private:
std::vector<AnyRange> ranges;
int curr_range_index;
};
</code>
Однако хочу отметить, что это решение очень медленное. Лучший, более похожий на C ++ подход состоит в том, чтобы просто хранить все указатели на объекты, с которыми вы хотите работать, и проходить через них. Кроме того, вы можете применить функтор или посетителя к вашим диапазонам.