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

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

cpp: divided the hash table sources to multiple headers for better readability and shareability with rbtree in the case of key extractors

  • Property mode set to 100644
File size: 14.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_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_current = current_;
94 auto tmp_idx = idx_;
95
96 current_ = current_->next;
97 if (current_ == table_[idx_].head)
98 {
99 if (idx_ < max_idx_)
100 {
101 while (!table_[++idx_].head && idx_ < max_idx_)
102 { /* DUMMY BODY */ }
103
104 if (idx_ < max_idx_)
105 current_ = table_[idx_].head;
106 else
107 current_ = nullptr;
108 }
109 else
110 current_ = nullptr;
111 }
112
113 return hash_table_const_iterator{
114 table_, tmp_idx, max_idx_, tmp_current
115 };
116 }
117
118 list_node<value_type>* node()
119 {
120 return const_cast<list_node<value_type>*>(current_);
121 }
122
123 const list_node<value_type>* node() const
124 {
125 return current_;
126 }
127
128 size_type idx() const
129 {
130 return idx_;
131 }
132
133 private:
134 const hash_table_bucket<value_type, size_type>* table_;
135 size_type idx_;
136 size_type max_idx_;
137 const list_node<value_type>* current_;
138 };
139
140 template<class Value, class ConstRef, class ConstPtr, class Size>
141 bool operator==(const hash_table_const_iterator<Value, ConstRef, ConstPtr, Size>& lhs,
142 const hash_table_const_iterator<Value, ConstRef, ConstPtr, Size>& rhs)
143 {
144 return lhs.node() == rhs.node();
145 }
146
147 template<class Value, class ConstRef, class ConstPtr, class Size>
148 bool operator!=(const hash_table_const_iterator<Value, ConstRef, ConstPtr, Size>& lhs,
149 const hash_table_const_iterator<Value, ConstRef, ConstPtr, Size>& rhs)
150 {
151 return !(lhs == rhs);
152 }
153
154 template<class Value, class Reference, class Pointer, class Size>
155 class hash_table_iterator
156 {
157 public:
158 using value_type = Value;
159 using size_type = Size;
160 using reference = Reference;
161 using pointer = Pointer;
162 using difference_type = ptrdiff_t;
163
164 using iterator_category = forward_iterator_tag;
165
166 hash_table_iterator(hash_table_bucket<value_type, size_type>* table = nullptr,
167 size_type idx = size_type{}, size_type max_idx = size_type{},
168 list_node<value_type>* current = nullptr)
169 : table_{table}, idx_{idx}, max_idx_{max_idx}, current_{current}
170 { /* DUMMY BODY */ }
171
172 hash_table_iterator(const hash_table_iterator&) = default;
173 hash_table_iterator& operator=(const hash_table_iterator&) = default;
174
175 reference operator*()
176 {
177 return current_->value;
178 }
179
180 pointer operator->()
181 {
182 return &current_->value;
183 }
184
185 hash_table_iterator& operator++()
186 {
187 current_ = current_->next;
188 if (current_ == table_[idx_].head)
189 {
190 if (idx_ < max_idx_)
191 {
192 while (!table_[++idx_].head && idx_ < max_idx_)
193 { /* DUMMY BODY */ }
194
195 if (idx_ < max_idx_)
196 current_ = table_[idx_].head;
197 else
198 current_ = nullptr;
199 }
200 else
201 current_ = nullptr;
202 }
203
204 return *this;
205 }
206
207 hash_table_iterator operator++(int)
208 {
209 auto tmp_current = current_;
210 auto tmp_idx = idx_;
211
212 current_ = current_->next;
213 if (current_ == table_[idx_].head)
214 {
215 if (idx_ < max_idx_)
216 {
217 while (!table_[++idx_].head && idx_ < max_idx_)
218 { /* DUMMY BODY */ }
219
220 if (idx_ < max_idx_)
221 current_ = table_[idx_].head;
222 else
223 current_ = nullptr;
224 }
225 else
226 current_ = nullptr;
227 }
228
229 return hash_table_iterator{
230 table_, tmp_idx, max_idx_, tmp_current
231 };
232 }
233
234 list_node<value_type>* node()
235 {
236 return current_;
237 }
238
239 const list_node<value_type>* node() const
240 {
241 return current_;
242 }
243
244 size_type idx() const
245 {
246 return idx_;
247 }
248
249 template<class ConstRef, class ConstPtr>
250 operator hash_table_const_iterator<
251 Value, ConstRef, ConstPtr, Size
252 >() const
253 {
254 return hash_table_const_iterator<value_type, ConstRef, ConstPtr, size_type>{
255 table_, idx_, max_idx_, current_
256 };
257 }
258
259 private:
260 hash_table_bucket<value_type, size_type>* table_;
261 size_type idx_;
262 size_type max_idx_;
263 list_node<value_type>* current_;
264 };
265
266 template<class Value, class Ref, class Ptr, class Size>
267 bool operator==(const hash_table_iterator<Value, Ref, Ptr, Size>& lhs,
268 const hash_table_iterator<Value, Ref, Ptr, Size>& rhs)
269 {
270 return lhs.node() == rhs.node();
271 }
272
273 template<class Value, class Ref, class Ptr, class Size>
274 bool operator!=(const hash_table_iterator<Value, Ref, Ptr, Size>& lhs,
275 const hash_table_iterator<Value, Ref, Ptr, Size>& rhs)
276 {
277 return !(lhs == rhs);
278 }
279
280 template<class Value, class ConstReference, class ConstPointer>
281 class hash_table_const_local_iterator
282 {
283 public:
284 using value_type = Value;
285 using const_reference = ConstReference;
286 using const_pointer = ConstPointer;
287 using difference_type = ptrdiff_t;
288
289 using iterator_category = forward_iterator_tag;
290
291 // TODO: requirement for forward iterator is default constructibility, fix others!
292 hash_table_const_local_iterator(const list_node<value_type>* head = nullptr,
293 const list_node<value_type>* current = nullptr)
294 : head_{head}, current_{current}
295 { /* DUMMY BODY */ }
296
297 hash_table_const_local_iterator(const hash_table_const_local_iterator&) = default;
298 hash_table_const_local_iterator& operator=(const hash_table_const_local_iterator&) = default;
299
300 const_reference operator*() const
301 {
302 return current_->value;
303 }
304
305 const_pointer operator->() const
306 {
307 return &current_->value;
308 }
309
310 hash_table_const_local_iterator& operator++()
311 {
312 current_ = current_->next;
313 if (current_ == head_)
314 current_ = nullptr;
315
316 return *this;
317 }
318
319 hash_table_const_local_iterator operator++(int)
320 {
321 auto tmp = current_;
322 current_ = current_->next;
323 if (current_ == head_)
324 current_ = nullptr;
325
326 return hash_table_const_local_iterator{head_, tmp};
327 }
328
329
330 list_node<value_type>* node()
331 {
332 return const_cast<list_node<value_type>*>(current_);
333 }
334
335 const list_node<value_type>* node() const
336 {
337 return current_;
338 }
339
340 private:
341 const list_node<value_type>* head_;
342 const list_node<value_type>* current_;
343 };
344
345 template<class Value, class ConstRef, class ConstPtr>
346 bool operator==(const hash_table_const_local_iterator<Value, ConstRef, ConstPtr>& lhs,
347 const hash_table_const_local_iterator<Value, ConstRef, ConstPtr>& rhs)
348 {
349 return lhs.node() == rhs.node();
350 }
351
352 template<class Value, class ConstRef, class ConstPtr>
353 bool operator!=(const hash_table_const_local_iterator<Value, ConstRef, ConstPtr>& lhs,
354 const hash_table_const_local_iterator<Value, ConstRef, ConstPtr>& rhs)
355 {
356 return !(lhs == rhs);
357 }
358
359 template<class Value, class Reference, class Pointer>
360 class hash_table_local_iterator
361 {
362 public:
363 using value_type = Value;
364 using reference = Reference;
365 using pointer = Pointer;
366 using difference_type = ptrdiff_t;
367
368 using iterator_category = forward_iterator_tag;
369
370 hash_table_local_iterator(list_node<value_type>* head = nullptr,
371 list_node<value_type>* current = nullptr)
372 : head_{head}, current_{current}
373 { /* DUMMY BODY */ }
374
375 hash_table_local_iterator(const hash_table_local_iterator&) = default;
376 hash_table_local_iterator& operator=(const hash_table_local_iterator&) = default;
377
378 reference operator*()
379 {
380 return current_->value;
381 }
382
383 pointer operator->()
384 {
385 return &current_->value;
386 }
387
388 hash_table_local_iterator& operator++()
389 {
390 current_ = current_->next;
391 if (current_ == head_)
392 current_ = nullptr;
393
394 return *this;
395 }
396
397 hash_table_local_iterator operator++(int)
398 {
399 auto tmp = current_;
400 current_ = current_->next;
401 if (current_ == head_)
402 current_ = nullptr;
403
404 return hash_table_local_iterator{head_, tmp};
405 }
406
407 list_node<value_type>* node()
408 {
409 return current_;
410 }
411
412 const list_node<value_type>* node() const
413 {
414 return current_;
415 }
416
417 template<class ConstRef, class ConstPtr>
418 operator hash_table_const_local_iterator<
419 Value, ConstRef, ConstPtr
420 >() const
421 {
422 return hash_table_const_local_iterator<
423 value_type, ConstRef, ConstPtr
424 >{head_, current_};
425 }
426
427 private:
428 list_node<value_type>* head_;
429 list_node<value_type>* current_;
430 };
431
432 template<class Value, class Ref, class Ptr>
433 bool operator==(const hash_table_local_iterator<Value, Ref, Ptr>& lhs,
434 const hash_table_local_iterator<Value, Ref, Ptr>& rhs)
435 {
436 return lhs.node() == rhs.node();
437 }
438
439 template<class Value, class Ref, class Ptr>
440 bool operator!=(const hash_table_local_iterator<Value, Ref, Ptr>& lhs,
441 const hash_table_local_iterator<Value, Ref, Ptr>& rhs)
442 {
443 return !(lhs == rhs);
444 }
445}
446
447#endif
Note: See TracBrowser for help on using the repository browser.