From c479fdeb85a3b3b607228a729cc2ead40caab50c Mon Sep 17 00:00:00 2001 From: Alberto Gonzalez Date: Mon, 13 Apr 2020 19:59:29 +0000 Subject: Add `dict` support for rvalue references and C++11 move semantics. --- kernel/hashlib.h | 42 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) (limited to 'kernel') diff --git a/kernel/hashlib.h b/kernel/hashlib.h index e7cb312ed..f15a9d611 100644 --- a/kernel/hashlib.h +++ b/kernel/hashlib.h @@ -314,11 +314,11 @@ class dict int do_insert(const K &key, int &hash) { if (hashtable.empty()) { - entries.push_back(entry_t(std::pair(key, T()), -1)); + entries.emplace_back(std::pair(key, T()), -1); do_rehash(); hash = do_hash(key); } else { - entries.push_back(entry_t(std::pair(key, T()), hashtable[hash])); + entries.emplace_back(std::pair(key, T()), hashtable[hash]); hashtable[hash] = entries.size() - 1; } return entries.size() - 1; @@ -327,11 +327,25 @@ class dict int do_insert(const std::pair &value, int &hash) { if (hashtable.empty()) { - entries.push_back(entry_t(value, -1)); + entries.emplace_back(value, -1); do_rehash(); hash = do_hash(value.first); } else { - entries.push_back(entry_t(value, hashtable[hash])); + entries.emplace_back(value, hashtable[hash]); + hashtable[hash] = entries.size() - 1; + } + return entries.size() - 1; + } + + int do_insert(std::pair &&rvalue, int &hash) + { + if (hashtable.empty()) { + auto key = rvalue.first; + entries.emplace_back(std::forward>(rvalue), -1); + do_rehash(); + hash = do_hash(key); + } else { + entries.emplace_back(std::forward>(rvalue), hashtable[hash]); hashtable[hash] = entries.size() - 1; } return entries.size() - 1; @@ -441,6 +455,26 @@ public: return std::pair(iterator(this, i), true); } + std::pair insert(std::pair &&rvalue) + { + int hash = do_hash(rvalue.first); + int i = do_lookup(rvalue.first, hash); + if (i >= 0) + return std::pair(iterator(this, i), false); + i = do_insert(std::forward>(rvalue), hash); + return std::pair(iterator(this, i), true); + } + + std::pair insert(K const &key, T &&rvalue) + { + int hash = do_hash(key); + int i = do_lookup(key, hash); + if (i >= 0) + return std::pair(iterator(this, i), false); + i = do_insert(std::make_pair(key, std::forward(rvalue)), hash); + return std::pair(iterator(this, i), true); + } + int erase(const K &key) { int hash = do_hash(key); -- cgit v1.2.3 From 5eb1f83d2d8da1f5390ed1a2658793a4e25809ba Mon Sep 17 00:00:00 2001 From: Alberto Gonzalez Date: Wed, 15 Apr 2020 16:22:22 +0000 Subject: Rename overloaded `insert()` to `emplace()` and add overloaded versions for all possible lvalue/rvalue combinationsfor its arguments. --- kernel/hashlib.h | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/hashlib.h b/kernel/hashlib.h index f15a9d611..996bda38e 100644 --- a/kernel/hashlib.h +++ b/kernel/hashlib.h @@ -465,7 +465,17 @@ public: return std::pair(iterator(this, i), true); } - std::pair insert(K const &key, T &&rvalue) + std::pair emplace(K const &key, T const &value) + { + int hash = do_hash(key); + int i = do_lookup(key, hash); + if (i >= 0) + return std::pair(iterator(this, i), false); + i = do_insert(std::make_pair(key, value), hash); + return std::pair(iterator(this, i), true); + } + + std::pair emplace(K const &key, T &&rvalue) { int hash = do_hash(key); int i = do_lookup(key, hash); @@ -475,6 +485,26 @@ public: return std::pair(iterator(this, i), true); } + std::pair emplace(K &&rkey, T const &value) + { + int hash = do_hash(rkey); + int i = do_lookup(rkey, hash); + if (i >= 0) + return std::pair(iterator(this, i), false); + i = do_insert(std::make_pair(std::forward(rkey), value), hash); + return std::pair(iterator(this, i), true); + } + + std::pair emplace(K &&rkey, T &&rvalue) + { + int hash = do_hash(rkey); + int i = do_lookup(rkey, hash); + if (i >= 0) + return std::pair(iterator(this, i), false); + i = do_insert(std::make_pair(std::forward(rkey), std::forward(rvalue)), hash); + return std::pair(iterator(this, i), true); + } + int erase(const K &key) { int hash = do_hash(key); -- cgit v1.2.3