0022815: Missing delete operator for placement new
[occt.git] / src / NCollection / NCollection_List.hxx
1 // File:         NCollection_List.hxx
2 // Created:      17.04.02 10:12:48
3 // Author:       Alexander Kartomin (akm)
4 //               <a-kartomin@opencascade.com>
5 // Copyright:    Open Cascade 2002
6
7 #ifndef NCollection_List_HeaderFile
8 #define NCollection_List_HeaderFile
9
10 #include <NCollection_TListIterator.hxx>
11
12 #if !defined No_Exception && !defined No_Standard_NoSuchObject
13 #include <Standard_NoSuchObject.hxx>
14 #endif
15
16 /**
17  * Purpose:      Simple list to link  items together keeping the first 
18  *               and the last one.
19  *               Inherits BaseList, adding the data item to each node.
20  */               
21 template <class TheItemType> class NCollection_List
22   : public NCollection_BaseCollection<TheItemType>,
23     public NCollection_BaseList
24 {
25  public:
26   typedef NCollection_TListNode<TheItemType>     ListNode;
27   typedef NCollection_TListIterator<TheItemType> Iterator;
28
29  public:
30   // ---------- PUBLIC METHODS ------------
31
32   //! Constructor
33   NCollection_List(const Handle(NCollection_BaseAllocator)& theAllocator=0L) :
34     NCollection_BaseCollection<TheItemType>(theAllocator),
35     NCollection_BaseList() {}
36
37   //! Copy constructor
38   NCollection_List (const NCollection_List& theOther) :
39     NCollection_BaseCollection<TheItemType>(theOther.myAllocator),
40     NCollection_BaseList()
41   { *this = theOther; }
42
43   //! Size - Number of items
44   virtual Standard_Integer Size (void) const
45   { return Extent(); }
46
47   //! Replace this list by the items of theOther collection
48   virtual void Assign (const NCollection_BaseCollection<TheItemType>& theOther)
49   {
50     if (this == &theOther) 
51       return;
52     Clear();
53     TYPENAME NCollection_BaseCollection<TheItemType>::Iterator& anIter = 
54       theOther.CreateIterator();
55     for (; anIter.More(); anIter.Next())
56     {
57       ListNode* pNew = new (this->myAllocator) ListNode(anIter.Value());
58       PAppend(pNew);
59     }
60   }
61
62   //! Replace this list by the items of another list (theOther parameter)
63   void Assign (const NCollection_List& theOther)
64   {
65     if (this != &theOther) {
66       Clear();
67       appendList(theOther.PFirst());
68     }
69   }
70
71   //! Replace this list by the items of theOther list
72   NCollection_List& operator= (const NCollection_List& theOther)
73   { 
74     if (this != &theOther) {
75       Clear (theOther.myAllocator);
76       appendList(theOther.PFirst());
77     }
78     return *this;
79   }
80
81   //! Clear this list
82   void Clear (const Handle(NCollection_BaseAllocator)& theAllocator=0L)
83   {
84     PClear (ListNode::delNode, this->myAllocator);
85     if (!theAllocator.IsNull())
86       this->myAllocator = theAllocator;
87   }
88
89   //! First item
90   const TheItemType& First (void) const
91   {
92 #if !defined No_Exception && !defined No_Standard_NoSuchObject
93     if (IsEmpty())
94       Standard_NoSuchObject::Raise ("NCollection_List::First");
95 #endif
96     return ((const ListNode *) PFirst())->Value();
97   }
98
99   //! Last item
100   const TheItemType& Last (void) const
101   { 
102 #if !defined No_Exception && !defined No_Standard_NoSuchObject
103     if (IsEmpty())
104       Standard_NoSuchObject::Raise ("NCollection_List::Last");
105 #endif
106     return ((const ListNode *) PLast())->Value();
107   }
108
109   //! Append one item at the end
110   TheItemType& Append (const TheItemType& theItem)
111   { 
112     ListNode * pNew = new (this->myAllocator) ListNode(theItem);
113     PAppend(pNew);
114     return ((ListNode *) PLast())->ChangeValue();
115   }
116
117   //! Append one item at the end and output iterator
118   //!   pointing at the appended item
119   void Append (const TheItemType& theItem, Iterator& theIter)
120   { 
121     ListNode * pNew = new (this->myAllocator) ListNode(theItem);
122     PAppend(pNew, theIter);
123   }
124
125   //! Append another list at the end
126   void Append (NCollection_List& theOther)
127   { 
128     if (this == &theOther || theOther.Extent()<1)
129       return;
130     if (this->myAllocator == theOther.myAllocator)
131     {
132       // Then we take the list and glue it to our end - 
133       // deallocation will bring no problem
134       PAppend(theOther);
135     }
136     else
137     {
138       // No - this list has different memory scope
139       appendList(theOther.myFirst);
140       theOther.Clear();
141     }
142   }
143
144   //! Prepend one item at the beginning
145   TheItemType& Prepend (const TheItemType& theItem)
146   { 
147     ListNode * pNew = new (this->myAllocator) ListNode(theItem);
148     PPrepend(pNew);
149     return ((ListNode *) PFirst())->ChangeValue();
150   }
151
152   //! Prepend another list at the beginning
153   void Prepend (NCollection_List& theOther)
154   { 
155     if (this == &theOther || theOther.Extent()<1) 
156       return;
157     if (this->myAllocator == theOther.myAllocator)
158     {
159       // Then we take the list and glue it to our head - 
160       // deallocation will bring no problem
161       PPrepend(theOther);
162     }
163     else
164     {
165       // No - this list has different memory scope
166       Iterator it(*this);
167       prependList(theOther.PFirst(), it);
168       theOther.Clear();
169     }
170   }
171
172   //! RemoveFirst item
173   void RemoveFirst (void) 
174   { PRemoveFirst (ListNode::delNode, this->myAllocator); }
175
176   //! Remove item
177   void Remove (Iterator& theIter) 
178   { 
179     PRemove (theIter, ListNode::delNode, this->myAllocator); 
180   }
181
182   //! InsertBefore
183   TheItemType& InsertBefore (const TheItemType& theItem,
184                              Iterator& theIter) 
185   { 
186     ListNode * pNew = new (this->myAllocator) ListNode(theItem);
187     PInsertBefore (pNew, theIter);
188     return pNew -> ChangeValue();
189   }
190
191   //! InsertBefore
192   void InsertBefore (NCollection_List& theOther,
193                      Iterator& theIter) 
194   {
195     if (this == &theOther) 
196       return;
197   
198     if (this->myAllocator == theOther.myAllocator)
199     {
200       // Then we take the list and glue it to our head - 
201       // deallocation will bring no problem
202       PInsertBefore (theOther, theIter);
203     }
204     else
205     {
206       // No - this list has different memory scope
207       prependList(theOther.myFirst, theIter);
208       theOther.Clear();
209     }
210   }
211
212   //! InsertAfter
213   TheItemType& InsertAfter (const TheItemType& theItem,
214                             Iterator& theIter) 
215   {
216     ListNode * pNew = new (this->myAllocator) ListNode(theItem);
217     PInsertAfter (pNew, theIter);
218     return pNew -> ChangeValue();
219   }
220
221   //! InsertAfter
222   void InsertAfter (NCollection_List& theOther,
223                     Iterator& theIter) 
224   {
225     if (!theIter.More())
226     {
227       Append(theOther);
228       return;
229     }
230     if (this->myAllocator == theOther.myAllocator)
231     {
232       // Then we take the list and glue it to our head - 
233       // deallocation will bring no problem
234       PInsertAfter (theOther, theIter);
235     }
236     else
237     {
238       // No - this list has different memory scope
239 #if !defined No_Exception && !defined No_Standard_NoSuchObject
240       if (!theIter.More())
241         Standard_NoSuchObject::Raise ("NCollection_List::InsertAfter");
242 #endif
243       Iterator anIter;
244       anIter.myPrevious = theIter.myCurrent;
245       anIter.myCurrent = theIter.myCurrent->Next();
246       prependList(theOther.PFirst(), anIter);
247       theOther.Clear();
248     }
249   }
250
251   //! Reverse the list
252   void Reverse ()
253   { PReverse(); }
254
255   //! Destructor - clears the List
256   ~NCollection_List (void)
257   { Clear(); }
258
259  private:
260   // ----------- PRIVATE METHODS -----------
261
262   //! Creates Iterator for use on BaseCollection
263   virtual TYPENAME NCollection_BaseCollection<TheItemType>::Iterator& 
264     CreateIterator(void) const
265   { return *(new (this->IterAllocator()) Iterator(*this)); }
266
267   //! append the list headed by the given ListNode
268   void appendList(const NCollection_ListNode * pCur) {
269     while (pCur) {
270       NCollection_ListNode * pNew =
271         new (this->myAllocator) ListNode(((const ListNode *)(pCur))->Value());
272       PAppend(pNew);
273       pCur = pCur->Next();
274     }
275   }
276
277   //! insert the list headed by the given ListNode before the given iterator
278   void prependList(const NCollection_ListNode * pCur, Iterator& theIter) {
279     while (pCur) {
280       NCollection_ListNode * pNew =
281         new (this->myAllocator) ListNode (((const ListNode *)(pCur))->Value());
282       PInsertBefore(pNew, theIter);
283       pCur = pCur->Next();
284     }
285   }
286 };
287
288 #endif