blob: cf164be806d352848586cc4e14a80f23997c7887 [file] [log] [blame]
Marshall Clow354d39c2014-01-16 16:58:45 +00001//===----------------------------------------------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Howard Hinnantc1198c32010-07-16 19:08:36 +000010#ifndef ITERATORS_H
11#define ITERATORS_H
12
13#include <iterator>
Marshall Clow29298662014-09-17 04:09:35 +000014#include <cassert>
Howard Hinnantc1198c32010-07-16 19:08:36 +000015
16template <class It>
Howard Hinnant48b242a2010-08-14 18:14:02 +000017class output_iterator
18{
19 It it_;
20
21 template <class U> friend class output_iterator;
22public:
23 typedef std::output_iterator_tag iterator_category;
Marshall Clow44761002013-01-09 17:20:02 +000024 typedef void value_type;
Howard Hinnant48b242a2010-08-14 18:14:02 +000025 typedef typename std::iterator_traits<It>::difference_type difference_type;
26 typedef It pointer;
27 typedef typename std::iterator_traits<It>::reference reference;
28
29 It base() const {return it_;}
30
Marshall Clowcf1589f2013-01-03 02:29:29 +000031 output_iterator () {}
Howard Hinnant48b242a2010-08-14 18:14:02 +000032 explicit output_iterator(It it) : it_(it) {}
33 template <class U>
34 output_iterator(const output_iterator<U>& u) :it_(u.it_) {}
35
36 reference operator*() const {return *it_;}
37
38 output_iterator& operator++() {++it_; return *this;}
39 output_iterator operator++(int)
40 {output_iterator tmp(*this); ++(*this); return tmp;}
41};
42
43template <class It>
Howard Hinnantc1198c32010-07-16 19:08:36 +000044class input_iterator
45{
46 It it_;
47
48 template <class U> friend class input_iterator;
49public:
50 typedef std::input_iterator_tag iterator_category;
51 typedef typename std::iterator_traits<It>::value_type value_type;
52 typedef typename std::iterator_traits<It>::difference_type difference_type;
53 typedef It pointer;
54 typedef typename std::iterator_traits<It>::reference reference;
55
56 It base() const {return it_;}
57
58 input_iterator() : it_() {}
59 explicit input_iterator(It it) : it_(it) {}
60 template <class U>
61 input_iterator(const input_iterator<U>& u) :it_(u.it_) {}
62
63 reference operator*() const {return *it_;}
64 pointer operator->() const {return it_;}
65
66 input_iterator& operator++() {++it_; return *this;}
67 input_iterator operator++(int)
68 {input_iterator tmp(*this); ++(*this); return tmp;}
69
70 friend bool operator==(const input_iterator& x, const input_iterator& y)
71 {return x.it_ == y.it_;}
72 friend bool operator!=(const input_iterator& x, const input_iterator& y)
73 {return !(x == y);}
74};
75
76template <class T, class U>
77inline
78bool
79operator==(const input_iterator<T>& x, const input_iterator<U>& y)
80{
81 return x.base() == y.base();
82}
83
84template <class T, class U>
85inline
86bool
87operator!=(const input_iterator<T>& x, const input_iterator<U>& y)
88{
89 return !(x == y);
90}
91
92template <class It>
93class forward_iterator
94{
95 It it_;
96
97 template <class U> friend class forward_iterator;
98public:
99 typedef std::forward_iterator_tag iterator_category;
100 typedef typename std::iterator_traits<It>::value_type value_type;
101 typedef typename std::iterator_traits<It>::difference_type difference_type;
102 typedef It pointer;
103 typedef typename std::iterator_traits<It>::reference reference;
104
105 It base() const {return it_;}
106
107 forward_iterator() : it_() {}
108 explicit forward_iterator(It it) : it_(it) {}
109 template <class U>
110 forward_iterator(const forward_iterator<U>& u) :it_(u.it_) {}
111
112 reference operator*() const {return *it_;}
113 pointer operator->() const {return it_;}
114
115 forward_iterator& operator++() {++it_; return *this;}
116 forward_iterator operator++(int)
117 {forward_iterator tmp(*this); ++(*this); return tmp;}
118
119 friend bool operator==(const forward_iterator& x, const forward_iterator& y)
120 {return x.it_ == y.it_;}
121 friend bool operator!=(const forward_iterator& x, const forward_iterator& y)
122 {return !(x == y);}
123};
124
125template <class T, class U>
126inline
127bool
128operator==(const forward_iterator<T>& x, const forward_iterator<U>& y)
129{
130 return x.base() == y.base();
131}
132
133template <class T, class U>
134inline
135bool
136operator!=(const forward_iterator<T>& x, const forward_iterator<U>& y)
137{
138 return !(x == y);
139}
140
141template <class It>
142class bidirectional_iterator
143{
144 It it_;
145
146 template <class U> friend class bidirectional_iterator;
147public:
148 typedef std::bidirectional_iterator_tag iterator_category;
149 typedef typename std::iterator_traits<It>::value_type value_type;
150 typedef typename std::iterator_traits<It>::difference_type difference_type;
151 typedef It pointer;
152 typedef typename std::iterator_traits<It>::reference reference;
153
154 It base() const {return it_;}
155
156 bidirectional_iterator() : it_() {}
157 explicit bidirectional_iterator(It it) : it_(it) {}
158 template <class U>
159 bidirectional_iterator(const bidirectional_iterator<U>& u) :it_(u.it_) {}
160
161 reference operator*() const {return *it_;}
162 pointer operator->() const {return it_;}
163
164 bidirectional_iterator& operator++() {++it_; return *this;}
165 bidirectional_iterator operator++(int)
166 {bidirectional_iterator tmp(*this); ++(*this); return tmp;}
167
168 bidirectional_iterator& operator--() {--it_; return *this;}
169 bidirectional_iterator operator--(int)
170 {bidirectional_iterator tmp(*this); --(*this); return tmp;}
171};
172
173template <class T, class U>
174inline
175bool
176operator==(const bidirectional_iterator<T>& x, const bidirectional_iterator<U>& y)
177{
178 return x.base() == y.base();
179}
180
181template <class T, class U>
182inline
183bool
184operator!=(const bidirectional_iterator<T>& x, const bidirectional_iterator<U>& y)
185{
186 return !(x == y);
187}
188
189template <class It>
190class random_access_iterator
191{
192 It it_;
193
194 template <class U> friend class random_access_iterator;
195public:
196 typedef std::random_access_iterator_tag iterator_category;
197 typedef typename std::iterator_traits<It>::value_type value_type;
198 typedef typename std::iterator_traits<It>::difference_type difference_type;
199 typedef It pointer;
200 typedef typename std::iterator_traits<It>::reference reference;
201
202 It base() const {return it_;}
203
204 random_access_iterator() : it_() {}
205 explicit random_access_iterator(It it) : it_(it) {}
206 template <class U>
207 random_access_iterator(const random_access_iterator<U>& u) :it_(u.it_) {}
208
209 reference operator*() const {return *it_;}
210 pointer operator->() const {return it_;}
211
212 random_access_iterator& operator++() {++it_; return *this;}
213 random_access_iterator operator++(int)
214 {random_access_iterator tmp(*this); ++(*this); return tmp;}
215
216 random_access_iterator& operator--() {--it_; return *this;}
217 random_access_iterator operator--(int)
218 {random_access_iterator tmp(*this); --(*this); return tmp;}
219
220 random_access_iterator& operator+=(difference_type n) {it_ += n; return *this;}
221 random_access_iterator operator+(difference_type n) const
222 {random_access_iterator tmp(*this); tmp += n; return tmp;}
223 friend random_access_iterator operator+(difference_type n, random_access_iterator x)
224 {x += n; return x;}
225 random_access_iterator& operator-=(difference_type n) {return *this += -n;}
226 random_access_iterator operator-(difference_type n) const
227 {random_access_iterator tmp(*this); tmp -= n; return tmp;}
228
229 reference operator[](difference_type n) const {return it_[n];}
230};
231
232template <class T, class U>
233inline
234bool
235operator==(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
236{
237 return x.base() == y.base();
238}
239
240template <class T, class U>
241inline
242bool
243operator!=(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
244{
245 return !(x == y);
246}
247
248template <class T, class U>
249inline
250bool
251operator<(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
252{
253 return x.base() < y.base();
254}
255
256template <class T, class U>
257inline
258bool
259operator<=(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
260{
261 return !(y < x);
262}
263
264template <class T, class U>
265inline
266bool
267operator>(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
268{
269 return y < x;
270}
271
272template <class T, class U>
273inline
274bool
275operator>=(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
276{
277 return !(x < y);
278}
279
280template <class T, class U>
281inline
282typename std::iterator_traits<T>::difference_type
283operator-(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
284{
285 return x.base() - y.base();
286}
287
Marshall Clowf1e473b2014-09-16 20:38:11 +0000288template <class It>
289class comma_iterator
290{
291 It it_;
292
293 template <class U> friend class comma_iterator;
294public:
295 typedef std::random_access_iterator_tag iterator_category;
296 typedef typename std::iterator_traits<It>::value_type value_type;
297 typedef typename std::iterator_traits<It>::difference_type difference_type;
298 typedef It pointer;
299 typedef typename std::iterator_traits<It>::reference reference;
300
301 It base() const {return it_;}
302
303 comma_iterator() : it_() {}
304 explicit comma_iterator(It it) : it_(it) {}
305 template <class U>
306 comma_iterator(const comma_iterator<U>& u) :it_(u.it_) {}
307
308 reference operator*() const {return *it_;}
309 pointer operator->() const {return it_;}
310
311 comma_iterator& operator++() {++it_; return *this;}
312 comma_iterator operator++(int)
313 {comma_iterator tmp(*this); ++(*this); return tmp;}
314
315 comma_iterator& operator--() {--it_; return *this;}
316 comma_iterator operator--(int)
317 {comma_iterator tmp(*this); --(*this); return tmp;}
318
319 comma_iterator& operator+=(difference_type n) {it_ += n; return *this;}
320 comma_iterator operator+(difference_type n) const
321 {comma_iterator tmp(*this); tmp += n; return tmp;}
322 friend comma_iterator operator+(difference_type n, comma_iterator x)
323 {x += n; return x;}
324 comma_iterator& operator-=(difference_type n) {return *this += -n;}
325 comma_iterator operator-(difference_type n) const
326 {comma_iterator tmp(*this); tmp -= n; return tmp;}
327
328 reference operator[](difference_type n) const {return it_[n];}
329 template <typename T>
330 void operator,(const T &) { assert(false); }
331};
332
333template <class T, class U>
334inline
335bool
336operator==(const comma_iterator<T>& x, const comma_iterator<U>& y)
337{
338 return x.base() == y.base();
339}
340
341template <class T, class U>
342inline
343bool
344operator!=(const comma_iterator<T>& x, const comma_iterator<U>& y)
345{
346 return !(x == y);
347}
348
349template <class T, class U>
350inline
351bool
352operator<(const comma_iterator<T>& x, const comma_iterator<U>& y)
353{
354 return x.base() < y.base();
355}
356
357template <class T, class U>
358inline
359bool
360operator<=(const comma_iterator<T>& x, const comma_iterator<U>& y)
361{
362 return !(y < x);
363}
364
365template <class T, class U>
366inline
367bool
368operator>(const comma_iterator<T>& x, const comma_iterator<U>& y)
369{
370 return y < x;
371}
372
373template <class T, class U>
374inline
375bool
376operator>=(const comma_iterator<T>& x, const comma_iterator<U>& y)
377{
378 return !(x < y);
379}
380
381template <class T, class U>
382inline
383typename std::iterator_traits<T>::difference_type
384operator-(const comma_iterator<T>& x, const comma_iterator<U>& y)
385{
386 return x.base() - y.base();
387}
388
389
Marshall Clowf8c2b822013-01-04 18:24:04 +0000390template <class Iter>
391inline Iter base(output_iterator<Iter> i) { return i.base(); }
392
393template <class Iter>
394inline Iter base(input_iterator<Iter> i) { return i.base(); }
395
396template <class Iter>
397inline Iter base(forward_iterator<Iter> i) { return i.base(); }
398
399template <class Iter>
400inline Iter base(bidirectional_iterator<Iter> i) { return i.base(); }
401
402template <class Iter>
403inline Iter base(random_access_iterator<Iter> i) { return i.base(); }
404
Marshall Clowf1e473b2014-09-16 20:38:11 +0000405template <class Iter>
406inline Iter base(comma_iterator<Iter> i) { return i.base(); }
407
Howard Hinnante0fe3d22013-07-08 21:06:38 +0000408template <class Iter> // everything else
Marshall Clowf8c2b822013-01-04 18:24:04 +0000409inline Iter base(Iter i) { return i; }
410
Howard Hinnantf36101d2010-08-22 00:45:01 +0000411#endif // ITERATORS_H