Merge pull request #2295 from epfl-vlsc/firrtl_blackbox_generic_parameters
[yosys.git] / kernel / hashlib.h
index 97fadea0edb0ba099daa1f1b09673d73e078fb09..a523afadd080db4ddfb6d0e3558252bf1cab068f 100644 (file)
@@ -207,6 +207,7 @@ class dict
                entry_t() { }
                entry_t(const std::pair<K, T> &udata, int next) : udata(udata), next(next) { }
                entry_t(std::pair<K, T> &&udata, int next) : udata(std::move(udata)), next(next) { }
+               bool operator<(const entry_t &other) const { return udata.first < other.udata.first; }
        };
 
        std::vector<int> hashtable;
@@ -362,6 +363,7 @@ public:
        public:
                const_iterator() { }
                const_iterator operator++() { index--; return *this; }
+               const_iterator operator+=(int amt) { index -= amt; return *this; }
                bool operator<(const const_iterator &other) const { return index > other.index; }
                bool operator==(const const_iterator &other) const { return index == other.index; }
                bool operator!=(const const_iterator &other) const { return index != other.index; }
@@ -379,6 +381,7 @@ public:
        public:
                iterator() { }
                iterator operator++() { index--; return *this; }
+               iterator operator+=(int amt) { index -= amt; return *this; }
                bool operator<(const iterator &other) const { return index > other.index; }
                bool operator==(const iterator &other) const { return index == other.index; }
                bool operator!=(const iterator &other) const { return index != other.index; }
@@ -615,6 +618,15 @@ public:
                return !operator==(other);
        }
 
+       unsigned int hash() const {
+               unsigned int h = mkhash_init;
+               for (auto &entry : entries) {
+                       h ^= hash_ops<K>::hash(entry.udata.first);
+                       h ^= hash_ops<T>::hash(entry.udata.second);
+               }
+               return h;
+       }
+
        void reserve(size_t n) { entries.reserve(n); }
        size_t size() const { return entries.size(); }
        bool empty() const { return entries.empty(); }
@@ -642,6 +654,7 @@ protected:
 
                entry_t() { }
                entry_t(const K &udata, int next) : udata(udata), next(next) { }
+               entry_t(K &&udata, int next) : udata(std::move(udata)), next(next) { }
        };
 
        std::vector<int> hashtable;
@@ -745,11 +758,24 @@ protected:
        int do_insert(const K &value, int &hash)
        {
                if (hashtable.empty()) {
-                       entries.push_back(entry_t(value, -1));
+                       entries.emplace_back(value, -1);
                        do_rehash();
                        hash = do_hash(value);
                } 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(K &&rvalue, int &hash)
+       {
+               if (hashtable.empty()) {
+                       entries.emplace_back(std::forward<K>(rvalue), -1);
+                       do_rehash();
+                       hash = do_hash(rvalue);
+               } else {
+                       entries.emplace_back(std::forward<K>(rvalue), hashtable[hash]);
                        hashtable[hash] = entries.size() - 1;
                }
                return entries.size() - 1;
@@ -847,6 +873,22 @@ public:
                return std::pair<iterator, bool>(iterator(this, i), true);
        }
 
+       std::pair<iterator, bool> insert(K &&rvalue)
+       {
+               int hash = do_hash(rvalue);
+               int i = do_lookup(rvalue, hash);
+               if (i >= 0)
+                       return std::pair<iterator, bool>(iterator(this, i), false);
+               i = do_insert(std::forward<K>(rvalue), hash);
+               return std::pair<iterator, bool>(iterator(this, i), true);
+       }
+
+       template<typename... Args>
+       std::pair<iterator, bool> emplace(Args&&... args)
+       {
+               return insert(K(std::forward<Args>(args)...));
+       }
+
        int erase(const K &key)
        {
                int hash = do_hash(key);