diff --git a/parallel_hashmap/phmap.h b/parallel_hashmap/phmap.h index d3ab145..653ae5e 100644 --- a/parallel_hashmap/phmap.h +++ b/parallel_hashmap/phmap.h @@ -1359,6 +1359,11 @@ public: std::forward(args)...); } + template ::value, int>::type = 0> + std::pair emplace_with_hash(size_t hashval, Args&&... args) { + return PolicyTraits::apply(EmplaceDecomposableHashval{*this, hashval}, std::forward(args)...); + } + // This overload kicks in if we cannot deduce the key from args. It constructs // value_type unconditionally and then either moves it into the table or // destroys. @@ -1374,11 +1379,26 @@ public: return PolicyTraits::apply(InsertSlot{*this, std::move(*slot)}, elem); } + template ::value, int>::type = 0> + std::pair emplace_with_hash(size_t hashval, Args&&... args) { + typename std::aligned_storage::type raw; + slot_type* slot = reinterpret_cast(&raw); + + PolicyTraits::construct(&alloc_ref(), slot, std::forward(args)...); + const auto& elem = PolicyTraits::element(slot); + return PolicyTraits::apply(InsertSlotWithHash{*this, std::move(*slot), hashval}, elem); + } + template iterator emplace_hint(const_iterator, Args&&... args) { return emplace(std::forward(args)...).first; } + template + iterator emplace_hint_with_hash(size_t hashval, const_iterator, Args&&... args) { + return emplace_with_hash(hashval, std::forward(args)...).first; + } + // Extension API: support for lazy emplace. // // Looks up key in the table. If found, returns the iterator to the element. @@ -1791,6 +1811,15 @@ private: raw_hash_set& s; }; + struct EmplaceDecomposableHashval { + template + std::pair operator()(const K& key, Args&&... args) const { + return s.emplace_decomposable(key, hashval, std::forward(args)...); + } + raw_hash_set& s; + size_t hashval; + }; + template struct InsertSlot { @@ -4431,6 +4460,8 @@ public: using Base::insert; using Base::emplace; using Base::emplace_hint; + using Base::emplace_with_hash; + using Base::emplace_hint_with_hash; using Base::extract; using Base::merge; using Base::swap;