source: mainline/uspace/lib/cpp/include/internal/hash_table_iterators.hpp@ 009d78b

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

cpp: refactored unnecessary code duplication

  • Property mode set to 100644
File size: 13.1 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_HASH_TABLE_ITERATORS
30#define LIBCPP_INTERNAL_HASH_TABLE_ITERATORS
31
32#include <internal/list.hpp>
33#include <internal/hash_table_bucket.hpp>
34#include <iterator>
35
36namespace std::aux
37{
38 template<class Value, class ConstReference, class ConstPointer, class Size>
39 class hash_table_const_iterator
40 {
41 public:
42 using value_type = Value;
43 using size_type = Size;
44 using const_reference = ConstReference;
45 using const_pointer = ConstPointer;
46 using difference_type = ptrdiff_t;
47
48 using iterator_category = forward_iterator_tag;
49
50 hash_table_const_iterator(const hash_table_bucket<value_type, size_type>* table = nullptr,
51 size_type idx = size_type{}, size_type max_idx = size_type{},
52 const list_node<value_type>* current = nullptr)
53 : table_{table}, idx_{idx}, max_idx_{max_idx}, current_{current}
54 { /* DUMMY BODY */ }
55
56 hash_table_const_iterator(const hash_table_const_iterator&) = default;
57 hash_table_const_iterator& operator=(const hash_table_const_iterator&) = default;
58
59 const_reference operator*() const
60 {
61 return current_->value;
62 }
63
64 const_pointer operator->() const
65 {
66 return &current_->value;
67 }
68
69 hash_table_const_iterator& operator++()
70 {
71 current_ = current_->next;
72 if (current_ == table_[idx_].head)
73 {
74 if (idx_ < max_idx_)
75 {
76 while (!table_[++idx_].head && idx_ < max_idx_)
77 { /* DUMMY BODY */ }
78
79 if (idx_ < max_idx_)
80 current_ = table_[idx_].head;
81 else
82 current_ = nullptr;
83 }
84 else
85 current_ = nullptr;
86 }
87
88 return *this;
89 }
90
91 hash_table_const_iterator operator++(int)
92 {
93 auto tmp = *this;
94 ++(*this);
95
96 return tmp;
97 }
98
99 list_node<value_type>* node()
100 {
101 return const_cast<list_node<value_type>*>(current_);
102 }
103
104 const list_node<value_type>* node() const
105 {
106 return current_;
107 }
108
109 size_type idx() const
110 {
111 return idx_;
112 }
113
114 private:
115 const hash_table_bucket<value_type, size_type>* table_;
116 size_type idx_;
117 size_type max_idx_;
118 const list_node<value_type>* current_;
119 };
120
121 template<class Value, class ConstRef, class ConstPtr, class Size>
122 bool operator==(const hash_table_const_iterator<Value, ConstRef, ConstPtr, Size>& lhs,
123 const hash_table_const_iterator<Value, ConstRef, ConstPtr, Size>& rhs)
124 {
125 return lhs.node() == rhs.node();
126 }
127
128 template<class Value, class ConstRef, class ConstPtr, class Size>
129 bool operator!=(const hash_table_const_iterator<Value, ConstRef, ConstPtr, Size>& lhs,
130 const hash_table_const_iterator<Value, ConstRef, ConstPtr, Size>& rhs)
131 {
132 return !(lhs == rhs);
133 }
134
135 template<class Value, class Reference, class Pointer, class Size>
136 class hash_table_iterator
137 {
138 public:
139 using value_type = Value;
140 using size_type = Size;
141 using reference = Reference;
142 using pointer = Pointer;
143 using difference_type = ptrdiff_t;
144
145 using iterator_category = forward_iterator_tag;
146
147 hash_table_iterator(hash_table_bucket<value_type, size_type>* table = nullptr,
148 size_type idx = size_type{}, size_type max_idx = size_type{},
149 list_node<value_type>* current = nullptr)
150 : table_{table}, idx_{idx}, max_idx_{max_idx}, current_{current}
151 { /* DUMMY BODY */ }
152
153 hash_table_iterator(const hash_table_iterator&) = default;
154 hash_table_iterator& operator=(const hash_table_iterator&) = default;
155
156 reference operator*()
157 {
158 return current_->value;
159 }
160
161 pointer operator->()
162 {
163 return &current_->value;
164 }
165
166 hash_table_iterator& operator++()
167 {
168 current_ = current_->next;
169 if (current_ == table_[idx_].head)
170 {
171 if (idx_ < max_idx_)
172 {
173 while (!table_[++idx_].head && idx_ < max_idx_)
174 { /* DUMMY BODY */ }
175
176 if (idx_ < max_idx_)
177 current_ = table_[idx_].head;
178 else
179 current_ = nullptr;
180 }
181 else
182 current_ = nullptr;
183 }
184
185 return *this;
186 }
187
188 hash_table_iterator operator++(int)
189 {
190 auto tmp = *this;
191 ++(*this);
192
193 return tmp;
194 }
195
196 list_node<value_type>* node()
197 {
198 return current_;
199 }
200
201 const list_node<value_type>* node() const
202 {
203 return current_;
204 }
205
206 size_type idx() const
207 {
208 return idx_;
209 }
210
211 template<class ConstRef, class ConstPtr>
212 operator hash_table_const_iterator<
213 Value, ConstRef, ConstPtr, Size
214 >() const
215 {
216 return hash_table_const_iterator<value_type, ConstRef, ConstPtr, size_type>{
217 table_, idx_, max_idx_, current_
218 };
219 }
220
221 private:
222 hash_table_bucket<value_type, size_type>* table_;
223 size_type idx_;
224 size_type max_idx_;
225 list_node<value_type>* current_;
226 };
227
228 template<class Value, class Ref, class Ptr, class Size>
229 bool operator==(const hash_table_iterator<Value, Ref, Ptr, Size>& lhs,
230 const hash_table_iterator<Value, Ref, Ptr, Size>& rhs)
231 {
232 return lhs.node() == rhs.node();
233 }
234
235 template<class Value, class Ref, class Ptr, class Size>
236 bool operator!=(const hash_table_iterator<Value, Ref, Ptr, Size>& lhs,
237 const hash_table_iterator<Value, Ref, Ptr, Size>& rhs)
238 {
239 return !(lhs == rhs);
240 }
241
242 template<class Value, class ConstReference, class ConstPointer>
243 class hash_table_const_local_iterator
244 {
245 public:
246 using value_type = Value;
247 using const_reference = ConstReference;
248 using const_pointer = ConstPointer;
249 using difference_type = ptrdiff_t;
250
251 using iterator_category = forward_iterator_tag;
252
253 // TODO: requirement for forward iterator is default constructibility, fix others!
254 hash_table_const_local_iterator(const list_node<value_type>* head = nullptr,
255 const list_node<value_type>* current = nullptr)
256 : head_{head}, current_{current}
257 { /* DUMMY BODY */ }
258
259 hash_table_const_local_iterator(const hash_table_const_local_iterator&) = default;
260 hash_table_const_local_iterator& operator=(const hash_table_const_local_iterator&) = default;
261
262 const_reference operator*() const
263 {
264 return current_->value;
265 }
266
267 const_pointer operator->() const
268 {
269 return &current_->value;
270 }
271
272 hash_table_const_local_iterator& operator++()
273 {
274 current_ = current_->next;
275 if (current_ == head_)
276 current_ = nullptr;
277
278 return *this;
279 }
280
281 hash_table_const_local_iterator operator++(int)
282 {
283 auto tmp = *this;
284 ++(*this);
285
286 return tmp;
287 }
288
289
290 list_node<value_type>* node()
291 {
292 return const_cast<list_node<value_type>*>(current_);
293 }
294
295 const list_node<value_type>* node() const
296 {
297 return current_;
298 }
299
300 private:
301 const list_node<value_type>* head_;
302 const list_node<value_type>* current_;
303 };
304
305 template<class Value, class ConstRef, class ConstPtr>
306 bool operator==(const hash_table_const_local_iterator<Value, ConstRef, ConstPtr>& lhs,
307 const hash_table_const_local_iterator<Value, ConstRef, ConstPtr>& rhs)
308 {
309 return lhs.node() == rhs.node();
310 }
311
312 template<class Value, class ConstRef, class ConstPtr>
313 bool operator!=(const hash_table_const_local_iterator<Value, ConstRef, ConstPtr>& lhs,
314 const hash_table_const_local_iterator<Value, ConstRef, ConstPtr>& rhs)
315 {
316 return !(lhs == rhs);
317 }
318
319 template<class Value, class Reference, class Pointer>
320 class hash_table_local_iterator
321 {
322 public:
323 using value_type = Value;
324 using reference = Reference;
325 using pointer = Pointer;
326 using difference_type = ptrdiff_t;
327
328 using iterator_category = forward_iterator_tag;
329
330 hash_table_local_iterator(list_node<value_type>* head = nullptr,
331 list_node<value_type>* current = nullptr)
332 : head_{head}, current_{current}
333 { /* DUMMY BODY */ }
334
335 hash_table_local_iterator(const hash_table_local_iterator&) = default;
336 hash_table_local_iterator& operator=(const hash_table_local_iterator&) = default;
337
338 reference operator*()
339 {
340 return current_->value;
341 }
342
343 pointer operator->()
344 {
345 return &current_->value;
346 }
347
348 hash_table_local_iterator& operator++()
349 {
350 current_ = current_->next;
351 if (current_ == head_)
352 current_ = nullptr;
353
354 return *this;
355 }
356
357 hash_table_local_iterator operator++(int)
358 {
359 auto tmp = *this;
360 ++(*this);
361
362 return tmp;
363 }
364
365 list_node<value_type>* node()
366 {
367 return current_;
368 }
369
370 const list_node<value_type>* node() const
371 {
372 return current_;
373 }
374
375 template<class ConstRef, class ConstPtr>
376 operator hash_table_const_local_iterator<
377 Value, ConstRef, ConstPtr
378 >() const
379 {
380 return hash_table_const_local_iterator<
381 value_type, ConstRef, ConstPtr
382 >{head_, current_};
383 }
384
385 private:
386 list_node<value_type>* head_;
387 list_node<value_type>* current_;
388 };
389
390 template<class Value, class Ref, class Ptr>
391 bool operator==(const hash_table_local_iterator<Value, Ref, Ptr>& lhs,
392 const hash_table_local_iterator<Value, Ref, Ptr>& rhs)
393 {
394 return lhs.node() == rhs.node();
395 }
396
397 template<class Value, class Ref, class Ptr>
398 bool operator!=(const hash_table_local_iterator<Value, Ref, Ptr>& lhs,
399 const hash_table_local_iterator<Value, Ref, Ptr>& rhs)
400 {
401 return !(lhs == rhs);
402 }
403}
404
405#endif
Note: See TracBrowser for help on using the repository browser.