///////////////////Software Control Header/////////////////////////////////// // TSingLst.h - Library to support singly list // // $LogThisFile$ \Projects\UtilCode\Include\TSingLst.h // // V01.01 15/10/2000 2337 // CSinglyList - Remove accept pointer to element(default = m_head). // Return true on success. // Accept pointer insertion. // // V01.00 10/10/2000 2159 // Initial revision. // // This code is freely distributed to help the development of complex // software in any field using C++. The author is not held responsible // for any damage caused by the usage of the code. // The author should be acknowledged for the use of this piece of code in // commercial software. // // Bug reports and suggestions are welcomed to report to // // tzzstan@hotmail.com ///////////////////////////////////////////////////////////////////////////// #ifndef __TS_SList__ #define __TS_SList__ #include ///////////////////////////////////////////////////////////////////////////// // CSinglyNode - Node representation of an object type. // // Desctiption: Manipulate object in node type. // // TSTan 12 Aug 2000 ///////////////////////////////////////////////////////////////////////////// template class CSinglyNode { T *m_data; CSinglyNode *m_next; public: CSinglyNode(CSinglyNode &, CSinglyNode *Next = NULL); // copy const CSinglyNode(T &, CSinglyNode *Next = NULL); CSinglyNode(T *, CSinglyNode *Next = NULL); ~CSinglyNode(); /////////////////// // Modifiers /////////////////// // Set to next pointer void SetNext(CSinglyNode *next) {m_next = next;} CSinglyNode &operator=(CSinglyNode &); /////////////////// // Data retrieval /////////////////// // Return data pointer T *Data() const {return m_data;} // Return next pointer CSinglyNode *Next() const {return m_next;} }; ///////////////////////////////////////////////////////////////////////////// // CSinglyNode(CSinglyNode &original, CSinglyNode *Next) // // Desctiption: Copy constructor that creates a copy from original. // // original - Original node. // Next - Optional pointer to next element(Defaulted to NULL). // // TSTan 12 Aug 2000 ///////////////////////////////////////////////////////////////////////////// template CSinglyNode::CSinglyNode(CSinglyNode &original, CSinglyNode *Next) { m_data = new T(*(original.m_data)); m_next = Next; } ///////////////////////////////////////////////////////////////////////////// // operator=(CSinglyNode &original // // Desctiption: Assignment with copy of T in node. // // Original - Original node. // // TSTan 12 Aug 2000 ///////////////////////////////////////////////////////////////////////////// template CSinglyNode &CSinglyNode:: operator=(CSinglyNode &original) { delete m_data; m_data = new T(*(original.m_data)); m_next = NULL; return *this; } ///////////////////////////////////////////////////////////////////////////// // CSinglyNode(T &Element, CSinglyNode *Next) // // Desctiption: Constructor to create copy of T in node. // // Element - Reference to the element to be inserted. // Next - Optional pointer to next element(Defaulted to NULL). // // TSTan 12 Aug 2000 ///////////////////////////////////////////////////////////////////////////// template CSinglyNode::CSinglyNode(T &Element, CSinglyNode *Next) { m_data = new T(Element); m_next = Next; } ///////////////////////////////////////////////////////////////////////////// // CSinglyNode(T *Element, CSinglyNode *Next) // // Desctiption: Constructor to create copy of T in node. // // Element - Reference to the element to be inserted. // Next - Optional pointer to next element(Defaulted to NULL). // // TSTan 14 Oct 2000 ///////////////////////////////////////////////////////////////////////////// template CSinglyNode::CSinglyNode(T *Element, CSinglyNode *Next) { m_data = Element; m_next = Next; } ///////////////////////////////////////////////////////////////////////////// // ~CSinglyNode() // // Desctiption: Destructor to clean up memory. // // TSTan 12 Aug 2000 ///////////////////////////////////////////////////////////////////////////// template CSinglyNode::~CSinglyNode() { delete m_data; } ///////////////////////////////////////////////////////////////////////////// // CSinglyList - class declaration of CSinglyList. // // Desctiption: Maintain objects in singly list. // // TSTan 12 Aug 2000 ///////////////////////////////////////////////////////////////////////////// template class CSinglyList { int m_size; CSinglyNode *m_head, *m_current; CSinglyNode *CopyNodes(CSinglyNode *); T *InsertTail(T &, CSinglyNode *); T *InsertTail(T *, CSinglyNode *); public: // HEAD/TAIL to insert element. enum Location{ HEAD, TAIL }; CSinglyList(CSinglyList &); // Copy constructor CSinglyList(); ~CSinglyList(); /////////////////// // Modifiers /////////////////// T *Insert(T &, enum Location = HEAD); T *Insert(T *, enum Location = HEAD); bool Remove(T *Element = NULL); void RemoveAll(); void ResetPtr(); CSinglyNode *Next(); CSinglyList &operator=(CSinglyList &); // Assignment operator /////////////////// // Data retrieval /////////////////// // Return data pointer to current node. T *Current() const {return m_current->Data();} // Return current pointer. CSinglyNode *CurrentPtr() const {return m_current;}; // Return true if the list is empty. bool IsEmpty() const {return !m_head;} // Return true if current point to valid element. bool IsValid() const {return !(m_current == NULL);} // Return the size of list. int Size() const {return m_size;} bool Exist(T &source); }; ///////////////////////////////////////////////////////////////////////////// // Exist(T &source) // // Desctiption: Check whether 'source' exist in list. // // TSTan 29 Aug 2000 ///////////////////////////////////////////////////////////////////////////// template bool CSinglyList::Exist(T &source) { for(ResetPtr(); IsValid(); Next()) if(*Current() == source) return true; return false; } ///////////////////////////////////////////////////////////////////////////// // ResetPtr() // // Desctiption: Set current pointer to the head of list. // // TSTan 13 Aug 2000 ///////////////////////////////////////////////////////////////////////////// template void CSinglyList::ResetPtr() { m_current = m_head; } ///////////////////////////////////////////////////////////////////////////// // Next() // // Desctiption: Set current pointer to the next of current node. // // TSTan 13 Aug 2000 ///////////////////////////////////////////////////////////////////////////// template CSinglyNode *CSinglyList::Next() { if(m_current) m_current = m_current->Next(); return m_current; } ///////////////////////////////////////////////////////////////////////////// // CSinglyList(CSinglyList &original) // // Desctiption: Copy constructor that creates list from original. // // original - Original list. // // TSTan 12 Aug 2000 ///////////////////////////////////////////////////////////////////////////// template CSinglyList::CSinglyList(CSinglyList &original) { m_head = NULL; m_current = NULL; m_size = 0; m_head = CopyNodes(original.m_head); ResetPtr(); } ///////////////////////////////////////////////////////////////////////////// // operator=(CSinglyList &original) // // Desctiption: Create list from original. // // original - Original list. // // TSTan 12 Aug 2000 ///////////////////////////////////////////////////////////////////////////// template CSinglyList &CSinglyList:: operator=(CSinglyList &original) { RemoveAll(); m_head = CopyNodes(original.m_head); ResetPtr(); return *this; } ///////////////////////////////////////////////////////////////////////////// // CopyNodes(CSinglyNode *thisNode) // // Desctiption: Function to recursively generates all nodes. // // thisNode - Pointer to node to generate // // TSTan 12 Aug 2000 ///////////////////////////////////////////////////////////////////////////// template CSinglyNode *CSinglyList:: CopyNodes(CSinglyNode *thisNode) { if(thisNode) { m_head = CopyNodes(thisNode->Next()); m_size++; return new CSinglyNode(*thisNode, m_head); } return NULL; } ///////////////////////////////////////////////////////////////////////////// // CSinglyList() // // Desctiption: Constructor to initialize list members. // // TSTan 12 Aug 2000 ///////////////////////////////////////////////////////////////////////////// template CSinglyList::CSinglyList() { m_head = NULL; m_size = 0; } ///////////////////////////////////////////////////////////////////////////// // ~CSinglyList() // // Desctiption: Destructor to clean up memory. // // TSTan 12 Aug 2000 ///////////////////////////////////////////////////////////////////////////// template CSinglyList::~CSinglyList() { RemoveAll(); } ///////////////////////////////////////////////////////////////////////////// // RemoveAll() // // Desctiption: Empty the list. // // TSTan 12 Aug 2000 ///////////////////////////////////////////////////////////////////////////// template void CSinglyList::RemoveAll() { while(m_head) Remove(); m_head = NULL; m_current = NULL; m_size = 0; } ///////////////////////////////////////////////////////////////////////////// // Insert(T &Element) // // Desctiption: Insert one element into list. // // TSTan 12 Aug 2000 ///////////////////////////////////////////////////////////////////////////// template T *CSinglyList::Insert(T &Element, enum Location where) { if(where == HEAD) { CSinglyNode *NewNode = new CSinglyNode(Element, m_head); m_head = NewNode; m_size++; return NewNode->Data(); } else return InsertTail(Element, m_head); } ///////////////////////////////////////////////////////////////////////////// // Insert(T *Element) // // Desctiption: Insert one element into list. // // TSTan 14 Oct 2000 ///////////////////////////////////////////////////////////////////////////// template T *CSinglyList::Insert(T *Element, enum Location where) { if(where == HEAD) { CSinglyNode *NewNode = new CSinglyNode(Element, m_head); m_head = NewNode; m_size++; return NewNode->Data(); } else return InsertTail(Element, m_head); } ///////////////////////////////////////////////////////////////////////////// // InsertTail(T &Element, CSiglyNode *thisNode) // // Desctiption: Insert one element into the end of list. // // TSTan 13 Aug 2000 ///////////////////////////////////////////////////////////////////////////// template T *CSinglyList::InsertTail(T &Element, CSinglyNode *thisNode) { if(thisNode) { if(thisNode->Next()) return InsertTail(Element, thisNode->Next()); else { m_size++; thisNode->SetNext(new CSinglyNode(Element)); return thisNode->Next()->Data(); } } else { m_size++; m_head = new CSinglyNode(Element); return m_head->Data(); } } ///////////////////////////////////////////////////////////////////////////// // InsertTail(T *Element, CSiglyNode *thisNode) // // Desctiption: Insert one element into the end of list. // // TSTan 14 Oct 2000 ///////////////////////////////////////////////////////////////////////////// template T *CSinglyList::InsertTail(T *Element, CSinglyNode *thisNode) { if(thisNode) { if(thisNode->Next()) return InsertTail(Element, thisNode->Next()); else { m_size++; thisNode->SetNext(new CSinglyNode(Element)); return thisNode->Next()->Data(); } } else { m_size++; m_head = new CSinglyNode(Element); return m_head->Data(); } } ///////////////////////////////////////////////////////////////////////////// // Remove() // // Desctiption: Remove the first element from head. // // TSTan 12 Aug 2000 // ///////////////////////////////////////////////////////////////////////////// template bool CSinglyList::Remove(T *Element) { if(!m_head) return false; if(Element == NULL) Element = m_head->Data(); CSinglyNode *PrevNode = NULL; for(CSinglyNode *CurrentNode = m_head; CurrentNode; CurrentNode = CurrentNode->Next()) { if(CurrentNode->Data() != Element) { PrevNode = CurrentNode; continue; } if(PrevNode) PrevNode->SetNext(CurrentNode->Next()); else m_head = CurrentNode->Next(); delete CurrentNode; m_size--; return true; } return false; } #endif