[llvm] MapVector: add C++17-style try_emplace and insert_or_assign (PR #71969)
Zhihao Yuan via llvm-commits
llvm-commits at lists.llvm.org
Fri Nov 10 10:56:25 PST 2023
================
@@ -114,31 +114,56 @@ class MapVector {
return Pos == Map.end()? ValueT() : Vector[Pos->second].second;
}
- std::pair<iterator, bool> insert(const std::pair<KeyT, ValueT> &KV) {
- std::pair<KeyT, typename MapType::mapped_type> Pair = std::make_pair(KV.first, 0);
- std::pair<typename MapType::iterator, bool> Result = Map.insert(Pair);
+ template <typename... Ts>
+ std::pair<iterator, bool> try_emplace(const KeyT &Key, Ts &&...Args) {
+ std::pair<typename MapType::iterator, bool> Result =
+ Map.insert(std::make_pair(Key, 0));
auto &I = Result.first->second;
if (Result.second) {
- Vector.push_back(std::make_pair(KV.first, KV.second));
+ Vector.emplace_back(std::piecewise_construct, std::forward_as_tuple(Key),
+ std::forward_as_tuple(std::forward<Ts>(Args)...));
I = Vector.size() - 1;
return std::make_pair(std::prev(end()), true);
}
return std::make_pair(begin() + I, false);
}
-
- std::pair<iterator, bool> insert(std::pair<KeyT, ValueT> &&KV) {
- // Copy KV.first into the map, then move it into the vector.
- std::pair<KeyT, typename MapType::mapped_type> Pair = std::make_pair(KV.first, 0);
- std::pair<typename MapType::iterator, bool> Result = Map.insert(Pair);
+ template <typename... Ts>
+ std::pair<iterator, bool> try_emplace(KeyT &&Key, Ts &&...Args) {
+ std::pair<typename MapType::iterator, bool> Result =
+ Map.insert(std::make_pair(Key, 0));
auto &I = Result.first->second;
if (Result.second) {
- Vector.push_back(std::move(KV));
+ Vector.emplace_back(std::piecewise_construct,
+ std::forward_as_tuple(static_cast<KeyT &&>(Key)),
+ std::forward_as_tuple(std::forward<Ts>(Args)...));
I = Vector.size() - 1;
return std::make_pair(std::prev(end()), true);
}
return std::make_pair(begin() + I, false);
}
+ std::pair<iterator, bool> insert(const std::pair<KeyT, ValueT> &KV) {
+ return try_emplace(KV.first, KV.second);
+ }
+ std::pair<iterator, bool> insert(std::pair<KeyT, ValueT> &&KV) {
+ return try_emplace(std::move(KV.first), std::move(KV.second));
+ }
+
+ template <typename V>
+ std::pair<iterator, bool> insert_or_assign(const KeyT &Key, V &&Val) {
+ auto Ret = try_emplace(Key, std::forward<V>(Val));
+ if (!Ret.second)
+ Ret.first->second = std::forward<V>(Val);
+ return Ret;
+ }
+ template <typename V>
+ std::pair<iterator, bool> insert_or_assign(KeyT &&Key, V &&Val) {
+ auto Ret = try_emplace(std::move(Key), std::forward<V>(Val));
----------------
lichray wrote:
The standard specified two overloads, then we should try to replicate the behavior. A parameter of forward reference does not replicate the behavior https://godbolt.org/z/59jbT6T9W
https://github.com/llvm/llvm-project/pull/71969
More information about the llvm-commits
mailing list