-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathiterator.hpp
343 lines (291 loc) · 9.38 KB
/
iterator.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
#pragma once
#include <cstddef>
#include <iterator>
namespace ft {
template <class Iterator>
struct iterator_traits {
typedef typename Iterator::difference_type difference_type;
typedef typename Iterator::value_type value_type;
typedef typename Iterator::pointer pointer;
typedef typename Iterator::reference reference;
typedef typename Iterator::iterator_category iterator_category;
};
template <class T>
struct iterator_traits<T *> {
typedef std::ptrdiff_t difference_type;
typedef T value_type;
typedef T *pointer;
typedef T &reference;
typedef std::random_access_iterator_tag iterator_category;
};
template <class T>
struct iterator_traits<const T *> {
typedef std::ptrdiff_t difference_type;
typedef T value_type;
typedef const T *pointer;
typedef const T &reference;
typedef std::random_access_iterator_tag iterator_category;
};
template <class Category, class T, class Distance = std::ptrdiff_t,
class Pointer = T *, class Reference = T &>
struct iterator {
typedef T value_type;
typedef Distance difference_type;
typedef Pointer pointer;
typedef Reference reference;
typedef Category iterator_category;
};
template <class Iterator>
class reverse_iterator
: public iterator<typename iterator_traits<Iterator>::iterator_category,
typename iterator_traits<Iterator>::value_type,
typename iterator_traits<Iterator>::difference_type,
typename iterator_traits<Iterator>::pointer,
typename iterator_traits<Iterator>::reference> {
protected:
Iterator m_current;
public:
typedef Iterator iterator_type;
typedef typename iterator_traits<Iterator>::difference_type difference_type;
typedef typename iterator_traits<Iterator>::reference reference;
typedef typename iterator_traits<Iterator>::pointer pointer;
reverse_iterator() {}
explicit reverse_iterator(Iterator x);
template <class U>
reverse_iterator(const reverse_iterator<U> &u);
Iterator base() const;
reference operator*() const;
pointer operator->() const;
reverse_iterator &operator++();
reverse_iterator operator++(int);
reverse_iterator &operator--();
reverse_iterator operator--(int);
reverse_iterator operator+(difference_type n) const;
reverse_iterator &operator+=(difference_type n);
reverse_iterator operator-(difference_type n) const;
reverse_iterator &operator-=(difference_type n);
reference operator[](difference_type n) const;
};
template <class Iterator>
reverse_iterator<Iterator>::reverse_iterator(Iterator x) : m_current(x) {}
template <class Iterator>
template <class U>
reverse_iterator<Iterator>::reverse_iterator(const reverse_iterator<U> &u)
: m_current(u.base()) {}
template <class Iterator>
Iterator reverse_iterator<Iterator>::base() const {
return m_current;
}
template <class Iterator>
typename reverse_iterator<Iterator>::reference
reverse_iterator<Iterator>::operator*() const {
Iterator tmp = m_current;
return *--tmp;
}
template <class Iterator>
typename reverse_iterator<Iterator>::pointer
reverse_iterator<Iterator>::operator->() const {
return &(operator*());
}
template <class Iterator>
reverse_iterator<Iterator> &reverse_iterator<Iterator>::operator++() {
--m_current;
return *this;
}
template <class Iterator>
reverse_iterator<Iterator> reverse_iterator<Iterator>::operator++(int) {
reverse_iterator tmp = *this;
--m_current;
return tmp;
}
template <class Iterator>
reverse_iterator<Iterator> &reverse_iterator<Iterator>::operator--() {
++m_current;
return *this;
}
template <class Iterator>
reverse_iterator<Iterator> reverse_iterator<Iterator>::operator--(int) {
reverse_iterator tmp = *this;
++m_current;
return tmp;
}
template <class Iterator>
reverse_iterator<Iterator> reverse_iterator<Iterator>::operator+(
typename reverse_iterator<Iterator>::difference_type n) const {
return reverse_iterator(m_current - n);
}
template <class Iterator>
reverse_iterator<Iterator> &reverse_iterator<Iterator>::operator+=(
typename reverse_iterator<Iterator>::difference_type n) {
m_current -= n;
return *this;
}
template <class Iterator>
reverse_iterator<Iterator> reverse_iterator<Iterator>::operator-(
typename reverse_iterator<Iterator>::difference_type n) const {
return reverse_iterator(m_current + n);
}
template <class Iterator>
reverse_iterator<Iterator> &reverse_iterator<Iterator>::operator-=(
typename reverse_iterator<Iterator>::difference_type n) {
m_current += n;
return *this;
}
template <class Iterator>
typename reverse_iterator<Iterator>::reference
reverse_iterator<Iterator>::operator[](
typename reverse_iterator<Iterator>::difference_type n) const {
return m_current[-n - 1];
}
template <class Iterator>
bool operator==(
const reverse_iterator<Iterator> &x, const reverse_iterator<Iterator> &y) {
return x.base() == y.base();
}
template <class Iterator>
bool operator!=(
const reverse_iterator<Iterator> &x, const reverse_iterator<Iterator> &y) {
return !(x == y);
}
template <class Iterator>
bool operator<(
const reverse_iterator<Iterator> &x, const reverse_iterator<Iterator> &y) {
return y.base() < x.base();
}
template <class Iterator>
bool operator>(
const reverse_iterator<Iterator> &x, const reverse_iterator<Iterator> &y) {
return y < x;
}
template <class Iterator>
bool operator<=(
const reverse_iterator<Iterator> &x, const reverse_iterator<Iterator> &y) {
return !(y < x);
}
template <class Iterator>
bool operator>=(
const reverse_iterator<Iterator> &x, const reverse_iterator<Iterator> &y) {
return !(x < y);
}
template <class Iterator>
typename reverse_iterator<Iterator>::difference_type operator-(
const reverse_iterator<Iterator> &x, const reverse_iterator<Iterator> &y) {
return y.base() - x.base();
}
template <class Iterator>
reverse_iterator<Iterator> operator+(
typename reverse_iterator<Iterator>::difference_type n,
const reverse_iterator<Iterator> &x) {
return reverse_iterator<Iterator>(x.base() - n);
}
// Fixes for the comparison of reverse_iterator to const reverse_iterator.
template <class IteratorL, class IteratorR>
bool operator==(const reverse_iterator<IteratorL> &x,
const reverse_iterator<IteratorR> &y) {
return x.base() == y.base();
}
template <class IteratorL, class IteratorR>
bool operator!=(const reverse_iterator<IteratorL> &x,
const reverse_iterator<IteratorR> &y) {
return x.base() != y.base();
}
template <class IteratorL, class IteratorR>
bool operator<(const reverse_iterator<IteratorL> &x,
const reverse_iterator<IteratorR> &y) {
return x.base() > y.base();
}
template <class IteratorL, class IteratorR>
bool operator>(const reverse_iterator<IteratorL> &x,
const reverse_iterator<IteratorR> &y) {
return x.base() < y.base();
}
template <class IteratorL, class IteratorR>
bool operator<=(const reverse_iterator<IteratorL> &x,
const reverse_iterator<IteratorR> &y) {
return x.base() >= y.base();
}
template <class IteratorL, class IteratorR>
bool operator>=(const reverse_iterator<IteratorL> &x,
const reverse_iterator<IteratorR> &y) {
return x.base() <= y.base();
}
template <class IteratorL, class IteratorR>
typename reverse_iterator<IteratorL>::difference_type operator-(
const reverse_iterator<IteratorL> &x,
const reverse_iterator<IteratorR> &y) {
return y.base() - x.base();
}
// distance implementation via tag dispatch
namespace detail {
template <class It>
typename ft::iterator_traits<It>::difference_type do_distance(
It first, It last, std::input_iterator_tag) {
typename iterator_traits<It>::difference_type result = 0;
while (first != last) {
first++;
result++;
}
return result;
}
template <class It>
typename ft::iterator_traits<It>::difference_type do_distance(
It first, It last, std::random_access_iterator_tag) {
return last - first;
}
} // namespace detail
// Returns the distance between two iterators
template <class It>
typename iterator_traits<It>::difference_type distance(It first, It last) {
return detail::do_distance(
first, last, typename ft::iterator_traits<It>::iterator_category());
}
// advance implementation via tag dispatch
namespace detail {
template <class It>
void do_advance(It &it, typename ft::iterator_traits<It>::difference_type n,
std::input_iterator_tag) {
while (n > 0) {
--n;
++it;
}
}
template <class It>
void do_advance(It &it, typename ft::iterator_traits<It>::difference_type n,
std::bidirectional_iterator_tag) {
while (n > 0) {
--n;
++it;
}
while (n < 0) {
++n;
--it;
}
}
template <class It>
void do_advance(It &it, typename ft::iterator_traits<It>::difference_type n,
std::random_access_iterator_tag) {
it += n;
}
} // namespace detail
// Advances an iterator by given distance
template <class It, class Distance>
void advance(It &it, Distance n) {
detail::do_advance(it,
typename std::iterator_traits<It>::difference_type(n),
typename ft::iterator_traits<It>::iterator_category());
}
// Decrement an iterator
template <class BidirIt>
BidirIt prev(
BidirIt it, typename ft::iterator_traits<BidirIt>::difference_type n = 1) {
ft::advance(it, -n);
return it;
}
// Increment an iterator
template <class InputIt>
InputIt next(
InputIt it, typename ft::iterator_traits<InputIt>::difference_type n = 1) {
ft::advance(it, n);
return it;
}
} // namespace ft