sqarray.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. /* see copyright notice in squirrel.h */
  2. #ifndef _SQARRAY_H_
  3. #define _SQARRAY_H_
  4. struct SQArrayBase : public CHAINABLE_OBJ
  5. {
  6. protected:
  7. SQArrayBase(SQSharedState *ss,SQInteger nsize){
  8. INIT_CHAIN();
  9. ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);
  10. }
  11. ~SQArrayBase()
  12. {
  13. REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this);
  14. }
  15. public:
  16. #ifndef NO_GARBAGE_COLLECTOR
  17. ABSTRACT_METHOD(virtual bool isCollectable(), {return true;})
  18. void Mark(SQCollectable **chain);
  19. SQObjectType GetType() {return OT_ARRAY;}
  20. #endif
  21. void Finalize(){Resize(0);}
  22. bool Get(const SQInteger nidx,SQObjectPtr &val)
  23. {
  24. if(((SQUnsignedInteger)nidx)<Size()){
  25. _getRealObjectPtr(nidx, val);
  26. return true;
  27. }
  28. return false;
  29. }
  30. SQObjectPtr operator[](SQInteger nidx) {
  31. SQObjectPtr val;
  32. Get(nidx, val);
  33. return val;
  34. }
  35. bool Exists(const SQInteger nidx)
  36. {
  37. return (((SQUnsignedInteger)nidx)<Size());
  38. }
  39. bool Set(const SQInteger nidx,const SQObjectPtr &val)
  40. {
  41. return (((SQUnsignedInteger)nidx)<Size())
  42. && _setObjectPtr(nidx, val);
  43. }
  44. SQInteger Next(const SQObjectPtr &refpos,SQObjectPtr &outkey,SQObjectPtr &outval)
  45. {
  46. SQUnsignedInteger idx=SQTranslateIndex(refpos);
  47. while(idx<Size()){
  48. //first found
  49. outkey=(SQInteger)idx;
  50. _getRealObjectPtr(idx, outval);
  51. //return idx for the next iteration
  52. return ++idx;
  53. }
  54. //nothing to iterate anymore
  55. return -1;
  56. }
  57. ABSTRACT_METHOD(virtual SQArrayBase *Clone(bool withData=true), { return NULL;})
  58. ABSTRACT_METHOD(virtual void *RawData(), { return NULL;})
  59. ABSTRACT_METHOD(virtual SQInteger GetArrayType(), { return 0;})
  60. ABSTRACT_METHOD(virtual SQUnsignedInteger SizeOf() const, { return 0;})
  61. ABSTRACT_METHOD(virtual SQUnsignedInteger Size() const, { return 0;})
  62. bool Resize(SQUnsignedInteger size)
  63. {
  64. SQObjectPtr _null;
  65. return Resize(size,_null);
  66. }
  67. bool Resize(SQUnsignedInteger size,SQObjectPtr &fill) {
  68. bool rc = _resizeValues(size,fill);
  69. if(rc) ShrinkIfNeeded();
  70. return rc;
  71. }
  72. bool Minsize(SQUnsignedInteger size) { return (Size() < size) ? Resize(size) : true;}
  73. bool Minsize(SQUnsignedInteger size,SQObjectPtr &fill) {
  74. return (Size() < size) ? _resizeValues(size,fill) : true;
  75. }
  76. ABSTRACT_METHOD(virtual void Reserve(SQUnsignedInteger size), {})
  77. ABSTRACT_METHOD(virtual SQUnsignedInteger Capacity(), {return 0;})
  78. ABSTRACT_METHOD(virtual bool Append(const SQObject &o), {return false;})
  79. void Extend(SQArrayBase *a);
  80. ABSTRACT_METHOD(virtual void Top(SQObjectPtr &out), {})
  81. ABSTRACT_METHOD(virtual void Pop(), {})
  82. bool Insert(SQInteger idx,const SQObject &val){
  83. return _insertValue((SQUnsignedInteger)idx,val);
  84. }
  85. void ShrinkIfNeeded() {
  86. if(Size() <= Capacity()>>2) //shrink the array
  87. _shrinktofit();
  88. }
  89. bool Remove(SQInteger idx){
  90. if(!_removeValue(idx)) return false;
  91. ShrinkIfNeeded();
  92. return true;
  93. }
  94. void Release()
  95. {
  96. sq_assert(NULL);
  97. }
  98. ABSTRACT_METHOD(virtual void _swap(SQInteger idx1, SQInteger idx2),{})
  99. ABSTRACT_METHOD(virtual void _copy(SQInteger idx1, SQInteger idx2),{})
  100. ABSTRACT_METHOD(virtual bool _set(SQInteger idx1, SQObjectPtr &val),{return false;})
  101. ABSTRACT_METHOD(virtual void _get2(SQInteger idx, SQObject& out),{})
  102. ABSTRACT_METHOD(virtual void DummyPinVtable(), {})
  103. private:
  104. ABSTRACT_METHOD(virtual void _getObjectPtr(const SQInteger nidx,SQObjectPtr &val),{})
  105. ABSTRACT_METHOD(virtual void _getRealObjectPtr(const SQInteger nidx,SQObjectPtr &val),{})
  106. ABSTRACT_METHOD(virtual bool _setObjectPtr(const SQInteger nidx, const SQObjectPtr &val),{return false;})
  107. ABSTRACT_METHOD(virtual bool _resizeValues(SQInteger size,SQObjectPtr &fill),{return false;})
  108. ABSTRACT_METHOD(virtual bool _insertValue(SQInteger idx,const SQObject &val),{return false;})
  109. ABSTRACT_METHOD(virtual bool _removeValue(SQInteger idx),{return false;})
  110. ABSTRACT_METHOD(virtual void _shrinktofit(),{})
  111. };
  112. #define DECLARE_CLASS_ARRAY_MEMBERS(atype)\
  113. static atype* Create(SQSharedState *ss,SQInteger nInitialSize){\
  114. atype *newarray=(atype*)SQ_MALLOC(sizeof(atype));\
  115. new (newarray) atype(ss,nInitialSize);\
  116. return newarray;\
  117. }\
  118. atype *Clone(bool withData=true){\
  119. atype *anew=Create(_opt_ss(this),0);\
  120. if(withData) anew->_vec_values.copy(_vec_values);\
  121. return anew;\
  122. }\
  123. void Release(){sq_delete(this,atype);}\
  124. virtual SQInteger GetArrayType() { return eat_##atype;} \
  125. void DummyPinVtable();
  126. struct SQArray : public SQArrayBase
  127. {
  128. protected:
  129. SQObjectPtrVec _vec_values;
  130. SQArray(SQSharedState *ss,SQInteger nsize):SQArrayBase(ss, nsize){
  131. Resize(nsize);
  132. }
  133. public:
  134. #ifndef NO_GARBAGE_COLLECTOR
  135. virtual bool isCollectable(){return true;}
  136. #endif
  137. DECLARE_CLASS_ARRAY_MEMBERS(SQArray)
  138. SQUnsignedInteger SizeOf() const {return _vec_values.sizeOf();}
  139. SQUnsignedInteger Size() const {return _vec_values.size();}
  140. void Reserve(SQUnsignedInteger size) { _vec_values.reserve(size); }
  141. SQUnsignedInteger Capacity() { return _vec_values.capacity(); }
  142. bool Append(const SQObject &o){_vec_values.push_back(o); return true;}
  143. void Top(SQObjectPtr &out){out = _vec_values.top();}
  144. void Pop(){_vec_values.pop_back(); ShrinkIfNeeded(); }
  145. void _swap(SQInteger idx1, SQInteger idx2)
  146. {
  147. SQObjectPtr t = _vec_values[idx1];
  148. _vec_values[idx1] = _vec_values[idx2];
  149. _vec_values[idx2] = t;
  150. }
  151. void _copy(SQInteger idx1, SQInteger idx2)
  152. {
  153. _vec_values[idx1] = _vec_values[idx2];
  154. }
  155. bool _set(SQInteger idx1, SQObjectPtr &val)
  156. {
  157. _vec_values[idx1] = val;
  158. return true;
  159. }
  160. void _get2(SQInteger idx, SQObject& out)
  161. {
  162. out = _vec_values[idx];
  163. }
  164. virtual void *RawData() { return NULL;}
  165. private:
  166. virtual void _getObjectPtr(const SQInteger nidx,SQObjectPtr &val){
  167. val = _vec_values[nidx];
  168. }
  169. virtual void _getRealObjectPtr(const SQInteger nidx,SQObjectPtr &val){
  170. SQObjectPtr &o = _vec_values[nidx];
  171. val = _realval(o);
  172. }
  173. virtual bool _setObjectPtr(const SQInteger nidx, const SQObjectPtr &val){
  174. _vec_values[nidx] = val;
  175. return true;
  176. }
  177. virtual bool _resizeValues(SQInteger size,SQObjectPtr &fill){
  178. _vec_values.resize(size,fill);
  179. return true;
  180. }
  181. virtual bool _insertValue(SQInteger idx,const SQObject &val){
  182. _vec_values.insert(idx,val);
  183. return true;
  184. }
  185. virtual bool _removeValue(SQInteger idx){
  186. return _vec_values.remove(idx);
  187. }
  188. virtual void _shrinktofit(){
  189. _vec_values.shrinktofit();
  190. }
  191. };
  192. template <typename T>
  193. struct SQNumericBaseArray : public SQArrayBase
  194. {
  195. protected:
  196. sqvector<T> _vec_values;
  197. SQNumericBaseArray(SQSharedState *ss,SQInteger nsize):SQArrayBase(ss, nsize){
  198. Resize(nsize);
  199. }
  200. virtual bool isNumeric(const SQObject &o, T &tv)
  201. {
  202. return false;
  203. }
  204. public:
  205. #ifndef NO_GARBAGE_COLLECTOR
  206. virtual bool isCollectable(){return false;}
  207. #endif
  208. SQUnsignedInteger SizeOf() const {return _vec_values.sizeOf();}
  209. SQUnsignedInteger Size() const {return _vec_values.size();}
  210. void Reserve(SQUnsignedInteger size) { _vec_values.reserve(size); }
  211. SQUnsignedInteger Capacity() { return _vec_values.capacity(); }
  212. bool Append(const SQObject &o){
  213. T tv;
  214. if(!isNumeric(o, tv)) return false;
  215. _vec_values.push_back(tv);
  216. return true;
  217. }
  218. //void Top(SQObjectPtr& out){out = _vec_values.top();}
  219. void Pop(){_vec_values.pop_back(); ShrinkIfNeeded(); }
  220. void _swap(SQInteger idx1, SQInteger idx2)
  221. {
  222. T tmp = _vec_values[idx1];
  223. _vec_values[idx1] = _vec_values[idx2];
  224. _vec_values[idx2] = tmp;
  225. }
  226. void _copy(SQInteger idx1, SQInteger idx2)
  227. {
  228. _vec_values[idx1] = _vec_values[idx2];
  229. }
  230. bool _set(SQInteger idx1, SQObjectPtr &val)
  231. {
  232. T tv;
  233. if(!isNumeric(val, tv)) return false;
  234. _vec_values[idx1] = tv;
  235. return true;
  236. }
  237. virtual void *RawData() { return _vec_values._vals;}
  238. private:
  239. virtual bool _setObjectPtr(const SQInteger nidx, const SQObjectPtr &val){
  240. T tv;
  241. if(!isNumeric(val, tv)) return false;
  242. _vec_values[nidx] = tv;
  243. return true;
  244. }
  245. virtual bool _resizeValues(SQInteger size,SQObjectPtr &fill){
  246. T tv;
  247. switch(sq_type(fill))
  248. {
  249. case OT_NULL: tv = 0;break;
  250. case OT_FLOAT: tv = _float(fill);break;
  251. case OT_INTEGER: tv = _integer(fill);break;
  252. default:
  253. return false;
  254. }
  255. _vec_values.resize(size,tv);
  256. return true;
  257. }
  258. virtual bool _insertValue(SQInteger idx,const SQObject &val){
  259. T tv;
  260. if(!isNumeric(val, tv)) return false;
  261. _vec_values.insert(idx,tv);
  262. return true;
  263. }
  264. virtual bool _removeValue(SQInteger idx){
  265. return _vec_values.remove(idx);
  266. }
  267. virtual void _shrinktofit(){
  268. _vec_values.shrinktofit();
  269. }
  270. };
  271. template <typename T>
  272. struct SQFloatBaseArray : public SQNumericBaseArray<T>
  273. {
  274. protected:
  275. SQFloatBaseArray(SQSharedState *ss,SQInteger nsize):
  276. SQNumericBaseArray<T>(ss, nsize){
  277. }
  278. bool isNumeric(const SQObject &o, T &tv)
  279. {
  280. switch(sq_type(o))
  281. {
  282. case OT_FLOAT: tv = _float(o);break;
  283. case OT_INTEGER: tv = _integer(o);break;
  284. default:
  285. return false;
  286. }
  287. return true;
  288. }
  289. public:
  290. void Top(SQObjectPtr& out){out = (SQFloat)SQNumericBaseArray<T>::_vec_values.top();}
  291. virtual void _getObjectPtr(const SQInteger nidx,SQObjectPtr &val){
  292. val = (SQFloat)SQNumericBaseArray<T>::_vec_values[nidx];
  293. }
  294. virtual void _getRealObjectPtr(const SQInteger nidx,SQObjectPtr &val){
  295. SQObjectPtr o = (SQFloat)SQNumericBaseArray<T>::_vec_values[nidx];
  296. val = _realval(o);
  297. }
  298. void _get2(SQInteger idx, SQObject& val)
  299. {
  300. val._type = OT_FLOAT;
  301. _float(val) = SQNumericBaseArray<T>::_vec_values[idx];
  302. }
  303. };
  304. struct SQFloat64Array : public SQFloatBaseArray<SQFloat64>
  305. {
  306. protected:
  307. SQFloat64Array(SQSharedState *ss,SQInteger nsize):SQFloatBaseArray(ss, nsize){}
  308. public:
  309. DECLARE_CLASS_ARRAY_MEMBERS(SQFloat64Array)
  310. };
  311. struct SQFloat32Array : public SQFloatBaseArray<SQFloat32>
  312. {
  313. protected:
  314. SQFloat32Array(SQSharedState *ss,SQInteger nsize):SQFloatBaseArray(ss, nsize){}
  315. public:
  316. DECLARE_CLASS_ARRAY_MEMBERS(SQFloat32Array)
  317. };
  318. template <typename T>
  319. struct SQIntegerBaseArray : public SQNumericBaseArray<T>
  320. {
  321. protected:
  322. SQIntegerBaseArray(SQSharedState *ss,SQInteger nsize):
  323. SQNumericBaseArray<T>(ss, nsize){
  324. }
  325. bool isNumeric(const SQObject &o, T &tv)
  326. {
  327. switch(sq_type(o))
  328. {
  329. //case OT_FLOAT: tv = _float(o);break;
  330. case OT_INTEGER: tv = _integer(o);break;
  331. default:
  332. return false;
  333. }
  334. return true;
  335. }
  336. public:
  337. virtual void _getObjectPtr(const SQInteger nidx,SQObjectPtr &val){
  338. val = (SQInteger)SQNumericBaseArray<T>::_vec_values[nidx];
  339. }
  340. void Top(SQObjectPtr& out){out = (SQInteger)SQNumericBaseArray<T>::_vec_values.top();}
  341. virtual void _getRealObjectPtr(const SQInteger nidx,SQObjectPtr &val){
  342. SQObjectPtr o = (SQInteger)SQNumericBaseArray<T>::_vec_values[nidx];
  343. val = _realval(o);
  344. }
  345. void _get2(SQInteger idx, SQObject& val)
  346. {
  347. val._type = OT_INTEGER;
  348. _integer(val) = SQNumericBaseArray<T>::_vec_values[idx];
  349. }
  350. };
  351. struct SQInt64Array : public SQIntegerBaseArray<SQInt64>
  352. {
  353. protected:
  354. SQInt64Array(SQSharedState *ss,SQInteger nsize):SQIntegerBaseArray(ss, nsize){}
  355. public:
  356. DECLARE_CLASS_ARRAY_MEMBERS(SQInt64Array)
  357. };
  358. struct SQInt32Array : public SQIntegerBaseArray<SQInt32>
  359. {
  360. protected:
  361. SQInt32Array(SQSharedState *ss,SQInteger nsize):SQIntegerBaseArray(ss, nsize){}
  362. public:
  363. DECLARE_CLASS_ARRAY_MEMBERS(SQInt32Array)
  364. };
  365. struct SQInt16Array : public SQIntegerBaseArray<SQInt16>
  366. {
  367. protected:
  368. SQInt16Array(SQSharedState *ss,SQInteger nsize):SQIntegerBaseArray(ss, nsize){}
  369. public:
  370. DECLARE_CLASS_ARRAY_MEMBERS(SQInt16Array)
  371. };
  372. struct SQInt8Array : public SQIntegerBaseArray<SQInt8>
  373. {
  374. protected:
  375. SQInt8Array(SQSharedState *ss,SQInteger nsize):SQIntegerBaseArray(ss, nsize){}
  376. public:
  377. DECLARE_CLASS_ARRAY_MEMBERS(SQInt8Array)
  378. };
  379. #endif //_SQARRAY_H_