afPtrList.h
上传用户:kaiguan
上传日期:2007-10-28
资源大小:1074k
文件大小:12k
源码类别:

其他游戏

开发平台:

Visual C++

  1. #ifndef AF_PTRLIST
  2. #define AF_PTRLIST
  3. /// Template pointer list, with no refcounting
  4. #include <assert.h>
  5. #include <string.h>
  6. #include "afLog.h"
  7. #ifndef NULL
  8. #define NULL    0
  9. #endif
  10. template <class TYPE>
  11. class afPtrList
  12. {
  13. public:  
  14.  afPtrList();
  15.  afPtrList(const afPtrList<TYPE> &other);
  16.  virtual 
  17. ~afPtrList();
  18. /// Sets how much elements the list grows when growing is necessary
  19. bool
  20. setStandardGrowingSize(int size) const;
  21. /// Returns the number of objects currently stored in the list
  22. int
  23. getSize() const { return actualItemCount;};
  24. /// Returns true if the list is empty
  25. bool
  26. isEmpty() const { return actualItemCount==0;};
  27. /// Checks if the index is valid
  28. bool
  29. checkIndex(int index) const;
  30. /// Adds one element to the head of the list (SLOW)
  31. virtual bool
  32. addHead(TYPE* item);
  33. /// Adds one element to the tail of the list
  34. virtual bool
  35. addTail(TYPE* item);
  36. /// Inserts one element after the given index
  37. virtual bool
  38. insertAfter(int index,TYPE* item);
  39. /// Inserts one element before the given index
  40. virtual bool
  41. insertBefore(int index,TYPE* item);
  42. /// Overwrites one element
  43. virtual bool
  44. setAt(int index,TYPE* item);
  45. /// Replaces the indices of the 2 items
  46. virtual bool
  47. replaceIndices(int nIndexA,int nIndexB);
  48. /// Replaces the first found element which is equal to 'old'  with 'item'
  49. virtual bool
  50. replace(TYPE* old,TYPE* item);
  51. /// Replaces all elements which are equal to 'old' with 'item'
  52. virtual bool
  53. replaceAll(TYPE* old,TYPE* item);
  54. /// Returns the first element of the list
  55. TYPE*
  56. getHead();
  57. /// Returns the last element of the list
  58. TYPE*
  59. getTail();
  60. /// Returns the element at the given position
  61. TYPE*
  62. getAt(int index) const;
  63. /// Removing the first element of the list (SLOW)
  64. bool
  65. removeHead();
  66. /// Removing the last element of the list
  67. bool
  68. removeTail();
  69. /// Removes the first element 'item'
  70. bool
  71. removeItem(TYPE* item);
  72. /// Removes the element a position 'index'
  73. virtual bool
  74. removeIndex(int index);
  75. /// Empties the list.
  76. virtual bool
  77. removeAll();
  78. /// Finds the first element which is equal to 'item'
  79. int
  80. find(const TYPE* item);
  81. /// Finds the first element which is equal to 'item' and positioned after 'after'
  82. int
  83. findAfter(const TYPE* item,int after);
  84. /// Finds the first element which is equal to 'item' and positioned before 'before'
  85. int
  86. findBefore(const TYPE* item,int before);
  87. /// Returns a part of the list
  88. virtual afPtrList*
  89. getSubList(int from,int to);
  90. /// Gives direct access to the list members
  91.     TYPE* operator[](int index) const 
  92. { return getAt(index); }
  93. /// Copies a list from another list
  94.     virtual inline afPtrList<TYPE>&
  95. operator=(const afPtrList<TYPE>& other);
  96. /// Adds the elements of another list to this list
  97.     virtual inline afPtrList<TYPE>&
  98. operator+=(const afPtrList<TYPE>& other);
  99. protected:
  100. static int standardGrowingSize;
  101. int actualBlockSize;
  102. int actualItemCount;
  103. TYPE** array;
  104. bool enlargeList(int size=-1);
  105. bool reserveBlockSize(int size);
  106. bool //raises an error
  107. raiseError(const char* nError) const
  108. {  afLog::error(nError);  return false;  }
  109. //plString error;
  110. };
  111. template <class TYPE>
  112.  int afPtrList<TYPE>::standardGrowingSize = 16;
  113. template <class TYPE> inline
  114. afPtrList<TYPE>::afPtrList<TYPE>()
  115. {
  116. array = NULL;
  117. actualBlockSize = 0;
  118. actualItemCount = 0;
  119. enlargeList();
  120. }
  121. template <class TYPE> inline
  122. afPtrList<TYPE>::afPtrList<TYPE>(const afPtrList<TYPE> &other)
  123. {
  124. //afPtrList<TYPE>();
  125. array = NULL;
  126. actualBlockSize = 0;
  127. actualItemCount = 0;
  128. enlargeList();
  129. *this = other;
  130. }
  131. template <class TYPE> inline
  132. afPtrList<TYPE>::~afPtrList()
  133. {
  134. bool ret = removeAll();
  135. ret;
  136. assert(ret);
  137. if (array!=NULL)
  138. delete []array;
  139. array = NULL;
  140. }
  141. template <class TYPE> inline bool 
  142. afPtrList<TYPE>::enlargeList(int size)
  143. {
  144. TYPE** tempList;
  145. if (size == -1)
  146. size = standardGrowingSize;
  147. try
  148. {
  149. tempList = new TYPE*[actualBlockSize + size];
  150. int i;
  151. for (i=0; i < actualBlockSize;++i)
  152. tempList[i] = array[i];
  153. for (; i < ( actualBlockSize+size );++i)
  154. tempList[i] = NULL;
  155. if (array!=NULL)
  156. delete array;
  157. array = tempList;
  158. actualBlockSize += size;
  159. }
  160. catch(...)
  161. {
  162. // return RaiseError("in EnlargeList");
  163. }
  164. return true;
  165. }
  166. template <class TYPE> inline bool 
  167. afPtrList<TYPE>::setStandardGrowingSize(int size) const
  168. {
  169. if (size<1)
  170. return raiseError("Wrong Size");
  171. standardGrowingSize = size;
  172. return true;
  173. }
  174. template <class TYPE> inline bool 
  175. afPtrList<TYPE>::reserveBlockSize(int size)
  176. {
  177. if (actualBlockSize < actualItemCount+size)
  178. return enlargeList();
  179. return true;
  180. }
  181. template <class TYPE> inline bool 
  182. afPtrList<TYPE>::checkIndex(int index) const
  183. {
  184. if (index<0 || index > actualItemCount-1)
  185. return false;
  186. return true;
  187. }
  188. template <class TYPE> inline bool 
  189. afPtrList<TYPE>::addHead(TYPE* item)
  190. {
  191. if (!reserveBlockSize(1))
  192. return false;
  193. try
  194. {
  195. memmove((void*)(reinterpret_cast<unsigned>(array)+sizeof(TYPE*)),
  196. array,actualItemCount*sizeof(TYPE*));
  197. array[0] = item;
  198. ++actualItemCount;
  199. }
  200. catch(...)
  201. {
  202. // return RaiseError("in AddHead");
  203. }
  204. return true;
  205. }
  206. template <class TYPE> inline bool 
  207. afPtrList<TYPE>::addTail(TYPE* item)
  208. {
  209. if (!reserveBlockSize(1))
  210. return false;
  211. try
  212. {
  213. array[actualItemCount] = item;
  214. ++actualItemCount;
  215. }
  216. catch(...)
  217. {
  218. // return RaiseError("in AddTail");
  219. }
  220. return true;
  221. }
  222. template <class TYPE> inline bool 
  223. afPtrList<TYPE>::insertAfter(int index,TYPE* item)
  224. {
  225. if (!checkIndex(index))
  226. return raiseError("IndexError");
  227. if (index == actualItemCount-1)
  228. return addTail(item);
  229. else
  230. {
  231. if (!reserveBlockSize(1))
  232. return false;
  233. try
  234. {
  235. memmove((void*)(reinterpret_cast<unsigned>(array)+(index+2)*sizeof(TYPE*)),
  236. (void*)(reinterpret_cast<unsigned>(array)+(index+1)*sizeof(TYPE*)),
  237. (actualItemCount-index-1)*sizeof(TYPE*));
  238. array[index+1] = item;
  239. ++actualItemCount;
  240. }
  241. catch(...)
  242. {
  243. // return RaiseError("in InsertAfter");
  244. }
  245. }
  246. return true;
  247. }
  248. template <class TYPE> inline bool 
  249. afPtrList<TYPE>::insertBefore(int index,TYPE* item)
  250. {
  251. if (!checkIndex(index))
  252. return raiseError("IndexError");
  253. if (index == 0)
  254. return addHead(item);
  255. else
  256. {
  257. if (!reserveBlockSize(1))
  258. return false;
  259. try
  260. {
  261. memmove((void*)(reinterpret_cast<unsigned>(array)+(index+1)*sizeof(TYPE*)),
  262. (void*)(reinterpret_cast<unsigned>(array)+(index)*sizeof(TYPE*)),
  263. (actualItemCount-index)*sizeof(TYPE*));
  264. array[index] = item;
  265. ++actualItemCount;
  266. }
  267. catch(...)
  268. {
  269. return raiseError("in InsertBefore");
  270. }
  271. }
  272. return true;
  273. }
  274. template <class TYPE> inline bool 
  275. afPtrList<TYPE>::setAt(int index,TYPE* item)
  276. {
  277. if (!checkIndex(index))
  278. return raiseError("IndexError");
  279. try
  280. {
  281. array[index] = item;
  282. }
  283. catch(...)
  284. {
  285. // return RaiseError("in SetAt");
  286. }
  287. return true;
  288. }
  289. template <class TYPE> inline bool
  290. afPtrList<TYPE>::replaceIndices(int nIndexA,int nIndexB)
  291. {
  292. if (!checkIndex(nIndexA))
  293. return false;
  294. if (!checkIndex(nIndexB))
  295. return false;
  296. TYPE *item = array[nIndexA];
  297. array[nIndexA] = array[nIndexB];
  298. array[nIndexB] = item;
  299. return true;
  300. }
  301. template <class TYPE> inline bool 
  302. afPtrList<TYPE>::replace(TYPE* old,TYPE* item)
  303. {
  304. bool ret = false;
  305. for (int i=0; i < actualItemCount; ++i)
  306. if (array[i] == old)
  307. {
  308. array[i] = item;
  309. ret = true;
  310. break;
  311. }
  312. return ret;
  313. }
  314. template <class TYPE> inline bool 
  315. afPtrList<TYPE>::replaceAll(TYPE* old,TYPE* item)
  316. {
  317. bool ret = false;
  318. for (int i=0; i < actualItemCount; ++i)
  319. if (array[i] == old)
  320. {
  321. array[i] = item;
  322. ret = true;
  323. }
  324. return ret;
  325. }
  326. template <class TYPE> inline TYPE* 
  327. afPtrList<TYPE>::getHead()
  328. {
  329. TYPE* ret = NULL;
  330. if (actualItemCount>0)
  331. {
  332. // RaiseError("Item not found");
  333. return NULL;
  334. }
  335. try
  336. {
  337. ret = array[0];
  338. }
  339. catch(...)
  340. {
  341. // RaiseError("in GetHead");
  342. return NULL;
  343. }
  344. return ret;
  345. }
  346. template <class TYPE> inline TYPE* 
  347. afPtrList<TYPE>::getTail()
  348. {
  349. TYPE* ret = NULL;
  350. if (actualItemCount<1)
  351. return NULL;
  352. try
  353. {
  354. ret = array[actualItemCount-1];
  355. }
  356. catch(...)
  357. {
  358. // RaiseError("in GetTail");
  359. return NULL;
  360. }
  361. return ret;
  362. }
  363. template <class TYPE> inline TYPE* 
  364. afPtrList<TYPE>::getAt(int index) const
  365. {
  366. TYPE* ret = NULL;
  367. if (!checkIndex(index))
  368. {
  369. // RaiseError("IndexError");
  370. return NULL;
  371. }
  372. try
  373. {
  374. ret = array[index];
  375. assert(ret!=NULL);
  376. }
  377. catch(...)
  378. {
  379. // RaiseError("in Get At");
  380. return NULL;
  381. }
  382. return ret;
  383. }
  384. template <class TYPE> inline bool 
  385. afPtrList<TYPE>::removeHead()
  386. {
  387. return removeIndex(0);
  388. }
  389. template <class TYPE> inline bool 
  390. afPtrList<TYPE>::removeTail()
  391. {
  392. return removeIndex(actualItemCount-1);
  393. }
  394. template <class TYPE> inline bool 
  395. afPtrList<TYPE>::removeItem(TYPE* item)
  396. {
  397. int index;
  398. index = find(item);
  399. if (index < 0)
  400. return false;
  401. return removeIndex(index);
  402. }
  403. template <class TYPE> inline bool 
  404. afPtrList<TYPE>::removeIndex(int index)
  405. {
  406. if (!checkIndex(index))
  407. return raiseError("IndexError");
  408. try
  409. {
  410. memmove((void*)(reinterpret_cast<unsigned>(array)+(index)*sizeof(TYPE*)),
  411. (void*)(reinterpret_cast<unsigned>(array)+(index+1)*sizeof(TYPE*)),
  412. (actualItemCount-index-1)*sizeof(TYPE*));
  413. --actualItemCount;
  414. }
  415. catch(...)
  416. {
  417. // return RaiseError("in RemoveIndex");
  418. }
  419. return true;
  420. }
  421. template <class TYPE> inline bool 
  422. afPtrList<TYPE>::removeAll()
  423. {
  424. try
  425. {
  426. actualItemCount = 0;
  427. }
  428. catch(...)
  429. {
  430. // return RaiseError("in RemoveAll");
  431. }
  432. return true;
  433. }
  434. template <class TYPE> inline int 
  435. afPtrList<TYPE>::find(const TYPE* item)
  436. {
  437. int ret = -1;
  438. try
  439. {
  440. for (int i=0; i < actualItemCount; ++i)
  441. if (item == array[i])
  442. {
  443. ret = i;
  444. break;
  445. }
  446. }
  447. catch(...)
  448. {
  449. // return RaiseError("in Find");
  450. }
  451. return ret;
  452. }
  453. template <class TYPE> inline int 
  454. afPtrList<TYPE>::findAfter(const TYPE* item,int after)
  455. {
  456. int ret = -1;
  457. int index = after+1;
  458. if (!checkIndex(index))
  459. return raiseError("IndexError");
  460. try
  461. {
  462. for (int i=index; i < actualItemCount; ++i)
  463. if (item == array[i])
  464. {
  465. ret = i;
  466. break;
  467. }
  468. }
  469. catch(...)
  470. {
  471. // return RaiseError("in FindAfter");
  472. }
  473. return ret;
  474. }
  475. template <class TYPE> inline int 
  476. afPtrList<TYPE>::findBefore(const TYPE* item,int before)
  477. {
  478. int ret = -1;
  479. int index = before-1;
  480. if (!checkIndex(index))
  481. return raiseError("IndexError");
  482. try
  483. {
  484. for (int i=0; i < before; ++i)
  485. if (item == array[i])
  486. {
  487. ret = i;
  488. break;
  489. }
  490. }
  491. catch(...)
  492. {
  493. // return RaiseError("in FindBefore");
  494. }
  495. return ret;
  496. }
  497. template <class TYPE> inline afPtrList<TYPE>* 
  498. afPtrList<TYPE>::getSubList(int from,int to)
  499. {
  500. if (!checkIndex(from))
  501. {
  502. // RaiseError("IndexError");
  503. return NULL;
  504. }
  505. if (!checkIndex(to))
  506. {
  507. // RaiseError("IndexError");
  508. return NULL;
  509. }
  510. if (from < to)
  511. {
  512. // RaiseError("IndexError");
  513. return NULL;
  514. }
  515. afPtrList<TYPE> *ret = new afPtrList<TYPE>;
  516. try
  517. {
  518. for (int i=from; i < to; ++i)
  519. ret->addTail(array[i]);
  520. }
  521. catch(...)
  522. {
  523. delete ret;
  524. // RaiseError("in GetSubList");
  525. return NULL;
  526. }
  527. return ret;
  528. }
  529. template <class TYPE> inline afPtrList<TYPE>&
  530. afPtrList<TYPE>::operator=(const afPtrList<TYPE>& other)
  531. {
  532. removeAll();
  533. for (int i=0;i<other.getSize();++i)
  534. addTail(other[i]);
  535. return *this;
  536. }
  537. template <class TYPE> inline afPtrList<TYPE>&
  538. afPtrList<TYPE>::operator+=(const afPtrList<TYPE>& other)
  539. {
  540. for (int i=0;i<other.getSize();++i)
  541. addTail(other[i]);
  542. return *this;
  543. }
  544. #endif