40 template <
typename Key,
typename Val,
typename Alloc >
41 template <
typename OtherAlloc >
44 Bucket *ptr, *old_ptr{
nullptr}, *new_elt{
nullptr};
54 new_elt = __alloc_bucket->allocate(1);
57 __alloc_bucket->construct(new_elt, *ptr);
59 __alloc_bucket->deallocate(new_elt, 1);
64 new_elt->
prev = old_ptr;
66 if (old_ptr !=
nullptr)
67 old_ptr->
next = new_elt;
74 if (old_ptr !=
nullptr) old_ptr->
next =
nullptr;
83 for (; __deb_list !=
nullptr; __deb_list = new_elt) {
84 new_elt = __deb_list->next;
85 __alloc_bucket->destroy(__deb_list);
86 __alloc_bucket->deallocate(__deb_list, 1);
96 template <
typename Key,
typename Val,
typename Alloc >
99 for (
Bucket* ptr = __deb_list; ptr !=
nullptr; ptr = ptr->
next)
100 if (ptr->key() == key)
return ptr;
105 template <
typename Key,
typename Val,
typename Alloc >
109 if (ptr ==
nullptr) {
114 if (ptr->
prev !=
nullptr)
117 __deb_list = ptr->
next;
119 if (ptr->
next !=
nullptr)
122 __end_list = ptr->
prev;
125 __alloc_bucket->destroy(ptr);
126 __alloc_bucket->deallocate(ptr, 1);
131 template <
typename Key,
typename Val,
typename Alloc >
134 allocator) noexcept :
135 __alloc_bucket{allocator} {}
137 template <
typename Key,
typename Val,
typename Alloc >
144 template <
typename Key,
typename Val,
typename Alloc >
148 __end_list{from.__end_list}, __nb_elements{from.__nb_elements},
149 __alloc_bucket{from.__alloc_bucket} {
150 from.__deb_list =
nullptr;
153 template <
typename Key,
typename Val,
typename Alloc >
155 for (
Bucket *next_ptr, *ptr = __deb_list; ptr !=
nullptr; ptr = next_ptr) {
156 next_ptr = ptr->
next;
157 __alloc_bucket->destroy(ptr);
158 __alloc_bucket->deallocate(ptr, 1);
162 template <
typename Key,
typename Val,
typename Alloc >
164 for (
Bucket *next_ptr, *ptr = __deb_list; ptr !=
nullptr; ptr = next_ptr) {
165 next_ptr = ptr->
next;
166 __alloc_bucket->destroy(ptr);
167 __alloc_bucket->deallocate(ptr, 1);
170 __nb_elements =
Size(0);
171 __deb_list =
nullptr;
172 __end_list =
nullptr;
175 template <
typename Key,
typename Val,
typename Alloc >
187 template <
typename Key,
typename Val,
typename Alloc >
188 template <
typename OtherAlloc >
201 template <
typename Key,
typename Val,
typename Alloc >
207 __end_list = from.__end_list;
208 __nb_elements = from.__nb_elements;
209 from.__deb_list =
nullptr;
215 template <
typename Key,
typename Val,
typename Alloc >
218 __alloc_bucket = &alloc;
221 template <
typename Key,
typename Val,
typename Alloc >
224 if (i >= __nb_elements) {
230 for (ptr = __deb_list; i; --i, ptr = ptr->
next) {}
235 template <
typename Key,
typename Val,
typename Alloc >
238 if (i >= __nb_elements) {
244 for (ptr = __deb_list; i; --i, ptr = ptr->
next) {}
249 template <
typename Key,
typename Val,
typename Alloc >
252 for (
Bucket* ptr = __deb_list; ptr !=
nullptr; ptr = ptr->
next)
253 if (ptr->key() == key)
return ptr->val();
256 "hashtable's chained list contains no element with this key <" 260 template <
typename Key,
typename Val,
typename Alloc >
263 for (
Bucket* ptr = __deb_list; ptr !=
nullptr; ptr = ptr->
next)
264 if (ptr->key() == key)
return ptr->val();
267 "hashtable's chained list contains no element with this key <" 271 template <
typename Key,
typename Val,
typename Alloc >
273 for (
Bucket* ptr = __deb_list; ptr !=
nullptr; ptr = ptr->
next) {
274 if (ptr->key() == key) {
return true; }
280 template <
typename Key,
typename Val,
typename Alloc >
282 return (__nb_elements ==
Size(0));
285 template <
typename Key,
typename Val,
typename Alloc >
289 new_elt->prev =
nullptr;
290 new_elt->next = __deb_list;
292 if (__deb_list !=
nullptr)
293 __deb_list->prev = new_elt;
295 __end_list = new_elt;
297 __deb_list = new_elt;
306 template <
typename Key,
typename Val,
typename Alloc >
307 template <
typename OtherAlloc >
312 GUM_ASSERT(table.
__size == __size);
321 for (
Size j = 0; j < __size; ++j)
324 __nb_elements =
Size(0);
334 template <
typename Key,
typename Val,
typename Alloc >
337 return *(
reinterpret_cast< const iterator*
>(
338 HashTableIteratorStaticEnd::end4Statics()));
341 template <
typename Key,
typename Val,
typename Alloc >
345 HashTableIteratorStaticEnd::constEnd4Statics()));
348 template <
typename Key,
typename Val,
typename Alloc >
352 HashTableIteratorStaticEnd::endSafe4Statics()));
355 template <
typename Key,
typename Val,
typename Alloc >
359 HashTableIteratorStaticEnd::constEndSafe4Statics()));
362 template <
typename Key,
typename Val,
typename Alloc >
367 for (
auto& list : __nodes) {
368 list.setAllocator(__alloc);
372 __hash_func.resize(size);
379 template <
typename Key,
typename Val,
typename Alloc >
382 bool key_uniqueness_pol) :
385 __resize_policy{resize_pol}, __key_uniqueness_policy{key_uniqueness_pol} {
393 template <
typename Key,
typename Val,
typename Alloc >
395 std::initializer_list< std::pair< Key, Val > > list) :
398 std::max< Size >(
Size(2),
Size(list.size()) / 2))} {
406 for (
const auto& elt : list) {
411 template <
typename Key,
typename Val,
typename Alloc >
415 __resize_policy{table.__resize_policy},
416 __key_uniqueness_policy{table.__key_uniqueness_policy},
417 __begin_index{table.__begin_index} {
428 template <
typename Key,
typename Val,
typename Alloc >
429 template <
typename OtherAlloc >
433 __resize_policy{table.__resize_policy},
434 __key_uniqueness_policy{table.__key_uniqueness_policy},
435 __begin_index{table.__begin_index} {
446 template <
typename Key,
typename Val,
typename Alloc >
448 __nodes(
std::move(table.__nodes)), __size{table.__size},
449 __nb_elements{table.__nb_elements}, __hash_func{table.__hash_func},
450 __resize_policy{table.__resize_policy},
451 __key_uniqueness_policy{table.__key_uniqueness_policy},
452 __begin_index{table.__begin_index},
453 __safe_iterators(std::move(table.__safe_iterators)),
454 __alloc(std::move(table.__alloc)) {
460 template <
typename Key,
typename Val,
typename Alloc >
462 const Size len = __safe_iterators.
size();
463 for (
Size i =
Size(0); i < len; ++i)
464 __safe_iterators[i]->clear();
467 template <
typename Key,
typename Val,
typename Alloc >
474 for (
Size i =
Size(0); i < __size; ++i)
477 __nb_elements =
Size(0);
478 __begin_index = std::numeric_limits< Size >::max();
481 template <
typename Key,
typename Val,
typename Alloc >
491 template <
typename Key,
typename Val,
typename Alloc >
506 if (__size != from.
__size) {
507 __nodes.resize(from.
__size);
510 __nodes[i].setAllocator(__alloc);
517 __hash_func.resize(__size);
531 template <
typename Key,
typename Val,
typename Alloc >
532 template <
typename OtherAlloc >
547 if (__size != from.
__size) {
548 __nodes.resize(from.
__size);
551 __nodes[i].setAllocator(__alloc);
558 __hash_func.resize(__size);
572 template <
typename Key,
typename Val,
typename Alloc >
576 if (
this != &table) {
584 __nodes = std::move(table.__nodes);
585 __safe_iterators = std::move(table.__safe_iterators);
586 __alloc = std::move(table.__alloc);
587 __size = table.__size;
588 __nb_elements = table.__nb_elements;
589 __hash_func = table.__hash_func;
590 __resize_policy = table.__resize_policy;
591 __key_uniqueness_policy = table.__key_uniqueness_policy;
592 __begin_index = table.__begin_index;
601 template <
typename Key,
typename Val,
typename Alloc >
607 return *(
reinterpret_cast< const iterator*
>(
608 HashTableIteratorStaticEnd::__HashTableIterEnd));
611 template <
typename Key,
typename Val,
typename Alloc >
618 HashTableIteratorStaticEnd::__HashTableIterEnd));
621 template <
typename Key,
typename Val,
typename Alloc >
628 HashTableIteratorStaticEnd::__HashTableIterEnd));
631 template <
typename Key,
typename Val,
typename Alloc >
635 if (__nb_elements ==
Size(0))
641 template <
typename Key,
typename Val,
typename Alloc >
645 if (__nb_elements ==
Size(0))
651 template <
typename Key,
typename Val,
typename Alloc >
655 if (__nb_elements ==
Size(0))
661 template <
typename Key,
typename Val,
typename Alloc >
668 HashTableIteratorStaticEnd::__HashTableIterEndSafe));
671 template <
typename Key,
typename Val,
typename Alloc >
678 HashTableIteratorStaticEnd::__HashTableIterEndSafe));
681 template <
typename Key,
typename Val,
typename Alloc >
688 HashTableIteratorStaticEnd::__HashTableIterEndSafe));
691 template <
typename Key,
typename Val,
typename Alloc >
695 if (__nb_elements ==
Size(0))
701 template <
typename Key,
typename Val,
typename Alloc >
705 if (__nb_elements ==
Size(0))
711 template <
typename Key,
typename Val,
typename Alloc >
715 if (__nb_elements ==
Size(0))
721 template <
typename Key,
typename Val,
typename Alloc >
723 return __nodes[__hash_func(key)][key];
726 template <
typename Key,
typename Val,
typename Alloc >
729 return __nodes[__hash_func(key)][key];
732 template <
typename Key,
typename Val,
typename Alloc >
734 return __nb_elements;
737 template <
typename Key,
typename Val,
typename Alloc >
742 template <
typename Key,
typename Val,
typename Alloc >
744 return __nodes[__hash_func(key)].
exists(key);
747 template <
typename Key,
typename Val,
typename Alloc >
749 const bool new_policy) noexcept {
750 __resize_policy = new_policy;
753 template <
typename Key,
typename Val,
typename Alloc >
755 return __resize_policy;
758 template <
typename Key,
typename Val,
typename Alloc >
760 const bool new_policy) noexcept {
761 __key_uniqueness_policy = new_policy;
764 template <
typename Key,
typename Val,
typename Alloc >
766 return __key_uniqueness_policy;
769 template <
typename Key,
typename Val,
typename Alloc >
772 new_size = std::max(
Size(2), new_size);
777 new_size =
Size(1) << log_size;
782 if (new_size != __size) {
787 <= new_size * HashTableConst::default_mean_val_by_slot)) {
789 std::vector< HashTableList< Key, Val, Alloc > > new_nodes(new_size);
791 for (
auto& list : new_nodes) {
792 list.setAllocator(__alloc);
796 __hash_func.resize(new_size);
802 for (
Size i =
Size(0); i < __size; ++i) {
803 while ((bucket = __nodes[i].__deb_list) !=
nullptr) {
805 new_hashed_key = __hash_func(bucket->
key());
809 __nodes[i].__deb_list = bucket->
next;
812 new_nodes[new_hashed_key].insert(bucket);
818 __begin_index = std::numeric_limits< Size >::max();
824 for (
auto iter : __safe_iterators) {
826 iter->__index = __hash_func(iter->__bucket->key());
828 iter->__next_bucket =
nullptr;
836 template <
typename Key,
typename Val,
typename Alloc >
839 Size hash_key = __hash_func(bucket->
key());
842 if (__key_uniqueness_policy && __nodes[hash_key].exists(bucket->
key())) {
844 Key k = bucket->
key();
845 __alloc.destroy(bucket);
846 __alloc.deallocate(bucket, 1);
848 "the hashtable contains an element with the same key (" << k
855 && (__nb_elements >= __size * HashTableConst::default_mean_val_by_slot)) {
857 hash_key = __hash_func(bucket->
key());
861 __nodes[hash_key].insert(bucket);
869 if (__begin_index < hash_key) { __begin_index = hash_key; }
872 template <
typename Key,
typename Val,
typename Alloc >
875 Bucket* bucket = __alloc.allocate(1);
878 __alloc.construct(bucket, thekey, theval);
880 __alloc.deallocate(bucket, 1);
885 return bucket->
elt();
888 template <
typename Key,
typename Val,
typename Alloc >
891 Bucket* bucket = __alloc.allocate(1);
894 __alloc.construct(bucket, std::move(thekey), std::move(theval));
896 __alloc.deallocate(bucket, 1);
901 return bucket->
elt();
904 template <
typename Key,
typename Val,
typename Alloc >
907 Bucket* bucket = __alloc.allocate(1);
910 __alloc.construct(bucket, reinterpret_cast< const value_type& >(elt));
912 __alloc.deallocate(bucket, 1);
917 return bucket->
elt();
920 template <
typename Key,
typename Val,
typename Alloc >
923 Bucket* bucket = __alloc.allocate(1);
926 __alloc.construct(bucket, std::move(reinterpret_cast< value_type& >(elt)));
928 __alloc.deallocate(bucket, 1);
933 return bucket->
elt();
936 template <
typename Key,
typename Val,
typename Alloc >
937 template <
typename... Args >
940 Bucket* bucket = __alloc.allocate(1);
943 __alloc.construct(bucket,
945 std::forward< Args >(args)...);
947 __alloc.deallocate(bucket, 1);
952 return bucket->
elt();
955 template <
typename Key,
typename Val,
typename Alloc >
958 const Val& default_value) {
959 Bucket* bucket = __nodes[__hash_func(key)].bucket(key);
961 if (bucket ==
nullptr)
962 return insert(key, default_value).second;
964 return bucket->
val();
967 template <
typename Key,
typename Val,
typename Alloc >
970 Bucket* bucket = __nodes[__hash_func(key)].bucket(key);
972 if (bucket ==
nullptr)
973 return insert(std::move(key), std::move(default_value)).second;
975 return bucket->
val();
978 template <
typename Key,
typename Val,
typename Alloc >
980 Bucket* bucket = __nodes[__hash_func(key)].bucket(key);
982 if (bucket ==
nullptr)
985 bucket->
val() = value;
988 template <
typename Key,
typename Val,
typename Alloc >
991 if (bucket ==
nullptr)
return;
994 for (
auto iter : __safe_iterators) {
995 if (iter->__bucket == bucket) {
997 iter->__next_bucket = iter->__bucket;
998 iter->__bucket =
nullptr;
999 }
else if (iter->__next_bucket == bucket) {
1000 iter->__bucket = bucket;
1002 iter->__next_bucket = iter->__bucket;
1003 iter->__bucket =
nullptr;
1008 __nodes[index].erase(bucket);
1012 if ((index == __begin_index) && __nodes[index].empty()) {
1013 __begin_index = std::numeric_limits< Size >::max();
1017 template <
typename Key,
typename Val,
typename Alloc >
1020 Size hash = __hash_func(key);
1025 __erase(bucket, hash);
1028 template <
typename Key,
typename Val,
typename Alloc >
1033 template <
typename Key,
typename Val,
typename Alloc >
1039 template <
typename Key,
typename Val,
typename Alloc >
1041 for (
auto iter = cbegin(); iter != cend(); ++iter)
1042 if (iter.__bucket->val() == val) {
1043 __erase(iter.__getBucket(), iter.__getIndex());
1048 template <
typename Key,
typename Val,
typename Alloc >
1053 template <
typename Key,
typename Val,
typename Alloc >
1055 for (
auto iter = begin(); iter != end(); ++iter)
1056 if (iter.__bucket->val() == val)
return iter.
key();
1061 template <
typename Key,
typename Val,
typename Alloc >
1064 Bucket* bucket = __nodes[__hash_func(key)].bucket(key);
1066 if (bucket ==
nullptr) {
1070 return bucket->
key();
1073 template <
typename Key,
typename Val,
typename Alloc >
1075 for (
auto iterAll = cbeginSafe(); iterAll != cendSafe(); ++iterAll) {
1076 if (iterAll.__bucket->val() == val) {
1077 __erase(iterAll.__bucket, iterAll.__index);
1082 template <
typename Key,
typename Val,
typename Alloc >
1084 return (__nb_elements ==
Size(0));
1087 template <
typename Key,
typename Val,
typename Alloc >
1088 template <
typename Mount,
typename OtherAlloc >
1090 Mount (*f)(Val),
Size size,
bool resize_pol,
bool key_uniqueness_pol)
const {
1095 if (size == 0) size = std::max(
Size(2), __nb_elements / 2);
1099 size, resize_pol, key_uniqueness_pol);
1102 for (
auto iter = begin(); iter != end(); ++iter) {
1103 table.
insert(iter.key(), f(iter.val()));
1109 template <
typename Key,
typename Val,
typename Alloc >
1110 template <
typename Mount,
typename OtherAlloc >
1112 Mount (*f)(Val&),
Size size,
bool resize_pol,
bool key_uniqueness_pol)
const {
1117 if (size ==
Size(0)) size = std::max(
Size(2), __nb_elements / 2);
1121 size, resize_pol, key_uniqueness_pol);
1124 for (
auto iter = begin(); iter != end(); ++iter) {
1125 table.
insert(iter.key(), f(const_cast< Val& >(iter.val())));
1131 template <
typename Key,
typename Val,
typename Alloc >
1132 template <
typename Mount,
typename OtherAlloc >
1137 bool key_uniqueness_pol)
const {
1142 if (size ==
Size(0)) size = std::max(
Size(2), __nb_elements / 2);
1146 size, resize_pol, key_uniqueness_pol);
1149 for (
auto iter = begin(); iter != end(); ++iter) {
1150 table.
insert(iter.key(), f(iter.val()));
1156 template <
typename Key,
typename Val,
typename Alloc >
1157 template <
typename Mount,
typename OtherAlloc >
1159 const Mount& val,
Size size,
bool resize_pol,
bool key_uniqueness_pol)
const {
1164 if (size ==
Size(0)) size = std::max(
Size(2), __nb_elements / 2);
1168 size, resize_pol, key_uniqueness_pol);
1171 for (
auto iter = begin(); iter != end(); ++iter) {
1172 table.
insert(iter.key(), val);
1178 template <
typename Key,
typename Val,
typename Alloc >
1179 template <
typename OtherAlloc >
1186 for (
auto iter = begin(); iter != end(); ++iter) {
1188 if (iter.val() != from[iter.key()])
return false;
1189 }
catch (
NotFound&) {
return false; }
1195 template <
typename Key,
typename Val,
typename Alloc >
1196 template <
typename OtherAlloc >
1202 template <
typename Key,
typename Val,
typename Alloc >
1209 ptr = ptr->list.next, deja =
true) {
1210 if (deja) stream <<
" , ";
1212 stream << ptr->key() <<
"=>" << ptr->val();
1220 template <
typename Key,
typename Val,
typename Alloc >
1227 ptr = ptr->list.next, deja =
true) {
1228 if (deja) stream <<
" , ";
1230 stream << ptr->key() <<
"=>" << ptr->val();
1238 template <
typename Key,
typename Val,
typename Alloc >
1245 for (
auto ptr = table.
__nodes[i].__deb_list; ptr; ptr = ptr->next) {
1246 if (deja) stream <<
" , ";
1248 stream << ptr->key() <<
"=>" << ptr->val();
1258 template <
typename Key,
typename Val,
typename Alloc >
1265 for (
auto ptr = table.
__nodes[i].__deb_list; ptr; ptr = ptr->next) {
1266 if (deja) stream <<
" , ";
1268 stream << ptr->key() <<
"=>" << ptr->val();
1282 template <
typename Key,
typename Val >
1285 __table->__safe_iterators.push_back(
1289 template <
typename Key,
typename Val >
1292 if (__table ==
nullptr)
return;
1295 std::vector< HashTableConstIteratorSafe< Key, Val >* >& iter_vect =
1296 __table->__safe_iterators;
1298 auto len = iter_vect.size();
1299 for (
Size i =
Size(0); i < len; ++i) {
1300 if (iter_vect[i] ==
this) {
1301 iter_vect.erase(iter_vect.begin() + i);
1307 template <
typename Key,
typename Val >
1313 template <
typename Key,
typename Val >
1314 template <
typename Alloc >
1322 __insertIntoSafeList();
1324 if (__table->__nb_elements) {
1325 if (__table->__begin_index != std::numeric_limits< Size >::max()) {
1326 __index = __table->__begin_index;
1327 __bucket = __table->__nodes[__index].__end_list;
1330 for (
Size i = __table->__size -
Size(1);; --i) {
1332 if (__table->__nodes[i].__nb_elements) {
1334 __bucket = __table->__nodes[__index].__end_list;
1335 __table->__begin_index = __index;
1343 template <
typename Key,
typename Val >
1344 template <
typename Alloc >
1351 if ((ind_elt ==
Size(0))
1352 && (__table->__begin_index != std::numeric_limits< Size >::max())) {
1354 __bucket = __table->__nodes[__index].__end_list;
1358 if (ind_elt < (__table->__nb_elements >> 1)) {
1360 for (i = __table->__size - 1;; --i) {
1362 if (__table->__nodes[i].__nb_elements) {
1363 if (ind_elt >= __table->__nodes[i].__nb_elements)
1364 ind_elt -= __table->__nodes[i].__nb_elements;
1366 for (__bucket = __table->__nodes[i].__end_list; ind_elt;
1367 --ind_elt, __bucket = __bucket->prev) {}
1377 if (ind_elt >= __table->__nb_elements) {
1379 "Not enough elements in the hashtable");
1383 for (i = 0, ind_elt = __table->__nb_elements - ind_elt - 1;; ++i) {
1384 if (__table->__nodes[i].__nb_elements) {
1385 if (ind_elt >= __table->__nodes[i].__nb_elements)
1386 ind_elt -= __table->__nodes[i].__nb_elements;
1388 for (__bucket = __table->__nodes[i].__deb_list; ind_elt;
1389 --ind_elt, __bucket = __bucket->next) {}
1403 __insertIntoSafeList();
1406 template <
typename Key,
typename Val >
1410 __index{from.__index}, __bucket{from.__bucket}, __next_bucket{
1411 from.__next_bucket} {
1413 if (__table !=
nullptr) { __insertIntoSafeList(); }
1419 template <
typename Key,
typename Val >
1423 __index{from.__index}, __bucket{from.__bucket} {
1425 if (__table !=
nullptr) { __insertIntoSafeList(); }
1431 template <
typename Key,
typename Val >
1434 __table{from.__table},
1435 __index{from.__index}, __bucket{from.__bucket}, __next_bucket{
1436 from.__next_bucket} {
1441 if (__table !=
nullptr) {
1442 std::vector< HashTableConstIteratorSafe< Key, Val >* >& vect =
1443 __table->__safe_iterators;
1445 for (
auto ptr = vect.rbegin(); ptr != vect.rend(); ++ptr) {
1446 if (*ptr == &from) {
1448 from.__table =
nullptr;
1455 template <
typename Key,
typename Val >
1458 Val >::~HashTableConstIteratorSafe() noexcept {
1463 __removeFromSafeList();
1466 template <
typename Key,
typename Val >
1476 if (__table != from.
__table) {
1478 __removeFromSafeList();
1483 if (__table) { __insertIntoSafeList(); }
1493 template <
typename Key,
typename Val >
1503 if (__table != from.
__table) {
1505 __removeFromSafeList();
1510 if (__table) { __insertIntoSafeList(); }
1515 __next_bucket =
nullptr;
1520 template <
typename Key,
typename Val >
1531 if (__table != from.__table) {
1533 __removeFromSafeList();
1535 if (from.__table !=
nullptr) {
1537 std::vector< HashTableConstIteratorSafe< Key, Val >* >& vect =
1538 from.__table->__safe_iterators;
1540 for (
auto ptr = vect.rbegin(); ptr != vect.rend(); ++ptr) {
1541 if (*ptr == &from) {
1548 __table = from.__table;
1549 from.__table =
nullptr;
1552 __index = from.__index;
1553 __bucket = from.__bucket;
1554 __next_bucket = from.__next_bucket;
1559 template <
typename Key,
typename Val >
1562 if (__bucket !=
nullptr)
1563 return __bucket->
key();
1569 template <
typename Key,
typename Val >
1572 if (__bucket !=
nullptr)
1573 return __bucket->
val();
1579 template <
typename Key,
typename Val >
1582 __removeFromSafeList();
1587 __next_bucket =
nullptr;
1593 template <
typename Key,
typename Val >
1597 if (__bucket ==
nullptr) {
1603 __bucket = __next_bucket;
1604 __next_bucket =
nullptr;
1610 if (__bucket->prev) {
1611 __bucket = __bucket->prev;
1621 if (__index ==
Size(0)) {
1631 if (__index >
Size(0)) {
1633 if (__table->__nodes[i].__nb_elements) {
1635 __bucket = __table->__nodes[i].__end_list;
1641 if (__table->__nodes[0].__nb_elements)
1642 __bucket = __table->__nodes[0].__end_list;
1654 template <
typename Key,
typename Val >
1657 if ((nb ==
Size(0)) || (__table ==
nullptr))
return *
this;
1660 if (__bucket ==
nullptr) {
1666 __bucket = __next_bucket;
1667 __next_bucket =
nullptr;
1673 for (; nb && __bucket !=
nullptr; --nb, __bucket = __bucket->prev) {}
1675 if (__bucket !=
nullptr)
return *
this;
1681 for (; __index < __table->__size
1682 && nb >= __table->__nodes[__index].__nb_elements;
1683 nb -= __table->__nodes[__index].__nb_elements, --__index) {}
1689 if (__index >= __table->__size) {
1694 for (__bucket = __table->__nodes[__index].__end_list; nb;
1695 --nb, __bucket = __bucket->prev) {}
1700 template <
typename Key,
typename Val >
1706 template <
typename Key,
typename Val >
1710 return ((__bucket != from.__bucket) || (__index != from.__index));
1713 template <
typename Key,
typename Val >
1717 return ((__bucket == from.__bucket) && (__index == from.__index));
1720 template <
typename Key,
typename Val >
1724 return __bucket->elt();
1730 template <
typename Key,
typename Val >
1736 template <
typename Key,
typename Val >
1745 template <
typename Key,
typename Val >
1751 template <
typename Key,
typename Val >
1752 template <
typename Alloc >
1759 template <
typename Key,
typename Val >
1760 template <
typename Alloc >
1767 template <
typename Key,
typename Val >
1774 template <
typename Key,
typename Val >
1781 template <
typename Key,
typename Val >
1788 template <
typename Key,
typename Val >
1793 template <
typename Key,
typename Val >
1799 template <
typename Key,
typename Val >
1807 template <
typename Key,
typename Val >
1815 template <
typename Key,
typename Val >
1822 template <
typename Key,
typename Val >
1829 template <
typename Key,
typename Val >
1836 template <
typename Key,
typename Val >
1844 template <
typename Key,
typename Val >
1850 template <
typename Key,
typename Val >
1856 template <
typename Key,
typename Val >
1862 template <
typename Key,
typename Val >
1872 template <
typename Key,
typename Val >
1877 template <
typename Key,
typename Val >
1878 template <
typename Alloc >
1885 if (__table->__nb_elements) {
1886 if (__table->__begin_index != std::numeric_limits< Size >::max()) {
1887 __index = __table->__begin_index;
1888 __bucket = __table->__nodes[__index].__end_list;
1891 for (
Size i = __table->__size -
Size(1);; --i) {
1893 if (__table->__nodes[i].__nb_elements) {
1895 __bucket = __table->__nodes[__index].__end_list;
1896 __table->__begin_index = __index;
1904 template <
typename Key,
typename Val >
1905 template <
typename Alloc >
1912 if ((ind_elt ==
Size(0))
1913 && (__table->__begin_index != std::numeric_limits< Size >::max())) {
1915 __bucket = __table->__nodes[__index].__end_list;
1919 if (ind_elt < (__table->__nb_elements >> 1)) {
1921 for (i = __table->__size - 1;; --i) {
1923 if (__table->__nodes[i].__nb_elements) {
1924 if (ind_elt >= __table->__nodes[i].__nb_elements)
1925 ind_elt -= __table->__nodes[i].__nb_elements;
1927 for (__bucket = __table->__nodes[i].__end_list; ind_elt;
1928 --ind_elt, __bucket = __bucket->prev) {}
1938 if (ind_elt >= __table->__nb_elements) {
1940 "Not enough elements in the hashtable");
1944 for (i = 0, ind_elt = __table->__nb_elements - ind_elt - 1;; ++i) {
1945 if (__table->__nodes[i].__nb_elements) {
1946 if (ind_elt >= __table->__nodes[i].__nb_elements)
1947 ind_elt -= __table->__nodes[i].__nb_elements;
1949 for (__bucket = __table->__nodes[i].__deb_list; ind_elt;
1950 --ind_elt, __bucket = __bucket->next) {}
1964 template <
typename Key,
typename Val >
1968 __index{from.__index}, __bucket{from.__bucket} {
1972 template <
typename Key,
typename Val >
1976 __index{from.__index}, __bucket{from.__bucket} {
1980 template <
typename Key,
typename Val >
1986 template <
typename Key,
typename Val >
1993 __index = from.__index;
1994 __bucket = from.__bucket;
1999 template <
typename Key,
typename Val >
2006 __index = from.__index;
2007 __bucket = from.__bucket;
2012 template <
typename Key,
typename Val >
2016 return __bucket->pair.first;
2022 template <
typename Key,
typename Val >
2026 return __bucket->
val();
2032 template <
typename Key,
typename Val >
2039 template <
typename Key,
typename Val >
2043 if (__bucket ==
nullptr)
return *
this;
2047 if (__bucket->prev) {
2048 __bucket = __bucket->prev;
2057 if (__index ==
Size(0)) {
2067 for (
Size i = __index -
Size(1); i; --i) {
2068 if (__table->__nodes[i].__nb_elements) {
2070 __bucket = __table->__nodes[i].__end_list;
2075 if (__table->__nodes[0].__nb_elements)
2076 __bucket = __table->__nodes[0].__end_list;
2087 template <
typename Key,
typename Val >
2090 if ((nb == 0) || (__table ==
nullptr) || (__bucket ==
nullptr))
return *
this;
2094 for (; nb && __bucket !=
nullptr; --nb, __bucket = __bucket->prev) {}
2096 if (__bucket !=
nullptr)
return *
this;
2102 for (; __index < __table->__size
2103 && nb >= __table->__nodes[__index].__nb_elements;
2104 nb -= __table->__nodes[__index].__nb_elements, --__index) {}
2110 if (__index >= __table->__size) {
2115 for (__bucket = __table->__nodes[__index].__end_list; nb;
2116 --nb, __bucket = __bucket->prev) {}
2121 template <
typename Key,
typename Val >
2127 template <
typename Key,
typename Val >
2130 return (__bucket != from.__bucket);
2133 template <
typename Key,
typename Val >
2136 return (__bucket == from.__bucket);
2139 template <
typename Key,
typename Val >
2143 return __bucket->elt();
2149 template <
typename Key,
typename Val >
2155 template <
typename Key,
typename Val >
2164 template <
typename Key,
typename Val >
2170 template <
typename Key,
typename Val >
2171 template <
typename Alloc >
2178 template <
typename Key,
typename Val >
2179 template <
typename Alloc >
2186 template <
typename Key,
typename Val >
2193 template <
typename Key,
typename Val >
2200 template <
typename Key,
typename Val >
2205 template <
typename Key,
typename Val >
2209 return this->__bucket->
val();
2215 template <
typename Key,
typename Val >
2222 template <
typename Key,
typename Val >
2229 template <
typename Key,
typename Val >
2236 template <
typename Key,
typename Val >
2243 template <
typename Key,
typename Val >
2251 template <
typename Key,
typename Val >
2257 template <
typename Key,
typename Val >
2263 template <
typename Key,
typename Val >
2270 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.
gum is the global namespace for all aGrUM entities
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.
Class hash tables iterators.
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