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