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