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 #define sq_aligning(v) (((size_t)(v) + (SQ_ALIGNMENT-1)) & (~(SQ_ALIGNMENT-1)))
16 
17 //sqvector mini vector class, supports objects by value
18 template<typename T> class sqvector
19 {
20 public:
sqvector()21 	sqvector()
22 	{
23 		_vals = NULL;
24 		_size = 0;
25 		_allocated = 0;
26 	}
sqvector(const sqvector<T> & v)27 	sqvector(const sqvector<T>& v)
28 	{
29 		copy(v);
30 	}
copy(const sqvector<T> & v)31 	void copy(const sqvector<T>& v)
32 	{
33 		if(_size) {
34 			resize(0); //destroys all previous stuff
35 		}
36 		//resize(v._size);
37 		if(v._size > _allocated) {
38 			_realloc(v._size);
39 		}
40 		for(SQUnsignedInteger i = 0; i < v._size; i++) {
41 			new ((void *)&_vals[i]) T(v._vals[i]);
42 		}
43 		_size = v._size;
44 	}
~sqvector()45 	~sqvector()
46 	{
47 		if(_allocated) {
48 			for(SQUnsignedInteger i = 0; i < _size; i++)
49 				_vals[i].~T();
50 			SQ_FREE(_vals, (_allocated * sizeof(T)));
51 		}
52 	}
reserve(SQUnsignedInteger newsize)53 	void reserve(SQUnsignedInteger newsize) { _realloc(newsize); }
54 	void resize(SQUnsignedInteger newsize, const T& fill = T())
55 	{
56 		if(newsize > _allocated)
57 			_realloc(newsize);
58 		if(newsize > _size) {
59 			while(_size < newsize) {
60 				new ((void *)&_vals[_size]) T(fill);
61 				_size++;
62 			}
63 		}
64 		else{
65 			for(SQUnsignedInteger i = newsize; i < _size; i++) {
66 				_vals[i].~T();
67 			}
68 			_size = newsize;
69 		}
70 	}
shrinktofit()71 	void shrinktofit() { if(_size > 4) { _realloc(_size); } }
top()72 	T& top() const { return _vals[_size - 1]; }
size()73 	inline SQUnsignedInteger size() const { return _size; }
empty()74 	bool empty() const { return (_size <= 0); }
75 	inline T &push_back(const T& val = T())
76 	{
77 		if(_allocated <= _size)
78 			_realloc(_size * 2);
79 		return *(new ((void *)&_vals[_size++]) T(val));
80 	}
pop_back()81 	inline void pop_back()
82 	{
83 		_size--; _vals[_size].~T();
84 	}
insert(SQUnsignedInteger idx,const T & val)85 	void insert(SQUnsignedInteger idx, const T& val)
86 	{
87 		resize(_size + 1);
88 		for(SQUnsignedInteger i = _size - 1; i > idx; i--) {
89 			_vals[i] = _vals[i - 1];
90 		}
91 		_vals[idx] = val;
92 	}
remove(SQUnsignedInteger idx)93 	void remove(SQUnsignedInteger idx)
94 	{
95 		_vals[idx].~T();
96 		if(idx < (_size - 1)) {
97 			memmove(&_vals[idx], &_vals[idx+1], sizeof(T) * (_size - idx - 1));
98 		}
99 		_size--;
100 	}
capacity()101 	SQUnsignedInteger capacity() { return _allocated; }
back()102 	inline T &back() const { return _vals[_size - 1]; }
103 	inline T& operator[](SQUnsignedInteger pos) const{ return _vals[pos]; }
104 	T* _vals;
105 private:
_realloc(SQUnsignedInteger newsize)106 	void _realloc(SQUnsignedInteger newsize)
107 	{
108 		newsize = (newsize > 0)?newsize:4;
109 		_vals = (T*)SQ_REALLOC(_vals, _allocated * sizeof(T), newsize * sizeof(T));
110 		_allocated = newsize;
111 	}
112 	SQUnsignedInteger _size;
113 	SQUnsignedInteger _allocated;
114 };
115 
116 #endif
117