mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 03:32:29 +00:00 
			
		
		
		
	Added hashlib::idict<>
This commit is contained in:
		
							parent
							
								
									61192514e3
								
							
						
					
					
						commit
						0217ea0fb8
					
				
					 3 changed files with 73 additions and 2 deletions
				
			
		
							
								
								
									
										14
									
								
								CodingReadme
									
										
									
									
									
								
							
							
						
						
									
										14
									
								
								CodingReadme
									
										
									
									
									
								
							|  | @ -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 | ||||||
|  |  | ||||||
|  | @ -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 | ||||||
|  |  | ||||||
|  | @ -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 { | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue