Home
CodeBlog
Articles
Downloads
Links
Books
About
|
Websites |
Virtual iteratorHow to iterate in any kind of STL container with using the same iterator?using namespace std; int main() { vector<int> vec; vec.push_back(1); vec.push_back(2); list<int> lst; lst.push_back(3); lst.push_back(4); for (v_iterator<int> it(vec); it.next() ; ) { cout << *it << endl; } v_iterator<int> it(vec, true); // true arg means "reverse" while(it.next()) { cout << it.get() << endl; } it.reset(); while(it.next()) { cout << it.get() << endl; } it.reset(lst); while(it.next()) { cout << *it << endl; } it.reset(); if (it.next()) { v_iterator<int> it2(it); cout << *it2 << endl; v_iterator<int> it3; it3 = it2; cout << *it3 << endl; } }Source code for the iterator template<class T> struct virtual_iterator { virtual void start() = 0; virtual bool end() const = 0; virtual void next() = 0; virtual const T & get() const = 0; virtual virtual_iterator * clone() const = 0; virtual ~virtual_iterator() {} }; template<class T> class virtual_iterator_imp : public virtual_iterator< typename T::value_type > { const typename T::const_iterator m_begin; const typename T::const_iterator m_end; typename T::const_iterator m_it; void start() { m_it = m_begin; } void next() { ++m_it; } bool end() const { return m_it != m_end; } typename const T::value_type & get() const { return *m_it; } virtual_iterator_imp * clone() const { return new virtual_iterator_imp(*this); } bool operator == (const virtual_iterator_imp &); //not imp bool operator != (const virtual_iterator_imp &); //not imp public: virtual_iterator_imp(const T & container) : m_begin(container.begin()), m_end(container.end()), m_it() { } virtual_iterator_imp(const virtual_iterator_imp & it) : m_begin(it.m_begin), m_end(it.m_end), m_it(it.m_it) { } virtual_iterator_imp & operator = (const virtual_iterator_imp & it) { m_begin = it.m_begin; m_end = it.end; m_it = it.m_it; return *this; } }; template<class T> class virtual_rev_iterator_imp : public virtual_iterator< typename T::value_type > { const typename T::const_reverse_iterator m_rbegin; const typename T::const_reverse_iterator m_rend; typename T::const_reverse_iterator m_it; void start() { m_it = m_rbegin; } void next() { ++m_it; } bool end() const { return m_it != m_rend; } typename const T::value_type & get() const { return *m_it; } virtual_rev_iterator_imp * clone() const { return new virtual_rev_iterator_imp(*this); } bool operator == (const virtual_rev_iterator_imp &); //not imp bool operator != (const virtual_rev_iterator_imp &); //not imp public: virtual_rev_iterator_imp(const T & container) : m_rbegin(container.rbegin()), m_rend(container.rend()), m_it() { } virtual_rev_iterator_imp(const virtual_rev_iterator_imp & it) : m_rbegin(it.m_rbegin), m_rend(it.m_rend), m_it(it.m_it) { } virtual_rev_iterator_imp & operator = (const virtual_rev_iterator_imp & it) { m_rbegin = it.m_rbegin; m_rend = it.rend; m_it = it.m_it; return *this; } }; template<class T> class v_iterator { virtual_iterator<T> * m_pIt; bool m_first; public: template<class ContainerType> v_iterator(const ContainerType & container, bool bReverse = false) : m_first(true) { if (bReverse) m_pIt = new virtual_rev_iterator_imp<ContainerType>(container); else m_pIt = new virtual_iterator_imp<ContainerType>(container); } v_iterator() : m_first(true), m_pIt(0) { } v_iterator(const v_iterator &it) : m_first(it.m_first), m_pIt(it.m_pIt->clone()) { } void swap(v_iterator &it) { std::swap(it.m_first, m_first); std::swap(it.m_pIt, m_pIt); } ~v_iterator() { delete m_pIt; } void reset() { m_first = true; } template<class ContainerType> void reset(const ContainerType & container, bool reverse = false) { v_iterator(container, reverse).swap(*this); } v_iterator& operator =(const v_iterator & it) { v_iterator(it).swap(*this); return *this; } bool next() { if (!m_pIt) return false; if (m_first) { m_pIt->start(); m_first = false; } else { m_pIt->next(); } return m_pIt->end(); } const T & get() const { return m_pIt->get(); } const T & operator *() const { return get(); } };
|