Johan Wikman / SQUIRREL3

Dependents:   Squirrel

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers sqtable.h Source File

sqtable.h

00001 /*  see copyright notice in squirrel.h */
00002 #ifndef _SQTABLE_H_
00003 #define _SQTABLE_H_
00004 /*
00005 * The following code is based on Lua 4.0 (Copyright 1994-2002 Tecgraf, PUC-Rio.)
00006 * http://www.lua.org/copyright.html#4
00007 * http://www.lua.org/source/4.0.1/src_ltable.c.html
00008 */
00009 
00010 #include "sqstring.h"
00011 
00012 
00013 #define hashptr(p)  ((SQHash)(((SQInteger)p) >> 3))
00014 
00015 inline SQHash HashObj(const SQObjectPtr &key)
00016 {
00017     switch(type(key)) {
00018         case OT_STRING:     return _string(key)->_hash;
00019         case OT_FLOAT:      return (SQHash)((SQInteger)_float(key));
00020         case OT_BOOL: case OT_INTEGER:  return (SQHash)((SQInteger)_integer(key));
00021         default:            return hashptr(key._unVal.pRefCounted);
00022     }
00023 }
00024 
00025 struct SQTable : public SQDelegable 
00026 {
00027 private:
00028     struct _HashNode
00029     {
00030         _HashNode() { next = NULL; }
00031         SQObjectPtr val;
00032         SQObjectPtr key;
00033         _HashNode *next;
00034     };
00035     _HashNode *_firstfree;
00036     _HashNode *_nodes;
00037     SQInteger _numofnodes;
00038     SQInteger _usednodes;
00039     
00040 ///////////////////////////
00041     void AllocNodes(SQInteger nSize);
00042     void Rehash(bool force);
00043     SQTable(SQSharedState *ss, SQInteger nInitialSize);
00044     void _ClearNodes();
00045 public:
00046     static SQTable* Create(SQSharedState *ss,SQInteger nInitialSize)
00047     {
00048         SQTable *newtable = (SQTable*)SQ_MALLOC(sizeof(SQTable));
00049         new (newtable) SQTable(ss, nInitialSize);
00050         newtable->_delegate = NULL;
00051         return newtable;
00052     }
00053     void Finalize();
00054     SQTable *Clone();
00055     ~SQTable()
00056     {
00057         SetDelegate(NULL);
00058         REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);
00059         for (SQInteger i = 0; i < _numofnodes; i++) _nodes[i].~_HashNode();
00060         SQ_FREE(_nodes, _numofnodes * sizeof(_HashNode));
00061     }
00062 #ifndef NO_GARBAGE_COLLECTOR 
00063     void Mark(SQCollectable **chain);
00064     SQObjectType GetType() {return OT_TABLE;}
00065 #endif
00066     inline _HashNode *_Get(const SQObjectPtr &key,SQHash hash)
00067     {
00068         _HashNode *n = &_nodes[hash];
00069         do{
00070             if(_rawval(n->key) == _rawval(key) && type(n->key) == type(key)){
00071                 return n;
00072             }
00073         }while((n = n->next));
00074         return NULL;
00075     }
00076     bool Get(const SQObjectPtr &key,SQObjectPtr &val);
00077     void Remove(const SQObjectPtr &key);
00078     bool Set(const SQObjectPtr &key, const SQObjectPtr &val);
00079     //returns true if a new slot has been created false if it was already present
00080     bool NewSlot(const SQObjectPtr &key,const SQObjectPtr &val);
00081     SQInteger Next(bool getweakrefs,const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);
00082     
00083     SQInteger CountUsed(){ return _usednodes;}
00084     void Clear();
00085     void Release()
00086     {
00087         sq_delete(this, SQTable);
00088     }
00089     
00090 };
00091 
00092 #endif //_SQTABLE_H_