Added hashlib::idict<>

This commit is contained in:
Clifford Wolf 2015-01-18 12:12:33 +01:00
parent 61192514e3
commit 0217ea0fb8
3 changed files with 73 additions and 2 deletions

View File

@ -72,6 +72,20 @@ replacement for std::unordered_set<T>. The main characteristics are:
- dict<K, T> and pool<T> will have the same order of iteration across - dict<K, T> and pool<T> will have the same order of iteration across
all compilers, standard libraries and architectures. all compilers, standard libraries and architectures.
In addition to dict<K, T> and pool<T> there is also an idict<K> that
creates a bijective map from K to the integers. For example:
idict<string, 42> si;
log("%d\n", si("hello")); // will print 42
log("%d\n", si("world")); // will print 43
log("%d\n", si.at("world")); // will print 43
log("%d\n", si.at("dummy")); // will throw exception
log("%s\n", si[42].c_str())); // will print hello
log("%s\n", si[43].c_str())); // will print world
log("%s\n", si[44].c_str())); // will throw exception
It is not possible to remove elements from an idict.
2. Standard STL data types 2. Standard STL data types
In Yosys we use std::vector<T> and std::string whenever applicable. When In Yosys we use std::vector<T> and std::string whenever applicable. When

View File

@ -163,7 +163,11 @@ inline int hashtable_size(int min_size)
throw std::length_error("hash table exceeded maximum size."); throw std::length_error("hash table exceeded maximum size.");
} }
template<typename K, typename T, typename OPS = hash_ops<K>> template<typename K, typename T, typename OPS = hash_ops<K>> class dict;
template<typename K, int offset = 0, typename OPS = hash_ops<K>> class idict;
template<typename K, typename OPS = hash_ops<K>> class pool;
template<typename K, typename T, typename OPS>
class dict class dict
{ {
struct entry_t struct entry_t
@ -485,9 +489,12 @@ public:
const_iterator end() const { return const_iterator(nullptr, -1); } const_iterator end() const { return const_iterator(nullptr, -1); }
}; };
template<typename K, typename OPS = hash_ops<K>> template<typename K, typename OPS>
class pool class pool
{ {
template<typename, int, typename> friend class idict;
protected:
struct entry_t struct entry_t
{ {
K udata; K udata;
@ -783,6 +790,55 @@ public:
const_iterator end() const { return const_iterator(nullptr, -1); } const_iterator end() const { return const_iterator(nullptr, -1); }
}; };
template<typename K, int offset, typename OPS>
class idict
{
pool<K, OPS> database;
public:
typedef typename pool<K, OPS>::const_iterator const_iterator;
int operator()(const K &key)
{
int hash = database.do_hash(key);
int i = database.do_lookup(key, hash);
if (i < 0)
i = database.do_insert(key, hash);
return i + offset;
}
int at(const K &key) const
{
int hash = database.do_hash(key);
int i = database.do_lookup(key, hash);
if (i < 0)
throw std::out_of_range("idict::at()");
return i + offset;
}
int count(const K &key) const
{
int hash = database.do_hash(key);
int i = database.do_lookup(key, hash);
return i < 0 ? 0 : 1;
}
void expect(const K &key, int i)
{
int j = (*this)(key);
if (i != j)
throw std::out_of_range("idict::expect()");
}
const K &operator[](int index) const
{
return database.entries.at(index - offset).udata;
}
const_iterator begin() const { return database.begin(); }
const_iterator end() const { return database.end(); }
};
} /* namespace hashlib */ } /* namespace hashlib */
#endif #endif

View File

@ -148,6 +148,7 @@ using hashlib::hash_cstr_ops;
using hashlib::hash_ptr_ops; using hashlib::hash_ptr_ops;
using hashlib::hash_obj_ops; using hashlib::hash_obj_ops;
using hashlib::dict; using hashlib::dict;
using hashlib::idict;
using hashlib::pool; using hashlib::pool;
namespace RTLIL { namespace RTLIL {