1 // Created on: 2002-04-17
2 // Created by: Alexander Kartomin (akm)
3 // Copyright (c) 2002-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #ifndef NCollection_List_HeaderFile
17 #define NCollection_List_HeaderFile
19 #include <NCollection_TListIterator.hxx>
21 #if !defined No_Exception && !defined No_Standard_NoSuchObject
22 #include <Standard_NoSuchObject.hxx>
26 * Purpose: Simple list to link items together keeping the first
28 * Inherits BaseList, adding the data item to each node.
30 template <class TheItemType> class NCollection_List
31 : public NCollection_BaseCollection<TheItemType>,
32 public NCollection_BaseList
35 typedef NCollection_TListNode<TheItemType> ListNode;
36 typedef NCollection_TListIterator<TheItemType> Iterator;
39 // ---------- PUBLIC METHODS ------------
42 NCollection_List(const Handle(NCollection_BaseAllocator)& theAllocator=0L) :
43 NCollection_BaseCollection<TheItemType>(theAllocator),
44 NCollection_BaseList() {}
47 NCollection_List (const NCollection_List& theOther) :
48 NCollection_BaseCollection<TheItemType>(theOther.myAllocator),
49 NCollection_BaseList()
52 //! Size - Number of items
53 virtual Standard_Integer Size (void) const
56 //! Replace this list by the items of theOther collection
57 virtual void Assign (const NCollection_BaseCollection<TheItemType>& theOther)
59 if (this == &theOther)
62 TYPENAME NCollection_BaseCollection<TheItemType>::Iterator& anIter =
63 theOther.CreateIterator();
64 for (; anIter.More(); anIter.Next())
66 ListNode* pNew = new (this->myAllocator) ListNode(anIter.Value());
71 //! Replace this list by the items of another list (theOther parameter)
72 void Assign (const NCollection_List& theOther)
74 if (this != &theOther) {
76 appendList(theOther.PFirst());
80 //! Replace this list by the items of theOther list
81 NCollection_List& operator= (const NCollection_List& theOther)
83 if (this != &theOther) {
84 Clear (theOther.myAllocator);
85 appendList(theOther.PFirst());
91 void Clear (const Handle(NCollection_BaseAllocator)& theAllocator=0L)
93 PClear (ListNode::delNode, this->myAllocator);
94 if (!theAllocator.IsNull())
95 this->myAllocator = theAllocator;
99 const TheItemType& First (void) const
101 #if !defined No_Exception && !defined No_Standard_NoSuchObject
103 Standard_NoSuchObject::Raise ("NCollection_List::First");
105 return ((const ListNode *) PFirst())->Value();
109 const TheItemType& Last (void) const
111 #if !defined No_Exception && !defined No_Standard_NoSuchObject
113 Standard_NoSuchObject::Raise ("NCollection_List::Last");
115 return ((const ListNode *) PLast())->Value();
118 //! Append one item at the end
119 TheItemType& Append (const TheItemType& theItem)
121 ListNode * pNew = new (this->myAllocator) ListNode(theItem);
123 return ((ListNode *) PLast())->ChangeValue();
126 //! Append one item at the end and output iterator
127 //! pointing at the appended item
128 void Append (const TheItemType& theItem, Iterator& theIter)
130 ListNode * pNew = new (this->myAllocator) ListNode(theItem);
131 PAppend(pNew, theIter);
134 //! Append another list at the end
135 void Append (NCollection_List& theOther)
137 if (this == &theOther || theOther.Extent()<1)
139 if (this->myAllocator == theOther.myAllocator)
141 // Then we take the list and glue it to our end -
142 // deallocation will bring no problem
147 // No - this list has different memory scope
148 appendList(theOther.myFirst);
153 //! Prepend one item at the beginning
154 TheItemType& Prepend (const TheItemType& theItem)
156 ListNode * pNew = new (this->myAllocator) ListNode(theItem);
158 return ((ListNode *) PFirst())->ChangeValue();
161 //! Prepend another list at the beginning
162 void Prepend (NCollection_List& theOther)
164 if (this == &theOther || theOther.Extent()<1)
166 if (this->myAllocator == theOther.myAllocator)
168 // Then we take the list and glue it to our head -
169 // deallocation will bring no problem
174 // No - this list has different memory scope
176 prependList(theOther.PFirst(), it);
182 void RemoveFirst (void)
183 { PRemoveFirst (ListNode::delNode, this->myAllocator); }
186 void Remove (Iterator& theIter)
188 PRemove (theIter, ListNode::delNode, this->myAllocator);
192 TheItemType& InsertBefore (const TheItemType& theItem,
195 ListNode * pNew = new (this->myAllocator) ListNode(theItem);
196 PInsertBefore (pNew, theIter);
197 return pNew -> ChangeValue();
201 void InsertBefore (NCollection_List& theOther,
204 if (this == &theOther)
207 if (this->myAllocator == theOther.myAllocator)
209 // Then we take the list and glue it to our head -
210 // deallocation will bring no problem
211 PInsertBefore (theOther, theIter);
215 // No - this list has different memory scope
216 prependList(theOther.myFirst, theIter);
222 TheItemType& InsertAfter (const TheItemType& theItem,
225 ListNode * pNew = new (this->myAllocator) ListNode(theItem);
226 PInsertAfter (pNew, theIter);
227 return pNew -> ChangeValue();
231 void InsertAfter (NCollection_List& theOther,
239 if (this->myAllocator == theOther.myAllocator)
241 // Then we take the list and glue it to our head -
242 // deallocation will bring no problem
243 PInsertAfter (theOther, theIter);
247 // No - this list has different memory scope
248 #if !defined No_Exception && !defined No_Standard_NoSuchObject
250 Standard_NoSuchObject::Raise ("NCollection_List::InsertAfter");
253 anIter.myPrevious = theIter.myCurrent;
254 anIter.myCurrent = theIter.myCurrent->Next();
255 prependList(theOther.PFirst(), anIter);
264 //! Destructor - clears the List
265 ~NCollection_List (void)
269 // ----------- PRIVATE METHODS -----------
271 //! Creates Iterator for use on BaseCollection
272 virtual TYPENAME NCollection_BaseCollection<TheItemType>::Iterator&
273 CreateIterator(void) const
274 { return *(new (this->IterAllocator()) Iterator(*this)); }
276 //! append the list headed by the given ListNode
277 void appendList(const NCollection_ListNode * pCur) {
279 NCollection_ListNode * pNew =
280 new (this->myAllocator) ListNode(((const ListNode *)(pCur))->Value());
286 //! insert the list headed by the given ListNode before the given iterator
287 void prependList(const NCollection_ListNode * pCur, Iterator& theIter) {
289 NCollection_ListNode * pNew =
290 new (this->myAllocator) ListNode (((const ListNode *)(pCur))->Value());
291 PInsertBefore(pNew, theIter);