blob: 6b3d3d1610c167ef2ee94d72c558d2462bd52879 [file] [log] [blame]
Howard Hinnantc1198c32010-07-16 19:08:36 +00001#ifndef ITERATORS_H
2#define ITERATORS_H
3
4#include <iterator>
5
6template <class It>
Howard Hinnant48b242a2010-08-14 18:14:02 +00007class output_iterator
8{
9 It it_;
10
11 template <class U> friend class output_iterator;
12public:
13 typedef std::output_iterator_tag iterator_category;
14 typedef typename std::iterator_traits<It>::value_type value_type;
15 typedef typename std::iterator_traits<It>::difference_type difference_type;
16 typedef It pointer;
17 typedef typename std::iterator_traits<It>::reference reference;
18
19 It base() const {return it_;}
20
Marshall Clowcf1589f2013-01-03 02:29:29 +000021 output_iterator () {}
Howard Hinnant48b242a2010-08-14 18:14:02 +000022 explicit output_iterator(It it) : it_(it) {}
23 template <class U>
24 output_iterator(const output_iterator<U>& u) :it_(u.it_) {}
25
26 reference operator*() const {return *it_;}
27
28 output_iterator& operator++() {++it_; return *this;}
29 output_iterator operator++(int)
30 {output_iterator tmp(*this); ++(*this); return tmp;}
31};
32
33template <class It>
Howard Hinnantc1198c32010-07-16 19:08:36 +000034class input_iterator
35{
36 It it_;
37
38 template <class U> friend class input_iterator;
39public:
40 typedef std::input_iterator_tag iterator_category;
41 typedef typename std::iterator_traits<It>::value_type value_type;
42 typedef typename std::iterator_traits<It>::difference_type difference_type;
43 typedef It pointer;
44 typedef typename std::iterator_traits<It>::reference reference;
45
46 It base() const {return it_;}
47
48 input_iterator() : it_() {}
49 explicit input_iterator(It it) : it_(it) {}
50 template <class U>
51 input_iterator(const input_iterator<U>& u) :it_(u.it_) {}
52
53 reference operator*() const {return *it_;}
54 pointer operator->() const {return it_;}
55
56 input_iterator& operator++() {++it_; return *this;}
57 input_iterator operator++(int)
58 {input_iterator tmp(*this); ++(*this); return tmp;}
59
60 friend bool operator==(const input_iterator& x, const input_iterator& y)
61 {return x.it_ == y.it_;}
62 friend bool operator!=(const input_iterator& x, const input_iterator& y)
63 {return !(x == y);}
64};
65
66template <class T, class U>
67inline
68bool
69operator==(const input_iterator<T>& x, const input_iterator<U>& y)
70{
71 return x.base() == y.base();
72}
73
74template <class T, class U>
75inline
76bool
77operator!=(const input_iterator<T>& x, const input_iterator<U>& y)
78{
79 return !(x == y);
80}
81
82template <class It>
83class forward_iterator
84{
85 It it_;
86
87 template <class U> friend class forward_iterator;
88public:
89 typedef std::forward_iterator_tag iterator_category;
90 typedef typename std::iterator_traits<It>::value_type value_type;
91 typedef typename std::iterator_traits<It>::difference_type difference_type;
92 typedef It pointer;
93 typedef typename std::iterator_traits<It>::reference reference;
94
95 It base() const {return it_;}
96
97 forward_iterator() : it_() {}
98 explicit forward_iterator(It it) : it_(it) {}
99 template <class U>
100 forward_iterator(const forward_iterator<U>& u) :it_(u.it_) {}
101
102 reference operator*() const {return *it_;}
103 pointer operator->() const {return it_;}
104
105 forward_iterator& operator++() {++it_; return *this;}
106 forward_iterator operator++(int)
107 {forward_iterator tmp(*this); ++(*this); return tmp;}
108
109 friend bool operator==(const forward_iterator& x, const forward_iterator& y)
110 {return x.it_ == y.it_;}
111 friend bool operator!=(const forward_iterator& x, const forward_iterator& y)
112 {return !(x == y);}
113};
114
115template <class T, class U>
116inline
117bool
118operator==(const forward_iterator<T>& x, const forward_iterator<U>& y)
119{
120 return x.base() == y.base();
121}
122
123template <class T, class U>
124inline
125bool
126operator!=(const forward_iterator<T>& x, const forward_iterator<U>& y)
127{
128 return !(x == y);
129}
130
131template <class It>
132class bidirectional_iterator
133{
134 It it_;
135
136 template <class U> friend class bidirectional_iterator;
137public:
138 typedef std::bidirectional_iterator_tag iterator_category;
139 typedef typename std::iterator_traits<It>::value_type value_type;
140 typedef typename std::iterator_traits<It>::difference_type difference_type;
141 typedef It pointer;
142 typedef typename std::iterator_traits<It>::reference reference;
143
144 It base() const {return it_;}
145
146 bidirectional_iterator() : it_() {}
147 explicit bidirectional_iterator(It it) : it_(it) {}
148 template <class U>
149 bidirectional_iterator(const bidirectional_iterator<U>& u) :it_(u.it_) {}
150
151 reference operator*() const {return *it_;}
152 pointer operator->() const {return it_;}
153
154 bidirectional_iterator& operator++() {++it_; return *this;}
155 bidirectional_iterator operator++(int)
156 {bidirectional_iterator tmp(*this); ++(*this); return tmp;}
157
158 bidirectional_iterator& operator--() {--it_; return *this;}
159 bidirectional_iterator operator--(int)
160 {bidirectional_iterator tmp(*this); --(*this); return tmp;}
161};
162
163template <class T, class U>
164inline
165bool
166operator==(const bidirectional_iterator<T>& x, const bidirectional_iterator<U>& y)
167{
168 return x.base() == y.base();
169}
170
171template <class T, class U>
172inline
173bool
174operator!=(const bidirectional_iterator<T>& x, const bidirectional_iterator<U>& y)
175{
176 return !(x == y);
177}
178
179template <class It>
180class random_access_iterator
181{
182 It it_;
183
184 template <class U> friend class random_access_iterator;
185public:
186 typedef std::random_access_iterator_tag iterator_category;
187 typedef typename std::iterator_traits<It>::value_type value_type;
188 typedef typename std::iterator_traits<It>::difference_type difference_type;
189 typedef It pointer;
190 typedef typename std::iterator_traits<It>::reference reference;
191
192 It base() const {return it_;}
193
194 random_access_iterator() : it_() {}
195 explicit random_access_iterator(It it) : it_(it) {}
196 template <class U>
197 random_access_iterator(const random_access_iterator<U>& u) :it_(u.it_) {}
198
199 reference operator*() const {return *it_;}
200 pointer operator->() const {return it_;}
201
202 random_access_iterator& operator++() {++it_; return *this;}
203 random_access_iterator operator++(int)
204 {random_access_iterator tmp(*this); ++(*this); return tmp;}
205
206 random_access_iterator& operator--() {--it_; return *this;}
207 random_access_iterator operator--(int)
208 {random_access_iterator tmp(*this); --(*this); return tmp;}
209
210 random_access_iterator& operator+=(difference_type n) {it_ += n; return *this;}
211 random_access_iterator operator+(difference_type n) const
212 {random_access_iterator tmp(*this); tmp += n; return tmp;}
213 friend random_access_iterator operator+(difference_type n, random_access_iterator x)
214 {x += n; return x;}
215 random_access_iterator& operator-=(difference_type n) {return *this += -n;}
216 random_access_iterator operator-(difference_type n) const
217 {random_access_iterator tmp(*this); tmp -= n; return tmp;}
218
219 reference operator[](difference_type n) const {return it_[n];}
220};
221
222template <class T, class U>
223inline
224bool
225operator==(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
226{
227 return x.base() == y.base();
228}
229
230template <class T, class U>
231inline
232bool
233operator!=(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
234{
235 return !(x == y);
236}
237
238template <class T, class U>
239inline
240bool
241operator<(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
242{
243 return x.base() < y.base();
244}
245
246template <class T, class U>
247inline
248bool
249operator<=(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
250{
251 return !(y < x);
252}
253
254template <class T, class U>
255inline
256bool
257operator>(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
258{
259 return y < x;
260}
261
262template <class T, class U>
263inline
264bool
265operator>=(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
266{
267 return !(x < y);
268}
269
270template <class T, class U>
271inline
272typename std::iterator_traits<T>::difference_type
273operator-(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
274{
275 return x.base() - y.base();
276}
277
Marshall Clowf8c2b822013-01-04 18:24:04 +0000278template <class Iter>
279inline Iter base(output_iterator<Iter> i) { return i.base(); }
280
281template <class Iter>
282inline Iter base(input_iterator<Iter> i) { return i.base(); }
283
284template <class Iter>
285inline Iter base(forward_iterator<Iter> i) { return i.base(); }
286
287template <class Iter>
288inline Iter base(bidirectional_iterator<Iter> i) { return i.base(); }
289
290template <class Iter>
291inline Iter base(random_access_iterator<Iter> i) { return i.base(); }
292
293template <class Iter> // everything else
294inline Iter base(Iter i) { return i; }
295
Howard Hinnantf36101d2010-08-22 00:45:01 +0000296#endif // ITERATORS_H