1 | /* |
2 | Copyright (c) Marshall Clow 2013. |
3 | |
4 | Distributed under the Boost Software License, Version 1.0. (See accompanying |
5 | file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
6 | |
7 | For more information, see http://www.boost.org |
8 | */ |
9 | |
10 | #ifndef ITERATOR_TEST_H |
11 | #define ITERATOR_TEST_H |
12 | |
13 | /* |
14 | A set of iterator adapters for constructing test cases |
15 | From an iterator (or a pointer), you can make any class of iterator. |
16 | Assuming you want to degrade the capabilities. |
17 | |
18 | Modeled closely on work that Howard Hinnant did for libc++. |
19 | */ |
20 | |
21 | #include <iterator> |
22 | |
23 | // == Input Iterator == |
24 | template <typename It> |
25 | class input_iterator { |
26 | public: |
27 | typedef std::input_iterator_tag iterator_category; |
28 | typedef typename std::iterator_traits<It>::value_type value_type; |
29 | typedef typename std::iterator_traits<It>::difference_type difference_type; |
30 | typedef It pointer; |
31 | typedef typename std::iterator_traits<It>::reference reference; |
32 | |
33 | It base() const {return it_;} |
34 | |
35 | input_iterator() : it_() {} |
36 | explicit input_iterator(It it) : it_(it) {} |
37 | |
38 | template <typename U> |
39 | input_iterator(const input_iterator<U>& u) :it_(u.it_) {} |
40 | |
41 | reference operator*() const {return *it_;} |
42 | pointer operator->() const {return it_;} |
43 | |
44 | input_iterator& operator++() {++it_; return *this;} |
45 | input_iterator operator++(int) {input_iterator tmp(*this); ++(*this); return tmp;} |
46 | |
47 | friend bool operator==(const input_iterator& x, const input_iterator& y) |
48 | {return x.it_ == y.it_;} |
49 | friend bool operator!=(const input_iterator& x, const input_iterator& y) |
50 | {return !(x == y);} |
51 | |
52 | private: |
53 | It it_; |
54 | template <typename U> friend class input_iterator; |
55 | }; |
56 | |
57 | template <typename T, typename U> |
58 | inline bool |
59 | operator==(const input_iterator<T>& x, const input_iterator<U>& y) |
60 | { |
61 | return x.base() == y.base(); |
62 | } |
63 | |
64 | template <typename T, typename U> |
65 | inline bool |
66 | operator!=(const input_iterator<T>& x, const input_iterator<U>& y) |
67 | { |
68 | return !(x == y); |
69 | } |
70 | |
71 | |
72 | // == Forward Iterator == |
73 | template <typename It> |
74 | class forward_iterator { |
75 | public: |
76 | typedef std::forward_iterator_tag iterator_category; |
77 | typedef typename std::iterator_traits<It>::value_type value_type; |
78 | typedef typename std::iterator_traits<It>::difference_type difference_type; |
79 | typedef It pointer; |
80 | typedef typename std::iterator_traits<It>::reference reference; |
81 | |
82 | It base() const {return it_;} |
83 | |
84 | forward_iterator() : it_() {} |
85 | explicit forward_iterator(It it) : it_(it) {} |
86 | template <typename U> |
87 | forward_iterator(const forward_iterator<U>& u) :it_(u.it_) {} |
88 | |
89 | reference operator*() const {return *it_;} |
90 | pointer operator->() const {return it_;} |
91 | |
92 | forward_iterator& operator++() {++it_; return *this;} |
93 | forward_iterator operator++(int) {forward_iterator tmp(*this); ++(*this); return tmp;} |
94 | |
95 | friend bool operator==(const forward_iterator& x, const forward_iterator& y) |
96 | {return x.it_ == y.it_;} |
97 | friend bool operator!=(const forward_iterator& x, const forward_iterator& y) |
98 | {return !(x == y);} |
99 | private: |
100 | It it_; |
101 | |
102 | template <typename U> friend class forward_iterator; |
103 | }; |
104 | |
105 | template <typename T, typename U> |
106 | inline bool |
107 | operator==(const forward_iterator<T>& x, const forward_iterator<U>& y) |
108 | { |
109 | return x.base() == y.base(); |
110 | } |
111 | |
112 | template <typename T, typename U> |
113 | inline bool |
114 | operator!=(const forward_iterator<T>& x, const forward_iterator<U>& y) |
115 | { |
116 | return !(x == y); |
117 | } |
118 | |
119 | // == Bidirectional Iterator == |
120 | template <typename It> |
121 | class bidirectional_iterator |
122 | { |
123 | public: |
124 | typedef std::bidirectional_iterator_tag iterator_category; |
125 | typedef typename std::iterator_traits<It>::value_type value_type; |
126 | typedef typename std::iterator_traits<It>::difference_type difference_type; |
127 | typedef It pointer; |
128 | typedef typename std::iterator_traits<It>::reference reference; |
129 | |
130 | It base() const {return it_;} |
131 | |
132 | bidirectional_iterator() : it_() {} |
133 | explicit bidirectional_iterator(It it) : it_(it) {} |
134 | template <typename U> |
135 | bidirectional_iterator(const bidirectional_iterator<U>& u) :it_(u.it_) {} |
136 | |
137 | reference operator*() const {return *it_;} |
138 | pointer operator->() const {return it_;} |
139 | |
140 | bidirectional_iterator& operator++() {++it_; return *this;} |
141 | bidirectional_iterator operator++(int) {bidirectional_iterator tmp(*this); ++(*this); return tmp;} |
142 | |
143 | bidirectional_iterator& operator--() {--it_; return *this;} |
144 | bidirectional_iterator operator--(int) {bidirectional_iterator tmp(*this); --(*this); return tmp;} |
145 | private: |
146 | It it_; |
147 | template <typename U> friend class bidirectional_iterator; |
148 | }; |
149 | |
150 | template <typename T, typename U> |
151 | inline bool |
152 | operator==(const bidirectional_iterator<T>& x, const bidirectional_iterator<U>& y) |
153 | { |
154 | return x.base() == y.base(); |
155 | } |
156 | |
157 | template <typename T, typename U> |
158 | inline bool |
159 | operator!=(const bidirectional_iterator<T>& x, const bidirectional_iterator<U>& y) |
160 | { |
161 | return !(x == y); |
162 | } |
163 | |
164 | |
165 | // == Random Access Iterator == |
166 | template <typename It> |
167 | class random_access_iterator { |
168 | public: |
169 | typedef std::random_access_iterator_tag iterator_category; |
170 | typedef typename std::iterator_traits<It>::value_type value_type; |
171 | typedef typename std::iterator_traits<It>::difference_type difference_type; |
172 | typedef It pointer; |
173 | typedef typename std::iterator_traits<It>::reference reference; |
174 | |
175 | It base() const {return it_;} |
176 | |
177 | random_access_iterator() : it_() {} |
178 | explicit random_access_iterator(It it) : it_(it) {} |
179 | template <typename U> |
180 | random_access_iterator(const random_access_iterator<U>& u) :it_(u.it_) {} |
181 | |
182 | reference operator*() const {return *it_;} |
183 | pointer operator->() const {return it_;} |
184 | |
185 | random_access_iterator& operator++() {++it_; return *this;} |
186 | random_access_iterator operator++(int) {random_access_iterator tmp(*this); ++(*this); return tmp;} |
187 | |
188 | random_access_iterator& operator--() {--it_; return *this;} |
189 | random_access_iterator operator--(int) {random_access_iterator tmp(*this); --(*this); return tmp;} |
190 | |
191 | random_access_iterator& operator+=(difference_type n) {it_ += n; return *this;} |
192 | random_access_iterator operator+ (difference_type n) const {random_access_iterator tmp(*this); tmp += n; return tmp;} |
193 | friend random_access_iterator operator+(difference_type n, random_access_iterator x) {x += n; return x;} |
194 | |
195 | random_access_iterator& operator-=(difference_type n) {return *this += -n;} |
196 | random_access_iterator operator- (difference_type n) const {random_access_iterator tmp(*this); tmp -= n; return tmp;} |
197 | |
198 | reference operator[](difference_type n) const {return it_[n];} |
199 | private: |
200 | It it_; |
201 | |
202 | template <typename U> friend class random_access_iterator; |
203 | }; |
204 | |
205 | template <typename T, typename U> |
206 | inline bool |
207 | operator==(const random_access_iterator<T>& x, const random_access_iterator<U>& y) |
208 | { |
209 | return x.base() == y.base(); |
210 | } |
211 | |
212 | template <typename T, typename U> |
213 | inline bool |
214 | operator!=(const random_access_iterator<T>& x, const random_access_iterator<U>& y) |
215 | { |
216 | return !(x == y); |
217 | } |
218 | |
219 | template <typename T, typename U> |
220 | inline bool |
221 | operator<(const random_access_iterator<T>& x, const random_access_iterator<U>& y) |
222 | { |
223 | return x.base() < y.base(); |
224 | } |
225 | |
226 | template <typename T, typename U> |
227 | inline bool |
228 | operator<=(const random_access_iterator<T>& x, const random_access_iterator<U>& y) |
229 | { |
230 | return !(y < x); |
231 | } |
232 | |
233 | template <typename T, typename U> |
234 | inline bool |
235 | operator>(const random_access_iterator<T>& x, const random_access_iterator<U>& y) |
236 | { |
237 | return y < x; |
238 | } |
239 | |
240 | template <typename T, typename U> |
241 | inline bool |
242 | operator>=(const random_access_iterator<T>& x, const random_access_iterator<U>& y) |
243 | { |
244 | return !(x < y); |
245 | } |
246 | |
247 | template <typename T, typename U> |
248 | inline typename std::iterator_traits<T>::difference_type |
249 | operator-(const random_access_iterator<T>& x, const random_access_iterator<U>& y) |
250 | { |
251 | return x.base() - y.base(); |
252 | } |
253 | |
254 | |
255 | // == Output Iterator == |
256 | template <typename It> |
257 | class output_iterator { |
258 | public: |
259 | typedef std::output_iterator_tag iterator_category; |
260 | typedef void value_type; |
261 | typedef typename std::iterator_traits<It>::difference_type difference_type; |
262 | typedef It pointer; |
263 | typedef typename std::iterator_traits<It>::reference reference; |
264 | |
265 | It base() const {return it_;} |
266 | |
267 | output_iterator () {} |
268 | explicit output_iterator(It it) : it_(it) {} |
269 | |
270 | template <typename U> |
271 | output_iterator(const output_iterator<U>& u) :it_(u.it_) {} |
272 | |
273 | reference operator*() const {return *it_;} |
274 | |
275 | output_iterator& operator++() {++it_; return *this;} |
276 | output_iterator operator++(int) {output_iterator tmp(*this); ++(*this); return tmp;} |
277 | |
278 | private: |
279 | It it_; |
280 | template <typename U> friend class output_iterator; |
281 | }; |
282 | |
283 | // No comparison operators for output iterators |
284 | |
285 | |
286 | // == Get the base of an iterator; used for comparisons == |
287 | template <typename Iter> |
288 | inline Iter base(output_iterator<Iter> i) { return i.base(); } |
289 | |
290 | template <typename Iter> |
291 | inline Iter base(input_iterator<Iter> i) { return i.base(); } |
292 | |
293 | template <typename Iter> |
294 | inline Iter base(forward_iterator<Iter> i) { return i.base(); } |
295 | |
296 | template <typename Iter> |
297 | inline Iter base(bidirectional_iterator<Iter> i) { return i.base(); } |
298 | |
299 | template <typename Iter> |
300 | inline Iter base(random_access_iterator<Iter> i) { return i.base(); } |
301 | |
302 | template <typename Iter> // everything else |
303 | inline Iter base(Iter i) { return i; } |
304 | |
305 | #endif // ITERATORS_H |
306 | |