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

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

cpp: added mostly functioning implementation of std::array, iterator traits, base iteratr and reverse iterator

  • 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
32namespace std
33{
34 /**
35 * 24.4.3, standard iterator tags:
36 */
37
38 struct input_iterator_tag
39 { /* DUMMY BODY */ };
40
41 struct output_iterator_tag
42 { /* DUMMY BODY */ };
43
44 struct forward_iterator_tag: input_iterator_tag
45 { /* DUMMY BODY */ };
46
47 struct bidirectional_iterator_tag: forward_iterator_tag
48 { /* DUMMY BODY */ };
49
50 struct random_access_iterator_tag: bidirectional_iterator_tag
51 { /* DUMMY BODY */ };
52
53 /**
54 * 24.4.1, iterator traits:
55 */
56
57 template<class Iterator>
58 struct iterator_traits
59 {
60 using difference_type = typename Iterator::difference_type;
61 using value_type = typename Iterator::value_type;
62 using iterator_category = typename Iterator::iterator_category;
63 using reference = typename Iterator::reference;
64 using pointer = typename Iterator::pointer;
65 };
66
67 template<class T>
68 struct iterator_traits<T*>
69 {
70 using difference_type = ptrdiff_t;
71 using value_type = T;
72 using iterator_category = random_access_iterator_tag;
73 using reference = T&;
74 using pointer = T*;
75 };
76
77 template<class T>
78 struct iterator_traits<const T*>
79 {
80 using difference_type = ptrdiff_t;
81 using value_type = T;
82 using iterator_category = random_access_iterator_tag;
83 using reference = const T&;
84 using pointer = const T*;
85 };
86
87 /**
88 * 24.4.2, basic iterator:
89 */
90
91 template<
92 class Category, class T, class Distance = ptrdiff_t,
93 class Pointer = T*, class Reference = T&
94 >
95 struct iterator
96 {
97 using difference_type = Distance;
98 using value_type = T;
99 using iterator_category = Category;
100 using reference = Reference;
101 using pointer = Pointer;
102 };
103
104 /**
105 * 25.5.1, reverse iterator:
106 */
107
108 template<class Iterator>
109 class reverse_iterator
110 : iterator<
111 typename iterator_traits<Iterator>::iterator_category,
112 typename iterator_traits<Iterator>::value_type,
113 typename iterator_traits<Iterator>::difference_type,
114 typename iterator_traits<Iterator>::pointer,
115 typename iterator_traits<Iterator>::reference
116 >
117 {
118 public:
119 using iterator_type = Iterator;
120 using difference_type = typename Iterator::difference_type;
121 using reference = typename Iterator::reference;
122 using pointer = typename Iterator::pointer;
123
124 reverse_iterator()
125 : current_{}
126 { /* DUMMY BODY */ }
127
128 explicit reverse_iterator(Iterator it)
129 : current_{it}
130 { /* DUMMY BODY */ }
131
132 template<class U>
133 reverse_iterator(const reverse_iterator<U>& other)
134 : current_{other.current_}
135 { /* DUMMY BODY */ }
136
137 template<class U>
138 reverse_iterator& operator=(const reverse_iterator<U>& other)
139 {
140 current_ = other.base();
141
142 return *this;
143 }
144
145 Iterator base() const
146 {
147 return current_;
148 }
149
150 reference operator*() const
151 {
152 auto tmp = current_;
153
154 return *(--tmp);
155 }
156
157 pointer operator->() const
158 {
159 // TODO: need std::addressof
160 return nullptr;
161 }
162
163 reverse_iterator& operator++()
164 {
165 --current_;
166
167 return *this;
168 }
169
170 reverse_iterator operator++(int)
171 {
172 auto tmp = *this;
173 --current_;
174
175 return tmp;
176 }
177
178 reverse_iterator& operator--()
179 {
180 ++current_;
181
182 return *this;
183 }
184
185 reverse_iterator operator--(int)
186 {
187 auto tmp = *this;
188 ++current_;
189
190 return tmp;
191 }
192
193 reverse_iterator operator+(difference_type n) const
194 {
195 return reverse_iterator{current_ - n};
196 }
197
198 reverse_iterator& operator+=(difference_type n)
199 {
200 current_ -= n;
201
202 return *this;
203 }
204
205 reverse_iterator operator-(difference_type n) const
206 {
207 return reverse_iterator{current_ + n};
208 }
209
210 reverse_iterator& operator-=(difference_type n)
211 {
212 current_ += n;
213
214 return *this;
215 }
216
217 // TODO: unspecified operator[difference_type] const;
218 auto operator[](difference_type n) const
219 {
220 return current_[-n - 1];
221 }
222
223 protected:
224 Iterator current_;
225 };
226
227 template<class Iterator1, class Iterator2>
228 bool operator==(const reverse_iterator<Iterator1>& lhs,
229 const reverse_iterator<Iterator2>& rhs)
230 {
231 return lhs.current_ == rhs.current_;
232 }
233
234 template<class Iterator1, class Iterator2>
235 bool operator<(const reverse_iterator<Iterator1>& lhs,
236 const reverse_iterator<Iterator2>& rhs)
237 {
238 // Remember: they are reversed!
239 return lhs.current_ > rhs.current_;
240 }
241
242 template<class Iterator1, class Iterator2>
243 bool operator!=(const reverse_iterator<Iterator1>& lhs,
244 const reverse_iterator<Iterator2>& rhs)
245 {
246 return lhs.current_ != rhs.current_;
247 }
248
249 template<class Iterator1, class Iterator2>
250 bool operator>(const reverse_iterator<Iterator1>& lhs,
251 const reverse_iterator<Iterator2>& rhs)
252 {
253 return lhs.current_ < rhs.current_;
254 }
255
256 template<class Iterator1, class Iterator2>
257 bool operator>=(const reverse_iterator<Iterator1>& lhs,
258 const reverse_iterator<Iterator2>& rhs)
259 {
260 return lhs.current_ <= rhs.current_;
261 }
262
263 template<class Iterator1, class Iterator2>
264 bool operator<=(const reverse_iterator<Iterator1>& lhs,
265 const reverse_iterator<Iterator2>& rhs)
266 {
267 return lhs.current_ >= rhs.current_;
268 }
269
270 template<class Iterator1, class Iterator2>
271 auto operator-(const reverse_iterator<Iterator1>& lhs,
272 const reverse_iterator<Iterator2>& rhs)
273 -> decltype(rhs.base() - lhs.base())
274 {
275 return rhs.current_ - lhs.current_;
276 }
277
278 template<class Iterator>
279 reverse_iterator<Iterator> operator+(
280 typename reverse_iterator<Iterator>::difference_type n,
281 const reverse_iterator<Iterator>& it
282 )
283 {
284 return reverse_iterator<Iterator>{it.current_ - n};
285 }
286
287 template<class Iterator>
288 reverse_iterator<Iterator> make_reverse_iterator(Iterator it)
289 {
290 return reverse_iterator<Iterator>(it);
291 }
292
293 // TODO: other kind of iterator adaptors!
294}
295
296#endif
Note: See TracBrowser for help on using the repository browser.