Как я могу написать оболочку итератора, которая объединяет группы последовательных значений из базового итератора?

Рассмотрим следующую последовательность:

1, 2, 3, 4, 5, 6, 7, 8, 9, 10

У меня есть итераторов ввода для этой последовательности. Я хочу обернуть эти итераторы итераторами, которые вместо этого производят следующую последовательность:

(1,2), (3,4), (5,6), (7,8), (9,10)

Если это не ясно, эта последовательность представляет собой последовательность последовательных пар последовательных элементов из исходной. В то время как в оригинале 10 элементов, в этом 5 :каждый получается из двух исходной последовательности.

Я использую Boost iterator_facadeдля реализации этого, и у меня есть неправильная попытка:

    template <typename Iterator>
    struct pairing_iterator
    : boost::iterator_facade<
        pairing_iterator<Iterator>,
        std::array<typename std::iterator_traits<Iterator>::value_type, 2>,
        std::input_iterator_category
        // I should probably customize reference too, but it's not relevant
    > {
        pairing_iterator(Iterator it) : it(it) {
            increment(); // A
        }
        pairing_iterator::value_type dereference() const {
            return pair;
        }
        bool equal(pairing_iterator const& that) const {
            return it == that.it; // B
        }
        void increment() {
            pair = { { *it++, *it++ } };
        }
        Iterator it;
        pairing_iterator::value_type pair;
    };

Одна проблема, с которой я сталкиваюсь, находится в строке, отмеченной A :, когда переданный итератор является конечным итератором, это приведет к его увеличению, чего я не могу сделать.

Другой находится на линии, отмеченной буквой B. :Я держу базовый итератор всегда впереди «текущей» пары, поэтому, если итератор находится в последней паре, базовый итератор будет конечным итератором, и поэтому сравнение истинно против итератора конечного спаривания _.

Если бы базовый итератор был прямым итератором , я мог бы просто читать пару каждый раз при разыменовании и просто дважды продвигаться вперед при увеличении. Но с итераторами ввода я могу прочитать только один раз.

Я заново изобретаю колесо, которое где-то уже существует? Я не нашел ничего подобного в Boost, что меня немного удивляет. Но хотелось бы найти готовое -решение.

Если этого колеса еще нет, как я могу заставить его вращаться?

9
задан R. Martinho Fernandes 11 July 2012 в 03:17
поделиться