another synce with SH
This commit is contained in:
		| @@ -17,6 +17,28 @@ | ||||
| //namespace SourceHook | ||||
| //{ | ||||
| //This class is from CSDM for AMX Mod X | ||||
| /* | ||||
| 	A circular, doubly-linked list with one sentinel node | ||||
|  | ||||
| 	Empty: | ||||
| 		m_Head = sentinel | ||||
| 		m_Head->next = m_Head; | ||||
| 		m_Head->prev = m_Head; | ||||
| 	One element: | ||||
| 		m_Head = sentinel | ||||
| 		m_Head->next = node1 | ||||
| 		m_Head->prev = node1 | ||||
| 		node1->next = m_Head | ||||
| 		node1->prev = m_Head | ||||
| 	Two elements: | ||||
| 		m_Head = sentinel | ||||
| 		m_Head->next = node1 | ||||
| 		m_Head->prev = node2 | ||||
| 		node1->next = node2 | ||||
| 		node1->prev = m_Head | ||||
| 		node2->next = m_Head | ||||
| 		node2->prev = node1 | ||||
| */ | ||||
| template <class T> | ||||
| class List | ||||
| { | ||||
| @@ -33,11 +55,13 @@ public: | ||||
| 		ListNode *prev; | ||||
| 	}; | ||||
| private: | ||||
| 	// Initializes the sentinel node. | ||||
| 	// BAIL used malloc instead of new in order to bypass the need for a constructor. | ||||
| 	ListNode *_Initialize() | ||||
| 	{ | ||||
| 		ListNode *n = (ListNode *)malloc(sizeof(ListNode)); | ||||
| 		n->next = NULL; | ||||
| 		n->prev = NULL; | ||||
| 		n->next = n; | ||||
| 		n->prev = n; | ||||
| 		return n; | ||||
| 	} | ||||
| public: | ||||
| @@ -53,6 +77,8 @@ public: | ||||
| 	~List() | ||||
| 	{ | ||||
| 		clear(); | ||||
|  | ||||
| 		// Don't forget to free the sentinel | ||||
| 		if (m_Head) | ||||
| 		{ | ||||
| 			free(m_Head); | ||||
| @@ -63,32 +89,27 @@ public: | ||||
| 	{ | ||||
| 		ListNode *node = new ListNode(obj); | ||||
|  | ||||
| 		if (!m_Head->prev) | ||||
| 		{ | ||||
| 			//link in the node as the first item  | ||||
| 			node->next = m_Head; | ||||
| 			node->prev = m_Head; | ||||
| 			m_Head->prev = node; | ||||
| 			m_Head->next = node; | ||||
| 		} else { | ||||
| 		node->prev = m_Head->prev; | ||||
| 		node->next = m_Head; | ||||
| 		m_Head->prev->next = node; | ||||
| 		m_Head->prev = node; | ||||
| 		} | ||||
|  | ||||
| 		m_Size++; | ||||
| 	} | ||||
| 	size_t size() | ||||
| 	{ | ||||
| 		return m_Size; | ||||
| 	} | ||||
|  | ||||
| 	void clear() | ||||
| 	{ | ||||
| 		ListNode *node = m_Head->next; | ||||
| 		ListNode *temp; | ||||
| 		m_Head->next = NULL; | ||||
| 		m_Head->prev = NULL; | ||||
| 		while (node && node != m_Head) | ||||
| 		m_Head->next = m_Head; | ||||
| 		m_Head->prev = m_Head; | ||||
|  | ||||
| 		// Iterate through the nodes until we find g_Head (the sentinel) again | ||||
| 		while (node != m_Head) | ||||
| 		{ | ||||
| 			temp = node->next; | ||||
| 			delete node; | ||||
| @@ -98,7 +119,7 @@ public: | ||||
| 	} | ||||
| 	bool empty() | ||||
| 	{ | ||||
| 		return (m_Head->next == NULL); | ||||
| 		return (m_Size == 0); | ||||
| 	} | ||||
| 	T & back() | ||||
| 	{ | ||||
| @@ -191,10 +212,7 @@ public: | ||||
| public: | ||||
| 	iterator begin() const | ||||
| 	{ | ||||
| 		if (m_Size) | ||||
| 		return iterator(m_Head->next); | ||||
| 		else | ||||
| 			return iterator(m_Head); | ||||
| 	} | ||||
| 	iterator end() const | ||||
| 	{ | ||||
| @@ -206,30 +224,34 @@ public: | ||||
| 		iterator iter(where); | ||||
| 		iter++; | ||||
|  | ||||
| 		//If we are both the head and tail... | ||||
| 		if (m_Head->next == pNode && m_Head->prev == pNode) | ||||
| 		{ | ||||
| 			m_Head->next = NULL; | ||||
| 			m_Head->prev = NULL; | ||||
| 		} else if (m_Head->next == pNode) { | ||||
| 			//we are only the first | ||||
| 			pNode->next->prev = m_Head; | ||||
| 			m_Head->next = pNode->next; | ||||
| 		} else if (m_Head->prev == pNode) { | ||||
| 			//we are the tail | ||||
| 			pNode->prev->next = m_Head; | ||||
| 			m_Head->prev = pNode->prev; | ||||
| 		} else { | ||||
| 			//middle unlink | ||||
|  | ||||
| 		// Works for all cases: empty list, erasing first element, erasing tail, erasing in the middle... | ||||
| 		pNode->prev->next = pNode->next; | ||||
| 		pNode->next->prev = pNode->prev; | ||||
| 		} | ||||
|  | ||||
| 		delete pNode; | ||||
| 		m_Size--; | ||||
|  | ||||
| 		return iter; | ||||
| 	} | ||||
|  | ||||
| 	iterator insert(iterator where, const T &obj) | ||||
| 	{ | ||||
| 		// Insert obj right before where | ||||
|  | ||||
| 		ListNode *node = new ListNode(obj); | ||||
| 		ListNode *pWhereNode = where.m_This; | ||||
|  | ||||
| 		pWhereNode->prev->next = node; | ||||
| 		node->prev = pWhereNode->prev; | ||||
| 		pWhereNode->prev = node; | ||||
| 		node->next = pWhereNode; | ||||
|  | ||||
| 		m_Size++; | ||||
|  | ||||
| 		return iterator(node); | ||||
| 	} | ||||
|  | ||||
| public: | ||||
| 	void remove(const T & obj) | ||||
| 	{ | ||||
| @@ -254,7 +276,7 @@ public: | ||||
| 		} | ||||
| 		return end(); | ||||
| 	} | ||||
| 	List & operator =(List &src) | ||||
| 	List & operator =(const List &src) | ||||
| 	{ | ||||
| 		clear(); | ||||
| 		iterator iter; | ||||
|   | ||||
| @@ -18,32 +18,38 @@ | ||||
|  | ||||
| //namespace SourceHook | ||||
| //{ | ||||
| 	template <class K> | ||||
| 	int HashFunction(const K & k); | ||||
| template <class K> | ||||
| int HashFunction(const K & k); | ||||
|  | ||||
| 	template <class K> | ||||
| 	int Compare(const K & k1, const K & k2); | ||||
| template <class K> | ||||
| int Compare(const K & k1, const K & k2); | ||||
|  | ||||
| 	/** | ||||
| 	 * This is a tiny, growable hash class. | ||||
| 	 * Meant for quick and dirty dictionaries only! | ||||
| 	 */ | ||||
| 	template <class K, class V>  | ||||
| 	class THash | ||||
| 	{ | ||||
| 	public: | ||||
| /** | ||||
| * This is a tiny, growable hash class. | ||||
| * Meant for quick and dirty dictionaries only! | ||||
| */ | ||||
| template <class K, class V>  | ||||
| class THash | ||||
| { | ||||
| public: | ||||
| 	struct THashNode | ||||
| 	{ | ||||
| 		THashNode(const K & k, const V & v) :  | ||||
| 	key(k), val(v) | ||||
| 	{ | ||||
| 	}; | ||||
| 	THashNode & operator =(const THashNode &other)  | ||||
| 	{  | ||||
| 		key = other.key;  | ||||
| 		val = other.val;  | ||||
| 	}  | ||||
| 	K key; | ||||
| 	V val; | ||||
| 	time_t stamp; | ||||
| 	}; | ||||
| 	typedef List<THashNode *> *	NodePtr; | ||||
| 	public: | ||||
| public: | ||||
| 	class const_iterator; | ||||
| 	THash() : m_Buckets(NULL), m_numBuckets(0), m_percentUsed(0.0f), m_Items(0) | ||||
| 	{ | ||||
| 		_Refactor(); | ||||
| @@ -181,17 +187,26 @@ | ||||
| 		THashNode *pNode = _FindOrInsert(key); | ||||
| 		return pNode->val; | ||||
| 	} | ||||
| 	private: | ||||
| private: | ||||
| 	void _Clear() | ||||
| 	{ | ||||
| 		typename List<THashNode *>::iterator iter, end; | ||||
| 		for (size_t i=0; i<m_numBuckets; i++) | ||||
| 		{ | ||||
| 			if (m_Buckets[i]) | ||||
| 			{ | ||||
| 				end = m_Buckets[i]->end();  | ||||
| 				iter = m_Buckets[i]->begin();  | ||||
| 				while (iter != end)  | ||||
| 				{  | ||||
| 					delete (*iter);  | ||||
| 					iter++;  | ||||
| 				}  | ||||
| 				m_Buckets[i]->clear(); | ||||
| 				delete m_Buckets[i]; | ||||
| 			} | ||||
| 		} | ||||
| 		if (m_Buckets) | ||||
| 			delete [] m_Buckets; | ||||
| 		m_numBuckets = 0; | ||||
| 		m_Items = 0; | ||||
| @@ -272,7 +287,7 @@ | ||||
| 			m_Buckets = temp; | ||||
| 		} | ||||
| 	} | ||||
| 	public: | ||||
| public: | ||||
| 	friend class iterator; | ||||
| 	friend class const_iterator; | ||||
| 	class iterator | ||||
| @@ -414,6 +429,7 @@ | ||||
|  | ||||
| 			iterator tmp = *this; | ||||
| 			++tmp; | ||||
| 			delete (*iter); | ||||
| 			hash->m_Items--; | ||||
| 			hash->m_Buckets[curbucket]->erase(iter); | ||||
| 			*this = tmp; | ||||
| @@ -490,7 +506,7 @@ | ||||
| 		const THash *hash; | ||||
| 		bool end; | ||||
| 	}; | ||||
| 	public: | ||||
| public: | ||||
| 	iterator begin() | ||||
| 	{ | ||||
| 		return iterator(this); | ||||
| @@ -548,12 +564,12 @@ | ||||
| 		} | ||||
| 		return end(); | ||||
| 	} | ||||
| 	private: | ||||
| private: | ||||
| 	NodePtr	*m_Buckets; | ||||
| 	size_t m_numBuckets; | ||||
| 	float m_percentUsed; | ||||
| 	size_t m_Items; | ||||
| 	}; | ||||
| }; | ||||
| //}; | ||||
|  | ||||
| #endif //_INCLUDE_SH_TINYHASH_H_ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user