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 >
190 template <
typename Key,
typename Val,
typename Alloc >
191 template <
typename OtherAlloc >
204 template <
typename Key,
typename Val,
typename Alloc >
210 __end_list = from.__end_list;
211 __nb_elements = from.__nb_elements;
212 from.__deb_list =
nullptr;
218 template <
typename Key,
typename Val,
typename Alloc >
221 __alloc_bucket = &alloc;
224 template <
typename Key,
typename Val,
typename Alloc >
227 if (i >= __nb_elements) {
233 for (ptr = __deb_list; i; --i, ptr = ptr->
next) {}
238 template <
typename Key,
typename Val,
typename Alloc >
241 if (i >= __nb_elements) {
247 for (ptr = __deb_list; i; --i, ptr = ptr->
next) {}
252 template <
typename Key,
typename Val,
typename Alloc >
255 for (
Bucket* ptr = __deb_list; ptr !=
nullptr; ptr = ptr->
next)
256 if (ptr->key() == key)
return ptr->val();
259 "hashtable's chained list contains no element with this key <" 263 template <
typename Key,
typename Val,
typename Alloc >
266 for (
Bucket* ptr = __deb_list; ptr !=
nullptr; ptr = ptr->
next)
267 if (ptr->key() == key)
return ptr->val();
270 "hashtable's chained list contains no element with this key <" 274 template <
typename Key,
typename Val,
typename Alloc >
276 for (
Bucket* ptr = __deb_list; ptr !=
nullptr; ptr = ptr->
next) {
277 if (ptr->key() == key) {
return true; }
283 template <
typename Key,
typename Val,
typename Alloc >
285 return (__nb_elements ==
Size(0));
288 template <
typename Key,
typename Val,
typename Alloc >
292 new_elt->prev =
nullptr;
293 new_elt->next = __deb_list;
295 if (__deb_list !=
nullptr)
296 __deb_list->prev = new_elt;
298 __end_list = new_elt;
300 __deb_list = new_elt;
309 template <
typename Key,
typename Val,
typename Alloc >
310 template <
typename OtherAlloc >
315 GUM_ASSERT(table.
__size == __size);
324 for (
Size j = 0; j < __size; ++j)
327 __nb_elements =
Size(0);
337 template <
typename Key,
typename Val,
typename Alloc >
340 return *(
reinterpret_cast< const iterator*
>(
341 HashTableIteratorStaticEnd::end4Statics()));
344 template <
typename Key,
typename Val,
typename Alloc >
348 HashTableIteratorStaticEnd::constEnd4Statics()));
351 template <
typename Key,
typename Val,
typename Alloc >
355 HashTableIteratorStaticEnd::endSafe4Statics()));
358 template <
typename Key,
typename Val,
typename Alloc >
362 HashTableIteratorStaticEnd::constEndSafe4Statics()));
365 template <
typename Key,
typename Val,
typename Alloc >
370 for (
auto& list : __nodes) {
371 list.setAllocator(__alloc);
375 __hash_func.resize(size);
382 template <
typename Key,
typename Val,
typename Alloc >
385 bool key_uniqueness_pol) :
388 __resize_policy{resize_pol}, __key_uniqueness_policy{key_uniqueness_pol} {
396 template <
typename Key,
typename Val,
typename Alloc >
398 std::initializer_list< std::pair< Key, Val > > list) :
401 std::max< Size >(
Size(2),
Size(list.size()) / 2))} {
409 for (
const auto& elt : list) {
414 template <
typename Key,
typename Val,
typename Alloc >
418 __resize_policy{table.__resize_policy},
419 __key_uniqueness_policy{table.__key_uniqueness_policy},
420 __begin_index{table.__begin_index} {
431 template <
typename Key,
typename Val,
typename Alloc >
432 template <
typename OtherAlloc >
436 __resize_policy{table.__resize_policy},
437 __key_uniqueness_policy{table.__key_uniqueness_policy},
438 __begin_index{table.__begin_index} {
449 template <
typename Key,
typename Val,
typename Alloc >
451 __nodes(
std::move(table.__nodes)), __size{table.__size},
452 __nb_elements{table.__nb_elements}, __hash_func{table.__hash_func},
453 __resize_policy{table.__resize_policy},
454 __key_uniqueness_policy{table.__key_uniqueness_policy},
455 __begin_index{table.__begin_index},
456 __safe_iterators(std::move(table.__safe_iterators)),
457 __alloc(std::move(table.__alloc)) {
463 template <
typename Key,
typename Val,
typename Alloc >
465 const Size len = __safe_iterators.
size();
466 for (
Size i =
Size(0); i < len; ++i)
467 __safe_iterators[i]->clear();
470 template <
typename Key,
typename Val,
typename Alloc >
477 for (
Size i =
Size(0); i < __size; ++i)
480 __nb_elements =
Size(0);
481 __begin_index = std::numeric_limits< Size >::max();
484 template <
typename Key,
typename Val,
typename Alloc >
494 template <
typename Key,
typename Val,
typename Alloc >
509 if (__size != from.
__size) {
510 __nodes.resize(from.
__size);
513 __nodes[i].setAllocator(__alloc);
520 __hash_func.resize(__size);
534 template <
typename Key,
typename Val,
typename Alloc >
535 template <
typename OtherAlloc >
550 if (__size != from.
__size) {
551 __nodes.resize(from.
__size);
554 __nodes[i].setAllocator(__alloc);
561 __hash_func.resize(__size);
575 template <
typename Key,
typename Val,
typename Alloc >
579 if (
this != &table) {
587 __nodes = std::move(table.__nodes);
588 __safe_iterators = std::move(table.__safe_iterators);
589 __alloc = std::move(table.__alloc);
590 __size = table.__size;
591 __nb_elements = table.__nb_elements;
592 __hash_func = table.__hash_func;
593 __resize_policy = table.__resize_policy;
594 __key_uniqueness_policy = table.__key_uniqueness_policy;
595 __begin_index = table.__begin_index;
604 template <
typename Key,
typename Val,
typename Alloc >
610 return *(
reinterpret_cast< const iterator*
>(
611 HashTableIteratorStaticEnd::__HashTableIterEnd));
614 template <
typename Key,
typename Val,
typename Alloc >
621 HashTableIteratorStaticEnd::__HashTableIterEnd));
624 template <
typename Key,
typename Val,
typename Alloc >
631 HashTableIteratorStaticEnd::__HashTableIterEnd));
634 template <
typename Key,
typename Val,
typename Alloc >
638 if (__nb_elements ==
Size(0))
644 template <
typename Key,
typename Val,
typename Alloc >
648 if (__nb_elements ==
Size(0))
654 template <
typename Key,
typename Val,
typename Alloc >
658 if (__nb_elements ==
Size(0))
664 template <
typename Key,
typename Val,
typename Alloc >
671 HashTableIteratorStaticEnd::__HashTableIterEndSafe));
674 template <
typename Key,
typename Val,
typename Alloc >
681 HashTableIteratorStaticEnd::__HashTableIterEndSafe));
684 template <
typename Key,
typename Val,
typename Alloc >
691 HashTableIteratorStaticEnd::__HashTableIterEndSafe));
694 template <
typename Key,
typename Val,
typename Alloc >
698 if (__nb_elements ==
Size(0))
704 template <
typename Key,
typename Val,
typename Alloc >
708 if (__nb_elements ==
Size(0))
714 template <
typename Key,
typename Val,
typename Alloc >
718 if (__nb_elements ==
Size(0))
724 template <
typename Key,
typename Val,
typename Alloc >
726 return __nodes[__hash_func(key)][key];
729 template <
typename Key,
typename Val,
typename Alloc >
732 return __nodes[__hash_func(key)][key];
735 template <
typename Key,
typename Val,
typename Alloc >
737 return __nb_elements;
740 template <
typename Key,
typename Val,
typename Alloc >
745 template <
typename Key,
typename Val,
typename Alloc >
747 return __nodes[__hash_func(key)].
exists(key);
750 template <
typename Key,
typename Val,
typename Alloc >
752 const bool new_policy) noexcept {
753 __resize_policy = new_policy;
756 template <
typename Key,
typename Val,
typename Alloc >
758 return __resize_policy;
761 template <
typename Key,
typename Val,
typename Alloc >
763 const bool new_policy) noexcept {
764 __key_uniqueness_policy = new_policy;
767 template <
typename Key,
typename Val,
typename Alloc >
769 return __key_uniqueness_policy;
772 template <
typename Key,
typename Val,
typename Alloc >
775 new_size = std::max(
Size(2), new_size);
780 new_size =
Size(1) << log_size;
785 if (new_size != __size) {
790 <= new_size * HashTableConst::default_mean_val_by_slot)) {
792 std::vector< HashTableList< Key, Val, Alloc > > new_nodes(new_size);
794 for (
auto& list : new_nodes) {
795 list.setAllocator(__alloc);
799 __hash_func.resize(new_size);
805 for (
Size i =
Size(0); i < __size; ++i) {
806 while ((bucket = __nodes[i].__deb_list) !=
nullptr) {
808 new_hashed_key = __hash_func(bucket->
key());
812 __nodes[i].__deb_list = bucket->
next;
815 new_nodes[new_hashed_key].insert(bucket);
821 __begin_index = std::numeric_limits< Size >::max();
827 for (
auto iter : __safe_iterators) {
829 iter->__index = __hash_func(iter->__bucket->key());
831 iter->__next_bucket =
nullptr;
839 template <
typename Key,
typename Val,
typename Alloc >
842 Size hash_key = __hash_func(bucket->
key());
845 if (__key_uniqueness_policy && __nodes[hash_key].exists(bucket->
key())) {
847 Key k = bucket->
key();
848 __alloc.destroy(bucket);
849 __alloc.deallocate(bucket, 1);
851 "the hashtable contains an element with the same key (" << k
858 && (__nb_elements >= __size * HashTableConst::default_mean_val_by_slot)) {
860 hash_key = __hash_func(bucket->
key());
864 __nodes[hash_key].insert(bucket);
872 if (__begin_index < hash_key) { __begin_index = hash_key; }
875 template <
typename Key,
typename Val,
typename Alloc >
878 Bucket* bucket = __alloc.allocate(1);
881 __alloc.construct(bucket, thekey, theval);
883 __alloc.deallocate(bucket, 1);
888 return bucket->
elt();
891 template <
typename Key,
typename Val,
typename Alloc >
894 Bucket* bucket = __alloc.allocate(1);
897 __alloc.construct(bucket, std::move(thekey), std::move(theval));
899 __alloc.deallocate(bucket, 1);
904 return bucket->
elt();
907 template <
typename Key,
typename Val,
typename Alloc >
910 Bucket* bucket = __alloc.allocate(1);
913 __alloc.construct(bucket, reinterpret_cast< const value_type& >(elt));
915 __alloc.deallocate(bucket, 1);
920 return bucket->
elt();
923 template <
typename Key,
typename Val,
typename Alloc >
926 Bucket* bucket = __alloc.allocate(1);
929 __alloc.construct(bucket, std::move(reinterpret_cast< value_type& >(elt)));
931 __alloc.deallocate(bucket, 1);
936 return bucket->
elt();
939 template <
typename Key,
typename Val,
typename Alloc >
940 template <
typename... Args >
943 Bucket* bucket = __alloc.allocate(1);
946 __alloc.construct(bucket,
948 std::forward< Args >(args)...);
950 __alloc.deallocate(bucket, 1);
955 return bucket->
elt();
958 template <
typename Key,
typename Val,
typename Alloc >
961 const Val& default_value) {
962 Bucket* bucket = __nodes[__hash_func(key)].bucket(key);
964 if (bucket ==
nullptr)
965 return insert(key, default_value).second;
967 return bucket->
val();
970 template <
typename Key,
typename Val,
typename Alloc >
973 Bucket* bucket = __nodes[__hash_func(key)].bucket(key);
975 if (bucket ==
nullptr)
976 return insert(std::move(key), std::move(default_value)).second;
978 return bucket->
val();
981 template <
typename Key,
typename Val,
typename Alloc >
983 Bucket* bucket = __nodes[__hash_func(key)].bucket(key);
985 if (bucket ==
nullptr)
988 bucket->
val() = value;
991 template <
typename Key,
typename Val,
typename Alloc >
994 if (bucket ==
nullptr)
return;
997 for (
auto iter : __safe_iterators) {
998 if (iter->__bucket == bucket) {
1000 iter->__next_bucket = iter->__bucket;
1001 iter->__bucket =
nullptr;
1002 }
else if (iter->__next_bucket == bucket) {
1003 iter->__bucket = bucket;
1005 iter->__next_bucket = iter->__bucket;
1006 iter->__bucket =
nullptr;
1011 __nodes[index].erase(bucket);
1015 if ((index == __begin_index) && __nodes[index].empty()) {
1016 __begin_index = std::numeric_limits< Size >::max();
1020 template <
typename Key,
typename Val,
typename Alloc >
1023 Size hash = __hash_func(key);
1028 __erase(bucket, hash);
1031 template <
typename Key,
typename Val,
typename Alloc >
1036 template <
typename Key,
typename Val,
typename Alloc >
1042 template <
typename Key,
typename Val,
typename Alloc >
1044 for (
auto iter = cbegin(); iter != cend(); ++iter)
1045 if (iter.__bucket->val() == val) {
1046 __erase(iter.__getBucket(), iter.__getIndex());
1051 template <
typename Key,
typename Val,
typename Alloc >
1056 template <
typename Key,
typename Val,
typename Alloc >
1058 for (
auto iter = begin(); iter != end(); ++iter)
1059 if (iter.__bucket->val() == val)
return iter.
key();
1064 template <
typename Key,
typename Val,
typename Alloc >
1067 Bucket* bucket = __nodes[__hash_func(key)].bucket(key);
1069 if (bucket ==
nullptr) {
1073 return bucket->
key();
1076 template <
typename Key,
typename Val,
typename Alloc >
1078 for (
auto iterAll = cbeginSafe(); iterAll != cendSafe(); ++iterAll) {
1079 if (iterAll.__bucket->val() == val) {
1080 __erase(iterAll.__bucket, iterAll.__index);
1085 template <
typename Key,
typename Val,
typename Alloc >
1087 return (__nb_elements ==
Size(0));
1090 template <
typename Key,
typename Val,
typename Alloc >
1091 template <
typename Mount,
typename OtherAlloc >
1093 Mount (*f)(Val),
Size size,
bool resize_pol,
bool key_uniqueness_pol)
const {
1098 if (size == 0) size = std::max(
Size(2), __nb_elements / 2);
1102 size, resize_pol, key_uniqueness_pol);
1105 for (
auto iter = begin(); iter != end(); ++iter) {
1106 table.
insert(iter.key(), f(iter.val()));
1112 template <
typename Key,
typename Val,
typename Alloc >
1113 template <
typename Mount,
typename OtherAlloc >
1115 Mount (*f)(Val&),
Size size,
bool resize_pol,
bool key_uniqueness_pol)
const {
1120 if (size ==
Size(0)) size = std::max(
Size(2), __nb_elements / 2);
1124 size, resize_pol, key_uniqueness_pol);
1127 for (
auto iter = begin(); iter != end(); ++iter) {
1128 table.
insert(iter.key(), f(const_cast< Val& >(iter.val())));
1134 template <
typename Key,
typename Val,
typename Alloc >
1135 template <
typename Mount,
typename OtherAlloc >
1140 bool key_uniqueness_pol)
const {
1145 if (size ==
Size(0)) size = std::max(
Size(2), __nb_elements / 2);
1149 size, resize_pol, key_uniqueness_pol);
1152 for (
auto iter = begin(); iter != end(); ++iter) {
1153 table.
insert(iter.key(), f(iter.val()));
1159 template <
typename Key,
typename Val,
typename Alloc >
1160 template <
typename Mount,
typename OtherAlloc >
1162 const Mount& val,
Size size,
bool resize_pol,
bool key_uniqueness_pol)
const {
1167 if (size ==
Size(0)) size = std::max(
Size(2), __nb_elements / 2);
1171 size, resize_pol, key_uniqueness_pol);
1174 for (
auto iter = begin(); iter != end(); ++iter) {
1175 table.
insert(iter.key(), val);
1181 template <
typename Key,
typename Val,
typename Alloc >
1182 template <
typename OtherAlloc >
1189 for (
auto iter = begin(); iter != end(); ++iter) {
1191 if (iter.val() != from[iter.key()])
return false;
1192 }
catch (
NotFound&) {
return false; }
1198 template <
typename Key,
typename Val,
typename Alloc >
1199 template <
typename OtherAlloc >
1205 template <
typename Key,
typename Val,
typename Alloc >
1212 ptr = ptr->list.next, deja =
true) {
1213 if (deja) stream <<
" , ";
1215 stream << ptr->key() <<
"=>" << ptr->val();
1223 template <
typename Key,
typename Val,
typename Alloc >
1230 ptr = ptr->list.next, deja =
true) {
1231 if (deja) stream <<
" , ";
1233 stream << ptr->key() <<
"=>" << ptr->val();
1241 template <
typename Key,
typename Val,
typename Alloc >
1248 for (
auto ptr = table.
__nodes[i].__deb_list; ptr; ptr = ptr->next) {
1249 if (deja) stream <<
" , ";
1251 stream << ptr->key() <<
"=>" << ptr->val();
1261 template <
typename Key,
typename Val,
typename Alloc >
1268 for (
auto ptr = table.
__nodes[i].__deb_list; ptr; ptr = ptr->next) {
1269 if (deja) stream <<
" , ";
1271 stream << ptr->key() <<
"=>" << ptr->val();
1285 template <
typename Key,
typename Val >
1288 __table->__safe_iterators.push_back(
1292 template <
typename Key,
typename Val >
1295 if (__table ==
nullptr)
return;
1298 std::vector< HashTableConstIteratorSafe< Key, Val >* >& iter_vect =
1299 __table->__safe_iterators;
1301 auto len = iter_vect.size();
1302 for (
Size i =
Size(0); i < len; ++i) {
1303 if (iter_vect[i] ==
this) {
1304 iter_vect.erase(iter_vect.begin() + i);
1310 template <
typename Key,
typename Val >
1316 template <
typename Key,
typename Val >
1317 template <
typename Alloc >
1325 __insertIntoSafeList();
1327 if (__table->__nb_elements) {
1328 if (__table->__begin_index != std::numeric_limits< Size >::max()) {
1329 __index = __table->__begin_index;
1330 __bucket = __table->__nodes[__index].__end_list;
1333 for (
Size i = __table->__size -
Size(1);; --i) {
1335 if (__table->__nodes[i].__nb_elements) {
1337 __bucket = __table->__nodes[__index].__end_list;
1338 __table->__begin_index = __index;
1346 template <
typename Key,
typename Val >
1347 template <
typename Alloc >
1354 if ((ind_elt ==
Size(0))
1355 && (__table->__begin_index != std::numeric_limits< Size >::max())) {
1357 __bucket = __table->__nodes[__index].__end_list;
1361 if (ind_elt < (__table->__nb_elements >> 1)) {
1363 for (i = __table->__size - 1;; --i) {
1365 if (__table->__nodes[i].__nb_elements) {
1366 if (ind_elt >= __table->__nodes[i].__nb_elements)
1367 ind_elt -= __table->__nodes[i].__nb_elements;
1369 for (__bucket = __table->__nodes[i].__end_list; ind_elt;
1370 --ind_elt, __bucket = __bucket->prev) {}
1380 if (ind_elt >= __table->__nb_elements) {
1382 "Not enough elements in the hashtable");
1386 for (i = 0, ind_elt = __table->__nb_elements - ind_elt - 1;; ++i) {
1387 if (__table->__nodes[i].__nb_elements) {
1388 if (ind_elt >= __table->__nodes[i].__nb_elements)
1389 ind_elt -= __table->__nodes[i].__nb_elements;
1391 for (__bucket = __table->__nodes[i].__deb_list; ind_elt;
1392 --ind_elt, __bucket = __bucket->next) {}
1406 __insertIntoSafeList();
1409 template <
typename Key,
typename Val >
1413 __index{from.__index}, __bucket{from.__bucket}, __next_bucket{
1414 from.__next_bucket} {
1416 if (__table !=
nullptr) { __insertIntoSafeList(); }
1422 template <
typename Key,
typename Val >
1426 __index{from.__index}, __bucket{from.__bucket} {
1428 if (__table !=
nullptr) { __insertIntoSafeList(); }
1434 template <
typename Key,
typename Val >
1437 __table{from.__table},
1438 __index{from.__index}, __bucket{from.__bucket}, __next_bucket{
1439 from.__next_bucket} {
1444 if (__table !=
nullptr) {
1445 std::vector< HashTableConstIteratorSafe< Key, Val >* >& vect =
1446 __table->__safe_iterators;
1448 for (
auto ptr = vect.rbegin(); ptr != vect.rend(); ++ptr) {
1449 if (*ptr == &from) {
1451 from.__table =
nullptr;
1458 template <
typename Key,
typename Val >
1461 Val >::~HashTableConstIteratorSafe() noexcept {
1466 __removeFromSafeList();
1469 template <
typename Key,
typename Val >
1479 if (__table != from.
__table) {
1481 __removeFromSafeList();
1486 if (__table) { __insertIntoSafeList(); }
1496 template <
typename Key,
typename Val >
1506 if (__table != from.
__table) {
1508 __removeFromSafeList();
1513 if (__table) { __insertIntoSafeList(); }
1518 __next_bucket =
nullptr;
1523 template <
typename Key,
typename Val >
1534 if (__table != from.__table) {
1536 __removeFromSafeList();
1538 if (from.__table !=
nullptr) {
1540 std::vector< HashTableConstIteratorSafe< Key, Val >* >& vect =
1541 from.__table->__safe_iterators;
1543 for (
auto ptr = vect.rbegin(); ptr != vect.rend(); ++ptr) {
1544 if (*ptr == &from) {
1551 __table = from.__table;
1552 from.__table =
nullptr;
1555 __index = from.__index;
1556 __bucket = from.__bucket;
1557 __next_bucket = from.__next_bucket;
1562 template <
typename Key,
typename Val >
1565 if (__bucket !=
nullptr)
1566 return __bucket->
key();
1572 template <
typename Key,
typename Val >
1575 if (__bucket !=
nullptr)
1576 return __bucket->
val();
1582 template <
typename Key,
typename Val >
1585 __removeFromSafeList();
1590 __next_bucket =
nullptr;
1596 template <
typename Key,
typename Val >
1600 if (__bucket ==
nullptr) {
1606 __bucket = __next_bucket;
1607 __next_bucket =
nullptr;
1613 if (__bucket->prev) {
1614 __bucket = __bucket->prev;
1624 if (__index ==
Size(0)) {
1634 if (__index >
Size(0)) {
1636 if (__table->__nodes[i].__nb_elements) {
1638 __bucket = __table->__nodes[i].__end_list;
1644 if (__table->__nodes[0].__nb_elements)
1645 __bucket = __table->__nodes[0].__end_list;
1657 template <
typename Key,
typename Val >
1660 if ((nb ==
Size(0)) || (__table ==
nullptr))
return *
this;
1663 if (__bucket ==
nullptr) {
1669 __bucket = __next_bucket;
1670 __next_bucket =
nullptr;
1676 for (; nb && __bucket !=
nullptr; --nb, __bucket = __bucket->prev) {}
1678 if (__bucket !=
nullptr)
return *
this;
1684 for (; __index < __table->__size
1685 && nb >= __table->__nodes[__index].__nb_elements;
1686 nb -= __table->__nodes[__index].__nb_elements, --__index) {}
1692 if (__index >= __table->__size) {
1697 for (__bucket = __table->__nodes[__index].__end_list; nb;
1698 --nb, __bucket = __bucket->prev) {}
1703 template <
typename Key,
typename Val >
1709 template <
typename Key,
typename Val >
1713 return ((__bucket != from.__bucket) || (__index != from.__index));
1716 template <
typename Key,
typename Val >
1720 return ((__bucket == from.__bucket) && (__index == from.__index));
1723 template <
typename Key,
typename Val >
1727 return __bucket->elt();
1733 template <
typename Key,
typename Val >
1739 template <
typename Key,
typename Val >
1748 template <
typename Key,
typename Val >
1754 template <
typename Key,
typename Val >
1755 template <
typename Alloc >
1762 template <
typename Key,
typename Val >
1763 template <
typename Alloc >
1770 template <
typename Key,
typename Val >
1777 template <
typename Key,
typename Val >
1784 template <
typename Key,
typename Val >
1791 template <
typename Key,
typename Val >
1796 template <
typename Key,
typename Val >
1802 template <
typename Key,
typename Val >
1810 template <
typename Key,
typename Val >
1818 template <
typename Key,
typename Val >
1825 template <
typename Key,
typename Val >
1832 template <
typename Key,
typename Val >
1839 template <
typename Key,
typename Val >
1847 template <
typename Key,
typename Val >
1853 template <
typename Key,
typename Val >
1859 template <
typename Key,
typename Val >
1865 template <
typename Key,
typename Val >
1875 template <
typename Key,
typename Val >
1880 template <
typename Key,
typename Val >
1881 template <
typename Alloc >
1888 if (__table->__nb_elements) {
1889 if (__table->__begin_index != std::numeric_limits< Size >::max()) {
1890 __index = __table->__begin_index;
1891 __bucket = __table->__nodes[__index].__end_list;
1894 for (
Size i = __table->__size -
Size(1);; --i) {
1896 if (__table->__nodes[i].__nb_elements) {
1898 __bucket = __table->__nodes[__index].__end_list;
1899 __table->__begin_index = __index;
1907 template <
typename Key,
typename Val >
1908 template <
typename Alloc >
1915 if ((ind_elt ==
Size(0))
1916 && (__table->__begin_index != std::numeric_limits< Size >::max())) {
1918 __bucket = __table->__nodes[__index].__end_list;
1922 if (ind_elt < (__table->__nb_elements >> 1)) {
1924 for (i = __table->__size - 1;; --i) {
1926 if (__table->__nodes[i].__nb_elements) {
1927 if (ind_elt >= __table->__nodes[i].__nb_elements)
1928 ind_elt -= __table->__nodes[i].__nb_elements;
1930 for (__bucket = __table->__nodes[i].__end_list; ind_elt;
1931 --ind_elt, __bucket = __bucket->prev) {}
1941 if (ind_elt >= __table->__nb_elements) {
1943 "Not enough elements in the hashtable");
1947 for (i = 0, ind_elt = __table->__nb_elements - ind_elt - 1;; ++i) {
1948 if (__table->__nodes[i].__nb_elements) {
1949 if (ind_elt >= __table->__nodes[i].__nb_elements)
1950 ind_elt -= __table->__nodes[i].__nb_elements;
1952 for (__bucket = __table->__nodes[i].__deb_list; ind_elt;
1953 --ind_elt, __bucket = __bucket->next) {}
1967 template <
typename Key,
typename Val >
1971 __index{from.__index}, __bucket{from.__bucket} {
1975 template <
typename Key,
typename Val >
1979 __index{from.__index}, __bucket{from.__bucket} {
1983 template <
typename Key,
typename Val >
1989 template <
typename Key,
typename Val >
1996 __index = from.__index;
1997 __bucket = from.__bucket;
2002 template <
typename Key,
typename Val >
2009 __index = from.__index;
2010 __bucket = from.__bucket;
2015 template <
typename Key,
typename Val >
2019 return __bucket->pair.first;
2025 template <
typename Key,
typename Val >
2029 return __bucket->
val();
2035 template <
typename Key,
typename Val >
2042 template <
typename Key,
typename Val >
2046 if (__bucket ==
nullptr)
return *
this;
2050 if (__bucket->prev) {
2051 __bucket = __bucket->prev;
2060 if (__index ==
Size(0)) {
2070 for (
Size i = __index -
Size(1); i; --i) {
2071 if (__table->__nodes[i].__nb_elements) {
2073 __bucket = __table->__nodes[i].__end_list;
2078 if (__table->__nodes[0].__nb_elements)
2079 __bucket = __table->__nodes[0].__end_list;
2090 template <
typename Key,
typename Val >
2093 if ((nb == 0) || (__table ==
nullptr) || (__bucket ==
nullptr))
return *
this;
2097 for (; nb && __bucket !=
nullptr; --nb, __bucket = __bucket->prev) {}
2099 if (__bucket !=
nullptr)
return *
this;
2105 for (; __index < __table->__size
2106 && nb >= __table->__nodes[__index].__nb_elements;
2107 nb -= __table->__nodes[__index].__nb_elements, --__index) {}
2113 if (__index >= __table->__size) {
2118 for (__bucket = __table->__nodes[__index].__end_list; nb;
2119 --nb, __bucket = __bucket->prev) {}
2124 template <
typename Key,
typename Val >
2130 template <
typename Key,
typename Val >
2133 return (__bucket != from.__bucket);
2136 template <
typename Key,
typename Val >
2139 return (__bucket == from.__bucket);
2142 template <
typename Key,
typename Val >
2146 return __bucket->elt();
2152 template <
typename Key,
typename Val >
2158 template <
typename Key,
typename Val >
2167 template <
typename Key,
typename Val >
2173 template <
typename Key,
typename Val >
2174 template <
typename Alloc >
2181 template <
typename Key,
typename Val >
2182 template <
typename Alloc >
2189 template <
typename Key,
typename Val >
2196 template <
typename Key,
typename Val >
2203 template <
typename Key,
typename Val >
2208 template <
typename Key,
typename Val >
2212 return this->__bucket->
val();
2218 template <
typename Key,
typename Val >
2225 template <
typename Key,
typename Val >
2232 template <
typename Key,
typename Val >
2239 template <
typename Key,
typename Val >
2246 template <
typename Key,
typename Val >
2254 template <
typename Key,
typename Val >
2260 template <
typename Key,
typename Val >
2266 template <
typename Key,
typename Val >
2273 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-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
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-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
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