Add lazy_emplace_l which is similar to try_emplace_l

lazy_emplace returns an iterator that is not thread-safe
This commit is contained in:
Brian McKinnon
2020-10-16 20:05:51 -05:00
parent f15998ac30
commit 02127f7bec
2 changed files with 33 additions and 8 deletions
+23 -6
View File
@@ -1424,9 +1424,7 @@ public:
iterator lazy_emplace(const key_arg<K>& key, F&& f) {
auto res = find_or_prepare_insert(key);
if (res.second) {
slot_type* slot = slots_ + res.first;
std::forward<F>(f)(constructor(&alloc_ref(), &slot));
assert(!slot);
lazy_emplace_at(res.first, std::forward<F>(f));
}
return iterator_at(res.first);
}
@@ -1435,13 +1433,18 @@ public:
iterator lazy_emplace_with_hash(const key_arg<K>& key, size_t &hash, F&& f) {
auto res = find_or_prepare_insert(key, hash);
if (res.second) {
slot_type* slot = slots_ + res.first;
std::forward<F>(f)(constructor(&alloc_ref(), &slot));
assert(!slot);
lazy_emplace_at(res.first, std::forward<F>(f));
}
return iterator_at(res.first);
}
template <class K = key_type, class F>
void lazy_emplace_at(size_t& idx, F&& f) {
slot_type* slot = slots_ + idx;
std::forward<F>(f)(constructor(&alloc_ref(), &slot));
assert(!slot);
}
// Extension API: support for heterogeneous keys.
//
@@ -2930,6 +2933,20 @@ public:
return make_iterator(&inner, set.lazy_emplace_with_hash(key, hashval, std::forward<F>(f)));
}
template <class K = key_type, class FExists, class FEmplace>
bool lazy_emplace_l(const key_arg<K>& key, FExists&& fExists, FEmplace&& fEmplace) {
typename Lockable::UniqueLock m;
auto res = this->find_or_prepare_insert(key, m);
typename Inner* inner = std::get<0>(res);
if (std::get<2>(res))
inner->set_.lazy_emplace_at(std::get<1>(res), std::forward<FEmplace>(fEmplace));
else {
auto it = this->iterator_at(inner, inner->set_.iterator_at(std::get<1>(res)));
std::forward<FExists>(fExists)(Policy::value(&*it));
}
return std::get<2>(res);
}
// Extension API: support for heterogeneous keys.
//
// std::unordered_set<std::string> s;