summaryrefslogtreecommitdiffabout
authorMichael Krelin <hacker@klever.net>2008-01-20 21:04:13 (UTC)
committer Michael Krelin <hacker@klever.net>2008-01-20 21:04:13 (UTC)
commit6d68bef7f60980ab70e0e1f9f8b5c50b616f4255 (patch) (unidiff)
tree198b34fb9ad5ea926c64e5b88d001cd056755f81
parent7f6d0f9ec59f8f04a1c768ae5c27a621223ff628 (diff)
downloadlibopkele-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>
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--include/opkele/iterator.h217
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
7namespace 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 */