05c63b0ed819a151126538e7156c7f8a279d5001
[occt.git] / src / NCollection / NCollection_BaseList.cxx
1 // Created on: 2002-04-23
2 // Created by: Alexander KARTOMIN (akm)
3 // Copyright (c) 2002-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
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.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 // Purpose:     Implementation of the BaseList class
17
18 #include <NCollection_BaseList.hxx>
19
20 //=======================================================================
21 //function : PClear
22 //purpose  : Deletes all nodes from the list
23 //=======================================================================
24
25 void NCollection_BaseList::PClear 
26   (NCollection_DelListNode fDel,
27    Handle(NCollection_BaseAllocator)& theAllocator)
28
29   NCollection_ListNode* pCur  = myFirst;
30   NCollection_ListNode* pNext = NULL;
31   while(pCur) 
32   {
33     pNext = pCur->Next();
34     fDel (pCur,theAllocator);
35     pCur = pNext;
36   }
37   myLength = 0;
38   myFirst = myLast = NULL;
39 }
40
41 //=======================================================================
42 //function : PAppend
43 //purpose  : Appends one item at the end
44 //=======================================================================
45
46 void NCollection_BaseList::PAppend (NCollection_ListNode* theNode)
47
48   if (myLength) 
49     myLast->Next() = theNode;
50   else 
51     myFirst = theNode;
52   theNode->Next() = NULL;
53   myLast = theNode;
54   myLength++;
55 }
56
57 //=======================================================================
58 //function : PAppend
59 //purpose  : Appends another list at the end
60 //=======================================================================
61
62 void NCollection_BaseList::PAppend (NCollection_BaseList& theOther)
63
64   if (this == &theOther || theOther.IsEmpty()) 
65     return;
66   
67   if (IsEmpty())
68     myFirst = theOther.myFirst;
69   else
70     myLast->Next() = theOther.myFirst;
71   myLast = theOther.myLast;
72   theOther.myFirst = theOther.myLast = NULL;
73
74   myLength += theOther.myLength;
75   theOther.myLength = 0;
76 }
77
78 //=======================================================================
79 //function : PPrepend
80 //purpose  : Prepends one item at the beginning
81 //=======================================================================
82
83 void NCollection_BaseList::PPrepend (NCollection_ListNode* theNode)
84
85   theNode->Next() = myFirst;
86   myFirst = theNode;
87   if (myLast==NULL)
88     myLast = myFirst;
89   myLength++;
90 }
91
92 //=======================================================================
93 //function : PPrepend
94 //purpose  : 
95 //=======================================================================
96
97 void NCollection_BaseList::PPrepend (NCollection_BaseList& theOther)
98
99   if (this == &theOther || theOther.IsEmpty()) 
100     return;
101
102   if (IsEmpty())
103     myLast = theOther.myLast;
104   else
105     theOther.myLast->Next() = myFirst;
106   myFirst = theOther.myFirst;
107   theOther.myFirst = theOther.myLast = NULL;
108
109   myLength += theOther.myLength;
110   theOther.myLength = 0;
111 }
112
113 //=======================================================================
114 //function : PRemoveFirst
115 //purpose  : 
116 //=======================================================================
117
118 void NCollection_BaseList::PRemoveFirst 
119   (NCollection_DelListNode fDel,
120    Handle(NCollection_BaseAllocator)& theAllocator) 
121 {
122   Standard_NoSuchObject_Raise_if(IsEmpty(),
123                                  "NCollection_BaseList::PRemoveFirst");
124   NCollection_ListNode* pItem = myFirst;
125   myFirst = pItem->Next();
126   fDel (pItem, theAllocator);
127   myLength--;
128   if (myLength == 0) 
129     myLast = NULL;
130 }
131
132 //=======================================================================
133 //function : PRemove
134 //purpose  : 
135 //=======================================================================
136
137 void NCollection_BaseList::PRemove 
138   (Iterator& theIter, 
139    NCollection_DelListNode fDel,
140    Handle(NCollection_BaseAllocator)& theAllocator) 
141 {
142   Standard_NoSuchObject_Raise_if(!theIter.More(),
143                                  "NCollection_BaseList::PRemove");
144   if (theIter.myPrevious == NULL) 
145   {
146     PRemoveFirst (fDel,theAllocator);
147     theIter.myCurrent = myFirst;
148   }
149   else 
150   {
151     NCollection_ListNode* pNode = (theIter.myCurrent)->Next();
152     (theIter.myPrevious)->Next() = pNode;
153     fDel (theIter.myCurrent,theAllocator);
154     theIter.myCurrent = pNode;
155     if (pNode == NULL) 
156       myLast = theIter.myPrevious;
157     myLength--;
158   }
159 }
160
161 //=======================================================================
162 //function : PInsertBefore
163 //purpose  : 
164 //=======================================================================
165
166 void NCollection_BaseList::PInsertBefore (NCollection_ListNode* theNode,
167                                           Iterator& theIter)
168 {
169   Standard_NoSuchObject_Raise_if(!theIter.More(),
170                                  "NCollection_BaseList::PInsertBefore");
171   if (theIter.myPrevious == NULL) 
172   {
173     PPrepend(theNode);
174     theIter.myPrevious = myFirst;
175   }
176   else 
177   {
178     (theIter.myPrevious)->Next() = theNode;
179     theNode->Next() = theIter.myCurrent;
180     theIter.myPrevious = theNode;
181     myLength++;
182   }
183 }
184
185 //=======================================================================
186 //function : PInsertBefore
187 //purpose  : 
188 //=======================================================================
189
190 void NCollection_BaseList::PInsertBefore (NCollection_BaseList& theOther,
191                                           Iterator& theIter)
192 {
193   Standard_NoSuchObject_Raise_if(!theIter.More(),
194                                  "NCollection_BaseList::PInsertBefore");
195   if (theIter.myPrevious == NULL) 
196   {
197     theIter.myPrevious = theOther.myLast;
198     PPrepend(theOther);
199   }
200   else if (!theOther.IsEmpty())
201   {
202     myLength += theOther.myLength;
203     (theIter.myPrevious)->Next() = theOther.myFirst;
204     (theOther.myLast)->Next() = theIter.myCurrent;
205     theIter.myPrevious = theOther.myLast;
206     theOther.myLast = theOther.myFirst = NULL;
207     theOther.myLength = 0;
208   }
209 }
210
211 //=======================================================================
212 //function : PInsertAfter
213 //purpose  : 
214 //=======================================================================
215
216 void NCollection_BaseList::PInsertAfter (NCollection_ListNode* theNode,
217                                          Iterator& theIter)
218 {
219   Standard_NoSuchObject_Raise_if(!theIter.More(),
220                                  "NCollection_BaseList::PInsertAfter");
221   if (theIter.myCurrent == myLast)
222   {
223     PAppend(theNode);
224   }
225   else
226   {
227     theNode->Next() = (theIter.myCurrent)->Next();
228     (theIter.myCurrent)->Next() = theNode;
229     myLength++;
230   }
231 }
232
233 //=======================================================================
234 //function : PInsertAfter
235 //purpose  : 
236 //=======================================================================
237
238 void NCollection_BaseList::PInsertAfter(NCollection_BaseList& theOther,
239                                         Iterator& theIter)
240 {
241   Standard_NoSuchObject_Raise_if(!theIter.More(),
242                                  "NCollection_BaseList::PInsertAfter");
243   if (theIter.myCurrent == myLast)
244   {
245     PAppend(theOther);
246   }
247   else if (!theOther.IsEmpty())
248   {
249     myLength += theOther.myLength;
250     (theOther.myLast)->Next() = (theIter.myCurrent)->Next();
251     (theIter.myCurrent)->Next() = theOther.myFirst;
252     theOther.myLast = theOther.myFirst = NULL;
253     theOther.myLength = 0;
254   }
255 }
256
257 //=======================================================================
258 //function : PReverse
259 //purpose  : reverse the list
260 //=======================================================================
261
262 void NCollection_BaseList::PReverse ()
263 {
264   if (myLength > 1) {
265     NCollection_ListNode * aHead = myFirst->Next();
266     NCollection_ListNode * aNeck = myFirst;
267     aNeck->Next() = NULL;
268     while (aHead) {
269       NCollection_ListNode * aTmp = aHead->Next();
270       aHead->Next() = aNeck;
271       aNeck = aHead;
272       aHead = aTmp;
273     }
274     myLast  = myFirst;
275     myFirst = aNeck;
276   }
277 }