Revert "Update to SQUIRREL 3.0.4"
[supertux.git] / external / squirrel / squirrel / sqtable.h
1 /*      see copyright notice in squirrel.h */\r
2 #ifndef _SQTABLE_H_\r
3 #define _SQTABLE_H_\r
4 /*\r
5 * The following code is based on Lua 4.0 (Copyright 1994-2002 Tecgraf, PUC-Rio.)\r
6 * http://www.lua.org/copyright.html#4\r
7 * http://www.lua.org/source/4.0.1/src_ltable.c.html\r
8 */\r
9 \r
10 #include "sqstring.h"\r
11 \r
12 \r
13 #define hashptr(p)  ((SQHash)(((SQInteger)p) >> 3))\r
14 \r
15 inline SQHash HashObj(const SQObjectPtr &key)\r
16 {\r
17         switch(type(key)) {\r
18                 case OT_STRING:         return _string(key)->_hash;\r
19                 case OT_FLOAT:          return (SQHash)((SQInteger)_float(key));\r
20                 case OT_BOOL: case OT_INTEGER:  return (SQHash)((SQInteger)_integer(key));\r
21                 default:                        return hashptr(key._unVal.pRefCounted);\r
22         }\r
23 }\r
24 \r
25 struct SQTable : public SQDelegable \r
26 {\r
27 private:\r
28         struct _HashNode\r
29         {\r
30                 _HashNode() { next = NULL; }\r
31                 SQObjectPtr val;\r
32                 SQObjectPtr key;\r
33                 _HashNode *next;\r
34         };\r
35         _HashNode *_firstfree;\r
36         _HashNode *_nodes;\r
37         SQInteger _numofnodes;\r
38         SQInteger _usednodes;\r
39         \r
40 ///////////////////////////\r
41         void AllocNodes(SQInteger nSize);\r
42         void Rehash(bool force);\r
43         SQTable(SQSharedState *ss, SQInteger nInitialSize);\r
44         void _ClearNodes();\r
45 public:\r
46         static SQTable* Create(SQSharedState *ss,SQInteger nInitialSize)\r
47         {\r
48                 SQTable *newtable = (SQTable*)SQ_MALLOC(sizeof(SQTable));\r
49                 new (newtable) SQTable(ss, nInitialSize);\r
50                 newtable->_delegate = NULL;\r
51                 return newtable;\r
52         }\r
53         void Finalize();\r
54         SQTable *Clone();\r
55         ~SQTable()\r
56         {\r
57                 SetDelegate(NULL);\r
58                 REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);\r
59                 for (SQInteger i = 0; i < _numofnodes; i++) _nodes[i].~_HashNode();\r
60                 SQ_FREE(_nodes, _numofnodes * sizeof(_HashNode));\r
61         }\r
62 #ifndef NO_GARBAGE_COLLECTOR \r
63         void Mark(SQCollectable **chain);\r
64 #endif\r
65         inline _HashNode *_Get(const SQObjectPtr &key,SQHash hash)\r
66         {\r
67                 _HashNode *n = &_nodes[hash];\r
68                 do{\r
69                         if(_rawval(n->key) == _rawval(key) && type(n->key) == type(key)){\r
70                                 return n;\r
71                         }\r
72                 }while((n = n->next));\r
73                 return NULL;\r
74         }\r
75         bool Get(const SQObjectPtr &key,SQObjectPtr &val);\r
76         void Remove(const SQObjectPtr &key);\r
77         bool Set(const SQObjectPtr &key, const SQObjectPtr &val);\r
78         //returns true if a new slot has been created false if it was already present\r
79         bool NewSlot(const SQObjectPtr &key,const SQObjectPtr &val);\r
80         SQInteger Next(bool getweakrefs,const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);\r
81         \r
82         SQInteger CountUsed(){ return _usednodes;}\r
83         void Clear();\r
84         void Release()\r
85         {\r
86                 sq_delete(this, SQTable);\r
87         }\r
88         \r
89 };\r
90 \r
91 #endif //_SQTABLE_H_\r