43 template <
typename Key,
typename Val,
typename Alloc >
44 template <
typename OtherAlloc >
47 Bucket *ptr, *old_ptr{
nullptr}, *new_elt{
nullptr};
57 new_elt = __alloc_bucket->allocate(1);
60 __alloc_bucket->construct(new_elt, *ptr);
62 __alloc_bucket->deallocate(new_elt, 1);
67 new_elt->
prev = old_ptr;
69 if (old_ptr !=
nullptr)
70 old_ptr->
next = new_elt;
77 if (old_ptr !=
nullptr) old_ptr->
next =
nullptr;
86 for (; __deb_list !=
nullptr; __deb_list = new_elt) {
87 new_elt = __deb_list->next;
88 __alloc_bucket->destroy(__deb_list);
89 __alloc_bucket->deallocate(__deb_list, 1);
99 template <
typename Key,
typename Val,
typename Alloc >
102 for (
Bucket* ptr = __deb_list; ptr !=
nullptr; ptr = ptr->
next)
103 if (ptr->key() == key)
return ptr;
108 template <
typename Key,
typename Val,
typename Alloc >
112 if (ptr ==
nullptr) {
117 if (ptr->
prev !=
nullptr)
120 __deb_list = ptr->
next;
122 if (ptr->
next !=
nullptr)
125 __end_list = ptr->
prev;
128 __alloc_bucket->destroy(ptr);
129 __alloc_bucket->deallocate(ptr, 1);
134 template <
typename Key,
typename Val,
typename Alloc >
137 allocator) noexcept :
138 __alloc_bucket{allocator} {}
140 template <
typename Key,
typename Val,
typename Alloc >
147 template <
typename Key,
typename Val,
typename Alloc >
151 __end_list{from.__end_list}, __nb_elements{from.__nb_elements},
152 __alloc_bucket{from.__alloc_bucket} {
153 from.__deb_list =
nullptr;
156 template <
typename Key,
typename Val,
typename Alloc >
158 for (
Bucket *next_ptr, *ptr = __deb_list; ptr !=
nullptr; ptr = next_ptr) {
159 next_ptr = ptr->
next;
160 __alloc_bucket->destroy(ptr);
161 __alloc_bucket->deallocate(ptr, 1);
165 template <
typename Key,
typename Val,
typename Alloc >
167 for (
Bucket *next_ptr, *ptr = __deb_list; ptr !=
nullptr; ptr = next_ptr) {
168 next_ptr = ptr->
next;
169 __alloc_bucket->destroy(ptr);
170 __alloc_bucket->deallocate(ptr, 1);
173 __nb_elements =
Size(0);
174 __deb_list =
nullptr;
175 __end_list =
nullptr;
178 template <
typename Key,
typename Val,
typename Alloc >
191 template <
typename Key,
typename Val,
typename Alloc >
192 template <
typename OtherAlloc >
206 template <
typename Key,
typename Val,
typename Alloc >
213 __end_list = from.__end_list;
214 __nb_elements = from.__nb_elements;
215 from.__deb_list =
nullptr;
221 template <
typename Key,
typename Val,
typename Alloc >
224 __alloc_bucket = &alloc;
227 template <
typename Key,
typename Val,
typename Alloc >
230 if (i >= __nb_elements) {
236 for (ptr = __deb_list; i; --i, ptr = ptr->
next) {}
241 template <
typename Key,
typename Val,
typename Alloc >
244 if (i >= __nb_elements) {
250 for (ptr = __deb_list; i; --i, ptr = ptr->
next) {}
255 template <
typename Key,
typename Val,
typename Alloc >
258 for (
Bucket* ptr = __deb_list; ptr !=
nullptr; ptr = ptr->
next)
259 if (ptr->key() == key)
return ptr->val();
262 "hashtable's chained list contains no element with this key <" 266 template <
typename Key,
typename Val,
typename Alloc >
269 for (
Bucket* ptr = __deb_list; ptr !=
nullptr; ptr = ptr->
next)
270 if (ptr->key() == key)
return ptr->val();
273 "hashtable's chained list contains no element with this key <" 277 template <
typename Key,
typename Val,
typename Alloc >
279 for (
Bucket* ptr = __deb_list; ptr !=
nullptr; ptr = ptr->
next) {
280 if (ptr->key() == key) {
return true; }
286 template <
typename Key,
typename Val,
typename Alloc >
288 return (__nb_elements ==
Size(0));
291 template <
typename Key,
typename Val,
typename Alloc >
295 new_elt->prev =
nullptr;
296 new_elt->next = __deb_list;
298 if (__deb_list !=
nullptr)
299 __deb_list->prev = new_elt;
301 __end_list = new_elt;
303 __deb_list = new_elt;
312 template <
typename Key,
typename Val,
typename Alloc >
313 template <
typename OtherAlloc >
318 GUM_ASSERT(table.
__size == __size);
327 for (
Size j = 0; j < __size; ++j)
330 __nb_elements =
Size(0);
340 template <
typename Key,
typename Val,
typename Alloc >
343 return *(
reinterpret_cast< const iterator*
>(
344 HashTableIteratorStaticEnd::end4Statics()));
347 template <
typename Key,
typename Val,
typename Alloc >
351 HashTableIteratorStaticEnd::constEnd4Statics()));
354 template <
typename Key,
typename Val,
typename Alloc >
358 HashTableIteratorStaticEnd::endSafe4Statics()));
361 template <
typename Key,
typename Val,
typename Alloc >
365 HashTableIteratorStaticEnd::constEndSafe4Statics()));
368 template <
typename Key,
typename Val,
typename Alloc >
373 for (
auto& list: __nodes) {
374 list.setAllocator(__alloc);
378 __hash_func.resize(size);
385 template <
typename Key,
typename Val,
typename Alloc >
388 bool key_uniqueness_pol) :
391 __resize_policy{resize_pol}, __key_uniqueness_policy{key_uniqueness_pol} {
399 template <
typename Key,
typename Val,
typename Alloc >
401 std::initializer_list< std::pair< Key, Val > > list) :
404 std::max< Size >(
Size(2),
Size(list.size()) / 2))} {
412 for (
const auto& elt: list) {
417 template <
typename Key,
typename Val,
typename Alloc >
421 __resize_policy{table.__resize_policy},
422 __key_uniqueness_policy{table.__key_uniqueness_policy},
423 __begin_index{table.__begin_index} {
434 template <
typename Key,
typename Val,
typename Alloc >
435 template <
typename OtherAlloc >
439 __resize_policy{table.__resize_policy},
440 __key_uniqueness_policy{table.__key_uniqueness_policy},
441 __begin_index{table.__begin_index} {
452 template <
typename Key,
typename Val,
typename Alloc >
454 __nodes(
std::move(table.__nodes)), __size{table.__size},
455 __nb_elements{table.__nb_elements}, __hash_func{table.__hash_func},
456 __resize_policy{table.__resize_policy},
457 __key_uniqueness_policy{table.__key_uniqueness_policy},
458 __begin_index{table.__begin_index},
459 __safe_iterators(std::move(table.__safe_iterators)),
460 __alloc(std::move(table.__alloc)) {
466 template <
typename Key,
typename Val,
typename Alloc >
468 const Size len = __safe_iterators.
size();
469 for (
Size i =
Size(0); i < len; ++i)
470 __safe_iterators[i]->clear();
473 template <
typename Key,
typename Val,
typename Alloc >
480 for (
Size i =
Size(0); i < __size; ++i)
483 __nb_elements =
Size(0);
484 __begin_index = std::numeric_limits< Size >::max();
487 template <
typename Key,
typename Val,
typename Alloc >
497 template <
typename Key,
typename Val,
typename Alloc >
512 if (__size != from.
__size) {
513 __nodes.resize(from.
__size);
516 __nodes[i].setAllocator(__alloc);
523 __hash_func.resize(__size);
537 template <
typename Key,
typename Val,
typename Alloc >
538 template <
typename OtherAlloc >
553 if (__size != from.
__size) {
554 __nodes.resize(from.
__size);
557 __nodes[i].setAllocator(__alloc);
564 __hash_func.resize(__size);
578 template <
typename Key,
typename Val,
typename Alloc >
582 if (
this != &table) {
590 __nodes = std::move(table.__nodes);
591 __safe_iterators = std::move(table.__safe_iterators);
592 __alloc = std::move(table.__alloc);
593 __size = table.__size;
594 __nb_elements = table.__nb_elements;
595 __hash_func = table.__hash_func;
596 __resize_policy = table.__resize_policy;
597 __key_uniqueness_policy = table.__key_uniqueness_policy;
598 __begin_index = table.__begin_index;
607 template <
typename Key,
typename Val,
typename Alloc >
613 return *(
reinterpret_cast< const iterator*
>(
614 HashTableIteratorStaticEnd::__HashTableIterEnd));
617 template <
typename Key,
typename Val,
typename Alloc >
624 HashTableIteratorStaticEnd::__HashTableIterEnd));
627 template <
typename Key,
typename Val,
typename Alloc >
634 HashTableIteratorStaticEnd::__HashTableIterEnd));
637 template <
typename Key,
typename Val,
typename Alloc >
641 if (__nb_elements ==
Size(0))
647 template <
typename Key,
typename Val,
typename Alloc >
651 if (__nb_elements ==
Size(0))
657 template <
typename Key,
typename Val,
typename Alloc >
661 if (__nb_elements ==
Size(0))
667 template <
typename Key,
typename Val,
typename Alloc >
674 HashTableIteratorStaticEnd::__HashTableIterEndSafe));
677 template <
typename Key,
typename Val,
typename Alloc >
684 HashTableIteratorStaticEnd::__HashTableIterEndSafe));
687 template <
typename Key,
typename Val,
typename Alloc >
694 HashTableIteratorStaticEnd::__HashTableIterEndSafe));
697 template <
typename Key,
typename Val,
typename Alloc >
701 if (__nb_elements ==
Size(0))
707 template <
typename Key,
typename Val,
typename Alloc >
711 if (__nb_elements ==
Size(0))
717 template <
typename Key,
typename Val,
typename Alloc >
721 if (__nb_elements ==
Size(0))
727 template <
typename Key,
typename Val,
typename Alloc >
729 return __nodes[__hash_func(key)][key];
732 template <
typename Key,
typename Val,
typename Alloc >
735 return __nodes[__hash_func(key)][key];
738 template <
typename Key,
typename Val,
typename Alloc >
740 return __nb_elements;
743 template <
typename Key,
typename Val,
typename Alloc >
748 template <
typename Key,
typename Val,
typename Alloc >
750 return __nodes[__hash_func(key)].
exists(key);
753 template <
typename Key,
typename Val,
typename Alloc >
755 const bool new_policy) noexcept {
756 __resize_policy = new_policy;
759 template <
typename Key,
typename Val,
typename Alloc >
761 return __resize_policy;
764 template <
typename Key,
typename Val,
typename Alloc >
766 const bool new_policy) noexcept {
767 __key_uniqueness_policy = new_policy;
770 template <
typename Key,
typename Val,
typename Alloc >
772 return __key_uniqueness_policy;
775 template <
typename Key,
typename Val,
typename Alloc >
778 new_size = std::max(
Size(2), new_size);
783 new_size =
Size(1) << log_size;
788 if (new_size != __size) {
793 <= new_size * HashTableConst::default_mean_val_by_slot)) {
795 std::vector< HashTableList< Key, Val, Alloc > > new_nodes(new_size);
797 for (
auto& list: new_nodes) {
798 list.setAllocator(__alloc);
802 __hash_func.resize(new_size);
808 for (
Size i =
Size(0); i < __size; ++i) {
809 while ((bucket = __nodes[i].__deb_list) !=
nullptr) {
811 new_hashed_key = __hash_func(bucket->
key());
815 __nodes[i].__deb_list = bucket->
next;
818 new_nodes[new_hashed_key].insert(bucket);
824 __begin_index = std::numeric_limits< Size >::max();
830 for (
auto iter: __safe_iterators) {
832 iter->__index = __hash_func(iter->__bucket->key());
834 iter->__next_bucket =
nullptr;
842 template <
typename Key,
typename Val,
typename Alloc >
845 Size hash_key = __hash_func(bucket->
key());
848 if (__key_uniqueness_policy && __nodes[hash_key].exists(bucket->
key())) {
850 Key k = bucket->
key();
851 __alloc.destroy(bucket);
852 __alloc.deallocate(bucket, 1);
854 "the hashtable contains an element with the same key (" << k
861 && (__nb_elements >= __size * HashTableConst::default_mean_val_by_slot)) {
863 hash_key = __hash_func(bucket->
key());
867 __nodes[hash_key].insert(bucket);
875 if (__begin_index < hash_key) { __begin_index = hash_key; }
878 template <
typename Key,
typename Val,
typename Alloc >
881 Bucket* bucket = __alloc.allocate(1);
884 __alloc.construct(bucket, thekey, theval);
886 __alloc.deallocate(bucket, 1);
891 return bucket->
elt();
894 template <
typename Key,
typename Val,
typename Alloc >
897 Bucket* bucket = __alloc.allocate(1);
900 __alloc.construct(bucket, std::move(thekey), std::move(theval));
902 __alloc.deallocate(bucket, 1);
907 return bucket->
elt();
910 template <
typename Key,
typename Val,
typename Alloc >
913 Bucket* bucket = __alloc.allocate(1);
916 __alloc.construct(bucket, reinterpret_cast< const value_type& >(elt));
918 __alloc.deallocate(bucket, 1);
923 return bucket->
elt();
926 template <
typename Key,
typename Val,
typename Alloc >
929 Bucket* bucket = __alloc.allocate(1);
932 __alloc.construct(bucket, std::move(reinterpret_cast< value_type& >(elt)));
934 __alloc.deallocate(bucket, 1);
939 return bucket->
elt();
942 template <
typename Key,
typename Val,
typename Alloc >
943 template <
typename... Args >
946 Bucket* bucket = __alloc.allocate(1);
949 __alloc.construct(bucket,
951 std::forward< Args >(args)...);
953 __alloc.deallocate(bucket, 1);
958 return bucket->
elt();
961 template <
typename Key,
typename Val,
typename Alloc >
964 const Val& default_value) {
965 Bucket* bucket = __nodes[__hash_func(key)].bucket(key);
967 if (bucket ==
nullptr)
968 return insert(key, default_value).second;
970 return bucket->
val();
973 template <
typename Key,
typename Val,
typename Alloc >
976 Bucket* bucket = __nodes[__hash_func(key)].bucket(key);
978 if (bucket ==
nullptr)
979 return insert(std::move(key), std::move(default_value)).second;
981 return bucket->
val();
984 template <
typename Key,
typename Val,
typename Alloc >
986 Bucket* bucket = __nodes[__hash_func(key)].bucket(key);
988 if (bucket ==
nullptr)
991 bucket->
val() = value;
994 template <
typename Key,
typename Val,
typename Alloc >
997 if (bucket ==
nullptr)
return;
1000 for (
auto iter: __safe_iterators) {
1001 if (iter->__bucket == bucket) {
1003 iter->__next_bucket = iter->__bucket;
1004 iter->__bucket =
nullptr;
1005 }
else if (iter->__next_bucket == bucket) {
1006 iter->__bucket = bucket;
1008 iter->__next_bucket = iter->__bucket;
1009 iter->__bucket =
nullptr;
1014 __nodes[index].erase(bucket);
1018 if ((index == __begin_index) && __nodes[index].empty()) {
1019 __begin_index = std::numeric_limits< Size >::max();
1023 template <
typename Key,
typename Val,
typename Alloc >
1026 Size hash = __hash_func(key);
1031 __erase(bucket, hash);
1034 template <
typename Key,
typename Val,
typename Alloc >
1039 template <
typename Key,
typename Val,
typename Alloc >
1045 template <
typename Key,
typename Val,
typename Alloc >
1047 for (
auto iter = cbegin(); iter != cend(); ++iter)
1048 if (iter.__bucket->val() == val) {
1049 __erase(iter.__getBucket(), iter.__getIndex());
1054 template <
typename Key,
typename Val,
typename Alloc >
1059 template <
typename Key,
typename Val,
typename Alloc >
1061 for (
auto iter = begin(); iter != end(); ++iter)
1062 if (iter.__bucket->val() == val)
return iter.
key();
1067 template <
typename Key,
typename Val,
typename Alloc >
1070 Bucket* bucket = __nodes[__hash_func(key)].bucket(key);
1072 if (bucket ==
nullptr) {
1076 return bucket->
key();
1079 template <
typename Key,
typename Val,
typename Alloc >
1081 for (
auto iterAll = cbeginSafe(); iterAll != cendSafe(); ++iterAll) {
1082 if (iterAll.__bucket->val() == val) {
1083 __erase(iterAll.__bucket, iterAll.__index);
1088 template <
typename Key,
typename Val,
typename Alloc >
1090 return (__nb_elements ==
Size(0));
1093 template <
typename Key,
typename Val,
typename Alloc >
1094 template <
typename Mount,
typename OtherAlloc >
1096 Mount (*f)(Val),
Size size,
bool resize_pol,
bool key_uniqueness_pol)
const {
1101 if (size == 0) size = std::max(
Size(2), __nb_elements / 2);
1105 size, resize_pol, key_uniqueness_pol);
1108 for (
auto iter = begin(); iter != end(); ++iter) {
1109 table.
insert(iter.key(), f(iter.val()));
1115 template <
typename Key,
typename Val,
typename Alloc >
1116 template <
typename Mount,
typename OtherAlloc >
1118 Mount (*f)(Val&),
Size size,
bool resize_pol,
bool key_uniqueness_pol)
const {
1123 if (size ==
Size(0)) size = std::max(
Size(2), __nb_elements / 2);
1127 size, resize_pol, key_uniqueness_pol);
1130 for (
auto iter = begin(); iter != end(); ++iter) {
1131 table.
insert(iter.key(), f(const_cast< Val& >(iter.val())));
1137 template <
typename Key,
typename Val,
typename Alloc >
1138 template <
typename Mount,
typename OtherAlloc >
1143 bool key_uniqueness_pol)
const {
1148 if (size ==
Size(0)) size = std::max(
Size(2), __nb_elements / 2);
1152 size, resize_pol, key_uniqueness_pol);
1155 for (
auto iter = begin(); iter != end(); ++iter) {
1156 table.
insert(iter.key(), f(iter.val()));
1162 template <
typename Key,
typename Val,
typename Alloc >
1163 template <
typename Mount,
typename OtherAlloc >
1165 const Mount& val,
Size size,
bool resize_pol,
bool key_uniqueness_pol)
const {
1170 if (size ==
Size(0)) size = std::max(
Size(2), __nb_elements / 2);
1174 size, resize_pol, key_uniqueness_pol);
1177 for (
auto iter = begin(); iter != end(); ++iter) {
1178 table.
insert(iter.key(), val);
1184 template <
typename Key,
typename Val,
typename Alloc >
1185 template <
typename OtherAlloc >
1192 for (
auto iter = begin(); iter != end(); ++iter) {
1194 if (iter.val() != from[iter.key()])
return false;
1195 }
catch (
NotFound&) {
return false; }
1201 template <
typename Key,
typename Val,
typename Alloc >
1202 template <
typename OtherAlloc >
1208 template <
typename Key,
typename Val,
typename Alloc >
1215 ptr = ptr->list.next, deja =
true) {
1216 if (deja) stream <<
" , ";
1218 stream << ptr->key() <<
"=>" << ptr->val();
1226 template <
typename Key,
typename Val,
typename Alloc >
1233 ptr = ptr->list.next, deja =
true) {
1234 if (deja) stream <<
" , ";
1236 stream << ptr->key() <<
"=>" << ptr->val();
1244 template <
typename Key,
typename Val,
typename Alloc >
1251 for (
auto ptr = table.
__nodes[i].__deb_list; ptr; ptr = ptr->next) {
1252 if (deja) stream <<
" , ";
1254 stream << ptr->key() <<
"=>" << ptr->val();
1264 template <
typename Key,
typename Val,
typename Alloc >
1271 for (
auto ptr = table.
__nodes[i].__deb_list; ptr; ptr = ptr->next) {
1272 if (deja) stream <<
" , ";
1274 stream << ptr->key() <<
"=>" << ptr->val();
1288 template <
typename Key,
typename Val >
1291 __table->__safe_iterators.push_back(
1295 template <
typename Key,
typename Val >
1298 if (__table ==
nullptr)
return;
1301 std::vector< HashTableConstIteratorSafe< Key, Val >* >& iter_vect =
1302 __table->__safe_iterators;
1304 auto len = iter_vect.size();
1305 for (
Size i =
Size(0); i < len; ++i) {
1306 if (iter_vect[i] ==
this) {
1307 iter_vect.erase(iter_vect.begin() + i);
1313 template <
typename Key,
typename Val >
1319 template <
typename Key,
typename Val >
1320 template <
typename Alloc >
1328 __insertIntoSafeList();
1330 if (__table->__nb_elements) {
1331 if (__table->__begin_index != std::numeric_limits< Size >::max()) {
1332 __index = __table->__begin_index;
1333 __bucket = __table->__nodes[__index].__end_list;
1336 for (
Size i = __table->__size -
Size(1);; --i) {
1338 if (__table->__nodes[i].__nb_elements) {
1340 __bucket = __table->__nodes[__index].__end_list;
1341 __table->__begin_index = __index;
1349 template <
typename Key,
typename Val >
1350 template <
typename Alloc >
1357 if ((ind_elt ==
Size(0))
1358 && (__table->__begin_index != std::numeric_limits< Size >::max())) {
1360 __bucket = __table->__nodes[__index].__end_list;
1364 if (ind_elt < (__table->__nb_elements >> 1)) {
1366 for (i = __table->__size - 1;; --i) {
1368 if (__table->__nodes[i].__nb_elements) {
1369 if (ind_elt >= __table->__nodes[i].__nb_elements)
1370 ind_elt -= __table->__nodes[i].__nb_elements;
1372 for (__bucket = __table->__nodes[i].__end_list; ind_elt;
1373 --ind_elt, __bucket = __bucket->prev) {}
1383 if (ind_elt >= __table->__nb_elements) {
1385 "Not enough elements in the hashtable");
1389 for (i = 0, ind_elt = __table->__nb_elements - ind_elt - 1;; ++i) {
1390 if (__table->__nodes[i].__nb_elements) {
1391 if (ind_elt >= __table->__nodes[i].__nb_elements)
1392 ind_elt -= __table->__nodes[i].__nb_elements;
1394 for (__bucket = __table->__nodes[i].__deb_list; ind_elt;
1395 --ind_elt, __bucket = __bucket->next) {}
1409 __insertIntoSafeList();
1412 template <
typename Key,
typename Val >
1416 __index{from.__index}, __bucket{from.__bucket}, __next_bucket{
1417 from.__next_bucket} {
1419 if (__table !=
nullptr) { __insertIntoSafeList(); }
1425 template <
typename Key,
typename Val >
1429 __index{from.__index}, __bucket{from.__bucket} {
1431 if (__table !=
nullptr) { __insertIntoSafeList(); }
1437 template <
typename Key,
typename Val >
1440 __table{from.__table},
1441 __index{from.__index}, __bucket{from.__bucket}, __next_bucket{
1442 from.__next_bucket} {
1447 if (__table !=
nullptr) {
1448 std::vector< HashTableConstIteratorSafe< Key, Val >* >& vect =
1449 __table->__safe_iterators;
1451 for (
auto ptr = vect.rbegin(); ptr != vect.rend(); ++ptr) {
1452 if (*ptr == &from) {
1454 from.__table =
nullptr;
1461 template <
typename Key,
typename Val >
1464 Val >::~HashTableConstIteratorSafe() noexcept {
1469 __removeFromSafeList();
1472 template <
typename Key,
typename Val >
1483 if (__table != from.
__table) {
1485 __removeFromSafeList();
1490 if (__table) { __insertIntoSafeList(); }
1500 template <
typename Key,
typename Val >
1511 if (__table != from.
__table) {
1513 __removeFromSafeList();
1518 if (__table) { __insertIntoSafeList(); }
1523 __next_bucket =
nullptr;
1528 template <
typename Key,
typename Val >
1539 if (__table != from.__table) {
1541 __removeFromSafeList();
1543 if (from.__table !=
nullptr) {
1545 std::vector< HashTableConstIteratorSafe< Key, Val >* >& vect =
1546 from.__table->__safe_iterators;
1548 for (
auto ptr = vect.rbegin(); ptr != vect.rend(); ++ptr) {
1549 if (*ptr == &from) {
1556 __table = from.__table;
1557 from.__table =
nullptr;
1560 __index = from.__index;
1561 __bucket = from.__bucket;
1562 __next_bucket = from.__next_bucket;
1567 template <
typename Key,
typename Val >
1570 if (__bucket !=
nullptr)
1571 return __bucket->
key();
1577 template <
typename Key,
typename Val >
1580 if (__bucket !=
nullptr)
1581 return __bucket->
val();
1587 template <
typename Key,
typename Val >
1590 __removeFromSafeList();
1595 __next_bucket =
nullptr;
1601 template <
typename Key,
typename Val >
1605 if (__bucket ==
nullptr) {
1611 __bucket = __next_bucket;
1612 __next_bucket =
nullptr;
1618 if (__bucket->prev) {
1619 __bucket = __bucket->prev;
1629 if (__index ==
Size(0)) {
1639 if (__index >
Size(0)) {
1641 if (__table->__nodes[i].__nb_elements) {
1643 __bucket = __table->__nodes[i].__end_list;
1649 if (__table->__nodes[0].__nb_elements)
1650 __bucket = __table->__nodes[0].__end_list;
1662 template <
typename Key,
typename Val >
1665 if ((nb ==
Size(0)) || (__table ==
nullptr))
return *
this;
1668 if (__bucket ==
nullptr) {
1674 __bucket = __next_bucket;
1675 __next_bucket =
nullptr;
1681 for (; nb && __bucket !=
nullptr; --nb, __bucket = __bucket->prev) {}
1683 if (__bucket !=
nullptr)
return *
this;
1689 for (; __index < __table->__size
1690 && nb >= __table->__nodes[__index].__nb_elements;
1691 nb -= __table->__nodes[__index].__nb_elements, --__index) {}
1697 if (__index >= __table->__size) {
1702 for (__bucket = __table->__nodes[__index].__end_list; nb;
1703 --nb, __bucket = __bucket->prev) {}
1708 template <
typename Key,
typename Val >
1714 template <
typename Key,
typename Val >
1717 return ((__bucket != from.__bucket) || (__index != from.__index));
1720 template <
typename Key,
typename Val >
1723 return ((__bucket == from.__bucket) && (__index == from.__index));
1726 template <
typename Key,
typename Val >
1730 return __bucket->elt();
1736 template <
typename Key,
typename Val >
1742 template <
typename Key,
typename Val >
1751 template <
typename Key,
typename Val >
1757 template <
typename Key,
typename Val >
1758 template <
typename Alloc >
1765 template <
typename Key,
typename Val >
1766 template <
typename Alloc >
1773 template <
typename Key,
typename Val >
1780 template <
typename Key,
typename Val >
1787 template <
typename Key,
typename Val >
1794 template <
typename Key,
typename Val >
1799 template <
typename Key,
typename Val >
1805 template <
typename Key,
typename Val >
1814 template <
typename Key,
typename Val >
1823 template <
typename Key,
typename Val >
1831 template <
typename Key,
typename Val >
1838 template <
typename Key,
typename Val >
1845 template <
typename Key,
typename Val >
1853 template <
typename Key,
typename Val >
1859 template <
typename Key,
typename Val >
1865 template <
typename Key,
typename Val >
1871 template <
typename Key,
typename Val >
1881 template <
typename Key,
typename Val >
1886 template <
typename Key,
typename Val >
1887 template <
typename Alloc >
1894 if (__table->__nb_elements) {
1895 if (__table->__begin_index != std::numeric_limits< Size >::max()) {
1896 __index = __table->__begin_index;
1897 __bucket = __table->__nodes[__index].__end_list;
1900 for (
Size i = __table->__size -
Size(1);; --i) {
1902 if (__table->__nodes[i].__nb_elements) {
1904 __bucket = __table->__nodes[__index].__end_list;
1905 __table->__begin_index = __index;
1913 template <
typename Key,
typename Val >
1914 template <
typename Alloc >
1921 if ((ind_elt ==
Size(0))
1922 && (__table->__begin_index != std::numeric_limits< Size >::max())) {
1924 __bucket = __table->__nodes[__index].__end_list;
1928 if (ind_elt < (__table->__nb_elements >> 1)) {
1930 for (i = __table->__size - 1;; --i) {
1932 if (__table->__nodes[i].__nb_elements) {
1933 if (ind_elt >= __table->__nodes[i].__nb_elements)
1934 ind_elt -= __table->__nodes[i].__nb_elements;
1936 for (__bucket = __table->__nodes[i].__end_list; ind_elt;
1937 --ind_elt, __bucket = __bucket->prev) {}
1947 if (ind_elt >= __table->__nb_elements) {
1949 "Not enough elements in the hashtable");
1953 for (i = 0, ind_elt = __table->__nb_elements - ind_elt - 1;; ++i) {
1954 if (__table->__nodes[i].__nb_elements) {
1955 if (ind_elt >= __table->__nodes[i].__nb_elements)
1956 ind_elt -= __table->__nodes[i].__nb_elements;
1958 for (__bucket = __table->__nodes[i].__deb_list; ind_elt;
1959 --ind_elt, __bucket = __bucket->next) {}
1973 template <
typename Key,
typename Val >
1977 __index{from.__index}, __bucket{from.__bucket} {
1981 template <
typename Key,
typename Val >
1985 __index{from.__index}, __bucket{from.__bucket} {
1989 template <
typename Key,
typename Val >
1995 template <
typename Key,
typename Val >
2003 __index = from.__index;
2004 __bucket = from.__bucket;
2009 template <
typename Key,
typename Val >
2017 __index = from.__index;
2018 __bucket = from.__bucket;
2023 template <
typename Key,
typename Val >
2027 return __bucket->pair.first;
2033 template <
typename Key,
typename Val >
2037 return __bucket->
val();
2043 template <
typename Key,
typename Val >
2050 template <
typename Key,
typename Val >
2054 if (__bucket ==
nullptr)
return *
this;
2058 if (__bucket->prev) {
2059 __bucket = __bucket->prev;
2068 if (__index ==
Size(0)) {
2078 for (
Size i = __index -
Size(1); i; --i) {
2079 if (__table->__nodes[i].__nb_elements) {
2081 __bucket = __table->__nodes[i].__end_list;
2086 if (__table->__nodes[0].__nb_elements)
2087 __bucket = __table->__nodes[0].__end_list;
2098 template <
typename Key,
typename Val >
2101 if ((nb == 0) || (__table ==
nullptr) || (__bucket ==
nullptr))
return *
this;
2105 for (; nb && __bucket !=
nullptr; --nb, __bucket = __bucket->prev) {}
2107 if (__bucket !=
nullptr)
return *
this;
2113 for (; __index < __table->__size
2114 && nb >= __table->__nodes[__index].__nb_elements;
2115 nb -= __table->__nodes[__index].__nb_elements, --__index) {}
2121 if (__index >= __table->__size) {
2126 for (__bucket = __table->__nodes[__index].__end_list; nb;
2127 --nb, __bucket = __bucket->prev) {}
2132 template <
typename Key,
typename Val >
2138 template <
typename Key,
typename Val >
2141 return (__bucket != from.__bucket);
2144 template <
typename Key,
typename Val >
2147 return (__bucket == from.__bucket);
2150 template <
typename Key,
typename Val >
2154 return __bucket->elt();
2160 template <
typename Key,
typename Val >
2166 template <
typename Key,
typename Val >
2175 template <
typename Key,
typename Val >
2181 template <
typename Key,
typename Val >
2182 template <
typename Alloc >
2189 template <
typename Key,
typename Val >
2190 template <
typename Alloc >
2197 template <
typename Key,
typename Val >
2204 template <
typename Key,
typename Val >
2211 template <
typename Key,
typename Val >
2216 template <
typename Key,
typename Val >
2220 return this->__bucket->
val();
2226 template <
typename Key,
typename Val >
2233 template <
typename Key,
typename Val >
2240 template <
typename Key,
typename Val >
2247 template <
typename Key,
typename Val >
2254 template <
typename Key,
typename Val >
2262 template <
typename Key,
typename Val >
2268 template <
typename Key,
typename Val >
2274 template <
typename Key,
typename Val >
2281 template <
typename Key,
typename Val >
void resize(Size new_size)
Changes the number of slots in the 'nodes' vector of the hash table.
unsigned int __hashTableLog2(const Size nb)
Returns the size in bits - 1 necessary to store the smallest power of 2 greater than or equal to nb...
Size __index
The index of the chained list pointed by the iterator in the array of nodes of the hash table...
const HashTable< Key, Val > * __table
The hash table the iterator is pointing to.
Key & key()
Returns the key part of the pair.
bool __resize_policy
Is resizing performed automatically?
Key key_type
Types for STL compliance.
const mapped_type & val() const
Returns the mapped value pointed to by the iterator.
Size __nb_elements
The number of elements in the chained list.
Unsafe Const Iterators for hashtablesHashTableConstIterator provides a fast but unsafe way to parse H...
Size size() const noexcept
Returns the number of elements stored into the hashtable.
Val mapped_type
Types for STL compliance.
const key_type & key() const
Returns the key pointed to by the iterator.
Unsafe Iterators for hashtablesHashTableIterator provides a fast but unsafe way to parse HashTables...
Safe Const Iterators for hashtables.
void erase(Bucket *ptr)
Removes an element from this chained list.
HashTableBucket< Key, Val > * __getBucket() const noexcept
Returns the current iterator's bucket.
bool exists(const Key &key) const
Checks whether there exists an element with a given key in the hashtable.
Size __size
The number of nodes in vector '__nodes'.
void swap(HashTable< LpCol, double > *&a, HashTable< LpCol, double > *&b)
Swap the addresses of two pointers to hashTables.
const Key & key(const Key &key) const
Returns a reference on a given key.
Safe Iterators for hashtables.
std::vector< HashTableList< Key, Val, Alloc > > __nodes
The hash table is represented as a vector of chained lists.
Copyright 2005-2020 Pierre-Henri WUILLEMIN () et Christophe GONZALES () info_at_agrum_dot_org.
BucketAllocator * __alloc_bucket
The allocator of the containing hashTable.
Size __index
the index of the chained list pointed to by the iterator in the array __nodes of the hash table...
const mapped_type & val() const
Returns the mapped value pointed to by the iterator.
The class for generic Hash Tables.
std::pair< const Key, Val > value_type
types for STL compliance
Size __nb_elements
Number of elements of type Val stored in the hash table.
Key key_type
Types for STL compliance.
void __copy(const HashTableList< Key, Val, OtherAlloc > &from)
A function used to perform copies of HashTableLists.
HashTableBucket< Key, Val > * __deb_list
A pointer on the first element of the chained list.
std::ostream & operator<<(std::ostream &output, const BayesNet< GUM_SCALAR > &bn)
Prints map's DAG in output using the Graphviz-dot format.
HashTableBucket< Key, Val > * __bucket
The bucket in the chained list pointed to by the iterator.
Val mapped_type
Types for STL compliance.
Val mapped_type
types for STL compliance
std::pair< const Key, Val > value_type
Types for STL compliance.
std::pair< const Key, Val > value_type
Types for STL compliance.
bool __key_uniqueness_policy
Shall we check for key uniqueness in the table?
LpExpr operator+(LpExpr &&lhs, const T2 &rhs)
Overload of operator + between anything ( a scalar, a variable or an expression ) and anything except...
Val mapped_type
Types for STL compliance.
bool operator==(const TiXmlString &a, const TiXmlString &b)
Val mapped_type
Types for STL compliance.
HashTable< Key, Val >::Bucket * __bucket
The bucket in the chained list pointed to by the iterator.
Val mapped_type
types for STL compliance
Size __begin_index
Returns where the begin index should be.
Val & val()
Returns the value part of the pair.
Size __getIndex() const noexcept
Returns the index in the hashtable's node vector pointed to by the iterator.
std::pair< const Key, Val > value_type
Types for STL compliance.
HashTableBucket< Key, Val > * next
A pointer toward the next bucket in the gum::HashTableList.
LpExpr operator*(const SCALAR &lhs, const LpCol &rhs)
Overload of operator * between a scalar and a variable.
std::pair< const Key, Val > value_type
Types for STL compliance.
const HashTable< Key, Val > * __table
The hash table the iterator is pointing to.
bool operator!=(const TiXmlString &a, const TiXmlString &b)
A chained list used by gum::HashTable.
friend class HashTableList
Friend for faster access.
HashTableBucket< Key, Val > * prev
A pointer toward the previous bucket in the gum::HashTableList.
Bucket * bucket(const Key &key) const
A method to get the bucket corresponding to a given key.
std::size_t Size
In aGrUM, hashed values are unsigned long int.
value_type & insert(const Key &key, const Val &val)
Adds a new element (actually a copy of this element) into the hash table.
HashTableBucket< Key, Val > * __next_bucket
the bucket we should start from when we decide to do a ++.
typename Alloc::template rebind< Bucket >::other BucketAllocator
The Bucket allocator.
Copyright 2005-2020 Pierre-Henri WUILLEMIN () et Christophe GONZALES () info_at_agrum_dot_org.
mapped_type & val()
Returns the mapped value pointed to by the iterator.
std::pair< const Key, Val > & elt()
Returns the pair stored in this bucket.
#define GUM_ERROR(type, msg)
std::pair< const Key, Val > value_type
types for STL compliance