# squtils.h

    00001 /*  see copyright notice in squirrel.h */
    00002 #ifndef _SQUTILS_H_
    00003 #define _SQUTILS_H_
    00004
    00005 #define sq_new(__ptr,__type) {__ptr=(__type *)sq_vm_malloc(sizeof(__type));new (__ptr) __type;}
    00006 #define sq_delete(__ptr,__type) {__ptr->~__type();sq_vm_free(__ptr,sizeof(__type));}
    00007 #define SQ_MALLOC(__size) sq_vm_malloc((__size));
    00008 #define SQ_FREE(__ptr,__size) sq_vm_free((__ptr),(__size));
    00009 #define SQ_REALLOC(__ptr,__oldsize,__size) sq_vm_realloc((__ptr),(__oldsize),(__size));
    00010
    00011 //sqvector mini vector class, supports objects by value
    00012 template<typename T> class sqvector
    00013 {
    00014 public:
    00015   sqvector()
    00016   {
    00017     _vals = NULL;
    00018     _size = 0;
    00019     _allocated = 0;
    00020   }
    00021   sqvector(const sqvector<T>& v)
    00022   {
    00023     copy(v);
    00024   }
    00025   void copy(const sqvector<T>& v)
    00026   {
    00027     resize(v._size);
    00028     for(SQUnsignedInteger i = 0; i < v._size; i++) {
    00029       new ((void *)&_vals[i]) T(v._vals[i]);
    00030     }
    00031     _size = v._size;
    00032   }
    00033   ~sqvector()
    00034   {
    00035     if(_allocated) {
    00036       for(SQUnsignedInteger i = 0; i < _size; i++)
    00037         _vals[i].~T();
    00038       SQ_FREE(_vals, (_allocated * sizeof(T)));
    00039     }
    00040   }
    00041   void reserve(SQUnsignedInteger newsize) { _realloc(newsize); }
    00042   void resize(SQUnsignedInteger newsize, const T& fill = T())
    00043   {
    00044     if(newsize > _allocated)
    00045       _realloc(newsize);
    00046     if(newsize > _size) {
    00047       while(_size < newsize) {
    00048         new ((void *)&_vals[_size]) T(fill);
    00049         _size++;
    00050       }
    00051     }
    00052     else{
    00053       for(SQUnsignedInteger i = newsize; i < _size; i++) {
    00054         _vals[i].~T();
    00055       }
    00056       _size = newsize;
    00057     }
    00058   }
    00059   void shrinktofit() { if(_size > 4) { _realloc(_size); } }
    00060   T& top() const { return _vals[_size - 1]; }
    00061   inline SQUnsignedInteger size() const { return _size; }
    00062   bool empty() const { return (_size <= 0); }
    00063   inline T &push_back(const T& val = T())
    00064   {
    00065     if(_allocated <= _size)
    00066       _realloc(_size * 2);
    00067     return *(new ((void *)&_vals[_size++]) T(val));
    00068   }
    00069   inline void pop_back()
    00070   {
    00071     _size--; _vals[_size].~T();
    00072   }
    00073   void insert(SQUnsignedInteger idx, const T& val)
    00074   {
    00075     resize(_size + 1);
    00076     for(SQUnsignedInteger i = _size - 1; i > idx; i--) {
    00077       _vals[i] = _vals[i - 1];
    00078     }
    00079       _vals[idx] = val;
    00080   }
    00081   void remove(SQUnsignedInteger idx)
    00082   {
    00083     _vals[idx].~T();
    00084     if(idx < (_size - 1)) {
    00085       memmove(&_vals[idx], &_vals[idx+1], sizeof(T) * (_size - idx - 1));
    00086     }
    00087     _size--;
    00088   }
    00089   SQUnsignedInteger capacity() { return _allocated; }
    00090   inline T &back() const { return _vals[_size - 1]; }
    00091   inline T& operator[](SQUnsignedInteger pos) const{ assert(pos < _allocated); return _vals[pos]; }
    00092   T* _vals;
    00093 private:
    00094   void _realloc(SQUnsignedInteger newsize)
    00095   {
    00096     newsize = (newsize > 0)?newsize:4;
    00097     _vals = (T*)SQ_REALLOC(_vals, _allocated * sizeof(T), newsize * sizeof(T));
    00098     _allocated = newsize;
    00099   }
    00100   SQUnsignedInteger _size;
    00101   SQUnsignedInteger _allocated;
    00102 };
    00103
    00104 #endif //_SQUTILS_H_