// File: NCollection_List.hxx // Created: 17.04.02 10:12:48 // Author: Alexander Kartomin (akm) // // Copyright: Open Cascade 2002 #ifndef NCollection_List_HeaderFile #define NCollection_List_HeaderFile #include #if !defined No_Exception && !defined No_Standard_NoSuchObject #include #endif #ifdef WNT // Disable the warning "operator new unmatched by delete" #pragma warning (push) #pragma warning (disable:4291) #endif /** * Purpose: Simple list to link items together keeping the first * and the last one. * Inherits BaseList, adding the data item to each node. */ template class NCollection_List : public NCollection_BaseCollection, public NCollection_BaseList { public: typedef NCollection_TListNode ListNode; typedef NCollection_TListIterator Iterator; public: // ---------- PUBLIC METHODS ------------ //! Constructor NCollection_List(const Handle(NCollection_BaseAllocator)& theAllocator=0L) : NCollection_BaseCollection(theAllocator), NCollection_BaseList() {} //! Copy constructor NCollection_List (const NCollection_List& theOther) : NCollection_BaseCollection(theOther.myAllocator), NCollection_BaseList() { *this = theOther; } //! Size - Number of items virtual Standard_Integer Size (void) const { return Extent(); } //! Replace this list by the items of theOther collection virtual void Assign (const NCollection_BaseCollection& theOther) { if (this == &theOther) return; Clear(); TYPENAME NCollection_BaseCollection::Iterator& anIter = theOther.CreateIterator(); for (; anIter.More(); anIter.Next()) { ListNode* pNew = new (this->myAllocator) ListNode(anIter.Value()); PAppend(pNew); } } //! Replace this list by the items of another list (theOther parameter) void Assign (const NCollection_List& theOther) { if (this != &theOther) { Clear(); appendList(theOther.PFirst()); } } //! Replace this list by the items of theOther list NCollection_List& operator= (const NCollection_List& theOther) { if (this != &theOther) { Clear (theOther.myAllocator); appendList(theOther.PFirst()); } return *this; } //! Clear this list void Clear (const Handle(NCollection_BaseAllocator)& theAllocator=0L) { PClear (ListNode::delNode, this->myAllocator); if (!theAllocator.IsNull()) this->myAllocator = theAllocator; } //! First item const TheItemType& First (void) const { #if !defined No_Exception && !defined No_Standard_NoSuchObject if (IsEmpty()) Standard_NoSuchObject::Raise ("NCollection_List::First"); #endif return ((const ListNode *) PFirst())->Value(); } //! Last item const TheItemType& Last (void) const { #if !defined No_Exception && !defined No_Standard_NoSuchObject if (IsEmpty()) Standard_NoSuchObject::Raise ("NCollection_List::Last"); #endif return ((const ListNode *) PLast())->Value(); } //! Append one item at the end TheItemType& Append (const TheItemType& theItem) { ListNode * pNew = new (this->myAllocator) ListNode(theItem); PAppend(pNew); return ((ListNode *) PLast())->ChangeValue(); } //! Append one item at the end and output iterator //! pointing at the appended item void Append (const TheItemType& theItem, Iterator& theIter) { ListNode * pNew = new (this->myAllocator) ListNode(theItem); PAppend(pNew, theIter); } //! Append another list at the end void Append (NCollection_List& theOther) { if (this == &theOther || theOther.Extent()<1) return; if (this->myAllocator == theOther.myAllocator) { // Then we take the list and glue it to our end - // deallocation will bring no problem PAppend(theOther); } else { // No - this list has different memory scope appendList(theOther.myFirst); theOther.Clear(); } } //! Prepend one item at the beginning TheItemType& Prepend (const TheItemType& theItem) { ListNode * pNew = new (this->myAllocator) ListNode(theItem); PPrepend(pNew); return ((ListNode *) PFirst())->ChangeValue(); } //! Prepend another list at the beginning void Prepend (NCollection_List& theOther) { if (this == &theOther || theOther.Extent()<1) return; if (this->myAllocator == theOther.myAllocator) { // Then we take the list and glue it to our head - // deallocation will bring no problem PPrepend(theOther); } else { // No - this list has different memory scope Iterator it(*this); prependList(theOther.PFirst(), it); theOther.Clear(); } } //! RemoveFirst item void RemoveFirst (void) { PRemoveFirst (ListNode::delNode, this->myAllocator); } //! Remove item void Remove (Iterator& theIter) { PRemove (theIter, ListNode::delNode, this->myAllocator); } //! InsertBefore TheItemType& InsertBefore (const TheItemType& theItem, Iterator& theIter) { ListNode * pNew = new (this->myAllocator) ListNode(theItem); PInsertBefore (pNew, theIter); return pNew -> ChangeValue(); } //! InsertBefore void InsertBefore (NCollection_List& theOther, Iterator& theIter) { if (this == &theOther) return; if (this->myAllocator == theOther.myAllocator) { // Then we take the list and glue it to our head - // deallocation will bring no problem PInsertBefore (theOther, theIter); } else { // No - this list has different memory scope prependList(theOther.myFirst, theIter); theOther.Clear(); } } //! InsertAfter TheItemType& InsertAfter (const TheItemType& theItem, Iterator& theIter) { ListNode * pNew = new (this->myAllocator) ListNode(theItem); PInsertAfter (pNew, theIter); return pNew -> ChangeValue(); } //! InsertAfter void InsertAfter (NCollection_List& theOther, Iterator& theIter) { if (!theIter.More()) { Append(theOther); return; } if (this->myAllocator == theOther.myAllocator) { // Then we take the list and glue it to our head - // deallocation will bring no problem PInsertAfter (theOther, theIter); } else { // No - this list has different memory scope #if !defined No_Exception && !defined No_Standard_NoSuchObject if (!theIter.More()) Standard_NoSuchObject::Raise ("NCollection_List::InsertAfter"); #endif Iterator anIter; anIter.myPrevious = theIter.myCurrent; anIter.myCurrent = theIter.myCurrent->Next(); prependList(theOther.PFirst(), anIter); theOther.Clear(); } } //! Reverse the list void Reverse () { PReverse(); } //! Destructor - clears the List ~NCollection_List (void) { Clear(); } private: // ----------- PRIVATE METHODS ----------- //! Creates Iterator for use on BaseCollection virtual TYPENAME NCollection_BaseCollection::Iterator& CreateIterator(void) const { return *(new (this->IterAllocator()) Iterator(*this)); } //! append the list headed by the given ListNode void appendList(const NCollection_ListNode * pCur) { while (pCur) { NCollection_ListNode * pNew = new (this->myAllocator) ListNode(((const ListNode *)(pCur))->Value()); PAppend(pNew); pCur = pCur->Next(); } } //! insert the list headed by the given ListNode before the given iterator void prependList(const NCollection_ListNode * pCur, Iterator& theIter) { while (pCur) { NCollection_ListNode * pNew = new (this->myAllocator) ListNode (((const ListNode *)(pCur))->Value()); PInsertBefore(pNew, theIter); pCur = pCur->Next(); } } }; #ifdef WNT #pragma warning (pop) #endif #endif