00001 #ifndef FILTER_ITERATOR_H 00002 #define FILTER_ITERATOR_H 00003 00004 #include "y2storage/AppUtil.h" 00005 #include "y2storage/IterPair.h" 00006 00007 namespace storage 00008 { 00009 00010 template< class Pred, class Iter > 00011 class FilterIterator : public std::iterator<std::bidirectional_iterator_tag, 00012 typename Iter::value_type> 00013 { 00014 public: 00015 typedef typename Iter::value_type value_type; 00016 typedef typename Iter::reference reference; 00017 typedef typename Iter::pointer pointer; 00018 typedef typename Iter::difference_type difference_type; 00019 typedef typename Iter::iterator_category iterator_category; 00020 00021 FilterIterator() { } 00022 00023 FilterIterator( const Iter& begin, const Iter& end, Pred f, bool setend=false ) : 00024 m_begin(begin), m_end(end), m_cur(begin), m_f(f) 00025 { 00026 initialize( setend ); 00027 } 00028 FilterIterator( const IterPair<Iter>& p, Pred f, bool setend=false ) : 00029 m_begin(p.begin()), m_end(p.end()), m_cur(p.begin()), m_f(f) 00030 { 00031 initialize( setend ); 00032 } 00033 00034 FilterIterator( const FilterIterator& x ) 00035 { 00036 copyMembers( x ); 00037 } 00038 00039 FilterIterator& operator=(const FilterIterator& x) 00040 { 00041 copyMembers( x ); 00042 return *this; 00043 } 00044 00045 FilterIterator& operator++() 00046 { 00047 ++m_cur; 00048 assertPred(); 00049 return *this; 00050 } 00051 FilterIterator operator++(int) 00052 { 00053 y2warning( "Expensive ++ FilterIterator" ); 00054 FilterIterator tmp(*this); 00055 ++m_cur; 00056 assertPred(); 00057 return tmp; 00058 } 00059 00060 FilterIterator& operator--() 00061 { 00062 --m_cur; 00063 assertPred(false); 00064 return *this; 00065 } 00066 FilterIterator operator--(int) 00067 { 00068 y2warning( "Expensive -- FilterIterator" ); 00069 FilterIterator tmp(*this); 00070 --m_cur; 00071 assertPred(false); 00072 return tmp; 00073 } 00074 00075 value_type operator*() const 00076 { 00077 return( *m_cur ); 00078 } 00079 00080 pointer operator->() const 00081 { 00082 return( &(*m_cur) ); 00083 } 00084 bool operator==(const FilterIterator& x) const 00085 { 00086 return( m_cur == x.cur() ); 00087 } 00088 bool operator!=(const FilterIterator& x) const 00089 { 00090 return( m_cur != x.cur() ); 00091 } 00092 00093 Pred pred() const {return m_f;} 00094 Iter end() const {return m_end;} 00095 Iter cur() const {return m_cur;} 00096 Iter begin() const {return m_begin;} 00097 00098 private: 00099 Iter m_begin; 00100 Iter m_end; 00101 Iter m_cur; 00102 Pred m_f; 00103 00104 void initialize( bool setend ) 00105 { 00106 if( setend ) 00107 m_cur = m_end; 00108 else 00109 assertPred(); 00110 } 00111 00112 void copyMembers( const FilterIterator& x ) 00113 { 00114 m_begin = x.begin(); 00115 m_end = x.end(); 00116 m_cur = x.cur(); 00117 m_f = x.pred(); 00118 } 00119 00120 00121 void assertPred( bool forward=true ) 00122 { 00123 if( forward ) 00124 while( m_cur!=m_end && !m_f(**m_cur) ) 00125 ++m_cur; 00126 else 00127 while( m_cur!=m_begin && !m_f(**m_cur) ) 00128 --m_cur; 00129 }; 00130 00131 }; 00132 00133 } 00134 00135 #endif