// Copyright 2008, Roland Bock #include #include #include #include #include /** * A MergeIterator * takes a vector of IteratorRanges for sorted ranges * represents an iterator over the merged and sorted combination of the two */ template > class MergeIterator: public boost::iterator_facade, const ItemType, boost::single_pass_traversal_tag> { public: // Constructor which takes a vector of Iterator Ranges MergeIterator(std::vector > iterators): iterators_(iterators.begin(), iterators.end()) { } // Empty constructor can be used for comparison (== end of a MergeIterator) MergeIterator() {} private: friend class boost::iterator_core_access; // Comparator for IteratorRanges. struct IteratorRangeComparator { bool operator()(const boost::iterator_range lhs, const boost::iterator_range rhs) { return ItemComparatorType()(lhs.front(), rhs.front()); } }; private: void increment() { boost::iterator_range top = iterators_.top(); iterators_.pop(); if (top.advance_begin(1).begin() != top.end()) { iterators_.push(top); } } const ItemType& dereference() const { return iterators_.top().front(); } const bool equal(const MergeIterator& rhs) const { return iterators_.size() == rhs.iterators_.size() && true; // How can two priority_queues be compared? } std::priority_queue, std::deque >, IteratorRangeComparator> iterators_; }; //------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------ // Sample program //------------------------------------------------------------------------------------------ #include using namespace std; int main() { vector a; vector b; for (int i = 0; i < 10; ++i) if (i%2) a.push_back(i); else b.push_back(i); boost::iterator_range::iterator> itA(a.begin(), a.end()); boost::iterator_range::iterator> itB(b.begin(), b.end()); vector::iterator> > iterators; iterators.push_back(itA); iterators.push_back(itB); MergeIterator::iterator, int> mergedBegin(iterators); MergeIterator::iterator, int> mergedEnd; for (MergeIterator::iterator, int> it = mergedBegin; it != mergedEnd; ++it) cerr << *it << endl; }