EList.h 48 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458
  1. #ifndef ELIST_H
  2. #define ELIST_H
  3. #pragma warning( disable : 4211 )
  4. #include <memory.h>
  5. #include "heap.h"
  6. //--------------------------------------------------------------------------------------
  7. //
  8. // Mech Commander 2
  9. //
  10. // standard linked list
  11. //
  12. //---------------------------------------------------------------------------//
  13. // Copyright (C) Microsoft Corporation. All rights reserved. //
  14. //===========================================================================//
  15. //*************************************************************************************************
  16. #define ELIST_TPL_DEF template<class T, class T_ARG>
  17. #define ELIST_TPL_ARG T, T_ARG
  18. //*************************************************************************************************
  19. /**************************************************************************************************
  20. CLASS DESCRIPTION
  21. EList:
  22. This template class is a doubly linked list. The list is implemented using a fixed memory pool,
  23. which ensures proximity of all the elements, in order to increase the cacheability of the list.
  24. Two template parameters are required to declare a list. The first is the type of the object,
  25. that is intended to be stored in the list. The second is the type by which we intend to pass the
  26. object.
  27. The user needs to pass the initial element count and the amount of elements to grow the
  28. memory pool by, if required to accomodate all elements, to the constructor.
  29. Optionally a name can be supplied, however this will only be used during debug builds.
  30. Example:
  31. EList<KSomeClass, const KSomeClass&> m_List(10, 5, "SomeList");
  32. EList<int, const int> m_List(100, 10);
  33. Note:
  34. The second template argument is const to provide for const safety.
  35. It is syntacticly legal to use a non-const version, however, it will not provide
  36. const safty. Unfortunately there is no way to prevent this.
  37. Classes used with the list need to define a copy constructor, an assignment operator, and
  38. an equality operator in order to work properly (of course only if the default versions are
  39. not sufficient).
  40. **************************************************************************************************/
  41. #ifndef __PLACEMENT_NEW_INLINE
  42. #define __PLACEMENT_NEW_INLINE
  43. inline void *__cdecl operator new(size_t, void *_P)
  44. {return (_P); } // placement new
  45. #endif
  46. ELIST_TPL_DEF class EList
  47. {
  48. protected:
  49. //
  50. // The node is used to chain the elements of the list together, it contains pointers
  51. // to the elements preceeding or following it, in addition to the element itself.
  52. // If no preceeding or following element are present the value is NULL
  53. //
  54. struct ENode
  55. {
  56. ENode(T_ARG New_Element) : m_Data(New_Element) {};
  57. ENode* m_pNext;
  58. ENode* m_pPrev;
  59. T m_Data;
  60. private:
  61. ENode& operator=(const ENode& rNode);
  62. };
  63. enum
  64. {
  65. MAX_NAME_LENGTH = 64
  66. };
  67. public:
  68. /**************************************************************************************************
  69. CLASS DESCRIPTION
  70. EList::EConstIterator
  71. This class is used to iterate through the List. You can read objects with this iterator but you
  72. can't change them. Use class !!(EIterator) for changing objects.
  73. **************************************************************************************************/
  74. class EConstIterator
  75. {
  76. public:
  77. // Note: Code needs to be implemented in class decleration, due
  78. // to MSVC bug with nested template classes
  79. inline EConstIterator() { m_pCur_Node = NULL; }
  80. inline EConstIterator(const EConstIterator& rIter) { m_pCur_Node = rIter.m_pCur_Node; }
  81. inline EConstIterator& operator=(const EConstIterator& rIter) { m_pCur_Node = rIter.m_pCur_Node; return(*this); }
  82. //
  83. // NOTE: Postfix operators require "int" to be passed as parameter,
  84. // else compiler error C2807 will occur when used
  85. //
  86. inline EConstIterator& operator++(int) // postfix increment
  87. {
  88. #ifdef DEBUG
  89. if(!(IsValid()))
  90. {
  91. gosASSERT("EList::EIterator: Attempt to increment invalid iterator\n");
  92. }
  93. #endif
  94. m_pCur_Node = m_pCur_Node->m_pNext;
  95. return(*this);
  96. }
  97. inline EConstIterator& operator--(int) // postfix decrement
  98. {
  99. #ifdef KTL_DEBUG
  100. if(!(IsValid()))
  101. {
  102. Assert("EList::EIterator: Attempt to decrement invalid iterator\n");
  103. }
  104. #endif
  105. m_pCur_Node = m_pCur_Node->m_pPrev;
  106. return(*this);
  107. }
  108. inline EConstIterator& operator+=(unsigned long Increment)
  109. {
  110. while(Increment)
  111. {
  112. #ifdef KTL_DEBUG
  113. if(!(IsValid()))
  114. {
  115. Assert("EList::EIterator: Attempt to increment invalid iterator\n");
  116. }
  117. #endif
  118. m_pCur_Node = m_pCur_Node->m_pNext;
  119. Increment--;
  120. }
  121. return(*this);
  122. }
  123. inline EConstIterator& operator-=(unsigned long Decrement)
  124. {
  125. while(Decrement)
  126. {
  127. #ifdef KTL_DEBUG
  128. if(!(IsValid()))
  129. {
  130. Assert("EList::EIterator: Attempt to increment invalid iterator\n");
  131. }
  132. #endif
  133. m_pCur_Node = m_pCur_Node->m_pPrev;
  134. Decrement--;
  135. }
  136. return(*this);
  137. }
  138. inline bool operator==(const EConstIterator& rIter) const
  139. {
  140. return(m_pCur_Node == rIter.m_pCur_Node);
  141. }
  142. inline bool operator!=(const EConstIterator& rIter) const
  143. {
  144. return(m_pCur_Node != rIter.m_pCur_Node);
  145. }
  146. inline T_ARG operator*() const
  147. {
  148. return Item();
  149. }
  150. inline T_ARG Item() const { return(m_pCur_Node->m_Data); }
  151. inline bool IsValid() const { return(m_pCur_Node ? true : false); }
  152. inline bool IsDone() const { return(m_pCur_Node ? false : true); }
  153. friend class EList<ELIST_TPL_ARG>;
  154. protected:
  155. ENode* m_pCur_Node;
  156. #ifdef KTL_DEBUG
  157. char m_Name[64];
  158. #endif
  159. }; // END CLASS EConstIterator
  160. /**************************************************************************************************
  161. CLASS DESCRIPTION
  162. EList::EIterator
  163. This class is used for non constant iteration through a list.
  164. **************************************************************************************************/
  165. class EIterator : public EConstIterator
  166. {
  167. public:
  168. inline EIterator() : EConstIterator() {}
  169. inline EIterator(const EIterator& rIter) : EConstIterator(rIter) {}
  170. inline T& Item() { return(m_pCur_Node->m_Data); }
  171. inline T& operator*()
  172. {
  173. return Item();
  174. }
  175. }; // END CLASS EIterator
  176. //===== ENUMERATIONS & CONSTANTS =====
  177. typename static const EIterator INVALID_ITERATOR;
  178. //===== CREATORS =====
  179. inline EList();
  180. EList(const EList<ELIST_TPL_ARG>& rList);
  181. ~EList();
  182. //===== OPERATORS =====
  183. EList<ELIST_TPL_ARG>& operator=(const EList<ELIST_TPL_ARG>& rList);
  184. inline T& operator[](unsigned long Pos);
  185. inline T& operator[](const typename EList<ELIST_TPL_ARG>::EIterator& rIter);
  186. inline T_ARG operator[](unsigned long Pos) const;
  187. inline T_ARG operator[](const typename EList<ELIST_TPL_ARG>::EIterator& rIter) const;
  188. inline bool operator==(const EList<ELIST_TPL_ARG>& rList) const;
  189. inline bool operator!=(const EList<ELIST_TPL_ARG>& rList) const;
  190. //===== MANIPULATORS =====
  191. bool Clear();
  192. inline bool Prepend(T_ARG New_Element); // Add an element to the start of the list
  193. inline bool Append(T_ARG New_Element); // Add an element to the end of the list
  194. inline bool Insert(T_ARG New_Element, const typename EList<ELIST_TPL_ARG>::EIterator& rIter); // Insert an element bofore the specified position
  195. inline bool Insert(T_ARG New_Element, unsigned long Pos); // Insert an element bofore the specified position
  196. bool Prepend(const EList<ELIST_TPL_ARG>& rList); // Prepend a list to this one
  197. bool Append(const EList<ELIST_TPL_ARG>& rList); // Append a list to this one
  198. bool Insert(const EList<ELIST_TPL_ARG>& rList, const typename EList<ELIST_TPL_ARG>::EIterator& rIter); // Insert a list at the specified position
  199. bool Insert(const EList<ELIST_TPL_ARG>& rList, unsigned long Pos); // Insert a list at the specified position
  200. inline bool DeleteHead(); // Remove the element at the beginning of the list
  201. inline bool DeleteTail(); // Remove the element at the end of the list
  202. inline bool Delete(const typename EList<ELIST_TPL_ARG>::EIterator& rIter); // Remove the element at the specified position
  203. inline bool Delete(unsigned long Pos); // Remove the element at the specified position
  204. inline bool Delete(const typename EList<ELIST_TPL_ARG>::EIterator& rStart_Iter, const typename EList<ELIST_TPL_ARG>::EIterator& rEnd_Iter); // Remove the element at the specified position
  205. inline bool Delete(unsigned long Start_Pos, unsigned long End_Pos); // Remove the element at the specified position
  206. inline bool Replace(T_ARG Element, const typename EList<ELIST_TPL_ARG>::EIterator& rIter); // Replace an element at the specified position
  207. inline bool Replace(T_ARG Element, unsigned long Pos); // Replace an element at the specified position
  208. inline typename EList<ELIST_TPL_ARG>::EIterator Iterator(unsigned long Pos);
  209. inline const typename EList<ELIST_TPL_ARG>::EConstIterator Iterator(unsigned long Pos) const;
  210. inline typename EList<ELIST_TPL_ARG>::EIterator Begin();
  211. inline const typename EList<ELIST_TPL_ARG>::EConstIterator Begin() const;
  212. inline typename EList<ELIST_TPL_ARG>::EIterator End();
  213. inline const typename EList<ELIST_TPL_ARG>::EConstIterator End() const;
  214. inline T& Get(const typename EList<const ELIST_TPL_ARG>::EIterator& rIter); // Retrieve the element at the specified position
  215. inline T& Get(unsigned long Pos); // Retrieve the element at the specified position
  216. inline T& GetHead(); // Retrieve the element at the start of the list
  217. inline T& GetTail(); // Retrieve the element at the end of the list
  218. //===== ACCESSORS =====
  219. inline T_ARG Get(const typename EList<ELIST_TPL_ARG>::EConstIterator& rIter) const; // Retrieve the element at the specified position
  220. inline T_ARG Get(unsigned long Pos) const; // Retrieve the element at the specified position
  221. inline T_ARG GetHead() const; // Retrieve the element at the start of the list
  222. inline T_ARG GetTail() const; // Retrieve the element at the end of the list
  223. inline unsigned long Count() const; // Get the number of elements in the list
  224. inline bool IsEmpty() const; // Check if the list is empty
  225. inline bool Exists(unsigned long Pos) const;// Check if an element at that position exists
  226. inline typename EList<ELIST_TPL_ARG>::EConstIterator Find(T_ARG Item, unsigned long Start_Index = 0) const;
  227. inline typename EList<ELIST_TPL_ARG>::EIterator Find(T_ARG Item, unsigned long Start_Index = 0);
  228. inline typename EList<ELIST_TPL_ARG>::EConstIterator Find(T_ARG Item, const typename EList<ELIST_TPL_ARG>::EConstIterator& rStart_Iterator) const;
  229. inline typename EList<ELIST_TPL_ARG>::EIterator Find(T_ARG Item, const typename EList<ELIST_TPL_ARG>::EIterator& rStart_Iterator);
  230. inline unsigned long GrowSize() const; // Get the growsize of list
  231. private:
  232. //===== DATA =====
  233. unsigned long m_Count; // number of elements currently in list
  234. ENode* m_pHead; // pointer to first node in list
  235. ENode* m_pTail; // pointer to last node in list
  236. //===== HELPER FUNCTIONS =====
  237. inline bool AddFirstElement(T_ARG New_Element);
  238. inline typename EList<ELIST_TPL_ARG>::ENode* CreateElement(T_ARG New_Element);
  239. inline void KillElement(ENode* pElement);
  240. void DestroyList();
  241. bool CopyData(const EList<ELIST_TPL_ARG>& rSrc);
  242. }; // END CLASS EList
  243. //*************************************************************************************************
  244. // Constants
  245. //*************************************************************************************************
  246. ELIST_TPL_DEF const typename EList<ELIST_TPL_ARG>::EIterator EList<ELIST_TPL_ARG>::INVALID_ITERATOR = EList<ELIST_TPL_ARG>::EIterator();
  247. //*************************************************************************************************
  248. // Inline Functions
  249. //*************************************************************************************************
  250. //-------------------------------------------------------------------------------------------------
  251. // CREATORS
  252. //-------------------------------------------------------------------------------------------------
  253. /**************************************************************************************************
  254. FUNCTION DESCRIPTION:
  255. EList
  256. Standard constructor used to instantiate a list
  257. INPUT PARAMETERS:
  258. Size: Initial size of the memory pool in number of elements
  259. Grow: The size in elements to grow the pool when required
  260. pName: The name of the list (optional)
  261. ***************************************************************************************************/
  262. ELIST_TPL_DEF inline EList<ELIST_TPL_ARG>::EList()
  263. : m_Count(0), m_pHead(NULL), m_pTail(NULL)
  264. {
  265. }
  266. /**************************************************************************************************
  267. FUNCTION DESCRIPTION:
  268. EList
  269. Copy constructor of the list
  270. INPUT PARAMETERS:
  271. rList:
  272. The list to be made a copy of
  273. ***************************************************************************************************/
  274. ELIST_TPL_DEF EList<ELIST_TPL_ARG>::EList(const EList<ELIST_TPL_ARG>& rList)
  275. {
  276. CopyData(rList);
  277. }
  278. /**************************************************************************************************
  279. FUNCTION DESCRIPTION:
  280. ~EList
  281. List Destructor, deletes all the elements in the list and then frees the memory pool
  282. ***************************************************************************************************/
  283. ELIST_TPL_DEF EList<ELIST_TPL_ARG>::~EList()
  284. {
  285. DestroyList();
  286. }
  287. //-------------------------------------------------------------------------------------------------
  288. // OPERATORS
  289. //-------------------------------------------------------------------------------------------------
  290. /**************************************************************************************************
  291. FUNCTION DESCRIPTION:
  292. operator=
  293. Assignment operator, destroys the current elements and creates copies of all the
  294. elements in the source list and adds them to this list.
  295. INPUT PARAMETERS:
  296. rList: The list to be assigned to this one
  297. RETURN VALUE:
  298. A reference to this list
  299. ***************************************************************************************************/
  300. ELIST_TPL_DEF EList<ELIST_TPL_ARG>& EList<ELIST_TPL_ARG>::operator=(const EList<ELIST_TPL_ARG>& rList)
  301. {
  302. //
  303. // Get rid of any list entries that might be used
  304. //
  305. DestroyList();
  306. CopyData(rList);
  307. return(*this);
  308. }
  309. /**************************************************************************************************
  310. FUNCTION DESCRIPTION:
  311. operator[]
  312. Retrieve a reference to an element in the list.
  313. Const versions of these functions are also supplied
  314. INPUT PARAMETERS:
  315. rIter: An iterator that points at the element for which we want a reference
  316. Pos: Position of the element in the list for which we want a reference
  317. RETURN VALUE:
  318. A reference to the desired element
  319. ***************************************************************************************************/
  320. ELIST_TPL_DEF inline T& EList<ELIST_TPL_ARG>::operator[](const typename EList<ELIST_TPL_ARG>::EIterator& rIter)
  321. {
  322. gosASSERT(rIter.IsValid() && m_Count); // Make sure we are using a valid iterator and have something in the list
  323. return(rIter.m_pCur_Node->m_Data);
  324. }
  325. //-------------------------------------------------------------------------------------------------
  326. ELIST_TPL_DEF inline T& EList<ELIST_TPL_ARG>::operator[](unsigned long Pos)
  327. {
  328. gosASSERT(Pos < m_Count); // Need to stay within range of number of elements
  329. return operator[](Iterator((unsigned long)Pos));
  330. }
  331. //-------------------------------------------------------------------------------------------------
  332. ELIST_TPL_DEF inline T_ARG EList<ELIST_TPL_ARG>::operator[](const typename EList<ELIST_TPL_ARG>::EIterator& rIter) const
  333. {
  334. gosASSERT(rIter.IsValid() && m_Count); // Make sure we are using a valid iterator and have something in the list
  335. return(rIter.m_pCur_Node->m_Data);
  336. }
  337. //-------------------------------------------------------------------------------------------------
  338. ELIST_TPL_DEF inline T_ARG EList<ELIST_TPL_ARG>::operator[](unsigned long Pos) const
  339. {
  340. gosASSERT(Pos < m_Count); // Need to stay within range of number of elements
  341. return(Get(Iterator(Pos)));
  342. }
  343. /**************************************************************************************************
  344. FUNCTION DESCRIPTION:
  345. operator==
  346. Equality operator, tests if this and another list are equal
  347. INPUT PARAMETERS:
  348. rList: Reference to the list we want to compare this one with
  349. RETURN VALUE:
  350. TRUE if equal, FALSE if not
  351. ***************************************************************************************************/
  352. ELIST_TPL_DEF inline bool EList<ELIST_TPL_ARG>::operator==(const EList<ELIST_TPL_ARG>& rList) const
  353. {
  354. //
  355. // If the count of elements is different in each list,
  356. // they're not equal
  357. //
  358. if(m_Count != rList.m_Count)
  359. {
  360. return(false);
  361. }
  362. //
  363. // In case both lists are empty, they're equal, however, we don't
  364. // want to iterate if there is nothing to iterate
  365. //
  366. if(m_Count == 0 && rList.m_Count == 0)
  367. {
  368. return(true);
  369. }
  370. EConstIterator List_Iter = rList.Begin();
  371. EConstIterator This_Iter = Begin();
  372. //
  373. // Iterate through both lists and check if they're equal
  374. //
  375. for(unsigned long i = 0; i < m_Count; i++)
  376. {
  377. if(List_Iter.Item() != This_Iter.Item())
  378. {
  379. return(false);
  380. }
  381. }
  382. return(true);
  383. }
  384. //-------------------------------------------------------------------------------------------------
  385. ELIST_TPL_DEF inline bool EList<ELIST_TPL_ARG>::operator!=(const EList<ELIST_TPL_ARG>& rList) const
  386. {
  387. return(!(rList == *this));
  388. }
  389. //-------------------------------------------------------------------------------------------------
  390. // MANIPULATORS
  391. //-------------------------------------------------------------------------------------------------
  392. /**************************************************************************************************
  393. FUNCTION DESCRIPTION:
  394. Iterator
  395. Get an iterator that points at the element corresponding with the Position passed
  396. INPUT PARAMETERS:
  397. Pos: The position of the element we want an iterator for
  398. RETURN VALUE:
  399. An iterator that points at the element at the position we passed
  400. ***************************************************************************************************/
  401. ELIST_TPL_DEF inline typename EList<ELIST_TPL_ARG>::EIterator EList<ELIST_TPL_ARG>::Iterator(unsigned long Pos)
  402. {
  403. gosASSERT(Pos < m_Count && m_Count); // Need to stay within range of number of elements
  404. if(!m_Count)
  405. {
  406. return(INVALID_ITERATOR);
  407. }
  408. //
  409. // Iterate through the list until we get to the element we desire
  410. //
  411. ENode *pNode = m_pHead;
  412. for(unsigned long i = 0; i < Pos; i++)
  413. {
  414. pNode = pNode->m_pNext;
  415. }
  416. EIterator Iter;
  417. Iter.m_pCur_Node = pNode;
  418. return(Iter);
  419. }
  420. //-------------------------------------------------------------------------------------------------
  421. ELIST_TPL_DEF inline const typename EList<ELIST_TPL_ARG>::EConstIterator EList<ELIST_TPL_ARG>::Iterator(unsigned long Pos) const
  422. {
  423. gosASSERT(Pos < m_Count && m_Count); // Need to stay within range of number of elements
  424. if(!m_Count)
  425. {
  426. return(INVALID_ITERATOR);
  427. }
  428. //
  429. // Iterate through the list until we get to the element we desire
  430. //
  431. ENode *pNode = m_pHead;
  432. for(unsigned long i = 0; i < Pos; i++)
  433. {
  434. pNode = pNode->m_pNext;
  435. }
  436. EIterator Iter;
  437. Iter.m_pCur_Node = pNode;
  438. return(Iter);
  439. }
  440. /**************************************************************************************************
  441. FUNCTION DESCRIPTION:
  442. Begin
  443. Get an iterator that points at the head element of the list.
  444. Also available as const version
  445. RETURN VALUE:
  446. An iterator that points at the head element
  447. ***************************************************************************************************/
  448. ELIST_TPL_DEF inline typename EList<ELIST_TPL_ARG>::EIterator EList<ELIST_TPL_ARG>::Begin()
  449. {
  450. if(!m_Count)
  451. {
  452. return(INVALID_ITERATOR);
  453. }
  454. EIterator Iter;
  455. Iter.m_pCur_Node = m_pHead;
  456. return(Iter);
  457. }
  458. //-------------------------------------------------------------------------------------------------
  459. ELIST_TPL_DEF inline const typename EList<ELIST_TPL_ARG>::EConstIterator EList<ELIST_TPL_ARG>::Begin() const
  460. {
  461. if(!m_Count)
  462. {
  463. return(INVALID_ITERATOR);
  464. }
  465. EIterator Iter;
  466. Iter.m_pCur_Node = m_pHead;
  467. return(Iter);
  468. }
  469. /**************************************************************************************************
  470. FUNCTION DESCRIPTION:
  471. End
  472. Get an iterator that points at the tail element of the list
  473. Also available as const version
  474. RETURN VALUE:
  475. An iterator that points at the tail element
  476. ***************************************************************************************************/
  477. ELIST_TPL_DEF inline typename EList<ELIST_TPL_ARG>::EIterator EList<ELIST_TPL_ARG>::End()
  478. {
  479. gosASSERT(m_Count); // Don't try to get an iterator if list is empty
  480. if(!m_Count)
  481. {
  482. return(INVALID_ITERATOR);
  483. }
  484. EIterator Iter;
  485. Iter.m_pCur_Node = m_pTail;
  486. return(Iter);
  487. }
  488. //-------------------------------------------------------------------------------------------------
  489. ELIST_TPL_DEF inline const typename EList<ELIST_TPL_ARG>::EConstIterator EList<ELIST_TPL_ARG>::End() const
  490. {
  491. gosASSERT(m_Count); // Don't try to get an iterator if list is empty
  492. if(!m_Count)
  493. {
  494. return(INVALID_ITERATOR);
  495. }
  496. EIterator Iter;
  497. Iter.m_pCur_Node = m_pTail;
  498. return(Iter);
  499. }
  500. /**************************************************************************************************
  501. FUNCTION DESCRIPTION:
  502. Clear
  503. Deletes all elements from the list
  504. RETURN VALUE:
  505. TRUE if success
  506. ***************************************************************************************************/
  507. ELIST_TPL_DEF bool EList<ELIST_TPL_ARG>::Clear()
  508. {
  509. DestroyList();
  510. return(true); // <<HACK>> BR - need to do checking
  511. }
  512. /**************************************************************************************************
  513. FUNCTION DESCRIPTION:
  514. Prepend
  515. Prepend an element to the list, this element will be the new head element
  516. INPUT PARAMETERS:
  517. New_Element: The element we want to prepend to the list
  518. RETURN VALUE:
  519. TRUE if success
  520. ***************************************************************************************************/
  521. ELIST_TPL_DEF inline bool EList<ELIST_TPL_ARG>::Prepend(T_ARG New_Element)
  522. {
  523. //
  524. // If the list is empty, let's create the first element
  525. //
  526. if(IsEmpty())
  527. {
  528. return(AddFirstElement(New_Element));
  529. }
  530. //
  531. // Otherwise create a new element and prepend to to the list
  532. //
  533. ENode* pNode = CreateElement(New_Element);
  534. if(pNode)
  535. {
  536. m_pHead->m_pPrev = pNode;
  537. pNode->m_pNext = m_pHead;
  538. pNode->m_pPrev = NULL;
  539. m_pHead = pNode;
  540. m_Count++;
  541. return(true);
  542. }
  543. return(false); // <<HACK>> BR
  544. }
  545. /**************************************************************************************************
  546. FUNCTION DESCRIPTION:
  547. Append
  548. Append an element to the list, this element will be the new tail element
  549. INPUT PARAMETERS:
  550. New_Element: The element we want to append to the list
  551. RETURN VALUE:
  552. TRUE if success
  553. ***************************************************************************************************/
  554. ELIST_TPL_DEF inline bool EList<ELIST_TPL_ARG>::Append(T_ARG New_Element)
  555. {
  556. //
  557. // If the list is empty, let's create the first element
  558. //
  559. if(IsEmpty())
  560. {
  561. return(AddFirstElement(New_Element));
  562. }
  563. //
  564. // Otherwise create a new element and append to to the list
  565. //
  566. ENode* pNode = CreateElement(New_Element);
  567. if(pNode)
  568. {
  569. m_pTail->m_pNext = pNode;
  570. pNode->m_pPrev = m_pTail;
  571. pNode->m_pNext = NULL;
  572. m_pTail = pNode;
  573. m_Count++;
  574. return(true);
  575. }
  576. return(false);
  577. }
  578. /**************************************************************************************************
  579. FUNCTION DESCRIPTION:
  580. Insert
  581. Insert an element into the list at the given position
  582. INPUT PARAMETERS:
  583. New_Element: The element to be added
  584. Pos: The position at which to insert the element
  585. rIter: An iterator the points to the location where we want to insert the element
  586. RETURN VALUE:
  587. TRUE if success
  588. ***************************************************************************************************/
  589. ELIST_TPL_DEF inline bool EList<ELIST_TPL_ARG>::Insert(T_ARG New_Element, const typename EList<ELIST_TPL_ARG>::EIterator& rIter)
  590. {
  591. //
  592. // Make sure we have a valid iterator before we continue
  593. //
  594. gosASSERT(rIter.m_pCur_Node);
  595. //
  596. // Attempt to create a new element
  597. //
  598. ENode* pNode = CreateElement(New_Element);
  599. if(!pNode)
  600. {
  601. return(false);
  602. }
  603. //
  604. // Connect the newly created node
  605. //
  606. pNode->m_pNext = rIter.m_pCur_Node;
  607. pNode->m_pPrev = rIter.m_pCur_Node->m_pPrev;
  608. //
  609. // Make sure to connect the previous node only if we are not the first in the list
  610. //
  611. if(pNode->m_pPrev)
  612. {
  613. pNode->m_pPrev->m_pNext = pNode;
  614. }
  615. else
  616. {
  617. // if we are, set the haed pointer
  618. m_pHead = pNode;
  619. }
  620. //
  621. // Last thing to do is to connect the next node to oursef
  622. //
  623. pNode->m_pNext->m_pPrev = pNode;
  624. m_Count++;
  625. return(true);
  626. }
  627. //-------------------------------------------------------------------------------------------------
  628. ELIST_TPL_DEF inline bool EList<ELIST_TPL_ARG>::Insert(T_ARG New_Element, unsigned long Pos)
  629. {
  630. gosASSERT(m_Count > Pos && m_Count);
  631. //
  632. // We can't INSERT after the end of the list, so fail here
  633. //
  634. if(m_Count <= Pos)
  635. {
  636. return(false);
  637. }
  638. //
  639. // In case list is empty, simply prepend the element, Prepend() handles this case
  640. //
  641. if(IsEmpty())
  642. {
  643. return(Prepend(New_Element));
  644. }
  645. return(Insert(New_Element, Iterator(Pos)));
  646. }
  647. /**************************************************************************************************
  648. FUNCTION DESCRIPTION:
  649. DeleteHead
  650. Delete the head element from the list. This will call the destructor of the element
  651. to assure that any memory allocated by the element can be freed.
  652. RETURN VALUE:
  653. TRUE is success, FALSE if list is empty
  654. ***************************************************************************************************/
  655. ELIST_TPL_DEF inline bool EList<ELIST_TPL_ARG>::DeleteHead()
  656. {
  657. //
  658. // can't delete anything if there is nothing...
  659. //
  660. gosASSERT(m_Count);
  661. if(!m_Count)
  662. {
  663. return(false);
  664. }
  665. //
  666. // In case it's the only element in the list
  667. //
  668. if(m_Count == 1)
  669. {
  670. KillElement(m_pHead);
  671. m_pHead = m_pTail = NULL; // make sure haed and tail pointers are set to NULL
  672. // if the list is empty
  673. m_Count = 0;
  674. return(true);
  675. }
  676. else
  677. {
  678. ENode* pElement_To_Kill = m_pHead; // Get the element we want to kill
  679. m_pHead = m_pHead->m_pNext; // Second element becomes head of the list
  680. m_pHead->m_pPrev = NULL;
  681. KillElement(pElement_To_Kill);
  682. m_Count--;
  683. return(true);
  684. }
  685. }
  686. /**************************************************************************************************
  687. FUNCTION DESCRIPTION:
  688. DeleteTail
  689. Delete the tail element from the list. This will call the destructor of the element
  690. to assure that any memory allocated by the element can be freed.
  691. RETURN VALUE:
  692. TRUE is success, FALSE if list is empty
  693. ***************************************************************************************************/
  694. ELIST_TPL_DEF inline bool EList<ELIST_TPL_ARG>::DeleteTail()
  695. {
  696. //
  697. // Make sure we're not trying to delete from an empty list
  698. //
  699. gosASSERT(m_Count);
  700. if(!m_Count)
  701. {
  702. return(false);
  703. }
  704. if(m_Count == 1)
  705. {
  706. KillElement(m_pHead);
  707. m_pHead = m_pTail = NULL; // make sure haed and tail pointers are set to NULL
  708. // if the list is empty
  709. m_Count = 0;
  710. return(true);
  711. }
  712. else
  713. {
  714. ENode* pElement_To_Kill = m_pTail;
  715. m_pTail = m_pTail->m_pPrev;
  716. m_pTail->m_pNext = NULL;
  717. KillElement(pElement_To_Kill);
  718. m_Count--;
  719. return(true);
  720. }
  721. }
  722. /**************************************************************************************************
  723. FUNCTION DESCRIPTION:
  724. Delete
  725. Delete an element from the list
  726. INPUT PARAMETERS:
  727. rIter: An iterator that points at the element we want to delete
  728. RETURN VALUE:
  729. TRUE if success
  730. ***************************************************************************************************/
  731. ELIST_TPL_DEF inline bool EList<ELIST_TPL_ARG>::Delete(const typename EList<ELIST_TPL_ARG>::EIterator& rIter)
  732. {
  733. //
  734. // Verify that we have a valid iterator
  735. //
  736. gosASSERT(rIter.IsValid());
  737. if(m_Count == 1)
  738. {
  739. KillElement(m_pHead);
  740. m_pHead = m_pTail = NULL;
  741. m_Count = 0;
  742. return(true);
  743. }
  744. else
  745. {
  746. ENode* pElement_To_Kill = rIter.m_pCur_Node;
  747. if(m_pTail == pElement_To_Kill)
  748. {
  749. m_pTail = pElement_To_Kill->m_pPrev;
  750. m_pTail->m_pNext = NULL;
  751. }
  752. else if(m_pHead == pElement_To_Kill)
  753. {
  754. m_pHead = pElement_To_Kill->m_pNext;
  755. m_pHead->m_pPrev = NULL;
  756. }
  757. else
  758. {
  759. pElement_To_Kill->m_pPrev->m_pNext = pElement_To_Kill->m_pNext;
  760. pElement_To_Kill->m_pNext->m_pPrev = pElement_To_Kill->m_pPrev;
  761. }
  762. KillElement(pElement_To_Kill);
  763. m_Count--;
  764. return(true);
  765. }
  766. }
  767. /**************************************************************************************************
  768. FUNCTION DESCRIPTION:
  769. Delete
  770. Delete an element from the list
  771. INPUT PARAMETERS:
  772. Pos: Position of the element we want to delete
  773. RETURN VALUE:
  774. TRUE if success
  775. ***************************************************************************************************/
  776. ELIST_TPL_DEF inline bool EList<ELIST_TPL_ARG>::Delete(unsigned long Pos)
  777. {
  778. gosASSERT(m_Count > Pos && m_Count);
  779. //
  780. // We can't DELETE after the end of the list or if empty, so fail here
  781. //
  782. if(m_Count <= Pos || (!m_Count))
  783. {
  784. return(false);
  785. }
  786. return(Delete(Iterator(Pos)));
  787. }
  788. /**************************************************************************************************
  789. FUNCTION DESCRIPTION:
  790. Delete
  791. Delete a range of elements in the list
  792. INPUT PARAMETERS:
  793. Start_Pos: First element in the list to delete
  794. End_Pos: Last element in the list to delete
  795. rStart_Iter:First element in the list to delete
  796. rEnd_Iter: Last element in the list to delete
  797. RETURN VALUE:
  798. TRUE if successfull
  799. ***************************************************************************************************/
  800. ELIST_TPL_DEF inline bool EList<ELIST_TPL_ARG>::Delete(const typename EList<ELIST_TPL_ARG>::EIterator& rStart_Iter, const typename EList<ELIST_TPL_ARG>::EIterator& rEnd_Iter)
  801. {
  802. gosASSERT(rStart_Iter.IsValid() && rEnd_Iter.IsValid());
  803. gosASSERT((rStart_Iter != rEnd_Iter));
  804. if( (!(rStart_Iter.IsValid())) || (!(rEnd_Iter.IsValid())) )
  805. {
  806. return(false);
  807. }
  808. EIterator Iter;
  809. EIterator Next_Iter = rStart_Iter;
  810. while(Next_Iter != rEnd_Iter)
  811. {
  812. Iter = Next_Iter;
  813. Next_Iter++;
  814. Delete(Iter);
  815. }
  816. return(true);
  817. }
  818. //-------------------------------------------------------------------------------------------------
  819. ELIST_TPL_DEF inline bool EList<ELIST_TPL_ARG>::Delete(unsigned long Start_Pos, unsigned long End_Pos)
  820. {
  821. gosASSERT(Start_Pos < End_Pos);
  822. return(Delete(Iterator(Start_Pos), Iterator(End_Pos)));
  823. }
  824. /**************************************************************************************************
  825. FUNCTION DESCRIPTION:
  826. Get
  827. Gets a reference to the element that is at the position we passed to the function
  828. INPUT PARAMETERS:
  829. Pos: The position of the element we want to get
  830. rIter: The iterator of the element we want to get
  831. RETURN VALUE:
  832. Reference to the element at the position we passed
  833. ***************************************************************************************************/
  834. ELIST_TPL_DEF inline T& EList<ELIST_TPL_ARG>::Get(const typename EList<const ELIST_TPL_ARG>::EIterator& rIter)
  835. {
  836. gosASSERT(m_Count && rIter.IsValid());
  837. return(rIter.m_pCur_Node->m_Data);
  838. }
  839. //-------------------------------------------------------------------------------------------------
  840. ELIST_TPL_DEF inline T& EList<ELIST_TPL_ARG>::Get(unsigned long Pos)
  841. {
  842. gosASSERT(m_Count > Pos && m_Count);
  843. return(Get(Iterator(Pos)));
  844. }
  845. /**************************************************************************************************
  846. FUNCTION DESCRIPTION:
  847. GetHead
  848. Get a reference to the element that is at the head of the list
  849. RETURN VALUE:
  850. Reference to the element at the head of the list
  851. ***************************************************************************************************/
  852. ELIST_TPL_DEF inline T& EList<ELIST_TPL_ARG>::GetHead()
  853. {
  854. gosASSERT(m_Count);
  855. return(m_pHead->m_Data);
  856. }
  857. /**************************************************************************************************
  858. FUNCTION DESCRIPTION:
  859. GetTail
  860. Get a reference to the element that is at the tail of the list
  861. RETURN VALUE:
  862. Reference to the element at the tail of the list
  863. ***************************************************************************************************/
  864. ELIST_TPL_DEF inline T& EList<ELIST_TPL_ARG>::GetTail()
  865. {
  866. gosASSERT(m_Count);
  867. return(m_pTail->m_Data);
  868. }
  869. /**************************************************************************************************
  870. FUNCTION DESCRIPTION:
  871. Replace
  872. Replace an element in the list with a new one
  873. INPUT PARAMETERS:
  874. Element: The new element we want to replace the old one with
  875. rIter: An iterator to the element we want to replace
  876. RETURN VALUE:
  877. TRUE if success, FALSE if not
  878. ***************************************************************************************************/
  879. ELIST_TPL_DEF inline bool EList<ELIST_TPL_ARG>::Replace(T_ARG Element, const typename EList<ELIST_TPL_ARG>::EIterator& rIter)
  880. {
  881. gosASSERT(rIter.IsValid());
  882. if(!(rIter.IsValid()))
  883. {
  884. return(false);
  885. }
  886. rIter.m_pCur_Node->m_Data = Element;
  887. return(true);
  888. }
  889. /**************************************************************************************************
  890. FUNCTION DESCRIPTION:
  891. Replace
  892. Replace an element in the list with a new one
  893. INPUT PARAMETERS:
  894. Element: The new element we want to replace the old one with
  895. Pos: An index to the element we want to replace
  896. RETURN VALUE:
  897. TRUE if success, FALSE if not
  898. ***************************************************************************************************/
  899. ELIST_TPL_DEF inline bool EList<ELIST_TPL_ARG>::Replace(T_ARG Element, unsigned long Pos)
  900. {
  901. return(Replace(Element, Iterator(Pos)));
  902. }
  903. /**************************************************************************************************
  904. FUNCTION DESCRIPTION:
  905. Append
  906. Appends the given list to this one
  907. INPUT PARAMETERS:
  908. rList: A reference to the list that is to be prepended
  909. RETURN VALUE:
  910. TRUE if success, FALSE if not
  911. ***************************************************************************************************/
  912. ELIST_TPL_DEF bool EList<ELIST_TPL_ARG>::Append(const EList<ELIST_TPL_ARG>& rList)
  913. {
  914. gosASSERT(&rList != this);
  915. //
  916. // Iterate through the source list and add any element to this one
  917. //
  918. const ENode* pNode = rList.m_pHead;
  919. for(unsigned long i = 0; i < rList.m_Count; i++)
  920. {
  921. Append(pNode->m_Data); // <<TODO>> BR - This needs to be optimized
  922. pNode = pNode->m_pNext;
  923. }
  924. return(true);
  925. }
  926. /**************************************************************************************************
  927. FUNCTION DESCRIPTION:
  928. Prepend
  929. Prepends the given list to this one
  930. INPUT PARAMETERS:
  931. rList: A reference to the list that is to be prepended
  932. RETURN VALUE:
  933. TRUE if success, FALSE if not
  934. ***************************************************************************************************/
  935. ELIST_TPL_DEF bool EList<ELIST_TPL_ARG>::Prepend(const EList<ELIST_TPL_ARG>& rList)
  936. {
  937. gosASSERT(&rList != this);
  938. //
  939. // Iterate through the source list and add any element to this one
  940. //
  941. const ENode* pNode = rList.m_pTail;
  942. for(unsigned long i = 0; i < rList.m_Count; i++)
  943. {
  944. Prepend(pNode->m_Data); // <<TODO>> BR - This needs to be optimized
  945. pNode = pNode->m_pPrev;
  946. }
  947. return(true);
  948. }
  949. /**************************************************************************************************
  950. FUNCTION DESCRIPTION:
  951. Insert
  952. Insert all elements from the list given into this list
  953. INPUT PARAMETERS:
  954. rList: A reference to the list to be inserted
  955. rIter: An iterator into the list at which to start the insert
  956. RETURN VALUE:
  957. TRUE if success, FALSE if not
  958. ***************************************************************************************************/
  959. ELIST_TPL_DEF bool EList<ELIST_TPL_ARG>::Insert(const EList<ELIST_TPL_ARG>& rList, const typename EList<ELIST_TPL_ARG>::EIterator& rIter)
  960. {
  961. gosASSERT(&rList != this);
  962. gosASSERT(rIter.IsValid());
  963. EConstIterator Src_Iter = rList.Begin();
  964. for(unsigned long i = 0; i < rList.m_Count; i++)
  965. {
  966. Insert(Src_Iter.Item(), rIter);
  967. Src_Iter++;
  968. }
  969. return(true);
  970. }
  971. /**************************************************************************************************
  972. FUNCTION DESCRIPTION:
  973. Insert
  974. Insert all elements from the list given into this list
  975. INPUT PARAMETERS:
  976. rList: A reference to the list to be inserted
  977. Pos: An index to the position at which to start the insert
  978. RETURN VALUE:
  979. TRUE if success, FALSE if not
  980. ***************************************************************************************************/
  981. ELIST_TPL_DEF bool EList<ELIST_TPL_ARG>::Insert(const EList<ELIST_TPL_ARG>& rList, unsigned long Pos)
  982. {
  983. gosASSERT( &rList != this);
  984. return(Insert(rList, Iterator(Pos)));
  985. }
  986. //-------------------------------------------------------------------------------------------------
  987. // ACCESSORS
  988. //-------------------------------------------------------------------------------------------------
  989. /**************************************************************************************************
  990. FUNCTION DESCRIPTION:
  991. Get
  992. Get an element from the list using an iterator to determine it's location
  993. INPUT PARAMETERS:
  994. rIter: The iterator of the element we want to get
  995. RETURN VALUE:
  996. The element referenced by the iterator
  997. ***************************************************************************************************/
  998. ELIST_TPL_DEF inline T_ARG EList<ELIST_TPL_ARG>::Get(const typename EList<ELIST_TPL_ARG>::EConstIterator& rIter) const
  999. {
  1000. gosASSERT(m_Count && rIter.IsValid());
  1001. return(rIter.m_pCur_Node->m_Data);
  1002. }
  1003. /**************************************************************************************************
  1004. FUNCTION DESCRIPTION:
  1005. Get
  1006. Get the element that is at the position we passed to the function
  1007. INPUT PARAMETERS:
  1008. Pos: The position of the element we want to get
  1009. RETURN VALUE:
  1010. The element at the position we passed
  1011. ***************************************************************************************************/
  1012. ELIST_TPL_DEF inline T_ARG EList<ELIST_TPL_ARG>::Get(unsigned long Pos) const
  1013. {
  1014. gosASSERT(m_Count > Pos && m_Count);
  1015. return(Get(Iterator(Pos)));
  1016. }
  1017. /**************************************************************************************************
  1018. FUNCTION DESCRIPTION:
  1019. GetHead
  1020. Get the element that is at the head of the list
  1021. RETURN VALUE:
  1022. The element at the head of the list
  1023. ***************************************************************************************************/
  1024. ELIST_TPL_DEF inline T_ARG EList<ELIST_TPL_ARG>::GetHead() const
  1025. {
  1026. gosASSERT(m_Count);
  1027. return(m_pHead->m_Data);
  1028. }
  1029. /**************************************************************************************************
  1030. FUNCTION DESCRIPTION:
  1031. GetTail
  1032. Get the element that is at the tail of the list
  1033. RETURN VALUE:
  1034. The element at the tail of the list
  1035. ***************************************************************************************************/
  1036. ELIST_TPL_DEF inline T_ARG EList<ELIST_TPL_ARG>::GetTail() const
  1037. {
  1038. gosASSERT(m_Count);
  1039. return(m_pTail->m_Data);
  1040. }
  1041. /**************************************************************************************************
  1042. FUNCTION DESCRIPTION:
  1043. Find
  1044. Search through the list for the item corresponding to "Item"
  1045. INPUT PARAMETERS:
  1046. Item: The item to search for
  1047. Start_Index: The element at which to start the search
  1048. RETURN VALUE:
  1049. The iterator that corresponds with the element in the list we searched for,
  1050. or INVALID_ITERATOR if the element could not be found
  1051. ***************************************************************************************************/
  1052. ELIST_TPL_DEF inline typename EList<ELIST_TPL_ARG>::EConstIterator EList<ELIST_TPL_ARG>::Find(T_ARG Item, unsigned long Start_Index) const
  1053. {
  1054. gosASSERT(Start_Index < m_Count && (!(IsEmpty())));
  1055. return(Find(Item, Iterator(Start_Index)));
  1056. }
  1057. /**************************************************************************************************
  1058. FUNCTION DESCRIPTION:
  1059. Find
  1060. Search through the list for the item corresponding to "Item"
  1061. INPUT PARAMETERS:
  1062. Item: The item to search for
  1063. Start_Index: The element at which to start the search
  1064. RETURN VALUE:
  1065. The iterator that corresponds with the element in the list we searched for,
  1066. or INVALID_ITERATOR if the element could not be found
  1067. ***************************************************************************************************/
  1068. ELIST_TPL_DEF inline typename EList<ELIST_TPL_ARG>::EIterator EList<ELIST_TPL_ARG>::Find(T_ARG Item, unsigned long Start_Index)
  1069. {
  1070. gosASSERT(Start_Index < m_Count && (!(IsEmpty())));
  1071. return(Find(Item, Iterator(Start_Index)));
  1072. }
  1073. /**************************************************************************************************
  1074. FUNCTION DESCRIPTION:
  1075. Find
  1076. Search through the list for the item corresponding to "Item"
  1077. INPUT PARAMETERS:
  1078. Item: The item to search for
  1079. rStart_Iterator: The element at which to start the search
  1080. RETURN VALUE:
  1081. The iterator that corresponds with the element in the list we searched for,
  1082. or INVALID_ITERATOR if the element could not be found
  1083. ***************************************************************************************************/
  1084. ELIST_TPL_DEF inline typename EList<ELIST_TPL_ARG>::EConstIterator EList<ELIST_TPL_ARG>::Find(T_ARG Item, const typename EList<ELIST_TPL_ARG>::EConstIterator& rStart_Iterator) const
  1085. {
  1086. gosASSERT(rStart_Iterator.IsValid());
  1087. EConstIterator Iter = rStart_Iterator;
  1088. while(!(Iter.IsDone()))
  1089. {
  1090. if(Iter.Item() == Item)
  1091. {
  1092. return(Iter);
  1093. }
  1094. Iter++;
  1095. }
  1096. return(INVALID_ITERATOR);
  1097. }
  1098. /**************************************************************************************************
  1099. FUNCTION DESCRIPTION:
  1100. Find
  1101. Search through the list for the item corresponding to "Item"
  1102. INPUT PARAMETERS:
  1103. Item: The item to search for
  1104. rStart_Iterator: The element at which to start the search
  1105. RETURN VALUE:
  1106. The iterator that corresponds with the element in the list we searched for,
  1107. or INVALID_ITERATOR if the element could not be found
  1108. ***************************************************************************************************/
  1109. ELIST_TPL_DEF inline typename EList<ELIST_TPL_ARG>::EIterator EList<ELIST_TPL_ARG>::Find(T_ARG Item, const typename EList<ELIST_TPL_ARG>::EIterator& rStart_Iterator)
  1110. {
  1111. gosASSERT(rStart_Iterator.IsValid());
  1112. EIterator Iter = rStart_Iterator;
  1113. while(!(Iter.IsDone()))
  1114. {
  1115. if(Iter.Item() == Item)
  1116. {
  1117. return(Iter);
  1118. }
  1119. Iter++;
  1120. }
  1121. return(INVALID_ITERATOR);
  1122. }
  1123. /**************************************************************************************************
  1124. FUNCTION DESCRIPTION:
  1125. Count
  1126. Retrieve the number of elements currently in the list
  1127. RETURN VALUE:
  1128. The number of elements in the list
  1129. ***************************************************************************************************/
  1130. ELIST_TPL_DEF inline unsigned long EList<ELIST_TPL_ARG>::Count() const
  1131. {
  1132. return(m_Count);
  1133. }
  1134. /**************************************************************************************************
  1135. FUNCTION DESCRIPTION:
  1136. IsEmpty
  1137. Test the list for emptyness
  1138. RETURN VALUE:
  1139. TRUE if list is empty, FALSE if not
  1140. ***************************************************************************************************/
  1141. ELIST_TPL_DEF inline bool EList<ELIST_TPL_ARG>::IsEmpty() const
  1142. {
  1143. return(m_Count ? false : true);
  1144. }
  1145. /**************************************************************************************************
  1146. FUNCTION DESCRIPTION:
  1147. GrowSize
  1148. Retrieve the current Growsize of the list
  1149. RETURN VALUE:
  1150. Current Growsize
  1151. ***************************************************************************************************/
  1152. ELIST_TPL_DEF inline unsigned long EList<ELIST_TPL_ARG>::GrowSize() const
  1153. {
  1154. return(m_List_Pool.PageSize());
  1155. }
  1156. /**************************************************************************************************
  1157. FUNCTION DESCRIPTION:
  1158. Exists
  1159. Determine whether an entry exists in the list
  1160. INPUT PARAMETERS:
  1161. Pos: The position of the element we want to check for existance
  1162. RETURN VALUE:
  1163. TRUE if exist, FALSE if not
  1164. ***************************************************************************************************/
  1165. ELIST_TPL_DEF inline bool EList<ELIST_TPL_ARG>::Exists(unsigned long Pos) const
  1166. {
  1167. if(Pos < m_Count)
  1168. {
  1169. return(true);
  1170. }
  1171. return(false);
  1172. }
  1173. //-------------------------------------------------------------------------------------------------
  1174. // HELPER FUNCTIONS
  1175. //-------------------------------------------------------------------------------------------------
  1176. ELIST_TPL_DEF inline bool EList<ELIST_TPL_ARG>::AddFirstElement(T_ARG New_Element)
  1177. {
  1178. ENode* pElement = CreateElement(New_Element);
  1179. if(!pElement)
  1180. {
  1181. return(false);
  1182. }
  1183. m_pHead = m_pTail = pElement; // Setup List head and tail pointers
  1184. pElement->m_pNext = pElement->m_pPrev = NULL;
  1185. m_Count = 1;
  1186. return(true);
  1187. }
  1188. //-------------------------------------------------------------------------------------------------
  1189. // Note: m_pNext and m_pPrev are not initialized
  1190. ELIST_TPL_DEF inline typename EList<ELIST_TPL_ARG>::ENode* EList<ELIST_TPL_ARG>::CreateElement(T_ARG New_Element)
  1191. {
  1192. ENode* pNode = (ENode*)systemHeap->Malloc( sizeof( ENode ) ); // Allocate memory for the node and data
  1193. if(!pNode)
  1194. {
  1195. return(NULL); // return NULL if it fails
  1196. }
  1197. pNode = new(pNode) ENode(New_Element); // and construct the data object explicitly
  1198. gosASSERT(pNode);
  1199. return(pNode); // return the pointer to the Node of the element we created
  1200. }
  1201. //-------------------------------------------------------------------------------------------------
  1202. ELIST_TPL_DEF inline void EList<ELIST_TPL_ARG>::KillElement(ENode* pElement)
  1203. {
  1204. gosASSERT(pElement);
  1205. pElement->m_Data.~T(); // Destruct the data component of the element
  1206. systemHeap->Free(pElement); // Now free the element
  1207. }
  1208. //-------------------------------------------------------------------------------------------------
  1209. ELIST_TPL_DEF inline void EList<ELIST_TPL_ARG>::DestroyList()
  1210. {
  1211. //
  1212. // simply return if list is empty
  1213. //
  1214. if(IsEmpty())
  1215. {
  1216. return;
  1217. }
  1218. //
  1219. // Otherwise remove the head element until none are left
  1220. //
  1221. while(m_Count)
  1222. {
  1223. DeleteHead();
  1224. }
  1225. }
  1226. /**************************************************************************************************
  1227. FUNCTION DESCRIPTION:
  1228. CopyData
  1229. Copies data from the source list into this one
  1230. NOTE: The function assumes the list to be empty at when it is called
  1231. INPUT PARAMETERS:
  1232. rSrc: Reference to the source list
  1233. RETURN VALUE:
  1234. TRUE is success
  1235. ***************************************************************************************************/
  1236. ELIST_TPL_DEF bool EList<ELIST_TPL_ARG>::CopyData(const EList<ELIST_TPL_ARG>& rSrc)
  1237. {
  1238. //
  1239. // Iterate through the source list and add any element to this one
  1240. //
  1241. m_Count = rSrc.m_Count;
  1242. if(!m_Count)
  1243. {
  1244. m_pHead = m_pTail = NULL;
  1245. return(true);
  1246. }
  1247. ENode* pSrc_Node = rSrc.m_pHead;
  1248. ENode* pNode = CreateElement(pSrc_Node->m_Data);
  1249. gosASSERT(pNode && pSrc_Node); // Should never be NULL
  1250. m_pHead = m_pTail = pNode;
  1251. m_pHead->m_pPrev = NULL;
  1252. for(unsigned long i = 1; i<rSrc.m_Count; i++)
  1253. {
  1254. pSrc_Node = pSrc_Node->m_pNext;
  1255. gosASSERT(pSrc_Node); // Should never be NULL
  1256. m_pTail = CreateElement(pSrc_Node->m_Data);
  1257. gosASSERT(m_pTail);
  1258. m_pTail->m_pPrev = pNode;
  1259. pNode->m_pNext = m_pTail;
  1260. pNode = m_pTail;
  1261. }
  1262. m_pTail->m_pNext = NULL;
  1263. return(true);
  1264. }
  1265. //*************************************************************************************************
  1266. #endif // end of file ( ELIST.h )