1 /*	see copyright notice in squirrel.h */
2 #ifndef _SQUTILS_H_
3 #define _SQUTILS_H_
4 
5 void *sq_vm_malloc(SQUnsignedInteger size);
6 void *sq_vm_realloc(void *p,SQUnsignedInteger oldsize,SQUnsignedInteger size);
7 void sq_vm_free(void *p,SQUnsignedInteger size);
8 
9 #define sq_new(__ptr,__type) {__ptr=(__type *)sq_vm_malloc(sizeof(__type));new (__ptr) __type;}
10 #define sq_delete(__ptr,__type) {__ptr->~__type();sq_vm_free(__ptr,sizeof(__type));}
11 #define SQ_MALLOC(__size) sq_vm_malloc(__size);
12 #define SQ_FREE(__ptr,__size) sq_vm_free(__ptr,__size);
13 #define SQ_REALLOC(__ptr,__oldsize,__size) sq_vm_realloc(__ptr,__oldsize,__size);
14 
15 //sqvector mini vector class, supports objects by value
16 template<typename T> class sqvector
17 {
18 public:
sqvector()19 	sqvector()
20 	{
21 		_vals = NULL;
22 		_size = 0;
23 		_allocated = 0;
24 	}
sqvector(const sqvector<T> & v)25 	sqvector(const sqvector<T>& v)
26 	{
27 		copy(v);
28 	}
copy(const sqvector<T> & v)29 	void copy(const sqvector<T>& v)
30 	{
31 		resize(v._size);
32 		for(SQUnsignedInteger i = 0; i < v._size; i++) {
33 			new ((void *)&_vals[i]) T(v._vals[i]);
34 		}
35 		_size = v._size;
36 	}
~sqvector()37 	~sqvector()
38 	{
39 		if(_allocated) {
40 			for(SQUnsignedInteger i = 0; i < _size; i++)
41 				_vals[i].~T();
42 			SQ_FREE(_vals, (_allocated * sizeof(T)));
43 		}
44 	}
reserve(SQUnsignedInteger newsize)45 	void reserve(SQUnsignedInteger newsize) { _realloc(newsize); }
46 	void resize(SQUnsignedInteger newsize, const T& fill = T())
47 	{
48 		if(newsize > _allocated)
49 			_realloc(newsize);
50 		if(newsize > _size) {
51 			while(_size < newsize) {
52 				new ((void *)&_vals[_size]) T(fill);
53 				_size++;
54 			}
55 		}
56 		else{
57 			for(SQUnsignedInteger i = newsize; i < _size; i++) {
58 				_vals[i].~T();
59 			}
60 			_size = newsize;
61 		}
62 	}
shrinktofit()63 	void shrinktofit() { if(_size > 4) { _realloc(_size); } }
top()64 	T& top() const { return _vals[_size - 1]; }
size()65 	inline SQUnsignedInteger size() const { return _size; }
empty()66 	bool empty() const { return (_size <= 0); }
67 	inline T &push_back(const T& val = T())
68 	{
69 		if(_allocated <= _size)
70 			_realloc(_size * 2);
71 		return *(new ((void *)&_vals[_size++]) T(val));
72 	}
pop_back()73 	inline void pop_back()
74 	{
75 		_size--; _vals[_size].~T();
76 	}
insert(SQUnsignedInteger idx,const T & val)77 	void insert(SQUnsignedInteger idx, const T& val)
78 	{
79 		resize(_size + 1);
80 		for(SQUnsignedInteger i = _size - 1; i > idx; i--) {
81 			_vals[i] = _vals[i - 1];
82 		}
83     	_vals[idx] = val;
84 	}
remove(SQUnsignedInteger idx)85 	void remove(SQUnsignedInteger idx)
86 	{
87 		_vals[idx].~T();
88 		if(idx < (_size - 1)) {
89 			memcpy(&_vals[idx], &_vals[idx+1], sizeof(T) * (_size - idx - 1));
90 		}
91 		_size--;
92 	}
capacity()93 	SQUnsignedInteger capacity() { return _allocated; }
back()94 	inline T &back() const { return _vals[_size - 1]; }
95 	inline T& operator[](SQUnsignedInteger pos) const{ return _vals[pos]; }
96 	T* _vals;
97 private:
_realloc(SQUnsignedInteger newsize)98 	void _realloc(SQUnsignedInteger newsize)
99 	{
100 		newsize = (newsize > 0)?newsize:4;
101 		_vals = (T*)SQ_REALLOC(_vals, _allocated * sizeof(T), newsize * sizeof(T));
102 		_allocated = newsize;
103 	}
104 	SQUnsignedInteger _size;
105 	SQUnsignedInteger _allocated;
106 };
107 
108 #endif //_SQUTILS_H_
109