author | Michael Krelin <hacker@klever.net> | 2008-01-20 21:04:13 (UTC) |
---|---|---|
committer | Michael Krelin <hacker@klever.net> | 2008-01-20 21:04:13 (UTC) |
commit | 6d68bef7f60980ab70e0e1f9f8b5c50b616f4255 (patch) (unidiff) | |
tree | 198b34fb9ad5ea926c64e5b88d001cd056755f81 /include | |
parent | 7f6d0f9ec59f8f04a1c768ae5c27a621223ff628 (diff) | |
download | libopkele-6d68bef7f60980ab70e0e1f9f8b5c50b616f4255.zip libopkele-6d68bef7f60980ab70e0e1f9f8b5c50b616f4255.tar.gz libopkele-6d68bef7f60980ab70e0e1f9f8b5c50b616f4255.tar.bz2 |
opkele/iterator.h header
added a bunch of utility iterators
* output and forward iterator proxies
* filtering iterator
* map key extracting iterator
Signed-off-by: Michael Krelin <hacker@klever.net>
-rw-r--r-- | include/opkele/iterator.h | 217 |
1 files changed, 217 insertions, 0 deletions
diff --git a/include/opkele/iterator.h b/include/opkele/iterator.h new file mode 100644 index 0000000..812a786 --- a/dev/null +++ b/include/opkele/iterator.h | |||
@@ -0,0 +1,217 @@ | |||
1 | #ifndef __OPKELE_ITERATOR_H | ||
2 | #define __OPKELE_ITERATOR_H | ||
3 | |||
4 | #include <cassert> | ||
5 | #include <iterator> | ||
6 | |||
7 | namespace opkele { | ||
8 | namespace util { | ||
9 | using std::iterator; | ||
10 | using std::forward_iterator_tag; | ||
11 | using std::output_iterator_tag; | ||
12 | |||
13 | template <typename T> | ||
14 | class basic_output_iterator_proxy_impl : public iterator<output_iterator_tag,T,void,T*,T&> { | ||
15 | public: | ||
16 | virtual ~basic_output_iterator_proxy_impl() { } | ||
17 | |||
18 | virtual basic_output_iterator_proxy_impl<T>* dup() const = 0; | ||
19 | basic_output_iterator_proxy_impl<T>& operator*() { return *this; }; | ||
20 | virtual basic_output_iterator_proxy_impl<T>& operator=(const T& x) = 0; | ||
21 | |||
22 | }; | ||
23 | |||
24 | template<typename IT,typename T=typename IT::value_type> | ||
25 | class output_iterator_proxy_impl : public basic_output_iterator_proxy_impl<T> { | ||
26 | public: | ||
27 | IT i; | ||
28 | |||
29 | output_iterator_proxy_impl(const IT& i) : i(i) { } | ||
30 | basic_output_iterator_proxy_impl<T>* dup() const { | ||
31 | return new output_iterator_proxy_impl<IT,T>(i); } | ||
32 | basic_output_iterator_proxy_impl<T>& operator=(const T& x) { | ||
33 | (*i) = x; | ||
34 | } | ||
35 | }; | ||
36 | |||
37 | template<typename T> | ||
38 | class output_iterator_proxy : public iterator<output_iterator_tag,T,void,T*,T&> { | ||
39 | public: | ||
40 | basic_output_iterator_proxy_impl<T> *I; | ||
41 | |||
42 | template<typename IT> | ||
43 | output_iterator_proxy(const IT& i) | ||
44 | : I(new output_iterator_proxy_impl<IT,T>(i)) { } | ||
45 | output_iterator_proxy(const output_iterator_proxy<T>& x) | ||
46 | : I(x.I->dup()) { } | ||
47 | ~output_iterator_proxy() { delete I; } | ||
48 | |||
49 | output_iterator_proxy& operator=(const output_iterator_proxy<T>& x) { | ||
50 | delete I; I = x.I->dup(); } | ||
51 | |||
52 | output_iterator_proxy& operator*() { return *this; } | ||
53 | output_iterator_proxy& operator=(const T& x) { | ||
54 | (**I) = x; } | ||
55 | |||
56 | output_iterator_proxy& operator++() { return *this; } | ||
57 | output_iterator_proxy& operator++(int) { return *this; } | ||
58 | }; | ||
59 | |||
60 | template <typename T,typename TR=T&,typename TP=T*> | ||
61 | class basic_forward_iterator_proxy_impl : public iterator<forward_iterator_tag,T,void,TP,TR> { | ||
62 | public: | ||
63 | virtual ~basic_forward_iterator_proxy_impl() { } | ||
64 | |||
65 | virtual basic_forward_iterator_proxy_impl<T,TR,TP>* dup() const = 0; | ||
66 | |||
67 | virtual bool operator==(const basic_forward_iterator_proxy_impl<T,TR,TP>& x) const = 0; | ||
68 | virtual bool operator!=(const basic_forward_iterator_proxy_impl<T,TR,TP>& x) const { | ||
69 | return !((*this)==x); } | ||
70 | virtual TR operator*() const = 0; | ||
71 | virtual TP operator->() const = 0; | ||
72 | virtual void advance() = 0; | ||
73 | }; | ||
74 | |||
75 | template <typename IT> | ||
76 | class forward_iterator_proxy_impl : public basic_forward_iterator_proxy_impl<typename IT::value_type,typename IT::reference,typename IT::pointer> { | ||
77 | public: | ||
78 | IT i; | ||
79 | |||
80 | forward_iterator_proxy_impl(const IT& i) : i(i) { } | ||
81 | |||
82 | virtual basic_forward_iterator_proxy_impl<typename IT::value_type,typename IT::reference,typename IT::pointer>* dup() const { | ||
83 | return new forward_iterator_proxy_impl<IT>(i); } | ||
84 | |||
85 | virtual bool operator==(const basic_forward_iterator_proxy_impl<typename IT::value_type,typename IT::reference,typename IT::pointer>& x) const { | ||
86 | return i==static_cast<const forward_iterator_proxy_impl<IT>*>(&x)->i; } | ||
87 | virtual bool operator!=(const basic_forward_iterator_proxy_impl<typename IT::value_type,typename IT::reference,typename IT::pointer>& x) const { | ||
88 | return i!=static_cast<const forward_iterator_proxy_impl<IT>*>(&x)->i; } | ||
89 | virtual typename IT::reference operator*() const { return *i; } | ||
90 | virtual typename IT::pointer operator->() const { return i.operator->(); } | ||
91 | virtual void advance() { ++i; } | ||
92 | }; | ||
93 | |||
94 | template<typename T,typename TR=T&,typename TP=T*> | ||
95 | class forward_iterator_proxy : public iterator<forward_iterator_tag,T,void,TP,TR> { | ||
96 | public: | ||
97 | basic_forward_iterator_proxy_impl<T,TR,TP> *I; | ||
98 | |||
99 | template<typename IT> | ||
100 | forward_iterator_proxy(const IT& i) | ||
101 | : I(new forward_iterator_proxy_impl<IT>(i)) { } | ||
102 | forward_iterator_proxy(const forward_iterator_proxy<T,TR,TP>& x) | ||
103 | : I(x.I->dup()) { } | ||
104 | ~forward_iterator_proxy() { delete I; } | ||
105 | |||
106 | forward_iterator_proxy& operator=(const forward_iterator_proxy<T,TR,TP>& x) { | ||
107 | delete I; I = x.I->dup(); } | ||
108 | |||
109 | bool operator==(const forward_iterator_proxy<T,TR,TP>& x) const { | ||
110 | return (*I)==(*(x.I)); } | ||
111 | bool operator!=(const forward_iterator_proxy<T,TR,TP>& x) const { | ||
112 | return (*I)!=(*(x.I)); } | ||
113 | |||
114 | TR operator*() const { | ||
115 | return **I; } | ||
116 | TP operator->() const { | ||
117 | return I->operator->(); } | ||
118 | |||
119 | forward_iterator_proxy<T,TR,TP>& operator++() { | ||
120 | I->advance(); return *this; } | ||
121 | forward_iterator_proxy<T,TR,TP>& operator++(int) { | ||
122 | forward_iterator_proxy<T,TR,TP> rv(*this); | ||
123 | I->advance(); return rv; } | ||
124 | }; | ||
125 | |||
126 | template<typename IT> | ||
127 | class basic_filterator : public iterator< | ||
128 | typename IT::iterator_category, | ||
129 | typename IT::value_type, | ||
130 | typename IT::difference_type, | ||
131 | typename IT::pointer, | ||
132 | typename IT::reference> { | ||
133 | public: | ||
134 | IT it; | ||
135 | IT ei; | ||
136 | bool empty; | ||
137 | |||
138 | basic_filterator() : empty(true) { } | ||
139 | basic_filterator(const IT& bi,const IT& ei) | ||
140 | : it(bi), ei(ei) { empty = (bi==ei); } | ||
141 | basic_filterator(const basic_filterator<IT>& x) | ||
142 | : it(x.it), ei(x.ei), empty(x.empty) { } | ||
143 | virtual ~basic_filterator() { } | ||
144 | |||
145 | bool operator==(const basic_filterator<IT>& x) const { | ||
146 | return empty?x.empty:(it==x.it); } | ||
147 | bool operator!=(const basic_filterator<IT>& x) const { | ||
148 | return empty!=x.empty || it!=x.it; } | ||
149 | |||
150 | typename IT::reference operator*() const { | ||
151 | assert(!empty); | ||
152 | return *it; } | ||
153 | typename IT::pointer operator->() const { | ||
154 | assert(!empty); | ||
155 | return it.operator->(); } | ||
156 | |||
157 | basic_filterator<IT>& operator++() { | ||
158 | bool found = false; | ||
159 | for(++it;!(it==ei || (found=is_interesting()));++it); | ||
160 | if(!found) empty=true; | ||
161 | return *this; | ||
162 | } | ||
163 | basic_filterator<IT> operator++(int) { | ||
164 | basic_filterator<IT> rv(*this); | ||
165 | ++(*this); | ||
166 | return rv; | ||
167 | } | ||
168 | |||
169 | void prepare() { | ||
170 | bool found = false; | ||
171 | for(;!(it==ei || (found=is_interesting()));++it); | ||
172 | if(!found) empty = true; | ||
173 | } | ||
174 | virtual bool is_interesting() const = 0; | ||
175 | }; | ||
176 | |||
177 | template<typename IT,typename T=typename IT::value_type::first_type,typename TR=T&,typename TP=T*> | ||
178 | class map_keys_iterator : public iterator< | ||
179 | typename IT::iterator_category, | ||
180 | T,void,TP,TR> { | ||
181 | public: | ||
182 | typedef map_keys_iterator<IT,T,TR,TP> self_type; | ||
183 | IT it; | ||
184 | IT ei; | ||
185 | bool empty; | ||
186 | |||
187 | map_keys_iterator() : empty(true) { } | ||
188 | map_keys_iterator(const IT& bi, | ||
189 | const IT& ei) | ||
190 | : it(bi), ei(ei) { empty = (bi==ei); } | ||
191 | map_keys_iterator(const self_type& x) | ||
192 | : it(x.it), ei(x.ei), empty(x.empty) { } | ||
193 | |||
194 | bool operator==(const self_type& x) const { | ||
195 | return empty?x.empty:(it==x.it); } | ||
196 | bool operator!=(const self_type& x) const { | ||
197 | return empty!=x.empty || it!=x.it; } | ||
198 | |||
199 | TR operator*() const { | ||
200 | assert(!empty); | ||
201 | return it->first; } | ||
202 | TP operator->() const { | ||
203 | assert(!empty); | ||
204 | return &(it->first); } | ||
205 | |||
206 | self_type& operator++() { | ||
207 | assert(!empty); | ||
208 | empty=((++it)==ei); return *this; } | ||
209 | self_type operator++(int) { | ||
210 | self_type rv(*this); | ||
211 | ++(*this); return rv; } | ||
212 | }; | ||
213 | |||
214 | } | ||
215 | } | ||
216 | |||
217 | #endif /* __OPKELE_ITERATOR_H */ | ||