source: mainline/uspace/lib/cpp/include/impl/iterator.hpp@ edbad13a

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since edbad13a was f041811, checked in by Dzejrou <dzejrou@…>, 7 years ago

cpp: fixed minor bugs

  • Property mode set to 100644
File size: 8.5 KB
Line 
1/*
2 * Copyright (c) 2017 Jaroslav Jindrak
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#ifndef LIBCPP_ITERATOR
30#define LIBCPP_ITERATOR
31
32#include <cstdlib>
33
34namespace std
35{
36 /**
37 * 24.4.3, standard iterator tags:
38 */
39
40 struct input_iterator_tag
41 { /* DUMMY BODY */ };
42
43 struct output_iterator_tag
44 { /* DUMMY BODY */ };
45
46 struct forward_iterator_tag: input_iterator_tag
47 { /* DUMMY BODY */ };
48
49 struct bidirectional_iterator_tag: forward_iterator_tag
50 { /* DUMMY BODY */ };
51
52 struct random_access_iterator_tag: bidirectional_iterator_tag
53 { /* DUMMY BODY */ };
54
55 /**
56 * 24.4.1, iterator traits:
57 */
58
59 template<class Iterator>
60 struct iterator_traits
61 {
62 using difference_type = typename Iterator::difference_type;
63 using value_type = typename Iterator::value_type;
64 using iterator_category = typename Iterator::iterator_category;
65 using reference = typename Iterator::reference;
66 using pointer = typename Iterator::pointer;
67 };
68
69 template<class T>
70 struct iterator_traits<T*>
71 {
72 using difference_type = ptrdiff_t;
73 using value_type = T;
74 using iterator_category = random_access_iterator_tag;
75 using reference = T&;
76 using pointer = T*;
77 };
78
79 template<class T>
80 struct iterator_traits<const T*>
81 {
82 using difference_type = ptrdiff_t;
83 using value_type = T;
84 using iterator_category = random_access_iterator_tag;
85 using reference = const T&;
86 using pointer = const T*;
87 };
88
89 /**
90 * 24.4.2, basic iterator:
91 */
92
93 template<
94 class Category, class T, class Distance = ptrdiff_t,
95 class Pointer = T*, class Reference = T&
96 >
97 struct iterator
98 {
99 using difference_type = Distance;
100 using value_type = T;
101 using iterator_category = Category;
102 using reference = Reference;
103 using pointer = Pointer;
104 };
105
106 /**
107 * 25.5.1, reverse iterator:
108 */
109
110 template<class Iterator>
111 class reverse_iterator
112 : iterator<
113 typename iterator_traits<Iterator>::iterator_category,
114 typename iterator_traits<Iterator>::value_type,
115 typename iterator_traits<Iterator>::difference_type,
116 typename iterator_traits<Iterator>::pointer,
117 typename iterator_traits<Iterator>::reference
118 >
119 {
120 public:
121 using iterator_type = Iterator;
122 using difference_type = typename iterator_traits<Iterator>::difference_type;
123 using reference = typename iterator_traits<Iterator>::reference;
124 using pointer = typename iterator_traits<Iterator>::pointer;
125
126 reverse_iterator()
127 : current_{}
128 { /* DUMMY BODY */ }
129
130 explicit reverse_iterator(Iterator it)
131 : current_{it}
132 { /* DUMMY BODY */ }
133
134 template<class U>
135 reverse_iterator(const reverse_iterator<U>& other)
136 : current_{other.current_}
137 { /* DUMMY BODY */ }
138
139 template<class U>
140 reverse_iterator& operator=(const reverse_iterator<U>& other)
141 {
142 current_ = other.base();
143
144 return *this;
145 }
146
147 Iterator base() const
148 {
149 return current_;
150 }
151
152 reference operator*() const
153 {
154 auto tmp = current_;
155
156 return *(--tmp);
157 }
158
159 pointer operator->() const
160 {
161 // TODO: need std::addressof
162 return nullptr;
163 }
164
165 reverse_iterator& operator++()
166 {
167 --current_;
168
169 return *this;
170 }
171
172 reverse_iterator operator++(int)
173 {
174 auto tmp = *this;
175 --current_;
176
177 return tmp;
178 }
179
180 reverse_iterator& operator--()
181 {
182 ++current_;
183
184 return *this;
185 }
186
187 reverse_iterator operator--(int)
188 {
189 auto tmp = *this;
190 ++current_;
191
192 return tmp;
193 }
194
195 reverse_iterator operator+(difference_type n) const
196 {
197 return reverse_iterator{current_ - n};
198 }
199
200 reverse_iterator& operator+=(difference_type n)
201 {
202 current_ -= n;
203
204 return *this;
205 }
206
207 reverse_iterator operator-(difference_type n) const
208 {
209 return reverse_iterator{current_ + n};
210 }
211
212 reverse_iterator& operator-=(difference_type n)
213 {
214 current_ += n;
215
216 return *this;
217 }
218
219 // TODO: unspecified operator[difference_type] const;
220 auto operator[](difference_type n) const
221 {
222 return current_[-n - 1];
223 }
224
225 protected:
226 Iterator current_;
227 };
228
229 template<class Iterator1, class Iterator2>
230 bool operator==(const reverse_iterator<Iterator1>& lhs,
231 const reverse_iterator<Iterator2>& rhs)
232 {
233 return lhs.base() == rhs.base();
234 }
235
236 template<class Iterator1, class Iterator2>
237 bool operator<(const reverse_iterator<Iterator1>& lhs,
238 const reverse_iterator<Iterator2>& rhs)
239 {
240 // Remember: they are reversed!
241 return lhs.base() > rhs.base();
242 }
243
244 template<class Iterator1, class Iterator2>
245 bool operator!=(const reverse_iterator<Iterator1>& lhs,
246 const reverse_iterator<Iterator2>& rhs)
247 {
248 return lhs.base() != rhs.base();
249 }
250
251 template<class Iterator1, class Iterator2>
252 bool operator>(const reverse_iterator<Iterator1>& lhs,
253 const reverse_iterator<Iterator2>& rhs)
254 {
255 return lhs.base() < rhs.base();
256 }
257
258 template<class Iterator1, class Iterator2>
259 bool operator>=(const reverse_iterator<Iterator1>& lhs,
260 const reverse_iterator<Iterator2>& rhs)
261 {
262 return lhs.base() <= rhs.base();
263 }
264
265 template<class Iterator1, class Iterator2>
266 bool operator<=(const reverse_iterator<Iterator1>& lhs,
267 const reverse_iterator<Iterator2>& rhs)
268 {
269 return lhs.base() >= rhs.base();
270 }
271
272 template<class Iterator1, class Iterator2>
273 auto operator-(const reverse_iterator<Iterator1>& lhs,
274 const reverse_iterator<Iterator2>& rhs)
275 -> decltype(rhs.base() - lhs.base())
276 {
277 return rhs.base() - lhs.base();
278 }
279
280 template<class Iterator>
281 reverse_iterator<Iterator> operator+(
282 typename reverse_iterator<Iterator>::difference_type n,
283 const reverse_iterator<Iterator>& it
284 )
285 {
286 return reverse_iterator<Iterator>{it.base() - n};
287 }
288
289 template<class Iterator>
290 reverse_iterator<Iterator> make_reverse_iterator(Iterator it)
291 {
292 return reverse_iterator<Iterator>(it);
293 }
294
295 // TODO: other kind of iterator adaptors!
296}
297
298#endif
Note: See TracBrowser for help on using the repository browser.