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 table.insert(1);
309 table.clear();
310 EXPECT_TRUE(table.is_empty());
311}
312
313// ============================================================================
314// Copy/Move Semantics Tests
315// ============================================================================
316
318{
320
321 for (int i : {1, 2, 3, 4, 5})
322 table1.insert(i);
323
325
326 EXPECT_EQ(table2.size(), 5u);
327 for (int i : {1, 2, 3, 4, 5})
328 EXPECT_TRUE(table2.contains(i));
329
330 // Verify independence
331 table1.remove(3);
332 EXPECT_FALSE(table1.contains(3));
333 EXPECT_TRUE(table2.contains(3));
334}
335
337{
339
340 for (int i : {1, 2, 3})
341 table1.insert(i);
342
343 for (int i : {10, 20})
344 table2.insert(i);
345
346 table2 = table1;
347
348 EXPECT_EQ(table2.size(), 3u);
349 for (int i : {1, 2, 3})
350 EXPECT_TRUE(table2.contains(i));
351 EXPECT_FALSE(table2.contains(10));
352 EXPECT_FALSE(table2.contains(20));
353}
354
356{
357 DynSetLhash<int> table;
358
359 for (int i : {1, 2, 3})
360 table.insert(i);
361
362 table = table;
363
364 EXPECT_EQ(table.size(), 3u);
365 for (int i : {1, 2, 3})
366 EXPECT_TRUE(table.contains(i));
367}
368
370{
372
373 for (int i : {1, 2, 3, 4, 5})
374 table1.insert(i);
375
376 DynSetLhash<int> table2(std::move(table1));
377
378 EXPECT_EQ(table2.size(), 5u);
379 for (int i : {1, 2, 3, 4, 5})
380 EXPECT_TRUE(table2.contains(i));
381
382 EXPECT_TRUE(table1.is_empty());
383}
384
386{
388
389 for (int i : {1, 2, 3})
390 table1.insert(i);
391
392 for (int i : {10, 20})
393 table2.insert(i);
394
395 table2 = std::move(table1);
396
397 EXPECT_EQ(table2.size(), 3u);
398 for (int i : {1, 2, 3})
399 EXPECT_TRUE(table2.contains(i));
400
401 // After fix: Move assignment should leave table1 empty
402 EXPECT_TRUE(table1.is_empty());
403 EXPECT_EQ(table1.size(), 0u);
404}
405
407{
409
410 for (int i : {1, 2, 3})
411 table1.insert(i);
412
413 for (int i : {10, 20})
414 table2.insert(i);
415
416 table1.swap(table2);
417
418 EXPECT_EQ(table1.size(), 2u);
419 EXPECT_TRUE(table1.contains(10));
420 EXPECT_TRUE(table1.contains(20));
421
422 EXPECT_EQ(table2.size(), 3u);
423 EXPECT_TRUE(table2.contains(1));
424 EXPECT_TRUE(table2.contains(2));
425 EXPECT_TRUE(table2.contains(3));
426}
427
428// ============================================================================
429// Iterator Tests
430// ============================================================================
431
433{
434 DynSetLhash<int> table;
435
437 EXPECT_FALSE(it.has_curr());
438}
439
441{
442 DynSetLhash<int> table;
443
444 for (int i : {5, 3, 7, 1, 9})
445 table.insert(i);
446
447 vector<int> keys;
448 for (DynSetLhash<int>::Iterator it(table); it.has_curr(); it.next_ne())
449 keys.push_back(it.get_curr());
450
451 EXPECT_EQ(keys.size(), 5u);
452
453 // Hash table doesn't guarantee order, just verify all keys present
454 sort(keys.begin(), keys.end());
455 vector<int> expected = {1, 3, 5, 7, 9};
457}
458
460{
461 DynSetLhash<int> table;
462
463 for (int i : {1, 2, 3, 4, 5})
464 table.insert(i);
465
467 ASSERT_TRUE(it.has_curr());
468
469 int first = it.get_curr();
470 it.del();
471
472 EXPECT_EQ(table.size(), 4u);
473 EXPECT_FALSE(table.contains(first));
474}
475
477{
478 DynSetLhash<int> table;
479
480 table.insert(10);
481 table.insert(20);
482 table.insert(30);
483
484 // Just verify they don't throw
485 EXPECT_NO_THROW(table.get_first());
486 EXPECT_NO_THROW(table.get_last());
487}
488
489// ============================================================================
490// String Keys Tests
491// ============================================================================
492
494{
496
497 table.insert("apple");
498 table.insert("banana");
499 table.insert("cherry");
500
501 EXPECT_EQ(table.size(), 3u);
502 EXPECT_TRUE(table.contains("apple"));
503 EXPECT_TRUE(table.contains("banana"));
504 EXPECT_FALSE(table.contains("date"));
505}
506
507// ============================================================================
508// Stress Tests
509// ============================================================================
510
512{
513 DynSetLhash<int> table;
514
515 // Insert 10000 elements
516 for (int i = 0; i < 10000; ++i)
517 table.insert(i);
518
519 EXPECT_EQ(table.size(), 10000u);
520
521 // Verify all present
522 for (int i = 0; i < 10000; ++i)
523 EXPECT_TRUE(table.contains(i));
524}
525
527{
528 // Custom hash that always returns same value -> forces collisions
529 auto bad_hash = [](const int &) -> size_t { return 42; };
530
531 DynSetLhash<int> table(100, bad_hash);
532
533 for (int i = 0; i < 100; ++i)
534 table.insert(i);
535
536 EXPECT_EQ(table.size(), 100u);
537
538 for (int i = 0; i < 100; ++i)
539 EXPECT_TRUE(table.contains(i));
540}
541
543{
544 DynSetLhash<int> table;
545 vector<int> inserted;
546
547 // Random insertions
548 for (int i = 0; i < 500; ++i)
549 {
550 if (int key = rand() % 1000; table.insert(key) != nullptr)
551 inserted.push_back(key);
552 }
553
554 // Verify all inserted keys are present
555 for (int key : inserted)
556 EXPECT_TRUE(table.contains(key));
557
558 EXPECT_EQ(table.size(), inserted.size());
559
560 // Random removals
561 for (size_t i = 0; i < inserted.size() / 2; ++i)
562 {
563 int idx = rand() % inserted.size();
564 table.remove(inserted[idx]);
565 inserted.erase(inserted.begin() + idx);
566 }
567
568 EXPECT_EQ(table.size(), inserted.size());
569 for (int key : inserted)
570 EXPECT_TRUE(table.contains(key));
571}
572
574{
575 DynSetLhash<int> table(10); // Start small
576
577 // Insert many elements to force rehashing
578 for (int i = 0; i < 1000; ++i)
579 table.insert(i);
580
581 EXPECT_EQ(table.size(), 1000u);
582
583 // Verify all still accessible
584 for (int i = 0; i < 1000; ++i)
585 EXPECT_TRUE(table.contains(i));
586
587 // Remove many to trigger shrinking
588 for (int i = 0; i < 950; ++i)
589 table.remove(i);
590
591 EXPECT_EQ(table.size(), 50u);
592
593 for (int i = 950; i < 1000; ++i)
594 EXPECT_TRUE(table.contains(i));
595}
596
597// ============================================================================
598// DynMapHashTable Tests
599// ============================================================================
600
602{
604
605 EXPECT_TRUE(map.is_empty());
606 EXPECT_EQ(map.size(), 0u);
607 EXPECT_FALSE(map.contains(42));
608 EXPECT_EQ(map.search(42), nullptr);
609}
610
612{
614
615 auto * p = map.insert(1, "one");
616 ASSERT_NE(p, nullptr);
617 EXPECT_EQ(p->first, 1);
618 EXPECT_EQ(p->second, "one");
619 EXPECT_EQ(map.size(), 1u);
620}
621
623{
625
626 map.insert(1, "one");
627 map.insert(2, "two");
628 map.insert(3, "three");
629
630 EXPECT_EQ(map.size(), 3u);
631 EXPECT_TRUE(map.contains(1));
632 EXPECT_TRUE(map.contains(2));
633 EXPECT_TRUE(map.contains(3));
634}
635
637{
639
640 auto * p1 = map.insert(1, "one");
641 ASSERT_NE(p1, nullptr);
642
643 auto * p2 = map.insert(1, "uno");
644 EXPECT_EQ(p2, nullptr); // Duplicate key rejected
645 EXPECT_EQ(map.size(), 1u);
646
647 // Original value unchanged
648 EXPECT_EQ(map.find(1), "one");
649}
650
652{
654
655 map.insert(1, "one");
656 map.insert(2, "two");
657
658 auto * p = map.search(2);
659 ASSERT_NE(p, nullptr);
660 EXPECT_EQ(p->first, 2);
661 EXPECT_EQ(p->second, "two");
662
663 EXPECT_EQ(map.search(99), nullptr);
664}
665
667{
669
670 map.insert(1, "one");
671
672 EXPECT_EQ(map.find(1), "one");
673 EXPECT_THROW(map.find(99), domain_error);
674}
675
677{
679
680 // Non-const operator[] inserts if key doesn't exist
681 map[1] = "one";
682 EXPECT_EQ(map.size(), 1u);
683 EXPECT_EQ(map[1], "one");
684
685 // Can modify existing
686 map[1] = "uno";
687 EXPECT_EQ(map[1], "uno");
688 EXPECT_EQ(map.size(), 1u);
689}
690
692{
694 map.insert(1, "one");
695
696 const auto & const_map = map;
697 EXPECT_EQ(const_map[1], "one");
698 EXPECT_THROW(const_map[99], domain_error);
699}
700
702{
704
705 map.insert(1, "one");
706 map.insert(2, "two");
707 map.insert(3, "three");
708
709 string removed = map.remove(2);
710 EXPECT_EQ(removed, "two");
711 EXPECT_EQ(map.size(), 2u);
712 EXPECT_FALSE(map.contains(2));
713
714 map.clear();
715 EXPECT_TRUE(map.is_empty());
716 EXPECT_EQ(map.size(), 0u);
717}
718
720{
722
723 map.insert(1, "one");
724 map.insert(2, "two");
725 map.insert(3, "three");
726
727 auto keys = map.keys();
728 EXPECT_EQ(keys.size(), 3u);
729
730 vector<int> sorted_keys;
731 keys.for_each([&sorted_keys](int k) { sorted_keys.push_back(k); });
732 sort(sorted_keys.begin(), sorted_keys.end());
733
734 vector<int> expected = {1, 2, 3};
736}
737
738// BUG: tpl_dynSetHash.H line 540 has wrong return type (DynList<Key> instead of DynList<Data>)
739// This test is disabled until the bug is fixed in the library
740// The values() method should return DynList<Data> but currently returns DynList<Key>
742{
743 // Test disabled due to bug in library implementation
744 GTEST_SKIP() << "values() has wrong return type in tpl_dynSetHash.H:540";
745}
746
748{
750
751 map.insert(1, "one");
752 map.insert(2, "two");
753
754 auto ptrs = map.values_ptr();
755 EXPECT_EQ(ptrs.size(), 2u);
756
757 // Modify through pointer
758 ptrs.for_each([](string * p) {
759 if (*p == "one")
760 *p = "ONE";
761 });
762
763 EXPECT_EQ(map.find(1), "ONE");
764}
765
767{
769
770 map.insert(1, "one");
771 map.insert(2, "two");
772
773 auto items = map.items_ptr();
774 EXPECT_EQ(items.size(), 2u);
775}
776
778{
780
781 string s = "hello";
782 map.insert(1, std::move(s));
783 EXPECT_EQ(map.find(1), "hello");
784
785 int k = 2;
786 map.insert(std::move(k), "world");
787 EXPECT_EQ(map.find(2), "world");
788}
789
790// ============================================================================
791// Free Functions Tests (join, intercept, unique, repeated)
792// ============================================================================
793
795{
796 DynList<int> l1 = {1, 2, 3, 4};
797 DynList<int> l2 = {3, 4, 5, 6};
798
799 auto result = join(l1, l2);
800
801 // Result should be union: {1, 2, 3, 4, 5, 6}
802 EXPECT_EQ(result.size(), 6u);
803
805 for (int i : {1, 2, 3, 4, 5, 6})
806 EXPECT_TRUE(result_set.contains(i));
807}
808
810{
811 DynList<int> l1 = {1, 2, 3, 4, 5};
812 DynList<int> l2 = {3, 4, 5, 6, 7};
813
814 auto result = intercept(l1, l2);
815
816 // Result should be intersection: {3, 4, 5}
817 EXPECT_EQ(result.size(), 3u);
818
819 vector<int> vec;
820 result.for_each([&vec](int i) { vec.push_back(i); });
821 sort(vec.begin(), vec.end());
822
823 vector<int> expected = {3, 4, 5};
825}
826
828{
829 DynList<int> l = {1, 2, 2, 3, 3, 3, 4, 4, 4, 4};
830
831 auto result = unique(l);
832
833 // Result should be {1, 2, 3, 4}
834 EXPECT_EQ(result.size(), 4u);
835
837 for (int i : {1, 2, 3, 4})
838 EXPECT_TRUE(result_set.contains(i));
839}
840
842{
843 DynList<int> l = {1, 2, 2, 3, 3, 3, 4, 5};
844
845 auto result = repeated(l);
846
847 // Result contains all occurrences of duplicated values
848 // The function returns ALL instances of keys that appear more than once
849 // So we get 3 elements: one 2 (at index 2), and two 3s (at indices 3 and 4)
850 EXPECT_GE(result.size(), 2u); // At least 2 and 3 are duplicated
851
853 EXPECT_TRUE(result_set.contains(2));
854 EXPECT_TRUE(result_set.contains(3));
855 EXPECT_FALSE(result_set.contains(1)); // 1 only appears once
856 EXPECT_FALSE(result_set.contains(4)); // 4 only appears once
857 EXPECT_FALSE(result_set.contains(5)); // 5 only appears once
858}
859
861{
862 DynList<int> l = {1, 2, 2, 3, 4, 3};
863
864 auto result = repeated_with_index(l);
865
866 // Result should be: {(2, 2), (3, 5)}
867 EXPECT_EQ(result.size(), 2u);
868
869 bool found_2 = false, found_3 = false;
870 result.for_each([&](const pair<int, size_t> & p) {
871 if (p.first == 2)
872 {
873 EXPECT_EQ(p.second, 2u);
874 found_2 = true;
875 }
876 if (p.first == 3)
877 {
878 EXPECT_EQ(p.second, 5u);
879 found_3 = true;
880 }
881 });
882
885}
886
887// ============================================================================
888// Different Hash Table Types Tests
889// ============================================================================
890
892{
893 DynSetLinHash<int> table;
894
895 for (int i : {1, 2, 3, 4, 5})
896 table.insert(i);
897
898 EXPECT_EQ(table.size(), 5u);
899 for (int i : {1, 2, 3, 4, 5})
900 EXPECT_TRUE(table.contains(i));
901}
902
904{
905 DynSetHash<int> table;
906
907 for (int i : {10, 20, 30})
908 table.insert(i);
909
910 EXPECT_EQ(table.size(), 3u);
911 EXPECT_TRUE(table.contains(20));
912}
913
914// ============================================================================
915// Edge Cases
916// ============================================================================
917
919{
920 DynSetLhash<int> table;
921
922 table.insert(42);
923
924 EXPECT_EQ(table.size(), 1u);
925 EXPECT_TRUE(table.contains(42));
926
927 table.remove(42);
928 EXPECT_TRUE(table.is_empty());
929}
930
932{
933 DynSetLhash<int> table;
934
935 for (int cycle = 0; cycle < 10; ++cycle)
936 {
937 for (int i = 0; i < 50; ++i)
938 table.insert(i);
939
940 EXPECT_EQ(table.size(), 50u);
941
942 for (int i = 0; i < 50; ++i)
943 table.remove(i);
944
945 EXPECT_TRUE(table.is_empty());
946 }
947}
948
950{
951 // Custom hash: just return the value modulo 100
952 auto custom_hash = [](const int & k) -> size_t { return k % 100; };
953
954 DynSetLhash<int> table(100, custom_hash);
955
956 table.insert(1);
957 table.insert(101);
958 table.insert(201);
959
960 EXPECT_EQ(table.size(), 3u);
961 EXPECT_TRUE(table.contains(1));
962 EXPECT_TRUE(table.contains(101));
963 EXPECT_TRUE(table.contains(201));
964}
965
966// ============================================================================
967// Custom Types Tests
968// ============================================================================
969
970struct Point
971{
972 int x, y;
973
974 bool operator == (const Point & other) const
975 {
976 return x == other.x && y == other.y;
977 }
978};
979
980namespace std
981{
982 template <>
983 struct hash<Point>
984 {
985 size_t operator()(const Point & p) const
986 {
987 return hash<int>()(p.x) ^ (hash<int>()(p.y) << 1);
988 }
989 };
990}
991
992size_t point_hash(const Point & p)
993{
994 return std::hash<Point>()(p);
995}
996
998{
999 DynSetLhash<Point> table(100, point_hash);
1000
1001 Point p1{1, 2};
1002 Point p2{3, 4};
1003 Point p3{5, 6};
1004
1005 table.insert(p1);
1006 table.insert(p2);
1007 table.insert(p3);
1008
1009 EXPECT_EQ(table.size(), 3u);
1010 EXPECT_TRUE(table.contains(p1));
1011 EXPECT_TRUE(table.contains(p2));
1012 EXPECT_TRUE(table.contains(p3));
1013
1014 Point p4{7, 8};
1015 EXPECT_FALSE(table.contains(p4));
1016}
1017
1018int main(int argc, char **argv)
1019{
1020 ::testing::InitGoogleTest(&argc, argv);
1021 return RUN_ALL_TESTS();
1022}
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
Return true if the key exists in the table.
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
void clear()
Empties the container.
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.
bool is_empty() const noexcept
Checks if the container is empty.
const Key & get_first() const
Dynamic singly linked list with functional programming support.
Definition htlist.H:1155
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.
Represents a point with rectangular coordinates in a 2D plane.
Definition point.H:229
bool operator==(const Point &point) const noexcept
Checks for exact equality between two points.
Definition point.H:268
#define TEST(name)
size_t point_hash(const Point &p)
static mpfr_t y
Definition mpfr_mul_d.c:3
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)
Divide_Conquer_DP_Result< Cost > divide_and_conquer_partition_dp(const size_t groups, const size_t n, Transition_Cost_Fn transition_cost, const Cost inf=dp_optimization_detail::default_inf< Cost >())
Optimize partition DP using divide-and-conquer optimization.
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.
STL namespace.
size_t operator()(const Point &p) const
DynList< int > l1
DynList< int > l2
int keys[]
static int * k
size_t custom_hash(const int &key)
Dynamic set implementations based on hash tables.
DynList< int > l