123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458 |
- #ifndef ELIST_H
- #define ELIST_H
- #pragma warning( disable : 4211 )
- #include <memory.h>
- #include "heap.h"
- //--------------------------------------------------------------------------------------
- //
- // Mech Commander 2
- //
- // standard linked list
- //
- //---------------------------------------------------------------------------//
- // Copyright (C) Microsoft Corporation. All rights reserved. //
- //===========================================================================//
- //*************************************************************************************************
- #define ELIST_TPL_DEF template<class T, class T_ARG>
- #define ELIST_TPL_ARG T, T_ARG
- //*************************************************************************************************
- /**************************************************************************************************
- CLASS DESCRIPTION
- EList:
- This template class is a doubly linked list. The list is implemented using a fixed memory pool,
- which ensures proximity of all the elements, in order to increase the cacheability of the list.
- Two template parameters are required to declare a list. The first is the type of the object,
- that is intended to be stored in the list. The second is the type by which we intend to pass the
- object.
- The user needs to pass the initial element count and the amount of elements to grow the
- memory pool by, if required to accomodate all elements, to the constructor.
- Optionally a name can be supplied, however this will only be used during debug builds.
- Example:
- EList<KSomeClass, const KSomeClass&> m_List(10, 5, "SomeList");
- EList<int, const int> m_List(100, 10);
- Note:
- The second template argument is const to provide for const safety.
- It is syntacticly legal to use a non-const version, however, it will not provide
- const safty. Unfortunately there is no way to prevent this.
- Classes used with the list need to define a copy constructor, an assignment operator, and
- an equality operator in order to work properly (of course only if the default versions are
- not sufficient).
- **************************************************************************************************/
- #ifndef __PLACEMENT_NEW_INLINE
- #define __PLACEMENT_NEW_INLINE
- inline void *__cdecl operator new(size_t, void *_P)
- {return (_P); } // placement new
- #endif
- ELIST_TPL_DEF class EList
- {
- protected:
- //
- // The node is used to chain the elements of the list together, it contains pointers
- // to the elements preceeding or following it, in addition to the element itself.
- // If no preceeding or following element are present the value is NULL
- //
- struct ENode
- {
- ENode(T_ARG New_Element) : m_Data(New_Element) {};
- ENode* m_pNext;
- ENode* m_pPrev;
- T m_Data;
- private:
- ENode& operator=(const ENode& rNode);
- };
- enum
- {
- MAX_NAME_LENGTH = 64
- };
- public:
- /**************************************************************************************************
- CLASS DESCRIPTION
- EList::EConstIterator
- This class is used to iterate through the List. You can read objects with this iterator but you
- can't change them. Use class !!(EIterator) for changing objects.
- **************************************************************************************************/
- class EConstIterator
- {
- public:
- // Note: Code needs to be implemented in class decleration, due
- // to MSVC bug with nested template classes
-
- inline EConstIterator() { m_pCur_Node = NULL; }
- inline EConstIterator(const EConstIterator& rIter) { m_pCur_Node = rIter.m_pCur_Node; }
- inline EConstIterator& operator=(const EConstIterator& rIter) { m_pCur_Node = rIter.m_pCur_Node; return(*this); }
- //
- // NOTE: Postfix operators require "int" to be passed as parameter,
- // else compiler error C2807 will occur when used
- //
- inline EConstIterator& operator++(int) // postfix increment
- {
- #ifdef DEBUG
- if(!(IsValid()))
- {
- gosASSERT("EList::EIterator: Attempt to increment invalid iterator\n");
- }
- #endif
- m_pCur_Node = m_pCur_Node->m_pNext;
- return(*this);
- }
- inline EConstIterator& operator--(int) // postfix decrement
- {
- #ifdef KTL_DEBUG
- if(!(IsValid()))
- {
- Assert("EList::EIterator: Attempt to decrement invalid iterator\n");
- }
- #endif
- m_pCur_Node = m_pCur_Node->m_pPrev;
- return(*this);
- }
- inline EConstIterator& operator+=(unsigned long Increment)
- {
- while(Increment)
- {
- #ifdef KTL_DEBUG
- if(!(IsValid()))
- {
- Assert("EList::EIterator: Attempt to increment invalid iterator\n");
- }
- #endif
- m_pCur_Node = m_pCur_Node->m_pNext;
- Increment--;
- }
- return(*this);
- }
- inline EConstIterator& operator-=(unsigned long Decrement)
- {
- while(Decrement)
- {
- #ifdef KTL_DEBUG
- if(!(IsValid()))
- {
- Assert("EList::EIterator: Attempt to increment invalid iterator\n");
- }
- #endif
- m_pCur_Node = m_pCur_Node->m_pPrev;
- Decrement--;
- }
- return(*this);
- }
- inline bool operator==(const EConstIterator& rIter) const
- {
- return(m_pCur_Node == rIter.m_pCur_Node);
- }
- inline bool operator!=(const EConstIterator& rIter) const
- {
- return(m_pCur_Node != rIter.m_pCur_Node);
- }
- inline T_ARG operator*() const
- {
- return Item();
- }
-
- inline T_ARG Item() const { return(m_pCur_Node->m_Data); }
- inline bool IsValid() const { return(m_pCur_Node ? true : false); }
- inline bool IsDone() const { return(m_pCur_Node ? false : true); }
- friend class EList<ELIST_TPL_ARG>;
- protected:
- ENode* m_pCur_Node;
- #ifdef KTL_DEBUG
- char m_Name[64];
- #endif
- }; // END CLASS EConstIterator
-
- /**************************************************************************************************
- CLASS DESCRIPTION
- EList::EIterator
- This class is used for non constant iteration through a list.
- **************************************************************************************************/
- class EIterator : public EConstIterator
- {
- public:
- inline EIterator() : EConstIterator() {}
- inline EIterator(const EIterator& rIter) : EConstIterator(rIter) {}
- inline T& Item() { return(m_pCur_Node->m_Data); }
- inline T& operator*()
- {
- return Item();
- }
- }; // END CLASS EIterator
- //===== ENUMERATIONS & CONSTANTS =====
- typename static const EIterator INVALID_ITERATOR;
- //===== CREATORS =====
- inline EList();
- EList(const EList<ELIST_TPL_ARG>& rList);
- ~EList();
- //===== OPERATORS =====
- EList<ELIST_TPL_ARG>& operator=(const EList<ELIST_TPL_ARG>& rList);
- inline T& operator[](unsigned long Pos);
- inline T& operator[](const typename EList<ELIST_TPL_ARG>::EIterator& rIter);
- inline T_ARG operator[](unsigned long Pos) const;
- inline T_ARG operator[](const typename EList<ELIST_TPL_ARG>::EIterator& rIter) const;
- inline bool operator==(const EList<ELIST_TPL_ARG>& rList) const;
- inline bool operator!=(const EList<ELIST_TPL_ARG>& rList) const;
- //===== MANIPULATORS =====
- bool Clear();
- inline bool Prepend(T_ARG New_Element); // Add an element to the start of the list
- inline bool Append(T_ARG New_Element); // Add an element to the end of the list
- inline bool Insert(T_ARG New_Element, const typename EList<ELIST_TPL_ARG>::EIterator& rIter); // Insert an element bofore the specified position
- inline bool Insert(T_ARG New_Element, unsigned long Pos); // Insert an element bofore the specified position
- bool Prepend(const EList<ELIST_TPL_ARG>& rList); // Prepend a list to this one
- bool Append(const EList<ELIST_TPL_ARG>& rList); // Append a list to this one
- bool Insert(const EList<ELIST_TPL_ARG>& rList, const typename EList<ELIST_TPL_ARG>::EIterator& rIter); // Insert a list at the specified position
- bool Insert(const EList<ELIST_TPL_ARG>& rList, unsigned long Pos); // Insert a list at the specified position
- inline bool DeleteHead(); // Remove the element at the beginning of the list
- inline bool DeleteTail(); // Remove the element at the end of the list
- inline bool Delete(const typename EList<ELIST_TPL_ARG>::EIterator& rIter); // Remove the element at the specified position
- inline bool Delete(unsigned long Pos); // Remove the element at the specified position
- 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
- inline bool Delete(unsigned long Start_Pos, unsigned long End_Pos); // Remove the element at the specified position
- inline bool Replace(T_ARG Element, const typename EList<ELIST_TPL_ARG>::EIterator& rIter); // Replace an element at the specified position
- inline bool Replace(T_ARG Element, unsigned long Pos); // Replace an element at the specified position
- inline typename EList<ELIST_TPL_ARG>::EIterator Iterator(unsigned long Pos);
- inline const typename EList<ELIST_TPL_ARG>::EConstIterator Iterator(unsigned long Pos) const;
- inline typename EList<ELIST_TPL_ARG>::EIterator Begin();
- inline const typename EList<ELIST_TPL_ARG>::EConstIterator Begin() const;
- inline typename EList<ELIST_TPL_ARG>::EIterator End();
- inline const typename EList<ELIST_TPL_ARG>::EConstIterator End() const;
-
- inline T& Get(const typename EList<const ELIST_TPL_ARG>::EIterator& rIter); // Retrieve the element at the specified position
- inline T& Get(unsigned long Pos); // Retrieve the element at the specified position
- inline T& GetHead(); // Retrieve the element at the start of the list
- inline T& GetTail(); // Retrieve the element at the end of the list
- //===== ACCESSORS =====
- inline T_ARG Get(const typename EList<ELIST_TPL_ARG>::EConstIterator& rIter) const; // Retrieve the element at the specified position
- inline T_ARG Get(unsigned long Pos) const; // Retrieve the element at the specified position
- inline T_ARG GetHead() const; // Retrieve the element at the start of the list
- inline T_ARG GetTail() const; // Retrieve the element at the end of the list
- inline unsigned long Count() const; // Get the number of elements in the list
- inline bool IsEmpty() const; // Check if the list is empty
- inline bool Exists(unsigned long Pos) const;// Check if an element at that position exists
- inline typename EList<ELIST_TPL_ARG>::EConstIterator Find(T_ARG Item, unsigned long Start_Index = 0) const;
- inline typename EList<ELIST_TPL_ARG>::EIterator Find(T_ARG Item, unsigned long Start_Index = 0);
- inline typename EList<ELIST_TPL_ARG>::EConstIterator Find(T_ARG Item, const typename EList<ELIST_TPL_ARG>::EConstIterator& rStart_Iterator) const;
- inline typename EList<ELIST_TPL_ARG>::EIterator Find(T_ARG Item, const typename EList<ELIST_TPL_ARG>::EIterator& rStart_Iterator);
- inline unsigned long GrowSize() const; // Get the growsize of list
- private:
- //===== DATA =====
- unsigned long m_Count; // number of elements currently in list
- ENode* m_pHead; // pointer to first node in list
- ENode* m_pTail; // pointer to last node in list
- //===== HELPER FUNCTIONS =====
- inline bool AddFirstElement(T_ARG New_Element);
- inline typename EList<ELIST_TPL_ARG>::ENode* CreateElement(T_ARG New_Element);
- inline void KillElement(ENode* pElement);
- void DestroyList();
- bool CopyData(const EList<ELIST_TPL_ARG>& rSrc);
- }; // END CLASS EList
- //*************************************************************************************************
- // Constants
- //*************************************************************************************************
- ELIST_TPL_DEF const typename EList<ELIST_TPL_ARG>::EIterator EList<ELIST_TPL_ARG>::INVALID_ITERATOR = EList<ELIST_TPL_ARG>::EIterator();
- //*************************************************************************************************
- // Inline Functions
- //*************************************************************************************************
- //-------------------------------------------------------------------------------------------------
- // CREATORS
- //-------------------------------------------------------------------------------------------------
- /**************************************************************************************************
- FUNCTION DESCRIPTION:
- EList
- Standard constructor used to instantiate a list
- INPUT PARAMETERS:
- Size: Initial size of the memory pool in number of elements
- Grow: The size in elements to grow the pool when required
- pName: The name of the list (optional)
- ***************************************************************************************************/
- ELIST_TPL_DEF inline EList<ELIST_TPL_ARG>::EList()
- : m_Count(0), m_pHead(NULL), m_pTail(NULL)
- {
- }
-
- /**************************************************************************************************
- FUNCTION DESCRIPTION:
- EList
- Copy constructor of the list
- INPUT PARAMETERS:
- rList:
- The list to be made a copy of
- ***************************************************************************************************/
- ELIST_TPL_DEF EList<ELIST_TPL_ARG>::EList(const EList<ELIST_TPL_ARG>& rList)
- {
- CopyData(rList);
- }
-
- /**************************************************************************************************
- FUNCTION DESCRIPTION:
- ~EList
- List Destructor, deletes all the elements in the list and then frees the memory pool
- ***************************************************************************************************/
- ELIST_TPL_DEF EList<ELIST_TPL_ARG>::~EList()
- {
- DestroyList();
- }
-
- //-------------------------------------------------------------------------------------------------
- // OPERATORS
- //-------------------------------------------------------------------------------------------------
- /**************************************************************************************************
- FUNCTION DESCRIPTION:
- operator=
- Assignment operator, destroys the current elements and creates copies of all the
- elements in the source list and adds them to this list.
- INPUT PARAMETERS:
- rList: The list to be assigned to this one
- RETURN VALUE:
- A reference to this list
- ***************************************************************************************************/
- ELIST_TPL_DEF EList<ELIST_TPL_ARG>& EList<ELIST_TPL_ARG>::operator=(const EList<ELIST_TPL_ARG>& rList)
- {
- //
- // Get rid of any list entries that might be used
- //
- DestroyList();
- CopyData(rList);
- return(*this);
- }
-
- /**************************************************************************************************
- FUNCTION DESCRIPTION:
- operator[]
- Retrieve a reference to an element in the list.
- Const versions of these functions are also supplied
- INPUT PARAMETERS:
- rIter: An iterator that points at the element for which we want a reference
- Pos: Position of the element in the list for which we want a reference
- RETURN VALUE:
- A reference to the desired element
- ***************************************************************************************************/
- ELIST_TPL_DEF inline T& EList<ELIST_TPL_ARG>::operator[](const typename EList<ELIST_TPL_ARG>::EIterator& rIter)
- {
- gosASSERT(rIter.IsValid() && m_Count); // Make sure we are using a valid iterator and have something in the list
- return(rIter.m_pCur_Node->m_Data);
- }
- //-------------------------------------------------------------------------------------------------
- ELIST_TPL_DEF inline T& EList<ELIST_TPL_ARG>::operator[](unsigned long Pos)
- {
- gosASSERT(Pos < m_Count); // Need to stay within range of number of elements
- return operator[](Iterator((unsigned long)Pos));
- }
- //-------------------------------------------------------------------------------------------------
- ELIST_TPL_DEF inline T_ARG EList<ELIST_TPL_ARG>::operator[](const typename EList<ELIST_TPL_ARG>::EIterator& rIter) const
- {
- gosASSERT(rIter.IsValid() && m_Count); // Make sure we are using a valid iterator and have something in the list
- return(rIter.m_pCur_Node->m_Data);
- }
- //-------------------------------------------------------------------------------------------------
- ELIST_TPL_DEF inline T_ARG EList<ELIST_TPL_ARG>::operator[](unsigned long Pos) const
- {
- gosASSERT(Pos < m_Count); // Need to stay within range of number of elements
- return(Get(Iterator(Pos)));
- }
- /**************************************************************************************************
- FUNCTION DESCRIPTION:
- operator==
- Equality operator, tests if this and another list are equal
- INPUT PARAMETERS:
- rList: Reference to the list we want to compare this one with
- RETURN VALUE:
- TRUE if equal, FALSE if not
- ***************************************************************************************************/
- ELIST_TPL_DEF inline bool EList<ELIST_TPL_ARG>::operator==(const EList<ELIST_TPL_ARG>& rList) const
- {
- //
- // If the count of elements is different in each list,
- // they're not equal
- //
- if(m_Count != rList.m_Count)
- {
- return(false);
- }
- //
- // In case both lists are empty, they're equal, however, we don't
- // want to iterate if there is nothing to iterate
- //
- if(m_Count == 0 && rList.m_Count == 0)
- {
- return(true);
- }
- EConstIterator List_Iter = rList.Begin();
- EConstIterator This_Iter = Begin();
- //
- // Iterate through both lists and check if they're equal
- //
- for(unsigned long i = 0; i < m_Count; i++)
- {
- if(List_Iter.Item() != This_Iter.Item())
- {
- return(false);
- }
- }
- return(true);
- }
- //-------------------------------------------------------------------------------------------------
- ELIST_TPL_DEF inline bool EList<ELIST_TPL_ARG>::operator!=(const EList<ELIST_TPL_ARG>& rList) const
- {
- return(!(rList == *this));
- }
- //-------------------------------------------------------------------------------------------------
- // MANIPULATORS
- //-------------------------------------------------------------------------------------------------
- /**************************************************************************************************
- FUNCTION DESCRIPTION:
- Iterator
- Get an iterator that points at the element corresponding with the Position passed
-
- INPUT PARAMETERS:
- Pos: The position of the element we want an iterator for
- RETURN VALUE:
- An iterator that points at the element at the position we passed
- ***************************************************************************************************/
- ELIST_TPL_DEF inline typename EList<ELIST_TPL_ARG>::EIterator EList<ELIST_TPL_ARG>::Iterator(unsigned long Pos)
- {
- gosASSERT(Pos < m_Count && m_Count); // Need to stay within range of number of elements
- if(!m_Count)
- {
- return(INVALID_ITERATOR);
- }
- //
- // Iterate through the list until we get to the element we desire
- //
- ENode *pNode = m_pHead;
- for(unsigned long i = 0; i < Pos; i++)
- {
- pNode = pNode->m_pNext;
- }
- EIterator Iter;
- Iter.m_pCur_Node = pNode;
- return(Iter);
- }
- //-------------------------------------------------------------------------------------------------
- ELIST_TPL_DEF inline const typename EList<ELIST_TPL_ARG>::EConstIterator EList<ELIST_TPL_ARG>::Iterator(unsigned long Pos) const
- {
- gosASSERT(Pos < m_Count && m_Count); // Need to stay within range of number of elements
- if(!m_Count)
- {
- return(INVALID_ITERATOR);
- }
- //
- // Iterate through the list until we get to the element we desire
- //
- ENode *pNode = m_pHead;
- for(unsigned long i = 0; i < Pos; i++)
- {
- pNode = pNode->m_pNext;
- }
- EIterator Iter;
- Iter.m_pCur_Node = pNode;
- return(Iter);
- }
- /**************************************************************************************************
- FUNCTION DESCRIPTION:
- Begin
- Get an iterator that points at the head element of the list.
- Also available as const version
- RETURN VALUE:
- An iterator that points at the head element
- ***************************************************************************************************/
- ELIST_TPL_DEF inline typename EList<ELIST_TPL_ARG>::EIterator EList<ELIST_TPL_ARG>::Begin()
- {
- if(!m_Count)
- {
- return(INVALID_ITERATOR);
- }
- EIterator Iter;
- Iter.m_pCur_Node = m_pHead;
- return(Iter);
- }
- //-------------------------------------------------------------------------------------------------
- ELIST_TPL_DEF inline const typename EList<ELIST_TPL_ARG>::EConstIterator EList<ELIST_TPL_ARG>::Begin() const
- {
- if(!m_Count)
- {
- return(INVALID_ITERATOR);
- }
- EIterator Iter;
- Iter.m_pCur_Node = m_pHead;
- return(Iter);
- }
- /**************************************************************************************************
- FUNCTION DESCRIPTION:
- End
- Get an iterator that points at the tail element of the list
- Also available as const version
- RETURN VALUE:
- An iterator that points at the tail element
- ***************************************************************************************************/
- ELIST_TPL_DEF inline typename EList<ELIST_TPL_ARG>::EIterator EList<ELIST_TPL_ARG>::End()
- {
- gosASSERT(m_Count); // Don't try to get an iterator if list is empty
- if(!m_Count)
- {
- return(INVALID_ITERATOR);
- }
- EIterator Iter;
- Iter.m_pCur_Node = m_pTail;
- return(Iter);
- }
- //-------------------------------------------------------------------------------------------------
- ELIST_TPL_DEF inline const typename EList<ELIST_TPL_ARG>::EConstIterator EList<ELIST_TPL_ARG>::End() const
- {
- gosASSERT(m_Count); // Don't try to get an iterator if list is empty
- if(!m_Count)
- {
- return(INVALID_ITERATOR);
- }
- EIterator Iter;
- Iter.m_pCur_Node = m_pTail;
- return(Iter);
- }
- /**************************************************************************************************
- FUNCTION DESCRIPTION:
- Clear
- Deletes all elements from the list
- RETURN VALUE:
- TRUE if success
- ***************************************************************************************************/
- ELIST_TPL_DEF bool EList<ELIST_TPL_ARG>::Clear()
- {
- DestroyList();
- return(true); // <<HACK>> BR - need to do checking
- }
-
- /**************************************************************************************************
- FUNCTION DESCRIPTION:
- Prepend
- Prepend an element to the list, this element will be the new head element
- INPUT PARAMETERS:
- New_Element: The element we want to prepend to the list
- RETURN VALUE:
- TRUE if success
- ***************************************************************************************************/
- ELIST_TPL_DEF inline bool EList<ELIST_TPL_ARG>::Prepend(T_ARG New_Element)
- {
- //
- // If the list is empty, let's create the first element
- //
- if(IsEmpty())
- {
- return(AddFirstElement(New_Element));
- }
- //
- // Otherwise create a new element and prepend to to the list
- //
- ENode* pNode = CreateElement(New_Element);
- if(pNode)
- {
- m_pHead->m_pPrev = pNode;
- pNode->m_pNext = m_pHead;
- pNode->m_pPrev = NULL;
- m_pHead = pNode;
- m_Count++;
- return(true);
- }
- return(false); // <<HACK>> BR
- }
-
- /**************************************************************************************************
- FUNCTION DESCRIPTION:
- Append
- Append an element to the list, this element will be the new tail element
- INPUT PARAMETERS:
- New_Element: The element we want to append to the list
- RETURN VALUE:
- TRUE if success
- ***************************************************************************************************/
- ELIST_TPL_DEF inline bool EList<ELIST_TPL_ARG>::Append(T_ARG New_Element)
- {
- //
- // If the list is empty, let's create the first element
- //
- if(IsEmpty())
- {
- return(AddFirstElement(New_Element));
- }
- //
- // Otherwise create a new element and append to to the list
- //
- ENode* pNode = CreateElement(New_Element);
- if(pNode)
- {
- m_pTail->m_pNext = pNode;
- pNode->m_pPrev = m_pTail;
- pNode->m_pNext = NULL;
- m_pTail = pNode;
- m_Count++;
- return(true);
- }
- return(false);
- }
- /**************************************************************************************************
- FUNCTION DESCRIPTION:
- Insert
- Insert an element into the list at the given position
- INPUT PARAMETERS:
- New_Element: The element to be added
- Pos: The position at which to insert the element
- rIter: An iterator the points to the location where we want to insert the element
- RETURN VALUE:
- TRUE if success
- ***************************************************************************************************/
- ELIST_TPL_DEF inline bool EList<ELIST_TPL_ARG>::Insert(T_ARG New_Element, const typename EList<ELIST_TPL_ARG>::EIterator& rIter)
- {
- //
- // Make sure we have a valid iterator before we continue
- //
- gosASSERT(rIter.m_pCur_Node);
- //
- // Attempt to create a new element
- //
- ENode* pNode = CreateElement(New_Element);
- if(!pNode)
- {
- return(false);
- }
- //
- // Connect the newly created node
- //
- pNode->m_pNext = rIter.m_pCur_Node;
- pNode->m_pPrev = rIter.m_pCur_Node->m_pPrev;
- //
- // Make sure to connect the previous node only if we are not the first in the list
- //
- if(pNode->m_pPrev)
- {
- pNode->m_pPrev->m_pNext = pNode;
- }
- else
- {
- // if we are, set the haed pointer
- m_pHead = pNode;
- }
- //
- // Last thing to do is to connect the next node to oursef
- //
- pNode->m_pNext->m_pPrev = pNode;
- m_Count++;
- return(true);
- }
- //-------------------------------------------------------------------------------------------------
- ELIST_TPL_DEF inline bool EList<ELIST_TPL_ARG>::Insert(T_ARG New_Element, unsigned long Pos)
- {
- gosASSERT(m_Count > Pos && m_Count);
- //
- // We can't INSERT after the end of the list, so fail here
- //
- if(m_Count <= Pos)
- {
- return(false);
- }
- //
- // In case list is empty, simply prepend the element, Prepend() handles this case
- //
- if(IsEmpty())
- {
- return(Prepend(New_Element));
- }
- return(Insert(New_Element, Iterator(Pos)));
- }
-
- /**************************************************************************************************
- FUNCTION DESCRIPTION:
- DeleteHead
- Delete the head element from the list. This will call the destructor of the element
- to assure that any memory allocated by the element can be freed.
- RETURN VALUE:
- TRUE is success, FALSE if list is empty
- ***************************************************************************************************/
- ELIST_TPL_DEF inline bool EList<ELIST_TPL_ARG>::DeleteHead()
- {
- //
- // can't delete anything if there is nothing...
- //
- gosASSERT(m_Count);
- if(!m_Count)
- {
- return(false);
- }
- //
- // In case it's the only element in the list
- //
- if(m_Count == 1)
- {
- KillElement(m_pHead);
- m_pHead = m_pTail = NULL; // make sure haed and tail pointers are set to NULL
- // if the list is empty
- m_Count = 0;
- return(true);
- }
- else
- {
- ENode* pElement_To_Kill = m_pHead; // Get the element we want to kill
- m_pHead = m_pHead->m_pNext; // Second element becomes head of the list
- m_pHead->m_pPrev = NULL;
- KillElement(pElement_To_Kill);
- m_Count--;
- return(true);
- }
- }
-
- /**************************************************************************************************
- FUNCTION DESCRIPTION:
- DeleteTail
- Delete the tail element from the list. This will call the destructor of the element
- to assure that any memory allocated by the element can be freed.
- RETURN VALUE:
- TRUE is success, FALSE if list is empty
- ***************************************************************************************************/
- ELIST_TPL_DEF inline bool EList<ELIST_TPL_ARG>::DeleteTail()
- {
- //
- // Make sure we're not trying to delete from an empty list
- //
- gosASSERT(m_Count);
- if(!m_Count)
- {
- return(false);
- }
- if(m_Count == 1)
- {
- KillElement(m_pHead);
- m_pHead = m_pTail = NULL; // make sure haed and tail pointers are set to NULL
- // if the list is empty
- m_Count = 0;
- return(true);
- }
- else
- {
- ENode* pElement_To_Kill = m_pTail;
- m_pTail = m_pTail->m_pPrev;
- m_pTail->m_pNext = NULL;
- KillElement(pElement_To_Kill);
- m_Count--;
- return(true);
- }
- }
-
- /**************************************************************************************************
- FUNCTION DESCRIPTION:
- Delete
- Delete an element from the list
- INPUT PARAMETERS:
- rIter: An iterator that points at the element we want to delete
- RETURN VALUE:
- TRUE if success
- ***************************************************************************************************/
- ELIST_TPL_DEF inline bool EList<ELIST_TPL_ARG>::Delete(const typename EList<ELIST_TPL_ARG>::EIterator& rIter)
- {
- //
- // Verify that we have a valid iterator
- //
- gosASSERT(rIter.IsValid());
- if(m_Count == 1)
- {
- KillElement(m_pHead);
- m_pHead = m_pTail = NULL;
- m_Count = 0;
- return(true);
- }
- else
- {
- ENode* pElement_To_Kill = rIter.m_pCur_Node;
- if(m_pTail == pElement_To_Kill)
- {
- m_pTail = pElement_To_Kill->m_pPrev;
- m_pTail->m_pNext = NULL;
- }
- else if(m_pHead == pElement_To_Kill)
- {
- m_pHead = pElement_To_Kill->m_pNext;
- m_pHead->m_pPrev = NULL;
- }
- else
- {
- pElement_To_Kill->m_pPrev->m_pNext = pElement_To_Kill->m_pNext;
- pElement_To_Kill->m_pNext->m_pPrev = pElement_To_Kill->m_pPrev;
- }
- KillElement(pElement_To_Kill);
- m_Count--;
- return(true);
- }
- }
- /**************************************************************************************************
- FUNCTION DESCRIPTION:
- Delete
- Delete an element from the list
- INPUT PARAMETERS:
- Pos: Position of the element we want to delete
- RETURN VALUE:
- TRUE if success
- ***************************************************************************************************/
- ELIST_TPL_DEF inline bool EList<ELIST_TPL_ARG>::Delete(unsigned long Pos)
- {
- gosASSERT(m_Count > Pos && m_Count);
- //
- // We can't DELETE after the end of the list or if empty, so fail here
- //
- if(m_Count <= Pos || (!m_Count))
- {
- return(false);
- }
- return(Delete(Iterator(Pos)));
- }
-
- /**************************************************************************************************
- FUNCTION DESCRIPTION:
- Delete
- Delete a range of elements in the list
- INPUT PARAMETERS:
- Start_Pos: First element in the list to delete
- End_Pos: Last element in the list to delete
- rStart_Iter:First element in the list to delete
- rEnd_Iter: Last element in the list to delete
- RETURN VALUE:
- TRUE if successfull
- ***************************************************************************************************/
- 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)
- {
- gosASSERT(rStart_Iter.IsValid() && rEnd_Iter.IsValid());
- gosASSERT((rStart_Iter != rEnd_Iter));
- if( (!(rStart_Iter.IsValid())) || (!(rEnd_Iter.IsValid())) )
- {
- return(false);
- }
- EIterator Iter;
- EIterator Next_Iter = rStart_Iter;
- while(Next_Iter != rEnd_Iter)
- {
- Iter = Next_Iter;
- Next_Iter++;
- Delete(Iter);
- }
- return(true);
- }
- //-------------------------------------------------------------------------------------------------
- ELIST_TPL_DEF inline bool EList<ELIST_TPL_ARG>::Delete(unsigned long Start_Pos, unsigned long End_Pos)
- {
- gosASSERT(Start_Pos < End_Pos);
- return(Delete(Iterator(Start_Pos), Iterator(End_Pos)));
- }
- /**************************************************************************************************
- FUNCTION DESCRIPTION:
- Get
- Gets a reference to the element that is at the position we passed to the function
- INPUT PARAMETERS:
- Pos: The position of the element we want to get
- rIter: The iterator of the element we want to get
- RETURN VALUE:
- Reference to the element at the position we passed
- ***************************************************************************************************/
- ELIST_TPL_DEF inline T& EList<ELIST_TPL_ARG>::Get(const typename EList<const ELIST_TPL_ARG>::EIterator& rIter)
- {
- gosASSERT(m_Count && rIter.IsValid());
- return(rIter.m_pCur_Node->m_Data);
- }
-
- //-------------------------------------------------------------------------------------------------
- ELIST_TPL_DEF inline T& EList<ELIST_TPL_ARG>::Get(unsigned long Pos)
- {
- gosASSERT(m_Count > Pos && m_Count);
- return(Get(Iterator(Pos)));
- }
- /**************************************************************************************************
- FUNCTION DESCRIPTION:
- GetHead
- Get a reference to the element that is at the head of the list
- RETURN VALUE:
- Reference to the element at the head of the list
- ***************************************************************************************************/
- ELIST_TPL_DEF inline T& EList<ELIST_TPL_ARG>::GetHead()
- {
- gosASSERT(m_Count);
- return(m_pHead->m_Data);
- }
-
- /**************************************************************************************************
- FUNCTION DESCRIPTION:
- GetTail
- Get a reference to the element that is at the tail of the list
- RETURN VALUE:
- Reference to the element at the tail of the list
- ***************************************************************************************************/
- ELIST_TPL_DEF inline T& EList<ELIST_TPL_ARG>::GetTail()
- {
- gosASSERT(m_Count);
- return(m_pTail->m_Data);
- }
-
- /**************************************************************************************************
- FUNCTION DESCRIPTION:
- Replace
- Replace an element in the list with a new one
- INPUT PARAMETERS:
- Element: The new element we want to replace the old one with
- rIter: An iterator to the element we want to replace
- RETURN VALUE:
- TRUE if success, FALSE if not
- ***************************************************************************************************/
- ELIST_TPL_DEF inline bool EList<ELIST_TPL_ARG>::Replace(T_ARG Element, const typename EList<ELIST_TPL_ARG>::EIterator& rIter)
- {
- gosASSERT(rIter.IsValid());
- if(!(rIter.IsValid()))
- {
- return(false);
- }
- rIter.m_pCur_Node->m_Data = Element;
- return(true);
- }
- /**************************************************************************************************
- FUNCTION DESCRIPTION:
- Replace
- Replace an element in the list with a new one
- INPUT PARAMETERS:
- Element: The new element we want to replace the old one with
- Pos: An index to the element we want to replace
- RETURN VALUE:
- TRUE if success, FALSE if not
- ***************************************************************************************************/
- ELIST_TPL_DEF inline bool EList<ELIST_TPL_ARG>::Replace(T_ARG Element, unsigned long Pos)
- {
- return(Replace(Element, Iterator(Pos)));
- }
- /**************************************************************************************************
- FUNCTION DESCRIPTION:
- Append
- Appends the given list to this one
- INPUT PARAMETERS:
- rList: A reference to the list that is to be prepended
- RETURN VALUE:
- TRUE if success, FALSE if not
- ***************************************************************************************************/
- ELIST_TPL_DEF bool EList<ELIST_TPL_ARG>::Append(const EList<ELIST_TPL_ARG>& rList)
- {
- gosASSERT(&rList != this);
- //
- // Iterate through the source list and add any element to this one
- //
- const ENode* pNode = rList.m_pHead;
- for(unsigned long i = 0; i < rList.m_Count; i++)
- {
- Append(pNode->m_Data); // <<TODO>> BR - This needs to be optimized
- pNode = pNode->m_pNext;
- }
- return(true);
- }
- /**************************************************************************************************
- FUNCTION DESCRIPTION:
- Prepend
- Prepends the given list to this one
- INPUT PARAMETERS:
- rList: A reference to the list that is to be prepended
- RETURN VALUE:
- TRUE if success, FALSE if not
- ***************************************************************************************************/
- ELIST_TPL_DEF bool EList<ELIST_TPL_ARG>::Prepend(const EList<ELIST_TPL_ARG>& rList)
- {
- gosASSERT(&rList != this);
- //
- // Iterate through the source list and add any element to this one
- //
- const ENode* pNode = rList.m_pTail;
- for(unsigned long i = 0; i < rList.m_Count; i++)
- {
- Prepend(pNode->m_Data); // <<TODO>> BR - This needs to be optimized
- pNode = pNode->m_pPrev;
- }
- return(true);
- }
- /**************************************************************************************************
- FUNCTION DESCRIPTION:
- Insert
- Insert all elements from the list given into this list
- INPUT PARAMETERS:
- rList: A reference to the list to be inserted
- rIter: An iterator into the list at which to start the insert
- RETURN VALUE:
- TRUE if success, FALSE if not
- ***************************************************************************************************/
- ELIST_TPL_DEF bool EList<ELIST_TPL_ARG>::Insert(const EList<ELIST_TPL_ARG>& rList, const typename EList<ELIST_TPL_ARG>::EIterator& rIter)
- {
- gosASSERT(&rList != this);
- gosASSERT(rIter.IsValid());
- EConstIterator Src_Iter = rList.Begin();
- for(unsigned long i = 0; i < rList.m_Count; i++)
- {
- Insert(Src_Iter.Item(), rIter);
- Src_Iter++;
- }
- return(true);
- }
- /**************************************************************************************************
- FUNCTION DESCRIPTION:
- Insert
- Insert all elements from the list given into this list
- INPUT PARAMETERS:
- rList: A reference to the list to be inserted
- Pos: An index to the position at which to start the insert
- RETURN VALUE:
- TRUE if success, FALSE if not
- ***************************************************************************************************/
- ELIST_TPL_DEF bool EList<ELIST_TPL_ARG>::Insert(const EList<ELIST_TPL_ARG>& rList, unsigned long Pos)
- {
- gosASSERT( &rList != this);
- return(Insert(rList, Iterator(Pos)));
- }
- //-------------------------------------------------------------------------------------------------
- // ACCESSORS
- //-------------------------------------------------------------------------------------------------
- /**************************************************************************************************
- FUNCTION DESCRIPTION:
- Get
- Get an element from the list using an iterator to determine it's location
- INPUT PARAMETERS:
- rIter: The iterator of the element we want to get
- RETURN VALUE:
- The element referenced by the iterator
- ***************************************************************************************************/
- ELIST_TPL_DEF inline T_ARG EList<ELIST_TPL_ARG>::Get(const typename EList<ELIST_TPL_ARG>::EConstIterator& rIter) const
- {
- gosASSERT(m_Count && rIter.IsValid());
- return(rIter.m_pCur_Node->m_Data);
- }
-
- /**************************************************************************************************
- FUNCTION DESCRIPTION:
- Get
- Get the element that is at the position we passed to the function
- INPUT PARAMETERS:
- Pos: The position of the element we want to get
- RETURN VALUE:
- The element at the position we passed
- ***************************************************************************************************/
- ELIST_TPL_DEF inline T_ARG EList<ELIST_TPL_ARG>::Get(unsigned long Pos) const
- {
- gosASSERT(m_Count > Pos && m_Count);
- return(Get(Iterator(Pos)));
- }
- /**************************************************************************************************
- FUNCTION DESCRIPTION:
- GetHead
- Get the element that is at the head of the list
- RETURN VALUE:
- The element at the head of the list
- ***************************************************************************************************/
- ELIST_TPL_DEF inline T_ARG EList<ELIST_TPL_ARG>::GetHead() const
- {
- gosASSERT(m_Count);
- return(m_pHead->m_Data);
- }
-
- /**************************************************************************************************
- FUNCTION DESCRIPTION:
- GetTail
- Get the element that is at the tail of the list
- RETURN VALUE:
- The element at the tail of the list
- ***************************************************************************************************/
- ELIST_TPL_DEF inline T_ARG EList<ELIST_TPL_ARG>::GetTail() const
- {
- gosASSERT(m_Count);
- return(m_pTail->m_Data);
- }
-
- /**************************************************************************************************
- FUNCTION DESCRIPTION:
- Find
- Search through the list for the item corresponding to "Item"
- INPUT PARAMETERS:
- Item: The item to search for
- Start_Index: The element at which to start the search
- RETURN VALUE:
- The iterator that corresponds with the element in the list we searched for,
- or INVALID_ITERATOR if the element could not be found
- ***************************************************************************************************/
- ELIST_TPL_DEF inline typename EList<ELIST_TPL_ARG>::EConstIterator EList<ELIST_TPL_ARG>::Find(T_ARG Item, unsigned long Start_Index) const
- {
- gosASSERT(Start_Index < m_Count && (!(IsEmpty())));
- return(Find(Item, Iterator(Start_Index)));
- }
- /**************************************************************************************************
- FUNCTION DESCRIPTION:
- Find
- Search through the list for the item corresponding to "Item"
- INPUT PARAMETERS:
- Item: The item to search for
- Start_Index: The element at which to start the search
- RETURN VALUE:
- The iterator that corresponds with the element in the list we searched for,
- or INVALID_ITERATOR if the element could not be found
- ***************************************************************************************************/
- ELIST_TPL_DEF inline typename EList<ELIST_TPL_ARG>::EIterator EList<ELIST_TPL_ARG>::Find(T_ARG Item, unsigned long Start_Index)
- {
- gosASSERT(Start_Index < m_Count && (!(IsEmpty())));
- return(Find(Item, Iterator(Start_Index)));
- }
- /**************************************************************************************************
- FUNCTION DESCRIPTION:
- Find
- Search through the list for the item corresponding to "Item"
- INPUT PARAMETERS:
- Item: The item to search for
- rStart_Iterator: The element at which to start the search
- RETURN VALUE:
- The iterator that corresponds with the element in the list we searched for,
- or INVALID_ITERATOR if the element could not be found
- ***************************************************************************************************/
- 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
- {
- gosASSERT(rStart_Iterator.IsValid());
- EConstIterator Iter = rStart_Iterator;
- while(!(Iter.IsDone()))
- {
- if(Iter.Item() == Item)
- {
- return(Iter);
- }
- Iter++;
- }
- return(INVALID_ITERATOR);
- }
- /**************************************************************************************************
- FUNCTION DESCRIPTION:
- Find
- Search through the list for the item corresponding to "Item"
- INPUT PARAMETERS:
- Item: The item to search for
- rStart_Iterator: The element at which to start the search
- RETURN VALUE:
- The iterator that corresponds with the element in the list we searched for,
- or INVALID_ITERATOR if the element could not be found
- ***************************************************************************************************/
- 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)
- {
- gosASSERT(rStart_Iterator.IsValid());
- EIterator Iter = rStart_Iterator;
- while(!(Iter.IsDone()))
- {
- if(Iter.Item() == Item)
- {
- return(Iter);
- }
- Iter++;
- }
- return(INVALID_ITERATOR);
- }
- /**************************************************************************************************
- FUNCTION DESCRIPTION:
- Count
- Retrieve the number of elements currently in the list
- RETURN VALUE:
- The number of elements in the list
- ***************************************************************************************************/
- ELIST_TPL_DEF inline unsigned long EList<ELIST_TPL_ARG>::Count() const
- {
- return(m_Count);
- }
-
- /**************************************************************************************************
- FUNCTION DESCRIPTION:
- IsEmpty
- Test the list for emptyness
- RETURN VALUE:
- TRUE if list is empty, FALSE if not
- ***************************************************************************************************/
- ELIST_TPL_DEF inline bool EList<ELIST_TPL_ARG>::IsEmpty() const
- {
- return(m_Count ? false : true);
- }
- /**************************************************************************************************
- FUNCTION DESCRIPTION:
- GrowSize
- Retrieve the current Growsize of the list
- RETURN VALUE:
- Current Growsize
- ***************************************************************************************************/
- ELIST_TPL_DEF inline unsigned long EList<ELIST_TPL_ARG>::GrowSize() const
- {
- return(m_List_Pool.PageSize());
- }
- /**************************************************************************************************
- FUNCTION DESCRIPTION:
- Exists
- Determine whether an entry exists in the list
- INPUT PARAMETERS:
- Pos: The position of the element we want to check for existance
- RETURN VALUE:
- TRUE if exist, FALSE if not
- ***************************************************************************************************/
- ELIST_TPL_DEF inline bool EList<ELIST_TPL_ARG>::Exists(unsigned long Pos) const
- {
- if(Pos < m_Count)
- {
- return(true);
- }
- return(false);
- }
- //-------------------------------------------------------------------------------------------------
- // HELPER FUNCTIONS
- //-------------------------------------------------------------------------------------------------
- ELIST_TPL_DEF inline bool EList<ELIST_TPL_ARG>::AddFirstElement(T_ARG New_Element)
- {
- ENode* pElement = CreateElement(New_Element);
- if(!pElement)
- {
- return(false);
- }
- m_pHead = m_pTail = pElement; // Setup List head and tail pointers
- pElement->m_pNext = pElement->m_pPrev = NULL;
- m_Count = 1;
- return(true);
- }
- //-------------------------------------------------------------------------------------------------
- // Note: m_pNext and m_pPrev are not initialized
- ELIST_TPL_DEF inline typename EList<ELIST_TPL_ARG>::ENode* EList<ELIST_TPL_ARG>::CreateElement(T_ARG New_Element)
- {
- ENode* pNode = (ENode*)systemHeap->Malloc( sizeof( ENode ) ); // Allocate memory for the node and data
- if(!pNode)
- {
- return(NULL); // return NULL if it fails
- }
- pNode = new(pNode) ENode(New_Element); // and construct the data object explicitly
- gosASSERT(pNode);
- return(pNode); // return the pointer to the Node of the element we created
- }
- //-------------------------------------------------------------------------------------------------
- ELIST_TPL_DEF inline void EList<ELIST_TPL_ARG>::KillElement(ENode* pElement)
- {
- gosASSERT(pElement);
- pElement->m_Data.~T(); // Destruct the data component of the element
- systemHeap->Free(pElement); // Now free the element
- }
-
- //-------------------------------------------------------------------------------------------------
- ELIST_TPL_DEF inline void EList<ELIST_TPL_ARG>::DestroyList()
- {
- //
- // simply return if list is empty
- //
- if(IsEmpty())
- {
- return;
- }
- //
- // Otherwise remove the head element until none are left
- //
- while(m_Count)
- {
- DeleteHead();
- }
- }
-
- /**************************************************************************************************
- FUNCTION DESCRIPTION:
- CopyData
- Copies data from the source list into this one
- NOTE: The function assumes the list to be empty at when it is called
- INPUT PARAMETERS:
- rSrc: Reference to the source list
- RETURN VALUE:
- TRUE is success
- ***************************************************************************************************/
- ELIST_TPL_DEF bool EList<ELIST_TPL_ARG>::CopyData(const EList<ELIST_TPL_ARG>& rSrc)
- {
- //
- // Iterate through the source list and add any element to this one
- //
- m_Count = rSrc.m_Count;
- if(!m_Count)
- {
- m_pHead = m_pTail = NULL;
- return(true);
- }
- ENode* pSrc_Node = rSrc.m_pHead;
- ENode* pNode = CreateElement(pSrc_Node->m_Data);
- gosASSERT(pNode && pSrc_Node); // Should never be NULL
- m_pHead = m_pTail = pNode;
- m_pHead->m_pPrev = NULL;
-
- for(unsigned long i = 1; i<rSrc.m_Count; i++)
- {
- pSrc_Node = pSrc_Node->m_pNext;
- gosASSERT(pSrc_Node); // Should never be NULL
- m_pTail = CreateElement(pSrc_Node->m_Data);
- gosASSERT(m_pTail);
- m_pTail->m_pPrev = pNode;
- pNode->m_pNext = m_pTail;
- pNode = m_pTail;
- }
- m_pTail->m_pNext = NULL;
- return(true);
- }
-
- //*************************************************************************************************
- #endif // end of file ( ELIST.h )
|