Port code to AMTL (#427)
* Remove CQueue * Remove duplicated files * Move sh_tinyhash to public/ * Remove sm_queue Make NVault use of ke::Deque * Remove sh_string (unused) * Remove CList dependency from CTask * Remove CList dependency from CEvent * Remove CList dependency from modules' functions * Remove CList dependency ForceObject * Remove CList dependency Player Auth * Remove left CList dependencies * Fix msvc project files * Update AMTL * Use InlineList for CScript * Use InlineList for CModule * Use Vector for Player Auth
This commit is contained in:
committed by
Vincent Herbet
parent
2d049b7ff3
commit
123246cc84
Submodule public/amtl updated: b0550fd444...c91e8560fb
@ -1,367 +0,0 @@
|
||||
/* ======== SourceMM ========
|
||||
* Copyright (C) 2004-2005 Metamod:Source Development Team
|
||||
* No warranties of any kind
|
||||
*
|
||||
* License: zlib/libpng
|
||||
*
|
||||
* Author(s): David "BAILOPAN" Anderson
|
||||
* ============================
|
||||
*/
|
||||
|
||||
/* AMX Mod X
|
||||
*
|
||||
* by the AMX Mod X Development Team
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_CSTRING_H
|
||||
#define _INCLUDE_CSTRING_H
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
//namespace SourceHook
|
||||
//{
|
||||
class String
|
||||
{
|
||||
public:
|
||||
String()
|
||||
{
|
||||
v = NULL;
|
||||
a_size = 0;
|
||||
//assign("");
|
||||
}
|
||||
|
||||
~String()
|
||||
{
|
||||
if (v)
|
||||
delete [] v;
|
||||
}
|
||||
|
||||
String(const char *src)
|
||||
{
|
||||
v = NULL;
|
||||
a_size = 0;
|
||||
assign(src);
|
||||
}
|
||||
|
||||
String(const String &src)
|
||||
{
|
||||
v = NULL;
|
||||
a_size = 0;
|
||||
assign(src.c_str());
|
||||
}
|
||||
|
||||
const char *c_str() { return v?v:""; }
|
||||
|
||||
const char *c_str() const { return v?v:""; }
|
||||
|
||||
void append(const char *t)
|
||||
{
|
||||
Grow(size() + strlen(t) + 1);
|
||||
strcat(v, t);
|
||||
}
|
||||
|
||||
void append(const char c)
|
||||
{
|
||||
size_t len = size();
|
||||
Grow(len + 2);
|
||||
v[len] = c;
|
||||
v[len + 1] = '\0';
|
||||
}
|
||||
|
||||
void append(String &d)
|
||||
{
|
||||
append(d.c_str());
|
||||
}
|
||||
|
||||
void assign(const String &src)
|
||||
{
|
||||
assign(src.c_str());
|
||||
}
|
||||
|
||||
void assign(const char *d)
|
||||
{
|
||||
if (!d)
|
||||
{
|
||||
clear();
|
||||
} else {
|
||||
Grow(strlen(d) + 1, false);
|
||||
strcpy(v, d);
|
||||
}
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
if (v)
|
||||
v[0] = '\0';
|
||||
}
|
||||
|
||||
int compare (const char *d)
|
||||
{
|
||||
if (!v)
|
||||
return strcmp("", d);
|
||||
else
|
||||
return strcmp(v, d);
|
||||
}
|
||||
|
||||
//Added this for amxx inclusion
|
||||
bool empty()
|
||||
{
|
||||
if (!v)
|
||||
return true;
|
||||
|
||||
if (v[0] == '\0')
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t size()
|
||||
{
|
||||
if (v)
|
||||
return strlen(v);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
int find(const char c, int index = 0)
|
||||
{
|
||||
int len = static_cast<int>(size());
|
||||
if (len < 1)
|
||||
return npos;
|
||||
if (index >= len || index < 0)
|
||||
return npos;
|
||||
int i = 0;
|
||||
for (i=index; i<len; i++)
|
||||
{
|
||||
if (v[i] == c)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return npos;
|
||||
}
|
||||
|
||||
bool is_space(int c)
|
||||
{
|
||||
if (c == '\f' || c == '\n' ||
|
||||
c == '\t' || c == '\r' ||
|
||||
c == '\v' || c == ' ')
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void trim()
|
||||
{
|
||||
if (!v)
|
||||
return;
|
||||
|
||||
unsigned int i = 0;
|
||||
unsigned int j = 0;
|
||||
size_t len = strlen(v);
|
||||
|
||||
if (len == 1)
|
||||
{
|
||||
if (is_space(v[i]))
|
||||
{
|
||||
clear();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char c0 = v[0];
|
||||
|
||||
if (is_space(c0))
|
||||
{
|
||||
for (i=0; i<len; i++)
|
||||
{
|
||||
if (!is_space(v[i]) || (is_space(v[i]) && ((unsigned char)i==len-1)))
|
||||
{
|
||||
erase(0, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
len = strlen(v);
|
||||
|
||||
if (len < 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_space(v[len-1]))
|
||||
{
|
||||
for (i=len-1; i<len; i--)
|
||||
{
|
||||
if (!is_space(v[i])
|
||||
|| (is_space(v[i]) && i==0))
|
||||
{
|
||||
erase(i+1, j);
|
||||
break;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
if (len == 1)
|
||||
{
|
||||
if (is_space(v[0]))
|
||||
{
|
||||
clear();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void erase(unsigned int start, int num = npos)
|
||||
{
|
||||
if (!v)
|
||||
return;
|
||||
unsigned int i = 0;
|
||||
size_t len = size();
|
||||
//check for bounds
|
||||
if (num == npos || start+num > len-start)
|
||||
num = len - start;
|
||||
//do the erasing
|
||||
bool copyflag = false;
|
||||
for (i=0; i<len; i++)
|
||||
{
|
||||
if (i>=start && i<start+num)
|
||||
{
|
||||
if (i+num < len)
|
||||
{
|
||||
v[i] = v[i+num];
|
||||
} else {
|
||||
v[i] = 0;
|
||||
}
|
||||
copyflag = true;
|
||||
} else if (copyflag) {
|
||||
if (i+num < len)
|
||||
{
|
||||
v[i] = v[i+num];
|
||||
} else {
|
||||
v[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
len -= num;
|
||||
v[len] = 0;
|
||||
}
|
||||
|
||||
String substr(unsigned int index, int num = npos)
|
||||
{
|
||||
if (!v)
|
||||
{
|
||||
String b("");
|
||||
return b;
|
||||
}
|
||||
|
||||
String ns;
|
||||
|
||||
size_t len = size();
|
||||
|
||||
if (index >= len || !v)
|
||||
return ns;
|
||||
|
||||
if (num == npos)
|
||||
{
|
||||
num = len - index;
|
||||
} else if (index+num >= len) {
|
||||
num = len - index;
|
||||
}
|
||||
|
||||
unsigned int i = 0;
|
||||
unsigned int nslen = num + 2;
|
||||
|
||||
ns.Grow(nslen);
|
||||
|
||||
for (i=index; i<index+num; i++)
|
||||
ns.append(v[i]);
|
||||
|
||||
return ns;
|
||||
}
|
||||
|
||||
void toLower()
|
||||
{
|
||||
if (!v)
|
||||
return;
|
||||
unsigned int i = 0;
|
||||
size_t len = strlen(v);
|
||||
for (i=0; i<len; i++)
|
||||
{
|
||||
if (v[i] >= 65 && v[i] <= 90)
|
||||
v[i] &= ~(1<<5);
|
||||
}
|
||||
}
|
||||
|
||||
String & operator = (const String &src)
|
||||
{
|
||||
assign(src);
|
||||
return *this;
|
||||
}
|
||||
|
||||
String & operator = (const char *src)
|
||||
{
|
||||
assign(src);
|
||||
return *this;
|
||||
|
||||
}
|
||||
|
||||
char operator [] (unsigned int index)
|
||||
{
|
||||
if (index > size() || !v)
|
||||
{
|
||||
return -1;
|
||||
} else {
|
||||
return v[index];
|
||||
}
|
||||
}
|
||||
|
||||
int at(int a)
|
||||
{
|
||||
if (a < 0 || a >= (int)size() || !v)
|
||||
return -1;
|
||||
|
||||
return v[a];
|
||||
}
|
||||
|
||||
bool at(int at, char c)
|
||||
{
|
||||
if (at < 0 || at >= (int)size() || !v)
|
||||
return false;
|
||||
|
||||
v[at] = c;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
void Grow(unsigned int d, bool copy=true)
|
||||
{
|
||||
if (d <= a_size)
|
||||
return;
|
||||
char *n = new char[d + 1];
|
||||
if (copy && v)
|
||||
strcpy(n, v);
|
||||
if (v)
|
||||
delete [] v;
|
||||
else
|
||||
strcpy(n, "");
|
||||
v = n;
|
||||
a_size = d + 1;
|
||||
}
|
||||
|
||||
char *v;
|
||||
unsigned int a_size;
|
||||
public:
|
||||
static const int npos = -1;
|
||||
};
|
||||
|
||||
//}; //NAMESPACE
|
||||
|
||||
#endif //_INCLUDE_CSTRING_H
|
519
public/sh_tinyhash.h
Normal file
519
public/sh_tinyhash.h
Normal file
@ -0,0 +1,519 @@
|
||||
/* ======== SourceMM ========
|
||||
* Copyright (C) 2004-2005 Metamod:Source Development Team
|
||||
* No warranties of any kind
|
||||
*
|
||||
* License: zlib/libpng
|
||||
*
|
||||
* Author(s): David "BAILOPAN" Anderson
|
||||
* ============================
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_SH_TINYHASH_H_
|
||||
#define _INCLUDE_SH_TINYHASH_H_
|
||||
|
||||
#include "sh_list.h"
|
||||
|
||||
#define _T_INIT_HASH_SIZE 512
|
||||
|
||||
//namespace SourceHook
|
||||
//{
|
||||
template <class K>
|
||||
int HashFunction(const K & k);
|
||||
|
||||
template <class K>
|
||||
int Compare(const K & k1, const K & k2);
|
||||
|
||||
template <class U, class K>
|
||||
int CompareAlt(const U &k1, const K &k2);
|
||||
|
||||
template <class U>
|
||||
int HashAlt(const U &u);
|
||||
|
||||
/**
|
||||
* 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;
|
||||
};
|
||||
typedef List<THashNode *> * NodePtr;
|
||||
public:
|
||||
class const_iterator;
|
||||
THash() : m_Buckets(NULL), m_numBuckets(0), m_percentUsed(0.0f)
|
||||
{
|
||||
_Refactor();
|
||||
}
|
||||
THash(const THash &other) : m_Buckets(new NodePtr[other.m_numBuckets]),
|
||||
m_numBuckets(other.m_numBuckets), m_percentUsed(other.m_percentUsed)
|
||||
{
|
||||
for (size_t i=0; i<m_numBuckets; i++)
|
||||
m_Buckets[i] = NULL;
|
||||
for (const_iterator iter = other.begin(); iter != other.end(); ++iter)
|
||||
_FindOrInsert(iter->key)->val = iter->val;
|
||||
}
|
||||
void operator=(const THash &other)
|
||||
{
|
||||
clear();
|
||||
for (const_iterator iter = other.begin(); iter != other.end(); ++iter)
|
||||
_FindOrInsert(iter->key)->val = iter->val;
|
||||
}
|
||||
|
||||
~THash()
|
||||
{
|
||||
_Clear();
|
||||
}
|
||||
void clear()
|
||||
{
|
||||
_Clear();
|
||||
_Refactor();
|
||||
}
|
||||
size_t GetBuckets()
|
||||
{
|
||||
return m_numBuckets;
|
||||
}
|
||||
float PercentUsed()
|
||||
{
|
||||
return m_percentUsed;
|
||||
}
|
||||
V & operator [](const K & key)
|
||||
{
|
||||
THashNode *pNode = _FindOrInsert(key);
|
||||
return pNode->val;
|
||||
}
|
||||
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++;
|
||||
}
|
||||
delete m_Buckets[i];
|
||||
m_Buckets[i] = NULL;
|
||||
}
|
||||
}
|
||||
if (m_Buckets)
|
||||
delete [] m_Buckets;
|
||||
m_Buckets = NULL;
|
||||
m_numBuckets = 0;
|
||||
}
|
||||
public:
|
||||
template <typename U>
|
||||
V & AltFindOrInsert(const U & ukey)
|
||||
{
|
||||
size_t place = HashAlt(ukey) % m_numBuckets;
|
||||
THashNode *pNode = NULL;
|
||||
if (!m_Buckets[place])
|
||||
{
|
||||
m_Buckets[place] = new List<THashNode *>;
|
||||
pNode = new THashNode(ukey, V());
|
||||
m_Buckets[place]->push_back(pNode);
|
||||
m_percentUsed += (1.0f / (float)m_numBuckets);
|
||||
m_items++;
|
||||
} else {
|
||||
typename List<THashNode *>::iterator iter;
|
||||
for (iter=m_Buckets[place]->begin(); iter!=m_Buckets[place]->end(); iter++)
|
||||
{
|
||||
if (CompareAlt(ukey, (*iter)->key) == 0)
|
||||
return (*iter)->val;
|
||||
}
|
||||
pNode = new THashNode(ukey, V());
|
||||
m_Buckets[place]->push_back(pNode);
|
||||
m_items++;
|
||||
}
|
||||
if (PercentUsed() > 0.75f)
|
||||
_Refactor();
|
||||
return pNode->val;
|
||||
}
|
||||
private:
|
||||
THashNode *_FindOrInsert(const K & key)
|
||||
{
|
||||
size_t place = HashFunction(key) % m_numBuckets;
|
||||
THashNode *pNode = NULL;
|
||||
if (!m_Buckets[place])
|
||||
{
|
||||
m_Buckets[place] = new List<THashNode *>;
|
||||
pNode = new THashNode(key, V());
|
||||
m_Buckets[place]->push_back(pNode);
|
||||
m_percentUsed += (1.0f / (float)m_numBuckets);
|
||||
m_items++;
|
||||
} else {
|
||||
typename List<THashNode *>::iterator iter;
|
||||
for (iter=m_Buckets[place]->begin(); iter!=m_Buckets[place]->end(); iter++)
|
||||
{
|
||||
if (Compare((*iter)->key, key) == 0)
|
||||
return (*iter);
|
||||
}
|
||||
//node does not exist
|
||||
pNode = new THashNode(key, V());
|
||||
m_Buckets[place]->push_back(pNode);
|
||||
m_items++;
|
||||
}
|
||||
if (PercentUsed() > 0.75f)
|
||||
_Refactor();
|
||||
return pNode;
|
||||
}
|
||||
void _Refactor()
|
||||
{
|
||||
m_percentUsed = 0.0f;
|
||||
if (!m_numBuckets)
|
||||
{
|
||||
m_numBuckets = _T_INIT_HASH_SIZE;
|
||||
m_Buckets = new NodePtr[m_numBuckets];
|
||||
for (size_t i=0; i<m_numBuckets; i++)
|
||||
m_Buckets[i] = NULL;
|
||||
} else {
|
||||
size_t oldSize = m_numBuckets;
|
||||
m_numBuckets *= 2;
|
||||
typename List<THashNode *>::iterator iter;
|
||||
size_t place;
|
||||
THashNode *pHashNode;
|
||||
NodePtr *temp = new NodePtr[m_numBuckets];
|
||||
for (size_t i=0; i<m_numBuckets; i++)
|
||||
temp[i] = NULL;
|
||||
//look in old hash table
|
||||
for (size_t i=0; i<oldSize; i++)
|
||||
{
|
||||
//does a bucket have anything?
|
||||
if (m_Buckets[i])
|
||||
{
|
||||
//go through the list of items
|
||||
for (iter = m_Buckets[i]->begin(); iter != m_Buckets[i]->end(); iter++)
|
||||
{
|
||||
pHashNode = (*iter);
|
||||
//rehash it with the new bucket filter
|
||||
place = HashFunction(pHashNode->key) % m_numBuckets;
|
||||
//add it to the new hash table
|
||||
if (!temp[place])
|
||||
{
|
||||
temp[place] = new List<THashNode *>;
|
||||
m_percentUsed += (1.0f / (float)m_numBuckets);
|
||||
}
|
||||
temp[place]->push_back(pHashNode);
|
||||
}
|
||||
//delete that bucket!
|
||||
delete m_Buckets[i];
|
||||
m_Buckets[i] = NULL;
|
||||
}
|
||||
}
|
||||
//reassign bucket table
|
||||
delete [] m_Buckets;
|
||||
m_Buckets = temp;
|
||||
}
|
||||
}
|
||||
public:
|
||||
class iterator
|
||||
{
|
||||
friend class THash;
|
||||
public:
|
||||
iterator() : curbucket(-1), hash(NULL), end(true)
|
||||
{
|
||||
};
|
||||
iterator(THash *h) : curbucket(-1), hash(h), end(false)
|
||||
{
|
||||
if (!h->m_Buckets)
|
||||
end = true;
|
||||
else
|
||||
_Inc();
|
||||
};
|
||||
//pre increment
|
||||
iterator & operator++()
|
||||
{
|
||||
_Inc();
|
||||
return *this;
|
||||
}
|
||||
//post increment
|
||||
iterator operator++(int)
|
||||
{
|
||||
iterator old(*this);
|
||||
_Inc();
|
||||
return old;
|
||||
}
|
||||
const THashNode & operator * () const
|
||||
{
|
||||
return *(*iter);
|
||||
}
|
||||
THashNode & operator * ()
|
||||
{
|
||||
return *(*iter);
|
||||
}
|
||||
const THashNode * operator ->() const
|
||||
{
|
||||
return (*iter);
|
||||
}
|
||||
THashNode * operator ->()
|
||||
{
|
||||
return (*iter);
|
||||
}
|
||||
bool operator ==(const iterator &where) const
|
||||
{
|
||||
if (where.hash == this->hash
|
||||
&& where.end == this->end
|
||||
&&
|
||||
(this->end ||
|
||||
((where.curbucket == this->curbucket)
|
||||
&& (where.iter == iter))
|
||||
))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
bool operator !=(const iterator &where) const
|
||||
{
|
||||
return !( (*this) == where );
|
||||
}
|
||||
|
||||
void erase()
|
||||
{
|
||||
if (end || !hash || curbucket < 0 || curbucket >= static_cast<int>(hash->m_numBuckets))
|
||||
return;
|
||||
|
||||
// Remove this element and move to the next one
|
||||
iterator tmp = *this;
|
||||
++tmp;
|
||||
delete (*iter);
|
||||
hash->m_Buckets[curbucket]->erase(iter);
|
||||
*this = tmp;
|
||||
|
||||
// :TODO: Maybe refactor to a lower size if required
|
||||
}
|
||||
private:
|
||||
void _Inc()
|
||||
{
|
||||
if (end || !hash || curbucket >= static_cast<int>(hash->m_numBuckets))
|
||||
return;
|
||||
if (curbucket < 0)
|
||||
{
|
||||
for (int i=0; i<(int)hash->m_numBuckets; i++)
|
||||
{
|
||||
if (hash->m_Buckets[i])
|
||||
{
|
||||
iter = hash->m_Buckets[i]->begin();
|
||||
if (iter == hash->m_Buckets[i]->end())
|
||||
continue;
|
||||
curbucket = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (curbucket < 0)
|
||||
end = true;
|
||||
} else {
|
||||
if (iter != hash->m_Buckets[curbucket]->end())
|
||||
iter++;
|
||||
if (iter == hash->m_Buckets[curbucket]->end())
|
||||
{
|
||||
int oldbucket = curbucket;
|
||||
for (int i=curbucket+1; i<(int)hash->m_numBuckets; i++)
|
||||
{
|
||||
if (hash->m_Buckets[i])
|
||||
{
|
||||
iter = hash->m_Buckets[i]->begin();
|
||||
if (iter == hash->m_Buckets[i]->end())
|
||||
continue;
|
||||
curbucket = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (curbucket == oldbucket)
|
||||
end = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
private:
|
||||
int curbucket;
|
||||
typename List<THashNode *>::iterator iter;
|
||||
THash *hash;
|
||||
bool end;
|
||||
};
|
||||
class const_iterator
|
||||
{
|
||||
friend class THash;
|
||||
public:
|
||||
const_iterator() : curbucket(-1), hash(NULL), end(true)
|
||||
{
|
||||
};
|
||||
const_iterator(const THash *h) : curbucket(-1), hash(h), end(false)
|
||||
{
|
||||
if (!h->m_Buckets)
|
||||
end = true;
|
||||
else
|
||||
_Inc();
|
||||
};
|
||||
//pre increment
|
||||
const_iterator & operator++()
|
||||
{
|
||||
_Inc();
|
||||
return *this;
|
||||
}
|
||||
//post increment
|
||||
const_iterator operator++(int)
|
||||
{
|
||||
iterator old(*this);
|
||||
_Inc();
|
||||
return old;
|
||||
}
|
||||
const THashNode & operator * () const
|
||||
{
|
||||
return *(*iter);
|
||||
}
|
||||
const THashNode * operator ->() const
|
||||
{
|
||||
return (*iter);
|
||||
}
|
||||
bool operator ==(const const_iterator &where) const
|
||||
{
|
||||
if (where.hash == this->hash
|
||||
&& where.end == this->end
|
||||
&&
|
||||
(this->end ||
|
||||
((where.curbucket == this->curbucket)
|
||||
&& (where.iter == iter))
|
||||
))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
bool operator !=(const const_iterator &where) const
|
||||
{
|
||||
return !( (*this) == where );
|
||||
}
|
||||
private:
|
||||
void _Inc()
|
||||
{
|
||||
if (end || !hash || curbucket >= static_cast<int>(hash->m_numBuckets))
|
||||
return;
|
||||
if (curbucket < 0)
|
||||
{
|
||||
for (int i=0; i<(int)hash->m_numBuckets; i++)
|
||||
{
|
||||
if (hash->m_Buckets[i])
|
||||
{
|
||||
iter = hash->m_Buckets[i]->begin();
|
||||
if (iter == hash->m_Buckets[i]->end())
|
||||
continue;
|
||||
curbucket = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (curbucket < 0)
|
||||
end = true;
|
||||
} else {
|
||||
if (iter != hash->m_Buckets[curbucket]->end())
|
||||
iter++;
|
||||
if (iter == hash->m_Buckets[curbucket]->end())
|
||||
{
|
||||
int oldbucket = curbucket;
|
||||
for (int i=curbucket+1; i<(int)hash->m_numBuckets; i++)
|
||||
{
|
||||
if (hash->m_Buckets[i])
|
||||
{
|
||||
iter = hash->m_Buckets[i]->begin();
|
||||
if (iter == hash->m_Buckets[i]->end())
|
||||
continue;
|
||||
curbucket = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (curbucket == oldbucket)
|
||||
end = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
private:
|
||||
int curbucket;
|
||||
typename List<THashNode *>::iterator iter;
|
||||
const THash *hash;
|
||||
bool end;
|
||||
};
|
||||
friend class iterator;
|
||||
friend class const_iterator;
|
||||
public:
|
||||
iterator begin()
|
||||
{
|
||||
return iterator(this);
|
||||
}
|
||||
iterator end()
|
||||
{
|
||||
iterator iter;
|
||||
iter.hash = this;
|
||||
return iter;
|
||||
}
|
||||
|
||||
const_iterator begin() const
|
||||
{
|
||||
return const_iterator(this);
|
||||
}
|
||||
const_iterator end() const
|
||||
{
|
||||
const_iterator iter;
|
||||
iter.hash = this;
|
||||
return iter;
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
iterator find(const U & u) const
|
||||
{
|
||||
iterator b = begin();
|
||||
iterator e = end();
|
||||
for (iterator iter = b; iter != e; iter++)
|
||||
{
|
||||
if ( (*iter).key == u )
|
||||
return iter;
|
||||
}
|
||||
return end();
|
||||
}
|
||||
template <typename U>
|
||||
iterator find(const U & u)
|
||||
{
|
||||
iterator b = begin();
|
||||
iterator e = end();
|
||||
for (iterator iter = b; iter != e; iter++)
|
||||
{
|
||||
if ( (*iter).key == u )
|
||||
return iter;
|
||||
}
|
||||
return end();
|
||||
}
|
||||
|
||||
iterator erase(iterator where)
|
||||
{
|
||||
where.erase();
|
||||
return where;
|
||||
}
|
||||
template <typename U>
|
||||
void erase(const U & u)
|
||||
{
|
||||
iterator iter = find(u);
|
||||
if (iter == end())
|
||||
return;
|
||||
iter.erase();
|
||||
}
|
||||
private:
|
||||
NodePtr *m_Buckets;
|
||||
size_t m_numBuckets;
|
||||
float m_percentUsed;
|
||||
size_t m_items;
|
||||
};
|
||||
//};
|
||||
|
||||
#endif //_INCLUDE_SH_TINYHASH_H_
|
@ -1,333 +0,0 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod
|
||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||
* =============================================================================
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||
* this exception to all derivative works. AlliedModders LLC defines further
|
||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||
* or <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_SM_QUEUE_H
|
||||
#define _INCLUDE_SM_QUEUE_H
|
||||
|
||||
#include <new>
|
||||
#include <stdlib.h>
|
||||
#include <sh_stack.h>
|
||||
|
||||
//using namespace SourceHook;
|
||||
|
||||
/*
|
||||
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 Queue
|
||||
{
|
||||
public:
|
||||
class iterator;
|
||||
friend class iterator;
|
||||
class QueueNode
|
||||
{
|
||||
public:
|
||||
T obj;
|
||||
QueueNode *next;
|
||||
QueueNode *prev;
|
||||
};
|
||||
private:
|
||||
// Initializes the sentinel node.
|
||||
QueueNode *_Initialize()
|
||||
{
|
||||
QueueNode *n = (QueueNode *)malloc(sizeof(QueueNode));
|
||||
n->next = n;
|
||||
n->prev = n;
|
||||
return n;
|
||||
}
|
||||
public:
|
||||
Queue() : m_Head(_Initialize()), m_Size(0)
|
||||
{
|
||||
}
|
||||
|
||||
Queue(const Queue &src) : m_Head(_Initialize()), m_Size(0)
|
||||
{
|
||||
iterator iter;
|
||||
for (iter=src.begin(); iter!=src.end(); iter++)
|
||||
{
|
||||
push_back( (*iter) );
|
||||
}
|
||||
}
|
||||
|
||||
~Queue()
|
||||
{
|
||||
clear();
|
||||
|
||||
// Don't forget to free the sentinel
|
||||
if (m_Head)
|
||||
{
|
||||
free(m_Head);
|
||||
m_Head = NULL;
|
||||
}
|
||||
|
||||
while (!m_FreeNodes.empty())
|
||||
{
|
||||
free(m_FreeNodes.front());
|
||||
m_FreeNodes.pop();
|
||||
}
|
||||
}
|
||||
|
||||
void push(const T &obj)
|
||||
{
|
||||
QueueNode *node;
|
||||
|
||||
if (m_FreeNodes.empty())
|
||||
{
|
||||
node = (QueueNode *)malloc(sizeof(QueueNode));
|
||||
} else {
|
||||
node = m_FreeNodes.front();
|
||||
m_FreeNodes.pop();
|
||||
}
|
||||
|
||||
/* Copy the object */
|
||||
new (&node->obj) T(obj);
|
||||
|
||||
/* Install into the Queue */
|
||||
node->prev = m_Head->prev;
|
||||
node->next = m_Head;
|
||||
m_Head->prev->next = node;
|
||||
m_Head->prev = node;
|
||||
|
||||
m_Size++;
|
||||
}
|
||||
|
||||
size_t size() const
|
||||
{
|
||||
return m_Size;
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
QueueNode *node = m_Head->next;
|
||||
QueueNode *temp;
|
||||
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;
|
||||
node->obj.~T();
|
||||
m_FreeNodes.push(node);
|
||||
node = temp;
|
||||
}
|
||||
m_Size = 0;
|
||||
}
|
||||
|
||||
bool empty() const
|
||||
{
|
||||
return (m_Size == 0);
|
||||
}
|
||||
|
||||
private:
|
||||
QueueNode *m_Head;
|
||||
size_t m_Size;
|
||||
CStack<QueueNode *> m_FreeNodes;
|
||||
public:
|
||||
class iterator
|
||||
{
|
||||
friend class Queue;
|
||||
public:
|
||||
iterator()
|
||||
{
|
||||
m_This = NULL;
|
||||
}
|
||||
iterator(const Queue &src)
|
||||
{
|
||||
m_This = src.m_Head;
|
||||
}
|
||||
iterator(QueueNode *n) : m_This(n)
|
||||
{
|
||||
}
|
||||
iterator(const iterator &where)
|
||||
{
|
||||
m_This = where.m_This;
|
||||
}
|
||||
//pre decrement
|
||||
iterator & operator--()
|
||||
{
|
||||
if (m_This)
|
||||
m_This = m_This->prev;
|
||||
return *this;
|
||||
}
|
||||
//post decrement
|
||||
iterator operator--(int)
|
||||
{
|
||||
iterator old(*this);
|
||||
if (m_This)
|
||||
m_This = m_This->prev;
|
||||
return old;
|
||||
}
|
||||
|
||||
//pre increment
|
||||
iterator & operator++()
|
||||
{
|
||||
if (m_This)
|
||||
m_This = m_This->next;
|
||||
return *this;
|
||||
}
|
||||
//post increment
|
||||
iterator operator++(int)
|
||||
{
|
||||
iterator old(*this);
|
||||
if (m_This)
|
||||
m_This = m_This->next;
|
||||
return old;
|
||||
}
|
||||
|
||||
const T & operator * () const
|
||||
{
|
||||
return m_This->obj;
|
||||
}
|
||||
T & operator * ()
|
||||
{
|
||||
return m_This->obj;
|
||||
}
|
||||
|
||||
T * operator -> ()
|
||||
{
|
||||
return &(m_This->obj);
|
||||
}
|
||||
const T * operator -> () const
|
||||
{
|
||||
return &(m_This->obj);
|
||||
}
|
||||
|
||||
bool operator != (const iterator &where) const
|
||||
{
|
||||
return (m_This != where.m_This);
|
||||
}
|
||||
bool operator ==(const iterator &where) const
|
||||
{
|
||||
return (m_This == where.m_This);
|
||||
}
|
||||
private:
|
||||
QueueNode *m_This;
|
||||
};
|
||||
public:
|
||||
iterator begin() const
|
||||
{
|
||||
return iterator(m_Head->next);
|
||||
}
|
||||
|
||||
iterator end() const
|
||||
{
|
||||
return iterator(m_Head);
|
||||
}
|
||||
|
||||
iterator erase(iterator &where)
|
||||
{
|
||||
QueueNode *pNode = where.m_This;
|
||||
iterator iter(where);
|
||||
iter++;
|
||||
|
||||
|
||||
// Works for all cases: empty Queue, erasing first element, erasing tail, erasing in the middle...
|
||||
pNode->prev->next = pNode->next;
|
||||
pNode->next->prev = pNode->prev;
|
||||
|
||||
pNode->obj.~T();
|
||||
m_FreeNodes.push(pNode);
|
||||
m_Size--;
|
||||
|
||||
return iter;
|
||||
}
|
||||
public:
|
||||
void remove(const T & obj)
|
||||
{
|
||||
iterator b;
|
||||
for (b=begin(); b!=end(); b++)
|
||||
{
|
||||
if ( (*b) == obj )
|
||||
{
|
||||
erase( b );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
template <typename U>
|
||||
iterator find(const U & equ) const
|
||||
{
|
||||
iterator iter;
|
||||
for (iter=begin(); iter!=end(); iter++)
|
||||
{
|
||||
if ( (*iter) == equ )
|
||||
{
|
||||
return iter;
|
||||
}
|
||||
}
|
||||
return end();
|
||||
}
|
||||
Queue & operator =(const Queue &src)
|
||||
{
|
||||
clear();
|
||||
iterator iter;
|
||||
for (iter=src.begin(); iter!=src.end(); iter++)
|
||||
{
|
||||
push_back( (*iter) );
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
public:
|
||||
T & first() const
|
||||
{
|
||||
iterator i = begin();
|
||||
|
||||
return (*i);
|
||||
}
|
||||
|
||||
void pop()
|
||||
{
|
||||
iterator iter = begin();
|
||||
erase(iter);
|
||||
}
|
||||
};
|
||||
|
||||
#endif //_INCLUDE_SM_QUEUE_H
|
Reference in New Issue
Block a user