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