source: mainline/uspace/lib/cpp/include/internal/rbtree_iterators.hpp@ 0fe0f32

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

cpp: fixed bugs found by the map tests

  • Property mode set to 100644
File size: 9.8 KB
Line 
1/*
2 * Copyright (c) 2018 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_INTERNAL_RBTREE_ITERATORS
30#define LIBCPP_INTERNAL_RBTREE_ITERATORS
31
32#include <internal/iterator.hpp>
33#include <internal/rbtree_node.hpp>
34#include <iterator>
35
36namespace std::aux
37{
38 /**
39 * Note: In order for these iterators to be reversible,
40 * the end state of an iterator is represented by a flag
41 * which can be set from true to false in operator--
42 * (i.e. decrementing end iterator) or set from false to
43 * true in operator++ (i.e. incrementing last before end
44 * iterator).
45 */
46
47 template<class Value, class Reference, class Pointer, class Size, class Node>
48 class rbtree_iterator
49 {
50 public:
51 using value_type = Value;
52 using size_type = Size;
53 using reference = Reference;
54 using pointer = Pointer;
55 using difference_type = ptrdiff_t;
56
57 using iterator_category = bidirectional_iterator_tag;
58
59 using node_type = Node;
60
61 rbtree_iterator(node_type* current = nullptr, bool end = true)
62 : current_{current}, end_{end}
63 { /* DUMMY BODY */ }
64
65 rbtree_iterator(const rbtree_iterator&) = default;
66 rbtree_iterator& operator=(const rbtree_iterator&) = default;
67
68 reference operator*() const
69 {
70 return current_->value;
71 }
72
73 pointer operator->() const
74 {
75 return &current_->value;
76 }
77
78 rbtree_iterator& operator++()
79 {
80 if (end_)
81 return *this;
82
83 if (current_)
84 {
85 auto next = current_->successor();
86 if (next)
87 current_ = next;
88 else
89 end_ = true;
90 }
91
92 return *this;
93 }
94
95 rbtree_iterator operator++(int)
96 {
97 auto tmp = *this;
98 ++(*this);
99
100 return tmp;
101 }
102
103 rbtree_iterator& operator--()
104 {
105 if (end_)
106 {
107 end_ = false;
108
109 return *this;
110 }
111
112 if (current_)
113 {
114 auto next = current_->predecessor();
115 if (next)
116 current_ = next;
117 else
118 end_ = true;
119 }
120
121 return *this;
122 }
123
124 rbtree_iterator operator--(int)
125 {
126 auto tmp = *this;
127 --(*this);
128
129 return tmp;
130 }
131
132 const node_type* node() const
133 {
134 return current_;
135 }
136
137 node_type* node()
138 {
139 return current_;
140 }
141
142 bool end() const
143 {
144 return end_;
145 }
146
147 private:
148 node_type* current_;
149 bool end_;
150 };
151
152 template<class Val, class Ref, class Ptr, class Sz, class N>
153 bool operator==(const rbtree_iterator<Val, Ref, Ptr, Sz, N>& lhs,
154 const rbtree_iterator<Val, Ref, Ptr, Sz, N>& rhs)
155 {
156 return (lhs.node() == rhs.node()) && (lhs.end() == rhs.end());
157 }
158
159 template<class Val, class Ref, class Ptr, class Sz, class N>
160 bool operator!=(const rbtree_iterator<Val, Ref, Ptr, Sz, N>& lhs,
161 const rbtree_iterator<Val, Ref, Ptr, Sz, N>& rhs)
162 {
163 return !(lhs == rhs);
164 }
165
166 template<class Value, class ConstReference, class ConstPointer, class Size, class Node>
167 class rbtree_const_iterator
168 {
169 using non_const_iterator_type = rbtree_iterator<
170 Value, get_non_const_ref_t<ConstReference>,
171 get_non_const_ptr_t<ConstPointer>, Size, Node
172 >;
173
174 public:
175 using value_type = Value;
176 using size_type = Size;
177 using const_reference = ConstReference;
178 using const_pointer = ConstPointer;
179 using difference_type = ptrdiff_t;
180
181 using iterator_category = bidirectional_iterator_tag;
182
183 using node_type = Node;
184
185 rbtree_const_iterator(const node_type* current = nullptr, bool end = true)
186 : current_{current}, end_{end}
187 { /* DUMMY BODY */ }
188
189 rbtree_const_iterator(const rbtree_const_iterator&) = default;
190 rbtree_const_iterator& operator=(const rbtree_const_iterator&) = default;
191
192 rbtree_const_iterator(const non_const_iterator_type& other)
193 : current_{other.node()}, end_{other.end()}
194 { /* DUMMY BODY */ }
195
196 rbtree_const_iterator& operator=(const non_const_iterator_type& other)
197 {
198 current_ = other.node();
199 end_ = other.end();
200
201 return *this;
202 }
203
204 const_reference operator*() const
205 {
206 return current_->value;
207 }
208
209 const_pointer operator->() const
210 {
211 return &current_->value;
212 }
213
214 rbtree_const_iterator& operator++()
215 {
216 if (end_)
217 return *this;
218
219 if (current_)
220 {
221 auto next = current_->successor();
222 if (next)
223 current_ = next;
224 else
225 end_ = true;
226 }
227
228 return *this;
229 }
230
231 rbtree_const_iterator operator++(int)
232 {
233 auto tmp = *this;
234 ++(*this);
235
236 return tmp;
237 }
238
239 rbtree_const_iterator& operator--()
240 {
241 if (end_)
242 {
243 end_ = false;
244
245 return *this;
246 }
247
248 if (current_)
249 {
250 auto next = current_->predecessor();
251 if (next)
252 current_ = next;
253 else
254 end_ = true;
255 }
256
257 return *this;
258 }
259
260 rbtree_const_iterator operator--(int)
261 {
262 auto tmp = *this;
263 --(*this);
264
265 return tmp;
266 }
267
268 const node_type* node() const
269 {
270 return current_;
271 }
272
273 bool end() const
274 {
275 return end_;
276 }
277
278 private:
279 const node_type* current_;
280 bool end_;
281 };
282
283 template<class Val, class CRef, class CPtr, class Sz, class N>
284 bool operator==(const rbtree_const_iterator<Val, CRef, CPtr, Sz, N>& lhs,
285 const rbtree_const_iterator<Val, CRef, CPtr, Sz, N>& rhs)
286 {
287 return (lhs.node() == rhs.node()) && (lhs.end() == rhs.end());
288 }
289
290 template<class Val, class CRef, class CPtr, class Sz, class N>
291 bool operator!=(const rbtree_const_iterator<Val, CRef, CPtr, Sz, N>& lhs,
292 const rbtree_const_iterator<Val, CRef, CPtr, Sz, N>& rhs)
293 {
294 return !(lhs == rhs);
295 }
296
297 template<class Val, class Ref, class Ptr, class CRef, class CPtr, class Sz, class N>
298 bool operator==(const rbtree_iterator<Val, Ref, Ptr, Sz, N>& lhs,
299 const rbtree_const_iterator<Val, CRef, CPtr, Sz, N>& rhs)
300 {
301 return (lhs.node() == rhs.node()) && (lhs.end() == rhs.end());
302 }
303
304 template<class Val, class Ref, class Ptr, class CRef, class CPtr, class Sz, class N>
305 bool operator!=(const rbtree_iterator<Val, Ref, Ptr, Sz, N>& lhs,
306 const rbtree_const_iterator<Val, CRef, CPtr, Sz, N>& rhs)
307 {
308 return !(lhs == rhs);
309 }
310
311 template<class Val, class CRef, class CPtr, class Ref, class Ptr, class Sz, class N>
312 bool operator==(const rbtree_const_iterator<Val, CRef, CPtr, Sz, N>& lhs,
313 const rbtree_iterator<Val, Ref, Ptr, Sz, N>& rhs)
314 {
315 return (lhs.node() == rhs.node()) && (lhs.end() == rhs.end());
316 }
317
318 template<class Val, class CRef, class CPtr, class Ref, class Ptr, class Sz, class N>
319 bool operator!=(const rbtree_const_iterator<Val, CRef, CPtr, Sz, N>& lhs,
320 const rbtree_iterator<Val, Ref, Ptr, Sz, N>& rhs)
321 {
322 return !(lhs == rhs);
323 }
324}
325
326#endif
Note: See TracBrowser for help on using the repository browser.