Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
dynsethash.cc
Go to the documentation of this file.
1
2/*
3 Aleph_w
4
5 Data structures & Algorithms
6 version 2.0.0b
7 https://github.com/lrleon/Aleph-w
8
9 This file is part of Aleph-w library
10
11 Copyright (c) 2002-2026 Leandro Rabindranath Leon
12
13 Permission is hereby granted, free of charge, to any person obtaining a copy
14 of this software and associated documentation files (the "Software"), to deal
15 in the Software without restriction, including without limitation the rights
16 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17 copies of the Software, and to permit persons to whom the Software is
18 furnished to do so, subject to the following conditions:
19
20 The above copyright notice and this permission notice shall be included in all
21 copies or substantial portions of the Software.
22
23 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 SOFTWARE.
30*/
31
32
38#include <algorithm>
39#include <stdexcept>
40#include <vector>
41#include <string>
42#include <gtest/gtest.h>
43
44#include <tpl_dynSetHash.H>
45
46using namespace std;
47using namespace Aleph;
48
49// ============================================================================
50// Basic Operations Tests - DynHashTable
51// ============================================================================
52
54{
55 DynSetLhash<int> table;
56
57 EXPECT_TRUE(table.is_empty());
58 EXPECT_EQ(table.size(), 0u);
59 EXPECT_FALSE(table.contains(42));
60 EXPECT_EQ(table.search(42), nullptr);
61 EXPECT_FALSE(table.has(42));
62}
63
65{
66 DynSetLhash<int> table;
67
68 auto * p = table.insert(42);
69 ASSERT_NE(p, nullptr);
70 EXPECT_EQ(*p, 42);
71 EXPECT_FALSE(table.is_empty());
72 EXPECT_EQ(table.size(), 1u);
73 EXPECT_TRUE(table.contains(42));
74 EXPECT_TRUE(table.has(42));
75}
76
78{
79 DynSetLhash<int> table;
80
81 for (int i : {5, 3, 7, 1, 9, 2, 8})
82 {
83 auto * p = table.insert(i);
84 ASSERT_NE(p, nullptr);
85 EXPECT_EQ(*p, i);
86 }
87
88 EXPECT_EQ(table.size(), 7u);
89
90 for (int i : {1, 2, 3, 5, 7, 8, 9})
91 EXPECT_TRUE(table.contains(i));
92
93 EXPECT_FALSE(table.contains(4));
94 EXPECT_FALSE(table.contains(6));
95}
96
98{
99 DynSetLhash<int> table;
100
101 auto * p1 = table.insert(42);
102 ASSERT_NE(p1, nullptr);
103 EXPECT_EQ(*p1, 42);
104 EXPECT_EQ(table.size(), 1u);
105
106 auto * p2 = table.insert(42);
107 EXPECT_EQ(p2, nullptr); // Duplicate rejected
108 EXPECT_EQ(table.size(), 1u); // Size unchanged
109}
110
112{
113 DynSetLhash<int> table;
114
115 table.insert(10);
116 table.insert(20);
117 table.insert(30);
118
119 auto * p = table.search(20);
120 ASSERT_NE(p, nullptr);
121 EXPECT_EQ(*p, 20);
122}
123
125{
126 DynSetLhash<int> table;
127
128 table.insert(10);
129 table.insert(30);
130
131 EXPECT_EQ(table.search(20), nullptr);
132}
133
135{
136 DynSetLhash<int> table;
137
138 table.insert(42);
139
140 const auto & key = table.find(42);
141 EXPECT_EQ(key, 42);
142
143 // Non-const version returns modifiable reference
144 auto & key2 = table.find(42);
145 EXPECT_EQ(key2, 42);
146
147 // WARNING: Modifying a key through the reference breaks the hash table invariants!
148 // The key is stored at hash(42)'s bucket, but if we change it to 99,
149 // it won't be found at hash(99)'s bucket. This is UNDEFINED BEHAVIOR.
150 // So we just verify that find() returns a non-const reference without actually modifying it.
151}
152
154{
155 DynSetLhash<int> table;
156
157 table.insert(10);
158
159 EXPECT_THROW(table.find(42), domain_error);
160}
161
162// ============================================================================
163// Insert Variations Tests
164// ============================================================================
165
167{
168 DynSetLhash<int> table;
169
170 // First call: inserts
171 auto * p1 = table.search_or_insert(42);
172 ASSERT_NE(p1, nullptr);
173 EXPECT_EQ(*p1, 42);
174 EXPECT_EQ(table.size(), 1u);
175
176 // Second call: returns existing
177 auto * p2 = table.search_or_insert(42);
178 ASSERT_NE(p2, nullptr);
179 EXPECT_EQ(*p2, 42);
180 EXPECT_EQ(table.size(), 1u); // Size unchanged
181 EXPECT_EQ(p1, p2); // Same pointer
182}
183
185{
186 DynSetLhash<int> table;
187
188 // First call: inserts, returns {ptr, false}
189 auto [p1, found1] = table.contains_or_insert(42);
190 ASSERT_NE(p1, nullptr);
191 EXPECT_EQ(*p1, 42);
192 EXPECT_FALSE(found1); // Was inserted
193 EXPECT_EQ(table.size(), 1u);
194
195 // Second call: finds, returns {ptr, true}
196 auto [p2, found2] = table.contains_or_insert(42);
197 ASSERT_NE(p2, nullptr);
198 EXPECT_EQ(*p2, 42);
199 EXPECT_TRUE(found2); // Already existed
200 EXPECT_EQ(table.size(), 1u);
201 EXPECT_EQ(p1, p2); // Same pointer
202}
203
205{
206 DynSetLhash<int> table;
207
208 auto * p1 = table.add(10);
209 ASSERT_NE(p1, nullptr);
210 EXPECT_EQ(*p1, 10);
211
212 auto * p2 = table.append(20);
213 ASSERT_NE(p2, nullptr);
214 EXPECT_EQ(*p2, 20);
215
216 EXPECT_EQ(table.size(), 2u);
217}
218
220{
222
223 string s = "hello";
224 auto * p = table.insert(std::move(s));
225 ASSERT_NE(p, nullptr);
226 EXPECT_EQ(*p, "hello");
227 // s should be in moved-from state (typically empty, but not guaranteed)
228}
229
230// ============================================================================
231// Remove Tests
232// ============================================================================
233
235{
236 DynSetLhash<int> table;
237
238 table.insert(10);
239 table.insert(20);
240 table.insert(30);
241
242 int removed = table.remove(20);
243 EXPECT_EQ(removed, 20);
244 EXPECT_EQ(table.size(), 2u);
245 EXPECT_FALSE(table.contains(20));
246 EXPECT_TRUE(table.contains(10));
247 EXPECT_TRUE(table.contains(30));
248}
249
251{
252 DynSetLhash<int> table;
253
254 table.insert(10);
255
256 EXPECT_THROW(table.remove(42), domain_error);
257}
258
260{
261 DynSetLhash<int> table;
262
263 table.insert(10);
264 auto * p20 = table.insert(20);
265 table.insert(30);
266
267 ASSERT_NE(p20, nullptr);
268
269 // Remove by pointer
270 table.remove(p20);
271
272 EXPECT_EQ(table.size(), 2u);
273 EXPECT_FALSE(table.contains(20));
274 EXPECT_TRUE(table.contains(10));
275 EXPECT_TRUE(table.contains(30));
276}
277
279{
280 DynSetLhash<int> table;
281
282 for (int i = 0; i < 50; ++i)
283 table.insert(i);
284
285 EXPECT_EQ(table.size(), 50u);
286
287 for (int i = 0; i < 50; ++i)
288 table.remove(i);
289
290 EXPECT_TRUE(table.is_empty());
291 EXPECT_EQ(table.size(), 0u);
292}
293
295{
296 DynSetLhash<int> table;
297
298 for (int i = 0; i < 100; ++i)
299 table.insert(i);
300
301 EXPECT_EQ(table.size(), 100u);
302
303 table.empty();
304
305 EXPECT_TRUE(table.is_empty());
306 EXPECT_EQ(table.size(), 0u);
307}
308
309// ============================================================================
310// Copy/Move Semantics Tests
311// ============================================================================
312
314{
316
317 for (int i : {1, 2, 3, 4, 5})
318 table1.insert(i);
319
321
322 EXPECT_EQ(table2.size(), 5u);
323 for (int i : {1, 2, 3, 4, 5})
324 EXPECT_TRUE(table2.contains(i));
325
326 // Verify independence
327 table1.remove(3);
328 EXPECT_FALSE(table1.contains(3));
329 EXPECT_TRUE(table2.contains(3));
330}
331
333{
335
336 for (int i : {1, 2, 3})
337 table1.insert(i);
338
339 for (int i : {10, 20})
340 table2.insert(i);
341
342 table2 = table1;
343
344 EXPECT_EQ(table2.size(), 3u);
345 for (int i : {1, 2, 3})
346 EXPECT_TRUE(table2.contains(i));
347 EXPECT_FALSE(table2.contains(10));
348 EXPECT_FALSE(table2.contains(20));
349}
350
352{
353 DynSetLhash<int> table;
354
355 for (int i : {1, 2, 3})
356 table.insert(i);
357
358 table = table;
359
360 EXPECT_EQ(table.size(), 3u);
361 for (int i : {1, 2, 3})
362 EXPECT_TRUE(table.contains(i));
363}
364
366{
368
369 for (int i : {1, 2, 3, 4, 5})
370 table1.insert(i);
371
372 DynSetLhash<int> table2(std::move(table1));
373
374 EXPECT_EQ(table2.size(), 5u);
375 for (int i : {1, 2, 3, 4, 5})
376 EXPECT_TRUE(table2.contains(i));
377
379}
380
382{
384
385 for (int i : {1, 2, 3})
386 table1.insert(i);
387
388 for (int i : {10, 20})
389 table2.insert(i);
390
391 table2 = std::move(table1);
392
393 EXPECT_EQ(table2.size(), 3u);
394 for (int i : {1, 2, 3})
395 EXPECT_TRUE(table2.contains(i));
396
397 // After fix: Move assignment should leave table1 empty
399 EXPECT_EQ(table1.size(), 0u);
400}
401
403{
405
406 for (int i : {1, 2, 3})
407 table1.insert(i);
408
409 for (int i : {10, 20})
410 table2.insert(i);
411
413
414 EXPECT_EQ(table1.size(), 2u);
415 EXPECT_TRUE(table1.contains(10));
416 EXPECT_TRUE(table1.contains(20));
417
418 EXPECT_EQ(table2.size(), 3u);
419 EXPECT_TRUE(table2.contains(1));
420 EXPECT_TRUE(table2.contains(2));
421 EXPECT_TRUE(table2.contains(3));
422}
423
424// ============================================================================
425// Iterator Tests
426// ============================================================================
427
429{
430 DynSetLhash<int> table;
431
433 EXPECT_FALSE(it.has_curr());
434}
435
437{
438 DynSetLhash<int> table;
439
440 for (int i : {5, 3, 7, 1, 9})
441 table.insert(i);
442
443 vector<int> keys;
444 for (DynSetLhash<int>::Iterator it(table); it.has_curr(); it.next_ne())
445 keys.push_back(it.get_curr());
446
447 EXPECT_EQ(keys.size(), 5u);
448
449 // Hash table doesn't guarantee order, just verify all keys present
450 sort(keys.begin(), keys.end());
451 vector<int> expected = {1, 3, 5, 7, 9};
452 EXPECT_EQ(keys, expected);
453}
454
456{
457 DynSetLhash<int> table;
458
459 for (int i : {1, 2, 3, 4, 5})
460 table.insert(i);
461
463 ASSERT_TRUE(it.has_curr());
464
465 int first = it.get_curr();
466 it.del();
467
468 EXPECT_EQ(table.size(), 4u);
469 EXPECT_FALSE(table.contains(first));
470}
471
473{
474 DynSetLhash<int> table;
475
476 table.insert(10);
477 table.insert(20);
478 table.insert(30);
479
480 // Just verify they don't throw
481 EXPECT_NO_THROW(table.get_first());
482 EXPECT_NO_THROW(table.get_last());
483}
484
485// ============================================================================
486// String Keys Tests
487// ============================================================================
488
490{
492
493 table.insert("apple");
494 table.insert("banana");
495 table.insert("cherry");
496
497 EXPECT_EQ(table.size(), 3u);
498 EXPECT_TRUE(table.contains("apple"));
499 EXPECT_TRUE(table.contains("banana"));
500 EXPECT_FALSE(table.contains("date"));
501}
502
503// ============================================================================
504// Stress Tests
505// ============================================================================
506
508{
509 DynSetLhash<int> table;
510
511 // Insert 10000 elements
512 for (int i = 0; i < 10000; ++i)
513 table.insert(i);
514
515 EXPECT_EQ(table.size(), 10000u);
516
517 // Verify all present
518 for (int i = 0; i < 10000; ++i)
519 EXPECT_TRUE(table.contains(i));
520}
521
523{
524 // Custom hash that always returns same value -> forces collisions
525 auto bad_hash = [](const int &) -> size_t { return 42; };
526
527 DynSetLhash<int> table(100, bad_hash);
528
529 for (int i = 0; i < 100; ++i)
530 table.insert(i);
531
532 EXPECT_EQ(table.size(), 100u);
533
534 for (int i = 0; i < 100; ++i)
535 EXPECT_TRUE(table.contains(i));
536}
537
539{
540 DynSetLhash<int> table;
541 vector<int> inserted;
542
543 // Random insertions
544 for (int i = 0; i < 500; ++i)
545 {
546 if (int key = rand() % 1000; table.insert(key) != nullptr)
547 inserted.push_back(key);
548 }
549
550 // Verify all inserted keys are present
551 for (int key : inserted)
552 EXPECT_TRUE(table.contains(key));
553
554 EXPECT_EQ(table.size(), inserted.size());
555
556 // Random removals
557 for (size_t i = 0; i < inserted.size() / 2; ++i)
558 {
559 int idx = rand() % inserted.size();
560 table.remove(inserted[idx]);
561 inserted.erase(inserted.begin() + idx);
562 }
563
564 EXPECT_EQ(table.size(), inserted.size());
565 for (int key : inserted)
566 EXPECT_TRUE(table.contains(key));
567}
568
570{
571 DynSetLhash<int> table(10); // Start small
572
573 // Insert many elements to force rehashing
574 for (int i = 0; i < 1000; ++i)
575 table.insert(i);
576
577 EXPECT_EQ(table.size(), 1000u);
578
579 // Verify all still accessible
580 for (int i = 0; i < 1000; ++i)
581 EXPECT_TRUE(table.contains(i));
582
583 // Remove many to trigger shrinking
584 for (int i = 0; i < 950; ++i)
585 table.remove(i);
586
587 EXPECT_EQ(table.size(), 50u);
588
589 for (int i = 950; i < 1000; ++i)
590 EXPECT_TRUE(table.contains(i));
591}
592
593// ============================================================================
594// DynMapHashTable Tests
595// ============================================================================
596
598{
600
601 EXPECT_TRUE(map.is_empty());
602 EXPECT_EQ(map.size(), 0u);
603 EXPECT_FALSE(map.contains(42));
604 EXPECT_EQ(map.search(42), nullptr);
605}
606
608{
610
611 auto * p = map.insert(1, "one");
612 ASSERT_NE(p, nullptr);
613 EXPECT_EQ(p->first, 1);
614 EXPECT_EQ(p->second, "one");
615 EXPECT_EQ(map.size(), 1u);
616}
617
619{
621
622 map.insert(1, "one");
623 map.insert(2, "two");
624 map.insert(3, "three");
625
626 EXPECT_EQ(map.size(), 3u);
627 EXPECT_TRUE(map.contains(1));
628 EXPECT_TRUE(map.contains(2));
629 EXPECT_TRUE(map.contains(3));
630}
631
633{
635
636 auto * p1 = map.insert(1, "one");
637 ASSERT_NE(p1, nullptr);
638
639 auto * p2 = map.insert(1, "uno");
640 EXPECT_EQ(p2, nullptr); // Duplicate key rejected
641 EXPECT_EQ(map.size(), 1u);
642
643 // Original value unchanged
644 EXPECT_EQ(map.find(1), "one");
645}
646
648{
650
651 map.insert(1, "one");
652 map.insert(2, "two");
653
654 auto * p = map.search(2);
655 ASSERT_NE(p, nullptr);
656 EXPECT_EQ(p->first, 2);
657 EXPECT_EQ(p->second, "two");
658
659 EXPECT_EQ(map.search(99), nullptr);
660}
661
663{
665
666 map.insert(1, "one");
667
668 EXPECT_EQ(map.find(1), "one");
669 EXPECT_THROW(map.find(99), domain_error);
670}
671
673{
675
676 // Non-const operator[] inserts if key doesn't exist
677 map[1] = "one";
678 EXPECT_EQ(map.size(), 1u);
679 EXPECT_EQ(map[1], "one");
680
681 // Can modify existing
682 map[1] = "uno";
683 EXPECT_EQ(map[1], "uno");
684 EXPECT_EQ(map.size(), 1u);
685}
686
688{
690 map.insert(1, "one");
691
692 const auto & const_map = map;
693 EXPECT_EQ(const_map[1], "one");
694 EXPECT_THROW(const_map[99], domain_error);
695}
696
698{
700
701 map.insert(1, "one");
702 map.insert(2, "two");
703 map.insert(3, "three");
704
705 string removed = map.remove(2);
706 EXPECT_EQ(removed, "two");
707 EXPECT_EQ(map.size(), 2u);
708 EXPECT_FALSE(map.contains(2));
709}
710
712{
714
715 map.insert(1, "one");
716 map.insert(2, "two");
717 map.insert(3, "three");
718
719 auto keys = map.keys();
720 EXPECT_EQ(keys.size(), 3u);
721
722 vector<int> sorted_keys;
723 keys.for_each([&sorted_keys](int k) { sorted_keys.push_back(k); });
725
726 vector<int> expected = {1, 2, 3};
728}
729
730// BUG: tpl_dynSetHash.H line 540 has wrong return type (DynList<Key> instead of DynList<Data>)
731// This test is disabled until the bug is fixed in the library
732// The values() method should return DynList<Data> but currently returns DynList<Key>
734{
735 // Test disabled due to bug in library implementation
736 GTEST_SKIP() << "values() has wrong return type in tpl_dynSetHash.H:540";
737}
738
740{
742
743 map.insert(1, "one");
744 map.insert(2, "two");
745
746 auto ptrs = map.values_ptr();
747 EXPECT_EQ(ptrs.size(), 2u);
748
749 // Modify through pointer
750 ptrs.for_each([](string * p) {
751 if (*p == "one")
752 *p = "ONE";
753 });
754
755 EXPECT_EQ(map.find(1), "ONE");
756}
757
759{
761
762 map.insert(1, "one");
763 map.insert(2, "two");
764
765 auto items = map.items_ptr();
766 EXPECT_EQ(items.size(), 2u);
767}
768
770{
772
773 string s = "hello";
774 map.insert(1, std::move(s));
775 EXPECT_EQ(map.find(1), "hello");
776
777 int k = 2;
778 map.insert(std::move(k), "world");
779 EXPECT_EQ(map.find(2), "world");
780}
781
782// ============================================================================
783// Free Functions Tests (join, intercept, unique, repeated)
784// ============================================================================
785
787{
788 DynList<int> l1 = {1, 2, 3, 4};
789 DynList<int> l2 = {3, 4, 5, 6};
790
791 auto result = join(l1, l2);
792
793 // Result should be union: {1, 2, 3, 4, 5, 6}
794 EXPECT_EQ(result.size(), 6u);
795
797 for (int i : {1, 2, 3, 4, 5, 6})
798 EXPECT_TRUE(result_set.contains(i));
799}
800
802{
803 DynList<int> l1 = {1, 2, 3, 4, 5};
804 DynList<int> l2 = {3, 4, 5, 6, 7};
805
806 auto result = intercept(l1, l2);
807
808 // Result should be intersection: {3, 4, 5}
809 EXPECT_EQ(result.size(), 3u);
810
811 vector<int> vec;
812 result.for_each([&vec](int i) { vec.push_back(i); });
813 sort(vec.begin(), vec.end());
814
815 vector<int> expected = {3, 4, 5};
817}
818
820{
821 DynList<int> l = {1, 2, 2, 3, 3, 3, 4, 4, 4, 4};
822
823 auto result = unique(l);
824
825 // Result should be {1, 2, 3, 4}
826 EXPECT_EQ(result.size(), 4u);
827
829 for (int i : {1, 2, 3, 4})
830 EXPECT_TRUE(result_set.contains(i));
831}
832
834{
835 DynList<int> l = {1, 2, 2, 3, 3, 3, 4, 5};
836
837 auto result = repeated(l);
838
839 // Result contains all occurrences of duplicated values
840 // The function returns ALL instances of keys that appear more than once
841 // So we get 3 elements: one 2 (at index 2), and two 3s (at indices 3 and 4)
842 EXPECT_GE(result.size(), 2u); // At least 2 and 3 are duplicated
843
845 EXPECT_TRUE(result_set.contains(2));
846 EXPECT_TRUE(result_set.contains(3));
847 EXPECT_FALSE(result_set.contains(1)); // 1 only appears once
848 EXPECT_FALSE(result_set.contains(4)); // 4 only appears once
849 EXPECT_FALSE(result_set.contains(5)); // 5 only appears once
850}
851
853{
854 DynList<int> l = {1, 2, 2, 3, 4, 3};
855
856 auto result = repeated_with_index(l);
857
858 // Result should be: {(2, 2), (3, 5)}
859 EXPECT_EQ(result.size(), 2u);
860
861 bool found_2 = false, found_3 = false;
862 result.for_each([&](const pair<int, size_t> & p) {
863 if (p.first == 2)
864 {
865 EXPECT_EQ(p.second, 2u);
866 found_2 = true;
867 }
868 if (p.first == 3)
869 {
870 EXPECT_EQ(p.second, 5u);
871 found_3 = true;
872 }
873 });
874
877}
878
879// ============================================================================
880// Different Hash Table Types Tests
881// ============================================================================
882
884{
885 DynSetLinHash<int> table;
886
887 for (int i : {1, 2, 3, 4, 5})
888 table.insert(i);
889
890 EXPECT_EQ(table.size(), 5u);
891 for (int i : {1, 2, 3, 4, 5})
892 EXPECT_TRUE(table.contains(i));
893}
894
896{
897 DynSetHash<int> table;
898
899 for (int i : {10, 20, 30})
900 table.insert(i);
901
902 EXPECT_EQ(table.size(), 3u);
903 EXPECT_TRUE(table.contains(20));
904}
905
906// ============================================================================
907// Edge Cases
908// ============================================================================
909
911{
912 DynSetLhash<int> table;
913
914 table.insert(42);
915
916 EXPECT_EQ(table.size(), 1u);
917 EXPECT_TRUE(table.contains(42));
918
919 table.remove(42);
920 EXPECT_TRUE(table.is_empty());
921}
922
924{
925 DynSetLhash<int> table;
926
927 for (int cycle = 0; cycle < 10; ++cycle)
928 {
929 for (int i = 0; i < 50; ++i)
930 table.insert(i);
931
932 EXPECT_EQ(table.size(), 50u);
933
934 for (int i = 0; i < 50; ++i)
935 table.remove(i);
936
937 EXPECT_TRUE(table.is_empty());
938 }
939}
940
942{
943 // Custom hash: just return the value modulo 100
944 auto custom_hash = [](const int & k) -> size_t { return k % 100; };
945
946 DynSetLhash<int> table(100, custom_hash);
947
948 table.insert(1);
949 table.insert(101);
950 table.insert(201);
951
952 EXPECT_EQ(table.size(), 3u);
953 EXPECT_TRUE(table.contains(1));
954 EXPECT_TRUE(table.contains(101));
955 EXPECT_TRUE(table.contains(201));
956}
957
958// ============================================================================
959// Custom Types Tests
960// ============================================================================
961
962struct Point
963{
964 int x, y;
965
966 bool operator == (const Point & other) const
967 {
968 return x == other.x && y == other.y;
969 }
970};
971
972namespace std
973{
974 template <>
975 struct hash<Point>
976 {
977 size_t operator()(const Point & p) const
978 {
979 return hash<int>()(p.x) ^ (hash<int>()(p.y) << 1);
980 }
981 };
982}
983
984size_t point_hash(const Point & p)
985{
986 return std::hash<Point>()(p);
987}
988
990{
991 DynSetLhash<Point> table(100, point_hash);
992
993 Point p1{1, 2};
994 Point p2{3, 4};
995 Point p3{5, 6};
996
997 table.insert(p1);
998 table.insert(p2);
999 table.insert(p3);
1000
1001 EXPECT_EQ(table.size(), 3u);
1002 EXPECT_TRUE(table.contains(p1));
1003 EXPECT_TRUE(table.contains(p2));
1004 EXPECT_TRUE(table.contains(p3));
1005
1006 Point p4{7, 8};
1007 EXPECT_FALSE(table.contains(p4));
1008}
1009
1010int main(int argc, char **argv)
1011{
1012 ::testing::InitGoogleTest(&argc, argv);
1013 return RUN_ALL_TESTS();
1014}
int main()
Self-adjusting dynamic hash table.
Key * add(const Key &key)
Key * search_or_insert(const Key &key)
Key * search(const Key &key) const noexcept
Searches for a key in the hash table.
Key * append(const Key &key)
bool contains(const Key &key) const noexcept
Alias for has()
void remove(Key *key)
Removes a key from the hash table using its pointer.
const Key & get_last() const
Key * insert(const Key &key)
Inserts key into the hash set.
const Key & find(const Key &key) const
std::pair< Key *, bool > contains_or_insert(const Key &key)
bool has(const Key &key) const noexcept
Checks if a key exists in the hash table.
const Key & get_first() const
Dynamic singly linked list with functional programming support.
Definition htlist.H:1423
T & insert(const T &item)
Insert a new item by copy.
Definition htlist.H:1502
T remove()
Remove the first item of the list.
Definition htlist.H:1611
DynList & swap(DynList &l) noexcept
Swap this with l.
Definition htlist.H:1448
DynList< Data * > values_ptr()
Pair * insert(const Key &key, const Data &data)
Inserts into the hash map the pair (key, record) indexed by key.
Data remove(const Key &key)
Removes a key-value pair from the map and returns the value.
bool contains(const Key &key) const noexcept
Alias for has()
DynList< Pair * > items_ptr()
Pair * search(const Key &key) const noexcept
Searches for key and, if found, returns a pointer to the associated pair stored in the table.
DynList< Key > keys() const
Data & find(const Key &key)
Finds and returns a reference to the value associated with key.
constexpr bool is_empty() const noexcept
Return true if list is empty.
Definition htlist.H:523
size_t size() const noexcept
Count the number of elements of the list.
Definition htlist.H:1319
void for_each(Operation &operation)
Traverse all the container and performs an operation on each element.
Definition ah-dry.H:685
Rectangular point in the plane.
Definition point.H:156
Geom_Number x
Definition point.H:161
Geom_Number y
Definition point.H:162
bool operator==(const Point &point) const
Definition point.H:185
iterator end() noexcept
Return an STL-compatible end iterator.
iterator begin() noexcept
Return an STL-compatible iterator to the first element.
#define TEST(name)
size_t point_hash(const Point &p)
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
Itor unique(Itor __first, Itor __last, BinaryPredicate __binary_pred=BinaryPredicate())
Remove consecutive duplicates in place.
Definition ahAlgo.H:1058
DynList< T > intercept(const Container< T > &c1, const Container< T > &c2)
DynList< std::pair< T, size_t > > repeated_with_index(const Container< T > &c)
DynList< T > repeated(const Container< T > &c)
DynArray< T > sort(const DynArray< T > &a, Cmp &&cmp=Cmp())
Returns a sorted copy of a DynArray.
Definition ahSort.H:227
std::pair< First, Second > pair
Alias to std::pair kept for backwards compatibility.
Definition ahPair.H:89
std::ostream & join(const C &c, const std::string &sep, std::ostream &out)
Join elements of an Aleph-style container into a stream.
DynList< T > maps(const C &c, Op op)
Classic map operation.
STL namespace.
size_t operator()(const Point &p) const
size_t custom_hash(const int &key)
Dynamic set implementations based on hash tables.
DynList< int > l