#ifndef __OPKELE_ITERATOR_H #define __OPKELE_ITERATOR_H #include #include namespace opkele { namespace util { using std::iterator; using std::forward_iterator_tag; using std::output_iterator_tag; template class basic_output_iterator_proxy_impl : public iterator { public: virtual ~basic_output_iterator_proxy_impl() { } virtual basic_output_iterator_proxy_impl* dup() const = 0; basic_output_iterator_proxy_impl& operator*() { return *this; }; virtual basic_output_iterator_proxy_impl& operator=(const T& x) = 0; }; template class output_iterator_proxy_impl : public basic_output_iterator_proxy_impl { public: IT i; output_iterator_proxy_impl(const IT& _i) : i(_i) { } basic_output_iterator_proxy_impl* dup() const { return new output_iterator_proxy_impl(i); } basic_output_iterator_proxy_impl& operator=(const T& x) { (*i) = x; return *this; } }; template class output_iterator_proxy : public iterator { public: basic_output_iterator_proxy_impl *I; template output_iterator_proxy(const IT& i) : I(new output_iterator_proxy_impl(i)) { } output_iterator_proxy(const output_iterator_proxy& x) : I(x.I->dup()) { } ~output_iterator_proxy() { delete I; } output_iterator_proxy& operator=(const output_iterator_proxy& x) { delete I; I = x.I->dup(); } output_iterator_proxy& operator*() { return *this; } output_iterator_proxy& operator=(const T& x) { (**I) = x; return *this; } output_iterator_proxy& operator++() { return *this; } output_iterator_proxy& operator++(int) { return *this; } }; template class basic_forward_iterator_proxy_impl : public iterator { public: virtual ~basic_forward_iterator_proxy_impl() { } virtual basic_forward_iterator_proxy_impl* dup() const = 0; virtual bool operator==(const basic_forward_iterator_proxy_impl& x) const = 0; virtual bool operator!=(const basic_forward_iterator_proxy_impl& x) const { return !((*this)==x); } virtual TR operator*() const = 0; virtual TP operator->() const = 0; virtual void advance() = 0; }; template class forward_iterator_proxy_impl : public basic_forward_iterator_proxy_impl { public: IT i; forward_iterator_proxy_impl(const IT& _i) : i(_i) { } virtual basic_forward_iterator_proxy_impl* dup() const { return new forward_iterator_proxy_impl(i); } virtual bool operator==(const basic_forward_iterator_proxy_impl& x) const { return i==static_cast*>(&x)->i; } virtual bool operator!=(const basic_forward_iterator_proxy_impl& x) const { return i!=static_cast*>(&x)->i; } virtual typename IT::reference operator*() const { return *i; } virtual typename IT::pointer operator->() const { return i.operator->(); } virtual void advance() { ++i; } }; template class forward_iterator_proxy : public iterator { public: basic_forward_iterator_proxy_impl *I; template forward_iterator_proxy(const IT& i) : I(new forward_iterator_proxy_impl(i)) { } forward_iterator_proxy(const forward_iterator_proxy& x) : I(x.I->dup()) { } ~forward_iterator_proxy() { delete I; } forward_iterator_proxy& operator=(const forward_iterator_proxy& x) { delete I; I = x.I->dup(); return *this; } bool operator==(const forward_iterator_proxy& x) const { return (*I)==(*(x.I)); } bool operator!=(const forward_iterator_proxy& x) const { return (*I)!=(*(x.I)); } TR operator*() const { return **I; } TP operator->() const { return I->operator->(); } forward_iterator_proxy& operator++() { I->advance(); return *this; } forward_iterator_proxy& operator++(int) { forward_iterator_proxy rv(*this); I->advance(); return rv; } }; template class basic_filterator : public iterator< typename IT::iterator_category, typename IT::value_type, typename IT::difference_type, typename IT::pointer, typename IT::reference> { public: IT it; IT ei; bool empty; basic_filterator() : empty(true) { } basic_filterator(const IT& _bi,const IT& _ei) : it(_bi), ei(_ei) { empty = (it==ei); } basic_filterator(const basic_filterator& x) : it(x.it), ei(x.ei), empty(x.empty) { } virtual ~basic_filterator() { } bool operator==(const basic_filterator& x) const { return empty?x.empty:(it==x.it); } bool operator!=(const basic_filterator& x) const { return empty!=x.empty || it!=x.it; } typename IT::reference operator*() const { assert(!empty); return *it; } typename IT::pointer operator->() const { assert(!empty); return it.operator->(); } basic_filterator& operator++() { bool found = false; for(++it;!(it==ei || (found=is_interesting()));++it) ; if(!found) empty=true; return *this; } void prepare() { bool found = false; for(;!(it==ei || (found=is_interesting()));++it) ; if(!found) empty = true; } virtual bool is_interesting() const = 0; }; template class map_keys_iterator : public iterator< typename IT::iterator_category, T,void,TP,TR> { public: typedef map_keys_iterator self_type; IT it; IT ei; bool empty; map_keys_iterator() : empty(true) { } map_keys_iterator(const IT& _bi, const IT& _ei) : it(_bi), ei(_ei) { empty = (it==ei); } map_keys_iterator(const self_type& x) : it(x.it), ei(x.ei), empty(x.empty) { } bool operator==(const self_type& x) const { return empty?x.empty:(it==x.it); } bool operator!=(const self_type& x) const { return empty!=x.empty || it!=x.it; } TR operator*() const { assert(!empty); return it->first; } TP operator->() const { assert(!empty); return &(it->first); } self_type& operator++() { assert(!empty); empty=((++it)==ei); return *this; } self_type operator++(int) { self_type rv(*this); ++(*this); return rv; } }; } } #endif /* __OPKELE_ITERATOR_H */